Whamcloud - gitweb
- readd the patch
authoralex <alex>
Mon, 12 Jan 2004 20:23:36 +0000 (20:23 +0000)
committeralex <alex>
Mon, 12 Jan 2004 20:23:36 +0000 (20:23 +0000)
lustre/kernel_patches/patches/2.6.0-mm2.patch [new file with mode: 0644]

diff --git a/lustre/kernel_patches/patches/2.6.0-mm2.patch b/lustre/kernel_patches/patches/2.6.0-mm2.patch
new file mode 100644 (file)
index 0000000..017d057
--- /dev/null
@@ -0,0 +1,203869 @@
+--- linux-2.6.0/arch/alpha/kernel/irq.c        2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/alpha/kernel/irq.c 2003-12-28 23:22:10.000000000 -0800
+@@ -252,9 +252,11 @@ static int
+ irq_affinity_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, irq_affinity[(long)data]);
++      if (count - len < 2)
+               return -EINVAL;
+-      return sprintf (page, "%016lx\n", irq_affinity[(long)data]);
++      len += sprintf(page + len, "\n");
++      return len;
+ }
+ static unsigned int
+@@ -331,10 +333,11 @@ static int
+ prof_cpu_mask_read_proc(char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      unsigned long *mask = (unsigned long *) data;
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, *(cpumask_t *)data);
++      if (count - len < 2)
+               return -EINVAL;
+-      return sprintf (page, "%016lx\n", *mask);
++      len += sprintf(page + len, "\n");
++      return len;
+ }
+ static int
+@@ -529,19 +532,21 @@ show_interrupts(struct seq_file *p, void
+ #ifdef CONFIG_SMP
+       int j;
+ #endif
+-      int i;
++      int i = *(loff_t *) v;
+       struct irqaction * action;
+       unsigned long flags;
+ #ifdef CONFIG_SMP
+-      seq_puts(p, "           ");
+-      for (i = 0; i < NR_CPUS; i++)
+-              if (cpu_online(i))
+-                      seq_printf(p, "CPU%d       ", i);
+-      seq_putc(p, '\n');
++      if (i == 0) {
++              seq_puts(p, "           ");
++              for (i = 0; i < NR_CPUS; i++)
++                      if (cpu_online(i))
++                              seq_printf(p, "CPU%d       ", i);
++              seq_putc(p, '\n');
++      }
+ #endif
+-      for (i = 0; i < ACTUAL_NR_IRQS; i++) {
++      if (i < ACTUAL_NR_IRQS) {
+               spin_lock_irqsave(&irq_desc[i].lock, flags);
+               action = irq_desc[i].action;
+               if (!action) 
+@@ -568,15 +573,16 @@ show_interrupts(struct seq_file *p, void
+               seq_putc(p, '\n');
+ unlock:
+               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+-      }
++      } else if (i == ACTUAL_NR_IRQS) {
+ #ifdef CONFIG_SMP
+-      seq_puts(p, "IPI: ");
+-      for (i = 0; i < NR_CPUS; i++)
+-              if (cpu_online(i))
+-                      seq_printf(p, "%10lu ", cpu_data[i].ipi_count);
+-      seq_putc(p, '\n');
++              seq_puts(p, "IPI: ");
++              for (i = 0; i < NR_CPUS; i++)
++                      if (cpu_online(i))
++                              seq_printf(p, "%10lu ", cpu_data[i].ipi_count);
++              seq_putc(p, '\n');
+ #endif
+-      seq_printf(p, "ERR: %10lu\n", irq_err_count);
++              seq_printf(p, "ERR: %10lu\n", irq_err_count);
++      }
+       return 0;
+ }
+--- linux-2.6.0/arch/alpha/kernel/traps.c      2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/alpha/kernel/traps.c       2003-12-28 23:22:11.000000000 -0800
+@@ -636,6 +636,7 @@ do_entUna(void * va, unsigned long opcod
+       lock_kernel();
+       printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n",
+               pc, va, opcode, reg);
++      dump_stack();
+       do_exit(SIGSEGV);
+ got_exception:
+--- linux-2.6.0/arch/arm26/kernel/irq.c        2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/arm26/kernel/irq.c 2003-12-28 23:22:06.000000000 -0800
+@@ -135,10 +135,10 @@ void enable_irq(unsigned int irq)
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i;
++      int i = *(loff_t *) v;
+       struct irqaction * action;
+-      for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               action = irq_desc[i].action;
+               if (!action)
+                       continue;
+@@ -148,10 +148,10 @@ int show_interrupts(struct seq_file *p, 
+                       seq_printf(p, ", %s", action->name);
+               }
+               seq_putc(p, '\n');
++      } else if (i == NR_IRQS) {
++              show_fiq_list(p, v);
++              seq_printf(p, "Err: %10lu\n", irq_err_count);
+       }
+-
+-      show_fiq_list(p, v);
+-      seq_printf(p, "Err: %10lu\n", irq_err_count);
+       return 0;
+ }
+--- linux-2.6.0/arch/arm/kernel/irq.c  2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/arm/kernel/irq.c   2003-12-28 23:22:06.000000000 -0800
+@@ -169,11 +169,11 @@ void disable_irq_wake(unsigned int irq)
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i;
++      int i = *(loff_t *) v;
+       struct irqaction * action;
+       unsigned long flags;
+-      for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               spin_lock_irqsave(&irq_controller_lock, flags);
+               action = irq_desc[i].action;
+               if (!action)
+@@ -187,12 +187,12 @@ int show_interrupts(struct seq_file *p, 
+               seq_putc(p, '\n');
+ unlock:
+               spin_unlock_irqrestore(&irq_controller_lock, flags);
+-      }
+-
++      } else if (i == NR_IRQS) {
+ #ifdef CONFIG_ARCH_ACORN
+-      show_fiq_list(p, v);
++              show_fiq_list(p, v);
+ #endif
+-      seq_printf(p, "Err: %10lu\n", irq_err_count);
++              seq_printf(p, "Err: %10lu\n", irq_err_count);
++      }
+       return 0;
+ }
+--- linux-2.6.0/arch/arm/mach-sa1100/Kconfig   2003-06-14 12:18:52.000000000 -0700
++++ 25/arch/arm/mach-sa1100/Kconfig    2003-12-28 23:23:06.000000000 -0800
+@@ -304,7 +304,7 @@ config SA1100_YOPY
+       depends on ARCH_SA1100
+       help
+         Say Y here to support the Yopy PDA.  Product information at
+-        <http://www.yopy.com/>.  See Documentation/arm/SA110/Yopy
++        <http://www.yopy.com/>.  See Documentation/arm/SA1100/Yopy
+         for more.
+ config SA1100_STORK
+--- linux-2.6.0/arch/arm/Makefile      2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/arm/Makefile       2003-12-28 23:21:55.000000000 -0800
+@@ -14,8 +14,6 @@ OBJCOPYFLAGS :=-O binary -R .note -R .co
+ GZFLAGS               :=-9
+ #CFLAGS               +=-pipe
+-CFLAGS                :=$(CFLAGS:-O2=-Os)
+-
+ ifeq ($(CONFIG_FRAME_POINTER),y)
+ CFLAGS                +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
+ endif
+--- linux-2.6.0/arch/cris/kernel/irq.c 2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/cris/kernel/irq.c  2003-12-28 23:22:06.000000000 -0800
+@@ -89,11 +89,11 @@ static struct irqaction *irq_action[NR_I
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i;
++      int i = *(loff_t *) v;
+       struct irqaction * action;
+       unsigned long flags;
+-      for (i = 0; i < NR_IRQS; i++) {
++      if (i < NR_IRQS) {
+               local_irq_save(flags);
+               action = irq_action[i];
+               if (!action) 
+--- linux-2.6.0/arch/h8300/Kconfig     2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/h8300/Kconfig      2003-12-28 23:21:55.000000000 -0800
+@@ -5,6 +5,10 @@
+ mainmenu "uClinux/h8300 (w/o MMU) Kernel Configuration"
++config H8300
++      bool
++      default y
++
+ config MMU
+       bool
+       default n
+--- linux-2.6.0/arch/h8300/Makefile    2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/h8300/Makefile     2003-12-28 23:21:55.000000000 -0800
+@@ -34,7 +34,7 @@ cflags-$(CONFIG_CPU_H8S)     := -ms
+ ldflags-$(CONFIG_CPU_H8S)     := -mh8300self
+ CFLAGS += $(cflags-y)
+-CFLAGS += -mint32 -fno-builtin -Os
++CFLAGS += -mint32 -fno-builtin
+ CFLAGS += -g
+ CFLAGS += -D__linux__
+ CFLAGS += -DUTS_SYSNAME=\"uClinux\"
+--- linux-2.6.0/arch/h8300/platform/h8300h/ints.c      2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/h8300/platform/h8300h/ints.c       2003-12-28 23:22:06.000000000 -0800
+@@ -228,9 +228,9 @@ asmlinkage void process_int(int vec, str
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i;
++      int i = *(loff_t *) v;
+-      for (i = 0; i < NR_IRQS; i++) {
++      if (i < NR_IRQS) {
+               if (irq_list[i]) {
+                       seq_printf(p, "%3d: %10u ",i,irq_list[i]->count);
+                       seq_printf(p, "%s\n", irq_list[i]->devname);
+--- linux-2.6.0/arch/h8300/platform/h8s/ints.c 2003-10-17 15:58:03.000000000 -0700
++++ 25/arch/h8300/platform/h8s/ints.c  2003-12-28 23:22:06.000000000 -0800
+@@ -280,9 +280,9 @@ asmlinkage void process_int(unsigned lon
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i;
++      int i = *(loff_t *) v;
+-      for (i = 0; i < NR_IRQS; i++) {
++      if (i < NR_IRQS) {
+               if (irq_list[i]) {
+                       seq_printf(p, "%3d: %10u ",i,irq_list[i]->count);
+                       seq_printf(p, "%s\n", irq_list[i]->devname);
+--- linux-2.6.0/arch/i386/boot/setup.S 2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/boot/setup.S  2003-12-28 23:26:36.000000000 -0800
+@@ -162,7 +162,7 @@ cmd_line_ptr:      .long 0                 # (Header versio
+                                       # can be located anywhere in
+                                       # low memory 0x10000 or higher.
+-ramdisk_max:  .long MAXMEM-1          # (Header version 0x0203 or later)
++ramdisk_max:  .long __MAXMEM-1        # (Header version 0x0203 or later)
+                                       # The highest safe address for
+                                       # the contents of an initrd
+--- linux-2.6.0/arch/i386/Kconfig      2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/Kconfig       2003-12-28 23:26:36.000000000 -0800
+@@ -115,10 +115,15 @@ config ACPI_SRAT
+       default y
+       depends on NUMA && (X86_SUMMIT || X86_GENERICARCH)
++config X86_SUMMIT_NUMA
++      bool
++      default y
++      depends on NUMA && (X86_SUMMIT || X86_GENERICARCH)
++
+ config X86_CYCLONE_TIMER
+-       bool 
+-       default y
+-       depends on X86_SUMMIT || X86_GENERICARCH
++      bool
++      default y
++      depends on X86_SUMMIT || X86_GENERICARCH
+ config ES7000_CLUSTERED_APIC
+       bool
+@@ -397,6 +402,54 @@ config X86_OOSTORE
+       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6
+       default y
++config X86_4G
++      bool "4 GB kernel-space and 4 GB user-space virtual memory support"
++      help
++          This option is only useful for systems that have more than 1 GB
++          of RAM.
++
++          The default kernel VM layout leaves 1 GB of virtual memory for
++          kernel-space mappings, and 3 GB of VM for user-space applications.
++          This option ups both the kernel-space VM and the user-space VM to
++          4 GB.
++
++          The cost of this option is additional TLB flushes done at
++          system-entry points that transition from user-mode into kernel-mode.
++          I.e. system calls and page faults, and IRQs that interrupt user-mode
++          code. There's also additional overhead to kernel operations that copy
++          memory to/from user-space. The overhead from this is hard to tell and
++          depends on the workload - it can be anything from no visible overhead
++          to 20-30% overhead. A good rule of thumb is to count with a runtime
++          overhead of 20%.
++
++          The upside is the much increased kernel-space VM, which more than
++          quadruples the maximum amount of RAM supported. Kernels compiled with
++          this option boot on 64GB of RAM and still have more than 3.1 GB of
++          'lowmem' left. Another bonus is that highmem IO bouncing decreases,
++          if used with drivers that still use bounce-buffers.
++
++          There's also a 33% increase in user-space VM size - database
++          applications might see a boost from this.
++
++          But the cost of the TLB flushes and the runtime overhead has to be
++          weighed against the bonuses offered by the larger VM spaces. The
++          dividing line depends on the actual workload - there might be 4 GB
++          systems that benefit from this option. Systems with less than 4 GB
++          of RAM will rarely see a benefit from this option - but it's not
++          out of question, the exact circumstances have to be considered.
++
++config X86_SWITCH_PAGETABLES
++      def_bool X86_4G
++
++config X86_4G_VM_LAYOUT
++      def_bool X86_4G
++
++config X86_UACCESS_INDIRECT
++      def_bool X86_4G
++
++config X86_HIGH_ENTRY
++      def_bool X86_4G
++
+ config HPET_TIMER
+       bool "HPET Timer Support"
+       help
+@@ -784,6 +837,25 @@ config MTRR
+         See <file:Documentation/mtrr.txt> for more information.
++config EFI
++      bool "Boot from EFI support (EXPERIMENTAL)"
++      depends on ACPI
++      default n
++      ---help---
++
++      This enables the the kernel to boot on EFI platforms using
++      system configuration information passed to it from the firmware.
++      This also enables the kernel to use any EFI runtime services that are
++      available (such as the EFI variable services).
++
++      This option is only useful on systems that have EFI firmware
++      and will result in a kernel image that is ~8k larger.  In addition,
++      you must use the latest ELILO loader available at
++      ftp.hpl.hp.com/pub/linux-ia64/ in order to take advantage of kernel
++      initialization using EFI information (neither GRUB nor LILO know
++      anything about EFI).  However, even with this option, the resultant
++      kernel should continue to boot on existing non-EFI platforms.
++
+ config HAVE_DEC_LOCK
+       bool
+       depends on (SMP || PREEMPT) && X86_CMPXCHG
+@@ -793,7 +865,7 @@ config HAVE_DEC_LOCK
+ # Summit needs it only when NUMA is on
+ config BOOT_IOREMAP
+       bool
+-      depends on ((X86_SUMMIT || X86_GENERICARCH) && NUMA)
++      depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI))
+       default y
+ endmenu
+@@ -1030,6 +1102,25 @@ config PCI_DIRECT
+       depends on PCI && ((PCI_GODIRECT || PCI_GOANY) || X86_VISWS)
+       default y
++config PCI_USE_VECTOR
++      bool "Vector-based interrupt indexing"
++      depends on X86_LOCAL_APIC
++      default n
++      help
++         This replaces the current existing IRQ-based index interrupt scheme
++         with the vector-base index scheme. The advantages of vector base
++         over IRQ base are listed below:
++         1) Support MSI implementation.
++         2) Support future IOxAPIC hotplug
++
++         Note that this enables MSI, Message Signaled Interrupt, on all
++         MSI capable device functions detected if users also install the
++         MSI patch. Message Signal Interrupt enables an MSI-capable
++         hardware device to send an inbound Memory Write on its PCI bus
++         instead of asserting IRQ signal on device IRQ pin.
++
++         If you don't know what to do here, say N.
++
+ source "drivers/pci/Kconfig"
+ config ISA
+@@ -1187,6 +1278,15 @@ config DEBUG_PAGEALLOC
+         This results in a large slowdown, but helps to find certain types
+         of memory corruptions.
++config SPINLINE
++      bool "Spinlock inlining"
++      depends on DEBUG_KERNEL
++      help
++        This will change spinlocks from out of line to inline, making them
++        account cost to the callers in readprofile, rather than the lock
++        itself (as ".text.lock.filename"). This can be helpful for finding
++        the callers of locks.
++
+ config DEBUG_HIGHMEM
+       bool "Highmem debugging"
+       depends on DEBUG_KERNEL && HIGHMEM
+@@ -1203,20 +1303,208 @@ config DEBUG_INFO
+         Say Y here only if you plan to use gdb to debug the kernel.
+         If you don't debug the kernel, you can say N.
+         
++config LOCKMETER
++      bool "Kernel lock metering"
++      depends on SMP
++      help
++        Say Y to enable kernel lock metering, which adds overhead to SMP locks,
++        but allows you to see various statistics using the lockstat command.
++
+ config DEBUG_SPINLOCK_SLEEP
+       bool "Sleep-inside-spinlock checking"
+       help
+         If you say Y here, various routines which may sleep will become very
+         noisy if they are called with a spinlock held.        
++config KGDB
++      bool "Include kgdb kernel debugger"
++      depends on DEBUG_KERNEL
++      help
++        If you say Y here, the system will be compiled with the debug
++        option (-g) and a debugging stub will be included in the
++        kernel.  This stub communicates with gdb on another (host)
++        computer via a serial port.  The host computer should have
++        access to the kernel binary file (vmlinux) and a serial port
++        that is connected to the target machine.  Gdb can be made to
++        configure the serial port or you can use stty and setserial to
++        do this. See the 'target' command in gdb. This option also
++        configures in the ability to request a breakpoint early in the
++        boot process.  To request the breakpoint just include 'kgdb'
++        as a boot option when booting the target machine.  The system
++        will then break as soon as it looks at the boot options.  This
++        option also installs a breakpoint in panic and sends any
++        kernel faults to the debugger. For more information see the
++        Documentation/i386/kgdb.txt file.
++
++choice
++      depends on KGDB
++      prompt "Debug serial port BAUD"
++      default KGDB_115200BAUD
++      help
++        Gdb and the kernel stub need to agree on the baud rate to be
++        used.  Some systems (x86 family at this writing) allow this to
++        be configured.
++
++config KGDB_9600BAUD
++      bool "9600"
++
++config KGDB_19200BAUD
++      bool "19200"
++
++config KGDB_38400BAUD
++      bool "38400"
++
++config KGDB_57600BAUD
++      bool "57600"
++
++config KGDB_115200BAUD
++      bool "115200"
++endchoice
++
++config KGDB_PORT
++      hex "hex I/O port address of the debug serial port"
++      depends on KGDB
++      default  3f8
++      help
++        Some systems (x86 family at this writing) allow the port
++        address to be configured.  The number entered is assumed to be
++        hex, don't put 0x in front of it.  The standard address are:
++        COM1 3f8 , irq 4 and COM2 2f8 irq 3.  Setserial /dev/ttySx
++        will tell you what you have.  It is good to test the serial
++        connection with a live system before trying to debug.
++
++config KGDB_IRQ
++      int "IRQ of the debug serial port"
++      depends on KGDB
++      default 4
++      help
++        This is the irq for the debug port.  If everything is working
++        correctly and the kernel has interrupts on a control C to the
++        port should cause a break into the kernel debug stub.
++
++config DEBUG_INFO
++      bool
++      depends on KGDB
++      default y
++
++config KGDB_MORE
++      bool "Add any additional compile options"
++      depends on KGDB
++      default n
++      help
++        Saying yes here turns on the ability to enter additional
++        compile options.
++
++
++config KGDB_OPTIONS
++      depends on KGDB_MORE
++      string "Additional compile arguments"
++      default "-O1"
++      help
++        This option allows you enter additional compile options for
++        the whole kernel compile.  Each platform will have a default
++        that seems right for it.  For example on PPC "-ggdb -O1", and
++        for i386 "-O1".  Note that by configuring KGDB "-g" is already
++        turned on.  In addition, on i386 platforms
++        "-fomit-frame-pointer" is deleted from the standard compile
++        options.
++
++config NO_KGDB_CPUS
++      int "Number of CPUs"
++      depends on KGDB && SMP
++      default NR_CPUS
++      help
++
++        This option sets the number of cpus for kgdb ONLY.  It is used
++        to prune some internal structures so they look "nice" when
++        displayed with gdb.  This is to overcome possibly larger
++        numbers that may have been entered above.  Enter the real
++        number to get nice clean kgdb_info displays.
++
++config KGDB_TS
++      bool "Enable kgdb time stamp macros?"
++      depends on KGDB
++      default n
++      help
++        Kgdb event macros allow you to instrument your code with calls
++        to the kgdb event recording function.  The event log may be
++        examined with gdb at a break point.  Turning on this
++        capability also allows you to choose how many events to
++        keep. Kgdb always keeps the lastest events.
++
++choice
++      depends on KGDB_TS
++      prompt "Max number of time stamps to save?"
++      default KGDB_TS_128
++
++config KGDB_TS_64
++      bool "64"
++
++config KGDB_TS_128
++      bool "128"
++
++config KGDB_TS_256
++      bool "256"
++
++config KGDB_TS_512
++      bool "512"
++
++config KGDB_TS_1024
++      bool "1024"
++
++endchoice
++
++config STACK_OVERFLOW_TEST
++      bool "Turn on kernel stack overflow testing?"
++      depends on KGDB
++      default n
++      help
++        This option enables code in the front line interrupt handlers
++        to check for kernel stack overflow on interrupts and system
++        calls.  This is part of the kgdb code on x86 systems.
++
++config KGDB_CONSOLE
++      bool "Enable serial console thru kgdb port"
++      depends on KGDB
++      default n
++      help
++        This option enables the command line "console=kgdb" option.
++        When the system is booted with this option in the command line
++        all kernel printk output is sent to gdb (as well as to other
++        consoles).  For this to work gdb must be connected.  For this
++        reason, this command line option will generate a breakpoint if
++        gdb has not yet connected.  After the gdb continue command is
++        given all pent up console output will be printed by gdb on the
++        host machine.  Neither this option, nor KGDB require the
++        serial driver to be configured.
++
++config KGDB_SYSRQ
++      bool "Turn on SysRq 'G' command to do a break?"
++      depends on KGDB
++      default y
++      help
++        This option includes an option in the SysRq code that allows
++        you to enter SysRq G which generates a breakpoint to the KGDB
++        stub.  This will work if the keyboard is alive and can
++        interrupt the system.  Because of constraints on when the
++        serial port interrupt can be enabled, this code may allow you
++        to interrupt the system before the serial port control C is
++        available.  Just say yes here.
++
+ config FRAME_POINTER
+       bool "Compile the kernel with frame pointers"
++      default KGDB
+       help
+         If you say Y here the resulting kernel image will be slightly larger
+         and slower, but it will give very useful debugging information.
+         If you don't debug the kernel, you can say N, but we may not be able
+         to solve problems without frame pointers.
++config MAGIC_SYSRQ
++      bool
++      depends on KGDB_SYSRQ
++      default y
++
+ config X86_EXTRA_IRQS
+       bool
+       depends on X86_LOCAL_APIC || X86_VOYAGER
+--- linux-2.6.0/arch/i386/kernel/acpi/boot.c   2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/i386/kernel/acpi/boot.c    2003-12-28 23:21:57.000000000 -0800
+@@ -26,6 +26,7 @@
+ #include <linux/init.h>
+ #include <linux/config.h>
+ #include <linux/acpi.h>
++#include <linux/efi.h>
+ #include <asm/pgalloc.h>
+ #include <asm/io_apic.h>
+ #include <asm/apic.h>
+@@ -40,9 +41,8 @@
+ #define PREFIX                        "ACPI: "
+-extern int acpi_disabled;
+-extern int acpi_irq;
+-extern int acpi_ht;
++int acpi_noirq __initdata = 0;        /* skip ACPI IRQ initialization */
++int acpi_ht __initdata = 1;   /* enable HT */
+ int acpi_lapic = 0;
+ int acpi_ioapic = 0;
+@@ -249,29 +249,66 @@ acpi_parse_nmi_src (
+ #ifdef        CONFIG_ACPI_BUS
+ /*
+- * Set specified PIC IRQ to level triggered mode.
++ * "acpi_pic_sci=level" (current default)
++ * programs the PIC-mode SCI to Level Trigger.
++ * (NO-OP if the BIOS set Level Trigger already)
++ *
++ * If a PIC-mode SCI is not recogznied or gives spurious IRQ7's
++ * it may require Edge Trigger -- use "acpi_pic_sci=edge"
++ * (NO-OP if the BIOS set Edge Trigger already)
+  *
+  * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers
+  * for the 8259 PIC.  bit[n] = 1 means irq[n] is Level, otherwise Edge.
+  * ECLR1 is IRQ's 0-7 (IRQ 0, 1, 2 must be 0)
+  * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0)
+- *
+- * As the BIOS should have done this for us,
+- * print a warning if the IRQ wasn't already set to level.
+  */
+-void acpi_pic_set_level_irq(unsigned int irq)
++static int __initdata acpi_pic_sci_trigger;   /* 0: level, 1: edge */
++
++void __init
++acpi_pic_sci_set_trigger(unsigned int irq)
+ {
+       unsigned char mask = 1 << (irq & 7);
+       unsigned int port = 0x4d0 + (irq >> 3);
+       unsigned char val = inb(port);
++      
++      printk(PREFIX "IRQ%d SCI:", irq);
+       if (!(val & mask)) {
+-              printk(KERN_WARNING PREFIX "IRQ %d was Edge Triggered, "
+-                      "setting to Level Triggerd\n", irq);
+-              outb(val | mask, port);
++              printk(" Edge");
++
++              if (!acpi_pic_sci_trigger) {
++                      printk(" set to Level");
++                      outb(val | mask, port);
++              }
++      } else {
++              printk(" Level");
++
++              if (acpi_pic_sci_trigger) {
++                      printk(" set to Edge");
++                      outb(val | mask, port);
++              }
++      }
++      printk(" Trigger.\n");
++}
++
++int __init
++acpi_pic_sci_setup(char *str)
++{
++      while (str && *str) {
++              if (strncmp(str, "level", 5) == 0)
++                      acpi_pic_sci_trigger = 0;       /* force level trigger */
++              if (strncmp(str, "edge", 4) == 0)
++                      acpi_pic_sci_trigger = 1;       /* force edge trigger */
++              str = strchr(str, ',');
++              if (str)
++                      str += strspn(str, ", \t");
+       }
++      return 1;
+ }
++
++__setup("acpi_pic_sci=", acpi_pic_sci_setup);
++
+ #endif /* CONFIG_ACPI_BUS */
+@@ -326,11 +363,48 @@ static int __init acpi_parse_hpet(unsign
+ }
+ #endif
++/* detect the location of the ACPI PM Timer */
++#ifdef CONFIG_X86_PM_TIMER
++extern u32 pmtmr_ioport;
++
++static int __init acpi_parse_fadt(unsigned long phys, unsigned long size)
++{
++      struct fadt_descriptor_rev2 *fadt =0;
++
++      fadt = (struct fadt_descriptor_rev2*) __acpi_map_table(phys,size);
++      if(!fadt) {
++              printk(KERN_WARNING PREFIX "Unable to map FADT\n");
++              return 0;
++      }
++
++      if (fadt->revision >= FADT2_REVISION_ID) {
++              /* FADT rev. 2 */
++              if (fadt->xpm_tmr_blk.address_space_id != ACPI_ADR_SPACE_SYSTEM_IO)
++                      return 0;
++
++              pmtmr_ioport = fadt->xpm_tmr_blk.address;
++      } else {
++              /* FADT rev. 1 */
++              pmtmr_ioport = fadt->V1_pm_tmr_blk;
++      }
++      if (pmtmr_ioport)
++              printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", pmtmr_ioport);
++      return 0;
++}
++#endif
++
++
+ unsigned long __init
+ acpi_find_rsdp (void)
+ {
+       unsigned long           rsdp_phys = 0;
++      if (efi_enabled) {
++              if (efi.acpi20)
++                      return __pa(efi.acpi20);
++              else if (efi.acpi)
++                      return __pa(efi.acpi);
++      }
+       /*
+        * Scan memory looking for the RSDP signature. First search EBDA (low
+        * memory) paragraphs and then search upper memory (E0000-FFFFF).
+@@ -380,8 +454,10 @@ acpi_boot_init (void)
+        * Initialize the ACPI boot-time table parser.
+        */
+       result = acpi_table_init();
+-      if (result)
++      if (result) {
++              acpi_disabled = 1;
+               return result;
++      }
+       result = acpi_blacklisted();
+       if (result) {
+@@ -462,7 +538,7 @@ acpi_boot_init (void)
+        * If MPS is present, it will handle them,
+        * otherwise the system will stay in PIC mode
+        */
+-      if (acpi_disabled || !acpi_irq) {
++      if (acpi_disabled || acpi_noirq) {
+               return 1;
+         }
+@@ -504,6 +580,8 @@ acpi_boot_init (void)
+       acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
++      acpi_irq_balance_set(NULL);
++
+       acpi_ioapic = 1;
+ #endif /* CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER */
+@@ -519,5 +597,9 @@ acpi_boot_init (void)
+       acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
+ #endif
++#ifdef CONFIG_X86_PM_TIMER
++      acpi_table_parse(ACPI_FADT, acpi_parse_fadt);
++#endif
++
+       return 0;
+ }
+--- linux-2.6.0/arch/i386/kernel/asm-offsets.c 2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/asm-offsets.c  2003-12-28 23:26:36.000000000 -0800
+@@ -4,9 +4,11 @@
+  * to extract and format the required data.
+  */
++#include <linux/sched.h>
+ #include <linux/signal.h>
+ #include <asm/ucontext.h>
+ #include "sigframe.h"
++#include <asm/fixmap.h>
+ #define DEFINE(sym, val) \
+         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+@@ -28,4 +30,17 @@ void foo(void)
+       DEFINE(RT_SIGFRAME_sigcontext,
+              offsetof (struct rt_sigframe, uc.uc_mcontext));
++      DEFINE(TI_task, offsetof (struct thread_info, task));
++      DEFINE(TI_exec_domain, offsetof (struct thread_info, exec_domain));
++      DEFINE(TI_flags, offsetof (struct thread_info, flags));
++      DEFINE(TI_preempt_count, offsetof (struct thread_info, preempt_count));
++      DEFINE(TI_addr_limit, offsetof (struct thread_info, addr_limit));
++      DEFINE(TI_real_stack, offsetof (struct thread_info, real_stack));
++      DEFINE(TI_virtual_stack, offsetof (struct thread_info, virtual_stack));
++      DEFINE(TI_user_pgd, offsetof (struct thread_info, user_pgd));
++
++      DEFINE(FIX_ENTRY_TRAMPOLINE_0_addr, __fix_to_virt(FIX_ENTRY_TRAMPOLINE_0));
++      DEFINE(FIX_VSYSCALL_addr, __fix_to_virt(FIX_VSYSCALL));
++      DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
++      DEFINE(task_thread_db7, offsetof (struct task_struct, thread.debugreg[7]));
+ }
+--- linux-2.6.0/arch/i386/kernel/cpu/common.c  2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/cpu/common.c   2003-12-28 23:26:36.000000000 -0800
+@@ -510,16 +510,20 @@ void __init cpu_init (void)
+               BUG();
+       enter_lazy_tlb(&init_mm, current);
+-      load_esp0(t, thread->esp0);
++      load_esp0(t, thread);
+       set_tss_desc(cpu,t);
+       cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff;
+       load_TR_desc();
+-      load_LDT(&init_mm.context);
++      if (cpu)
++              load_LDT(&init_mm.context);
+       /* Set up doublefault TSS pointer in the GDT */
+       __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
+       cpu_gdt_table[cpu][GDT_ENTRY_DOUBLEFAULT_TSS].b &= 0xfffffdff;
++      if (cpu)
++              trap_init_virtual_GDT();
++
+       /* Clear %fs and %gs. */
+       asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
+--- linux-2.6.0/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c      2003-09-08 13:58:55.000000000 -0700
++++ 25/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c       2003-12-28 23:22:07.000000000 -0800
+@@ -73,6 +73,16 @@ static struct cpufreq_frequency_table op
+       { .frequency = CPUFREQ_TABLE_END }
+ };
++/* Ultra Low Voltage Intel Pentium M processor 1000MHz */
++static struct cpufreq_frequency_table op_1000[] =
++  {
++    OP(600,  844),
++    OP(800,  972),
++    OP(900, 988),
++    OP(1000, 1004),
++    { .frequency = CPUFREQ_TABLE_END }
++  };
++
+ /* Low Voltage Intel Pentium M processor 1.10GHz */
+ static struct cpufreq_frequency_table op_1100[] =
+ {
+@@ -165,6 +175,7 @@ static struct cpufreq_frequency_table op
+ static const struct cpu_model models[] = 
+ {
+        _CPU( 900, " 900"),
++       CPU(1000),
+       CPU(1100),
+       CPU(1200),
+       CPU(1300),
+--- linux-2.6.0/arch/i386/kernel/cpu/intel.c   2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/i386/kernel/cpu/intel.c    2003-12-28 23:26:36.000000000 -0800
+@@ -1,5 +1,7 @@
++#include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
++
+ #include <linux/string.h>
+ #include <linux/bitops.h>
+ #include <linux/smp.h>
+@@ -8,10 +10,15 @@
+ #include <asm/processor.h>
+ #include <asm/msr.h>
+ #include <asm/uaccess.h>
++#include <asm/desc.h>
+ #include "cpu.h"
+-extern int trap_init_f00f_bug(void);
++#ifdef CONFIG_X86_LOCAL_APIC
++#include <asm/mpspec.h>
++#include <asm/apic.h>
++#include <mach_apic.h>
++#endif
+ #ifdef CONFIG_X86_INTEL_USERCOPY
+ /*
+@@ -157,7 +164,7 @@ static void __init init_intel(struct cpu
+               c->f00f_bug = 1;
+               if ( !f00f_workaround_enabled ) {
+-                      trap_init_f00f_bug();
++                      trap_init_virtual_IDT();
+                       printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
+                       f00f_workaround_enabled = 1;
+               }
+@@ -240,6 +247,12 @@ static void __init init_intel(struct cpu
+       /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until model 3 mask 3 */
+       if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633)
+               clear_bit(X86_FEATURE_SEP, c->x86_capability);
++      /*
++       * FIXME: SEP is disabled for 4G/4G for now:
++       */
++#ifdef CONFIG_X86_HIGH_ENTRY
++      clear_bit(X86_FEATURE_SEP, c->x86_capability);
++#endif
+       /* Names for the Pentium II/Celeron processors 
+          detectable only by also checking the cache size.
+@@ -277,6 +290,7 @@ static void __init init_intel(struct cpu
+               extern  int phys_proc_id[NR_CPUS];
+               
+               u32     eax, ebx, ecx, edx;
++              int     index_lsb, index_msb, tmp;
+               int     cpu = smp_processor_id();
+               cpuid(1, &eax, &ebx, &ecx, &edx);
+@@ -285,6 +299,8 @@ static void __init init_intel(struct cpu
+               if (smp_num_siblings == 1) {
+                       printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
+               } else if (smp_num_siblings > 1 ) {
++                      index_lsb = 0;
++                      index_msb = 31;
+                       /*
+                        * At this point we only support two siblings per
+                        * processor package.
+@@ -295,13 +311,19 @@ static void __init init_intel(struct cpu
+                               smp_num_siblings = 1;
+                               goto too_many_siblings;
+                       }
+-                      /* cpuid returns the value latched in the HW at reset,
+-                       * not the APIC ID register's value.  For any box
+-                       * whose BIOS changes APIC IDs, like clustered APIC
+-                       * systems, we must use hard_smp_processor_id.
+-                       * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
+-                       */
+-                      phys_proc_id[cpu] = hard_smp_processor_id() & ~(smp_num_siblings - 1);
++                      tmp = smp_num_siblings;
++                      while ((tmp & 1) == 0) {
++                              tmp >>=1 ;
++                              index_lsb++;
++                      }
++                      tmp = smp_num_siblings;
++                      while ((tmp & 0x80000000 ) == 0) {
++                              tmp <<=1 ;
++                              index_msb--;
++                      }
++                      if (index_lsb != index_msb )
++                              index_msb++;
++                      phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
+                       printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
+                                phys_proc_id[cpu]);
+--- linux-2.6.0/arch/i386/kernel/dmi_scan.c    2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/i386/kernel/dmi_scan.c     2003-12-28 23:21:33.000000000 -0800
+@@ -6,6 +6,7 @@
+ #include <linux/module.h>
+ #include <linux/apm_bios.h>
+ #include <linux/slab.h>
++#include <asm/acpi.h>
+ #include <asm/io.h>
+ #include <linux/pm.h>
+ #include <asm/system.h>
+@@ -16,6 +17,7 @@ EXPORT_SYMBOL(dmi_broken);
+ int is_sony_vaio_laptop;
+ int is_unsafe_smbus;
++int es7000_plat = 0;
+ struct dmi_header
+ {
+@@ -504,6 +506,7 @@ static __init int print_if_true(struct d
+ }
++#ifdef        CONFIG_ACPI_BOOT
+ extern int acpi_disabled, acpi_force;
+ static __init __attribute__((unused)) int acpi_disable(struct dmi_blacklist *d) 
+@@ -518,8 +521,6 @@ static __init __attribute__((unused)) in
+       return 0;
+ } 
+-
+-#ifdef        CONFIG_ACPI_BOOT
+ extern int acpi_ht;
+ /*
+@@ -542,10 +543,8 @@ static __init __attribute__((unused)) in
+ #ifdef        CONFIG_ACPI_PCI
+ static __init int disable_acpi_pci(struct dmi_blacklist *d) 
+ { 
+-      extern __init void pci_disable_acpi(void) ;
+-
+       printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident);         
+-      pci_disable_acpi();
++      acpi_noirq_set();
+       return 0;
+ } 
+ #endif
+@@ -1011,6 +1010,7 @@ static __init void dmi_check_blacklist(v
+                               printk(KERN_NOTICE "ACPI disabled because your bios is from %s and too old\n", s);
+                               printk(KERN_NOTICE "You can enable it with acpi=force\n");
+                               acpi_disabled = 1; 
++                              acpi_ht = 0;
+                       } 
+               }
+       }
+--- linux-2.6.0/arch/i386/kernel/doublefault.c 2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/doublefault.c  2003-12-28 23:26:36.000000000 -0800
+@@ -7,12 +7,13 @@
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+ #include <asm/desc.h>
++#include <asm/fixmap.h>
+ #define DOUBLEFAULT_STACKSIZE (1024)
+ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
+ #define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
+-#define ptr_ok(x) ((x) > 0xc0000000 && (x) < 0xc1000000)
++#define ptr_ok(x) (((x) > __PAGE_OFFSET && (x) < (__PAGE_OFFSET + 0x01000000)) || ((x) >= FIXADDR_START))
+ static void doublefault_fn(void)
+ {
+@@ -38,8 +39,8 @@ static void doublefault_fn(void)
+                       printk("eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
+                               t->eax, t->ebx, t->ecx, t->edx);
+-                      printk("esi = %08lx, edi = %08lx\n",
+-                              t->esi, t->edi);
++                      printk("esi = %08lx, edi = %08lx, ebp = %08lx\n",
++                              t->esi, t->edi, t->ebp);
+               }
+       }
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/efi.c  2003-12-28 23:21:45.000000000 -0800
+@@ -0,0 +1,645 @@
++/*
++ * Extensible Firmware Interface
++ *
++ * Based on Extensible Firmware Interface Specification version 1.0
++ *
++ * Copyright (C) 1999 VA Linux Systems
++ * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
++ * Copyright (C) 1999-2002 Hewlett-Packard Co.
++ *    David Mosberger-Tang <davidm@hpl.hp.com>
++ *    Stephane Eranian <eranian@hpl.hp.com>
++ *
++ * All EFI Runtime Services are not implemented yet as EFI only
++ * supports physical mode addressing on SoftSDV. This is to be fixed
++ * in a future version.  --drummond 1999-07-20
++ *
++ * Implemented EFI runtime services and virtual mode calls.  --davidm
++ *
++ * Goutham Rao: <goutham.rao@intel.com>
++ *    Skip non-WB memory and ignore empty memory ranges.
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/types.h>
++#include <linux/time.h>
++#include <linux/spinlock.h>
++#include <linux/bootmem.h>
++#include <linux/ioport.h>
++#include <linux/proc_fs.h>
++#include <linux/efi.h>
++
++#include <asm/setup.h>
++#include <asm/io.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/processor.h>
++#include <asm/desc.h>
++#include <asm/pgalloc.h>
++#include <asm/tlbflush.h>
++
++#define EFI_DEBUG     0
++#define PFX           "EFI: "
++
++extern efi_status_t asmlinkage efi_call_phys(void *, ...);
++
++struct efi efi;
++struct efi efi_phys __initdata;
++struct efi_memory_map memmap __initdata;
++
++/*
++ * We require an early boot_ioremap mapping mechanism initially
++ */
++extern void * boot_ioremap(unsigned long, unsigned long);
++
++/*
++ * efi_dir is allocated here, but the directory isn't created
++ * here, as proc_mkdir() doesn't work this early in the bootup
++ * process.  Therefore, each module, like efivars, must test for
++ *    if (!efi_dir) efi_dir = proc_mkdir("efi", NULL);
++ * prior to creating their own entries under /proc/efi.
++ */
++#ifdef CONFIG_PROC_FS
++struct proc_dir_entry *efi_dir;
++#endif
++
++
++/*
++ * To make EFI call EFI runtime service in physical addressing mode we need
++ * prelog/epilog before/after the invocation to disable interrupt, to
++ * claim EFI runtime service handler exclusively and to duplicate a memory in
++ * low memory space say 0 - 3G.
++ */
++
++static unsigned long efi_rt_eflags;
++static spinlock_t efi_rt_lock = SPIN_LOCK_UNLOCKED;
++static pgd_t efi_bak_pg_dir_pointer[2];
++
++static void efi_call_phys_prelog(void)
++{
++      unsigned long cr4;
++      unsigned long temp;
++
++      spin_lock(&efi_rt_lock);
++      local_irq_save(efi_rt_eflags);
++
++      /*
++       * If I don't have PSE, I should just duplicate two entries in page
++       * directory. If I have PSE, I just need to duplicate one entry in
++       * page directory.
++       */
++      __asm__ __volatile__("movl %%cr4, %0":"=r"(cr4));
++
++      if (cr4 & X86_CR4_PSE) {
++              efi_bak_pg_dir_pointer[0].pgd =
++                  swapper_pg_dir[pgd_index(0)].pgd;
++              swapper_pg_dir[0].pgd =
++                  swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
++      } else {
++              efi_bak_pg_dir_pointer[0].pgd =
++                  swapper_pg_dir[pgd_index(0)].pgd;
++              efi_bak_pg_dir_pointer[1].pgd =
++                  swapper_pg_dir[pgd_index(0x400000)].pgd;
++              swapper_pg_dir[pgd_index(0)].pgd =
++                  swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
++              temp = PAGE_OFFSET + 0x400000;
++              swapper_pg_dir[pgd_index(0x400000)].pgd =
++                  swapper_pg_dir[pgd_index(temp)].pgd;
++      }
++
++      /*
++       * After the lock is released, the original page table is restored.
++       */
++      local_flush_tlb();
++
++      cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
++      __asm__ __volatile__("lgdt %0":"=m"
++                          (*(struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0])));
++}
++
++static void efi_call_phys_epilog(void)
++{
++      unsigned long cr4;
++
++      cpu_gdt_descr[0].address =
++              (unsigned long) __va(cpu_gdt_descr[0].address);
++      __asm__ __volatile__("lgdt %0":"=m"(cpu_gdt_descr));
++      __asm__ __volatile__("movl %%cr4, %0":"=r"(cr4));
++
++      if (cr4 & X86_CR4_PSE) {
++              swapper_pg_dir[pgd_index(0)].pgd =
++                  efi_bak_pg_dir_pointer[0].pgd;
++      } else {
++              swapper_pg_dir[pgd_index(0)].pgd =
++                  efi_bak_pg_dir_pointer[0].pgd;
++              swapper_pg_dir[pgd_index(0x400000)].pgd =
++                  efi_bak_pg_dir_pointer[1].pgd;
++      }
++
++      /*
++       * After the lock is released, the original page table is restored.
++       */
++      local_flush_tlb();
++
++      local_irq_restore(efi_rt_eflags);
++      spin_unlock(&efi_rt_lock);
++}
++
++static efi_status_t
++phys_efi_set_virtual_address_map(unsigned long memory_map_size,
++                               unsigned long descriptor_size,
++                               u32 descriptor_version,
++                               efi_memory_desc_t *virtual_map)
++{
++      efi_status_t status;
++
++      efi_call_phys_prelog();
++      status = efi_call_phys(efi_phys.set_virtual_address_map,
++                                   memory_map_size, descriptor_size,
++                                   descriptor_version, virtual_map);
++      efi_call_phys_epilog();
++      return status;
++}
++
++efi_status_t
++phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
++{
++      efi_status_t status;
++
++      efi_call_phys_prelog();
++      status = efi_call_phys(efi_phys.get_time, tm, tc);
++      efi_call_phys_epilog();
++      return status;
++}
++
++int inline efi_set_rtc_mmss(unsigned long nowtime)
++{
++      int real_seconds, real_minutes;
++      efi_status_t    status;
++      efi_time_t      eft;
++      efi_time_cap_t  cap;
++
++      spin_lock(&efi_rt_lock);
++      status = efi.get_time(&eft, &cap);
++      spin_unlock(&efi_rt_lock);
++      if (status != EFI_SUCCESS)
++              panic("Ooops, efitime: can't read time!\n");
++      real_seconds = nowtime % 60;
++      real_minutes = nowtime / 60;
++
++      if (((abs(real_minutes - eft.minute) + 15)/30) & 1)
++              real_minutes += 30;
++      real_minutes %= 60;
++
++      eft.minute = real_minutes;
++      eft.second = real_seconds;
++
++      if (status != EFI_SUCCESS) {
++              printk("Ooops: efitime: can't read time!\n");
++              return -1;
++      }
++      return 0;
++}
++/*
++ * This should only be used during kernel init and before runtime
++ * services have been remapped, therefore, we'll need to call in physical
++ * mode.  Note, this call isn't used later, so mark it __init.
++ */
++unsigned long inline __init efi_get_time(void)
++{
++      efi_status_t status;
++      efi_time_t eft;
++      efi_time_cap_t cap;
++
++      status = phys_efi_get_time(&eft, &cap);
++      if (status != EFI_SUCCESS)
++              printk("Oops: efitime: can't read time status: 0x%lx\n",status);
++
++      return mktime(eft.year, eft.month, eft.day, eft.hour,
++                      eft.minute, eft.second);
++}
++
++int is_available_memory(efi_memory_desc_t * md)
++{
++      if (!(md->attribute & EFI_MEMORY_WB))
++              return 0;
++
++      switch (md->type) {
++              case EFI_LOADER_CODE:
++              case EFI_LOADER_DATA:
++              case EFI_BOOT_SERVICES_CODE:
++              case EFI_BOOT_SERVICES_DATA:
++              case EFI_CONVENTIONAL_MEMORY:
++                      return 1;
++      }
++      return 0;
++}
++
++/*
++ * We need to map the EFI memory map again after paging_init().
++ */
++void __init efi_map_memmap(void)
++{
++      memmap.map = NULL;
++
++      memmap.map = (efi_memory_desc_t *)
++              bt_ioremap((unsigned long) memmap.phys_map,
++                      (memmap.nr_map * sizeof(efi_memory_desc_t)));
++
++      if (memmap.map == NULL)
++              printk(KERN_ERR PFX "Could not remap the EFI memmap!\n");
++}
++
++void __init print_efi_memmap(void)
++{
++      efi_memory_desc_t *md;
++      int i;
++
++      for (i = 0; i < memmap.nr_map; i++) {
++              md = &memmap.map[i];
++              printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, "
++                      "range=[0x%016llx-0x%016llx) (%lluMB)\n",
++                      i, md->type, md->attribute, md->phys_addr,
++                      md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
++                      (md->num_pages >> (20 - EFI_PAGE_SHIFT)));
++      }
++}
++
++/*
++ * Walks the EFI memory map and calls CALLBACK once for each EFI
++ * memory descriptor that has memory that is available for kernel use.
++ */
++void efi_memmap_walk(efi_freemem_callback_t callback, void *arg)
++{
++      int prev_valid = 0;
++      struct range {
++              unsigned long start;
++              unsigned long end;
++      } prev, curr;
++      efi_memory_desc_t *md;
++      unsigned long start, end;
++      int i;
++
++      for (i = 0; i < memmap.nr_map; i++) {
++              md = &memmap.map[i];
++
++              if ((md->num_pages == 0) || (!is_available_memory(md)))
++                      continue;
++
++              curr.start = md->phys_addr;
++              curr.end = curr.start + (md->num_pages << EFI_PAGE_SHIFT);
++
++              if (!prev_valid) {
++                      prev = curr;
++                      prev_valid = 1;
++              } else {
++                      if (curr.start < prev.start)
++                              printk(KERN_INFO PFX "Unordered memory map\n");
++                      if (prev.end == curr.start)
++                              prev.end = curr.end;
++                      else {
++                              start =
++                                  (unsigned long) (PAGE_ALIGN(prev.start));
++                              end = (unsigned long) (prev.end & PAGE_MASK);
++                              if ((end > start)
++                                  && (*callback) (start, end, arg) < 0)
++                                      return;
++                              prev = curr;
++                      }
++              }
++      }
++      if (prev_valid) {
++              start = (unsigned long) PAGE_ALIGN(prev.start);
++              end = (unsigned long) (prev.end & PAGE_MASK);
++              if (end > start)
++                      (*callback) (start, end, arg);
++      }
++}
++
++void __init efi_init(void)
++{
++      efi_config_table_t *config_tables;
++      efi_runtime_services_t *runtime;
++      efi_char16_t *c16;
++      char vendor[100] = "unknown";
++      unsigned long num_config_tables;
++      int i = 0;
++
++      memset(&efi, 0, sizeof(efi) );
++      memset(&efi_phys, 0, sizeof(efi_phys));
++
++      efi_phys.systab = EFI_SYSTAB;
++      memmap.phys_map = EFI_MEMMAP;
++      memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE;
++      memmap.desc_version = EFI_MEMDESC_VERSION;
++
++      efi.systab = (efi_system_table_t *)
++              boot_ioremap((unsigned long) efi_phys.systab,
++                      sizeof(efi_system_table_t));
++      /*
++       * Verify the EFI Table
++       */
++      if (efi.systab == NULL)
++              printk(KERN_ERR PFX "Woah! Couldn't map the EFI system table.\n");
++      if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
++              printk(KERN_ERR PFX "Woah! EFI system table signature incorrect\n");
++      if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
++              printk(KERN_ERR PFX
++                     "Warning: EFI system table major version mismatch: "
++                     "got %d.%02d, expected %d.%02d\n",
++                     efi.systab->hdr.revision >> 16,
++                     efi.systab->hdr.revision & 0xffff,
++                     EFI_SYSTEM_TABLE_REVISION >> 16,
++                     EFI_SYSTEM_TABLE_REVISION & 0xffff);
++      /*
++       * Grab some details from the system table
++       */
++      num_config_tables = efi.systab->nr_tables;
++      config_tables = (efi_config_table_t *)efi.systab->tables;
++      runtime = efi.systab->runtime;
++
++      /*
++       * Show what we know for posterity
++       */
++      c16 = (efi_char16_t *) boot_ioremap(efi.systab->fw_vendor, 2);
++      if (c16) {
++              for (i = 0; i < sizeof(vendor) && *c16; ++i)
++                      vendor[i] = *c16++;
++              vendor[i] = '\0';
++      } else
++              printk(KERN_ERR PFX "Could not map the firmware vendor!\n");
++
++      printk(KERN_INFO PFX "EFI v%u.%.02u by %s \n",
++             efi.systab->hdr.revision >> 16,
++             efi.systab->hdr.revision & 0xffff, vendor);
++
++      /*
++       * Let's see what config tables the firmware passed to us.
++       */
++      config_tables = (efi_config_table_t *)
++                              boot_ioremap((unsigned long) config_tables,
++                              num_config_tables * sizeof(efi_config_table_t));
++
++      if (config_tables == NULL)
++              printk(KERN_ERR PFX "Could not map EFI Configuration Table!\n");
++
++      for (i = 0; i < num_config_tables; i++) {
++              if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
++                      efi.mps = (void *)config_tables[i].table;
++                      printk(KERN_INFO " MPS=0x%lx ", config_tables[i].table);
++              } else
++                  if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) {
++                      efi.acpi20 = __va(config_tables[i].table);
++                      printk(KERN_INFO " ACPI 2.0=0x%lx ", config_tables[i].table);
++              } else
++                  if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) {
++                      efi.acpi = __va(config_tables[i].table);
++                      printk(KERN_INFO " ACPI=0x%lx ", config_tables[i].table);
++              } else
++                  if (efi_guidcmp(config_tables[i].guid, SMBIOS_TABLE_GUID) == 0) {
++                      efi.smbios = (void *) config_tables[i].table;
++                      printk(KERN_INFO " SMBIOS=0x%lx ", config_tables[i].table);
++              } else
++                  if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
++                      efi.hcdp = (void *)config_tables[i].table;
++                      printk(KERN_INFO " HCDP=0x%lx ", config_tables[i].table);
++              } else
++                  if (efi_guidcmp(config_tables[i].guid, UGA_IO_PROTOCOL_GUID) == 0) {
++                      efi.uga = (void *)config_tables[i].table;
++                      printk(KERN_INFO " UGA=0x%lx ", config_tables[i].table);
++              }
++      }
++      printk("\n");
++
++      /*
++       * Check out the runtime services table. We need to map
++       * the runtime services table so that we can grab the physical
++       * address of several of the EFI runtime functions, needed to
++       * set the firmware into virtual mode.
++       */
++
++      runtime = (efi_runtime_services_t *) boot_ioremap((unsigned long)
++                                              runtime,
++                                              sizeof(efi_runtime_services_t));
++      if (runtime != NULL) {
++              /*
++               * We will only need *early* access to the following
++               * two EFI runtime services before set_virtual_address_map
++               * is invoked.
++               */
++              efi_phys.get_time = (efi_get_time_t *) runtime->get_time;
++              efi_phys.set_virtual_address_map =
++                      (efi_set_virtual_address_map_t *)
++                              runtime->set_virtual_address_map;
++      } else
++              printk(KERN_ERR PFX "Could not map the runtime service table!\n");
++
++      /* Map the EFI memory map for use until paging_init() */
++
++      memmap.map = (efi_memory_desc_t *)
++              boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE);
++
++      if (memmap.map == NULL)
++              printk(KERN_ERR PFX "Could not map the EFI memory map!\n");
++
++      if (EFI_MEMDESC_SIZE != sizeof(efi_memory_desc_t)) {
++              printk(KERN_WARNING PFX "Warning! Kernel-defined memdesc doesn't "
++                         "match the one from EFI!\n");
++      }
++#if EFI_DEBUG
++      print_efi_memmap();
++#endif
++}
++
++/*
++ * This function will switch the EFI runtime services to virtual mode.
++ * Essentially, look through the EFI memmap and map every region that
++ * has the runtime attribute bit set in its memory descriptor and update
++ * that memory descriptor with the virtual address obtained from ioremap().
++ * This enables the runtime services to be called without having to
++ * thunk back into physical mode for every invocation.
++ */
++
++void __init efi_enter_virtual_mode(void)
++{
++      efi_memory_desc_t *md;
++      efi_status_t status;
++      int i;
++
++      efi.systab = NULL;
++
++      for (i = 0; i < memmap.nr_map; i++) {
++              md = &memmap.map[i];
++
++              if (md->attribute & EFI_MEMORY_RUNTIME) {
++                      md->virt_addr =
++                              (unsigned long)ioremap(md->phys_addr,
++                                      md->num_pages << EFI_PAGE_SHIFT);
++                      if (!(unsigned long)md->virt_addr) {
++                              printk(KERN_ERR PFX "ioremap of 0x%lX failed\n",
++                                      (unsigned long)md->phys_addr);
++                      }
++
++                      if (((unsigned long)md->phys_addr <=
++                                      (unsigned long)efi_phys.systab) &&
++                              ((unsigned long)efi_phys.systab <
++                                      md->phys_addr +
++                                      ((unsigned long)md->num_pages <<
++                                              EFI_PAGE_SHIFT))) {
++                              unsigned long addr;
++
++                              addr = md->virt_addr - md->phys_addr +
++                                              (unsigned long)efi_phys.systab;
++                              efi.systab = (efi_system_table_t *)addr;
++                      }
++              }
++      }
++
++      if (!efi.systab)
++              BUG();
++
++      status = phys_efi_set_virtual_address_map(
++                      sizeof(efi_memory_desc_t) * memmap.nr_map,
++                      sizeof(efi_memory_desc_t),
++                      memmap.desc_version,
++                      memmap.phys_map);
++
++      if (status != EFI_SUCCESS) {
++              printk (KERN_ALERT "You are screwed! "
++                      "Unable to switch EFI into virtual mode "
++                      "(status=%lx)\n", status);
++              panic("EFI call to SetVirtualAddressMap() failed!");
++      }
++
++      /*
++       * Now that EFI is in virtual mode, update the function
++       * pointers in the runtime service table to the new virtual addresses.
++       */
++
++      efi.get_time = (efi_get_time_t *) efi.systab->runtime->get_time;
++      efi.set_time = (efi_set_time_t *) efi.systab->runtime->set_time;
++      efi.get_wakeup_time = (efi_get_wakeup_time_t *)
++                                      efi.systab->runtime->get_wakeup_time;
++      efi.set_wakeup_time = (efi_set_wakeup_time_t *)
++                                      efi.systab->runtime->set_wakeup_time;
++      efi.get_variable = (efi_get_variable_t *)
++                                      efi.systab->runtime->get_variable;
++      efi.get_next_variable = (efi_get_next_variable_t *)
++                                      efi.systab->runtime->get_next_variable;
++      efi.set_variable = (efi_set_variable_t *)
++                                      efi.systab->runtime->set_variable;
++      efi.get_next_high_mono_count = (efi_get_next_high_mono_count_t *)
++                                      efi.systab->runtime->get_next_high_mono_count;
++      efi.reset_system = (efi_reset_system_t *)
++                                      efi.systab->runtime->reset_system;
++}
++
++void __init
++efi_initialize_iomem_resources(struct resource *code_resource,
++                             struct resource *data_resource)
++{
++      struct resource *res;
++      efi_memory_desc_t *md;
++      int i;
++
++      for (i = 0; i < memmap.nr_map; i++) {
++              md = &memmap.map[i];
++
++              if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >
++                  0x100000000ULL)
++                      continue;
++              res = alloc_bootmem_low(sizeof(struct resource));
++              switch (md->type) {
++              case EFI_RESERVED_TYPE:
++                      res->name = "Reserved Memory";
++                      break;
++              case EFI_LOADER_CODE:
++                      res->name = "Loader Code";
++                      break;
++              case EFI_LOADER_DATA:
++                      res->name = "Loader Data";
++                      break;
++              case EFI_BOOT_SERVICES_DATA:
++                      res->name = "BootServices Data";
++                      break;
++              case EFI_BOOT_SERVICES_CODE:
++                      res->name = "BootServices Code";
++                      break;
++              case EFI_RUNTIME_SERVICES_CODE:
++                      res->name = "Runtime Service Code";
++                      break;
++              case EFI_RUNTIME_SERVICES_DATA:
++                      res->name = "Runtime Service Data";
++                      break;
++              case EFI_CONVENTIONAL_MEMORY:
++                      res->name = "Conventional Memory";
++                      break;
++              case EFI_UNUSABLE_MEMORY:
++                      res->name = "Unusable Memory";
++                      break;
++              case EFI_ACPI_RECLAIM_MEMORY:
++                      res->name = "ACPI Reclaim";
++                      break;
++              case EFI_ACPI_MEMORY_NVS:
++                      res->name = "ACPI NVS";
++                      break;
++              case EFI_MEMORY_MAPPED_IO:
++                      res->name = "Memory Mapped IO";
++                      break;
++              case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
++                      res->name = "Memory Mapped IO Port Space";
++                      break;
++              default:
++                      res->name = "Reserved";
++                      break;
++              }
++              res->start = md->phys_addr;
++              res->end = res->start + ((md->num_pages << EFI_PAGE_SHIFT) - 1);
++              res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
++              if (request_resource(&iomem_resource, res) < 0)
++                      printk(KERN_ERR PFX "Failed to allocate res %s : 0x%lx-0x%lx\n",
++                              res->name, res->start, res->end);
++              /*
++               * We don't know which region contains kernel data so we try
++               * it repeatedly and let the resource manager test it.
++               */
++              if (md->type == EFI_CONVENTIONAL_MEMORY) {
++                      request_resource(res, code_resource);
++                      request_resource(res, data_resource);
++              }
++      }
++}
++
++/*
++ * Convenience functions to obtain memory types and attributes
++ */
++
++u32 efi_mem_type(unsigned long phys_addr)
++{
++      efi_memory_desc_t *md;
++      int i;
++
++      for (i = 0; i < memmap.nr_map; i++) {
++              md = &memmap.map[i];
++              if ((md->phys_addr <= phys_addr) && (phys_addr <
++                      (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
++                      return md->type;
++      }
++      return 0;
++}
++
++u64 efi_mem_attributes(unsigned long phys_addr)
++{
++      efi_memory_desc_t *md;
++      int i;
++
++      for (i = 0; i < memmap.nr_map; i++) {
++              md = &memmap.map[i];
++              if ((md->phys_addr <= phys_addr) && (phys_addr <
++                      (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) ))
++                      return md->attribute;
++      }
++      return 0;
++}
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/efi_stub.S     2003-12-28 23:21:45.000000000 -0800
+@@ -0,0 +1,124 @@
++/*
++ * EFI call stub for IA32.
++ *
++ * This stub allows us to make EFI calls in physical mode with interrupts
++ * turned off.
++ */
++
++#include <linux/config.h>
++#include <linux/linkage.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++
++/*
++ * efi_call_phys(void *, ...) is a function with variable parameters.
++ * All the callers of this function assure that all the parameters are 4-bytes.
++ */
++
++/*
++ * In gcc calling convention, EBX, ESP, EBP, ESI and EDI are all callee save.
++ * So we'd better save all of them at the beginning of this function and restore
++ * at the end no matter how many we use, because we can not assure EFI runtime
++ * service functions will comply with gcc calling convention, too.
++ */
++
++.text
++ENTRY(efi_call_phys)
++      /*
++       * 0. The function can only be called in Linux kernel. So CS has been
++       * set to 0x0010, DS and SS have been set to 0x0018. In EFI, I found
++       * the values of these registers are the same. And, the corresponding
++       * GDT entries are identical. So I will do nothing about segment reg
++       * and GDT, but change GDT base register in prelog and epilog.
++       */
++
++      /*
++       * 1. Now I am running with EIP = <physical address> + PAGE_OFFSET.
++       * But to make it smoothly switch from virtual mode to flat mode.
++       * The mapping of lower virtual memory has been created in prelog and
++       * epilog.
++       */
++      movl    $1f, %edx
++      subl    $__PAGE_OFFSET, %edx
++      jmp     *%edx
++1:
++
++      /*
++       * 2. Now on the top of stack is the return
++       * address in the caller of efi_call_phys(), then parameter 1,
++       * parameter 2, ..., param n. To make things easy, we save the return
++       * address of efi_call_phys in a global variable.
++       */
++      popl    %edx
++      movl    %edx, saved_return_addr
++      /* get the function pointer into ECX*/
++      popl    %ecx
++      movl    %ecx, efi_rt_function_ptr
++      movl    $2f, %edx
++      subl    $__PAGE_OFFSET, %edx
++      pushl   %edx
++
++      /*
++       * 3. Clear PG bit in %CR0.
++       */
++      movl    %cr0, %edx
++      andl    $0x7fffffff, %edx
++      movl    %edx, %cr0
++      jmp     1f
++1:
++
++      /*
++       * 4. Adjust stack pointer.
++       */
++      subl    $__PAGE_OFFSET, %esp
++
++      /*
++       * 5. Call the physical function.
++       */
++      jmp     *%ecx
++
++2:
++      /*
++       * 6. After EFI runtime service returns, control will return to
++       * following instruction. We'd better readjust stack pointer first.
++       */
++      addl    $__PAGE_OFFSET, %esp
++
++      /*
++       * 7. Restore PG bit
++       */
++      movl    %cr0, %edx
++      orl     $0x80000000, %edx
++      movl    %edx, %cr0
++      jmp     1f
++1:
++      /*
++       * 8. Now restore the virtual mode from flat mode by
++       * adding EIP with PAGE_OFFSET.
++       */
++      movl    $1f, %edx
++      jmp     *%edx
++1:
++
++      /*
++       * 9. Balance the stack. And because EAX contain the return value,
++       * we'd better not clobber it.
++       */
++      leal    efi_rt_function_ptr, %edx
++      movl    (%edx), %ecx
++      pushl   %ecx
++
++      /*
++       * 10. Push the saved return address onto the stack and return.
++       */
++      leal    saved_return_addr, %edx
++      movl    (%edx), %ecx
++      pushl   %ecx
++      ret
++.previous
++
++.data
++saved_return_addr:
++      .long 0
++efi_rt_function_ptr:
++      .long 0
+--- linux-2.6.0/arch/i386/kernel/entry.S       2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/i386/kernel/entry.S        2003-12-28 23:26:36.000000000 -0800
+@@ -43,11 +43,25 @@
+ #include <linux/config.h>
+ #include <linux/linkage.h>
+ #include <asm/thread_info.h>
++#include <asm/asm_offsets.h>
+ #include <asm/errno.h>
+ #include <asm/segment.h>
++#include <asm/page.h>
+ #include <asm/smp.h>
+ #include <asm/page.h>
+ #include "irq_vectors.h"
++        /* We do not recover from a stack overflow, but at least
++         * we know it happened and should be able to track it down.
++         */
++#ifdef CONFIG_STACK_OVERFLOW_TEST
++#define STACK_OVERFLOW_TEST \
++        testl $7680,%esp;    \
++        jnz   10f;            \
++        call  stack_overflow; \
++10:
++#else
++#define STACK_OVERFLOW_TEST
++#endif
+ #define nr_syscalls ((syscall_table_size)/4)
+@@ -87,7 +101,102 @@ TSS_ESP0_OFFSET = (4 - 0x200)
+ #define resume_kernel         restore_all
+ #endif
+-#define SAVE_ALL \
++#ifdef CONFIG_X86_HIGH_ENTRY
++
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++
++#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
++/*
++ * If task is preempted in __SWITCH_KERNELSPACE, and moved to another cpu,
++ * __switch_to repoints %esp to the appropriate virtual stack; but %ebp is
++ * left stale, so we must check whether to repeat the real stack calculation.
++ */
++#define repeat_if_esp_changed                         \
++      xorl %esp, %ebp;                                \
++      testl $0xffffe000, %ebp;                        \
++      jnz 0b
++#else
++#define repeat_if_esp_changed
++#endif
++
++/* clobbers ebx, edx and ebp */
++
++#define __SWITCH_KERNELSPACE                          \
++      cmpl $0xff000000, %esp;                         \
++      jb 1f;                                          \
++                                                      \
++      /*                                              \
++       * switch pagetables and load the real stack,   \
++       * keep the stack offset:                       \
++       */                                             \
++                                                      \
++      movl $swapper_pg_dir-__PAGE_OFFSET, %edx;       \
++                                                      \
++      /* GET_THREAD_INFO(%ebp) intermixed */          \
++0:                                                    \
++      movl %esp, %ebp;                                \
++      movl %esp, %ebx;                                \
++      andl $0xffffe000, %ebp;                         \
++      andl $0x00001fff, %ebx;                         \
++      orl TI_real_stack(%ebp), %ebx;                  \
++      repeat_if_esp_changed;                          \
++                                                      \
++      movl %edx, %cr3;                                \
++      movl %ebx, %esp;                                \
++1:
++
++#endif
++
++
++#define __SWITCH_USERSPACE \
++      /* interrupted any of the user return paths? */ \
++                                                      \
++      movl EIP(%esp), %eax;                           \
++                                                      \
++      cmpl $int80_ret_start_marker, %eax;             \
++      jb 33f; /* nope - continue with sysexit check */\
++      cmpl $int80_ret_end_marker, %eax;               \
++      jb 22f; /* yes - switch to virtual stack */     \
++33:                                                   \
++      cmpl $sysexit_ret_start_marker, %eax;           \
++      jb 44f; /* nope - continue with user check */   \
++      cmpl $sysexit_ret_end_marker, %eax;             \
++      jb 22f; /* yes - switch to virtual stack */     \
++      /* return to userspace? */                      \
++44:                                                   \
++      movl EFLAGS(%esp),%ecx;                         \
++      movb CS(%esp),%cl;                              \
++      testl $(VM_MASK | 3),%ecx;                      \
++      jz 2f;                                          \
++22:                                                   \
++      /*                                              \
++       * switch to the virtual stack, then switch to  \
++       * the userspace pagetables.                    \
++       */                                             \
++                                                      \
++      GET_THREAD_INFO(%ebp);                          \
++      movl TI_virtual_stack(%ebp), %edx;              \
++      movl TI_user_pgd(%ebp), %ecx;                   \
++                                                      \
++      movl %esp, %ebx;                                \
++      andl $0x1fff, %ebx;                             \
++      orl %ebx, %edx;                                 \
++int80_ret_start_marker:                                       \
++      movl %edx, %esp;                                \
++      movl %ecx, %cr3;                                \
++                                                      \
++      __RESTORE_ALL;                                  \
++int80_ret_end_marker:                                 \
++2:
++
++#else /* !CONFIG_X86_HIGH_ENTRY */
++
++#define __SWITCH_KERNELSPACE
++#define __SWITCH_USERSPACE
++
++#endif
++
++#define __SAVE_ALL \
+       cld; \
+       pushl %es; \
+       pushl %ds; \
+@@ -102,7 +211,7 @@ TSS_ESP0_OFFSET = (4 - 0x200)
+       movl %edx, %ds; \
+       movl %edx, %es;
+-#define RESTORE_INT_REGS \
++#define __RESTORE_INT_REGS \
+       popl %ebx;      \
+       popl %ecx;      \
+       popl %edx;      \
+@@ -111,29 +220,28 @@ TSS_ESP0_OFFSET = (4 - 0x200)
+       popl %ebp;      \
+       popl %eax
+-#define RESTORE_REGS  \
+-      RESTORE_INT_REGS; \
+-1:    popl %ds;       \
+-2:    popl %es;       \
++#define __RESTORE_REGS        \
++      __RESTORE_INT_REGS; \
++111:  popl %ds;       \
++222:  popl %es;       \
+ .section .fixup,"ax"; \
+-3:    movl $0,(%esp); \
+-      jmp 1b;         \
+-4:    movl $0,(%esp); \
+-      jmp 2b;         \
++444:  movl $0,(%esp); \
++      jmp 111b;       \
++555:  movl $0,(%esp); \
++      jmp 222b;       \
+ .previous;            \
+ .section __ex_table,"a";\
+       .align 4;       \
+-      .long 1b,3b;    \
+-      .long 2b,4b;    \
++      .long 111b,444b;\
++      .long 222b,555b;\
+ .previous
+-
+-#define RESTORE_ALL   \
+-      RESTORE_REGS    \
++#define __RESTORE_ALL \
++      __RESTORE_REGS  \
+       addl $4, %esp;  \
+-1:    iret;           \
++333:  iret;           \
+ .section .fixup,"ax";   \
+-2:    sti;            \
++666:  sti;            \
+       movl $(__USER_DS), %edx; \
+       movl %edx, %ds; \
+       movl %edx, %es; \
+@@ -142,10 +250,19 @@ TSS_ESP0_OFFSET = (4 - 0x200)
+ .previous;            \
+ .section __ex_table,"a";\
+       .align 4;       \
+-      .long 1b,2b;    \
++      .long 333b,666b;\
+ .previous
++#define SAVE_ALL \
++      __SAVE_ALL;                                     \
++      __SWITCH_KERNELSPACE;                           \
++        STACK_OVERFLOW_TEST;
++
++#define RESTORE_ALL                                   \
++      __SWITCH_USERSPACE;                             \
++      __RESTORE_ALL;
++.section .entry.text,"ax"
+ ENTRY(lcall7)
+       pushfl                  # We get a different stack layout with call
+@@ -163,7 +280,7 @@ do_lcall:
+       movl %edx,EIP(%ebp)     # Now we move them to their "normal" places
+       movl %ecx,CS(%ebp)      #
+       andl $-8192, %ebp       # GET_THREAD_INFO
+-      movl TI_EXEC_DOMAIN(%ebp), %edx # Get the execution domain
++      movl TI_exec_domain(%ebp), %edx # Get the execution domain
+       call *4(%edx)           # Call the lcall7 handler for the domain
+       addl $4, %esp
+       popl %eax
+@@ -208,7 +325,7 @@ ENTRY(resume_userspace)
+       cli                             # make sure we don't miss an interrupt
+                                       # setting need_resched or sigpending
+                                       # between sampling and the iret
+-      movl TI_FLAGS(%ebp), %ecx
++      movl TI_flags(%ebp), %ecx
+       andl $_TIF_WORK_MASK, %ecx      # is there any work to be done on
+                                       # int/exception return?
+       jne work_pending
+@@ -216,18 +333,18 @@ ENTRY(resume_userspace)
+ #ifdef CONFIG_PREEMPT
+ ENTRY(resume_kernel)
+-      cmpl $0,TI_PRE_COUNT(%ebp)      # non-zero preempt_count ?
++      cmpl $0,TI_preempt_count(%ebp)  # non-zero preempt_count ?
+       jnz restore_all
+ need_resched:
+-      movl TI_FLAGS(%ebp), %ecx       # need_resched set ?
++      movl TI_flags(%ebp), %ecx       # need_resched set ?
+       testb $_TIF_NEED_RESCHED, %cl
+       jz restore_all
+       testl $IF_MASK,EFLAGS(%esp)     # interrupts off (exception path) ?
+       jz restore_all
+-      movl $PREEMPT_ACTIVE,TI_PRE_COUNT(%ebp)
++      movl $PREEMPT_ACTIVE,TI_preempt_count(%ebp)
+       sti
+       call schedule
+-      movl $0,TI_PRE_COUNT(%ebp)
++      movl $0,TI_preempt_count(%ebp)
+       cli
+       jmp need_resched
+ #endif
+@@ -246,37 +363,50 @@ sysenter_past_esp:
+       pushl $(__USER_CS)
+       pushl $SYSENTER_RETURN
+-/*
+- * Load the potential sixth argument from user stack.
+- * Careful about security.
+- */
+-      cmpl $__PAGE_OFFSET-3,%ebp
+-      jae syscall_fault
+-1:    movl (%ebp),%ebp
+-.section __ex_table,"a"
+-      .align 4
+-      .long 1b,syscall_fault
+-.previous
+-
+       pushl %eax
+       SAVE_ALL
+       GET_THREAD_INFO(%ebp)
+       cmpl $(nr_syscalls), %eax
+       jae syscall_badsys
+-      testb $_TIF_SYSCALL_TRACE,TI_FLAGS(%ebp)
++      testb $_TIF_SYSCALL_TRACE,TI_flags(%ebp)
+       jnz syscall_trace_entry
+       call *sys_call_table(,%eax,4)
+       movl %eax,EAX(%esp)
+       cli
+-      movl TI_FLAGS(%ebp), %ecx
++      movl TI_flags(%ebp), %ecx
+       testw $_TIF_ALLWORK_MASK, %cx
+       jne syscall_exit_work
++
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++
++      GET_THREAD_INFO(%ebp)
++      movl TI_virtual_stack(%ebp), %edx
++      movl TI_user_pgd(%ebp), %ecx
++      movl %esp, %ebx
++      andl $0x1fff, %ebx
++      orl %ebx, %edx
++sysexit_ret_start_marker:
++      movl %edx, %esp
++      movl %ecx, %cr3
++#endif
++      /*
++       * only ebx is not restored by the userspace sysenter vsyscall
++       * code, it assumes it to be callee-saved.
++       */
++      movl EBX(%esp), %ebx
++
+ /* if something modifies registers it must also disable sysexit */
++
+       movl EIP(%esp), %edx
+       movl OLDESP(%esp), %ecx
++
+       sti
+       sysexit
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++sysexit_ret_end_marker:
++      nop
++#endif
+       # system call handler stub
+@@ -287,7 +417,7 @@ ENTRY(system_call)
+       cmpl $(nr_syscalls), %eax
+       jae syscall_badsys
+                                       # system call tracing in operation
+-      testb $_TIF_SYSCALL_TRACE,TI_FLAGS(%ebp)
++      testb $_TIF_SYSCALL_TRACE,TI_flags(%ebp)
+       jnz syscall_trace_entry
+ syscall_call:
+       call *sys_call_table(,%eax,4)
+@@ -296,10 +426,23 @@ syscall_exit:
+       cli                             # make sure we don't miss an interrupt
+                                       # setting need_resched or sigpending
+                                       # between sampling and the iret
+-      movl TI_FLAGS(%ebp), %ecx
++      movl TI_flags(%ebp), %ecx
+       testw $_TIF_ALLWORK_MASK, %cx   # current->work
+       jne syscall_exit_work
+ restore_all:
++#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
++      movl EFLAGS(%esp), %eax         # mix EFLAGS and CS
++      movb CS(%esp), %al
++      testl $(VM_MASK | 3), %eax
++      jz resume_kernelX               # returning to kernel or vm86-space
++
++      cmpl $0,TI_preempt_count(%ebp)  # non-zero preempt_count ?
++      jz resume_kernelX
++
++        int $3
++
++resume_kernelX:
++#endif
+       RESTORE_ALL
+       # perform work that needs to be done immediately before resumption
+@@ -312,7 +455,7 @@ work_resched:
+       cli                             # make sure we don't miss an interrupt
+                                       # setting need_resched or sigpending
+                                       # between sampling and the iret
+-      movl TI_FLAGS(%ebp), %ecx
++      movl TI_flags(%ebp), %ecx
+       andl $_TIF_WORK_MASK, %ecx      # is there any work to be done other
+                                       # than syscall tracing?
+       jz restore_all
+@@ -327,6 +470,22 @@ work_notifysig:                           # deal with pending s
+                                       # vm86-space
+       xorl %edx, %edx
+       call do_notify_resume
++
++#if CONFIG_X86_HIGH_ENTRY
++      /*
++       * Reload db7 if necessary:
++       */
++      movl TI_flags(%ebp), %ecx
++      testb $_TIF_DB7, %cl
++      jnz work_db7
++
++      jmp restore_all
++
++work_db7:
++      movl TI_task(%ebp), %edx;
++      movl task_thread_db7(%edx), %edx;
++      movl %edx, %db7;
++#endif
+       jmp restore_all
+       ALIGN
+@@ -382,7 +541,7 @@ syscall_badsys:
+  */
+ .data
+ ENTRY(interrupt)
+-.text
++.previous
+ vector=0
+ ENTRY(irq_entries_start)
+@@ -392,7 +551,7 @@ ENTRY(irq_entries_start)
+       jmp common_interrupt
+ .data
+       .long 1b
+-.text
++.previous
+ vector=vector+1
+ .endr
+@@ -433,12 +592,17 @@ error_code:
+       movl ES(%esp), %edi             # get the function address
+       movl %eax, ORIG_EAX(%esp)
+       movl %ecx, ES(%esp)
+-      movl %esp, %edx
+       pushl %esi                      # push the error code
+-      pushl %edx                      # push the pt_regs pointer
+       movl $(__USER_DS), %edx
+       movl %edx, %ds
+       movl %edx, %es
++
++/* clobbers edx, ebx and ebp */
++      __SWITCH_KERNELSPACE
++
++      leal 4(%esp), %edx              # prepare pt_regs
++      pushl %edx                      # push pt_regs
++
+       call *%edi
+       addl $8, %esp
+       jmp ret_from_exception
+@@ -529,7 +693,7 @@ nmi_stack_correct:
+       pushl %edx
+       call do_nmi
+       addl $8, %esp
+-      RESTORE_ALL
++      jmp restore_all
+ nmi_stack_fixup:
+       FIX_STACK(12,nmi_stack_correct, 1)
+@@ -606,6 +770,8 @@ ENTRY(spurious_interrupt_bug)
+       pushl $do_spurious_interrupt_bug
+       jmp error_code
++.previous
++
+ .data
+ ENTRY(sys_call_table)
+       .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/entry_trampoline.c     2003-12-28 23:26:36.000000000 -0800
+@@ -0,0 +1,75 @@
++/*
++ * linux/arch/i386/kernel/entry_trampoline.c
++ *
++ * (C) Copyright 2003 Ingo Molnar
++ *
++ * This file contains the needed support code for 4GB userspace
++ */
++
++#include <linux/init.h>
++#include <linux/smp.h>
++#include <linux/mm.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/highmem.h>
++#include <asm/desc.h>
++#include <asm/atomic_kmap.h>
++
++extern char __entry_tramp_start, __entry_tramp_end, __start___entry_text;
++
++void __init init_entry_mappings(void)
++{
++#ifdef CONFIG_X86_HIGH_ENTRY
++      void *tramp;
++
++      /*
++       * We need a high IDT and GDT for the 4G/4G split:
++       */
++      trap_init_virtual_IDT();
++
++      __set_fixmap(FIX_ENTRY_TRAMPOLINE_0, __pa((unsigned long)&__entry_tramp_start), PAGE_KERNEL);
++      __set_fixmap(FIX_ENTRY_TRAMPOLINE_1, __pa((unsigned long)&__entry_tramp_start) + PAGE_SIZE, PAGE_KERNEL);
++      tramp = (void *)fix_to_virt(FIX_ENTRY_TRAMPOLINE_0);
++
++      printk("mapped 4G/4G trampoline to %p.\n", tramp);
++      BUG_ON((void *)&__start___entry_text != tramp);
++      /*
++       * Virtual kernel stack:
++       */
++      BUG_ON(__kmap_atomic_vaddr(KM_VSTACK0) & 8191);
++      BUG_ON(sizeof(struct desc_struct)*NR_CPUS*GDT_ENTRIES > 2*PAGE_SIZE);
++      BUG_ON((unsigned int)&__entry_tramp_end - (unsigned int)&__entry_tramp_start > 2*PAGE_SIZE);
++
++      /*
++       * set up the initial thread's virtual stack related
++       * fields:
++       */
++      current->thread.stack_page0 = virt_to_page((char *)current->thread_info);
++      current->thread.stack_page1 = virt_to_page((char *)current->thread_info + PAGE_SIZE);
++      current->thread_info->virtual_stack = (void *)__kmap_atomic_vaddr(KM_VSTACK0);
++
++      __kunmap_atomic_type(KM_VSTACK0);
++      __kunmap_atomic_type(KM_VSTACK1);
++        __kmap_atomic(current->thread.stack_page0, KM_VSTACK0);
++        __kmap_atomic(current->thread.stack_page1, KM_VSTACK1);
++
++#endif
++      printk("current: %p\n", current);
++      printk("current->thread_info: %p\n", current->thread_info);
++      current->thread_info->real_stack = (void *)current->thread_info;
++      current->thread_info->user_pgd = NULL;
++      current->thread.esp0 = (unsigned long)current->thread_info->real_stack + THREAD_SIZE;
++}
++
++
++
++void __init entry_trampoline_setup(void)
++{
++      /*
++       * old IRQ entries set up by the boot code will still hang
++       * around - they are a sign of hw trouble anyway, now they'll
++       * produce a double fault message.
++       */
++      trap_init_virtual_GDT();
++}
+--- linux-2.6.0/arch/i386/kernel/head.S        2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/head.S 2003-12-28 23:26:36.000000000 -0800
+@@ -16,6 +16,7 @@
+ #include <asm/pgtable.h>
+ #include <asm/desc.h>
+ #include <asm/cache.h>
++#include <asm/asm_offsets.h>
+ #define OLD_CL_MAGIC_ADDR     0x90020
+ #define OLD_CL_MAGIC          0xA33F
+@@ -330,7 +331,7 @@ ENTRY(stack_start)
+ /* This is the default interrupt "handler" :-) */
+ int_msg:
+-      .asciz "Unknown interrupt\n"
++      .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
+       ALIGN
+ ignore_int:
+       cld
+@@ -342,9 +343,17 @@ ignore_int:
+       movl $(__KERNEL_DS),%eax
+       movl %eax,%ds
+       movl %eax,%es
++      pushl 16(%esp)
++      pushl 24(%esp)
++      pushl 32(%esp)
++      pushl 40(%esp)
+       pushl $int_msg
+       call printk
+       popl %eax
++      popl %eax
++      popl %eax
++      popl %eax
++      popl %eax
+       popl %ds
+       popl %es
+       popl %edx
+@@ -377,23 +386,27 @@ cpu_gdt_descr:
+       .fill NR_CPUS-1,8,0             # space for the other GDT descriptors
+ /*
+- * This is initialized to create an identity-mapping at 0-8M (for bootup
+- * purposes) and another mapping of the 0-8M area at virtual address
++ * This is initialized to create an identity-mapping at 0-16M (for bootup
++ * purposes) and another mapping of the 0-16M area at virtual address
+  * PAGE_OFFSET.
+  */
+ .org 0x1000
+ ENTRY(swapper_pg_dir)
+       .long 0x00102007
+       .long 0x00103007
+-      .fill BOOT_USER_PGD_PTRS-2,4,0
+-      /* default: 766 entries */
++      .long 0x00104007
++      .long 0x00105007
++      .fill BOOT_USER_PGD_PTRS-4,4,0
++      /* default: 764 entries */
+       .long 0x00102007
+       .long 0x00103007
+-      /* default: 254 entries */
+-      .fill BOOT_KERNEL_PGD_PTRS-2,4,0
++      .long 0x00104007
++      .long 0x00105007
++      /* default: 252 entries */
++      .fill BOOT_KERNEL_PGD_PTRS-4,4,0
+ /*
+- * The page tables are initialized to only 8MB here - the final page
++ * The page tables are initialized to only 16MB here - the final page
+  * tables are set up later depending on memory size.
+  */
+ .org 0x2000
+@@ -402,15 +415,21 @@ ENTRY(pg0)
+ .org 0x3000
+ ENTRY(pg1)
++.org 0x4000
++ENTRY(pg2)
++
++.org 0x5000
++ENTRY(pg3)
++
+ /*
+  * empty_zero_page must immediately follow the page tables ! (The
+  * initialization loop counts until empty_zero_page)
+  */
+-.org 0x4000
++.org 0x6000
+ ENTRY(empty_zero_page)
+-.org 0x5000
++.org 0x7000
+ /*
+  * Real beginning of normal "text" segment
+@@ -419,12 +438,12 @@ ENTRY(stext)
+ ENTRY(_stext)
+ /*
+- * This starts the data section. Note that the above is all
+- * in the text section because it has alignment requirements
+- * that we cannot fulfill any other way.
++ * This starts the data section.
+  */
+ .data
++.align PAGE_SIZE_asm
++
+ /*
+  * The Global Descriptor Table contains 28 quadwords, per-CPU.
+  */
+@@ -439,7 +458,9 @@ ENTRY(boot_gdt_table)
+       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
+       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
+ #endif
+-      .align L1_CACHE_BYTES
++
++.align PAGE_SIZE_asm
++
+ ENTRY(cpu_gdt_table)
+       .quad 0x0000000000000000        /* NULL descriptor */
+       .quad 0x0000000000000000        /* 0x0b reserved */
+--- linux-2.6.0/arch/i386/kernel/i386_ksyms.c  2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/i386_ksyms.c   2003-12-28 23:26:36.000000000 -0800
+@@ -98,7 +98,6 @@ EXPORT_SYMBOL_NOVERS(__down_failed_inter
+ EXPORT_SYMBOL_NOVERS(__down_failed_trylock);
+ EXPORT_SYMBOL_NOVERS(__up_wakeup);
+ /* Networking helper routines. */
+-EXPORT_SYMBOL(csum_partial_copy_generic);
+ /* Delay loops */
+ EXPORT_SYMBOL(__ndelay);
+ EXPORT_SYMBOL(__udelay);
+@@ -112,13 +111,17 @@ EXPORT_SYMBOL_NOVERS(__get_user_4);
+ EXPORT_SYMBOL(strpbrk);
+ EXPORT_SYMBOL(strstr);
++#if !defined(CONFIG_X86_UACCESS_INDIRECT)
+ EXPORT_SYMBOL(strncpy_from_user);
+-EXPORT_SYMBOL(__strncpy_from_user);
++EXPORT_SYMBOL(__direct_strncpy_from_user);
+ EXPORT_SYMBOL(clear_user);
+ EXPORT_SYMBOL(__clear_user);
+ EXPORT_SYMBOL(__copy_from_user_ll);
+ EXPORT_SYMBOL(__copy_to_user_ll);
+ EXPORT_SYMBOL(strnlen_user);
++#else /* CONFIG_X86_UACCESS_INDIRECT */
++EXPORT_SYMBOL(direct_csum_partial_copy_generic);
++#endif
+ EXPORT_SYMBOL(dma_alloc_coherent);
+ EXPORT_SYMBOL(dma_free_coherent);
+--- linux-2.6.0/arch/i386/kernel/i387.c        2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/i387.c 2003-12-28 23:26:36.000000000 -0800
+@@ -218,6 +218,7 @@ void set_fpu_mxcsr( struct task_struct *
+ static int convert_fxsr_to_user( struct _fpstate __user *buf,
+                                       struct i387_fxsave_struct *fxsave )
+ {
++      struct _fpreg tmp[8]; /* 80 bytes scratch area */
+       unsigned long env[7];
+       struct _fpreg __user *to;
+       struct _fpxreg *from;
+@@ -234,23 +235,25 @@ static int convert_fxsr_to_user( struct 
+       if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
+               return 1;
+-      to = &buf->_st[0];
++      to = tmp;
+       from = (struct _fpxreg *) &fxsave->st_space[0];
+       for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
+               unsigned long *t = (unsigned long *)to;
+               unsigned long *f = (unsigned long *)from;
+-              if (__put_user(*f, t) ||
+-                              __put_user(*(f + 1), t + 1) ||
+-                              __put_user(from->exponent, &to->exponent))
+-                      return 1;
++              *t = *f;
++              *(t + 1) = *(f+1);
++              to->exponent = from->exponent;
+       }
++      if (copy_to_user(buf->_st, tmp, sizeof(struct _fpreg [8])))
++              return 1;
+       return 0;
+ }
+ static int convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
+                                         struct _fpstate __user *buf )
+ {
++      struct _fpreg tmp[8]; /* 80 bytes scratch area */
+       unsigned long env[7];
+       struct _fpxreg *to;
+       struct _fpreg __user *from;
+@@ -258,6 +261,8 @@ static int convert_fxsr_from_user( struc
+       if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
+               return 1;
++      if (copy_from_user(tmp, buf->_st, sizeof(struct _fpreg [8])))
++              return 1;
+       fxsave->cwd = (unsigned short)(env[0] & 0xffff);
+       fxsave->swd = (unsigned short)(env[1] & 0xffff);
+@@ -269,15 +274,14 @@ static int convert_fxsr_from_user( struc
+       fxsave->fos = env[6];
+       to = (struct _fpxreg *) &fxsave->st_space[0];
+-      from = &buf->_st[0];
++      from = tmp;
+       for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
+               unsigned long *t = (unsigned long *)to;
+               unsigned long *f = (unsigned long *)from;
+-              if (__get_user(*t, f) ||
+-                              __get_user(*(t + 1), f + 1) ||
+-                              __get_user(to->exponent, &from->exponent))
+-                      return 1;
++              *t = *f;
++              *(t + 1) = *(f + 1);
++              to->exponent = from->exponent;
+       }
+       return 0;
+ }
+--- linux-2.6.0/arch/i386/kernel/i8259.c       2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/i8259.c        2003-12-28 23:21:44.000000000 -0800
+@@ -419,8 +419,10 @@ void __init init_IRQ(void)
+        * us. (some of these will be overridden and become
+        * 'special' SMP interrupts)
+        */
+-      for (i = 0; i < NR_IRQS; i++) {
++      for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
+               int vector = FIRST_EXTERNAL_VECTOR + i;
++              if (i >= NR_IRQS)
++                      break;
+               if (vector != SYSCALL_VECTOR) 
+                       set_intr_gate(vector, interrupt[i]);
+       }
+--- linux-2.6.0/arch/i386/kernel/init_task.c   2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/init_task.c    2003-12-28 23:26:36.000000000 -0800
+@@ -26,7 +26,7 @@ EXPORT_SYMBOL(init_mm);
+  */
+ union thread_union init_thread_union 
+       __attribute__((__section__(".data.init_task"))) =
+-              { INIT_THREAD_INFO(init_task) };
++              { INIT_THREAD_INFO(init_task, init_thread_union) };
+ /*
+  * Initial task structure.
+@@ -44,5 +44,5 @@ EXPORT_SYMBOL(init_task);
+  * section. Since TSS's are completely CPU-local, we want them
+  * on exact cacheline boundaries, to eliminate cacheline ping-pong.
+  */ 
+-struct tss_struct init_tss[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = INIT_TSS };
++struct tss_struct init_tss[NR_CPUS] __attribute__((__section__(".data.tss"))) = { [0 ... NR_CPUS-1] = INIT_TSS };
+--- linux-2.6.0/arch/i386/kernel/io_apic.c     2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/io_apic.c      2003-12-28 23:21:44.000000000 -0800
+@@ -76,6 +76,14 @@ static struct irq_pin_list {
+       int apic, pin, next;
+ } irq_2_pin[PIN_MAP_SIZE];
++#ifdef CONFIG_PCI_USE_VECTOR
++int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1};
++#define vector_to_irq(vector)         \
++      (platform_legacy_irq(vector) ? vector : vector_irq[vector])
++#else
++#define vector_to_irq(vector) (vector)
++#endif
++
+ /*
+  * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
+  * shared ISA-space IRQs, so we have to support them. We are super
+@@ -249,7 +257,7 @@ static void clear_IO_APIC (void)
+                       clear_IO_APIC_pin(apic, pin);
+ }
+-static void set_ioapic_affinity(unsigned int irq, cpumask_t cpumask)
++static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
+ {
+       unsigned long flags;
+       int pin;
+@@ -288,7 +296,7 @@ static void set_ioapic_affinity(unsigned
+ extern cpumask_t irq_affinity[NR_IRQS];
+-static cpumask_t __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS];
++cpumask_t __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS];
+ #define IRQBALANCE_CHECK_ARCH -999
+ static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH;
+@@ -670,13 +678,11 @@ static int __init irqbalance_disable(cha
+ __setup("noirqbalance", irqbalance_disable);
+-static void set_ioapic_affinity(unsigned int irq, cpumask_t mask);
+-
+ static inline void move_irq(int irq)
+ {
+       /* note - we hold the desc->lock */
+       if (unlikely(!cpus_empty(pending_irq_balance_cpumask[irq]))) {
+-              set_ioapic_affinity(irq, pending_irq_balance_cpumask[irq]);
++              set_ioapic_affinity_irq(irq, pending_irq_balance_cpumask[irq]);
+               cpus_clear(pending_irq_balance_cpumask[irq]);
+       }
+ }
+@@ -853,7 +859,7 @@ void __init setup_ioapic_dest(cpumask_t 
+                       if (irq_entry == -1)
+                               continue;
+                       irq = pin_2_irq(irq_entry, ioapic, pin);
+-                      set_ioapic_affinity(irq, mask);
++                      set_ioapic_affinity_irq(irq, mask);
+               }
+       }
+@@ -1141,7 +1147,8 @@ static inline int IO_APIC_irq_trigger(in
+ /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
+ u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 };
+-static int __init assign_irq_vector(int irq)
++#ifndef CONFIG_PCI_USE_VECTOR
++int __init assign_irq_vector(int irq)
+ {
+       static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
+       BUG_ON(irq >= NR_IRQ_VECTORS);
+@@ -1158,11 +1165,36 @@ next:
+       }
+       IO_APIC_VECTOR(irq) = current_vector;
++
+       return current_vector;
+ }
++#endif
++
++static struct hw_interrupt_type ioapic_level_type;
++static struct hw_interrupt_type ioapic_edge_type;
+-static struct hw_interrupt_type ioapic_level_irq_type;
+-static struct hw_interrupt_type ioapic_edge_irq_type;
++#define IOAPIC_AUTO   -1
++#define IOAPIC_EDGE   0
++#define IOAPIC_LEVEL  1
++
++static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger)
++{
++      if (use_pci_vector() && !platform_legacy_irq(irq)) {
++              if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
++                              trigger == IOAPIC_LEVEL)
++                      irq_desc[vector].handler = &ioapic_level_type;
++              else
++                      irq_desc[vector].handler = &ioapic_edge_type;
++              set_intr_gate(vector, interrupt[vector]);
++      } else  {
++              if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
++                              trigger == IOAPIC_LEVEL)
++                      irq_desc[irq].handler = &ioapic_level_type;
++              else
++                      irq_desc[irq].handler = &ioapic_edge_type;
++              set_intr_gate(vector, interrupt[irq]);
++      }
++}
+ void __init setup_IO_APIC_irqs(void)
+ {
+@@ -1220,13 +1252,7 @@ void __init setup_IO_APIC_irqs(void)
+               if (IO_APIC_IRQ(irq)) {
+                       vector = assign_irq_vector(irq);
+                       entry.vector = vector;
+-
+-                      if (IO_APIC_irq_trigger(irq))
+-                              irq_desc[irq].handler = &ioapic_level_irq_type;
+-                      else
+-                              irq_desc[irq].handler = &ioapic_edge_irq_type;
+-
+-                      set_intr_gate(vector, interrupt[irq]);
++                      ioapic_register_intr(irq, vector, IOAPIC_AUTO);
+               
+                       if (!apic && (irq < 16))
+                               disable_8259A_irq(irq);
+@@ -1273,7 +1299,7 @@ void __init setup_ExtINT_IRQ0_pin(unsign
+        * The timer IRQ doesn't have to know that behind the
+        * scene we have a 8259A-master in AEOI mode ...
+        */
+-      irq_desc[0].handler = &ioapic_edge_irq_type;
++      irq_desc[0].handler = &ioapic_edge_type;
+       /*
+        * Add it to the IO-APIC irq-routing table:
+@@ -1624,10 +1650,6 @@ static void __init setup_ioapic_ids_from
+       unsigned char old_id;
+       unsigned long flags;
+-      if (acpi_ioapic)
+-              /* This gets done during IOAPIC enumeration for ACPI. */
+-              return;
+-
+       /*
+        * This is broken; anything with a real cpu count has to
+        * circumvent this idiocy regardless.
+@@ -1763,9 +1785,6 @@ static int __init timer_irq_works(void)
+  * that was delayed but this is now handled in the device
+  * independent code.
+  */
+-#define enable_edge_ioapic_irq unmask_IO_APIC_irq
+-
+-static void disable_edge_ioapic_irq (unsigned int irq) { /* nothing */ }
+ /*
+  * Starting up a edge-triggered IO-APIC interrupt is
+@@ -1776,7 +1795,6 @@ static void disable_edge_ioapic_irq (uns
+  * This is not complete - we should be able to fake
+  * an edge even if it isn't on the 8259A...
+  */
+-
+ static unsigned int startup_edge_ioapic_irq(unsigned int irq)
+ {
+       int was_pending = 0;
+@@ -1794,8 +1812,6 @@ static unsigned int startup_edge_ioapic_
+       return was_pending;
+ }
+-#define shutdown_edge_ioapic_irq      disable_edge_ioapic_irq
+-
+ /*
+  * Once we have recorded IRQ_PENDING already, we can mask the
+  * interrupt for real. This prevents IRQ storms from unhandled
+@@ -1810,9 +1826,6 @@ static void ack_edge_ioapic_irq(unsigned
+       ack_APIC_irq();
+ }
+-static void end_edge_ioapic_irq (unsigned int i) { /* nothing */ }
+-
+-
+ /*
+  * Level triggered interrupts can just be masked,
+  * and shutting down and starting up the interrupt
+@@ -1834,10 +1847,6 @@ static unsigned int startup_level_ioapic
+       return 0; /* don't check for pending */
+ }
+-#define shutdown_level_ioapic_irq     mask_IO_APIC_irq
+-#define enable_level_ioapic_irq               unmask_IO_APIC_irq
+-#define disable_level_ioapic_irq      mask_IO_APIC_irq
+-
+ static void end_level_ioapic_irq (unsigned int irq)
+ {
+       unsigned long v;
+@@ -1864,6 +1873,7 @@ static void end_level_ioapic_irq (unsign
+  * The idea is from Manfred Spraul.  --macro
+  */
+       i = IO_APIC_VECTOR(irq);
++
+       v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
+       ack_APIC_irq();
+@@ -1898,7 +1908,57 @@ static void end_level_ioapic_irq (unsign
+       }
+ }
+-static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ }
++#ifdef CONFIG_PCI_USE_VECTOR
++static unsigned int startup_edge_ioapic_vector(unsigned int vector)
++{
++      int irq = vector_to_irq(vector);
++
++      return startup_edge_ioapic_irq(irq);
++}
++
++static void ack_edge_ioapic_vector(unsigned int vector)
++{
++      int irq = vector_to_irq(vector);
++
++      ack_edge_ioapic_irq(irq);
++}
++
++static unsigned int startup_level_ioapic_vector (unsigned int vector)
++{
++      int irq = vector_to_irq(vector);
++
++      return startup_level_ioapic_irq (irq);
++}
++
++static void end_level_ioapic_vector (unsigned int vector)
++{
++      int irq = vector_to_irq(vector);
++
++      end_level_ioapic_irq(irq);
++}
++
++static void mask_IO_APIC_vector (unsigned int vector)
++{
++      int irq = vector_to_irq(vector);
++
++      mask_IO_APIC_irq(irq);
++}
++
++static void unmask_IO_APIC_vector (unsigned int vector)
++{
++      int irq = vector_to_irq(vector);
++
++      unmask_IO_APIC_irq(irq);
++}
++
++static void set_ioapic_affinity_vector (unsigned int vector,
++                                      cpumask_t cpu_mask)
++{
++      int irq = vector_to_irq(vector);
++
++      set_ioapic_affinity_irq(irq, cpu_mask);
++}
++#endif
+ /*
+  * Level and edge triggered IO-APIC interrupts need different handling,
+@@ -1908,26 +1968,25 @@ static void mask_and_ack_level_ioapic_ir
+  * edge-triggered handler, without risking IRQ storms and other ugly
+  * races.
+  */
+-
+-static struct hw_interrupt_type ioapic_edge_irq_type = {
++static struct hw_interrupt_type ioapic_edge_type = {
+       .typename       = "IO-APIC-edge",
+-      .startup        = startup_edge_ioapic_irq,
+-      .shutdown       = shutdown_edge_ioapic_irq,
+-      .enable         = enable_edge_ioapic_irq,
+-      .disable        = disable_edge_ioapic_irq,
+-      .ack            = ack_edge_ioapic_irq,
+-      .end            = end_edge_ioapic_irq,
++      .startup        = startup_edge_ioapic,
++      .shutdown       = shutdown_edge_ioapic,
++      .enable         = enable_edge_ioapic,
++      .disable        = disable_edge_ioapic,
++      .ack            = ack_edge_ioapic,
++      .end            = end_edge_ioapic,
+       .set_affinity   = set_ioapic_affinity,
+ };
+-static struct hw_interrupt_type ioapic_level_irq_type = {
++static struct hw_interrupt_type ioapic_level_type = {
+       .typename       = "IO-APIC-level",
+-      .startup        = startup_level_ioapic_irq,
+-      .shutdown       = shutdown_level_ioapic_irq,
+-      .enable         = enable_level_ioapic_irq,
+-      .disable        = disable_level_ioapic_irq,
+-      .ack            = mask_and_ack_level_ioapic_irq,
+-      .end            = end_level_ioapic_irq,
++      .startup        = startup_level_ioapic,
++      .shutdown       = shutdown_level_ioapic,
++      .enable         = enable_level_ioapic,
++      .disable        = disable_level_ioapic,
++      .ack            = mask_and_ack_level_ioapic,
++      .end            = end_level_ioapic,
+       .set_affinity   = set_ioapic_affinity,
+ };
+@@ -1947,7 +2006,13 @@ static inline void init_IO_APIC_traps(vo
+        * 0x80, because int 0x80 is hm, kind of importantish. ;)
+        */
+       for (irq = 0; irq < NR_IRQS ; irq++) {
+-              if (IO_APIC_IRQ(irq) && !IO_APIC_VECTOR(irq)) {
++              int tmp = irq;
++              if (use_pci_vector()) {
++                      if (!platform_legacy_irq(tmp))
++                              if ((tmp = vector_to_irq(tmp)) == -1)
++                                      continue;
++              }
++              if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
+                       /*
+                        * Hmm.. We don't have an entry for this,
+                        * so default to an old-fashioned 8259
+@@ -2217,12 +2282,14 @@ void __init setup_IO_APIC(void)
+       /*
+        * Set up IO-APIC IRQ routing.
+        */
+-      setup_ioapic_ids_from_mpc();
++      if (!acpi_ioapic)
++              setup_ioapic_ids_from_mpc();
+       sync_Arb_IDs();
+       setup_IO_APIC_irqs();
+       init_IO_APIC_traps();
+       check_timer();
+-      print_IO_APIC();
++      if (!acpi_ioapic)
++              print_IO_APIC();
+ }
+ /*
+@@ -2379,10 +2446,12 @@ int io_apic_set_pci_routing (int ioapic,
+               "IRQ %d Mode:%i Active:%i)\n", ioapic, 
+               mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, edge_level, active_high_low);
++      if (use_pci_vector() && !platform_legacy_irq(irq))
++              irq = IO_APIC_VECTOR(irq);
+       if (edge_level) {
+-      irq_desc[irq].handler = &ioapic_level_irq_type;
++              irq_desc[irq].handler = &ioapic_level_type;
+       } else {
+-              irq_desc[irq].handler = &ioapic_edge_irq_type;
++              irq_desc[irq].handler = &ioapic_edge_type;
+       }
+       set_intr_gate(entry.vector, interrupt[irq]);
+--- linux-2.6.0/arch/i386/kernel/irq.c 2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/irq.c  2003-12-28 23:22:10.000000000 -0800
+@@ -138,17 +138,19 @@ atomic_t irq_mis_count;
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i, j;
++      int i = *(loff_t *) v, j;
+       struct irqaction * action;
+       unsigned long flags;
+-      seq_printf(p, "           ");
+-      for (j=0; j<NR_CPUS; j++)
+-              if (cpu_online(j))
+-                      seq_printf(p, "CPU%d       ",j);
+-      seq_putc(p, '\n');
++      if (i == 0) {
++              seq_printf(p, "           ");
++              for (j=0; j<NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "CPU%d       ",j);
++              seq_putc(p, '\n');
++      }
+-      for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               spin_lock_irqsave(&irq_desc[i].lock, flags);
+               action = irq_desc[i].action;
+               if (!action) 
+@@ -170,28 +172,32 @@ int show_interrupts(struct seq_file *p, 
+               seq_putc(p, '\n');
+ skip:
+               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+-      }
+-      seq_printf(p, "NMI: ");
+-      for (j = 0; j < NR_CPUS; j++)
+-              if (cpu_online(j))
+-                      seq_printf(p, "%10u ", nmi_count(j));
+-      seq_putc(p, '\n');
++      } else if (i == NR_IRQS) {
++              seq_printf(p, "NMI: ");
++              for (j = 0; j < NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "%10u ", nmi_count(j));
++              seq_putc(p, '\n');
+ #ifdef CONFIG_X86_LOCAL_APIC
+-      seq_printf(p, "LOC: ");
+-      for (j = 0; j < NR_CPUS; j++)
+-              if (cpu_online(j))
+-                      seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs);
+-      seq_putc(p, '\n');
++              seq_printf(p, "LOC: ");
++              for (j = 0; j < NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs);
++              seq_putc(p, '\n');
+ #endif
+-      seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
++              seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+ #ifdef CONFIG_X86_IO_APIC
+ #ifdef APIC_MISMATCH_DEBUG
+-      seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
++              seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+ #endif
+ #endif
++      }
+       return 0;
+ }
++
++
++
+ #ifdef CONFIG_SMP
+ inline void synchronize_irq(unsigned int irq)
+ {
+@@ -502,6 +508,8 @@ out:
+       irq_exit();
++      kgdb_process_breakpoint();
++
+       return 1;
+ }
+@@ -898,48 +906,6 @@ int setup_irq(unsigned int irq, struct i
+ static struct proc_dir_entry * root_irq_dir;
+ static struct proc_dir_entry * irq_dir [NR_IRQS];
+-#define HEX_DIGITS (2*sizeof(cpumask_t))
+-
+-static unsigned int parse_hex_value(const char __user *buffer,
+-              unsigned long count, cpumask_t *ret)
+-{
+-      unsigned char hexnum[HEX_DIGITS];
+-      cpumask_t value = CPU_MASK_NONE;
+-      int i;
+-
+-      if (!count)
+-              return -EINVAL;
+-      if (count > HEX_DIGITS)
+-              count = HEX_DIGITS;
+-      if (copy_from_user(hexnum, buffer, count))
+-              return -EFAULT;
+-
+-      /*
+-       * Parse the first HEX_DIGITS characters as a hex string, any non-hex char
+-       * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+-       */
+-
+-      for (i = 0; i < count; i++) {
+-              unsigned int c = hexnum[i];
+-              int k;
+-
+-              switch (c) {
+-                      case '0' ... '9': c -= '0'; break;
+-                      case 'a' ... 'f': c -= 'a'-10; break;
+-                      case 'A' ... 'F': c -= 'A'-10; break;
+-              default:
+-                      goto out;
+-              }
+-              cpus_shift_left(value, value, 4);
+-              for (k = 0; k < 4; ++k)
+-                      if (test_bit(k, (unsigned long *)&c))
+-                              cpu_set(k, value);
+-      }
+-out:
+-      *ret = value;
+-      return 0;
+-}
+-
+ #ifdef CONFIG_SMP
+ static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
+@@ -949,20 +915,10 @@ cpumask_t irq_affinity[NR_IRQS] = { [0 .
+ static int irq_affinity_read_proc(char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      int k, len;
+-      cpumask_t tmp = irq_affinity[(long)data];
+-
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, irq_affinity[(long)data]);
++      if (count - len < 2)
+               return -EINVAL;
+-
+-      len = 0;
+-      for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-              int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
+-              len += j;
+-              page += j;
+-              cpus_shift_right(tmp, tmp, 16);
+-      }
+-      len += sprintf(page, "\n");
++      len += sprintf(page + len, "\n");
+       return len;
+ }
+@@ -975,7 +931,7 @@ static int irq_affinity_write_proc(struc
+       if (!irq_desc[irq].handler->set_affinity)
+               return -EIO;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       if (err)
+               return err;
+@@ -1000,10 +956,11 @@ static int irq_affinity_write_proc(struc
+ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      unsigned long *mask = (unsigned long *) data;
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, *(cpumask_t *)data);
++      if (count - len < 2)
+               return -EINVAL;
+-      return sprintf (page, "%08lx\n", *mask);
++      len += sprintf(page + len, "\n");
++      return len;
+ }
+ static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
+@@ -1013,7 +970,7 @@ static int prof_cpu_mask_write_proc (str
+       unsigned long full_count = count, err;
+       cpumask_t new_value;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       if (err)
+               return err;
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/kgdb_stub.c    2003-12-28 23:21:09.000000000 -0800
+@@ -0,0 +1,2457 @@
++/*
++ *
++ * 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.
++ *
++ */
++
++/*
++ * Copyright (c) 2000 VERITAS Software Corporation.
++ *
++ */
++/****************************************************************************
++ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
++ *
++ *  Module name: remcom.c $
++ *  Revision: 1.34 $
++ *  Date: 91/03/09 12:29:49 $
++ *  Contributor:     Lake Stevens Instrument Division$
++ *
++ *  Description:     low level support for gdb debugger. $
++ *
++ *  Considerations:  only works on target hardware $
++ *
++ *  Written by:            Glenn Engel $
++ *  Updated by:            David Grothe <dave@gcom.com>
++ *  Updated by:            Robert Walsh <rjwalsh@durables.org>
++ *  Updated by:            wangdi <wangdi@clusterfs.com>
++ *  ModuleState:     Experimental $
++ *
++ *  NOTES:         See Below $
++ *
++ *  Modified for 386 by Jim Kingdon, Cygnus Support.
++ *  Compatibility with 2.1.xx kernel by David Grothe <dave@gcom.com>
++ *
++ *  Changes to allow auto initilization.  All that is needed is that it
++ *  be linked with the kernel and a break point (int 3) be executed.
++ *  The header file <asm/kgdb.h> defines BREAKPOINT to allow one to do
++ *  this. It should also be possible, once the interrupt system is up, to
++ *  call putDebugChar("+").  Once this is done, the remote debugger should
++ *  get our attention by sending a ^C in a packet. George Anzinger
++ *  <george@mvista.com>
++ *  Integrated into 2.2.5 kernel by Tigran Aivazian <tigran@sco.com>
++ *  Added thread support, support for multiple processors,
++ *    support for ia-32(x86) hardware debugging.
++ *    Amit S. Kale ( akale@veritas.com )
++ *
++ *  Modified to support debugging over ethernet by Robert Walsh
++ *  <rjwalsh@durables.org> and wangdi <wangdi@clusterfs.com>, based on
++ *  code by San Mehat.
++ *
++ *
++ *  To enable debugger support, two things need to happen.  One, a
++ *  call to set_debug_traps() is necessary in order to allow any breakpoints
++ *  or error conditions to be properly intercepted and reported to gdb.
++ *  Two, a breakpoint needs to be generated to begin communication.  This
++ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
++ *  simulates a breakpoint by executing an int 3.
++ *
++ *************
++ *
++ *    The following gdb commands are supported:
++ *
++ * command        function                               Return value
++ *
++ *    g                   return the value of the CPU registers  hex data or ENN
++ *    G                   set the value of the CPU registers     OK or ENN
++ *
++ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA    hex data or ENN
++ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA    OK or ENN
++ *
++ *    c                   Resume at current address              SNN   ( signal NN)
++ *    cAA..AA     Continue at address AA..AA             SNN
++ *
++ *    s                   Step one instruction                   SNN
++ *    sAA..AA     Step one instruction from AA..AA       SNN
++ *
++ *    k                   kill
++ *
++ *    ?                   What was the last sigval ?             SNN   (signal NN)
++ *
++ * All commands and responses are sent with a packet which includes a
++ * checksum.  A packet consists of
++ *
++ * $<packet info>#<checksum>.
++ *
++ * where
++ * <packet info> :: <characters representing the command or response>
++ * <checksum>  :: < two hex digits computed as modulo 256 sum of <packetinfo>>
++ *
++ * When a packet is received, it is first acknowledged with either '+' or '-'.
++ * '+' indicates a successful transfer.        '-' indicates a failed transfer.
++ *
++ * Example:
++ *
++ * Host:                Reply:
++ * $m0,10#2a             +$00010203040506070809101112131415#42
++ *
++ ****************************************************************************/
++#define KGDB_VERSION "<20030915.1651.33>"
++#include <linux/config.h>
++#include <linux/types.h>
++#include <asm/string.h>               /* for strcpy */
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <asm/vm86.h>
++#include <asm/system.h>
++#include <asm/ptrace.h>               /* for linux pt_regs struct */
++#include <asm/kgdb_local.h>
++#include <linux/list.h>
++#include <asm/atomic.h>
++#include <asm/processor.h>
++#include <linux/irq.h>
++#include <asm/desc.h>
++#include <linux/inet.h>
++#include <linux/netpoll.h>
++
++/************************************************************************
++ *
++ * external low-level support routines
++ */
++typedef void (*Function) (void);      /* pointer to a function */
++
++/* Thread reference */
++typedef unsigned char threadref[8];
++
++extern int tty_putDebugChar(int);     /* write a single character      */
++extern int tty_getDebugChar(void);    /* read and return a single char */
++extern void tty_flushDebugChar(void); /* flush pending characters      */
++extern int eth_putDebugChar(int);     /* write a single character      */
++extern int eth_getDebugChar(void);    /* read and return a single char */
++extern void eth_flushDebugChar(void); /* flush pending characters      */
++
++/************************************************************************/
++/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
++/* at least NUMREGBYTES*2 are needed for register packets */
++/* Longer buffer is needed to list all threads */
++#define BUFMAX 400
++
++char *kgdb_version = KGDB_VERSION;
++
++/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
++int debug_regs = 0;           /* set to non-zero to print registers */
++
++/* filled in by an external module */
++char *gdb_module_offsets;
++
++static const char hexchars[] = "0123456789abcdef";
++
++/* Number of bytes of registers.  */
++#define NUMREGBYTES 64
++/*
++ * Note that this register image is in a different order than
++ * the register image that Linux produces at interrupt time.
++ *
++ * Linux's register image is defined by struct pt_regs in ptrace.h.
++ * Just why GDB uses a different order is a historical mystery.
++ */
++enum regnames { _EAX,         /* 0 */
++      _ECX,                   /* 1 */
++      _EDX,                   /* 2 */
++      _EBX,                   /* 3 */
++      _ESP,                   /* 4 */
++      _EBP,                   /* 5 */
++      _ESI,                   /* 6 */
++      _EDI,                   /* 7 */
++      _PC /* 8 also known as eip */ ,
++      _PS /* 9 also known as eflags */ ,
++      _CS,                    /* 10 */
++      _SS,                    /* 11 */
++      _DS,                    /* 12 */
++      _ES,                    /* 13 */
++      _FS,                    /* 14 */
++      _GS                     /* 15 */
++};
++
++/***************************  ASSEMBLY CODE MACROS *************************/
++/*
++ * Put the error code here just in case the user cares.
++ * Likewise, the vector number here (since GDB only gets the signal
++ * number through the usual means, and that's not very specific).
++ * The called_from is the return address so he can tell how we entered kgdb.
++ * This will allow him to seperate out the various possible entries.
++ */
++#define REMOTE_DEBUG 0                /* set != to turn on printing (also available in info) */
++
++#define PID_MAX PID_MAX_DEFAULT
++
++#ifdef CONFIG_SMP
++void smp_send_nmi_allbutself(void);
++#define IF_SMP(x) x
++#undef MAX_NO_CPUS
++#ifndef CONFIG_NO_KGDB_CPUS
++#define CONFIG_NO_KGDB_CPUS 2
++#endif
++#if CONFIG_NO_KGDB_CPUS > NR_CPUS
++#define MAX_NO_CPUS NR_CPUS
++#else
++#define MAX_NO_CPUS CONFIG_NO_KGDB_CPUS
++#endif
++#define hold_init hold_on_sstep: 1,
++#define MAX_CPU_MASK (unsigned long)((1LL << MAX_NO_CPUS) - 1LL)
++#define NUM_CPUS num_online_cpus()
++#else
++#define IF_SMP(x)
++#define hold_init
++#undef MAX_NO_CPUS
++#define MAX_NO_CPUS 1
++#define NUM_CPUS 1
++#endif
++#define NOCPU (struct task_struct *)0xbad1fbad
++/* *INDENT-OFF*        */
++struct kgdb_info {
++      int used_malloc;
++      void *called_from;
++      long long entry_tsc;
++      int errcode;
++      int vector;
++      int print_debug_info;
++#ifdef CONFIG_SMP
++      int hold_on_sstep;
++      struct {
++              volatile struct task_struct *task;
++              int pid;
++              int hold;
++              struct pt_regs *regs;
++      } cpus_waiting[MAX_NO_CPUS];
++#endif
++} kgdb_info = {hold_init print_debug_info:REMOTE_DEBUG, vector:-1};
++
++/* *INDENT-ON*        */
++
++#define used_m kgdb_info.used_malloc
++/*
++ * This is little area we set aside to contain the stack we
++ * need to build to allow gdb to call functions.  We use one
++ * per cpu to avoid locking issues.  We will do all this work
++ * with interrupts off so that should take care of the protection
++ * issues.
++ */
++#define LOOKASIDE_SIZE 200    /* should be more than enough */
++#define MALLOC_MAX   200      /* Max malloc size */
++struct {
++      unsigned int esp;
++      int array[LOOKASIDE_SIZE];
++} fn_call_lookaside[MAX_NO_CPUS];
++
++static int trap_cpu;
++static unsigned int OLD_esp;
++
++#define END_OF_LOOKASIDE  &fn_call_lookaside[trap_cpu].array[LOOKASIDE_SIZE]
++#define IF_BIT 0x200
++#define TF_BIT 0x100
++
++#define MALLOC_ROUND 8-1
++
++static char malloc_array[MALLOC_MAX];
++IF_SMP(static void to_gdb(const char *mess));
++void *
++malloc(int size)
++{
++
++      if (size <= (MALLOC_MAX - used_m)) {
++              int old_used = used_m;
++              used_m += ((size + MALLOC_ROUND) & (~MALLOC_ROUND));
++              return &malloc_array[old_used];
++      } else {
++              return NULL;
++      }
++}
++
++/*
++ * I/O dispatch functions...
++ * Based upon kgdboe, either call the ethernet
++ * handler or the serial one..
++ */
++void
++putDebugChar(int c)
++{
++      if (!kgdboe) {
++              tty_putDebugChar(c);
++      } else {
++              eth_putDebugChar(c);
++      }
++}
++
++int
++getDebugChar(void)
++{
++      if (!kgdboe) {
++              return tty_getDebugChar();
++      } else {
++              return eth_getDebugChar();
++      }
++}
++
++void
++flushDebugChar(void)
++{
++      if (!kgdboe) {
++              tty_flushDebugChar();
++      } else {
++              eth_flushDebugChar();
++      }
++}
++
++/*
++ * Gdb calls functions by pushing agruments, including a return address
++ * on the stack and the adjusting EIP to point to the function.        The
++ * whole assumption in GDB is that we are on a different stack than the
++ * one the "user" i.e. code that hit the break point, is on.  This, of
++ * course is not true in the kernel.  Thus various dodges are needed to
++ * do the call without directly messing with EIP (which we can not change
++ * as it is just a location and not a register.        To adjust it would then
++ * require that we move every thing below EIP up or down as needed.  This
++ * will not work as we may well have stack relative pointer on the stack
++ * (such as the pointer to regs, for example).
++
++ * So here is what we do:
++ * We detect gdb attempting to store into the stack area and instead, store
++ * into the fn_call_lookaside.array at the same relative location as if it
++ * were the area ESP pointed at.  We also trap ESP modifications
++ * and uses these to adjust fn_call_lookaside.esp.  On entry
++ * fn_call_lookaside.esp will be set to point at the last entry in
++ * fn_call_lookaside.array.  This allows us to check if it has changed, and
++ * if so, on exit, we add the registers we will use to do the move and a
++ * trap/ interrupt return exit sequence.  We then adjust the eflags in the
++ * regs array (remember we now have a copy in the fn_call_lookaside.array) to
++ * kill the interrupt bit, AND we change EIP to point at our set up stub.
++ * As part of the register set up we preset the registers to point at the
++ * begining and end of the fn_call_lookaside.array, so all the stub needs to
++ * do is move words from the array to the stack until ESP= the desired value
++ * then do the rti.  This will then transfer to the desired function with
++ * all the correct registers.  Nifty huh?
++ */
++extern asmlinkage void fn_call_stub(void);
++extern asmlinkage void fn_rtn_stub(void);
++/*                                       *INDENT-OFF*  */
++__asm__("fn_rtn_stub:\n\t"
++      "movl %eax,%esp\n\t"
++      "fn_call_stub:\n\t"
++      "1:\n\t"
++      "addl $-4,%ebx\n\t"
++      "movl (%ebx), %eax\n\t"
++      "pushl %eax\n\t"
++      "cmpl %esp,%ecx\n\t"
++      "jne  1b\n\t"
++      "popl %eax\n\t"
++      "popl %ebx\n\t"
++      "popl %ecx\n\t"
++      "iret \n\t");
++/*                                         *INDENT-ON*  */
++#define gdb_i386vector        kgdb_info.vector
++#define gdb_i386errcode kgdb_info.errcode
++#define waiting_cpus  kgdb_info.cpus_waiting
++#define remote_debug  kgdb_info.print_debug_info
++#define hold_cpu(cpu) kgdb_info.cpus_waiting[cpu].hold
++/* gdb locks */
++
++#ifdef CONFIG_SMP
++static int in_kgdb_called;
++static spinlock_t waitlocks[MAX_NO_CPUS] =
++    {[0 ... MAX_NO_CPUS - 1] = SPIN_LOCK_UNLOCKED };
++/*
++ * The following array has the thread pointer of each of the "other"
++ * cpus.  We make it global so it can be seen by gdb.
++ */
++volatile int in_kgdb_entry_log[MAX_NO_CPUS];
++volatile struct pt_regs *in_kgdb_here_log[MAX_NO_CPUS];
++/*
++static spinlock_t continuelocks[MAX_NO_CPUS];
++*/
++spinlock_t kgdb_spinlock = SPIN_LOCK_UNLOCKED;
++/* waiters on our spinlock plus us */
++static atomic_t spinlock_waiters = ATOMIC_INIT(1);
++static int spinlock_count = 0;
++static int spinlock_cpu = 0;
++/*
++ * Note we use nested spin locks to account for the case where a break
++ * point is encountered when calling a function by user direction from
++ * kgdb. Also there is the memory exception recursion to account for.
++ * Well, yes, but this lets other cpus thru too.  Lets add a
++ * cpu id to the lock.
++ */
++#define KGDB_SPIN_LOCK(x) if( spinlock_count == 0 || \
++                            spinlock_cpu != smp_processor_id()){\
++                                    atomic_inc(&spinlock_waiters); \
++                                    while (! spin_trylock(x)) {\
++                                          in_kgdb(&regs);\
++                                    }\
++                                    atomic_dec(&spinlock_waiters); \
++                                    spinlock_count = 1; \
++                                    spinlock_cpu = smp_processor_id(); \
++                        }else{  \
++                                    spinlock_count++; \
++                        }
++#define KGDB_SPIN_UNLOCK(x) if( --spinlock_count == 0) spin_unlock(x)
++#else
++unsigned kgdb_spinlock = 0;
++#define KGDB_SPIN_LOCK(x) --*x
++#define KGDB_SPIN_UNLOCK(x) ++*x
++#endif
++
++int
++hex(char ch)
++{
++      if ((ch >= 'a') && (ch <= 'f'))
++              return (ch - 'a' + 10);
++      if ((ch >= '0') && (ch <= '9'))
++              return (ch - '0');
++      if ((ch >= 'A') && (ch <= 'F'))
++              return (ch - 'A' + 10);
++      return (-1);
++}
++
++/* scan for the sequence $<data>#<checksum>   */
++void
++getpacket(char *buffer)
++{
++      unsigned char checksum;
++      unsigned char xmitcsum;
++      int i;
++      int count;
++      char ch;
++
++      do {
++              /* wait around for the start character, ignore all other characters */
++              while ((ch = (getDebugChar() & 0x7f)) != '$') ;
++              checksum = 0;
++              xmitcsum = -1;
++
++              count = 0;
++
++              /* now, read until a # or end of buffer is found */
++              while (count < BUFMAX) {
++                      ch = getDebugChar() & 0x7f;
++                      if (ch == '#')
++                              break;
++                      checksum = checksum + ch;
++                      buffer[count] = ch;
++                      count = count + 1;
++              }
++              buffer[count] = 0;
++
++              if (ch == '#') {
++                      xmitcsum = hex(getDebugChar() & 0x7f) << 4;
++                      xmitcsum += hex(getDebugChar() & 0x7f);
++                      if ((remote_debug) && (checksum != xmitcsum)) {
++                              printk
++                                  ("bad checksum.     My count = 0x%x, sent=0x%x. buf=%s\n",
++                                   checksum, xmitcsum, buffer);
++                      }
++
++                      if (checksum != xmitcsum)
++                              putDebugChar('-');      /* failed checksum */
++                      else {
++                              putDebugChar('+');      /* successful transfer */
++                              /* if a sequence char is present, reply the sequence ID */
++                              if (buffer[2] == ':') {
++                                      putDebugChar(buffer[0]);
++                                      putDebugChar(buffer[1]);
++                                      /* remove sequence chars from buffer */
++                                      count = strlen(buffer);
++                                      for (i = 3; i <= count; i++)
++                                              buffer[i - 3] = buffer[i];
++                              }
++                      }
++              }
++      } while (checksum != xmitcsum);
++
++      if (remote_debug)
++              printk("R:%s\n", buffer);
++      flushDebugChar();
++}
++
++/* send the packet in buffer.  */
++
++void
++putpacket(char *buffer)
++{
++      unsigned char checksum;
++      int count;
++      char ch;
++
++      /*  $<packet info>#<checksum>. */
++
++      if (!kgdboe) {
++              do {
++                      if (remote_debug)
++                              printk("T:%s\n", buffer);
++                      putDebugChar('$');
++                      checksum = 0;
++                      count = 0;
++
++                      while ((ch = buffer[count])) {
++                              putDebugChar(ch);
++                              checksum += ch;
++                              count += 1;
++                      }
++
++                      putDebugChar('#');
++                      putDebugChar(hexchars[checksum >> 4]);
++                      putDebugChar(hexchars[checksum % 16]);
++                      flushDebugChar();
++
++              } while ((getDebugChar() & 0x7f) != '+');
++      } else {
++              /*
++               * For udp, we can not transfer too much bytes once.
++               * We only transfer MAX_SEND_COUNT size bytes each time
++               */
++
++#define MAX_SEND_COUNT 30
++
++              int send_count = 0, i = 0;
++              char send_buf[MAX_SEND_COUNT];
++
++              do {
++                      if (remote_debug)
++                              printk("T:%s\n", buffer);
++                      putDebugChar('$');
++                      checksum = 0;
++                      count = 0;
++                      send_count = 0;
++                      while ((ch = buffer[count])) {
++                              if (send_count >= MAX_SEND_COUNT) {
++                                      for(i = 0; i < MAX_SEND_COUNT; i++) {
++                                              putDebugChar(send_buf[i]);
++                                      }
++                                      flushDebugChar();
++                                      send_count = 0;
++                              } else {
++                                      send_buf[send_count] = ch;
++                                      checksum += ch;
++                                      count ++;
++                                      send_count++;
++                              }
++                      }
++                      for(i = 0; i < send_count; i++)
++                              putDebugChar(send_buf[i]);
++                      putDebugChar('#');
++                      putDebugChar(hexchars[checksum >> 4]);
++                      putDebugChar(hexchars[checksum % 16]);
++                      flushDebugChar();
++              } while ((getDebugChar() & 0x7f) != '+');
++      }
++}
++
++static char remcomInBuffer[BUFMAX];
++static char remcomOutBuffer[BUFMAX];
++static short error;
++
++void
++debug_error(char *format, char *parm)
++{
++      if (remote_debug)
++              printk(format, parm);
++}
++
++static void
++print_regs(struct pt_regs *regs)
++{
++      printk("EAX=%08lx ", regs->eax);
++      printk("EBX=%08lx ", regs->ebx);
++      printk("ECX=%08lx ", regs->ecx);
++      printk("EDX=%08lx ", regs->edx);
++      printk("\n");
++      printk("ESI=%08lx ", regs->esi);
++      printk("EDI=%08lx ", regs->edi);
++      printk("EBP=%08lx ", regs->ebp);
++      printk("ESP=%08lx ", (long) &regs->esp);
++      printk("\n");
++      printk(" DS=%08x ", regs->xds);
++      printk(" ES=%08x ", regs->xes);
++      printk(" SS=%08x ", __KERNEL_DS);
++      printk(" FL=%08lx ", regs->eflags);
++      printk("\n");
++      printk(" CS=%08x ", regs->xcs);
++      printk(" IP=%08lx ", regs->eip);
++#if 0
++      printk(" FS=%08x ", regs->fs);
++      printk(" GS=%08x ", regs->gs);
++#endif
++      printk("\n");
++
++}                             /* print_regs */
++
++#define NEW_esp fn_call_lookaside[trap_cpu].esp
++
++static void
++regs_to_gdb_regs(int *gdb_regs, struct pt_regs *regs)
++{
++      gdb_regs[_EAX] = regs->eax;
++      gdb_regs[_EBX] = regs->ebx;
++      gdb_regs[_ECX] = regs->ecx;
++      gdb_regs[_EDX] = regs->edx;
++      gdb_regs[_ESI] = regs->esi;
++      gdb_regs[_EDI] = regs->edi;
++      gdb_regs[_EBP] = regs->ebp;
++      gdb_regs[_DS] = regs->xds;
++      gdb_regs[_ES] = regs->xes;
++      gdb_regs[_PS] = regs->eflags;
++      gdb_regs[_CS] = regs->xcs;
++      gdb_regs[_PC] = regs->eip;
++      /* Note, as we are a debugging the kernel, we will always
++       * trap in kernel code, this means no priviledge change,
++       * and so the pt_regs structure is not completely valid.  In a non
++       * privilege change trap, only EFLAGS, CS and EIP are put on the stack,
++       * SS and ESP are not stacked, this means that the last 2 elements of
++       * pt_regs is not valid (they would normally refer to the user stack)
++       * also, using regs+1 is no good because you end up will a value that is
++       * 2 longs (8) too high.  This used to cause stepping over functions
++       * to fail, so my fix is to use the address of regs->esp, which
++       * should point at the end of the stack frame.  Note I have ignored
++       * completely exceptions that cause an error code to be stacked, such
++       * as double fault.  Stuart Hughes, Zentropix.
++       * original code: gdb_regs[_ESP] =  (int) (regs + 1) ;
++
++       * this is now done on entry and moved to OLD_esp (as well as NEW_esp).
++       */
++      gdb_regs[_ESP] = NEW_esp;
++      gdb_regs[_SS] = __KERNEL_DS;
++      gdb_regs[_FS] = 0xFFFF;
++      gdb_regs[_GS] = 0xFFFF;
++}                             /* regs_to_gdb_regs */
++
++static void
++gdb_regs_to_regs(int *gdb_regs, struct pt_regs *regs)
++{
++      regs->eax = gdb_regs[_EAX];
++      regs->ebx = gdb_regs[_EBX];
++      regs->ecx = gdb_regs[_ECX];
++      regs->edx = gdb_regs[_EDX];
++      regs->esi = gdb_regs[_ESI];
++      regs->edi = gdb_regs[_EDI];
++      regs->ebp = gdb_regs[_EBP];
++      regs->xds = gdb_regs[_DS];
++      regs->xes = gdb_regs[_ES];
++      regs->eflags = gdb_regs[_PS];
++      regs->xcs = gdb_regs[_CS];
++      regs->eip = gdb_regs[_PC];
++      NEW_esp = gdb_regs[_ESP];       /* keep the value */
++#if 0                         /* can't change these */
++      regs->esp = gdb_regs[_ESP];
++      regs->xss = gdb_regs[_SS];
++      regs->fs = gdb_regs[_FS];
++      regs->gs = gdb_regs[_GS];
++#endif
++
++}                             /* gdb_regs_to_regs */
++extern void scheduling_functions_start_here(void);
++extern void scheduling_functions_end_here(void);
++#define first_sched   ((unsigned long) scheduling_functions_start_here)
++#define last_sched    ((unsigned long) scheduling_functions_end_here)
++
++int thread_list = 0;
++
++void
++get_gdb_regs(struct task_struct *p, struct pt_regs *regs, int *gdb_regs)
++{
++      unsigned long stack_page;
++      int count = 0;
++      IF_SMP(int i);
++      if (!p || p == current) {
++              regs_to_gdb_regs(gdb_regs, regs);
++              return;
++      }
++#ifdef CONFIG_SMP
++      for (i = 0; i < MAX_NO_CPUS; i++) {
++              if (p == kgdb_info.cpus_waiting[i].task) {
++                      regs_to_gdb_regs(gdb_regs,
++                                       kgdb_info.cpus_waiting[i].regs);
++                      gdb_regs[_ESP] =
++                          (int) &kgdb_info.cpus_waiting[i].regs->esp;
++
++                      return;
++              }
++      }
++#endif
++      memset(gdb_regs, 0, NUMREGBYTES);
++      gdb_regs[_ESP] = p->thread.esp;
++      gdb_regs[_PC] = p->thread.eip;
++      gdb_regs[_EBP] = *(int *) gdb_regs[_ESP];
++      gdb_regs[_EDI] = *(int *) (gdb_regs[_ESP] + 4);
++      gdb_regs[_ESI] = *(int *) (gdb_regs[_ESP] + 8);
++
++/*
++ * This code is to give a more informative notion of where a process
++ * is waiting.        It is used only when the user asks for a thread info
++ * list.  If he then switches to the thread, s/he will find the task
++ * is in schedule, but a back trace should show the same info we come
++ * up with.  This code was shamelessly purloined from process.c.  It was
++ * then enhanced to provide more registers than simply the program
++ * counter.
++ */
++
++      if (!thread_list) {
++              return;
++      }
++
++      if (p->state == TASK_RUNNING)
++              return;
++      stack_page = (unsigned long) p->thread_info;
++      if (gdb_regs[_ESP] < stack_page || gdb_regs[_ESP] > 8188 + stack_page)
++              return;
++      /* include/asm-i386/system.h:switch_to() pushes ebp last. */
++      do {
++              if (gdb_regs[_EBP] < stack_page ||
++                  gdb_regs[_EBP] > 8184 + stack_page)
++                      return;
++              gdb_regs[_PC] = *(unsigned long *) (gdb_regs[_EBP] + 4);
++              gdb_regs[_ESP] = gdb_regs[_EBP] + 8;
++              gdb_regs[_EBP] = *(unsigned long *) gdb_regs[_EBP];
++              if (gdb_regs[_PC] < first_sched || gdb_regs[_PC] >= last_sched)
++                      return;
++      } while (count++ < 16);
++      return;
++}
++
++/* Indicate to caller of mem2hex or hex2mem that there has been an
++   error.  */
++static volatile int mem_err = 0;
++static volatile int mem_err_expected = 0;
++static volatile int mem_err_cnt = 0;
++static int garbage_loc = -1;
++
++int
++get_char(char *addr)
++{
++      return *addr;
++}
++
++void
++set_char(char *addr, int val, int may_fault)
++{
++      /*
++       * This code traps references to the area mapped to the kernel
++       * stack as given by the regs and, instead, stores to the
++       * fn_call_lookaside[cpu].array
++       */
++      if (may_fault &&
++          (unsigned int) addr < OLD_esp &&
++          ((unsigned int) addr > (OLD_esp - (unsigned int) LOOKASIDE_SIZE))) {
++              addr = (char *) END_OF_LOOKASIDE - ((char *) OLD_esp - addr);
++      }
++      *addr = val;
++}
++
++/* convert the memory pointed to by mem into hex, placing result in buf */
++/* return a pointer to the last char put in buf (null) */
++/* If MAY_FAULT is non-zero, then we should set mem_err in response to
++   a fault; if zero treat a fault like any other fault in the stub.  */
++char *
++mem2hex(char *mem, char *buf, int count, int may_fault)
++{
++      int i;
++      unsigned char ch;
++
++      if (may_fault) {
++              mem_err_expected = 1;
++              mem_err = 0;
++      }
++      for (i = 0; i < count; i++) {
++              /* printk("%lx = ", mem) ; */
++
++              ch = get_char(mem++);
++
++              /* printk("%02x\n", ch & 0xFF) ; */
++              if (may_fault && mem_err) {
++                      if (remote_debug)
++                              printk("Mem fault fetching from addr %lx\n",
++                                     (long) (mem - 1));
++                      *buf = 0;       /* truncate buffer */
++                      return (buf);
++              }
++              *buf++ = hexchars[ch >> 4];
++              *buf++ = hexchars[ch % 16];
++      }
++      *buf = 0;
++      if (may_fault)
++              mem_err_expected = 0;
++      return (buf);
++}
++
++/* convert the hex array pointed to by buf into binary to be placed in mem */
++/* return a pointer to the character AFTER the last byte written */
++/* NOTE: We use the may fault flag to also indicate if the write is to
++ * the registers (0) or "other" memory (!=0)
++ */
++char *
++hex2mem(char *buf, char *mem, int count, int may_fault)
++{
++      int i;
++      unsigned char ch;
++
++      if (may_fault) {
++              mem_err_expected = 1;
++              mem_err = 0;
++      }
++      for (i = 0; i < count; i++) {
++              ch = hex(*buf++) << 4;
++              ch = ch + hex(*buf++);
++              set_char(mem++, ch, may_fault);
++
++              if (may_fault && mem_err) {
++                      if (remote_debug)
++                              printk("Mem fault storing to addr %lx\n",
++                                     (long) (mem - 1));
++                      return (mem);
++              }
++      }
++      if (may_fault)
++              mem_err_expected = 0;
++      return (mem);
++}
++
++/**********************************************/
++/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
++/* RETURN NUMBER OF CHARS PROCESSED         */
++/**********************************************/
++int
++hexToInt(char **ptr, int *intValue)
++{
++      int numChars = 0;
++      int hexValue;
++
++      *intValue = 0;
++
++      while (**ptr) {
++              hexValue = hex(**ptr);
++              if (hexValue >= 0) {
++                      *intValue = (*intValue << 4) | hexValue;
++                      numChars++;
++              } else
++                      break;
++
++              (*ptr)++;
++      }
++
++      return (numChars);
++}
++
++#define stubhex(h) hex(h)
++#ifdef old_thread_list
++
++static int
++stub_unpack_int(char *buff, int fieldlength)
++{
++      int nibble;
++      int retval = 0;
++
++      while (fieldlength) {
++              nibble = stubhex(*buff++);
++              retval |= nibble;
++              fieldlength--;
++              if (fieldlength)
++                      retval = retval << 4;
++      }
++      return retval;
++}
++#endif
++static char *
++pack_hex_byte(char *pkt, int byte)
++{
++      *pkt++ = hexchars[(byte >> 4) & 0xf];
++      *pkt++ = hexchars[(byte & 0xf)];
++      return pkt;
++}
++
++#define BUF_THREAD_ID_SIZE 16
++
++static char *
++pack_threadid(char *pkt, threadref * id)
++{
++      char *limit;
++      unsigned char *altid;
++
++      altid = (unsigned char *) id;
++      limit = pkt + BUF_THREAD_ID_SIZE;
++      while (pkt < limit)
++              pkt = pack_hex_byte(pkt, *altid++);
++      return pkt;
++}
++
++#ifdef old_thread_list
++static char *
++unpack_byte(char *buf, int *value)
++{
++      *value = stub_unpack_int(buf, 2);
++      return buf + 2;
++}
++
++static char *
++unpack_threadid(char *inbuf, threadref * id)
++{
++      char *altref;
++      char *limit = inbuf + BUF_THREAD_ID_SIZE;
++      int x, y;
++
++      altref = (char *) id;
++
++      while (inbuf < limit) {
++              x = stubhex(*inbuf++);
++              y = stubhex(*inbuf++);
++              *altref++ = (x << 4) | y;
++      }
++      return inbuf;
++}
++#endif
++void
++int_to_threadref(threadref * id, int value)
++{
++      unsigned char *scan;
++
++      scan = (unsigned char *) id;
++      {
++              int i = 4;
++              while (i--)
++                      *scan++ = 0;
++      }
++      *scan++ = (value >> 24) & 0xff;
++      *scan++ = (value >> 16) & 0xff;
++      *scan++ = (value >> 8) & 0xff;
++      *scan++ = (value & 0xff);
++}
++int
++int_to_hex_v(unsigned char * id, int value)
++{
++      unsigned char *start = id;
++      int shift;
++      int ch;
++
++      for (shift = 28; shift >= 0; shift -= 4) {
++              if ((ch = (value >> shift) & 0xf) || (id != start)) {
++                      *id = hexchars[ch];
++                      id++;
++              }
++      }
++      if (id == start)
++              *id++ = '0';
++      return id - start;
++}
++#ifdef old_thread_list
++
++static int
++threadref_to_int(threadref * ref)
++{
++      int i, value = 0;
++      unsigned char *scan;
++
++      scan = (char *) ref;
++      scan += 4;
++      i = 4;
++      while (i-- > 0)
++              value = (value << 8) | ((*scan++) & 0xff);
++      return value;
++}
++#endif
++static int
++cmp_str(char *s1, char *s2, int count)
++{
++      while (count--) {
++              if (*s1++ != *s2++)
++                      return 0;
++      }
++      return 1;
++}
++
++#if 1                         /* this is a hold over from 2.4 where O(1) was "sometimes" */
++extern struct task_struct *kgdb_get_idle(int cpu);
++#define idle_task(cpu) kgdb_get_idle(cpu)
++#else
++#define idle_task(cpu) init_tasks[cpu]
++#endif
++
++extern int kgdb_pid_init_done;
++
++struct task_struct *
++getthread(int pid)
++{
++      struct task_struct *thread;
++      if (pid >= PID_MAX && pid <= (PID_MAX + MAX_NO_CPUS)) {
++
++              return idle_task(pid - PID_MAX);
++      } else {
++              /*
++               * find_task_by_pid is relatively safe all the time
++               * Other pid functions require lock downs which imply
++               * that we may be interrupting them (as we get here
++               * in the middle of most any lock down).
++               * Still we don't want to call until the table exists!
++               */
++              if (kgdb_pid_init_done){
++                      thread = find_task_by_pid(pid);
++                      if (thread) {
++                              return thread;
++                      }
++              }
++      }
++      return NULL;
++}
++/* *INDENT-OFF*        */
++struct hw_breakpoint {
++      unsigned enabled;
++      unsigned type;
++      unsigned len;
++      unsigned addr;
++} breakinfo[4] = { {enabled:0},
++                 {enabled:0},
++                 {enabled:0},
++                 {enabled:0}};
++/* *INDENT-ON*        */
++unsigned hw_breakpoint_status;
++void
++correct_hw_break(void)
++{
++      int breakno;
++      int correctit;
++      int breakbit;
++      unsigned dr7;
++
++      asm volatile ("movl %%db7, %0\n":"=r" (dr7)
++                    :);
++      /* *INDENT-OFF*  */
++      do {
++              unsigned addr0, addr1, addr2, addr3;
++              asm volatile ("movl %%db0, %0\n"
++                            "movl %%db1, %1\n"
++                            "movl %%db2, %2\n"
++                            "movl %%db3, %3\n"
++                            :"=r" (addr0), "=r"(addr1),
++                            "=r"(addr2), "=r"(addr3)
++                            :);
++      } while (0);
++      /* *INDENT-ON*  */
++      correctit = 0;
++      for (breakno = 0; breakno < 3; breakno++) {
++              breakbit = 2 << (breakno << 1);
++              if (!(dr7 & breakbit) && breakinfo[breakno].enabled) {
++                      correctit = 1;
++                      dr7 |= breakbit;
++                      dr7 &= ~(0xf0000 << (breakno << 2));
++                      dr7 |= (((breakinfo[breakno].len << 2) |
++                               breakinfo[breakno].type) << 16) <<
++                          (breakno << 2);
++                      switch (breakno) {
++                      case 0:
++                              asm volatile ("movl %0, %%dr0\n"::"r"
++                                            (breakinfo[breakno].addr));
++                              break;
++
++                      case 1:
++                              asm volatile ("movl %0, %%dr1\n"::"r"
++                                            (breakinfo[breakno].addr));
++                              break;
++
++                      case 2:
++                              asm volatile ("movl %0, %%dr2\n"::"r"
++                                            (breakinfo[breakno].addr));
++                              break;
++
++                      case 3:
++                              asm volatile ("movl %0, %%dr3\n"::"r"
++                                            (breakinfo[breakno].addr));
++                              break;
++                      }
++              } else if ((dr7 & breakbit) && !breakinfo[breakno].enabled) {
++                      correctit = 1;
++                      dr7 &= ~breakbit;
++                      dr7 &= ~(0xf0000 << (breakno << 2));
++              }
++      }
++      if (correctit) {
++              asm volatile ("movl %0, %%db7\n"::"r" (dr7));
++      }
++}
++
++int
++remove_hw_break(unsigned breakno)
++{
++      if (!breakinfo[breakno].enabled) {
++              return -1;
++      }
++      breakinfo[breakno].enabled = 0;
++      return 0;
++}
++
++int
++set_hw_break(unsigned breakno, unsigned type, unsigned len, unsigned addr)
++{
++      if (breakinfo[breakno].enabled) {
++              return -1;
++      }
++      breakinfo[breakno].enabled = 1;
++      breakinfo[breakno].type = type;
++      breakinfo[breakno].len = len;
++      breakinfo[breakno].addr = addr;
++      return 0;
++}
++
++#ifdef CONFIG_SMP
++static int in_kgdb_console = 0;
++
++int
++in_kgdb(struct pt_regs *regs)
++{
++      unsigned flags;
++      int cpu = smp_processor_id();
++      in_kgdb_called = 1;
++      if (!spin_is_locked(&kgdb_spinlock)) {
++              if (in_kgdb_here_log[cpu] ||    /* we are holding this cpu */
++                  in_kgdb_console) {  /* or we are doing slow i/o */
++                      return 1;
++              }
++              return 0;
++      }
++
++      /* As I see it the only reason not to let all cpus spin on
++       * the same spin_lock is to allow selected ones to proceed.
++       * This would be a good thing, so we leave it this way.
++       * Maybe someday....  Done !
++
++       * in_kgdb() is called from an NMI so we don't pretend
++       * to have any resources, like printk() for example.
++       */
++
++      kgdb_local_irq_save(flags);     /* only local here, to avoid hanging */
++      /*
++       * log arival of this cpu
++       * The NMI keeps on ticking.  Protect against recurring more
++       * than once, and ignor the cpu that has the kgdb lock
++       */
++      in_kgdb_entry_log[cpu]++;
++      in_kgdb_here_log[cpu] = regs;
++      if (cpu == spinlock_cpu || waiting_cpus[cpu].task)
++              goto exit_in_kgdb;
++
++      /*
++       * For protection of the initilization of the spin locks by kgdb
++       * it locks the kgdb spinlock before it gets the wait locks set
++       * up.  We wait here for the wait lock to be taken.  If the
++       * kgdb lock goes away first??  Well, it could be a slow exit
++       * sequence where the wait lock is removed prior to the kgdb lock
++       * so if kgdb gets unlocked, we just exit.
++       */
++
++      while (spin_is_locked(&kgdb_spinlock) &&
++             !spin_is_locked(waitlocks + cpu)) ;
++      if (!spin_is_locked(&kgdb_spinlock))
++              goto exit_in_kgdb;
++
++      waiting_cpus[cpu].task = current;
++      waiting_cpus[cpu].pid = (current->pid) ? : (PID_MAX + cpu);
++      waiting_cpus[cpu].regs = regs;
++
++      spin_unlock_wait(waitlocks + cpu);
++
++      /*
++       * log departure of this cpu
++       */
++      waiting_cpus[cpu].task = 0;
++      waiting_cpus[cpu].pid = 0;
++      waiting_cpus[cpu].regs = 0;
++      correct_hw_break();
++      exit_in_kgdb:
++      in_kgdb_here_log[cpu] = 0;
++      kgdb_local_irq_restore(flags);
++      return 1;
++      /*
++         spin_unlock(continuelocks + smp_processor_id());
++       */
++}
++
++void
++smp__in_kgdb(struct pt_regs regs)
++{
++      ack_APIC_irq();
++      in_kgdb(&regs);
++}
++#else
++int
++in_kgdb(struct pt_regs *regs)
++{
++      return (kgdb_spinlock);
++}
++#endif
++
++void
++printexceptioninfo(int exceptionNo, int errorcode, char *buffer)
++{
++      unsigned dr6;
++      int i;
++      switch (exceptionNo) {
++      case 1:         /* debug exception */
++              break;
++      case 3:         /* breakpoint */
++              sprintf(buffer, "Software breakpoint");
++              return;
++      default:
++              sprintf(buffer, "Details not available");
++              return;
++      }
++      asm volatile ("movl %%db6, %0\n":"=r" (dr6)
++                    :);
++      if (dr6 & 0x4000) {
++              sprintf(buffer, "Single step");
++              return;
++      }
++      for (i = 0; i < 4; ++i) {
++              if (dr6 & (1 << i)) {
++                      sprintf(buffer, "Hardware breakpoint %d", i);
++                      return;
++              }
++      }
++      sprintf(buffer, "Unknown trap");
++      return;
++}
++
++/*
++ * This function does all command procesing for interfacing to gdb.
++ *
++ * NOTE:  The INT nn instruction leaves the state of the interrupt
++ *      enable flag UNCHANGED.  That means that when this routine
++ *      is entered via a breakpoint (INT 3) instruction from code
++ *      that has interrupts enabled, then interrupts will STILL BE
++ *      enabled when this routine is entered.  The first thing that
++ *      we do here is disable interrupts so as to prevent recursive
++ *      entries and bothersome serial interrupts while we are
++ *      trying to run the serial port in polled mode.
++ *
++ * For kernel version 2.1.xx the kgdb_cli() actually gets a spin lock so
++ * it is always necessary to do a restore_flags before returning
++ * so as to let go of that lock.
++ */
++int
++kgdb_handle_exception(int exceptionVector,
++                    int signo, int err_code, struct pt_regs *linux_regs)
++{
++      struct task_struct *usethread = NULL;
++      struct task_struct *thread_list_start = 0, *thread = NULL;
++      int addr, length;
++      int breakno, breaktype;
++      char *ptr;
++      int newPC;
++      threadref thref;
++      int threadid;
++      int thread_min = PID_MAX + MAX_NO_CPUS;
++#ifdef old_thread_list
++      int maxthreads;
++#endif
++      int nothreads;
++      unsigned long flags;
++      int gdb_regs[NUMREGBYTES / 4];
++      int dr6;
++      IF_SMP(int entry_state = 0);    /* 0, ok, 1, no nmi, 2 sync failed */
++#define NO_NMI 1
++#define NO_SYNC 2
++#define       regs    (*linux_regs)
++#define NUMREGS NUMREGBYTES/4
++      /*
++       * If the entry is not from the kernel then return to the Linux
++       * trap handler and let it process the interrupt normally.
++       */
++      if ((linux_regs->eflags & VM_MASK) || (3 & linux_regs->xcs)) {
++              printk("ignoring non-kernel exception\n");
++              print_regs(&regs);
++              return (0);
++      }
++      /*
++       * If we're using eth mode, set the 'mode' in the netdevice.
++       */
++
++      if (kgdboe)
++              netpoll_set_trap(1);
++
++      kgdb_local_irq_save(flags);
++
++      /* Get kgdb spinlock */
++
++      KGDB_SPIN_LOCK(&kgdb_spinlock);
++      rdtscll(kgdb_info.entry_tsc);
++      /*
++       * We depend on this spinlock and the NMI watch dog to control the
++       * other cpus.  They will arrive at "in_kgdb()" as a result of the
++       * NMI and will wait there for the following spin locks to be
++       * released.
++       */
++#ifdef CONFIG_SMP
++
++#if 0
++      if (cpu_callout_map & ~MAX_CPU_MASK) {
++              printk("kgdb : too many cpus, possibly not mapped"
++                     " in contiguous space, change MAX_NO_CPUS"
++                     " in kgdb_stub and make new kernel.\n"
++                     " cpu_callout_map is %lx\n", cpu_callout_map);
++              goto exit_just_unlock;
++      }
++#endif
++      if (spinlock_count == 1) {
++              int time, end_time, dum;
++              int i;
++              int cpu_logged_in[MAX_NO_CPUS] = {[0 ... MAX_NO_CPUS - 1] = (0)
++              };
++              if (remote_debug) {
++                      printk("kgdb : cpu %d entry, syncing others\n",
++                             smp_processor_id());
++              }
++              for (i = 0; i < MAX_NO_CPUS; i++) {
++                      /*
++                       * Use trylock as we may already hold the lock if
++                       * we are holding the cpu.  Net result is all
++                       * locked.
++                       */
++                      spin_trylock(&waitlocks[i]);
++              }
++              for (i = 0; i < MAX_NO_CPUS; i++)
++                      cpu_logged_in[i] = 0;
++              /*
++               * Wait for their arrival.  We know the watch dog is active if
++               * in_kgdb() has ever been called, as it is always called on a
++               * watchdog tick.
++               */
++              rdtsc(dum, time);
++              end_time = time + 2;    /* Note: we use the High order bits! */
++              i = 1;
++              if (num_online_cpus() > 1) {
++                      int me_in_kgdb = in_kgdb_entry_log[smp_processor_id()];
++                      smp_send_nmi_allbutself();
++
++                      while (i < num_online_cpus() && time != end_time) {
++                              int j;
++                              for (j = 0; j < MAX_NO_CPUS; j++) {
++                                      if (waiting_cpus[j].task &&
++                                          waiting_cpus[j].task != NOCPU &&
++                                          !cpu_logged_in[j]) {
++                                              i++;
++                                              cpu_logged_in[j] = 1;
++                                              if (remote_debug) {
++                                                      printk
++                                                          ("kgdb : cpu %d arrived at kgdb\n",
++                                                           j);
++                                              }
++                                              break;
++                                      } else if (!waiting_cpus[j].task &&
++                                                 !cpu_online(j)) {
++                                              waiting_cpus[j].task = NOCPU;
++                                              cpu_logged_in[j] = 1;
++                                              waiting_cpus[j].hold = 1;
++                                              break;
++                                      }
++                                      if (!waiting_cpus[j].task &&
++                                          in_kgdb_here_log[j]) {
++
++                                              int wait = 100000;
++                                              while (wait--) ;
++                                              if (!waiting_cpus[j].task &&
++                                                  in_kgdb_here_log[j]) {
++                                                      printk
++                                                          ("kgdb : cpu %d stall"
++                                                           " in in_kgdb\n",
++                                                           j);
++                                                      i++;
++                                                      cpu_logged_in[j] = 1;
++                                                      waiting_cpus[j].task =
++                                                          (struct task_struct
++                                                           *) 1;
++                                              }
++                                      }
++                              }
++
++                              if (in_kgdb_entry_log[smp_processor_id()] >
++                                  (me_in_kgdb + 10)) {
++                                      break;
++                              }
++
++                              rdtsc(dum, time);
++                      }
++                      if (i < num_online_cpus()) {
++                              printk
++                                  ("kgdb : time out, proceeding without sync\n");
++#if 0
++                              printk("kgdb : Waiting_cpus: 0 = %d, 1 = %d\n",
++                                     waiting_cpus[0].task != 0,
++                                     waiting_cpus[1].task != 0);
++                              printk("kgdb : Cpu_logged in: 0 = %d, 1 = %d\n",
++                                     cpu_logged_in[0], cpu_logged_in[1]);
++                              printk
++                                  ("kgdb : in_kgdb_here_log in: 0 = %d, 1 = %d\n",
++                                   in_kgdb_here_log[0] != 0,
++                                   in_kgdb_here_log[1] != 0);
++#endif
++                              entry_state = NO_SYNC;
++                      } else {
++#if 0
++                              int ent =
++                                  in_kgdb_entry_log[smp_processor_id()] -
++                                  me_in_kgdb;
++                              printk("kgdb : sync after %d entries\n", ent);
++#endif
++                      }
++              } else {
++                      if (remote_debug) {
++                              printk
++                                  ("kgdb : %d cpus, but watchdog not active\n"
++                                   "proceeding without locking down other cpus\n",
++                                   num_online_cpus());
++                              entry_state = NO_NMI;
++                      }
++              }
++      }
++#endif
++
++      if (remote_debug) {
++              unsigned long *lp = (unsigned long *) &linux_regs;
++
++              printk("handle_exception(exceptionVector=%d, "
++                     "signo=%d, err_code=%d, linux_regs=%p)\n",
++                     exceptionVector, signo, err_code, linux_regs);
++              if (debug_regs) {
++                      print_regs(&regs);
++                      printk("Stk: %8lx %8lx %8lx %8lx"
++                             "  %8lx %8lx %8lx %8lx\n",
++                             lp[0], lp[1], lp[2], lp[3],
++                             lp[4], lp[5], lp[6], lp[7]);
++                      printk("     %8lx %8lx %8lx %8lx"
++                             "  %8lx %8lx %8lx %8lx\n",
++                             lp[8], lp[9], lp[10], lp[11],
++                             lp[12], lp[13], lp[14], lp[15]);
++                      printk("     %8lx %8lx %8lx %8lx  "
++                             "%8lx %8lx %8lx %8lx\n",
++                             lp[16], lp[17], lp[18], lp[19],
++                             lp[20], lp[21], lp[22], lp[23]);
++                      printk("     %8lx %8lx %8lx %8lx  "
++                             "%8lx %8lx %8lx %8lx\n",
++                             lp[24], lp[25], lp[26], lp[27],
++                             lp[28], lp[29], lp[30], lp[31]);
++              }
++      }
++
++      /* Disable hardware debugging while we are in kgdb */
++      /* Get the debug register status register */
++/*                                   *INDENT-OFF*  */
++      __asm__("movl %0,%%db7"
++            : /* no output */
++            :"r"(0));
++
++      asm volatile ("movl %%db6, %0\n"
++                    :"=r" (hw_breakpoint_status)
++                    :);
++
++/*                                   *INDENT-ON*  */
++      switch (exceptionVector) {
++      case 0:         /* divide error */
++      case 1:         /* debug exception */
++      case 2:         /* NMI */
++      case 3:         /* breakpoint */
++      case 4:         /* overflow */
++      case 5:         /* bounds check */
++      case 6:         /* invalid opcode */
++      case 7:         /* device not available */
++      case 8:         /* double fault (errcode) */
++      case 10:                /* invalid TSS (errcode) */
++      case 12:                /* stack fault (errcode) */
++      case 16:                /* floating point error */
++      case 17:                /* alignment check (errcode) */
++      default:                /* any undocumented */
++              break;
++      case 11:                /* segment not present (errcode) */
++      case 13:                /* general protection (errcode) */
++      case 14:                /* page fault (special errcode) */
++      case 19:                /* cache flush denied */
++              if (mem_err_expected) {
++                      /*
++                       * This fault occured because of the
++                       * get_char or set_char routines.  These
++                       * two routines use either eax of edx to
++                       * indirectly reference the location in
++                       * memory that they are working with.
++                       * For a page fault, when we return the
++                       * instruction will be retried, so we
++                       * have to make sure that these
++                       * registers point to valid memory.
++                       */
++                      mem_err = 1;    /* set mem error flag */
++                      mem_err_expected = 0;
++                      mem_err_cnt++;  /* helps in debugging */
++                      /* make valid address */
++                      regs.eax = (long) &garbage_loc;
++                      /* make valid address */
++                      regs.edx = (long) &garbage_loc;
++                      if (remote_debug)
++                              printk("Return after memory error: "
++                                     "mem_err_cnt=%d\n", mem_err_cnt);
++                      if (debug_regs)
++                              print_regs(&regs);
++                      goto exit_kgdb;
++              }
++              break;
++      }
++      if (remote_debug)
++              printk("kgdb : entered kgdb on cpu %d\n", smp_processor_id());
++
++      gdb_i386vector = exceptionVector;
++      gdb_i386errcode = err_code;
++      kgdb_info.called_from = __builtin_return_address(0);
++#ifdef CONFIG_SMP
++      /*
++       * OK, we can now communicate, lets tell gdb about the sync.
++       * but only if we had a problem.
++       */
++      switch (entry_state) {
++      case NO_NMI:
++              to_gdb("NMI not active, other cpus not stopped\n");
++              break;
++      case NO_SYNC:
++              to_gdb("Some cpus not stopped, see 'kgdb_info' for details\n");
++      default:;
++      }
++
++#endif
++/*
++ * Set up the gdb function call area.
++ */
++      trap_cpu = smp_processor_id();
++      OLD_esp = NEW_esp = (int) (&linux_regs->esp);
++
++      IF_SMP(once_again:)
++          /* reply to host that an exception has occurred */
++          remcomOutBuffer[0] = 'S';
++      remcomOutBuffer[1] = hexchars[signo >> 4];
++      remcomOutBuffer[2] = hexchars[signo % 16];
++      remcomOutBuffer[3] = 0;
++
++      putpacket(remcomOutBuffer);
++
++      while (1 == 1) {
++              error = 0;
++              remcomOutBuffer[0] = 0;
++              getpacket(remcomInBuffer);
++              switch (remcomInBuffer[0]) {
++              case '?':
++                      remcomOutBuffer[0] = 'S';
++                      remcomOutBuffer[1] = hexchars[signo >> 4];
++                      remcomOutBuffer[2] = hexchars[signo % 16];
++                      remcomOutBuffer[3] = 0;
++                      break;
++              case 'd':
++                      remote_debug = !(remote_debug); /* toggle debug flag */
++                      printk("Remote debug %s\n",
++                             remote_debug ? "on" : "off");
++                      break;
++              case 'g':       /* return the value of the CPU registers */
++                      get_gdb_regs(usethread, &regs, gdb_regs);
++                      mem2hex((char *) gdb_regs,
++                              remcomOutBuffer, NUMREGBYTES, 0);
++                      break;
++              case 'G':       /* set the value of the CPU registers - return OK */
++                      hex2mem(&remcomInBuffer[1],
++                              (char *) gdb_regs, NUMREGBYTES, 0);
++                      if (!usethread || usethread == current) {
++                              gdb_regs_to_regs(gdb_regs, &regs);
++                              strcpy(remcomOutBuffer, "OK");
++                      } else {
++                              strcpy(remcomOutBuffer, "E00");
++                      }
++                      break;
++
++              case 'P':{      /* set the value of a single CPU register -
++                                 return OK */
++                              /*
++                               * For some reason, gdb wants to talk about psudo
++                               * registers (greater than 15).  These may have
++                               * meaning for ptrace, but for us it is safe to
++                               * ignor them.  We do this by dumping them into
++                               * _GS which we also ignor, but do have memory for.
++                               */
++                              int regno;
++
++                              ptr = &remcomInBuffer[1];
++                              regs_to_gdb_regs(gdb_regs, &regs);
++                              if ((!usethread || usethread == current) &&
++                                  hexToInt(&ptr, &regno) &&
++                                  *ptr++ == '=' && (regno >= 0)) {
++                                      regno =
++                                          (regno >= NUMREGS ? _GS : regno);
++                                      hex2mem(ptr, (char *) &gdb_regs[regno],
++                                              4, 0);
++                                      gdb_regs_to_regs(gdb_regs, &regs);
++                                      strcpy(remcomOutBuffer, "OK");
++                                      break;
++                              }
++                              strcpy(remcomOutBuffer, "E01");
++                              break;
++                      }
++
++                      /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
++              case 'm':
++                      /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
++                      ptr = &remcomInBuffer[1];
++                      if (hexToInt(&ptr, &addr) &&
++                          (*(ptr++) == ',') && (hexToInt(&ptr, &length))) {
++                              ptr = 0;
++                              /*
++                               * hex doubles the byte count
++                               */
++                              if (length > (BUFMAX / 2))
++                                      length = BUFMAX / 2;
++                              mem2hex((char *) addr,
++                                      remcomOutBuffer, length, 1);
++                              if (mem_err) {
++                                      strcpy(remcomOutBuffer, "E03");
++                                      debug_error("memory fault\n", NULL);
++                              }
++                      }
++
++                      if (ptr) {
++                              strcpy(remcomOutBuffer, "E01");
++                              debug_error
++                                  ("malformed read memory command: %s\n",
++                                   remcomInBuffer);
++                      }
++                      break;
++
++                      /* MAA..AA,LLLL:
++                         Write LLLL bytes at address AA.AA return OK */
++              case 'M':
++                      /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
++                      ptr = &remcomInBuffer[1];
++                      if (hexToInt(&ptr, &addr) &&
++                          (*(ptr++) == ',') &&
++                          (hexToInt(&ptr, &length)) && (*(ptr++) == ':')) {
++                              hex2mem(ptr, (char *) addr, length, 1);
++
++                              if (mem_err) {
++                                      strcpy(remcomOutBuffer, "E03");
++                                      debug_error("memory fault\n", NULL);
++                              } else {
++                                      strcpy(remcomOutBuffer, "OK");
++                              }
++
++                              ptr = 0;
++                      }
++                      if (ptr) {
++                              strcpy(remcomOutBuffer, "E02");
++                              debug_error
++                                  ("malformed write memory command: %s\n",
++                                   remcomInBuffer);
++                      }
++                      break;
++              case 'S':
++                      remcomInBuffer[0] = 's';
++              case 'C':
++                      /* Csig;AA..AA where ;AA..AA is optional
++                       * continue with signal
++                       * Since signals are meaning less to us, delete that
++                       * part and then fall into the 'c' code.
++                       */
++                      ptr = &remcomInBuffer[1];
++                      length = 2;
++                      while (*ptr && *ptr != ';') {
++                              length++;
++                              ptr++;
++                      }
++                      if (*ptr) {
++                              do {
++                                      ptr++;
++                                      *(ptr - length++) = *ptr;
++                              } while (*ptr);
++                      } else {
++                              remcomInBuffer[1] = 0;
++                      }
++
++                      /* cAA..AA  Continue at address AA..AA(optional) */
++                      /* sAA..AA  Step one instruction from AA..AA(optional) */
++                      /* D        detach, reply OK and then continue */
++              case 'c':
++              case 's':
++              case 'D':
++
++                      /* try to read optional parameter,
++                         pc unchanged if no parm */
++                      ptr = &remcomInBuffer[1];
++                      if (hexToInt(&ptr, &addr)) {
++                              if (remote_debug)
++                                      printk("Changing EIP to 0x%x\n", addr);
++
++                              regs.eip = addr;
++                      }
++
++                      newPC = regs.eip;
++
++                      /* clear the trace bit */
++                      regs.eflags &= 0xfffffeff;
++
++                      /* set the trace bit if we're stepping */
++                      if (remcomInBuffer[0] == 's')
++                              regs.eflags |= 0x100;
++
++                      /* detach is a friendly version of continue. Note that
++                         debugging is still enabled (e.g hit control C)
++                       */
++                      if (remcomInBuffer[0] == 'D') {
++                              strcpy(remcomOutBuffer, "OK");
++                              putpacket(remcomOutBuffer);
++                      }
++
++                      if (remote_debug) {
++                              printk("Resuming execution\n");
++                              print_regs(&regs);
++                      }
++                      asm volatile ("movl %%db6, %0\n":"=r" (dr6)
++                                    :);
++                      if (!(dr6 & 0x4000)) {
++                              for (breakno = 0; breakno < 4; ++breakno) {
++                                      if (dr6 & (1 << breakno) &&
++                                          (breakinfo[breakno].type == 0)) {
++                                              /* Set restore flag */
++                                              regs.eflags |= 0x10000;
++                                              break;
++                                      }
++                              }
++                      }
++
++                      if (kgdboe)
++                              netpoll_set_trap(0);
++
++                      correct_hw_break();
++                      asm volatile ("movl %0, %%db6\n"::"r" (0));
++                      goto exit_kgdb;
++
++                      /* kill the program */
++              case 'k':       /* do nothing */
++                      break;
++
++                      /* query */
++              case 'q':
++                      nothreads = 0;
++                      switch (remcomInBuffer[1]) {
++                      case 'f':
++                              threadid = 1;
++                              thread_list = 2;
++                              thread_list_start = (usethread ? : current);
++                      case 's':
++                              if (!cmp_str(&remcomInBuffer[2],
++                                           "ThreadInfo", 10))
++                                      break;
++
++                              remcomOutBuffer[nothreads++] = 'm';
++                              for (; threadid < PID_MAX + MAX_NO_CPUS;
++                                   threadid++) {
++                                      thread = getthread(threadid);
++                                      if (thread) {
++                                              nothreads += int_to_hex_v(
++                                                      &remcomOutBuffer[
++                                                              nothreads],
++                                                      threadid);
++                                              if (thread_min > threadid)
++                                                      thread_min = threadid;
++                                              remcomOutBuffer[
++                                                      nothreads] = ',';
++                                              nothreads++;
++                                              if (nothreads > BUFMAX - 10)
++                                                      break;
++                                      }
++                              }
++                              if (remcomOutBuffer[nothreads - 1] == 'm') {
++                                      remcomOutBuffer[nothreads - 1] = 'l';
++                              } else {
++                                      nothreads--;
++                              }
++                              remcomOutBuffer[nothreads] = 0;
++                              break;
++
++#ifdef old_thread_list /* Old thread info request */
++                      case 'L':
++                              /* List threads */
++                              thread_list = 2;
++                              thread_list_start = (usethread ? : current);
++                              unpack_byte(remcomInBuffer + 3, &maxthreads);
++                              unpack_threadid(remcomInBuffer + 5, &thref);
++                              do {
++                                      int buf_thread_limit =
++                                          (BUFMAX - 22) / BUF_THREAD_ID_SIZE;
++                                      if (maxthreads > buf_thread_limit) {
++                                              maxthreads = buf_thread_limit;
++                                      }
++                              } while (0);
++                              remcomOutBuffer[0] = 'q';
++                              remcomOutBuffer[1] = 'M';
++                              remcomOutBuffer[4] = '0';
++                              pack_threadid(remcomOutBuffer + 5, &thref);
++
++                              threadid = threadref_to_int(&thref);
++                              for (nothreads = 0;
++                                   nothreads < maxthreads &&
++                                   threadid < PID_MAX + MAX_NO_CPUS;
++                                   threadid++) {
++                                      thread = getthread(threadid);
++                                      if (thread) {
++                                              int_to_threadref(&thref,
++                                                               threadid);
++                                              pack_threadid(remcomOutBuffer +
++                                                            21 +
++                                                            nothreads * 16,
++                                                            &thref);
++                                              nothreads++;
++                                              if (thread_min > threadid)
++                                                      thread_min = threadid;
++                                      }
++                              }
++
++                              if (threadid == PID_MAX + MAX_NO_CPUS) {
++                                      remcomOutBuffer[4] = '1';
++                              }
++                              pack_hex_byte(remcomOutBuffer + 2, nothreads);
++                              remcomOutBuffer[21 + nothreads * 16] = '\0';
++                              break;
++#endif
++                      case 'C':
++                              /* Current thread id */
++                              remcomOutBuffer[0] = 'Q';
++                              remcomOutBuffer[1] = 'C';
++                              threadid = current->pid;
++                              if (!threadid) {
++                                      /*
++                                       * idle thread
++                                       */
++                                      for (threadid = PID_MAX;
++                                           threadid < PID_MAX + MAX_NO_CPUS;
++                                           threadid++) {
++                                              if (current ==
++                                                  idle_task(threadid -
++                                                            PID_MAX))
++                                                      break;
++                                      }
++                              }
++                              int_to_threadref(&thref, threadid);
++                              pack_threadid(remcomOutBuffer + 2, &thref);
++                              remcomOutBuffer[18] = '\0';
++                              break;
++
++                      case 'E':
++                              /* Print exception info */
++                              printexceptioninfo(exceptionVector,
++                                                 err_code, remcomOutBuffer);
++                              break;
++                      case 'T':{
++                              char * nptr;
++                              /* Thread extra info */
++                              if (!cmp_str(&remcomInBuffer[2],
++                                          "hreadExtraInfo,", 15)) {
++                                      break;
++                              }
++                              ptr = &remcomInBuffer[17];
++                              hexToInt(&ptr, &threadid);
++                              thread = getthread(threadid);
++                              nptr = &thread->comm[0];
++                              length = 0;
++                              ptr = &remcomOutBuffer[0];
++                              do {
++                                      length++;
++                                      ptr = pack_hex_byte(ptr, *nptr++);
++                               } while (*nptr && length < 16);
++                              /*
++                               * would like that 16 to be the size of
++                               * task_struct.comm but don't know the
++                               * syntax..
++                               */
++                              *ptr = 0;
++                      }
++                      }
++                      break;
++
++                      /* task related */
++              case 'H':
++                      switch (remcomInBuffer[1]) {
++                      case 'g':
++                              ptr = &remcomInBuffer[2];
++                              hexToInt(&ptr, &threadid);
++                              thread = getthread(threadid);
++                              if (!thread) {
++                                      remcomOutBuffer[0] = 'E';
++                                      remcomOutBuffer[1] = '\0';
++                                      break;
++                              }
++                              /*
++                               * Just in case I forget what this is all about,
++                               * the "thread info" command to gdb causes it
++                               * to ask for a thread list.  It then switches
++                               * to each thread and asks for the registers.
++                               * For this (and only this) usage, we want to
++                               * fudge the registers of tasks not on the run
++                               * list (i.e. waiting) to show the routine that
++                               * called schedule. Also, gdb, is a minimalist
++                               * in that if the current thread is the last
++                               * it will not re-read the info when done.
++                               * This means that in this case we must show
++                               * the real registers. So here is how we do it:
++                               * Each entry we keep track of the min
++                               * thread in the list (the last that gdb will)
++                               * get info for.  We also keep track of the
++                               * starting thread.
++                               * "thread_list" is cleared when switching back
++                               * to the min thread if it is was current, or
++                               * if it was not current, thread_list is set
++                               * to 1.  When the switch to current comes,
++                               * if thread_list is 1, clear it, else do
++                               * nothing.
++                               */
++                              usethread = thread;
++                              if ((thread_list == 1) &&
++                                  (thread == thread_list_start)) {
++                                      thread_list = 0;
++                              }
++                              if (thread_list && (threadid == thread_min)) {
++                                      if (thread == thread_list_start) {
++                                              thread_list = 0;
++                                      } else {
++                                              thread_list = 1;
++                                      }
++                              }
++                              /* follow through */
++                      case 'c':
++                              remcomOutBuffer[0] = 'O';
++                              remcomOutBuffer[1] = 'K';
++                              remcomOutBuffer[2] = '\0';
++                              break;
++                      }
++                      break;
++
++                      /* Query thread status */
++              case 'T':
++                      ptr = &remcomInBuffer[1];
++                      hexToInt(&ptr, &threadid);
++                      thread = getthread(threadid);
++                      if (thread) {
++                              remcomOutBuffer[0] = 'O';
++                              remcomOutBuffer[1] = 'K';
++                              remcomOutBuffer[2] = '\0';
++                              if (thread_min > threadid)
++                                      thread_min = threadid;
++                      } else {
++                              remcomOutBuffer[0] = 'E';
++                              remcomOutBuffer[1] = '\0';
++                      }
++                      break;
++
++              case 'Y': /* set up a hardware breakpoint */
++                      ptr = &remcomInBuffer[1];
++                      hexToInt(&ptr, &breakno);
++                      ptr++;
++                      hexToInt(&ptr, &breaktype);
++                      ptr++;
++                      hexToInt(&ptr, &length);
++                      ptr++;
++                      hexToInt(&ptr, &addr);
++                      if (set_hw_break(breakno & 0x3,
++                                       breaktype & 0x3,
++                                       length & 0x3, addr) == 0) {
++                              strcpy(remcomOutBuffer, "OK");
++                      } else {
++                              strcpy(remcomOutBuffer, "ERROR");
++                      }
++                      break;
++
++                      /* Remove hardware breakpoint */
++              case 'y':
++                      ptr = &remcomInBuffer[1];
++                      hexToInt(&ptr, &breakno);
++                      if (remove_hw_break(breakno & 0x3) == 0) {
++                              strcpy(remcomOutBuffer, "OK");
++                      } else {
++                              strcpy(remcomOutBuffer, "ERROR");
++                      }
++                      break;
++
++              case 'r':       /* reboot */
++                      strcpy(remcomOutBuffer, "OK");
++                      putpacket(remcomOutBuffer);
++                      /*to_gdb("Rebooting\n"); */
++                      /* triplefault   no return from here */
++                      {
++                              static long no_idt[2];
++                              __asm__ __volatile__("lidt %0"::"m"(no_idt[0]));
++                              BREAKPOINT;
++                      }
++
++              }               /* switch */
++
++              /* reply to the request */
++              putpacket(remcomOutBuffer);
++      }                       /* while(1==1) */
++      /*
++       *  reached by goto only.
++       */
++      exit_kgdb:
++      /*
++       * Here is where we set up to trap a gdb function call.  NEW_esp
++       * will be changed if we are trying to do this.  We handle both
++       * adding and subtracting, thus allowing gdb to put grung on
++       * the stack which it removes later.
++       */
++      if (NEW_esp != OLD_esp) {
++              int *ptr = END_OF_LOOKASIDE;
++              if (NEW_esp < OLD_esp)
++                      ptr -= (OLD_esp - NEW_esp) / sizeof (int);
++              *--ptr = linux_regs->eflags;
++              *--ptr = linux_regs->xcs;
++              *--ptr = linux_regs->eip;
++              *--ptr = linux_regs->ecx;
++              *--ptr = linux_regs->ebx;
++              *--ptr = linux_regs->eax;
++              linux_regs->ecx = NEW_esp - (sizeof (int) * 6);
++              linux_regs->ebx = (unsigned int) END_OF_LOOKASIDE;
++              if (NEW_esp < OLD_esp) {
++                      linux_regs->eip = (unsigned int) fn_call_stub;
++              } else {
++                      linux_regs->eip = (unsigned int) fn_rtn_stub;
++                      linux_regs->eax = NEW_esp;
++              }
++              linux_regs->eflags &= ~(IF_BIT | TF_BIT);
++      }
++#ifdef CONFIG_SMP
++      /*
++       * Release gdb wait locks
++       * Sanity check time.  Must have at least one cpu to run.  Also single
++       * step must not be done if the current cpu is on hold.
++       */
++      if (spinlock_count == 1) {
++              int ss_hold = (regs.eflags & 0x100) && kgdb_info.hold_on_sstep;
++              int cpu_avail = 0;
++              int i;
++
++              for (i = 0; i < MAX_NO_CPUS; i++) {
++                      if (!cpu_online(i))
++                              break;
++                      if (!hold_cpu(i)) {
++                              cpu_avail = 1;
++                      }
++              }
++              /*
++               * Early in the bring up there will be NO cpus on line...
++               */
++              if (!cpu_avail && !cpus_empty(cpu_online_map)) {
++                      to_gdb("No cpus unblocked, see 'kgdb_info.hold_cpu'\n");
++                      goto once_again;
++              }
++              if (hold_cpu(smp_processor_id()) && (regs.eflags & 0x100)) {
++                      to_gdb
++                          ("Current cpu must be unblocked to single step\n");
++                      goto once_again;
++              }
++              if (!(ss_hold)) {
++                      int i;
++                      for (i = 0; i < MAX_NO_CPUS; i++) {
++                              if (!hold_cpu(i)) {
++                                      spin_unlock(&waitlocks[i]);
++                              }
++                      }
++              } else {
++                      spin_unlock(&waitlocks[smp_processor_id()]);
++              }
++              /* Release kgdb spinlock */
++              KGDB_SPIN_UNLOCK(&kgdb_spinlock);
++              /*
++               * If this cpu is on hold, this is where we
++               * do it.  Note, the NMI will pull us out of here,
++               * but will return as the above lock is not held.
++               * We will stay here till another cpu releases the lock for us.
++               */
++              spin_unlock_wait(waitlocks + smp_processor_id());
++              kgdb_local_irq_restore(flags);
++              return (0);
++      }
++#if 0
++exit_just_unlock:
++#endif
++#endif
++      /* Release kgdb spinlock */
++      KGDB_SPIN_UNLOCK(&kgdb_spinlock);
++      kgdb_local_irq_restore(flags);
++      return (0);
++}
++
++/* this function is used to set up exception handlers for tracing and
++ * breakpoints.
++ * This function is not needed as the above line does all that is needed.
++ * We leave it for backward compatitability...
++ */
++void
++set_debug_traps(void)
++{
++      /*
++       * linux_debug_hook is defined in traps.c.  We store a pointer
++       * to our own exception handler into it.
++
++       * But really folks, every hear of labeled common, an old Fortran
++       * concept.  Lots of folks can reference it and it is define if
++       * anyone does.  Only one can initialize it at link time.  We do
++       * this with the hook.  See the statement above.  No need for any
++       * executable code and it is ready as soon as the kernel is
++       * loaded.  Very desirable in kernel debugging.
++
++       linux_debug_hook = handle_exception ;
++       */
++
++      /* In case GDB is started before us, ack any packets (presumably
++         "$?#xx") sitting there.
++         putDebugChar ('+');
++
++         initialized = 1;
++       */
++}
++
++/* This function will generate a breakpoint exception.        It is used at the
++   beginning of a program to sync up with a debugger and can be used
++   otherwise as a quick means to stop program execution and "break" into
++   the debugger. */
++/* But really, just use the BREAKPOINT macro.  We will handle the int stuff
++ */
++
++#ifdef later
++/*
++ * possibly we should not go thru the traps.c code at all?  Someday.
++ */
++void
++do_kgdb_int3(struct pt_regs *regs, long error_code)
++{
++      kgdb_handle_exception(3, 5, error_code, regs);
++      return;
++}
++#endif
++#undef regs
++#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
++asmlinkage void
++bad_sys_call_exit(int stuff)
++{
++      struct pt_regs *regs = (struct pt_regs *) &stuff;
++      printk("Sys call %d return with %x preempt_count\n",
++             (int) regs->orig_eax, preempt_count());
++}
++#endif
++#ifdef CONFIG_STACK_OVERFLOW_TEST
++#include <asm/kgdb.h>
++asmlinkage void
++stack_overflow(void)
++{
++#ifdef BREAKPOINT
++      BREAKPOINT;
++#else
++      printk("Kernel stack overflow, looping forever\n");
++#endif
++      while (1) {
++      }
++}
++#endif
++
++#if defined(CONFIG_SMP) || defined(CONFIG_KGDB_CONSOLE)
++char gdbconbuf[BUFMAX];
++
++static void
++kgdb_gdb_message(const char *s, unsigned count)
++{
++      int i;
++      int wcount;
++      char *bufptr;
++      /*
++       * This takes care of NMI while spining out chars to gdb
++       */
++      IF_SMP(in_kgdb_console = 1);
++      gdbconbuf[0] = 'O';
++      bufptr = gdbconbuf + 1;
++      while (count > 0) {
++              if ((count << 1) > (BUFMAX - 2)) {
++                      wcount = (BUFMAX - 2) >> 1;
++              } else {
++                      wcount = count;
++              }
++              count -= wcount;
++              for (i = 0; i < wcount; i++) {
++                      bufptr = pack_hex_byte(bufptr, s[i]);
++              }
++              *bufptr = '\0';
++              s += wcount;
++
++              putpacket(gdbconbuf);
++
++      }
++      IF_SMP(in_kgdb_console = 0);
++}
++#endif
++#ifdef CONFIG_SMP
++static void
++to_gdb(const char *s)
++{
++      int count = 0;
++      while (s[count] && (count++ < BUFMAX)) ;
++      kgdb_gdb_message(s, count);
++}
++#endif
++#ifdef CONFIG_KGDB_CONSOLE
++#include <linux/console.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <asm/uaccess.h>
++#include <asm/semaphore.h>
++
++void
++kgdb_console_write(struct console *co, const char *s, unsigned count)
++{
++
++      if (gdb_i386vector == -1) {
++              /*
++               * We have not yet talked to gdb.  What to do...
++               * lets break, on continue we can do the write.
++               * But first tell him whats up. Uh, well no can do,
++               * as this IS the console.  Oh well...
++               * We do need to wait or the messages will be lost.
++               * Other option would be to tell the above code to
++               * ignore this breakpoint and do an auto return,
++               * but that might confuse gdb.  Also this happens
++               * early enough in boot up that we don't have the traps
++               * set up yet, so...
++               */
++              breakpoint();
++      }
++      kgdb_gdb_message(s, count);
++}
++
++/*
++ * ------------------------------------------------------------
++ * Serial KGDB driver
++ * ------------------------------------------------------------
++ */
++
++static struct console kgdbcons = {
++      name:"kgdb",
++      write:kgdb_console_write,
++#ifdef CONFIG_KGDB_USER_CONSOLE
++      device:kgdb_console_device,
++#endif
++      flags:CON_PRINTBUFFER | CON_ENABLED,
++      index:-1,
++};
++
++/*
++ * The trick here is that this file gets linked before printk.o
++ * That means we get to peer at the console info in the command
++ * line before it does.        If we are up, we register, otherwise,
++ * do nothing.        By returning 0, we allow printk to look also.
++ */
++static int kgdb_console_enabled;
++
++int __init
++kgdb_console_init(char *str)
++{
++      if ((strncmp(str, "kgdb", 4) == 0) || (strncmp(str, "gdb", 3) == 0)) {
++              register_console(&kgdbcons);
++              kgdb_console_enabled = 1;
++      }
++      return 0;               /* let others look at the string */
++}
++
++__setup("console=", kgdb_console_init);
++
++#ifdef CONFIG_KGDB_USER_CONSOLE
++static kdev_t kgdb_console_device(struct console *c);
++/* This stuff sort of works, but it knocks out telnet devices
++ * we are leaving it here in case we (or you) find time to figure it out
++ * better..
++ */
++
++/*
++ * We need a real char device as well for when the console is opened for user
++ * space activities.
++ */
++
++static int
++kgdb_consdev_open(struct inode *inode, struct file *file)
++{
++      return 0;
++}
++
++static ssize_t
++kgdb_consdev_write(struct file *file, const char *buf,
++                 size_t count, loff_t * ppos)
++{
++      int size, ret = 0;
++      static char kbuf[128];
++      static DECLARE_MUTEX(sem);
++
++      /* We are not reentrant... */
++      if (down_interruptible(&sem))
++              return -ERESTARTSYS;
++
++      while (count > 0) {
++              /* need to copy the data from user space */
++              size = count;
++              if (size > sizeof (kbuf))
++                      size = sizeof (kbuf);
++              if (copy_from_user(kbuf, buf, size)) {
++                      ret = -EFAULT;
++                      break;;
++              }
++              kgdb_console_write(&kgdbcons, kbuf, size);
++              count -= size;
++              ret += size;
++              buf += size;
++      }
++
++      up(&sem);
++
++      return ret;
++}
++
++struct file_operations kgdb_consdev_fops = {
++      open:kgdb_consdev_open,
++      write:kgdb_consdev_write
++};
++static kdev_t
++kgdb_console_device(struct console *c)
++{
++      return MKDEV(TTYAUX_MAJOR, 1);
++}
++
++/*
++ * This routine gets called from the serial stub in the i386/lib
++ * This is so it is done late in bring up (just before the console open).
++ */
++void
++kgdb_console_finit(void)
++{
++      if (kgdb_console_enabled) {
++              char *cptr = cdevname(MKDEV(TTYAUX_MAJOR, 1));
++              char *cp = cptr;
++              while (*cptr && *cptr != '(')
++                      cptr++;
++              *cptr = 0;
++              unregister_chrdev(TTYAUX_MAJOR, cp);
++              register_chrdev(TTYAUX_MAJOR, "kgdb", &kgdb_consdev_fops);
++      }
++}
++#endif
++#endif
++#ifdef CONFIG_KGDB_TS
++#include <asm/msr.h>          /* time stamp code */
++#include <asm/hardirq.h>      /* in_interrupt */
++#ifdef CONFIG_KGDB_TS_64
++#define DATA_POINTS 64
++#endif
++#ifdef CONFIG_KGDB_TS_128
++#define DATA_POINTS 128
++#endif
++#ifdef CONFIG_KGDB_TS_256
++#define DATA_POINTS 256
++#endif
++#ifdef CONFIG_KGDB_TS_512
++#define DATA_POINTS 512
++#endif
++#ifdef CONFIG_KGDB_TS_1024
++#define DATA_POINTS 1024
++#endif
++#ifndef DATA_POINTS
++#define DATA_POINTS 128               /* must be a power of two */
++#endif
++#define INDEX_MASK (DATA_POINTS - 1)
++#if (INDEX_MASK & DATA_POINTS)
++#error "CONFIG_KGDB_TS_COUNT must be a power of 2"
++#endif
++struct kgdb_and_then_struct {
++#ifdef CONFIG_SMP
++      int on_cpu;
++#endif
++      struct task_struct *task;
++      long long at_time;
++      int from_ln;
++      char *in_src;
++      void *from;
++      int *with_shpf;
++      int data0;
++      int data1;
++};
++struct kgdb_and_then_struct2 {
++#ifdef CONFIG_SMP
++      int on_cpu;
++#endif
++      struct task_struct *task;
++      long long at_time;
++      int from_ln;
++      char *in_src;
++      void *from;
++      int *with_shpf;
++      struct task_struct *t1;
++      struct task_struct *t2;
++};
++struct kgdb_and_then_struct kgdb_data[DATA_POINTS];
++
++struct kgdb_and_then_struct *kgdb_and_then = &kgdb_data[0];
++int kgdb_and_then_count;
++
++void
++kgdb_tstamp(int line, char *source, int data0, int data1)
++{
++      static spinlock_t ts_spin = SPIN_LOCK_UNLOCKED;
++      int flags;
++      kgdb_local_irq_save(flags);
++      spin_lock(&ts_spin);
++      rdtscll(kgdb_and_then->at_time);
++#ifdef CONFIG_SMP
++      kgdb_and_then->on_cpu = smp_processor_id();
++#endif
++      kgdb_and_then->task = current;
++      kgdb_and_then->from_ln = line;
++      kgdb_and_then->in_src = source;
++      kgdb_and_then->from = __builtin_return_address(0);
++      kgdb_and_then->with_shpf = (int *) (((flags & IF_BIT) >> 9) |
++                                          (preempt_count() << 8));
++      kgdb_and_then->data0 = data0;
++      kgdb_and_then->data1 = data1;
++      kgdb_and_then = &kgdb_data[++kgdb_and_then_count & INDEX_MASK];
++      spin_unlock(&ts_spin);
++      kgdb_local_irq_restore(flags);
++#ifdef CONFIG_PREEMPT
++
++#endif
++      return;
++}
++#endif
++typedef int gdb_debug_hook(int exceptionVector,
++                         int signo, int err_code, struct pt_regs *linux_regs);
++gdb_debug_hook *linux_debug_hook = &kgdb_handle_exception;    /* histerical reasons... */
++
++static int kgdb_need_breakpoint[NR_CPUS];
++
++void kgdb_schedule_breakpoint(void)
++{
++      kgdb_need_breakpoint[smp_processor_id()] = 1;
++}
++
++void kgdb_process_breakpoint(void)
++{
++      /*
++       * Handle a breakpoint queued from inside network driver code
++         * to avoid reentrancy issues
++       */
++      if (kgdb_need_breakpoint[smp_processor_id()]) {
++              kgdb_need_breakpoint[smp_processor_id()] = 0;
++              BREAKPOINT;
++      }
++}
++
+--- linux-2.6.0/arch/i386/kernel/ldt.c 2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/ldt.c  2003-12-28 23:26:36.000000000 -0800
+@@ -2,7 +2,7 @@
+  * linux/kernel/ldt.c
+  *
+  * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
+- * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
++ * Copyright (C) 1999, 2003 Ingo Molnar <mingo@redhat.com>
+  */
+ #include <linux/errno.h>
+@@ -18,6 +18,8 @@
+ #include <asm/system.h>
+ #include <asm/ldt.h>
+ #include <asm/desc.h>
++#include <linux/highmem.h>
++#include <asm/atomic_kmap.h>
+ #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
+ static void flush_ldt(void *null)
+@@ -29,34 +31,31 @@ static void flush_ldt(void *null)
+ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
+ {
+-      void *oldldt;
+-      void *newldt;
+-      int oldsize;
++      int oldsize, newsize, i;
+       if (mincount <= pc->size)
+               return 0;
++      /*
++       * LDT got larger - reallocate if necessary.
++       */
+       oldsize = pc->size;
+       mincount = (mincount+511)&(~511);
+-      if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
+-              newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
+-      else
+-              newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
+-
+-      if (!newldt)
+-              return -ENOMEM;
+-
+-      if (oldsize)
+-              memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
+-      oldldt = pc->ldt;
+-      memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
+-      pc->ldt = newldt;
+-      wmb();
++      newsize = mincount*LDT_ENTRY_SIZE;
++      for (i = 0; i < newsize; i += PAGE_SIZE) {
++              int nr = i/PAGE_SIZE;
++              BUG_ON(i >= 64*1024);
++              if (!pc->ldt_pages[nr]) {
++                      pc->ldt_pages[nr] = alloc_page(GFP_HIGHUSER);
++                      if (!pc->ldt_pages[nr])
++                              return -ENOMEM;
++                      clear_highpage(pc->ldt_pages[nr]);
++              }
++      }
+       pc->size = mincount;
+-      wmb();
+-
+       if (reload) {
+ #ifdef CONFIG_SMP
+               cpumask_t mask;
++
+               preempt_disable();
+               load_LDT(pc);
+               mask = cpumask_of_cpu(smp_processor_id());
+@@ -67,21 +66,20 @@ static int alloc_ldt(mm_context_t *pc, i
+               load_LDT(pc);
+ #endif
+       }
+-      if (oldsize) {
+-              if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
+-                      vfree(oldldt);
+-              else
+-                      kfree(oldldt);
+-      }
+       return 0;
+ }
+ static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
+ {
+-      int err = alloc_ldt(new, old->size, 0);
+-      if (err < 0)
++      int i, err, size = old->size, nr_pages = (size*LDT_ENTRY_SIZE + PAGE_SIZE-1)/PAGE_SIZE;
++
++      err = alloc_ldt(new, size, 0);
++      if (err < 0) {
++              new->size = 0;
+               return err;
+-      memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
++      }
++      for (i = 0; i < nr_pages; i++)
++              copy_user_highpage(new->ldt_pages[i], old->ldt_pages[i], 0);
+       return 0;
+ }
+@@ -96,6 +94,7 @@ int init_new_context(struct task_struct 
+       init_MUTEX(&mm->context.sem);
+       mm->context.size = 0;
++      memset(mm->context.ldt_pages, 0, sizeof(struct page *) * MAX_LDT_PAGES);
+       old_mm = current->mm;
+       if (old_mm && old_mm->context.size > 0) {
+               down(&old_mm->context.sem);
+@@ -107,23 +106,21 @@ int init_new_context(struct task_struct 
+ /*
+  * No need to lock the MM as we are the last user
++ * Do not touch the ldt register, we are already
++ * in the next thread.
+  */
+ void destroy_context(struct mm_struct *mm)
+ {
+-      if (mm->context.size) {
+-              if (mm == current->active_mm)
+-                      clear_LDT();
+-              if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
+-                      vfree(mm->context.ldt);
+-              else
+-                      kfree(mm->context.ldt);
+-              mm->context.size = 0;
+-      }
++      int i, nr_pages = (mm->context.size*LDT_ENTRY_SIZE + PAGE_SIZE-1) / PAGE_SIZE;
++
++      for (i = 0; i < nr_pages; i++)
++              __free_page(mm->context.ldt_pages[i]);
++      mm->context.size = 0;
+ }
+ static int read_ldt(void __user * ptr, unsigned long bytecount)
+ {
+-      int err;
++      int err, i;
+       unsigned long size;
+       struct mm_struct * mm = current->mm;
+@@ -138,8 +135,25 @@ static int read_ldt(void __user * ptr, u
+               size = bytecount;
+       err = 0;
+-      if (copy_to_user(ptr, mm->context.ldt, size))
+-              err = -EFAULT;
++      /*
++       * This is necessary just in case we got here straight from a
++       * context-switch where the ptes were set but no tlb flush
++       * was done yet. We rather avoid doing a TLB flush in the
++       * context-switch path and do it here instead.
++       */
++      __flush_tlb_global();
++
++      for (i = 0; i < size; i += PAGE_SIZE) {
++              int nr = i / PAGE_SIZE, bytes;
++              char *kaddr = kmap(mm->context.ldt_pages[nr]);
++
++              bytes = size - i;
++              if (bytes > PAGE_SIZE)
++                      bytes = PAGE_SIZE;
++              if (copy_to_user(ptr + i, kaddr, size - i))
++                      err = -EFAULT;
++              kunmap(mm->context.ldt_pages[nr]);
++      }
+       up(&mm->context.sem);
+       if (err < 0)
+               return err;
+@@ -158,7 +172,7 @@ static int read_default_ldt(void __user 
+       err = 0;
+       address = &default_ldt[0];
+-      size = 5*sizeof(struct desc_struct);
++      size = 5*LDT_ENTRY_SIZE;
+       if (size > bytecount)
+               size = bytecount;
+@@ -200,7 +214,15 @@ static int write_ldt(void __user * ptr, 
+                       goto out_unlock;
+       }
+-      lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
++      /*
++       * No rescheduling allowed from this point to the install.
++       *
++       * We do a TLB flush for the same reason as in the read_ldt() path.
++       */
++      preempt_disable();
++      __flush_tlb_global();
++      lp = (__u32 *) ((ldt_info.entry_number << 3) +
++                      (char *) __kmap_atomic_vaddr(KM_LDT_PAGE0));
+       /* Allow LDTs to be cleared by the user. */
+       if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
+@@ -221,6 +243,7 @@ install:
+       *lp     = entry_1;
+       *(lp+1) = entry_2;
+       error = 0;
++      preempt_enable();
+ out_unlock:
+       up(&mm->context.sem);
+@@ -248,3 +271,26 @@ asmlinkage int sys_modify_ldt(int func, 
+       }
+       return ret;
+ }
++
++/*
++ * load one particular LDT into the current CPU
++ */
++void load_LDT_nolock(mm_context_t *pc, int cpu)
++{
++      struct page **pages = pc->ldt_pages;
++      int count = pc->size;
++      int nr_pages, i;
++
++      if (likely(!count)) {
++              pages = &default_ldt_page;
++              count = 5;
++      }
++              nr_pages = (count*LDT_ENTRY_SIZE + PAGE_SIZE-1) / PAGE_SIZE;
++
++      for (i = 0; i < nr_pages; i++) {
++              __kunmap_atomic_type(KM_LDT_PAGE0 - i);
++              __kmap_atomic(pages[i], KM_LDT_PAGE0 - i);
++      }
++      set_ldt_desc(cpu, (void *)__kmap_atomic_vaddr(KM_LDT_PAGE0), count);
++      load_LDT_desc();
++}
+--- linux-2.6.0/arch/i386/kernel/Makefile      2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/Makefile       2003-12-28 23:26:36.000000000 -0800
+@@ -7,13 +7,14 @@ extra-y := head.o init_task.o vmlinux.ld
+ obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
+               ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
+               pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \
+-              doublefault.o
++              doublefault.o entry_trampoline.o
+ obj-y                         += cpu/
+ obj-y                         += timers/
+ obj-$(CONFIG_ACPI_BOOT)               += acpi/
+ obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o
+ obj-$(CONFIG_MCA)             += mca.o
++obj-$(CONFIG_KGDB)            += kgdb_stub.o
+ obj-$(CONFIG_X86_MSR)         += msr.o
+ obj-$(CONFIG_X86_CPUID)               += cpuid.o
+ obj-$(CONFIG_MICROCODE)               += microcode.o
+@@ -24,12 +25,13 @@ obj-$(CONFIG_X86_MPPARSE)  += mpparse.o
+ obj-$(CONFIG_X86_LOCAL_APIC)  += apic.o nmi.o
+ obj-$(CONFIG_X86_IO_APIC)     += io_apic.o
+ obj-$(CONFIG_X86_NUMAQ)               += numaq.o
+-obj-$(CONFIG_X86_SUMMIT)      += summit.o
++obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o
+ obj-$(CONFIG_EDD)                     += edd.o
+ obj-$(CONFIG_MODULES)         += module.o
+ obj-y                         += sysenter.o vsyscall.o
+ obj-$(CONFIG_ACPI_SRAT)       += srat.o
+ obj-$(CONFIG_HPET_TIMER)      += time_hpet.o
++obj-$(CONFIG_EFI)             += efi.o efi_stub.o
+ EXTRA_AFLAGS   := -traditional
+--- linux-2.6.0/arch/i386/kernel/mpparse.c     2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/i386/kernel/mpparse.c      2003-12-28 23:26:36.000000000 -0800
+@@ -668,7 +668,7 @@ void __init get_smp_config (void)
+                * Read the physical hardware table.  Anything here will
+                * override the defaults.
+                */
+-              if (!smp_read_mpc((void *)mpf->mpf_physptr)) {
++              if (!smp_read_mpc((void *)phys_to_virt(mpf->mpf_physptr))) {
+                       smp_found_config = 0;
+                       printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
+                       printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
+@@ -962,7 +962,8 @@ void __init mp_override_legacy_irq (
+        */
+       for (i = 0; i < mp_irq_entries; i++) {
+               if ((mp_irqs[i].mpc_dstapic == intsrc.mpc_dstapic) 
+-                      && (mp_irqs[i].mpc_srcbusirq == intsrc.mpc_srcbusirq)) {
++                      && (mp_irqs[i].mpc_srcbusirq == intsrc.mpc_srcbusirq)
++                      && (mp_irqs[i].mpc_irqtype == intsrc.mpc_irqtype)) {
+                       mp_irqs[i] = intsrc;
+                       found = 1;
+                       break;
+@@ -1081,8 +1082,14 @@ found:
+       ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
++      /*
++       * MPS INTI flags:
++       *  trigger: 0=default, 1=edge, 3=level
++       *  polarity: 0=default, 1=high, 3=low
++       * Per ACPI spec, default for SCI means level/low.
++       */
+       io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 
+-                              (flags.trigger >> 1) , (flags.polarity >> 1));
++              (flags.trigger == 1 ? 0 : 1), (flags.polarity == 1 ? 0 : 1));
+ }
+ #ifdef CONFIG_ACPI_PCI
+@@ -1129,8 +1136,11 @@ void __init mp_parse_prt (void)
+                       continue;
+               ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
+-              if (!ioapic && (irq < 16))
+-                      irq += 16;
++              if (es7000_plat) {
++                      if (!ioapic && (irq < 16))
++                              irq += 16;
++              }
++
+               /* 
+                * Avoid pin reprogramming.  PRTs typically include entries  
+                * with redundant pin->irq mappings (but unique PCI devices);
+@@ -1147,21 +1157,29 @@ void __init mp_parse_prt (void)
+               if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
+                       printk(KERN_DEBUG "Pin %d-%d already programmed\n",
+                               mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
+-                      entry->irq = irq;
++                      if (use_pci_vector() && !platform_legacy_irq(irq))
++                              irq = IO_APIC_VECTOR(irq);
++                      entry->irq = irq;
+                       continue;
+               }
+               mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
+-              if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq, edge_level, active_high_low))
+-                      entry->irq = irq;
+-
++              if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq, edge_level, active_high_low)) {
++                      if (use_pci_vector() && !platform_legacy_irq(irq))
++                              irq = IO_APIC_VECTOR(irq);
++                      entry->irq = irq;
++              }
+               printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n",
+                       entry->id.segment, entry->id.bus, 
+                       entry->id.device, ('A' + entry->pin), 
+                       mp_ioapic_routing[ioapic].apic_id, ioapic_pin, 
+                       entry->irq);
+       }
++
++      print_IO_APIC();
++
++      return;
+ }
+ #endif /*CONFIG_ACPI_PCI*/
+--- linux-2.6.0/arch/i386/kernel/nmi.c 2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/nmi.c  2003-12-28 23:21:06.000000000 -0800
+@@ -31,7 +31,16 @@
+ #include <asm/mpspec.h>
+ #include <asm/nmi.h>
++#ifdef CONFIG_KGDB
++#include <asm/kgdb.h>
++#ifdef CONFIG_SMP
++unsigned int nmi_watchdog = NMI_IO_APIC;
++#else
++unsigned int nmi_watchdog = NMI_LOCAL_APIC;
++#endif
++#else
+ unsigned int nmi_watchdog = NMI_NONE;
++#endif
+ static unsigned int nmi_hz = HZ;
+ unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */
+ extern void show_registers(struct pt_regs *regs);
+@@ -408,6 +417,9 @@ void touch_nmi_watchdog (void)
+       for (i = 0; i < NR_CPUS; i++)
+               alert_counter[i] = 0;
+ }
++#ifdef CONFIG_KGDB
++int tune_watchdog = 5*HZ;
++#endif
+ void nmi_watchdog_tick (struct pt_regs * regs)
+ {
+@@ -421,12 +433,24 @@ void nmi_watchdog_tick (struct pt_regs *
+       sum = irq_stat[cpu].apic_timer_irqs;
++#ifdef CONFIG_KGDB
++      if (! in_kgdb(regs) && last_irq_sums[cpu] == sum ) {
++
++#else
+       if (last_irq_sums[cpu] == sum) {
++#endif
+               /*
+                * Ayiee, looks like this CPU is stuck ...
+                * wait a few IRQs (5 seconds) before doing the oops ...
+                */
+               alert_counter[cpu]++;
++#ifdef CONFIG_KGDB
++                if (alert_counter[cpu] == tune_watchdog) {
++                        kgdb_handle_exception(2, SIGPWR, 0, regs);
++                        last_irq_sums[cpu] = sum;
++                        alert_counter[cpu] = 0;
++                }
++#endif
+               if (alert_counter[cpu] == 5*nmi_hz) {
+                       spin_lock(&nmi_print_lock);
+                       /*
+--- linux-2.6.0/arch/i386/kernel/process.c     2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/process.c      2003-12-28 23:26:36.000000000 -0800
+@@ -47,6 +47,7 @@
+ #include <asm/i387.h>
+ #include <asm/irq.h>
+ #include <asm/desc.h>
++#include <asm/atomic_kmap.h>
+ #ifdef CONFIG_MATH_EMULATION
+ #include <asm/math_emu.h>
+ #endif
+@@ -302,6 +303,9 @@ void flush_thread(void)
+       struct task_struct *tsk = current;
+       memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
++#ifdef CONFIG_X86_HIGH_ENTRY
++      clear_thread_flag(TIF_DB7);
++#endif
+       memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
+       /*
+        * Forget coprocessor state..
+@@ -315,9 +319,8 @@ void release_thread(struct task_struct *
+       if (dead_task->mm) {
+               // temporary debugging check
+               if (dead_task->mm->context.size) {
+-                      printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
++                      printk("WARNING: dead process %8s still has LDT? <%d>\n",
+                                       dead_task->comm,
+-                                      dead_task->mm->context.ldt,
+                                       dead_task->mm->context.size);
+                       BUG();
+               }
+@@ -352,7 +355,17 @@ int copy_thread(int nr, unsigned long cl
+       p->thread.esp = (unsigned long) childregs;
+       p->thread.esp0 = (unsigned long) (childregs+1);
++      /*
++       * get the two stack pages, for the virtual stack.
++       *
++       * IMPORTANT: this code relies on the fact that the task
++       * structure is an 8K aligned piece of physical memory.
++       */
++      p->thread.stack_page0 = virt_to_page((unsigned long)p->thread_info);
++      p->thread.stack_page1 = virt_to_page((unsigned long)p->thread_info + PAGE_SIZE);
++
+       p->thread.eip = (unsigned long) ret_from_fork;
++      p->thread_info->real_stack = p->thread_info;
+       savesegment(fs,p->thread.fs);
+       savesegment(gs,p->thread.gs);
+@@ -504,10 +517,41 @@ struct task_struct * __switch_to(struct 
+       __unlazy_fpu(prev_p);
++#ifdef CONFIG_X86_HIGH_ENTRY
++      /*
++       * Set the ptes of the virtual stack. (NOTE: a one-page TLB flush is
++       * needed because otherwise NMIs could interrupt the
++       * user-return code with a virtual stack and stale TLBs.)
++       */
++      __kunmap_atomic_type(KM_VSTACK0);
++      __kunmap_atomic_type(KM_VSTACK1);
++      __kmap_atomic(next->stack_page0, KM_VSTACK0);
++      __kmap_atomic(next->stack_page1, KM_VSTACK1);
++
++      /*
++       * NOTE: here we rely on the task being the stack as well
++       */
++      next_p->thread_info->virtual_stack =
++                      (void *)__kmap_atomic_vaddr(KM_VSTACK0);
++
++#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
++      /*
++       * If next was preempted on entry from userspace to kernel,
++       * and now it's on a different cpu, we need to adjust %esp.
++       * This assumes that entry.S does not copy %esp while on the
++       * virtual stack (with interrupts enabled): which is so,
++       * except within __SWITCH_KERNELSPACE itself.
++       */
++      if (unlikely(next->esp >= TASK_SIZE)) {
++              next->esp &= THREAD_SIZE - 1;
++              next->esp |= (unsigned long) next_p->thread_info->virtual_stack;
++      }
++#endif
++#endif
+       /*
+        * Reload esp0, LDT and the page table pointer:
+        */
+-      load_esp0(tss, next->esp0);
++      load_virtual_esp0(tss, next_p);
+       /*
+        * Load the per-thread Thread-Local Storage descriptor.
+--- linux-2.6.0/arch/i386/kernel/reboot.c      2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/reboot.c       2003-12-28 23:26:36.000000000 -0800
+@@ -8,6 +8,7 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/mc146818rtc.h>
++#include <linux/efi.h>
+ #include <asm/uaccess.h>
+ #include <asm/apic.h>
+ #include "mach_reboot.h"
+@@ -154,12 +155,11 @@ void machine_real_restart(unsigned char 
+       CMOS_WRITE(0x00, 0x8f);
+       spin_unlock_irqrestore(&rtc_lock, flags);
+-      /* Remap the kernel at virtual address zero, as well as offset zero
+-         from the kernel segment.  This assumes the kernel segment starts at
+-         virtual address PAGE_OFFSET. */
+-
+-      memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
+-              sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
++      /*
++       * Remap the first 16 MB of RAM (which includes the kernel image)
++       * at virtual address zero:
++       */
++      setup_identity_mappings(swapper_pg_dir, 0, 16*1024*1024);
+       /*
+        * Use `swapper_pg_dir' as our page directory.
+@@ -263,7 +263,12 @@ void machine_restart(char * __unused)
+       disable_IO_APIC();
+ #endif
+-      if(!reboot_thru_bios) {
++      if (!reboot_thru_bios) {
++              if (efi_enabled) {
++                      efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, 0);
++                      __asm__ __volatile__("lidt %0": :"m" (no_idt));
++                      __asm__ __volatile__("int3");
++              }
+               /* rebooting needs to touch the page at absolute addr 0 */
+               *((unsigned short *)__va(0x472)) = reboot_mode;
+               for (;;) {
+@@ -273,6 +278,8 @@ void machine_restart(char * __unused)
+                       __asm__ __volatile__("int3");
+               }
+       }
++      if (efi_enabled)
++              efi.reset_system(EFI_RESET_WARM, EFI_SUCCESS, 0, 0);
+       machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
+ }
+@@ -287,6 +294,8 @@ EXPORT_SYMBOL(machine_halt);
+ void machine_power_off(void)
+ {
++      if (efi_enabled)
++              efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, 0);
+       if (pm_power_off)
+               pm_power_off();
+ }
+--- linux-2.6.0/arch/i386/kernel/setup.c       2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/setup.c        2003-12-28 23:21:45.000000000 -0800
+@@ -36,6 +36,8 @@
+ #include <linux/root_dev.h>
+ #include <linux/highmem.h>
+ #include <linux/module.h>
++#include <linux/efi.h>
++#include <linux/init.h>
+ #include <video/edid.h>
+ #include <asm/e820.h>
+ #include <asm/mpspec.h>
+@@ -56,6 +58,10 @@ static inline char * __init machine_spec
+  * Machine setup..
+  */
++#ifdef CONFIG_EFI
++int efi_enabled = 0;
++#endif
++
+ /* cpu data as detected by the assembly code in head.S */
+ struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
+ /* common cpu data for all cpus */
+@@ -72,13 +78,10 @@ EXPORT_SYMBOL_GPL(mmu_cr4_features);
+ EXPORT_SYMBOL(acpi_disabled);
+ #ifdef        CONFIG_ACPI_BOOT
+-      int acpi_irq __initdata = 1;    /* enable IRQ */
+-      int acpi_ht __initdata = 1;     /* enable HT */
++extern int __initdata acpi_ht;
++int __initdata acpi_force = 0;
+ #endif
+-int acpi_force __initdata = 0;
+-
+-
+ int MCA_bus;
+ /* for MCA, but anyone else can use it if they want */
+ unsigned int machine_id;
+@@ -144,6 +147,20 @@ static void __init limit_regions(unsigne
+       unsigned long long current_addr = 0;
+       int i;
++      if (efi_enabled) {
++              for (i = 0; i < memmap.nr_map; i++) {
++                      current_addr = memmap.map[i].phys_addr +
++                                     (memmap.map[i].num_pages << 12);
++                      if (memmap.map[i].type == EFI_CONVENTIONAL_MEMORY) {
++                              if (current_addr >= size) {
++                                      memmap.map[i].num_pages -=
++                                              (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT);
++                                      memmap.nr_map = i + 1;
++                                      return;
++                              }
++                      }
++              }
++      }
+       for (i = 0; i < e820.nr_map; i++) {
+               if (e820.map[i].type == E820_RAM) {
+                       current_addr = e820.map[i].addr + e820.map[i].size;
+@@ -159,17 +176,21 @@ static void __init limit_regions(unsigne
+ static void __init add_memory_region(unsigned long long start,
+                                   unsigned long long size, int type)
+ {
+-      int x = e820.nr_map;
++      int x;
+-      if (x == E820MAX) {
+-          printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
+-          return;
+-      }
++      if (!efi_enabled) {
++                      x = e820.nr_map;
++
++              if (x == E820MAX) {
++                  printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
++                  return;
++              }
+-      e820.map[x].addr = start;
+-      e820.map[x].size = size;
+-      e820.map[x].type = type;
+-      e820.nr_map++;
++              e820.map[x].addr = start;
++              e820.map[x].size = size;
++              e820.map[x].type = type;
++              e820.nr_map++;
++      }
+ } /* add_memory_region */
+ #define E820_DEBUG    1
+@@ -446,7 +467,6 @@ static inline void copy_edd(void)
+ static void __init setup_memory_region(void)
+ {
+       char *who = machine_specific_memory_setup();
+-
+       printk(KERN_INFO "BIOS-provided physical RAM map:\n");
+       print_memory_map(who);
+ } /* setup_memory_region */
+@@ -550,7 +570,7 @@ static void __init parse_cmdline_early (
+               /* "pci=noacpi" disables ACPI interrupt routing */
+               else if (!memcmp(from, "pci=noacpi", 10)) {
+-                      acpi_irq = 0;
++                      acpi_noirq_set();
+               }
+ #ifdef CONFIG_X86_LOCAL_APIC
+@@ -584,6 +604,23 @@ static void __init parse_cmdline_early (
+ }
+ /*
++ * Callback for efi_memory_walk.
++ */
++static int __init
++efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
++{
++      unsigned long *max_pfn = arg, pfn;
++
++      if (start < end) {
++              pfn = PFN_UP(end -1);
++              if (pfn > *max_pfn)
++                      *max_pfn = pfn;
++      }
++      return 0;
++}
++
++
++/*
+  * Find the highest page frame number we have available
+  */
+ void __init find_max_pfn(void)
+@@ -591,6 +628,11 @@ void __init find_max_pfn(void)
+       int i;
+       max_pfn = 0;
++      if (efi_enabled) {
++              efi_memmap_walk(efi_find_max_pfn, &max_pfn);
++              return;
++      }
++
+       for (i = 0; i < e820.nr_map; i++) {
+               unsigned long start, end;
+               /* RAM? */
+@@ -665,6 +707,25 @@ unsigned long __init find_max_low_pfn(vo
+ }
+ #ifndef CONFIG_DISCONTIGMEM
++
++/*
++ * Free all available memory for boot time allocation.  Used
++ * as a callback function by efi_memory_walk()
++ */
++
++static int __init
++free_available_memory(unsigned long start, unsigned long end, void *arg)
++{
++      /* check max_low_pfn */
++      if (start >= ((max_low_pfn + 1) << PAGE_SHIFT))
++              return 0;
++      if (end >= ((max_low_pfn + 1) << PAGE_SHIFT))
++              end = (max_low_pfn + 1) << PAGE_SHIFT;
++      if (start < end)
++              free_bootmem(start, end - start);
++
++      return 0;
++}
+ /*
+  * Register fully available low RAM pages with the bootmem allocator.
+  */
+@@ -672,6 +733,10 @@ static void __init register_bootmem_low_
+ {
+       int i;
++      if (efi_enabled) {
++              efi_memmap_walk(free_available_memory, NULL);
++              return;
++      }
+       for (i = 0; i < e820.nr_map; i++) {
+               unsigned long curr_pfn, last_pfn, size;
+               /*
+@@ -799,9 +864,9 @@ extern unsigned long setup_memory(void);
+  * Request address space for all standard RAM and ROM resources
+  * and also for regions reported as reserved by the e820.
+  */
+-static void __init register_memory(unsigned long max_low_pfn)
++static void __init
++legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
+ {
+-      unsigned long low_mem_size;
+       int i;
+       probe_roms();
+@@ -826,11 +891,26 @@ static void __init register_memory(unsig
+                        *  so we try it repeatedly and let the resource manager
+                        *  test it.
+                        */
+-                      request_resource(res, &code_resource);
+-                      request_resource(res, &data_resource);
++                      request_resource(res, code_resource);
++                      request_resource(res, data_resource);
+               }
+       }
++}
++
++/*
++ * Request address space for all standard resources
++ */
++static void __init register_memory(unsigned long max_low_pfn)
++{
++      unsigned long low_mem_size;
++      int i;
++
++      if (efi_enabled)
++              efi_initialize_iomem_resources(&code_resource, &data_resource);
++      else
++              legacy_init_iomem_resources(&code_resource, &data_resource);
++       /* EFI systems may still have VGA */
+       request_graphics_resource();
+       /* request I/O space for devices used on all i[345]86 PCs */
+@@ -950,6 +1030,13 @@ static int __init noreplacement_setup(ch
+ __setup("noreplacement", noreplacement_setup); 
++/*
++ * Determine if we were loaded by an EFI loader.  If so, then we have also been
++ * passed the efi memmap, systab, etc., so we should use these data structures
++ * for initialization.  Note, the efi init code path is determined by the
++ * global efi_enabled. This allows the same kernel image to be used on existing
++ * systems (with a traditional BIOS) as well as on EFI systems.
++ */
+ void __init setup_arch(char **cmdline_p)
+ {
+       unsigned long max_low_pfn;
+@@ -958,6 +1045,18 @@ void __init setup_arch(char **cmdline_p)
+       pre_setup_arch_hook();
+       early_cpu_init();
++      /*
++       * FIXME: This isn't an official loader_type right
++       * now but does currently work with elilo.
++       * If we were configured as an EFI kernel, check to make
++       * sure that we were loaded correctly from elilo and that
++       * the system table is valid.  If not, then initialize normally.
++       */
++#ifdef CONFIG_EFI
++      if ((LOADER_TYPE == 0x50) && EFI_SYSTAB)
++              efi_enabled = 1;
++#endif
++
+       ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+       drive_info = DRIVE_INFO;
+       screen_info = SCREEN_INFO;
+@@ -979,7 +1078,11 @@ void __init setup_arch(char **cmdline_p)
+       rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
+ #endif
+       ARCH_SETUP
+-      setup_memory_region();
++      if (efi_enabled)
++              efi_init();
++      else
++              setup_memory_region();
++
+       copy_edd();
+       if (!MOUNT_ROOT_RDONLY)
+@@ -1013,6 +1116,8 @@ void __init setup_arch(char **cmdline_p)
+ #ifdef CONFIG_X86_GENERICARCH
+       generic_apic_probe(*cmdline_p);
+ #endif        
++      if (efi_enabled)
++              efi_map_memmap();
+       /*
+        * Parse the ACPI tables for possible boot-time SMP configuration.
+@@ -1028,7 +1133,8 @@ void __init setup_arch(char **cmdline_p)
+ #ifdef CONFIG_VT
+ #if defined(CONFIG_VGA_CONSOLE)
+-      conswitchp = &vga_con;
++      if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
++              conswitchp = &vga_con;
+ #elif defined(CONFIG_DUMMY_CONSOLE)
+       conswitchp = &dummy_con;
+ #endif
+--- linux-2.6.0/arch/i386/kernel/signal.c      2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/i386/kernel/signal.c       2003-12-28 23:26:36.000000000 -0800
+@@ -128,28 +128,29 @@ sys_sigaltstack(const stack_t __user *us
+  */
+ static int
+-restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax)
++restore_sigcontext(struct pt_regs *regs,
++              struct sigcontext __user *__sc, int *peax)
+ {
+-      unsigned int err = 0;
++      struct sigcontext scratch; /* 88 bytes of scratch area */
+       /* Always make any pending restarted system calls return -EINTR */
+       current_thread_info()->restart_block.fn = do_no_restart_syscall;
+-#define COPY(x)               err |= __get_user(regs->x, &sc->x)
++      if (copy_from_user(&scratch, __sc, sizeof(scratch)))
++              return -EFAULT;
++
++#define COPY(x)               regs->x = scratch.x
+ #define COPY_SEG(seg)                                                 \
+-      { unsigned short tmp;                                           \
+-        err |= __get_user(tmp, &sc->seg);                             \
++      { unsigned short tmp = scratch.seg;                             \
+         regs->x##seg = tmp; }
+ #define COPY_SEG_STRICT(seg)                                          \
+-      { unsigned short tmp;                                           \
+-        err |= __get_user(tmp, &sc->seg);                             \
++      { unsigned short tmp = scratch.seg;                             \
+         regs->x##seg = tmp|3; }
+ #define GET_SEG(seg)                                                  \
+-      { unsigned short tmp;                                           \
+-        err |= __get_user(tmp, &sc->seg);                             \
++      { unsigned short tmp = scratch.seg;                             \
+         loadsegment(seg,tmp); }
+       GET_SEG(gs);
+@@ -168,27 +169,23 @@ restore_sigcontext(struct pt_regs *regs,
+       COPY_SEG_STRICT(ss);
+       
+       {
+-              unsigned int tmpflags;
+-              err |= __get_user(tmpflags, &sc->eflags);
++              unsigned int tmpflags = scratch.eflags;
+               regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
+               regs->orig_eax = -1;            /* disable syscall checks */
+       }
+       {
+-              struct _fpstate __user * buf;
+-              err |= __get_user(buf, &sc->fpstate);
++              struct _fpstate * buf = scratch.fpstate;
+               if (buf) {
+                       if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
+-                              goto badframe;
+-                      err |= restore_i387(buf);
++                              return -EFAULT;
++                      if (restore_i387(buf))
++                              return -EFAULT;
+               }
+       }
+-      err |= __get_user(*peax, &sc->eax);
+-      return err;
+-
+-badframe:
+-      return 1;
++      *peax = scratch.eax;
++      return 0;
+ }
+ asmlinkage int sys_sigreturn(unsigned long __unused)
+@@ -266,46 +263,47 @@ badframe:
+  */
+ static int
+-setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
++setup_sigcontext(struct sigcontext __user *__sc, struct _fpstate __user *fpstate,
+                struct pt_regs *regs, unsigned long mask)
+ {
+-      int tmp, err = 0;
++      struct sigcontext sc; /* 88 bytes of scratch area */
++      int tmp;
+       tmp = 0;
+       __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
+-      err |= __put_user(tmp, (unsigned int *)&sc->gs);
++      *(unsigned int *)&sc.gs = tmp;
+       __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
+-      err |= __put_user(tmp, (unsigned int *)&sc->fs);
+-
+-      err |= __put_user(regs->xes, (unsigned int *)&sc->es);
+-      err |= __put_user(regs->xds, (unsigned int *)&sc->ds);
+-      err |= __put_user(regs->edi, &sc->edi);
+-      err |= __put_user(regs->esi, &sc->esi);
+-      err |= __put_user(regs->ebp, &sc->ebp);
+-      err |= __put_user(regs->esp, &sc->esp);
+-      err |= __put_user(regs->ebx, &sc->ebx);
+-      err |= __put_user(regs->edx, &sc->edx);
+-      err |= __put_user(regs->ecx, &sc->ecx);
+-      err |= __put_user(regs->eax, &sc->eax);
+-      err |= __put_user(current->thread.trap_no, &sc->trapno);
+-      err |= __put_user(current->thread.error_code, &sc->err);
+-      err |= __put_user(regs->eip, &sc->eip);
+-      err |= __put_user(regs->xcs, (unsigned int *)&sc->cs);
+-      err |= __put_user(regs->eflags, &sc->eflags);
+-      err |= __put_user(regs->esp, &sc->esp_at_signal);
+-      err |= __put_user(regs->xss, (unsigned int *)&sc->ss);
++      *(unsigned int *)&sc.fs = tmp;
++      *(unsigned int *)&sc.es = regs->xes;
++      *(unsigned int *)&sc.ds = regs->xds;
++      sc.edi = regs->edi;
++      sc.esi = regs->esi;
++      sc.ebp = regs->ebp;
++      sc.esp = regs->esp;
++      sc.ebx = regs->ebx;
++      sc.edx = regs->edx;
++      sc.ecx = regs->ecx;
++      sc.eax = regs->eax;
++      sc.trapno = current->thread.trap_no;
++      sc.err = current->thread.error_code;
++      sc.eip = regs->eip;
++      *(unsigned int *)&sc.cs = regs->xcs;
++      sc.eflags = regs->eflags;
++      sc.esp_at_signal = regs->esp;
++      *(unsigned int *)&sc.ss = regs->xss;
+       tmp = save_i387(fpstate);
+       if (tmp < 0)
+-        err = 1;
+-      else
+-        err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
++              return 1;
++      sc.fpstate = tmp ? fpstate : NULL;
+       /* non-iBCS2 extensions.. */
+-      err |= __put_user(mask, &sc->oldmask);
+-      err |= __put_user(current->thread.cr2, &sc->cr2);
++      sc.oldmask = mask;
++      sc.cr2 = current->thread.cr2;
+-      return err;
++      if (copy_to_user(__sc, &sc, sizeof(sc)))
++              return 1;
++      return 0;
+ }
+ /*
+@@ -443,7 +441,7 @@ static void setup_rt_frame(int sig, stru
+       /* Create the ucontext.  */
+       err |= __put_user(0, &frame->uc.uc_flags);
+       err |= __put_user(0, &frame->uc.uc_link);
+-      err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
++      err |= __put_user(current->sas_ss_sp, (unsigned long *)&frame->uc.uc_stack.ss_sp);
+       err |= __put_user(sas_ss_flags(regs->esp),
+                         &frame->uc.uc_stack.ss_flags);
+       err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+--- linux-2.6.0/arch/i386/kernel/smp.c 2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/smp.c  2003-12-28 23:26:36.000000000 -0800
+@@ -327,10 +327,12 @@ asmlinkage void smp_invalidate_interrupt
+                
+       if (flush_mm == cpu_tlbstate[cpu].active_mm) {
+               if (cpu_tlbstate[cpu].state == TLBSTATE_OK) {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+                       if (flush_va == FLUSH_ALL)
+                               local_flush_tlb();
+                       else
+                               __flush_tlb_one(flush_va);
++#endif
+               } else
+                       leave_mm(cpu);
+       }
+@@ -396,21 +398,6 @@ static void flush_tlb_others(cpumask_t c
+       spin_unlock(&tlbstate_lock);
+ }
+       
+-void flush_tlb_current_task(void)
+-{
+-      struct mm_struct *mm = current->mm;
+-      cpumask_t cpu_mask;
+-
+-      preempt_disable();
+-      cpu_mask = mm->cpu_vm_mask;
+-      cpu_clear(smp_processor_id(), cpu_mask);
+-
+-      local_flush_tlb();
+-      if (!cpus_empty(cpu_mask))
+-              flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+-      preempt_enable();
+-}
+-
+ void flush_tlb_mm (struct mm_struct * mm)
+ {
+       cpumask_t cpu_mask;
+@@ -442,7 +429,10 @@ void flush_tlb_page(struct vm_area_struc
+       if (current->active_mm == mm) {
+               if(current->mm)
+-                      __flush_tlb_one(va);
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
++                      __flush_tlb_one(va)
++#endif
++                              ;
+                else
+                       leave_mm(smp_processor_id());
+       }
+@@ -466,7 +456,17 @@ void flush_tlb_all(void)
+ {
+       on_each_cpu(do_flush_tlb_all, 0, 1, 1);
+ }
+-
++#ifdef CONFIG_KGDB
++/*
++ * By using the NMI code instead of a vector we just sneak thru the
++ * word generator coming out with just what we want.  AND it does
++ * not matter if clustered_apic_mode is set or not.
++ */
++void smp_send_nmi_allbutself(void)
++{
++      send_IPI_allbutself(APIC_DM_NMI);
++}
++#endif
+ /*
+  * this function sends a 'reschedule' IPI to another CPU.
+  * it goes straight through and wastes no time serializing
+--- linux-2.6.0/arch/i386/kernel/summit.c      2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/i386/kernel/summit.c       2003-12-28 23:22:43.000000000 -0800
+@@ -29,86 +29,85 @@
+ #include <linux/mm.h>
+ #include <linux/init.h>
+ #include <asm/io.h>
+-#include <mach_mpparse.h>
++#include <asm/mach-summit/mach_mpparse.h>
+-#ifdef CONFIG_NUMA
+-static void __init setup_pci_node_map_for_wpeg(int wpeg_num, struct rio_table_hdr *rth, 
+-              struct scal_detail **scal_nodes, struct rio_detail **rio_nodes){
+-      int twst_num = 0, node = 0, first_bus = 0;
+-      int i, bus, num_busses;
+-
+-      for(i = 0; i < rth->num_rio_dev; i++){
+-              if (rio_nodes[i]->node_id == rio_nodes[wpeg_num]->owner_id){
+-                      twst_num = rio_nodes[i]->owner_id;
++static struct rio_table_hdr *rio_table_hdr __initdata;
++static struct scal_detail   *scal_devs[MAX_NUMNODES] __initdata;
++static struct rio_detail    *rio_devs[MAX_NUMNODES*4] __initdata;
++
++static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
++{
++      int twister = 0, node = 0;
++      int i, bus, num_buses;
++
++      for(i = 0; i < rio_table_hdr->num_rio_dev; i++){
++              if (rio_devs[i]->node_id == rio_devs[wpeg_num]->owner_id){
++                      twister = rio_devs[i]->owner_id;
+                       break;
+               }
+       }
+-      if (i == rth->num_rio_dev){
+-              printk("%s: Couldn't find owner Cyclone for Winnipeg!\n", __FUNCTION__);
+-              return;
++      if (i == rio_table_hdr->num_rio_dev){
++              printk(KERN_ERR "%s: Couldn't find owner Cyclone for Winnipeg!\n", __FUNCTION__);
++              return last_bus;
+       }
+-      for(i = 0; i < rth->num_scal_dev; i++){
+-              if (scal_nodes[i]->node_id == twst_num){
+-                      node = scal_nodes[i]->node_id;
++      for(i = 0; i < rio_table_hdr->num_scal_dev; i++){
++              if (scal_devs[i]->node_id == twister){
++                      node = scal_devs[i]->node_id;
+                       break;
+               }
+       }
+-      if (i == rth->num_scal_dev){
+-              printk("%s: Couldn't find owner Twister for Cyclone!\n", __FUNCTION__);
+-              return;
++      if (i == rio_table_hdr->num_scal_dev){
++              printk(KERN_ERR "%s: Couldn't find owner Twister for Cyclone!\n", __FUNCTION__);
++              return last_bus;
+       }
+-      switch (rio_nodes[wpeg_num]->type){
++      switch (rio_devs[wpeg_num]->type){
+       case CompatWPEG:
+-              /* The Compatability Winnipeg controls the legacy busses
+-                 (busses 0 & 1), the 66MHz PCI bus [2 slots] (bus 2), 
+-                 and the "extra" busses in case a PCI-PCI bridge card is 
+-                 used in either slot (busses 3 & 4): total 5 busses. */
+-              num_busses = 5;
+-              /* The BIOS numbers the busses starting at 1, and in a 
+-                 slightly wierd manner.  You'll have to trust that 
+-                 the math used below to determine the number of the 
+-                 first bus works. */
+-              first_bus = (rio_nodes[wpeg_num]->first_slot - 1) * 2;
++              /* The Compatability Winnipeg controls the 2 legacy buses,
++               * the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case
++               * a PCI-PCI bridge card is used in either slot: total 5 buses.
++               */
++              num_buses = 5;
+               break;
+       case AltWPEG:
+-              /* The Alternate/Secondary Winnipeg controls the 1st 133MHz 
+-                 bus [1 slot] & its "extra" bus (busses 0 & 1), the 2nd 
+-                 133MHz bus [1 slot] & its "extra" bus (busses 2 & 3), the 
+-                 100MHz bus [2 slots] (bus 4), and the "extra" busses for 
+-                 the 2 100MHz slots (busses 5 & 6): total 7 busses. */
+-              num_busses = 7;
+-              first_bus = (rio_nodes[wpeg_num]->first_slot * 2) - 1;
++              /* The Alternate Winnipeg controls the 2 133MHz buses [1 slot
++               * each], their 2 "extra" buses, the 100MHz bus [2 slots] and
++               * the "extra" buses for each of those slots: total 7 buses.
++               */
++              num_buses = 7;
+               break;
+       case LookOutAWPEG:
+       case LookOutBWPEG:
+-              printk("%s: LookOut Winnipegs not supported yet!\n", __FUNCTION__);
+-              return;
++              /* A Lookout Winnipeg controls 3 100MHz buses [2 slots each]
++               * & the "extra" buses for each of those slots: total 9 buses.
++               */
++              num_buses = 9;
++              break;
+       default:
+-              printk("%s: Unsupported Winnipeg type!\n", __FUNCTION__);
+-              return;
++              printk(KERN_INFO "%s: Unsupported Winnipeg type!\n", __FUNCTION__);
++              return last_bus;
+       }
+-      for(bus = first_bus; bus < first_bus + num_busses; bus++)
++      for(bus = last_bus; bus < last_bus + num_buses; bus++)
+               mp_bus_id_to_node[bus] = node;
++      return bus;
+ }
+-static int __init build_detail_arrays(struct rio_table_hdr *rth,
+-              struct scal_detail **sd, struct rio_detail **rd){
++static int __init build_detail_arrays(void)
++{
+       unsigned long ptr;
+       int i, scal_detail_size, rio_detail_size;
+-      if ((rth->num_scal_dev > MAX_NUMNODES) ||
+-          (rth->num_rio_dev > MAX_NUMNODES * 2)){
+-              printk("%s: MAX_NUMNODES too low!  Defined as %d, but system has %d nodes.\n", __FUNCTION__, MAX_NUMNODES, rth->num_scal_dev);
+-              return 1;
++      if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){
++              printk(KERN_WARNING "%s: MAX_NUMNODES too low!  Defined as %d, but system has %d nodes.\n", __FUNCTION__, MAX_NUMNODES, rio_table_hdr->num_scal_dev);
++              return 0;
+       }
+-      switch (rth->version){
++      switch (rio_table_hdr->version){
+       default:
+-              printk("%s: Bad Rio Grande Table Version: %d\n", __FUNCTION__, rth->version);
+-              return 1;
++              printk(KERN_WARNING "%s: Invalid Rio Grande Table Version: %d\n", __FUNCTION__, rio_table_hdr->version);
++              return 0;
+       case 2:
+               scal_detail_size = 11;
+               rio_detail_size = 13;
+@@ -119,32 +118,27 @@ static int __init build_detail_arrays(st
+               break;
+       }
+-      ptr = (unsigned long)rth + 3;
+-      for(i = 0; i < rth->num_scal_dev; i++)
+-              sd[i] = (struct scal_detail *)(ptr + (scal_detail_size * i));
+-
+-      ptr += scal_detail_size * rth->num_scal_dev;
+-      for(i = 0; i < rth->num_rio_dev; i++)
+-              rd[i] = (struct rio_detail *)(ptr + (rio_detail_size * i));
++      ptr = (unsigned long)rio_table_hdr + 3;
++      for(i = 0; i < rio_table_hdr->num_scal_dev; i++, ptr += scal_detail_size)
++              scal_devs[i] = (struct scal_detail *)ptr;
+-      return 0;
++      for(i = 0; i < rio_table_hdr->num_rio_dev; i++, ptr += rio_detail_size)
++              rio_devs[i] = (struct rio_detail *)ptr;
++
++      return 1;
+ }
+ void __init setup_summit(void)
+ {
+-      struct rio_table_hdr    *rio_table_hdr = NULL;
+-      struct scal_detail      *scal_devs[MAX_NUMNODES];
+-      struct rio_detail       *rio_devs[MAX_NUMNODES*2];
+       unsigned long           ptr;
+       unsigned short          offset;
+-      int                     i;
+-
+-      memset(mp_bus_id_to_node, -1, sizeof(mp_bus_id_to_node));
++      int                     i, next_wpeg, next_bus = 0;
+       /* The pointer to the EBDA is stored in the word @ phys 0x40E(40:0E) */
+       ptr = *(unsigned short *)phys_to_virt(0x40Eul);
+       ptr = (unsigned long)phys_to_virt(ptr << 4);
++      rio_table_hdr = NULL;
+       offset = 0x180;
+       while (offset){
+               /* The block id is stored in the 2nd word */
+@@ -157,16 +151,30 @@ void __init setup_summit(void)
+               offset = *((unsigned short *)(ptr + offset));
+       }
+       if (!rio_table_hdr){
+-              printk("%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __FUNCTION__);
++              printk(KERN_ERR "%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __FUNCTION__);
+               return;
+       }
+-      if (build_detail_arrays(rio_table_hdr, scal_devs, rio_devs))
++      if (!build_detail_arrays())
+               return;
+-      for(i = 0; i < rio_table_hdr->num_rio_dev; i++)
+-              if (is_WPEG(rio_devs[i]->type))
+-                      /* It's a Winnipeg, it's got PCI Busses */
+-                      setup_pci_node_map_for_wpeg(i, rio_table_hdr, scal_devs, rio_devs);
++      /* The first Winnipeg we're looking for has an index of 0 */
++      next_wpeg = 0;
++      do {
++              for(i = 0; i < rio_table_hdr->num_rio_dev; i++){
++                      if (is_WPEG(rio_devs[i]) && rio_devs[i]->WP_index == next_wpeg){
++                              /* It's the Winnipeg we're looking for! */
++                              next_bus = setup_pci_node_map_for_wpeg(i, next_bus);
++                              next_wpeg++;
++                              break;
++                      }
++              }
++              /*
++               * If we go through all Rio devices and don't find one with
++               * the next index, it means we've found all the Winnipegs,
++               * and thus all the PCI buses.
++               */
++              if (i == rio_table_hdr->num_rio_dev)
++                      next_wpeg = 0;
++      } while (next_wpeg != 0);
+ }
+-#endif /* CONFIG_NUMA */
+--- linux-2.6.0/arch/i386/kernel/sysenter.c    2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/sysenter.c     2003-12-28 23:26:36.000000000 -0800
+@@ -18,13 +18,18 @@
+ #include <asm/msr.h>
+ #include <asm/pgtable.h>
+ #include <asm/unistd.h>
++#include <linux/highmem.h>
+ extern asmlinkage void sysenter_entry(void);
+ void enable_sep_cpu(void *info)
+ {
+       int cpu = get_cpu();
++#ifdef CONFIG_X86_HIGH_ENTRY
++      struct tss_struct *tss = (struct tss_struct *) __fix_to_virt(FIX_TSS_0) + cpu;
++#else
+       struct tss_struct *tss = init_tss + cpu;
++#endif
+       tss->ss1 = __KERNEL_CS;
+       tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
+--- linux-2.6.0/arch/i386/kernel/time.c        2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/i386/kernel/time.c 2003-12-28 23:22:19.000000000 -0800
+@@ -44,6 +44,7 @@
+ #include <linux/module.h>
+ #include <linux/sysdev.h>
+ #include <linux/bcd.h>
++#include <linux/efi.h>
+ #include <asm/io.h>
+ #include <asm/smp.h>
+@@ -94,7 +95,7 @@ void do_gettimeofday(struct timeval *tv)
+ {
+       unsigned long seq;
+       unsigned long usec, sec;
+-      unsigned long max_ntp_tick = tick_usec - tickadj;
++      unsigned long max_ntp_tick;
+       do {
+               unsigned long lost;
+@@ -110,13 +111,14 @@ void do_gettimeofday(struct timeval *tv)
+                * Better to lose some accuracy than have time go backwards..
+                */
+               if (unlikely(time_adjust < 0)) {
++                      max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj;
+                       usec = min(usec, max_ntp_tick);
+                       if (lost)
+                               usec += lost * max_ntp_tick;
+               }
+               else if (unlikely(lost))
+-                      usec += lost * tick_usec;
++                      usec += lost * (USEC_PER_SEC / HZ);
+               sec = xtime.tv_sec;
+               usec += (xtime.tv_nsec / 1000);
+@@ -174,7 +176,10 @@ static int set_rtc_mmss(unsigned long no
+       /* gets recalled with irq locally disabled */
+       spin_lock(&rtc_lock);
+-      retval = mach_set_rtc_mmss(nowtime);
++      if (efi_enabled)
++              retval = efi_set_rtc_mmss(nowtime);
++      else
++              retval = mach_set_rtc_mmss(nowtime);
+       spin_unlock(&rtc_lock);
+       return retval;
+@@ -232,7 +237,13 @@ static inline void do_timer_interrupt(in
+                       >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 &&
+           (xtime.tv_nsec / 1000)
+                       <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2) {
+-              if (set_rtc_mmss(xtime.tv_sec) == 0)
++              /* horrible...FIXME */
++              if (efi_enabled) {
++                      if (efi_set_rtc_mmss(xtime.tv_sec) == 0)
++                              last_rtc_update = xtime.tv_sec;
++                      else
++                              last_rtc_update = xtime.tv_sec - 600;
++              } else if (set_rtc_mmss(xtime.tv_sec) == 0)
+                       last_rtc_update = xtime.tv_sec;
+               else
+                       last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+@@ -286,7 +297,10 @@ unsigned long get_cmos_time(void)
+       spin_lock(&rtc_lock);
+-      retval = mach_get_cmos_time();
++      if (efi_enabled)
++              retval = efi_get_time();
++      else
++              retval = mach_get_cmos_time();
+       spin_unlock(&rtc_lock);
+@@ -297,6 +311,7 @@ static struct sysdev_class pit_sysclass 
+       set_kset_name("pit"),
+ };
++
+ /* XXX this driverfs stuff should probably go elsewhere later -john */
+ static struct sys_device device_i8253 = {
+       .id     = 0,
+@@ -328,6 +343,8 @@ void __init hpet_time_init(void)
+       }
+       cur_timer = select_timer();
++      printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
++
+       time_init_hook();
+ }
+ #endif
+@@ -344,12 +361,13 @@ void __init time_init(void)
+               return;
+       }
+ #endif
+-
+       xtime.tv_sec = get_cmos_time();
+       wall_to_monotonic.tv_sec = -xtime.tv_sec;
+       xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
+       wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
+       cur_timer = select_timer();
++      printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
++
+       time_init_hook();
+ }
+--- linux-2.6.0/arch/i386/kernel/timers/common.c       2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/timers/common.c        2003-12-28 23:21:57.000000000 -0800
+@@ -137,3 +137,23 @@ bad_calibration:
+ }
+ #endif
++/* calculate cpu_khz */
++void __init init_cpu_khz(void)
++{
++      if (cpu_has_tsc) {
++              unsigned long tsc_quotient = calibrate_tsc();
++              if (tsc_quotient) {
++                      /* report CPU clock rate in Hz.
++                       * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
++                       * clock/second. Our precision is about 100 ppm.
++                       */
++                      {       unsigned long eax=0, edx=1000;
++                              __asm__("divl %2"
++                              :"=a" (cpu_khz), "=d" (edx)
++                              :"r" (tsc_quotient),
++                              "0" (eax), "1" (edx));
++                              printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
++                      }
++              }
++      }
++}
+--- linux-2.6.0/arch/i386/kernel/timers/Makefile       2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/i386/kernel/timers/Makefile        2003-12-28 23:21:57.000000000 -0800
+@@ -6,3 +6,4 @@ obj-y := timer.o timer_none.o timer_tsc.
+ obj-$(CONFIG_X86_CYCLONE_TIMER)       += timer_cyclone.o
+ obj-$(CONFIG_HPET_TIMER)      += timer_hpet.o
++obj-$(CONFIG_X86_PM_TIMER)    += timer_pm.o
+--- linux-2.6.0/arch/i386/kernel/timers/timer.c        2003-09-08 13:58:55.000000000 -0700
++++ 25/arch/i386/kernel/timers/timer.c 2003-12-28 23:21:57.000000000 -0800
+@@ -19,6 +19,9 @@ static struct timer_opts* timers[] = {
+ #ifdef CONFIG_HPET_TIMER
+       &timer_hpet,
+ #endif
++#ifdef CONFIG_X86_PM_TIMER
++      &timer_pmtmr,
++#endif
+       &timer_tsc,
+       &timer_pit,
+       NULL,
+--- linux-2.6.0/arch/i386/kernel/timers/timer_cyclone.c        2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/timers/timer_cyclone.c 2003-12-28 23:22:29.000000000 -0800
+@@ -71,7 +71,7 @@ static void mark_offset_cyclone(void)
+       lost = delta/(1000000/HZ);
+       delay = delta%(1000000/HZ);
+       if (lost >= 2)
+-              jiffies += lost-1;
++              jiffies_64 += lost-1;
+       
+       /* update the monotonic base value */
+       this_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low;
+@@ -88,7 +88,7 @@ static void mark_offset_cyclone(void)
+        * usec delta is > 90% # of usecs/tick)
+        */
+       if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ))
+-              jiffies++;
++              jiffies_64++;
+ }
+ static unsigned long get_offset_cyclone(void)
+@@ -212,26 +212,7 @@ static int __init init_cyclone(char* ove
+               }
+       }
+-      /* init cpu_khz.
+-       * XXX - This should really be done elsewhere, 
+-       *              and in a more generic fashion. -johnstul@us.ibm.com
+-       */
+-      if (cpu_has_tsc) {
+-              unsigned long tsc_quotient = calibrate_tsc();
+-              if (tsc_quotient) {
+-                      /* report CPU clock rate in Hz.
+-                       * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
+-                       * clock/second. Our precision is about 100 ppm.
+-                       */
+-                      {       unsigned long eax=0, edx=1000;
+-                              __asm__("divl %2"
+-                              :"=a" (cpu_khz), "=d" (edx)
+-                              :"r" (tsc_quotient),
+-                              "0" (eax), "1" (edx));
+-                              printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
+-                      }
+-              }
+-      }
++      init_cpu_khz();
+       /* Everything looks good! */
+       return 0;
+@@ -253,6 +234,7 @@ static void delay_cyclone(unsigned long 
+ /* cyclone timer_opts struct */
+ struct timer_opts timer_cyclone = {
++      .name = "cyclone",
+       .init = init_cyclone, 
+       .mark_offset = mark_offset_cyclone, 
+       .get_offset = get_offset_cyclone,
+--- linux-2.6.0/arch/i386/kernel/timers/timer_hpet.c   2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/timers/timer_hpet.c    2003-12-28 23:22:29.000000000 -0800
+@@ -108,7 +108,7 @@ static void mark_offset_hpet(void)
+       offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
+       if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) {
+               int lost_ticks = (offset - hpet_last) / hpet_tick;
+-              jiffies += lost_ticks;
++              jiffies_64 += lost_ticks;
+       }
+       hpet_last = offset;
+@@ -178,6 +178,7 @@ static int __init init_hpet(char* overri
+ /* tsc timer_opts struct */
+ struct timer_opts timer_hpet = {
++      .name =                 "hpet",
+       .init =                 init_hpet,
+       .mark_offset =          mark_offset_hpet,
+       .get_offset =           get_offset_hpet,
+--- linux-2.6.0/arch/i386/kernel/timers/timer_none.c   2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/timers/timer_none.c    2003-12-28 23:21:56.000000000 -0800
+@@ -36,6 +36,7 @@ static void delay_none(unsigned long loo
+ /* tsc timer_opts struct */
+ struct timer_opts timer_none = {
++      .name =         "none",
+       .init =         init_none, 
+       .mark_offset =  mark_offset_none, 
+       .get_offset =   get_offset_none,
+--- linux-2.6.0/arch/i386/kernel/timers/timer_pit.c    2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/timers/timer_pit.c     2003-12-28 23:21:56.000000000 -0800
+@@ -149,6 +149,7 @@ static unsigned long get_offset_pit(void
+ /* tsc timer_opts struct */
+ struct timer_opts timer_pit = {
++      .name =         "pit",
+       .init =         init_pit, 
+       .mark_offset =  mark_offset_pit, 
+       .get_offset =   get_offset_pit,
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/kernel/timers/timer_pm.c      2003-12-28 23:21:57.000000000 -0800
+@@ -0,0 +1,203 @@
++/*
++ * (C) Dominik Brodowski <linux@brodo.de> 2003
++ *
++ * Driver to use the Power Management Timer (PMTMR) available in some
++ * southbridges as primary timing source for the Linux kernel.
++ *
++ * Based on parts of linux/drivers/acpi/hardware/hwtimer.c, timer_pit.c,
++ * timer_hpet.c, and on Arjan van de Ven's implementation for 2.4.
++ *
++ * This file is licensed under the GPL v2.
++ */
++
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/init.h>
++#include <asm/types.h>
++#include <asm/timer.h>
++#include <asm/smp.h>
++#include <asm/io.h>
++#include <asm/arch_hooks.h>
++
++
++/* The I/O port the PMTMR resides at.
++ * The location is detected during setup_arch(),
++ * in arch/i386/acpi/boot.c */
++u32 pmtmr_ioport = 0;
++
++
++/* value of the Power timer at last timer interrupt */
++static u32 offset_tick;
++static u32 offset_delay;
++
++static unsigned long long monotonic_base;
++static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
++
++#define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */
++
++static int init_pmtmr(char* override)
++{
++      u32 value1, value2;
++      unsigned int i;
++
++      if (override[0] && strncmp(override,"pmtmr",5))
++              return -ENODEV;
++
++      if (!pmtmr_ioport)
++              return -ENODEV;
++
++      /* "verify" this timing source */
++      value1 = inl(pmtmr_ioport);
++      value1 &= ACPI_PM_MASK;
++      for (i=0; i < 10000; i++) {
++              value2 = inl(pmtmr_ioport);
++              value2 &= ACPI_PM_MASK;
++              if (value2 == value1)
++                      continue;
++              if (value2 > value1)
++                      goto pm_good;
++              if ((value2 < value1) && ((value2) < 0xFFF))
++                      goto pm_good;
++              printk(KERN_INFO "PM-Timer had inconsistent results: 0x%#x, 0x%#x - aborting.\n", value1, value2);
++              return -EINVAL;
++      }
++      printk(KERN_INFO "PM-Timer had no reasonable result: 0x%#x - aborting.\n", value1);
++      return -ENODEV;
++
++pm_good:
++      init_cpu_khz();
++      return 0;
++}
++
++static inline u32 cyc2us(u32 cycles)
++{
++      /* The Power Management Timer ticks at 3.579545 ticks per microsecond.
++       * 1 / PM_TIMER_FREQUENCY == 0.27936511 =~ 286/1024 [error: 0.024%]
++       *
++       * Even with HZ = 100, delta is at maximum 35796 ticks, so it can
++       * easily be multiplied with 286 (=0x11E) without having to fear
++       * u32 overflows.
++       */
++      cycles *= 286;
++      return (cycles >> 10);
++}
++
++/*
++ * this gets called during each timer interrupt
++ *   - Called while holding the writer xtime_lock
++ */
++static void mark_offset_pmtmr(void)
++{
++      u32 lost, delta, last_offset;
++      static int first_run = 1;
++      last_offset = offset_tick;
++
++      write_seqlock(&monotonic_lock);
++
++      offset_tick = inl(pmtmr_ioport);
++      offset_tick &= ACPI_PM_MASK; /* limit it to 24 bits */
++
++      /* calculate tick interval */
++      delta = (offset_tick - last_offset) & ACPI_PM_MASK;
++
++      /* convert to usecs */
++      delta = cyc2us(delta);
++
++      /* update the monotonic base value */
++      monotonic_base += delta*NSEC_PER_USEC;
++      write_sequnlock(&monotonic_lock);
++
++      /* convert to ticks */
++      delta += offset_delay;
++      lost = delta/(USEC_PER_SEC/HZ);
++      offset_delay = delta%(USEC_PER_SEC/HZ);
++
++
++      /* compensate for lost ticks */
++      if (lost >= 2)
++              jiffies += lost - 1;
++
++      /* don't calculate delay for first run,
++         or if we've got less then a tick */
++      if (first_run || (lost < 1)) {
++              first_run = 0;
++              offset_delay = 0;
++      }
++
++      return;
++}
++
++
++static unsigned long long monotonic_clock_pmtmr(void)
++{
++      u32 last_offset, this_offset;
++      unsigned long long base, ret;
++      unsigned seq;
++
++
++      /* atomically read monotonic base & last_offset */
++      do {
++              seq = read_seqbegin(&monotonic_lock);
++              last_offset = offset_tick;
++              base = monotonic_base;
++      } while (read_seqretry(&monotonic_lock, seq));
++
++      /* Read the pmtmr */
++      this_offset =  inl(pmtmr_ioport) & ACPI_PM_MASK;
++
++      /* convert to nanoseconds */
++      ret = (this_offset - last_offset) & ACPI_PM_MASK;
++      ret = base + (cyc2us(ret)*NSEC_PER_USEC);
++      return ret;
++}
++
++/*
++ * copied from delay_pit
++ */
++static void delay_pmtmr(unsigned long loops)
++{
++      int d0;
++      __asm__ __volatile__(
++              "\tjmp 1f\n"
++              ".align 16\n"
++              "1:\tjmp 2f\n"
++              ".align 16\n"
++              "2:\tdecl %0\n\tjns 2b"
++              :"=&a" (d0)
++              :"0" (loops));
++}
++
++
++/*
++ * get the offset (in microseconds) from the last call to mark_offset()
++ *    - Called holding a reader xtime_lock
++ */
++static unsigned long get_offset_pmtmr(void)
++{
++      u32 now, offset, delta = 0;
++
++      offset = offset_tick;
++      now = inl(pmtmr_ioport);
++      now &= ACPI_PM_MASK;
++      delta = (now - offset)&ACPI_PM_MASK;
++
++      return (unsigned long) offset_delay + cyc2us(delta);
++}
++
++
++/* acpi timer_opts struct */
++struct timer_opts timer_pmtmr = {
++      .name                   = "acpi_pm_timer",
++      .init                   = init_pmtmr,
++      .mark_offset            = mark_offset_pmtmr,
++      .get_offset             = get_offset_pmtmr,
++      .monotonic_clock        = monotonic_clock_pmtmr,
++      .delay                  = delay_pmtmr,
++};
++
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
++MODULE_DESCRIPTION("Power Management Timer (PMTMR) as primary timing source for x86");
+--- linux-2.6.0/arch/i386/kernel/timers/timer_tsc.c    2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/i386/kernel/timers/timer_tsc.c     2003-12-28 23:26:25.000000000 -0800
+@@ -30,7 +30,6 @@ struct timer_opts timer_tsc;
+ int tsc_disable __initdata = 0;
+ extern spinlock_t i8253_lock;
+-extern volatile unsigned long jiffies;
+ static int use_tsc;
+ /* Number of usecs that the last interrupt was delayed */
+@@ -141,6 +140,7 @@ unsigned long long sched_clock(void)
+ #ifndef CONFIG_NUMA
+       if (!use_tsc)
+ #endif
++              /* jiffies might overflow but this is not a big deal here */
+               return (unsigned long long)jiffies * (1000000000 / HZ);
+       /* Read the Time Stamp Counter */
+@@ -184,6 +184,18 @@ static void mark_offset_tsc(void)
+       count = inb_p(PIT_CH0);    /* read the latched count */
+       count |= inb(PIT_CH0) << 8;
++
++      /*
++       * VIA686a test code... reset the latch if count > max + 1
++       * from timer_pit.c - cjb
++       */
++      if (count > LATCH) {
++              outb_p(0x34, PIT_MODE);
++              outb_p(LATCH & 0xff, PIT_CH0);
++              outb(LATCH >> 8, PIT_CH0);
++              count = LATCH - 1;
++      }
++
+       spin_unlock(&i8253_lock);
+       if (pit_latch_buggy) {
+@@ -215,7 +227,7 @@ static void mark_offset_tsc(void)
+       lost = delta/(1000000/HZ);
+       delay = delta%(1000000/HZ);
+       if (lost >= 2) {
+-              jiffies += lost-1;
++              jiffies_64 += lost-1;
+               /* sanity check to ensure we're not always losing ticks */
+               if (lost_count++ > 100) {
+@@ -241,7 +253,7 @@ static void mark_offset_tsc(void)
+        * usec delta is > 90% # of usecs/tick)
+        */
+       if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ))
+-              jiffies++;
++              jiffies_64++;
+ }
+ static void delay_tsc(unsigned long loops)
+@@ -283,7 +295,7 @@ static void mark_offset_tsc_hpet(void)
+       offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
+       if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) {
+               int lost_ticks = (offset - hpet_last) / hpet_tick;
+-              jiffies += lost_ticks;
++              jiffies_64 += lost_ticks;
+       }
+       hpet_last = hpet_current;
+@@ -472,6 +484,7 @@ __setup("notsc", tsc_setup);
+ /* tsc timer_opts struct */
+ struct timer_opts timer_tsc = {
++      .name =         "tsc",
+       .init =         init_tsc,
+       .mark_offset =  mark_offset_tsc, 
+       .get_offset =   get_offset_tsc,
+--- linux-2.6.0/arch/i386/kernel/traps.c       2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/traps.c        2003-12-28 23:26:36.000000000 -0800
+@@ -54,12 +54,8 @@
+ #include "mach_traps.h"
+-asmlinkage int system_call(void);
+-asmlinkage void lcall7(void);
+-asmlinkage void lcall27(void);
+-
+-struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
+-              { 0, 0 }, { 0, 0 } };
++struct desc_struct default_ldt[] __attribute__((__section__(".data.default_ldt"))) = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
++struct page *default_ldt_page;
+ /* Do we ignore FPU interrupts ? */
+ char ignore_fpu_irq = 0;
+@@ -91,6 +87,43 @@ asmlinkage void alignment_check(void);
+ asmlinkage void spurious_interrupt_bug(void);
+ asmlinkage void machine_check(void);
++#ifdef CONFIG_KGDB
++extern void sysenter_entry(void);
++#include <asm/kgdb.h>
++#include <linux/init.h>
++extern void int3(void);
++extern void debug(void);
++void set_intr_gate(unsigned int n, void *addr);
++static void set_intr_usr_gate(unsigned int n, void *addr);
++/*
++ * Should be able to call this breakpoint() very early in
++ * bring up.  Just hard code the call where needed.
++ * The breakpoint() code is here because set_?_gate() functions
++ * are local (static) to trap.c.  They need be done only once,
++ * but it does not hurt to do them over.
++ */
++void breakpoint(void)
++{
++      init_entry_mappings();
++        set_intr_usr_gate(3,&int3); /* disable ints on trap */
++      set_intr_gate(1,&debug);
++      set_intr_gate(14,&page_fault);
++
++        BREAKPOINT;
++}
++#define       CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after)            \
++    {                                                                 \
++      if (!user_mode(regs)  ) \
++      {                                                               \
++              kgdb_handle_exception(trapnr, signr, error_code, regs); \
++              after;                                                  \
++      } else if ((trapnr == 3) && (regs->eflags &0x200)) local_irq_enable(); \
++    }
++#else
++#define       CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after)
++#endif
++
++
+ static int kstack_depth_to_print = 24;
+ void show_trace(struct task_struct *task, unsigned long * stack)
+@@ -175,8 +208,9 @@ void show_registers(struct pt_regs *regs
+               ss = regs->xss & 0xffff;
+       }
+       print_modules();
+-      printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s\nEFLAGS: %08lx\n",
+-              smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags);
++      printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s VLI\nEFLAGS: %08lx\n",
++              smp_processor_id(), 0xffff & regs->xcs,
++              regs->eip, print_tainted(), regs->eflags);
+       print_symbol("EIP is at %s\n", regs->eip);
+       printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
+@@ -192,23 +226,27 @@ void show_registers(struct pt_regs *regs
+        * time of the fault..
+        */
+       if (in_kernel) {
++              u8 *eip;
+               printk("\nStack: ");
+               show_stack(NULL, (unsigned long*)esp);
+               printk("Code: ");
+-              if(regs->eip < PAGE_OFFSET)
+-                      goto bad;
+-              for(i=0;i<20;i++)
+-              {
+-                      unsigned char c;
+-                      if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
+-bad:
++              eip = (u8 *)regs->eip - 43;
++              for (i = 0; i < 64; i++, eip++) {
++                      unsigned char c = 0xff;
++
++                      if ((user_mode(regs) && get_user(c, eip)) ||
++                          (!user_mode(regs) && __direct_get_user(c, eip))) {
++
+                               printk(" Bad EIP value.");
+                               break;
+                       }
+-                      printk("%02x ", c);
++                      if (eip == (u8 *)regs->eip)
++                              printk("<%02x> ", c);
++                      else
++                              printk("%02x ", c);
+               }
+       }
+       printk("\n");
+@@ -255,12 +293,36 @@ spinlock_t die_lock = SPIN_LOCK_UNLOCKED
+ void die(const char * str, struct pt_regs * regs, long err)
+ {
+       static int die_counter;
++      int nl = 0;
+       console_verbose();
+       spin_lock_irq(&die_lock);
+       bust_spinlocks(1);
+       handle_BUG(regs);
+       printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
++#ifdef CONFIG_PREEMPT
++      printk("PREEMPT ");
++      nl = 1;
++#endif
++#ifdef CONFIG_SMP
++      printk("SMP ");
++      nl = 1;
++#endif
++#ifdef CONFIG_DEBUG_PAGEALLOC
++      printk("DEBUG_PAGEALLOC");
++      nl = 1;
++#endif
++      if (nl)
++              printk("\n");
++#ifdef CONFIG_KGDB
++      /* This is about the only place we want to go to kgdb even if in
++       * user mode.  But we must go in via a trap so within kgdb we will
++       * always be in kernel mode.
++       */
++      if (user_mode(regs))
++              BREAKPOINT;
++#endif
++      CHK_REMOTE_DEBUG(0,SIGTRAP,err,regs,)
+       show_registers(regs);
+       bust_spinlocks(0);
+       spin_unlock_irq(&die_lock);
+@@ -330,6 +392,7 @@ static inline void do_trap(int trapnr, i
+ #define DO_ERROR(trapnr, signr, str, name) \
+ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+ { \
++      CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,)\
+       do_trap(trapnr, signr, str, 0, regs, error_code, NULL); \
+ }
+@@ -347,7 +410,9 @@ asmlinkage void do_##name(struct pt_regs
+ #define DO_VM86_ERROR(trapnr, signr, str, name) \
+ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+ { \
++      CHK_REMOTE_DEBUG(trapnr, signr, error_code,regs, return)\
+       do_trap(trapnr, signr, str, 1, regs, error_code, NULL); \
++      return; \
+ }
+ #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
+@@ -394,8 +459,10 @@ gp_in_vm86:
+       return;
+ gp_in_kernel:
+-      if (!fixup_exception(regs))
++      if (!fixup_exception(regs)){
++              CHK_REMOTE_DEBUG(13,SIGSEGV,error_code,regs,)
+               die("general protection fault", regs, error_code);
++      }
+ }
+ static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
+@@ -534,10 +601,18 @@ asmlinkage void do_debug(struct pt_regs 
+       if (regs->eflags & X86_EFLAGS_IF)
+               local_irq_enable();
+-      /* Mask out spurious debug traps due to lazy DR7 setting */
++      /*
++       * Mask out spurious debug traps due to lazy DR7 setting or
++       * due to 4G/4G kernel mode:
++       */
+       if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
+               if (!tsk->thread.debugreg[7])
+                       goto clear_dr7;
++              if (!user_mode(regs)) {
++                      // restore upon return-to-userspace:
++                      set_thread_flag(TIF_DB7);
++                      goto clear_dr7;
++              }
+       }
+       if (regs->eflags & VM_MASK)
+@@ -557,8 +632,18 @@ asmlinkage void do_debug(struct pt_regs 
+                * allowing programs to debug themselves without the ptrace()
+                * interface.
+                */
++#ifdef CONFIG_KGDB
++              /*
++               * I think this is the only "real" case of a TF in the kernel
++               * that really belongs to user space.  Others are
++               * "Ours all ours!"
++               */
++              if (((regs->xcs & 3) == 0) && ((void *)regs->eip == sysenter_entry))
++                      goto clear_TF_reenable;
++#else
+               if ((regs->xcs & 3) == 0)
+                       goto clear_TF_reenable;
++#endif
+               if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
+                       goto clear_TF;
+       }
+@@ -570,6 +655,17 @@ asmlinkage void do_debug(struct pt_regs 
+       info.si_errno = 0;
+       info.si_code = TRAP_BRKPT;
+       
++#ifdef CONFIG_KGDB
++        /*
++       * If this is a kernel mode trap, we need to reset db7 to allow us
++       * to continue sanely ALSO skip the signal delivery
++         */
++      if ((regs->xcs & 3) == 0)
++              goto clear_dr7;
++
++        /* if not kernel, allow ints but only if they were on */
++       if ( regs->eflags & 0x200) local_irq_enable();
++#endif
+       /* If this is a kernel mode trap, save the user PC on entry to 
+        * the kernel, that's what the debugger can make sense of.
+        */
+@@ -584,6 +680,7 @@ clear_dr7:
+       __asm__("movl %0,%%db7"
+               : /* no output */
+               : "r" (0));
++      CHK_REMOTE_DEBUG(1,SIGTRAP,error_code,regs,)
+       return;
+ debug_vm86:
+@@ -779,19 +876,53 @@ asmlinkage void math_emulate(long arg)
+ #endif /* CONFIG_MATH_EMULATION */
+-#ifdef CONFIG_X86_F00F_BUG
+-void __init trap_init_f00f_bug(void)
++void __init trap_init_virtual_IDT(void)
+ {
+-      __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
+-
+       /*
+-       * Update the IDT descriptor and reload the IDT so that
+-       * it uses the read-only mapped virtual address.
++       * "idt" is magic - it overlaps the idt_descr
++       * variable so that updating idt will automatically
++       * update the idt descriptor..
+        */
+-      idt_descr.address = fix_to_virt(FIX_F00F_IDT);
++      __set_fixmap(FIX_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
++      idt_descr.address = __fix_to_virt(FIX_IDT);
++
+       __asm__ __volatile__("lidt %0" : : "m" (idt_descr));
+ }
++
++void __init trap_init_virtual_GDT(void)
++{
++      int cpu = smp_processor_id();
++      struct Xgt_desc_struct *gdt_desc = cpu_gdt_descr + cpu;
++      struct Xgt_desc_struct tmp_desc = {0, 0};
++      struct tss_struct * t;
++
++      __asm__ __volatile__("sgdt %0": "=m" (tmp_desc): :"memory");
++
++#ifdef CONFIG_X86_HIGH_ENTRY
++      if (!cpu) {
++              __set_fixmap(FIX_GDT_0, __pa(cpu_gdt_table), PAGE_KERNEL);
++              __set_fixmap(FIX_GDT_1, __pa(cpu_gdt_table) + PAGE_SIZE, PAGE_KERNEL);
++              __set_fixmap(FIX_TSS_0, __pa(init_tss), PAGE_KERNEL);
++              __set_fixmap(FIX_TSS_1, __pa(init_tss) + 1*PAGE_SIZE, PAGE_KERNEL);
++              __set_fixmap(FIX_TSS_2, __pa(init_tss) + 2*PAGE_SIZE, PAGE_KERNEL);
++              __set_fixmap(FIX_TSS_3, __pa(init_tss) + 3*PAGE_SIZE, PAGE_KERNEL);
++      }
++
++      gdt_desc->address = __fix_to_virt(FIX_GDT_0) + sizeof(cpu_gdt_table[0]) * cpu;
++#else
++      gdt_desc->address = (unsigned long)cpu_gdt_table[cpu];
++#endif
++      __asm__ __volatile__("lgdt %0": "=m" (*gdt_desc));
++
++#ifdef CONFIG_X86_HIGH_ENTRY
++      t = (struct tss_struct *) __fix_to_virt(FIX_TSS_0) + cpu;
++#else
++      t = init_tss + cpu;
+ #endif
++      set_tss_desc(cpu, t);
++      cpu_gdt_table[cpu][GDT_ENTRY_TSS].b &= 0xfffffdff;
++      load_TR_desc();
++}
+ #define _set_gate(gate_addr,type,dpl,addr,seg) \
+ do { \
+@@ -818,20 +949,26 @@ void set_intr_gate(unsigned int n, void 
+       _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
+ }
+-static void __init set_trap_gate(unsigned int n, void *addr)
++void __init set_trap_gate(unsigned int n, void *addr)
+ {
+       _set_gate(idt_table+n,15,0,addr,__KERNEL_CS);
+ }
+-static void __init set_system_gate(unsigned int n, void *addr)
++void __init set_system_gate(unsigned int n, void *addr)
+ {
+       _set_gate(idt_table+n,15,3,addr,__KERNEL_CS);
+ }
+-static void __init set_call_gate(void *a, void *addr)
++void __init set_call_gate(void *a, void *addr)
+ {
+       _set_gate(a,12,3,addr,__KERNEL_CS);
+ }
++#ifdef CONFIG_KGDB
++void set_intr_usr_gate(unsigned int n, void *addr)
++{
++      _set_gate(idt_table+n,14,3,addr,__KERNEL_CS);
++}
++#endif
+ static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
+ {
+@@ -850,11 +987,16 @@ void __init trap_init(void)
+ #ifdef CONFIG_X86_LOCAL_APIC
+       init_apic_mappings();
+ #endif
++      init_entry_mappings();
+       set_trap_gate(0,&divide_error);
+       set_intr_gate(1,&debug);
+       set_intr_gate(2,&nmi);
++#ifndef CONFIG_KGDB
+       set_system_gate(3,&int3);       /* int3-5 can be called from all */
++#else
++      set_intr_usr_gate(3,&int3);     /* int3-5 can be called from all */
++#endif
+       set_system_gate(4,&overflow);
+       set_system_gate(5,&bounds);
+       set_trap_gate(6,&invalid_op);
+--- linux-2.6.0/arch/i386/kernel/vm86.c        2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/i386/kernel/vm86.c 2003-12-28 23:26:36.000000000 -0800
+@@ -124,7 +124,8 @@ struct pt_regs * save_v86_state(struct k
+       tss = init_tss + get_cpu();
+       current->thread.esp0 = current->thread.saved_esp0;
+-      load_esp0(tss, current->thread.esp0);
++      current->thread.sysenter_cs = __KERNEL_CS;
++      load_virtual_esp0(tss, current);
+       current->thread.saved_esp0 = 0;
+       put_cpu();
+@@ -301,8 +302,10 @@ static void do_sys_vm86(struct kernel_vm
+       asm volatile("movl %%gs,%0":"=m" (tsk->thread.saved_gs));
+       tss = init_tss + get_cpu();
+-      tss->esp0 = tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
+-      disable_sysenter(tss);
++      tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
++      if (cpu_has_sep)
++              tsk->thread.sysenter_cs = 0;
++      load_virtual_esp0(tss, tsk);
+       put_cpu();
+       tsk->thread.screen_bitmap = info->screen_bitmap;
+--- linux-2.6.0/arch/i386/kernel/vmlinux.lds.S 2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/vmlinux.lds.S  2003-12-28 23:26:36.000000000 -0800
+@@ -3,6 +3,9 @@
+  */
+ #include <asm-generic/vmlinux.lds.h>
++#include <linux/config.h>
++#include <asm/page.h>
++#include <asm/asm_offsets.h>
+       
+ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+ OUTPUT_ARCH(i386)
+@@ -10,7 +13,7 @@ ENTRY(startup_32)
+ jiffies = jiffies_64;
+ SECTIONS
+ {
+-  . = 0xC0000000 + 0x100000;
++  . = __PAGE_OFFSET + 0x100000;
+   /* read-only */
+   _text = .;                  /* Text and read-only data */
+   .text : {
+@@ -19,6 +22,19 @@ SECTIONS
+       *(.gnu.warning)
+       } = 0x9090
++#ifdef CONFIG_X86_4G
++  . = ALIGN(PAGE_SIZE_asm);
++  __entry_tramp_start = .;
++  . = FIX_ENTRY_TRAMPOLINE_0_addr;
++  __start___entry_text = .;
++  .entry.text : AT (__entry_tramp_start) { *(.entry.text) }
++  __entry_tramp_end = __entry_tramp_start + SIZEOF(.entry.text);
++  . = __entry_tramp_end;
++  . = ALIGN(PAGE_SIZE_asm);
++#else
++  .entry.text : { *(.entry.text) }
++#endif
++
+   _etext = .;                 /* End of text section */
+   . = ALIGN(16);              /* Exception table */
+@@ -34,15 +50,12 @@ SECTIONS
+       CONSTRUCTORS
+       }
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE_asm);
+   __nosave_begin = .;
+   .data_nosave : { *(.data.nosave) }
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE_asm);
+   __nosave_end = .;
+-  . = ALIGN(4096);
+-  .data.page_aligned : { *(.data.idt) }
+-
+   . = ALIGN(32);
+   .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+@@ -52,7 +65,7 @@ SECTIONS
+   .data.init_task : { *(.data.init_task) }
+   /* will be freed after init */
+-  . = ALIGN(4096);            /* Init code and data */
++  . = ALIGN(PAGE_SIZE_asm);           /* Init code and data */
+   __init_begin = .;
+   .init.text : { 
+       _sinittext = .;
+@@ -91,7 +104,7 @@ SECTIONS
+      from .altinstructions and .eh_frame */
+   .exit.text : { *(.exit.text) }
+   .exit.data : { *(.exit.data) }
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE_asm);
+   __initramfs_start = .;
+   .init.ramfs : { *(.init.ramfs) }
+   __initramfs_end = .;
+@@ -99,10 +112,22 @@ SECTIONS
+   __per_cpu_start = .;
+   .data.percpu  : { *(.data.percpu) }
+   __per_cpu_end = .;
+-  . = ALIGN(4096);
++  . = ALIGN(PAGE_SIZE_asm);
+   __init_end = .;
+   /* freed after init ends here */
+-      
++
++  . = ALIGN(PAGE_SIZE_asm);
++  .data.page_aligned_tss : { *(.data.tss) }
++
++  . = ALIGN(PAGE_SIZE_asm);
++  .data.page_aligned_default_ldt : { *(.data.default_ldt) }
++
++  . = ALIGN(PAGE_SIZE_asm);
++  .data.page_aligned_idt : { *(.data.idt) }
++
++  . = ALIGN(PAGE_SIZE_asm);
++  .data.page_aligned_gdt : { *(.data.gdt) }
++
+   __bss_start = .;            /* BSS */
+   .bss : { *(.bss) }
+   __bss_stop = .; 
+@@ -122,4 +147,6 @@ SECTIONS
+   .stab.index 0 : { *(.stab.index) }
+   .stab.indexstr 0 : { *(.stab.indexstr) }
+   .comment 0 : { *(.comment) }
++
++
+ }
+--- linux-2.6.0/arch/i386/kernel/vsyscall.lds  2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/vsyscall.lds   2003-12-28 23:26:36.000000000 -0800
+@@ -5,7 +5,7 @@
+  */
+ /* This must match <asm/fixmap.h>.  */
+-VSYSCALL_BASE = 0xffffe000;
++VSYSCALL_BASE = 0xffffd000;
+ SECTIONS
+ {
+--- linux-2.6.0/arch/i386/kernel/vsyscall-sysenter.S   2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/kernel/vsyscall-sysenter.S    2003-12-28 23:26:36.000000000 -0800
+@@ -7,6 +7,11 @@
+       .type __kernel_vsyscall,@function
+ __kernel_vsyscall:
+ .LSTART_vsyscall:
++      cmpl $192, %eax
++      jne 1f
++      int $0x80
++      ret
++1:
+       push %ecx
+ .Lpush_ecx:
+       push %edx
+--- linux-2.6.0/arch/i386/lib/checksum.S       2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/lib/checksum.S        2003-12-28 23:26:36.000000000 -0800
+@@ -280,14 +280,14 @@ unsigned int csum_partial_copy_generic (
+       .previous
+ .align 4
+-.globl csum_partial_copy_generic
++.globl direct_csum_partial_copy_generic
+                               
+ #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
+ #define ARGBASE 16            
+ #define FP            12
+               
+-csum_partial_copy_generic:
++direct_csum_partial_copy_generic:
+       subl  $4,%esp   
+       pushl %edi
+       pushl %esi
+@@ -422,7 +422,7 @@ DST(       movb %cl, (%edi)        )
+ #define ARGBASE 12
+               
+-csum_partial_copy_generic:
++direct_csum_partial_copy_generic:
+       pushl %ebx
+       pushl %edi
+       pushl %esi
+--- linux-2.6.0/arch/i386/lib/dec_and_lock.c   2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/lib/dec_and_lock.c    2003-12-28 23:26:33.000000000 -0800
+@@ -10,6 +10,7 @@
+ #include <linux/spinlock.h>
+ #include <asm/atomic.h>
++#ifndef ATOMIC_DEC_AND_LOCK
+ int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
+ {
+       int counter;
+@@ -38,3 +39,5 @@ slow_path:
+       spin_unlock(lock);
+       return 0;
+ }
++#endif
++
+--- linux-2.6.0/arch/i386/lib/getuser.S        2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/lib/getuser.S 2003-12-28 23:26:36.000000000 -0800
+@@ -9,6 +9,7 @@
+  * return value.
+  */
+ #include <asm/thread_info.h>
++#include <asm/asm_offsets.h>
+ /*
+@@ -28,7 +29,7 @@
+ .globl __get_user_1
+ __get_user_1:
+       GET_THREAD_INFO(%edx)
+-      cmpl TI_ADDR_LIMIT(%edx),%eax
++      cmpl TI_addr_limit(%edx),%eax
+       jae bad_get_user
+ 1:    movzbl (%eax),%edx
+       xorl %eax,%eax
+@@ -40,7 +41,7 @@ __get_user_2:
+       addl $1,%eax
+       jc bad_get_user
+       GET_THREAD_INFO(%edx)
+-      cmpl TI_ADDR_LIMIT(%edx),%eax
++      cmpl TI_addr_limit(%edx),%eax
+       jae bad_get_user
+ 2:    movzwl -1(%eax),%edx
+       xorl %eax,%eax
+@@ -52,7 +53,7 @@ __get_user_4:
+       addl $3,%eax
+       jc bad_get_user
+       GET_THREAD_INFO(%edx)
+-      cmpl TI_ADDR_LIMIT(%edx),%eax
++      cmpl TI_addr_limit(%edx),%eax
+       jae bad_get_user
+ 3:    movl -3(%eax),%edx
+       xorl %eax,%eax
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/i386/lib/kgdb_serial.c     2003-12-28 23:21:09.000000000 -0800
+@@ -0,0 +1,499 @@
++/*
++ * Serial interface GDB stub
++ *
++ * Written (hacked together) by David Grothe (dave@gcom.com)
++ * Modified to allow invokation early in boot see also
++ * kgdb.h for instructions by George Anzinger(george@mvista.com)
++ * Modified to handle debugging over ethernet by Robert Walsh
++ * <rjwalsh@durables.org> and wangdi <wangdi@clusterfs.com>, based on
++ * code by San Mehat.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial.h>
++#include <linux/serial_reg.h>
++#include <linux/config.h>
++#include <linux/major.h>
++#include <linux/string.h>
++#include <linux/fcntl.h>
++#include <linux/ptrace.h>
++#include <linux/ioport.h>
++#include <linux/mm.h>
++#include <linux/init.h>
++#include <linux/highmem.h>
++#include <asm/system.h>
++#include <asm/io.h>
++#include <asm/segment.h>
++#include <asm/bitops.h>
++#include <asm/system.h>
++#include <asm/kgdb_local.h>
++#ifdef CONFIG_KGDB_USER_CONSOLE
++extern void kgdb_console_finit(void);
++#endif
++#define PRNT_off
++#define TEST_EXISTANCE
++#ifdef PRNT
++#define dbprintk(s) printk s
++#else
++#define dbprintk(s)
++#endif
++#define TEST_INTERRUPT_off
++#ifdef TEST_INTERRUPT
++#define intprintk(s) printk s
++#else
++#define intprintk(s)
++#endif
++
++#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
++
++#define       GDB_BUF_SIZE    512     /* power of 2, please */
++
++static char gdb_buf[GDB_BUF_SIZE];
++static int gdb_buf_in_inx;
++static atomic_t gdb_buf_in_cnt;
++static int gdb_buf_out_inx;
++
++struct async_struct *gdb_async_info;
++static int gdb_async_irq;
++
++#define outb_px(a,b) outb_p(b,a)
++
++static void program_uart(struct async_struct *info);
++static void write_char(struct async_struct *info, int chr);
++/*
++ * Get a byte from the hardware data buffer and return it
++ */
++static int
++read_data_bfr(struct async_struct *info)
++{
++      char it = inb_p(info->port + UART_LSR);
++
++      if (it & UART_LSR_DR)
++              return (inb_p(info->port + UART_RX));
++      /*
++       * If we have a framing error assume somebody messed with
++       * our uart.  Reprogram it and send '-' both ways...
++       */
++      if (it & 0xc) {
++              program_uart(info);
++              write_char(info, '-');
++              return ('-');
++      }
++      return (-1);
++
++}                             /* read_data_bfr */
++
++/*
++ * Get a char if available, return -1 if nothing available.
++ * Empty the receive buffer first, then look at the interface hardware.
++
++ * Locking here is a bit of a problem.        We MUST not lock out communication
++ * if we are trying to talk to gdb about a kgdb entry.        ON the other hand
++ * we can loose chars in the console pass thru if we don't lock.  It is also
++ * possible that we could hold the lock or be waiting for it when kgdb
++ * NEEDS to talk.  Since kgdb locks down the world, it does not need locks.
++ * We do, of course have possible issues with interrupting a uart operation,
++ * but we will just depend on the uart status to help keep that straight.
++
++ */
++static spinlock_t uart_interrupt_lock = SPIN_LOCK_UNLOCKED;
++#ifdef CONFIG_SMP
++extern spinlock_t kgdb_spinlock;
++#endif
++
++static int
++read_char(struct async_struct *info)
++{
++      int chr;
++      unsigned long flags;
++      local_irq_save(flags);
++#ifdef CONFIG_SMP
++      if (!spin_is_locked(&kgdb_spinlock)) {
++              spin_lock(&uart_interrupt_lock);
++      }
++#endif
++      if (atomic_read(&gdb_buf_in_cnt) != 0) {        /* intr routine has q'd chars */
++              chr = gdb_buf[gdb_buf_out_inx++];
++              gdb_buf_out_inx &= (GDB_BUF_SIZE - 1);
++              atomic_dec(&gdb_buf_in_cnt);
++      } else {
++              chr = read_data_bfr(info);
++      }
++#ifdef CONFIG_SMP
++      if (!spin_is_locked(&kgdb_spinlock)) {
++              spin_unlock(&uart_interrupt_lock);
++      }
++#endif
++      local_irq_restore(flags);
++      return (chr);
++}
++
++/*
++ * Wait until the interface can accept a char, then write it.
++ */
++static void
++write_char(struct async_struct *info, int chr)
++{
++      while (!(inb_p(info->port + UART_LSR) & UART_LSR_THRE)) ;
++
++      outb_p(chr, info->port + UART_TX);
++
++}                             /* write_char */
++
++/*
++ * Mostly we don't need a spinlock, but since the console goes
++ * thru here with interrutps on, well, we need to catch those
++ * chars.
++ */
++/*
++ * This is the receiver interrupt routine for the GDB stub.
++ * It will receive a limited number of characters of input
++ * from the gdb  host machine and save them up in a buffer.
++ *
++ * When the gdb stub routine tty_getDebugChar() is called it
++ * draws characters out of the buffer until it is empty and
++ * then reads directly from the serial port.
++ *
++ * We do not attempt to write chars from the interrupt routine
++ * since the stubs do all of that via tty_putDebugChar() which
++ * writes one byte after waiting for the interface to become
++ * ready.
++ *
++ * The debug stubs like to run with interrupts disabled since,
++ * after all, they run as a consequence of a breakpoint in
++ * the kernel.
++ *
++ * Perhaps someone who knows more about the tty driver than I
++ * care to learn can make this work for any low level serial
++ * driver.
++ */
++static irqreturn_t
++gdb_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++      struct async_struct *info;
++      unsigned long flags;
++
++      info = gdb_async_info;
++      if (!info || !info->tty || irq != gdb_async_irq)
++              return IRQ_NONE;
++
++      local_irq_save(flags);
++      spin_lock(&uart_interrupt_lock);
++      do {
++              int chr = read_data_bfr(info);
++              intprintk(("Debug char on int: %x hex\n", chr));
++              if (chr < 0)
++                      continue;
++
++              if (chr == 3) { /* Ctrl-C means remote interrupt */
++                      BREAKPOINT;
++                      continue;
++              }
++
++              if (atomic_read(&gdb_buf_in_cnt) >= GDB_BUF_SIZE) {
++                      /* buffer overflow tosses early char */
++                      read_char(info);
++              }
++              gdb_buf[gdb_buf_in_inx++] = chr;
++              gdb_buf_in_inx &= (GDB_BUF_SIZE - 1);
++      } while (inb_p(info->port + UART_IIR) & UART_IIR_RDI);
++      spin_unlock(&uart_interrupt_lock);
++      local_irq_restore(flags);
++      return IRQ_HANDLED;
++}                             /* gdb_interrupt */
++
++/*
++ * Just a NULL routine for testing.
++ */
++void
++gdb_null(void)
++{
++}                             /* gdb_null */
++
++/* These structure are filled in with values defined in asm/kgdb_local.h
++ */
++static struct serial_state state = SB_STATE;
++static struct async_struct local_info = SB_INFO;
++static int ok_to_enable_ints = 0;
++static void kgdb_enable_ints_now(void);
++
++extern char *kgdb_version;
++/*
++ * Hook an IRQ for KGDB.
++ *
++ * This routine is called from tty_putDebugChar, below.
++ */
++static int ints_disabled = 1;
++int
++gdb_hook_interrupt(struct async_struct *info, int verb)
++{
++      struct serial_state *state = info->state;
++      unsigned long flags;
++      int port;
++#ifdef TEST_EXISTANCE
++      int scratch, scratch2;
++#endif
++
++      /* The above fails if memory managment is not set up yet.
++       * Rather than fail the set up, just keep track of the fact
++       * and pick up the interrupt thing later.
++       */
++      gdb_async_info = info;
++      port = gdb_async_info->port;
++      gdb_async_irq = state->irq;
++      if (verb) {
++              printk("kgdb %s : port =%x, IRQ=%d, divisor =%d\n",
++                     kgdb_version,
++                     port,
++                     gdb_async_irq, gdb_async_info->state->custom_divisor);
++      }
++      local_irq_save(flags);
++#ifdef TEST_EXISTANCE
++      /* Existance test */
++      /* Should not need all this, but just in case.... */
++
++      scratch = inb_p(port + UART_IER);
++      outb_px(port + UART_IER, 0);
++      outb_px(0xff, 0x080);
++      scratch2 = inb_p(port + UART_IER);
++      outb_px(port + UART_IER, scratch);
++      if (scratch2) {
++              printk
++                  ("gdb_hook_interrupt: Could not clear IER, not a UART!\n");
++              local_irq_restore(flags);
++              return 1;       /* We failed; there's nothing here */
++      }
++      scratch2 = inb_p(port + UART_LCR);
++      outb_px(port + UART_LCR, 0xBF); /* set up for StarTech test */
++      outb_px(port + UART_EFR, 0);    /* EFR is the same as FCR */
++      outb_px(port + UART_LCR, 0);
++      outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO);
++      scratch = inb_p(port + UART_IIR) >> 6;
++      if (scratch == 1) {
++              printk("gdb_hook_interrupt: Undefined UART type!"
++                     "  Not a UART! \n");
++              local_irq_restore(flags);
++              return 1;
++      } else {
++              dbprintk(("gdb_hook_interrupt: UART type "
++                        "is %d where 0=16450, 2=16550 3=16550A\n", scratch));
++      }
++      scratch = inb_p(port + UART_MCR);
++      outb_px(port + UART_MCR, UART_MCR_LOOP | scratch);
++      outb_px(port + UART_MCR, UART_MCR_LOOP | 0x0A);
++      scratch2 = inb_p(port + UART_MSR) & 0xF0;
++      outb_px(port + UART_MCR, scratch);
++      if (scratch2 != 0x90) {
++              printk("gdb_hook_interrupt: "
++                     "Loop back test failed! Not a UART!\n");
++              local_irq_restore(flags);
++              return scratch2 + 1000; /* force 0 to fail */
++      }
++#endif                                /* test existance */
++      program_uart(info);
++      local_irq_restore(flags);
++
++      return (0);
++
++}                             /* gdb_hook_interrupt */
++
++static void
++program_uart(struct async_struct *info)
++{
++      int port = info->port;
++
++      (void) inb_p(port + UART_RX);
++      outb_px(port + UART_IER, 0);
++
++      (void) inb_p(port + UART_RX);   /* serial driver comments say */
++      (void) inb_p(port + UART_IIR);  /* this clears the interrupt regs */
++      (void) inb_p(port + UART_MSR);
++      outb_px(port + UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
++      outb_px(port + UART_DLL, info->state->custom_divisor & 0xff);   /* LS */
++      outb_px(port + UART_DLM, info->state->custom_divisor >> 8);     /* MS  */
++      outb_px(port + UART_MCR, info->MCR);
++
++      outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1 | UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR);        /* set fcr */
++      outb_px(port + UART_LCR, UART_LCR_WLEN8);       /* reset DLAB */
++      outb_px(port + UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1);    /* set fcr */
++      if (!ints_disabled) {
++              intprintk(("KGDB: Sending %d to port %x offset %d\n",
++                         gdb_async_info->IER,
++                         (int) gdb_async_info->port, UART_IER));
++              outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
++      }
++      return;
++}
++
++/*
++ * tty_getDebugChar
++ *
++ * This is a GDB stub routine.        It waits for a character from the
++ * serial interface and then returns it.  If there is no serial
++ * interface connection then it returns a bogus value which will
++ * almost certainly cause the system to hang.  In the
++ */
++int kgdb_in_isr = 0;
++int kgdb_in_lsr = 0;
++extern spinlock_t kgdb_spinlock;
++
++/* Caller takes needed protections */
++
++int
++tty_getDebugChar(void)
++{
++      volatile int chr, dum, time, end_time;
++
++      dbprintk(("tty_getDebugChar(port %x): ", gdb_async_info->port));
++
++      if (gdb_async_info == NULL) {
++              gdb_hook_interrupt(&local_info, 0);
++      }
++      /*
++       * This trick says if we wait a very long time and get
++       * no char, return the -1 and let the upper level deal
++       * with it.
++       */
++      rdtsc(dum, time);
++      end_time = time + 2;
++      while (((chr = read_char(gdb_async_info)) == -1) &&
++             (end_time - time) > 0) {
++              rdtsc(dum, time);
++      };
++      /*
++       * This covers our butts if some other code messes with
++       * our uart, hay, it happens :o)
++       */
++      if (chr == -1)
++              program_uart(gdb_async_info);
++
++      dbprintk(("%c\n", chr > ' ' && chr < 0x7F ? chr : ' '));
++      return (chr);
++
++}                             /* tty_getDebugChar */
++
++static int count = 3;
++static spinlock_t one_at_atime = SPIN_LOCK_UNLOCKED;
++
++static int __init
++kgdb_enable_ints(void)
++{
++      if (kgdboe) {
++              return 0;
++      }
++      if (gdb_async_info == NULL) {
++              gdb_hook_interrupt(&local_info, 1);
++      }
++      ok_to_enable_ints = 1;
++      kgdb_enable_ints_now();
++#ifdef CONFIG_KGDB_USER_CONSOLE
++      kgdb_console_finit();
++#endif
++      return 0;
++}
++
++#ifdef CONFIG_SERIAL_8250
++void shutdown_for_kgdb(struct async_struct *gdb_async_info);
++#endif
++
++#ifdef CONFIG_DISCONTIGMEM
++static inline int kgdb_mem_init_done(void)
++{
++      return highmem_start_page != NULL;
++}
++#else
++static inline int kgdb_mem_init_done(void)
++{
++      return max_mapnr != 0;
++}
++#endif
++
++static void
++kgdb_enable_ints_now(void)
++{
++      if (!spin_trylock(&one_at_atime))
++              return;
++      if (!ints_disabled)
++              goto exit;
++      if (kgdb_mem_init_done() &&
++                      ints_disabled) {        /* don't try till mem init */
++#ifdef CONFIG_SERIAL_8250
++              /*
++               * The ifdef here allows the system to be configured
++               * without the serial driver.
++               * Don't make it a module, however, it will steal the port
++               */
++              shutdown_for_kgdb(gdb_async_info);
++#endif
++              ints_disabled = request_irq(gdb_async_info->state->irq,
++                                          gdb_interrupt,
++                                          IRQ_T(gdb_async_info),
++                                          "KGDB-stub", NULL);
++              intprintk(("KGDB: request_irq returned %d\n", ints_disabled));
++      }
++      if (!ints_disabled) {
++              intprintk(("KGDB: Sending %d to port %x offset %d\n",
++                         gdb_async_info->IER,
++                         (int) gdb_async_info->port, UART_IER));
++              outb_px(gdb_async_info->port + UART_IER, gdb_async_info->IER);
++      }
++      exit:
++      spin_unlock(&one_at_atime);
++}
++
++/*
++ * tty_putDebugChar
++ *
++ * This is a GDB stub routine.        It waits until the interface is ready
++ * to transmit a char and then sends it.  If there is no serial
++ * interface connection then it simply returns to its caller, having
++ * pretended to send the char.        Caller takes needed protections.
++ */
++void
++tty_putDebugChar(int chr)
++{
++      dbprintk(("tty_putDebugChar(port %x): chr=%02x '%c', ints_on=%d\n",
++                gdb_async_info->port,
++                chr,
++                chr > ' ' && chr < 0x7F ? chr : ' ', ints_disabled ? 0 : 1));
++
++      if (gdb_async_info == NULL) {
++              gdb_hook_interrupt(&local_info, 0);
++      }
++
++      write_char(gdb_async_info, chr);        /* this routine will wait */
++      count = (chr == '#') ? 0 : count + 1;
++      if ((count == 2)) {     /* try to enable after */
++              if (ints_disabled & ok_to_enable_ints)
++                      kgdb_enable_ints_now(); /* try to enable after */
++
++              /* We do this a lot because, well we really want to get these
++               * interrupts.  The serial driver will clear these bits when it
++               * initializes the chip.  Every thing else it does is ok,
++               * but this.
++               */
++              if (!ints_disabled) {
++                      outb_px(gdb_async_info->port + UART_IER,
++                              gdb_async_info->IER);
++              }
++      }
++
++}                             /* tty_putDebugChar */
++
++/*
++ * This does nothing for the serial port, since it doesn't buffer.
++ */
++
++void tty_flushDebugChar(void)
++{
++}
++
++module_init(kgdb_enable_ints);
+--- linux-2.6.0/arch/i386/lib/Makefile 2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/lib/Makefile  2003-12-28 23:21:06.000000000 -0800
+@@ -9,4 +9,5 @@ lib-y = checksum.o delay.o \
+ lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
+ lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
++lib-$(CONFIG_KGDB) += kgdb_serial.o
+ lib-$(CONFIG_DEBUG_IOVIRT)  += iodebug.o
+--- linux-2.6.0/arch/i386/lib/usercopy.c       2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/lib/usercopy.c        2003-12-28 23:26:36.000000000 -0800
+@@ -76,7 +76,7 @@ do {                                                                    \
+  * and returns @count.
+  */
+ long
+-__strncpy_from_user(char *dst, const char __user *src, long count)
++__direct_strncpy_from_user(char *dst, const char __user *src, long count)
+ {
+       long res;
+       __do_strncpy_from_user(dst, src, count, res);
+@@ -102,7 +102,7 @@ __strncpy_from_user(char *dst, const cha
+  * and returns @count.
+  */
+ long
+-strncpy_from_user(char *dst, const char __user *src, long count)
++direct_strncpy_from_user(char *dst, const char __user *src, long count)
+ {
+       long res = -EFAULT;
+       if (access_ok(VERIFY_READ, src, 1))
+@@ -147,7 +147,7 @@ do {                                                                       \
+  * On success, this will be zero.
+  */
+ unsigned long
+-clear_user(void __user *to, unsigned long n)
++direct_clear_user(void __user *to, unsigned long n)
+ {
+       might_sleep();
+       if (access_ok(VERIFY_WRITE, to, n))
+@@ -167,7 +167,7 @@ clear_user(void __user *to, unsigned lon
+  * On success, this will be zero.
+  */
+ unsigned long
+-__clear_user(void __user *to, unsigned long n)
++__direct_clear_user(void __user *to, unsigned long n)
+ {
+       __do_clear_user(to, n);
+       return n;
+@@ -184,7 +184,7 @@ __clear_user(void __user *to, unsigned l
+  * On exception, returns 0.
+  * If the string is too long, returns a value greater than @n.
+  */
+-long strnlen_user(const char __user *s, long n)
++long direct_strnlen_user(const char __user *s, long n)
+ {
+       unsigned long mask = -__addr_ok(s);
+       unsigned long res, tmp;
+@@ -541,8 +541,10 @@ survive:
+                               goto survive;
+                       }
+-                      if (retval != 1)
++                      if (retval != 1) {
++                              up_read(&current->mm->mmap_sem);
+                               break;
++                      }
+                       maddr = kmap_atomic(pg, KM_USER0);
+                       memcpy(maddr + offset, from, len);
+@@ -573,3 +575,4 @@ unsigned long __copy_from_user_ll(void *
+               n = __copy_user_zeroing_intel(to, (const void *) from, n);
+       return n;
+ }
++
+--- linux-2.6.0/arch/i386/mach-es7000/es7000.c 2003-06-16 22:32:20.000000000 -0700
++++ 25/arch/i386/mach-es7000/es7000.c  2003-12-28 23:21:33.000000000 -0800
+@@ -51,8 +51,6 @@ struct mip_reg               *host_reg;
+ int                   mip_port;
+ unsigned long         mip_addr, host_addr;
+-static int            es7000_plat;
+-
+ /*
+  * Parse the OEM Table
+  */
+--- linux-2.6.0/arch/i386/Makefile     2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/Makefile      2003-12-28 23:21:06.000000000 -0800
+@@ -84,6 +84,9 @@ mcore-$(CONFIG_X86_ES7000)   := mach-es700
+ # default subarch .h files
+ mflags-y += -Iinclude/asm-i386/mach-default
++mflags-$(CONFIG_KGDB) += -gdwarf-2
++mflags-$(CONFIG_KGDB_MORE) += $(shell echo $(CONFIG_KGDB_OPTIONS) | sed -e 's/"//g')
++
+ head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
+ libs-y                                        += arch/i386/lib/
+--- linux-2.6.0/arch/i386/math-emu/fpu_system.h        2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/math-emu/fpu_system.h 2003-12-28 23:26:36.000000000 -0800
+@@ -15,6 +15,7 @@
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
++#include <asm/atomic_kmap.h>
+ /* This sets the pointer FPU_info to point to the argument part
+    of the stack frame of math_emulate() */
+@@ -22,7 +23,7 @@
+ /* s is always from a cpu register, and the cpu does bounds checking
+  * during register load --> no further bounds checks needed */
+-#define LDT_DESCRIPTOR(s)     (((struct desc_struct *)current->mm->context.ldt)[(s) >> 3])
++#define LDT_DESCRIPTOR(s)     (((struct desc_struct *)__kmap_atomic_vaddr(KM_LDT_PAGE0))[(s) >> 3])
+ #define SEG_D_SIZE(x)         ((x).b & (3 << 21))
+ #define SEG_G_BIT(x)          ((x).b & (1 << 23))
+ #define SEG_GRANULARITY(x)    (((x).b & (1 << 23)) ? 4096 : 1)
+--- linux-2.6.0/arch/i386/mm/extable.c 2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/mm/extable.c  2003-12-28 23:26:36.000000000 -0800
+@@ -6,6 +6,52 @@
+ #include <linux/module.h>
+ #include <linux/spinlock.h>
+ #include <asm/uaccess.h>
++#include <asm/pgtable.h>
++
++extern struct exception_table_entry __start___ex_table[];
++extern struct exception_table_entry __stop___ex_table[];
++
++/*
++ * The exception table needs to be sorted because we use the macros
++ * which put things into the exception table in a variety of sections
++ * as well as the init section and the main kernel text section.
++ */
++static inline void
++sort_ex_table(struct exception_table_entry *start,
++            struct exception_table_entry *finish)
++{
++      struct exception_table_entry el, *p, *q;
++
++      /* insertion sort */
++      for (p = start + 1; p < finish; ++p) {
++              /* start .. p-1 is sorted */
++              if (p[0].insn < p[-1].insn) {
++                      /* move element p down to its right place */
++                      el = *p;
++                      q = p;
++                      do {
++                              /* el comes before q[-1], move q[-1] up one */
++                              q[0] = q[-1];
++                              --q;
++                      } while (q > start && el.insn < q[-1].insn);
++                      *q = el;
++              }
++      }
++}
++
++void fixup_sort_exception_table(void)
++{
++      struct exception_table_entry *p;
++
++      /*
++       * Fix up the trampoline exception addresses:
++       */
++      for (p = __start___ex_table; p < __stop___ex_table; p++) {
++              p->insn = (unsigned long)(void *)p->insn;
++              p->fixup = (unsigned long)(void *)p->fixup;
++      }
++      sort_ex_table(__start___ex_table, __stop___ex_table);
++}
+ /* Simple binary search */
+ const struct exception_table_entry *
+@@ -15,13 +61,15 @@ search_extable(const struct exception_ta
+ {
+         while (first <= last) {
+               const struct exception_table_entry *mid;
+-              long diff;
+               mid = (last - first) / 2 + first;
+-              diff = mid->insn - value;
+-                if (diff == 0)
++              /*
++               * careful, the distance between entries can be
++               * larger than 2GB:
++               */
++                if (mid->insn == value)
+                         return mid;
+-                else if (diff < 0)
++                else if (mid->insn < value)
+                         first = mid+1;
+                 else
+                         last = mid-1;
+--- linux-2.6.0/arch/i386/mm/fault.c   2003-12-17 21:20:01.000000000 -0800
++++ 25/arch/i386/mm/fault.c    2003-12-28 23:26:36.000000000 -0800
+@@ -27,6 +27,7 @@
+ #include <asm/pgalloc.h>
+ #include <asm/hardirq.h>
+ #include <asm/desc.h>
++#include <asm/tlbflush.h>
+ extern void die(const char *,struct pt_regs *,long);
+@@ -104,8 +105,17 @@ static inline unsigned long get_segment_
+       if (seg & (1<<2)) {
+               /* Must lock the LDT while reading it. */
+               down(&current->mm->context.sem);
++#if 1
++              /* horrible hack for 4/4 disabled kernels.
++                 I'm not quite sure what the TLB flush is good for,
++                 it's mindlessly copied from the read_ldt code */
++              __flush_tlb_global();
++              desc = kmap(current->mm->context.ldt_pages[(seg&~7)/PAGE_SIZE]);
++              desc = (void *)desc + ((seg & ~7) % PAGE_SIZE);
++#else
+               desc = current->mm->context.ldt;
+               desc = (void *)desc + (seg & ~7);
++#endif
+       } else {
+               /* Must disable preemption while reading the GDT. */
+               desc = (u32 *)&cpu_gdt_table[get_cpu()];
+@@ -118,6 +128,9 @@ static inline unsigned long get_segment_
+                (desc[1] & 0xff000000);
+       if (seg & (1<<2)) { 
++#if 1
++              kunmap((void *)((unsigned long)desc & PAGE_MASK));
++#endif
+               up(&current->mm->context.sem);
+       } else
+               put_cpu();
+@@ -243,6 +256,19 @@ asmlinkage void do_page_fault(struct pt_
+        * (error_code & 4) == 0, and that the fault was not a
+        * protection error (error_code & 1) == 0.
+        */
++#ifdef CONFIG_X86_4G
++      /*
++       * On 4/4 all kernels faults are either bugs, vmalloc or prefetch
++       */
++      if (unlikely((regs->xcs & 3) == 0)) {
++              if (error_code & 3)
++                      goto bad_area_nosemaphore;
++
++              /* If it's vm86 fall through */
++              if (!(regs->eflags & VM_MASK))
++                      goto vmalloc_fault;
++      }
++#else
+       if (unlikely(address >= TASK_SIZE)) { 
+               if (!(error_code & 5))
+                       goto vmalloc_fault;
+@@ -252,6 +278,7 @@ asmlinkage void do_page_fault(struct pt_
+                */
+               goto bad_area_nosemaphore;
+       } 
++#endif
+       mm = tsk->mm;
+@@ -403,6 +430,12 @@ no_context:
+  * Oops. The kernel tried to access some bad page. We'll have to
+  * terminate things with extreme prejudice.
+  */
++#ifdef CONFIG_KGDB
++        if (!user_mode(regs)){
++                kgdb_handle_exception(14,SIGBUS, error_code, regs);
++                return;
++        }
++#endif
+       bust_spinlocks(1);
+--- linux-2.6.0/arch/i386/mm/highmem.c 2003-06-14 12:18:22.000000000 -0700
++++ 25/arch/i386/mm/highmem.c  2003-12-28 23:22:58.000000000 -0800
+@@ -30,6 +30,7 @@ void *kmap_atomic(struct page *page, enu
+       enum fixed_addresses idx;
+       unsigned long vaddr;
++      /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
+       inc_preempt_count();
+       if (page < highmem_start_page)
+               return page_address(page);
+@@ -54,6 +55,7 @@ void kunmap_atomic(void *kvaddr, enum km
+       if (vaddr < FIXADDR_START) { // FIXME
+               dec_preempt_count();
++              preempt_check_resched();
+               return;
+       }
+@@ -69,6 +71,7 @@ void kunmap_atomic(void *kvaddr, enum km
+ #endif
+       dec_preempt_count();
++      preempt_check_resched();
+ }
+ struct page *kmap_atomic_to_page(void *ptr)
+--- linux-2.6.0/arch/i386/mm/hugetlbpage.c     2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/i386/mm/hugetlbpage.c      2003-12-28 23:22:12.000000000 -0800
+@@ -534,7 +534,7 @@ int is_hugepage_mem_enough(size_t size)
+  * this far.
+  */
+ static struct page *hugetlb_nopage(struct vm_area_struct *vma,
+-                              unsigned long address, int unused)
++                              unsigned long address, int *unused)
+ {
+       BUG();
+       return NULL;
+--- linux-2.6.0/arch/i386/mm/init.c    2003-11-09 16:45:04.000000000 -0800
++++ 25/arch/i386/mm/init.c     2003-12-28 23:26:36.000000000 -0800
+@@ -26,6 +26,7 @@
+ #include <linux/bootmem.h>
+ #include <linux/slab.h>
+ #include <linux/proc_fs.h>
++#include <linux/efi.h>
+ #include <asm/processor.h>
+ #include <asm/system.h>
+@@ -39,125 +40,13 @@
+ #include <asm/tlb.h>
+ #include <asm/tlbflush.h>
+ #include <asm/sections.h>
++#include <asm/desc.h>
+ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+ unsigned long highstart_pfn, highend_pfn;
+ static int do_test_wp_bit(void);
+-/*
+- * Creates a middle page table and puts a pointer to it in the
+- * given global directory entry. This only returns the gd entry
+- * in non-PAE compilation mode, since the middle layer is folded.
+- */
+-static pmd_t * __init one_md_table_init(pgd_t *pgd)
+-{
+-      pmd_t *pmd_table;
+-              
+-#ifdef CONFIG_X86_PAE
+-      pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+-      set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
+-      if (pmd_table != pmd_offset(pgd, 0)) 
+-              BUG();
+-#else
+-      pmd_table = pmd_offset(pgd, 0);
+-#endif
+-
+-      return pmd_table;
+-}
+-
+-/*
+- * Create a page table and place a pointer to it in a middle page
+- * directory entry.
+- */
+-static pte_t * __init one_page_table_init(pmd_t *pmd)
+-{
+-      if (pmd_none(*pmd)) {
+-              pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+-              set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
+-              if (page_table != pte_offset_kernel(pmd, 0))
+-                      BUG();  
+-
+-              return page_table;
+-      }
+-      
+-      return pte_offset_kernel(pmd, 0);
+-}
+-
+-/*
+- * This function initializes a certain range of kernel virtual memory 
+- * with new bootmem page tables, everywhere page tables are missing in
+- * the given range.
+- */
+-
+-/*
+- * NOTE: The pagetables are allocated contiguous on the physical space 
+- * so we can cache the place of the first one and move around without 
+- * checking the pgd every time.
+- */
+-static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
+-{
+-      pgd_t *pgd;
+-      pmd_t *pmd;
+-      int pgd_idx, pmd_idx;
+-      unsigned long vaddr;
+-
+-      vaddr = start;
+-      pgd_idx = pgd_index(vaddr);
+-      pmd_idx = pmd_index(vaddr);
+-      pgd = pgd_base + pgd_idx;
+-
+-      for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
+-              if (pgd_none(*pgd)) 
+-                      one_md_table_init(pgd);
+-
+-              pmd = pmd_offset(pgd, vaddr);
+-              for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
+-                      if (pmd_none(*pmd)) 
+-                              one_page_table_init(pmd);
+-
+-                      vaddr += PMD_SIZE;
+-              }
+-              pmd_idx = 0;
+-      }
+-}
+-
+-/*
+- * This maps the physical memory to kernel virtual address space, a total 
+- * of max_low_pfn pages, by creating page tables starting from address 
+- * PAGE_OFFSET.
+- */
+-static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
+-{
+-      unsigned long pfn;
+-      pgd_t *pgd;
+-      pmd_t *pmd;
+-      pte_t *pte;
+-      int pgd_idx, pmd_idx, pte_ofs;
+-
+-      pgd_idx = pgd_index(PAGE_OFFSET);
+-      pgd = pgd_base + pgd_idx;
+-      pfn = 0;
+-
+-      for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
+-              pmd = one_md_table_init(pgd);
+-              if (pfn >= max_low_pfn)
+-                      continue;
+-              for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
+-                      /* Map with big pages if possible, otherwise create normal page tables. */
+-                      if (cpu_has_pse) {
+-                              set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
+-                              pfn += PTRS_PER_PTE;
+-                      } else {
+-                              pte = one_page_table_init(pmd);
+-
+-                              for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++)
+-                                      set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
+-                      }
+-              }
+-      }       
+-}
+-
+ static inline int page_kills_ppro(unsigned long pagenr)
+ {
+       if (pagenr >= 0x70000 && pagenr <= 0x7003F)
+@@ -165,12 +54,30 @@ static inline int page_kills_ppro(unsign
+       return 0;
+ }
++extern int is_available_memory(efi_memory_desc_t *);
++
+ static inline int page_is_ram(unsigned long pagenr)
+ {
+       int i;
++      unsigned long addr, end;
++
++      if (efi_enabled) {
++              efi_memory_desc_t *md;
++
++              for (i = 0; i < memmap.nr_map; i++) {
++                      md = &memmap.map[i];
++                      if (!is_available_memory(md))
++                              continue;
++                      addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT;
++                      end = (md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) >> PAGE_SHIFT;
++
++                      if ((pagenr >= addr) && (pagenr < end))
++                              return 1;
++              }
++              return 0;
++      }
+       for (i = 0; i < e820.nr_map; i++) {
+-              unsigned long addr, end;
+               if (e820.map[i].type != E820_RAM)       /* not usable memory */
+                       continue;
+@@ -187,11 +94,8 @@ static inline int page_is_ram(unsigned l
+       return 0;
+ }
+-#ifdef CONFIG_HIGHMEM
+ pte_t *kmap_pte;
+-pgprot_t kmap_prot;
+-EXPORT_SYMBOL(kmap_prot);
+ EXPORT_SYMBOL(kmap_pte);
+ #define kmap_get_fixmap_pte(vaddr)                                    \
+@@ -199,29 +103,7 @@ EXPORT_SYMBOL(kmap_pte);
+ void __init kmap_init(void)
+ {
+-      unsigned long kmap_vstart;
+-
+-      /* cache the first kmap pte */
+-      kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+-      kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+-
+-      kmap_prot = PAGE_KERNEL;
+-}
+-
+-void __init permanent_kmaps_init(pgd_t *pgd_base)
+-{
+-      pgd_t *pgd;
+-      pmd_t *pmd;
+-      pte_t *pte;
+-      unsigned long vaddr;
+-
+-      vaddr = PKMAP_BASE;
+-      page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+-
+-      pgd = swapper_pg_dir + pgd_index(vaddr);
+-      pmd = pmd_offset(pgd, vaddr);
+-      pte = pte_offset_kernel(pmd, vaddr);
+-      pkmap_page_table = pte; 
++      kmap_pte = kmap_get_fixmap_pte(__fix_to_virt(FIX_KMAP_BEGIN));
+ }
+ void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
+@@ -236,6 +118,8 @@ void __init one_highpage_init(struct pag
+               SetPageReserved(page);
+ }
++#ifdef CONFIG_HIGHMEM
++
+ #ifndef CONFIG_DISCONTIGMEM
+ void __init set_highmem_pages_init(int bad_ppro) 
+ {
+@@ -247,12 +131,9 @@ void __init set_highmem_pages_init(int b
+ #else
+ extern void set_highmem_pages_init(int);
+ #endif /* !CONFIG_DISCONTIGMEM */
+-
+ #else
+-#define kmap_init() do { } while (0)
+-#define permanent_kmaps_init(pgd_base) do { } while (0)
+-#define set_highmem_pages_init(bad_ppro) do { } while (0)
+-#endif /* CONFIG_HIGHMEM */
++# define set_highmem_pages_init(bad_ppro) do { } while (0)
++#endif
+ unsigned long __PAGE_KERNEL = _PAGE_KERNEL;
+@@ -262,30 +143,125 @@ unsigned long __PAGE_KERNEL = _PAGE_KERN
+ extern void __init remap_numa_kva(void);
+ #endif
+-static void __init pagetable_init (void)
++static __init void prepare_pagetables(pgd_t *pgd_base, unsigned long address)
++{
++      pgd_t *pgd;
++      pmd_t *pmd;
++      pte_t *pte;
++
++      pgd = pgd_base + pgd_index(address);
++      pmd = pmd_offset(pgd, address);
++      if (!pmd_present(*pmd)) {
++              pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
++              set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)));
++      }
++}
++
++static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
++{
++      unsigned long vaddr;
++
++      for (vaddr = start; vaddr != end; vaddr += PAGE_SIZE)
++              prepare_pagetables(pgd_base, vaddr);
++}
++
++void setup_identity_mappings(pgd_t *pgd_base, unsigned long start, unsigned long end)
+ {
+       unsigned long vaddr;
+-      pgd_t *pgd_base = swapper_pg_dir;
++      pgd_t *pgd;
++      int i, j, k;
++      pmd_t *pmd;
++      pte_t *pte, *pte_base;
++
++      pgd = pgd_base;
++
++      for (i = 0; i < PTRS_PER_PGD; pgd++, i++) {
++              vaddr = i*PGDIR_SIZE;
++              if (end && (vaddr >= end))
++                      break;
++              pmd = pmd_offset(pgd, 0);
++              for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
++                      vaddr = i*PGDIR_SIZE + j*PMD_SIZE;
++                      if (end && (vaddr >= end))
++                              break;
++                      if (vaddr < start)
++                              continue;
++                      if (cpu_has_pse) {
++                              unsigned long __pe;
++
++                              set_in_cr4(X86_CR4_PSE);
++                              boot_cpu_data.wp_works_ok = 1;
++                              __pe = _KERNPG_TABLE + _PAGE_PSE + vaddr - start;
++                              /* Make it "global" too if supported */
++                              if (cpu_has_pge) {
++                                      set_in_cr4(X86_CR4_PGE);
++#if !defined(CONFIG_X86_SWITCH_PAGETABLES)
++                                      __pe += _PAGE_GLOBAL;
++                                      __PAGE_KERNEL |= _PAGE_GLOBAL;
++#endif
++                              }
++                              set_pmd(pmd, __pmd(__pe));
++                              continue;
++                      }
++                      if (!pmd_present(*pmd))
++                              pte_base = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
++                      else
++                              pte_base = (pte_t *) page_address(pmd_page(*pmd));
++                      pte = pte_base;
++                      for (k = 0; k < PTRS_PER_PTE; pte++, k++) {
++                              vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE;
++                              if (end && (vaddr >= end))
++                                      break;
++                              if (vaddr < start)
++                                      continue;
++                              *pte = mk_pte_phys(vaddr-start, PAGE_KERNEL);
++                      }
++                      set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte_base)));
++              }
++      }
++}
++static void __init pagetable_init (void)
++{
++      unsigned long vaddr, end;
++      pgd_t *pgd_base;
+ #ifdef CONFIG_X86_PAE
+       int i;
+-      /* Init entries of the first-level page table to the zero page */
+-      for (i = 0; i < PTRS_PER_PGD; i++)
+-              set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
+ #endif
+-      /* Enable PSE if available */
+-      if (cpu_has_pse) {
+-              set_in_cr4(X86_CR4_PSE);
+-      }
++      /*
++       * This can be zero as well - no problem, in that case we exit
++       * the loops anyway due to the PTRS_PER_* conditions.
++       */
++      end = (unsigned long)__va(max_low_pfn*PAGE_SIZE);
+-      /* Enable PGE if available */
+-      if (cpu_has_pge) {
+-              set_in_cr4(X86_CR4_PGE);
+-              __PAGE_KERNEL |= _PAGE_GLOBAL;
++      pgd_base = swapper_pg_dir;
++#ifdef CONFIG_X86_PAE
++      /*
++       * It causes too many problems if there's no proper pmd set up
++       * for all 4 entries of the PGD - so we allocate all of them.
++       * PAE systems will not miss this extra 4-8K anyway ...
++       */
++      for (i = 0; i < PTRS_PER_PGD; i++) {
++              pmd_t *pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
++              set_pgd(pgd_base + i, __pgd(__pa(pmd) + 0x1));
+       }
++#endif
++      /*
++       * Set up lowmem-sized identity mappings at PAGE_OFFSET:
++       */
++      setup_identity_mappings(pgd_base, PAGE_OFFSET, end);
+-      kernel_physical_mapping_init(pgd_base);
++      /*
++       * Add flat-mode identity-mappings - SMP needs it when
++       * starting up on an AP from real-mode. (In the non-PAE
++       * case we already have these mappings through head.S.)
++       * All user-space mappings are explicitly cleared after
++       * SMP startup.
++       */
++#if CONFIG_SMP && CONFIG_X86_PAE
++      setup_identity_mappings(pgd_base, 0, 16*1024*1024);
++#endif
+       remap_numa_kva();
+       /*
+@@ -293,38 +269,64 @@ static void __init pagetable_init (void)
+        * created - mappings will be set by set_fixmap():
+        */
+       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+-      page_table_range_init(vaddr, 0, pgd_base);
++      fixrange_init(vaddr, 0, pgd_base);
+-      permanent_kmaps_init(pgd_base);
++#if CONFIG_HIGHMEM
++      {
++              pgd_t *pgd;
++              pmd_t *pmd;
++              pte_t *pte;
+-#ifdef CONFIG_X86_PAE
+-      /*
+-       * Add low memory identity-mappings - SMP needs it when
+-       * starting up on an AP from real-mode. In the non-PAE
+-       * case we already have these mappings through head.S.
+-       * All user-space mappings are explicitly cleared after
+-       * SMP startup.
+-       */
+-      pgd_base[0] = pgd_base[USER_PTRS_PER_PGD];
++              /*
++               * Permanent kmaps:
++               */
++              vaddr = PKMAP_BASE;
++              fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
++
++              pgd = swapper_pg_dir + pgd_index(vaddr);
++              pmd = pmd_offset(pgd, vaddr);
++              pte = pte_offset_kernel(pmd, vaddr);
++              pkmap_page_table = pte;
++      }
+ #endif
+ }
+-void zap_low_mappings (void)
++/*
++ * Clear kernel pagetables in a PMD_SIZE-aligned range.
++ */
++static void clear_mappings(pgd_t *pgd_base, unsigned long start, unsigned long end)
+ {
+-      int i;
++      unsigned long vaddr;
++      pgd_t *pgd;
++      pmd_t *pmd;
++      int i, j;
++
++      pgd = pgd_base;
++
++      for (i = 0; i < PTRS_PER_PGD; pgd++, i++) {
++              vaddr = i*PGDIR_SIZE;
++              if (end && (vaddr >= end))
++                      break;
++              pmd = pmd_offset(pgd, 0);
++              for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
++                      vaddr = i*PGDIR_SIZE + j*PMD_SIZE;
++                      if (end && (vaddr >= end))
++                              break;
++                      if (vaddr < start)
++                              continue;
++                      pmd_clear(pmd);
++              }
++      }
++      flush_tlb_all();
++}
++
++void __init zap_low_mappings(void)
++{
++      printk("zapping low mappings.\n");
+       /*
+        * Zap initial low-memory mappings.
+-       *
+-       * Note that "pgd_clear()" doesn't do it for
+-       * us, because pgd_clear() is a no-op on i386.
+        */
+-      for (i = 0; i < USER_PTRS_PER_PGD; i++)
+-#ifdef CONFIG_X86_PAE
+-              set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page)));
+-#else
+-              set_pgd(swapper_pg_dir+i, __pgd(0));
+-#endif
+-      flush_tlb_all();
++      clear_mappings(swapper_pg_dir, 0, 16*1024*1024);
+ }
+ #ifndef CONFIG_DISCONTIGMEM
+@@ -388,12 +390,6 @@ void __init paging_init(void)
+ void __init test_wp_bit(void)
+ {
+-      if (cpu_has_pse) {
+-              /* Ok, all PSE-capable CPUs are definitely handling the WP bit right. */
+-              boot_cpu_data.wp_works_ok = 1;
+-              return;
+-      }
+-
+       printk("Checking if this processor honours the WP bit even in supervisor mode... ");
+       /* Any page-aligned address will do, the test is non-destructive */
+@@ -428,6 +424,7 @@ extern void set_max_mapnr_init(void);
+ #endif /* !CONFIG_DISCONTIGMEM */
+ static struct kcore_list kcore_mem, kcore_vmalloc; 
++extern void fixup_sort_exception_table(void);
+ void __init mem_init(void)
+ {
+@@ -436,6 +433,8 @@ void __init mem_init(void)
+       int tmp;
+       int bad_ppro;
++      fixup_sort_exception_table();
++
+ #ifndef CONFIG_DISCONTIGMEM
+       if (!mem_map)
+               BUG();
+@@ -511,13 +510,18 @@ void __init mem_init(void)
+ #ifndef CONFIG_SMP
+       zap_low_mappings();
+ #endif
++      entry_trampoline_setup();
++      default_ldt_page = virt_to_page(default_ldt);
++      load_LDT(&init_mm.context);
+ }
+-kmem_cache_t *pgd_cache;
+-kmem_cache_t *pmd_cache;
++kmem_cache_t *pgd_cache, *pmd_cache, *kpmd_cache;
+ void __init pgtable_cache_init(void)
+ {
++      void (*ctor)(void *, kmem_cache_t *, unsigned long);
++      void (*dtor)(void *, kmem_cache_t *, unsigned long);
++
+       if (PTRS_PER_PMD > 1) {
+               pmd_cache = kmem_cache_create("pmd",
+                                       PTRS_PER_PMD*sizeof(pmd_t),
+@@ -527,13 +531,36 @@ void __init pgtable_cache_init(void)
+                                       NULL);
+               if (!pmd_cache)
+                       panic("pgtable_cache_init(): cannot create pmd cache");
++
++              if (TASK_SIZE > PAGE_OFFSET) {
++                      kpmd_cache = kmem_cache_create("kpmd",
++                                      PTRS_PER_PMD*sizeof(pmd_t),
++                                      0,
++                                      SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN,
++                                      kpmd_ctor,
++                                      NULL);
++                      if (!kpmd_cache)
++                              panic("pgtable_cache_init(): "
++                                              "cannot create kpmd cache");
++              }
+       }
++
++      if (PTRS_PER_PMD == 1 || TASK_SIZE <= PAGE_OFFSET)
++              ctor = pgd_ctor;
++      else
++              ctor = NULL;
++
++      if (PTRS_PER_PMD == 1 && TASK_SIZE <= PAGE_OFFSET)
++              dtor = pgd_dtor;
++      else
++              dtor = NULL;
++
+       pgd_cache = kmem_cache_create("pgd",
+                               PTRS_PER_PGD*sizeof(pgd_t),
+                               0,
+                               SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN,
+-                              pgd_ctor,
+-                              PTRS_PER_PMD == 1 ? pgd_dtor : NULL);
++                              ctor,
++                              dtor);
+       if (!pgd_cache)
+               panic("pgtable_cache_init(): Cannot create pgd cache");
+ }
+--- linux-2.6.0/arch/i386/mm/pgtable.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/arch/i386/mm/pgtable.c  2003-12-28 23:26:36.000000000 -0800
+@@ -21,6 +21,7 @@
+ #include <asm/e820.h>
+ #include <asm/tlb.h>
+ #include <asm/tlbflush.h>
++#include <asm/atomic_kmap.h>
+ void show_mem(void)
+ {
+@@ -157,11 +158,20 @@ void pmd_ctor(void *pmd, kmem_cache_t *c
+       memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
+ }
++void kpmd_ctor(void *__pmd, kmem_cache_t *cache, unsigned long flags)
++{
++      pmd_t *kpmd, *pmd;
++      kpmd = pmd_offset(&swapper_pg_dir[PTRS_PER_PGD-1],
++                              (PTRS_PER_PMD - NR_SHARED_PMDS)*PMD_SIZE);
++      pmd = (pmd_t *)__pmd + (PTRS_PER_PMD - NR_SHARED_PMDS);
++
++      memset(__pmd, 0, (PTRS_PER_PMD - NR_SHARED_PMDS)*sizeof(pmd_t));
++      memcpy(pmd, kpmd, NR_SHARED_PMDS*sizeof(pmd_t));
++}
++
+ /*
+- * List of all pgd's needed for non-PAE so it can invalidate entries
+- * in both cached and uncached pgd's; not needed for PAE since the
+- * kernel pmd is shared. If PAE were not to share the pmd a similar
+- * tactic would be needed. This is essentially codepath-based locking
++ * List of all pgd's needed so it can invalidate entries in both cached
++ * and uncached pgd's. This is essentially codepath-based locking
+  * against pageattr.c; it is the unique case in which a valid change
+  * of kernel pagetables can't be lazily synchronized by vmalloc faults.
+  * vmalloc faults work because attached pagetables are never freed.
+@@ -170,30 +180,60 @@ void pmd_ctor(void *pmd, kmem_cache_t *c
+  * could be used. The locking scheme was chosen on the basis of
+  * manfred's recommendations and having no core impact whatsoever.
+  * -- wli
++ *
++ * The entire issue goes away when XKVA is configured.
+  */
+ spinlock_t pgd_lock = SPIN_LOCK_UNLOCKED;
+ LIST_HEAD(pgd_list);
+-void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
++/*
++ * This is not that hard to figure out.
++ * (a) PTRS_PER_PMD == 1 means non-PAE.
++ * (b) PTRS_PER_PMD > 1 means PAE.
++ * (c) TASK_SIZE > PAGE_OFFSET means XKVA.
++ * (d) TASK_SIZE <= PAGE_OFFSET means non-XKVA.
++ *
++ * Do *NOT* back out the preconstruction like the patch I'm cleaning
++ * up after this very instant did, or at all, for that matter.
++ * This is never called when PTRS_PER_PMD > 1 && TASK_SIZE > PAGE_OFFSET.
++ * -- wli
++ */
++void pgd_ctor(void *__pgd, kmem_cache_t *cache, unsigned long unused)
+ {
++      pgd_t *pgd = (pgd_t *)__pgd;
+       unsigned long flags;
+-      if (PTRS_PER_PMD == 1)
+-              spin_lock_irqsave(&pgd_lock, flags);
++      if (PTRS_PER_PMD == 1) {
++              if (TASK_SIZE <= PAGE_OFFSET)
++                      spin_lock_irqsave(&pgd_lock, flags);
++              else
++                      memcpy(&pgd[PTRS_PER_PGD - NR_SHARED_PMDS],
++                              &swapper_pg_dir[PTRS_PER_PGD - NR_SHARED_PMDS],
++                              NR_SHARED_PMDS * sizeof(pgd_t));
++      }
+-      memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD,
+-                      swapper_pg_dir + USER_PTRS_PER_PGD,
+-                      (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
++      if (TASK_SIZE <= PAGE_OFFSET)
++              memcpy(pgd + USER_PTRS_PER_PGD,
++                      swapper_pg_dir + USER_PTRS_PER_PGD,
++                      (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+       if (PTRS_PER_PMD > 1)
+               return;
+-      list_add(&virt_to_page(pgd)->lru, &pgd_list);
+-      spin_unlock_irqrestore(&pgd_lock, flags);
+-      memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
++      if (TASK_SIZE > PAGE_OFFSET)
++              memset(pgd, 0, (PTRS_PER_PGD - NR_SHARED_PMDS)*sizeof(pgd_t));
++      else {
++              list_add(&virt_to_page(pgd)->lru, &pgd_list);
++              spin_unlock_irqrestore(&pgd_lock, flags);
++              memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
++      }
+ }
+-/* never called when PTRS_PER_PMD > 1 */
++/*
++ * Never called when PTRS_PER_PMD > 1 || TASK_SIZE > PAGE_OFFSET
++ * for with PAE we would list_del() multiple times, and for non-PAE
++ * with XKVA all the AGP pgd shootdown code is unnecessary.
++ */
+ void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
+ {
+       unsigned long flags; /* can be called from interrupt context */
+@@ -203,6 +243,12 @@ void pgd_dtor(void *pgd, kmem_cache_t *c
+       spin_unlock_irqrestore(&pgd_lock, flags);
+ }
++/*
++ * See the comments above pgd_ctor() wrt. preconstruction.
++ * Do *NOT* memcpy() here. If you do, you back out important
++ * anti- cache pollution code.
++ *
++ */
+ pgd_t *pgd_alloc(struct mm_struct *mm)
+ {
+       int i;
+@@ -211,15 +257,33 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
+       if (PTRS_PER_PMD == 1 || !pgd)
+               return pgd;
++      /*
++       * In the 4G userspace case alias the top 16 MB virtual
++       * memory range into the user mappings as well (these
++       * include the trampoline and CPU data structures).
++       */
+       for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
+-              pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
++              kmem_cache_t *cache;
++              pmd_t *pmd;
++
++              if (TASK_SIZE > PAGE_OFFSET && i == USER_PTRS_PER_PGD - 1)
++                      cache = kpmd_cache;
++              else
++                      cache = pmd_cache;
++
++              pmd = kmem_cache_alloc(cache, GFP_KERNEL);
+               if (!pmd)
+                       goto out_oom;
+               set_pgd(&pgd[i], __pgd(1 + __pa((u64)((u32)pmd))));
+       }
+-      return pgd;
++      return pgd;
+ out_oom:
++      /*
++       * we don't have to handle the kpmd_cache here, since it's the
++       * last allocation, and has either nothing to free or when it
++       * succeeds the whole operation succeeds.
++       */
+       for (i--; i >= 0; i--)
+               kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
+       kmem_cache_free(pgd_cache, pgd);
+@@ -230,10 +294,29 @@ void pgd_free(pgd_t *pgd)
+ {
+       int i;
+-      /* in the PAE case user pgd entries are overwritten before usage */
+-      if (PTRS_PER_PMD > 1)
+-              for (i = 0; i < USER_PTRS_PER_PGD; ++i)
+-                      kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
+       /* in the non-PAE case, clear_page_tables() clears user pgd entries */
++      if (PTRS_PER_PMD == 1)
++              goto out_free;
++
++      /* in the PAE case user pgd entries are overwritten before usage */
++      for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
++              kmem_cache_t *cache;
++              pmd_t *pmd = __va(pgd_val(pgd[i]) - 1);
++
++              /*
++               * only userspace pmd's are cleared for us
++               * by mm/memory.c; it's a slab cache invariant
++               * that we must separate the kernel pmd slab
++               * all times, else we'll have bad pmd's.
++               */
++              if (TASK_SIZE > PAGE_OFFSET && i == USER_PTRS_PER_PGD - 1)
++                      cache = kpmd_cache;
++              else
++                      cache = pmd_cache;
++
++              kmem_cache_free(cache, pmd);
++      }
++out_free:
+       kmem_cache_free(pgd_cache, pgd);
+ }
++
+--- linux-2.6.0/arch/i386/pci/acpi.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/arch/i386/pci/acpi.c    2003-12-28 23:21:33.000000000 -0800
+@@ -18,7 +18,7 @@ static int __init pci_acpi_init(void)
+       if (pcibios_scanned)
+               return 0;
+-      if (!(pci_probe & PCI_NO_ACPI_ROUTING)) {
++      if (!acpi_noirq) {
+               if (!acpi_pci_irq_init()) {
+                       printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
+                       printk(KERN_INFO "PCI: if you experience problems, try using option 'pci=noacpi' or even 'acpi=off'\n");
+@@ -31,15 +31,4 @@ static int __init pci_acpi_init(void)
+       return 0;
+ }
+-
+-/*
+- * pci_disable_acpi()
+- * act like pci=noacpi seen on command line
+- * called by DMI blacklist code
+- */
+-__init void pci_disable_acpi(void)
+-{
+-        pci_probe |= PCI_NO_ACPI_ROUTING;
+-}
+-
+ subsys_initcall(pci_acpi_init);
+--- linux-2.6.0/arch/i386/pci/common.c 2003-09-08 13:58:55.000000000 -0700
++++ 25/arch/i386/pci/common.c  2003-12-28 23:21:33.000000000 -0800
+@@ -9,6 +9,7 @@
+ #include <linux/ioport.h>
+ #include <linux/init.h>
++#include <asm/acpi.h>
+ #include <asm/segment.h>
+ #include <asm/io.h>
+ #include <asm/smp.h>
+@@ -197,12 +198,10 @@ char * __devinit  pcibios_setup(char *st
+               return NULL;
+       }
+ #endif
+-#ifdef CONFIG_ACPI_PCI
+       else if (!strcmp(str, "noacpi")) {
+-              pci_probe |= PCI_NO_ACPI_ROUTING;
++              acpi_noirq_set();
+               return NULL;
+       }
+-#endif
+ #ifndef CONFIG_X86_VISWS
+       else if (!strcmp(str, "usepirqmask")) {
+               pci_probe |= PCI_USE_PIRQ_MASK;
+--- linux-2.6.0/arch/i386/pci/fixup.c  2003-08-08 22:55:10.000000000 -0700
++++ 25/arch/i386/pci/fixup.c   2003-12-28 23:26:29.000000000 -0800
+@@ -6,27 +6,52 @@
+ #include <linux/init.h>
+ #include "pci.h"
++static void __devinit i450nx_scan_bus(struct pci_bus *parent, u8 busnr)
++{
++      struct list_head *tmp;
++
++      pci_scan_bus(busnr, &pci_root_ops, NULL);
++
++      list_for_each(tmp, &parent->children) {
++              u8 childnr;
++              struct pci_dev *dev = pci_dev_b(tmp);
++
++              if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE)
++                      continue;
++              pci_read_config_byte(dev, PCI_PRIMARY_BUS, &childnr);
++              if (childnr != busnr)
++                      continue;
++
++              printk(KERN_WARNING "PCI: Removing fake PCI bridge %s\n",
++                              pci_name(dev));
++              pci_remove_bus_device(dev);
++              break;
++      }
++}
+ static void __devinit pci_fixup_i450nx(struct pci_dev *d)
+ {
+       /*
+        * i450NX -- Find and scan all secondary buses on all PXB's.
++       * Some manufacturers added fake PCI-PCI bridges that also point
++       * to the peer busses.  Look for them and delete them.
+        */
+       int pxb, reg;
+       u8 busno, suba, subb;
+-      printk(KERN_WARNING "PCI: Searching for i450NX host bridges on %s\n", pci_name(d));
++      printk(KERN_NOTICE "PCI: Searching for i450NX host bridges on %s\n", pci_name(d));
+       reg = 0xd0;
+-      for(pxb=0; pxb<2; pxb++) {
++      for (pxb = 0; pxb < 2; pxb++) {
+               pci_read_config_byte(d, reg++, &busno);
+               pci_read_config_byte(d, reg++, &suba);
+               pci_read_config_byte(d, reg++, &subb);
+               DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
+               if (busno)
+-                      pci_scan_bus(busno, &pci_root_ops, NULL);       /* Bus A */
++                      i450nx_scan_bus(d->bus, busno);         /* Bus A */
+               if (suba < subb)
+-                      pci_scan_bus(suba+1, &pci_root_ops, NULL);      /* Bus B */
++                      i450nx_scan_bus(d->bus, suba+1);        /* Bus B */
+       }
++
+       pcibios_last_bus = -1;
+ }
+@@ -187,6 +212,22 @@ static void __devinit pci_fixup_transpar
+               dev->transparent = 1;
+ }
++/*
++ * Halt Disconnect and Stop Grant Disconnect (bit 4 at offset 0x6F)
++ * must be disabled when APIC is used (or lockups will happen).
++ */
++static void __devinit pci_fixup_nforce2_disconnect(struct pci_dev *d)
++{
++      u8 t;
++
++      pci_read_config_byte(d, 0x6F, &t);
++      if (t & 0x10) {
++              printk(KERN_INFO "PCI: disabling nForce2 Halt Disconnect"
++                               " and Stop Grant Disconnect\n");
++              pci_write_config_byte(d, 0x6F, (t & 0xef));
++      }
++}
++
+ struct pci_fixup pcibios_fixups[] = {
+       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82451NX,    pci_fixup_i450nx },
+       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82454GX,    pci_fixup_i450gx },
+@@ -205,5 +246,6 @@ struct pci_fixup pcibios_fixups[] = {
+       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_8367_0,       pci_fixup_via_northbridge_bug },
+       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_NCR,      PCI_DEVICE_ID_NCR_53C810,       pci_fixup_ncr53c810 },
+       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_ANY_ID,                     pci_fixup_transparent_bridge },
++      { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_NVIDIA,   PCI_DEVICE_ID_NVIDIA_NFORCE2,   pci_fixup_nforce2_disconnect },
+       { 0 }
+ };
+--- linux-2.6.0/arch/i386/pci/irq.c    2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/i386/pci/irq.c     2003-12-28 23:22:07.000000000 -0800
+@@ -455,7 +455,10 @@ static __init int intel_router_probe(str
+ #if 0 /* Let's see what chip this is supposed to be ... */
+       /* We must not touch 440GX even if we have tables. 440GX has
+          different IRQ routing weirdness */
+-      if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82440GX, NULL))
++      if (    pci_find_device(PCI_VENDOR_ID_INTEL,
++                              PCI_DEVICE_ID_INTEL_82443GX_0, NULL) ||
++              pci_find_device(PCI_VENDOR_ID_INTEL,
++                              PCI_DEVICE_ID_INTEL_82443GX_2, NULL))
+               return 0;
+ #endif
+@@ -695,9 +698,10 @@ static struct irq_info *pirq_get_info(st
+       return NULL;
+ }
+-static irqreturn_t pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t
++pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+ {
+-      return IRQ_NONE;
++      return IRQ_HANDLED;
+ }
+ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
+@@ -813,8 +817,10 @@ static int pcibios_lookup_irq(struct pci
+                       if ( dev2->irq && dev2->irq != irq && \
+                       (!(pci_probe & PCI_USE_PIRQ_MASK) || \
+                       ((1 << dev2->irq) & mask)) ) {
++#ifndef CONFIG_PCI_USE_VECTOR
+                               printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n",
+                                      pci_name(dev2), dev2->irq, irq);
++#endif
+                               continue;
+                       }
+                       dev2->irq = irq;
+@@ -878,6 +884,10 @@ static void __init pcibios_fixup_irqs(vo
+                                                       bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
+                               }
+                               if (irq >= 0) {
++                                      if (use_pci_vector() &&
++                                              !platform_legacy_irq(irq))
++                                              irq = IO_APIC_VECTOR(irq);
++
+                                       printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
+                                               dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
+                                       dev->irq = irq;
+--- linux-2.6.0/arch/i386/pci/pci.h    2003-06-22 12:04:43.000000000 -0700
++++ 25/arch/i386/pci/pci.h     2003-12-28 23:21:33.000000000 -0800
+@@ -22,7 +22,6 @@
+ #define PCI_ASSIGN_ROMS               0x1000
+ #define PCI_BIOS_IRQ_SCAN     0x2000
+ #define PCI_ASSIGN_ALL_BUSSES 0x4000
+-#define PCI_NO_ACPI_ROUTING   0x8000
+ extern unsigned int pci_probe;
+--- linux-2.6.0/arch/ia64/defconfig    2003-11-09 16:45:05.000000000 -0800
++++ 25/arch/ia64/defconfig     2003-12-28 23:21:45.000000000 -0800
+@@ -48,7 +48,6 @@ CONFIG_IA64_HP_ZX1=y
+ CONFIG_IA64_PAGE_SIZE_16KB=y
+ # CONFIG_IA64_PAGE_SIZE_64KB is not set
+ CONFIG_ACPI=y
+-CONFIG_ACPI_EFI=y
+ CONFIG_ACPI_INTERPRETER=y
+ CONFIG_ACPI_KERNEL_CONFIG=y
+ CONFIG_IA64_L1_CACHE_SHIFT=7
+@@ -76,6 +75,7 @@ CONFIG_IA32_SUPPORT=y
+ CONFIG_COMPAT=y
+ CONFIG_PERFMON=y
+ CONFIG_IA64_PALINFO=y
++CONFIG_EFI=y
+ CONFIG_EFI_VARS=y
+ CONFIG_NR_CPUS=16
+ CONFIG_BINFMT_ELF=y
+--- linux-2.6.0/arch/ia64/ia32/binfmt_elf32.c  2003-10-25 14:45:44.000000000 -0700
++++ 25/arch/ia64/ia32/binfmt_elf32.c   2003-12-28 23:22:12.000000000 -0800
+@@ -60,10 +60,12 @@ extern struct page *ia32_shared_page[];
+ extern unsigned long *ia32_gdt;
+ struct page *
+-ia32_install_shared_page (struct vm_area_struct *vma, unsigned long address, int no_share)
++ia32_install_shared_page (struct vm_area_struct *vma, unsigned long address, int *type)
+ {
+       struct page *pg = ia32_shared_page[smp_processor_id()];
+       get_page(pg);
++      if (type)
++              *type = VM_FAULT_MINOR;
+       return pg;
+ }
+--- linux-2.6.0/arch/ia64/Kconfig      2003-11-09 16:45:05.000000000 -0800
++++ 25/arch/ia64/Kconfig       2003-12-28 23:26:35.000000000 -0800
+@@ -164,11 +164,6 @@ config ACPI
+         The ACPI Sourceforge project may also be of interest:
+         <http://sf.net/projects/acpi/>
+-config ACPI_EFI
+-      bool
+-      depends on !IA64_HP_SIM
+-      default y
+-
+ config ACPI_INTERPRETER
+       bool
+       depends on !IA64_HP_SIM
+@@ -404,6 +399,11 @@ config IA64_SALINFO
+         To use this option, you have to ensure that the "/proc file system
+         support" (CONFIG_PROC_FS) is enabled, too.
++config EFI
++      bool
++      depends on !IA64_HP_SIM
++      default y
++
+ config EFI_VARS
+       tristate "/proc/efi/vars support"
+       help
+@@ -670,6 +670,13 @@ config DEBUG_INFO
+         Say Y here only if you plan to use gdb to debug the kernel.
+         If you don't debug the kernel, you can say N.
+         
++config LOCKMETER
++       bool "Kernel lock metering"
++       depends on SMP
++       help
++         Say Y to enable kernel lock metering, which adds overhead to SMP locks,
++         but allows you to see various statistics using the lockstat command.
++
+ endmenu
+ source "security/Kconfig"
+--- linux-2.6.0/arch/ia64/kernel/irq.c 2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/ia64/kernel/irq.c  2003-12-28 23:22:10.000000000 -0800
+@@ -160,18 +160,20 @@ atomic_t irq_mis_count;
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i, j;
++      int j, i = *(loff_t *) v;
+       struct irqaction * action;
+       irq_desc_t *idesc;
+       unsigned long flags;
+-      seq_puts(p, "           ");
+-      for (j=0; j<NR_CPUS; j++)
+-              if (cpu_online(j))
+-                      seq_printf(p, "CPU%d       ",j);
+-      seq_putc(p, '\n');
++      if (i == 0) {
++              seq_puts(p, "           ");
++              for (j=0; j<NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "CPU%d       ",j);
++              seq_putc(p, '\n');
++      }
+-      for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               idesc = irq_descp(i);
+               spin_lock_irqsave(&idesc->lock, flags);
+               action = idesc->action;
+@@ -194,25 +196,26 @@ int show_interrupts(struct seq_file *p, 
+               seq_putc(p, '\n');
+ skip:
+               spin_unlock_irqrestore(&idesc->lock, flags);
+-      }
+-      seq_puts(p, "NMI: ");
+-      for (j = 0; j < NR_CPUS; j++)
+-              if (cpu_online(j))
+-                      seq_printf(p, "%10u ", nmi_count(j));
+-      seq_putc(p, '\n');
++      } else if (i == NR_IRQS) {
++              seq_puts(p, "NMI: ");
++              for (j = 0; j < NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "%10u ", nmi_count(j));
++              seq_putc(p, '\n');
+ #ifdef CONFIG_X86_LOCAL_APIC
+-      seq_puts(p, "LOC: ");
+-      for (j = 0; j < NR_CPUS; j++)
+-              if (cpu_online(j))
+-                      seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs);
+-      seq_putc(p, '\n');
++              seq_puts(p, "LOC: ");
++              for (j = 0; j < NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs);
++              seq_putc(p, '\n');
+ #endif
+-      seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
++              seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+ #ifdef CONFIG_X86_IO_APIC
+ #ifdef APIC_MISMATCH_DEBUG
+-      seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
++              seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+ #endif
+ #endif
++      }
+       return 0;
+ }
+@@ -910,47 +913,6 @@ int setup_irq(unsigned int irq, struct i
+ static struct proc_dir_entry * root_irq_dir;
+ static struct proc_dir_entry * irq_dir [NR_IRQS];
+-#define HEX_DIGITS (2*sizeof(cpumask_t))
+-
+-static unsigned int parse_hex_value(const char *buffer,
+-              unsigned long count, cpumask_t *ret)
+-{
+-      unsigned char hexnum[HEX_DIGITS];
+-      cpumask_t value = CPU_MASK_NONE;
+-      unsigned long i;
+-
+-      if (!count)
+-              return -EINVAL;
+-      if (count > HEX_DIGITS)
+-              count = HEX_DIGITS;
+-      if (copy_from_user(hexnum, buffer, count))
+-              return -EFAULT;
+-
+-      /*
+-       * Parse the first 8 characters as a hex string, any non-hex char
+-       * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+-       */
+-      for (i = 0; i < count; i++) {
+-              unsigned int c = hexnum[i];
+-              int k;
+-
+-              switch (c) {
+-                      case '0' ... '9': c -= '0'; break;
+-                      case 'a' ... 'f': c -= 'a'-10; break;
+-                      case 'A' ... 'F': c -= 'A'-10; break;
+-              default:
+-                      goto out;
+-              }
+-              cpus_shift_left(value, value, 4);
+-              for (k = 0; k < 4; ++k)
+-                      if (test_bit(k, (unsigned long *)&c))
+-                              cpu_set(k, value);
+-      }
+-out:
+-      *ret = value;
+-      return 0;
+-}
+-
+ #ifdef CONFIG_SMP
+ static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+@@ -974,20 +936,10 @@ void set_irq_affinity_info (unsigned int
+ static int irq_affinity_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      int k, len;
+-      cpumask_t tmp = irq_affinity[(long)data];
+-
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, irq_affinity[(long)data]);
++      if (count - len < 2)
+               return -EINVAL;
+-
+-      len = 0;
+-      for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-              int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
+-              len += j;
+-              page += j;
+-              cpus_shift_right(tmp, tmp, 16);
+-      }
+-      len += sprintf(page, "\n");
++      len += sprintf(page + len, "\n");
+       return len;
+ }
+@@ -1011,7 +963,7 @@ static int irq_affinity_write_proc (stru
+       } else
+               redir = 0;
+-      err = parse_hex_value(buf, count, &new_value);
++      err = cpumask_parse(buf, count - (buf-buffer), new_value);
+       if (err)
+               return err;
+@@ -1033,19 +985,10 @@ static int irq_affinity_write_proc (stru
+ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      cpumask_t *mask = (cpumask_t *)data;
+-      int k, len = 0;
+-
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, *(cpumask_t *)data);
++      if (count - len < 2)
+               return -EINVAL;
+-
+-      for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-              int j = sprintf(page, "%04hx", (u16)cpus_coerce(*mask));
+-              len += j;
+-              page += j;
+-              cpus_shift_right(*mask, *mask, 16);
+-      }
+-      len += sprintf(page, "\n");
++      len += sprintf(page + len, "\n");
+       return len;
+ }
+@@ -1056,7 +999,7 @@ static int prof_cpu_mask_write_proc (str
+       unsigned long full_count = count, err;
+       cpumask_t new_value;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       if (err)
+               return err;
+--- linux-2.6.0/arch/ia64/kernel/perfmon.c     2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/ia64/kernel/perfmon.c      2003-12-28 23:21:18.000000000 -0800
+@@ -2157,6 +2157,7 @@ pfm_alloc_fd(struct file **cfile)
+       d_add(file->f_dentry, inode);
+       file->f_vfsmnt = mntget(pfmfs_mnt);
++      file->f_mapping = inode->i_mapping;
+       file->f_op    = &pfm_file_ops;
+       file->f_mode  = FMODE_READ;
+--- linux-2.6.0/arch/ia64/kernel/setup.c       2003-11-09 16:45:05.000000000 -0800
++++ 25/arch/ia64/kernel/setup.c        2003-12-28 23:21:45.000000000 -0800
+@@ -54,6 +54,10 @@
+ # error "struct cpuinfo_ia64 too big!"
+ #endif
++#ifdef CONFIG_EFI
++int efi_enabled = 1;
++#endif
++
+ #ifdef CONFIG_SMP
+ unsigned long __per_cpu_offset[NR_CPUS];
+ #endif
+--- linux-2.6.0/arch/ia64/mm/hugetlbpage.c     2003-10-17 15:58:03.000000000 -0700
++++ 25/arch/ia64/mm/hugetlbpage.c      2003-12-28 23:22:12.000000000 -0800
+@@ -518,7 +518,7 @@ int is_hugepage_mem_enough(size_t size)
+       return 1;
+ }
+-static struct page *hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int unused)
++static struct page *hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int *unused)
+ {
+       BUG();
+       return NULL;
+--- linux-2.6.0/arch/m68k/Kconfig      2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/m68k/Kconfig       2003-12-28 23:23:06.000000000 -0800
+@@ -1025,7 +1025,7 @@ config WATCHDOG
+         implementation entirely in software (which can sometimes fail to
+         reboot the machine) and a driver for hardware watchdog boards, which
+         are more robust and can also keep track of the temperature inside
+-        your computer. For details, read <file:Documentation/watchdog.txt>
++        your computer. For details, read <file:Documentation/watchdog/watchdog.txt>
+         in the kernel source.
+         The watchdog is usually used together with the watchdog daemon
+--- linux-2.6.0/arch/m68k/kernel/ints.c        2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/m68k/kernel/ints.c 2003-12-28 23:22:06.000000000 -0800
+@@ -253,19 +253,18 @@ asmlinkage void process_int(unsigned lon
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i;
++      int i = *(loff_t *) v;
+       /* autovector interrupts */
+       if (mach_default_handler) {
+-              for (i = 0; i < SYS_IRQS; i++) {
++              if (i < SYS_IRQS) {
+                       seq_printf(p, "auto %2d: %10u ", i,
+                                      i ? kstat_cpu(0).irqs[i] : num_spurious);
+                       seq_puts(p, "  ");
+                       seq_printf(p, "%s\n", irq_list[i].devname);
+               }
+-      }
+-
+-      mach_get_irq_list(p, v);
++      } else if (i == SYS_IRQS)
++              mach_get_irq_list(p, v);
+       return 0;
+ }
+--- linux-2.6.0/arch/m68knommu/platform/5307/ints.c    2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/m68knommu/platform/5307/ints.c     2003-12-28 23:22:06.000000000 -0800
+@@ -254,9 +254,9 @@ asmlinkage void process_int(unsigned lon
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i;
++      int i = *(loff_t *) v;
+-      for (i = 0; i < NR_IRQS; i++) {
++      if (i < NR_IRQS) {
+               if (irq_list[i].flags & IRQ_FLG_STD)
+                       continue;
+@@ -269,7 +269,7 @@ int show_interrupts(struct seq_file *p, 
+               seq_printf(p, "%s\n", irq_list[i].devname);
+       }
+-      if (mach_get_irq_list)
++      if (i == NR_IRQS && mach_get_irq_list)
+               mach_get_irq_list(p, v);
+       return(0);
+ }
+--- linux-2.6.0/arch/m68knommu/platform/68328/ints.c   2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/m68knommu/platform/68328/ints.c    2003-12-28 23:22:06.000000000 -0800
+@@ -198,9 +198,9 @@ EXPORT_SYMBOL(free_irq);
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i;
++      int i = *(loff_t *) v;
+-      for (i = 0; i < NR_IRQS; i++) {
++      if (i < NR_IRQS) {
+               if (int_irq_list[i].flags & IRQ_FLG_STD)
+                       continue;
+@@ -211,7 +211,8 @@ int show_interrupts(struct seq_file *p, 
+                       seq_printf(p, "  ");
+               seq_printf(p, "%s\n", int_irq_list[i].devname);
+       }
+-      seq_printf(p, "   : %10u   spurious\n", num_spurious);
++      if (i == NR_IRQS)
++              seq_printf(p, "   : %10u   spurious\n", num_spurious);
+       return 0;
+ }
+--- linux-2.6.0/arch/m68knommu/platform/68360/ints.c   2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/m68knommu/platform/68360/ints.c    2003-12-28 23:22:06.000000000 -0800
+@@ -278,9 +278,9 @@ void M68360_disable_irq(unsigned int irq
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i;
++      int i = *(loff_t *) v;
+-      for (i = 0; i < NR_IRQS; i++) {
++      if (i < NR_IRQS) {
+               if (int_irq_list[i].flags & IRQ_FLG_STD)
+                       continue;
+@@ -291,7 +291,8 @@ int show_interrupts(struct seq_file *p, 
+                       seq_printf(p, "  ");
+               seq_printf(p, "%s\n", int_irq_list[i].devname);
+       }
+-      seq_printf(p, "   : %10u   spurious\n", num_spurious);
++      if (i == NR_IRQS)
++              seq_printf(p, "   : %10u   spurious\n", num_spurious);
+       return 0;
+ }
+--- linux-2.6.0/arch/mips/Kconfig      2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/mips/Kconfig       2003-12-28 23:23:06.000000000 -0800
+@@ -1261,8 +1261,8 @@ config SOUND
+         You want to read the Sound-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>. General information about
+         the modular sound system is contained in the files
+-        <file:Documentation/sound/Introduction>.  The file
+-        <file:Documentation/sound/README.OSS> contains some slightly
++        <file:Documentation/sound/oss/Introduction>.  The file
++        <file:Documentation/sound/oss/README.OSS> contains some slightly
+         outdated but still useful information as well.
+         If you have a PnP sound card and you want to configure it at boot
+@@ -1270,7 +1270,7 @@ config SOUND
+         <http://www.roestock.demon.co.uk/isapnptools/>), then you need to
+         compile the sound card support as a module and load that module
+         after the PnP configuration is finished. To do this, choose M here
+-        and read <file:Documentation/sound/README.modules>; the module
++        and read <file:Documentation/sound/oss/README.modules>; the module
+         will be called soundcore.
+         I'm told that even without a sound card, you can make your computer
+--- linux-2.6.0/arch/mips/kernel/irq.c 2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/mips/kernel/irq.c  2003-12-28 23:22:10.000000000 -0800
+@@ -85,17 +85,19 @@ atomic_t irq_err_count;
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i, j;
++      int i = *(loff_t *) v, j;
+       struct irqaction * action;
+       unsigned long flags;
+-      seq_printf(p, "           ");
+-      for (j=0; j<NR_CPUS; j++)
+-              if (cpu_online(j))
+-                      seq_printf(p, "CPU%d       ",j);
+-      seq_putc(p, '\n');
++      if (i == 0) {
++              seq_printf(p, "           ");
++              for (j=0; j<NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "CPU%d       ",j);
++              seq_putc(p, '\n');
++      }
+-      for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               spin_lock_irqsave(&irq_desc[i].lock, flags);
+               action = irq_desc[i].action;
+               if (!action) 
+@@ -117,10 +119,10 @@ int show_interrupts(struct seq_file *p, 
+               seq_putc(p, '\n');
+ skip:
+               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
++      } else if (i == NR_IRQS) {
++              seq_putc(p, '\n');
++              seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+       }
+-      seq_putc(p, '\n');
+-      seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+-
+       return 0;
+ }
+@@ -825,45 +827,6 @@ EXPORT_SYMBOL(probe_irq_mask);
+ static struct proc_dir_entry * root_irq_dir;
+ static struct proc_dir_entry * irq_dir [NR_IRQS];
+-#define HEX_DIGITS 8
+-
+-static unsigned int parse_hex_value (const char *buffer,
+-              unsigned long count, unsigned long *ret)
+-{
+-      unsigned char hexnum [HEX_DIGITS];
+-      unsigned long value;
+-      int i;
+-
+-      if (!count)
+-              return -EINVAL;
+-      if (count > HEX_DIGITS)
+-              count = HEX_DIGITS;
+-      if (copy_from_user(hexnum, buffer, count))
+-              return -EFAULT;
+-
+-      /*
+-       * Parse the first 8 characters as a hex string, any non-hex char
+-       * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+-       */
+-      value = 0;
+-
+-      for (i = 0; i < count; i++) {
+-              unsigned int c = hexnum[i];
+-
+-              switch (c) {
+-                      case '0' ... '9': c -= '0'; break;
+-                      case 'a' ... 'f': c -= 'a'-10; break;
+-                      case 'A' ... 'F': c -= 'A'-10; break;
+-              default:
+-                      goto out;
+-              }
+-              value = (value << 4) | c;
+-      }
+-out:
+-      *ret = value;
+-      return 0;
+-}
+-
+ #ifdef CONFIG_SMP
+ static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+@@ -872,18 +835,10 @@ static cpumask_t irq_affinity [NR_IRQS] 
+ static int irq_affinity_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      int len, k;
+-      cpumask_t tmp = irq_affinity[(long)data];
+-
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, irq_affinity[(long)data]);
++      if (count - len < 2)
+               return -EINVAL;
+-      for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-              int j = sprintf(page, "%04hx", cpus_coerce(tmp));
+-              len += j;
+-              page += j;
+-              cpus_shift_right(tmp, tmp, 16);
+-      }
+-      len += sprintf(page, "\n");
++      len += sprintf(page + len, "\n");
+       return len;
+ }
+@@ -896,7 +851,7 @@ static int irq_affinity_write_proc (stru
+       if (!irq_desc[irq].handler->set_affinity)
+               return -EIO;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       /*
+        * Do not allow disabling IRQs completely - it's a too easy
+@@ -918,20 +873,10 @@ static int irq_affinity_write_proc (stru
+ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      int len, k;
+-      cpumask_t *mask = (cpumask_t *)data, tmp;
+-
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, *(cpumask_t *)data);
++      if (count - len < 2)
+               return -EINVAL;
+-      tmp = *mask;
+-
+-      for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-              int j = sprintf(page, "%04hx", cpus_coerce(tmp));
+-              len += j;
+-              page += j;
+-              cpus_shift_right(tmp, tmp, 16);
+-      }
+-      len += sprintf(page, "\n");
++      len += sprintf(page + len, "\n");
+       return len;
+ }
+@@ -941,7 +886,7 @@ static int prof_cpu_mask_write_proc (str
+       cpumask_t *mask = (cpumask_t *)data, new_value;
+       unsigned long full_count = count, err;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       if (err)
+               return err;
+--- linux-2.6.0/arch/mips/mm/highmem.c 2003-07-02 14:53:13.000000000 -0700
++++ 25/arch/mips/mm/highmem.c  2003-12-28 23:22:58.000000000 -0800
+@@ -40,6 +40,7 @@ void *kmap_atomic(struct page *page, enu
+       enum fixed_addresses idx;
+       unsigned long vaddr;
++      /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
+       inc_preempt_count();
+       if (page < highmem_start_page)
+               return page_address(page);
+@@ -64,6 +65,7 @@ void kunmap_atomic(void *kvaddr, enum km
+       if (vaddr < FIXADDR_START) { // FIXME
+               dec_preempt_count();
++              preempt_check_resched();
+               return;
+       }
+@@ -79,6 +81,7 @@ void kunmap_atomic(void *kvaddr, enum km
+ #endif
+       dec_preempt_count();
++      preempt_check_resched();
+ }
+ struct page *kmap_atomic_to_page(void *ptr)
+--- linux-2.6.0/arch/parisc/kernel/irq.c       2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/parisc/kernel/irq.c        2003-12-28 23:22:06.000000000 -0800
+@@ -215,29 +215,30 @@ EXPORT_SYMBOL(enable_irq);
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+ #ifdef CONFIG_PROC_FS
+-      unsigned int regnr = 0;
++      unsigned int regnr = *(loff_t *) v, i;
+-      seq_puts(p, "     ");
++      if (regnr == 0) {
++              seq_puts(p, "     ");
+ #ifdef CONFIG_SMP
+-      for (regnr = 0; regnr < NR_CPUS; regnr++)
++              for (i = 0; i < NR_CPUS; i++)
+ #endif
+-              seq_printf(p, "      CPU%02d ", regnr);
++                      seq_printf(p, "      CPU%02d ", i);
+ #ifdef PARISC_IRQ_CR16_COUNTS
+-      seq_printf(p, "[min/avg/max] (CPU cycle counts)");
++              seq_printf(p, "[min/avg/max] (CPU cycle counts)");
+ #endif
+-      seq_putc(p, '\n');
++              seq_putc(p, '\n');
++      }
+       /* We don't need *irqsave lock variants since this is
+       ** only allowed to change while in the base context.
+       */
+       spin_lock(&irq_lock);
+-      for (regnr = 0; regnr < NR_IRQ_REGS; regnr++) {
+-          unsigned int i;
++      if (regnr < NR_IRQ_REGS) {
+           struct irq_region *region = irq_region[regnr];
+             if (!region || !region->action)
+-              continue;
++                  goto skip;
+           for (i = 0; i <= MAX_CPU_IRQ; i++) {
+               struct irqaction *action = &region->action[i];
+@@ -286,9 +287,9 @@ int show_interrupts(struct seq_file *p, 
+               seq_putc(p, '\n');
+           }
+       }
++  skip:
+       spin_unlock(&irq_lock);
+-      seq_putc(p, '\n');
+ #endif        /* CONFIG_PROC_FS */
+       return 0;
+ }
+--- linux-2.6.0/arch/parisc/kernel/sys_parisc.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/arch/parisc/kernel/sys_parisc.c 2003-12-28 23:21:20.000000000 -0800
+@@ -93,17 +93,13 @@ static unsigned long get_shared_area(str
+ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+               unsigned long len, unsigned long pgoff, unsigned long flags)
+ {
+-      struct inode *inode;
+-
+       if (len > TASK_SIZE)
+               return -ENOMEM;
+       if (!addr)
+               addr = TASK_UNMAPPED_BASE;
+-      inode = filp ? filp->f_dentry->d_inode : NULL;
+-
+-      if (inode && (flags & MAP_SHARED)) {
+-              addr = get_shared_area(inode->i_mapping, addr, len, pgoff);
++      if (filp && (flags & MAP_SHARED)) {
++              addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
+       } else {
+               addr = get_unshared_area(addr, len);
+       }
+--- linux-2.6.0/arch/ppc64/kernel/irq.c        2003-10-17 15:58:03.000000000 -0700
++++ 25/arch/ppc64/kernel/irq.c 2003-12-28 23:22:10.000000000 -0800
+@@ -300,7 +300,7 @@ void enable_irq(unsigned int irq)
+       spin_lock_irqsave(&desc->lock, flags);
+       switch (desc->depth) {
+       case 1: {
+-              unsigned int status = desc->status & ~(IRQ_DISABLED | IRQ_INPROGRESS);
++              unsigned int status = desc->status & ~IRQ_DISABLED;
+               desc->status = status;
+               if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+                       desc->status = status | IRQ_REPLAY;
+@@ -323,18 +323,20 @@ EXPORT_SYMBOL(enable_irq);
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i, j;
++      int i = *(loff_t *) v, j;
+       struct irqaction * action;
+       unsigned long flags;
+-      seq_printf(p, "           ");
+-      for (j=0; j<NR_CPUS; j++) {
+-              if (cpu_online(j))
+-                      seq_printf(p, "CPU%d       ",j);
++      if (i == 0) {
++              seq_printf(p, "           ");
++              for (j=0; j<NR_CPUS; j++) {
++                      if (cpu_online(j))
++                              seq_printf(p, "CPU%d       ",j);
++              }
++              seq_putc(p, '\n');
+       }
+-      seq_putc(p, '\n');
+-      for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               spin_lock_irqsave(&irq_desc[i].lock, flags);
+               action = irq_desc[i].action;
+               if (!action || !action->handler)
+@@ -359,8 +361,8 @@ int show_interrupts(struct seq_file *p, 
+               seq_putc(p, '\n');
+ skip:
+               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+-      }
+-      seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
++      } else if (i == NR_IRQS)
++              seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
+       return 0;
+ }
+@@ -652,67 +654,16 @@ cpumask_t irq_affinity [NR_IRQS] = { [0 
+ cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_NONE };
+ #endif /* CONFIG_IRQ_ALL_CPUS */
+-#define HEX_DIGITS (2*sizeof(cpumask_t))
+-
+ static int irq_affinity_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      int k, len;
+-      cpumask_t tmp = irq_affinity[(long)data];
+-
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, irq_affinity[(long)data]);
++      if (count - len < 2)
+               return -EINVAL;
+-
+-      for (k = 0; k < sizeof(cpumask_t) / sizeof(u16); ++k) {
+-              int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
+-              len += j;
+-              page += j;
+-              cpus_shift_right(tmp, tmp, 16);
+-      }
+-      len += sprintf(page, "\n");
++      len += sprintf(page + len, "\n");
+       return len;
+ }
+-static unsigned int parse_hex_value (const char *buffer,
+-              unsigned long count, cpumask_t *ret)
+-{
+-      unsigned char hexnum[HEX_DIGITS];
+-      cpumask_t value = CPU_MASK_NONE;
+-      int i;
+-
+-      if (!count)
+-              return -EINVAL;
+-      if (count > HEX_DIGITS)
+-              count = HEX_DIGITS;
+-      if (copy_from_user(hexnum, buffer, count))
+-              return -EFAULT;
+-
+-      /*
+-       * Parse the first HEX_DIGITS characters as a hex string, any non-hex char
+-       * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+-       */
+-
+-      for (i = 0; i < count; i++) {
+-              unsigned int c = hexnum[i];
+-              int k;
+-
+-              switch (c) {
+-                      case '0' ... '9': c -= '0'; break;
+-                      case 'a' ... 'f': c -= 'a'-10; break;
+-                      case 'A' ... 'F': c -= 'A'-10; break;
+-              default:
+-                      goto out;
+-              }
+-              cpus_shift_left(value, value, 4);
+-              for (k = 0; k < 4; ++k)
+-                      if (test_bit(k, (unsigned long *)&c))
+-                              cpu_set(k, value);
+-      }
+-out:
+-      *ret = value;
+-      return 0;
+-}
+-
+ static int irq_affinity_write_proc (struct file *file, const char *buffer,
+                                       unsigned long count, void *data)
+ {
+@@ -722,7 +673,7 @@ static int irq_affinity_write_proc (stru
+       if (!irq_desc[irq].handler->set_affinity)
+               return -EIO;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       if (err)
+               return err;
+@@ -744,10 +695,11 @@ static int irq_affinity_write_proc (stru
+ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      unsigned long *mask = (unsigned long *) data;
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, *(cpumask_t *)data);
++      if (count - len < 2)
+               return -EINVAL;
+-      return sprintf (page, "%08lx\n", *mask);
++      len += sprintf(page + len, "\n");
++      return len;
+ }
+ static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
+@@ -757,7 +709,7 @@ static int prof_cpu_mask_write_proc (str
+       unsigned long full_count = count, err;
+       cpumask_t new_value;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       if (err)
+               return err;
+--- linux-2.6.0/arch/ppc64/kernel/misc.S       2003-10-17 15:58:03.000000000 -0700
++++ 25/arch/ppc64/kernel/misc.S        2003-12-28 23:21:37.000000000 -0800
+@@ -843,15 +843,15 @@ _GLOBAL(sys_call_table32)
+       .llong .sys_ni_syscall
+       .llong .sys_ni_syscall
+       .llong .sys_ni_syscall
+-      .llong .sys_ni_syscall          /* 245 */
+-      .llong .sys_ni_syscall
+-      .llong .sys_ni_syscall
+-      .llong .sys_ni_syscall
+-      .llong .sys_ni_syscall
++      .llong .compat_clock_settime    /* 245 */
++      .llong .compat_clock_gettime
++      .llong .compat_clock_getres
++      .llong .compat_clock_nanosleep
++      .llong .sys_ni_syscall          /* 249 swapcontext */
+       .llong .sys32_tgkill            /* 250 */
+       .llong .sys32_utimes
+-      .llong .sys_statfs64
+-      .llong .sys_fstatfs64
++      .llong .compat_statfs64
++      .llong .compat_fstatfs64
+       .balign 8
+ _GLOBAL(sys_call_table)
+--- linux-2.6.0/arch/ppc64/kernel/time.c       2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/ppc64/kernel/time.c        2003-12-28 23:21:36.000000000 -0800
+@@ -91,6 +91,9 @@ unsigned      tb_to_us;
+ unsigned long processor_freq;
+ spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
++unsigned long tb_to_ns_scale;
++unsigned long tb_to_ns_shift;
++
+ struct gettimeofday_struct do_gtod;
+ extern unsigned long wall_jiffies;
+@@ -313,11 +316,13 @@ int timer_interrupt(struct pt_regs * reg
+ /*
+  * Scheduler clock - returns current time in nanosec units.
+  *
+- * This is wrong, but my CPUs run at 1GHz, so nyer nyer.
++ * Note: mulhdu(a, b) (multiply high double unsigned) returns
++ * the high 64 bits of a * b, i.e. (a * b) >> 64, where a and b
++ * are 64-bit unsigned numbers.
+  */
+ unsigned long long sched_clock(void)
+ {
+-      return get_tb();
++      return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift;
+ }
+ /*
+@@ -473,9 +478,30 @@ void __init time_init(void)
+       /* This function is only called on the boot processor */
+       unsigned long flags;
+       struct rtc_time tm;
++      struct div_result res;
++      unsigned long scale, shift;
+       ppc_md.calibrate_decr();
++      /*
++       * Compute scale factor for sched_clock.
++       * The calibrate_decr() function has set tb_ticks_per_sec,
++       * which is the timebase frequency.
++       * We compute 1e9 * 2^64 / tb_ticks_per_sec and interpret
++       * the 128-bit result as a 64.64 fixed-point number.
++       * We then shift that number right until it is less than 1.0,
++       * giving us the scale factor and shift count to use in
++       * sched_clock().
++       */
++      div128_by_32(1000000000, 0, tb_ticks_per_sec, &res);
++      scale = res.result_low;
++      for (shift = 0; res.result_high != 0; ++shift) {
++              scale = (scale >> 1) | (res.result_high << 63);
++              res.result_high >>= 1;
++      }
++      tb_to_ns_scale = scale;
++      tb_to_ns_shift = shift;
++
+ #ifdef CONFIG_PPC_ISERIES
+       if (!piranha_simulator)
+ #endif
+--- linux-2.6.0/arch/ppc64/mm/hugetlbpage.c    2003-10-17 15:58:03.000000000 -0700
++++ 25/arch/ppc64/mm/hugetlbpage.c     2003-12-28 23:22:12.000000000 -0800
+@@ -921,7 +921,7 @@ int is_hugepage_mem_enough(size_t size)
+  * this far.
+  */
+ static struct page *hugetlb_nopage(struct vm_area_struct *vma,
+-                              unsigned long address, int unused)
++                              unsigned long address, int *unused)
+ {
+       BUG();
+       return NULL;
+--- linux-2.6.0/arch/ppc64/mm/numa.c   2003-10-17 15:58:03.000000000 -0700
++++ 25/arch/ppc64/mm/numa.c    2003-12-28 23:21:37.000000000 -0800
+@@ -108,7 +108,7 @@ static int __init parse_numa_properties(
+       for (memory = find_type_devices("memory"); memory;
+            memory = memory->next) {
+-              int *tmp1, *tmp2;
++              unsigned int *tmp1, *tmp2;
+               unsigned long i;
+               unsigned long start = 0;
+               unsigned long size = 0;
+--- linux-2.6.0/arch/ppc/boot/ld.script        2003-11-09 16:45:05.000000000 -0800
++++ 25/arch/ppc/boot/ld.script 2003-12-28 23:26:37.000000000 -0800
+@@ -82,6 +82,7 @@ SECTIONS
+     *(__ksymtab)
+     *(__ksymtab_strings)
+     *(__bug_table)
++    *(__kcrctab)
+   }
+ }
+--- linux-2.6.0/arch/ppc/boot/simple/Makefile  2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/ppc/boot/simple/Makefile   2003-12-28 23:22:26.000000000 -0800
+@@ -4,30 +4,38 @@
+ # Author: Tom Rini <trini@mvista.com>
+ #
+ # Notes:
+-# (1) For machine targets which produce more than one image, define
+-# ZNETBOOT and ZNETBOOTRD to the image which should be available for
+-# 'znetboot' and 'znetboot.initrd`
+-# (2) Also, for machine targets which just need to remove the ELF header,
+-# define END to be the machine name you want in the image.
+-# (3) For machine targets which use the mktree program, define END to be
+-# the machine name you want in the image, and you can optionally set
+-# ENTRYPOINT which the image should be loaded at.  The optimal setting
+-# for ENTRYPOINT is the link address.
++# (1) For machines that do not want to use the ELF image directly (including
++# stripping just the ELF header off), they must set the variables
++# zimage-$(CONFIG_MACHINE) and zimagerd-$(CONFIG_MACHINE) to the target
++# that produces the desired image and they must set end-$(CONFIG_MACHINE)
++# to what will be suffixed to the image filename.
++# (2) Regardless of (1), to have the resulting image be something other
++# than 'zImage.elf', set end-$(CONFIG_MACHINE) to be the suffix used for
++# the zImage, znetboot, and znetbootrd targets.
++# (3) For machine targets which use the mktree program, you can optionally
++# set entrypoint-$(CONFIG_MACHINE) to the location which the image should be
++# loaded at.  The optimal setting for entrypoint-$(CONFIG_MACHINE) is the link
++# address.
+ # (4) It is advisable to pass in the memory size using BI_MEMSIZE and
+ # get_mem_size(), which is memory controller dependent.  Add in the correct
+-# XXX_memory.o file for this to work, as well as editing the $(MISC) file.
+-
++# XXX_memory.o file for this to work, as well as editing the
++# misc-$(CONFIG_MACHINE) variable.
+ boot                          := arch/ppc/boot
+ common                                := $(boot)/common
+ utils                         := $(boot)/utils
+ bootlib                               := $(boot)/lib
+ images                                := $(boot)/images
++tftpboot                      := /tftpboot
+ # Normally, we use the 'misc.c' file for decompress_kernel and
+ # whatnot.  Sometimes we need to override this however.
+ misc-y        := misc.o
++# Normally, we have our images end in .elf, but something we want to
++# change this.
++end-y := elf
++
+ # Additionally, we normally don't need to mess with the L2 / L3 caches
+ # if present on 'classic' PPC.
+ cacheflag-y   := -DCLEAR_CACHES=""
+@@ -41,48 +49,43 @@ clear_L2_L3        := $(boot)/simple/clear.S
+       zimage-$(CONFIG_IBM_OPENBIOS)   := zImage-TREE
+ zimageinitrd-$(CONFIG_IBM_OPENBIOS)   := zImage.initrd-TREE
+          end-$(CONFIG_IBM_OPENBIOS)   := treeboot
+-   tftpimage-$(CONFIG_IBM_OPENBIOS)   := /tftpboot/zImage.$(end-y)
+         misc-$(CONFIG_IBM_OPENBIOS)   := misc-embedded.o
+-   tftpimage-$(CONFIG_EMBEDDEDBOOT)   :=  /tftpboot/zImage.embedded
++         end-$(CONFIG_EMBEDDEDBOOT)   := embedded
+         misc-$(CONFIG_EMBEDDEDBOOT)   := misc-embedded.o
+       zimage-$(CONFIG_EBONY)          := zImage-TREE
+ zimageinitrd-$(CONFIG_EBONY)          := zImage.initrd-TREE
+          end-$(CONFIG_EBONY)          := ebony
+   entrypoint-$(CONFIG_EBONY)          := 0x01000000
+-   tftpimage-$(CONFIG_EBONY)          := /tftpboot/zImage.$(end-y)
+       zimage-$(CONFIG_OCOTEA)         := zImage-TREE
+ zimageinitrd-$(CONFIG_OCOTEA)         := zImage.initrd-TREE
+          end-$(CONFIG_OCOTEA)         := ocotea
+   entrypoint-$(CONFIG_OCOTEA)         := 0x01000000
+-   tftpimage-$(CONFIG_OCOTEA)         := /tftpboot/zImage.$(end-y)
+      extra.o-$(CONFIG_EV64260)                := direct.o misc-ev64260.o
+-   tftpimage-$(CONFIG_EV64260)                := /tftpboot/zImage.ev64260
++         end-$(CONFIG_EV64260)                := ev64260
+    cacheflag-$(CONFIG_EV64260)                := -include $(clear_L2_L3)
+       zimage-$(CONFIG_GEMINI)         := zImage-STRIPELF
+ zimageinitrd-$(CONFIG_GEMINI)         := zImage.initrd-STRIPELF
+          end-$(CONFIG_GEMINI)         := gemini
+-   tftpimage-$(CONFIG_GEMINI)         := /tftpboot/zImage.$(end-y)
+      extra.o-$(CONFIG_K2)             := legacy.o
+-   tftpimage-$(CONFIG_K2)             := /tftpboot/zImage.k2
++         end-$(CONFIG_K2)             := k2
+    cacheflag-$(CONFIG_K2)             := -include $(clear_L2_L3)
+ # kconfig 'feature', only one of these will ever be 'y' at a time.
+ # The rest will be unset.
+ motorola := $(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750) \
+ $(CONFIG_PRPMC800)$(CONFIG_LOPEC)$(CONFIG_PPLUS)
++motorola := $(strip $(motorola))
+ pcore := $(CONFIG_PCORE)$(CONFIG_POWERPMC250)
+       zimage-$(motorola)              := zImage-PPLUS
+ zimageinitrd-$(motorola)              := zImage.initrd-PPLUS
+-   tftpimage-$(motorola)              := /tftpboot/zImage.pplus
+-    znetboot-$(motorola)              := zImage.pplus
+-  znetbootrd-$(motorola)              := zImage.initrd.pplus
++         end-$(motorola)              := pplus
+ # Overrides previous assingment
+      extra.o-$(CONFIG_PPLUS)          := legacy.o
+@@ -91,10 +94,9 @@ zimageinitrd-$(motorola)            := zImage.init
+ zimageinitrd-$(pcore)                 := zImage.initrd-STRIPELF
+      extra.o-$(pcore)                 := chrpmap.o
+          end-$(pcore)                 := pcore
+-   tftpimage-$(pcore)                 := /tftpboot/zImage.$(end-y)
+    cacheflag-$(pcore)                 := -include $(clear_L2_L3)
+-   tftpimage-$(CONFIG_SANDPOINT)      := /tftpboot/zImage.sandpoint
++         end-$(CONFIG_SANDPOINT)      := sandpoint
+    cacheflag-$(CONFIG_SANDPOINT)      := -include $(clear_L2_L3)
+       zimage-$(CONFIG_SPRUCE)         := zImage-TREE
+@@ -102,11 +104,9 @@ zimageinitrd-$(CONFIG_SPRUCE)             := zImage
+          end-$(CONFIG_SPRUCE)         := spruce
+   entrypoint-$(CONFIG_SPRUCE)         := 0x00800000
+         misc-$(CONFIG_SPRUCE)         := misc-spruce.o
+-   tftpimage-$(CONFIG_SPRUCE)         := /tftpboot/zImage.$(end-y)
+-
+-# tftp image is prefixed with .smp if compiled for SMP
+-tftpimage-$(CONFIG_SMP)       += .smp
++# SMP images should have a '.smp' suffix.
++         end-$(CONFIG_SMP)            += .smp
+ # This is a treeboot that needs init functions until the
+ # boot rom is sorted out (i.e. this is short lived)
+@@ -180,18 +180,10 @@ zImage.initrd: $(images)/$(zimageinitrd-
+       rm -f $(obj)/zvmlinux.initrd
+ znetboot: zImage
+-ifneq ($(ZNETBOOT),)
+-      cp $(images)/$(ZNETBOOT) $(tftpimage-y)
+-else
+-      cp $(images)/zImage.* $(tftpimage-y)
+-endif
++      cp $(images)/zImage.$(end-y) $(tftpboot)/zImage.$(end-y)
+ znetboot.initrd: zImage.initrd
+-ifneq ($(znetbootrd-y),)
+-      cp $(images)/$(znetbootrd-y) $(tftpimage-y)
+-else
+-      cp $(images)/zImage.* $(tftpimage-y)
+-endif
++      cp $(images)/zImage.initrd.$(end-y) $(tftpboot)/zImage.initrd.$(end-y)
+ $(images)/zImage-STRIPELF: $(obj)/zvmlinux
+       dd if=$(obj)/zvmlinux of=$(images)/zImage.$(end-y) skip=64 bs=1k
+--- linux-2.6.0/arch/ppc/boot/utils/mkprep.c   2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/ppc/boot/utils/mkprep.c    2003-12-28 23:22:26.000000000 -0800
+@@ -12,12 +12,14 @@
+  *                  -- Cort
+  *
+  * Modified for x86 hosted builds by Matt Porter <porter@neta.com>
++ * Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de>
+  */
+ #include <fcntl.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <strings.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+@@ -147,7 +149,7 @@ int main(int argc, char *argv[])
+ void write_prep_partition(int in, int out)
+ {
+   unsigned char block[512];
+-  partition_entry_t *pe = (partition_entry_t *)&block[0x1BE];
++  partition_entry_t pe;
+   dword_t *entry  = (dword_t *)&block[0];
+   dword_t *length = (dword_t *)&block[sizeof(long)];
+   struct stat info;
+@@ -177,8 +179,8 @@ void write_prep_partition(int in, int ou
+    * Build a "PReP" partition table entry in the boot record
+    *  - "PReP" may only look at the system_indicator
+    */
+-  pe->boot_indicator   = BootActive;
+-  pe->system_indicator = SystemPrep;
++  pe.boot_indicator   = BootActive;
++  pe.system_indicator = SystemPrep;
+   /*
+    * The first block of the diskette is used by this "boot record" which
+    * actually contains the partition table. (The first block of the
+@@ -186,12 +188,12 @@ void write_prep_partition(int in, int ou
+    * one partition on the diskette and it shall contain the rest of the
+    * diskette.
+    */
+-  pe->starting_head     = 0;  /* zero-based                        */
+-  pe->starting_sector   = 2;  /* one-based                         */
+-  pe->starting_cylinder = 0;  /* zero-based                        */
+-  pe->ending_head       = 1;  /* assumes two heads                 */
+-  pe->ending_sector     = 18; /* assumes 18 sectors/track          */
+-  pe->ending_cylinder   = 79; /* assumes 80 cylinders/diskette     */
++  pe.starting_head     = 0;   /* zero-based                        */
++  pe.starting_sector   = 2;   /* one-based                         */
++  pe.starting_cylinder = 0;   /* zero-based                        */
++  pe.ending_head       = 1;   /* assumes two heads                 */
++  pe.ending_sector     = 18;  /* assumes 18 sectors/track          */
++  pe.ending_cylinder   = 79;  /* assumes 80 cylinders/diskette     */
+   /*
+    * The "PReP" software ignores the above fields and just looks at
+@@ -201,20 +203,20 @@ void write_prep_partition(int in, int ou
+    *   - unlike the above sector numbers, the beginning sector is zero-based!
+    */
+ #if 0
+-  pe->beginning_sector  = cpu_to_le32(1);
++  pe.beginning_sector  = cpu_to_le32(1);
+ #else
+   /* This has to be 0 on the PowerStack? */
+ #ifdef __i386__
+-  pe->beginning_sector  = 0;
++  pe.beginning_sector  = 0;
+ #else
+-  pe->beginning_sector  = cpu_to_le32(0);
++  pe.beginning_sector  = cpu_to_le32(0);
+ #endif /* __i386__ */
+ #endif
+ #ifdef __i386__
+-  pe->number_of_sectors = 2*18*80-1;
++  pe.number_of_sectors = 2*18*80-1;
+ #else
+-  pe->number_of_sectors = cpu_to_le32(2*18*80-1);
++  pe.number_of_sectors = cpu_to_le32(2*18*80-1);
+ #endif /* __i386__ */
+   write( out, block, sizeof(block) );
+--- linux-2.6.0/arch/ppc/kernel/irq.c  2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/ppc/kernel/irq.c   2003-12-28 23:22:10.000000000 -0800
+@@ -346,17 +346,19 @@ void enable_irq(unsigned int irq)
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i, j;
++      int i = *(loff_t *) v, j;
+       struct irqaction * action;
+       unsigned long flags;
+-      seq_puts(p, "           ");
+-      for (j=0; j<NR_CPUS; j++)
+-              if (cpu_online(j))
+-                      seq_printf(p, "CPU%d       ", j);
+-      seq_putc(p, '\n');
++      if (i == 0) {
++              seq_puts(p, "           ");
++              for (j=0; j<NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "CPU%d       ", j);
++              seq_putc(p, '\n');
++      }
+-      for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               spin_lock_irqsave(&irq_desc[i].lock, flags);
+               action = irq_desc[i].action;
+               if ( !action || !action->handler )
+@@ -381,22 +383,23 @@ int show_interrupts(struct seq_file *p, 
+               seq_putc(p, '\n');
+ skip:
+               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+-      }
++      } else if (i == NR_IRQS) {
+ #ifdef CONFIG_TAU_INT
+-      if (tau_initialized){
+-              seq_puts(p, "TAU: ");
+-              for (j = 0; j < NR_CPUS; j++)
+-                      if (cpu_online(j))
+-                              seq_printf(p, "%10u ", tau_interrupts(j));
+-              seq_puts(p, "  PowerPC             Thermal Assist (cpu temp)\n");
+-      }
++              if (tau_initialized){
++                      seq_puts(p, "TAU: ");
++                      for (j = 0; j < NR_CPUS; j++)
++                              if (cpu_online(j))
++                                      seq_printf(p, "%10u ", tau_interrupts(j));
++                      seq_puts(p, "  PowerPC             Thermal Assist (cpu temp)\n");
++              }
+ #endif
+ #ifdef CONFIG_SMP
+-      /* should this be per processor send/receive? */
+-      seq_printf(p, "IPI (recv/sent): %10u/%u\n",
+-                 atomic_read(&ipi_recv), atomic_read(&ipi_sent));
++              /* should this be per processor send/receive? */
++              seq_printf(p, "IPI (recv/sent): %10u/%u\n",
++                              atomic_read(&ipi_recv), atomic_read(&ipi_sent));
+ #endif
+-      seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
++              seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
++      }
+       return 0;
+ }
+@@ -569,67 +572,16 @@ static struct proc_dir_entry *smp_affini
+ cpumask_t irq_affinity [NR_IRQS];
+-#define HEX_DIGITS (2*sizeof(cpumask_t))
+-
+ static int irq_affinity_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      cpumask_t tmp = irq_affinity[(long)data];
+-      int k, len = 0;
+-
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, irq_affinity[(long)data]);
++      if (count - len < 2)
+               return -EINVAL;
+-
+-      for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-              int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
+-              len += j;
+-              page += j;
+-              cpus_shift_right(tmp, tmp, 16);
+-      }
+-
+-      len += sprintf(page, "\n");
++      len += sprintf(page + len, "\n");
+       return len;
+ }
+-static unsigned int parse_hex_value (const char __user *buffer,
+-              unsigned long count, cpumask_t *ret)
+-{
+-      unsigned char hexnum [HEX_DIGITS];
+-      cpumask_t value = CPU_MASK_NONE;
+-      int i;
+-
+-      if (!count)
+-              return -EINVAL;
+-      if (count > HEX_DIGITS)
+-              count = HEX_DIGITS;
+-      if (copy_from_user(hexnum, buffer, count))
+-              return -EFAULT;
+-
+-      /*
+-       * Parse the first 8 characters as a hex string, any non-hex char
+-       * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+-       */
+-      for (i = 0; i < count; i++) {
+-              unsigned int c = hexnum[i];
+-              int k;
+-
+-              switch (c) {
+-                      case '0' ... '9': c -= '0'; break;
+-                      case 'a' ... 'f': c -= 'a'-10; break;
+-                      case 'A' ... 'F': c -= 'A'-10; break;
+-              default:
+-                      goto out;
+-              }
+-              cpus_shift_left(value, value, 4);
+-              for (k = 0; k < 4; ++k)
+-                      if (c & (1 << k))
+-                              cpu_set(k, value);
+-      }
+-out:
+-      *ret = value;
+-      return 0;
+-}
+-
+ static int irq_affinity_write_proc (struct file *file, const char __user *buffer,
+                                       unsigned long count, void *data)
+ {
+@@ -639,7 +591,7 @@ static int irq_affinity_write_proc (stru
+       if (!irq_desc[irq].handler->set_affinity)
+               return -EIO;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       /*
+        * Do not allow disabling IRQs completely - it's a too easy
+@@ -664,19 +616,10 @@ static int irq_affinity_write_proc (stru
+ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      cpumask_t mask = *(cpumask_t *)data;
+-      int k, len = 0;
+-
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, *(cpumask_t *)data);
++      if (count - len < 2)
+               return -EINVAL;
+-
+-      for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-              int j = sprintf(page, "%04hx", (u16)cpus_coerce(mask));
+-              len += j;
+-              page += j;
+-              cpus_shift_right(mask, mask, 16);
+-      }
+-      len += sprintf(page, "\n");
++      len += sprintf(page + len, "\n");
+       return len;
+ }
+@@ -686,7 +629,7 @@ static int prof_cpu_mask_write_proc (str
+       cpumask_t *mask = (cpumask_t *)data, full_count = count, err;
+       cpumask_t new_value;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       if (err)
+               return err;
+--- linux-2.6.0/arch/ppc/kernel/Makefile       2003-09-27 18:57:43.000000000 -0700
++++ 25/arch/ppc/kernel/Makefile        2003-12-28 23:22:27.000000000 -0800
+@@ -9,8 +9,7 @@ ifdef CONFIG_4xx
+ EXTRA_AFLAGS          := -Wa,-m405
+ endif
+-# Start off with 'head.o', change as needed.
+-extra-y                               := head.o
++extra-$(CONFIG_PPC_STD_MMU)   := head.o
+ extra-$(CONFIG_40x)           := head_4xx.o
+ extra-$(CONFIG_44x)           := head_44x.o
+ extra-$(CONFIG_8xx)           := head_8xx.o
+--- linux-2.6.0/arch/ppc/kernel/ppc_ksyms.c    2003-10-17 15:58:03.000000000 -0700
++++ 25/arch/ppc/kernel/ppc_ksyms.c     2003-12-28 23:22:27.000000000 -0800
+@@ -92,7 +92,7 @@ EXPORT_SYMBOL(disable_irq_nosync);
+ EXPORT_SYMBOL(probe_irq_mask);
+ EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
+-EXPORT_SYMBOL_NOVERS(DMA_MODE_READ);
++EXPORT_SYMBOL(DMA_MODE_READ);
+ EXPORT_SYMBOL(DMA_MODE_WRITE);
+ #if defined(CONFIG_PPC_PREP)
+ EXPORT_SYMBOL(_prep_type);
+@@ -167,9 +167,9 @@ EXPORT_SYMBOL(ppc_ide_md);
+ #endif
+ #ifdef CONFIG_PCI
+-EXPORT_SYMBOL_NOVERS(isa_io_base);
+-EXPORT_SYMBOL_NOVERS(isa_mem_base);
+-EXPORT_SYMBOL_NOVERS(pci_dram_offset);
++EXPORT_SYMBOL(isa_io_base);
++EXPORT_SYMBOL(isa_mem_base);
++EXPORT_SYMBOL(pci_dram_offset);
+ EXPORT_SYMBOL(pci_alloc_consistent);
+ EXPORT_SYMBOL(pci_free_consistent);
+ EXPORT_SYMBOL(pci_bus_io_base);
+@@ -246,7 +246,7 @@ EXPORT_SYMBOL(register_backlight_control
+ EXPORT_SYMBOL(_machine);
+ #endif
+ #ifdef CONFIG_PPC_PMAC
+-EXPORT_SYMBOL_NOVERS(sys_ctrler);
++EXPORT_SYMBOL(sys_ctrler);
+ EXPORT_SYMBOL(pmac_newworld);
+ #endif
+ #ifdef CONFIG_PPC_OF
+@@ -294,15 +294,15 @@ EXPORT_SYMBOL(to_tm);
+ EXPORT_SYMBOL(pm_power_off);
+-EXPORT_SYMBOL_NOVERS(__ashrdi3);
+-EXPORT_SYMBOL_NOVERS(__ashldi3);
+-EXPORT_SYMBOL_NOVERS(__lshrdi3);
+-EXPORT_SYMBOL_NOVERS(memcpy);
+-EXPORT_SYMBOL_NOVERS(memset);
+-EXPORT_SYMBOL_NOVERS(memmove);
+-EXPORT_SYMBOL_NOVERS(memscan);
+-EXPORT_SYMBOL_NOVERS(memcmp);
+-EXPORT_SYMBOL_NOVERS(memchr);
++EXPORT_SYMBOL(__ashrdi3);
++EXPORT_SYMBOL(__ashldi3);
++EXPORT_SYMBOL(__lshrdi3);
++EXPORT_SYMBOL(memcpy);
++EXPORT_SYMBOL(memset);
++EXPORT_SYMBOL(memmove);
++EXPORT_SYMBOL(memscan);
++EXPORT_SYMBOL(memcmp);
++EXPORT_SYMBOL(memchr);
+ EXPORT_SYMBOL(abs);
+@@ -366,10 +366,10 @@ EXPORT_SYMBOL(request_8xxirq);
+ EXPORT_SYMBOL(next_mmu_context);
+ EXPORT_SYMBOL(set_context);
+ EXPORT_SYMBOL(handle_mm_fault); /* For MOL */
+-EXPORT_SYMBOL_NOVERS(disarm_decr);
++EXPORT_SYMBOL(disarm_decr);
++#ifdef CONFIG_PPC_STD_MMU
+ extern long mol_trampoline;
+ EXPORT_SYMBOL(mol_trampoline); /* For MOL */
+-#ifdef CONFIG_PPC_STD_MMU
+ EXPORT_SYMBOL(flush_hash_pages); /* For MOL */
+ #ifdef CONFIG_SMP
+ extern int mmu_hash_lock;
+@@ -381,5 +381,5 @@ EXPORT_SYMBOL(intercept_table);
+ EXPORT_SYMBOL(cur_cpu_spec);
+ #ifdef CONFIG_PPC_PMAC
+ extern unsigned long agp_special_page;
+-EXPORT_SYMBOL_NOVERS(agp_special_page);
++EXPORT_SYMBOL(agp_special_page);
+ #endif
+--- linux-2.6.0/arch/ppc/mm/cachemap.c 2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/ppc/mm/cachemap.c  2003-12-28 23:22:26.000000000 -0800
+@@ -170,3 +170,5 @@ void consistent_sync_page(struct page *p
+       start = (unsigned long)page_address(page) + offset;
+       consistent_sync((void *)start, size, direction);
+ }
++
++EXPORT_SYMBOL(consistent_sync_page);
+--- linux-2.6.0/arch/ppc/platforms/mpc82xx.h   2003-09-27 18:57:43.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,42 +0,0 @@
+-/*
+- * arch/ppc/platforms/mpc82xx.h
+- *
+- * Board specific support for various 82xx platforms.
+- *
+- * Author: Allen Curtis <acurtis@onz.com>
+- *
+- * Copyright 2002 Ones and Zeros, Inc.
+- *
+- * This program is free software; you can redistribute  it and/or modify it
+- * under  the terms of  the GNU General  Public License as published by the
+- * Free Software Foundation;  either version 2 of the  License, or (at your
+- * option) any later version.
+- */
+-#ifndef __CONFIG_82XX_PLATFORMS
+-#define __CONFIG_82XX_PLATFORMS
+-
+-#ifdef CONFIG_8260
+-
+-#ifdef CONFIG_EST8260
+-#include <platforms/est8260.h>
+-#endif
+-
+-#ifdef CONFIG_SBS8260
+-#include <platforms/sbs8260.h>
+-#endif
+-
+-#ifdef CONFIG_RPX6
+-#include <platforms/rpxsuper.h>
+-#endif
+-
+-#ifdef CONFIG_WILLOW
+-#include <platforms/willow.h>
+-#endif
+-
+-#ifdef CONFIG_TQM8260
+-#include <platforms/tqm8260.h>
+-#endif
+-
+-#endif        /* CONFIG_8260 */
+-
+-#endif
+--- linux-2.6.0/arch/s390/kernel/compat_wrapper.S      2003-06-14 12:18:51.000000000 -0700
++++ 25/arch/s390/kernel/compat_wrapper.S       2003-12-28 23:21:47.000000000 -0800
+@@ -5,6 +5,7 @@
+ *  S390 version
+ *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Gerhard Tonn (ton@de.ibm.com),
++*               Thomas Spatzier (tspat@de.ibm.com)
+ */ 
+       .globl  sys32_exit_wrapper 
+@@ -1230,3 +1231,37 @@ sys_epoll_wait_wrapper:
+       lgfr    %r4,%r4                 # int
+       lgfr    %r5,%r5                 # int
+       jg      sys_epoll_wait          # branch to system call
++
++      .globl  sys32_io_setup_wrapper
++sys32_io_setup_wrapper:
++      llgfr   %r2,%r2                 # unsigned int
++      llgtr   %r3,%r3                 # u32 *
++      jg      compat_sys_io_setup
++
++      .globl  sys32_io_destroy_wrapper
++sys32_io_destroy_wrapper:
++      llgfr   %r2,%r2                 # (aio_context_t) u32
++      jg      sys_io_destroy
++
++      .globl  sys32_io_getevents_wrapper
++sys32_io_getevents_wrapper:
++      llgfr   %r2,%r2                 # (aio_context_t) u32
++      lgfr    %r3,%r3                 # long
++      lgfr    %r4,%r4                 # long
++      llgtr   %r5,%r5                 # struct io_event *
++      llgtr   %r6,%r6                 # struct compat_timespec *
++      jg      compat_sys_io_getevents
++
++      .globl  sys32_io_submit_wrapper
++sys32_io_submit_wrapper:
++      llgfr   %r2,%r2                 # (aio_context_t) u32
++      lgfr    %r3,%r3                 # long
++      llgtr   %r4,%r4                 # struct iocb **
++      jg      compat_sys_io_submit
++
++      .globl  sys32_io_cancel_wrapper
++sys32_io_cancel_wrapper:
++      llgfr   %r2,%r2                 # (aio_context_t) u32
++      llgtr   %r3,%r3                 # struct iocb *
++      llgtr   %r4,%r4                 # struct io_event *
++      jg      sys_io_cancel
+--- linux-2.6.0/arch/s390/kernel/setup.c       2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/s390/kernel/setup.c        2003-12-28 23:22:06.000000000 -0800
+@@ -617,17 +617,17 @@ static const char *intrclass_names[] = {
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-        int i, j;
++        int i = *(loff_t *) v, j;
+       
+-        seq_puts(p, "           ");
+-      
+-        for (j=0; j<NR_CPUS; j++)
+-                if (cpu_online(j))
+-                        seq_printf(p, "CPU%d       ",j);
+-      
+-        seq_putc(p, '\n');
++      if (i == 0) {
++              seq_puts(p, "           ");
++              for (j=0; j<NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "CPU%d       ",j);
++              seq_putc(p, '\n');
++      }
+       
+-        for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               seq_printf(p, "%s: ", intrclass_names[i]);
+ #ifndef CONFIG_SMP
+               seq_printf(p, "%10u ", kstat_irqs(i));
+--- linux-2.6.0/arch/s390/kernel/syscalls.S    2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/s390/kernel/syscalls.S     2003-12-28 23:21:47.000000000 -0800
+@@ -251,11 +251,11 @@ SYSCALL(sys_sched_setaffinity,sys_sched_
+ SYSCALL(sys_sched_getaffinity,sys_sched_getaffinity,sys32_sched_getaffinity_wrapper)  /* 240 */
+ SYSCALL(sys_tgkill,sys_tgkill,sys_tgkill)
+ NI_SYSCALL                                                    /* reserved for TUX */
+-SYSCALL(sys_io_setup,sys_io_setup,sys_ni_syscall)
+-SYSCALL(sys_io_destroy,sys_io_destroy,sys_ni_syscall)
+-SYSCALL(sys_io_getevents,sys_io_getevents,sys_ni_syscall)     /* 245 */
+-SYSCALL(sys_io_submit,sys_io_submit,sys_ni_syscall)
+-SYSCALL(sys_io_cancel,sys_io_cancel,sys_ni_syscall)
++SYSCALL(sys_io_setup,sys_io_setup,sys32_io_setup_wrapper)
++SYSCALL(sys_io_destroy,sys_io_destroy,sys32_io_destroy_wrapper)
++SYSCALL(sys_io_getevents,sys_io_getevents,sys32_io_getevents_wrapper) /* 245 */
++SYSCALL(sys_io_submit,sys_io_submit,sys32_io_submit_wrapper)
++SYSCALL(sys_io_cancel,sys_io_cancel,sys32_io_cancel_wrapper)
+ SYSCALL(sys_exit_group,sys_exit_group,sys32_exit_group_wrapper)
+ SYSCALL(sys_epoll_create,sys_epoll_create,sys_epoll_create_wrapper)
+ SYSCALL(sys_epoll_ctl,sys_epoll_ctl,sys_epoll_ctl_wrapper)    /* 250 */
+--- linux-2.6.0/arch/sh/Kconfig        2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/sh/Kconfig 2003-12-28 23:23:06.000000000 -0800
+@@ -1053,7 +1053,7 @@ config WATCHDOG
+         implementation entirely in software (which can sometimes fail to
+         reboot the machine) and a driver for hardware watchdog boards, which
+         are more robust and can also keep track of the temperature inside
+-        your computer. For details, read <file:Documentation/watchdog.txt>
++        your computer. For details, read <file:Documentation/watchdog/watchdog.txt>
+         in the kernel source.
+         The watchdog is usually used together with the watchdog daemon
+--- linux-2.6.0/arch/sh/kernel/irq.c   2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/sh/kernel/irq.c    2003-12-28 23:22:06.000000000 -0800
+@@ -93,17 +93,19 @@ struct hw_interrupt_type no_irq_type = {
+ #if defined(CONFIG_PROC_FS)
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i, j;
++      int i = *(loff_t *) v, j;
+       struct irqaction * action;
+       unsigned long flags;
+-      seq_puts(p, "           ");
+-      for (j=0; j<NR_CPUS; j++)
+-              if (cpu_online(j))
+-                      seq_printf(p, "CPU%d       ",j);
+-      seq_putc(p, '\n');
++      if (i == 0) {
++              seq_puts(p, "           ");
++              for (j=0; j<NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "CPU%d       ",j);
++              seq_putc(p, '\n');
++      }
+-      for (i = 0 ; i < ACTUAL_NR_IRQS ; i++) {
++      if (i < ACTUAL_NR_IRQS) {
+               spin_lock_irqsave(&irq_desc[i].lock, flags);
+               action = irq_desc[i].action;
+               if (!action)
+--- linux-2.6.0/arch/sparc64/Kconfig   2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/sparc64/Kconfig    2003-12-28 23:26:33.000000000 -0800
+@@ -808,12 +808,19 @@ config DEBUG_SPINLOCK
+         best used in conjunction with the NMI watchdog so that spinlock
+         deadlocks are also debuggable.
++config LOCKMETER
++      bool "Kernel lock metering"
++      depends on SMP && !PREEMPT
++      help
++        Say Y to enable kernel lock metering, which adds overhead to SMP locks,
++        but allows you to see various statistics using the lockstat command.
++
+ # We have a custom atomic_dec_and_lock() implementation but it's not
+ # compatible with spinlock debugging so we need to fall back on
+ # the generic version in that case.
+ config HAVE_DEC_LOCK
+       bool
+-      depends on SMP && !DEBUG_SPINLOCK
++      depends on SMP && !DEBUG_SPINLOCK && !LOCKMETER
+       default y
+ config DEBUG_SPINLOCK_SLEEP
+--- linux-2.6.0/arch/sparc64/kernel/irq.c      2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/sparc64/kernel/irq.c       2003-12-28 23:22:10.000000000 -0800
+@@ -128,14 +128,14 @@ static void register_irq_proc (unsigned 
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+       unsigned long flags;
+-      int i;
++      int i = *(loff_t *) v;
+       struct irqaction *action;
+ #ifdef CONFIG_SMP
+       int j;
+ #endif
+       spin_lock_irqsave(&irq_action_lock, flags);
+-      for (i = 0; i < (NR_IRQS + 1); i++) {
++      if (i <= NR_IRQS) {
+               if (!(action = *(i + irq_action)))
+                       continue;
+               seq_printf(p, "%3d: ", i);
+@@ -1204,11 +1204,17 @@ static int irq_affinity_read_proc (char 
+ {
+       struct ino_bucket *bp = ivector_table + (long)data;
+       struct irqaction *ap = bp->irq_info;
+-      unsigned long mask = get_smpaff_in_irqaction(ap);
++      cpumask_t mask = get_smpaff_in_irqaction(ap);
++      int len;
++
++      if (cpus_empty(mask))
++              mask = cpu_online_map;
+-      if (count < HEX_DIGITS+1)
++      len = cpumask_snprintf(page, count, mask);
++      if (count - len < 2)
+               return -EINVAL;
+-      return sprintf (page, "%016lx\n", mask == 0 ? ~0UL : mask);
++      len += sprintf(page + len, "\n");
++      return len;
+ }
+ static inline void set_intr_affinity(int irq, unsigned long hw_aff)
+--- linux-2.6.0/arch/sparc64/kernel/systbls.S  2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/sparc64/kernel/systbls.S   2003-12-28 23:21:47.000000000 -0800
+@@ -72,8 +72,8 @@ sys_call_table32:
+ /*250*/       .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
+       .word sys_ni_syscall, compat_clock_settime, compat_clock_gettime, compat_clock_getres, compat_clock_nanosleep
+ /*260*/       .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, compat_timer_settime, compat_timer_gettime, sys_timer_getoverrun
+-      .word sys_timer_delete, sys32_timer_create, sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
+-/*270*/       .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
++      .word sys_timer_delete, sys32_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
++/*270*/       .word compat_sys_io_submit, sys_io_cancel, compat_sys_io_getevents, sys_ni_syscall
+       /* Now the 64-bit native Linux syscall table. */
+--- linux-2.6.0/arch/sparc64/lib/rwlock.S      2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/sparc64/lib/rwlock.S       2003-12-28 23:26:34.000000000 -0800
+@@ -85,5 +85,20 @@ __write_trylock_succeed:
+ __write_trylock_fail:
+       retl
+        mov            0, %o0
++
++      .globl  __read_trylock
++__read_trylock: /* %o0 = lock_ptr */
++      ldsw            [%o0], %g5
++      brlz,pn         %g5, 100f
++      add             %g5, 1, %g7
++      cas             [%o0], %g5, %g7
++      cmp             %g5, %g7
++      bne,pn          %icc, __read_trylock
++       membar         #StoreLoad | #StoreStore
++      retl
++      mov             1, %o0
++100:  retl
++      mov             0, %o0
++
+ rwlock_impl_end:
+--- linux-2.6.0/arch/sparc64/mm/hugetlbpage.c  2003-10-25 14:45:44.000000000 -0700
++++ 25/arch/sparc64/mm/hugetlbpage.c   2003-12-28 23:22:12.000000000 -0800
+@@ -504,7 +504,7 @@ int is_hugepage_mem_enough(size_t size)
+  * this far.
+  */
+ static struct page *hugetlb_nopage(struct vm_area_struct *vma,
+-                                 unsigned long address, int unused)
++                                 unsigned long address, int *unused)
+ {
+       BUG();
+       return NULL;
+--- linux-2.6.0/arch/sparc/kernel/irq.c        2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/sparc/kernel/irq.c 2003-12-28 23:22:06.000000000 -0800
+@@ -102,7 +102,7 @@ struct irqaction *irq_action[NR_IRQS] = 
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i;
++      int i = *(loff_t *) v;
+       struct irqaction * action;
+       unsigned long flags;
+ #ifdef CONFIG_SMP
+@@ -114,7 +114,7 @@ int show_interrupts(struct seq_file *p, 
+               
+               return show_sun4d_interrupts(p, v);
+       }
+-      for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               local_irq_save(flags);
+               action = *(i + irq_action);
+               if (!action) 
+--- linux-2.6.0/arch/sparc/kernel/sun4d_irq.c  2003-06-14 12:17:55.000000000 -0700
++++ 25/arch/sparc/kernel/sun4d_irq.c   2003-12-28 23:22:06.000000000 -0800
+@@ -75,13 +75,13 @@ spinlock_t sun4d_imsk_lock = SPIN_LOCK_U
+ int show_sun4d_interrupts(struct seq_file *p, void *v)
+ {
+-      int i, j = 0, k = 0, sbusl;
++      int i = *(loff_t *) v, j = 0, k = 0, sbusl;
+       struct irqaction * action;
+ #ifdef CONFIG_SMP
+       int x;
+ #endif
+-      for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               sbusl = pil_to_sbus[i];
+               if (!sbusl) {
+                       action = *(i + irq_action);
+--- linux-2.6.0/arch/sparc/mm/highmem.c        2003-06-14 12:18:04.000000000 -0700
++++ 25/arch/sparc/mm/highmem.c 2003-12-28 23:22:58.000000000 -0800
+@@ -33,6 +33,7 @@ void *kmap_atomic(struct page *page, enu
+       unsigned long idx;
+       unsigned long vaddr;
++      /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
+       inc_preempt_count();
+       if (page < highmem_start_page)
+               return page_address(page);
+@@ -69,6 +70,7 @@ void kunmap_atomic(void *kvaddr, enum km
+       if (vaddr < fix_kmap_begin) { // FIXME
+               dec_preempt_count();
++              preempt_check_resched();
+               return;
+       }
+@@ -96,4 +98,5 @@ void kunmap_atomic(void *kvaddr, enum km
+ #endif
+ #endif
+       dec_preempt_count();
++      preempt_check_resched();
+ }
+--- linux-2.6.0/arch/um/drivers/ubd_kern.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/arch/um/drivers/ubd_kern.c      2003-12-28 23:21:17.000000000 -0800
+@@ -49,9 +49,9 @@ static spinlock_t ubd_lock = SPIN_LOCK_U
+ static void (*do_ubd)(void);
+-static int ubd_open(struct inode * inode, struct file * filp);
+-static int ubd_release(struct inode * inode, struct file * file);
+-static int ubd_ioctl(struct inode * inode, struct file * file,
++static int ubd_open(struct block_device *bdev, struct file * filp);
++static int ubd_release(struct gendisk *disk);
++static int ubd_ioctl(struct block_device *bdev, struct file * file,
+                    unsigned int cmd, unsigned long arg);
+ #define MAX_DEV (8)
+@@ -710,9 +710,9 @@ int ubd_driver_init(void){
+ device_initcall(ubd_driver_init);
+-static int ubd_open(struct inode *inode, struct file *filp)
++static int ubd_open(struct block_device *bdev, struct file *filp)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
++      struct gendisk *disk = bdev->bd_disk;
+       struct ubd *dev = disk->private_data;
+       int err = -EISDIR;
+@@ -739,9 +739,8 @@ static int ubd_open(struct inode *inode,
+       return(err);
+ }
+-static int ubd_release(struct inode * inode, struct file * file)
++static int ubd_release(struct gendisk *disk)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct ubd *dev = disk->private_data;
+       if(--dev->count == 0)
+@@ -865,11 +864,11 @@ static void do_ubd_request(request_queue
+       }
+ }
+-static int ubd_ioctl(struct inode * inode, struct file * file,
++static int ubd_ioctl(struct block_device *bdev, struct file * file,
+                    unsigned int cmd, unsigned long arg)
+ {
+       struct hd_geometry *loc = (struct hd_geometry *) arg;
+-      struct ubd *dev = inode->i_bdev->bd_disk->private_data;
++      struct ubd *dev = bdev->bd_disk->private_data;
+       int err;
+       struct hd_driveid ubd_id = {
+               .cyls           = 0,
+@@ -890,7 +889,7 @@ static int ubd_ioctl(struct inode * inod
+       case HDIO_SET_UNMASKINTR:
+               if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
+-              if((arg > 1) || (inode->i_bdev->bd_contains != inode->i_bdev))
++              if((arg > 1) || (bdev->bd_contains != bdev))
+                       return(-EINVAL);
+               return(0);
+@@ -910,7 +909,7 @@ static int ubd_ioctl(struct inode * inod
+       case HDIO_SET_MULTCOUNT:
+               if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
+-              if(inode->i_bdev->bd_contains != inode->i_bdev)
++              if(bdev->bd_contains != bdev)
+                       return(-EINVAL);
+               return(0);
+--- linux-2.6.0/arch/um/kernel/irq.c   2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/um/kernel/irq.c    2003-12-28 23:22:10.000000000 -0800
+@@ -572,53 +572,14 @@ static struct proc_dir_entry * smp_affin
+  */
+ static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
+-#define HEX_DIGITS (2*sizeof(cpumask_t))
+-
+ static int irq_affinity_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      if (count < HEX_DIGITS+1)
+-              return -EINVAL;
+-      return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
+-}
+-
+-static unsigned int parse_hex_value (const char *buffer,
+-              unsigned long count, cpumask_t *ret)
+-{
+-      unsigned char hexnum [HEX_DIGITS];
+-      cpumask_t value = CPU_MASK_NONE;
+-      int i;
+-
+-      if (!count)
++      int len = cpumask_snprintf(page, count, irq_affinity[(long)data]);
++      if (count - len < 2)
+               return -EINVAL;
+-      if (count > HEX_DIGITS)
+-              count = HEX_DIGITS;
+-      if (copy_from_user(hexnum, buffer, count))
+-              return -EFAULT;
+-
+-      /*
+-       * Parse the first 8 characters as a hex string, any non-hex char
+-       * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+-       */
+-
+-      for (i = 0; i < count; i++) {
+-              unsigned int k, c = hexnum[i];
+-
+-              switch (c) {
+-                      case '0' ... '9': c -= '0'; break;
+-                      case 'a' ... 'f': c -= 'a'-10; break;
+-                      case 'A' ... 'F': c -= 'A'-10; break;
+-              default:
+-                      goto out;
+-              }
+-              cpus_shift_left(value, value, 16);
+-              for (k = 0; k < 4; ++k)
+-                      if (c & (1 << k))
+-                              cpu_set(k, value);
+-      }
+-out:
+-      *ret = value;
+-      return 0;
++      len += sprintf(page + len, "\n");
++      return len;
+ }
+ static int irq_affinity_write_proc (struct file *file, const char *buffer,
+@@ -630,7 +591,7 @@ static int irq_affinity_write_proc (stru
+       if (!irq_desc[irq].handler->set_affinity)
+               return -EIO;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+ #ifdef CONFIG_SMP
+       /*
+@@ -652,19 +613,10 @@ static int irq_affinity_write_proc (stru
+ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      cpumask_t tmp, *mask = (cpumask_t *) data;
+-      int k, len = 0;
+-
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, *(cpumask_t *)data);
++      if (count - len < 2)
+               return -EINVAL;
+-      tmp = *mask;
+-      for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-              int j = sprintf(page, "%04hx", cpus_coerce(tmp));
+-              len += j;
+-              page += j;
+-              cpus_shift_right(tmp, tmp, 16);
+-      }
+-      len += sprintf(page, "\n");
++      len += sprintf(page + len, "\n");
+       return len;
+ }
+@@ -674,7 +626,7 @@ static int prof_cpu_mask_write_proc (str
+       cpumask_t *mask = (cpumask_t *)data, new_value;
+       unsigned long full_count = count, err;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       if (err)
+               return err;
+--- linux-2.6.0/arch/v850/kernel/irq.c 2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/v850/kernel/irq.c  2003-12-28 23:22:06.000000000 -0800
+@@ -81,16 +81,18 @@ volatile unsigned long irq_err_count, sp
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i;
++      int i = *(loff_t *) v;
+       struct irqaction * action;
+       unsigned long flags;
+-      seq_puts(p, "           ");
+-      for (i=0; i < 1 /*smp_num_cpus*/; i++)
+-              seq_printf(p, "CPU%d       ", i);
+-      seq_putc(p, '\n');
++      if (i == 0) {
++              seq_puts(p, "           ");
++              for (i=0; i < 1 /*smp_num_cpus*/; i++)
++                      seq_printf(p, "CPU%d       ", i);
++              seq_putc(p, '\n');
++      }
+-      for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               int j, count, num;
+               const char *type_name = irq_desc[i].handler->typename;
+               spin_lock_irqsave(&irq_desc[j].lock, flags);
+@@ -121,8 +123,8 @@ int show_interrupts(struct seq_file *p, 
+               seq_putc(p, '\n');
+ skip:
+               spin_unlock_irqrestore(&irq_desc[j].lock, flags);
+-      }
+-      seq_printf(p, "ERR: %10lu\n", irq_err_count);
++      } else if (i == NR_IRQS)
++              seq_printf(p, "ERR: %10lu\n", irq_err_count);
+       return 0;
+ }
+--- linux-2.6.0/arch/x86_64/boot/compressed/head.S     2003-11-09 16:45:05.000000000 -0800
++++ 25/arch/x86_64/boot/compressed/head.S      2003-12-28 23:21:09.000000000 -0800
+@@ -26,6 +26,7 @@
+ .code32
+ .text
++#define IN_BOOTLOADER
+ #include <linux/linkage.h>
+ #include <asm/segment.h>
+--- linux-2.6.0/arch/x86_64/boot/compressed/misc.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/arch/x86_64/boot/compressed/misc.c      2003-12-28 23:21:09.000000000 -0800
+@@ -9,6 +9,7 @@
+  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+  */
++#define IN_BOOTLOADER
+ #include "miscsetup.h"
+ #include <asm/io.h>
+--- linux-2.6.0/arch/x86_64/defconfig  2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/x86_64/defconfig   2003-12-28 23:26:30.000000000 -0800
+@@ -743,7 +743,7 @@ CONFIG_MAGIC_SYSRQ=y
+ # CONFIG_INIT_DEBUG is not set
+ # CONFIG_DEBUG_INFO is not set
+ # CONFIG_FRAME_POINTER is not set
+-CONFIG_IOMMU_DEBUG=y
++# CONFIG_IOMMU_DEBUG is not set
+ CONFIG_IOMMU_LEAK=y
+ CONFIG_MCE_DEBUG=y
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/arch/x86_64/ia32/ia32_aout.c    2003-12-28 23:22:16.000000000 -0800
+@@ -0,0 +1,506 @@
++/*
++ *  a.out loader for x86-64
++ *
++ *  Copyright (C) 1991, 1992, 1996  Linus Torvalds
++ *  Hacked together by Andi Kleen
++ */
++
++#include <linux/module.h>
++
++#include <linux/time.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++#include <linux/mman.h>
++#include <linux/a.out.h>
++#include <linux/errno.h>
++#include <linux/signal.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/stat.h>
++#include <linux/fcntl.h>
++#include <linux/ptrace.h>
++#include <linux/user.h>
++#include <linux/slab.h>
++#include <linux/binfmts.h>
++#include <linux/personality.h>
++#include <linux/init.h>
++
++#include <asm/system.h>
++#include <asm/uaccess.h>
++#include <asm/pgalloc.h>
++#include <asm/cacheflush.h>
++#include <asm/user32.h>
++
++#undef WARN_OLD
++
++extern int ia32_setup_arg_pages(struct linux_binprm *bprm);
++
++static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
++static int load_aout_library(struct file*);
++static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file);
++
++/*
++ * fill in the user structure for a core dump..
++ */
++static void dump_thread32(struct pt_regs * regs, struct user32 * dump)
++{
++      u32 fs,gs;
++
++/* changed the size calculations - should hopefully work better. lbt */
++      dump->magic = CMAGIC;
++      dump->start_code = 0;
++      dump->start_stack = regs->rsp & ~(PAGE_SIZE - 1);
++      dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
++      dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
++      dump->u_dsize -= dump->u_tsize;
++      dump->u_ssize = 0;
++      dump->u_debugreg[0] = current->thread.debugreg0;  
++      dump->u_debugreg[1] = current->thread.debugreg1;  
++      dump->u_debugreg[2] = current->thread.debugreg2;  
++      dump->u_debugreg[3] = current->thread.debugreg3;  
++      dump->u_debugreg[4] = 0;  
++      dump->u_debugreg[5] = 0;  
++      dump->u_debugreg[6] = current->thread.debugreg6;  
++      dump->u_debugreg[7] = current->thread.debugreg7;  
++
++      if (dump->start_stack < 0xc0000000)
++              dump->u_ssize = ((unsigned long) (0xc0000000 - dump->start_stack)) >> PAGE_SHIFT;
++
++      dump->regs.ebx = regs->rbx;
++      dump->regs.ecx = regs->rcx;
++      dump->regs.edx = regs->rdx;
++      dump->regs.esi = regs->rsi;
++      dump->regs.edi = regs->rdi;
++      dump->regs.ebp = regs->rbp;
++      dump->regs.eax = regs->rax;
++      dump->regs.ds = current->thread.ds;
++      dump->regs.es = current->thread.es;
++      asm("movl %%fs,%0" : "=r" (fs)); dump->regs.fs = fs;
++      asm("movl %%gs,%0" : "=r" (gs)); dump->regs.gs = gs; 
++      dump->regs.orig_eax = regs->orig_rax;
++      dump->regs.eip = regs->rip;
++      dump->regs.cs = regs->cs;
++      dump->regs.eflags = regs->eflags;
++      dump->regs.esp = regs->rsp;
++      dump->regs.ss = regs->ss;
++
++#if 1 /* FIXME */
++      dump->u_fpvalid = 0;
++#else
++      dump->u_fpvalid = dump_fpu (regs, &dump->i387);
++#endif
++}
++
++static struct linux_binfmt aout_format = {
++      .module         = THIS_MODULE,
++      .load_binary    = load_aout_binary,
++      .load_shlib     = load_aout_library,
++      .core_dump      = aout_core_dump,
++      .min_coredump   = PAGE_SIZE
++};
++
++static void set_brk(unsigned long start, unsigned long end)
++{
++      start = PAGE_ALIGN(start);
++      end = PAGE_ALIGN(end);
++      if (end <= start)
++              return;
++      do_brk(start, end - start);
++}
++
++/*
++ * These are the only things you should do on a core-file: use only these
++ * macros to write out all the necessary info.
++ */
++
++static int dump_write(struct file *file, const void *addr, int nr)
++{
++      return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
++}
++
++#define DUMP_WRITE(addr, nr)  \
++      if (!dump_write(file, (void *)(addr), (nr))) \
++              goto end_coredump;
++
++#define DUMP_SEEK(offset) \
++if (file->f_op->llseek) { \
++      if (file->f_op->llseek(file,(offset),0) != (offset)) \
++              goto end_coredump; \
++} else file->f_pos = (offset)
++
++/*
++ * Routine writes a core dump image in the current directory.
++ * Currently only a stub-function.
++ *
++ * Note that setuid/setgid files won't make a core-dump if the uid/gid
++ * changed due to the set[u|g]id. It's enforced by the "current->mm->dumpable"
++ * field, which also makes sure the core-dumps won't be recursive if the
++ * dumping of the process results in another error..
++ */
++
++static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
++{
++      mm_segment_t fs;
++      int has_dumped = 0;
++      unsigned long dump_start, dump_size;
++      struct user32 dump;
++#       define START_DATA(u)  (u.u_tsize << PAGE_SHIFT)
++#       define START_STACK(u)   (u.start_stack)
++
++      fs = get_fs();
++      set_fs(KERNEL_DS);
++      has_dumped = 1;
++      current->flags |= PF_DUMPCORE;
++              strncpy(dump.u_comm, current->comm, sizeof(current->comm));
++      dump.u_ar0 = (u32)(((unsigned long)(&dump.regs)) - ((unsigned long)(&dump)));
++      dump.signal = signr;
++      dump_thread32(regs, &dump);
++
++/* If the size of the dump file exceeds the rlimit, then see what would happen
++   if we wrote the stack, but not the data area.  */
++      if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
++          current->rlim[RLIMIT_CORE].rlim_cur)
++              dump.u_dsize = 0;
++
++/* Make sure we have enough room to write the stack and data areas. */
++      if ((dump.u_ssize+1) * PAGE_SIZE >
++          current->rlim[RLIMIT_CORE].rlim_cur)
++              dump.u_ssize = 0;
++
++/* make sure we actually have a data and stack area to dump */
++      set_fs(USER_DS);
++      if (verify_area(VERIFY_READ, (void *) (unsigned long)START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
++              dump.u_dsize = 0;
++      if (verify_area(VERIFY_READ, (void *) (unsigned long)START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
++              dump.u_ssize = 0;
++
++      set_fs(KERNEL_DS);
++/* struct user */
++      DUMP_WRITE(&dump,sizeof(dump));
++/* Now dump all of the user data.  Include malloced stuff as well */
++      DUMP_SEEK(PAGE_SIZE);
++/* now we start writing out the user space info */
++      set_fs(USER_DS);
++/* Dump the data area */
++      if (dump.u_dsize != 0) {
++              dump_start = START_DATA(dump);
++              dump_size = dump.u_dsize << PAGE_SHIFT;
++              DUMP_WRITE(dump_start,dump_size);
++      }
++/* Now prepare to dump the stack area */
++      if (dump.u_ssize != 0) {
++              dump_start = START_STACK(dump);
++              dump_size = dump.u_ssize << PAGE_SHIFT;
++              DUMP_WRITE(dump_start,dump_size);
++      }
++/* Finally dump the task struct.  Not be used by gdb, but could be useful */
++      set_fs(KERNEL_DS);
++      DUMP_WRITE(current,sizeof(*current));
++end_coredump:
++      set_fs(fs);
++      return has_dumped;
++}
++
++/*
++ * create_aout_tables() parses the env- and arg-strings in new user
++ * memory and creates the pointer tables from them, and puts their
++ * addresses on the "stack", returning the new stack pointer value.
++ */
++static u32 * create_aout_tables(char * p, struct linux_binprm * bprm)
++{
++      u32 *argv, *envp;
++      u32 * sp;
++      int argc = bprm->argc;
++      int envc = bprm->envc;
++
++      sp = (u32 *) ((-(unsigned long)sizeof(u32)) & (unsigned long) p);
++      sp -= envc+1;
++      envp = (u32 *) sp;
++      sp -= argc+1;
++      argv = (u32 *) sp;
++      put_user((unsigned long) envp,--sp);
++      put_user((unsigned long) argv,--sp);
++      put_user(argc,--sp);
++      current->mm->arg_start = (unsigned long) p;
++      while (argc-->0) {
++              char c;
++              put_user((u32)(unsigned long)p,argv++);
++              do {
++                      get_user(c,p++);
++              } while (c);
++      }
++      put_user(NULL,argv);
++      current->mm->arg_end = current->mm->env_start = (unsigned long) p;
++      while (envc-->0) {
++              char c;
++              put_user((u32)(unsigned long)p,envp++);
++              do {
++                      get_user(c,p++);
++              } while (c);
++      }
++      put_user(NULL,envp);
++      current->mm->env_end = (unsigned long) p;
++      return sp;
++}
++
++/*
++ * These are the functions used to load a.out style executables and shared
++ * libraries.  There is no binary dependent code anywhere else.
++ */
++
++static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
++{
++      struct exec ex;
++      unsigned long error;
++      unsigned long fd_offset;
++      unsigned long rlim;
++      int retval;
++
++      ex = *((struct exec *) bprm->buf);              /* exec-header */
++      if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
++           N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) ||
++          N_TRSIZE(ex) || N_DRSIZE(ex) ||
++          i_size_read(bprm->file->f_dentry->d_inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
++              return -ENOEXEC;
++      }
++
++      fd_offset = N_TXTOFF(ex);
++
++      /* Check initial limits. This avoids letting people circumvent
++       * size limits imposed on them by creating programs with large
++       * arrays in the data or bss.
++       */
++      rlim = current->rlim[RLIMIT_DATA].rlim_cur;
++      if (rlim >= RLIM_INFINITY)
++              rlim = ~0;
++      if (ex.a_data + ex.a_bss > rlim)
++              return -ENOMEM;
++
++      /* Flush all traces of the currently running executable */
++      retval = flush_old_exec(bprm);
++      if (retval)
++              return retval;
++
++      regs->cs = __USER32_CS; 
++      regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
++              regs->r13 = regs->r14 = regs->r15 = 0;
++      set_thread_flag(TIF_IA32); 
++
++      /* OK, This is the point of no return */
++      set_personality(PER_LINUX);
++
++      current->mm->end_code = ex.a_text +
++              (current->mm->start_code = N_TXTADDR(ex));
++      current->mm->end_data = ex.a_data +
++              (current->mm->start_data = N_DATADDR(ex));
++      current->mm->brk = ex.a_bss +
++              (current->mm->start_brk = N_BSSADDR(ex));
++      current->mm->free_area_cache = TASK_UNMAPPED_BASE;
++
++      current->mm->rss = 0;
++      current->mm->mmap = NULL;
++      compute_creds(bprm);
++      current->flags &= ~PF_FORKNOEXEC;
++
++      if (N_MAGIC(ex) == OMAGIC) {
++              unsigned long text_addr, map_size;
++              loff_t pos;
++
++              text_addr = N_TXTADDR(ex);
++
++              pos = 32;
++              map_size = ex.a_text+ex.a_data;
++
++              error = do_brk(text_addr & PAGE_MASK, map_size);
++              if (error != (text_addr & PAGE_MASK)) {
++                      send_sig(SIGKILL, current, 0);
++                      return error;
++              }
++
++              error = bprm->file->f_op->read(bprm->file, (char *)text_addr,
++                        ex.a_text+ex.a_data, &pos);
++              if ((signed long)error < 0) {
++                      send_sig(SIGKILL, current, 0);
++                      return error;
++              }
++                       
++              flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data);
++      } else {
++#ifdef WARN_OLD
++              static unsigned long error_time, error_time2;
++              if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
++                  (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time2) > 5*HZ)
++              {
++                      printk(KERN_NOTICE "executable not page aligned\n");
++                      error_time2 = jiffies;
++              }
++
++              if ((fd_offset & ~PAGE_MASK) != 0 &&
++                  (jiffies-error_time) > 5*HZ)
++              {
++                      printk(KERN_WARNING 
++                             "fd_offset is not page aligned. Please convert program: %s\n",
++                             bprm->file->f_dentry->d_name.name);
++                      error_time = jiffies;
++              }
++#endif
++
++              if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
++                      loff_t pos = fd_offset;
++                      do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
++                      bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex),
++                                      ex.a_text+ex.a_data, &pos);
++                      flush_icache_range((unsigned long) N_TXTADDR(ex),
++                                         (unsigned long) N_TXTADDR(ex) +
++                                         ex.a_text+ex.a_data);
++                      goto beyond_if;
++              }
++
++              down_write(&current->mm->mmap_sem);
++              error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
++                      PROT_READ | PROT_EXEC,
++                      MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT,
++                      fd_offset);
++              up_write(&current->mm->mmap_sem);
++
++              if (error != N_TXTADDR(ex)) {
++                      send_sig(SIGKILL, current, 0);
++                      return error;
++              }
++
++              down_write(&current->mm->mmap_sem);
++              error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
++                              PROT_READ | PROT_WRITE | PROT_EXEC,
++                              MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT,
++                              fd_offset + ex.a_text);
++              up_write(&current->mm->mmap_sem);
++              if (error != N_DATADDR(ex)) {
++                      send_sig(SIGKILL, current, 0);
++                      return error;
++              }
++      }
++beyond_if:
++      set_binfmt(&aout_format);
++
++      set_brk(current->mm->start_brk, current->mm->brk);
++
++      retval = ia32_setup_arg_pages(bprm); 
++      if (retval < 0) { 
++              /* Someone check-me: is this error path enough? */ 
++              send_sig(SIGKILL, current, 0); 
++              return retval;
++      }
++
++      current->mm->start_stack =
++              (unsigned long) create_aout_tables((char *) bprm->p, bprm);
++      /* start thread */
++      asm volatile("movl %0,%%fs" :: "r" (0)); \
++      asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS));
++      load_gs_index(0); 
++      (regs)->rip = ex.a_entry;
++      (regs)->rsp = current->mm->start_stack;
++      (regs)->eflags = 0x200;
++      (regs)->cs = __USER32_CS;
++      (regs)->ss = __USER32_DS;
++      set_fs(USER_DS);
++      if (unlikely(current->ptrace & PT_PTRACED)) {
++              if (current->ptrace & PT_TRACE_EXEC)
++                      ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
++              else
++                      send_sig(SIGTRAP, current, 0);
++      }
++      return 0;
++}
++
++static int load_aout_library(struct file *file)
++{
++      struct inode * inode;
++      unsigned long bss, start_addr, len;
++      unsigned long error;
++      int retval;
++      struct exec ex;
++
++      inode = file->f_dentry->d_inode;
++
++      retval = -ENOEXEC;
++      error = kernel_read(file, 0, (char *) &ex, sizeof(ex));
++      if (error != sizeof(ex))
++              goto out;
++
++      /* We come in here for the regular a.out style of shared libraries */
++      if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||
++          N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
++          i_size_read(inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
++              goto out;
++      }
++
++      if (N_FLAGS(ex))
++              goto out;
++
++      /* For  QMAGIC, the starting address is 0x20 into the page.  We mask
++         this off to get the starting address for the page */
++
++      start_addr =  ex.a_entry & 0xfffff000;
++
++      if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) {
++              loff_t pos = N_TXTOFF(ex);
++
++#ifdef WARN_OLD
++              static unsigned long error_time;
++              if ((jiffies-error_time) > 5*HZ)
++              {
++                      printk(KERN_WARNING 
++                             "N_TXTOFF is not page aligned. Please convert library: %s\n",
++                             file->f_dentry->d_name.name);
++                      error_time = jiffies;
++              }
++#endif
++
++              do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
++              
++              file->f_op->read(file, (char *)start_addr,
++                      ex.a_text + ex.a_data, &pos);
++              flush_icache_range((unsigned long) start_addr,
++                                 (unsigned long) start_addr + ex.a_text + ex.a_data);
++
++              retval = 0;
++              goto out;
++      }
++      /* Now use mmap to map the library into memory. */
++      down_write(&current->mm->mmap_sem);
++      error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
++                      PROT_READ | PROT_WRITE | PROT_EXEC,
++                      MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT,
++                      N_TXTOFF(ex));
++      up_write(&current->mm->mmap_sem);
++      retval = error;
++      if (error != start_addr)
++              goto out;
++
++      len = PAGE_ALIGN(ex.a_text + ex.a_data);
++      bss = ex.a_text + ex.a_data + ex.a_bss;
++      if (bss > len) {
++              error = do_brk(start_addr + len, bss - len);
++              retval = error;
++              if (error != start_addr + len)
++                      goto out;
++      }
++      retval = 0;
++out:
++      return retval;
++}
++
++static int __init init_aout_binfmt(void)
++{
++      return register_binfmt(&aout_format);
++}
++
++static void __exit exit_aout_binfmt(void)
++{
++      unregister_binfmt(&aout_format);
++}
++
++module_init(init_aout_binfmt);
++module_exit(exit_aout_binfmt);
++MODULE_LICENSE("GPL");
+--- linux-2.6.0/arch/x86_64/ia32/ia32entry.S   2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/x86_64/ia32/ia32entry.S    2003-12-28 23:26:31.000000000 -0800
+@@ -221,7 +221,7 @@ ia32_sys_call_table:
+       .quad sys_chmod         /* 15 */
+       .quad sys_lchown16
+       .quad ni_syscall                        /* old break syscall holder */
+-      .quad ni_syscall        /* (old)stat */ 
++      .quad sys_stat
+       .quad sys32_lseek
+       .quad sys_getpid                /* 20 */
+       .quad sys_mount /* mount  */
+@@ -231,7 +231,7 @@ ia32_sys_call_table:
+       .quad sys_stime         /* stime */             /* 25 */
+       .quad sys32_ptrace      /* ptrace */
+       .quad sys_alarm         /* XXX sign extension??? */ 
+-      .quad ni_syscall        /* (old)fstat */
++      .quad sys_fstat /* (old)fstat */
+       .quad sys_pause
+       .quad compat_sys_utime  /* 30 */
+       .quad ni_syscall        /* old stty syscall holder */
+@@ -287,7 +287,7 @@ ia32_sys_call_table:
+       .quad sys_setgroups16
+       .quad sys32_old_select
+       .quad sys_symlink
+-      .quad ni_syscall        /* (old)lstat */
++      .quad sys_lstat
+       .quad sys_readlink              /* 85 */
+       .quad sys_uselib
+       .quad sys_swapon
+@@ -396,8 +396,8 @@ ia32_sys_call_table:
+       .quad stub32_vfork            /* 190 */
+       .quad compat_sys_getrlimit
+       .quad sys32_mmap2
+-      .quad sys_truncate
+-      .quad sys_ftruncate
++      .quad sys32_truncate64
++      .quad sys32_ftruncate64
+       .quad sys32_stat64              /* 195 */
+       .quad sys32_lstat64
+       .quad sys32_fstat64
+--- linux-2.6.0/arch/x86_64/ia32/ia32_signal.c 2003-09-08 13:58:56.000000000 -0700
++++ 25/arch/x86_64/ia32/ia32_signal.c  2003-12-28 23:26:32.000000000 -0800
+@@ -46,25 +46,25 @@ void signal_fault(struct pt_regs *regs, 
+ static int ia32_copy_siginfo_to_user(siginfo_t32 *to, siginfo_t *from)
+ {
++      int err;
+       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+               return -EFAULT;
+-      if (from->si_code < 0) { 
+-              /* the only field that's different is the alignment
+-                 of the pointer in sigval_t. Move that 4 bytes down including
+-                 padding. */
+-              memmove(&((siginfo_t32 *)&from)->si_int,
+-                      &from->si_int, 
+-                      sizeof(siginfo_t) - offsetof(siginfo_t, si_int));
+-              /* last 4 bytes stay the same */
+-              return __copy_to_user(to, from, sizeof(siginfo_t32));
+-      } else {
+-              int err;
+-              /* If you change siginfo_t structure, please be sure
++      /* If you change siginfo_t structure, please make sure that
+                  this code is fixed accordingly.
+                  It should never copy any pad contained in the structure
+                  to avoid security leaks, but must copy the generic
+                  3 ints plus the relevant union member.  */
++
++      if (from->si_code < 0) {
++              err = __put_user(from->si_signo, &to->si_signo);
++              err |= __put_user(from->si_errno, &to->si_errno);
++              err |= __put_user(from->si_code, &to->si_code);
++              err |= __put_user(from->_sifields._rt._pid, &to->_sifields._rt._pid);
++              err |= __put_user(from->_sifields._rt._uid, &to->_sifields._rt._uid);
++              err |= __put_user((u32)(u64)from->_sifields._rt._sigval.sival_ptr,
++                                &to->_sifields._rt._sigval.sival_ptr);
++      } else {
+               err = __put_user(from->si_signo, &to->si_signo);
+               err |= __put_user(from->si_errno, &to->si_errno);
+               err |= __put_user(from->si_code, &to->si_code);
+@@ -86,8 +86,8 @@ static int ia32_copy_siginfo_to_user(sig
+                       break;
+               /* case __SI_RT: This is not generated by the kernel as of now.  */
+               }
+-              return err;
+       }
++      return err;
+ }
+ asmlinkage long
+@@ -173,6 +173,9 @@ ia32_restore_sigcontext(struct pt_regs *
+ {
+       unsigned int err = 0;
+       
++      /* Always make any pending restarted system calls return -EINTR */
++      current_thread_info()->restart_block.fn = do_no_restart_syscall;
++
+ #if DEBUG_SIG
+       printk("SIG restore_sigcontext: sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
+               sc, sc->err, sc->eip, sc->cs, sc->eflags);
+--- linux-2.6.0/arch/x86_64/ia32/Makefile      2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/x86_64/ia32/Makefile       2003-12-28 23:22:16.000000000 -0800
+@@ -6,6 +6,8 @@ obj-$(CONFIG_IA32_EMULATION) := ia32entr
+       ia32_signal.o tls32.o \
+       ia32_binfmt.o fpu32.o ptrace32.o ipc32.o syscall32.o
++obj-$(CONFIG_IA32_AOUT) += ia32_aout.o
++
+ $(obj)/syscall32.o: $(src)/syscall32.c $(obj)/vsyscall.so
+ # Teach kbuild about targets
+--- linux-2.6.0/arch/x86_64/ia32/sys_ia32.c    2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/x86_64/ia32/sys_ia32.c     2003-12-28 23:26:31.000000000 -0800
+@@ -110,6 +110,21 @@ int cp_compat_stat(struct kstat *kbuf, s
+       return 0;
+ }
++extern long sys_truncate(char *, loff_t);
++extern long sys_ftruncate(int, loff_t);
++
++asmlinkage long
++sys32_truncate64(char * filename, unsigned long offset_low, unsigned long offset_high)
++{
++       return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low);
++}
++
++asmlinkage long
++sys32_ftruncate64(unsigned int fd, unsigned long offset_low, unsigned long offset_high)
++{
++       return sys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low);
++}
++
+ /* Another set for IA32/LFS -- x86_64 struct stat is different due to 
+    support for 64bit inode numbers. */
+--- linux-2.6.0/arch/x86_64/Kconfig    2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/x86_64/Kconfig     2003-12-28 23:26:30.000000000 -0800
+@@ -314,7 +314,7 @@ config SOFTWARE_SUSPEND
+         This option is close to getting stable. However there is still some
+         absence of features.
+-        For more information take a look at Documentation/swsusp.txt.
++        For more information take a look at Documentation/power/swsusp.txt.
+ source "drivers/acpi/Kconfig"
+@@ -371,6 +371,12 @@ config IA32_EMULATION
+         turn this on, unless you're 100% sure that you don't have any 32-bit programs
+         left.
++config IA32_AOUT
++       bool "IA32 a.out support"
++       depends on IA32_EMULATION
++       help
++         Support old a.out binaries in the 32bit emulation.
++
+ config COMPAT
+       bool
+       depends on IA32_EMULATION
+@@ -505,6 +511,7 @@ config FRAME_POINTER
+        Normally you should say N.
+ config IOMMU_DEBUG
++       depends on GART_IOMMU && DEBUG_KERNEL
+        bool "Force IOMMU to on" 
+        help
+          Force the IOMMU to on even when you have less than 4GB of memory and add 
+--- linux-2.6.0/arch/x86_64/kernel/acpi/boot.c 2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/x86_64/kernel/acpi/boot.c  2003-12-28 23:21:33.000000000 -0800
+@@ -46,11 +46,13 @@
+ #include <asm/proto.h>
+ #include <asm/tlbflush.h>
+-int acpi_lapic = 0;
+-int acpi_ioapic = 0;
+-
+ #define PREFIX                        "ACPI: "
++int acpi_noirq __initdata = 0;        /* skip ACPI IRQ initialization */
++int acpi_ht __initdata = 1;   /* enable HT */
++
++int acpi_lapic = 0;
++int acpi_ioapic = 0;
+ /* --------------------------------------------------------------------------
+                               Boot-time Configuration
+@@ -253,29 +255,66 @@ acpi_parse_hpet (
+ #ifdef CONFIG_ACPI_BUS
+ /*
+- * Set specified PIC IRQ to level triggered mode.
++ * "acpi_pic_sci=level" (current default)
++ * programs the PIC-mode SCI to Level Trigger.
++ * (NO-OP if the BIOS set Level Trigger already)
++ *
++ * If a PIC-mode SCI is not recogznied or gives spurious IRQ7's
++ * it may require Edge Trigger -- use "acpi_pic_sci=edge"
++ * (NO-OP if the BIOS set Edge Trigger already)
+  *
+  * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers
+  * for the 8259 PIC.  bit[n] = 1 means irq[n] is Level, otherwise Edge.
+  * ECLR1 is IRQ's 0-7 (IRQ 0, 1, 2 must be 0)
+  * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0)
+- *
+- * As the BIOS should have done this for us,
+- * print a warning if the IRQ wasn't already set to level.
+  */
+-void acpi_pic_set_level_irq(unsigned int irq)
++static int __initdata acpi_pic_sci_trigger;   /* 0: level, 1: edge */
++
++void __init
++acpi_pic_sci_set_trigger(unsigned int irq)
+ {
+       unsigned char mask = 1 << (irq & 7);
+       unsigned int port = 0x4d0 + (irq >> 3);
+       unsigned char val = inb(port);
++      
++      printk(PREFIX "IRQ%d SCI:", irq);
+       if (!(val & mask)) {
+-              printk(KERN_WARNING PREFIX "IRQ %d was Edge Triggered, "
+-                      "setting to Level Triggerd\n", irq);
+-              outb(val | mask, port);
++              printk(" Edge");
++
++              if (!acpi_pic_sci_trigger) {
++                      printk(" set to Level");
++                      outb(val | mask, port);
++              }
++      } else {
++              printk(" Level");
++
++              if (acpi_pic_sci_trigger) {
++                      printk(" set to Edge");
++                      outb(val | mask, port);
++              }
+       }
++      printk(" Trigger.\n");
+ }
++
++int __init
++acpi_pic_sci_setup(char *str)
++{
++      while (str && *str) {
++              if (strncmp(str, "level", 5) == 0)
++                      acpi_pic_sci_trigger = 0;       /* force level trigger */
++              if (strncmp(str, "edge", 4) == 0)
++                      acpi_pic_sci_trigger = 1;       /* force edge trigger */
++              str = strchr(str, ',');
++              if (str)
++                      str += strspn(str, ", \t");
++      }
++      return 1;
++}
++
++__setup("acpi_pic_sci=", acpi_pic_sci_setup);
++
+ #endif /* CONFIG_ACPI_BUS */
+ static unsigned long __init
+@@ -354,8 +393,10 @@ acpi_boot_init (void)
+        * Initialize the ACPI boot-time table parser.
+        */
+       result = acpi_table_init();
+-      if (result)
++      if (result) {
++              acpi_disabled = 1;
+               return result;
++      }
+       result = acpi_blacklisted();
+       if (result) {
+@@ -442,7 +483,7 @@ acpi_boot_init (void)
+         * If MPS is present, it will handle them,
+         * otherwise the system will stay in PIC mode
+         */
+-        if (acpi_disabled) {
++        if (acpi_disabled || acpi_noirq) {
+                return 1;
+       }
+@@ -484,6 +525,8 @@ acpi_boot_init (void)
+       acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
++      acpi_irq_balance_set(NULL);
++
+       acpi_ioapic = 1;
+ #endif /*CONFIG_X86_IO_APIC*/
+--- linux-2.6.0/arch/x86_64/kernel/io_apic.c   2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/x86_64/kernel/io_apic.c    2003-12-28 23:21:33.000000000 -0800
+@@ -1087,8 +1087,6 @@ static void __init setup_ioapic_ids_from
+       unsigned char old_id;
+       unsigned long flags;
+-      if (acpi_ioapic) return; /* ACPI does that already */
+-
+       /*
+        * Set the IOAPIC ID to the value stored in the MPC table.
+        */
+@@ -1673,12 +1671,14 @@ void __init setup_IO_APIC(void)
+       /*
+        * Set up the IO-APIC IRQ routing table.
+        */
+-      setup_ioapic_ids_from_mpc();
++      if (!acpi_ioapic)
++              setup_ioapic_ids_from_mpc();
+       sync_Arb_IDs();
+       setup_IO_APIC_irqs();
+       init_IO_APIC_traps();
+       check_timer();
+-      print_IO_APIC();
++      if (!acpi_ioapic)
++              print_IO_APIC();
+ }
+ /* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
+--- linux-2.6.0/arch/x86_64/kernel/irq.c       2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/x86_64/kernel/irq.c        2003-12-28 23:22:10.000000000 -0800
+@@ -138,17 +138,19 @@ atomic_t irq_mis_count;
+ int show_interrupts(struct seq_file *p, void *v)
+ {
+-      int i, j;
++      int i = *(loff_t *) v, j;
+       struct irqaction * action;
+       unsigned long flags;
+-      seq_printf(p, "           ");
+-      for (j=0; j<NR_CPUS; j++)
+-              if (cpu_online(j))
+-              seq_printf(p, "CPU%d       ",j);
+-      seq_putc(p, '\n');
++      if (i == 0) {
++              seq_printf(p, "           ");
++              for (j=0; j<NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "CPU%d       ",j);
++              seq_putc(p, '\n');
++      }
+-      for (i = 0 ; i < NR_IRQS ; i++) {
++      if (i < NR_IRQS) {
+               spin_lock_irqsave(&irq_desc[i].lock, flags);
+               action = irq_desc[i].action;
+               if (!action) 
+@@ -170,25 +172,26 @@ int show_interrupts(struct seq_file *p, 
+               seq_putc(p, '\n');
+ skip:
+               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+-      }
+-      seq_printf(p, "NMI: ");
+-      for (j = 0; j < NR_CPUS; j++)
+-              if (cpu_online(j))
+-              seq_printf(p, "%10u ", cpu_pda[j].__nmi_count);
+-      seq_putc(p, '\n');
++      } else if (i == NR_IRQS) {
++              seq_printf(p, "NMI: ");
++              for (j = 0; j < NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "%10u ", cpu_pda[j].__nmi_count);
++              seq_putc(p, '\n');
+ #ifdef CONFIG_X86_LOCAL_APIC
+-      seq_printf(p, "LOC: ");
+-      for (j = 0; j < NR_CPUS; j++)
+-              if (cpu_online(j))
+-              seq_printf(p, "%10u ", cpu_pda[j].apic_timer_irqs);
+-      seq_putc(p, '\n');
++              seq_printf(p, "LOC: ");
++              for (j = 0; j < NR_CPUS; j++)
++                      if (cpu_online(j))
++                              seq_printf(p, "%10u ", cpu_pda[j].apic_timer_irqs);
++              seq_putc(p, '\n');
+ #endif
+-      seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
++              seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+ #ifdef CONFIG_X86_IO_APIC
+ #ifdef APIC_MISMATCH_DEBUG
+-      seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
++              seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+ #endif
+ #endif
++      }
+       return 0;
+ }
+@@ -801,47 +804,6 @@ int setup_irq(unsigned int irq, struct i
+ static struct proc_dir_entry * root_irq_dir;
+ static struct proc_dir_entry * irq_dir [NR_IRQS];
+-#define HEX_DIGITS (2*sizeof(cpumask_t))
+-
+-static unsigned int parse_hex_value (const char *buffer,
+-              unsigned long count, cpumask_t *ret)
+-{
+-      unsigned char hexnum [HEX_DIGITS];
+-      cpumask_t value = CPU_MASK_NONE;
+-      unsigned i;
+-
+-      if (!count)
+-              return -EINVAL;
+-      if (count > HEX_DIGITS)
+-              count = HEX_DIGITS;
+-      if (copy_from_user(hexnum, buffer, count))
+-              return -EFAULT;
+-
+-      /*
+-       * Parse the first 8 characters as a hex string, any non-hex char
+-       * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+-       */
+-
+-      for (i = 0; i < count; i++) {
+-              unsigned int k, c = hexnum[i];
+-
+-              switch (c) {
+-                      case '0' ... '9': c -= '0'; break;
+-                      case 'a' ... 'f': c -= 'a'-10; break;
+-                      case 'A' ... 'F': c -= 'A'-10; break;
+-              default:
+-                      goto out;
+-              }
+-              cpus_shift_left(value, value, 4);
+-              for (k = 0; k < 4; ++k)
+-                      if (c & (1 << k))
+-                              cpu_set(k, value);
+-      }
+-out:
+-      *ret = value;
+-      return 0;
+-}
+-
+ #ifdef CONFIG_SMP
+ static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+@@ -850,19 +812,10 @@ static cpumask_t irq_affinity [NR_IRQS] 
+ static int irq_affinity_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      int k, len;
+-      cpumask_t tmp = irq_affinity[(long)data];
+-
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, irq_affinity[(long)data]);
++      if (count - len < 2)
+               return -EINVAL;
+-
+-      for (k = len = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-              int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
+-              len += j;
+-              page += j;
+-              cpus_shift_right(tmp, tmp, 16);
+-      }
+-      len += sprintf(page, "\n");
++      len += sprintf(page + len, "\n");
+       return len;
+ }
+@@ -875,7 +828,7 @@ static int irq_affinity_write_proc (stru
+       if (!irq_desc[irq].handler->set_affinity)
+               return -EIO;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       /*
+        * Do not allow disabling IRQs completely - it's a too easy
+@@ -897,20 +850,10 @@ static int irq_affinity_write_proc (stru
+ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+                       int count, int *eof, void *data)
+ {
+-      cpumask_t tmp, *mask = (cpumask_t *) data;
+-      int k, len;
+-
+-      if (count < HEX_DIGITS+1)
++      int len = cpumask_snprintf(page, count, *(cpumask_t *)data);
++      if (count - len < 2)
+               return -EINVAL;
+-
+-      tmp = *mask;
+-      for (k = len = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-              int j = sprintf(page, "%04hx", (u16)cpus_coerce(tmp));
+-              len += j;
+-              page += j;
+-              cpus_shift_right(tmp, tmp, 16);
+-      }
+-      len += sprintf(page, "\n");
++      len += sprintf(page + len, "\n");
+       return len;
+ }
+@@ -920,7 +863,7 @@ static int prof_cpu_mask_write_proc (str
+       unsigned long full_count = count, err;
+       cpumask_t new_value, *mask = (cpumask_t *)data;
+-      err = parse_hex_value(buffer, count, &new_value);
++      err = cpumask_parse(buffer, count, new_value);
+       if (err)
+               return err;
+--- linux-2.6.0/arch/x86_64/kernel/Makefile    2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/x86_64/kernel/Makefile     2003-12-28 23:26:30.000000000 -0800
+@@ -25,6 +25,6 @@ obj-$(CONFIG_DUMMY_IOMMU)    += pci-nommu.o
+ obj-$(CONFIG_MODULES)         += module.o
+ bootflag-y                    += ../../i386/kernel/bootflag.o
+-cpuid-$(CONFIG_X86_CPUID)     += ../../i386/kernel/cpuid.o
++cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  += ../../i386/kernel/cpuid.o
+ obj-$(CONFIG_CPU_FREQ)        +=      cpufreq/
+--- linux-2.6.0/arch/x86_64/kernel/mpparse.c   2003-09-27 18:57:44.000000000 -0700
++++ 25/arch/x86_64/kernel/mpparse.c    2003-12-28 23:26:32.000000000 -0800
+@@ -226,7 +226,7 @@ static int __init smp_read_mpc(struct mp
+       unsigned char *mpt=((unsigned char *)mpc)+count;
+       if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) {
+-              panic("SMP mptable: bad signature [%c%c%c%c]!\n",
++              printk("SMP mptable: bad signature [%c%c%c%c]!\n",
+                       mpc->mpc_signature[0],
+                       mpc->mpc_signature[1],
+                       mpc->mpc_signature[2],
+@@ -234,7 +234,7 @@ static int __init smp_read_mpc(struct mp
+               return 0;
+       }
+       if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) {
+-              panic("SMP mptable: checksum error!\n");
++              printk("SMP mptable: checksum error!\n");
+               return 0;
+       }
+       if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) {
+@@ -950,6 +950,8 @@ void __init mp_parse_prt (void)
+                       entry->irq);
+       }
+       
++      print_IO_APIC();
++
+       return;
+ }
+--- linux-2.6.0/arch/x86_64/kernel/pci-gart.c  2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/x86_64/kernel/pci-gart.c   2003-12-28 23:26:30.000000000 -0800
+@@ -44,12 +44,13 @@ static int no_agp; 
+ #ifdef CONFIG_IOMMU_DEBUG
+ int panic_on_overflow = 1; 
+ int force_iommu = 1;
+-int sac_force_size = 0; 
+ #else
+-int panic_on_overflow = 1; /* for testing */
++int panic_on_overflow = 0;
+ int force_iommu = 0;
+-int sac_force_size = 256*1024*1024;
+ #endif
++int iommu_merge = 0; 
++int iommu_sac_force = 0; 
++int iommu_fullflush = 1;
+ /* Allocation bitmap for the remapping area */ 
+ static spinlock_t iommu_bitmap_lock = SPIN_LOCK_UNLOCKED;
+@@ -125,7 +126,7 @@ static void free_iommu(unsigned long off
+ /* 
+  * Use global flush state to avoid races with multiple flushers.
+  */
+-static void __flush_gart(struct pci_dev *dev)
++static void flush_gart(struct pci_dev *dev)
+ { 
+       unsigned long flags;
+       int bus = dev ? dev->bus->number : -1;
+@@ -134,13 +135,17 @@ static void __flush_gart(struct pci_dev 
+       int i;
+       spin_lock_irqsave(&iommu_bitmap_lock, flags);
+-      /* recheck flush count inside lock */
+-      if (need_flush) { 
++      if (need_flush || iommu_fullflush) { 
+               for (i = 0; northbridges[i]; i++) {
++                      u32 w;
+                       if (bus >= 0 && !(cpu_isset_const(i, bus_cpumask)))
+                               continue;
+                       pci_write_config_dword(northbridges[i], 0x9c, 
+                                              northbridge_flush_word[i] | 1); 
++                      /* Make sure the hardware actually executed the flush. */
++                      do { 
++                              pci_read_config_dword(northbridges[i], 0x9c, &w);
++                      } while (w & 1);
+                       flushed++;
+               } 
+               if (!flushed) 
+@@ -150,12 +155,6 @@ static void __flush_gart(struct pci_dev 
+       spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
+ } 
+-static inline void flush_gart(struct pci_dev *dev)
+-{ 
+-      if (need_flush)
+-              __flush_gart(dev);
+-} 
+-
+ /* 
+  * Allocate memory for a consistent mapping.
+  * All mappings are consistent here, so this is just a wrapper around
+@@ -174,11 +173,16 @@ void *pci_alloc_consistent(struct pci_de
+       } else {
+               dma_mask = hwdev->consistent_dma_mask; 
+       }
++
+       if (dma_mask == 0) 
+               dma_mask = 0xffffffff; 
+       if (dma_mask < 0xffffffff || no_iommu)
+               gfp |= GFP_DMA;
++      /* Kludge to make it bug-to-bug compatible with i386. i386
++         uses the normal dma_mask for alloc_consistent. */
++      dma_mask &= hwdev->dma_mask;
++
+       memory = (void *)__get_free_pages(gfp, get_order(size));
+       if (memory == NULL) {
+               return NULL; 
+@@ -394,7 +398,9 @@ static int __pci_map_cont(struct scatter
+       
+       for (i = start; i < stopat; i++) {
+               struct scatterlist *s = &sg[i];
+-              unsigned long start_addr = s->dma_address;
++              unsigned long pages, addr;
++              unsigned long phys_addr = s->dma_address;
++              
+               BUG_ON(i > start && s->offset);
+               if (i == start) {
+                       *sout = *s; 
+@@ -403,8 +409,10 @@ static int __pci_map_cont(struct scatter
+               } else { 
+                       sout->length += s->length; 
+               }
+-              unsigned long addr = start_addr;
+-              while (addr < start_addr + s->length) { 
++
++              addr = phys_addr;
++              pages = to_pages(s->offset, s->length); 
++              while (pages--) { 
+                       iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); 
+                       SET_LEAK(iommu_page);
+                       addr += PAGE_SIZE;
+@@ -437,7 +445,7 @@ int pci_map_sg(struct pci_dev *dev, stru
+       int out;
+       int start;
+       unsigned long pages = 0;
+-      int need = 0;
++      int need = 0, nextneed;
+       unsigned long size = 0; 
+@@ -453,13 +461,14 @@ int pci_map_sg(struct pci_dev *dev, stru
+               BUG_ON(s->length == 0); 
+               size += s->length; 
++              nextneed = need_iommu(dev, addr, s->length); 
+               /* Handle the previous not yet processed entries */
+               if (i > start) {
+                       struct scatterlist *ps = &sg[i-1];
+                       /* Can only merge when the last chunk ends on a page 
+-                         boundary. */
+-                      if (!force_iommu || !need || (i-1 > start && ps->offset) ||
++                         boundary and the new one doesn't have an offset. */
++                      if (!iommu_merge || !nextneed || !need || s->offset ||
+                           (ps->offset + ps->length) % PAGE_SIZE) { 
+                               if (pci_map_cont(sg, start, i, sg+out, pages, 
+                                                need) < 0)
+@@ -470,7 +479,7 @@ int pci_map_sg(struct pci_dev *dev, stru
+                       }
+       }
+-              need = need_iommu(dev, addr, s->length); 
++              need = nextneed;
+               pages += to_pages(s->offset, s->length);
+       }
+       if (pci_map_cont(sg, start, i, sg+out, pages, need) < 0)
+@@ -544,14 +553,12 @@ int pci_dma_supported(struct pci_dev *de
+          Problem with this is that if we overflow the IOMMU area
+          and return DAC as fallback address the device may not handle it correctly.
+-         As a compromise we only do this if the IOMMU area is >= 256MB 
+-         which should make overflow unlikely enough.
+          
+          As a special case some controllers have a 39bit address mode 
+          that is as efficient as 32bit (aic79xx). Don't force SAC for these.
+          Assume all masks <= 40 bits are of this type. Normally this doesn't
+          make any difference, but gives more gentle handling of IOMMU overflow. */
+-      if (force_iommu && (mask > 0xffffffffffULL) && (iommu_size >= sac_force_size)){ 
++      if (iommu_sac_force && (mask >= 0xffffffffffULL)) { 
+               printk(KERN_INFO "%s: Force SAC with mask %Lx\n", dev->slot_name,mask);
+               return 0; 
+       }
+@@ -680,7 +687,7 @@ static int __init pci_iommu_init(void)
+       unsigned long iommu_start;
+       struct pci_dev *dev;
+               
+-#ifndef CONFIG_AGP_AMD_8151
++#ifndef CONFIG_AGP_AMD64
+       no_agp = 1; 
+ #else
+       /* Makefile puts PCI initialization via subsys_initcall first. */
+--- linux-2.6.0/arch/x86_64/kernel/pci-nommu.c 2003-08-22 19:23:40.000000000 -0700
++++ 25/arch/x86_64/kernel/pci-nommu.c  2003-12-28 23:26:30.000000000 -0800
+@@ -4,6 +4,8 @@
+ #include <linux/string.h>
+ #include <asm/proto.h>
++int iommu_merge = 0;
++
+ /* 
+  * Dummy IO MMU functions
+  */
+--- linux-2.6.0/arch/x86_64/kernel/setup.c     2003-10-17 15:58:03.000000000 -0700
++++ 25/arch/x86_64/kernel/setup.c      2003-12-28 23:21:33.000000000 -0800
+@@ -65,7 +65,11 @@ unsigned long mmu_cr4_features;
+ EXPORT_SYMBOL_GPL(mmu_cr4_features);
+ int acpi_disabled = 0;
+-int acpi_ht = 0;
++
++#ifdef        CONFIG_ACPI_BOOT
++extern int __initdata acpi_ht;
++/* int __initdata acpi_force = 0; */
++#endif
+ /* For PCI or other memory-mapped resources */
+ unsigned long pci_mem_start = 0x10000000;
+@@ -195,6 +199,7 @@ static __init void parse_cmdline_early (
+               if (c != ' ') 
+                       goto next_char; 
+  
++#ifdef CONFIG_ACPI_BOOT
+               /* "acpi=off" disables both ACPI table parsing and interpreter init */
+               if (!memcmp(from, "acpi=off", 8))
+                       acpi_disabled = 1;
+@@ -210,6 +215,7 @@ static __init void parse_cmdline_early (
+               if (!memcmp(from, "acpi=ht", 7)) { 
+                       acpi_ht = 1; 
+               }
++#endif
+               if (!memcmp(from, "nolapic", 7) ||
+                   !memcmp(from, "disableapic", 11))
+--- linux-2.6.0/arch/x86_64/kernel/signal.c    2003-06-16 22:32:20.000000000 -0700
++++ 25/arch/x86_64/kernel/signal.c     2003-12-28 23:26:31.000000000 -0800
+@@ -93,6 +93,8 @@ restore_sigcontext(struct pt_regs *regs,
+ {
+       unsigned int err = 0;
++      /* Always make any pending restarted system calls return -EINTR */
++      current_thread_info()->restart_block.fn = do_no_restart_syscall;
+ #define COPY(x)               err |= __get_user(regs->x, &sc->x)
+@@ -355,8 +357,6 @@ handle_signal(unsigned long sig, siginfo
+               /* If so, check system call restarting.. */
+               switch (regs->rax) {
+                       case -ERESTART_RESTARTBLOCK:
+-                              current_thread_info()->restart_block.fn = do_no_restart_syscall;
+-                              /* FALL THROUGH */
+                       case -ERESTARTNOHAND:
+                               regs->rax = -EINTR;
+                               break;
+@@ -371,10 +371,6 @@ handle_signal(unsigned long sig, siginfo
+                               regs->rax = regs->orig_rax;
+                               regs->rip -= 2;
+               }
+-              if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK){
+-                      regs->rax = __NR_restart_syscall;
+-                      regs->rip -= 2;
+-              }               
+       }
+ #ifdef CONFIG_IA32_EMULATION
+@@ -453,6 +449,10 @@ int do_signal(struct pt_regs *regs, sigs
+                       regs->rax = regs->orig_rax;
+                       regs->rip -= 2;
+               }
++              if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) {
++                      regs->rax = __NR_restart_syscall;
++                      regs->rip -= 2;
++              }
+       }
+       return 0;
+ }
+--- linux-2.6.0/arch/x86_64/kernel/traps.c     2003-10-08 15:07:08.000000000 -0700
++++ 25/arch/x86_64/kernel/traps.c      2003-12-28 23:26:30.000000000 -0800
+@@ -218,8 +218,12 @@ void show_stack(struct task_struct *tsk,
+       // debugging aid: "show_stack(NULL, NULL);" prints the
+       // back trace for this cpu.
+-      if(rsp==NULL)
+-              rsp=(unsigned long*)&rsp;
++      if (rsp == NULL) {
++              if (tsk)
++                      rsp = (unsigned long *)tsk->thread.rsp;
++              else
++                      rsp = (unsigned long *)&rsp;
++      }
+       stack = rsp;
+       for(i=0; i < kstack_depth_to_print; i++) {
+--- linux-2.6.0/arch/x86_64/mm/fault.c 2003-11-23 19:03:00.000000000 -0800
++++ 25/arch/x86_64/mm/fault.c  2003-12-28 23:26:31.000000000 -0800
+@@ -73,6 +73,9 @@ static int is_prefetch(struct pt_regs *r
+       if (regs->cs & (1<<2))
+               return 0;
++      if ((regs->cs & 3) != 0 && regs->rip >= TASK_SIZE)
++              return 0;
++
+       while (scan_more && instr < max_instr) { 
+               unsigned char opcode;
+               unsigned char instr_hi;
+@@ -337,7 +340,8 @@ bad_area_nosemaphore:
+               }
+        
+               tsk->thread.cr2 = address;
+-              tsk->thread.error_code = error_code;
++              /* Kernel addresses are always protection faults */
++              tsk->thread.error_code = error_code | (address >= TASK_SIZE);
+               tsk->thread.trap_no = 14;
+               info.si_signo = SIGSEGV;
+               info.si_errno = 0;
+--- linux-2.6.0/crypto/tcrypt.c        2003-09-08 13:58:56.000000000 -0700
++++ 25/crypto/tcrypt.c 2003-12-28 23:22:31.000000000 -0800
+@@ -6,2384 +6,409 @@
+  *
+  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+  * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+- * 
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License as published by the Free
+- * Software Foundation; either version 2 of the License, or (at your option) 
+- * any later version.
+- *
+- */
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/mm.h>
+-#include <linux/slab.h>
+-#include <asm/scatterlist.h>
+-#include <linux/string.h>
+-#include <linux/crypto.h>
+-#include <linux/highmem.h>
+-#include "tcrypt.h"
+-
+-/*
+- * Need to kmalloc() memory for testing kmap().
+- */
+-#define TVMEMSIZE     4096
+-#define XBUFSIZE      32768
+-
+-/*
+- * Indexes into the xbuf to simulate cross-page access.
+- */
+-#define IDX1          37
+-#define IDX2          32400
+-#define IDX3          1
+-#define IDX4          8193
+-#define IDX5          22222
+-#define IDX6          17101
+-#define IDX7          27333
+-#define IDX8          3000
+-
+-static int mode;
+-static char *xbuf;
+-static char *tvmem;
+-
+-static char *check[] = {
+-      "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
+-      "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", 
+-      "deflate", NULL
+-};
+-
+-static void
+-hexdump(unsigned char *buf, unsigned int len)
+-{
+-      while (len--)
+-              printk("%02x", *buf++);
+-
+-      printk("\n");
+-}
+-
+-static void
+-test_md5(void)
+-{
+-      char *p;
+-      unsigned int i;
+-      struct scatterlist sg[2];
+-      char result[128];
+-      struct crypto_tfm *tfm;
+-      struct md5_testvec *md5_tv;
+-      unsigned int tsize;
+-
+-      printk("\ntesting md5\n");
+-
+-      tsize = sizeof (md5_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, md5_tv_template, tsize);
+-      md5_tv = (void *) tvmem;
+-
+-      tfm = crypto_alloc_tfm("md5", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for md5\n");
+-              return;
+-      }
+-
+-      for (i = 0; i < MD5_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-              memset(result, 0, sizeof (result));
+-
+-              p = md5_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = strlen(md5_tv[i].plaintext);
+-
+-              crypto_digest_init(tfm);
+-              crypto_digest_update(tfm, sg, 1);
+-              crypto_digest_final(tfm, result);
+-
+-              hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-              printk("%s\n",
+-                     memcmp(result, md5_tv[i].digest,
+-                            crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+-                     "pass");
+-      }
+-
+-      printk("\ntesting md5 across pages\n");
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, XBUFSIZE);
+-      memcpy(&xbuf[IDX1], "abcdefghijklm", 13);
+-      memcpy(&xbuf[IDX2], "nopqrstuvwxyz", 13);
+-
+-      p = &xbuf[IDX1];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 13;
+-
+-      p = &xbuf[IDX2];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 13;
+-
+-      memset(result, 0, sizeof (result));
+-      crypto_digest_digest(tfm, sg, 2, result);
+-      hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-
+-      printk("%s\n",
+-             memcmp(result, md5_tv[4].digest,
+-                    crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+-      crypto_free_tfm(tfm);
+-}
+-
+-#ifdef CONFIG_CRYPTO_HMAC
+-static void
+-test_hmac_md5(void)
+-{
+-      char *p;
+-      unsigned int i, klen;
+-      struct scatterlist sg[2];
+-      char result[128];
+-      struct crypto_tfm *tfm;
+-      struct hmac_md5_testvec *hmac_md5_tv;
+-      unsigned int tsize;
+-
+-      tfm = crypto_alloc_tfm("md5", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for md5\n");
+-              return;
+-      }
+-
+-      printk("\ntesting hmac_md5\n");
+-      
+-      tsize = sizeof (hmac_md5_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              goto out;
+-      }
+-
+-      memcpy(tvmem, hmac_md5_tv_template, tsize);
+-      hmac_md5_tv = (void *) tvmem;
+-
+-      for (i = 0; i < HMAC_MD5_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-              memset(result, 0, sizeof (result));
+-
+-              p = hmac_md5_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = strlen(hmac_md5_tv[i].plaintext);
+-
+-              klen = strlen(hmac_md5_tv[i].key);
+-              crypto_hmac(tfm, hmac_md5_tv[i].key, &klen, sg, 1, result);
+-
+-              hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-              printk("%s\n",
+-                     memcmp(result, hmac_md5_tv[i].digest,
+-                            crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+-                     "pass");
+-      }
+-
+-      printk("\ntesting hmac_md5 across pages\n");
+-
+-      memset(xbuf, 0, XBUFSIZE);
+-
+-      memcpy(&xbuf[IDX1], "what do ya want ", 16);
+-      memcpy(&xbuf[IDX2], "for nothing?", 12);
+-
+-      p = &xbuf[IDX1];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 16;
+-
+-      p = &xbuf[IDX2];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 12;
+-
+-      memset(result, 0, sizeof (result));
+-      klen = strlen(hmac_md5_tv[7].key);
+-      crypto_hmac(tfm, hmac_md5_tv[7].key, &klen, sg, 2, result);
+-      hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-
+-      printk("%s\n",
+-             memcmp(result, hmac_md5_tv[7].digest,
+-                    crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+-out:
+-      crypto_free_tfm(tfm);
+-}
+-
+-static void
+-test_hmac_sha1(void)
+-{
+-      char *p;
+-      unsigned int i, klen;
+-      struct crypto_tfm *tfm;
+-      struct hmac_sha1_testvec *hmac_sha1_tv;
+-      struct scatterlist sg[2];
+-      unsigned int tsize;
+-      char result[SHA1_DIGEST_SIZE];
+-
+-      tfm = crypto_alloc_tfm("sha1", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for sha1\n");
+-              return;
+-      }
+-
+-      printk("\ntesting hmac_sha1\n");
+-
+-      tsize = sizeof (hmac_sha1_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              goto out;
+-      }
+-
+-      memcpy(tvmem, hmac_sha1_tv_template, tsize);
+-      hmac_sha1_tv = (void *) tvmem;
+-
+-      for (i = 0; i < HMAC_SHA1_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-              memset(result, 0, sizeof (result));
+-
+-              p = hmac_sha1_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = strlen(hmac_sha1_tv[i].plaintext);
+-
+-              klen = strlen(hmac_sha1_tv[i].key);
+-              
+-              crypto_hmac(tfm, hmac_sha1_tv[i].key, &klen, sg, 1, result);
+-
+-              hexdump(result, sizeof (result));
+-              printk("%s\n",
+-                     memcmp(result, hmac_sha1_tv[i].digest,
+-                            crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+-                     "pass");
+-      }
+-
+-      printk("\ntesting hmac_sha1 across pages\n");
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, XBUFSIZE);
+-
+-      memcpy(&xbuf[IDX1], "what do ya want ", 16);
+-      memcpy(&xbuf[IDX2], "for nothing?", 12);
+-
+-      p = &xbuf[IDX1];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 16;
+-
+-      p = &xbuf[IDX2];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 12;
+-
+-      memset(result, 0, sizeof (result));
+-      klen = strlen(hmac_sha1_tv[7].key);
+-      crypto_hmac(tfm, hmac_sha1_tv[7].key, &klen, sg, 2, result);
+-      hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-
+-      printk("%s\n",
+-             memcmp(result, hmac_sha1_tv[7].digest,
+-                    crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+-out:
+-      crypto_free_tfm(tfm);
+-}
+-
+-static void
+-test_hmac_sha256(void)
+-{
+-      char *p;
+-      unsigned int i, klen;
+-      struct crypto_tfm *tfm;
+-      struct hmac_sha256_testvec *hmac_sha256_tv;
+-      struct scatterlist sg[2];
+-      unsigned int tsize;
+-      char result[SHA256_DIGEST_SIZE];
+-
+-      tfm = crypto_alloc_tfm("sha256", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for sha256\n");
+-              return;
+-      }
+-
+-      printk("\ntesting hmac_sha256\n");
+-
+-      tsize = sizeof (hmac_sha256_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              goto out;
+-      }
+-
+-      memcpy(tvmem, hmac_sha256_tv_template, tsize);
+-      hmac_sha256_tv = (void *) tvmem;
+-
+-      for (i = 0; i < HMAC_SHA256_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-              memset(result, 0, sizeof (result));
+-
+-              p = hmac_sha256_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = strlen(hmac_sha256_tv[i].plaintext);
+-
+-              klen = strlen(hmac_sha256_tv[i].key);
+-      
+-              hexdump(hmac_sha256_tv[i].key, strlen(hmac_sha256_tv[i].key));
+-              crypto_hmac(tfm, hmac_sha256_tv[i].key, &klen, sg, 1, result);
+-              hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-              printk("%s\n",
+-                     memcmp(result, hmac_sha256_tv[i].digest,
+-                     crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+-      }
+-
+-out:
+-      crypto_free_tfm(tfm);
+-}
+-
+-#endif        /* CONFIG_CRYPTO_HMAC */
+-
+-static void
+-test_md4(void)
+-{
+-      char *p;
+-      unsigned int i;
+-      struct scatterlist sg[1];
+-      char result[128];
+-      struct crypto_tfm *tfm;
+-      struct md4_testvec *md4_tv;
+-      unsigned int tsize;
+-
+-      printk("\ntesting md4\n");
+-
+-      tsize = sizeof (md4_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, md4_tv_template, tsize);
+-      md4_tv = (void *) tvmem;
+-
+-      tfm = crypto_alloc_tfm("md4", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for md4\n");
+-              return;
+-      }
+-
+-      for (i = 0; i < MD4_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-              memset(result, 0, sizeof (result));
+-
+-              p = md4_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = strlen(md4_tv[i].plaintext);
+-
+-              crypto_digest_digest(tfm, sg, 1, result);
+-
+-              hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-              printk("%s\n",
+-                     memcmp(result, md4_tv[i].digest,
+-                            crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+-                     "pass");
+-      }
+-
+-      crypto_free_tfm(tfm);
+-}
+-
+-static void
+-test_sha1(void)
+-{
+-      char *p;
+-      unsigned int i;
+-      struct crypto_tfm *tfm;
+-      struct sha1_testvec *sha1_tv;
+-      struct scatterlist sg[2];
+-      unsigned int tsize;
+-      char result[SHA1_DIGEST_SIZE];
+-
+-      printk("\ntesting sha1\n");
+-
+-      tsize = sizeof (sha1_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, sha1_tv_template, tsize);
+-      sha1_tv = (void *) tvmem;
+-
+-      tfm = crypto_alloc_tfm("sha1", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for sha1\n");
+-              return;
+-      }
+-
+-      for (i = 0; i < SHA1_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-              memset(result, 0, sizeof (result));
+-
+-              p = sha1_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = strlen(sha1_tv[i].plaintext);
+-
+-              crypto_digest_init(tfm);
+-              crypto_digest_update(tfm, sg, 1);
+-              crypto_digest_final(tfm, result);
+-
+-              hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-              printk("%s\n",
+-                     memcmp(result, sha1_tv[i].digest,
+-                            crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+-                     "pass");
+-      }
+-
+-      printk("\ntesting sha1 across pages\n");
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, XBUFSIZE);
+-      memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28);
+-      memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28);
+-
+-      p = &xbuf[IDX1];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 28;
+-
+-      p = &xbuf[IDX2];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 28;
+-
+-      memset(result, 0, sizeof (result));
+-      crypto_digest_digest(tfm, sg, 2, result);
+-      hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-      printk("%s\n",
+-             memcmp(result, sha1_tv[1].digest,
+-                    crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+-      crypto_free_tfm(tfm);
+-}
+-
+-static void
+-test_sha256(void)
+-{
+-      char *p;
+-      unsigned int i;
+-      struct crypto_tfm *tfm;
+-      struct sha256_testvec *sha256_tv;
+-      struct scatterlist sg[2];
+-      unsigned int tsize;
+-      char result[SHA256_DIGEST_SIZE];
+-
+-      printk("\ntesting sha256\n");
+-
+-      tsize = sizeof (sha256_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, sha256_tv_template, tsize);
+-      sha256_tv = (void *) tvmem;
+-
+-      tfm = crypto_alloc_tfm("sha256", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for sha256\n");
+-              return;
+-      }
+-
+-      for (i = 0; i < SHA256_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-              memset(result, 0, sizeof (result));
+-
+-              p = sha256_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = strlen(sha256_tv[i].plaintext);
+-
+-              crypto_digest_init(tfm);
+-              crypto_digest_update(tfm, sg, 1);
+-              crypto_digest_final(tfm, result);
+-
+-              hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-              printk("%s\n",
+-                     memcmp(result, sha256_tv[i].digest,
+-                            crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+-                     "pass");
+-      }
+-
+-      printk("\ntesting sha256 across pages\n");
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, XBUFSIZE);
+-      memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28);
+-      memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28);
+-
+-      p = &xbuf[IDX1];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 28;
+-
+-      p = &xbuf[IDX2];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 28;
+-
+-      memset(result, 0, sizeof (result));
+-      crypto_digest_digest(tfm, sg, 2, result);
+-      hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-      printk("%s\n",
+-             memcmp(result, sha256_tv[1].digest,
+-                    crypto_tfm_alg_digestsize(tfm)) ? "fail" : "pass");
+-                   
+-      crypto_free_tfm(tfm);
+-}
+-
+-static void
+-test_sha384(void)
+-{
+-      char *p;
+-      unsigned int i;
+-      struct crypto_tfm *tfm;
+-      struct sha384_testvec *sha384_tv;
+-      struct scatterlist sg[2];
+-      unsigned int tsize;
+-      char result[SHA384_DIGEST_SIZE];
+-
+-      printk("\ntesting sha384\n");
+-
+-      tsize = sizeof (sha384_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, sha384_tv_template, tsize);
+-      sha384_tv = (void *) tvmem;
+-
+-      tfm = crypto_alloc_tfm("sha384", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for sha384\n");
+-              return;
+-      }
+-
+-      for (i = 0; i < SHA384_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-              memset(result, 0, sizeof (result));
+-
+-              p = sha384_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = strlen(sha384_tv[i].plaintext);
+-
+-              crypto_digest_init(tfm);
+-              crypto_digest_update(tfm, sg, 1);
+-              crypto_digest_final(tfm, result);
+-
+-              hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-              printk("%s\n",
+-                     memcmp(result, sha384_tv[i].digest,
+-                            crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+-                     "pass");
+-      }
+-
+-      crypto_free_tfm(tfm);
+-}
+-
+-static void
+-test_sha512(void)
+-{
+-      char *p;
+-      unsigned int i;
+-      struct crypto_tfm *tfm;
+-      struct sha512_testvec *sha512_tv;
+-      struct scatterlist sg[2];
+-      unsigned int tsize;
+-      char result[SHA512_DIGEST_SIZE];
+-
+-      printk("\ntesting sha512\n");
+-
+-      tsize = sizeof (sha512_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, sha512_tv_template, tsize);
+-      sha512_tv = (void *) tvmem;
+-
+-      tfm = crypto_alloc_tfm("sha512", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for sha512\n");
+-              return;
+-      }
+-
+-      for (i = 0; i < SHA512_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-              memset(result, 0, sizeof (result));
+-
+-              p = sha512_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = strlen(sha512_tv[i].plaintext);
+-
+-              crypto_digest_init(tfm);
+-              crypto_digest_update(tfm, sg, 1);
+-              crypto_digest_final(tfm, result);
+-
+-              hexdump(result, crypto_tfm_alg_digestsize(tfm));
+-              printk("%s\n",
+-                     memcmp(result, sha512_tv[i].digest,
+-                            crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+-                     "pass");
+-      }
+-
+-      crypto_free_tfm(tfm);
+-}
+-
+-void
+-test_des(void)
+-{
+-      unsigned int ret, i, len;
+-      unsigned int tsize;
+-      char *p, *q;
+-      struct crypto_tfm *tfm;
+-      char *key;
+-      char res[8];
+-      struct des_tv *des_tv;
+-      struct scatterlist sg[8];
+-
+-      printk("\ntesting des encryption\n");
+-
+-      tsize = sizeof (des_enc_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, des_enc_tv_template, tsize);
+-      des_tv = (void *) tvmem;
+-
+-      tfm = crypto_alloc_tfm("des", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for des (default ecb)\n");
+-              return;
+-      }
+-
+-      for (i = 0; i < DES_ENC_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-
+-              key = des_tv[i].key;
+-              tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
+-
+-              ret = crypto_cipher_setkey(tfm, key, 8);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!des_tv[i].fail)
+-                              goto out;
+-              }
+-
+-              len = des_tv[i].len;
+-
+-              p = des_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = len;
+-              ret = crypto_cipher_encrypt(tfm, sg, sg, len);
+-              if (ret) {
+-                      printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, len);
+-
+-              printk("%s\n",
+-                     memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+-
+-      }
+-
+-      printk("\ntesting des ecb encryption across pages\n");
+-
+-      i = 5;
+-      key = des_tv[i].key;
+-      tfm->crt_flags = 0;
+-
+-      hexdump(key, 8);
+-
+-      ret = crypto_cipher_setkey(tfm, key, 8);
+-      if (ret) {
+-              printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, sizeof (xbuf));
+-      memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8);
+-      memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8);
+-
+-      p = &xbuf[IDX1];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 8;
+-
+-      p = &xbuf[IDX2];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 8;
+-
+-      ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
+-      if (ret) {
+-              printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      printk("page 1\n");
+-      q = kmap(sg[0].page) + sg[0].offset;
+-      hexdump(q, 8);
+-      printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass");
+-
+-      printk("page 2\n");
+-      q = kmap(sg[1].page) + sg[1].offset;
+-      hexdump(q, 8);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass");
+-
+-      printk("\ntesting des ecb encryption chunking scenario A\n");
+-
+-      /*
+-       * Scenario A:
+-       * 
+-       *  F1       F2      F3
+-       *  [8 + 6]  [2 + 8] [8]
+-       *       ^^^^^^   ^
+-       *       a    b   c
+-       *
+-       * Chunking should begin at a, then end with b, and
+-       * continue encrypting at an offset of 2 until c.
+-       *
+-       */
+-      i = 7;
+-
+-      key = des_tv[i].key;
+-      tfm->crt_flags = 0;
+-
+-      ret = crypto_cipher_setkey(tfm, key, 8);
+-      if (ret) {
+-              printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, sizeof (xbuf));
+-
+-      /* Frag 1: 8 + 6 */
+-      memcpy(&xbuf[IDX3], des_tv[i].plaintext, 14);
+-
+-      /* Frag 2: 2 + 8 */
+-      memcpy(&xbuf[IDX4], des_tv[i].plaintext + 14, 10);
+-
+-      /* Frag 3: 8 */
+-      memcpy(&xbuf[IDX5], des_tv[i].plaintext + 24, 8);
+-
+-      p = &xbuf[IDX3];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 14;
+-
+-      p = &xbuf[IDX4];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 10;
+-
+-      p = &xbuf[IDX5];
+-      sg[2].page = virt_to_page(p);
+-      sg[2].offset = offset_in_page(p);
+-      sg[2].length = 8;
+-
+-      ret = crypto_cipher_encrypt(tfm, sg, sg, 32);
+-
+-      if (ret) {
+-              printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      printk("page 1\n");
+-      q = kmap(sg[0].page) + sg[0].offset;
+-      hexdump(q, 14);
+-      printk("%s\n", memcmp(q, des_tv[i].result, 14) ? "fail" : "pass");
+-
+-      printk("page 2\n");
+-      q = kmap(sg[1].page) + sg[1].offset;
+-      hexdump(q, 10);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 14, 10) ? "fail" : "pass");
+-
+-      printk("page 3\n");
+-      q = kmap(sg[2].page) + sg[2].offset;
+-      hexdump(q, 8);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 24, 8) ? "fail" : "pass");
+-
+-      printk("\ntesting des ecb encryption chunking scenario B\n");
+-
+-      /*
+-       * Scenario B:
+-       * 
+-       *  F1  F2  F3  F4
+-       *  [2] [1] [3] [2 + 8 + 8]
+-       */
+-      i = 7;
+-
+-      key = des_tv[i].key;
+-      tfm->crt_flags = 0;
+-
+-      ret = crypto_cipher_setkey(tfm, key, 8);
+-      if (ret) {
+-              printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, sizeof (xbuf));
+-
+-      /* Frag 1: 2 */
+-      memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2);
+-
+-      /* Frag 2: 1 */
+-      memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 1);
+-
+-      /* Frag 3: 3 */
+-      memcpy(&xbuf[IDX5], des_tv[i].plaintext + 3, 3);
+-
+-      /* Frag 4: 2 + 8 + 8 */
+-      memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 18);
+-
+-      p = &xbuf[IDX3];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 2;
+-
+-      p = &xbuf[IDX4];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 1;
+-
+-      p = &xbuf[IDX5];
+-      sg[2].page = virt_to_page(p);
+-      sg[2].offset = offset_in_page(p);
+-      sg[2].length = 3;
+-
+-      p = &xbuf[IDX6];
+-      sg[3].page = virt_to_page(p);
+-      sg[3].offset = offset_in_page(p);
+-      sg[3].length = 18;
+-
+-      ret = crypto_cipher_encrypt(tfm, sg, sg, 24);
+-
+-      if (ret) {
+-              printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      printk("page 1\n");
+-      q = kmap(sg[0].page) + sg[0].offset;
+-      hexdump(q, 2);
+-      printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass");
+-
+-      printk("page 2\n");
+-      q = kmap(sg[1].page) + sg[1].offset;
+-      hexdump(q, 1);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 2, 1) ? "fail" : "pass");
+-
+-      printk("page 3\n");
+-      q = kmap(sg[2].page) + sg[2].offset;
+-      hexdump(q, 3);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 3, 3) ? "fail" : "pass");
+-
+-      printk("page 4\n");
+-      q = kmap(sg[3].page) + sg[3].offset;
+-      hexdump(q, 18);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 6, 18) ? "fail" : "pass");
+-
+-      printk("\ntesting des ecb encryption chunking scenario C\n");
+-
+-      /*
+-       * Scenario B:
+-       * 
+-       *  F1  F2  F3  F4  F5
+-       *  [2] [2] [2] [2] [8]
+-       */
+-      i = 7;
+-
+-      key = des_tv[i].key;
+-      tfm->crt_flags = 0;
+-
+-      ret = crypto_cipher_setkey(tfm, key, 8);
+-      if (ret) {
+-              printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, sizeof (xbuf));
+-
+-      /* Frag 1: 2 */
+-      memcpy(&xbuf[IDX3], des_tv[i].plaintext, 2);
+-
+-      /* Frag 2: 2 */
+-      memcpy(&xbuf[IDX4], des_tv[i].plaintext + 2, 2);
+-
+-      /* Frag 3: 2 */
+-      memcpy(&xbuf[IDX5], des_tv[i].plaintext + 4, 2);
+-
+-      /* Frag 4: 2 */
+-      memcpy(&xbuf[IDX6], des_tv[i].plaintext + 6, 2);
+-
+-      /* Frag 5: 8 */
+-      memcpy(&xbuf[IDX7], des_tv[i].plaintext + 8, 8);
+-
+-      p = &xbuf[IDX3];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 2;
+-
+-      p = &xbuf[IDX4];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 2;
+-
+-      p = &xbuf[IDX5];
+-      sg[2].page = virt_to_page(p);
+-      sg[2].offset = offset_in_page(p);
+-      sg[2].length = 2;
+-
+-      p = &xbuf[IDX6];
+-      sg[3].page = virt_to_page(p);
+-      sg[3].offset = offset_in_page(p);
+-      sg[3].length = 2;
+-
+-      p = &xbuf[IDX7];
+-      sg[4].page = virt_to_page(p);
+-      sg[4].offset = offset_in_page(p);
+-      sg[4].length = 8;
+-
+-      ret = crypto_cipher_encrypt(tfm, sg, sg, 16);
+-
+-      if (ret) {
+-              printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      printk("page 1\n");
+-      q = kmap(sg[0].page) + sg[0].offset;
+-      hexdump(q, 2);
+-      printk("%s\n", memcmp(q, des_tv[i].result, 2) ? "fail" : "pass");
+-
+-      printk("page 2\n");
+-      q = kmap(sg[1].page) + sg[1].offset;
+-      hexdump(q, 2);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 2, 2) ? "fail" : "pass");
+-
+-      printk("page 3\n");
+-      q = kmap(sg[2].page) + sg[2].offset;
+-      hexdump(q, 2);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 4, 2) ? "fail" : "pass");
+-
+-      printk("page 4\n");
+-      q = kmap(sg[3].page) + sg[3].offset;
+-      hexdump(q, 2);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 6, 2) ? "fail" : "pass");
+-
+-      printk("page 5\n");
+-      q = kmap(sg[4].page) + sg[4].offset;
+-      hexdump(q, 8);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass");
+-
+-      printk("\ntesting des ecb encryption chunking scenario D\n");
+-
+-      /*
+-       * Scenario D, torture test, one byte per frag.
+-       */
+-      i = 7;
+-      key = des_tv[i].key;
+-      tfm->crt_flags = 0;
+-
+-      ret = crypto_cipher_setkey(tfm, key, 8);
+-      if (ret) {
+-              printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, XBUFSIZE);
+-
+-      xbuf[IDX1] = des_tv[i].plaintext[0];
+-      xbuf[IDX2] = des_tv[i].plaintext[1];
+-      xbuf[IDX3] = des_tv[i].plaintext[2];
+-      xbuf[IDX4] = des_tv[i].plaintext[3];
+-      xbuf[IDX5] = des_tv[i].plaintext[4];
+-      xbuf[IDX6] = des_tv[i].plaintext[5];
+-      xbuf[IDX7] = des_tv[i].plaintext[6];
+-      xbuf[IDX8] = des_tv[i].plaintext[7];
+-
+-      p = &xbuf[IDX1];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 1;
+-
+-      p = &xbuf[IDX2];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 1;
+-
+-      p = &xbuf[IDX3];
+-      sg[2].page = virt_to_page(p);
+-      sg[2].offset = offset_in_page(p);
+-      sg[2].length = 1;
+-
+-      p = &xbuf[IDX4];
+-      sg[3].page = virt_to_page(p);
+-      sg[3].offset = offset_in_page(p);
+-      sg[3].length = 1;
+-
+-      p = &xbuf[IDX5];
+-      sg[4].page = virt_to_page(p);
+-      sg[4].offset = offset_in_page(p);
+-      sg[4].length = 1;
+-
+-      p = &xbuf[IDX6];
+-      sg[5].page = virt_to_page(p);
+-      sg[5].offset = offset_in_page(p);
+-      sg[5].length = 1;
+-
+-      p = &xbuf[IDX7];
+-      sg[6].page = virt_to_page(p);
+-      sg[6].offset = offset_in_page(p);
+-      sg[6].length = 1;
+-
+-      p = &xbuf[IDX8];
+-      sg[7].page = virt_to_page(p);
+-      sg[7].offset = offset_in_page(p);
+-      sg[7].length = 1;
+-
+-      ret = crypto_cipher_encrypt(tfm, sg, sg, 8);
+-      if (ret) {
+-              printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      for (i = 0; i < 8; i++)
+-              res[i] = *(char *) (kmap(sg[i].page) + sg[i].offset);
+-
+-      hexdump(res, 8);
+-      printk("%s\n", memcmp(res, des_tv[7].result, 8) ? "fail" : "pass");
+-
+-      printk("\ntesting des decryption\n");
+-
+-      tsize = sizeof (des_dec_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-      memcpy(tvmem, des_dec_tv_template, tsize);
+-      des_tv = (void *) tvmem;
+-
+-      for (i = 0; i < DES_DEC_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-
+-              key = des_tv[i].key;
+-
+-              tfm->crt_flags = 0;
+-              ret = crypto_cipher_setkey(tfm, key, 8);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              len = des_tv[i].len;
+-
+-              p = des_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = len;
+-
+-              ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("des_decrypt() failed flags=%x\n",
+-                             tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, len);
+-
+-              printk("%s\n",
+-                     memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+-
+-      }
+-
+-      printk("\ntesting des ecb decryption across pages\n");
+-
+-      i = 6;
+-
+-      key = des_tv[i].key;
+-      tfm->crt_flags = 0;
+-
+-      ret = crypto_cipher_setkey(tfm, key, 8);
+-      if (ret) {
+-              printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, sizeof (xbuf));
+-      memcpy(&xbuf[IDX1], des_tv[i].plaintext, 8);
+-      memcpy(&xbuf[IDX2], des_tv[i].plaintext + 8, 8);
+-
+-      p = &xbuf[IDX1];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 8;
+-
+-      p = &xbuf[IDX2];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 8;
+-
+-      ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
+-      if (ret) {
+-              printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      printk("page 1\n");
+-      q = kmap(sg[0].page) + sg[0].offset;
+-      hexdump(q, 8);
+-      printk("%s\n", memcmp(q, des_tv[i].result, 8) ? "fail" : "pass");
+-
+-      printk("page 2\n");
+-      q = kmap(sg[1].page) + sg[1].offset;
+-      hexdump(q, 8);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 8, 8) ? "fail" : "pass");
+-
+-      /*
+-       * Scenario E:
+-       * 
+-       *  F1   F2      F3
+-       *  [3]  [5 + 7] [1]
+-       *
+-       */
+-      printk("\ntesting des ecb decryption chunking scenario E\n");
+-      i = 2;
+-
+-      key = des_tv[i].key;
+-      tfm->crt_flags = 0;
+-
+-      ret = crypto_cipher_setkey(tfm, key, 8);
+-      if (ret) {
+-              printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, sizeof (xbuf));
+-
+-      memcpy(&xbuf[IDX1], des_tv[i].plaintext, 3);
+-      memcpy(&xbuf[IDX2], des_tv[i].plaintext + 3, 12);
+-      memcpy(&xbuf[IDX3], des_tv[i].plaintext + 15, 1);
+-
+-      p = &xbuf[IDX1];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 3;
+-
+-      p = &xbuf[IDX2];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 12;
+-
+-      p = &xbuf[IDX3];
+-      sg[2].page = virt_to_page(p);
+-      sg[2].offset = offset_in_page(p);
+-      sg[2].length = 1;
+-
+-      ret = crypto_cipher_decrypt(tfm, sg, sg, 16);
+-
+-      if (ret) {
+-              printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      printk("page 1\n");
+-      q = kmap(sg[0].page) + sg[0].offset;
+-      hexdump(q, 3);
+-      printk("%s\n", memcmp(q, des_tv[i].result, 3) ? "fail" : "pass");
+-
+-      printk("page 2\n");
+-      q = kmap(sg[1].page) + sg[1].offset;
+-      hexdump(q, 12);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 3, 12) ? "fail" : "pass");
+-
+-      printk("page 3\n");
+-      q = kmap(sg[2].page) + sg[2].offset;
+-      hexdump(q, 1);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 15, 1) ? "fail" : "pass");
+-
+-      crypto_free_tfm(tfm);
+-
+-      tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for des cbc\n");
+-              return;
+-      }
+-
+-      printk("\ntesting des cbc encryption\n");
+-
+-      tsize = sizeof (des_cbc_enc_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-      memcpy(tvmem, des_cbc_enc_tv_template, tsize);
+-      des_tv = (void *) tvmem;
+-
+-      crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
+-      crypto_cipher_get_iv(tfm, res, crypto_tfm_alg_ivsize(tfm));
+-      
+-      if (memcmp(res, des_tv[i].iv, sizeof(res))) {
+-              printk("crypto_cipher_[set|get]_iv() failed\n");
+-              goto out;
+-      }
+-      
+-      for (i = 0; i < DES_CBC_ENC_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-
+-              key = des_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, 8);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              len = des_tv[i].len;
+-              p = des_tv[i].plaintext;
+-
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = len;
+-
+-              crypto_cipher_set_iv(tfm, des_tv[i].iv,
+-                                   crypto_tfm_alg_ivsize(tfm));
+-
+-              ret = crypto_cipher_encrypt(tfm, sg, sg, len);
+-              if (ret) {
+-                      printk("des_cbc_encrypt() failed flags=%x\n",
+-                             tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, len);
+-
+-              printk("%s\n",
+-                     memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+-      }
+-
+-      crypto_free_tfm(tfm);
+-
+-      /*
+-       * Scenario F:
+-       * 
+-       *  F1       F2      
+-       *  [8 + 5]  [3 + 8]
+-       *
+-       */
+-      printk("\ntesting des cbc encryption chunking scenario F\n");
+-      i = 4;
+-
+-      tfm = crypto_alloc_tfm("des", CRYPTO_TFM_MODE_CBC);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for CRYPTO_ALG_DES_CCB\n");
+-              return;
+-      }
+-
+-      tfm->crt_flags = 0;
+-      key = des_tv[i].key;
+-
+-      ret = crypto_cipher_setkey(tfm, key, 8);
+-      if (ret) {
+-              printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, sizeof (xbuf));
+-
+-      memcpy(&xbuf[IDX1], des_tv[i].plaintext, 13);
+-      memcpy(&xbuf[IDX2], des_tv[i].plaintext + 13, 11);
+-
+-      p = &xbuf[IDX1];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 13;
+-
+-      p = &xbuf[IDX2];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 11;
+-
+-      crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
+-
+-      ret = crypto_cipher_encrypt(tfm, sg, sg, 24);
+-      if (ret) {
+-              printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      printk("page 1\n");
+-      q = kmap(sg[0].page) + sg[0].offset;
+-      hexdump(q, 13);
+-      printk("%s\n", memcmp(q, des_tv[i].result, 13) ? "fail" : "pass");
+-
+-      printk("page 2\n");
+-      q = kmap(sg[1].page) + sg[1].offset;
+-      hexdump(q, 11);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 13, 11) ? "fail" : "pass");
+-
+-      tsize = sizeof (des_cbc_dec_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-      memcpy(tvmem, des_cbc_dec_tv_template, tsize);
+-      des_tv = (void *) tvmem;
+-
+-      printk("\ntesting des cbc decryption\n");
+-
+-      for (i = 0; i < DES_CBC_DEC_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-
+-              tfm->crt_flags = 0;
+-              key = des_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, 8);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              len = des_tv[i].len;
+-              p = des_tv[i].plaintext;
+-
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = len;
+-
+-              crypto_cipher_set_iv(tfm, des_tv[i].iv,
+-                                    crypto_tfm_alg_blocksize(tfm));
+-
+-              ret = crypto_cipher_decrypt(tfm, sg, sg, len);
+-              if (ret) {
+-                      printk("des_cbc_decrypt() failed flags=%x\n",
+-                             tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              hexdump(tfm->crt_cipher.cit_iv, 8);
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, len);
+-
+-              printk("%s\n",
+-                     memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+-      }
+-
+-      /*
+-       * Scenario G:
+-       * 
+-       *  F1   F2      
+-       *  [4]  [4]
+-       *
+-       */
+-      printk("\ntesting des cbc decryption chunking scenario G\n");
+-      i = 3;
+-
+-      tfm->crt_flags = 0;
+-      key = des_tv[i].key;
+-
+-      ret = crypto_cipher_setkey(tfm, key, 8);
+-      if (ret) {
+-              printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      /* setup the dummy buffer first */
+-      memset(xbuf, 0, sizeof (xbuf));
+-      memcpy(&xbuf[IDX1], des_tv[i].plaintext, 4);
+-      memcpy(&xbuf[IDX2], des_tv[i].plaintext + 4, 4);
+-
+-      p = &xbuf[IDX1];
+-      sg[0].page = virt_to_page(p);
+-      sg[0].offset = offset_in_page(p);
+-      sg[0].length = 4;
+-
+-      p = &xbuf[IDX2];
+-      sg[1].page = virt_to_page(p);
+-      sg[1].offset = offset_in_page(p);
+-      sg[1].length = 4;
+-
+-      crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm));
+-
+-      ret = crypto_cipher_decrypt(tfm, sg, sg, 8);
+-      if (ret) {
+-              printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags);
+-              goto out;
+-      }
+-
+-      printk("page 1\n");
+-      q = kmap(sg[0].page) + sg[0].offset;
+-      hexdump(q, 4);
+-      printk("%s\n", memcmp(q, des_tv[i].result, 4) ? "fail" : "pass");
+-
+-      printk("page 2\n");
+-      q = kmap(sg[1].page) + sg[1].offset;
+-      hexdump(q, 4);
+-      printk("%s\n", memcmp(q, des_tv[i].result + 4, 4) ? "fail" : "pass");
+-
+-      out:
+-      crypto_free_tfm(tfm);
+-}
+-
+-void
+-test_des3_ede(void)
+-{
+-      unsigned int ret, i, len;
+-      unsigned int tsize;
+-      char *p, *q;
+-      struct crypto_tfm *tfm;
+-      char *key;
+-      /*char res[8]; */
+-      struct des_tv *des_tv;
+-      struct scatterlist sg[8];
+-
+-      printk("\ntesting des3 ede encryption\n");
+-
+-      tsize = sizeof (des3_ede_enc_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, des3_ede_enc_tv_template, tsize);
+-      des_tv = (void *) tvmem;
+-
+-      tfm = crypto_alloc_tfm("des3_ede", CRYPTO_TFM_MODE_ECB);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for 3des ecb\n");
+-              return;
+-      }
+-
+-      for (i = 0; i < DES3_EDE_ENC_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-
+-              key = des_tv[i].key;
+-              ret = crypto_cipher_setkey(tfm, key, 24);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!des_tv[i].fail)
+-                              goto out;
+-              }
+-
+-              len = des_tv[i].len;
+-
+-              p = des_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = len;
+-              ret = crypto_cipher_encrypt(tfm, sg, sg, len);
+-              if (ret) {
+-                      printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, len);
+-
+-              printk("%s\n",
+-                     memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+-      }
+-
+-      printk("\ntesting des3 ede decryption\n");
+-
+-      tsize = sizeof (des3_ede_dec_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, des3_ede_dec_tv_template, tsize);
+-      des_tv = (void *) tvmem;
+-
+-      for (i = 0; i < DES3_EDE_DEC_TEST_VECTORS; i++) {
+-              printk("test %u:\n", i + 1);
+-
+-              key = des_tv[i].key;
+-              ret = crypto_cipher_setkey(tfm, key, 24);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!des_tv[i].fail)
+-                              goto out;
+-              }
+-
+-              len = des_tv[i].len;
+-
+-              p = des_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = len;
+-              ret = crypto_cipher_decrypt(tfm, sg, sg, len);
+-              if (ret) {
+-                      printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, len);
+-
+-              printk("%s\n",
+-                     memcmp(q, des_tv[i].result, len) ? "fail" : "pass");
+-      }
+-
+-      out:
+-      crypto_free_tfm(tfm);
+-}
+-
+-void
+-test_blowfish(void)
+-{
+-      unsigned int ret, i;
+-      unsigned int tsize;
+-      char *p, *q;
+-      struct crypto_tfm *tfm;
+-      char *key;
+-      struct bf_tv *bf_tv;
+-      struct scatterlist sg[1];
+-
+-      printk("\ntesting blowfish encryption\n");
+-
+-      tsize = sizeof (bf_enc_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, bf_enc_tv_template, tsize);
+-      bf_tv = (void *) tvmem;
+-
+-      tfm = crypto_alloc_tfm("blowfish", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for blowfish (default ecb)\n");
+-              return;
+-      }
+-
+-      for (i = 0; i < BF_ENC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n",
+-                      i + 1, bf_tv[i].keylen * 8);
+-              key = bf_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!bf_tv[i].fail)
+-                              goto out;
+-              }
+-
+-              p = bf_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = bf_tv[i].plen;
+-              ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, bf_tv[i].rlen);
+-
+-              printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ?
+-                      "fail" : "pass");
+-      }
+-
+-      printk("\ntesting blowfish decryption\n");
+-
+-      tsize = sizeof (bf_dec_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, bf_dec_tv_template, tsize);
+-      bf_tv = (void *) tvmem;
+-
+-      for (i = 0; i < BF_DEC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n",
+-                      i + 1, bf_tv[i].keylen * 8);
+-              key = bf_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!bf_tv[i].fail)
+-                              goto out;
+-              }
+-
+-              p = bf_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = bf_tv[i].plen;
+-              ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, bf_tv[i].rlen);
+-
+-              printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen) ?
+-                      "fail" : "pass");
+-      }
+-      
+-      crypto_free_tfm(tfm);
+-      
+-      tfm = crypto_alloc_tfm("blowfish", CRYPTO_TFM_MODE_CBC);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for blowfish cbc\n");
+-              return;
+-      }
+-
+-      printk("\ntesting blowfish cbc encryption\n");
+-
+-      tsize = sizeof (bf_cbc_enc_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              goto out;
+-      }
+-      memcpy(tvmem, bf_cbc_enc_tv_template, tsize);
+-      bf_tv = (void *) tvmem;
+-
+-      for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n",
+-                      i + 1, bf_tv[i].keylen * 8);
+-
+-              key = bf_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              p = bf_tv[i].plaintext;
+-
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length =  bf_tv[i].plen;
+-
+-              crypto_cipher_set_iv(tfm, bf_tv[i].iv,
+-                                   crypto_tfm_alg_ivsize(tfm));
+-
+-              ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("blowfish_cbc_encrypt() failed flags=%x\n",
+-                             tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, bf_tv[i].rlen);
+-
+-              printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen)
+-                      ? "fail" : "pass");
+-      }
+-
+-      printk("\ntesting blowfish cbc decryption\n");
+-
+-      tsize = sizeof (bf_cbc_dec_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              goto out;
+-      }
+-      memcpy(tvmem, bf_cbc_dec_tv_template, tsize);
+-      bf_tv = (void *) tvmem;
+-
+-      for (i = 0; i < BF_CBC_ENC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n",
+-                      i + 1, bf_tv[i].keylen * 8);
+-              key = bf_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, bf_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              p = bf_tv[i].plaintext;
+-
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length =  bf_tv[i].plen;
+-
+-              crypto_cipher_set_iv(tfm, bf_tv[i].iv,
+-                                   crypto_tfm_alg_ivsize(tfm));
+-
+-              ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("blowfish_cbc_decrypt() failed flags=%x\n",
+-                             tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, bf_tv[i].rlen);
+-
+-              printk("%s\n", memcmp(q, bf_tv[i].result, bf_tv[i].rlen)
+-                      ? "fail" : "pass");
+-      }
+-
+-out:
+-      crypto_free_tfm(tfm);
+-}
+-
+-
+-void
+-test_twofish(void)
+-{
+-      unsigned int ret, i;
+-      unsigned int tsize;
+-      char *p, *q;
+-      struct crypto_tfm *tfm;
+-      char *key;
+-      struct tf_tv *tf_tv;
+-      struct scatterlist sg[1];
+-
+-      printk("\ntesting twofish encryption\n");
+-
+-      tsize = sizeof (tf_enc_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, tf_enc_tv_template, tsize);
+-      tf_tv = (void *) tvmem;
+-
+-      tfm = crypto_alloc_tfm("twofish", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for blowfish (default ecb)\n");
+-              return;
+-      }
+-
+-      for (i = 0; i < TF_ENC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n",
+-                      i + 1, tf_tv[i].keylen * 8);
+-              key = tf_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!tf_tv[i].fail)
+-                              goto out;
+-              }
+-
+-              p = tf_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = tf_tv[i].plen;
+-              ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, tf_tv[i].rlen);
+-
+-              printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ?
+-                      "fail" : "pass");
+-      }
+-
+-      printk("\ntesting twofish decryption\n");
+-
+-      tsize = sizeof (tf_dec_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, tf_dec_tv_template, tsize);
+-      tf_tv = (void *) tvmem;
+-
+-      for (i = 0; i < TF_DEC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n",
+-                      i + 1, tf_tv[i].keylen * 8);
+-              key = tf_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!tf_tv[i].fail)
+-                              goto out;
+-              }
+-
+-              p = tf_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = tf_tv[i].plen;
+-              ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, tf_tv[i].rlen);
+-
+-              printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen) ?
+-                      "fail" : "pass");
+-      }
+-
+-      crypto_free_tfm(tfm);
+-      
+-      tfm = crypto_alloc_tfm("twofish", CRYPTO_TFM_MODE_CBC);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for twofish cbc\n");
+-              return;
+-      }
+-
+-      printk("\ntesting twofish cbc encryption\n");
+-
+-      tsize = sizeof (tf_cbc_enc_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              goto out;
+-      }
+-      memcpy(tvmem, tf_cbc_enc_tv_template, tsize);
+-      tf_tv = (void *) tvmem;
+-
+-      for (i = 0; i < TF_CBC_ENC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n",
+-                      i + 1, tf_tv[i].keylen * 8);
+-
+-              key = tf_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              p = tf_tv[i].plaintext;
+-
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length =  tf_tv[i].plen;
+-
+-              crypto_cipher_set_iv(tfm, tf_tv[i].iv,
+-                                   crypto_tfm_alg_ivsize(tfm));
+-
+-              ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("blowfish_cbc_encrypt() failed flags=%x\n",
+-                             tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, tf_tv[i].rlen);
+-
+-              printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen)
+-                      ? "fail" : "pass");
+-      }
+-
+-      printk("\ntesting twofish cbc decryption\n");
+-
+-      tsize = sizeof (tf_cbc_dec_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              goto out;
+-      }
+-      memcpy(tvmem, tf_cbc_dec_tv_template, tsize);
+-      tf_tv = (void *) tvmem;
+-
+-      for (i = 0; i < TF_CBC_DEC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n",
+-                      i + 1, tf_tv[i].keylen * 8);
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the Free
++ * Software Foundation; either version 2 of the License, or (at your option) 
++ * any later version.
++ *
++ * 14 - 09 - 2003 
++ *    Rewritten by Kartikey Mahendra Bhatt
++ */
+-              key = tf_tv[i].key;
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <asm/scatterlist.h>
++#include <linux/string.h>
++#include <linux/crypto.h>
++#include <linux/highmem.h>
++#include "tcrypt.h"
+-              ret = crypto_cipher_setkey(tfm, key, tf_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
++/*
++ * Need to kmalloc() memory for testing kmap().
++ */
++#define TVMEMSIZE     4096
++#define XBUFSIZE      32768
+-              p = tf_tv[i].plaintext;
++/*
++ * Indexes into the xbuf to simulate cross-page access.
++ */
++#define IDX1          37
++#define IDX2          32400
++#define IDX3          1
++#define IDX4          8193
++#define IDX5          22222
++#define IDX6          17101
++#define IDX7          27333
++#define IDX8          3000
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length =  tf_tv[i].plen;
++/*
++* Used by test_cipher()
++*/
++#define ENCRYPT 1
++#define DECRYPT 0
++#define MODE_ECB 1
++#define MODE_CBC 0
+-              crypto_cipher_set_iv(tfm, tf_tv[i].iv,
+-                                   crypto_tfm_alg_ivsize(tfm));
++static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
+-              ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("blowfish_cbc_decrypt() failed flags=%x\n",
+-                             tfm->crt_flags);
+-                      goto out;
+-              }
++static int mode;
++static char *xbuf;
++static char *tvmem;
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, tf_tv[i].rlen);
++static char *check[] = {
++      "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
++      "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", 
++      "deflate", NULL
++};
+-              printk("%s\n", memcmp(q, tf_tv[i].result, tf_tv[i].rlen)
+-                      ? "fail" : "pass");
+-      }
++static void
++hexdump(unsigned char *buf, unsigned int len)
++{
++      while (len--)
++              printk("%02x", *buf++);
+-out:  
+-      crypto_free_tfm(tfm);
++      printk("\n");
+ }
+-void
+-test_serpent(void)
++static void 
++test_hash (char * algo, struct hash_testvec * template, unsigned int tcount)
+ {
+-      unsigned int ret, i, tsize;
+-      u8 *p, *q, *key;
+-      struct crypto_tfm *tfm;
+-      struct serpent_tv *serp_tv;
+-      struct scatterlist sg[1];
+-
+-      printk("\ntesting serpent encryption\n");
++      char *p; 
++        unsigned int i, j, k, temp;
++        struct scatterlist sg[8];
++        char result[64];
++        struct crypto_tfm *tfm;
++        struct hash_testvec *hash_tv;
++        unsigned int tsize;
++       
++        printk("\ntesting %s\n", algo);
+-      tfm = crypto_alloc_tfm("serpent", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for serpent (default ecb)\n");
++      tsize = sizeof (struct hash_testvec);
++      tsize *= tcount;
++      
++      if (tsize > TVMEMSIZE) {
++              printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE);
+               return;
+       }
+-      tsize = sizeof (serpent_enc_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
++      memcpy(tvmem, template, tsize);
++      hash_tv = (void *) tvmem;
++      tfm = crypto_alloc_tfm(algo, 0);
++      if (tfm == NULL) {
++              printk("failed to load transform for %s\n", algo);
+               return;
+       }
+-      memcpy(tvmem, serpent_enc_tv_template, tsize);
+-      serp_tv = (void *) tvmem;
+-      for (i = 0; i < SERPENT_ENC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8);
+-              key = serp_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!serp_tv[i].fail)
+-                              goto out;
+-              }
++      for (i = 0; i < tcount; i++) {
++              printk ("test %u:\n", i + 1);
++              memset (result, 0, 64);
+-              p = serp_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = sizeof(serp_tv[i].plaintext);
+-              ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
++              p = hash_tv[i].plaintext;
++              sg[0].page = virt_to_page (p);
++              sg[0].offset = offset_in_page (p);
++              sg[0].length = hash_tv[i].psize;
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, sizeof(serp_tv[i].result));
++              crypto_digest_init (tfm);
++              crypto_digest_update (tfm, sg, 1);
++              crypto_digest_final (tfm, result);
+-              printk("%s\n", memcmp(q, serp_tv[i].result,
+-                      sizeof(serp_tv[i].result)) ? "fail" : "pass");
++              hexdump (result, crypto_tfm_alg_digestsize (tfm));
++              printk("%s\n",
++                      memcmp(result, hash_tv[i].digest,
++                              crypto_tfm_alg_digestsize(tfm)) ? "fail" :
++                      "pass");
+       }
+-      printk("\ntesting serpent decryption\n");
+-
+-      tsize = sizeof (serpent_dec_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
++      printk ("testing %s across pages\n", algo);
+-      memcpy(tvmem, serpent_dec_tv_template, tsize);
+-      serp_tv = (void *) tvmem;
+-      for (i = 0; i < SERPENT_DEC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n", i + 1, serp_tv[i].keylen * 8);
+-              key = serp_tv[i].key;
++      /* setup the dummy buffer first */
++        memset(xbuf, 0, XBUFSIZE);
+-              ret = crypto_cipher_setkey(tfm, key, serp_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
++      j = 0;
++      for (i = 0; i < tcount; i++) {
++              if (hash_tv[i].np) {
++                      j++;
++                      printk ("test %u:\n", j);
++                      memset (result, 0, 64);
+-                      if (!serp_tv[i].fail)
+-                              goto out;
+-              }
++                      temp = 0;
++                      for (k = 0; k < hash_tv[i].np; k++) {
++                              memcpy (&xbuf[IDX[k]], hash_tv[i].plaintext + temp, 
++                                              hash_tv[i].tap[k]);     
++                              temp += hash_tv[i].tap[k];
++                              p = &xbuf[IDX[k]];
++                              sg[k].page = virt_to_page (p);
++                              sg[k].offset = offset_in_page (p);
++                              sg[k].length = hash_tv[i].tap[k];
++                      }
+-              p = serp_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = sizeof(serp_tv[i].plaintext);
+-              ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
++                      crypto_digest_digest (tfm, sg, hash_tv[i].np, result);
++                      
++                      hexdump (result, crypto_tfm_alg_digestsize (tfm));
++                      printk("%s\n",
++                              memcmp(result, hash_tv[i].digest,
++                                      crypto_tfm_alg_digestsize(tfm)) ? "fail" :
++                              "pass");
+               }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, sizeof(serp_tv[i].result));
+-
+-              printk("%s\n", memcmp(q, serp_tv[i].result,
+-                      sizeof(serp_tv[i].result)) ? "fail" : "pass");
+       }
+-
+-out:
+-      crypto_free_tfm(tfm);
++      
++      crypto_free_tfm (tfm);
+ }
++
++#ifdef CONFIG_CRYPTO_HMAC
++
+ static void
+-test_cast6(void)
++test_hmac(char *algo, struct hmac_testvec * template, unsigned int tcount)
+ {
+-      unsigned int ret, i, tsize;
+-      u8 *p, *q, *key;
++      char *p;
++      unsigned int i, j, k, temp;
++      struct scatterlist sg[8];
++      char result[64];
+       struct crypto_tfm *tfm;
+-      struct cast6_tv *cast_tv;
+-      struct scatterlist sg[1];
++      struct hmac_testvec *hmac_tv;
++      unsigned int tsize, klen;
+-      printk("\ntesting cast6 encryption\n");
+-
+-      tfm = crypto_alloc_tfm("cast6", 0);
++      tfm = crypto_alloc_tfm(algo, 0);
+       if (tfm == NULL) {
+-              printk("failed to load transform for cast6 (default ecb)\n");
++              printk("failed to load transform for %s\n", algo);
+               return;
+       }
+-      tsize = sizeof (cast6_enc_tv_template);
++      printk("\ntesting hmac_%s\n", algo);
++      
++      tsize = sizeof (struct hmac_testvec);
++      tsize *= tcount;
+       if (tsize > TVMEMSIZE) {
+               printk("template (%u) too big for tvmem (%u)\n", tsize,
+                      TVMEMSIZE);
+-              return;
++              goto out;
+       }
+-      memcpy(tvmem, cast6_enc_tv_template, tsize);
+-      cast_tv = (void *) tvmem;
+-      for (i = 0; i < CAST6_ENC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n", i + 1, cast_tv[i].keylen * 8);
+-              key = cast_tv[i].key;
++      memcpy(tvmem, template, tsize);
++      hmac_tv = (void *) tvmem;
+-              ret = crypto_cipher_setkey(tfm, key, cast_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!cast_tv[i].fail)
+-                              goto out;
+-              }
++      for (i = 0; i < tcount; i++) {
++              printk("test %u:\n", i + 1);
++              memset(result, 0, sizeof (result));
+-              p = cast_tv[i].plaintext;
++              p = hmac_tv[i].plaintext;
++              klen = hmac_tv[i].ksize;
+               sg[0].page = virt_to_page(p);
+-              sg[0].offset = ((long) p & ~PAGE_MASK);
+-              sg[0].length = sizeof(cast_tv[i].plaintext);
+-              ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, sizeof(cast_tv[i].result));
+-
+-              printk("%s\n", memcmp(q, cast_tv[i].result,
+-                      sizeof(cast_tv[i].result)) ? "fail" : "pass");
+-      }
++              sg[0].offset = offset_in_page(p);
++              sg[0].length = hmac_tv[i].psize;
+-      printk("\ntesting cast6 decryption\n");
++              crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, 1, result);
+-      tsize = sizeof (cast6_dec_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
++              hexdump(result, crypto_tfm_alg_digestsize(tfm));
++              printk("%s\n",
++                     memcmp(result, hmac_tv[i].digest,
++                            crypto_tfm_alg_digestsize(tfm)) ? "fail" :
++                     "pass");
+       }
+-      memcpy(tvmem, cast6_dec_tv_template, tsize);
+-      cast_tv = (void *) tvmem;
+-      for (i = 0; i < CAST6_DEC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n", i + 1, cast_tv[i].keylen * 8);
+-              key = cast_tv[i].key;
++      printk("\ntesting hmac_%s across pages\n", algo);
+-              ret = crypto_cipher_setkey(tfm, key, cast_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!cast_tv[i].fail)
+-                              goto out;
+-              }
+-
+-              p = cast_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = ((long) p & ~PAGE_MASK);
+-              sg[0].length = sizeof(cast_tv[i].plaintext);
+-              ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
++      memset(xbuf, 0, XBUFSIZE);
++      
++      j = 0;
++      for (i = 0; i < tcount; i++) {
++              if (hmac_tv[i].np) {
++                      j++;
++                      printk ("test %u:\n",j);
++                      memset (result, 0, 64);
++
++                      temp = 0;
++                      klen = hmac_tv[i].ksize;
++                      for (k = 0; k < hmac_tv[i].np; k++) {
++                              memcpy (&xbuf[IDX[k]], hmac_tv[i].plaintext + temp, 
++                                              hmac_tv[i].tap[k]);     
++                              temp += hmac_tv[i].tap[k];
++                              p = &xbuf[IDX[k]];
++                              sg[k].page = virt_to_page (p);
++                              sg[k].offset = offset_in_page (p);
++                              sg[k].length = hmac_tv[i].tap[k];
++                      }
++
++                      crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, hmac_tv[i].np, 
++                                      result);
++                      hexdump(result, crypto_tfm_alg_digestsize(tfm));
++                      
++                      printk("%s\n",
++                              memcmp(result, hmac_tv[i].digest,
++                                      crypto_tfm_alg_digestsize(tfm)) ? "fail" : 
++                              "pass");
+               }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, sizeof(cast_tv[i].result));
+-
+-              printk("%s\n", memcmp(q, cast_tv[i].result,
+-                      sizeof(cast_tv[i].result)) ? "fail" : "pass");
+       }
+-
+ out:
+       crypto_free_tfm(tfm);
+ }
++#endif        /* CONFIG_CRYPTO_HMAC */
++
+ void
+-test_aes(void)
++test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, unsigned int tcount)
+ {
+-      unsigned int ret, i;
++      unsigned int ret, i, j, k, temp;
+       unsigned int tsize;
+       char *p, *q;
+       struct crypto_tfm *tfm;
+       char *key;
+-      struct aes_tv *aes_tv;
+-      struct scatterlist sg[1];
+-
+-      printk("\ntesting aes encryption\n");
+-
+-      tsize = sizeof (aes_enc_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, aes_enc_tv_template, tsize);
+-      aes_tv = (void *) tvmem;
+-
+-      tfm = crypto_alloc_tfm("aes", 0);
+-      if (tfm == NULL) {
+-              printk("failed to load transform for aes (default ecb)\n");
+-              return;
+-      }
+-
+-      for (i = 0; i < AES_ENC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n",
+-                      i + 1, aes_tv[i].keylen * 8);
+-              key = aes_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!aes_tv[i].fail)
+-                              goto out;
+-              }
++      struct cipher_testvec *cipher_tv;
++      struct scatterlist sg[8];
++      char e[11], m[4];
+-              p = aes_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = aes_tv[i].plen;
+-              ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
++      if (enc == ENCRYPT)
++              strncpy(e, "encryption", 11);
++      else
++              strncpy(e, "decryption", 11);
++      if (mode == MODE_ECB)
++              strncpy(m, "ECB", 4);
++      else
++              strncpy(m, "CBC", 4);
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, aes_tv[i].rlen);
++      printk("\ntesting %s %s %s \n", algo, m, e);
+-              printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ?
+-                      "fail" : "pass");
+-      }
++      tsize = sizeof (struct cipher_testvec); 
++      tsize *= tcount;
+       
+-      printk("\ntesting aes decryption\n");
+-
+-      tsize = sizeof (aes_dec_tv_template);
+       if (tsize > TVMEMSIZE) {
+               printk("template (%u) too big for tvmem (%u)\n", tsize,
+                      TVMEMSIZE);
+               return;
+       }
+-      memcpy(tvmem, aes_dec_tv_template, tsize);
+-      aes_tv = (void *) tvmem;
+-
+-      for (i = 0; i < AES_DEC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n",
+-                      i + 1, aes_tv[i].keylen * 8);
+-              key = aes_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, aes_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!aes_tv[i].fail)
+-                              goto out;
+-              }
+-
+-              p = aes_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = offset_in_page(p);
+-              sg[0].length = aes_tv[i].plen;
+-              ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, aes_tv[i].rlen);
+-
+-              printk("%s\n", memcmp(q, aes_tv[i].result, aes_tv[i].rlen) ?
+-                      "fail" : "pass");
+-      }
+-
+-out:
+-      crypto_free_tfm(tfm);
+-}
+-
+-void
+-test_cast5(void)
+-{
+-      unsigned int ret, i, tsize;
+-      u8 *p, *q, *key;
+-      struct crypto_tfm *tfm;
+-      struct cast5_tv *c5_tv;
+-      struct scatterlist sg[1];
+-
+-      printk("\ntesting cast5 encryption\n");
++      memcpy(tvmem, template, tsize);
++      cipher_tv = (void *) tvmem;
+-      tfm = crypto_alloc_tfm("cast5", 0);
++      if (mode) 
++              tfm = crypto_alloc_tfm (algo, 0);
++      else 
++              tfm = crypto_alloc_tfm (algo, CRYPTO_TFM_MODE_CBC);
++      
+       if (tfm == NULL) {
+-              printk("failed to load transform for cast5 (default ecb)\n");
+-              return;
+-      }
+-
+-      tsize = sizeof (cast5_enc_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
++              printk("failed to load transform for %s %s\n", algo, m);
+               return;
+       }
++      
++      j = 0;
++      for (i = 0; i < tcount; i++) {
++              if (!(cipher_tv[i].np)) {
++                      j++;    
++                      printk("test %u (%d bit key):\n",
++                      j, cipher_tv[i].klen * 8);
+-      memcpy(tvmem, cast5_enc_tv_template, tsize);
+-      c5_tv = (void *) tvmem;
+-      for (i = 0; i < CAST5_ENC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n", i + 1, c5_tv[i].keylen * 8);
+-              key = c5_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, c5_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
++                      tfm->crt_flags = 0;
++                      if (cipher_tv[i].wk) 
++                              tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
++                      key = cipher_tv[i].key;
++      
++                      ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen);
++                      if (ret) {
++                              printk("setkey() failed flags=%x\n", tfm->crt_flags);
++      
++                              if (!cipher_tv[i].fail)
++                                      goto out;
++                      }       
+-                      if (!c5_tv[i].fail)
++                      p = cipher_tv[i].input;
++                      sg[0].page = virt_to_page(p);
++                      sg[0].offset = offset_in_page(p);
++                      sg[0].length = cipher_tv[i].ilen;
++      
++                      if (!mode) {
++                              crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
++                                      crypto_tfm_alg_ivsize (tfm));
++                      }
++              
++                      if (enc)
++                              ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen);
++                      else
++                              ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen);
++                      
++                              
++                      if (ret) {
++                              printk("%s () failed flags=%x\n", e, tfm->crt_flags);
+                               goto out;
++                      }       
++      
++                      q = kmap(sg[0].page) + sg[0].offset;
++                      hexdump(q, cipher_tv[i].rlen);
++      
++                      printk("%s\n", 
++                              memcmp(q, cipher_tv[i].result, cipher_tv[i].rlen) ? "fail" : 
++                      "pass");
+               }
+-
+-              p = c5_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = ((long) p & ~PAGE_MASK);
+-              sg[0].length = sizeof(c5_tv[i].plaintext);
+-              ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("encrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
+-              }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, sizeof(c5_tv[i].ciphertext));
+-
+-              printk("%s\n", memcmp(q, c5_tv[i].ciphertext,
+-                      sizeof(c5_tv[i].ciphertext)) ? "fail" : "pass");
+       }
+       
+-      tsize = sizeof (cast5_dec_tv_template);
+-      if (tsize > TVMEMSIZE) {
+-              printk("template (%u) too big for tvmem (%u)\n", tsize,
+-                     TVMEMSIZE);
+-              return;
+-      }
+-
+-      memcpy(tvmem, cast5_dec_tv_template, tsize);
+-      c5_tv = (void *) tvmem;
+-      for (i = 0; i < CAST5_DEC_TEST_VECTORS; i++) {
+-              printk("test %u (%d bit key):\n", i + 1, c5_tv[i].keylen * 8);
+-              key = c5_tv[i].key;
+-
+-              ret = crypto_cipher_setkey(tfm, key, c5_tv[i].keylen);
+-              if (ret) {
+-                      printk("setkey() failed flags=%x\n", tfm->crt_flags);
+-
+-                      if (!c5_tv[i].fail)
+-                              goto out;
+-              }
+-
+-              p = c5_tv[i].plaintext;
+-              sg[0].page = virt_to_page(p);
+-              sg[0].offset = ((long) p & ~PAGE_MASK);
+-              sg[0].length = sizeof(c5_tv[i].plaintext);
+-              ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length);
+-              if (ret) {
+-                      printk("decrypt() failed flags=%x\n", tfm->crt_flags);
+-                      goto out;
++      printk("\ntesting %s %s %s across pages (chunking) \n", algo, m, e);
++      memset(xbuf, 0, XBUFSIZE);
++      
++      j = 0;
++      for (i = 0; i < tcount; i++) {
++              if (cipher_tv[i].np) {
++                      j++;                            
++                      printk("test %u (%d bit key):\n",
++                      j, cipher_tv[i].klen * 8);
++
++                      tfm->crt_flags = 0;                     
++                      if (cipher_tv[i].wk) 
++                              tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
++                      key = cipher_tv[i].key;
++                      
++                      ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen);                
++                      if (ret) {
++                              printk("setkey() failed flags=%x\n", tfm->crt_flags);
++                              
++                              if (!cipher_tv[i].fail)
++                                      goto out;
++                      }
++
++                      temp = 0;
++                      for (k = 0; k < cipher_tv[i].np; k++) {
++                              memcpy (&xbuf[IDX[k]], cipher_tv[i].input + temp, 
++                                              cipher_tv[i].tap[k]);   
++                              temp += cipher_tv[i].tap[k];
++                              p = &xbuf[IDX[k]];
++                              sg[k].page = virt_to_page (p);
++                              sg[k].offset = offset_in_page (p);
++                              sg[k].length = cipher_tv[i].tap[k];
++                      }
++                      
++                      if (!mode) {
++                              crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
++                                              crypto_tfm_alg_ivsize (tfm));
++                      }
++                      
++                      if (enc)
++                              ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen);
++                      else
++                              ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen);
++                      
++                      if (ret) {
++                              printk("%s () failed flags=%x\n", e, tfm->crt_flags);
++                              goto out;
++                      }
++
++                      temp = 0;
++                      for (k = 0; k < cipher_tv[i].np; k++) {
++                              printk("page %u\n", k);
++                              q = kmap(sg[k].page) + sg[k].offset;
++                              hexdump(q, cipher_tv[i].tap[k]);
++                              printk("%s\n", 
++                                      memcmp(q, cipher_tv[i].result + temp, 
++                                              cipher_tv[i].tap[k]) ? "fail" : 
++                                      "pass");
++                              temp += cipher_tv[i].tap[k];
++                      }
+               }
+-
+-              q = kmap(sg[0].page) + sg[0].offset;
+-              hexdump(q, sizeof(c5_tv[i].ciphertext));
+-
+-              printk("%s\n", memcmp(q, c5_tv[i].ciphertext,
+-                      sizeof(c5_tv[i].ciphertext)) ? "fail" : "pass");
+       }
++
+ out:
+-      crypto_free_tfm (tfm);
++      crypto_free_tfm(tfm);
+ }
+ static void
+@@ -2485,75 +510,118 @@ do_test(void)
+       switch (mode) {
+       case 0:
+-              test_md5();
+-              test_sha1();
+-              test_des();
+-              test_des3_ede();
+-              test_md4();
+-              test_sha256();
+-              test_blowfish();
+-              test_twofish();
+-              test_serpent();
+-              test_cast6();
+-              test_aes();
+-              test_sha384();
+-              test_sha512();
+-              test_deflate();
+-              test_cast5();
+-              test_cast6();
++              test_hash("md5", md5_tv_template, MD5_TEST_VECTORS);
++              
++              test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
++              
++              //DES
++              test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS);
++                test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS);
++                test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS);
++                test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS);
++      
++              //DES3_EDE
++              test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS);
++                test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
++              
++              test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
++              
++              test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
++              
++              //BLOWFISH
++              test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS);
++              test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS);
++              test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS);
++              test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS);
++              
++              //TWOFISH
++              test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS);
++              test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS);
++              test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS);
++              test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS);
++              
++              //SERPENT
++              test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS);
++              test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS);
++              
++              //AES
++              test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS);
++              test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);
++
++              //CAST5
++              test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS);
++              test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS);
++              
++              //CAST6
++              test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS);
++              test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS);
++
++              test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
++              test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
++              test_deflate();         
+ #ifdef CONFIG_CRYPTO_HMAC
+-              test_hmac_md5();
+-              test_hmac_sha1();
+-              test_hmac_sha256();
++              test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
++              test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);               
++              test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
+ #endif                
+               break;
+       case 1:
+-              test_md5();
++              test_hash("md5", md5_tv_template, MD5_TEST_VECTORS);
+               break;
+       case 2:
+-              test_sha1();
++              test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
+               break;
+       case 3:
+-              test_des();
++              test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS);
++              test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS);
++              test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS);
++              test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS);
+               break;
+       case 4:
+-              test_des3_ede();
++              test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS);
++                test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
+               break;
+       case 5:
+-              test_md4();
++              test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
+               break;
+               
+       case 6:
+-              test_sha256();
++              test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
+               break;
+       
+       case 7:
+-              test_blowfish();
++              test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS);
++              test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS);
++              test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS);
++              test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS);
+               break;
+       case 8:
+-              test_twofish();
++              test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS);
++              test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS);
++              test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS);
++              test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS);
+               break;
+-
++              
+       case 9:
+-              test_serpent();
+               break;
+       case 10:
+-              test_aes();
++              test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS);
++              test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);      
+               break;
+       case 11:
+-              test_sha384();
++              test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
+               break;
+               
+       case 12:
+-              test_sha512();
++              test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
+               break;
+       case 13:
+@@ -2561,24 +629,26 @@ do_test(void)
+               break;
+       case 14:
+-              test_cast5();
++              test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS);
++              test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS);
+               break;
+       case 15:
+-              test_cast6();
++              test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS);
++              test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS);
+               break;
+ #ifdef CONFIG_CRYPTO_HMAC
+       case 100:
+-              test_hmac_md5();
++              test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
+               break;
+               
+       case 101:
+-              test_hmac_sha1();
++              test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);               
+               break;
+       
+       case 102:
+-              test_hmac_sha256();
++              test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
+               break;
+ #endif
+@@ -2614,7 +684,14 @@ init(void)
+       return 0;
+ }
++/*
++ * If an init function is provided, an exit function must also be provided
++ * to allow module unload.
++ */
++static void __exit fini(void) { }
++
+ module_init(init);
++module_exit(fini);
+ MODULE_PARM(mode, "i");
+--- linux-2.6.0/crypto/tcrypt.h        2003-08-22 19:23:40.000000000 -0700
++++ 25/crypto/tcrypt.h 2003-12-28 23:22:31.000000000 -0800
+@@ -1,4 +1,4 @@
+-/* 
++/*
+  * Quick & dirty crypto testing module.
+  *
+  * This will only exist until we have a better testing mechanism
+@@ -6,565 +6,165 @@
+  *
+  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+  * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org>
+- * 
++ *
+  * This program is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU General Public License as published by the Free
+  * Software Foundation; either version 2 of the License, or (at your option) 
+  * any later version.
+  *
++ * 14 - 09 - 2003 Changes by Kartikey Mahendra Bhatt
++ *
+  */
+ #ifndef _CRYPTO_TCRYPT_H
+ #define _CRYPTO_TCRYPT_H
+-#define MD5_DIGEST_SIZE               16
+-#define MD4_DIGEST_SIZE               16
+-#define SHA1_DIGEST_SIZE      20
+-#define SHA256_DIGEST_SIZE    32
+-#define SHA384_DIGEST_SIZE    48
+-#define SHA512_DIGEST_SIZE    64
+-
+-/*
+- * MD4 test vectors from RFC1320
+- */
+-#define MD4_TEST_VECTORS      7
+-
+-struct md4_testvec {
+-      char plaintext[128];
+-      char digest[MD4_DIGEST_SIZE];
+-} md4_tv_template[] = {
+-      { "",
+-              { 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
+-                0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 }
+-      },
+-      
+-      { "a",
+-              { 0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
+-                0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24 }
+-      },
+-
+-      { "abc",
+-              { 0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
+-                0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d }
+-      },
+-      
+-      { "message digest",
+-              { 0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
+-                0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b }
+-      },
+-      
+-      { "abcdefghijklmnopqrstuvwxyz",
+-              { 0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
+-                0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9 }
+-      },
+-              
+-      { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+-              { 0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
+-                0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4 }
+-      },
+-      
+-      { "123456789012345678901234567890123456789012345678901234567890123"
+-        "45678901234567890",
+-              { 0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
+-                0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36 }
+-      },
+-};
++#define MAX_DIGEST_SIZE               64
++#define MAX_TAP                       8
+-/*
+- * MD5 test vectors from RFC1321
+- */
+-#define MD5_TEST_VECTORS      7
++#define MAX_KEYLEN            56
++#define MAX_IVLEN             32
+-struct md5_testvec {
++struct hash_testvec {
+       char plaintext[128];
+-      char digest[MD5_DIGEST_SIZE];
+-} md5_tv_template[] = {
+-      { "",
+-              { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
+-                0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
+-                      
+-      { "a",
+-              { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
+-                0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
+-                
+-      { "abc",
+-              { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
+-                0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, 
+-                
+-      { "message digest",
+-              { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
+-                0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
+-                
+-      { "abcdefghijklmnopqrstuvwxyz",
+-              { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
+-                0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
+-                
+-      { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+-              { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
+-                0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
+-                
+-      { "12345678901234567890123456789012345678901234567890123456789012"
+-        "345678901234567890",
+-              { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
+-                0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }
++      unsigned char psize;
++      char digest[MAX_DIGEST_SIZE];
++      unsigned char np;
++      unsigned char tap[MAX_TAP];             
+ };
+-#ifdef CONFIG_CRYPTO_HMAC
+-/*
+- * HMAC-MD5 test vectors from RFC2202
+- * (These need to be fixed to not use strlen).
+- */
+-#define HMAC_MD5_TEST_VECTORS 7
+-
+-struct hmac_md5_testvec {
++struct hmac_testvec { 
+       char key[128];
++      unsigned char ksize;
+       char plaintext[128];
+-      char digest[MD5_DIGEST_SIZE];
++      unsigned char psize;
++      char digest[MAX_DIGEST_SIZE];
++      unsigned char np;
++      unsigned char tap[MAX_TAP];             
+ };
+-struct hmac_md5_testvec hmac_md5_tv_template[] =
+-{
+-      
+-      {
+-              { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+-                0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00},
+-                
+-              "Hi There",
+-              
+-              { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
+-                0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d }
+-      },
+-          
+-      {
+-              { 'J', 'e', 'f', 'e', 0 },
+-              
+-              "what do ya want for nothing?",
+-              
+-              { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
+-                0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 }
+-      },
+-      
+-      {
+-              { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 },
+-                
+-              { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0x00 },
+-                
+-              { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
+-                0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }
+-      },
+-      
+-      {
+-              { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+-                0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 
+-                0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00 },
+-                
+-              { 
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0x00 },
+-                
+-              { 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
+-                0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 }
+-      },
+-      
+-      {
+-              { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+-                0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00 },
+-                
+-              "Test With Truncation",
+-              
+-              { 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00,
+-                0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c }
+-      },
+-      
+-      {
+-              { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0x00 },
+-                
+-              "Test Using Larger Than Block-Size Key - Hash Key First",
+-              
+-              { 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
+-                0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd }
+-      },
+-      
+-      {
+-              { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0x00 },
+-              
+-              "Test Using Larger Than Block-Size Key and Larger Than One "
+-              "Block-Size Data",
+-              
+-              { 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
+-                0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e }
+-      },
+-      
+-      /* cross page test, need to retain key */
+-      
+-      {
+-              { 'J', 'e', 'f', 'e', 0 },
+-              
+-              "what do ya want for nothing?",
+-              
+-              { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
+-                0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 }
+-      },
+-      
++struct cipher_testvec {
++      unsigned char fail;
++      unsigned char wk; /* weak key flag */
++      char key[MAX_KEYLEN];
++      unsigned char klen;
++      char iv[MAX_IVLEN];
++      char input[48];
++      unsigned char ilen;
++      char result[48];
++      unsigned char rlen;
++      int np;
++      unsigned char tap[MAX_TAP];     
+ };
+-      
+ /*
+- * HMAC-SHA1 test vectors from RFC2202
++ * MD4 test vectors from RFC1320
+  */
++#define MD4_TEST_VECTORS      7
+-#define HMAC_SHA1_TEST_VECTORS        7
+-
+-struct hmac_sha1_testvec {
+-      char key[128];
+-      char plaintext[128];
+-      char digest[SHA1_DIGEST_SIZE];
+-} hmac_sha1_tv_template[] = {
+-      
+-      {
+-              { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+-                0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+-                0x00},
+-                
+-              "Hi There",
+-
+-              { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
+-                  0xe2, 0x8b, 0xc0, 0xb6, 0xfb ,0x37, 0x8c, 0x8e, 0xf1,
+-                  0x46, 0xbe, 0x00 }
+-      },
+-          
+-      {
+-              { 'J', 'e', 'f', 'e', 0 },
+-              
+-              "what do ya want for nothing?",
+-
+-              { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, 
+-                0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 }
+-
+-      },
+-      
+-      {
+-              { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0x00},
+-
+-                
+-              { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0x00 },
+-                
+-              { 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x91, 0xa3, 
+-                0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, 0x63, 0xf1, 0x75, 0xd3 }
+-
+-      },
+-      
+-      {
+-              { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+-                0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 
+-                0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00 },
+-                
+-              { 
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0x00 },
+-                
+-              { 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0xbc, 0x84, 
+-                0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, 0x2d, 0x72, 0x35, 0xda }
+-
+-      },
+-      
+-      {
+-              { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+-                0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+-                0x00 },
+-                
+-              "Test With Truncation",
+-              
+-              { 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, 
+-                0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04 }
+-
+-      },
+-      
+-      {
+-              { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0x00 },
+-                
+-              "Test Using Larger Than Block-Size Key - Hash Key First",
+-              
+-              { 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70, 
+-                0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0xed, 0x40, 0x21, 0x12 }
+-
+-      },
+-      
++struct hash_testvec md4_tv_template [] = {
+       {
+-              { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0x00 },
+-              
+-              "Test Using Larger Than Block-Size Key and Larger Than One "
+-              "Block-Size Data",
+-              
+-              { 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b, 
+-                0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91 }
++              .plaintext = "",
++              .digest = { 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
++                          0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 },
++      }, {
++              .plaintext = "a",
++              .psize  = 1,
++              .digest = { 0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
++                          0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24 },
++      }, {
++              .plaintext = "abc",
++              .psize  = 3,
++              .digest = { 0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
++                          0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d },
++      }, {
++              .plaintext = "message digest",
++              .psize  = 14,
++              .digest = { 0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
++                          0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b },
++      }, {
++              .plaintext = "abcdefghijklmnopqrstuvwxyz",
++              .psize  = 26,
++              .digest = { 0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
++                          0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9 },
++              .np     = 2,
++              .tap    = { 13, 13 },
++      }, {
++              .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
++              .psize  = 62,
++              .digest = { 0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
++                          0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4 },
++      }, {
++              .plaintext = "123456789012345678901234567890123456789012345678901234567890123"
++                           "45678901234567890",
++              .psize  = 80,
++              .digest = { 0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
++                          0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36 },
+       },
+-      
+-      /* cross page test */
+-      {
+-              { 'J', 'e', 'f', 'e', 0 },
+-              
+-              "what do ya want for nothing?",
+-
+-              { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, 
+-                0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 }
+-
+-      },
+-
+ };
+ /*
+- * HMAC-SHA256 test vectors from
+- * draft-ietf-ipsec-ciph-sha-256-01.txt
++ * MD5 test vectors from RFC1321
+  */
+-#define HMAC_SHA256_TEST_VECTORS      10
+-
+-struct hmac_sha256_testvec {
+-      char key[128];
+-      char plaintext[128];
+-      char digest[SHA256_DIGEST_SIZE];
+-} hmac_sha256_tv_template[] = {
+-
+-      {
+-              { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+-                0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+-                0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+-                0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 },
+-                
+-      
+-              { "abc" },
+-              
+-              { 0xa2, 0x1b, 0x1f, 0x5d, 0x4c, 0xf4, 0xf7, 0x3a,
+-                0x4d, 0xd9, 0x39, 0x75, 0x0f, 0x7a, 0x06, 0x6a,
+-                0x7f, 0x98, 0xcc, 0x13, 0x1c, 0xb1, 0x6a, 0x66,
+-                0x92, 0x75, 0x90, 0x21, 0xcf, 0xab, 0x81, 0x81 },
+-
+-      },
+-      
+-      {
+-              { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+-                0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+-                0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+-                 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 },
+-              
+-              { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+-              
+-              { 0x10, 0x4f, 0xdc, 0x12, 0x57, 0x32, 0x8f, 0x08,
+-                0x18, 0x4b, 0xa7, 0x31, 0x31, 0xc5, 0x3c, 0xae,
+-                0xe6, 0x98, 0xe3, 0x61, 0x19, 0x42, 0x11, 0x49,
+-                0xea, 0x8c, 0x71, 0x24, 0x56, 0x69, 0x7d, 0x30 }
+-      },
+-
+-      {
+-              { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+-                0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+-                0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+-                0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x00 },
+-              
+-              { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+-                "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+-              
+-              { 0x47, 0x03, 0x05, 0xfc, 0x7e, 0x40, 0xfe, 0x34,
+-                0xd3, 0xee, 0xb3, 0xe7, 0x73, 0xd9, 0x5a, 0xab,
+-                0x73, 0xac, 0xf0, 0xfd, 0x06, 0x04, 0x47, 0xa5,
+-                0xeb, 0x45, 0x95, 0xbf, 0x33, 0xa9, 0xd1, 0xa3 }
+-      },
+-
+-      {
+-              { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+-                0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+-                0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+-                0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x00 },
+-              
+-              { "Hi There" },
+-              
+-              { 0x19, 0x8a, 0x60, 0x7e, 0xb4, 0x4b, 0xfb, 0xc6,
+-                0x99, 0x03, 0xa0, 0xf1, 0xcf, 0x2b, 0xbd, 0xc5,
+-                0xba, 0x0a, 0xa3, 0xf3, 0xd9, 0xae, 0x3c, 0x1c,
+-                0x7a, 0x3b, 0x16, 0x96, 0xa0, 0xb6, 0x8c, 0xf7 }
+-      },
+-
+-      {
+-              { "Jefe" },
+-              
+-              { "what do ya want for nothing?" },
+-              
+-              { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
+-                0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
+-                0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
+-                0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 }
+-      },
+-
+-      {
+-              { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 },
+-              
+-              { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+-                0xdd, 0xdd, 0x00 },
+-              
+-              { 0xcd, 0xcb, 0x12, 0x20, 0xd1, 0xec, 0xcc, 0xea,
+-                0x91, 0xe5, 0x3a, 0xba, 0x30, 0x92, 0xf9, 0x62,
+-                0xe5, 0x49, 0xfe, 0x6c, 0xe9, 0xed, 0x7f, 0xdc,
+-                0x43, 0x19, 0x1f, 0xbd, 0xe4, 0x5c, 0x30, 0xb0 }
+-      },
+-
+-      {
+-              { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+-                0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+-                0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+-                0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+-                0x21, 0x22, 0x23, 0x24, 0x25, 0x00 },
+-              
+-              { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+-                0xcd, 0xcd, 0x00 },
+-              
+-              { 0xd4, 0x63, 0x3c, 0x17, 0xf6, 0xfb, 0x8d, 0x74,
+-                0x4c, 0x66, 0xde, 0xe0, 0xf8, 0xf0, 0x74, 0x55,
+-                0x6e, 0xc4, 0xaf, 0x55, 0xef, 0x07, 0x99, 0x85,
+-                0x41, 0x46, 0x8e, 0xb4, 0x9b, 0xd2, 0xe9, 0x17 }
+-      },
+-
+-      {
+-              { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+-                0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+-                0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+-                0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00 },
+-              
+-              { "Test With Truncation" },
+-              
+-              { 0x75, 0x46, 0xaf, 0x01, 0x84, 0x1f, 0xc0, 0x9b,
+-                0x1a, 0xb9, 0xc3, 0x74, 0x9a, 0x5f, 0x1c, 0x17,
+-                0xd4, 0xf5, 0x89, 0x66, 0x8a, 0x58, 0x7b, 0x27,
+-                0x00, 0xa9, 0xc9, 0x7c, 0x11, 0x93, 0xcf, 0x42 }
+-      },
+-      
+-      {
+-              { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 },
+-              
+-              { "Test Using Larger Than Block-Size Key - Hash Key First" },
+-              
+-              { 0x69, 0x53, 0x02, 0x5e, 0xd9, 0x6f, 0x0c, 0x09,
+-                0xf8, 0x0a, 0x96, 0xf7, 0x8e, 0x65, 0x38, 0xdb,
+-                0xe2, 0xe7, 0xb8, 0x20, 0xe3, 0xdd, 0x97, 0x0e,
+-                0x7d, 0xdd, 0x39, 0x09, 0x1b, 0x32, 0x35, 0x2f }
+-      },
++#define MD5_TEST_VECTORS      7
++struct hash_testvec md5_tv_template[] = {
+       {
+-              { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+-                0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00 },
+-              
+-              { "Test Using Larger Than Block-Size Key and Larger Than "
+-                "One Block-Size Data" },
+-              
+-              { 0x63, 0x55, 0xac, 0x22, 0xe8, 0x90, 0xd0, 0xa3,
+-                0xc8, 0x48, 0x1a, 0x5c, 0xa4, 0x82, 0x5b, 0xc8,
+-                0x84, 0xd3, 0xe7, 0xa1, 0xff, 0x98, 0xa2, 0xfc,
+-                0x2a, 0xc7, 0xd8, 0xe0, 0x64, 0xc3, 0xb2, 0xe6 }
+-      },
++              .digest = { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
++                          0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e },
++      }, {
++              .plaintext = "a",
++              .psize  = 1,
++              .digest = { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
++                          0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 },
++      }, {
++              .plaintext = "abc",
++              .psize  = 3,
++              .digest = { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
++                          0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 },
++      }, {
++              .plaintext = "message digest",
++              .psize  = 14,
++              .digest = { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
++                          0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 },
++      }, {
++              .plaintext = "abcdefghijklmnopqrstuvwxyz",
++              .psize  = 26,
++              .digest = { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
++                          0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b },
++              .np     = 2,
++              .tap    = {13, 13}
++      }, {
++              .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
++              .psize  = 62,
++              .digest = { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
++                          0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f },
++      }, {
++              .plaintext = "12345678901234567890123456789012345678901234567890123456789012"
++                           "345678901234567890",
++              .psize  = 80,
++              .digest = { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
++                          0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a },
++      }
+ };
+-
+-#endif        /* CONFIG_CRYPTO_HMAC */
+-
+ /*
+  * SHA1 test vectors  from from FIPS PUB 180-1
+  */
+ #define SHA1_TEST_VECTORS     2
+-struct sha1_testvec {
+-      char plaintext[128];
+-      char digest[SHA1_DIGEST_SIZE];
+-} sha1_tv_template[] = {
+-      { "abc",
+-        { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 
+-          0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C ,0x9C, 0xD0, 0xD8, 0x9D }
+-      },
+-                      
+-      { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+-
+-        { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E ,0xBA, 0xAE,
+-          0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }
++struct hash_testvec sha1_tv_template[] = {
++      { 
++              .plaintext = "abc",
++              .psize  = 3,
++              .digest = { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e,
++                          0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d },
++      }, {
++              .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
++              .psize  = 56,
++              .digest = { 0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, 0xba, 0xae,
++                          0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5, 0xe5, 0x46, 0x70, 0xf1 },
++              .np     = 2,
++              .tap    = { 28, 28 }
+       }
+ };
+@@ -573,22 +173,23 @@ struct sha1_testvec {
+  */
+ #define SHA256_TEST_VECTORS   2
+-struct sha256_testvec {
+-      char plaintext[128];
+-      char digest[SHA256_DIGEST_SIZE];
+-} sha256_tv_template[] = {
+-      { "abc",
+-        { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
+-          0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
+-          0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
+-          0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }
+-      },
+-                      
+-      { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+-        { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
+-          0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
+-          0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
+-          0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
++struct hash_testvec sha256_tv_template[] = {  
++      { 
++              .plaintext = "abc",
++              .psize  = 3,
++              .digest = { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
++                          0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
++                          0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
++                          0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad },
++      }, {
++              .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
++              .psize  = 56,
++              .digest = { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
++                          0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
++                          0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
++                          0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 },
++              .np     = 2,
++              .tap    = { 28, 28 }
+       },
+ };
+@@ -597,47 +198,47 @@ struct sha256_testvec {
+  */
+ #define SHA384_TEST_VECTORS   4
+-struct sha384_testvec {
+-      char plaintext[128];
+-      char digest[SHA384_DIGEST_SIZE];
+-} sha384_tv_template[] = {
+-
+-      { "abc",
+-        { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
+-          0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
+-          0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
+-          0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
+-          0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
+-          0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }
+-      },
+-      
+-      { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+-        { 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39,
+-          0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39,
+-          0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab,
+-          0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6,
+-          0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f,
+-          0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b  }
+-      },
+-      
+-      { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+-        "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+-        { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
+-          0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
+-          0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
+-          0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
+-          0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
+-          0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39  }
+-      },
+-      
+-      { "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+-        "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+-        { 0x3d, 0x20, 0x89, 0x73, 0xab, 0x35, 0x08, 0xdb,
+-          0xbd, 0x7e, 0x2c, 0x28, 0x62, 0xba, 0x29, 0x0a,
+-          0xd3, 0x01, 0x0e, 0x49, 0x78, 0xc1, 0x98, 0xdc,
+-          0x4d, 0x8f, 0xd0, 0x14, 0xe5, 0x82, 0x82, 0x3a,
+-          0x89, 0xe1, 0x6f, 0x9b, 0x2a, 0x7b, 0xbc, 0x1a,
+-          0xc9, 0x38, 0xe2, 0xd1, 0x99, 0xe8, 0xbe, 0xa4 }
++struct hash_testvec sha384_tv_template[] = {
++      { 
++              .plaintext= "abc",
++              .psize  = 3,
++              .digest = { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
++                          0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
++                          0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
++                          0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
++                          0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
++                          0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 },
++      }, {
++              .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
++              .psize  = 56,
++              .digest = { 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39,
++                          0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39,
++                          0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab,
++                          0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6,
++                          0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f,
++                          0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b},
++      }, {
++              .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
++                           "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
++              .psize  = 112,
++              .digest = { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
++                          0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
++                          0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
++                          0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
++                          0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
++                          0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39  },
++      }, {
++              .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
++                           "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
++              .psize  = 104,
++              .digest = { 0x3d, 0x20, 0x89, 0x73, 0xab, 0x35, 0x08, 0xdb,
++                          0xbd, 0x7e, 0x2c, 0x28, 0x62, 0xba, 0x29, 0x0a,
++                          0xd3, 0x01, 0x0e, 0x49, 0x78, 0xc1, 0x98, 0xdc,
++                          0x4d, 0x8f, 0xd0, 0x14, 0xe5, 0x82, 0x82, 0x3a,
++                          0x89, 0xe1, 0x6f, 0x9b, 0x2a, 0x7b, 0xbc, 0x1a,
++                          0xc9, 0x38, 0xe2, 0xd1, 0x99, 0xe8, 0xbe, 0xa4 },
++              .np     = 4,
++              .tap    = { 26, 26, 26, 26 }
+       },
+ };
+@@ -646,439 +247,616 @@ struct sha384_testvec {
+  */
+ #define SHA512_TEST_VECTORS   4
+-struct sha512_testvec {
+-      char plaintext[128];
+-      char digest[SHA512_DIGEST_SIZE];
+-} sha512_tv_template[] = {
+-
+-      { "abc",
+-        { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
+-          0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
+-          0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+-          0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
+-          0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
+-          0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+-          0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
+-          0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
+-      },
+-      
+-      { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+-        { 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a,
+-          0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16,
+-          0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8,
+-          0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35,
+-          0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9,
+-          0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0,
+-          0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03,
+-          0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45 }
+-      },
+-      
+-      { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+-        "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+-        { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
+-          0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
+-          0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
+-          0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
+-          0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
+-          0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
+-          0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
+-          0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
+-      },
+-      
+-      { "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+-        "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+-        { 0x93, 0x0d, 0x0c, 0xef, 0xcb, 0x30, 0xff, 0x11,
+-          0x33, 0xb6, 0x89, 0x81, 0x21, 0xf1, 0xcf, 0x3d,
+-          0x27, 0x57, 0x8a, 0xfc, 0xaf, 0xe8, 0x67, 0x7c,
+-          0x52, 0x57, 0xcf, 0x06, 0x99, 0x11, 0xf7, 0x5d,
+-          0x8f, 0x58, 0x31, 0xb5, 0x6e, 0xbf, 0xda, 0x67,
+-          0xb2, 0x78, 0xe6, 0x6d, 0xff, 0x8b, 0x84, 0xfe,
+-          0x2b, 0x28, 0x70, 0xf7, 0x42, 0xa5, 0x80, 0xd8,
+-          0xed, 0xb4, 0x19, 0x87, 0x23, 0x28, 0x50, 0xc9
+-        }
++struct hash_testvec sha512_tv_template[] = {
++      { 
++              .plaintext = "abc",
++              .psize  = 3,
++              .digest = { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
++                          0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
++                          0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
++                          0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
++                          0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
++                          0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
++                          0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
++                          0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f },
++      }, {
++              .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
++              .psize  = 56,
++              .digest = { 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a,
++                          0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16,
++                          0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8,
++                          0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35,
++                          0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9,
++                          0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0,
++                          0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03,
++                          0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45 },
++      }, {
++              .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
++                           "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
++              .psize  = 112,
++              .digest = { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
++                          0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
++                          0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
++                          0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
++                          0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
++                          0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
++                          0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
++                          0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 },
++      }, {
++              .plaintext = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
++                           "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
++              .psize  = 104,
++              .digest = { 0x93, 0x0d, 0x0c, 0xef, 0xcb, 0x30, 0xff, 0x11,
++                          0x33, 0xb6, 0x89, 0x81, 0x21, 0xf1, 0xcf, 0x3d,
++                          0x27, 0x57, 0x8a, 0xfc, 0xaf, 0xe8, 0x67, 0x7c,
++                          0x52, 0x57, 0xcf, 0x06, 0x99, 0x11, 0xf7, 0x5d,
++                          0x8f, 0x58, 0x31, 0xb5, 0x6e, 0xbf, 0xda, 0x67,
++                          0xb2, 0x78, 0xe6, 0x6d, 0xff, 0x8b, 0x84, 0xfe,
++                          0x2b, 0x28, 0x70, 0xf7, 0x42, 0xa5, 0x80, 0xd8,
++                          0xed, 0xb4, 0x19, 0x87, 0x23, 0x28, 0x50, 0xc9 },
++              .np     = 4,
++              .tap    = { 26, 26, 26, 26 }
+       },
+ };
++#ifdef CONFIG_CRYPTO_HMAC
+ /*
+- * DES test vectors.
++ * HMAC-MD5 test vectors from RFC2202
++ * (These need to be fixed to not use strlen).
+  */
+-#define DES_ENC_TEST_VECTORS          5
+-#define DES_DEC_TEST_VECTORS          2
+-#define DES_CBC_ENC_TEST_VECTORS      4
+-#define DES_CBC_DEC_TEST_VECTORS      3
+-#define DES3_EDE_ENC_TEST_VECTORS     3
+-#define DES3_EDE_DEC_TEST_VECTORS     3
+-
+-struct des_tv {
+-      unsigned int len;
+-      int fail;
+-      char key[24];
+-      char iv[8];
+-      char plaintext[128];
+-      char result[128];
+-};
+-
+-struct des_tv des_enc_tv_template[] = {
+-
+-      /* From Applied Cryptography */
+-      {
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0 },
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 },
+-              { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d }
+-      },
+-      
+-      /* Same key, different plaintext block */
+-      {
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0 },
+-              { 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
+-              { 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }
+-      },
+-      
+-      /* Sbox test from NBS */
+-      {
+-              8, 0,
+-              
+-              { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 },
+-              { 0 },
+-              { 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42 },
+-              { 0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B }
+-      },
+-      
+-      /* Three blocks */
+-      {
+-              24, 0,
+-              
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              
+-              { 0 },
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
+-                0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
+-                0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef },
+-
+-              { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
+-                0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b,
+-                0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90 },               
+-      },
+-      
+-      /* Weak key */
+-      {
+-              8, 1,
+-              
+-              { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
+-              { 0 },
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 },
+-              { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d }
+-      },
+-      
+-      /* Two blocks -- for testing encryption across pages */
+-      {
+-              16, 0,
+-              
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              
+-              { 0 },
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
+-                0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
+-
+-              { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
+-                0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b }
+-      },
++#define HMAC_MD5_TEST_VECTORS 7
+-      /* Two blocks -- for testing decryption across pages */
+-      {
+-              16, 0,
+-              
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              
+-              { 0 },
+-              
+-              { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
+-                0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b },
+-                
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
+-                0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
+-      },
+-      
+-      /* Four blocks -- for testing encryption with chunking */
++struct hmac_testvec hmac_md5_tv_template[] =
++{     
+       {
+-              24, 0,
+-              
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              
+-              { 0 },
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
+-                0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
+-                0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef,
+-                0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
+-
+-              { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
+-                0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b,
+-                0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90,
+-                0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b },
++              .key    = { [0 ... 15] =  0x0b },
++              .ksize  = 16,
++              .plaintext = "Hi There",
++              .psize  = 8,
++              .digest = { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
++                          0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d },
++      }, {
++              .key    = { 'J', 'e', 'f', 'e' },
++              .ksize  = 4,
++              .plaintext = "what do ya want for nothing?",
++              .psize  = 28,
++              .digest = { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
++                          0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 },
++              .np     = 2,
++              .tap    = {14, 14}
++      }, {
++              .key    = { [0 ... 15] = 0xaa },
++              .ksize  = 16,
++              .plaintext = { [0 ... 49] =  0xdd },
++              .psize  = 50,
++              .digest = { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
++                          0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 },
++      }, {
++              .key    = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++                          0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
++                          0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, },
++              .ksize  = 25,
++              .plaintext = { [0 ... 49] =  0xcd },
++              .psize  = 50,
++              .digest = { 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
++                          0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 },
++      }, {
++              .key    = { [0 ... 15] = 0x0c },
++              .ksize  = 16,
++              .plaintext = "Test With Truncation",
++              .psize  = 20,
++              .digest = { 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00,
++                          0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c },
++      }, {
++              .key    = { [0 ... 79] =  0xaa },
++              .ksize  = 80,
++              .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
++              .psize  = 54,
++              .digest = { 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
++                          0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd },
++      }, {
++              .key    = { [0 ... 79] =  0xaa },
++              .ksize  = 80,
++              .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
++                           "Block-Size Data",
++              .psize  = 73,
++              .digest = { 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
++                          0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e },
+       },
+-      
+ };
+-struct des_tv des_dec_tv_template[] = {
+-
+-      /* From Applied Cryptography */
+-      {
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0 },
+-              { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d },
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 },
+-      },
+-      
+-      /* Sbox test from NBS */
+-      {
+-              8, 0,
++/*
++ * HMAC-SHA1 test vectors from RFC2202
++ */
++#define HMAC_SHA1_TEST_VECTORS        7
+-              { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 },
+-              { 0 },
+-              { 0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B },
+-              { 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42 }
+-      },
+-      
+-      /* Two blocks, for chunking test */
++struct hmac_testvec hmac_sha1_tv_template[] = {       
+       {
+-              16, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0 },
+-              
+-              { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
+-                0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B },
+-                
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
+-                0xa3, 0x99, 0x7b, 0xca, 0xaf, 0x69, 0xa0, 0xf5 }
++              .key    = { [0 ... 19] = 0x0b },
++              .ksize  = 20,
++              .plaintext = "Hi There",
++              .psize  = 8,
++              .digest = { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
++                          0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 0xf1,
++                          0x46, 0xbe },
++      }, {
++              .key    = { 'J', 'e', 'f', 'e' },               
++              .ksize  = 4,
++              .plaintext = "what do ya want for nothing?",
++              .psize  = 28,
++              .digest = { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, 
++                          0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 },
++              .np     = 2,
++              .tap    = { 14, 14 }
++      }, {
++              .key    = { [0 ... 19] = 0xaa },
++              .ksize  = 20,
++              .plaintext = { [0 ... 49] = 0xdd },
++              .psize  = 50,
++              .digest = { 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x91, 0xa3, 
++                          0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, 0x63, 0xf1, 0x75, 0xd3 },
++      }, {
++              .key    = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++                          0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 
++                          0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 },
++              .ksize  = 25,
++              .plaintext = { [0 ... 49] = 0xcd },
++              .psize  = 50,
++              .digest = { 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0xbc, 0x84, 
++                          0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, 0x2d, 0x72, 0x35, 0xda },
++      }, {
++              .key    = { [0 ... 19] = 0x0c },
++              .ksize  = 20,
++              .plaintext = "Test With Truncation",
++              .psize  = 20,
++              .digest = { 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, 
++                          0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04 },
++      }, {
++              .key    = { [0 ... 79] = 0xaa },
++              .ksize  = 80,
++              .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
++              .psize  = 54,
++              .digest = { 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70, 
++                          0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0xed, 0x40, 0x21, 0x12 },
++      }, {
++              .key    = { [0 ... 79] = 0xaa },
++              .ksize  = 80,
++              .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
++                           "Block-Size Data",
++              .psize  = 73,
++              .digest = { 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b, 
++                          0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91 },
+       },
+-
+ };
+-struct des_tv des_cbc_enc_tv_template[] = {
+-      /* From OpenSSL */
+-      {
+-              24, 0,
+-              
+-              {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+-              {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+-              
+-              { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, 
+-                0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 
+-                0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 
+-                0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00 },
+-                
+-              { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, 
+-                0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, 
+-                0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68, 
+-                0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4 }
+-      },
++/*
++ * HMAC-SHA256 test vectors from
++ * draft-ietf-ipsec-ciph-sha-256-01.txt
++ */
++#define HMAC_SHA256_TEST_VECTORS      10
+-      /* FIPS Pub 81 */
+-      {
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef },
+-              { 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 },
+-              { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
+-              
+-      },
+-      
++struct hmac_testvec hmac_sha256_tv_template[] = {
+       {
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
+-              { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 },
+-              { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
+-      },
+-      
+-      {       
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
+-              { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 },
+-              { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 },
+-      },
+-      
+-      /* Copy of openssl vector for chunk testing */
+-      
+-      /* From OpenSSL */
+-      {
+-              24, 0,
+-              
+-              {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+-              {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+-              
+-              { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, 
+-                0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 
+-                0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, 
+-                0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00 },
+-                
+-              { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, 
+-                0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, 
+-                0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68, 
+-                0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4 }
++              .key    = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++                          0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
++                          0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
++                          0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20},
++              .ksize  = 32,
++              .plaintext = "abc",
++              .psize  = 3,
++              .digest = { 0xa2, 0x1b, 0x1f, 0x5d, 0x4c, 0xf4, 0xf7, 0x3a,
++                          0x4d, 0xd9, 0x39, 0x75, 0x0f, 0x7a, 0x06, 0x6a,
++                          0x7f, 0x98, 0xcc, 0x13, 0x1c, 0xb1, 0x6a, 0x66,
++                          0x92, 0x75, 0x90, 0x21, 0xcf, 0xab, 0x81, 0x81 },
++      }, {
++              .key    = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++                          0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
++                          0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
++                          0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 },
++              .ksize  = 32,
++              .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
++              .psize  = 56,
++              .digest = { 0x10, 0x4f, 0xdc, 0x12, 0x57, 0x32, 0x8f, 0x08,
++                          0x18, 0x4b, 0xa7, 0x31, 0x31, 0xc5, 0x3c, 0xae,
++                          0xe6, 0x98, 0xe3, 0x61, 0x19, 0x42, 0x11, 0x49,
++                          0xea, 0x8c, 0x71, 0x24, 0x56, 0x69, 0x7d, 0x30 },
++      }, {
++              .key    = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++                          0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
++                          0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
++                          0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 },
++              .ksize  = 32,
++              .plaintext = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
++                           "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
++              .psize  = 112,
++              .digest = { 0x47, 0x03, 0x05, 0xfc, 0x7e, 0x40, 0xfe, 0x34,
++                          0xd3, 0xee, 0xb3, 0xe7, 0x73, 0xd9, 0x5a, 0xab,
++                          0x73, 0xac, 0xf0, 0xfd, 0x06, 0x04, 0x47, 0xa5,
++                          0xeb, 0x45, 0x95, 0xbf, 0x33, 0xa9, 0xd1, 0xa3 },
++      }, {
++              .key    = { [0 ... 31] = 0x0b },
++              .ksize  = 32,
++              .plaintext = "Hi There",
++              .psize  = 8,
++              .digest = { 0x19, 0x8a, 0x60, 0x7e, 0xb4, 0x4b, 0xfb, 0xc6,
++                          0x99, 0x03, 0xa0, 0xf1, 0xcf, 0x2b, 0xbd, 0xc5,
++                          0xba, 0x0a, 0xa3, 0xf3, 0xd9, 0xae, 0x3c, 0x1c,
++                          0x7a, 0x3b, 0x16, 0x96, 0xa0, 0xb6, 0x8c, 0xf7 },
++      }, {
++              .key    = "Jefe",
++              .ksize  = 4,
++              .plaintext = "what do ya want for nothing?",
++              .psize  = 28,
++              .digest = { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
++                          0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
++                          0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
++                          0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 },
++              .np     = 2,
++              .tap    = { 14, 14 }
++      }, {
++              .key    = { [0 ... 31] = 0xaa },
++              .ksize  = 32,
++              .plaintext = { [0 ... 49] = 0xdd },
++              .psize  = 50,
++              .digest = { 0xcd, 0xcb, 0x12, 0x20, 0xd1, 0xec, 0xcc, 0xea,
++                          0x91, 0xe5, 0x3a, 0xba, 0x30, 0x92, 0xf9, 0x62,
++                          0xe5, 0x49, 0xfe, 0x6c, 0xe9, 0xed, 0x7f, 0xdc,
++                          0x43, 0x19, 0x1f, 0xbd, 0xe4, 0x5c, 0x30, 0xb0 },
++      }, {
++              .key    = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
++                          0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
++                          0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
++                          0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
++                          0x21, 0x22, 0x23, 0x24, 0x25 },
++              .ksize  = 37,
++              .plaintext = { [0 ... 49] = 0xcd },
++              .psize  = 50,
++              .digest = { 0xd4, 0x63, 0x3c, 0x17, 0xf6, 0xfb, 0x8d, 0x74,
++                          0x4c, 0x66, 0xde, 0xe0, 0xf8, 0xf0, 0x74, 0x55,
++                          0x6e, 0xc4, 0xaf, 0x55, 0xef, 0x07, 0x99, 0x85,
++                          0x41, 0x46, 0x8e, 0xb4, 0x9b, 0xd2, 0xe9, 0x17 },
++      }, {
++              .key    = { [0 ... 31] = 0x0c },
++              .ksize  = 32,
++              .plaintext = "Test With Truncation",
++              .psize  = 20,
++              .digest = { 0x75, 0x46, 0xaf, 0x01, 0x84, 0x1f, 0xc0, 0x9b,
++                          0x1a, 0xb9, 0xc3, 0x74, 0x9a, 0x5f, 0x1c, 0x17,
++                          0xd4, 0xf5, 0x89, 0x66, 0x8a, 0x58, 0x7b, 0x27,
++                          0x00, 0xa9, 0xc9, 0x7c, 0x11, 0x93, 0xcf, 0x42 },
++      }, {
++              .key    = { [0 ... 79] = 0xaa },
++              .ksize  = 80,
++              .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
++              .psize  = 54,
++              .digest = { 0x69, 0x53, 0x02, 0x5e, 0xd9, 0x6f, 0x0c, 0x09,
++                          0xf8, 0x0a, 0x96, 0xf7, 0x8e, 0x65, 0x38, 0xdb,
++                          0xe2, 0xe7, 0xb8, 0x20, 0xe3, 0xdd, 0x97, 0x0e,
++                          0x7d, 0xdd, 0x39, 0x09, 0x1b, 0x32, 0x35, 0x2f },
++      }, {
++              .key    = { [0 ... 79] = 0xaa },
++              .ksize  = 80,
++              .plaintext = "Test Using Larger Than Block-Size Key and Larger Than "
++                           "One Block-Size Data",
++              .psize  = 73,
++              .digest = { 0x63, 0x55, 0xac, 0x22, 0xe8, 0x90, 0xd0, 0xa3,
++                          0xc8, 0x48, 0x1a, 0x5c, 0xa4, 0x82, 0x5b, 0xc8,
++                          0x84, 0xd3, 0xe7, 0xa1, 0xff, 0x98, 0xa2, 0xfc,
++                          0x2a, 0xc7, 0xd8, 0xe0, 0x64, 0xc3, 0xb2, 0xe6 },
+       },
+-
+-      
+ };
+-struct des_tv des_cbc_dec_tv_template[] = {
++#endif        /* CONFIG_CRYPTO_HMAC */
+-      /* FIPS Pub 81 */
+-      {
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef },
+-              { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
+-              { 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 },
+-      },
+-      
+-      {
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
+-              { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
+-              { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, 
+-      },
+-      
+-      {
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
+-              { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, 
+-              { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 },
+-      },
+-      
+-      /* Copy of above, for chunk testing */
+-      
+-      {
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
+-              { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, 
+-              { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 },
++/*
++ * DES test vectors.
++ */
++#define DES_ENC_TEST_VECTORS          10
++#define DES_DEC_TEST_VECTORS          4
++#define DES_CBC_ENC_TEST_VECTORS      5
++#define DES_CBC_DEC_TEST_VECTORS      4
++#define DES3_EDE_ENC_TEST_VECTORS     3
++#define DES3_EDE_DEC_TEST_VECTORS     3
++
++struct cipher_testvec des_enc_tv_template[] = {
++      { /* From Applied Cryptography */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 },
++              .ilen   = 8,
++              .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d },
++              .rlen   = 8,
++      }, { /* Same key, different plaintext block */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .input  = { 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
++              .ilen   = 8,
++              .result = { 0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b },
++              .rlen   = 8,
++      }, { /* Sbox test from NBS */
++              .key    = { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 },
++              .klen   = 8,
++              .input  = { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 },
++              .ilen   = 8,
++              .result = { 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b },
++              .rlen   = 8,
++      }, { /* Three blocks */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
++                          0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
++                          0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef },
++              .ilen   = 24,
++              .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
++                          0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b,
++                          0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90 },
++              .rlen   = 24,
++      }, { /* Weak key */
++              .fail   = 1,
++              .wk     = 1,
++              .key    = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
++              .klen   = 8,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 },
++              .ilen   = 8,
++              .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d },
++              .rlen   = 8,
++      }, { /* Two blocks -- for testing encryption across pages */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
++                          0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
++              .ilen   = 16,
++              .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
++                          0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b },
++              .rlen   = 16,
++              .np     = 2,
++              .tap    = { 8, 8 }
++      }, { /* Four blocks -- for testing encryption with chunking */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
++                          0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
++                          0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef,
++                          0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
++              .ilen   = 32,
++              .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
++                          0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b,
++                          0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90,
++                          0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b },
++              .rlen   = 32,
++              .np     = 3,
++              .tap    = { 14, 10, 8 } 
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
++                          0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
++                          0xca, 0xfe, 0xba, 0xbe, 0xfe, 0xed, 0xbe, 0xef },
++              .ilen   = 24,
++              .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
++                          0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b,
++                          0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90 },
++              .rlen   = 24,
++              .np     = 4,
++              .tap    = { 2, 1, 3, 18 } 
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
++                          0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 },
++              .ilen   = 16,
++              .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
++                          0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b },
++              .rlen   = 16,
++              .np     = 5,
++              .tap    = { 2, 2, 2, 2, 8 } 
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 },
++              .ilen   = 8,
++              .result = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d },
++              .rlen   = 8,
++              .np     = 8,
++              .tap    = { 1, 1, 1, 1, 1, 1, 1, 1 } 
++      },
++};
++
++struct cipher_testvec des_dec_tv_template[] = {
++      { /* From Applied Cryptography */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .input  = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d },
++              .ilen   = 8,
++              .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 },
++              .rlen   = 8,
++      }, { /* Sbox test from NBS */
++              .key    = { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 },           
++              .klen   = 8,
++              .input  = { 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b },
++              .ilen   = 8,
++              .result = { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 },
++              .rlen   = 8,
++      }, { /* Two blocks, for chunking test */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .input  = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
++                          0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b },
++              .ilen   = 16,
++              .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
++                          0xa3, 0x99, 0x7b, 0xca, 0xaf, 0x69, 0xa0, 0xf5 },
++              .rlen   = 16,
++              .np     = 2,
++              .tap    = { 8, 8 }
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .input  = { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d,
++                          0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b },
++              .ilen   = 16,
++              .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7,
++                          0xa3, 0x99, 0x7b, 0xca, 0xaf, 0x69, 0xa0, 0xf5 },
++              .rlen   = 16,
++              .np     = 3,
++              .tap    = { 3, 12, 1 }
++      },
++};
++
++struct cipher_testvec des_cbc_enc_tv_template[] = {
++      { /* From OpenSSL */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
++              .klen   = 8,
++              .iv     = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},            
++              .input  = { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, 
++                          0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 
++                          0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, 
++              .ilen   = 24,
++              .result = { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, 
++                          0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, 
++                          0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68 }, 
++              .rlen   = 24,
++      }, { /* FIPS Pub 81 */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .iv     = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef },           
++              .input  = { 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 },
++              .ilen   = 8,
++              .result = { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .iv     = { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
++              .input  = { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 },
++              .ilen   = 8,
++              .result = { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
++              .rlen   = 8,
++      }, {    
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .iv     = { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
++              .input  = { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 },
++              .ilen   = 8,
++              .result = { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 },
++              .rlen   = 8,
++      }, { /* Copy of openssl vector for chunk testing */     
++           /* From OpenSSL */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
++              .klen   = 8,
++              .iv     = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},            
++              .input  = { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, 
++                          0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 
++                          0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, 
++              .ilen   = 24,
++              .result = { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, 
++                          0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, 
++                          0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68 }, 
++              .rlen   = 24,
++              .np     = 2,
++              .tap    = { 13, 11 }
++      },
++};
++
++struct cipher_testvec des_cbc_dec_tv_template[] = {
++      { /* FIPS Pub 81 */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .iv     = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef },
++              .input  = { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
++              .ilen   = 8,
++              .result = { 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .iv     = { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },           
++              .input  = { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
++              .ilen   = 8,
++              .result = { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, 
++              .rlen   = 8,
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .iv     = { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
++              .input  = { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, 
++              .ilen   = 8,
++              .result = { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 },
++              .rlen   = 8,
++      }, { /* Copy of above, for chunk testing */     
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .klen   = 8,
++              .iv     = { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
++              .input  = { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, 
++              .ilen   = 8,
++              .result = { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 },
++              .rlen   = 8,
++              .np     = 2,
++              .tap    = { 4, 4 }
+       },
+ };
+ /*
+  * We really need some more test vectors, especially for DES3 CBC.
+  */
+-struct des_tv des3_ede_enc_tv_template[] = {
+-
+-      /* These are from openssl */
+-      {
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+-                0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+-                0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
+-                
+-              { 0 },
+-              
+-              { 0x73, 0x6F, 0x6D, 0x65, 0x64, 0x61, 0x74, 0x61  },
+-              
+-              { 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 },
+-      },
+-      
+-      {
+-              8, 0,
+-              
+-              { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17,
+-                0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98,
+-                0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57  },
+-               
+-              { 0 },
+-              
+-              { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65  },
+-              
+-              { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30  }
+-      },
+-      
+-
+-      {
+-              8, 0,
+-              
+-              { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20,
+-                0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01,
+-                0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01  },
+-                
+-              { 0 },
+-                        
+-              { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  },
+-              
+-              { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b  }    
++struct cipher_testvec des3_ede_enc_tv_template[] = {
++      { /* These are from openssl */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
++                          0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
++                          0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
++              .klen   = 24,
++              .input  = { 0x73, 0x6f, 0x6d, 0x65, 0x64, 0x61, 0x74, 0x61 },
++              .ilen   = 8,
++              .result = { 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x03, 0x52, 0x02, 0x07, 0x67, 0x20, 0x82, 0x17,
++                          0x86, 0x02, 0x87, 0x66, 0x59, 0x08, 0x21, 0x98,
++                          0x64, 0x05, 0x6a, 0xbd, 0xfe, 0xa9, 0x34, 0x57 },
++              .klen   = 24,
++              .input  = { 0x73, 0x71, 0x75, 0x69, 0x67, 0x67, 0x6c, 0x65 },
++              .ilen   = 8,
++              .result = { 0xc0, 0x7d, 0x2a, 0x0f, 0xa5, 0x66, 0xfa, 0x30 },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
++                          0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01,
++                          0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01 },
++              .klen   = 24,
++              .input  = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
++              .ilen   = 8,
++              .result = { 0xe1, 0xef, 0x62, 0xc3, 0x32, 0xfe, 0x82, 0x5b },
++              .rlen   = 8,
+       },
+ };
+-struct des_tv des3_ede_dec_tv_template[] = {
+-
+-      /* These are from openssl */
+-      {
+-              8, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+-                0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+-                0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
+-                
+-              { 0 },
+-              
+-              
+-              { 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 },
+-              
+-              { 0x73, 0x6F, 0x6D, 0x65, 0x64, 0x61, 0x74, 0x61  },
+-      },
+-      
+-      {
+-              8, 0,
+-              
+-              { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17,
+-                0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98,
+-                0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57  },
+-               
+-              { 0 },
+-              
+-              { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30  },
+-              
+-              { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65  },
+-              
+-      },
+-      
+-
+-      {
+-              8, 0,
+-              
+-              { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20,
+-                0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01,
+-                0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01  },
+-                
+-              { 0 },
+-                        
+-              { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b  },
+-              
+-              { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  },
++struct cipher_testvec des3_ede_dec_tv_template[] = {
++      { /* These are from openssl */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
++                          0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
++                          0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
++              .klen   = 24,
++              .input  = { 0x18, 0xd7, 0x48, 0xe5, 0x63, 0x62, 0x05, 0x72 },
++              .ilen   = 8,
++              .result = { 0x73, 0x6f, 0x6d, 0x65, 0x64, 0x61, 0x74, 0x61 },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x03, 0x52, 0x02, 0x07, 0x67, 0x20, 0x82, 0x17,
++                          0x86, 0x02, 0x87, 0x66, 0x59, 0x08, 0x21, 0x98,
++                          0x64, 0x05, 0x6a, 0xbd, 0xfe, 0xa9, 0x34, 0x57 },
++              .klen   = 24,
++              .input  = { 0xc0, 0x7d, 0x2a, 0x0f, 0xa5, 0x66, 0xfa, 0x30 },
++              .ilen   = 8,
++              .result = { 0x73, 0x71, 0x75, 0x69, 0x67, 0x67, 0x6c, 0x65 },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
++                          0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01,
++                          0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01 },
++              .klen   = 24,
++              .input  = { 0xe1, 0xef, 0x62, 0xc3, 0x32, 0xfe, 0x82, 0x5b },
++              .ilen   = 8,
++              .result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
++              .rlen   = 8,
+       },
+ };
+@@ -1090,189 +868,151 @@ struct des_tv des3_ede_dec_tv_template[]
+ #define BF_CBC_ENC_TEST_VECTORS       1
+ #define BF_CBC_DEC_TEST_VECTORS       1
+-struct bf_tv {
+-      unsigned int keylen;
+-      unsigned int plen;
+-      unsigned int rlen;
+-      int fail;
+-      char key[56];
+-      char iv[8];
+-      char plaintext[32];
+-      char result[32];
+-};
+-
+-struct bf_tv bf_enc_tv_template[] = {
+-
+-      /* DES test vectors from OpenSSL */
+-      {
+-              8, 8, 8, 0,
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
+-              { 0 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78 },
+-      },
+-      
+-      {
+-              8, 8, 8, 0,
+-              { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E,  },
+-              { 0 },
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
+-              { 0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE },
+-      },
+-      
+-      {
+-              8, 8, 8, 0,
+-              { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, },
+-              { 0 },
+-              { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+-              { 0xE8, 0x7A, 0x24, 0x4E, 0x2C, 0xC8, 0x5E, 0x82 }
+-      },
+-      
+-      /* Vary the keylength... */
+-      
+-      {
+-              16, 8, 8, 0,
+-              { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+-                0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F },
+-              { 0 },
+-              { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+-              { 0x93, 0x14, 0x28, 0x87, 0xEE, 0x3B, 0xE1, 0x5C }
+-      },
+-      
+-      {
+-              21, 8, 8, 0,
+-              { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+-                0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F,
+-                0x00, 0x11, 0x22, 0x33, 0x44 },
+-              { 0 },
+-              { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+-              { 0xE6, 0xF5, 0x1E, 0xD7, 0x9B, 0x9D, 0xB2, 0x1F }
+-      },
+-      
+-      /* Generated with bf488 */
+-      {
+-              56, 8, 8, 0,
+-              { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+-                0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F,
+-                0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+-                0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F, 
+-                0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76, 
+-                0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, 
+-                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+-                { 0 },
+-                { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+-                { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 }
+-      }
+-      
+-};
+-
+-struct bf_tv bf_dec_tv_template[] = {
+-
+-      /* DES test vectors from OpenSSL */
+-      {
+-              8, 8, 8, 0,
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
+-              { 0 },
+-              { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+-      },
+-      
+-      {
+-              8, 8, 8, 0,
+-              { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E,  },
+-              { 0 },
+-              { 0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE },
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }
+-      },
+-      
+-      {
+-              8, 8, 8, 0,
+-              { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, },
+-              { 0 },
+-              { 0xE8, 0x7A, 0x24, 0x4E, 0x2C, 0xC8, 0x5E, 0x82 },
+-              { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }
+-      },
+-      
+-      /* Vary the keylength... */
+-      
+-      {
+-              16, 8, 8, 0,
+-              { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+-                0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F },
+-              { 0 },
+-              { 0x93, 0x14, 0x28, 0x87, 0xEE, 0x3B, 0xE1, 0x5C },
+-              { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }
+-      },
+-      
+-      {
+-              21, 8, 8, 0,
+-              { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+-                0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F,
+-                0x00, 0x11, 0x22, 0x33, 0x44 },
+-              { 0 },
+-              { 0xE6, 0xF5, 0x1E, 0xD7, 0x9B, 0x9D, 0xB2, 0x1F },
+-              { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }
+-      },
+-      
+-      /* Generated with bf488, using OpenSSL, Libgcrypt and Nettle */
+-      {
+-              56, 8, 8, 0,
+-              { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
+-                0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F,
+-                0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+-                0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F, 
+-                0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76, 
+-                0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E, 
+-                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+-              { 0 },
+-              { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 },
+-              { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }
+-      }
+-};
+-
+-struct bf_tv bf_cbc_enc_tv_template[] = {
+-
+-      /* From OpenSSL */
+-      {
+-              16, 32, 32, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+-                0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 },
+-                
+-              { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+-              
+-              { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
+-                0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
+-                0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20,
+-                0x66, 0x6F, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 },
+-                
+-              { 0x6B, 0x77, 0xB4, 0xD6, 0x30, 0x06, 0xDE, 0xE6,
+-                0x05, 0xB1, 0x56, 0xE2, 0x74, 0x03, 0x97, 0x93,
+-                0x58, 0xDE, 0xB9, 0xE7, 0x15, 0x46, 0x16, 0xD9,
+-                0x59, 0xF1, 0x65, 0x2B, 0xD5, 0xFF, 0x92, 0xCC }
+-      },
+-};
+-
+-struct bf_tv bf_cbc_dec_tv_template[] = {
+-
+-      /* From OpenSSL */
+-      {
+-              16, 32, 32, 0,
+-              
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+-                0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 },
+-                
+-              { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 },
+-              
+-              { 0x6B, 0x77, 0xB4, 0xD6, 0x30, 0x06, 0xDE, 0xE6,
+-                0x05, 0xB1, 0x56, 0xE2, 0x74, 0x03, 0x97, 0x93,
+-                0x58, 0xDE, 0xB9, 0xE7, 0x15, 0x46, 0x16, 0xD9,
+-                0x59, 0xF1, 0x65, 0x2B, 0xD5, 0xFF, 0x92, 0xCC },
+-                
+-              { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
+-                0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
+-                0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20,
+-                0x66, 0x6F, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 }
++struct cipher_testvec bf_enc_tv_template[] = {
++      { /* DES test vectors from OpenSSL */
++              .key    = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
++              .klen   = 8,
++              .input  = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
++              .ilen   = 8,
++              .result = { 0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78 },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e },
++              .klen   = 8,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .ilen   = 8,
++              .result = { 0xa7, 0x90, 0x79, 0x51, 0x08, 0xea, 0x3c, 0xae },
++              .rlen   = 8,
++      }, {
++              .key    = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
++              .klen   = 8,
++              .input  = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
++              .ilen   = 8,
++              .result = { 0xe8, 0x7a, 0x24, 0x4e, 0x2c, 0xc8, 0x5e, 0x82 },
++              .rlen   = 8,
++      }, { /* Vary the keylength... */        
++              .key    = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
++                          0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f },
++              .klen   = 16,
++              .input  = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
++              .ilen   = 8,
++              .result = { 0x93, 0x14, 0x28, 0x87, 0xee, 0x3b, 0xe1, 0x5c },
++              .rlen   = 8,
++      }, {
++              .key    = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
++                          0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
++                          0x00, 0x11, 0x22, 0x33, 0x44 },
++              .klen   = 21,
++              .input  = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
++              .ilen   = 8,
++              .result = { 0xe6, 0xf5, 0x1e, 0xd7, 0x9b, 0x9d, 0xb2, 0x1f },
++              .rlen   = 8,
++      }, { /* Generated with bf488 */
++              .key    = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
++                          0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
++                          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
++                          0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f, 
++                          0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76, 
++                          0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 
++                          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
++              .klen   = 56,
++              .input  = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
++              .ilen   = 8,
++              .result = { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 },
++              .rlen   = 8,
++      },
++};
++
++struct cipher_testvec bf_dec_tv_template[] = {
++      { /* DES test vectors from OpenSSL */
++              .key    = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
++              .klen   = 8,
++              .input  = { 0x4e, 0xf9, 0x97, 0x45, 0x61, 0x98, 0xdd, 0x78 },
++              .ilen   = 8,
++              .result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e },
++              .klen   = 8,
++              .input  = { 0xa7, 0x90, 0x79, 0x51, 0x08, 0xea, 0x3c, 0xae },
++              .ilen   = 8,
++              .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .rlen   = 8,
++      }, {
++              .key    = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
++              .klen   = 8,
++              .input  = { 0xe8, 0x7a, 0x24, 0x4e, 0x2c, 0xc8, 0x5e, 0x82 },
++              .ilen   = 8,
++              .result = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
++              .rlen   = 8,
++      }, { /* Vary the keylength... */        
++              .key    = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
++                          0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f },
++              .klen   = 16,
++              .input  = { 0x93, 0x14, 0x28, 0x87, 0xee, 0x3b, 0xe1, 0x5c },
++              .ilen   = 8,
++              .result = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
++              .rlen   = 8,
++      }, {
++              .key    = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
++                          0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
++                          0x00, 0x11, 0x22, 0x33, 0x44 },
++              .klen   = 21,
++              .input  = { 0xe6, 0xf5, 0x1e, 0xd7, 0x9b, 0x9d, 0xb2, 0x1f },
++              .ilen   = 8,
++              .result = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
++              .rlen   = 8,
++      }, { /* Generated with bf488, using OpenSSL, Libgcrypt and Nettle */
++              .key    = { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
++                          0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
++                          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
++                          0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f, 
++                          0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76, 
++                          0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 
++                          0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
++              .klen   = 56,
++              .input  = { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 },
++              .ilen   = 8,
++              .result = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
++              .rlen   = 8,
++      },
++};
++
++struct cipher_testvec bf_cbc_enc_tv_template[] = {
++      { /* From OpenSSL */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
++                          0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
++              .klen   = 16,
++              .iv     = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },           
++              .input  = { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
++                          0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
++                          0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
++                          0x66, 0x6f, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 },
++              .ilen   = 32,
++              .result = { 0x6b, 0x77, 0xb4, 0xd6, 0x30, 0x06, 0xde, 0xe6,
++                          0x05, 0xb1, 0x56, 0xe2, 0x74, 0x03, 0x97, 0x93,
++                          0x58, 0xde, 0xb9, 0xe7, 0x15, 0x46, 0x16, 0xd9,
++                          0x59, 0xf1, 0x65, 0x2b, 0xd5, 0xff, 0x92, 0xcc },
++              .rlen   = 32,
++      },
++};
++
++struct cipher_testvec bf_cbc_dec_tv_template[] = {
++      { /* From OpenSSL */
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
++                          0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
++              .klen   = 16,
++              .iv     = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },           
++              .input  = { 0x6b, 0x77, 0xb4, 0xd6, 0x30, 0x06, 0xde, 0xe6,
++                          0x05, 0xb1, 0x56, 0xe2, 0x74, 0x03, 0x97, 0x93,
++                          0x58, 0xde, 0xb9, 0xe7, 0x15, 0x46, 0x16, 0xd9,
++                          0x59, 0xf1, 0x65, 0x2b, 0xd5, 0xff, 0x92, 0xcc },
++              .ilen   = 32,
++              .result = { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
++                          0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
++                          0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
++                          0x66, 0x6f, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00 },
++              .rlen   = 32,
+       },
+ };
+@@ -1284,212 +1024,161 @@ struct bf_tv bf_cbc_dec_tv_template[] = 
+ #define TF_CBC_ENC_TEST_VECTORS               4
+ #define TF_CBC_DEC_TEST_VECTORS               4
+-struct tf_tv {
+-      unsigned int keylen;
+-      unsigned int plen;
+-      unsigned int rlen;
+-      int fail;
+-      char key[32];
+-      char iv[16];
+-      char plaintext[48];
+-      char result[48];
+-};
+-
+-struct tf_tv tf_enc_tv_template[] = {
+-      {
+-              16, 16, 16, 0,
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
+-                0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }
+-      },
+-      {
+-              24, 16, 16, 0,
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+-                0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+-                0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
+-              { 0 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF,
+-                0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48 }
+-      },
+-      {       
+-              32, 16, 16, 0,
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+-                0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+-                0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+-                0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
+-              { 0 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8,
+-                0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20 }
+-      },
+-};
+-
+-struct tf_tv tf_dec_tv_template[] = {
+-      {
+-              16, 16, 16, 0,
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0 },
+-              { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
+-                0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+-      },
+-      {
+-              24, 16, 16, 0,
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+-                0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+-                0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
+-              { 0 },
+-              { 0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF,
+-                0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-      },
+-      {       
+-              32, 16, 16, 0,
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+-                0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+-                0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+-                0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
+-              { 0 },
+-              { 0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8,
+-                0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-      },
+-};
+-
+-struct tf_tv tf_cbc_enc_tv_template[] = {
+-      /* Generated with Nettle */
+-      {
+-              16, 16, 16, 0,
+-              
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+-                0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
+-      },
+-      
+-      {
+-              16, 16, 16, 0,
+-              
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+-                0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+-                0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+-      },
+-      
+-      {
+-              16, 16, 16, 0,
+-              
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+-                0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+-                0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+-      },
+-      
+-      {
+-              16, 48, 48, 0,
+-              
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+-                0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a,
+-                0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+-                0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19,
+-                0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+-                0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+-      },
+-};
+-
+-struct tf_tv tf_cbc_dec_tv_template[] = {
+-      /* Reverse of the first four above */
+-      {
+-              16, 16, 16, 0,
+-              
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+-                0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },               
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-      },
+-      
+-      {
+-              16, 16, 16, 0,
+-              
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+-                0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
+-              { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+-                0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+-      },
+-      
+-      {
+-              16, 16, 16, 0,
+-              
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+-                0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
+-              { 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+-                0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+-      },
+-      
++struct cipher_testvec tf_enc_tv_template[] = {
+       {
+-              16, 48, 48, 0,
+-              
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
+-                0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a,
+-                0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
+-                0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19,
+-                0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
+-                0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
++              .key    = { [0 ... 15] = 0x00 },
++              .klen   = 16,
++              .input  = { [0 ... 15] = 0x00 },
++              .ilen   = 16,
++              .result = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
++                          0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
++                          0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
++                          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
++              .klen   = 24,
++              .input  = { [0 ... 15] = 0x00 },
++              .ilen   = 16,
++              .result = { 0xcf, 0xd1, 0xd2, 0xe5, 0xa9, 0xbe, 0x9c, 0xdf,
++                          0x50, 0x1f, 0x13, 0xb8, 0x92, 0xbd, 0x22, 0x48 },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
++                          0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
++                          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
++                          0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
++              .klen   = 32,
++              .input  = { [0 ... 15] = 0x00 },
++              .ilen   = 16,
++              .result = { 0x37, 0x52, 0x7b, 0xe0, 0x05, 0x23, 0x34, 0xb8,
++                          0x9f, 0x0c, 0xfc, 0xca, 0xe8, 0x7c, 0xfa, 0x20 },
++              .rlen   = 16,
++      },
++};
++
++struct cipher_testvec tf_dec_tv_template[] = {
++      {
++              .key    = { [0 ... 15] = 0x00 },
++              .klen   = 16,
++              .input  = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
++                          0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
++              .ilen   = 16,
++              .result = { [0 ... 15] = 0x00 },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
++                          0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
++                          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
++              .klen   = 24,
++              .input  = { 0xcf, 0xd1, 0xd2, 0xe5, 0xa9, 0xbe, 0x9c, 0xdf,
++                          0x50, 0x1f, 0x13, 0xb8, 0x92, 0xbd, 0x22, 0x48 },
++              .ilen   = 16,
++              .result = { [0 ... 15] = 0x00 },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
++                          0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
++                          0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
++                          0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
++              .klen   = 32,
++              .input  = { 0x37, 0x52, 0x7b, 0xe0, 0x05, 0x23, 0x34, 0xb8,
++                          0x9f, 0x0c, 0xfc, 0xca, 0xe8, 0x7c, 0xfa, 0x20 },
++              .ilen   = 16,
++              .result = { [0 ... 15] = 0x00 },
++              .rlen   = 16,
++      },
++};
++
++struct cipher_testvec tf_cbc_enc_tv_template[] = {
++      { /* Generated with Nettle */
++              .key    = { [0 ... 15] = 0x00 },
++              .klen   = 16,
++              .iv     = { [0 ... 15] = 0x00 },
++              .input  = { [0 ... 15] = 0x00 },
++              .ilen   = 16,
++              .result = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
++                          0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
++              .rlen   = 16,
++      }, {
++              .key    = { [0 ... 15] = 0x00 },
++              .klen   = 16,
++              .iv     = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
++                          0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },           
++              .input  = { [0 ... 15] = 0x00 },
++              .ilen   = 16,
++              .result = { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
++                          0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
++              .rlen   = 16,
++      }, {
++              .key    = { [0 ... 15] = 0x00 },
++              .klen   = 16,
++              .iv     = { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
++                          0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
++              .input  = { [0 ... 15] = 0x00 },
++              .ilen   = 16,
++              .result = { 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
++                          0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
++              .rlen   = 16,
++      }, {
++              .key    = { [0 ... 15] = 0x00 },
++              .klen   = 16,
++              .iv     = { [0 ... 15] = 0x00 },
++              .input  = { [0 ... 47] = 0x00 },
++              .ilen   = 48,
++              .result = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
++                          0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a,
++                          0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
++                          0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19,
++                          0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
++                          0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
++              .rlen   = 48,
++      },
++};
++
++struct cipher_testvec tf_cbc_dec_tv_template[] = {
++      { /* Reverse of the first four above */
++              .key    = { [0 ... 15] = 0x00 },
++              .klen   = 16,
++              .iv     = { [0 ... 15] = 0x00 },
++              .input  = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
++                          0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },             
++              .ilen   = 16,
++              .result = { [0 ... 15] = 0x00 },
++              .rlen   = 16,
++      }, {
++              .key    = { [0 ... 15] = 0x00 },
++              .klen   = 16,
++              .iv     = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
++                          0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
++              .input  = { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
++                          0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
++              .ilen   = 16,
++              .result = { [0 ... 15] = 0x00 },
++              .rlen   = 16,
++      }, {
++              .key    = { [0 ... 15] = 0x00 },
++              .klen   = 16,
++              .iv     = { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
++                          0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19 },
++              .input  = { 0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
++                          0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
++              .ilen   = 16,
++              .result = { [0 ... 15] = 0x00 },
++              .rlen   = 16,
++      }, {
++              .key    = { [0 ... 15] = 0x00 },
++              .klen   = 16,
++              .iv     = { [0 ... 15] = 0x00 },
++              .input  = { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
++                          0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a,
++                          0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
++                          0x86, 0xcb, 0x08, 0x6b, 0x78, 0x9f, 0x54, 0x19,
++                          0x05, 0xef, 0x8c, 0x61, 0xa8, 0x11, 0x58, 0x26,
++                          0x34, 0xba, 0x5c, 0xb7, 0x10, 0x6a, 0xa6, 0x41 },
++              .ilen   = 48,
++              .result = { [0 ... 47] = 0x00 },
++              .rlen   = 48,
+       },
+ };
+@@ -1500,179 +1189,162 @@ struct tf_tv tf_cbc_dec_tv_template[] = 
+ #define SERPENT_ENC_TEST_VECTORS      4
+ #define SERPENT_DEC_TEST_VECTORS      4
+-struct serpent_tv {
+-      unsigned int keylen, fail;
+-      u8 key[32], plaintext[16], result[16];
+-};
+-
+-struct serpent_tv serpent_enc_tv_template[] = 
++struct cipher_testvec serpent_enc_tv_template[] = 
+ {
+       {
+-              0, 0,
+-              { 0 },
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+-              { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
+-                0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 }
++              .input  = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
++              .ilen   = 16,
++              .result = { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
++                          0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
++              .klen   = 16,
++              .input  = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
++              .ilen   = 16,
++              .result = { 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c,
++                          0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
++                          0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
++                          0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
++              .klen   = 32,
++              .input  = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
++              .ilen   = 16,
++              .result = { 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8,
++                          0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c },
++              .rlen   = 16,
++      }, {
++              .key    = { [15] = 0x80 },
++              .klen   = 16,
++              .input  = { [0 ... 15] = 0x00 },
++              .ilen   = 16,
++              .result = { 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
++                          0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49},
++              .rlen   = 16,
+       },
+-      {
+-              16, 0,
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+-              { 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c,
+-                0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d }
+-      },
+-      {
+-              32, 0,
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+-                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+-                0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+-              { 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8,
+-                0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c }
+-      },
+-      {
+-              16, 0,
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
+-                0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49}
+-      }
+ };
+-struct serpent_tv serpent_dec_tv_template[] = 
++struct cipher_testvec serpent_dec_tv_template[] = 
+ {
+       {
+-              0, 0,
+-              { 0 },
+-              { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
+-                0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 },
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+-
+-      },
+-      {
+-              16, 0,
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+-              { 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c,
+-                0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d },
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+-      },
+-      {
+-              32, 0,
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+-                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+-                0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+-
+-              { 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8,
+-                0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c },
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
++              .input  = { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
++                          0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 },
++              .ilen   = 16,
++              .result = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
++              .klen   = 16,
++              .input  = { 0x4c, 0x7d, 0x8a, 0x32, 0x80, 0x72, 0xa2, 0x2c,
++                          0x82, 0x3e, 0x4a, 0x1f, 0x3a, 0xcd, 0xa1, 0x6d },
++              .ilen   = 16,
++              .result = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
++                          0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
++                          0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
++              .klen   = 32,
++              .input  = { 0xde, 0x26, 0x9f, 0xf8, 0x33, 0xe4, 0x32, 0xb8,
++                          0x5b, 0x2e, 0x88, 0xd2, 0x70, 0x1c, 0xe7, 0x5c },
++              .ilen   = 16,
++              .result = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
++              .rlen   = 16,
++      }, {
++              .key    = { [15] = 0x80 },
++              .klen   = 16,
++              .input  = { 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
++                          0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49},
++              .ilen   = 16,
++              .result = { [0 ... 15] = 0x00 },
++              .rlen   = 16,
+       },
+-      {
+-              16, 0,
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
+-              { 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
+-                0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49},
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  
+-      }
+ };
+ /* Cast6 test vectors from RFC 2612 */
+ #define CAST6_ENC_TEST_VECTORS        3
+ #define CAST6_DEC_TEST_VECTORS  3
+-struct cast6_tv {
+-      unsigned keylen;
+-      unsigned fail;
+-      u8 key[32];
+-      u8 plaintext[16];
+-      u8 result[16];
+-};
+-
+-struct cast6_tv cast6_enc_tv_template[] = 
++struct cipher_testvec cast6_enc_tv_template[] = 
+ {
+       {
+-              16, 
+-              0,
+-              { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
+-                0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20, 
+-                0x83, 0x6c, 0x91, 0xd1, 0xb7, 0x53, 0x0f, 0x6b },
++              .key    = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
++                          0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d },
++              .klen   = 16,
++              .input  = { [0 ... 15] = 0x00 },
++              .ilen   = 16,
++              .result = { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20, 
++                          0x83, 0x6c, 0x91, 0xd1, 0xb7, 0x53, 0x0f, 0x6b },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
++                          0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, 
++                          0xba, 0xc7, 0x7a, 0x77, 0x17, 0x94, 0x28, 0x63 },
++              .klen   = 24,
++              .input  = { [0 ... 15] = 0x00 },
++              .ilen   = 16,
++              .result = { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb, 
++                          0xdd, 0x0e, 0x41, 0xaa, 0x08, 0xa7, 0xa7, 0xe8 },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
++                          0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98,
++                          0x8d, 0x7c, 0x47, 0xce, 0x26, 0x49, 0x08, 0x46,
++                          0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 },                             
++              .klen   = 32,
++              .input  = { [0 ... 15] = 0x00 },
++              .ilen   = 16,
++              .result = { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9, 
++                          0xc9, 0x87, 0x01, 0x36, 0x55, 0x33, 0x17, 0xfa },
++              .rlen   = 16,
+       },
+-      {
+-              24, 
+-              0,
+-              { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
+-                0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, 
+-                0xba, 0xc7, 0x7a, 0x77, 0x17, 0x94, 0x28, 0x63 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb, 
+-                0xdd, 0x0e, 0x41, 0xaa, 0x08, 0xa7, 0xa7, 0xe8 },
+-      },
+-      {
+-              32, 
+-              0,
+-              { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
+-                  0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98,
+-                0x8d, 0x7c, 0x47, 0xce, 0x26, 0x49, 0x08, 0x46,
+-                0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 },                               
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-              { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9, 
+-                0xc9, 0x87, 0x01, 0x36, 0x55, 0x33, 0x17, 0xfa },
+-      }
+ };
+-struct cast6_tv cast6_dec_tv_template[] = 
++struct cipher_testvec cast6_dec_tv_template[] = 
+ {
+       {
+-              16, 
+-              0,
+-              { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
+-                0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d },
+-              { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20, 
+-                0x83, 0x6c, 0x91, 0xd1, 0xb7, 0x53, 0x0f, 0x6b },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-      },
+-      {
+-              24, 
+-              0,
+-              { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
+-                0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, 
+-                0xba, 0xc7, 0x7a, 0x77, 0x17, 0x94, 0x28, 0x63 },
+-              { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb, 
+-                0xdd, 0x0e, 0x41, 0xaa, 0x08, 0xa7, 0xa7, 0xe8 },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
++              .key    = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
++                          0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d },
++              .klen   = 16,
++              .input  = { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20, 
++                          0x83, 0x6c, 0x91, 0xd1, 0xb7, 0x53, 0x0f, 0x6b },
++              .ilen   = 16,
++              .result = { [0 ... 15] = 0x00 },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
++                          0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, 
++                          0xba, 0xc7, 0x7a, 0x77, 0x17, 0x94, 0x28, 0x63 },
++              .klen   = 24,
++              .input  = { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb, 
++                          0xdd, 0x0e, 0x41, 0xaa, 0x08, 0xa7, 0xa7, 0xe8 },
++              .ilen   = 16,
++              .result = { [0 ... 15] = 0x00 },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
++                          0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98,
++                          0x8d, 0x7c, 0x47, 0xce, 0x26, 0x49, 0x08, 0x46,
++                          0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 },                             
++              .klen   = 32,
++              .input  = { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9, 
++                          0xc9, 0x87, 0x01, 0x36, 0x55, 0x33, 0x17, 0xfa },
++              .ilen   = 16,
++              .result = { [0 ... 15] = 0x00 },
++              .rlen   = 16,
+       },
+-      {
+-              32, 
+-              0,
+-              { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
+-                  0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98,
+-                0x8d, 0x7c, 0x47, 0xce, 0x26, 0x49, 0x08, 0x46,
+-                0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 },                               
+-              { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9, 
+-                0xc9, 0x87, 0x01, 0x36, 0x55, 0x33, 0x17, 0xfa },
+-              { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+-      }
+ };
+@@ -1682,90 +1354,77 @@ struct cast6_tv cast6_dec_tv_template[] 
+ #define AES_ENC_TEST_VECTORS 3
+ #define AES_DEC_TEST_VECTORS 3
+-struct aes_tv {
+-      unsigned int keylen;
+-      unsigned int plen;
+-      unsigned int rlen;
+-      int fail;
+-      char key[32];
+-      char iv[8];
+-      char plaintext[16];
+-      char result[16];
+-};
+-
+-struct aes_tv aes_enc_tv_template[] = { 
+-      /* From FIPS-197 */
+-      {
+-              16, 16, 16, 0,
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+-              { 0 },
+-              { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+-                0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+-              { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
+-                0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a },
+-      },
+-      {
+-              24, 16, 16, 0,
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+-                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
+-              { 0 },
+-              { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
+-                0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+-              { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
+-                0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 },
+-      },
+-      {
+-              32, 16, 16, 0,
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+-                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+-                0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+-              { 0 },
+-              { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
+-                0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+-              { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
+-                0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 },
+-      },
+-};
+-
+-struct aes_tv aes_dec_tv_template[] = { 
+-      /* From FIPS-197 */
+-      {
+-              16, 16, 16, 0,
+-              
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+-              { 0 },
+-              { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
+-                0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a },
+-              { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+-                0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+-      },
+-      
+-      {
+-              24, 16, 16, 0,
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+-                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
+-              { 0 },
+-              { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
+-                0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 },
+-              { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
+-                0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },  
+-      },
+-      {
+-              32, 16, 16, 0,
+-              { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+-                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+-                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+-                0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+-              { 0 },
+-              { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
+-                0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 },
+-              { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
+-                0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
++struct cipher_testvec aes_enc_tv_template[] = { 
++      { /* From FIPS-197 */
++              .key    = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
++              .klen   = 16,
++              .input  = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
++                          0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
++              .ilen   = 16,
++              .result = { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
++                          0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
++                          0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
++              .klen   = 24,
++              .input  = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
++                          0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
++              .ilen   = 16,
++              .result = { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
++                          0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
++                          0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
++                          0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
++              .klen   = 32,
++              .input  = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
++                          0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
++              .ilen   = 16,
++              .result = { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
++                          0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 },
++              .rlen   = 16,
++      },
++};
++
++struct cipher_testvec aes_dec_tv_template[] = { 
++      { /* From FIPS-197 */
++              .key    = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
++              .klen   = 16,
++              .input  = { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
++                          0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a },
++              .ilen   = 16,
++              .result = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
++                          0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
++              .rlen   = 16,
++      }, {
++              .key    = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
++                          0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
++              .klen   = 24,
++              .input  = { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
++                          0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 },
++              .ilen   = 16,
++              .result = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
++                          0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },  
++              .rlen   = 16,
++      }, {
++              .key    = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
++                          0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
++                          0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
++                          0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
++              .klen   = 32,
++              .input  = { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
++                          0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 },
++              .ilen   = 16,
++              .result = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
++                          0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
++              .rlen   = 16,
+       },
+ };
+@@ -1773,68 +1432,60 @@ struct aes_tv aes_dec_tv_template[] = { 
+ #define CAST5_ENC_TEST_VECTORS        3
+ #define CAST5_DEC_TEST_VECTORS        3
+-struct cast5_tv {
+-      unsigned keylen;
+-      unsigned fail;
+-      u8 key[16];
+-      u8 plaintext[8];
+-      u8 ciphertext[8];
+-};
+-
+-struct cast5_tv cast5_enc_tv_template[] =
++struct cipher_testvec cast5_enc_tv_template[] =
+ {
+       {
+-              16,
+-              0,
+-              { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
+-                0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A },
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2 },
+-
+-      },
+-      {
+-              10,
+-              0,
+-              { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
+-                0x23, 0x45 },
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b },
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
++                          0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a },
++              .klen   = 16,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .ilen   = 8,
++              .result = { 0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2 },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
++                          0x23, 0x45 },
++              .klen   = 10,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .ilen   = 8,
++              .result = { 0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x12 },
++              .klen   = 5,
++              .input  = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .ilen   = 8,
++              .result = { 0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e },
++              .rlen   = 8,
+       },
+-      {
+-              5,
+-              0,
+-              { 0x01, 0x23, 0x45, 0x67, 0x12 },
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-              { 0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e },
+-      }
+ };
+-struct cast5_tv cast5_dec_tv_template[] =
++struct cipher_testvec cast5_dec_tv_template[] =
+ {
+       {
+-              16,
+-              0,
+-              { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
+-                0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A },
+-              { 0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2 },
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-
+-      },
+-      {
+-              10,
+-              0,
+-              { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
+-                0x23, 0x45 },
+-              { 0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b },
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
++                          0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a },
++              .klen   = 16,
++              .input  = { 0x23, 0x8b, 0x4f, 0xe5, 0x84, 0x7e, 0x44, 0xb2 },
++              .ilen   = 8,
++              .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
++                          0x23, 0x45 },
++              .klen   = 10,
++              .input  = { 0xeb, 0x6a, 0x71, 0x1a, 0x2c, 0x02, 0x27, 0x1b },
++              .ilen   = 8,
++              .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .rlen   = 8,
++      }, {
++              .key    = { 0x01, 0x23, 0x45, 0x67, 0x12 },
++              .klen   = 5,
++              .input  = { 0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e },
++              .ilen   = 8,
++              .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
++              .rlen   = 8,
+       },
+-      {
+-              5,
+-              0,
+-              { 0x01, 0x23, 0x45, 0x67, 0x12 },
+-              { 0x7a, 0xc8, 0x16, 0xd1, 0x6e, 0x9b, 0x30, 0x2e },
+-              { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
+-      }
+ };
+ /*
+@@ -1857,83 +1508,73 @@ struct comp_testvec {
+ struct comp_testvec deflate_comp_tv_template[] = {
+       {
+-        70, 38,
+-        
+-        "Join us now and share the software "
+-        "Join us now and share the software ",
+-
+-          { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56,
+-            0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51,
+-            0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9,
+-            0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07,
+-            0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 
+-          },
+-      },
+-        
+-      {
+-        191, 122,
+-        
+-        "This document describes a compression method based on the DEFLATE"
+-        "compression algorithm.  This document defines the application of "
+-        "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+-        
+-        { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04,
+-          0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09,
+-          0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8,
+-          0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49,
+-          0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27,
+-          0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2,
+-          0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad,
+-          0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4,
+-          0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b,
+-          0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f,
+-          0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf,
+-          0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02,
+-          0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98,
+-          0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a,
+-          0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79,
+-          0xfa, 0x02 },
++              .inlen  = 70,
++              .outlen = 38,
++              .input  = "Join us now and share the software "
++                        "Join us now and share the software ",
++              .output = { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56,
++                          0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51,
++                          0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9,
++                          0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07,
++                          0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 },
++      }, {
++              .inlen  = 191,
++              .outlen = 122,
++              .input  = "This document describes a compression method based on the DEFLATE"
++                        "compression algorithm.  This document defines the application of "
++                        "the DEFLATE algorithm to the IP Payload Compression Protocol.",
++              .output = { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04,
++                          0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09,
++                          0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8,
++                          0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49,
++                          0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27,
++                          0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2,
++                          0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad,
++                          0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4,
++                          0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b,
++                          0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f,
++                          0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf,
++                          0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02,
++                          0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98,
++                          0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a,
++                          0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79,
++                          0xfa, 0x02 },
+       },
+ };
+ struct comp_testvec deflate_decomp_tv_template[] = {
+       {
+-        122, 191,
+-        
+-        { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04,
+-          0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09,
+-          0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8,
+-          0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49,
+-          0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27,
+-          0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2,
+-          0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad,
+-          0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4,
+-          0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b,
+-          0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f,
+-          0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf,
+-          0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02,
+-          0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98,
+-          0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a,
+-          0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79,
+-          0xfa, 0x02 },
+-          
+-          "This document describes a compression method based on the DEFLATE"
+-          "compression algorithm.  This document defines the application of "
+-          "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+-      },
+-      
+-      {
+-        38, 70,
+-        
+-          { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56,
+-            0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51,
+-            0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9,
+-            0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07,
+-            0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00
+-          },
+-          
+-          "Join us now and share the software "
+-        "Join us now and share the software ",
++              .inlen  = 122,
++              .outlen = 191,
++              .input  = { 0x5d, 0x8d, 0x31, 0x0e, 0xc2, 0x30, 0x10, 0x04,
++                          0xbf, 0xb2, 0x2f, 0xc8, 0x1f, 0x10, 0x04, 0x09,
++                          0x89, 0xc2, 0x85, 0x3f, 0x70, 0xb1, 0x2f, 0xf8,
++                          0x24, 0xdb, 0x67, 0xd9, 0x47, 0xc1, 0xef, 0x49,
++                          0x68, 0x12, 0x51, 0xae, 0x76, 0x67, 0xd6, 0x27,
++                          0x19, 0x88, 0x1a, 0xde, 0x85, 0xab, 0x21, 0xf2,
++                          0x08, 0x5d, 0x16, 0x1e, 0x20, 0x04, 0x2d, 0xad,
++                          0xf3, 0x18, 0xa2, 0x15, 0x85, 0x2d, 0x69, 0xc4,
++                          0x42, 0x83, 0x23, 0xb6, 0x6c, 0x89, 0x71, 0x9b,
++                          0xef, 0xcf, 0x8b, 0x9f, 0xcf, 0x33, 0xca, 0x2f,
++                          0xed, 0x62, 0xa9, 0x4c, 0x80, 0xff, 0x13, 0xaf,
++                          0x52, 0x37, 0xed, 0x0e, 0x52, 0x6b, 0x59, 0x02,
++                          0xd9, 0x4e, 0xe8, 0x7a, 0x76, 0x1d, 0x02, 0x98,
++                          0xfe, 0x8a, 0x87, 0x83, 0xa3, 0x4f, 0x56, 0x8a,
++                          0xb8, 0x9e, 0x8e, 0x5c, 0x57, 0xd3, 0xa0, 0x79,
++                          0xfa, 0x02 },
++              .output = "This document describes a compression method based on the DEFLATE"
++                        "compression algorithm.  This document defines the application of "
++                        "the DEFLATE algorithm to the IP Payload Compression Protocol.",
++      }, {
++              .inlen  = 38,
++              .outlen = 70,
++              .input  = { 0xf3, 0xca, 0xcf, 0xcc, 0x53, 0x28, 0x2d, 0x56,
++                          0xc8, 0xcb, 0x2f, 0x57, 0x48, 0xcc, 0x4b, 0x51,
++                          0x28, 0xce, 0x48, 0x2c, 0x4a, 0x55, 0x28, 0xc9,
++                          0x48, 0x55, 0x28, 0xce, 0x4f, 0x2b, 0x29, 0x07,
++                          0x71, 0xbc, 0x08, 0x2b, 0x01, 0x00 },
++              .output = "Join us now and share the software "
++                        "Join us now and share the software ",
+       },
+ };
+--- linux-2.6.0/Documentation/block/biodoc.txt 2003-09-27 18:57:43.000000000 -0700
++++ 25/Documentation/block/biodoc.txt  2003-12-28 23:23:06.000000000 -0800
+@@ -323,7 +323,7 @@ involved. In the latter case, the driver
+ request->buffer, request->sector and request->nr_sectors or
+ request->current_nr_sectors fields itself rather than using the block layer
+ end_request or end_that_request_first completion interfaces.
+-(See 2.3 or Documentation/bio/request.txt for a brief explanation of
++(See 2.3 or Documentation/block/request.txt for a brief explanation of
+ the request structure fields)
+ [TBD: end_that_request_last should be usable even in this case;
+@@ -517,7 +517,7 @@ request structure.
+ Only some relevant fields (mainly those which changed or may be referred
+ to in some of the discussion here) are listed below, not necessarily in
+ the order in which they occur in the structure (see include/linux/blkdev.h)
+-Refer to Documentation/bio/request.txt for details about all the request
++Refer to Documentation/block/request.txt for details about all the request
+ structure fields and a quick reference about the layers which are
+ supposed to use or modify those fields.
+--- linux-2.6.0/Documentation/Changes  2003-10-08 15:07:08.000000000 -0700
++++ 25/Documentation/Changes   2003-12-28 23:22:28.000000000 -0800
+@@ -56,7 +56,7 @@ o  module-init-tools      0.9.10        
+ o  e2fsprogs              1.29                    # tune2fs
+ o  jfsutils               1.1.3                   # fsck.jfs -V
+ o  reiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep reiserfsprogs
+-o  xfsprogs               2.1.0                   # xfs_db -V
++o  xfsprogs               2.6.0                   # xfs_db -V
+ o  pcmcia-cs              3.1.21                  # cardmgr -V
+ o  quota-tools            3.09                    # quota -V
+ o  PPP                    2.4.0                   # pppd --version
+@@ -183,9 +183,8 @@ Xfsprogs
+ The latest version of xfsprogs contains mkfs.xfs, xfs_db, and the
+ xfs_repair utilities, among others, for the XFS filesystem.  It is
+ architecture independent and any version from 2.0.0 onward should
+-work correctly with this version of the XFS kernel code.  For the new
+-(v2) log format that has better support for stripe-size aligning on
+-LVM and MD devices at least xfsprogs 2.1.0 is needed.
++work correctly with this version of the XFS kernel code (2.6.0 or
++later is recommended, due to some significant improvements).
+ Pcmcia-cs
+@@ -359,7 +358,7 @@ o  <http://www.namesys.com/pub/reiserfsp
+ Xfsprogs
+ --------
+-o  <ftp://oss.sgi.com/projects/xfs/download/cmd_tars/xfsprogs-2.1.0.src.tar.gz>
++o  <ftp://oss.sgi.com/projects/xfs/download/>
+ Pcmcia-cs
+ ---------
+--- linux-2.6.0/Documentation/DocBook/kernel-locking.tmpl      2003-09-27 18:57:43.000000000 -0700
++++ 25/Documentation/DocBook/kernel-locking.tmpl       2003-12-28 23:22:34.000000000 -0800
+@@ -6,8 +6,7 @@
+   
+   <authorgroup>
+    <author>
+-    <firstname>Paul</firstname>
+-    <othername>Rusty</othername>
++    <firstname>Rusty</firstname>
+     <surname>Russell</surname>
+     <affiliation>
+      <address>
+@@ -18,8 +17,8 @@
+   </authorgroup>
+   <copyright>
+-   <year>2000</year>
+-   <holder>Paul Russell</holder>
++   <year>2003</year>
++   <holder>Rusty Russell</holder>
+   </copyright>
+   <legalnotice>
+@@ -58,16 +57,17 @@
+    <para>
+      Welcome, to Rusty's Remarkably Unreliable Guide to Kernel
+      Locking issues.  This document describes the locking systems in
+-     the Linux Kernel as we approach 2.4.
++     the Linux Kernel in 2.6.
+    </para>
+    <para>
+-     It looks like <firstterm linkend="gloss-smp"><acronym>SMP</acronym>
+-     </firstterm> is here to stay; so everyone hacking on the kernel 
+-     these days needs to know the fundamentals of concurrency and locking 
+-     for SMP.
++     With the wide availability of HyperThreading, and <firstterm
++     linkend="gloss-preemption">preemption </firstterm> in the Linux
++     Kernel, everyone hacking on the kernel needs to know the
++     fundamentals of concurrency and locking for
++     <firstterm linkend="gloss-smp"><acronym>SMP</acronym></firstterm>.
+    </para>
+-   <sect1 id="races">
++   <chapter id="races">
+     <title>The Problem With Concurrency</title>
+     <para>
+       (Skip this if you know what a Race Condition is).
+@@ -169,15 +169,23 @@
+      </tgroup>
+     </table>
++    <sect1 id="race-condition">
++    <title>Race Conditions and Critical Regions</title>
+     <para>
+-      This overlap, where what actually happens depends on the
+-      relative timing of multiple tasks, is called a race condition.
++      This overlap, where the result depends on the
++      relative timing of multiple tasks, is called a <firstterm>race condition</firstterm>.
+       The piece of code containing the concurrency issue is called a
+-      critical region.  And especially since Linux starting running
++      <firstterm>critical region</firstterm>.  And especially since Linux starting running
+       on SMP machines, they became one of the major issues in kernel
+       design and implementation.
+     </para>
+     <para>
++      Preemption can have the same effect, even if there is only one
++      CPU: by preempting one task during the critical region, we have
++      exactly the same race condition.  In this case the thread which
++      preempts might run the critical region itself.
++    </para>
++    <para>
+       The solution is to recognize when these simultaneous accesses
+       occur, and use locks to make sure that only one instance can
+       enter the critical region at any time.  There are many
+@@ -185,10 +193,28 @@
+       And then there are the unfriendly primitives, but I'll pretend
+       they don't exist.
+     </para>
+-   </sect1>
+   </chapter>
+   <chapter id="locks">
++   <title>Locking in the Linux Kernel</title>
++
++   <para>
++     If I could give you one piece of advice: never sleep with anyone
++     crazier than yourself.  But if I had to give you advice on
++     locking: <emphasis>keep it simple</emphasis>.
++   </para>
++
++   <para>
++     Be reluctant to introduce new locks.
++   </para>
++
++   <para>
++     Strangely enough, this last one is the exact reverse of my advice when
++     you <emphasis>have</emphasis> slept with someone crazier than yourself.
++     And you should think about getting a big dog.
++   </para>
++
++   <sect1 id="lock-intro">
+    <title>Two Main Types of Kernel Locks: Spinlocks and Semaphores</title>
+    <para>
+@@ -213,23 +239,32 @@
+    </para>
+    <para>
+      Neither type of lock is recursive: see
+-     <xref linkend="techniques-deadlocks">.
++     <xref linkend="deadlock">.
+    </para>
++   </sect1>
+  
+    <sect1 id="uniprocessor">
+     <title>Locks and Uniprocessor Kernels</title>
+     <para>
+-      For kernels compiled without <symbol>CONFIG_SMP</symbol>, spinlocks 
+-      do not exist at all.  This is an excellent design decision: when
+-      no-one else can run at the same time, there is no reason to
+-      have a lock at all.
++      For kernels compiled without <symbol>CONFIG_SMP</symbol>, and
++      without <symbol>CONFIG_PREEMPT</symbol> spinlocks do not exist at
++      all.  This is an excellent design decision: when no-one else can
++      run at the same time, there is no reason to have a lock.
++    </para>
++
++    <para>
++      If the kernel is compiled without <symbol>CONFIG_SMP</symbol>,
++      but <symbol>CONFIG_PREEMPT</symbol> is set, then spinlocks
++      simply disable preemption, which is sufficient to prevent any
++      races.  For most purposes, we can think of preemption as
++      equivalent to SMP, and not worry about it separately.
+     </para>
+     <para>
+       You should always test your locking code with <symbol>CONFIG_SMP</symbol>
+-      enabled, even if you don't have an SMP test box, because it
+-      will still catch some (simple) kinds of deadlock.
++      and <symbol>CONFIG_PREEMPT</symbol> enabled, even if you don't have an SMP test box, because it
++      will still catch some kinds of locking bugs.
+     </para>
+     <para>
+@@ -239,25 +274,6 @@
+     </para>
+    </sect1>
+-   <sect1 id="rwlocks">
+-    <title>Read/Write Lock Variants</title>
+-
+-    <para>
+-      Both spinlocks and semaphores have read/write variants:
+-      <type>rwlock_t</type> and <structname>struct rw_semaphore</structname>. 
+-      These divide users into two classes: the readers and the writers.  If 
+-      you are only reading the data, you can get a read lock, but to write to 
+-      the data you need the write lock.  Many people can hold a read lock,
+-      but a writer must be sole holder.
+-    </para>
+-
+-    <para>
+-      This means much smoother locking if your code divides up
+-      neatly along reader/writer lines.  All the discussions below
+-      also apply to read/write variants.
+-    </para>
+-   </sect1>
+-
+     <sect1 id="usercontextlocking">
+      <title>Locking Only In User Context</title>
+@@ -289,17 +305,26 @@
+    </sect1>
+    <sect1 id="lock-user-bh">
+-    <title>Locking Between User Context and BHs</title>
++    <title>Locking Between User Context and Softirqs</title>
+     <para>
+-      If a <firstterm linkend="gloss-bh">bottom half</firstterm> shares 
++      If a <firstterm linkend="gloss-softirq">softirq</firstterm> shares
+       data with user context, you have two problems.  Firstly, the current 
+-      user context can be interrupted by a bottom half, and secondly, the 
++      user context can be interrupted by a softirq, and secondly, the
+       critical region could be entered from another CPU.  This is where
+       <function>spin_lock_bh()</function> 
+       (<filename class=headerfile>include/linux/spinlock.h</filename>) is 
+-      used.  It disables bottom halves on that CPU, then grabs the lock.
+-      <function>spin_unlock_bh()</function> does the reverse.
++      used.  It disables softirqs on that CPU, then grabs the lock.
++      <function>spin_unlock_bh()</function> does the reverse.  (The
++      '_bh' suffix is a historical reference to "Bottom Halves", the
++      old name for software interrupts.  It should really be
++      called spin_lock_softirq()' in a perfect world).
++    </para>
++
++    <para>
++      Note that you can also use <function>spin_lock_irq()</function>
++      or <function>spin_lock_irqsave()</function> here, which stop
++      hardware interrupts as well: see <xref linkend="hardirq-context">.
+     </para>
+     <para>
+@@ -307,70 +332,41 @@
+       </acronym></firstterm> as well: the spin lock vanishes, and this macro 
+       simply becomes <function>local_bh_disable()</function>
+       (<filename class=headerfile>include/linux/interrupt.h</filename>), which
+-      protects you from the bottom half being run.
++      protects you from the softirq being run.
+     </para>
+    </sect1>
+    <sect1 id="lock-user-tasklet">
+-    <title>Locking Between User Context and Tasklets/Soft IRQs</title>
++    <title>Locking Between User Context and Tasklets</title>
+     <para>
+-      This is exactly the same as above, because
+-      <function>local_bh_disable()</function> actually disables all 
+-      softirqs and <firstterm linkend="gloss-tasklet">tasklets</firstterm>
+-      on that CPU as well.  It should really be 
+-      called `local_softirq_disable()', but the name has been preserved 
+-      for historical reasons.  Similarly,
+-      <function>spin_lock_bh()</function> would now be called 
+-      spin_lock_softirq() in a perfect world.
++      This is exactly the same as above, because <firstterm
++      linkend="gloss-tasklet">tasklets</firstterm> are actually run
++      from a softirq.
+     </para>
+    </sect1>
+-   <sect1 id="lock-bh">
+-    <title>Locking Between Bottom Halves</title>
++   <sect1 id="lock-user-timers">
++    <title>Locking Between User Context and Timers</title>
+     <para>
+-      Sometimes a bottom half might want to share data with
+-      another bottom half (especially remember that timers are run
+-      off a bottom half).
++      This, too, is exactly the same as above, because <firstterm
++      linkend="gloss-timers">timers</firstterm> are actually run from
++      a softirq.  From a locking point of view, tasklets and timers
++      are identical.
+     </para>
+-
+-    <sect2 id="lock-bh-same">
+-     <title>The Same BH</title>
+-
+-     <para>
+-       Since a bottom half is never run on two CPUs at once, you
+-       don't need to worry about your bottom half being run twice
+-       at once, even on SMP.
+-     </para>
+-    </sect2>
+-
+-    <sect2 id="lock-bh-different">
+-     <title>Different BHs</title>
+-
+-     <para>
+-       Since only one bottom half ever runs at a time once, you
+-       don't need to worry about race conditions with other bottom
+-       halves.  Beware that things might change under you, however,
+-       if someone changes your bottom half to a tasklet.  If you
+-       want to make your code future-proof, pretend you're already
+-       running from a tasklet (see below), and doing the extra
+-       locking.  Of course, if it's five years before that happens,
+-       you're gonna look like a damn fool.
+-     </para>
+-    </sect2>
+    </sect1>
+    <sect1 id="lock-tasklets">
+-    <title>Locking Between Tasklets</title>
++    <title>Locking Between Tasklets/Timers</title>
+     <para>
+-      Sometimes a tasklet might want to share data with another
+-      tasklet, or a bottom half.
++      Sometimes a tasklet or timer might want to share data with
++      another tasklet or timer.
+     </para>
+     <sect2 id="lock-tasklets-same">
+-     <title>The Same Tasklet</title>
++     <title>The Same Tasklet/Timer</title>
+      <para>
+        Since a tasklet is never run on two CPUs at once, you don't
+        need to worry about your tasklet being reentrant (running
+@@ -379,10 +375,10 @@
+     </sect2>
+     <sect2 id="lock-tasklets-different">
+-     <title>Different Tasklets</title>
++     <title>Different Tasklets/Timers</title>
+      <para>
+-       If another tasklet (or bottom half, such as a timer) wants
+-       to share data with your tasklet, you will both need to use
++       If another tasklet/timer wants
++       to share data with your tasklet or timer , you will both need to use
+        <function>spin_lock()</function> and
+        <function>spin_unlock()</function> calls.  
+        <function>spin_lock_bh()</function> is
+@@ -396,8 +392,8 @@
+     <title>Locking Between Softirqs</title>
+     <para>
+-      Often a <firstterm linkend="gloss-softirq">softirq</firstterm> might 
+-      want to share data with itself, a tasklet, or a bottom half.
++      Often a softirq might
++      want to share data with itself or a tasklet/timer.
+     </para>
+     <sect2 id="lock-softirqs-same">
+@@ -421,10 +417,10 @@
+      <title>Different Softirqs</title>
+      <para>
+-       You'll need to use <function>spin_lock()</function> and 
+-       <function>spin_unlock()</function> for shared data, whether it 
+-       be a timer (which can be running on a different CPU), bottom half, 
+-       tasklet or the same or another softirq.
++       You'll need to use <function>spin_lock()</function> and
++       <function>spin_unlock()</function> for shared data, whether it
++       be a timer, tasklet, different softirq or the same or another
++       softirq: any of them could be running on a different CPU.
+      </para>
+     </sect2>
+    </sect1>
+@@ -434,13 +430,13 @@
+    <title>Hard IRQ Context</title>
+    <para>
+-     Hardware interrupts usually communicate with a bottom half,
++     Hardware interrupts usually communicate with a
+      tasklet or softirq.  Frequently this involves putting work in a
+-     queue, which the BH/softirq will take out.
++     queue, which the softirq will take out.
+    </para>
+    <sect1 id="hardirq-softirq">
+-    <title>Locking Between Hard IRQ and Softirqs/Tasklets/BHs</title>
++    <title>Locking Between Hard IRQ and Softirqs/Tasklets</title>
+     <para>
+       If a hardware irq handler shares data with a softirq, you have
+@@ -453,6 +449,16 @@
+     </para>
+     <para>
++      The irq handler does not to use
++      <function>spin_lock_irq()</function>, because the softirq cannot
++      run while the irq handler is running: it can use
++      <function>spin_lock()</function>, which is slightly faster.  The
++      only exception would be if a different hardware irq handler uses
++      the same lock: <function>spin_lock_irq()</function> will stop
++      that from interrupting us.
++    </para>
++
++    <para>
+       This works perfectly for UP as well: the spin lock vanishes,
+       and this macro simply becomes <function>local_irq_disable()</function>
+       (<filename class=headerfile>include/asm/smp.h</filename>), which 
+@@ -468,60 +474,766 @@
+       interrupts are already off) and in softirqs (where the irq
+       disabling is required).
+     </para>
++
++    <para>
++      Note that softirqs (and hence tasklets and timers) are run on
++      return from hardware interrupts, so
++      <function>spin_lock_irq()</function> also stops these.  In that
++      sense, <function>spin_lock_irqsave()</function> is the most
++      general and powerful locking function.
++    </para>
++
++   </sect1>
++   <sect1 id="hardirq-hardirq">
++    <title>Locking Between Two Hard IRQ Handlers</title>
++    <para>
++      It is rare to have to share data between two IRQ handlers, but
++      if you do, <function>spin_lock_irqsave()</function> should be
++      used: it is architecture-specific whether all interrupts are
++      disabled inside irq handlers themselves.
++    </para>
+    </sect1>
+-  </chapter>
+-  <chapter id="common-techniques">
+-   <title>Common Techniques</title>
++  </chapter>
++  <chapter id="cheatsheet">
++   <title>Cheat Sheet For Locking</title>
+    <para>
+-     This section lists some common dilemmas and the standard
+-     solutions used in the Linux kernel code.  If you use these,
+-     people will find your code simpler to understand.
++     Pete Zaitcev gives the following summary:
+    </para>
++   <itemizedlist>
++      <listitem>
++      <para>
++          If you are in a process context (any syscall) and want to
++      lock other process out, use a semaphore.  You can take a semaphore
++      and sleep (<function>copy_from_user*(</function> or
++      <function>kmalloc(x,GFP_KERNEL)</function>).
++      </para>
++      </listitem>
++      <listitem>
++      <para>
++      Otherwise (== data can be touched in an interrupt), use
++      <function>spin_lock_irqsave()</function> and
++      <function>spin_unlock_irqrestore()</function>.
++      </para>
++      </listitem>
++      <listitem>
++      <para>
++      Avoid holding spinlock for more than 5 lines of code and
++      across any function call (except accessors like
++      <function>readb</function>).
++      </para>
++      </listitem>
++    </itemizedlist>
+-   <para>
+-     If I could give you one piece of advice: never sleep with anyone
+-     crazier than yourself.  But if I had to give you advice on
+-     locking: <emphasis>keep it simple</emphasis>.
+-   </para>
++   <sect1 id="minimum-lock-reqirements">
++   <title>Table of Minimum Requirements</title>
+-   <para>
+-     Lock data, not code.
++   <para> The following table lists the <emphasis>minimum</emphasis>
++      locking requirements between various contexts.  In some cases,
++      the same context can only be running on one CPU at a time, so
++      no locking is required for that context (eg. a particular
++      thread can only run on one CPU at a time, but if it needs
++      shares data with another thread, locking is required).
+    </para>
+-
+    <para>
+-     Be reluctant to introduce new locks.
++      Remember the advice above: you can always use
++      <function>spin_lock_irqsave()</function>, which is a superset
++      of all other spinlock primitives.
+    </para>
++   <table>
++<title>Table of Locking Requirements</title>
++<TGROUP COLS=11>
++<TBODY>
++<ROW>
++<ENTRY></ENTRY>
++<ENTRY>IRQ Handler A</ENTRY>
++<ENTRY>IRQ Handler B</ENTRY>
++<ENTRY>Softirq A</ENTRY>
++<ENTRY>Softirq B</ENTRY>
++<ENTRY>Tasklet A</ENTRY>
++<ENTRY>Tasklet B</ENTRY>
++<ENTRY>Timer A</ENTRY>
++<ENTRY>Timer B</ENTRY>
++<ENTRY>User Context A</ENTRY>
++<ENTRY>User Context B</ENTRY>
++</ROW>
++
++<ROW>
++<ENTRY>IRQ Handler A</ENTRY>
++<ENTRY>None</ENTRY>
++</ROW>
++
++<ROW>
++<ENTRY>IRQ Handler B</ENTRY>
++<ENTRY>spin_lock_irqsave</ENTRY>
++<ENTRY>None</ENTRY>
++</ROW>
++
++<ROW>
++<ENTRY>Softirq A</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++</ROW>
++
++<ROW>
++<ENTRY>Softirq B</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++</ROW>
++
++<ROW>
++<ENTRY>Tasklet A</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>None</ENTRY>
++</ROW>
++
++<ROW>
++<ENTRY>Tasklet B</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>None</ENTRY>
++</ROW>
++
++<ROW>
++<ENTRY>Timer A</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>None</ENTRY>
++</ROW>
++
++<ROW>
++<ENTRY>Timer B</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>spin_lock</ENTRY>
++<ENTRY>None</ENTRY>
++</ROW>
++
++<ROW>
++<ENTRY>User Context A</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>None</ENTRY>
++</ROW>
++
++<ROW>
++<ENTRY>User Context B</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock_irq</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>spin_lock_bh</ENTRY>
++<ENTRY>down_interruptible</ENTRY>
++<ENTRY>None</ENTRY>
++</ROW>
++
++</TBODY>
++</TGROUP>
++</TABLE>
++</chapter>
++
++  <chapter id="Examples">
++   <title>Common Examples</title>
++    <para>
++Let's step through a simple example: a cache of number to name
++mappings.  The cache keeps a count of how often each of the objects is
++used, and when it gets full, throws out the least used one.
++
++    </para>
++
++   <sect1 id="examples-usercontext">
++    <title>All In User Context</title>
++    <para>
++For our first example, we assume that all operations are in user
++context (ie. from system calls), so we can sleep.  This means we can
++use a semaphore to protect the cache and all the objects within
++it.  Here's the code:
++    </para>
+-   <para>
+-     Strangely enough, this is the exact reverse of my advice when
+-     you <emphasis>have</emphasis> slept with someone crazier than yourself.
+-   </para>
++    <programlisting>
++#include &lt;linux/list.h&gt;
++#include &lt;linux/slab.h&gt;
++#include &lt;linux/string.h&gt;
++#include &lt;asm/semaphore.h&gt;
++#include &lt;asm/errno.h&gt;
++
++struct object
++{
++        struct list_head list;
++        int id;
++        char name[32];
++        int popularity;
++};
++
++/* Protects the cache, cache_num, and the objects within it */
++static DECLARE_MUTEX(cache_lock);
++static LIST_HEAD(cache);
++static unsigned int cache_num = 0;
++#define MAX_CACHE_SIZE 10
++
++/* Must be holding cache_lock */
++static struct object *__cache_find(int id)
++{
++        struct object *i;
++
++        list_for_each_entry(i, &amp;cache, list)
++                if (i-&gt;id == id) {
++                        i-&gt;popularity++;
++                        return i;
++                }
++        return NULL;
++}
+-   <sect1 id="techniques-no-writers">
+-    <title>No Writers in Interrupt Context</title>
++/* Must be holding cache_lock */
++static void __cache_delete(struct object *obj)
++{
++        BUG_ON(!obj);
++        list_del(&amp;obj-&gt;list);
++        kfree(obj);
++        cache_num--;
++}
++
++/* Must be holding cache_lock */
++static void __cache_add(struct object *obj)
++{
++        list_add(&amp;obj-&gt;list, &amp;cache);
++        if (++cache_num > MAX_CACHE_SIZE) {
++                struct object *i, *outcast = NULL;
++                list_for_each_entry(i, &amp;cache, list) {
++                        if (!outcast || i-&gt;popularity &lt; outcast-&gt;popularity)
++                                outcast = i;
++                }
++                __cache_delete(outcast);
++        }
++}
+-    <para>
+-      There is a fairly common case where an interrupt handler needs
+-      access to a critical region, but does not need write access.
+-      In this case, you do not need to use
+-      <function>read_lock_irq()</function>, but only
+-      <function>read_lock()</function> everywhere (since if an interrupt 
+-      occurs, the irq handler will only try to grab a read lock, which 
+-      won't deadlock).  You will still need to use 
+-      <function>write_lock_irq()</function>.
++int cache_add(int id, const char *name)
++{
++        struct object *obj;
++
++        if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
++                return -ENOMEM;
++
++        strlcpy(obj-&gt;name, name, sizeof(obj-&gt;name));
++        obj-&gt;id = id;
++        obj-&gt;popularity = 0;
++
++        down(&amp;cache_lock);
++        __cache_add(obj);
++        up(&amp;cache_lock);
++        return 0;
++}
++
++void cache_delete(int id)
++{
++        down(&amp;cache_lock);
++        __cache_delete(__cache_find(id));
++        up(&amp;cache_lock);
++}
++
++int cache_find(int id, char *name)
++{
++        struct object *obj;
++        int ret = -ENOENT;
++
++        down(&amp;cache_lock);
++        obj = __cache_find(id);
++        if (obj) {
++                ret = 0;
++                strcpy(name, obj-&gt;name);
++        }
++        up(&amp;cache_lock);
++        return ret;
++}
++</programlisting>
++
++    <para>
++Note that we always make sure we have the cache_lock when we add,
++delete, or look up the cache: both the cache infrastructure itself and
++the contents of the objects are protected by the lock.  In this case
++it's easy, since we copy the data for the user, and never let them
++access the objects directly.
++    </para>
++    <para>
++There is a slight (and common) optimization here: in
++<function>cache_add</function> we set up the fields of the object
++before grabbing the lock.  This is safe, as no-one else can access it
++until we put it in cache.
++    </para>
++    </sect1>
++
++   <sect1 id="examples-interrupt">
++    <title>Accessing From Interrupt Context</title>
++    <para>
++Now consider the case where <function>cache_find</function> can be
++called from interrupt context: either a hardware interrupt or a
++softirq.  An example would be a timer which deletes object from the
++cache.
++    </para>
++    <para>
++The change is shown below, in standard patch format: the
++<symbol>-</symbol> are lines which are taken away, and the
++<symbol>+</symbol> are lines which are added.
++    </para>
++<programlisting>
++--- cache.c.usercontext       2003-12-09 13:58:54.000000000 +1100
+++++ cache.c.interrupt 2003-12-09 14:07:49.000000000 +1100
++@@ -12,7 +12,7 @@
++         int popularity;
++ };
++
++-static DECLARE_MUTEX(cache_lock);
+++static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED;
++ static LIST_HEAD(cache);
++ static unsigned int cache_num = 0;
++ #define MAX_CACHE_SIZE 10
++@@ -55,6 +55,7 @@
++ int cache_add(int id, const char *name)
++ {
++         struct object *obj;
+++        unsigned long flags;
++
++         if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
++                 return -ENOMEM;
++@@ -63,30 +64,33 @@
++         obj-&gt;id = id;
++         obj-&gt;popularity = 0;
++
++-        down(&amp;cache_lock);
+++        spin_lock_irqsave(&amp;cache_lock, flags);
++         __cache_add(obj);
++-        up(&amp;cache_lock);
+++        spin_unlock_irqrestore(&amp;cache_lock, flags);
++         return 0;
++ }
++
++ void cache_delete(int id)
++ {
++-        down(&amp;cache_lock);
+++        unsigned long flags;
+++
+++        spin_lock_irqsave(&amp;cache_lock, flags);
++         __cache_delete(__cache_find(id));
++-        up(&amp;cache_lock);
+++        spin_unlock_irqrestore(&amp;cache_lock, flags);
++ }
++
++ int cache_find(int id, char *name)
++ {
++         struct object *obj;
++         int ret = -ENOENT;
+++        unsigned long flags;
++
++-        down(&amp;cache_lock);
+++        spin_lock_irqsave(&amp;cache_lock, flags);
++         obj = __cache_find(id);
++         if (obj) {
++                 ret = 0;
++                 strcpy(name, obj-&gt;name);
++         }
++-        up(&amp;cache_lock);
+++        spin_unlock_irqrestore(&amp;cache_lock, flags);
++         return ret;
++ }
++</programlisting>
++
++    <para>
++Note that the <function>spin_lock_irqsave</function> will turn off
++interrupts if they are on, otherwise does nothing (if we are already
++in an interrupt handler), hence these functions are safe to call from
++any context.
++    </para>
++    <para>
++Unfortunately, <function>cache_add</function> calls
++<function>kmalloc</function> with the <symbol>GFP_KERNEL</symbol>
++flag, which is only legal in user context.  I have assumed that
++<function>cache_add</function> is still only called in user context,
++otherwise this should become a parameter to
++<function>cache_add</function>.
++    </para>
++  </sect1>
++   <sect1 id="examples-refcnt">
++    <title>Exposing Objects Outside This File</title>
++    <para>
++If our objects contained more information, it might not be sufficient
++to copy the information in and out: other parts of the code might want
++to keep pointers to these objects, for example, rather than looking up
++the id every time.  This produces two problems.
++    </para>
++    <para>
++The first problem is that we use the <symbol>cache_lock</symbol> to
++protect objects: we'd need to make this non-static so the rest of the
++code can use it.  This makes locking trickier, as it is no longer all
++in one place.
++    </para>
++    <para>
++The second problem is the lifetime problem: if another structure keeps
++a pointer to an object, it presumably expects that pointer to remain
++valid.  Unfortunately, this is only guaranteed while you hold the
++lock, otherwise someone might call <function>cache_delete</function>
++and even worse, add another object, re-using the same address.
++    </para>
++    <para>
++As there is only one lock, you can't hold it forever: no-one else would
++get any work done.
++    </para>
++    <para>
++The solution to this problem is to use a reference count: everyone who
++has a pointer to the object increases it when they first get the
++object, and drops the reference count when they're finished with it.
++Whoever drops it to zero knows it is unused, and can actually delete it.
++    </para>
++    <para>
++Here is the code:
++    </para>
++
++<programlisting>
++--- cache.c.interrupt 2003-12-09 14:25:43.000000000 +1100
+++++ cache.c.refcnt    2003-12-09 14:33:05.000000000 +1100
++@@ -7,6 +7,7 @@
++ struct object
++ {
++         struct list_head list;
+++        unsigned int refcnt;
++         int id;
++         char name[32];
++         int popularity;
++@@ -17,6 +18,35 @@
++ static unsigned int cache_num = 0;
++ #define MAX_CACHE_SIZE 10
++
+++static void __object_put(struct object *obj)
+++{
+++        if (--obj-&gt;refcnt == 0)
+++                kfree(obj);
+++}
+++
+++static void __object_get(struct object *obj)
+++{
+++        obj-&gt;refcnt++;
+++}
+++
+++void object_put(struct object *obj)
+++{
+++        unsigned long flags;
+++
+++        spin_lock_irqsave(&amp;cache_lock, flags);
+++        __object_put(obj);
+++        spin_unlock_irqrestore(&amp;cache_lock, flags);
+++}
+++
+++void object_get(struct object *obj)
+++{
+++        unsigned long flags;
+++
+++        spin_lock_irqsave(&amp;cache_lock, flags);
+++        __object_get(obj);
+++        spin_unlock_irqrestore(&amp;cache_lock, flags);
+++}
+++
++ /* Must be holding cache_lock */
++ static struct object *__cache_find(int id)
++ {
++@@ -35,6 +65,7 @@
++ {
++         BUG_ON(!obj);
++         list_del(&amp;obj-&gt;list);
+++        __object_put(obj);
++         cache_num--;
++ }
++
++@@ -63,6 +94,7 @@
++         strlcpy(obj-&gt;name, name, sizeof(obj-&gt;name));
++         obj-&gt;id = id;
++         obj-&gt;popularity = 0;
+++        obj-&gt;refcnt = 1; /* The cache holds a reference */
++
++         spin_lock_irqsave(&amp;cache_lock, flags);
++         __cache_add(obj);
++@@ -79,18 +111,15 @@
++         spin_unlock_irqrestore(&amp;cache_lock, flags);
++ }
++
++-int cache_find(int id, char *name)
+++struct object *cache_find(int id)
++ {
++         struct object *obj;
++-        int ret = -ENOENT;
++         unsigned long flags;
++
++         spin_lock_irqsave(&amp;cache_lock, flags);
++         obj = __cache_find(id);
++-        if (obj) {
++-                ret = 0;
++-                strcpy(name, obj-&gt;name);
++-        }
+++        if (obj)
+++                __object_get(obj);
++         spin_unlock_irqrestore(&amp;cache_lock, flags);
++-        return ret;
+++        return obj;
++ }
++</programlisting>
++
++<para>
++We encapsulate the reference counting in the standard 'get' and 'put'
++functions.  Now we can return the object itself from
++<function>cache_find</function> which has the advantage that the user
++can now sleep holding the object (eg. to
++<function>copy_to_user</function> to name to userspace).
++</para>
++<para>
++The other point to note is that I said a reference should be held for
++every pointer to the object: thus the reference count is 1 when first
++inserted into the cache.  In some versions the framework does not hold
++a reference count, but they are more complicated.
++</para>
++
++   <sect2 id="examples-refcnt-atomic">
++    <title>Using Atomic Operations For The Reference Count</title>
++<para>
++In practice, <type>atomic_t</type> would usually be used for
++<structfield>refcnt</structfield>.  There are a number of atomic
++operations defined in
++
++<filename class=headerfile>include/asm/atomic.h</filename>: these are
++guaranteed to be seen atomically from all CPUs in the system, so no
++lock is required.  In this case, it is simpler than using spinlocks,
++although for anything non-trivial using spinlocks is clearer.  The
++<function>atomic_inc</function> and
++<function>atomic_dec_and_test</function> are used instead of the
++standard increment and decrement operators, and the lock is no longer
++used to protect the reference count itself.
++</para>
++
++<programlisting>
++--- cache.c.refcnt    2003-12-09 15:00:35.000000000 +1100
+++++ cache.c.refcnt-atomic     2003-12-11 15:49:42.000000000 +1100
++@@ -7,7 +7,7 @@
++ struct object
++ {
++         struct list_head list;
++-        unsigned int refcnt;
+++        atomic_t refcnt;
++         int id;
++         char name[32];
++         int popularity;
++@@ -18,33 +18,15 @@
++ static unsigned int cache_num = 0;
++ #define MAX_CACHE_SIZE 10
++
++-static void __object_put(struct object *obj)
++-{
++-        if (--obj-&gt;refcnt == 0)
++-                kfree(obj);
++-}
++-
++-static void __object_get(struct object *obj)
++-{
++-        obj-&gt;refcnt++;
++-}
++-
++ void object_put(struct object *obj)
++ {
++-        unsigned long flags;
++-
++-        spin_lock_irqsave(&amp;cache_lock, flags);
++-        __object_put(obj);
++-        spin_unlock_irqrestore(&amp;cache_lock, flags);
+++        if (atomic_dec_and_test(&amp;obj-&gt;refcnt))
+++                kfree(obj);
++ }
++
++ void object_get(struct object *obj)
++ {
++-        unsigned long flags;
++-
++-        spin_lock_irqsave(&amp;cache_lock, flags);
++-        __object_get(obj);
++-        spin_unlock_irqrestore(&amp;cache_lock, flags);
+++        atomic_inc(&amp;obj-&gt;refcnt);
++ }
++
++ /* Must be holding cache_lock */
++@@ -65,7 +47,7 @@
++ {
++         BUG_ON(!obj);
++         list_del(&amp;obj-&gt;list);
++-        __object_put(obj);
+++        object_put(obj);
++         cache_num--;
++ }
++
++@@ -94,7 +76,7 @@
++         strlcpy(obj-&gt;name, name, sizeof(obj-&gt;name));
++         obj-&gt;id = id;
++         obj-&gt;popularity = 0;
++-        obj-&gt;refcnt = 1; /* The cache holds a reference */
+++        atomic_set(&amp;obj-&gt;refcnt, 1); /* The cache holds a reference */
++
++         spin_lock_irqsave(&amp;cache_lock, flags);
++         __cache_add(obj);
++@@ -119,7 +101,7 @@
++         spin_lock_irqsave(&amp;cache_lock, flags);
++         obj = __cache_find(id);
++         if (obj)
++-                __object_get(obj);
+++                object_get(obj);
++         spin_unlock_irqrestore(&amp;cache_lock, flags);
++         return obj;
++ }
++</programlisting>
++</sect1>
++
++   <sect1 id="examples-lock-per-obj">
++    <title>Protecting The Objects Themselves</title>
++    <para>
++In these examples, we assumed that the objects (except the reference
++counts) never changed once they are created.  If we wanted to allow
++the name to change, there are three possibilities:
+     </para>
++    <itemizedlist>
++      <listitem>
++      <para>
++You can make <symbol>cache_lock</symbol> non-static, and tell people
++to grab that lock before changing the name in any object.
++        </para>
++      </listitem>
++      <listitem>
++        <para>
++You can provide a <function>cache_obj_rename</function> which grabs
++this lock and changes the name for the caller, and tell everyone to
++use that function.
++        </para>
++      </listitem>
++      <listitem>
++        <para>
++You can make the <symbol>cache_lock</symbol> protect only the cache
++itself, and use another lock to protect the name.
++        </para>
++      </listitem>
++    </itemizedlist>
+-    <para>
+-      Similar logic applies to locking between softirqs/tasklets/BHs
+-      which never need a write lock, and user context: 
+-      <function>read_lock()</function> and
+-      <function>write_lock_bh()</function>.
+-    </para>
+-   </sect1>
++      <para>
++Theoretically, you can make the locks as fine-grained as one lock for
++every field, for every object.  In practice, the most common variants
++are:
++</para>
++    <itemizedlist>
++      <listitem>
++      <para>
++One lock which protects the infrastructure (the <symbol>cache</symbol>
++list in this example) and all the objects.  This is what we have done
++so far.
++      </para>
++      </listitem>
++      <listitem>
++        <para>
++One lock which protects the infrastructure (including the list
++pointers inside the objects), and one lock inside the object which
++protects the rest of that object.
++        </para>
++      </listitem>
++      <listitem>
++        <para>
++Multiple locks to protect the infrastructure (eg. one lock per hash
++chain), possibly with a separate per-object lock.
++        </para>
++      </listitem>
++    </itemizedlist>
+-   <sect1 id="techniques-deadlocks">
++<para>
++Here is the "lock-per-object" implementation:
++</para>
++<programlisting>
++--- cache.c.refcnt-atomic     2003-12-11 15:50:54.000000000 +1100
+++++ cache.c.perobjectlock     2003-12-11 17:15:03.000000000 +1100
++@@ -6,11 +6,17 @@
++
++ struct object
++ {
+++        /* These two protected by cache_lock. */
++         struct list_head list;
+++        int popularity;
+++
++         atomic_t refcnt;
+++
+++        /* Doesn't change once created. */
++         int id;
+++
+++        spinlock_t lock; /* Protects the name */
++         char name[32];
++-        int popularity;
++ };
++
++ static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED;
++@@ -77,6 +84,7 @@
++         obj-&gt;id = id;
++         obj-&gt;popularity = 0;
++         atomic_set(&amp;obj-&gt;refcnt, 1); /* The cache holds a reference */
+++        spin_lock_init(&amp;obj-&gt;lock);
++
++         spin_lock_irqsave(&amp;cache_lock, flags);
++         __cache_add(obj);
++</programlisting>
++
++<para>
++Note that I decide that the <structfield>popularity</structfield>
++count should be protected by the <symbol>cache_lock</symbol> rather
++than the per-object lock: this is because it (like the
++<structname>struct list_head</structname> inside the object) is
++logically part of the infrastructure.  This way, I don't need to grab
++the lock of every object in <function>__cache_add</function> when
++seeking the least popular.
++</para>
++
++<para>
++I also decided that the <structfield>id</structfield> member is
++unchangeable, so I don't need to grab each object lock in
++<function>__cache_find()</function> to examine the
++<structfield>id</structfield>: the object lock is only used by a
++caller who wants to read or write the <structfield>name</structfield>
++field.
++</para>
++
++<para>
++Note also that I added a comment describing what data was protected by
++which locks.  This is extremely important, as it describes the runtime
++behavior of the code, and can be hard to gain from just reading.  And
++as Alan Cox says, <quote>Lock data, not code</quote>.
++</para>
++</chapter>
++
++   <chapter id="common-problems">
++    <title>Common Problems</title>
++    <sect1 id="deadlock">
+     <title>Deadlock: Simple and Advanced</title>
+     <para>
+@@ -535,10 +1247,10 @@
+     <para>
+       For a slightly more complex case, imagine you have a region
+-      shared by a bottom half and user context.  If you use a
++      shared by a softirq and user context.  If you use a
+       <function>spin_lock()</function> call to protect it, it is 
+-      possible that the user context will be interrupted by the bottom 
+-      half while it holds the lock, and the bottom half will then spin 
++      possible that the user context will be interrupted by the softirq
++      while it holds the lock, and the softirq will then spin
+       forever trying to get the same lock.
+     </para>
+@@ -558,7 +1270,7 @@
+     </para>
+     <para>
+-      A more complex problem is the so-called `deadly embrace',
++      A more complex problem is the so-called 'deadly embrace',
+       involving two or more locks.  Say you have a hash table: each
+       entry in the table is a spinlock, and a chain of hashed
+       objects.  Inside a softirq handler, you sometimes want to
+@@ -606,7 +1318,7 @@
+       their lock.  It will look, smell, and feel like a crash.
+     </para>
+-    <sect2 id="techs-deadlock-prevent">
++    <sect1 id="techs-deadlock-prevent">
+      <title>Preventing Deadlock</title>
+      <para>
+@@ -634,7 +1346,6 @@
+        will do?).  Remember, the other programmers are out to get
+        you, so don't do this.
+      </para>
+-    </sect2>
+     <sect2 id="techs-deadlock-overprevent">
+      <title>Overzealous Prevention Of Deadlocks</title>
+@@ -650,266 +1361,481 @@
+        If you don't see why, please stay the fuck away from my code.
+      </para>
+     </sect2>
+-   </sect1>
++    </sect1>
+-   <sect1 id="per-cpu">
+-    <title>Per-CPU Data</title>
+-      
+-    <para>
+-      A great technique for avoiding locking which is used fairly
+-      widely is to duplicate information for each CPU.  For example,
+-      if you wanted to keep a count of a common condition, you could
+-      use a spin lock and a single counter.  Nice and simple.
+-    </para>
++   <sect1 id="racing-timers">
++    <title>Racing Timers: A Kernel Pastime</title>
+     <para>
+-      If that was too slow [it's probably not], you could instead
+-      use a counter for each CPU [don't], then none of them need an
+-      exclusive lock [you're wasting your time here].  To make sure
+-      the CPUs don't have to synchronize caches all the time, align
+-      the counters to cache boundaries by appending
+-      `__cacheline_aligned' to the declaration
+-      (<filename class=headerfile>include/linux/cache.h</filename>). 
+-      [Can't you think of anything better to do?]
++      Timers can produce their own special problems with races.
++      Consider a collection of objects (list, hash, etc) where each
++      object has a timer which is due to destroy it.
+     </para>
+     <para>
+-      They will need a read lock to access their own counters,
+-      however.  That way you can use a write lock to grant exclusive
+-      access to all of them at once, to tally them up.
++      If you want to destroy the entire collection (say on module
++      removal), you might do the following:
+     </para>
+-   </sect1>
+-   <sect1 id="brlock">
+-    <title>Big Reader Locks</title>
++    <programlisting>
++        /* THIS CODE BAD BAD BAD BAD: IF IT WAS ANY WORSE IT WOULD USE
++           HUNGARIAN NOTATION */
++        spin_lock_bh(&amp;list_lock);
+-    <para>
+-      A classic example of per-CPU information is Ingo's `big
+-      reader' locks 
+-      (<filename class=headerfile>linux/include/brlock.h</filename>).  These 
+-      use the Per-CPU Data techniques described above to create a lock which 
+-      is very fast to get a read lock, but agonizingly slow for a write
+-      lock.
+-    </para>
++        while (list) {
++                struct foo *next = list-&gt;next;
++                del_timer(&amp;list-&gt;timer);
++                kfree(list);
++                list = next;
++        }
++
++        spin_unlock_bh(&amp;list_lock);
++    </programlisting>
+     <para>
+-      Fortunately, there are a limited number of these locks
+-      available: you have to go through a strict interview process
+-      to get one.
++      Sooner or later, this will crash on SMP, because a timer can
++      have just gone off before the <function>spin_lock_bh()</function>,
++      and it will only get the lock after we
++      <function>spin_unlock_bh()</function>, and then try to free
++      the element (which has already been freed!).
+     </para>
+-   </sect1>
+-
+-   <sect1 id="lock-avoidance-rw">
+-    <title>Avoiding Locks: Read And Write Ordering</title>
+     <para>
+-      Sometimes it is possible to avoid locking.  Consider the
+-      following case from the 2.2 firewall code, which inserted an
+-      element into a single linked list in user context:
++      This can be avoided by checking the result of
++      <function>del_timer()</function>: if it returns
++      <returnvalue>1</returnvalue>, the timer has been deleted.
++      If <returnvalue>0</returnvalue>, it means (in this
++      case) that it is currently running, so we can do:
+     </para>
+     <programlisting>
+-        new-&gt;next = i-&gt;next;
+-        i-&gt;next = new;
+-    </programlisting>
++        retry:
++                spin_lock_bh(&amp;list_lock);
+-    <para>
+-      Here the author (Alan Cox, who knows what he's doing) assumes
+-      that the pointer assignments are atomic.  This is important,
+-      because networking packets would traverse this list on bottom
+-      halves without a lock.  Depending on their exact timing, they
+-      would either see the new element in the list with a valid 
+-      <structfield>next</structfield> pointer, or it would not be in the 
+-      list yet.  A lock is still required against other CPUs inserting
+-      or deleting from the list, of course.
+-    </para>
++                while (list) {
++                        struct foo *next = list-&gt;next;
++                        if (!del_timer(&amp;list-&gt;timer)) {
++                                /* Give timer a chance to delete this */
++                                spin_unlock_bh(&amp;list_lock);
++                                goto retry;
++                        }
++                        kfree(list);
++                        list = next;
++                }
+-    <para>
+-      Of course, the writes <emphasis>must</emphasis> be in this
+-      order, otherwise the new element appears in the list with an
+-      invalid <structfield>next</structfield> pointer, and any other 
+-      CPU iterating at the wrong time will jump through it into garbage.  
+-      Because modern CPUs reorder, Alan's code actually read as follows:
+-    </para>
+-      
+-    <programlisting>
+-        new-&gt;next = i-&gt;next;
+-        wmb();
+-        i-&gt;next = new;
++                spin_unlock_bh(&amp;list_lock);
+     </programlisting>
+     <para>
+-      The <function>wmb()</function> is a write memory barrier 
+-      (<filename class=headerfile>include/asm/system.h</filename>): neither 
+-      the compiler nor the CPU will allow any writes to memory after the 
+-      <function>wmb()</function> to be visible to other hardware
+-      before any of the writes before the <function>wmb()</function>.
++      Another common problem is deleting timers which restart
++      themselves (by calling <function>add_timer()</function> at the end
++      of their timer function).  Because this is a fairly common case
++      which is prone to races, you should use <function>del_timer_sync()</function>
++      (<filename class=headerfile>include/linux/timer.h</filename>)
++      to handle this case.  It returns the number of times the timer
++      had to be deleted before we finally stopped it from adding itself back
++      in.
+     </para>
++   </sect1>
+-    <para>
+-      As i386 does not do write reordering, this bug would never
+-      show up on that platform.  On other SMP platforms, however, it
+-      will.
+-    </para>
++   <sect1 id="sparc">
++    <title>The Fucked Up Sparc</title>
+     <para>
+-      There is also <function>rmb()</function> for read ordering: to ensure 
+-      any previous variable reads occur before following reads.  The simple
+-      <function>mb()</function> macro combines both 
+-      <function>rmb()</function> and <function>wmb()</function>.
++      Alan Cox says <quote>the irq disable/enable is in the register
++      window on a sparc</quote>.  Andi Kleen says <quote>when you do
++      restore_flags in a different function you mess up all the
++      register windows</quote>.
+     </para>
+     <para>
+-      Some atomic operations are defined to act as a memory barrier
+-      (ie. as per the <function>mb()</function> macro, but if in
+-      doubt, be explicit.
+-      <!-- Rusty Russell 2 May 2001, 2.4.4 -->
+-      Also,
+-      spinlock operations act as partial barriers: operations after
+-      gaining a spinlock will never be moved to precede the
+-      <function>spin_lock()</function> call, and operations before
+-      releasing a spinlock will never be moved after the
+-      <function>spin_unlock()</function> call.
+-      <!-- Manfred Spraul <manfreds@colorfullife.com>
+-           24 May 2000 2.3.99-pre9 -->
++      So never pass the flags word set by
++      <function>spin_lock_irqsave()</function> and brethren to another
++      function (unless it's declared <type>inline</type>).  Usually no-one
++      does this, but now you've been warned.  Dave Miller can never do
++      anything in a straightforward manner (I can say that, because I have
++      pictures of him and a certain PowerPC maintainer in a compromising
++      position).
+     </para>
+    </sect1>
+-   <sect1 id="lock-avoidance-atomic-ops">
+-    <title>Avoiding Locks: Atomic Operations</title>
++  </chapter>
++
++ <chapter id="Efficiency">
++    <title>Locking Speed</title>
+     <para>
+-      There are a number of atomic operations defined in
+-      <filename class=headerfile>include/asm/atomic.h</filename>: these 
+-      are guaranteed to be seen atomically from all CPUs in the system, thus 
+-      avoiding races. If your shared data consists of a single counter, say, 
+-      these operations might be simpler than using spinlocks (although for
+-      anything non-trivial using spinlocks is clearer).
++There are three main things to worry about when considering speed of
++some code which does locking.  First is concurrency: how many things
++are going to be waiting while someone else is holding a lock.  Second
++is the time taken to actually acquire and release an uncontended lock.
++Third is using fewer, or smarter locks.  I'm assuming that the lock is
++used fairly often: otherwise, you wouldn't be concerned about
++efficiency.
++</para>
++    <para>
++Concurrency depends on how long the lock is usually held: you should
++hold the lock for as long as needed, but no longer.  In the cache
++example, we always create the object without the lock held, and then
++grab the lock only when we are ready to insert it in the list.
++</para>
++    <para>
++Acquisition times depend on how much damage the lock operations do to
++the pipeline (pipeline stalls) and how likely it is that this CPU was
++the last one to grab the lock (ie. is the lock cache-hot for this
++CPU): on a machine with more CPUs, this likelihood drops fast.
++Consider a 700MHz Intel Pentium III: an instruction takes about 0.7ns,
++an atomic increment takes about 58ns, a lock which is cache-hot on
++this CPU takes 160ns, and a cacheline transfer from another CPU takes
++an additional 170 to 360ns.  (These figures from Paul McKenney's
++<ulink url="http://www.linuxjournal.com/article.php?sid=6993"> Linux
++Journal RCU article</ulink>).
++</para>
++    <para>
++These two aims conflict: holding a lock for a short time might be done
++by splitting locks into parts (such as in our final per-object-lock
++example), but this increases the number of lock acquisitions, and the
++results are often slower than having a single lock.  This is another
++reason to advocate locking simplicity.
++</para>
++    <para>
++The third concern is addressed below: there are some methods to reduce
++the amount of locking which needs to be done.
++</para>
++
++  <sect1 id="efficiency-rwlocks">
++   <title>Read/Write Lock Variants</title>
++
++   <para>
++      Both spinlocks and semaphores have read/write variants:
++      <type>rwlock_t</type> and <structname>struct rw_semaphore</structname>.
++      These divide users into two classes: the readers and the writers.  If
++      you are only reading the data, you can get a read lock, but to write to
++      the data you need the write lock.  Many people can hold a read lock,
++      but a writer must be sole holder.
+     </para>
+-    <para>
+-      Note that the atomic operations do in general not act as memory
+-      barriers. Instead you can insert a memory barrier before or
+-      after <function>atomic_inc()</function> or
+-      <function>atomic_dec()</function> by inserting
+-      <function>smp_mb__before_atomic_inc()</function>,
+-      <function>smp_mb__after_atomic_inc()</function>,
+-      <function>smp_mb__before_atomic_dec()</function> or
+-      <function>smp_mb__after_atomic_dec()</function>
+-      respectively. The advantage of using those macros instead of
+-      <function>smp_mb()</function> is, that they are cheaper on some
+-      platforms.    
+-      <!-- Sebastian Wilhelmi <seppi@seppi.de> 2002-03-04 -->
++   <para>
++      If your code divides neatly along reader/writer lines (as our
++      cache code does), and the lock is held by readers for
++      significant lengths of time, using these locks can help.  They
++      are slightly slower than the normal locks though, so in practice
++      <type>rwlock_t</type> is not usually worthwhile.
+     </para>
+    </sect1>
+-   <sect1 id="ref-counts">
+-    <title>Protecting A Collection of Objects: Reference Counts</title>
++   <sect1 id="efficiency-read-copy-update">
++    <title>Avoiding Locks: Read Copy Update</title>
+     <para>
+-      Locking a collection of objects is fairly easy: you get a
+-      single spinlock, and you make sure you grab it before
+-      searching, adding or deleting an object.
++      There is a special method of read/write locking called Read Copy
++      Update.  Using RCU, the readers can avoid taking a lock
++      altogether: as we expect our cache to be read more often than
++      updated (otherwise the cache is a waste of time), it is a
++      candidate for this optimization.
+     </para>
+     <para>
+-      The purpose of this lock is not to protect the individual
+-      objects: you might have a separate lock inside each one for
+-      that.  It is to protect the <emphasis>data structure
+-      containing the objects</emphasis> from race conditions.  Often
+-      the same lock is used to protect the contents of all the
+-      objects as well, for simplicity, but they are inherently
+-      orthogonal (and many other big words designed to confuse).
++      How do we get rid of read locks?  Getting rid of read locks
++      means that writers may be changing the list underneath the
++      readers.  That is actually quite simple: we can read a linked
++      list while an element is being added if the writer adds the
++      element very carefully.  For example, adding
++      <symbol>new</symbol> to a single linked list called
++      <symbol>list</symbol>:
+     </para>
++    <programlisting>
++        new-&gt;next = list-&gt;next;
++        wmb();
++        list-&gt;next = new;
++    </programlisting>
++
+     <para>
+-      Changing this to a read-write lock will often help markedly if
+-      reads are far more common that writes.  If not, there is
+-      another approach you can use to reduce the time the lock is
+-      held: reference counts.
++      The <function>wmb()</function> is a write memory barrier.  It
++      ensures that the first operation (setting the new element's
++      <symbol>next</symbol> pointer) is complete and will be seen by
++      all CPUs, before the second operation is (putting the new
++      element into the list).  This is important, since modern
++      compilers and modern CPUs can both reorder instructions unless
++      told otherwise: we want a reader to either not see the new
++      element at all, or see the new element with the
++      <symbol>next</symbol> pointer correctly pointing at the rest of
++      the list.
++    </para>
++    <para>
++      Fortunately, there is a function to do this for standard
++      <structname>struct list_head</structname> lists:
++      <function>list_add_rcu()</function>
++      (<filename>include/linux/list.h</filename>).
++    </para>
++    <para>
++      Removing an element from the list is even simpler: we replace
++      the pointer to the old element with a pointer to its successor,
++      and readers will either see it, or skip over it.
+     </para>
++    <programlisting>
++        list-&gt;next = old-&gt;next;
++    </programlisting>
++    <para>
++      There is <function>list_del_rcu()</function>
++      (<filename>include/linux/list.h</filename>) which does this (the
++      normal version poisons the old object, which we don't want).
++    </para>
++    <para>
++      The reader must also be careful: some CPUs can look through the
++      <symbol>next</symbol> pointer to start reading the contents of
++      the next element early, but don't realize that the pre-fetched
++      contents is wrong when the <symbol>next</symbol> pointer changes
++      underneath them.  Once again, there is a
++      <function>list_for_each_entry_rcu()</function>
++      (<filename>include/linux/list.h</filename>) to help you.  Of
++      course, writers can just use
++      <function>list_for_each_entry()</function>, since there cannot
++      be two simultaneous writers.
++    </para>
++    <para>
++      Our final dilemma is this: when can we actually destroy the
++      removed element?  Remember, a reader might be stepping through
++      this element in the list right now: it we free this element and
++      the <symbol>next</symbol> pointer changes, the reader will jump
++      off into garbage and crash.  We need to wait until we know that
++      all the readers who were traversing the list when we deleted the
++      element are finished.  We use <function>call_rcu()</function> to
++      register a callback which will actually destroy the object once
++      the readers are finished.
++    </para>
++    <para>
++      But how does Read Copy Update know when the readers are
++      finished?  The method is this: firstly, the readers always
++      traverse the list inside
++      <function>rcu_read_lock()</function>/<function>rcu_read_unlock()</function>
++      pairs: these simply disable preemption so the reader won't go to
++      sleep while reading the list.
++    </para>
++    <para>
++      RCU then waits until every other CPU has slept at least once:
++      since readers cannot sleep, we know that any readers which were
++      traversing the list during the deletion are finished, and the
++      callback is triggered.  The real Read Copy Update code is a
++      little more optimized than this, but this is the fundamental
++      idea.
++    </para>
++
++<programlisting>
++--- cache.c.perobjectlock     2003-12-11 17:15:03.000000000 +1100
+++++ cache.c.rcupdate  2003-12-11 17:55:14.000000000 +1100
++@@ -1,15 +1,18 @@
++ #include &lt;linux/list.h&gt;
++ #include &lt;linux/slab.h&gt;
++ #include &lt;linux/string.h&gt;
+++#include &lt;linux/rcupdate.h&gt;
++ #include &lt;asm/semaphore.h&gt;
++ #include &lt;asm/errno.h&gt;
++
++ struct object
++ {
++-        /* These two protected by cache_lock. */
+++        /* This is protected by RCU */
++         struct list_head list;
++         int popularity;
++
+++        struct rcu_head rcu;
+++
++         atomic_t refcnt;
++
++         /* Doesn't change once created. */
++@@ -40,7 +43,7 @@
++ {
++         struct object *i;
++
++-        list_for_each_entry(i, &amp;cache, list) {
+++        list_for_each_entry_rcu(i, &amp;cache, list) {
++                 if (i-&gt;id == id) {
++                         i-&gt;popularity++;
++                         return i;
++@@ -49,19 +52,25 @@
++         return NULL;
++ }
++
+++/* Final discard done once we know no readers are looking. */
+++static void cache_delete_rcu(void *arg)
+++{
+++        object_put(arg);
+++}
+++
++ /* Must be holding cache_lock */
++ static void __cache_delete(struct object *obj)
++ {
++         BUG_ON(!obj);
++-        list_del(&amp;obj-&gt;list);
++-        object_put(obj);
+++        list_del_rcu(&amp;obj-&gt;list);
++         cache_num--;
+++        call_rcu(&amp;obj-&gt;rcu, cache_delete_rcu, obj);
++ }
++
++ /* Must be holding cache_lock */
++ static void __cache_add(struct object *obj)
++ {
++-        list_add(&amp;obj-&gt;list, &amp;cache);
+++        list_add_rcu(&amp;obj-&gt;list, &amp;cache);
++         if (++cache_num > MAX_CACHE_SIZE) {
++                 struct object *i, *outcast = NULL;
++                 list_for_each_entry(i, &amp;cache, list) {
++@@ -85,6 +94,7 @@
++         obj-&gt;popularity = 0;
++         atomic_set(&amp;obj-&gt;refcnt, 1); /* The cache holds a reference */
++         spin_lock_init(&amp;obj-&gt;lock);
+++        INIT_RCU_HEAD(&amp;obj-&gt;rcu);
++
++         spin_lock_irqsave(&amp;cache_lock, flags);
++         __cache_add(obj);
++@@ -104,12 +114,11 @@
++ struct object *cache_find(int id)
++ {
++         struct object *obj;
++-        unsigned long flags;
++
++-        spin_lock_irqsave(&amp;cache_lock, flags);
+++        rcu_read_lock();
++         obj = __cache_find(id);
++         if (obj)
++                 object_get(obj);
++-        spin_unlock_irqrestore(&amp;cache_lock, flags);
+++        rcu_read_unlock();
++         return obj;
++ }
++</programlisting>
++
++<para>
++Note that the reader will alter the
++<structfield>popularity</structfield> member in
++<function>__cache_find()</function>, and now it doesn't hold a lock.
++One solution would be to make it an <type>atomic_t</type>, but for
++this usage, we don't really care about races: an approximate result is
++good enough, so I didn't change it.
++</para>
++
++<para>
++The result is that <function>cache_find()</function> requires no
++synchronization with any other functions, so is almost as fast on SMP
++as it would be on UP.
++</para>
++
++<para>
++There is a furthur optimization possible here: remember our original
++cache code, where there were no reference counts and the caller simply
++held the lock whenever using the object?  This is still possible: if
++you hold the lock, noone can delete the object, so you don't need to
++get and put the reference count.
++</para>
++
++<para>
++Now, because the 'read lock' in RCU is simply disabling preemption, a
++caller which always has preemption disabled between calling
++<function>cache_find()</function> and
++<function>object_put()</function> does not need to actually get and
++put the reference count: we could expose
++<function>__cache_find()</function> by making it non-static, and
++such callers could simply call that.
++</para>
++<para>
++The benefit here is that the reference count is not written to: the
++object is not altered in any way, which is much faster on SMP
++machines due to caching.
++</para>
++  </sect1>
++
++   <sect1 id="per-cpu">
++    <title>Per-CPU Data</title>
+     <para>
+-      In this approach, an object has an owner, who sets the
+-      reference count to one.  Whenever you get a pointer to the
+-      object, you increment the reference count (a `get' operation).
+-      Whenever you relinquish a pointer, you decrement the reference
+-      count (a `put' operation).  When the owner wants to destroy
+-      it, they mark it dead, and do a put.
++      Another technique for avoiding locking which is used fairly
++      widely is to duplicate information for each CPU.  For example,
++      if you wanted to keep a count of a common condition, you could
++      use a spin lock and a single counter.  Nice and simple.
+     </para>
+     <para>
+-      Whoever drops the reference count to zero (usually implemented
+-      with <function>atomic_dec_and_test()</function>) actually cleans 
+-      up and frees the object.
++      If that was too slow (it's usually not, but if you've got a
++      really big machine to test on and can show that it is), you
++      could instead use a counter for each CPU, then none of them need
++      an exclusive lock.  See <function>DEFINE_PER_CPU()</function>,
++      <function>get_cpu_var()</function> and
++      <function>put_cpu_var()</function>
++      (<filename class=headerfile>include/linux/percpu.h</filename>).
+     </para>
+     <para>
+-      This means that you are guaranteed that the object won't
+-      vanish underneath you, even though you no longer have a lock
+-      for the collection.
++      Of particular use for simple per-cpu counters is the
++      <type>local_t</type> type, and the
++      <function>cpu_local_inc()</function> and related functions,
++      which are more efficient than simple code on some architectures
++      (<filename class=headerfile>include/asm/local.h</filename>).
+     </para>
+     <para>
+-      Here's some skeleton code:
++      Note that there is no simple, reliable way of getting an exact
++      value of such a counter, without introducing more locks.  This
++      is not a problem for some uses.
+     </para>
++   </sect1>
+-    <programlisting>
+-        void create_foo(struct foo *x)
+-        {
+-                atomic_set(&amp;x-&gt;use, 1);
+-                spin_lock_bh(&amp;list_lock);
+-                ... insert in list ...
+-                spin_unlock_bh(&amp;list_lock);
+-        }
+-
+-        struct foo *get_foo(int desc)
+-        {
+-                struct foo *ret;
+-
+-                spin_lock_bh(&amp;list_lock);
+-                ... find in list ...
+-                if (ret) atomic_inc(&amp;ret-&gt;use);
+-                spin_unlock_bh(&amp;list_lock);
+-
+-                return ret;
+-        }
++   <sect1 id="mostly-hardirq">
++    <title>Data Which Mostly Used By An IRQ Handler</title>
+-        void put_foo(struct foo *x)
+-        {
+-                if (atomic_dec_and_test(&amp;x-&gt;use))
+-                        kfree(foo);
+-        }
++    <para>
++      If data is always accessed from within the same IRQ handler, you
++      don't need a lock at all: the kernel already guarantees that the
++      irq handler will not run simultaneously on multiple CPUs.
++    </para>
++    <para>
++      Manfred Spraul points out that you can still do this, even if
++      the data is very occasionally accessed in user context or
++      softirqs/tasklets.  The irq handler doesn't use a lock, and
++      all other accesses are done as so:
++    </para>
++
++<programlisting>
++      spin_lock(&amp;lock);
++      disable_irq(irq);
++      ...
++      enable_irq(irq);
++      spin_unlock(&amp;lock);
++</programlisting>
++    <para>
++      The <function>disable_irq()</function> prevents the irq handler
++      from running (and waits for it to finish if it's currently
++      running on other CPUs).  The spinlock prevents any other
++      accesses happening at the same time.  Naturally, this is slower
++      than just a <function>spin_lock_irq()</function> call, so it
++      only makes sense if this type of access happens extremely
++      rarely.
++    </para>
++   </sect1>
++  </chapter>
+-        void destroy_foo(struct foo *x)
+-        {
+-                spin_lock_bh(&amp;list_lock);
+-                ... remove from list ...
+-                spin_unlock_bh(&amp;list_lock);
++ <chapter id="sleeping-things">
++    <title>What Functions Are Safe To Call From Interrupts?</title>
+-                put_foo(x);
+-        }
+-    </programlisting>
++    <para>
++      Many functions in the kernel sleep (ie. call schedule())
++      directly or indirectly: you can never call them while holding a
++      spinlock, or with preemption disabled.  This also means you need
++      to be in user context: calling them from an interrupt is illegal.
++    </para>
+-    <sect2 id="helpful-macros">
+-     <title>Macros To Help You</title>
+-     <para>
+-       There are a set of debugging macros tucked inside
+-       <filename class=headerfile>include/linux/netfilter_ipv4/lockhelp.h</filename>
+-       and <filename class=headerfile>listhelp.h</filename>: these are very
+-       useful for ensuring that locks are held in the right places to protect
+-       infrastructure.
+-     </para>
+-    </sect2>
+-   </sect1>
+-   
+-   <sect1 id="sleeping-things">
+-    <title>Things Which Sleep</title>
++   <sect1 id="sleeping">
++    <title>Some Functions Which Sleep</title>
+     <para>
+-      You can never call the following routines while holding a
+-      spinlock, as they may sleep.  This also means you need to be in
+-      user context.
++      The most common ones are listed below, but you usually have to
++      read the code to find out if other calls are safe.  If everyone
++      else who calls it can sleep, you probably need to be able to
++      sleep, too.  In particular, registration and deregistration
++      functions usually expect to be called from user context, and can
++      sleep.
+     </para>
+     <itemizedlist>
+@@ -961,106 +1887,31 @@
+      </listitem>
+     </itemizedlist>
+-    <para>
+-     <function>printk()</function> can be called in
+-     <emphasis>any</emphasis> context, interestingly enough.
+-    </para>
+-   </sect1>
+-
+-   <sect1 id="sparc">
+-    <title>The Fucked Up Sparc</title>
++   <sect1 id="dont-sleep">
++    <title>Some Functions Which Don't Sleep</title>
+     <para>
+-      Alan Cox says <quote>the irq disable/enable is in the register
+-      window on a sparc</quote>.  Andi Kleen says <quote>when you do
+-      restore_flags in a different function you mess up all the
+-      register windows</quote>.
+-    </para>
+-
+-    <para>
+-      So never pass the flags word set by 
+-      <function>spin_lock_irqsave()</function> and brethren to another 
+-      function (unless it's declared <type>inline</type>.  Usually no-one 
+-      does this, but now you've been warned.  Dave Miller can never do 
+-      anything in a straightforward manner (I can say that, because I have
+-      pictures of him and a certain PowerPC maintainer in a compromising 
+-      position).
+-    </para>
+-   </sect1>
+-
+-   <sect1 id="racing-timers">
+-    <title>Racing Timers: A Kernel Pastime</title>
+-
+-    <para>
+-      Timers can produce their own special problems with races.
+-      Consider a collection of objects (list, hash, etc) where each
+-      object has a timer which is due to destroy it.
++     Some functions are safe to call from any context, or holding
++     almost any lock.
+     </para>
+-    <para>
+-      If you want to destroy the entire collection (say on module
+-      removal), you might do the following:
+-    </para>
+-
+-    <programlisting>
+-        /* THIS CODE BAD BAD BAD BAD: IF IT WAS ANY WORSE IT WOULD USE
+-           HUNGARIAN NOTATION */
+-        spin_lock_bh(&amp;list_lock);
+-
+-        while (list) {
+-                struct foo *next = list-&gt;next;
+-                del_timer(&amp;list-&gt;timer);
+-                kfree(list);
+-                list = next;
+-        }
+-
+-        spin_unlock_bh(&amp;list_lock);
+-    </programlisting>
+-
+-    <para>
+-      Sooner or later, this will crash on SMP, because a timer can
+-      have just gone off before the <function>spin_lock_bh()</function>, 
+-      and it will only get the lock after we 
+-      <function>spin_unlock_bh()</function>, and then try to free
+-      the element (which has already been freed!).
+-    </para>
+-
+-    <para>
+-      This can be avoided by checking the result of 
+-      <function>del_timer()</function>: if it returns
+-      <returnvalue>1</returnvalue>, the timer has been deleted.  
+-      If <returnvalue>0</returnvalue>, it means (in this
+-      case) that it is currently running, so we can do:
+-    </para>
+-
+-    <programlisting>
+-        retry:  
+-                spin_lock_bh(&amp;list_lock);
+-
+-                while (list) {
+-                        struct foo *next = list-&gt;next;
+-                        if (!del_timer(&amp;list-&gt;timer)) {
+-                                /* Give timer a chance to delete this */
+-                                spin_unlock_bh(&amp;list_lock);
+-                                goto retry;
+-                        }
+-                        kfree(list);
+-                        list = next;
+-                }
+-
+-                spin_unlock_bh(&amp;list_lock);
+-    </programlisting>
+-
+-    <para>
+-      Another common problem is deleting timers which restart
+-      themselves (by calling <function>add_timer()</function> at the end 
+-      of their timer function).  Because this is a fairly common case 
+-      which is prone to races, you should use <function>del_timer_sync()</function> 
+-      (<filename class=headerfile>include/linux/timer.h</filename>) 
+-      to handle this case.  It returns the number of times the timer 
+-      had to be deleted before we finally stopped it from adding itself back 
+-      in.
+-    </para>
++    <itemizedlist>
++     <listitem>
++      <para>
++      <function>printk()</function>
++      </para>
++     </listitem>
++     <listitem>
++      <para>
++        <function>kfree()</function>
++      </para>
++     </listitem>
++     <listitem>
++      <para>
++      <function>add_timer()</function> and <function>del_timer()</function>
++      </para>
++     </listitem>
++    </itemizedlist>
+    </sect1>
+   </chapter>
+@@ -1101,8 +1952,9 @@
+     <para>
+       Thanks to Martin Pool, Philipp Rumpf, Stephen Rothwell, Paul
+-      Mackerras, Ruedi Aschwanden, Alan Cox, Manfred Spraul and Tim
+-      Waugh for proofreading, correcting, flaming, commenting.
++      Mackerras, Ruedi Aschwanden, Alan Cox, Manfred Spraul, Tim
++      Waugh, Pete Zaitcev, James Morris, Robert Love, Paul McKenney,
++      John Ashby for proofreading, correcting, flaming, commenting.
+     </para>
+     <para>
+@@ -1113,12 +1965,27 @@
+   <glossary id="glossary">
+    <title>Glossary</title>
++   <glossentry id="gloss-preemption">
++    <glossterm>preemption</glossterm>
++     <glossdef>
++      <para>
++        Prior to 2.5, or when <symbol>CONFIG_PREEMPT</symbol> is
++        unset, processes in user context inside the kernel would not
++        preempt each other (ie. you had that CPU until you have it up,
++        except for interrupts).  With the addition of
++        <symbol>CONFIG_PREEMPT</symbol> in 2.5.4, this changed: when
++        in user context, higher priority tasks can "cut in": spinlocks
++        were changed to disable preemption, even on UP.
++     </para>
++    </glossdef>
++   </glossentry>
++
+    <glossentry id="gloss-bh">
+     <glossterm>bh</glossterm>
+      <glossdef>
+       <para>
+         Bottom Half: for historical reasons, functions with
+-        `_bh' in them often now refer to any software interrupt, e.g.
++        '_bh' in them often now refer to any software interrupt, e.g.
+         <function>spin_lock_bh()</function> blocks any software interrupt 
+         on the current CPU.  Bottom halves are deprecated, and will 
+         eventually be replaced by tasklets.  Only one bottom half will be 
+@@ -1132,8 +1999,7 @@
+     <glossdef>
+      <para>
+        Hardware interrupt request.  <function>in_irq()</function> returns 
+-       <returnvalue>true</returnvalue> in a hardware interrupt handler (it 
+-       also returns true when interrupts are blocked).
++       <returnvalue>true</returnvalue> in a hardware interrupt handler.
+      </para>
+     </glossdef>
+    </glossentry>
+@@ -1144,8 +2010,7 @@
+      <para>
+        Not user context: processing a hardware irq or software irq.
+        Indicated by the <function>in_interrupt()</function> macro 
+-       returning <returnvalue>true</returnvalue> (although it also
+-       returns true when interrupts or BHs are blocked).
++       returning <returnvalue>true</returnvalue>.
+      </para>
+     </glossdef>
+    </glossentry>
+@@ -1161,35 +2026,40 @@
+    </glossentry>
+    <glossentry id="gloss-softirq">
+-    <glossterm>softirq</glossterm>
++    <glossterm>Software Interrupt / softirq</glossterm>
+     <glossdef>
+      <para>
+-       Strictly speaking, one of up to 32 enumerated software
++       Software interrupt handler.  <function>in_irq()</function> returns
++       <returnvalue>false</returnvalue>; <function>in_softirq()</function>
++       returns <returnvalue>true</returnvalue>.  Tasklets and softirqs
++      both fall into the category of 'software interrupts'.
++     </para>
++     <para>
++       Strictly speaking a softirq is one of up to 32 enumerated software
+        interrupts which can run on multiple CPUs at once.
+-       Sometimes used to refer to tasklets and bottom halves as
++       Sometimes used to refer to tasklets as
+        well (ie. all software interrupts).
+      </para>
+     </glossdef>
+    </glossentry>
+-   <glossentry id="gloss-swinterrupt">
+-    <glossterm>Software Interrupt / Software IRQ</glossterm>
++   <glossentry id="gloss-tasklet">
++    <glossterm>tasklet</glossterm>
+     <glossdef>
+      <para>
+-       Software interrupt handler.  <function>in_irq()</function> returns 
+-       <returnvalue>false</returnvalue>; <function>in_softirq()</function>
+-       returns <returnvalue>true</returnvalue>.  Tasklets, softirqs and 
+-       bottom halves all fall into the category of `software interrupts'.
++       A dynamically-registrable software interrupt,
++       which is guaranteed to only run on one CPU at a time.
+      </para>
+     </glossdef>
+    </glossentry>
+-   <glossentry id="gloss-tasklet">
+-    <glossterm>tasklet</glossterm>
++   <glossentry id="gloss-timers">
++    <glossterm>timer</glossterm>
+     <glossdef>
+      <para>
+-       A dynamically-registrable software interrupt,
+-       which is guaranteed to only run on one CPU at a time.
++       A dynamically-registrable software interrupt, which is run at
++       (or close to) a given time.  When running, it is just like a
++       tasklet (in fact, they are called from the TIMER_SOFTIRQ).
+      </para>
+     </glossdef>
+    </glossentry>
+@@ -1207,10 +2077,11 @@
+     <glossterm>User Context</glossterm>
+     <glossdef>
+      <para>
+-       The kernel executing on behalf of a particular
+-       process or kernel thread (given by the <function>current()</function>
+-       macro.)  Not to be confused with userspace.  Can be interrupted by 
+-       software  or hardware interrupts.
++       The kernel executing on behalf of a particular process (ie. a
++       system call or trap) or kernel thread.  You can tell which
++       process with the <symbol>current</symbol> macro.)  Not to
++       be confused with userspace.  Can be interrupted by software or
++       hardware interrupts.
+      </para>
+     </glossdef>
+    </glossentry>
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/dvb/cards.txt     2003-12-28 23:22:41.000000000 -0800
+@@ -0,0 +1,63 @@
++Hardware supported by the linuxtv.org DVB drivers
++=================================================
++
++  Generally, the DVB hardware manufacturers frequently change the
++  frontends (i.e. tuner / demodulator units) used, usually without
++  changing the product name, revision number or specs. Some cards
++  are also available in versions with different frontends for
++  DVB-S/DVB-C/DVB-T. Thus the frontend drivers are listed seperately.
++
++  Note 1: There is no guarantee that every frontend driver works
++  out-of-the box with every card, because of different wiring.
++
++  Note 2: The demodulator chips can be used with a variety of
++  tuner/PLL chips, and not all combinations are supported. Often
++  the demodulator and tuner/PLL chip are inside a metal box for
++  shielding, and the whole metal box has its own part number.
++
++
++o Frontends drivers: 
++  - dvb_dummy_fe: for testing...
++  DVB-S:
++   - alps_bsrv2               : Alps BSRV2 (ves1893 demodulator)
++   - cx24110          : Conexant HM1221/HM1811 (cx24110 or cx24106 demod, cx24108 PLL)
++   - grundig_29504-491        : Grundig 29504-491 (Philips TDA8083 demodulator), tsa5522 PLL
++   - mt312            : Zarlink mt312 or Mitel vp310 demodulator, sl1935 or tsa5059 PLL
++   - stv0299          : Alps BSRU6 (tsa5059 PLL), LG TDQB-S00x (tsa5059 PLL),
++                        LG TDQF-S001F (sl1935 PLL), Philips SU1278 (tua6100 PLL), 
++                        Philips SU1278SH (tsa5059 PLL)
++  DVB-C:
++   - ves1820          : various (ves1820 demodulator, sp5659c or spXXXX PLL)
++   - at76c651         : Atmel AT76c651(B) with DAT7021 PLL
++  DVB-T:
++   - alps_tdlb7               : Alps TDLB7 (sp8870 demodulator, sp5659 PLL)
++   - alps_tdmb7               : Alps TDMB7 (cx22700 demodulator)
++   - grundig_29504-401        : Grundig 29504-401 (LSI L64781 demodulator), tsa5060 PLL
++   - tda1004x         : Philips tda10045h (td1344 or tdm1316l PLL)
++   - nxt6000          : Alps TDME7 (MITEL SP5659 PLL), Alps TDED4 (TI ALP510 PLL),
++                                Comtech DVBT-6k07 (SP5730 PLL)
++                                (NxtWave Communications NXT6000 demodulator)
++
++
++o Cards based on the Phillips saa7146 multimedia PCI bridge chip:
++  - TI AV7110 based cards (i.e. with hardware MPEG decoder):
++    - Siemens/Technotrend/Hauppauge PCI DVB card revision 1.1, 1.3, 1.5, 1.6, 2.1
++      (aka Hauppauge Nexus)
++  - "budget" cards (i.e. without hardware MPEG decoder):
++    - Technotrend Budget / Hauppauge WinTV-Nova PCI Cards
++    - SATELCO Multimedia PCI
++    - KNC1 DVB-S
++
++o Cards based on the B2C2 Inc. FlexCopII:
++  - Technisat SkyStar2 PCI DVB
++
++o Cards based on the Conexant Bt8xx PCI bridge:
++  - Pinnacle PCTV Sat DVB
++  - Nebula Electronics DigiTV
++
++o Technotrend / Hauppauge DVB USB devices:
++  - Nova USB
++  - DEC 2000-T
++
++o Preliminary support for the analog module of the Siemens DVB-C PCI card
++
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/dvb/contributors.txt      2003-12-28 23:22:41.000000000 -0800
+@@ -0,0 +1,54 @@
++Thanks go to the following people for patches and contributions:
++
++Michael Hunold <m.hunold@gmx.de>
++  for the initial saa7146 driver and it's recent overhaul
++
++Christian Theiss
++  for his work on the initial Linux DVB driver
++
++Marcus Metzler <mocm@metzlerbros.de>
++Ralph Metzler <rjkm@metzlerbros.de>
++  for their contining work on the DVB driver
++
++Michael Holzt <kju@debian.org>
++  for his contributions to the dvb-net driver
++
++Diego Picciani <d.picciani@novacomp.it>
++  for CyberLogin for Linux which allows logging onto EON
++  (in case you are wondering where CyberLogin is, EON changed its login 
++  procedure and CyberLogin is no longer used.)
++
++Martin Schaller <martin@smurf.franken.de>
++  for patching the cable card decoder driver
++
++Klaus Schmidinger <Klaus.Schmidinger@cadsoft.de>
++  for various fixes regarding tuning, OSD and CI stuff and his work on VDR
++
++Steve Brown <sbrown@cortland.com>
++  for his AFC kernel thread
++
++Christoph Martin <martin@uni-mainz.de>
++  for his LIRC infrared handler
++
++Andreas Oberritter <andreas@oberritter.de>
++Florian Schirmer <jolt@tuxbox.org>
++...and all the other dBox2 people
++  for many bugfixes in the generic DVB Core and their work on the 
++  dBox2 port of the DVB driver
++
++Oliver Endriss <o.endriss@gmx.de>
++  for many bugfixes
++
++Andrew de Quincey <adq_dvb@lidskialf.net>
++  for the tda1004x frontend driver, and various bugfixes
++
++Peter Schildmann <peter.schildmann@web.de>
++  for the driver for the Technisat SkyStar2 PCI DVB card
++
++Vadim Catana <skystar@moldova.cc>
++Roberto Ragusa <r.ragusa@libero.it>
++Augusto Cardoso <augusto@carhil.net>
++  for all the work for the FlexCopII chipset by B2C2,Inc.
++
++(If you think you should be in this list, but you are not, drop a
++ line to the DVB mailing list)
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/dvb/faq.txt       2003-12-28 23:22:41.000000000 -0800
+@@ -0,0 +1,109 @@
++Some very frequently asked questions about linuxtv-dvb
++
++1. The signal seems to die a few seconds after tuning.
++
++      It's not a bug, it's a feature. Because the frontends have
++      significant power requirements (and hence get very hot), they
++      are powered down if they are unused (i.e. if the frontend device
++      is closed). The dvb-core.o module paramter "dvb_shutdown_timeout"
++      allow you to change the timeout (default 5 seconds). Setting the
++      timeout to 0 disables the timeout feature.
++
++2. How can I watch TV?
++
++      The driver distribution includes some simple utilities which
++      are mainly intended for testing and to demonstrate how the
++      DVB API works.
++
++      Depending on whether you have a DVB-S, DVB-C or DVB-T card, use
++      apps/szap/szap, czap or tzap. You must supply a channel list
++      in ~/.[sct]zap/channels.conf. If you are lucky you can just copy
++      one of the supplied channel lists, or you can create a new one
++      by running apps/scan/scan. If you run scan on an unknown network
++      you might have to supply some start data in apps/scan/initial.h.
++
++      If you have a card with a built-in hardware MPEG-decoder the
++      drivers create a video4linux device (/dev/v4l/video0) which
++      you can use to watch TV with any v4l application. xawtv is known
++      to work. Note that you cannot change channels with xawtv, you
++      have to zap using [sct]zap. If you want a nice application for
++      TV watching and record/playback, have a look at VDR.
++
++      If your card does not have a hardware MPEG decoder you need
++      a software MPEG decoder. Mplayer or xine are known to work.
++      Newsflash: MythTV also has DVB support now.
++      Note: Only very recent versions of Mplayer and xine can decode.
++      MPEG2 transport streams (TS) directly. Then, run
++      '[sct]zap channelname -r' in one xterm, and keep it running,
++      and start 'mplayer - < /dev/dvb/adapter0/dvr0' or 
++      'xine stdin://mpeg2 < /dev/dvb/adapter0/dvr0' in a second xterm.
++      That's all far from perfect, but it seems no one has written
++      a nice DVB application which includes a builtin software MPEG
++      decoder yet.
++
++      Newsflash: Newest xine directly supports DVB. Just copy your
++      channels.conf to ~/.xine and start 'xine dvb://', or select
++      the DVB button in the xine GUI. Channel switching works using the
++      numpad pgup/pgdown (NP9 / NP3) keys to scroll through the channel osd
++      menu and pressing numpad-enter to switch to the selected channel.
++
++      Note: Older versions of xine and mplayer understand MPEG program
++      streams (PS) only, and can be used in conjunction with the
++      ts2ps tool from the Metzler Brother's dvb-mpegtools package.
++
++3. Which other DVB applications exist?
++
++      http://www.cadsoft.de/people/kls/vdr/
++              Klaus Schmidinger's Video Disk Recorder
++
++      http://www.metzlerbros.org/dvb/
++              Metzler Bros. DVB development; alternate drivers and
++              DVB utilities, include dvb-mpegtools and tuxzap.
++
++      http://www.linuxstb.org/
++      http://sourceforge.net/projects/dvbtools/
++              Dave Chapman's dvbtools package, including
++              dvbstream and dvbtune
++
++      http://www.linuxdvb.tv/
++              Henning Holtschneider's site with many interesting
++              links and docs
++
++      http://www.dbox2.info/
++              LinuxDVB on the dBox2
++
++      http://www.tuxbox.org/
++      http://cvs.tuxbox.org/
++              the TuxBox CVS many interesting DVB applications and the dBox2
++              DVB source
++
++      http://sourceforge.net/projects/dvbsak/
++              DVB Swiss Army Knife library and utilities
++
++      http://www.nenie.org/misc/mpsys/
++              MPSYS: a MPEG2 system library and tools
++
++      http://mplayerhq.hu/
++              mplayer
++
++      http://xine.sourceforge.net/
++      http://xinehq.de/
++              xine
++
++      http://www.mythtv.org/
++              MythTV - analog TV PVR, but now with DVB support, too
++              (with software MPEG decode)
++
++4. Can't get a signal tuned correctly
++
++      If you are using a Technotrend/Hauppauge DVB-C card *without* analog
++      module, you might have to use module parameter adac=-1 (dvb-ttpci.o).
++
++5. The dvb_net device doesn't give me any multicast packets
++
++      Check your routes if they include the multicast address range.
++      Additionally make sure that "source validation by reversed path
++      lookup" is disabled:
++        $ "echo 0 > /proc/sys/net/ipv4/conf/dvb0/rp_filter"
++
++eof
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/dvb/firmware.txt  2003-12-28 23:22:41.000000000 -0800
+@@ -0,0 +1,116 @@
++Some DVB cards and many newer frontends require proprietary,
++binary-only firmware.
++
++The DVB drivers will be converted to use the request_firmware()
++hotplug interface (see linux/Documentation/firmware_class/).
++(CONFIG_FW_LOADER)
++
++The firmware can be loaded automatically via the hotplug manager
++or manually with the steps described below.
++
++Currently the drivers still use various different methods
++to load their firmwares, so here's just a short list of the
++current state:
++
++- dvb-ttpci: driver uses firmware hotplug interface
++- ttusb-budget: firmware is compiled in (dvb-ttusb-dspbootcode.h)
++- sp887x: firmware is compiled in (sp887x_firm.h)
++- alps_tdlb7: firmware is loaded from path specified by
++              "mcfile" module parameter; the binary must be
++              extracted from the Windows driver (Sc_main.mc).
++- tda1004x: firmware is loaded from path specified in
++              DVB_TDA1004X_FIRMWARE_FILE kernel config
++              variable (default /etc/dvb/tda1004x.bin); the
++              firmware binary must be extracted from the windows
++              driver
++- ttusb-dec: see "ttusb-dec.txt" for details
++
++1) Automatic firmware loading
++
++You need to install recent hotplug scripts if your distribution did not do it
++for you already, especially the  /etc/hotplug/firmware.agent.
++http://linux-hotplug.sourceforge.net/ (Call /sbin/hotplug without arguments
++to find out if the firmware agent is installed.)
++
++The firmware.agent script expects firmware binaries in
++/usr/lib/hotplug/firmware/. To avoid naming and versioning
++conflicts we propose the following naming scheme:
++
++  /usr/lib/hotplug/firmware/dvb-{driver}-{ver}.fw     for MPEG decoders etc.
++  /usr/lib/hotplug/firmware/dvb-fe-{driver}-{ver}.fw  for frontends
++
++  {driver} name is the basename of the driver kernel module (e.g. dvb-ttpci)
++  {ver} is a version number/name that should change only when the
++  driver/firmware internal API changes (so users are free to install the
++  latest firmware compatible with the driver).
++
++2) Manually loading the firmware into a driver
++   (currently only the dvb-ttpci / av7110 driver supports this)
++   
++Step a) Mount sysfs-filesystem.
++
++Sysfs provides a means to export kernel data structures, their attributes,
++and the linkages between them to userspace. 
++
++For detailed informations have a look at Documentation/filesystems/sysfs.txt 
++All you need to know at the moment is that firmware loading only works through
++sysfs.
++
++> mkdir /sys
++> mount -t sysfs sysfs /sys
++
++Step b) Exploring the firmware loading facilities
++
++Firmware_class support is located in
++/sys/class/firmware
++
++> dir /sys/class/firmware
++
++The "timeout" values specifies the amount of time that is waited before the
++firmware upload  process is cancelled. The default values is 10 seconds. If
++you use a hotplug script for the firmware upload, this is sufficient. If
++you want to upload the firmware by hand, however, this might be too fast.
++
++> echo "180" > /sys/class/firmware/timeout
++
++Step c) Getting a usable firmware file for the dvb-ttpci driver/av7110 card.
++
++You can download the firmware files from
++http://www.linuxtv.org/download/dvb/
++
++Please note that in case of the dvb-ttpci driver this is *not* the "Root"
++file you probably know from the 2.4 DVB releases driver.
++
++> wget http://www.linuxtv.org/download/dvb/dvb-ttpci-01.fw
++gets you the version 01 of the firmware fot the ttpci driver.
++
++Step d) Loading the dvb-ttpci driver and loading the firmware
++
++"modprobe" will take care that every needed module will be loaded
++automatically (except the frontend driver)
++
++> modprobe dvb-ttpci
++
++The "modprobe" process will hang until
++a) you upload the firmware or
++b) the timeout occurs.
++
++Change to another terminal and have a look at 
++
++> dir /sys/class/firmware/
++
++total 0
++drwxr-xr-x    2 root     root            0 Jul 29 11:00 0000:03:05.0
++-rw-r--r--    1 root     root            0 Jul 29 10:41 timeout
++
++"0000:03:05.0" is the id for my dvb-c card. It depends on the pci slot,
++so it changes if you plug the card to different slots.
++
++You can upload the firmware like that:
++
++> export DEVDIR=/sys/class/firmware/0000\:03\:05.0
++> echo 1 > $DEVDIR/loading
++> cat dvb-ttpci-01.fw > $DEVDIR/data
++> echo 0 > $DEVDIR/loading
++
++That's it. The driver should be up and running now.
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/dvb/readme.txt    2003-12-28 23:22:41.000000000 -0800
+@@ -0,0 +1,39 @@
++Linux Digital Video Broadcast (DVB) subsystem
++=============================================
++
++The main development site and CVS repository for these
++drivers is http://linuxtv.org/.
++
++The developer mailing list linux-dvb is also hosted there,
++see http://linuxtv.org/mailinglists.xml. Please check
++the archive http://linuxtv.org/mailinglists/linux-dvb/
++before asking newbie questions on the list.
++
++API documentation, utilities and test/example programs
++are available as part of the old driver package for Linux 2.4
++(linuxtv-dvb-1.0.x.tar.gz), or from CVS (module DVB).
++We plan to split this into separate packages, but it's not
++been done yet.
++
++http://linuxtv.org/download/dvb/
++
++What's inside this directory:
++
++"cards.txt" 
++contains a list of supported hardware.
++
++"contributors.txt"
++is the who-is-who of DVB development
++
++"faq.txt"
++contains frequently asked questions and their answers.
++
++"firmware.txt" 
++contains informations for required external firmware
++files and where to get them.
++
++"ttusb-dec.txt"
++contains detailed informations about the
++TT DEC2000/DEC3000 USB DVB hardware.
++
++Good luck and have fun!
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/dvb/ttusb-dec.txt 2003-12-28 23:22:41.000000000 -0800
+@@ -0,0 +1,52 @@
++TechnoTrend/Hauppauge DEC USB Driver
++====================================
++
++Driver Status
++-------------
++
++Supported:
++      DEC2000-t
++      Linux Kernels 2.4 and 2.6
++      Video Streaming
++      Audio Streaming
++      Channel Zapping
++      Hotplug firmware loader under 2.6 kernels
++
++In Progress:
++      DEC3000-s
++
++To Do:
++      Section data
++      Teletext streams
++      Tuner status information
++      DVB network interface
++      Streaming video PC->DEC
++
++Note: Since section data can not be retreived yet, scan apps will not work.
++
++Getting the Firmware
++--------------------
++Currently, the driver only works with v2.15a of the firmware.  The firmwares
++can be obtained in this way:
++
++wget http://hauppauge.lightpath.net/de/dec215a.exe
++unzip -j dec215a.exe Software/Oem/STB/App/Boot/STB_PC_T.bin
++unzip -j dec215a.exe Software/Oem/STB/App/Boot/STB_PC_S.bin
++
++
++Compilation Notes for 2.4 kernels
++---------------------------------
++For 2.4 kernels the firmware for the DECs is compiled into the driver itself.
++The firmwares are expected to be in /etc/dvb at compilation time.
++
++mv STB_PC_T.bin /etc/dvb/dec2000t.bin
++mv STB_PC_S.bin /etc/dvb/dec3000s.bin
++
++
++Hotplug Firmware Loading for 2.6 kernels
++----------------------------------------
++For 2.6 kernels the firmware is loaded at the point that the driver module is
++loaded.  See linux/Documentation/dvb/FIRMWARE for more information.
++
++mv STB_PC_T.bin /usr/lib/hotplug/firmware/dec2000t.bin
++mv STB_PC_S.bin /usr/lib/hotplug/firmware/dec3000s.bin
+--- linux-2.6.0/Documentation/fb/aty128fb.txt  2003-06-14 12:17:56.000000000 -0700
++++ 25/Documentation/fb/aty128fb.txt   2003-12-28 23:23:06.000000000 -0800
+@@ -32,7 +32,7 @@ resolutions.
+ You should compile in both vgacon (to boot if you remove your Rage128 from
+ box) and aty128fb (for graphics mode). You should not compile-in vesafb
+ unless you have primary display on non-Rage128 VBE2.0 device (see 
+-Documentation/vesafb.txt for details).
++Documentation/fb/vesafb.txt for details).
+ X11
+--- linux-2.6.0/Documentation/fb/matroxfb.txt  2003-06-14 12:18:30.000000000 -0700
++++ 25/Documentation/fb/matroxfb.txt   2003-12-28 23:23:06.000000000 -0800
+@@ -31,7 +31,7 @@ pass to the kernel this command line: "v
+ You should compile in both vgacon (to boot if you remove you Matrox from
+ box) and matroxfb (for graphics mode). You should not compile-in vesafb
+ unless you have primary display on non-Matrox VBE2.0 device (see 
+-Documentation/vesafb.txt for details).
++Documentation/fb/vesafb.txt for details).
+ Currently supported video modes are (through vesa:... interface, PowerMac
+ has [as addon] compatibility code):
+--- linux-2.6.0/Documentation/filesystems/Locking      2003-08-22 19:23:39.000000000 -0700
++++ 25/Documentation/filesystems/Locking       2003-12-28 23:22:12.000000000 -0800
+@@ -420,7 +420,7 @@ transfer:  no
+ prototypes:
+       void (*open)(struct vm_area_struct*);
+       void (*close)(struct vm_area_struct*);
+-      struct page *(*nopage)(struct vm_area_struct*, unsigned long, int);
++      struct page *(*nopage)(struct vm_area_struct*, unsigned long, int *);
+ locking rules:
+               BKL     mmap_sem
+--- linux-2.6.0/Documentation/filesystems/proc.txt     2003-11-09 16:45:05.000000000 -0800
++++ 25/Documentation/filesystems/proc.txt      2003-12-28 23:26:39.000000000 -0800
+@@ -900,6 +900,15 @@ super-nr shows the number of currently a
+ Every mounted file system needs a super block, so if you plan to mount lots of
+ file systems, you may want to increase these numbers.
++aio-nr and aio-max-nr
++---------------------
++
++aio-nr is the running total of the number of events specified on the
++io_setup system call for all currently active aio contexts.  If aio-nr
++reaches aio-max-nr then io_setup will fail with EAGAIN.  Note that
++raising aio-max-nr does not result in the pre-allocation or re-sizing
++of any kernel data structures.
++
+ 2.2 /proc/sys/fs/binfmt_misc - Miscellaneous binary formats
+ -----------------------------------------------------------
+--- linux-2.6.0/Documentation/filesystems/xfs.txt      2003-10-17 15:58:03.000000000 -0700
++++ 25/Documentation/filesystems/xfs.txt       2003-12-28 23:22:28.000000000 -0800
+@@ -29,10 +29,11 @@ When mounting an XFS filesystem, the fol
+       The preferred buffered I/O size can also be altered on an
+       individual file basis using the ioctl(2) system call.
+-  ikeep
++  ikeep/noikeep
+       When inode clusters are emptied of inodes, keep them around
+-      on the disk, this is the old XFS behavior. Default is now to
+-      return the inode cluster to the free space pool.
++      on the disk (ikeep) - this is the traditional XFS behaviour
++      and is still the default for now.  Using the noikeep option,
++      inode clusters are returned to the free space pool.
+   logbufs=value
+       Set the number of in-memory log buffers.  Valid numbers range
+@@ -75,6 +76,10 @@ When mounting an XFS filesystem, the fol
+       Filesystems mounted "norecovery" must be mounted read-only or
+       the mount will fail.
++  nouuid
++      Don't check for double mounted file systems using the file system uuid.
++      This is useful to mount LVM snapshot volumes.
++
+   osyncisosync
+       Make O_SYNC writes implement true O_SYNC.  WITHOUT this option,
+       Linux XFS behaves as if an "osyncisdsync" option is used,
+@@ -108,10 +113,6 @@ When mounting an XFS filesystem, the fol
+       The "swidth" option is required if the "sunit" option has been
+       specified, and must be a multiple of the "sunit" value.
+-  nouuid
+-        Don't check for double mounted file systems using the file system uuid.
+-        This is useful to mount LVM snapshot volumes.
+-
+ sysctls
+ =======
+@@ -139,14 +140,14 @@ The following sysctls are available for 
+       Causes certain error conditions to call BUG(). Value is a bitmask; 
+       AND together the tags which represent errors which should cause panics:
+       
+-              XFS_NO_PTAG                     0LL
+-              XFS_PTAG_IFLUSH                 0x0000000000000001LL
+-              XFS_PTAG_LOGRES                 0x0000000000000002LL
+-              XFS_PTAG_AILDELETE              0x0000000000000004LL
+-              XFS_PTAG_ERROR_REPORT           0x0000000000000008LL
+-              XFS_PTAG_SHUTDOWN_CORRUPT       0x0000000000000010LL
+-              XFS_PTAG_SHUTDOWN_IOERROR       0x0000000000000020LL
+-              XFS_PTAG_SHUTDOWN_LOGERROR      0x0000000000000040LL
++              XFS_NO_PTAG                     0
++              XFS_PTAG_IFLUSH                 0x00000001
++              XFS_PTAG_LOGRES                 0x00000002
++              XFS_PTAG_AILDELETE              0x00000004
++              XFS_PTAG_ERROR_REPORT           0x00000008
++              XFS_PTAG_SHUTDOWN_CORRUPT       0x00000010
++              XFS_PTAG_SHUTDOWN_IOERROR       0x00000020
++              XFS_PTAG_SHUTDOWN_LOGERROR      0x00000040
+       This option is intended for debugging only.             
+@@ -165,6 +166,21 @@ The following sysctls are available for 
+       Controls whether unprivileged users can use chown to "give away"
+       a file to another user.
++  fs.xfs.inherit_sync         (Min: 0  Default: 1  Max 1)
++      Setting this to "1" will cause the "sync" flag set
++      by the chattr(1) command on a directory to be
++      inherited by files in that directory.
++
++  fs.xfs.inherit_nodump               (Min: 0  Default: 1  Max 1)
++      Setting this to "1" will cause the "nodump" flag set
++      by the chattr(1) command on a directory to be
++      inherited by files in that directory.
++
++  fs.xfs.inherit_noatime      (Min: 0  Default: 1  Max 1)
++      Setting this to "1" will cause the "noatime" flag set
++      by the chattr(1) command on a directory to be
++      inherited by files in that directory.
++
+   vm.pagebuf.stats_clear      (Min: 0  Default: 0  Max: 1)
+       Setting this to "1" clears accumulated pagebuf statistics 
+       in /proc/fs/pagebuf/stat.  It then immediately reset to "0".
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/andthen 2003-12-28 23:21:06.000000000 -0800
+@@ -0,0 +1,100 @@
++
++define        set_andthen
++      set var $thp=0
++      set var $thp=(struct kgdb_and_then_struct *)&kgdb_data[0]
++      set var $at_size = (sizeof kgdb_data)/(sizeof *$thp)
++      set var $at_oc=kgdb_and_then_count
++      set var $at_cc=$at_oc
++end
++
++define andthen_next
++      set var $at_cc=$arg0
++end
++
++define andthen
++      andthen_set_edge
++      if ($at_cc >= $at_oc)
++              printf "Outside window.  Window size is %d\n",($at_oc-$at_low)
++      else
++              printf "%d: ",$at_cc
++              output *($thp+($at_cc++ % $at_size ))
++              printf "\n"
++      end
++end
++define andthen_set_edge
++      set var $at_oc=kgdb_and_then_count
++      set var $at_low = $at_oc - $at_size
++      if ($at_low < 0 )
++              set var $at_low = 0
++      end
++      if (( $at_cc > $at_oc) || ($at_cc < $at_low))
++              printf "Count outside of window, setting count to "
++              if ($at_cc >= $at_oc)
++                      set var $at_cc = $at_oc
++              else
++                      set var $at_cc = $at_low
++              end
++              printf "%d\n",$at_cc
++      end
++end
++
++define beforethat
++      andthen_set_edge
++      if ($at_cc <= $at_low)
++              printf "Outside window.  Window size is %d\n",($at_oc-$at_low)
++      else
++              printf "%d: ",$at_cc-1
++              output *($thp+(--$at_cc % $at_size ))
++              printf "\n"
++      end
++end
++
++document andthen_next
++      andthen_next <count>
++      .       sets the number of the event to display next. If this event
++      .       is not in the event pool, either andthen or beforethat will
++      .       correct it to the nearest event pool edge.  The event pool
++      .       ends at the last event recorded and begins <number of events>
++      .       prior to that.  If beforethat is used next, it will display
++      .       event <count> -1.
++.
++      andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
++
++
++document andthen
++      andthen
++.     displays the next event in the list.  <set_andthen> sets up to display
++.     the oldest saved event first.
++.     <count> (optional) count of the event to display.
++.     note the number of events saved is specified at configure time.
++.     if events are saved between calls to andthen the index will change
++.     but the displayed event will be the next one (unless the event buffer
++.     is overrun).
++.
++.     andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
++
++document set_andthen
++      set_andthen
++.     sets up to use the <andthen> and <beforethat> commands.
++.             if you have defined your own struct, use the above and
++.             then enter the following:
++.             p $thp=(struct kgdb_and_then_structX *)&kgdb_data[0]
++.             where <kgdb_and_then_structX> is the name of your structure.
++.
++.     andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
++
++document beforethat
++      beforethat
++.     displays the next prior event in the list. <set_andthen> sets up to
++.     display the last occuring event first.
++.
++.     note the number of events saved is specified at configure time.
++.     if events are saved between calls to beforethat the index will change
++.     but the displayed event will be the next one (unless the event buffer
++.     is overrun).
++.
++.     andthen commands are: set_andthen, andthen_next, andthen and beforethat
++end
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/debug-nmi.txt   2003-12-28 23:21:06.000000000 -0800
+@@ -0,0 +1,37 @@
++Subject: Debugging with NMI
++Date: Mon, 12 Jul 1999 11:28:31 -0500
++From: David Grothe <dave@gcom.com>
++Organization: Gcom, Inc
++To: David Grothe <dave@gcom.com>
++
++Kernel hackers:
++
++Maybe this is old hat, but it is new to me --
++
++On an ISA bus machine, if you short out the A1 and B1 pins of an ISA
++slot you will generate an NMI to the CPU.  This interrupts even a
++machine that is hung in a loop with interrupts disabled.  Used in
++conjunction with kgdb <
++ftp://ftp.gcom.com/pub/linux/src/kgdb-2.3.35/kgdb-2.3.35.tgz > you can
++gain debugger control of a machine that is hung in the kernel!  Even
++without kgdb the kernel will print a stack trace so you can find out
++where it was hung.
++
++The A1/B1 pins are directly opposite one another and the farthest pins
++towards the bracket end of the ISA bus socket.  You can stick a paper
++clip or multi-meter probe between them to short them out.
++
++I had a spare ISA bus to PC104 bus adapter around.  The PC104 end of the
++board consists of two rows of wire wrap pins.  So I wired a push button
++between the A1/B1 pins and now have an ISA board that I can stick into
++any ISA bus slot for debugger entry.
++
++Microsoft has a circuit diagram of a PCI card at
++http://www.microsoft.com/hwdev/DEBUGGING/DMPSW.HTM.  If you want to
++build one you will have to mail them and ask for the PAL equations.
++Nobody makes one comercially.
++
++[THIS TIP COMES WITH NO WARRANTY WHATSOEVER.  It works for me, but if
++your machine catches fire, it is your problem, not mine.]
++
++-- Dave (the kgdb guy)
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/gdb-globals.txt 2003-12-28 23:21:07.000000000 -0800
+@@ -0,0 +1,71 @@
++Sender: akale@veritas.com
++Date: Fri, 23 Jun 2000 19:26:35 +0530
++From: "Amit S. Kale" <akale@veritas.com>
++Organization: Veritas Software (India)
++To: Dave Grothe <dave@gcom.com>, linux-kernel@vger.rutgers.edu
++CC: David Milburn <dmilburn@wirespeed.com>,
++        "Edouard G. Parmelan" <Edouard.Parmelan@quadratec.fr>,
++        ezannoni@cygnus.com, Keith Owens <kaos@ocs.com.au>
++Subject: Re: Module debugging using kgdb
++
++Dave Grothe wrote:
++>
++> Amit:
++>
++> There is a 2.4.0 version of kgdb on our ftp site:
++> ftp://ftp.gcom.com/pub/linux/src/kgdb.  I mirrored your version of gdb
++> and loadmodule.sh there.
++>
++> Have a look at the README file and see if I go it right.  If not, send
++> me some corrections and I will update it.
++>
++> Does your version of gdb solve the global variable problem?
++
++Yes.
++Thanks to Elena Zanoni, gdb (developement version) can now calculate
++correctly addresses  of dynamically loaded object files. I have not been
++following gdb developement for sometime and am not sure when symbol
++address calculation fix is going to appear in a gdb stable version.
++
++Elena, any idea when the fix will make it to a prebuilt gdb from a
++redhat release?
++
++For the time being I have built a gdb developement version. It can be
++used for module debugging with loadmodule.sh script.
++
++The problem with calculating of module addresses with previous versions
++of gdb was as follows:
++gdb did not use base address of a section while calculating address of
++a symbol in the section in an object file loaded via 'add-symbol-file'.
++It used address of .text segment instead. Due to this addresses of
++symbols in .data, .bss etc. (e.g. global variables) were calculated incorrectly.
++
++Above mentioned fix allow gdb to use base address of a segment while
++calculating address of a symbol in it. It adds a parameter '-s' to
++'add-symbol-file' command for specifying base address of a segment.
++
++loadmodule.sh script works as follows.
++
++1. Copy a module file to target machine.
++2. Load the module on the target machine using insmod with -m parameter.
++insmod produces a module load map which contains base addresses of all
++sections in the module and addresses of symbols in the module file.
++3. Find all sections and their base addresses in the module from
++the module map.
++4. Generate a script that loads the module file. The script uses
++'add-symbol-file' and specifies address of text segment followed by
++addresses of all segments in the module.
++
++Here is an example gdb script produced by loadmodule.sh script.
++
++add-symbol-file foo 0xd082c060 -s .text.lock 0xd08cbfb5
++-s .fixup 0xd08cfbdf -s .rodata 0xd08cfde0 -s __ex_table 0xd08e3b38
++-s .data 0xd08e3d00 -s .bss 0xd08ec8c0 -s __ksymtab 0xd08ee838
++
++With this command gdb can calculate addresses of symbols in ANY segment
++in a module file.
++
++Regards.
++--
++Amit Kale
++Veritas Software ( http://www.veritas.com )
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/gdbinit 2003-12-28 23:21:07.000000000 -0800
+@@ -0,0 +1,14 @@
++shell echo -e "\003" >/dev/ttyS0
++set remotebaud 38400
++target remote /dev/ttyS0
++define si
++stepi
++printf "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n", $eax, $ebx, $ecx, $edx
++printf "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n", $esi, $edi, $ebp, $esp
++x/i $eip
++end
++define ni
++nexti
++printf "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n", $eax, $ebx, $ecx, $edx
++printf "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n", $esi, $edi, $ebp, $esp
++x/i $eip
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/gdbinit.hw      2003-12-28 23:21:07.000000000 -0800
+@@ -0,0 +1,117 @@
++
++#Using ia-32 hardware breakpoints.
++#
++#4 hardware breakpoints are available in ia-32 processors. These breakpoints
++#do not need code modification. They are set using debug registers.
++#
++#Each hardware breakpoint can be of one of the
++#three types: execution, write, access.
++#1. An Execution breakpoint is triggered when code at the breakpoint address is
++#executed.
++#2. A write breakpoint ( aka watchpoints ) is triggered when memory location
++#at the breakpoint address is written.
++#3. An access breakpoint is triggered when memory location at the breakpoint
++#address is either read or written.
++#
++#As hardware breakpoints are available in limited number, use software
++#breakpoints ( br command in gdb ) instead of execution hardware breakpoints.
++#
++#Length of an access or a write breakpoint defines length of the datatype to
++#be watched. Length is 1 for char, 2 short , 3 int.
++#
++#For placing execution, write and access breakpoints, use commands
++#hwebrk, hwwbrk, hwabrk
++#To remove a breakpoint use hwrmbrk command.
++#
++#These commands take following types of arguments. For arguments associated
++#with each command, use help command.
++#1. breakpointno: 0 to 3
++#2. length: 1 to 3
++#3. address: Memory location in hex ( without 0x ) e.g c015e9bc
++#
++#Use the command exinfo to find which hardware breakpoint occured.
++
++#hwebrk breakpointno address
++define hwebrk
++      maintenance packet Y$arg0,0,0,$arg1
++end
++document hwebrk
++      hwebrk <breakpointno> <address>
++      Places a hardware execution breakpoint
++      <breakpointno> = 0 - 3
++      <address> = Hex digits without leading "0x".
++end
++
++#hwwbrk breakpointno length address
++define hwwbrk
++      maintenance packet Y$arg0,1,$arg1,$arg2
++end
++document hwwbrk
++      hwwbrk <breakpointno> <length> <address>
++      Places a hardware write breakpoint
++      <breakpointno> = 0 - 3
++      <length> = 1 (1 byte), 2 (2 byte), 3 (4 byte)
++      <address> = Hex digits without leading "0x".
++end
++
++#hwabrk breakpointno length address
++define hwabrk
++      maintenance packet Y$arg0,1,$arg1,$arg2
++end
++document hwabrk
++      hwabrk <breakpointno> <length> <address>
++      Places a hardware access breakpoint
++      <breakpointno> = 0 - 3
++      <length> = 1 (1 byte), 2 (2 byte), 3 (4 byte)
++      <address> = Hex digits without leading "0x".
++end
++
++#hwrmbrk breakpointno
++define hwrmbrk
++      maintenance packet y$arg0
++end
++document hwrmbrk
++      hwrmbrk <breakpointno>
++      <breakpointno> = 0 - 3
++      Removes a hardware breakpoint
++end
++
++define reboot
++        maintenance packet r
++end
++#exinfo
++define exinfo
++      maintenance packet qE
++end
++document exinfo
++      exinfo
++      Gives information about a breakpoint.
++end
++define get_th
++      p $th=(struct thread_info *)((int)$esp & ~8191)
++end
++document get_th
++      get_tu
++      Gets and prints the current thread_info pointer, Defines th to be it.
++end
++define get_cu
++      p $cu=((struct thread_info *)((int)$esp & ~8191))->task
++end
++document get_cu
++      get_cu
++      Gets and print the "current" value.  Defines $cu to be it.
++end
++define int_off
++      set var $flags=$eflags
++      set $eflags=$eflags&~0x200
++      end
++define int_on
++      set var $eflags|=$flags&0x200
++      end
++document int_off
++      saves the current interrupt state and clears the processor interrupt
++      flag.  Use int_on to restore the saved flag.
++end
++document int_on
++      Restores the interrupt flag saved by int_off.
++end
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/gdbinit-modules 2003-12-28 23:21:07.000000000 -0800
+@@ -0,0 +1,146 @@
++#
++# Usefull GDB user-command to debug Linux Kernel Modules with gdbstub.
++#
++# This don't work for Linux-2.0 or older.
++#
++# Author Edouard G. Parmelan <Edouard.Parmelan@quadratec.fr>
++#
++#
++# Fri Apr 30 20:33:29 CEST 1999
++#   First public release.
++#
++#   Major cleanup after experiment Linux-2.0 kernel without success.
++#   Symbols of a module are not in the correct order, I can't explain
++#   why :(
++#
++# Fri Mar 19 15:41:40 CET 1999
++#   Initial version.
++#
++# Thu Jan  6 16:29:03 CST 2000
++#   A little fixing by Dave Grothe <dave@gcom.com>
++#
++# Mon Jun 19 09:33:13 CDT 2000
++#   Alignment changes from Edouard Parmelan
++#
++# The basic idea is to find where insmod load the module and inform
++# GDB to load the symbol table of the module with the GDB command
++# ``add-symbol-file <object> <address>''.
++#
++# The Linux kernel holds the list of all loaded modules in module_list,
++# this list end with &kernel_module (exactly with module->next == NULL,
++# but the last module is not a real module).
++#
++# Insmod allocates the struct module before the object file.  Since
++# Linux-2.1, this structure contain his size.  The real address of
++# the object file is then (char*)module + module->size_of_struct.
++#
++# You can use three user functions ``mod-list'', ``mod-print-symbols''
++# and ``add-module-symbols''.
++#
++# mod-list list all loaded modules with the format:
++#    <module-address> <module-name>
++#
++# As soon as you have found the address of your module, you can
++# print its exported symbols (mod-print-symbols) or inform GDB to add
++# symbols from your module file (mod-add-symbols).
++#
++# The argument that you give to mod-print-symbols or mod-add-symbols
++# is the <module-address> from the mod-list command.
++#
++# When using the mod-add-symbols command you must also give the full
++# pathname of the modules object code file.
++#
++# The command mod-add-lis is an example of how to make this easier.
++# You can edit this macro to contain the path name of your own
++# favorite module and then use it as a shorthand to load it.  You
++# still need the module-address, however.
++#
++# The internal function ``mod-validate'' set the GDB variable $mod
++# as a ``struct module*'' if the kernel known the module otherwise
++# $mod is set to NULL.  This ensure to not add symbols for a wrong
++# address.
++#
++# Have a nice hacking day !
++#
++#
++define mod-list
++    set $mod = (struct module*)module_list
++    # the last module is the kernel, ignore it
++    while $mod != &kernel_module
++      printf "%p\t%s\n", (long)$mod, ($mod)->name
++      set $mod = $mod->next
++    end
++end
++document mod-list
++List all modules in the form: <module-address> <module-name>
++Use the <module-address> as the argument for the other
++mod-commands: mod-print-symbols, mod-add-symbols.
++end
++
++define mod-validate
++    set $mod = (struct module*)module_list
++    while ($mod != $arg0) && ($mod != &kernel_module)
++      set $mod = $mod->next
++    end
++    if $mod == &kernel_module
++      set $mod = 0
++      printf "%p is not a module\n", $arg0
++    end
++end
++document mod-validate
++mod-validate <module-address>
++Internal user-command used to validate the module parameter.
++If <module> is a real loaded module, set $mod to it otherwise set $mod to 0.
++end
++
++
++define mod-print-symbols
++    mod-validate $arg0
++    if $mod != 0
++      set $i = 0
++      while $i < $mod->nsyms
++          set $sym = $mod->syms[$i]
++          printf "%p\t%s\n", $sym->value, $sym->name
++          set $i = $i + 1
++      end
++    end
++end
++document mod-print-symbols
++mod-print-symbols <module-address>
++Print all exported symbols of the module.  see mod-list
++end
++
++
++define mod-add-symbols-align
++    mod-validate $arg0
++    if $mod != 0
++      set $mod_base = ($mod->size_of_struct + (long)$mod)
++      if ($arg2 != 0) && (($mod_base & ($arg2 - 1)) != 0)
++          set $mod_base = ($mod_base | ($arg2 - 1)) + 1
++      end
++      add-symbol-file $arg1 $mod_base
++    end
++end
++document mod-add-symbols-align
++mod-add-symbols-align <module-address> <object file path name> <align>
++Load the symbols table of the module from the object file where
++first section aligment is <align>.
++To retreive alignment, use `objdump -h <object file path name>'.
++end
++
++define mod-add-symbols
++    mod-add-symbols-align $arg0 $arg1 sizeof(long)
++end
++document mod-add-symbols
++mod-add-symbols <module-address> <object file path name>
++Load the symbols table of the module from the object file.
++Default alignment is 4.  See mod-add-symbols-align.
++end
++
++define mod-add-lis
++    mod-add-symbols-align $arg0 /usr/src/LiS/streams.o 16
++end
++document mod-add-lis
++mod-add-lis <module-address>
++Does mod-add-symbols <module-address> /usr/src/LiS/streams.o
++end
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/kgdbeth.txt     2003-12-28 23:21:09.000000000 -0800
+@@ -0,0 +1,92 @@
++KGDB over ethernet
++==================
++
++Authors
++-------
++
++Robert Walsh <rjwalsh@durables.org>  (2.6 port)
++wangdi <wangdi@clusterfs.com>        (2.6 port)
++Matt Mackall <mpm@selenic.com>       (netpoll api)
++San Mehat                            (original 2.4 code)
++
++
++Introduction
++------------
++
++KGDB supports debugging over ethernet (kgdboe) via polling of a given
++network interface. Most cards should be supported automatically.
++Debugging facilities are available as soon as the network driver and
++kgdboe have initialized. Unfortunately, this is too late in the boot
++process for debugging some issues, but works quite well for many
++others. This should not interfere with normal network usage and
++doesn't require a dedicated NIC.
++
++Terminology
++-----------
++
++This document uses the following terms:
++
++  TARGET: the machine being debugged.
++  HOST:   the machine running gdb.
++
++
++Usage
++-----
++
++You need to use the following command-line option on the TARGET kernel:
++
++  kgdboe=[tgt-port]@<tgt-ip>/[dev],[host-port]@<host-ip>/[host-macaddr]
++
++    where
++        tgt-port      source for UDP packets (defaults to 6443)
++        tgt-ip        source IP to use (interface address)
++        dev           network interface (eth0)
++        host-port     HOST UDP port (6442) (not really used)
++        host-ip       IP address for HOST machine
++        host-macaddr  ethernet MAC address for HOST (ff:ff:ff:ff:ff:ff)
++
++  examples:
++
++    kgdboe=7000@192.168.0.1/eth1,7001@192.168.0.2/00:05:3C:04:47:5D
++        this machine is 192.168.0.1 on eth1
++        remote machine is 192.168.0.2 with MAC address 00:05:3C:04:47:5D
++        listen for gdb packets on port 7000
++        send unsolicited gdb packets to port 7001
++
++    kgdboe=@192.168.0.1/,@192.168.0.2/
++        this machine is 192.168.0.1 on default interface eth0
++        remote machine is 192.168.0.2, use default broadcast MAC address
++        listen for gdb packets on default port 6443
++        send unsolicited gdb packets to port 6442
++
++Only packets originating from the configured HOST IP address will be
++accepted by the debugger.
++
++On the HOST side, run gdb as normal and use a remote UDP host as the
++target:
++
++   % gdb ./vmlinux
++   GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
++   Copyright 2003 Free Software Foundation, Inc.
++   GDB is free software, covered by the GNU General Public License, and you are
++   welcome to change it and/or distribute copies of it under certain conditions.
++   Type "show copying" to see the conditions.
++   There is absolutely no warranty for GDB.  Type "show warranty" for details.
++   This GDB was configured as "i386-redhat-linux-gnu"...
++   (gdb) target remote udp:HOSTNAME:6443
++
++You can now continue as if you were debugging over a serial line.
++
++Limitations
++-----------
++
++The current release of this code is exclusive of using kgdb on a
++serial interface, so you must boot without the kgdboe option to use
++serial debugging. Trying to debug the network driver while using it
++will prove interesting.
++
++Bug reports
++-----------
++
++Send bug reports to Robert Walsh <rjwalsh@durables.org> and Matt
++Mackall <mpm@selenic.com>.
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/kgdb.txt        2003-12-28 23:21:07.000000000 -0800
+@@ -0,0 +1,775 @@
++Last edit: <20030806.1637.12>
++This file has information specific to the i386 kgdb option.  Other
++platforms with the kgdb option may behave in a similar fashion.
++
++New features:
++============
++20030806.1557.37
++This version was made against the 2.6.0-test2 kernel. We have made the
++following changes:
++
++- The getthread() code in the stub calls find_task_by_pid().  It fails
++  if we are early in the bring up such that the pid arrays have yet to
++  be allocated.  We have added a line to kernel/pid.c to make
++  "kgdb_pid_init_done" true once the arrays are allocated.  This way the
++  getthread() code knows not to call.  This is only used by the thread
++  debugging stuff and threads will not yet exist at this point in the
++  boot.
++
++- For some reason, gdb was not asking for a new thread list when the
++  "info thread" command was given.  We changed to the newer version of
++  the thread info command and gdb now seems to ask when needed.  Result,
++  we now get all threads in the thread list.
++
++- We now respond to the ThreadExtraInfo request from gdb with the thread
++  name from task_struct .comm.  This then appears in the thread list.
++  Thoughts on additional options for this are welcome.  Things such as
++  "has BKL" and "Preempted" come to mind.  I think we could have a flag
++  word that could enable different bits of info here.
++
++- We now honor, sort of, the C and S commands.  These are continue and
++  single set after delivering a signal.  We ignore the signal and do the
++  requested action.  This only happens when we told gdb that a signal
++  was the reason for entry, which is only done on memory faults.  The
++  result is that you can now continue into the Oops.
++
++- We changed the -g to -gdwarf-2.  This seems to be the same as -ggdb,
++  but it is more exact on what language to use.
++
++- We added two dwarf2 include files and a bit of code at the end of
++  entry.S.  This does not yet work, so it is disabled.  Still we want to
++  keep track of the code and "maybe" someone out there can fix it.
++
++- Randy Dunlap sent some fix ups for this file which are now merged.
++
++- Hugh Dickins sent a fix to a bit of code in traps.c that prevents a
++  compiler warning if CONFIG_KGDB is off (now who would do that :).
++
++- Andrew Morton sent a fix for the serial driver which is now merged.
++
++- Andrew also sent a change to the stub around the cpu managment code
++  which is also merged.
++
++- Andrew also sent a patch to make "f" as well as "g" work as SysRq
++  commands to enter kgdb, merged.
++
++- If CONFIG_KGDB and CONFIG_DEBUG_SPINLOCKS are both set we added a
++  "who" field to the spinlock data struct.  This is filled with
++  "current" when ever the spinlock suceeds.  Useful if you want to know
++  who has the lock.
++
++_ And last, but not least, we fixed the "get_cu" macro to properly get
++  the current value of "current".
++
++New features:
++============
++20030505.1827.27
++We are starting to align with the sourceforge version, at least in
++commands.  To this end, the boot command string to start kgdb at
++boot time has been changed from "kgdb" to "gdb".
++
++Andrew Morton sent a couple of patches which are now included as follows:
++1.) We now return a flag to the interrupt handler.
++2.) We no longer use smp_num_cpus (a conflict with the lock meter).
++3.) And from William Lee Irwin III <wli@holomorphy.com> code to make
++    sure high-mem is set up before we attempt to register our interrupt
++    handler.
++We now include asm/kgdb.h from config.h so you will most likely never
++have to include it.  It also 'NULLS' the kgdb macros you might have in
++your code when CONFIG_KGDB is not defined.  This allows you to just
++turn off CONFIG_KGDB to turn off all the kgdb_ts() calls and such.
++This include is conditioned on the machine being an x86 so as to not
++mess with other archs.
++
++20020801.1129.03
++This is currently the version for the 2.4.18 (and beyond?) kernel.
++
++We have several new "features" beginning with this version:
++
++1.) Kgdb now syncs the "other" CPUs with a cross-CPU NMI.  No more
++    waiting and it will pull that guy out of an IRQ off spin lock :)
++
++2.) We doctored up the code that tells where a task is waiting and
++    included it so that the "info thread" command will show a bit more
++    than "schedule()".  Try it...
++
++3.) Added the ability to call a function from gdb.  All the standard gdb
++    issues apply, i.e. if you hit a breakpoint in the function, you are
++    not allowed to call another (gdb limitation, not kgdb).  To help
++    this capability we added a memory allocation function.  Gdb does not
++    return this memory (it is used for strings that you pass to that function
++    you are calling from gdb) so we fixed up a way to allow you to
++    manually return the memory (see below).
++
++4.) Kgdb time stamps (kgdb_ts()) are enhanced to expand what was the
++    interrupt flag to now also include the preemption count and the
++    "in_interrupt" info.  The flag is now called "with_pif" to indicate
++    the order, preempt_count, in_interrupt, flag.  The preempt_count is
++    shifted left by 4 bits so you can read the count in hex by dropping
++    the low order digit.  In_interrupt is in bit 1, and the flag is in
++    bit 0.
++
++5.) The command: "p kgdb_info" is now expanded and prints something
++    like:
++(gdb) p kgdb_info
++$2 = {used_malloc = 0, called_from = 0xc0107506, entry_tsc = 67468627259,
++  errcode = 0, vector = 3, print_debug_info = 0, hold_on_sstep = 1,
++  cpus_waiting = {{task = 0xc027a000, pid = 32768, hold = 0,
++      regs = 0xc027bf84}, {task = 0x0, pid = 0, hold = 0, regs = 0x0}}}
++
++    Things to note here: a.) used_malloc is the amount of memory that
++    has been malloc'ed to do calls from gdb.  You can reclaim this
++    memory like this: "p kgdb_info.used_malloc=0" Cool, huh?  b.)
++    cpus_waiting is now "sized" by the number of CPUs you enter at
++    configure time in the kgdb configure section.  This is NOT used
++    anywhere else in the system, but it is "nice" here.  c.)  The task's
++    "pid" is now in the structure.  This is the pid you will need to use
++    to decode to the thread id to get gdb to look at that thread.
++    Remember that the "info thread" command prints a list of threads
++    wherein it numbers each thread with its reference number followed
++    by the thread's pid.  Note that the per-CPU idle threads actually
++    have pids of 0 (yes, there is more than one pid 0 in an SMP system).
++    To avoid confusion, kgdb numbers these threads with numbers beyond
++    the MAX_PID.  That is why you see 32768 and above.
++
++6.) A subtle change, we now provide the complete register set for tasks
++    that are active on the other CPUs.  This allows better trace back on
++    those tasks.
++
++    And, let's mention what we could not fix.  Back-trace from all but the
++    thread that we trapped will, most likely, have a bogus entry in it.
++    The problem is that gdb does not recognize the entry code for
++    functions that use "current" near (at all?) the entry.  The compiler
++    is putting the "current" decode as the first two instructions of the
++    function where gdb expects to find %ebp changing code.  Back trace
++    also has trouble with interrupt frames.  I am talking with Daniel
++    Jacobowitz about some way to fix this, but don't hold your breath.
++
++20011220.0050.35
++Major enhancement with this version is the ability to hold one or more
++CPUs in an SMP system while allowing the others to continue.  Also, by
++default only the current CPU is enabled on single-step commands (please
++note that gdb issues single-step commands at times other than when you
++use the si command).
++
++Another change is to collect some useful information in
++a global structure called "kgdb_info".  You should be able to just:
++
++p kgdb_info
++
++although I have seen cases where the first time this is done gdb just
++prints the first member but prints the whole structure if you then enter
++CR (carriage return or enter).  This also works:
++
++p *&kgdb_info
++
++Here is a sample:
++(gdb) p kgdb_info
++$4 = {called_from = 0xc010732c, entry_tsc = 32804123790856, errcode = 0,
++  vector = 3, print_debug_info = 0}
++
++"Called_from" is the return address from the current entry into kgdb.
++Sometimes it is useful to know why you are in kgdb, for example, was
++it an NMI or a real breakpoint?  The simple way to interrogate this
++return address is:
++
++l *0xc010732c
++
++which will print the surrounding few lines of source code.
++
++"Entry_tsc" is the CPU TSC on entry to kgdb (useful to compare to the
++kgdb_ts entries).
++
++"errcode" and "vector" are other entry parameters which may be helpful on
++some traps.
++
++"print_debug_info" is the internal debugging kgdb print enable flag.  Yes,
++you can modify it.
++
++In SMP systems kgdb_info also includes the "cpus_waiting" structure and
++"hold_on_step":
++
++(gdb) p kgdb_info
++$7 = {called_from = 0xc0112739, entry_tsc = 1034936624074, errcode = 0,
++  vector = 2, print_debug_info = 0, hold_on_sstep = 1, cpus_waiting = {{
++      task = 0x0, hold = 0, regs = 0x0}, {task = 0xc71b8000, hold = 0,
++      regs = 0xc71b9f70}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
++      hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
++      hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
++      hold = 0, regs = 0x0}}}
++
++"Cpus_waiting" has an entry for each CPU other than the current one that
++has been stopped.  Each entry contains the task_struct address for that
++CPU, the address of the regs for that task and a hold flag.  All these
++have the proper typing so that, for example:
++
++p *kgdb_info.cpus_waiting[1].regs
++
++will print the registers for CPU 1.
++
++"Hold_on_sstep" is a new feature with this version and comes up set or
++true.  What this means is that whenever kgdb is asked to single-step all
++other CPUs are held (i.e. not allowed to execute).  The flag applies to
++all but the current CPU and, again, can be changed:
++
++p kgdb_info.hold_on_sstep=0
++
++restores the old behavior of letting all CPUs run during single-stepping.
++
++Likewise, each CPU has a "hold" flag, which if set, locks that CPU out
++of execution.  Note that this has some risk in cases where the CPUs need
++to communicate with each other.  If kgdb finds no CPU available on exit,
++it will push a message thru gdb and stay in kgdb.  Note that it is legal
++to hold the current CPU as long as at least one CPU can execute.
++
++20010621.1117.09
++This version implements an event queue.  Events are signaled by calling
++a function in the kgdb stub and may be examined from gdb.  See EVENTS
++below for details.  This version also tightens up the interrupt and SMP
++handling to not allow interrupts on the way to kgdb from a breakpoint
++trap.  It is fine to allow these interrupts for user code, but not
++system debugging.
++
++Version
++=======
++
++This version of the kgdb package was developed and tested on
++kernel version 2.4.16.  It will not install on any earlier kernels.
++It is possible that it will continue to work on later versions
++of 2.4 and then versions of 2.5 (I hope).
++
++
++Debugging Setup
++===============
++
++Designate one machine as the "development" machine.  This is the
++machine on which you run your compiles and which has your source
++code for the kernel.  Designate a second machine as the "target"
++machine.  This is the machine that will run your experimental
++kernel.
++
++The two machines will be connected together via a serial line out
++one or the other of the COM ports of the PC.  You will need the
++appropriate modem eliminator (null modem) cable(s) for this.
++
++Decide on which tty port you want the machines to communicate, then
++connect them up back-to-back using the null modem cable.  COM1 is
++/dev/ttyS0 and COM2 is /dev/ttyS1. You should test this connection
++with the two machines prior to trying to debug a kernel.  Once you
++have it working, on the TARGET machine, enter:
++
++setserial /dev/ttyS0 (or what ever tty you are using)
++
++and record the port address and the IRQ number.
++
++On the DEVELOPMENT machine you need to apply the patch for the kgdb
++hooks.  You have probably already done that if you are reading this
++file.
++
++On your DEVELOPMENT machine, go to your kernel source directory and do
++"make Xconfig" where X is one of "x", "menu", or "".  If you are
++configuring in the standard serial driver, it must not be a module.
++Either yes or no is ok, but making the serial driver a module means it
++will initialize after kgdb has set up the UART interrupt code and may
++cause a failure of the control-C option discussed below.  The configure
++question for the serial driver is under the "Character devices" heading
++and is:
++
++"Standard/generic (8250/16550 and compatible UARTs) serial support"
++
++Go down to the kernel debugging menu item and open it up.  Enable the
++kernel kgdb stub code by selecting that item.  You can also choose to
++turn on the "-ggdb -O1" compile options.  The -ggdb causes the compiler
++to put more debug info (like local symbols) in the object file.  On the
++i386 -g and -ggdb are the same so this option just reduces to "O1".  The
++-O1 reduces the optimization level.  This may be helpful in some cases,
++be aware, however, that this may also mask the problem you are looking
++for.
++
++The baud rate.  Default is 115200.  What ever you choose be sure that
++the host machine is set to the same speed.  I recommend the default.
++
++The port.  This is the I/O address of the serial UART that you should
++have gotten using setserial as described above.  The standard COM1 port
++(3f8) using IRQ 4 is default.  COM2 is 2f8 which by convention uses IRQ
++3.
++
++The port IRQ (see above).
++
++Stack overflow test.  This option makes a minor change in the trap,
++system call and interrupt code to detect stack overflow and transfer
++control to kgdb if it happens.  (Some platforms have this in the
++baseline code, but the i386 does not.)
++
++You can also configure the system to recognize the boot option
++"console=kgdb" which if given will cause all console output during
++booting to be put thru gdb as well as other consoles.  This option
++requires that gdb and kgdb be connected prior to sending console output
++so, if they are not, a breakpoint is executed to force the connection.
++This will happen before any kernel output (it is going thru gdb, right),
++and will stall the boot until the connection is made.
++
++You can also configure in a patch to SysRq to enable the kGdb SysRq.
++This request generates a breakpoint.  Since the serial port IRQ line is
++set up after any serial drivers, it is possible that this command will
++work when the control-C will not.
++
++Save and exit the Xconfig program.  Then do "make clean" , "make dep"
++and "make bzImage" (or whatever target you want to make).  This gets the
++kernel compiled with the "-g" option set -- necessary for debugging.
++
++You have just built the kernel on your DEVELOPMENT machine that you
++intend to run on your TARGET machine.
++
++To install this new kernel, use the following installation procedure.
++Remember, you are on the DEVELOPMENT machine patching the kernel source
++for the kernel that you intend to run on the TARGET machine.
++
++Copy this kernel to your target machine using your usual procedures.  I
++usually arrange to copy development:
++/usr/src/linux/arch/i386/boot/bzImage to /vmlinuz on the TARGET machine
++via a LAN based NFS access.  That is, I run the cp command on the target
++and copy from the development machine via the LAN.  Run Lilo (see "man
++lilo" for details on how to set this up) on the new kernel on the target
++machine so that it will boot!  Then boot the kernel on the target
++machine.
++
++On the DEVELOPMENT machine, create a file called .gdbinit in the
++directory /usr/src/linux.  An example .gdbinit file looks like this:
++
++shell echo -e "\003" >/dev/ttyS0
++set remotebaud 38400 (or what ever speed you have chosen)
++target remote /dev/ttyS0
++
++
++Change the "echo" and "target" definition so that it specifies the tty
++port that you intend to use.  Change the "remotebaud" definition to
++match the data rate that you are going to use for the com line.
++
++You are now ready to try it out.
++
++Boot your target machine with "kgdb" in the boot command i.e. something
++like:
++
++lilo> test kgdb
++
++or if you also want console output thru gdb:
++
++lilo> test kgdb console=kgdb
++
++You should see the lilo message saying it has loaded the kernel and then
++all output stops.  The kgdb stub is trying to connect with gdb.  Start
++gdb something like this:
++
++
++On your DEVELOPMENT machine, cd /usr/src/linux and enter "gdb vmlinux".
++When gdb gets the symbols loaded it will read your .gdbinit file and, if
++everything is working correctly, you should see gdb print out a few
++lines indicating that a breakpoint has been taken.  It will actually
++show a line of code in the target kernel inside the kgdb activation
++code.
++
++The gdb interaction should look something like this:
++
++    linux-dev:/usr/src/linux# gdb vmlinux
++    GDB is free software and you are welcome to distribute copies of it
++     under certain conditions; type "show copying" to see the conditions.
++    There is absolutely no warranty for GDB; type "show warranty" for details.
++    GDB 4.15.1 (i486-slackware-linux),
++    Copyright 1995 Free Software Foundation, Inc...
++    breakpoint () at i386-stub.c:750
++    750     }
++    (gdb)
++
++You can now use whatever gdb commands you like to set breakpoints.
++Enter "continue" to start your target machine executing again.  At this
++point the target system will run at full speed until it encounters
++your breakpoint or gets a segment violation in the kernel, or whatever.
++
++If you have the kgdb console enabled when you continue, gdb will print
++out all the console messages.
++
++The above example caused a breakpoint relatively early in the boot
++process.  For the i386 kgdb it is possible to code a break instruction
++as the first C-language point in init/main.c, i.e. as the first instruction
++in start_kernel().  This could be done as follows:
++
++#include <asm/kgdb.h>
++       breakpoint();
++
++This breakpoint() is really a function that sets up the breakpoint and
++single-step hardware trap cells and then executes a breakpoint.  Any
++early hard coded breakpoint will need to use this function.  Once the
++trap cells are set up they need not be set again, but doing it again
++does not hurt anything, so you don't need to be concerned about which
++breakpoint is hit first.  Once the trap cells are set up (and the kernel
++sets them up in due course even if breakpoint() is never called) the
++macro:
++
++BREAKPOINT;
++
++will generate an inline breakpoint.  This may be more useful as it stops
++the processor at the instruction instead of in a function a step removed
++from the location of interest.  In either case <asm/kgdb.h> must be
++included to define both breakpoint() and BREAKPOINT.
++
++Triggering kgdbstub at other times
++==================================
++
++Often you don't need to enter the debugger until much later in the boot
++or even after the machine has been running for some time.  Once the
++kernel is booted and interrupts are on, you can force the system to
++enter the debugger by sending a control-C to the debug port. This is
++what the first line of the recommended .gdbinit file does.  This allows
++you to start gdb any time after the system is up as well as when the
++system is already at a breakpoint.  (In the case where the system is
++already at a breakpoint the control-C is not needed, however, it will
++be ignored by the target so no harm is done.  Also note the the echo
++command assumes that the port speed is already set.  This will be true
++once gdb has connected, but it is best to set the port speed before you
++run gdb.)
++
++Another simple way to do this is to put the following file in you ~/bin
++directory:
++
++#!/bin/bash
++echo  -e "\003"  > /dev/ttyS0
++
++Here, the ttyS0 should be replaced with what ever port you are using.
++The "\003" is control-C.  Once you are connected with gdb, you can enter
++control-C at the command prompt.
++
++An alternative way to get control to the debugger is to enable the kGdb
++SysRq command.  Then you would enter Alt-SysRq-g (all three keys at the
++same time, but push them down in the order given).  To refresh your
++memory of the available SysRq commands try Alt-SysRq-=.  Actually any
++undefined command could replace the "=", but I like to KNOW that what I
++am pushing will never be defined.
++
++Debugging hints
++===============
++
++You can break into the target machine at any time from the development
++machine by typing ^C (see above paragraph).  If the target machine has
++interrupts enabled this will stop it in the kernel and enter the
++debugger.
++
++There is unfortunately no way of breaking into the kernel if it is
++in a loop with interrupts disabled, so if this happens to you then
++you need to place exploratory breakpoints or printk's into the kernel
++to find out where it is looping.  The exploratory breakpoints can be
++entered either thru gdb or hard coded into the source.  This is very
++handy if you do something like:
++
++if (<it hurts>) BREAKPOINT;
++
++
++There is a copy of an e-mail in the Documentation/i386/kgdb/ directory
++(debug-nmi.txt) which describes how to create an NMI on an ISA bus
++machine using a paper clip.  I have a sophisticated version of this made
++by wiring a push button switch into a PC104/ISA bus adapter card.  The
++adapter card nicely furnishes wire wrap pins for all the ISA bus
++signals.
++
++When you are done debugging the kernel on the target machine it is a
++good idea to leave it in a running state.  This makes reboots faster,
++bypassing the fsck.  So do a gdb "continue" as the last gdb command if
++this is possible.  To terminate gdb itself on the development machine
++and leave the target machine running, first clear all breakpoints and
++continue, then type ^Z to suspend gdb and then kill it with "kill %1" or
++something similar.
++
++If gdbstub Does Not Work
++========================
++
++If it doesn't work, you will have to troubleshoot it.  Do the easy
++things first like double checking your cabling and data rates.  You
++might try some non-kernel based programs to see if the back-to-back
++connection works properly.  Just something simple like cat /etc/hosts
++>/dev/ttyS0 on one machine and cat /dev/ttyS0 on the other will tell you
++if you can send data from one machine to the other.  Make sure it works
++in both directions.  There is no point in tearing out your hair in the
++kernel if the line doesn't work.
++
++All of the real action takes place in the file
++/usr/src/linux/arch/i386/kernel/kgdb_stub.c.  That is the code on the target
++machine that interacts with gdb on the development machine.  In gdb you can
++turn on a debug switch with the following command:
++
++      set remotedebug
++
++This will print out the protocol messages that gdb is exchanging with
++the target machine.
++
++Another place to look is /usr/src/arch/i386/lib/kgdb_serial.c. This is
++the code that talks to the serial port on the target side.  There might
++be a problem there.  In particular there is a section of this code that
++tests the UART which will tell you what UART you have if you define
++"PRNT" (just remove "_off" from the #define PRNT_off).  To view this
++report you will need to boot the system without any beakpoints.  This
++allows the kernel to run to the point where it calls kgdb to set up
++interrupts.  At this time kgdb will test the UART and print out the type
++it finds.  (You need to wait so that the printks are actually being
++printed.  Early in the boot they are cached, waiting for the console to
++be enabled.  Also, if kgdb is entered thru a breakpoint it is possible
++to cause a dead lock by calling printk when the console is locked.  The
++stub thus avoids doing printks from breakpoints, especially in the
++serial code.)  At this time, if the UART fails to do the expected thing,
++kgdb will print out (using printk) information on what failed.  (These
++messages will be buried in all the other boot up messages.  Look for
++lines that start with "gdb_hook_interrupt:".  You may want to use dmesg
++once the system is up to view the log.  If this fails or if you still
++don't connect, review your answers for the port address.  Use:
++
++setserial /dev/ttyS0
++
++to get the current port and IRQ information.  This command will also
++tell you what the system found for the UART type. The stub recognizes
++the following UART types:
++
++16450, 16550, and 16550A
++
++If you are really desperate you can use printk debugging in the
++kgdbstub code in the target kernel until you get it working.  In particular,
++there is a global variable in /usr/src/linux/arch/i386/kernel/kgdb_stub.c
++named "remote_debug".  Compile your kernel with this set to 1, rather
++than 0 and the debug stub will print out lots of stuff as it does
++what it does.  Likewise there are debug printks in the kgdb_serial.c
++code that can be turned on with simple changes in the macro defines.
++
++
++Debugging Loadable Modules
++==========================
++
++This technique comes courtesy of Edouard Parmelan
++<Edouard.Parmelan@quadratec.fr>
++
++When you run gdb, enter the command
++
++source gdbinit-modules
++
++This will read in a file of gdb macros that was installed in your
++kernel source directory when kgdb was installed.  This file implements
++the following commands:
++
++mod-list
++    Lists the loaded modules in the form <module-address> <module-name>
++
++mod-print-symbols <module-address>
++    Prints all the symbols in the indicated module.
++
++mod-add-symbols <module-address> <object-file-path-name>
++    Loads the symbols from the object file and associates them
++    with the indicated module.
++
++After you have loaded the module that you want to debug, use the command
++mod-list to find the <module-address> of your module.  Then use that
++address in the mod-add-symbols command to load your module's symbols.
++From that point onward you can debug your module as if it were a part
++of the kernel.
++
++The file gdbinit-modules also contains a command named mod-add-lis as
++an example of how to construct a command of your own to load your
++favorite module.  The idea is to "can" the pathname of the module
++in the command so you don't have to type so much.
++
++Threads
++=======
++
++Each process in a target machine is seen as a gdb thread. gdb thread
++related commands (info threads, thread n) can be used.
++
++ia-32 hardware breakpoints
++==========================
++
++kgdb stub contains support for hardware breakpoints using debugging features
++of ia-32(x86) processors. These breakpoints do not need code modification.
++They use debugging registers. 4 hardware breakpoints are available in ia-32
++processors.
++
++Each hardware breakpoint can be of one of the following three types.
++
++1. Execution breakpoint - An Execution breakpoint is triggered when code
++      at the breakpoint address is executed.
++
++      As limited number of hardware breakpoints are available, it is
++      advisable to use software breakpoints ( break command ) instead
++      of execution hardware breakpoints, unless modification of code
++      is to be avoided.
++
++2. Write breakpoint - A write breakpoint is triggered when memory
++      location at the breakpoint address is written.
++
++      A write or can be placed for data of variable length. Length of
++      a write breakpoint indicates length of the datatype to be
++      watched. Length is 1 for 1 byte data , 2 for 2 byte data, 3 for
++      4 byte data.
++
++3. Access breakpoint - An access breakpoint is triggered when memory
++      location at the breakpoint address is either read or written.
++
++      Access breakpoints also have lengths similar to write breakpoints.
++
++IO breakpoints in ia-32 are not supported.
++
++Since gdb stub at present does not use the protocol used by gdb for hardware
++breakpoints, hardware breakpoints are accessed through gdb macros. gdb macros
++for hardware breakpoints are described below.
++
++hwebrk        - Places an execution breakpoint
++      hwebrk breakpointno address
++hwwbrk        - Places a write breakpoint
++      hwwbrk breakpointno length address
++hwabrk        - Places an access breakpoint
++      hwabrk breakpointno length address
++hwrmbrk       - Removes a breakpoint
++      hwrmbrk breakpointno
++exinfo        - Tells whether a software or hardware breakpoint has occurred.
++      Prints number of the hardware breakpoint if a hardware breakpoint has
++      occurred.
++
++Arguments required by these commands are as follows
++breakpointno  - 0 to 3
++length                - 1 to 3
++address               - Memory location in hex digits ( without 0x ) e.g c015e9bc
++
++SMP support
++==========
++
++When a breakpoint occurs or user issues a break ( Ctrl + C ) to gdb
++client, all the processors are forced to enter the debugger. Current
++thread corresponds to the thread running on the processor where
++breakpoint occurred.  Threads running on other processor(s) appear
++similar to other non-running threads in the 'info threads' output.
++Within the kgdb stub there is a structure "waiting_cpus" in which kgdb
++records the values of "current" and "regs" for each CPU other than the
++one that hit the breakpoint.  "current" is a pointer to the task
++structure for the task that CPU is running, while "regs" points to the
++saved registers for the task.  This structure can be examined with the
++gdb "p" command.
++
++ia-32 hardware debugging registers on all processors are set to same
++values.  Hence any hardware breakpoints may occur on any processor.
++
++gdb troubleshooting
++===================
++
++1. gdb hangs
++Kill it. restart gdb. Connect to target machine.
++
++2. gdb cannot connect to target machine (after killing a gdb and
++restarting another) If the target machine was not inside debugger when
++you killed gdb, gdb cannot connect because the target machine won't
++respond.  In this case echo "Ctrl+C"(ASCII 3) to the serial line.
++e.g. echo -e "\003" > /dev/ttyS1
++This forces that target machine into the debugger, after which you
++can connect.
++
++3. gdb cannot connect even after echoing Ctrl+C into serial line
++Try changing serial line settings min to 1 and time to 0
++e.g. stty min 1 time 0 < /dev/ttyS1
++Try echoing again
++
++Check serial line speed and set it to correct value if required
++e.g. stty ispeed 115200 ospeed 115200 < /dev/ttyS1
++
++EVENTS
++======
++
++Ever want to know the order of things happening?  Which CPU did what and
++when?  How did the spinlock get the way it is?  Then events are for
++you.  Events are defined by calls to an event collection interface and
++saved for later examination.  In this case, kgdb events are saved by a
++very fast bit of code in kgdb which is fully SMP and interrupt protected
++and they are examined by using gdb to display them.  Kgdb keeps only
++the last N events, where N must be a power of two and is defined at
++configure time.
++
++
++Events are signaled to kgdb by calling:
++
++kgdb_ts(data0,data1)
++
++For each call kgdb records each call in an array along with other info.
++Here is the array definition:
++
++struct kgdb_and_then_struct {
++#ifdef CONFIG_SMP
++      int     on_cpu;
++#endif
++      long long at_time;
++      int     from_ln;
++      char    * in_src;
++      void    *from;
++        int     with_if;
++      int     data0;
++      int     data1;
++};
++
++For SMP machines the CPU is recorded, for all machines the TSC is
++recorded (gets a time stamp) as well as the line number and source file
++the call was made from.  The address of the (from), the "if" (interrupt
++flag) and the two data items are also recorded.  The macro kgdb_ts casts
++the types to int, so you can put any 32-bit values here.  There is a
++configure option to select the number of events you want to keep.  A
++nice number might be 128, but you can keep up to 1024 if you want.  The
++number must be a power of two.  An "andthen" macro library is provided
++for gdb to help you look at these events.  It is also possible to define
++a different structure for the event storage and cast the data to this
++structure.  For example the following structure is defined in kgdb:
++
++struct kgdb_and_then_struct2 {
++#ifdef CONFIG_SMP
++      int     on_cpu;
++#endif
++      long long at_time;
++      int     from_ln;
++      char    * in_src;
++      void    *from;
++        int     with_if;
++      struct task_struct *t1;
++      struct task_struct *t2;
++};
++
++If you use this for display, the data elements will be displayed as
++pointers to task_struct entries.  You may want to define your own
++structure to use in casting.  You should only change the last two items
++and you must keep the structure size the same.  Kgdb will handle these
++as 32-bit ints, but within that constraint you can define a structure to
++cast to any 32-bit quantity.  This need only be available to gdb and is
++only used for casting in the display code.
++
++Final Items
++===========
++
++I picked up this code from Amit S. Kale and enhanced it.
++
++If you make some really cool modification to this stuff, or if you
++fix a bug, please let me know.
++
++George Anzinger
++<george@mvista.com>
++
++Amit S. Kale
++<akale@veritas.com>
++
++(First kgdb by David Grothe <dave@gcom.com>)
++
++(modified by Tigran Aivazian <tigran@sco.com>)
++    Putting gdbstub into the kernel config menu.
++
++(modified by Scott Foehner <sfoehner@engr.sgi.com>)
++    Hooks for entering gdbstub at boot time.
++
++(modified by Amit S. Kale <akale@veritas.com>)
++    Threads, ia-32 hw debugging, mp support, console support,
++    nmi watchdog handling.
++
++(modified by George Anzinger <george@mvista.com>)
++    Extended threads to include the idle threads.
++    Enhancements to allow breakpoint() at first C code.
++    Use of module_init() and __setup() to automate the configure.
++    Enhanced the cpu "collection" code to work in early bring-up.
++    Added ability to call functions from gdb
++    Print info thread stuff without going back to schedule()
++    Now collect the "other" cpus with an IPI/ NMI.
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/i386/kgdb/loadmodule.sh   2003-12-28 23:21:07.000000000 -0800
+@@ -0,0 +1,78 @@
++#/bin/sh
++# This script loads a module on a target machine and generates a gdb script.
++# source generated gdb script to load the module file at appropriate addresses
++# in gdb.
++#
++# Usage:
++# Loading the module on target machine and generating gdb script)
++#     [foo]$ loadmodule.sh <modulename>
++#
++# Loading the module file into gdb
++#     (gdb) source <gdbscriptpath>
++#
++# Modify following variables according to your setup.
++#     TESTMACHINE - Name of the target machine
++#     GDBSCRIPTS - The directory where a gdb script will be generated
++#
++# Author: Amit S. Kale (akale@veritas.com).
++#
++# If you run into problems, please check files pointed to by following
++# variables.
++#     ERRFILE - /tmp/<modulename>.errs contains stderr output of insmod
++#     MAPFILE - /tmp/<modulename>.map contains stdout output of insmod
++#     GDBSCRIPT - $GDBSCRIPTS/load<modulename> gdb script.
++
++TESTMACHINE=foo
++GDBSCRIPTS=/home/bar
++
++if [ $# -lt 1 ] ; then {
++      echo Usage: $0 modulefile
++      exit
++} ; fi
++
++MODULEFILE=$1
++MODULEFILEBASENAME=`basename $1`
++
++if [ $MODULEFILE = $MODULEFILEBASENAME ] ; then {
++      MODULEFILE=`pwd`/$MODULEFILE
++} fi
++
++ERRFILE=/tmp/$MODULEFILEBASENAME.errs
++MAPFILE=/tmp/$MODULEFILEBASENAME.map
++GDBSCRIPT=$GDBSCRIPTS/load$MODULEFILEBASENAME
++
++function findaddr() {
++      local ADDR=0x$(echo "$SEGMENTS" | \
++              grep "$1" | sed 's/^[^ ]*[ ]*[^ ]*[ ]*//' | \
++              sed 's/[ ]*[^ ]*$//')
++      echo $ADDR
++}
++
++function checkerrs() {
++      if [ "`cat $ERRFILE`" != "" ] ; then {
++              cat $ERRFILE
++              exit
++      } fi
++}
++
++#load the module
++echo Copying $MODULEFILE to $TESTMACHINE
++rcp $MODULEFILE root@${TESTMACHINE}:
++
++echo Loading module $MODULEFILE
++rsh -l root $TESTMACHINE  /sbin/insmod -m ./`basename $MODULEFILE` \
++      > $MAPFILE 2> $ERRFILE
++checkerrs
++
++SEGMENTS=`head -n 11 $MAPFILE | tail -n 10`
++TEXTADDR=$(findaddr "\\.text[^.]")
++LOADSTRING="add-symbol-file $MODULEFILE $TEXTADDR"
++SEGADDRS=`echo "$SEGMENTS" | awk '//{
++      if ($1 != ".text" && $1 != ".this" &&
++          $1 != ".kstrtab" && $1 != ".kmodtab") {
++              print " -s " $1 " 0x" $3 " "
++      }
++}'`
++LOADSTRING="$LOADSTRING $SEGADDRS"
++echo Generating script $GDBSCRIPT
++echo $LOADSTRING > $GDBSCRIPT
+--- linux-2.6.0/Documentation/i386/zero-page.txt       2003-06-14 12:18:07.000000000 -0700
++++ 25/Documentation/i386/zero-page.txt        2003-12-28 23:22:56.000000000 -0800
+@@ -22,6 +22,7 @@ Offset       Type            Description
+                         0x90000 + contents of CL_OFFSET
+                       (only taken, when CL_MAGIC = 0xA33F)
+  0x40 20 bytes        struct apm_bios_info, APM_BIOS_INFO
++ 0x60 16 bytes        Intel SpeedStep (IST) BIOS support information
+  0x80 16 bytes        hd0-disk-parameter from intvector 0x41
+  0x90 16 bytes        hd1-disk-parameter from intvector 0x46
+--- linux-2.6.0/Documentation/input/input.txt  2003-06-14 12:18:02.000000000 -0700
++++ 25/Documentation/input/input.txt   2003-12-28 23:23:06.000000000 -0800
+@@ -255,7 +255,7 @@ driver. 
+ is also emulated, characters should appear if you move it.
+   You can test the joystick emulation with the 'jstest' utility,
+-available in the joystick package (see Documentation/joystick.txt).
++available in the joystick package (see Documentation/input/joystick.txt).
+   You can test the event devices with the 'evtest' utility available
+ in the LinuxConsole project CVS archive (see the URL below).
+--- linux-2.6.0/Documentation/kbuild/kconfig-language.txt      2003-10-08 15:07:08.000000000 -0700
++++ 25/Documentation/kbuild/kconfig-language.txt       2003-12-28 23:23:04.000000000 -0800
+@@ -141,8 +141,8 @@ Expressions are listed in decreasing ord
+     otherwise 'y'.
+ (4) Returns the value of the expression. Used to override precedence.
+ (5) Returns the result of (2-/expr/).
+-(6) Returns the result of max(/expr/, /expr/).
+-(7) Returns the result of min(/expr/, /expr/).
++(6) Returns the result of min(/expr/, /expr/).
++(7) Returns the result of max(/expr/, /expr/).
+ An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
+ respectively for calculations). A menu entry becomes visible when it's
+--- linux-2.6.0/Documentation/kbuild/modules.txt       2003-09-27 18:57:43.000000000 -0700
++++ 25/Documentation/kbuild/modules.txt        2003-12-28 23:23:06.000000000 -0800
+@@ -1,4 +1,4 @@
+-For now this is a raw copy from the old Documentation/modules.txt,
++For now this is a raw copy from the old Documentation/kbuild/modules.txt,
+ which was removed in 2.6.0-test5.
+ The information herein is correct but not complete.
+--- linux-2.6.0/Documentation/kernel-parameters.txt    2003-10-08 15:07:08.000000000 -0700
++++ 25/Documentation/kernel-parameters.txt     2003-12-28 23:23:06.000000000 -0800
+@@ -24,6 +24,7 @@ restrictions referred to are that the re
+       HW      Appropriate hardware is enabled.
+       IA-32   IA-32 aka i386 architecture is enabled.
+       IA-64   IA-64 architecture is enabled.
++      IOSCHED More than one I/O scheduler is enabled.
+       IP_PNP  IP DCHP, BOOTP, or RARP is enabled.
+       ISAPNP  ISA PnP code is enabled.
+       ISDN    Appropriate ISDN support is enabled.
+@@ -91,6 +92,23 @@ running once the system is up.
+                       ht -- run only enough ACPI to enable Hyper Threading
+                       See also Documentation/pm.txt.
+  
++      acpi_pic_sci=   [HW,ACPI] ACPI System Control Interrupt trigger mode
++                      Format: { level | edge }
++                      level   Force PIC-mode SCI to Level Trigger (default)
++                      edge    Force PIC-mode SCI to Edge Trigge
++
++      acpi_irq_balance        [HW,ACPI] ACPI will balance active IRQs
++                              default in APIC mode
++
++      acpi_irq_nobalance      [HW,ACPI] ACPI will not move active IRQs (default)
++                              default in PIC mode
++
++      acpi_irq_pci=   [HW,ACPI] If irq_balance, Clear listed IRQs for use by PCI
++                      Format: <irq>,<irq>...
++
++      acpi_irq_isa=   [HW,ACPI] If irq_balance, Mark listed IRQs used by ISA
++                      Format: <irq>,<irq>...
++
+       ad1816=         [HW,OSS]
+                       Format: <io>,<irq>,<dma>,<dma2>
+                       See also Documentation/sound/oss/AD1816.
+@@ -214,7 +232,7 @@ running once the system is up.
+                       Forces specified timesource (if avaliable) to be used
+                       when calculating gettimeofday(). If specicified timesource
+                       is not avalible, it defaults to PIT. 
+-                      Format: { pit | tsc | cyclone | ... }
++                      Format: { pit | tsc | cyclone | pmtmr }
+       hpet=           [IA-32,HPET] option to disable HPET and use PIT.
+                       Format: disable
+@@ -303,6 +321,10 @@ running once the system is up.
+                       See comment before function elanfreq_setup() in
+                       arch/i386/kernel/cpu/cpufreq/elanfreq.c.
++      elevator=       [IOSCHED]
++                      Format: {"as"|"cfq"|"deadline"|"noop"}
++                      See Documentation/as-iosched.txt for details
++
+       es1370=         [HW,OSS]
+                       Format: <lineout>[,<micbias>]
+                       See also header of sound/oss/es1370.c.
+@@ -790,7 +812,8 @@ running once the system is up.
+                       before loading.
+                       See Documentation/ramdisk.txt.
+-      psmouse_noext   [HW,MOUSE] Disable probing for PS2 mouse protocol extensions
++      psmouse_proto=  [HW,MOUSE] Highest PS2 mouse protocol extension to
++                      probe for (bare|imps|exps).
+       psmouse_resetafter=
+                       [HW,MOUSE] Try to reset Synaptics Touchpad after so many
+@@ -1144,7 +1167,7 @@ running once the system is up.
+                       See header of drivers/scsi/wd7000.c.
+       wdt=            [WDT] Watchdog
+-                      See Documentation/watchdog.txt.
++                      See Documentation/watchdog/watchdog.txt.
+       xd=             [HW,XT] Original XT pre-IDE (RLL encoded) disks.
+       xd_geo=         See header of drivers/block/xd.c.
+--- linux-2.6.0/Documentation/kobject.txt      2003-09-08 13:58:55.000000000 -0700
++++ 25/Documentation/kobject.txt       2003-12-28 23:22:05.000000000 -0800
+@@ -2,7 +2,7 @@ The kobject Infrastructure
+ Patrick Mochel <mochel@osdl.org>
+-Updated: 3 June 2003
++Updated: 12 November 2003
+ Copyright (c)  2003 Patrick Mochel
+@@ -128,7 +128,33 @@ reference count or do other wacky things
+ (like the networking layer). 
+-1.4 sysfs
++1.4 Order dependencies
++
++Fields in a kobject must be initialized before they are used, as
++indicated in this table:
++
++      k_name          Before kobject_add() (1)
++      name            Before kobject_add() (1)
++      refcount        Before kobject_init() (2)
++      entry           Set by kobject_init()
++      parent          Before kobject_add() (3)
++      kset            Before kobject_init() (4)
++      ktype           Before kobject_add() (4)
++      dentry          Set by kobject_add()
++
++(1) If k_name isn't already set when kobject_add() is called,
++it will be set to name.
++
++(2) Although kobject_init() sets refcount to 1, a warning will be logged
++if refcount is not equal to 0 beforehand.
++
++(3) If parent isn't already set when kobject_add() is called,
++it will be set to kset's embedded kobject.
++
++(4) kset and ktype are optional. If they are used, they should be set
++at the times indicated.
++
++1.5 sysfs
+ Each kobject receives a directory in sysfs. This directory is created
+ under the kobject's parent directory. 
+@@ -210,7 +236,25 @@ kset_find_obj() may be used to locate a 
+ name. The kobject, if found, is returned. 
+-2.3 sysfs
++2.3 Order dependencies
++
++Fields in a kset must be initialized before they are used, as indicated
++in this table:
++
++      subsys          Before kset_add()
++      ktype           Before kset_add() (1)
++      list            Set by kset_init()
++      kobj            Before kset_init() (2)
++      hotplug_ops     Before kset_add() (1)
++
++(1) ktype and hotplug_ops are optional. If they are used, they should
++be set at the times indicated.
++
++(2) kobj is passed to kobject_init() during kset_init() and to
++kobject_add() during kset_add(); it must initialized accordingly.
++
++
++2.4 sysfs
+ ksets are represented in sysfs when their embedded kobjects are
+ registered. They follow the same rules of parenting, with one
+@@ -352,7 +396,21 @@ subsys_set_kset(obj,subsys)
+ - Sets obj->subsys.kset.kobj.kset to the subsystem's embedded kset.
+-4.4 sysfs
++4.4 Order dependencies
++
++Fields in a subsystem must be initialized before they are used,
++as indicated in this table:
++
++      kset            Before subsystem_register() (1)
++      rwsem           Set by subsystem_register()
++
++(1) kset is minimally initialized by the decl_subsys macro. It is
++passed to kset_init() and kset_add() by subsystem_register(). If its
++subsys member isn't already set, subsystem_register() sets it to the
++containing subsystem.
++
++
++4.5 sysfs
+ subsystems are represented in sysfs via their embedded kobjects. They
+ follow the same rules as previously mentioned with no exceptions. They
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/MSI-HOWTO.txt     2003-12-28 23:21:44.000000000 -0800
+@@ -0,0 +1,321 @@
++              The MSI Driver Guide HOWTO
++      Tom L Nguyen tom.l.nguyen@intel.com
++                      10/03/2003
++
++1. About this guide
++
++This guide describes the basics of Message Signaled Interrupts(MSI), the
++advantages of using MSI over traditional interrupt mechanisms, and how
++to enable your driver to use MSI or MSI-X. Also included is a Frequently
++Asked Questions.
++
++2. Copyright 2003 Intel Corporation
++
++3. What is MSI/MSI-X?
++
++Message Signaled Interrupt (MSI), as described in the PCI Local Bus
++Specification Revision 2.3 or latest, is an optional feature, and a
++required feature for PCI Express devices. MSI enables a device function
++to request service by sending an Inbound Memory Write on its PCI bus to
++the FSB as a Message Signal Interrupt transaction. Because MSI is
++generated in the form of a Memory Write, all transaction conditions,
++such as a Retry, Master-Abort, Target-Abort or normal completion, are
++supported.
++
++A PCI device that supports MSI must also support pin IRQ assertion
++interrupt mechanism to provide backward compatibility for systems that
++do not support MSI. In Systems, which support MSI, the bus driver is
++responsible for initializing the message address and message data of
++the device function's MSI/MSI-X capability structure during device
++initial configuration.
++
++An MSI capable device function indicates MSI support by implementing
++the MSI/MSI-X capability structure in its PCI capability list. The
++device function may implement both the MSI capability structure and
++the MSI-X capability structure; however, the bus driver should not
++enable both, but instead enable only the MSI-X capability structure.
++
++The MSI capability structure contains Message Control register,
++Message Address register and Message Data register. These registers
++provide the bus driver control over MSI. The Message Control register
++indicates the MSI capability supported by the device. The Message
++Address register specifies the target address and the Message Data
++register specifies the characteristics of the message. To request
++service, the device function writes the content of the Message Data
++register to the target address. The device and its software driver
++are prohibited from writing to these registers.
++
++The MSI-X capability structure is an optional extension to MSI. It
++uses an independent and separate capability structure. There are
++some key advantages to implementing the MSI-X capability structure
++over the MSI capability structure as described below.
++
++      - Support a larger maximum number of vectors per function.
++
++      - Provide the ability for system software to configure
++      each vector with an independent message address and message
++      data, specified by a table that resides in Memory Space.
++
++        - MSI and MSI-X both support per-vector masking. Per-vector
++      masking is an optional extension of MSI but a required
++      feature for MSI-X. Per-vector masking provides the kernel
++      the ability to mask/unmask MSI when servicing its software
++      interrupt service routing handler. If per-vector masking is
++      not supported, then the device driver should provide the
++      hardware/software synchronization to ensure that the device
++      generates MSI when the driver wants it to do so.
++
++4. Why use MSI?
++
++As a benefit the simplification of board design, MSI allows board
++designers to remove out of band interrupt routing. MSI is another
++step towards a legacy-free environment.
++
++Due to increasing pressure on chipset and processor packages to
++reduce pin count, the need for interrupt pins is expected to
++diminish over time. Devices, due to pin constraints, may implement
++messages to increase performance.
++
++PCI Express endpoints uses INTx emulation (in-band messages) instead
++of IRQ pin assertion. Using INTx emulation requires interrupt
++sharing among devices connected to the same node (PCI bridge) while
++MSI is unique (non-shared) and does not require BIOS configuration
++support. As a result, the PCI Express technology requires MSI
++support for better interrupt performance.
++
++Using MSI enables the device functions to support two or more
++vectors, which can be configure to target different CPU's to
++increase scalability.
++
++5. Configuring a driver to use MSI/MSI-X
++
++By default, the kernel will not enable MSI/MSI-X on all devices that
++support this capability once the patch is installed. A kernel
++configuration option must be selected to enable MSI/MSI-X support.
++
++5.1 Including MSI support into the kernel
++
++To include MSI support into the kernel requires users to patch the
++VECTOR-base patch first and then the MSI patch because the MSI
++support needs VECTOR based scheme. Once these patches are installed,
++setting CONFIG_PCI_USE_VECTOR enables the VECTOR based scheme and
++the option for MSI-capable device drivers to selectively enable MSI
++(using pci_enable_msi as desribed below).
++
++Since the target of the inbound message is the local APIC, providing
++CONFIG_PCI_USE_VECTOR is dependent on whether CONFIG_X86_LOCAL_APIC
++is enabled or not.
++
++int pci_enable_msi(struct pci_dev *)
++
++With this new API, any existing device driver, which like to have
++MSI enabled on its device function, must call this explicitly. A
++successful call will initialize the MSI/MSI-X capability structure
++with ONE vector, regardless of whether the device function is
++capable of supporting multiple messages. This vector replaces the
++pre-assigned dev->irq with a new MSI vector. To avoid the conflict
++of new assigned vector with existing pre-assigned vector requires
++the device driver to call this API before calling request_irq(...).
++
++The below diagram shows the events, which switches the interrupt
++mode on the MSI-capable device function between MSI mode and
++PIN-IRQ assertion mode.
++
++       ------------   pci_enable_msi   ------------------------
++      |            | <=============== |                        |
++      | MSI MODE   |                  | PIN-IRQ ASSERTION MODE |
++      |            | ===============> |                        |
++       ------------   free_irq         ------------------------
++
++5.2 Configuring for MSI support
++
++Due to the non-contiguous fashion in vector assignment of the
++existing Linux kernel, this patch does not support multiple
++messages regardless of the device function is capable of supporting
++more than one vector. The bus driver initializes only entry 0 of
++this capability if pci_enable_msi(...) is called successfully by
++the device driver.
++
++5.3 Configuring for MSI-X support
++
++Both the MSI capability structure and the MSI-X capability structure
++share the same above semantics; however, due to the ability of the
++system software to configure each vector of the MSI-X capability
++structure with an independent message address and message data, the
++non-contiguous fashion in vector assignment of the existing Linux
++kernel has no impact on supporting multiple messages on an MSI-X
++capable device functions. By default, as mentioned above, ONE vector
++should be always allocated to the MSI-X capability structure at
++entry 0. The bus driver does not initialize other entries of the
++MSI-X table.
++
++Note that the PCI subsystem should have full control of a MSI-X
++table that resides in Memory Space. The software device driver
++should not access this table.
++
++To request for additional vectors, the device software driver should
++call function msi_alloc_vectors(). It is recommended that the
++software driver should call this function once during the
++initialization phase of the device driver.
++
++The function msi_alloc_vectors(), once invoked, enables either
++all or nothing, depending on the current availability of vector
++resources. If no vector resources are available, the device function
++still works with ONE vector. If the vector resources are available
++for the number of vectors requested by the driver, this function
++will reconfigure the MSI-X capability structure of the device with
++additional messages, starting from entry 1. To emphasize this
++reason, for example, the device may be capable for supporting the
++maximum of 32 vectors while its software driver usually may request
++4 vectors.
++
++For each vector, after this successful call, the device driver is
++responsible to call other functions like request_irq(), enable_irq(),
++etc. to enable this vector with its corresponding interrupt service
++handler. It is the device driver's choice to have all vectors shared
++the same interrupt service handler or each vector with a unique
++interrupt service handler.
++
++In addition to the function msi_alloc_vectors(), another function
++msi_free_vectors() is provided to allow the software driver to
++release a number of vectors back to the vector resources. Once
++invoked, the PCI subsystem disables (masks) each vector released.
++These vectors are no longer valid for the hardware device and its
++software driver to use. Like free_irq, it recommends that the
++device driver should also call msi_free_vectors to release all
++additional vectors previously requested.
++
++int msi_alloc_vectors(struct pci_dev *dev, int *vector, int nvec)
++
++This API enables the software driver to request the PCI subsystem
++for additional messages. Depending on the number of vectors
++available, the PCI subsystem enables either all or nothing.
++
++Argument dev points to the device (pci_dev) structure.
++Argument vector is a pointer of integer type. The number of
++elements is indicated in argument nvec.
++Argument nvec is an integer indicating the number of messages
++requested.
++A return of zero indicates that the number of allocated vector is
++successfully allocated. Otherwise, indicate resources not
++available.
++
++int msi_free_vectors(struct pci_dev* dev, int *vector, int nvec)
++
++This API enables the software driver to inform the PCI subsystem
++that it is willing to release a number of vectors back to the
++MSI resource pool. Once invoked, the PCI subsystem disables each
++MSI-X entry associated with each vector stored in the argument 2.
++These vectors are no longer valid for the hardware device and
++its software driver to use.
++
++Argument dev points to the device (pci_dev) structure.
++Argument vector is a pointer of integer type. The number of
++elements is indicated in argument nvec.
++Argument nvec is an integer indicating the number of messages
++released.
++A return of zero indicates that the number of allocated vectors
++is successfully released. Otherwise, indicates a failure.
++
++5.4 Hardware requirements for MSI support
++MSI support requires support from both system hardware and
++individual hardware device functions.
++
++5.4.1 System hardware support
++Since the target of MSI address is the local APIC CPU, enabling
++MSI support in Linux kernel is dependent on whether existing
++system hardware supports local APIC. Users should verify their
++system whether it runs when CONFIG_X86_LOCAL_APIC=y.
++
++In SMP environment, CONFIG_X86_LOCAL_APIC is automatically set;
++however, in UP environment, users must manually set
++CONFIG_X86_LOCAL_APIC. Once CONFIG_X86_LOCAL_APIC=y, setting
++CONFIG_PCI_USE_VECTOR enables the VECTOR based scheme and
++the option for MSI-capable device drivers to selectively enable
++MSI (using pci_enable_msi as desribed below).
++
++Note that CONFIG_X86_IO_APIC setting is irrelevant because MSI
++vector is allocated new during runtime and MSI support does not
++depend on BIOS support. This key independency enables MSI support
++on future IOxAPIC free platform.
++
++5.4.2 Device hardware support
++The hardware device function supports MSI by indicating the
++MSI/MSI-X capability structure on its PCI capability list. By
++default, this capability structure will not be initialized by
++the kernel to enable MSI during the system boot. In other words,
++the device function is running on its default pin assertion mode.
++Note that in many cases the hardware supporting MSI have bugs,
++which may result in system hang. The software driver of specific
++MSI-capable hardware is responsible for whether calling
++pci_enable_msi or not. A return of zero indicates the kernel
++successfully initializes the MSI/MSI-X capability structure of the
++device funtion. The device function is now running on MSI mode.
++
++5.5 How to tell whether MSI is enabled on device function
++
++At the driver level, a return of zero from pci_enable_msi(...)
++indicates to the device driver that its device function is
++initialized successfully and ready to run in MSI mode.
++
++At the user level, users can use command 'cat /proc/interrupts'
++to display the vector allocated for the device and its interrupt
++mode, as shown below.
++
++           CPU0       CPU1
++  0:     324639          0    IO-APIC-edge  timer
++  1:       1186          0    IO-APIC-edge  i8042
++  2:          0          0          XT-PIC  cascade
++ 12:       2797          0    IO-APIC-edge  i8042
++ 14:       6543          0    IO-APIC-edge  ide0
++ 15:          1          0    IO-APIC-edge  ide1
++169:          0          0   IO-APIC-level  uhci-hcd
++185:          0          0   IO-APIC-level  uhci-hcd
++193:        138         10         PCI MSI  aic79xx
++201:         30          0         PCI MSI  aic79xx
++225:         30          0   IO-APIC-level  aic7xxx
++233:         30          0   IO-APIC-level  aic7xxx
++NMI:          0          0
++LOC:     324553     325068
++ERR:          0
++MIS:          0
++
++6. FAQ
++
++Q1. Are there any limitations on using the MSI?
++
++A1. If the PCI device supports MSI and conforms to the
++specification and the platform supports the APIC local bus,
++then using MSI should work.
++
++Q2. Will it work on all the Pentium processors (P3, P4, Xeon,
++AMD processors)? In P3 IPI's are transmitted on the APIC local
++bus and in P4 and Xeon they are transmitted on the system
++bus. Are there any implications with this?
++
++A2. MSI support enables a PCI device sending an inbound
++memory write (0xfeexxxxx as target address) on its PCI bus
++directly to the FSB. Since the message address has a
++redirection hint bit cleared, it should work.
++
++Q3. The target address 0xfeexxxxx will be translated by the
++Host Bridge into an interrupt message. Are there any
++limitations on the chipsets such as Intel 8xx, Intel e7xxx,
++or VIA?
++
++A3. If these chipsets support an inbound memory write with
++target address set as 0xfeexxxxx, as conformed to PCI
++specification 2.3 or latest, then it should work.
++
++Q4. From the driver point of view, if the MSI is lost because
++of the errors occur during inbound memory write, then it may
++wait for ever. Is there a mechanism for it to recover?
++
++A4. Since the target of the transaction is an inbound memory
++write, all transaction termination conditions (Retry,
++Master-Abort, Target-Abort, or normal completion) are
++supported. A device sending an MSI must abide by all the PCI
++rules and conditions regarding that inbound memory write. So,
++if a retry is signaled it must retry, etc... We believe that
++the recommendation for Abort is also a retry (refer to PCI
++specification 2.3 or latest).
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/must-fix.txt      2003-12-28 23:21:10.000000000 -0800
+@@ -0,0 +1,288 @@
++
++Must-fix bugs
++=============
++
++drivers/char/
++~~~~~~~~~~~~~
++
++o TTY locking is broken.
++
++  o see FIXME in do_tty_hangup().  This causes ppp BUGs in local_bh_enable()
++
++  o Other problems: aviro, dipankar, Alan have details.
++
++  o somebody will have to document the tty driver and ldisc API
++
++drivers/tty
++~~~~~~~~~~~
++
++o viro: tty_driver refcounting, tty/misc/upper levels of sound still not
++  completely fixed.
++
++drivers/block/
++~~~~~~~~~~~~~~
++
++o loop.c: Concurrent write access on block devices might cause a deadlock
++  of the complete system. See:
++  http://marc.theaimsgroup.com/?l=linux-kernel&m=106275365925769&w==
++  http://bugzilla.kernel.org/show_bug.cgi?id=1198
++  Thread of possible fix:
++  http://www.kerneli.org/pipermail/cryptoapi-devel/2003-October/000676.html
++
++  (Fruhwirth Clemens)
++
++o ideraid hasn't been ported to 2.5 at all yet.
++
++  We need to understand whether the proposed BIO split code will suffice
++  for this.
++
++drivers/input/
++~~~~~~~~~~~~~~
++
++o rmk: unconverted keyboard/mouse drivers (there's a deadline of 2.6.0
++  currently on these remaining in my/Linus' tree.)
++
++o viro: large absence of locking.
++
++o viro: parport is nearly as bad as that and there the code is more hairy.
++  IMO parport is more of "figure out what API changes are needed for its
++  users, get them done ASAP, then fix generic layer at leisure"
++
++o (Albert Cahalan) Lots of people (check Google) get this message from the
++  kernel:
++
++  psmouse.c: Lost synchronization, throwing 2 bytes away.
++
++  (the number of bytes will be 1, 2, or 3)
++
++  At work, I get it when there is heavy NFS traffic.  The mouse goes crazy,
++  jumping around and doing random cut-and-paste all over everything.  This
++  is with a decently fast and modern PC.
++
++o There seem to be too many reports of keyboards and mice failing or acting
++  strangely.
++
++
++drivers/misc/
++~~~~~~~~~~~~~
++
++o rmk: UCB1[23]00 drivers, currently sitting in drivers/misc in the ARM
++  tree.  (touchscreen, audio, gpio, type device.)
++
++  These need to be moved out of drivers/misc/ and into real places
++
++o viro: actually, misc.c has a good chance to die.  With cdev-cidr that's
++  trivial.
++
++drivers/net/
++~~~~~~~~~~~~
++
++drivers/net/irda/
++~~~~~~~~~~~~~~~~~
++
++  (Jean Tourrilhes)
++
++o irport need to be converted to sir-kthread
++
++o dongle drivers need to be converted to sir-dev (in progress)
++
++o new drivers (irtty-sir/smsc-ircc2/donauboe) need more testing (in progress)
++
++
++drivers/pci/
++~~~~~~~~~~~~
++
++o alan: Some cardbus crashes the system
++
++  (bugzilla, please?)
++
++drivers/pcmcia/
++~~~~~~~~~~~~~~~
++
++o alan: This is a locking disaster.
++
++  (rmk, brodo: in progress)
++
++drivers/pld/
++~~~~~~~~~~~~
++
++o rmk: EPXA (ARM platform) PLD hotswap drivers (drivers/pld)
++
++  (rmk: will work out what to do here.  maybe drivers/arm/)
++
++drivers/video/
++~~~~~~~~~~~~~~
++
++o Lots of drivers don't compile, others do but don't work.
++
++drivers/scsi/
++~~~~~~~~~~~~~
++
++o Convert am53c974, dpt_i2o, initio and pci2220i to DMA-mapping
++
++o Make inia100, cpqfc, pci2000 and dc390t compile
++
++o Convert
++
++   wd33c99 based: a2091 a3000 gpv11 mvme174 sgiwd93
++
++   53c7xx based: amiga7xxx bvme6000 mvme16x initio am53c974 pci2000
++   pci2220i dc390t
++
++  To new error handling
++
++  It also might be possible to shift the 53c7xx based drivers over to
++  53c700 which does the new EH stuff, but I don't have the hardware to check
++  such a shift.
++
++  For the non-compiling stuff, I've probably missed a few that just aren't
++  compilable on my platforms, so any updates would be welcome.  Also, are
++  some of our non-compiling or unconverted drivers obsolete?
++
++fs/
++~~~
++
++o AIO/direct-IO writes can race with truncate and wreck filesystems.
++  (Badari has a patch)
++
++o viro: fs/char_dev.c needs removal of aeb stuff and merge of cdev-cidr.
++  In progress.
++
++o forward-port sct's O_DIRECT fixes (Badari has a patch)
++
++o viro: there is some generic stuff for namei/namespace/super, but that's a
++  slow-merge and can go in 2.6 just fine
++
++o trond: NFS has a mmap-versus-truncate problem (fixed? needs testing)
++
++o trond: NFSv4 client, bugs in lockd, RPSEC_GSS for NFSv[23], some atomic open
++  bits. more info: http://www.fys.uio.no/~trondmy/src/Linux-2.6.x/2.6.0-test11/
++
++kernel/sched.c
++~~~~~~~~~~~~~~
++
++o Starvation, general interactivity need close monitoring.
++
++o SMT aware scheduler (Ingo, Rusty, Nick have implementations)
++
++kernel/
++~~~~~~~
++
++o Alan: 32bit uid support is *still* broken for process accounting.
++
++  Create a 32bit uid, turn accounting on.  Shock horror it doesn't work
++  because the field is 16bit.  We need an acct structure flag day for 2.6
++  IMHO
++
++  (alan has patch)
++
++o viro: core sysctl code is racy.  And its interaction wiuth sysfs
++
++o (ingo) rwsems (on x86) are limited to 32766 waiting processes.  This
++  means that setting pid_max to above 32K is unsafe :-(
++
++  An option is to use CONFIG_RWSEM_GENERIC_SPINLOCK variant all the time,
++  for all archs, and not inline any part of the ops.
++
++lib/kobject.c
++~~~~~~~~~~~~~
++
++o kobject refcounting (comments from Al Viro):
++
++  _anything_ can grab a temporary reference to kobject.  IOW, if kobject is
++  embedded into something that could be freed - it _MUST_ have a destructor
++  and that destructor _MUST_ be the destructor for containing object.
++
++  Any violation of the above (and we already have a bunch of those) is a
++  user-triggerable memory corruption.
++
++  We can tolerate it for a while in 2.5 (e.g.  during work on susbsystem we
++  can decide to switch to that way of handling objects and have subsystem
++  vulnerable for a while), but all such windows must be closed before 2.6
++  and during 2.6 we can't open them at all.
++
++o All block drivers which control multiple gendisks with a single
++  request_queue are broken, due to one-to-one assumptions in the request
++  queue sysfs hookup.
++
++mm/
++~~~
++
++o GFP_DMA32 (or something like that).  Lots of ideas.  jejb, zaitcev,
++  willy, arjan, wli.
++
++  Specifically, 64-bit systems need to be able to enforce 32-bit addressing
++  limits for device metadata like network cards' ring buffers and SCSI
++  command descriptors.
++
++o access_process_vm() doesn't flush right.  We probably need new flushing
++  primitives to do this (davem?)
++
++
++modules
++~~~~~~~
++
++  (Rusty)
++
++net/
++~~~~
++
++  (davem)
++
++o UDP apps can in theory deadlock, because the ip_append_data path can end
++  up sleeping while the socket lock is held.
++
++  It is OK to sleep with the socket held held, normally.  But in this case
++  the sleep happens while waiting for socket memory/space to become
++  available, if another context needs to take the socket lock to free up the
++  space we could hang.
++
++  I sent a rough patch on how to fix this to Alexey, and he is analyzing
++  the situation.  I expect a final fix from him next week or so.
++
++o Semantics for IPSEC during operations such as TCP connect suck currently.
++
++  When we first try to connect to a destination, we may need to ask the
++  IPSEC key management daemon to resolve the IPSEC routes for us.  For the
++  purposes of what the kernel needs to do, you can think of it like ARP.  We
++  can't send the packet out properly until we resolve the path.
++
++  What happens now for IPSEC is basically this:
++
++  O_NONBLOCK: returns -EAGAIN over and over until route is resolved
++
++  !O_NONBLOCK: Sleeps until route is resolved
++
++  These semantics are total crap.  The solution, which Alexey is working
++  on, is to allow incomplete routes to exist.  These "incomplete" routes
++  merely put the packet onto a "resolution queue", and once the key manager
++  does it's thing we finish the output of the packet.  This is precisely how
++  ARP works.
++
++  I don't know when Alexey will be done with this.
++
++net/*/netfilter/
++~~~~~~~~~~~~~~~~
++
++  (Rusty)
++
++sound/
++~~~~~~
++
++global
++~~~~~~
++
++o viro: 64-bit dev_t (not a mustfix for 2.6.0). 32-bit dev_t is done, 64-bit
++  means extra work on nfsd/raid/etc.
++
++o alan: Forward port 2.4 fixes
++  - Chris Wright: Security fixes including execve holes, execve vs proc races
++
++o There are about 60 or 70 security related checks that need doing
++  (copy_user etc) from Stanford tools.  (badari is looking into this, and
++  hollisb)
++
++o A couple of hundred real looking bugzilla bugs
++
++o viro: cdev rework. Mostly done.
++
+--- linux-2.6.0/Documentation/networking/8139too.txt   2003-08-22 19:23:39.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,449 +0,0 @@
+-
+-              "8139too" Fast Ethernet driver for Linux
+-       RTL-8139, -8129, and -8130 10/100 Fast Ethernet adapters
+-
+-      Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
+-
+-                http://sourceforge.net/projects/gkernel/
+-
+-
+-            Architectures supported (all PCI platforms):
+-                  x86, Alpha AXP, PowerPC, Sparc64
+-
+-                  Kernel versions supported: 2.4.x
+-
+-
+-
+-Disclaimer
+-----------
+-
+-DO NOT CONTACT DONALD BECKER FOR SUPPORT OF THIS DRIVER, his driver is
+-completely different and maintained independently of the 8139too code base.
+-
+-
+-
+-Requirements
+-------------
+-Kernel 2.4.3 or later.
+-A Fast Ethernet adapter containing an RTL8139-based chip.
+-
+-
+-
+-Introduction
+-------------
+-
+-The "8139too" Fast Ethernet driver for Linux 2.4.0 is a substantial
+-modification of the experimental rtl8139 driver from Donald Becker,
+-some versions of which appeared in 2.2.x and 2.3.x kernels.  The
+-RTL-8139 is a very low-cost Fast Ethernet chip, which makes it very
+-popular.
+-
+-The step from 2.2.x to 2.4.x kernels brings many new features to Linux
+-device drivers.  Features for MMIO resources, a standard hot-plug API,
+-and other interfaces are now becoming requirements, as drivers move
+-off the x86 platform.  With that in mind, I have begun updating the
+-RTL-8139 driver to current 2.3.x (2.4) kernel standards and APIs, and
+-fixing the problems that users have been encountering.
+-
+-
+-
+-Features of 8139too
+--------------------
+-[note - this list intended for people familiar with kernel drivers]
+-
+-** 100% MMIO, for full speed operation.  All users (so far) have
+-reported performance increases over their existing RTL drivers.
+-
+-** Multi-platform support:  x86, Alpha, PPC, ...
+-
+-** Use proper SMP spinlocking, fixing SMP interrupt bugs, making the
+-driver portable to non-x86 SMP platforms in the process.
+-
+-** Use new PCI driver API for seamless, low-maintenance hot-plug support
+-
+-** Several bugs fixes from original rtl8139 1.08r (October 5, 1999),
+-including the very common "transmit timeout" problem.
+-
+-* Use new resource allocation API, required for hot-plug support
+-* Use new register read/write macros
+-* initcall support (module_init/exit)
+-* vastly improved debug tracing support
+-* code formatting in many places for readability
+-* use new init_etherdev() facilities
+-
+-...and probably some other less important changes which I forgot.
+-
+-
+-
+-Installation
+-------------
+-
+-OPTION 1: Build inside kernel tree (into kernel image, or as module)
+-
+-      (overwrite 8139too driver in kernel tree with different version)
+-      1) cp 8139too.c $my_source_tree/drivers/net/8139too.c
+-
+-OPTION 2: Build outside kernel tree
+-
+-      Use the included Makefile.
+-
+-
+-
+-Tested Adapters
+----------------
+-AOpen ALN-325C
+-AT-2500TX 10/100 PCI Fast Ethernet Network Adapter Card
+-D-Link DFE-530TX
+-Cnet CNF401 'SinglePoint' 10/100 Base-TX
+-Genius GF 100TXR4 Fast Ethernet 10/100M PCI Network Card
+-KTI KF-230TX
+-KTI KF-230TX/2
+-Lantech FastNet TX
+-Ovislink Fast Ethernet
+-Planet ENW-9504 (V.4) 10/100
+-SDT Jeoun Fast PCI-TX
+-SMC EZNET 10/100
+-UNEX NexNIC ND012C
+-
+-(please add your adapter model to this list)
+-
+-
+-
+-Status of Platform Support
+---------------------------
+-
+-(see errata below for details)
+-
+-x86:          tested, stable
+-Alpha AXP:    tested, stable
+-PowerPC:      tested, unstable
+-Sparc64:      not tested
+-
+-
+-
+-Special Thanks
+---------------
+-The following people contributed invaluable testing time, feedback
+-and/or patches during the development of this driver.  Thanks to all
+-of them.
+-
+-Donald Becker, Alan Cox, Richard Stallman, Linus Torvalds - inspiration
+-
+-Alan Cox, Gerard Roudier - insight on posted MMIO writes
+-
+-Martin Mares - code review
+-
+-Tigran Aivazian - testing, code review, and a bug fix
+-
+-Chmouel Boudjnah, Alexander Dietrich, Oleg Drokin,
+-James Fidell, Taso Hatzi, Peter K - intrepid test team
+-
+-And thanks to every supporter free software.
+-
+-(see top of 8139too.c for further credits and kudos)
+-
+-
+-
+-Submitting Bug Reports
+-----------------------
+-Obtain and compile the modified rtl8139-diag source code from the
+-8139too driver Web site, http://sourceforge.net/projects/gkernel/
+-This diagnostics programs, originally from Donald Becker, has been
+-modified to display all registers on your RTL8139 chip, not just the
+-first 0x80.
+-
+-If possible, send the output of a working and broken driver with
+-      rtl8139-diag -mmaaavvveefN > my-output-file.txt
+-
+-Send "lspci -vvv" or "cat /proc/pci" output for PCI information.
+-
+-
+-
+-Known Bugs / Errata / To-Do
+----------------------------
+-The following issues are known, and are actively being pursued.  Patches
+-to resolve these issues is welcome.  If a problem occurs which is not in
+-the list, please report it.  That's why we do beta releases, after all...
+-
+-
+-
+-1) Work with Donald to merge fixes and updates into his driver.
+-
+-2) ETHTOOL_SSET support
+-
+-3) PPC platform has stability problems. (XXX: verify this is still true)
+-
+-4) Sparc64 platform not tested at all.
+-
+-8) Much improved command line / module parameter setup.  (patches and
+-suggestions welcome)  (WIP)
+-
+-9) Better documentation.  (patches welcome)
+-
+-12) 10base-T support flaky or slow (todo: verify this is still true)
+-
+-
+-
+-
+-Change History
+---------------
+-
+-Version 0.9.26 - August 9, 2002
+-
+-* Fix MII ioctl phy id corruption.
+-* Fix big-endian multicast bug.
+-* Support register dumps via ethtool.
+-* Fix several uses of 'len' after potential skb free, in dev->hard_start_xmit
+-* Replace several "magic numbers" with their proper representation
+-  constants in linux/mii.h.
+-* Support ethtool media interface via generic kernel MII API
+-* Export NIC-specific statistics via ethtool.
+-* Proper support for RTL8139 rev K. (can be disabled via
+-  compile-time conditional)
+-* Add PCI ids for new 8139 boards.
+-* Use ethernet crc via generic linux/crc32.h kernel API.
+-* Better RX reset.  Old rx-reset method still available via
+-  a compile-time conditional.
+-* Only account specific RX errors if rx_status is !OK
+-
+-
+-Version 0.9.22 - November 8, 2001
+-
+-* Additional retries before aborting Tx
+-* Do not write other TxConfig bits when writing clear-abort bit.
+-* Ack TxErr intr status after each Tx abort, too.
+-* Fix oops in interface restart
+-
+-
+-Version 0.9.21 - November 1, 2001
+-
+-* Disable early Rx, it hurts performance and creates races.
+-* Remove DPRINTK macro function tracing.
+-* Better interrupt sharing behavior.
+-* Acknowledge PCI errors.
+-* Remove early-Rx acknowledgement, unnecessary
+-* Remove code for uncommon case where Tx packets are
+-  properly aligned, and do not need to be copied.
+-  Tx packets are now always copied into a static DMA buffer,
+-  which is allocated at interface open.
+-* Fix problems with kernel thread exit.
+-
+-
+-Version 0.9.20 - October 18, 2001
+-
+-* Print out notice when 8139C+ chip is detected
+-* Add id for D-Link DFE690TXD pcmcia cardbus card (Gert Dewit)
+-
+-
+-Version 0.9.19 - October 9, 2001
+-
+-* Eliminate buffer copy for unaligned Tx's (manfred)
+-* Better RX error recovery (manfred)
+-* Wake-On-LAN and ETHTOOL_GSET support (Kalle Niemitalo)
+-* Fix assertion in PIO mode (various)
+-
+-
+-Version 0.9.18 - July 6, 2001
+-
+-* Fix race leading to crashes on some machines.
+-* Minimize race leading to low performance.
+-* Correct interrupt acknowledgement to cover all three
+-  relevant Rx events.
+-* Add ethtool driver info support.
+-* Collect additional driver-internal statistics.
+-* Add descriptions for module parameters.
+-* Support new SIOCxMIIxxx ioctls added in kernel 2.4.6.
+-* Multicast filter big endian fix.
+-* Support new PCI PM API added in kernel 2.4.6.
+-
+-
+-Version 0.9.17 - May 7, 2001
+-
+-* Fix chipset wakeup bug which prevent media connection for 8139B
+-* Print out "media is unconnected..." instead of
+-  "partner ability 0000"
+-
+-
+-Version 0.9.16 - April 14, 2001
+-
+-* Complete MMIO audit, disable read-after-every-write
+-* Update Rx interrupt handling
+-* Enable Early Rx thresholds, highly recommended to reduce
+-  Rx FIFO overflow
+-* Make 8129 support conditional
+-* Support for new 2.4.3 kernel APIs
+-* More correct PIO/MMIO PCI BAR region size checking
+-* Add check for totally dead/missing hardware
+-* Disable media timer code to "set full duplex"
+-* s/spin_lock_irq/spin_lock_irqsave/
+-* Only set AcceptMulticast if more than one mc address
+-* Only set rx_mode if changed, in set_rx_mode
+-* Only suspend/resume if interface is up
+-* Always print out version upon module load, even if no devices found
+-
+-
+-Version 0.9.15 - February 20, 2001
+-
+-* Call pci_enable_device to wake up/assign resource to device,
+-  before actually using it.
+-* Support wacky clone PCI ids (report from Norival Toniato Junior)
+-* Text spelling corrections
+-* Make sure tp->phys[] is signed
+-* Always wake queue after hw restart, in tx_timeout
+-* Record time of last received packet
+-
+-
+-Version 0.9.14 - January 11, 2001
+-
+-* Merge some changes from Becker version 1.13:
+-      * Add DFE 538TX PCI id
+-      * MII read/write functions updated
+-      * Cfg93[45]6 lock/unlock fix
+-      * RTL-8129 (MII) support
+-* Clean up spinlocking
+-
+-
+-Version 0.9.13 - December, 2000
+-
+-* Clear blocked signals, avoid buffer overrun setting current->comm
+-* Remove bogus PCI BAR length assertions
+-* Remove unused 'debug' module parameter
+-
+-
+-Version 0.9.12 - November 23, 2000
+-
+-* Kill major Tx stop/wake queue race
+-* Use SET_MODULE_OWNER and fix module unload race
+-* Fix cable length ("Twister") tuning
+-* Proper media[] array length checking
+-* Replace timer with kernel thread for twister tuning state machine
+-  and media checking.  Fixes mdio_xxx locking, now mdio_xxx is always
+-  protected by rtnl_lock semaphore.
+-* Correct some sledgehammer a.k.a. overzealous spin-locks
+-* Performance: Eliminate atomic_t for Tx counters, we don't need it
+-* Performance: Don't copy Tx buffer if the rare case occurs where it
+-  is aligned perfectly for us.
+-* Eliminate needless casting of dev->priv
+-* PIO mode selection and Twister tuning are now CONFIG_xxx options
+-  (though purposefully not in net/Config.in... yet)
+-
+-
+-Version 0.9.11 - October 28, 2000
+-
+-* Do not fail when PIO and MMIO region lengths do not match.
+-  (They don't on some CardBus models, at least)
+-* Sanity check Rx packet status and size (Tobias)
+-* When handling a Tx timeout, disable Tx ASAP if not already.
+-* Do not inline Tx interrupt handler (better register usage)
+-* Handle dirty_tx signed integer wrap
+-* Do not abort Rx processing on lack of memory, keep going
+-  until the current Rx ring is completely handling. (Tobias)
+-* Clean up rtl8139_close
+-* Whitespace correction for dev_kfree_skb_irq call
+-
+-
+-Version 0.9.10 - September 12, 2000
+-
+-* Never wrap an Rx packet (faster Rx interrupt handling)
+-* Clear all TxAborted conditions (bug fix)
+-* Correct copyright
+-* More credits
+-* Update NWay doc URL
+-* Clean up commonly used ifdef switches
+-* Reorg info displayed at bootup/modprobe time
+-* Remove some unneeded spinlocks
+-* Misc cosmetic code cleanup
+-* Always print interrupt status for abnormal interrupts
+-* Use RealTek-recommended FIFO and DMA burst settings (1024 bytes)
+-
+-
+-Version 0.9.9 - September 9, 2000
+-
+-* Fix oops-able bug in Rx ring wrap calculation (David Ford)
+-* Use PIO instead of MMIO when USE_IO_OPS is defined
+-* Move Rx error handling out of Rx interrupt handler, resulting in
+-  tighter Rx interrupt processing
+-
+-
+-Version 0.9.8 - September 7, 2000
+-
+-* Propagate request_irq error value (andrew morton)
+-* Correct potential oops bug in PCI DMA unmap code
+-* Fix bugs related to counting/discounting of 32-bit CRC in each Rx packet
+-* Fix 16/32-bit bug in interrupt status check
+-* Timer cleanups (andrew morton)
+-
+-
+-Version 0.9.7 - June 11, 2000
+-
+-* Fix support for older chips (RTL8139 early chips should now work again)
+-
+-
+-Version 0.9.6 - May 30, 2000
+-
+-* Fix 4-extra-bytes bug
+-  (thanks to Markus Westergren, via Santiago Garcia Mantinan)
+-* Yet more improved chip recognition
+-
+-
+-Version 0.9.5 - May 17, 2000
+-
+-* Improved chip version recognition
+-* Continue banging away at receiver hang problem
+-* Use spin_lock_irq in another spot
+-* Don't print anything on pci_enable_device, it does so for us
+-* Disable buggy NWay code
+-* Define TxConfig bitmasks
+-
+-
+-Version 0.9.4.1 - April 27, 2000 - third public beta release
+-
+-* Replace several "magic numbers" with symbolic constants
+-* Differentiate between board-specific info and chip-specific info
+-  (allows for easier support of specific boards or chips)
+-* Move some of the transmit side outside of the spinlock
+-  by using atomic variables.  Use spin_lock_irq instead of
+-  spin_lock_irq{save,restore} in select places, for better performance.
+-* New module option "media" for forcing media selection.  Functions the
+-  same as "options" in other drivers, and will soon be renamed
+-  'options' to be homogeneous.
+-* New power management wake-up code
+-* Slightly more verbose chip id messages in kernel log
+-* Add/correct chip register constant list
+-* New chipset wake up (open) logic
+-* No longer locks CONFIGx updates
+-* Do not set Interfame Gap (IFG) bits in TxConfig
+-* Better Rx reset logic in case of Rx FIFO Overflow
+-* For chips which support it, enable bit to automatically clear Rx
+-  FIFO overflow
+-* No longer enable and disable interrupts in interrupt handler
+-  (technique borrowed from BSD driver, appears to have problems
+-   with some chips)
+-* H/W spinlock now protects ioctl
+-* Chipset-dependent RxConfig settings
+-
+-
+-Version 0.9.3.3.2 - Feb 22, 2000 - second public beta release
+-
+-* Begin integration of Daniel Kobras' MMIO flush patch (disabled for now)
+-* Softnet logic updates to fix bugs and improve performance
+-* Dynamic sizing of I/O resources (0x80 for older chips, 0xFF for newer ones)
+-* Remove bogus SiS entries from PCI probe table
+-* Add support for cards
+-      "Delta Electronics 8139 10/100BaseTX"
+-      "Addtron Technolgy 8139 10/100BaseTX"
+-* Fix major bug with rx ring buffer size (also present in rtl8139.c 1.08r)
+-* PCI DMA mapping by Dave Miller
+-* Complete rewrite of SMP locking logic
+-* Hotplug support
+-* Call rtl8139_hw_start from rtl8139_open, and remove duplicated code
+-  from rtl8139_open
+-* Reset NWay registers to sane defaults on rtl8139_open/hw_start
+-* Miscellaneous code cleanup
+-
+-
+-Version 0.7.0 - Feb 7, 2000 - first public beta release
+-* Initial public version, derived from Donald Becker's rtl8139.c v1.08r
+-
+-[EOF]
+-
+--- linux-2.6.0/Documentation/networking/bonding.txt   2003-09-27 18:57:43.000000000 -0700
++++ 25/Documentation/networking/bonding.txt    2003-12-28 23:21:00.000000000 -0800
+@@ -21,7 +21,7 @@ userspace tools, please follow the links
+ Table of Contents
+ =================
+- 
++
+ Installation
+ Bond Configuration
+ Module Parameters
+@@ -66,7 +66,7 @@ of the -I option on the ifenslave compil
+ /usr/include/linux.
+ To install ifenslave.c, do:
+-    # gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave 
++    # gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave
+     # cp ifenslave /sbin/ifenslave
+@@ -74,10 +74,10 @@ Bond Configuration
+ ==================
+ You will need to add at least the following line to /etc/modules.conf
+-so the bonding driver will automatically load when the bond0 interface is 
+-configured. Refer to the modules.conf manual page for specific modules.conf 
+-syntax details. The Module Parameters section of this document describes each 
+-bonding driver parameter. 
++so the bonding driver will automatically load when the bond0 interface is
++configured. Refer to the modules.conf manual page for specific modules.conf
++syntax details. The Module Parameters section of this document describes each
++bonding driver parameter.
+       alias bond0 bonding
+@@ -113,7 +113,7 @@ bonding interface (bond1), use MASTER=bo
+ network interface be a slave of bond1.
+ Restart the networking subsystem or just bring up the bonding device if your
+-administration tools allow it. Otherwise, reboot. On Red Hat distros you can 
++administration tools allow it. Otherwise, reboot. On Red Hat distros you can
+ issue `ifup bond0' or `/etc/rc.d/init.d/network restart'.
+ If the administration tools of your distribution do not support
+@@ -128,30 +128,30 @@ manually configure the bonding device wi
+ (use appropriate values for your network above)
+-You can then create a script containing these commands and place it in the 
++You can then create a script containing these commands and place it in the
+ appropriate rc directory.
+ If you specifically need all network drivers loaded before the bonding driver,
+-adding the following line to modules.conf will cause the network driver for 
++adding the following line to modules.conf will cause the network driver for
+ eth0 and eth1 to be loaded before the bonding driver.
+ probeall bond0 eth0 eth1 bonding
+-Be careful not to reference bond0 itself at the end of the line, or modprobe 
++Be careful not to reference bond0 itself at the end of the line, or modprobe
+ will die in an endless recursive loop.
+-To have device characteristics (such as MTU size) propagate to slave devices, 
+-set the bond characteristics before enslaving the device.  The characteristics 
++To have device characteristics (such as MTU size) propagate to slave devices,
++set the bond characteristics before enslaving the device.  The characteristics
+ are propagated during the enslave process.
+-If running SNMP agents, the bonding driver should be loaded before any network 
+-drivers participating in a bond. This requirement is due to the the interface 
+-index (ipAdEntIfIndex) being associated to the first interface found with a 
+-given IP address. That is, there is only one ipAdEntIfIndex for each IP 
+-address. For example, if eth0 and eth1 are slaves of bond0 and the driver for 
+-eth0 is loaded before the bonding driver, the interface for the IP address 
+-will be associated with the eth0 interface. This configuration is shown below, 
+-the IP address 192.168.1.1 has an interface index of 2 which indexes to eth0 
++If running SNMP agents, the bonding driver should be loaded before any network
++drivers participating in a bond. This requirement is due to the the interface
++index (ipAdEntIfIndex) being associated to the first interface found with a
++given IP address. That is, there is only one ipAdEntIfIndex for each IP
++address. For example, if eth0 and eth1 are slaves of bond0 and the driver for
++eth0 is loaded before the bonding driver, the interface for the IP address
++will be associated with the eth0 interface. This configuration is shown below,
++the IP address 192.168.1.1 has an interface index of 2 which indexes to eth0
+ in the ifDescr table (ifDescr.2).
+      interfaces.ifTable.ifEntry.ifDescr.1 = lo
+@@ -189,10 +189,10 @@ functions such as Interface_Scan_Next wi
+ Module Parameters
+ =================
+-Optional parameters for the bonding driver can be supplied as command line 
+-arguments to the insmod command. Typically, these parameters are specified in 
+-the file /etc/modules.conf (see the manual page for modules.conf). The 
+-available bonding driver parameters are listed below. If a parameter is not 
++Optional parameters for the bonding driver can be supplied as command line
++arguments to the insmod command. Typically, these parameters are specified in
++the file /etc/modules.conf (see the manual page for modules.conf). The
++available bonding driver parameters are listed below. If a parameter is not
+ specified the default value is used. When initially configuring a bond, it
+ is recommended "tail -f /var/log/messages" be run in a separate window to
+ watch for bonding driver error messages.
+@@ -202,19 +202,19 @@ parameters be specified, otherwise serio
+ during link failures.
+ arp_interval
+- 
+-        Specifies the ARP monitoring frequency in milli-seconds. 
+-        If ARP monitoring is used in a load-balancing mode (mode 0 or 2), the 
+-        switch should be configured in a mode that evenly distributes packets 
+-        across all links - such as round-robin. If the switch is configured to 
+-        distribute the packets in an XOR fashion, all replies from the ARP 
+-        targets will be received on the same link which could cause the other 
++
++        Specifies the ARP monitoring frequency in milli-seconds.
++        If ARP monitoring is used in a load-balancing mode (mode 0 or 2), the
++        switch should be configured in a mode that evenly distributes packets
++        across all links - such as round-robin. If the switch is configured to
++        distribute the packets in an XOR fashion, all replies from the ARP
++        targets will be received on the same link which could cause the other
+         team members to fail. ARP monitoring should not be used in conjunction
+-        with miimon. A value of 0 disables ARP monitoring. The default value 
++        with miimon. A value of 0 disables ARP monitoring. The default value
+         is 0.
+- 
++
+ arp_ip_target
+- 
++
+       Specifies the ip addresses to use when arp_interval is > 0. These
+       are the targets of the ARP request sent to determine the health of
+       the link to the targets. Specify these values in ddd.ddd.ddd.ddd
+@@ -223,8 +223,8 @@ arp_ip_target
+       maximum number of targets that can be specified is set at 16.
+ downdelay
+- 
+-        Specifies the delay time in milli-seconds to disable a link after a 
++
++        Specifies the delay time in milli-seconds to disable a link after a
+         link failure has been detected. This should be a multiple of miimon
+         value, otherwise the value will be rounded. The default value is 0.
+@@ -247,7 +247,7 @@ max_bonds
+       and bond2 will be created.  The default value is 1.
+ miimon
+- 
++
+         Specifies the frequency in milli-seconds that MII link monitoring
+         will occur. A value of zero disables MII link monitoring. A value
+         of 100 is a good starting point. See High Availability section for
+@@ -258,7 +258,7 @@ mode
+       Specifies one of the bonding policies. The default is
+       round-robin (balance-rr).  Possible values are (you can use
+       either the text or numeric option):
+- 
++
+       balance-rr or 0
+               Round-robin policy: Transmit in a sequential order
+@@ -273,7 +273,7 @@ mode
+               externally visible on only one port (network adapter)
+               to avoid confusing the switch.  This mode provides
+               fault tolerance.
+- 
++
+       balance-xor or 2
+               XOR policy: Transmit based on [(source MAC address
+@@ -293,7 +293,7 @@ mode
+               groups that share the same speed and duplex settings.
+               Transmits and receives on all slaves in the active
+               aggregator.
+- 
++
+               Pre-requisites:
+               1. Ethtool support in the base drivers for retrieving the
+@@ -317,7 +317,7 @@ mode
+               Ethtool support in the base drivers for retrieving the
+               speed of each slave.
+-      balance-alb or 6 
++      balance-alb or 6
+               Adaptive load balancing: includes balance-tlb + receive
+               load balancing (rlb) for IPV4 traffic and does not require
+@@ -327,7 +327,7 @@ mode
+               overwrites the src hw address with the unique hw address of
+               one of the slaves in the bond such that different clients
+               use different hw addresses for the server.
+-              
++
+               Receive traffic from connections created by the server is
+               also balanced. When the server sends an ARP Request the
+               bonding driver copies and saves the client's IP information
+@@ -363,25 +363,11 @@ mode
+               2. Base driver support for setting the hw address of a
+               device also when it is open. This is required so that there
+               will always be one slave in the team using the bond hw
+-              address (the current_slave) while having a unique hw
+-              address for each slave in the bond. If the current_slave
+-              fails it's hw address is swapped with the new current_slave
++              address (the curr_active_slave) while having a unique hw
++              address for each slave in the bond. If the curr_active_slave
++              fails it's hw address is swapped with the new curr_active_slave
+               that was chosen.
+-multicast
+-
+-        Option specifying the mode of operation for multicast support.
+-        Possible values are:
+-
+-      disabled or 0
+-              Disabled (no multicast support)
+-
+-        active or 1
+-              Enabled on active slave only, useful in active-backup mode
+-
+-      all or 2
+-              Enabled on all slaves, this is the default
+-
+ primary
+         A string (eth0, eth2, etc) to equate to a primary device. If this
+@@ -397,11 +383,11 @@ primary
+         primary is only valid in active-backup mode.
+ updelay
+- 
+-        Specifies the delay time in milli-seconds to enable a link after a 
++
++        Specifies the delay time in milli-seconds to enable a link after a
+         link up status has been detected. This should be a multiple of miimon
+         value, otherwise the value will be rounded. The default value is 0.
+- 
++
+ use_carrier
+         Specifies whether or not miimon should use MII or ETHTOOL
+@@ -529,20 +515,20 @@ Verifying Bond Configuration
+ ----------------------------
+ The bonding driver information files reside in the /proc/net/bonding directory.
+-Sample contents of /proc/net/bonding/bond0 after the driver is loaded with 
++Sample contents of /proc/net/bonding/bond0 after the driver is loaded with
+ parameters of mode=0 and miimon=1000 is shown below.
+- 
++
+         Bonding Mode: load balancing (round-robin)
+         Currently Active Slave: eth0
+         MII Status: up
+         MII Polling Interval (ms): 1000
+         Up Delay (ms): 0
+         Down Delay (ms): 0
+- 
++
+         Slave Interface: eth1
+         MII Status: up
+         Link Failure Count: 1
+- 
++
+         Slave Interface: eth0
+         MII Status: up
+         Link Failure Count: 1
+@@ -550,34 +536,34 @@ parameters of mode=0 and miimon=1000 is 
+ 2) Network verification
+ -----------------------
+ The network configuration can be verified using the ifconfig command. In
+-the example below, the bond0 interface is the master (MASTER) while eth0 and 
+-eth1 are slaves (SLAVE). Notice all slaves of bond0 have the same MAC address 
++the example below, the bond0 interface is the master (MASTER) while eth0 and
++eth1 are slaves (SLAVE). Notice all slaves of bond0 have the same MAC address
+ (HWaddr) as bond0 for all modes except TLB and ALB that require a unique MAC
+ address for each slave.
+ [root]# /sbin/ifconfig
+-bond0     Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4  
++bond0     Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4
+           inet addr:XXX.XXX.XXX.YYY  Bcast:XXX.XXX.XXX.255  Mask:255.255.252.0
+           UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
+           RX packets:7224794 errors:0 dropped:0 overruns:0 frame:0
+           TX packets:3286647 errors:1 dropped:0 overruns:1 carrier:0
+-          collisions:0 txqueuelen:0 
++          collisions:0 txqueuelen:0
+-eth0      Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4  
++eth0      Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4
+           inet addr:XXX.XXX.XXX.YYY  Bcast:XXX.XXX.XXX.255  Mask:255.255.252.0
+           UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
+           RX packets:3573025 errors:0 dropped:0 overruns:0 frame:0
+           TX packets:1643167 errors:1 dropped:0 overruns:1 carrier:0
+-          collisions:0 txqueuelen:100 
+-          Interrupt:10 Base address:0x1080 
++          collisions:0 txqueuelen:100
++          Interrupt:10 Base address:0x1080
+-eth1      Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4  
++eth1      Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4
+           inet addr:XXX.XXX.XXX.YYY  Bcast:XXX.XXX.XXX.255  Mask:255.255.252.0
+           UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
+           RX packets:3651769 errors:0 dropped:0 overruns:0 frame:0
+           TX packets:1643480 errors:0 dropped:0 overruns:0 carrier:0
+-          collisions:0 txqueuelen:100 
+-          Interrupt:9 Base address:0x1400 
++          collisions:0 txqueuelen:100
++          Interrupt:9 Base address:0x1400
+ Frequently Asked Questions
+@@ -605,9 +591,9 @@ Frequently Asked Questions
+ 5.  What happens when a slave link dies?
+-      If your ethernet cards support MII or ETHTOOL link status monitoring 
+-        and the MII monitoring has been enabled in the driver (see description 
+-        of module parameters), there will be no adverse consequences. This 
++      If your ethernet cards support MII or ETHTOOL link status monitoring
++        and the MII monitoring has been enabled in the driver (see description
++        of module parameters), there will be no adverse consequences. This
+         release of the bonding driver knows how to get the MII information and
+       enables or disables its slaves according to their link status.
+       See section on High Availability for additional information.
+@@ -622,8 +608,8 @@ Frequently Asked Questions
+         slave.
+       If neither mii_monitor and arp_interval is configured, the bonding
+-      driver will not handle this situation very well. The driver will 
+-      continue to send packets but some packets will be lost. Retransmits 
++      driver will not handle this situation very well. The driver will
++      continue to send packets but some packets will be lost. Retransmits
+       will cause serious degradation of performance (in the case when one
+       of two slave links fails, 50% packets will be lost, which is a serious
+       problem for both TCP and UDP).
+@@ -636,9 +622,9 @@ Frequently Asked Questions
+ 7.  Which switches/systems does it work with?
+-      In round-robin and XOR mode, it works with systems that support 
++      In round-robin and XOR mode, it works with systems that support
+       trunking:
+-      
++
+       * Many Cisco switches and routers (look for EtherChannel support).
+       * SunTrunking software.
+       * Alteon AceDirector switches / WebOS (use Trunks).
+@@ -646,7 +632,7 @@ Frequently Asked Questions
+         models (450) can define trunks between ports on different physical
+         units.
+       * Linux bonding, of course !
+-      
++
+       In 802.3ad mode, it works with with systems that support IEEE 802.3ad
+       Dynamic Link Aggregation:
+@@ -667,21 +653,21 @@ Frequently Asked Questions
+       is then passed to all following slaves and remains persistent (even if
+       the the first slave is removed) until the bonding device is brought
+       down or reconfigured.
+-      
++
+       If you wish to change the MAC address, you can set it with ifconfig:
+         # ifconfig bond0 hw ether 00:11:22:33:44:55
+       The MAC address can be also changed by bringing down/up the device
+       and then changing its slaves (or their order):
+-      
++
+         # ifconfig bond0 down ; modprobe -r bonding
+         # ifconfig bond0 .... up
+         # ifenslave bond0 eth...
+       This method will automatically take the address from the next slave
+       that will be added.
+-      
++
+       To restore your slaves' MAC addresses, you need to detach them
+       from the bond (`ifenslave -d bond0 eth0'), set them down
+       (`ifconfig eth0 down'), unload the drivers (`rmmod 3c59x', for
+@@ -729,27 +715,27 @@ High Availability
+ =================
+ To implement high availability using the bonding driver, the driver needs to be
+-compiled as a module, because currently it is the only way to pass parameters 
++compiled as a module, because currently it is the only way to pass parameters
+ to the driver. This may change in the future.
+-High availability is achieved by using MII or ETHTOOL status reporting. You 
+-need to verify that all your interfaces support MII or ETHTOOL link status 
+-reporting.  On Linux kernel 2.2.17, all the 100 Mbps capable drivers and 
+-yellowfin gigabit driver support MII. To determine if ETHTOOL link reporting 
+-is available for interface eth0, type "ethtool eth0" and the "Link detected:" 
+-line should contain the correct link status. If your system has an interface 
+-that does not support MII or ETHTOOL status reporting, a failure of its link 
+-will not be detected! A message indicating MII and ETHTOOL is not supported by 
+-a network driver is logged when the bonding driver is loaded with a non-zero 
++High availability is achieved by using MII or ETHTOOL status reporting. You
++need to verify that all your interfaces support MII or ETHTOOL link status
++reporting.  On Linux kernel 2.2.17, all the 100 Mbps capable drivers and
++yellowfin gigabit driver support MII. To determine if ETHTOOL link reporting
++is available for interface eth0, type "ethtool eth0" and the "Link detected:"
++line should contain the correct link status. If your system has an interface
++that does not support MII or ETHTOOL status reporting, a failure of its link
++will not be detected! A message indicating MII and ETHTOOL is not supported by
++a network driver is logged when the bonding driver is loaded with a non-zero
+ miimon value.
+ The bonding driver can regularly check all its slaves links using the ETHTOOL
+-IOCTL (ETHTOOL_GLINK command) or by checking the MII status registers. The 
+-check interval is specified by the module argument "miimon" (MII monitoring). 
+-It takes an integer that represents the checking time in milliseconds. It 
+-should not come to close to (1000/HZ) (10 milli-seconds on i386) because it 
+-may then reduce the system interactivity. A value of 100 seems to be a good 
+-starting point. It means that a dead link will be detected at most 100 
++IOCTL (ETHTOOL_GLINK command) or by checking the MII status registers. The
++check interval is specified by the module argument "miimon" (MII monitoring).
++It takes an integer that represents the checking time in milliseconds. It
++should not come to close to (1000/HZ) (10 milli-seconds on i386) because it
++may then reduce the system interactivity. A value of 100 seems to be a good
++starting point. It means that a dead link will be detected at most 100
+ milli-seconds after it goes down.
+ Example:
+@@ -761,7 +747,7 @@ Or, put the following lines in /etc/modu
+    alias bond0 bonding
+    options bond0 miimon=100
+-There are currently two policies for high availability. They are dependent on 
++There are currently two policies for high availability. They are dependent on
+ whether:
+    a) hosts are connected to a single host or switch that support trunking
+@@ -811,7 +797,7 @@ Example 2 : host to switch at twice the 
+      # ifenslave bond0 eth0 eth1
+-2) High Availability on two or more switches (or a single switch without 
++2) High Availability on two or more switches (or a single switch without
+    trunking support)
+ ---------------------------------------------------------------------------
+ This mode is more problematic because it relies on the fact that there
+@@ -870,10 +856,10 @@ by another external mechanism, it is goo
+ connected to one switch and host2's to the other. Such system will survive
+ a failure of a single host, cable, or switch. The worst thing that may happen
+ in the case of a switch failure is that half of the hosts will be temporarily
+-unreachable until the other switch expires its tables. 
++unreachable until the other switch expires its tables.
+ Example 2: Using multiple ethernet cards connected to a switch to configure
+-           NIC failover (switch is not required to support trunking). 
++           NIC failover (switch is not required to support trunking).
+           +----------+                          +----------+
+@@ -957,7 +943,7 @@ The main limitations are :
+     servers, but may be useful when the front switches send multicast
+     information on their links (e.g. VRRP), or even health-check the servers.
+     Use the arp_interval/arp_ip_target parameters to count incoming/outgoing
+-    frames.  
++    frames.
+@@ -973,13 +959,12 @@ Donald Becker's Ethernet Drivers and dia
+ You will also find a lot of information regarding Ethernet, NWay, MII, etc. at
+ www.scyld.com.
+-For new versions of the driver, patches for older kernels and the updated
+-userspace tools, take a look at Willy Tarreau's site :
++Patches for 2.2 kernels are at Willy Tarreau's site :
+  - http://wtarreau.free.fr/pub/bonding/
+- - http://www-miaif.lip6.fr/willy/pub/bonding/
++ - http://www-miaif.lip6.fr/~tarreau/pub/bonding/
+ To get latest informations about Linux Kernel development, please consult
+ the Linux Kernel Mailing List Archives at :
+-   http://boudicca.tux.org/hypermail/linux-kernel/latest/
++   http://www.ussg.iu.edu/hypermail/linux/kernel/
+ -- END --
+--- linux-2.6.0/Documentation/networking/ifenslave.c   2003-09-27 18:57:43.000000000 -0700
++++ 25/Documentation/networking/ifenslave.c    2003-12-28 23:21:00.000000000 -0800
+@@ -4,8 +4,6 @@
+  *    This program controls the Linux implementation of running multiple
+  *    network interfaces in parallel.
+  *
+- * Usage:     ifenslave [-v] master-interface < slave-interface [metric <N>] > ...
+- *
+  * Author:    Donald Becker <becker@cesdis.gsfc.nasa.gov>
+  *            Copyright 1994-1996 Donald Becker
+  *
+@@ -90,24 +88,30 @@
+  *     - For opt_c: slave should not be set to the master's setting
+  *       while it is running. It was already set during enslave. To
+  *       simplify things, it is now handeled separately.
++ *
++ *    - 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
++ *     - Code cleanup and style changes
++ *       set version to 1.1.0
+  */
+-#define APP_VERSION   "1.0.12"
+-#define APP_RELDATE   "June 30, 2003"
++#define APP_VERSION   "1.1.0"
++#define APP_RELDATE   "Septemer 24, 2003"
+ #define APP_NAME      "ifenslave"
+ static char *version =
+-APP_NAME ".c:v" APP_VERSION " (" APP_RELDATE ") "  "\nDonald Becker (becker@cesdis.gsfc.nasa.gov).\n"
+-"detach support added on 2000/10/02 by Willy Tarreau (willy at meta-x.org).\n"
+-"2.4 kernel support added on 2001/02/16 by Chad N. Tindel (ctindel at ieee dot org.\n";
++APP_NAME ".c:v" APP_VERSION " (" APP_RELDATE ")\n"
++"o Donald Becker (becker@cesdis.gsfc.nasa.gov).\n"
++"o Detach support added on 2000/10/02 by Willy Tarreau (willy at meta-x.org).\n"
++"o 2.4 kernel support added on 2001/02/16 by Chad N. Tindel\n"
++"  (ctindel at ieee dot org).\n";
+ static const char *usage_msg =
+-"Usage: ifenslave [-adfrvVh] <master-interface> < <slave-if> [metric <N>] > ...\n"
+-"       ifenslave -c master-interface slave-if\n";
++"Usage: ifenslave [-f] <master-if> <slave-if> [<slave-if>...]\n"
++"       ifenslave -d   <master-if> <slave-if> [<slave-if>...]\n"
++"       ifenslave -c   <master-if> <slave-if>\n"
++"       ifenslave --help\n";
+-static const char *howto_msg =
+-"Usage: ifenslave [-adfrvVh] <master-interface> < <slave-if> [metric <N>] > ...\n"
+-"       ifenslave -c master-interface slave-if\n"
++static const char *help_msg =
+ "\n"
+ "       To create a bond device, simply follow these three steps :\n"
+ "       - ensure that the required drivers are properly loaded :\n"
+@@ -115,18 +119,32 @@ static const char *howto_msg =
+ "       - assign an IP address to the bond device :\n"
+ "         # ifconfig bond0 <addr> netmask <mask> broadcast <bcast>\n"
+ "       - attach all the interfaces you need to the bond device :\n"
+-"         # ifenslave bond0 eth0 eth1 eth2\n"
++"         # ifenslave [{-f|--force}] bond0 eth0 [eth1 [eth2]...]\n"
+ "         If bond0 didn't have a MAC address, it will take eth0's. Then, all\n"
+ "         interfaces attached AFTER this assignment will get the same MAC addr.\n"
+-"\n"
+-"       To detach a dead interface without setting the bond device down :\n"
+-"         # ifenslave -d bond0 eth1\n"
++"         (except for ALB/TLB modes)\n"
+ "\n"
+ "       To set the bond device down and automatically release all the slaves :\n"
+ "         # ifconfig bond0 down\n"
+ "\n"
++"       To detach a dead interface without setting the bond device down :\n"
++"         # ifenslave {-d|--detach} bond0 eth0 [eth1 [eth2]...]\n"
++"\n"
+ "       To change active slave :\n"
+-"         # ifenslave -c bond0 eth0\n"
++"         # ifenslave {-c|--change-active} bond0 eth0\n"
++"\n"
++"       To show master interface info\n"
++"         # ifenslave bond0\n"
++"\n"
++"       To show all interfaces info\n"
++"       # ifenslave {-a|--all-interfaces}\n"
++"\n"
++"       To be more verbose\n"
++"       # ifenslave {-v|--verbose} ...\n"
++"\n"
++"       # ifenslave {-u|--usage}   Show usage\n"
++"       # ifenslave {-V|--version} Show version\n"
++"       # ifenslave {-h|--help}    This message\n"
+ "\n";
+ #include <unistd.h>
+@@ -153,476 +171,332 @@ typedef __uint8_t u8;          /* ditto */
+ #include <linux/ethtool.h>
+ struct option longopts[] = {
+- /* { name  has_arg  *flag  val } */
+-    {"all-interfaces", 0, 0, 'a'},    /* Show all interfaces. */
+-    {"force",       0, 0, 'f'},               /* Force the operation. */
+-    {"help",          0, 0, '?'},             /* Give help */
+-      {"howto",       0, 0, 'h'},     /* Give some more help */
+-    {"receive-slave", 0, 0, 'r'},     /* Make a receive-only slave.  */
+-    {"verbose",       0, 0, 'v'},             /* Report each action taken.  */
+-    {"version",       0, 0, 'V'},             /* Emit version information.  */
+-    {"detach",       0, 0, 'd'},      /* Detach a slave interface. */
+-    {"change-active", 0, 0, 'c'},     /* Change the active slave.  */
+-    { 0, 0, 0, 0 }
++      /* { name  has_arg  *flag  val } */
++      {"all-interfaces",      0, 0, 'a'},     /* Show all interfaces. */
++      {"change-active",       0, 0, 'c'},     /* Change the active slave.  */
++      {"detach",              0, 0, 'd'},     /* Detach a slave interface. */
++      {"force",               0, 0, 'f'},     /* Force the operation. */
++      {"help",                0, 0, 'h'},     /* Give help */
++      {"usage",               0, 0, 'u'},     /* Give usage */
++      {"verbose",             0, 0, 'v'},     /* Report each action taken. */
++      {"version",             0, 0, 'V'},     /* Emit version information. */
++      { 0, 0, 0, 0}
+ };
+ /* Command-line flags. */
+ unsigned int
+-opt_a = 0,                                    /* Show-all-interfaces flag. */
+-opt_f = 0,                                    /* Force the operation. */
+-opt_r = 0,                                    /* Set up a Rx-only slave. */
+-opt_d = 0,                                    /* detach a slave interface. */
+-opt_c = 0,                                    /* change-active-slave flag. */
+-verbose = 0,                                  /* Verbose flag. */
+-opt_version = 0,
+-opt_howto = 0;
+-int skfd = -1;                                        /* AF_INET socket for ioctl() calls.    */
++opt_a = 0,    /* Show-all-interfaces flag. */
++opt_c = 0,    /* Change-active-slave flag. */
++opt_d = 0,    /* Detach a slave interface. */
++opt_f = 0,    /* Force the operation. */
++opt_h = 0,    /* Help */
++opt_u = 0,    /* Usage */
++opt_v = 0,    /* Verbose flag. */
++opt_V = 0;    /* Version */
++
++int skfd = -1;                /* AF_INET socket for ioctl() calls.*/
++int abi_ver = 0;      /* userland - kernel ABI version */
++int hwaddr_set = 0;   /* Master's hwaddr is set */
++int saved_errno;
++
++struct ifreq master_mtu, master_flags, master_hwaddr;
++struct ifreq slave_mtu, slave_flags, slave_hwaddr;
++
++struct dev_ifr {
++      struct ifreq *req_ifr;
++      char *req_name;
++      int req_type;
++};
++
++struct dev_ifr master_ifra[] = {
++      {&master_mtu,     "SIOCGIFMTU",     SIOCGIFMTU},
++      {&master_flags,   "SIOCGIFFLAGS",   SIOCGIFFLAGS},
++      {&master_hwaddr,  "SIOCGIFHWADDR",  SIOCGIFHWADDR},
++      {NULL, "", 0}
++};
++
++struct dev_ifr slave_ifra[] = {
++      {&slave_mtu,     "SIOCGIFMTU",     SIOCGIFMTU},
++      {&slave_flags,   "SIOCGIFFLAGS",   SIOCGIFFLAGS},
++      {&slave_hwaddr,  "SIOCGIFHWADDR",  SIOCGIFHWADDR},
++      {NULL, "", 0}
++};
+ static void if_print(char *ifname);
+-static int get_abi_ver(char *master_ifname);
++static int get_drv_info(char *master_ifname);
++static int get_if_settings(char *ifname, struct dev_ifr ifra[]);
++static int get_slave_flags(char *slave_ifname);
++static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr);
++static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr);
++static int set_slave_mtu(char *slave_ifname, int mtu);
++static int set_if_flags(char *ifname, short flags);
++static int set_if_up(char *ifname, short flags);
++static int set_if_down(char *ifname, short flags);
++static int clear_if_addr(char *ifname);
++static int set_if_addr(char *master_ifname, char *slave_ifname);
++static int change_active(char *master_ifname, char *slave_ifname);
++static int enslave(char *master_ifname, char *slave_ifname);
++static int release(char *master_ifname, char *slave_ifname);
++#define v_print(fmt, args...) \
++      if (opt_v)              \
++              fprintf(stderr, fmt, ## args )
+-int
+-main(int argc, char **argv)
++int main(int argc, char *argv[])
+ {
+-      struct ifreq  ifr2, if_hwaddr, if_ipaddr, if_metric, if_mtu, if_dstaddr;
+-      struct ifreq  if_netmask, if_brdaddr, if_flags;
+-      int rv, goterr = 0;
+-      int c, errflag = 0;
+-      sa_family_t master_family;
+       char **spp, *master_ifname, *slave_ifname;
+-      int hwaddr_notset;
+-      int abi_ver = 0;
++      int c, i, rv;
++      int res = 0;
++      int exclusive = 0;
+-      while ((c = getopt_long(argc, argv, "acdfrvV?h", longopts, 0)) != EOF)
++      while ((c = getopt_long(argc, argv, "acdfhuvV", longopts, 0)) != EOF) {
+               switch (c) {
+-              case 'a': opt_a++; break;
+-              case 'f': opt_f++; break;
+-              case 'r': opt_r++; break;
+-              case 'd': opt_d++; break;
+-              case 'c': opt_c++; break;
+-              case 'v': verbose++;            break;
+-              case 'V': opt_version++;        break;
+-              case 'h': opt_howto++;  break;
+-              case '?': errflag++;
+-              }
++              case 'a': opt_a++; exclusive++; break;
++              case 'c': opt_c++; exclusive++; break;
++              case 'd': opt_d++; exclusive++; break;
++              case 'f': opt_f++; exclusive++; break;
++              case 'h': opt_h++; exclusive++; break;
++              case 'u': opt_u++; exclusive++; break;
++              case 'v': opt_v++; break;
++              case 'V': opt_V++; exclusive++; break;
+-      /* option check */
+-      if (opt_c)
+-              if(opt_a || opt_f || opt_r || opt_d || verbose || opt_version ||
+-                 opt_howto || errflag ) {
++              case '?':
+                       fprintf(stderr, usage_msg);
+-                      return 2;
++                      res = 2;
++                      goto out;
+               }
++      }
+-      if (errflag) {
++      /* options check */
++      if (exclusive > 1) {
+               fprintf(stderr, usage_msg);
+-              return 2;
++              res = 2;
++              goto out;
+       }
+-      if (opt_howto) {
+-              fprintf(stderr, howto_msg);
+-              return 0;
++      if (opt_v || opt_V) {
++              printf(version);
++              if (opt_V) {
++                      res = 0;
++                      goto out;
++              }
+       }
+-      if (verbose || opt_version) {
+-              printf(version);
+-              if (opt_version)
+-                      exit(0);
++      if (opt_u) {
++              printf(usage_msg);
++              res = 0;
++              goto out;
+       }
+-      /* Open a basic socket. */
+-      if ((skfd = socket(AF_INET, SOCK_DGRAM,0)) < 0) {
+-              perror("socket");
+-              exit(-1);
++      if (opt_h) {
++              printf(usage_msg);
++              printf(help_msg);
++              res = 0;
++              goto out;
+       }
+-      if (verbose)
+-              fprintf(stderr, "DEBUG: argc=%d, optind=%d and argv[optind] is %s.\n",
+-                              argc, optind, argv[optind]);
++      /* Open a basic socket */
++      if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
++              perror("socket");
++              res = 1;
++              goto out;
++      }
+-      /* No remaining args means show all interfaces. */
+-      if (optind == argc) {
+-              if_print((char *)NULL);
+-              (void) close(skfd);
+-              exit(0);
++      if (opt_a) {
++              if (optind == argc) {
++                      /* No remaining args */
++                      /* show all interfaces */
++                      if_print((char *)NULL);
++                      goto out;
++              } else {
++                      /* Just show usage */
++                      fprintf(stderr, usage_msg);
++                      res = 2;
++                      goto out;
++              }
+       }
+-      /* Copy the interface name. */
++      /* Copy the interface name */
+       spp = argv + optind;
+       master_ifname = *spp++;
+-      slave_ifname = *spp++;
+-      /* Check command line. */
+-      if (opt_c) {
+-              char **tempp = spp;
+-              if ((master_ifname == NULL)||(slave_ifname == NULL)||(*tempp++ != NULL)) {
+-                      fprintf(stderr, usage_msg);
+-                      (void) close(skfd);
+-                      return 2;
+-              }
++      if (master_ifname == NULL) {
++              fprintf(stderr, usage_msg);
++              res = 2;
++              goto out;
+       }
+-      /* A single args means show the configuration for this interface. */
+-      if (slave_ifname == NULL) {
+-              if_print(master_ifname);
+-              (void) close(skfd);
+-              exit(0);
++      /* exchange abi version with bonding module */
++      res = get_drv_info(master_ifname);
++      if (res) {
++              fprintf(stderr,
++                      "Master '%s': Error: handshake with driver failed. "
++                      "Aborting\n",
++                      master_ifname);
++              goto out;
+       }
+-      /* exchange abi version with bonding driver */
+-      abi_ver = get_abi_ver(master_ifname);
+-      if (abi_ver < 0) {
+-              (void) close(skfd);
+-              exit(1);
+-      }
+-
+-      /* Get the vitals from the master interface. */
+-      {
+-              struct ifreq *ifra[7] = { &if_ipaddr, &if_mtu, &if_dstaddr,
+-                                                                &if_brdaddr, &if_netmask, &if_flags,
+-                                                                &if_hwaddr };
+-              const char *req_name[7] = {
+-                      "IP address", "MTU", "destination address",
+-                      "broadcast address", "netmask", "status flags",
+-                      "hardware address" };
+-              const int ioctl_req_type[7] = {
+-                      SIOCGIFADDR, SIOCGIFMTU, SIOCGIFDSTADDR,
+-                      SIOCGIFBRDADDR, SIOCGIFNETMASK, SIOCGIFFLAGS,
+-                      SIOCGIFHWADDR };
+-              int i;
+-
+-              for (i = 0; i < 7; i++) {
+-                      strncpy(ifra[i]->ifr_name, master_ifname, IFNAMSIZ);
+-                      if (ioctl(skfd, ioctl_req_type[i], ifra[i]) < 0) {
+-                              fprintf(stderr,
+-                                              "Something broke getting the master's %s: %s.\n",
+-                                              req_name[i], strerror(errno));
+-                      }
+-              }
+-
+-              /* check if master is up; if not then fail any operation */
+-              if (!(if_flags.ifr_flags & IFF_UP)) {
+-                      fprintf(stderr, "Illegal operation; the specified master interface '%s' is not up.\n", master_ifname);
+-                      (void) close(skfd);
+-                      exit (1);
+-              }
++      slave_ifname = *spp++;
+-              hwaddr_notset = 1; /* assume master's address not set yet */
+-              for (i = 0; hwaddr_notset && (i < 6); i++) {
+-                      hwaddr_notset &= ((unsigned char *)if_hwaddr.ifr_hwaddr.sa_data)[i] == 0;
++      if (slave_ifname == NULL) {
++              if (opt_d || opt_c) {
++                      fprintf(stderr, usage_msg);
++                      res = 2;
++                      goto out;
+               }
+-              /* The family '1' is ARPHRD_ETHER for ethernet. */
+-              if (if_hwaddr.ifr_hwaddr.sa_family != 1 && !opt_f) {
+-                      fprintf(stderr, "The specified master interface '%s' is not"
+-                                      " ethernet-like.\n  This program is designed to work"
+-                                      " with ethernet-like network interfaces.\n"
+-                                      " Use the '-f' option to force the operation.\n",
+-                                      master_ifname);
+-                      (void) close(skfd);
+-                      exit (1);
+-              }
+-              master_family = if_hwaddr.ifr_hwaddr.sa_family;
+-              if (verbose) {
+-                      unsigned char *hwaddr = (unsigned char *)if_hwaddr.ifr_hwaddr.sa_data;
+-                      printf("The current hardware address (SIOCGIFHWADDR) of %s is type %d  "
+-                                 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", master_ifname,
+-                                 if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
+-                                 hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
+-              }
++              /* A single arg means show the
++               * configuration for this interface
++               */
++              if_print(master_ifname);
++              goto out;
+       }
++      res = get_if_settings(master_ifname, master_ifra);
++      if (res) {
++              /* Probably a good reason not to go on */
++              fprintf(stderr,
++                      "Master '%s': Error: get settings failed: %s. "
++                      "Aborting\n",
++                      master_ifname, strerror(res));
++              goto out;
++      }
+-      /* do this when enslaving interfaces */
+-      do {
+-              if (opt_d) {  /* detach a slave interface from the master */
+-                      strncpy(if_flags.ifr_name, master_ifname, IFNAMSIZ);
+-                      strncpy(if_flags.ifr_slave, slave_ifname, IFNAMSIZ);
+-                      if ((ioctl(skfd, SIOCBONDRELEASE, &if_flags) < 0) &&
+-                              (ioctl(skfd, BOND_RELEASE_OLD, &if_flags) < 0)) {
+-                                      fprintf(stderr, "SIOCBONDRELEASE: cannot detach %s from %s. errno=%s.\n",
+-                                                      slave_ifname, master_ifname, strerror(errno));
+-                      }
+-                      else if (abi_ver < 1) {
+-                              /* The driver is using an old ABI, so we'll set the interface
+-                               * down to avoid any conflicts due to same IP/MAC
+-                               */
+-                              strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ);
+-                              if (ioctl(skfd, SIOCGIFFLAGS, &ifr2) < 0) {
+-                                      int saved_errno = errno;
+-                                      fprintf(stderr, "SIOCGIFFLAGS on %s failed: %s\n", slave_ifname,
+-                                              strerror(saved_errno));
+-                              }
+-                              else {
+-                                      ifr2.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
+-                                      if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
+-                                              int saved_errno = errno;
+-                                              fprintf(stderr, "Shutting down interface %s failed: %s\n",
+-                                                      slave_ifname, strerror(saved_errno));
+-                                      }
+-                              }
+-                      }
+-              } else if (opt_c) { /* change primary slave */
+-                      strncpy(if_flags.ifr_name, master_ifname, IFNAMSIZ);
+-                      strncpy(if_flags.ifr_slave, slave_ifname, IFNAMSIZ);
+-                      if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &if_flags) < 0) &&
+-                          (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &if_flags) < 0)) {
+-                              fprintf(stderr, "SIOCBONDCHANGEACTIVE: %s.\n", strerror(errno));
+-                      }
+-              } else {  /* attach a slave interface to the master */
+-
+-                      strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ);
+-                      if (ioctl(skfd, SIOCGIFFLAGS, &ifr2) < 0) {
+-                              int saved_errno = errno;
+-                              fprintf(stderr, "SIOCGIFFLAGS on %s failed: %s\n", slave_ifname,
+-                                              strerror(saved_errno));
+-                              (void) close(skfd);
+-                              return 1;
+-                      }
+-
+-                      if ((ifr2.ifr_flags & IFF_SLAVE) && !opt_r) {
+-                              fprintf(stderr, "%s is already a slave\n", slave_ifname);
+-                              (void) close(skfd);
+-                              return 1;
+-                      }
+-
+-                      /* if hwaddr_notset, assign the slave hw address to the master */
+-                      if (hwaddr_notset) {
+-                              /* assign the slave hw address to the
+-                               * master since it currently does not
+-                               * have one; otherwise, slaves may
+-                               * have different hw addresses in
+-                               * active-backup mode as seen when enslaving
+-                               * using "ifenslave bond0 eth0 eth1" because
+-                               * hwaddr_notset is set outside this loop.
+-                               * TODO: put this and the "else" portion in
+-                               *       a function.
+-                               */
+-                              /* get the slaves MAC address */
+-                              strncpy(if_hwaddr.ifr_name, slave_ifname,
+-                                      IFNAMSIZ);
+-                              rv = ioctl(skfd, SIOCGIFHWADDR, &if_hwaddr);
+-                              if (-1 == rv) {
+-                                      fprintf(stderr, "Could not get MAC "
+-                                              "address of %s: %s\n",
+-                                              slave_ifname,
+-                                              strerror(errno));
+-                                      strncpy(if_hwaddr.ifr_name,
+-                                              master_ifname, IFNAMSIZ);
+-                                      goterr = 1;
+-                              }
+-
+-                              if (!goterr) {
+-                                      if (abi_ver < 1) {
+-                                              /* In ABI versions older than 1, the
+-                                               * master's set_mac routine couldn't
+-                                               * work if it was up, because it
+-                                               * used the default ethernet set_mac
+-                                               * function.
+-                                               */
+-                                              /* bring master down */
+-                                              if_flags.ifr_flags &= ~IFF_UP;
+-                                              if (ioctl(skfd, SIOCSIFFLAGS,
+-                                                              &if_flags) < 0) {
+-                                                      goterr = 1;
+-                                                      fprintf(stderr,
+-                                                              "Shutting down "
+-                                                              "interface %s failed: "
+-                                                              "%s\n",
+-                                                              master_ifname,
+-                                                              strerror(errno));
+-                                              }
+-                                      }
+-
+-                                      strncpy(if_hwaddr.ifr_name,
+-                                              master_ifname, IFNAMSIZ);
+-                                      if (ioctl(skfd, SIOCSIFHWADDR,
+-                                                      &if_hwaddr) < 0) {
+-                                              fprintf(stderr,
+-                                                      "Could not set MAC "
+-                                                      "address of %s: %s\n",
+-                                                      master_ifname,
+-                                                      strerror(errno));
+-                                              goterr=1;
+-                                      } else {
+-                                              hwaddr_notset = 0;
+-                                      }
+-
+-                                      if (abi_ver < 1) {
+-                                              /* bring master back up */
+-                                              if_flags.ifr_flags |= IFF_UP;
+-                                              if (ioctl(skfd, SIOCSIFFLAGS,
+-                                                        &if_flags) < 0) {
+-                                                      fprintf(stderr,
+-                                                              "Bringing up interface "
+-                                                              "%s failed: %s\n",
+-                                                              master_ifname,
+-                                                              strerror(errno));
+-                                              }
+-                                      }
+-                              }
+-                      } else if (abi_ver < 1) { /* if (hwaddr_notset) */
+-
+-                              /* The driver is using an old ABI, so we'll set the interface
+-                               * down and assign the master's hwaddr to it
+-                               */
+-                              if (ifr2.ifr_flags & IFF_UP) {
+-                                      ifr2.ifr_flags &= ~IFF_UP;
+-                                      if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
+-                                              int saved_errno = errno;
+-                                              fprintf(stderr, "Shutting down interface %s failed: %s\n",
+-                                                      slave_ifname, strerror(saved_errno));
+-                                      }
+-                              }
+-
+-                              strncpy(if_hwaddr.ifr_name, slave_ifname, IFNAMSIZ);
+-                              if (ioctl(skfd, SIOCSIFHWADDR, &if_hwaddr) < 0) {
+-                                      int saved_errno = errno;
+-                                      fprintf(stderr, "SIOCSIFHWADDR on %s failed: %s\n", if_hwaddr.ifr_name,
+-                                              strerror(saved_errno));
+-                                      if (saved_errno == EBUSY)
+-                                              fprintf(stderr, "  The slave device %s is busy: it must be"
+-                                                      " idle before running this command.\n", slave_ifname);
+-                                      else if (saved_errno == EOPNOTSUPP)
+-                                              fprintf(stderr, "  The slave device you specified does not support"
+-                                                      " setting the MAC address.\n  Your kernel likely does not"
+-                                                      " support slave devices.\n");
+-                                      else if (saved_errno == EINVAL)
+-                                              fprintf(stderr, "  The slave device's address type does not match"
+-                                                      " the master's address type.\n");
+-                              } else {
+-                                      if (verbose) {
+-                                              unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data;
+-                                              printf("Slave's (%s) hardware address set to "
+-                                                         "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", slave_ifname,
+-                                                         hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
+-                                      }
+-                              }
+-                      }
++      /* check if master is indeed a master;
++       * if not then fail any operation
++       */
++      if (!(master_flags.ifr_flags & IFF_MASTER)) {
++              fprintf(stderr,
++                      "Illegal operation; the specified interface '%s' "
++                      "is not a master. Aborting\n",
++                      master_ifname);
++              res = 1;
++              goto out;
++      }
+-                      if (*spp  &&  !strcmp(*spp, "metric")) {
+-                              if (*++spp == NULL) {
+-                                      fprintf(stderr, usage_msg);
+-                                      (void) close(skfd);
+-                                      exit(2);
+-                              }
+-                              if_metric.ifr_metric = atoi(*spp);
+-                              strncpy(if_metric.ifr_name, slave_ifname, IFNAMSIZ);
+-                              if (ioctl(skfd, SIOCSIFMETRIC, &if_metric) < 0) {
+-                                      fprintf(stderr, "SIOCSIFMETRIC on %s: %s\n", slave_ifname,
+-                                                      strerror(errno));
+-                                      goterr = 1;
+-                              }
+-                              spp++;
+-                      }
++      /* check if master is up; if not then fail any operation */
++      if (!(master_flags.ifr_flags & IFF_UP)) {
++              fprintf(stderr,
++                      "Illegal operation; the specified master interface "
++                      "'%s' is not up.\n",
++                      master_ifname);
++              res = 1;
++              goto out;
++      }
+-                      if (strncpy(if_ipaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0
+-                              || ioctl(skfd, SIOCSIFADDR, &if_ipaddr) < 0) {
+-                              fprintf(stderr,
+-                                              "Something broke setting the slave's address: %s.\n",
+-                                              strerror(errno));
+-                      } else {
+-                              if (verbose) {
+-                                      unsigned char *ipaddr = if_ipaddr.ifr_addr.sa_data;
+-                                      printf("Set the slave's (%s) IP address to %d.%d.%d.%d.\n",
+-                                                 slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+-                              }
+-                      }
++      /* Only for enslaving */
++      if (!opt_c && !opt_d) {
++              sa_family_t master_family = master_hwaddr.ifr_hwaddr.sa_family;
++              unsigned char *hwaddr =
++                      (unsigned char *)master_hwaddr.ifr_hwaddr.sa_data;
+-                      if (strncpy(if_mtu.ifr_name, slave_ifname, IFNAMSIZ) <= 0
+-                              || ioctl(skfd, SIOCSIFMTU, &if_mtu) < 0) {
+-                              fprintf(stderr, "Something broke setting the slave MTU: %s.\n",
+-                                              strerror(errno));
+-                      } else {
+-                              if (verbose)
+-                                      printf("Set the slave's (%s) MTU to %d.\n", slave_ifname, if_mtu.ifr_mtu);
+-                      }
++              /* The family '1' is ARPHRD_ETHER for ethernet. */
++              if (master_family != 1 && !opt_f) {
++                      fprintf(stderr,
++                              "Illegal operation: The specified master "
++                              "interface '%s' is not ethernet-like.\n "
++                              "This program is designed to work with "
++                              "ethernet-like network interfaces.\n "
++                              "Use the '-f' option to force the "
++                              "operation.\n",
++                              master_ifname);
++                      res = 1;
++                      goto out;
++              }
+-                      if (strncpy(if_dstaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0
+-                              || ioctl(skfd, SIOCSIFDSTADDR, &if_dstaddr) < 0) {
+-                              fprintf(stderr, "Error setting the slave (%s) with SIOCSIFDSTADDR: %s.\n",
+-                                              slave_ifname, strerror(errno));
+-                      } else {
+-                              if (verbose) {
+-                                      unsigned char *ipaddr = if_dstaddr.ifr_dstaddr.sa_data;
+-                                      printf("Set the slave's (%s) destination address to %d.%d.%d.%d.\n",
+-                                                 slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+-                              }
++              /* Check master's hw addr */
++              for (i = 0; i < 6; i++) {
++                      if (hwaddr[i] != 0) {
++                              hwaddr_set = 1;
++                              break;
+                       }
++              }
+-                      if (strncpy(if_brdaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0
+-                              || ioctl(skfd, SIOCSIFBRDADDR, &if_brdaddr) < 0) {
+-                              fprintf(stderr,
+-                                              "Something broke setting the slave (%s) broadcast address: %s.\n",
+-                                              slave_ifname, strerror(errno));
+-                      } else {
+-                              if (verbose) {
+-                                      unsigned char *ipaddr = if_brdaddr.ifr_broadaddr.sa_data;
+-                                      printf("Set the slave's (%s) broadcast address to %d.%d.%d.%d.\n",
+-                                                 slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+-                              }
+-                      }
++              if (hwaddr_set) {
++                      v_print("current hardware address of master '%s' "
++                              "is %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
++                              "type %d\n",
++                              master_ifname,
++                              hwaddr[0], hwaddr[1],
++                              hwaddr[2], hwaddr[3],
++                              hwaddr[4], hwaddr[5],
++                              master_family);
++              }
++      }
+-                      if (strncpy(if_netmask.ifr_name, slave_ifname, IFNAMSIZ) <= 0
+-                              || ioctl(skfd, SIOCSIFNETMASK, &if_netmask) < 0) {
+-                              fprintf(stderr,
+-                                              "Something broke setting the slave (%s) netmask: %s.\n",
+-                                              slave_ifname, strerror(errno));
+-                      } else {
+-                              if (verbose) {
+-                                      unsigned char *ipaddr = if_netmask.ifr_netmask.sa_data;
+-                                      printf("Set the slave's (%s) netmask to %d.%d.%d.%d.\n",
+-                                                 slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
++      /* Accepts only one slave */
++      if (opt_c) {
++              /* change active slave */
++              res = get_slave_flags(slave_ifname);
++              if (res) {
++                      fprintf(stderr,
++                              "Slave '%s': Error: get flags failed. "
++                              "Aborting\n",
++                              slave_ifname);
++                      goto out;
++              }
++              res = change_active(master_ifname, slave_ifname);
++              if (res) {
++                      fprintf(stderr,
++                              "Master '%s', Slave '%s': Error: "
++                              "Change active failed\n",
++                              master_ifname, slave_ifname);
++              }
++      } else {
++              /* Accept multiple slaves */
++              do {
++                      if (opt_d) {
++                              /* detach a slave interface from the master */
++                              rv = get_slave_flags(slave_ifname);
++                              if (rv) {
++                                      /* Can't work with this slave. */
++                                      /* remember the error and skip it*/
++                                      fprintf(stderr,
++                                              "Slave '%s': Error: get flags "
++                                              "failed. Skipping\n",
++                                              slave_ifname);
++                                      res = rv;
++                                      continue;
+                               }
+-                      }
+-
+-                      if (abi_ver < 1) {
+-
+-                              /* The driver is using an old ABI, so we'll set the interface
+-                               * up before enslaving it
+-                               */
+-                              ifr2.ifr_flags |= IFF_UP;
+-                              if ((ifr2.ifr_flags &= ~(IFF_SLAVE | IFF_MASTER)) == 0
+-                                      || strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ) <= 0
+-                                      || ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
+-                                              fprintf(stderr,
+-                                                      "Something broke setting the slave (%s) flags: %s.\n",
+-                                                      slave_ifname, strerror(errno));
+-                              } else {
+-                                      if (verbose)
+-                                              printf("Set the slave's (%s) flags %4.4x.\n",
+-                                                      slave_ifname, if_flags.ifr_flags);
++                              rv = release(master_ifname, slave_ifname);
++                              if (rv) {
++                                      fprintf(stderr,
++                                              "Master '%s', Slave '%s': Error: "
++                                              "Release failed\n",
++                                              master_ifname, slave_ifname);
++                                      res = rv;
+                               }
+                       } else {
+-                              /* the bonding module takes care of setting the slave's mac address
+-                               * and opening its interface
+-                               */
+-                              if (ifr2.ifr_flags & IFF_UP) { /* the interface will need to be down */
+-                                      ifr2.ifr_flags &= ~IFF_UP;
+-                                      if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
+-                                              int saved_errno = errno;
+-                                              fprintf(stderr, "Shutting down interface %s failed: %s\n",
+-                                                      slave_ifname, strerror(saved_errno));
+-                                      }
++                              /* attach a slave interface to the master */
++                              rv = get_if_settings(slave_ifname, slave_ifra);
++                              if (rv) {
++                                      /* Can't work with this slave. */
++                                      /* remember the error and skip it*/
++                                      fprintf(stderr,
++                                              "Slave '%s': Error: get "
++                                              "settings failed: %s. "
++                                              "Skipping\n",
++                                              slave_ifname, strerror(rv));
++                                      res = rv;
++                                      continue;
+                               }
+-                      }
+-
+-                      /* Do the real thing */
+-                      if (!opt_r) {
+-                              strncpy(if_flags.ifr_name, master_ifname, IFNAMSIZ);
+-                              strncpy(if_flags.ifr_slave, slave_ifname, IFNAMSIZ);
+-                              if ((ioctl(skfd, SIOCBONDENSLAVE, &if_flags) < 0) &&
+-                                  (ioctl(skfd, BOND_ENSLAVE_OLD, &if_flags) < 0)) {
+-                                      fprintf(stderr, "SIOCBONDENSLAVE: %s.\n", strerror(errno));
++                              rv = enslave(master_ifname, slave_ifname);
++                              if (rv) {
++                                      fprintf(stderr,
++                                              "Master '%s', Slave '%s': Error: "
++                                              "Enslave failed\n",
++                                              master_ifname, slave_ifname);
++                                      res = rv;
+                               }
+                       }
+-              }
+-      } while ( (slave_ifname = *spp++) != NULL);
++              } while ((slave_ifname = *spp++) != NULL);
++      }
+-      /* Close the socket. */
+-      (void) close(skfd);
++out:
++      if (skfd >= 0) {
++              close(skfd);
++      }
+-      return(goterr);
++      return res;
+ }
+ static short mif_flags;
+@@ -631,35 +505,34 @@ static short mif_flags;
+ static int if_getconfig(char *ifname)
+ {
+       struct ifreq ifr;
+-      int metric, mtu;                        /* Parameters of the master interface. */
++      int metric, mtu;        /* Parameters of the master interface. */
+       struct sockaddr dstaddr, broadaddr, netmask;
++      unsigned char *hwaddr;
+       strcpy(ifr.ifr_name, ifname);
+       if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
+               return -1;
+       mif_flags = ifr.ifr_flags;
+       printf("The result of SIOCGIFFLAGS on %s is %x.\n",
+-                 ifname, ifr.ifr_flags);
++             ifname, ifr.ifr_flags);
+       strcpy(ifr.ifr_name, ifname);
+       if (ioctl(skfd, SIOCGIFADDR, &ifr) < 0)
+               return -1;
+       printf("The result of SIOCGIFADDR is %2.2x.%2.2x.%2.2x.%2.2x.\n",
+-                 ifr.ifr_addr.sa_data[0], ifr.ifr_addr.sa_data[1],
+-                 ifr.ifr_addr.sa_data[2], ifr.ifr_addr.sa_data[3]);
++             ifr.ifr_addr.sa_data[0], ifr.ifr_addr.sa_data[1],
++             ifr.ifr_addr.sa_data[2], ifr.ifr_addr.sa_data[3]);
+       strcpy(ifr.ifr_name, ifname);
+       if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
+               return -1;
+-      {
+-              /* Gotta convert from 'char' to unsigned for printf().  */
+-              unsigned char *hwaddr = (unsigned char *)ifr.ifr_hwaddr.sa_data;
+-              printf("The result of SIOCGIFHWADDR is type %d  "
+-                         "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
+-                         ifr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
+-                         hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
+-      }
++      /* Gotta convert from 'char' to unsigned for printf(). */
++      hwaddr = (unsigned char *)ifr.ifr_hwaddr.sa_data;
++      printf("The result of SIOCGIFHWADDR is type %d  "
++             "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
++             ifr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
++             hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
+       strcpy(ifr.ifr_name, ifname);
+       if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) {
+@@ -691,7 +564,7 @@ static int if_getconfig(char *ifname)
+       } else
+               netmask = ifr.ifr_netmask;
+-      return(0);
++      return 0;
+ }
+ static void if_print(char *ifname)
+@@ -705,15 +578,16 @@ static void if_print(char *ifname)
+               ifc.ifc_len = sizeof(buff);
+               ifc.ifc_buf = buff;
+               if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
+-                      fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
++                      perror("SIOCGIFCONF failed");
+                       return;
+               }
+               ifr = ifc.ifc_req;
+               for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
+                       if (if_getconfig(ifr->ifr_name) < 0) {
+-                              fprintf(stderr, "%s: unknown interface.\n",
+-                                              ifr->ifr_name);
++                              fprintf(stderr,
++                                      "%s: unknown interface.\n",
++                                      ifr->ifr_name);
+                               continue;
+                       }
+@@ -721,16 +595,18 @@ static void if_print(char *ifname)
+                       /*ife_print(&ife);*/
+               }
+       } else {
+-              if (if_getconfig(ifname) < 0)
+-                      fprintf(stderr, "%s: unknown interface.\n", ifname);
++              if (if_getconfig(ifname) < 0) {
++                      fprintf(stderr,
++                              "%s: unknown interface.\n", ifname);
++              }
+       }
+ }
+-static int get_abi_ver(char *master_ifname)
++static int get_drv_info(char *master_ifname)
+ {
+       struct ifreq ifr;
+       struct ethtool_drvinfo info;
+-      int abi_ver = 0;
++      char *endptr;
+       memset(&ifr, 0, sizeof(ifr));
+       strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
+@@ -739,24 +615,487 @@ static int get_abi_ver(char *master_ifna
+       info.cmd = ETHTOOL_GDRVINFO;
+       strncpy(info.driver, "ifenslave", 32);
+       snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);
+-      if (ioctl(skfd, SIOCETHTOOL, &ifr) >= 0) {
+-              char *endptr;
+-              abi_ver = strtoul(info.fw_version, &endptr, 0);
+-              if (*endptr) {
+-                      fprintf(stderr, "Error: got invalid string as an ABI "
+-                              "version from the bonding module\n");
+-                      return -1;
++      if (ioctl(skfd, SIOCETHTOOL, &ifr) < 0) {
++              if (errno == EOPNOTSUPP) {
++                      goto out;
+               }
++
++              saved_errno = errno;
++              v_print("Master '%s': Error: get bonding info failed %s\n",
++                      master_ifname, strerror(saved_errno));
++              return 1;
+       }
+-      if (verbose) {
+-              printf("ABI ver is %d\n", abi_ver);
++      abi_ver = strtoul(info.fw_version, &endptr, 0);
++      if (*endptr) {
++                v_print("Master '%s': Error: got invalid string as an ABI "
++                      "version from the bonding module\n",
++                      master_ifname);
++              return 1;
+       }
+-      return abi_ver;
++
++out:
++      v_print("ABI ver is %d\n", abi_ver);
++
++      return 0;
+ }
++static int change_active(char *master_ifname, char *slave_ifname)
++{
++      struct ifreq ifr;
++      int res = 0;
++      if (!(slave_flags.ifr_flags & IFF_SLAVE)) {
++              fprintf(stderr,
++                      "Illegal operation: The specified slave interface "
++                      "'%s' is not a slave\n",
++                      slave_ifname);
++              return 1;
++      }
++
++      strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
++      strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
++      if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &ifr) < 0) &&
++          (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &ifr) < 0)) {
++              saved_errno = errno;
++              v_print("Master '%s': Error: SIOCBONDCHANGEACTIVE failed: "
++                      "%s\n",
++                      master_ifname, strerror(saved_errno));
++              res = 1;
++      }
++
++      return res;
++}
++
++static int enslave(char *master_ifname, char *slave_ifname)
++{
++      struct ifreq ifr;
++      int res = 0;
++
++      if (slave_flags.ifr_flags & IFF_SLAVE) {
++              fprintf(stderr,
++                      "Illegal operation: The specified slave interface "
++                      "'%s' is already a slave\n",
++                      slave_ifname);
++              return 1;
++      }
++
++      res = set_if_down(slave_ifname, slave_flags.ifr_flags);
++      if (res) {
++              fprintf(stderr,
++                      "Slave '%s': Error: bring interface down failed\n",
++                      slave_ifname);
++              return res;
++      }
++
++      if (abi_ver < 2) {
++              /* Older bonding versions would panic if the slave has no IP
++               * address, so get the IP setting from the master.
++               */
++              res = set_if_addr(master_ifname, slave_ifname);
++              if (res) {
++                      fprintf(stderr,
++                              "Slave '%s': Error: set address failed\n",
++                              slave_ifname);
++                      return res;
++              }
++      } else {
++              res = clear_if_addr(slave_ifname);
++              if (res) {
++                      fprintf(stderr,
++                              "Slave '%s': Error: clear address failed\n",
++                              slave_ifname);
++                      return res;
++              }
++      }
++
++      if (master_mtu.ifr_mtu != slave_mtu.ifr_mtu) {
++              res = set_slave_mtu(slave_ifname, master_mtu.ifr_mtu);
++              if (res) {
++                      fprintf(stderr,
++                              "Slave '%s': Error: set MTU failed\n",
++                              slave_ifname);
++                      return res;
++              }
++      }
++
++      if (hwaddr_set) {
++              /* Master already has an hwaddr
++               * so set it's hwaddr to the slave
++               */
++              if (abi_ver < 1) {
++                      /* The driver is using an old ABI, so
++                       * the application sets the slave's
++                       * hwaddr
++                       */
++                      res = set_slave_hwaddr(slave_ifname,
++                                             &(master_hwaddr.ifr_hwaddr));
++                      if (res) {
++                              fprintf(stderr,
++                                      "Slave '%s': Error: set hw address "
++                                      "failed\n",
++                                      slave_ifname);
++                              goto undo_mtu;
++                      }
++
++                      /* For old ABI the application needs to bring the
++                       * slave back up
++                       */
++                      res = set_if_up(slave_ifname, slave_flags.ifr_flags);
++                      if (res) {
++                              fprintf(stderr,
++                                      "Slave '%s': Error: bring interface "
++                                      "down failed\n",
++                                      slave_ifname);
++                              goto undo_slave_mac;
++                      }
++              }
++              /* The driver is using a new ABI,
++               * so the driver takes care of setting
++               * the slave's hwaddr and bringing
++               * it up again
++               */
++      } else {
++              /* No hwaddr for master yet, so
++               * set the slave's hwaddr to it
++               */
++              if (abi_ver < 1) {
++                      /* For old ABI, the master needs to be
++                       * down before setting it's hwaddr
++                       */
++                      res = set_if_down(master_ifname, master_flags.ifr_flags);
++                      if (res) {
++                              fprintf(stderr,
++                                      "Master '%s': Error: bring interface "
++                                      "down failed\n",
++                                      master_ifname);
++                              goto undo_mtu;
++                      }
++              }
++
++              res = set_master_hwaddr(master_ifname,
++                                      &(slave_hwaddr.ifr_hwaddr));
++              if (res) {
++                      fprintf(stderr,
++                              "Master '%s': Error: set hw address "
++                              "failed\n",
++                              master_ifname);
++                      goto undo_mtu;
++              }
++
++              if (abi_ver < 1) {
++                      /* For old ABI, bring the master
++                       * back up
++                       */
++                      res = set_if_up(master_ifname, master_flags.ifr_flags);
++                      if (res) {
++                              fprintf(stderr,
++                                      "Master '%s': Error: bring interface "
++                                      "up failed\n",
++                                      master_ifname);
++                              goto undo_master_mac;
++                      }
++              }
++
++              hwaddr_set = 1;
++      }
++
++      /* Do the real thing */
++      strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
++      strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
++      if ((ioctl(skfd, SIOCBONDENSLAVE, &ifr) < 0) &&
++          (ioctl(skfd, BOND_ENSLAVE_OLD, &ifr) < 0)) {
++              saved_errno = errno;
++              v_print("Master '%s': Error: SIOCBONDENSLAVE failed: %s\n",
++                      master_ifname, strerror(saved_errno));
++              res = 1;
++      }
++
++      if (res) {
++              goto undo_master_mac;
++      }
++
++      return 0;
++
++/* rollback (best effort) */
++undo_master_mac:
++      set_master_hwaddr(master_ifname, &(master_hwaddr.ifr_hwaddr));
++      hwaddr_set = 0;
++      goto undo_mtu;
++undo_slave_mac:
++      set_slave_hwaddr(slave_ifname, &(slave_hwaddr.ifr_hwaddr));
++undo_mtu:
++      set_slave_mtu(slave_ifname, slave_mtu.ifr_mtu);
++      return res;
++}
++
++static int release(char *master_ifname, char *slave_ifname)
++{
++      struct ifreq ifr;
++      int res = 0;
++
++      if (!(slave_flags.ifr_flags & IFF_SLAVE)) {
++              fprintf(stderr,
++                      "Illegal operation: The specified slave interface "
++                      "'%s' is not a slave\n",
++                      slave_ifname);
++              return 1;
++      }
++
++      strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
++      strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);
++      if ((ioctl(skfd, SIOCBONDRELEASE, &ifr) < 0) &&
++          (ioctl(skfd, BOND_RELEASE_OLD, &ifr) < 0)) {
++              saved_errno = errno;
++              v_print("Master '%s': Error: SIOCBONDRELEASE failed: %s\n",
++                      master_ifname, strerror(saved_errno));
++              return 1;
++      } else if (abi_ver < 1) {
++              /* The driver is using an old ABI, so we'll set the interface
++               * down to avoid any conflicts due to same MAC/IP
++               */
++              res = set_if_down(slave_ifname, slave_flags.ifr_flags);
++              if (res) {
++                      fprintf(stderr,
++                              "Slave '%s': Error: bring interface "
++                              "down failed\n",
++                              slave_ifname);
++              }
++      }
++
++      /* set to default mtu */
++      set_slave_mtu(slave_ifname, 1500);
++
++      return res;
++}
++
++static int get_if_settings(char *ifname, struct dev_ifr ifra[])
++{
++      int i;
++      int res = 0;
++
++      for (i = 0; ifra[i].req_ifr; i++) {
++              strncpy(ifra[i].req_ifr->ifr_name, ifname, IFNAMSIZ);
++              res = ioctl(skfd, ifra[i].req_type, ifra[i].req_ifr);
++              if (res < 0) {
++                      saved_errno = errno;
++                      v_print("Interface '%s': Error: %s failed: %s\n",
++                              ifname, ifra[i].req_name,
++                              strerror(saved_errno));
++
++                      return saved_errno;
++              }
++      }
++
++      return 0;
++}
++
++static int get_slave_flags(char *slave_ifname)
++{
++      int res = 0;
++
++      strncpy(slave_flags.ifr_name, slave_ifname, IFNAMSIZ);
++      res = ioctl(skfd, SIOCGIFFLAGS, &slave_flags);
++      if (res < 0) {
++              saved_errno = errno;
++              v_print("Slave '%s': Error: SIOCGIFFLAGS failed: %s\n",
++                      slave_ifname, strerror(saved_errno));
++      } else {
++              v_print("Slave %s: flags %04X.\n",
++                      slave_ifname, slave_flags.ifr_flags);
++      }
++
++      return res;
++}
++
++static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr)
++{
++      unsigned char *addr = (unsigned char *)hwaddr->sa_data;
++      struct ifreq ifr;
++      int res = 0;
++
++      strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
++      memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr));
++      res = ioctl(skfd, SIOCSIFHWADDR, &ifr);
++      if (res < 0) {
++              saved_errno = errno;
++              v_print("Master '%s': Error: SIOCSIFHWADDR failed: %s\n",
++                      master_ifname, strerror(saved_errno));
++              return res;
++      } else {
++              v_print("Master '%s': hardware address set to "
++                      "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
++                      master_ifname, addr[0], addr[1], addr[2],
++                      addr[3], addr[4], addr[5]);
++      }
++
++      return res;
++}
++
++static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr)
++{
++      unsigned char *addr = (unsigned char *)hwaddr->sa_data;
++      struct ifreq ifr;
++      int res = 0;
++
++      strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
++      memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr));
++      res = ioctl(skfd, SIOCSIFHWADDR, &ifr);
++      if (res < 0) {
++              saved_errno = errno;
++
++              v_print("Slave '%s': Error: SIOCSIFHWADDR failed: %s\n",
++                      slave_ifname, strerror(saved_errno));
++
++              if (saved_errno == EBUSY) {
++                      v_print("  The device is busy: it must be idle "
++                              "before running this command.\n");
++              } else if (saved_errno == EOPNOTSUPP) {
++                      v_print("  The device does not support setting "
++                              "the MAC address.\n"
++                              "  Your kernel likely does not support slave "
++                              "devices.\n");
++              } else if (saved_errno == EINVAL) {
++                      v_print("  The device's address type does not match "
++                              "the master's address type.\n");
++              }
++              return res;
++      } else {
++              v_print("Slave '%s': hardware address set to "
++                      "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
++                      slave_ifname, addr[0], addr[1], addr[2],
++                      addr[3], addr[4], addr[5]);
++      }
++
++      return res;
++}
++
++static int set_slave_mtu(char *slave_ifname, int mtu)
++{
++      struct ifreq ifr;
++      int res = 0;
++
++      ifr.ifr_mtu = mtu;
++      strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
++
++      res = ioctl(skfd, SIOCSIFMTU, &ifr);
++      if (res < 0) {
++              saved_errno = errno;
++              v_print("Slave '%s': Error: SIOCSIFMTU failed: %s\n",
++                      slave_ifname, strerror(saved_errno));
++      } else {
++              v_print("Slave '%s': MTU set to %d.\n", slave_ifname, mtu);
++      }
++
++      return res;
++}
++
++static int set_if_flags(char *ifname, short flags)
++{
++      struct ifreq ifr;
++      int res = 0;
++
++      ifr.ifr_flags = flags;
++      strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
++
++      res = ioctl(skfd, SIOCSIFFLAGS, &ifr);
++      if (res < 0) {
++              saved_errno = errno;
++              v_print("Interface '%s': Error: SIOCSIFFLAGS failed: %s\n",
++                      ifname, strerror(saved_errno));
++      } else {
++              v_print("Interface '%s': flags set to %04X.\n", ifname, flags);
++      }
++
++      return res;
++}
++
++static int set_if_up(char *ifname, short flags)
++{
++      return set_if_flags(ifname, flags | IFF_UP);
++}
++
++static int set_if_down(char *ifname, short flags)
++{
++      return set_if_flags(ifname, flags & ~IFF_UP);
++}
++
++static int clear_if_addr(char *ifname)
++{
++      struct ifreq ifr;
++      int res = 0;
++
++      strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
++      ifr.ifr_addr.sa_family = AF_INET;
++      memset(ifr.ifr_addr.sa_data, 0, sizeof(ifr.ifr_addr.sa_data));
++
++      res = ioctl(skfd, SIOCSIFADDR, &ifr);
++      if (res < 0) {
++              saved_errno = errno;
++              v_print("Interface '%s': Error: SIOCSIFADDR failed: %s\n",
++                      ifname, strerror(saved_errno));
++      } else {
++              v_print("Interface '%s': address cleared\n", ifname);
++      }
++
++      return res;
++}
++
++static int set_if_addr(char *master_ifname, char *slave_ifname)
++{
++      struct ifreq ifr;
++      int res;
++      unsigned char *ipaddr;
++      int i;
++      struct {
++              char *req_name;
++              char *desc;
++              int g_ioctl;
++              int s_ioctl;
++      } ifra[] = {
++              {"IFADDR", "addr", SIOCGIFADDR, SIOCSIFADDR},
++              {"DSTADDR", "destination addr", SIOCGIFDSTADDR, SIOCSIFDSTADDR},
++              {"BRDADDR", "broadcast addr", SIOCGIFBRDADDR, SIOCSIFBRDADDR},
++              {"NETMASK", "netmask", SIOCGIFNETMASK, SIOCSIFNETMASK},
++              {NULL, NULL, 0, 0},
++      };
++
++      for (i = 0; ifra[i].req_name; i++) {
++              strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
++              res = ioctl(skfd, ifra[i].g_ioctl, &ifr);
++              if (res < 0) {
++                      int saved_errno = errno;
++
++                      v_print("Interface '%s': Error: SIOCG%s failed: %s\n",
++                              master_ifname, ifra[i].req_name,
++                              strerror(saved_errno));
++
++                      ifr.ifr_addr.sa_family = AF_INET;
++                      memset(ifr.ifr_addr.sa_data, 0,
++                             sizeof(ifr.ifr_addr.sa_data));
++              }
++
++              strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);
++              res = ioctl(skfd, ifra[i].s_ioctl, &ifr);
++              if (res < 0) {
++                      int saved_errno = errno;
++
++                      v_print("Interface '%s': Error: SIOCS%s failed: %s\n",
++                              slave_ifname, ifra[i].req_name,
++                              strerror(saved_errno));
++
++                      return res;
++              }
++
++              ipaddr = ifr.ifr_addr.sa_data;
++              v_print("Interface '%s': set IP %s to %d.%d.%d.%d\n",
++                      slave_ifname, ifra[i].desc,
++                      ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
++      }
++
++      return 0;
++}
+ /*
+  * Local variables:
+@@ -768,3 +1107,4 @@ static int get_abi_ver(char *master_ifna
+  *  compile-command: "gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave"
+  * End:
+  */
++
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/networking/netconsole.txt 2003-12-28 23:21:00.000000000 -0800
+@@ -0,0 +1,57 @@
++
++started by Ingo Molnar <mingo@redhat.com>, 2001.09.17
++2.6 port and netpoll api by Matt Mackall <mpm@selenic.com>, Sep 9 2003
++
++Please send bug reports to Matt Mackall <mpm@selenic.com>
++
++This module logs kernel printk messages over UDP allowing debugging of
++problem where disk logging fails and serial consoles are impractical.
++
++It can be used either built-in or as a module. As a built-in,
++netconsole initializes immediately after NIC cards and will bring up
++the specified interface as soon as possible. While this doesn't allow
++capture of early kernel panics, it does capture most of the boot
++process.
++
++It takes a string configuration parameter "netconsole" in the
++following format:
++
++ netconsole=[src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]
++
++   where
++        src-port      source for UDP packets (defaults to 6665)
++        src-ip        source IP to use (interface address)
++        dev           network interface (eth0)
++        tgt-port      port for logging agent (6666)
++        tgt-ip        IP address for logging agent
++        tgt-macaddr   ethernet MAC address for logging agent (broadcast)
++
++Examples:
++
++ linux netconsole=4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc
++
++  or
++
++ insmod netconsole netconsole=@/,@10.0.0.2/
++
++Built-in netconsole starts immediately after the TCP stack is
++initialized and attempts to bring up the supplied dev at the supplied
++address.
++
++The remote host can run either 'netcat -u -l -p <port>' or syslogd.
++
++WARNING: the default target ethernet setting uses the broadcast
++ethernet address to send packets, which can cause increased load on
++other systems on the same ethernet segment.
++
++NOTE: the network device (eth1 in the above case) can run any kind
++of other network traffic, netconsole is not intrusive. Netconsole
++might cause slight delays in other traffic if the volume of kernel
++messages is high, but should have no other impact.
++
++Netconsole was designed to be as instantaneous as possible, to
++enable the logging of even the most critical kernel bugs. It works
++from IRQ contexts as well, and does not enable interrupts while
++sending packets. Due to these unique needs, configuration can not
++be more automatic, and some fundamental limitations will remain:
++only IP networks, UDP packets and ethernet devices are supported.
+--- linux-2.6.0/Documentation/networking/sk98lin.txt   2003-09-27 18:57:43.000000000 -0700
++++ 25/Documentation/networking/sk98lin.txt    2003-12-28 23:21:00.000000000 -0800
+@@ -2,9 +2,9 @@
+ All rights reserved
+ ===========================================================================
+-sk98lin.txt created 23-Sep-2003
++sk98lin.txt created 15-Dec-2003
+-Readme File for sk98lin v6.18
++Readme File for sk98lin v6.21
+ Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
+ This file contains
+@@ -466,7 +466,7 @@ The Marvell Yukon/SysKonnect Linux drive
+ Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad. 
+ These features are only available after installation of open source 
+ modules available on the Internet:
+-For VLAN go to: http://scry.wanfear.com/~greear/vlan.html
++For VLAN go to: http://www.candelatech.com/~greear/vlan.html
+ For Link Aggregation go to: http://www.st.rim.or.jp/~yumo
+ NOTE: SysKonnect GmbH does not offer any support for these open source 
+--- linux-2.6.0/Documentation/scsi/aic79xx.txt 2003-06-14 12:18:29.000000000 -0700
++++ 25/Documentation/scsi/aic79xx.txt  2003-12-28 23:21:39.000000000 -0800
+@@ -1,5 +1,5 @@
+ ====================================================================
+-=             Adaptec Ultra320 Family Manager Set v1.3.0           =
++=             Adaptec Ultra320 Family Manager Set v2.0.5           =
+ =                                                                  =
+ =                            README for                            =
+ =                    The Linux Operating System                    =
+@@ -19,57 +19,274 @@ The following information is available i
+    The following Adaptec SCSI Host Adapters are supported by this 
+    driver set. 
+-   Ultra320 Adapters         Description
++   Ultra320 ASIC              Description
+    ----------------------------------------------------------------
+-   Adaptec SCSI Card 39320   Dual Channel 64-bit PCI-X 133MHz to
+-                             Ultra320 SCSI Card (one external 
+-                             68-pin, two internal 68-pin)
+-   Adaptec SCSI Card 39320D  Dual Channel 64-bit PCI-X 133MHz to
+-                             Ultra320 SCSI Card (two external VHDC
+-                             and one internal 68-pin)
+-   Adaptec SCSI Card 39320D  Dual Channel 64-bit PCI-X 133MHz to
+-                             Ultra320 SCSI Card (two external VHDC
+-                             and one internal 68-pin) based on the
+-                             AIC-7902B ASIC
+-   Adaptec SCSI Card 29320   Single Channel 64-bit PCI-X 133MHz to
+-                             Ultra320 SCSI Card (one external 
+-                             68-pin, two internal 68-pin, one
+-                             internal 50-pin)
+-   Adaptec SCSI Card 29320LP Single Channel 64-bit Low Profile
+-                             PCI-X 133MHz to Ultra320 SCSI Card
+-                             (One external VHDC, one internal
+-                             68-pin)
+-   AIC-7901A                 Single Channel 64-bit PCI-X 133MHz to 
+-                             Ultra320 SCSI ASIC
+-   AIC-7902A4                Dual Channel 64-bit PCI-X 133MHz to 
+-                             Ultra320 SCSI ASIC
+-   AIC-7902B                 Dual Channel 64-bit PCI-X 133MHz to
+-                             Ultra320 SCSI ASIC
+-
++   AIC-7901A                  Single Channel 64-bit PCI-X 133MHz to 
++                              Ultra320 SCSI ASIC
++   AIC-7901B                  Single Channel 64-bit PCI-X 133MHz to 
++                              Ultra320 SCSI ASIC with Retained Training
++   AIC-7902A4                 Dual Channel 64-bit PCI-X 133MHz to 
++                              Ultra320 SCSI ASIC
++   AIC-7902B                  Dual Channel 64-bit PCI-X 133MHz to
++                              Ultra320 SCSI ASIC with Retained Training
++
++   Ultra320 Adapters          Description                              ASIC
++   --------------------------------------------------------------------------
++   Adaptec SCSI Card 39320    Dual Channel 64-bit PCI-X 133MHz to   7902A4/7902B
++                              Ultra320 SCSI Card (one external 
++                              68-pin, two internal 68-pin)
++   Adaptec SCSI Card 39320A   Dual Channel 64-bit PCI-X 133MHz to      7902B
++                              Ultra320 SCSI Card (one external 
++                              68-pin, two internal 68-pin)
++   Adaptec SCSI Card 39320D   Dual Channel 64-bit PCI-X 133MHz to      7902A4
++                              Ultra320 SCSI Card (two external VHDC
++                              and one internal 68-pin)
++   Adaptec SCSI Card 39320D   Dual Channel 64-bit PCI-X 133MHz to      7902A4
++                              Ultra320 SCSI Card (two external VHDC
++                              and one internal 68-pin) based on the
++                              AIC-7902B ASIC
++   Adaptec SCSI Card 29320    Single Channel 64-bit PCI-X 133MHz to    7901A
++                              Ultra320 SCSI Card (one external 
++                              68-pin, two internal 68-pin, one
++                              internal 50-pin)
++   Adaptec SCSI Card 29320A   Single Channel 64-bit PCI-X 133MHz to    7901B
++                              Ultra320 SCSI Card (one external 
++                              68-pin, two internal 68-pin, one
++                              internal 50-pin)
++   Adaptec SCSI Card 29320LP  Single Channel 64-bit Low Profile        7901A
++                              PCI-X 133MHz to Ultra320 SCSI Card
++                              (One external VHDC, one internal
++                              68-pin)
++   Adaptec SCSI Card 29320ALP Single Channel 64-bit Low Profile        7901B
++                              PCI-X 133MHz to Ultra320 SCSI Card
++                              (One external VHDC, one internal
++                              68-pin)
+ 2. Version History
+-   (V1.3.0, January 2003) Full regression testing for all U320 products
+-   completed.
+-
+-   (V1.3.0 ALPHA, November 2002) Initial Alpha release.
+-   Added abort and target/lun reset error recovery handler and
+-   interrupt coalessing.
+-
+-   (V1.2.0, November 2002) Added support for Domain Validation and
+-   Hewlett-Packard version of the 39320D and AIC-7902 adapters.
+-   Support for previous adapters has not been fully tested and should
+-   only be used at the customer's own risk.
+-
+-   (V1.1.1, September 2002) Added support for the Linux 2.5.X kernel series
+-
+-   (V1.1.0, August 2002) Added support for four additional SCSI
+-   products: ASC-39320, ASC-29320, ASC-29320LP, AIC-7901.
+-
+-   (V1.1, August 2002) Added support for four additional SCSI
+-   products: ASC-39320, ASC-29320, ASC-29320LP, AIC-7901.
++   2.0.5 (December 22nd, 2003)
++        - Correct a bug preventing the driver from renegotiating
++          during auto-request operations when a check condition
++          occurred for a zero length command.
++        - Sniff sense information returned by targets for unit
++          attention errors that may indicate that the device has
++          been changed.  If we see such status for non Domain
++          Validation related commands, start a DV scan for the
++          target.  In the past, DV would only occur for hot-plugged
++          devices if no target had been previously probed for a
++          particular ID.  This change guarantees that the DV process
++          will occur even if the user swaps devices without any
++          interveining I/O to tell us that a device has gone missing.
++          The old behavior, among other things, would fail to spin up
++          drives that were hot-plugged since the Linux mid-layer
++          will only spin-up drives on initial attach.
++        - Correct several issues in the rundown of the good status
++          FIFO during error recovery.  The typical failure scenario
++          evidenced by this defect was the loss of several commands
++          under high load when         several queue full conditions occured
++          back to back.
++
++   2.0.4 (November 6th, 2003)
++        - Support the 2.6.0-test9 kernel
++        - Fix rare deadlock caused by using del_timer_sync from within
++          a timer handler.
++
++   2.0.3 (October 21st, 2003)
++        - On 7902A4 hardware, use the slow slew rate for transfer
++          rates slower than U320.  This behavior matches the Windows
++          driver.
++        - Fix some issues with the ahd_flush_qoutfifo() routine.
++        - Add a delay in the loop waiting for selection activity
++          to cease.  Otherwise we may exhaust the loop counter too
++          quickly on fast machines.
++        - Return to processing bad status completions through the
++          qoutfifo.  This reduces the amount of time the controller
++          is paused for these kinds of errors.
++        - Move additional common routines to the aiclib OSM library
++          to reduce code duplication.
++        - Leave removal of softcs from the global list of softcs to
++          the OSM.  This allows us to avoid holding the list_lock during
++          device destruction.
++        - Enforce a bus settle delay for bus resets that the
++          driver initiates.
++        - Fall back to basic DV for U160 devices that lack an
++          echo buffer.
++
++   2.0.2 (September 4th, 2003)
++        - Move additional common routines to the aiclib OSM library
++          to reduce code duplication.
++        - Avoid an inadvertant reset of the controller during the
++          memory mapped I/O test should the controller be left in
++          the reset state prior to driver initialization.  On some
++          systems, this extra reset resulted in a system hang due
++          to a chip access that occurred too soon after reset.
++        - Correct an endian bug in ahd_swap_with_next_hscb.  This
++          corrects strong-arm support.
++        - Reset the bus for transactions that timeout waiting for
++          the bus to go free after a disconnect or command complete
++          message.
++
++   2.0.1 (August 26th, 2003)
++        - Add magic sysrq handler that causes a card dump to be output
++          to the console for each controller.
++        - Avoid waking the mid-layer's error recovery handler during
++          timeout recovery by returning DID_ERROR instead of DID_TIMEOUT
++          for timed-out commands that have been aborted.
++        - Move additional common routines to the aiclib OSM library
++          to reduce code duplication.
++
++   2.0.0 (August 20th, 2003)
++        - Remove MMAPIO definition and allow memory mapped
++          I/O for any platform that supports PCI.
++        - Avoid clearing ENBUSFREE during single stepping to avoid
++          spurious "unexpected busfree while idle" messages.
++        - Correct deadlock in ahd_run_qoutfifo() processing.
++        - Optimize support for the 7901B.
++        - Correct a few cases where an explicit flush of pending
++          register writes was required to ensure acuracy in delays.
++        - Correct problems in manually flushing completed commands
++          on the controller.  The FIFOs are now flushed to ensure
++          that completed commands that are still draining to the
++          host are completed correctly.
++        - Correct incomplete CDB delivery detection on the 790XB.
++        - Ignore the cmd->underflow field since userland applications
++          using the legacy command pass-thru interface do not set
++          it correctly.  Honoring this field led to spurious errors
++          when users used the "scsi_unique_id" program.
++        - Perform timeout recovery within the driver instead of relying
++          on the Linux SCSI mid-layer to perform this function.  The
++          mid-layer does not know the full state of the SCSI bus and
++          is therefore prone to looping for several minutes to effect
++          recovery.  The new scheme recovers within 15 seconds of the
++          failure.
++        - Correct support for manual termination settings.
++        - Increase maximum wait time for serial eeprom writes allowing
++          writes to function correctly.
++
++   1.3.12 (August 11, 2003)
++        - Implement new error recovery thread that supercedes the existing
++          Linux SCSI error recovery code.
++        - Fix termination logic for 29320ALP.
++        - Fix SEEPROM delay to compensate for write ops taking longer.
++
++   1.3.11 (July 11, 2003)
++        - Fix several deadlock issues.
++        - Add 29320ALP and 39320B Id's.
++
++   1.3.10 (June 3rd, 2003)
++        - Align the SCB_TAG field on a 16byte boundary.  This avoids
++          SCB corruption on some PCI-33 busses.
++        - Correct non-zero luns on Rev B. hardware.
++        - Update for change in 2.5.X SCSI proc FS interface.
++        - When negotiation async via an 8bit WDTR message, send
++          an SDTR with an offset of 0 to be sure the target
++          knows we are async.  This works around a firmware defect
++          in the Quantum Atlas 10K.
++        - Implement controller susupend and resume.
++        - Clear PCI error state during driver attach so that we
++          don't disable memory mapped I/O due to a stray write
++          by some other driver probe that occurred before we
++          claimed the controller.
++
++   1.3.9 (May 22nd, 2003)
++        - Fix compiler errors.
++        - Remove S/G splitting for segments that cross a 4GB boundary.
++          This is guaranteed not to happen in Linux.
++        - Add support for scsi_report_device_reset() found in
++          2.5.X kernels.
++        - Add 7901B support.
++        - Simplify handling of the packtized lun Rev A workaround.
++        - Correct and simplify handling of the ignore wide residue
++          message.  The previous code would fail to report a residual
++          if the transaction data length was even and we received
++          an IWR message.
++
++   1.3.8 (April 29th, 2003)
++        - Fix types accessed via the command line interface code.
++        - Perform a few firmware optimizations.
++        - Fix "Unexpected PKT busfree" errors.
++        - Use a sequencer interrupt to notify the host of
++          commands with bad status.  We defer the notification
++          until there are no outstanding selections to ensure
++          that the host is interrupted for as short a time as
++          possible.
++        - Remove pre-2.2.X support.
++        - Add support for new 2.5.X interrupt API.
++        - Correct big-endian architecture support.
++
++   1.3.7 (April 16th, 2003)
++        - Use del_timer_sync() to ensure that no timeouts
++          are pending during controller shutdown.
++        - For pre-2.5.X kernels, carefully adjust our segment
++          list size to avoid SCSI malloc pool fragmentation.
++        - Cleanup channel display in our /proc output.
++        - Workaround duplicate device entries in the mid-layer
++          devlice list during add-single-device.
++
++   1.3.6 (March 28th, 2003)
++        - Correct a double free in the Domain Validation code.
++        - Correct a reference to free'ed memory during controller
++          shutdown.
++        - Reset the bus on an SE->LVD change.  This is required
++          to reset our transcievers.
++
++   1.3.5 (March 24th, 2003)
++        - Fix a few register window mode bugs.
++        - Include read streaming in the PPR flags we display in
++          diagnostics as well as /proc.
++        - Add PCI hot plug support for 2.5.X kernels.
++        - Correct default precompensation value for RevA hardware.
++        - Fix Domain Validation thread shutdown.
++        - Add a firmware workaround to make the LED blink
++          brighter during packetized operations on the H2A4.
++        - Correct /proc display of user read streaming settings.
++        - Simplify driver locking by releasing the io_request_lock
++          upon driver entry from the mid-layer.
++        - Cleanup command line parsing and move much of this code
++          to aiclib.
++
++   1.3.4 (February 28th, 2003)
++        - Correct a race condition in our error recovery handler.
++        - Allow Test Unit Ready commands to take a full 5 seconds
++          during Domain Validation.
++
++   1.3.2 (February 19th, 2003)
++        - Correct a Rev B. regression due to the GEM318
++          compatibility fix included in 1.3.1.
++          
++   1.3.1 (February 11th, 2003)
++        - Add support for the 39320A.
++        - Improve recovery for certain PCI-X errors.
++        - Fix handling of LQ/DATA/LQ/DATA for the
++          same write transaction that can occur without
++          interveining training.
++        - Correct compatibility issues with the GEM318
++          enclosure services device.
++        - Correct data corruption issue that occurred under
++          high tag depth write loads.
++        - Adapt to a change in the 2.5.X daemonize() API.
++        - Correct a "Missing case in ahd_handle_scsiint" panic.
++
++   1.3.0 (January 21st, 2003)
++        - Full regression testing for all U320 products completed.
++        - Added abort and target/lun reset error recovery handler and
++          interrupt coalessing.
++
++   1.2.0 (November 14th, 2002)
++        - Added support for Domain Validation
++        - Add support for the Hewlett-Packard version of the 39320D
++          and AIC-7902 adapters.
++        Support for previous adapters has not been fully tested and should
++        only be used at the customer's own risk.
++
++   1.1.1 (September 24th, 2002)
++        - Added support for the Linux 2.5.X kernel series
++
++   1.1.0 (September 17th, 2002)
++        - Added support for four additional SCSI products:
++          ASC-39320, ASC-29320, ASC-29320LP, AIC-7901.
+-   (V1.0, May 2002) This is the initial release of the 
+-   Ultra320 FMS.  The following is a list of supported features:
++   1.0.0 (May 30th, 2002)
++        - Initial driver release.
+    2.1. Software/Hardware Features
+         - Support for the SPI-4 "Ultra320" standard:
+@@ -82,6 +299,7 @@ The following information is available i
+           supported)
+         - Support for the PCI-X standard up to 133MHz
+         - Support for the PCI v2.2 standard
++      - Domain Validation
+    2.2. Operating System Support:
+         - Redhat Linux 7.2, 7.3, 8.0, Advanced Server 2.1
+--- linux-2.6.0/Documentation/scsi/aic7xxx.txt 2003-06-14 12:18:05.000000000 -0700
++++ 25/Documentation/scsi/aic7xxx.txt  2003-12-28 23:21:39.000000000 -0800
+@@ -1,5 +1,5 @@
+ ====================================================================
+-=    Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v6.2.28   =
++=    Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v6.3.4    =
+ =                            README for                            =
+ =                     The Linux Operating System                   =
+ ====================================================================
+@@ -132,26 +132,127 @@ The following information is available i
+ 2. Version History
+-        6.2.34 - Fix locking regression instroduced in 6.2.29 that
+-                 could cuase a lock order reversal between the io_request_lock
+-                 and our per-softc lock.  This was only possible on RH9,
+-                 SuSE, and kernel.org 2.4.X kernels.
+-
+-        6.2.33 - Dynamically disable PCI parity error reporting after
+-               10 errors are reported to the user.  These errors are
+-               the result of some other device issuing PCI transactions
+-               with bad parity.  Once the user has been informed of the
+-               problem, continuing to report the errors just degrades
+-               our performance.
+-
+-        6.2.32 - Dynamically sized S/G lists to avoid SCSI malloc
+-               pool fragmentation and SCSI mid-layer deadlock.
+-
+-        6.2.28 - Domain Validation Fixes
+-                 PCI parity error disable
+-                 Enhanced Memory Mapped I/O probe
++   6.3.4 (December 22nd, 2003)
++        - Provide a better description string for the 2915/30LP.
++        - Sniff sense information returned by targets for unit
++          attention errors that may indicate that the device has
++          been changed.  If we see such status for non Domain
++          Validation related commands, start a DV scan for the
++          target.  In the past, DV would only occur for hot-plugged
++          devices if no target had been previously probed for a
++          particular ID.  This change guarantees that the DV process
++          will occur even if the user swaps devices without any
++          interveining I/O to tell us that a device has gone missing.
++          The old behavior, among other things, would fail to spin up
++          drives that were hot-plugged since the Linux mid-layer
++          will only spin-up drives on initial attach.
++
++   6.3.3 (November 6th, 2003)
++        - Support the 2.6.0-test9 kernel
++        - Fix rare deadlock caused by using del_timer_sync from within
++          a timer handler.
++
++   6.3.2 (October 28th, 2003)
++        - Enforce a bus settle delay for bus resets that the
++          driver initiates.
++        - Fall back to basic DV for U160 devices that lack an
++          echo buffer.
++        - Correctly detect that left over BIOS data has not
++          been initialized when the CHPRST status bit is set
++          during driver initialization.
++
++   6.3.1 (October 21st, 2003)
++        - Fix a compiler error when building with only EISA or PCI
++          support compiled into the kernel.
++        - Add chained dependencies to both the driver and aicasm Makefiles
++          to avoid problems with parallel builds.
++        - Move additional common routines to the aiclib OSM library
++          to reduce code duplication.
++        - Fix a bug in the testing of the AHC_TMODE_WIDEODD_BUG that
++          could cause target mode operations to hang.
++        - Leave removal of softcs from the global list of softcs to
++          the OSM.  This allows us to avoid holding the list_lock during
++          device destruction.
++
++   6.3.0 (September 8th, 2003)
++        - Move additional common routines to the aiclib OSM library
++          to reduce code duplication.
++        - Bump minor number to reflect change in error recovery strategy.
++
++   6.2.38 (August 31st, 2003)
++        - Avoid an inadvertant reset of the controller during the
++          memory mapped I/O test should the controller be left in
++          the reset state prior to driver initialization.  On some
++          systems, this extra reset resulted in a system hang due
++          to a chip access that occurred too soon after reset.
++        - Move additional common routines to the aiclib OSM library
++          to reduce code duplication.
++        - Add magic sysrq handler that causes a card dump to be output
++          to the console for each controller.
++
++   6.2.37 (August 12th, 2003)
++        - Perform timeout recovery within the driver instead of relying
++          on the Linux SCSI mid-layer to perform this function.  The
++          mid-layer does not know the full state of the SCSI bus and
++          is therefore prone to looping for several minutes to effect
++          recovery.  The new scheme recovers within 15 seconds of the
++          failure.
++        - Support writing 93c56/66 SEEPROM on newer cards.
++      - Avoid clearing ENBUSFREE during single stepping to avoid
++          spurious "unexpected busfree while idle" messages.
++        - Enable the use of the "Auto-Access-Pause" feature on the
++          aic7880 and aic7870 chips.  It was disabled due to an
++          oversight.  Using this feature drastically reduces command
++          delivery latency.
++
++   6.2.36 (June 3rd, 2003)
++        - Correct code that disables PCI parity error checking.
++        - Correct and simplify handling of the ignore wide residue
++          message.  The previous code would fail to report a residual
++          if the transaction data length was even and we received
++          an IWR message.
++        - Add support for the 2.5.X EISA framework.
++        - Update for change in 2.5.X SCSI proc FS interface.
++        - Correct Domain Validation command-line option parsing.
++        - When negotiation async via an 8bit WDTR message, send
++          an SDTR with an offset of 0 to be sure the target
++          knows we are async.  This works around a firmware defect
++          in the Quantum Atlas 10K.
++        - Clear PCI error state during driver attach so that we
++          don't disable memory mapped I/O due to a stray write
++          by some other driver probe that occurred before we
++          claimed the controller.
++
++   6.2.35 (May 14th, 2003)
++        - Fix a few GCC 3.3 compiler warnings.
++        - Correct operation on EISA Twin Channel controller.
++        - Add support for 2.5.X's scsi_report_device_reset().
++
++   6.2.34 (May 5th, 2003)
++        - Fix locking regression instroduced in 6.2.29 that
++          could cuase a lock order reversal between the io_request_lock
++          and our per-softc lock.  This was only possible on RH9,
++          SuSE, and kernel.org 2.4.X kernels.
++
++   6.2.33 (April 30th, 2003)
++        - Dynamically disable PCI parity error reporting after
++          10 errors are reported to the user.  These errors are
++          the result of some other device issuing PCI transactions
++          with bad parity.  Once the user has been informed of the
++          problem, continuing to report the errors just degrades
++          our performance.
++
++   6.2.32 (March 28th, 2003)
++        - Dynamically sized S/G lists to avoid SCSI malloc
++          pool fragmentation and SCSI mid-layer deadlock.
++
++   6.2.28 (January 20th, 2003)
++        - Domain Validation Fixes
++        - Add ability to disable PCI parity error checking.
++        - Enhanced Memory Mapped I/O probe
+-        6.2.20 - Added Domain Validation
++   6.2.20 (November 7th, 2002)
++        - Added Domain Validation.
+ 3. Command Line Options
+--- linux-2.6.0/Documentation/scsi/BusLogic.txt        2003-08-08 22:55:10.000000000 -0700
++++ 25/Documentation/scsi/BusLogic.txt 2003-12-28 23:22:18.000000000 -0800
+@@ -577,7 +577,7 @@ LILO Linux Boot Loader (in /etc/lilo.con
+ INSMOD Loadable Kernel Module Installation Facility:
+   insmod BusLogic.o \
+-      'BusLogic_Options="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
++      'BusLogic="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
+ NOTE: Module Utilities 2.1.71 or later is required for correct parsing
+       of driver options containing commas.
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/Documentation/should-fix.txt    2003-12-28 23:21:10.000000000 -0800
+@@ -0,0 +1,545 @@
++Not-ready features and speedups
++===============================
++
++Legend:
++
++PRI1: We're totally lame if this doesn't get in
++PRI2: Would be nice
++PRI3: Not very important
++
++drivers/block/
++~~~~~~~~~~~~~~
++
++o viro: paride drivers need a big cleanup. Partially done, but ATAPI drivers
++  need serious work and bug fixing.
++
++  PRI2
++
++drivers/char/rtc/
++~~~~~~~~~~~~~~~~~
++
++o rmk, trini: add support for alarms to the existing generic rtc driver.
++
++  PRI2
++
++console drivers
++~~~~~~~~~~~~~~~
++  (Pavel Machek <pavel@ucw.cz>)
++
++o There are few must-fix bugs in cursor handling.
++
++o Play with gpm selection for a while and your cursor gets corrupted with
++  random dots. Ouch.
++
++device mapper
++~~~~~~~~~~~~~
++
++o ioctl interface cleanup patch is ready (redo the structure layouts)
++
++  PRI1
++
++o A port of the 2.4 snapshot and mirror targets is in progress
++
++  PRI1
++
++o the fs interface to dm needs to be redone.  gregkh was going to work on
++  this.  viro is interested in seeing work thus-far.
++
++  PRI2
++
++drivers/net/wireless/
++~~~~~~~~~~~~~~~~~~~~~
++
++  (Jean Tourrilhes <jt@bougret.hpl.hp.com>)
++
++o get HostAP driver in the kernel.  No consolidation of the 802.11
++  management across driver can happen until this one is in (which is probably
++  2.7.X material).  I think Jouni is mostly ready but didn't find time for
++  it.
++
++  PRI2
++
++o get more wireless drivers into the kernel.  The most "integrable" drivers
++  at this point seem the NWN driver, Pavel's Spectrum driver.
++
++  PRI1
++
++drivers/usb/gadget/
++~~~~~~~~~~~~~~~~~~~
++
++o rmk: SA11xx USB client/gadget code (David B has been doing some work on
++  this, and keeps trying to prod me, but unfortunately I haven't had the time
++  to look at his work, sorry David.)
++
++  PRI3
++
++fs/
++~~~
++
++o ext3 and ext2 block allocators have serious failure modes - interleaved
++  allocations.
++
++  PRI3
++
++o Integrate Chris Mason's 2.4 reiserfs ordered data and data journaling
++  patches.  They make reiserfs a lot safer.
++
++  Ordered: PRI2
++  data journalled: PRI3
++
++o viro: convert more filesystems to use lib/parser.c for options.
++
++  PRI2
++
++o aio: fs IO isn't async at present.  suparna has restart patches, they're
++  in -mm.  Need to get Ben to review/comment.
++
++  PRI1.
++
++o drepper: various filesystems use ->pid wrongly
++
++  PRI1
++
++o hch: devfs: there's a fundamental lookup vs devfsd race that's only
++  fixable by introducing a lookup vs devfs deadlock.  I can't see how this is
++  fixable without getting rid of the current devfsd design.  Mandrake seems
++  to have a workaround for this so this is at least not triggered so easily,
++  but that's not what I'd consider a fix..
++
++  PRI2
++
++kernel/
++~~~~~~~
++
++o rusty: Zippel's Reference count simplification.  Tricky code, but cuts
++  about 120 lines from module.c.  Patch exists, needs stressing.
++
++  PRI3
++
++o rusty: Fix module-failed-init races by starting module "disabled".  Patch
++  exists, requires some subsystems (ie.  add_partition) to explicitly say
++  "make module live now".  Without patch we are no worse off than 2.4 etc.
++
++  PRI1
++
++o Integrate userspace irq balancing daemon.
++
++  PRI2
++
++o kexec.  Seems to work, was in -mm.
++
++  PRI3
++
++o rmk: lib/inflate.c must not use static variables (causes these to be
++  referenced via GOTOFF relocations in PIC decompressor.  We have a PIC
++  decompressor to avoid having to hard code a per platform zImage link
++  address into the makefiles.)
++
++  PRI2
++
++o klibc merge?
++
++  PRI2
++
++mm/
++~~~
++
++o dropbehind for large files
++
++  PRI2
++
++net/
++~~~~
++
++  (davem)
++
++o Real serious use of IPSEC is hampered by lack of MPLS support.  MPLS is a
++  switching technology that works by switching based upon fixed length labels
++  prepended to packets.  Many people use this and IPSEC to implement VPNs
++  over public networks, it is also used for things like traffic engineering.
++
++  A good reference site is:
++
++      http://www.mplsrc.com/
++
++  Anyways, an existing (crappy) implementation exists.  I've almost
++  completed a rewrite, I should have something in the tree next week.
++
++  PRI1
++
++o Sometimes we generate IP fragments when it truly isn't necessary.
++
++  The way IP fragmentation is specified, each fragment must be modulo 8
++  bytes in length.  So suppose the device has an MTU that is not 0 modulo 8,
++  ethernet even classifies in this way.  1500 == (8 * 187) + 4
++
++  Our IP fragmenting engine can fragment on packets that are sized within
++  the last modulo 8 bytes of the MTU.  This happens in obscure cases, but it
++  does happen.
++
++  I've proposed a fix to Alexey, whereby very late in the output path we
++  check the packet, if we fragmented but the data length would fit into the
++  MTU we unfragment the packet.
++
++  This is low priority, because technically it creates suboptimal behavior
++  rather than mis-operation.
++
++  PRI1
++
++net/*/netfilter/
++~~~~~~~~~~~~~~~~
++
++o Lots of misc. cleanups, which are happening slowly.
++
++  PRI2
++
++power management
++~~~~~~~~~~~~~~~~
++
++o Pat and Pavel disagree over swsusp. Need to sort that out.
++
++  PRI2
++
++o Frame buffer restore codepaths (that requires some deep PCI magic)
++
++  PRI2
++
++o XFree86 hooks
++
++  PRI2
++
++o AGP restoration
++
++  PRI2
++
++o DRI restoration
++
++  (davej/Alan: not super-critical, can crash laptop on restore.  davej
++  looking into it.)
++
++  PRI2
++
++o IDE suspend/resume without races (Ben is looking at this a little)
++
++  PRI2
++
++o Pat: There are already CPU device structures; MTRRs should be a
++  dynamically registered interface of CPUs, which implies there needs
++  to be some other glue to know that there are MTRRs that need to be
++  saved/restored.
++
++  PRI1
++
++global
++~~~~~~
++
++o We need a kernel side API for reporting error events to userspace (could
++  be async to 2.6 itself)
++
++  (Prototype core based on netlink exists)
++
++  PRI2
++
++o Kai: Introduce a sane, easy and standard way to build external modules
++  - make clean and make modules_install are both broken
++
++  PRI2
++
++drivers
++~~~~~~~
++
++o Alan: Cardbus/PCMCIA requires all Russell's stuff is merged to do
++  multiheader right and so on
++
++  PRI1
++
++drivers/acpi/
++~~~~~~~~~~~~~
++
++o Fix acpi for all newer IBM Thinkpads see
++  http://bugme.osdl.org/show_bug.cgi?id=1038 for more information
++
++o alan: VIA APIC stuff is one bit of this, there are also some other
++  reports that were caused by ACPI not setting level v edge trigger some
++  times
++
++  PRI1
++
++o mochel: it seems the acpi irq routing code could use a serious rewrite.
++
++  grover: The problem is the ACPI irq routing code is trying to piggyback
++  on the existing MPS-specific data structures, and it's generally a hack.
++  So yes mochel is right, but it is also purging MPS-ities from common code
++  as well.  I've done some preliminary work in this area and it doesn't seem
++  to break anything (yet) but a rewrite in this area imho should not be
++  rushed out the door.  And, I think the above bugs can be fixed w/o the
++  rewrite.
++
++  PRI2
++
++o mochel: ACPI suspend doesn't work.  Important, not cricital.  Pat is
++  working it.
++
++  PRI2
++
++drivers/block/
++~~~~~~~~~~~~~~
++
++o More testing of floppy
++
++  PRI3
++
++drivers/char/
++~~~~~~~~~~~~~
++
++
++drivers/ide/
++~~~~~~~~~~~~
++
++  (Alan)
++
++o IDE PIO has occasional unexplained PIO disk eating reports
++
++  PRI1
++
++o IDE has multiple zillions of races/hangs in 2.5 still
++
++  PRI1
++
++o IDE scsi needs rewriting
++
++  PRI2
++
++o IDE needs significant reworking to handle Simplex right
++
++  PRI2
++
++o IDE hotplug handling for 2.5 is completely broken still
++
++  PRI2
++
++o There are lots of other IDE bugs that wont go away until the taskfile
++  stuff is included, the locking bugs that allow any user to hang the IDE
++  layer in 2.5, and some other updates are forward ported.  (esp.  HPT372N).
++
++  PRI1
++
++drivers/isdn/
++~~~~~~~~~~~~~
++
++  (Kai, rmk)
++
++o isdn_tty locking is completely broken (cli() and friends)
++
++  PRI2
++
++o fix other drivers
++
++  PRI2
++
++o lots more cleanups, adaption to recent APIs etc
++
++  PRI3
++
++o fixup tty-based ISDN drivers which provide TIOCM* ioctls (see my recent
++  3-set patch for serial stuff)
++
++  Alternatively, we could re-introduce the fallback to driver ioctl parsing
++  for these if not enough drivers get updated.
++
++  PRI3
++
++drivers/net/
++~~~~~~~~~~~~
++
++o davej: Either Wireless network drivers or PCMCIA broke somewhen.  A
++  configuration that worked fine under 2.4 doesn't receive any packets.  Need
++  to look into this more to make sure I don't have any misconfiguration that
++  just 'happened to work' under 2.4
++
++  PRI1
++
++drivers/scsi/
++~~~~~~~~~~~~~
++
++o jejb: qlogic -
++
++  o Merge the feral driver.  It covers all qlogic chips: 1020 all the way
++    up to 23xxx. http://linux-scsi.bkbits.net/scsi-isp-2.5
++
++  o qla2xxx: only for FC chips.  Has significant build issues.  hch
++    promises to send me a "must fix" list for this.
++    http://linux-scsi.bkbits.net/scsi-qla2xxx-2.5
++
++  PRI2
++
++o hch, Mike Anderson, Badari Pulavarty: scsi locking issues
++
++  o there are lots of members of struct Scsi_Host/scsi_device/scsi_cmnd
++    with very unclear locking, many of them probably want to become
++    atomic_t's or bitmaps (for the 1bit bitfields).
++
++  o there's lots of volatile abuse in the scsi code that needs to be
++    thought about.
++
++  o there's some global variables incremented without any locks
++
++  PRI2
++
++sound/
++~~~~~~
++
++o rmk: several OSS drivers for SA11xx-based hardware in need of
++  ALSA-ification and L3 bus support code for these.
++
++o rmk: need to complete ALSA-ification of the WaveArtist driver for both
++  NetWinder and other stuff (there's some fairly fundamental differences in
++  the way the mixer needs to be handled for the NetWinder.)
++
++  (Issues with forward-porting 2.4 bugfixes.)
++  (Killing off OSS is 2.7 material)
++
++PRI2
++
++arch/i386/
++~~~~~~~~~~
++
++o Also PC9800 merge needs finishing to the point we want for 2.6 (not all).
++
++  PRI3
++
++o davej: PAT support (for mtrr exhaustion w/ AGP)
++
++  PRI2
++
++o 2.5.x won't boot on some 440GX
++
++  alan: Problem understood now, feasible fix in 2.4/2.4-ac.  (440GX has two
++  IRQ routers, we use the $PIR table with the PIIX, but the 440GX doesnt use
++  the PIIX for its IRQ routing).  Fall back to BIOS for 440GX works and Intel
++  concurs.
++
++  PRI1
++
++o 2.5.x doesn't handle VIA APIC right yet.
++
++  1. We must write the PCI_INTERRUPT_LINE
++
++  2. We have quirk handlers that seem to trash it.
++
++  PRI1
++
++o ECC driver questions are not yet sorted (DaveJ is working on this) (Dan
++  Hollis)
++
++  alan: ECC - I have some test bits from Dan's stuff - they need no kernel
++  core changes for most platforms.  That means we can treat it as a random
++  driver merge.
++
++  PRI3
++
++o alan: 2.4 has some fixes for tsc handling bugs.  One where some bioses in
++  SMM mode mess up our toggle on the time high/low or mangle the counter and
++  one where a few chips need religious use of _p for timer access and we
++  don't do that.  This is forward porting little bits of fixup.
++
++  ACPI HZ stuff we can't trap - a lot of ACPI is implemented as outb's
++  triggering SMM traps
++
++  PRI1
++
++arch/x86_64/
++~~~~~~~~~~~~
++
++  (Andi)
++
++o time handling is broken. Need to move up 2.4 time.c code.
++
++  PRI1
++
++o NMI watchdog seems to tick too fast
++
++  PRI2
++
++o need to coredump 64bit vsyscall code with dwarf2
++
++  PRI2
++
++o move 64bit signal trampolines into vsyscall code and add dwarf2 for it.
++  (in progress)
++
++  PRI1
++
++o describe kernel assembly with dwarf2 annotations for kgdb
++
++  PRI3
++
++arch/alpha/
++~~~~~~~~~~~
++
++o rth: Ptrace writes are broken.  This means we can't (reliably) set
++  breakpoints or modify variables from gdb.
++
++  PRI1
++
++arch/arm/
++~~~~~~~~~
++
++o rmk: missing raw keyboard translation tables for all ARM machines.
++  Haven't even looked into this at all.  This could be messy since there
++  isn't an ARM architecture standard.  I'm presently hoping that it won't be
++  an issue.  If it does, I guess we'll see drivers/char/keyboard.c explode.
++
++  PRI2
++
++arch/others/
++~~~~~~~~~~~~
++
++o SH needs resyncing, as do some other ports. SH64 needs merging.
++  No impact on mainstream platforms hopefully.
++
++  PRI2
++
++arch/s390/
++~~~~~~~~~
++
++o A nastly memory management problem causes random crashes.  These appear
++  to be fixed/hidden by the objrmap patch, more investigation is needed.
++
++  PRI1
++
++drivers/s390/
++~~~~~~~~~~~~~
++
++o Early userspace and 64 bit dev_t will allow the removal of most of
++  dasd_devmap.c and dasd_genhd.c.
++
++  PRI2
++
++o The 3270 console driver needs to be replaced with a working one
++  (prototype is there, needs to be finished).
++
++  PRI2
++
++o Minor interface changes are pending in cio/ when the z990 machines are
++  out.
++
++  PRI2
++
++o Jan Glauber is working on a fix for the timer issues related to running
++  on virtualized CPUs (wall-clock vs.  cpu time).
++
++  PRI1
++
++o a block device driver for ramdisks shared among virtual machines
++
++  PRI3
++
++o driver for crypto hardware
++
++  PRI3
++
++o 'claw' network device driver
++
++  PRI3
++
+--- linux-2.6.0/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl   2003-08-22 19:23:39.000000000 -0700
++++ 25/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl    2003-12-28 23:23:06.000000000 -0800
+@@ -3623,7 +3623,7 @@ struct _snd_pcm_runtime {
+         <para>
+           More precise information can be found in
+-        <filename>alsa-kernel/Documentation/ControlNames.txt</filename>.
++        <filename>alsa-kernel/Documentation/sound/alsa/ControlNames.txt</filename>.
+         </para>
+       </section>
+     </section>
+--- linux-2.6.0/Documentation/sound/oss/CMI8330        2003-06-14 12:17:57.000000000 -0700
++++ 25/Documentation/sound/oss/CMI8330 2003-12-28 23:23:06.000000000 -0800
+@@ -2,7 +2,7 @@ Documentation for CMI 8330 (SoundPRO) 
+ -------------------------------------
+ Alessandro Zummo <azummo@ita.flashnet.it>
+-( Be sure to read Documentation/sound/SoundPro too )
++( Be sure to read Documentation/sound/oss/SoundPro too )
+ This adapter is now directly supported by the sb driver.
+--- linux-2.6.0/Documentation/sound/oss/INSTALL.awe    2003-06-14 12:18:29.000000000 -0700
++++ 25/Documentation/sound/oss/INSTALL.awe     2003-12-28 23:23:06.000000000 -0800
+@@ -114,7 +114,7 @@ See INSTALL.RH for more details.
+               # insmod awe_wave
+               (Be sure to load awe_wave after sb!)
+-              See /usr/src/linux/Documentation/sound/AWE32 for
++              See /usr/src/linux/Documentation/sound/oss/AWE32 for
+               more details.
+   9. (only for obsolete systems) If you don't have /dev/sequencer
+--- linux-2.6.0/Documentation/sound/oss/Introduction   2003-10-08 15:07:08.000000000 -0700
++++ 25/Documentation/sound/oss/Introduction    2003-12-28 23:23:06.000000000 -0800
+@@ -24,7 +24,7 @@ History:
+ ========
+ 0.1.0  11/20/1998  First version, draft
+ 1.0.0  11/1998     Alan Cox changes, incorporation in 2.2.0
+-                   as /usr/src/linux/Documentation/sound/Introduction
++                   as /usr/src/linux/Documentation/sound/oss/Introduction
+ 1.1.0  6/30/1999   Second version, added notes on making the drivers,
+                    added info on multiple sound cards of similar types,]
+                    added more diagnostics info, added info about esd.
+--- linux-2.6.0/Documentation/sound/oss/PAS16  2003-06-14 12:18:34.000000000 -0700
++++ 25/Documentation/sound/oss/PAS16   2003-12-28 23:23:06.000000000 -0800
+@@ -9,7 +9,7 @@ and others whose names I could not find.
+ This documentation is relevant for the PAS16 driver (pas2_card.c and
+ friends) under kernel version 2.3.99 and later.  If you are
+ unfamiliar with configuring sound under Linux, please read the
+-Sound-HOWTO, linux/Documentation/sound/Introduction and other 
++Sound-HOWTO, linux/Documentation/sound/oss/Introduction and other
+ relevant docs first.
+ The following information is relevant information from README.OSS
+@@ -73,8 +73,8 @@ CONFIG_SOUND
+   You want to read the Sound-HOWTO, available from
+   http://www.tldp.org/docs.html#howto . General information
+   about the modular sound system is contained in the files
+-  Documentation/sound/Introduction. The file
+-  Documentation/sound/README.OSS contains some slightly outdated but
++  Documentation/sound/oss/Introduction. The file
++  Documentation/sound/oss/README.OSS contains some slightly outdated but
+   still useful information as well.
+ OSS sound modules
+@@ -119,7 +119,7 @@ CONFIG_SOUND_YM3812
+   cards may have software (TSR) FM emulation. Enabling FM support with
+   these cards may cause trouble (I don't currently know of any such
+   cards, however).
+-  Please read the file Documentation/sound/OPL3 if your card has an
++  Please read the file Documentation/sound/oss/OPL3 if your card has an
+   OPL3 chip.
+   If you compile the driver into the kernel, you have to add
+   "opl3=<io>" to the kernel command line.
+--- linux-2.6.0/Documentation/sound/oss/SoundPro       2003-06-14 12:18:51.000000000 -0700
++++ 25/Documentation/sound/oss/SoundPro        2003-12-28 23:23:06.000000000 -0800
+@@ -1,7 +1,7 @@
+ Documentation for the SoundPro CMI8330 extensions in the WSS driver (ad1848.o)
+ ------------------------------------------------------------------------------
+-( Be sure to read Documentation/sound/CMI8330 too )
++( Be sure to read Documentation/sound/oss/CMI8330 too )
+ Ion Badulescu, ionut@cs.columbia.edu
+ February 24, 1999
+--- linux-2.6.0/Documentation/sound/oss/Wavefront      2003-08-08 22:55:10.000000000 -0700
++++ 25/Documentation/sound/oss/Wavefront       2003-12-28 23:23:06.000000000 -0800
+@@ -105,7 +105,7 @@ design and implementation of the driver.
+    drivers/sound/wf_midi.c              -- the "uart401" driver 
+                                             to support virtual MIDI mode.
+    include/wavefront.h                  -- the header file
+-   Documentation/sound/Tropez+          -- short docs on configuration
++   Documentation/sound/oss/Tropez+          -- short docs on configuration
+ **********************************************************************
+ 4) How do I compile/install/use it ?
+--- linux-2.6.0/Documentation/SubmittingDrivers        2003-07-10 18:50:30.000000000 -0700
++++ 25/Documentation/SubmittingDrivers 2003-12-28 23:22:58.000000000 -0800
+@@ -34,14 +34,13 @@ Linux 2.2:
+       maintainer then please contact Alan Cox <alan@lxorguk.ukuu.org.uk>
+ Linux 2.4:
+-      The same rules apply as 2.2 but this kernel tree is under active
+-      development. The final contact point for Linux 2.4 submissions is
+-      Marcelo Tosatti <marcelo@conectiva.com.br>.
++      The same rules apply as 2.2. The final contact point for Linux 2.4
++      submissions is Marcelo Tosatti <marcelo.tosatti@cyclades.com>.
+-Linux 2.5:
++Linux 2.6:
+       The same rules apply as 2.4 except that you should follow linux-kernel
+-      to track changes in API's. The final contact point for Linux 2.5
+-      submissions is Linus Torvalds <torvalds@osdl.org>.
++      to track changes in API's. The final contact point for Linux 2.6
++      submissions is Andrew Morton <akpm@osdl.org>.
+ What Criteria Determine Acceptance
+ ----------------------------------
+--- linux-2.6.0/Documentation/SubmittingPatches        2003-07-10 18:50:30.000000000 -0700
++++ 25/Documentation/SubmittingPatches 2003-12-28 23:21:00.000000000 -0800
+@@ -239,7 +239,7 @@ Let the compiler optimize away the "no-o
+ Simple example, of poor code:
+-      dev = init_etherdev (NULL, 0);
++      dev = alloc_etherdev (sizeof(struct funky_private));
+       if (!dev)
+               return -ENODEV;
+       #ifdef CONFIG_NET_FUNKINESS
+@@ -254,7 +254,7 @@ Cleaned-up example:
+       #endif
+ (in the code itself)
+-      dev = init_etherdev (NULL, 0);
++      dev = alloc_etherdev (sizeof(struct funky_private));
+       if (!dev)
+               return -ENODEV;
+       init_funky_net(dev);
+--- linux-2.6.0/Documentation/sysctl/fs.txt    2003-11-09 16:45:05.000000000 -0800
++++ 25/Documentation/sysctl/fs.txt     2003-12-28 23:26:39.000000000 -0800
+@@ -138,3 +138,13 @@ thus the maximum number of mounted files
+ can have. You only need to increase super-max if you need to
+ mount more filesystems than the current value in super-max
+ allows you to.
++
++==============================================================
++
++aio-nr & aio-max-nr:
++
++aio-nr shows the current system-wide number of asynchronous io
++requests.  aio-max-nr allows you to change the maximum value
++aio-nr can grow to.
++
++==============================================================
+--- linux-2.6.0/Documentation/watchdog/watchdog-api.txt        2003-09-08 13:58:55.000000000 -0700
++++ 25/Documentation/watchdog/watchdog-api.txt 2003-12-28 23:22:31.000000000 -0800
+@@ -358,6 +358,15 @@ w83877f_wdt.c -- W83877F Computer
+       No bits set in GETSUPPORT
++w83627hf_wdt.c -- w83627hf watchdog
++
++      Timeout that defaults to 60 seconds, supports SETTIMEOUT.
++
++      Supports CONFIG_WATCHDOG_NOWAYOUT
++
++      GETSUPPORT returns WDIOF_KEEPALIVEPING and WDIOF_SETTIMEOUT.
++      The GETSTATUS call returns if the device is open or not.
++
+ wdt.c -- ICS WDT500/501 ISA and
+ wdt_pci.c -- ICS WDT500/501 PCI
+--- linux-2.6.0/drivers/acorn/block/fd1772.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/acorn/block/fd1772.c    2003-12-28 23:21:17.000000000 -0800
+@@ -365,13 +365,12 @@ static void finish_fdc_done(int dummy);
+ static void floppy_off(unsigned int nr);
+ static void setup_req_params(int drive);
+ static void redo_fd_request(void);
+-static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int
++static int fd_ioctl(struct block_device *bdev, struct file *filp, unsigned int
+                   cmd, unsigned long param);
+ static void fd_probe(int drive);
+ static int fd_test_drive_present(int drive);
+ static void config_types(void);
+-static int floppy_open(struct inode *inode, struct file *filp);
+-static int floppy_release(struct inode *inode, struct file *filp);
++static int floppy_open(struct block_device *bdev, struct file *filp);
+ static void do_fd_request(request_queue_t *);
+ /************************* End of Prototypes **************************/
+@@ -1309,11 +1308,9 @@ static int invalidate_drive(struct block
+       return 0;
+ }
+-static int fd_ioctl(struct inode *inode, struct file *filp,
++static int fd_ioctl(struct block_device *bdev, struct file *filp,
+                   unsigned int cmd, unsigned long param)
+ {
+-      struct block_device *bdev = inode->i_bdev;
+-
+       switch (cmd) {
+       case FDFMTEND:
+       case FDFLUSH:
+@@ -1453,10 +1450,11 @@ static void config_types(void)
+  * drive with different device numbers.
+  */
+-static int floppy_open(struct inode *inode, struct file *filp)
++static int floppy_open(struct block_device *bdev, struct file *filp)
+ {
+-      int drive = iminor(inode) & 3;
+-      int type =  iminor(inode) >> 2;
++      struct archy_floppy_struct *p = bdev->bd_disk->private_data;
++      int drive = p - unit;
++      int type =  MINOR(bdev->bd_dev) >> 2;
+       int old_dev = fd_device[drive];
+       if (fd_ref[drive] && old_dev != type)
+@@ -1476,10 +1474,13 @@ static int floppy_open(struct inode *ino
+               return 0;
+       if (filp->f_mode & 3) {
+-              check_disk_change(inode->i_bdev);
++              check_disk_change(bdev);
+               if (filp->f_mode & 2) {
+-                      if (unit[drive].wpstat) {
+-                              floppy_release(inode, filp);
++                      if (p->wpstat) {
++                              if (fd_ref[drive] < 0)
++                                      fd_ref[drive] = 0;
++                              else
++                                      fd_ref[drive]--;
+                               return -EROFS;
+                       }
+               }
+@@ -1487,10 +1488,10 @@ static int floppy_open(struct inode *ino
+       return 0;
+ }
+-
+-static int floppy_release(struct inode *inode, struct file *filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-      int drive = iminor(inode) & 3;
++      struct archy_floppy_struct *p = disk->private_data;
++      int drive = p - unit;
+       if (fd_ref[drive] < 0)
+               fd_ref[drive] = 0;
+--- linux-2.6.0/drivers/acorn/block/mfmhd.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/acorn/block/mfmhd.c     2003-12-28 23:21:12.000000000 -0800
+@@ -1153,9 +1153,9 @@ static int mfm_initdrives(void)
+  * The 'front' end of the mfm driver follows...
+  */
+-static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg)
++static int mfm_ioctl(struct block_device *bdev, struct file *file, u_int cmd, u_long arg)
+ {
+-      struct mfm_info *p = inode->i_bdev->bd_disk->private_data;
++      struct mfm_info *p = bdev->bd_disk->private_data;
+       struct hd_geometry *geo = (struct hd_geometry *) arg;
+       if (cmd != HDIO_GETGEO)
+               return -EINVAL;
+@@ -1167,7 +1167,7 @@ static int mfm_ioctl(struct inode *inode
+               return -EFAULT;
+       if (put_user (p->cylinders, &geo->cylinders))
+               return -EFAULT;
+-      if (put_user (get_start_sect(inode->i_bdev), &geo->start))
++      if (put_user (get_start_sect(bdev), &geo->start))
+               return -EFAULT;
+       return 0;
+ }
+--- linux-2.6.0/drivers/acpi/bus.c     2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/acpi/bus.c      2003-12-28 23:21:33.000000000 -0800
+@@ -39,7 +39,7 @@
+ #define _COMPONENT            ACPI_BUS_COMPONENT
+ ACPI_MODULE_NAME              ("acpi_bus")
+-extern void acpi_pic_set_level_irq(unsigned int irq);
++extern void __init acpi_pic_sci_set_trigger(unsigned int irq);
+ FADT_DESCRIPTOR                       acpi_fadt;
+ struct acpi_device            *acpi_root;
+@@ -615,7 +615,7 @@ acpi_bus_init (void)
+       if (acpi_ioapic)
+               mp_config_ioapic_for_sci(acpi_fadt.sci_int);
+       else
+-              acpi_pic_set_level_irq(acpi_fadt.sci_int);
++              acpi_pic_sci_set_trigger(acpi_fadt.sci_int);
+ #endif
+       status = acpi_enable_subsystem(ACPI_FULL_INITIALIZATION);
+--- linux-2.6.0/drivers/acpi/dispatcher/dsinit.c       2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dsinit.c        2003-12-28 23:21:33.000000000 -0800
+@@ -106,7 +106,7 @@ acpi_ds_init_one_object (
+               status = acpi_ds_initialize_region (obj_handle);
+               if (ACPI_FAILURE (status)) {
+                       ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %p [%4.4s] - Init failure, %s\n",
+-                              obj_handle, ((struct acpi_namespace_node *) obj_handle)->name.ascii,
++                              obj_handle, acpi_ut_get_node_name (obj_handle),
+                               acpi_format_exception (status)));
+               }
+@@ -141,7 +141,7 @@ acpi_ds_init_one_object (
+               status = acpi_ds_parse_method (obj_handle);
+               if (ACPI_FAILURE (status)) {
+                       ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n",
+-                              obj_handle, ((struct acpi_namespace_node *) obj_handle)->name.ascii,
++                              obj_handle, acpi_ut_get_node_name (obj_handle),
+                               acpi_format_exception (status)));
+                       /* This parse failed, but we will continue parsing more methods */
+--- linux-2.6.0/drivers/acpi/dispatcher/dsmethod.c     2003-06-14 12:18:21.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dsmethod.c      2003-12-28 23:21:33.000000000 -0800
+@@ -94,7 +94,7 @@ acpi_ds_parse_method (
+       }
+       ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Parsing [%4.4s] **** named_obj=%p\n",
+-              ((struct acpi_namespace_node *) obj_handle)->name.ascii, obj_handle));
++              acpi_ut_get_node_name (obj_handle), obj_handle));
+       /* Extract the method object from the method Node */
+@@ -169,7 +169,7 @@ acpi_ds_parse_method (
+       ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+               "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
+-              ((struct acpi_namespace_node *) obj_handle)->name.ascii, obj_handle, op));
++              acpi_ut_get_node_name (obj_handle), obj_handle, op));
+       acpi_ps_delete_parse_tree (op);
+       return_ACPI_STATUS (status);
+--- linux-2.6.0/drivers/acpi/dispatcher/dsmthdat.c     2003-06-22 12:04:44.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dsmthdat.c      2003-12-28 23:21:35.000000000 -0800
+@@ -567,13 +567,13 @@ acpi_ds_store_object_to_local (
+       acpi_status                     status;
+       struct acpi_namespace_node      *node;
+       union acpi_operand_object       *current_obj_desc;
++      union acpi_operand_object       *new_obj_desc;
+       ACPI_FUNCTION_TRACE ("ds_store_object_to_local");
+       ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n",
+               opcode, index, obj_desc));
+-
+       /* Parameter validation */
+       if (!obj_desc) {
+@@ -595,6 +595,18 @@ acpi_ds_store_object_to_local (
+       }
+       /*
++       * If the reference count on the object is more than one, we must
++       * take a copy of the object before we store.
++       */
++      new_obj_desc = obj_desc;
++      if (obj_desc->common.reference_count > 1) {
++              status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state);
++              if (ACPI_FAILURE (status)) {
++                      return_ACPI_STATUS (status);
++              }
++      }
++
++      /*
+        * If there is an object already in this slot, we either
+        * have to delete it, or if this is an argument and there
+        * is an object reference stored there, we have to do
+@@ -624,8 +636,8 @@ acpi_ds_store_object_to_local (
+                        * operand objects of type Reference.
+                        */
+                       if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+-                              ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: %X\n",
+-                                      current_obj_desc->common.type));
++                              ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: [%s]\n",
++                                              acpi_ut_get_descriptor_name (current_obj_desc)));
+                               return_ACPI_STATUS (AE_AML_INTERNAL);
+                       }
+@@ -636,15 +648,21 @@ acpi_ds_store_object_to_local (
+                       if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+                               (current_obj_desc->reference.opcode == AML_REF_OF_OP)) {
+                               ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+-                                      "Arg (%p) is an obj_ref(Node), storing in node %p\n",
+-                                      obj_desc, current_obj_desc));
++                                              "Arg (%p) is an obj_ref(Node), storing in node %p\n",
++                                              new_obj_desc, current_obj_desc));
+                               /*
+                                * Store this object to the Node
+                                * (perform the indirect store)
+                                */
+-                              status = acpi_ex_store_object_to_node (obj_desc,
++                              status = acpi_ex_store_object_to_node (new_obj_desc,
+                                                current_obj_desc->reference.object, walk_state);
++
++                              /* Remove local reference if we copied the object above */
++
++                              if (new_obj_desc != obj_desc) {
++                                      acpi_ut_remove_reference (new_obj_desc);
++                              }
+                               return_ACPI_STATUS (status);
+                       }
+               }
+@@ -657,12 +675,18 @@ acpi_ds_store_object_to_local (
+       }
+       /*
+-       * Install the obj_stack descriptor (*obj_desc) into
++       * Install the Obj descriptor (*new_obj_desc) into
+        * the descriptor for the Arg or Local.
+-       * Install the new object in the stack entry
+        * (increments the object reference count by one)
+        */
+-      status = acpi_ds_method_data_set_value (opcode, index, obj_desc, walk_state);
++      status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state);
++
++      /* Remove local reference if we copied the object above */
++
++      if (new_obj_desc != obj_desc) {
++              acpi_ut_remove_reference (new_obj_desc);
++      }
++
+       return_ACPI_STATUS (status);
+ }
+--- linux-2.6.0/drivers/acpi/dispatcher/dsopcode.c     2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/acpi/dispatcher/dsopcode.c      2003-12-28 23:21:33.000000000 -0800
+@@ -201,7 +201,7 @@ acpi_ds_get_buffer_field_arguments (
+       ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL));
+       ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n",
+-              node->name.ascii));
++              acpi_ut_get_node_name (node)));
+       /* Execute the AML code for the term_arg arguments */
+@@ -346,7 +346,7 @@ acpi_ds_get_region_arguments (
+       ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL));
+       ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n",
+-              node->name.ascii, extra_desc->extra.aml_start));
++              acpi_ut_get_node_name (node), extra_desc->extra.aml_start));
+       /* Execute the argument AML */
+@@ -438,8 +438,8 @@ acpi_ds_init_buffer_field (
+        * after resolution in acpi_ex_resolve_operands().
+        */
+       if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) {
+-              ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination must be a NS Node\n",
+-                      acpi_ps_get_opcode_name (aml_opcode)));
++              ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination not a NS Node [%s]\n",
++                              acpi_ps_get_opcode_name (aml_opcode), acpi_ut_get_descriptor_name (result_desc)));
+               status = AE_AML_OPERAND_TYPE;
+               goto cleanup;
+@@ -514,14 +514,16 @@ acpi_ds_init_buffer_field (
+               goto cleanup;
+       }
+-
+       /* Entire field must fit within the current length of the buffer */
+       if ((bit_offset + bit_count) >
+               (8 * (u32) buffer_desc->buffer.length)) {
+               ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+-                      "Field size %d exceeds Buffer size %d (bits)\n",
+-                       bit_offset + bit_count, 8 * (u32) buffer_desc->buffer.length));
++                      "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
++                       acpi_ut_get_node_name (result_desc),
++                       bit_offset + bit_count,
++                       acpi_ut_get_node_name (buffer_desc->buffer.node),
++                       8 * (u32) buffer_desc->buffer.length));
+               status = AE_AML_BUFFER_LIMIT;
+               goto cleanup;
+       }
+@@ -742,7 +744,7 @@ acpi_ds_eval_region_operands (
+       ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n",
+               obj_desc,
+-              ACPI_HIDWORD (obj_desc->region.address), ACPI_LODWORD (obj_desc->region.address),
++              ACPI_FORMAT_UINT64 (obj_desc->region.address),
+               obj_desc->region.length));
+       /* Now the address and length are valid for this opregion */
+--- linux-2.6.0/drivers/acpi/dispatcher/dswexec.c      2003-06-14 12:18:35.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dswexec.c       2003-12-28 23:21:33.000000000 -0800
+@@ -416,10 +416,24 @@ acpi_ds_exec_end_op (
+                       status = acpi_gbl_op_type_dispatch [op_type] (walk_state);
+               }
+               else {
+-                      ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+-                              "[%s]: Could not resolve operands, %s\n",
+-                              acpi_ps_get_opcode_name (walk_state->opcode),
+-                              acpi_format_exception (status)));
++                      /*
++                       * Treat constructs of the form "Store(local_x,local_x)" as noops when the
++                       * Local is uninitialized.
++                       */
++                      if  ((status == AE_AML_UNINITIALIZED_LOCAL) &&
++                              (walk_state->opcode == AML_STORE_OP) &&
++                              (walk_state->operands[0]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
++                              (walk_state->operands[1]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
++                              (walk_state->operands[0]->reference.opcode ==
++                               walk_state->operands[1]->reference.opcode)) {
++                              status = AE_OK;
++                      }
++                      else {
++                              ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
++                                      "[%s]: Could not resolve operands, %s\n",
++                                      acpi_ps_get_opcode_name (walk_state->opcode),
++                                      acpi_format_exception (status)));
++                      }
+               }
+               /* Always delete the argument objects and clear the operand stack */
+--- linux-2.6.0/drivers/acpi/dispatcher/dswload.c      2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dswload.c       2003-12-28 23:21:33.000000000 -0800
+@@ -167,7 +167,7 @@ acpi_ds_load1_begin_op (
+       object_type = walk_state->op_info->object_type;
+       ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+-              "State=%p Op=%p [%s] ", walk_state, op, acpi_ut_get_type_name (object_type)));
++              "State=%p Op=%p [%s]\n", walk_state, op, acpi_ut_get_type_name (object_type)));
+       switch (walk_state->opcode) {
+       case AML_SCOPE_OP:
+@@ -260,10 +260,12 @@ acpi_ds_load1_begin_op (
+               if ((walk_state->opcode != AML_SCOPE_OP) &&
+                       (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
+                       flags |= ACPI_NS_ERROR_IF_FOUND;
+-                      ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Cannot already exist\n"));
++                      ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n",
++                                      acpi_ut_get_type_name (object_type)));
+               }
+               else {
+-                      ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Both Find or Create allowed\n"));
++                      ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Both Find or Create allowed\n",
++                                      acpi_ut_get_type_name (object_type)));
+               }
+               /*
+--- linux-2.6.0/drivers/acpi/dispatcher/dswscope.c     2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/acpi/dispatcher/dswscope.c      2003-12-28 23:21:33.000000000 -0800
+@@ -146,7 +146,7 @@ acpi_ds_scope_stack_push (
+       if (old_scope_info) {
+               ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+                       "[%4.4s] (%s)",
+-                      old_scope_info->scope.node->name.ascii,
++                      acpi_ut_get_node_name (old_scope_info->scope.node),
+                       acpi_ut_get_type_name (old_scope_info->common.value)));
+       }
+       else {
+@@ -156,7 +156,7 @@ acpi_ds_scope_stack_push (
+       ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+               ", New scope -> [%4.4s] (%s)\n",
+-              scope_info->scope.node->name.ascii,
++              acpi_ut_get_node_name (scope_info->scope.node),
+               acpi_ut_get_type_name (scope_info->common.value)));
+       /* Push new scope object onto stack */
+@@ -207,14 +207,14 @@ acpi_ds_scope_stack_pop (
+       ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+               "[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
+               (u32) walk_state->scope_depth,
+-              scope_info->scope.node->name.ascii,
++              acpi_ut_get_node_name (scope_info->scope.node),
+               acpi_ut_get_type_name (scope_info->common.value)));
+       new_scope_info = walk_state->scope_info;
+       if (new_scope_info) {
+               ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
+                       "[%4.4s] (%s)\n",
+-                      new_scope_info->scope.node->name.ascii,
++                      acpi_ut_get_node_name (new_scope_info->scope.node),
+                       acpi_ut_get_type_name (new_scope_info->common.value)));
+       }
+       else {
+--- linux-2.6.0/drivers/acpi/events/evgpeblk.c 2003-06-22 12:04:44.000000000 -0700
++++ 25/drivers/acpi/events/evgpeblk.c  2003-12-28 23:21:33.000000000 -0800
+@@ -477,7 +477,7 @@ unlock_and_exit:
+  *
+  * RETURN:      Status
+  *
+- * DESCRIPTION: Install new GPE block with mutex support
++ * DESCRIPTION: Remove a GPE block
+  *
+  ******************************************************************************/
+@@ -743,8 +743,7 @@ acpi_ev_create_gpe_block (
+                               ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
+               gpe_device->name.ascii,
+               gpe_block->register_count,
+-              ACPI_HIDWORD (gpe_block->block_address.address),
+-              ACPI_LODWORD (gpe_block->block_address.address),
++              ACPI_FORMAT_UINT64 (gpe_block->block_address.address),
+               interrupt_level));
+       /* Find all GPE methods (_Lxx, _Exx) for this block */
+--- linux-2.6.0/drivers/acpi/events/evgpe.c    2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/acpi/events/evgpe.c     2003-12-28 23:21:33.000000000 -0800
+@@ -139,12 +139,10 @@ acpi_ev_gpe_detect (
+ {
+       u32                             int_status = ACPI_INTERRUPT_NOT_HANDLED;
+       u8                              enabled_status_byte;
+-      u8                              bit_mask;
+       struct acpi_gpe_register_info   *gpe_register_info;
+       u32                             in_value;
+       acpi_status                     status;
+       struct acpi_gpe_block_info      *gpe_block;
+-      u32                             gpe_number;
+       u32                             i;
+       u32                             j;
+@@ -187,11 +185,9 @@ acpi_ev_gpe_detect (
+                       ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
+                               "GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n",
+-                              ACPI_HIDWORD (gpe_register_info->status_address.address),
+-                              ACPI_LODWORD (gpe_register_info->status_address.address),
++                              ACPI_FORMAT_UINT64 (gpe_register_info->status_address.address),
+                               gpe_register_info->status,
+-                              ACPI_HIDWORD (gpe_register_info->enable_address.address),
+-                              ACPI_LODWORD (gpe_register_info->enable_address.address),
++                              ACPI_FORMAT_UINT64 (gpe_register_info->enable_address.address),
+                               gpe_register_info->enable));
+                       /* First check if there is anything active at all in this register */
+@@ -206,19 +202,17 @@ acpi_ev_gpe_detect (
+                       /* Now look at the individual GPEs in this byte register */
+-                      for (j = 0, bit_mask = 1; j < ACPI_GPE_REGISTER_WIDTH; j++, bit_mask <<= 1) {
++                      for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
+                               /* Examine one GPE bit */
+-                              if (enabled_status_byte & bit_mask) {
++                              if (enabled_status_byte & acpi_gbl_decode_to8bit[j]) {
+                                       /*
+                                        * Found an active GPE. Dispatch the event to a handler
+                                        * or method.
+                                        */
+-                                      gpe_number = (i * ACPI_GPE_REGISTER_WIDTH) + j;
+-
+                                       int_status |= acpi_ev_gpe_dispatch (
+-                                                      &gpe_block->event_info[gpe_number],
+-                                                      j + gpe_register_info->base_gpe_number);
++                                                        &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j],
++                                                        j + gpe_register_info->base_gpe_number);
+                               }
+                       }
+               }
+@@ -294,7 +288,7 @@ acpi_ev_asynch_execute_gpe_method (
+               if (ACPI_FAILURE (status)) {
+                       ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n",
+                               acpi_format_exception (status),
+-                              local_gpe_event_info.method_node->name.ascii, gpe_number));
++                              acpi_ut_get_node_name (local_gpe_event_info.method_node), gpe_number));
+               }
+       }
+@@ -367,6 +361,18 @@ acpi_ev_gpe_dispatch (
+               /* Invoke the installed handler (at interrupt level) */
+               gpe_event_info->handler (gpe_event_info->context);
++
++              /* It is now safe to clear level-triggered events. */
++
++              if (gpe_event_info->flags & ACPI_EVENT_LEVEL_TRIGGERED) {
++                      status = acpi_hw_clear_gpe (gpe_event_info);
++                      if (ACPI_FAILURE (status)) {
++                              ACPI_REPORT_ERROR ((
++                                      "acpi_ev_gpe_dispatch: Unable to clear GPE[%2X]\n",
++                                      gpe_number));
++                              return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
++                      }
++              }
+       }
+       else if (gpe_event_info->method_node) {
+               /*
+@@ -375,13 +381,16 @@ acpi_ev_gpe_dispatch (
+                */
+               status = acpi_hw_disable_gpe (gpe_event_info);
+               if (ACPI_FAILURE (status)) {
+-                      ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
++                      ACPI_REPORT_ERROR ((
++                              "acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
+                               gpe_number));
+                       return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+               }
+-              /* Execute the method associated with the GPE. */
+-
++              /*
++               * Execute the method associated with the GPE
++               * NOTE: Level-triggered GPEs are cleared after the method completes.
++               */
+               if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
+                                acpi_ev_asynch_execute_gpe_method,
+                                gpe_event_info))) {
+@@ -399,22 +408,12 @@ acpi_ev_gpe_dispatch (
+               /*
+                * Disable the GPE.  The GPE will remain disabled until the ACPI
+-               * Core Subsystem is restarted, or the handler is reinstalled.
++               * Core Subsystem is restarted, or a handler is installed.
+                */
+               status = acpi_hw_disable_gpe (gpe_event_info);
+               if (ACPI_FAILURE (status)) {
+-                      ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
+-                              gpe_number));
+-                      return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+-              }
+-      }
+-
+-      /* It is now safe to clear level-triggered events. */
+-
+-      if (gpe_event_info->flags & ACPI_EVENT_LEVEL_TRIGGERED) {
+-              status = acpi_hw_clear_gpe (gpe_event_info);
+-              if (ACPI_FAILURE (status)) {
+-                      ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2X]\n",
++                      ACPI_REPORT_ERROR ((
++                              "acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
+                               gpe_number));
+                       return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+               }
+--- linux-2.6.0/drivers/acpi/events/evmisc.c   2003-06-14 12:18:23.000000000 -0700
++++ 25/drivers/acpi/events/evmisc.c    2003-12-28 23:21:33.000000000 -0800
+@@ -195,7 +195,8 @@ acpi_ev_queue_notify_request (
+               /* There is no per-device notify handler for this device */
+               ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+-                      "No notify handler for [%4.4s] node %p\n", node->name.ascii, node));
++                      "No notify handler for [%4.4s] node %p\n",
++                      acpi_ut_get_node_name (node), node));
+       }
+       return (status);
+--- linux-2.6.0/drivers/acpi/events/evregion.c 2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/acpi/events/evregion.c  2003-12-28 23:21:33.000000000 -0800
+@@ -136,7 +136,7 @@ acpi_ev_init_address_spaces (
+  *
+  ******************************************************************************/
+-static acpi_status
++acpi_status
+ acpi_ev_execute_reg_method (
+       union acpi_operand_object      *region_obj,
+       u32                             function)
+@@ -202,7 +202,7 @@ cleanup:
+  *
+  * FUNCTION:    acpi_ev_address_space_dispatch
+  *
+- * PARAMETERS:  region_obj          - internal region object
++ * PARAMETERS:  region_obj          - Internal region object
+  *              space_id            - ID of the address space (0-255)
+  *              Function            - Read or Write operation
+  *              Address             - Where in the space to read or write
+@@ -243,9 +243,11 @@ acpi_ev_address_space_dispatch (
+       /* Ensure that there is a handler associated with this region */
+-      handler_desc = region_obj->region.address_space;
++      handler_desc = region_obj->region.handler;
+       if (!handler_desc) {
+-              ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n",
++              ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
++                      "No handler for Region [%4.4s] (%p) [%s]\n",
++                      acpi_ut_get_node_name (region_obj->region.node),
+                       region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
+               return_ACPI_STATUS (AE_NOT_EXIST);
+@@ -320,8 +322,8 @@ acpi_ev_address_space_dispatch (
+       ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+               "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
+-              &region_obj->region.address_space->address_space, handler,
+-              ACPI_HIDWORD (address), ACPI_LODWORD (address),
++              &region_obj->region.handler->address_space, handler,
++              ACPI_FORMAT_UINT64 (address),
+               acpi_ut_get_region_name (region_obj->region.space_id)));
+       if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+@@ -359,6 +361,7 @@ acpi_ev_address_space_dispatch (
+       return_ACPI_STATUS (status);
+ }
++
+ /*******************************************************************************
+  *
+  * FUNCTION:    acpi_ev_detach_region
+@@ -398,7 +401,7 @@ acpi_ev_detach_region(
+       /* Get the address handler from the region object */
+-      handler_obj = region_obj->region.address_space;
++      handler_obj = region_obj->region.handler;
+       if (!handler_obj) {
+               /* This region has no handler, all done */
+@@ -472,7 +475,7 @@ acpi_ev_detach_region(
+                        * If the region is on the handler's list
+                        * this better be the region's handler
+                        */
+-                      region_obj->region.address_space = NULL;
++                      region_obj->region.handler = NULL;
+                       acpi_ut_remove_reference (handler_obj);
+                       return_VOID;
+@@ -515,17 +518,15 @@ acpi_ev_attach_region (
+       union acpi_operand_object       *region_obj,
+       u8                              acpi_ns_is_locked)
+ {
+-      acpi_status                     status;
+-      acpi_status                     status2;
+-
+       ACPI_FUNCTION_TRACE ("ev_attach_region");
+       ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+-              "Adding Region %p to address handler %p [%s]\n",
+-              region_obj, handler_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
+-
++              "Adding Region [%4.4s] %p to address handler %p [%s]\n",
++              acpi_ut_get_node_name (region_obj->region.node),
++              region_obj, handler_obj,
++              acpi_ut_get_region_name (region_obj->region.space_id)));
+       /* Link this region to the front of the handler's list */
+@@ -534,34 +535,14 @@ acpi_ev_attach_region (
+       /* Install the region's handler */
+-      if (region_obj->region.address_space) {
++      if (region_obj->region.handler) {
+               return_ACPI_STATUS (AE_ALREADY_EXISTS);
+       }
+-      region_obj->region.address_space = handler_obj;
++      region_obj->region.handler = handler_obj;
+       acpi_ut_add_reference (handler_obj);
+-      /*
+-       * Tell all users that this region is usable by running the _REG
+-       * method
+-       */
+-      if (acpi_ns_is_locked) {
+-              status2 = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+-              if (ACPI_FAILURE (status2)) {
+-                      return_ACPI_STATUS (status2);
+-              }
+-      }
+-
+-      status = acpi_ev_execute_reg_method (region_obj, 1);
+-
+-      if (acpi_ns_is_locked) {
+-              status2 = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+-              if (ACPI_FAILURE (status2)) {
+-                      return_ACPI_STATUS (status2);
+-              }
+-      }
+-
+-      return_ACPI_STATUS (status);
++      return_ACPI_STATUS (AE_OK);
+ }
+@@ -569,9 +550,7 @@ acpi_ev_attach_region (
+  *
+  * FUNCTION:    acpi_ev_install_handler
+  *
+- * PARAMETERS:  Handle              - Node to be dumped
+- *              Level               - Nesting level of the handle
+- *              Context             - Passed into acpi_ns_walk_namespace
++ * PARAMETERS:  walk_namespace callback
+  *
+  * DESCRIPTION: This routine installs an address handler into objects that are
+  *              of type Region or Device.
+@@ -640,7 +619,7 @@ acpi_ev_install_handler (
+       if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) {
+               /* Check if this Device already has a handler for this address space */
+-              next_handler_obj = obj_desc->device.address_space;
++              next_handler_obj = obj_desc->device.handler;
+               while (next_handler_obj) {
+                       /* Found a handler, is it for the same address space? */
+@@ -697,4 +676,77 @@ acpi_ev_install_handler (
+       return (status);
+ }
++/*******************************************************************************
++ *
++ * FUNCTION:    acpi_ev_reg_run
++ *
++ * PARAMETERS:  walk_namespace callback
++ *
++ * DESCRIPTION: Run _REg method for region objects of the requested space_iD
++ *
++ ******************************************************************************/
++
++acpi_status
++acpi_ev_reg_run (
++      acpi_handle                     obj_handle,
++      u32                             level,
++      void                            *context,
++      void                            **return_value)
++{
++      union acpi_operand_object       *handler_obj;
++      union acpi_operand_object       *obj_desc;
++      struct acpi_namespace_node      *node;
++      acpi_status                     status;
++
++
++      ACPI_FUNCTION_NAME ("ev_reg_run");
++
++
++      handler_obj = (union acpi_operand_object   *) context;
++
++      /* Parameter validation */
++
++      if (!handler_obj) {
++              return (AE_OK);
++      }
++
++      /* Convert and validate the device handle */
++
++      node = acpi_ns_map_handle_to_node (obj_handle);
++      if (!node) {
++              return (AE_BAD_PARAMETER);
++      }
++
++      /*
++       * We only care about regions.and objects
++       * that are allowed to have address space handlers
++       */
++      if ((node->type != ACPI_TYPE_REGION) &&
++              (node != acpi_gbl_root_node)) {
++              return (AE_OK);
++      }
++
++      /* Check for an existing internal object */
++
++      obj_desc = acpi_ns_get_attached_object (node);
++      if (!obj_desc) {
++              /* No object, just exit */
++
++              return (AE_OK);
++      }
++
++
++      /* Object is a Region */
++
++      if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
++              /*
++               * This region is for a different address space
++               * -- just ignore it
++               */
++              return (AE_OK);
++      }
++
++      status = acpi_ev_execute_reg_method (obj_desc, 1);
++      return (status);
++}
+--- linux-2.6.0/drivers/acpi/events/evrgnini.c 2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/acpi/events/evrgnini.c  2003-12-28 23:21:33.000000000 -0800
+@@ -177,7 +177,7 @@ acpi_ev_pci_config_region_setup (
+       ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup");
+-      handler_obj = region_obj->region.address_space;
++      handler_obj = region_obj->region.handler;
+       if (!handler_obj) {
+               /*
+                * No installed handler. This shouldn't happen because the dispatch
+@@ -239,7 +239,7 @@ acpi_ev_pci_config_region_setup (
+                                               else {
+                                                       ACPI_REPORT_ERROR ((
+                                                               "Could not install pci_config handler for Root Bridge %4.4s, %s\n",
+-                                                              pci_root_node->name.ascii, acpi_format_exception (status)));
++                                                              acpi_ut_get_node_name (pci_root_node), acpi_format_exception (status)));
+                                               }
+                                       }
+                                       break;
+@@ -469,7 +469,7 @@ acpi_ev_initialize_region (
+       /* Setup defaults */
+-      region_obj->region.address_space = NULL;
++      region_obj->region.handler = NULL;
+       region_obj2->extra.method_REG = NULL;
+       region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
+       region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
+@@ -502,17 +502,17 @@ acpi_ev_initialize_region (
+                       switch (node->type) {
+                       case ACPI_TYPE_DEVICE:
+-                              handler_obj = obj_desc->device.address_space;
++                              handler_obj = obj_desc->device.handler;
+                               break;
+                       case ACPI_TYPE_PROCESSOR:
+-                              handler_obj = obj_desc->processor.address_space;
++                              handler_obj = obj_desc->processor.handler;
+                               break;
+                       case ACPI_TYPE_THERMAL:
+-                              handler_obj = obj_desc->thermal_zone.address_space;
++                              handler_obj = obj_desc->thermal_zone.handler;
+                               break;
+                       default:
+@@ -533,6 +533,26 @@ acpi_ev_initialize_region (
+                                       status = acpi_ev_attach_region (handler_obj, region_obj,
+                                                        acpi_ns_locked);
++                                      /*
++                                       * Tell all users that this region is usable by running the _REG
++                                       * method
++                                       */
++                                      if (acpi_ns_locked) {
++                                              status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
++                                              if (ACPI_FAILURE (status)) {
++                                                      return_ACPI_STATUS (status);
++                                              }
++                                      }
++
++                                      status = acpi_ev_execute_reg_method (region_obj, 1);
++
++                                      if (acpi_ns_locked) {
++                                              status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
++                                              if (ACPI_FAILURE (status)) {
++                                                      return_ACPI_STATUS (status);
++                                              }
++                                      }
++
+                                       return_ACPI_STATUS (AE_OK);
+                               }
+--- linux-2.6.0/drivers/acpi/events/evxfregn.c 2003-06-14 12:17:59.000000000 -0700
++++ 25/drivers/acpi/events/evxfregn.c  2003-12-28 23:21:33.000000000 -0800
+@@ -173,7 +173,7 @@ acpi_install_address_space_handler (
+                * The attached device object already exists.
+                * Make sure the handler is not already installed.
+                */
+-              handler_obj = obj_desc->device.address_space;
++              handler_obj = obj_desc->device.handler;
+               /* Walk the handler list for this device */
+@@ -240,7 +240,8 @@ acpi_install_address_space_handler (
+       ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+               "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
+-              acpi_ut_get_region_name (space_id), space_id, node->name.ascii, node, obj_desc));
++              acpi_ut_get_region_name (space_id), space_id,
++              acpi_ut_get_node_name (node), node, obj_desc));
+       /*
+        * Install the handler
+@@ -267,13 +268,13 @@ acpi_install_address_space_handler (
+       /* Install at head of Device.address_space list */
+-      handler_obj->address_space.next      = obj_desc->device.address_space;
++      handler_obj->address_space.next      = obj_desc->device.handler;
+       /*
+        * The Device object is the first reference on the handler_obj.
+        * Each region that uses the handler adds a reference.
+        */
+-      obj_desc->device.address_space = handler_obj;
++      obj_desc->device.handler = handler_obj;
+       /*
+        * Walk the namespace finding all of the regions this
+@@ -291,6 +292,17 @@ acpi_install_address_space_handler (
+                         ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
+                         handler_obj, NULL);
++      /*
++       * Now we can run the _REG methods for all Regions for this
++       * space ID.  This is a separate walk in order to handle any
++       * interdependencies between regions and _REG methods.  (i.e. handlers
++       * must be installed for all regions of this Space ID before we
++       * can run any _REG methods.
++       */
++      status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX,
++                        ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
++                        handler_obj, NULL);
++
+ unlock_and_exit:
+       (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+       return_ACPI_STATUS (status);
+@@ -357,8 +369,8 @@ acpi_remove_address_space_handler (
+       /* Find the address handler the user requested */
+-      handler_obj = obj_desc->device.address_space;
+-      last_obj_ptr = &obj_desc->device.address_space;
++      handler_obj = obj_desc->device.handler;
++      last_obj_ptr = &obj_desc->device.handler;
+       while (handler_obj) {
+               /* We have a handler, see if user requested this one */
+--- linux-2.6.0/drivers/acpi/executer/exdump.c 2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/acpi/executer/exdump.c  2003-12-28 23:21:33.000000000 -0800
+@@ -89,27 +89,27 @@ acpi_ex_dump_operand (
+       if (!obj_desc) {
+               /*
+-               * This usually indicates that something serious is wrong --
+-               * since most (if not all)
+-               * code that dumps the stack expects something to be there!
++               * This usually indicates that something serious is wrong
+                */
+-              acpi_os_printf ("Null stack entry ptr\n");
++              acpi_os_printf ("Null Object Descriptor\n");
+               return;
+       }
+       if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
+-              ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p NS Node: ", obj_desc));
++              ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p is a NS Node: ", obj_desc));
+               ACPI_DUMP_ENTRY (obj_desc, ACPI_LV_EXEC);
+               return;
+       }
+       if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+-              ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p is not a local object\n", obj_desc));
++              ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
++                              "%p is not a node or operand object: [%s]\n",
++                              obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
+               ACPI_DUMP_BUFFER (obj_desc, sizeof (union acpi_operand_object));
+               return;
+       }
+-      /*  obj_desc is a valid object */
++      /* obj_desc is a valid object */
+       ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc));
+@@ -151,11 +151,10 @@ acpi_ex_dump_operand (
+                                        obj_desc->reference.offset);
+                       if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+-                              /* Value is a Number */
++                              /* Value is an Integer */
+                               acpi_os_printf (" value is [%8.8X%8.8x]",
+-                                               ACPI_HIDWORD(obj_desc->integer.value),
+-                                               ACPI_LODWORD(obj_desc->integer.value));
++                                               ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+                       }
+                       acpi_os_printf ("\n");
+@@ -169,11 +168,10 @@ acpi_ex_dump_operand (
+                       if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
+-                              /* Value is a Number */
++                              /* Value is an Integer */
+                               acpi_os_printf (" value is [%8.8X%8.8x]",
+-                                               ACPI_HIDWORD(obj_desc->integer.value),
+-                                               ACPI_LODWORD(obj_desc->integer.value));
++                                               ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+                       }
+                       acpi_os_printf ("\n");
+@@ -189,7 +187,7 @@ acpi_ex_dump_operand (
+               default:
+-                      /*  unknown opcode  */
++                      /* Unknown opcode */
+                       acpi_os_printf ("Unknown Reference opcode=%X\n",
+                               obj_desc->reference.opcode);
+@@ -229,8 +227,7 @@ acpi_ex_dump_operand (
+       case ACPI_TYPE_INTEGER:
+               acpi_os_printf ("Integer %8.8X%8.8X\n",
+-                               ACPI_HIDWORD (obj_desc->integer.value),
+-                               ACPI_LODWORD (obj_desc->integer.value));
++                               ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+               break;
+@@ -271,8 +268,7 @@ acpi_ex_dump_operand (
+               }
+               else {
+                       acpi_os_printf (" base %8.8X%8.8X Length %X\n",
+-                              ACPI_HIDWORD (obj_desc->region.address),
+-                              ACPI_LODWORD (obj_desc->region.address),
++                              ACPI_FORMAT_UINT64 (obj_desc->region.address),
+                               obj_desc->region.length);
+               }
+               break;
+@@ -494,7 +490,7 @@ acpi_ex_out_address (
+       acpi_os_printf ("%20s : %p\n", title, value);
+ #else
+       acpi_os_printf ("%20s : %8.8X%8.8X\n", title,
+-                       ACPI_HIDWORD (value), ACPI_LODWORD (value));
++                       ACPI_FORMAT_UINT64 (value));
+ #endif
+ }
+@@ -525,7 +521,7 @@ acpi_ex_dump_node (
+               }
+       }
+-      acpi_os_printf ("%20s : %4.4s\n",     "Name", node->name.ascii);
++      acpi_os_printf ("%20s : %4.4s\n",     "Name", acpi_ut_get_node_name (node));
+       acpi_ex_out_string ("Type",           acpi_ut_get_type_name (node->type));
+       acpi_ex_out_integer ("Flags",         node->flags);
+       acpi_ex_out_integer ("Owner Id",      node->owner_id);
+@@ -573,7 +569,8 @@ acpi_ex_dump_object_descriptor (
+       }
+       if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
+-              acpi_os_printf ("ex_dump_object_descriptor: %p is not a valid ACPI object\n", obj_desc);
++              acpi_os_printf ("ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n",
++                              obj_desc, acpi_ut_get_descriptor_name (obj_desc));
+               return_VOID;
+       }
+@@ -589,8 +586,7 @@ acpi_ex_dump_object_descriptor (
+       case ACPI_TYPE_INTEGER:
+               acpi_os_printf ("%20s : %8.8X%8.8X\n", "Value",
+-                                ACPI_HIDWORD (obj_desc->integer.value),
+-                                ACPI_LODWORD (obj_desc->integer.value));
++                              ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+               break;
+@@ -635,7 +631,7 @@ acpi_ex_dump_object_descriptor (
+       case ACPI_TYPE_DEVICE:
+-              acpi_ex_out_pointer ("address_space", obj_desc->device.address_space);
++              acpi_ex_out_pointer ("Handler",     obj_desc->device.handler);
+               acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify);
+               acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify);
+               break;
+@@ -673,7 +669,7 @@ acpi_ex_dump_object_descriptor (
+               acpi_ex_out_integer ("Flags",        obj_desc->region.flags);
+               acpi_ex_out_address ("Address",      obj_desc->region.address);
+               acpi_ex_out_integer ("Length",       obj_desc->region.length);
+-              acpi_ex_out_pointer ("address_space", obj_desc->region.address_space);
++              acpi_ex_out_pointer ("Handler",      obj_desc->region.handler);
+               acpi_ex_out_pointer ("Next",         obj_desc->region.next);
+               break;
+@@ -694,7 +690,7 @@ acpi_ex_dump_object_descriptor (
+               acpi_ex_out_address ("Address",      (acpi_physical_address) obj_desc->processor.address);
+               acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify);
+               acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify);
+-              acpi_ex_out_pointer ("address_space", obj_desc->processor.address_space);
++              acpi_ex_out_pointer ("Handler",      obj_desc->processor.handler);
+               break;
+@@ -702,7 +698,7 @@ acpi_ex_dump_object_descriptor (
+               acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify);
+               acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify);
+-              acpi_ex_out_pointer ("address_space", obj_desc->thermal_zone.address_space);
++              acpi_ex_out_pointer ("Handler",      obj_desc->thermal_zone.handler);
+               break;
+--- linux-2.6.0/drivers/acpi/executer/exfldio.c        2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/acpi/executer/exfldio.c 2003-12-28 23:21:33.000000000 -0800
+@@ -138,8 +138,9 @@ acpi_ex_setup_region (
+                        */
+                       ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+                               "Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n",
+-                              obj_desc->common_field.node->name.ascii, obj_desc->common_field.access_byte_width,
+-                              rgn_desc->region.node->name.ascii, rgn_desc->region.length));
++                              acpi_ut_get_node_name (obj_desc->common_field.node),
++                              obj_desc->common_field.access_byte_width,
++                              acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
+               }
+               /*
+@@ -148,9 +149,10 @@ acpi_ex_setup_region (
+                */
+               ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+                       "Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n",
+-                      obj_desc->common_field.node->name.ascii, obj_desc->common_field.base_byte_offset,
++                      acpi_ut_get_node_name (obj_desc->common_field.node),
++                      obj_desc->common_field.base_byte_offset,
+                       field_datum_byte_offset, obj_desc->common_field.access_byte_width,
+-                      rgn_desc->region.node->name.ascii, rgn_desc->region.length));
++                      acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
+               #ifdef CONFIG_ACPI_RELAXED_AML
+               {
+@@ -261,7 +263,7 @@ acpi_ex_access_region (
+               obj_desc->common_field.access_byte_width,
+               obj_desc->common_field.base_byte_offset,
+               field_datum_byte_offset,
+-              ACPI_HIDWORD (address), ACPI_LODWORD (address)));
++              ACPI_FORMAT_UINT64 (address)));
+       /* Invoke the appropriate address_space/op_region handler */
+@@ -514,12 +516,12 @@ acpi_ex_field_datum_io (
+       if (ACPI_SUCCESS (status)) {
+               if (read_write == ACPI_READ) {
+                       ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n",
+-                                         ACPI_HIDWORD (*value), ACPI_LODWORD (*value),
++                                         ACPI_FORMAT_UINT64 (*value),
+                                          obj_desc->common_field.access_byte_width));
+               }
+               else {
+                       ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n",
+-                                         ACPI_HIDWORD (*value), ACPI_LODWORD (*value),
++                                         ACPI_FORMAT_UINT64 (*value),
+                                          obj_desc->common_field.access_byte_width));
+               }
+       }
+@@ -612,11 +614,11 @@ acpi_ex_write_with_update_rule (
+       ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+               "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n",
+-              ACPI_HIDWORD (mask), ACPI_LODWORD (mask),
++              ACPI_FORMAT_UINT64 (mask),
+               field_datum_byte_offset,
+               obj_desc->common_field.access_byte_width,
+-              ACPI_HIDWORD (field_value), ACPI_LODWORD (field_value),
+-              ACPI_HIDWORD (merged_value),ACPI_LODWORD (merged_value)));
++              ACPI_FORMAT_UINT64 (field_value),
++              ACPI_FORMAT_UINT64 (merged_value)));
+       /* Write the merged value */
+@@ -784,12 +786,13 @@ acpi_ex_extract_from_field (
+ {
+       acpi_status                     status;
+       u32                             field_datum_byte_offset;
+-      u32                             datum_offset;
+-      acpi_integer                    previous_raw_datum;
++      u32                             buffer_datum_offset;
++      acpi_integer                    previous_raw_datum = 0;
+       acpi_integer                    this_raw_datum = 0;
+       acpi_integer                    merged_datum = 0;
+       u32                             byte_field_length;
+       u32                             datum_count;
++      u32                             i;
+       ACPI_FUNCTION_TRACE ("ex_extract_from_field");
+@@ -812,77 +815,74 @@ acpi_ex_extract_from_field (
+       datum_count = ACPI_ROUND_UP_TO (byte_field_length,
+                          obj_desc->common_field.access_byte_width);
++      /*
++       * If the field is not aligned on a datum boundary and does not
++       * fit within a single datum, we must read an extra datum.
++       *
++       * We could just split the aligned and non-aligned cases since the
++       * aligned case is so very simple, but this would require more code.
++       */
++      if ((obj_desc->common_field.end_field_valid_bits != 0)    &&
++              (!(obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM))) {
++              datum_count++;
++      }
++
+       ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+               "byte_len %X, datum_len %X, byte_gran %X\n",
+               byte_field_length, datum_count,obj_desc->common_field.access_byte_width));
+       /*
+        * Clear the caller's buffer (the whole buffer length as given)
+-       * This is very important, especially in the cases where a byte is read,
+-       * but the buffer is really a u32 (4 bytes).
++       * This is very important, especially in the cases where the buffer
++       * is longer than the size of the field.
+        */
+       ACPI_MEMSET (buffer, 0, buffer_length);
+-      /* Read the first raw datum to prime the loop */
+-
+       field_datum_byte_offset = 0;
+-      datum_offset= 0;
+-
+-      status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
+-                        &previous_raw_datum, ACPI_READ);
+-      if (ACPI_FAILURE (status)) {
+-              return_ACPI_STATUS (status);
+-      }
+-
++      buffer_datum_offset= 0;
+-      /* We might actually be done if the request fits in one datum */
++      /* Read the entire field */
+-      if ((datum_count == 1) &&
+-              (obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM)) {
+-              /* 1) Shift the valid data bits down to start at bit 0 */
++      for (i = 0; i < datum_count; i++) {
++              status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
++                                &this_raw_datum, ACPI_READ);
++              if (ACPI_FAILURE (status)) {
++                      return_ACPI_STATUS (status);
++              }
+-              merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset);
++              /* We might actually be done if the request fits in one datum */
+-              /* 2) Mask off any upper unused bits (bits not part of the field) */
++              if ((datum_count == 1) &&
++                      (obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM)) {
++                      /* 1) Shift the valid data bits down to start at bit 0 */
+-              if (obj_desc->common_field.end_buffer_valid_bits) {
+-                      merged_datum &= ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits);
+-              }
++                      merged_datum = (this_raw_datum >> obj_desc->common_field.start_field_bit_offset);
+-              /* Store the datum to the caller buffer */
++                      /* 2) Mask off any upper unused bits (bits not part of the field) */
+-              acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
+-                              obj_desc->common_field.access_byte_width, datum_offset);
++                      if (obj_desc->common_field.end_buffer_valid_bits) {
++                              merged_datum &= ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits);
++                      }
+-              return_ACPI_STATUS (AE_OK);
+-      }
++                      /* Store the datum to the caller buffer */
++                      acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
++                                      obj_desc->common_field.access_byte_width, buffer_datum_offset);
+-      /* We need to get more raw data to complete one or more field data */
++                      return_ACPI_STATUS (AE_OK);
++              }
+-      while (datum_offset < datum_count) {
+-              field_datum_byte_offset += obj_desc->common_field.access_byte_width;
++              /* Special handling for the last datum to ignore extra bits */
+-              /*
+-               * If the field is aligned on a byte boundary, we don't want
+-               * to perform a final read, since this would potentially read
+-               * past the end of the region.
+-               *
+-               * We could just split the aligned and non-aligned cases since the
+-               * aligned case is so very simple, but this would require more code.
+-               */
+-              if ((obj_desc->common_field.start_field_bit_offset != 0) ||
+-                      ((obj_desc->common_field.start_field_bit_offset == 0) &&
+-                      (datum_offset < (datum_count -1)))) {
++              if ((i >= (datum_count -1))          &&
++                      (obj_desc->common_field.end_field_valid_bits)) {
+                       /*
+-                       * Get the next raw datum, it contains some or all bits
+-                       * of the current field datum
++                       * This is the last iteration of the loop.  We need to clear
++                       * any unused bits (bits that are not part of this field) before
++                       * we store the final merged datum into the caller buffer.
+                        */
+-                      status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
+-                                        &this_raw_datum, ACPI_READ);
+-                      if (ACPI_FAILURE (status)) {
+-                              return_ACPI_STATUS (status);
+-                      }
++                      this_raw_datum &=
++                              ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits);
+               }
+               /*
+@@ -891,48 +891,48 @@ acpi_ex_extract_from_field (
+               if (obj_desc->common_field.start_field_bit_offset == 0) {
+                       /* Field is not skewed and we can just copy the datum */
+-                      merged_datum = previous_raw_datum;
++                      acpi_ex_set_buffer_datum (this_raw_datum, buffer, buffer_length,
++                                      obj_desc->common_field.access_byte_width, buffer_datum_offset);
++                      buffer_datum_offset++;
+               }
+               else {
+-                      /*
+-                       * Put together the appropriate bits of the two raw data to make a
+-                       * single complete field datum
+-                       *
+-                       * 1) Normalize the first datum down to bit 0
+-                       */
+-                      merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset);
+-
+-                      /* 2) Insert the second datum "above" the first datum */
++                      /* Not aligned -- on the first iteration, just save the datum */
+-                      merged_datum |= (this_raw_datum << obj_desc->common_field.datum_valid_bits);
+-
+-                      if ((datum_offset >= (datum_count -1))) {
++                      if (i != 0) {
+                               /*
+-                               * This is the last iteration of the loop.  We need to clear
+-                               * any unused bits (bits that are not part of this field) that
+-                               * came from the last raw datum before we store the final
+-                               * merged datum into the caller buffer.
++                               * Put together the appropriate bits of the two raw data to make a
++                               * single complete field datum
++                               *
++                               * 1) Normalize the first datum down to bit 0
+                                */
+-                              if (obj_desc->common_field.end_buffer_valid_bits) {
+-                                      merged_datum &=
+-                                              ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits);
+-                              }
++                              merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset);
++
++                              /* 2) Insert the second datum "above" the first datum */
++
++                              merged_datum |= (this_raw_datum << obj_desc->common_field.datum_valid_bits);
++
++                              acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
++                                              obj_desc->common_field.access_byte_width, buffer_datum_offset);
++                              buffer_datum_offset++;
+                       }
++
++                      /*
++                       * Save the raw datum that was just acquired since it may contain bits
++                       * of the *next* field datum
++                       */
++                      previous_raw_datum = this_raw_datum;
+               }
+-              /*
+-               * Store the merged field datum in the caller's buffer, according to
+-               * the granularity of the field (size of each datum).
+-               */
+-              acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
+-                              obj_desc->common_field.access_byte_width, datum_offset);
++              field_datum_byte_offset += obj_desc->common_field.access_byte_width;
++      }
+-              /*
+-               * Save the raw datum that was just acquired since it may contain bits
+-               * of the *next* field datum.  Update offsets
+-               */
+-              previous_raw_datum = this_raw_datum;
+-              datum_offset++;
++      /* For non-aligned case, there is one last datum to insert */
++
++      if (obj_desc->common_field.start_field_bit_offset != 0) {
++              merged_datum = (this_raw_datum >> obj_desc->common_field.start_field_bit_offset);
++
++              acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
++                              obj_desc->common_field.access_byte_width, buffer_datum_offset);
+       }
+       return_ACPI_STATUS (AE_OK);
+--- linux-2.6.0/drivers/acpi/executer/exmisc.c 2003-06-14 12:18:30.000000000 -0700
++++ 25/drivers/acpi/executer/exmisc.c  2003-12-28 23:21:33.000000000 -0800
+@@ -121,8 +121,8 @@ acpi_ex_get_object_reference (
+       default:
+-              ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type %X in %p\n",
+-                      ACPI_GET_DESCRIPTOR_TYPE (obj_desc), obj_desc));
++              ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p has invalid descriptor [%s]\n",
++                              obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
+               return_ACPI_STATUS (AE_TYPE);
+       }
+@@ -139,7 +139,7 @@ acpi_ex_get_object_reference (
+       *return_desc = reference_obj;
+       ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p Type [%s], returning Reference %p\n",
+-              obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
++                      obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
+       return_ACPI_STATUS (AE_OK);
+ }
+--- linux-2.6.0/drivers/acpi/executer/exmutex.c        2003-06-14 12:18:30.000000000 -0700
++++ 25/drivers/acpi/executer/exmutex.c 2003-12-28 23:21:33.000000000 -0800
+@@ -159,7 +159,7 @@ acpi_ex_acquire_mutex (
+       if (!walk_state->thread) {
+               ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], null thread info\n",
+-                              obj_desc->mutex.node->name.ascii));
++                              acpi_ut_get_node_name (obj_desc->mutex.node)));
+               return_ACPI_STATUS (AE_AML_INTERNAL);
+       }
+@@ -169,7 +169,7 @@ acpi_ex_acquire_mutex (
+        */
+       if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
+               ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], incorrect sync_level\n",
+-                              obj_desc->mutex.node->name.ascii));
++                              acpi_ut_get_node_name (obj_desc->mutex.node)));
+               return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+       }
+@@ -242,7 +242,7 @@ acpi_ex_release_mutex (
+       if (!obj_desc->mutex.owner_thread) {
+               ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], not acquired\n",
+-                              obj_desc->mutex.node->name.ascii));
++                              acpi_ut_get_node_name (obj_desc->mutex.node)));
+               return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
+       }
+@@ -250,7 +250,7 @@ acpi_ex_release_mutex (
+       if (!walk_state->thread) {
+               ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], null thread info\n",
+-                              obj_desc->mutex.node->name.ascii));
++                              acpi_ut_get_node_name (obj_desc->mutex.node)));
+               return_ACPI_STATUS (AE_AML_INTERNAL);
+       }
+@@ -260,7 +260,7 @@ acpi_ex_release_mutex (
+               ACPI_REPORT_ERROR ((
+                       "Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n",
+                       walk_state->thread->thread_id,
+-                      obj_desc->mutex.node->name.ascii,
++                      acpi_ut_get_node_name (obj_desc->mutex.node),
+                       obj_desc->mutex.owner_thread->thread_id));
+               return_ACPI_STATUS (AE_AML_NOT_OWNER);
+       }
+@@ -271,7 +271,7 @@ acpi_ex_release_mutex (
+        */
+       if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
+               ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], incorrect sync_level\n",
+-                              obj_desc->mutex.node->name.ascii));
++                              acpi_ut_get_node_name (obj_desc->mutex.node)));
+               return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
+       }
+--- linux-2.6.0/drivers/acpi/executer/exoparg1.c       2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/acpi/executer/exoparg1.c        2003-12-28 23:21:33.000000000 -0800
+@@ -351,8 +351,7 @@ acpi_ex_opcode_1A_1T_1R (
+                       if (digit > 0) {
+                               ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Integer too large to convert to BCD: %8.8X%8.8X\n",
+-                                      ACPI_HIDWORD(operand[0]->integer.value),
+-                                      ACPI_LODWORD(operand[0]->integer.value)));
++                                              ACPI_FORMAT_UINT64 (operand[0]->integer.value)));
+                               status = AE_AML_NUMERIC_OVERFLOW;
+                               goto cleanup;
+                       }
+--- linux-2.6.0/drivers/acpi/executer/exoparg3.c       2003-06-14 12:17:56.000000000 -0700
++++ 25/drivers/acpi/executer/exoparg3.c        2003-12-28 23:21:33.000000000 -0800
+@@ -101,15 +101,14 @@ acpi_ex_opcode_3A_0T_0R (
+       switch (walk_state->opcode) {
+-
+       case AML_FATAL_OP:          /* Fatal (fatal_type fatal_code fatal_arg)   */
+               ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+                       "fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
+-                      (u32) operand[0]->integer.value, (u32) operand[1]->integer.value,
++                      (u32) operand[0]->integer.value,
++                      (u32) operand[1]->integer.value,
+                       (u32) operand[2]->integer.value));
+-
+               fatal = ACPI_MEM_ALLOCATE (sizeof (struct acpi_signal_fatal_info));
+               if (fatal) {
+                       fatal->type     = (u32) operand[0]->integer.value;
+--- linux-2.6.0/drivers/acpi/executer/exprep.c 2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/acpi/executer/exprep.c  2003-12-28 23:21:33.000000000 -0800
+@@ -351,7 +351,7 @@ acpi_ex_prep_common_field_object (
+        */
+       nearest_byte_address =
+                       ACPI_ROUND_BITS_DOWN_TO_BYTES (field_bit_position);
+-      obj_desc->common_field.base_byte_offset =
++      obj_desc->common_field.base_byte_offset = (u32)
+                       ACPI_ROUND_DOWN (nearest_byte_address, byte_alignment);
+       /*
+@@ -539,7 +539,7 @@ acpi_ex_prep_field_value (
+                         acpi_ns_get_type (info->field_node));
+       ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set named_obj %p [%4.4s], obj_desc %p\n",
+-                      info->field_node, info->field_node->name.ascii, obj_desc));
++                      info->field_node, acpi_ut_get_node_name (info->field_node), obj_desc));
+       /* Remove local reference to the object */
+--- linux-2.6.0/drivers/acpi/executer/exregion.c       2003-06-14 12:17:58.000000000 -0700
++++ 25/drivers/acpi/executer/exregion.c        2003-12-28 23:21:33.000000000 -0800
+@@ -161,7 +161,7 @@ acpi_ex_system_memory_space_handler (
+                                 (void **) &mem_info->mapped_logical_address);
+               if (ACPI_FAILURE (status)) {
+                       ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X%8.8X, size %X\n",
+-                              ACPI_HIDWORD (address), ACPI_LODWORD (address), (u32) window_size));
++                                      ACPI_FORMAT_UINT64 (address), (u32) window_size));
+                       mem_info->mapped_length = 0;
+                       return_ACPI_STATUS (status);
+               }
+@@ -180,8 +180,8 @@ acpi_ex_system_memory_space_handler (
+                         ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address);
+       ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+-              "system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
+-              ACPI_HIDWORD (address), ACPI_LODWORD (address)));
++                      "system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
++                      ACPI_FORMAT_UINT64 (address)));
+    /*
+       * Perform the memory read or write
+@@ -290,8 +290,8 @@ acpi_ex_system_io_space_handler (
+       ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+-              "system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
+-              ACPI_HIDWORD (address), ACPI_LODWORD (address)));
++                      "system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
++                      ACPI_FORMAT_UINT64 (address)));
+       /* Decode the function parameter */
+--- linux-2.6.0/drivers/acpi/executer/exresolv.c       2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/acpi/executer/exresolv.c        2003-12-28 23:21:33.000000000 -0800
+@@ -349,6 +349,8 @@ acpi_ex_resolve_multiple (
+                       /* All "References" point to a NS node */
+                       if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
++                              ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
++                                              node, acpi_ut_get_descriptor_name (node)));
+                               return_ACPI_STATUS (AE_AML_INTERNAL);
+                       }
+@@ -399,7 +401,9 @@ acpi_ex_resolve_multiple (
+                       /* All "References" point to a NS node */
+                       if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
+-                              return_ACPI_STATUS (AE_AML_INTERNAL);
++                              ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
++                                              node, acpi_ut_get_descriptor_name (node)));
++                         return_ACPI_STATUS (AE_AML_INTERNAL);
+                       }
+                       /* Get the attached object */
+--- linux-2.6.0/drivers/acpi/executer/exresop.c        2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/acpi/executer/exresop.c 2003-12-28 23:21:33.000000000 -0800
+@@ -247,8 +247,8 @@ acpi_ex_resolve_operands (
+                       /* Invalid descriptor */
+                       ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+-                              "Bad descriptor type %X in Obj %p\n",
+-                              ACPI_GET_DESCRIPTOR_TYPE (obj_desc), obj_desc));
++                                      "Invalid descriptor %p [%s]\n",
++                                      obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
+                       return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+               }
+--- linux-2.6.0/drivers/acpi/executer/exstore.c        2003-06-22 12:04:44.000000000 -0700
++++ 25/drivers/acpi/executer/exstore.c 2003-12-28 23:21:33.000000000 -0800
+@@ -190,8 +190,7 @@ acpi_ex_store (
+               case ACPI_TYPE_INTEGER:
+                       ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%8.8X%8.8X\n",
+-                                      ACPI_HIDWORD (source_desc->integer.value),
+-                                      ACPI_LODWORD (source_desc->integer.value)));
++                                      ACPI_FORMAT_UINT64 (source_desc->integer.value)));
+                       break;
+--- linux-2.6.0/drivers/acpi/executer/exsystem.c       2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/acpi/executer/exsystem.c        2003-12-28 23:21:33.000000000 -0800
+@@ -111,11 +111,16 @@ acpi_ex_system_wait_semaphore (
+  *
+  * FUNCTION:    acpi_ex_system_do_stall
+  *
+- * PARAMETERS:  how_long            - The amount of time to stall
++ * PARAMETERS:  how_long            - The amount of time to stall,
++ *                                    in microseconds
+  *
+  * RETURN:      Status
+  *
+  * DESCRIPTION: Suspend running thread for specified amount of time.
++ *              Note: ACPI specification requires that Stall() does not
++ *              relinquish the processor, and delays longer than 100 usec
++ *              should use Sleep() instead.  We allow stalls up to 255 usec
++ *              for compatibility with other interpreters and existing BIOSs.
+  *
+  ******************************************************************************/
+@@ -129,12 +134,15 @@ acpi_ex_system_do_stall (
+       ACPI_FUNCTION_ENTRY ();
+-      if (how_long > 100) /* 100 microseconds */ {
++      if (how_long > 255) /* 255 microseconds */ {
+               /*
+-               * Longer than 100 usec, use sleep instead
+-               * (according to ACPI specification)
++               * Longer than 255 usec, this is an error
++               *
++               * (ACPI specifies 100 usec as max, but this gives some slack in
++               * order to support existing BIOSs)
+                */
+-              status = acpi_ex_system_do_suspend ((how_long / 1000) + 1);
++              ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n", how_long));
++              status = AE_AML_OPERAND_VALUE;
+       }
+       else {
+               acpi_os_stall (how_long);
+@@ -148,7 +156,8 @@ acpi_ex_system_do_stall (
+  *
+  * FUNCTION:    acpi_ex_system_do_suspend
+  *
+- * PARAMETERS:  how_long            - The amount of time to suspend
++ * PARAMETERS:  how_long            - The amount of time to suspend,
++ *                                    in milliseconds
+  *
+  * RETURN:      None
+  *
+--- linux-2.6.0/drivers/acpi/hardware/hwacpi.c 2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/acpi/hardware/hwacpi.c  2003-12-28 23:21:33.000000000 -0800
+@@ -119,7 +119,7 @@ acpi_hw_set_mode (
+        * system does not support mode transition.
+        */
+       if (!acpi_gbl_FADT->smi_cmd) {
+-              ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No SMI_CMD in FADT, mode transition failed.\n"));
++              ACPI_REPORT_ERROR (("No SMI_CMD in FADT, mode transition failed.\n"));
+               return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+       }
+@@ -131,7 +131,7 @@ acpi_hw_set_mode (
+        * transitions are not supported.
+        */
+       if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) {
+-              ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "No mode transition supported in this system.\n"));
++              ACPI_REPORT_ERROR (("No ACPI mode transition supported in this system (enable/disable both zero)\n"));
+               return_ACPI_STATUS (AE_OK);
+       }
+@@ -162,6 +162,7 @@ acpi_hw_set_mode (
+       }
+       if (ACPI_FAILURE (status)) {
++              ACPI_REPORT_ERROR (("Could not write mode change, %s\n", acpi_format_exception (status)));
+               return_ACPI_STATUS (status);
+       }
+@@ -171,18 +172,16 @@ acpi_hw_set_mode (
+        */
+       retry = 3000;
+       while (retry) {
+-              status = AE_NO_HARDWARE_RESPONSE;
+-
+               if (acpi_hw_get_mode() == mode) {
+                       ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", mode));
+-                      status = AE_OK;
+-                      break;
++                      return_ACPI_STATUS (AE_OK);
+               }
+               acpi_os_stall(1000);
+               retry--;
+       }
+-      return_ACPI_STATUS (status);
++      ACPI_REPORT_ERROR (("Hardware never changed modes\n"));
++      return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ }
+--- linux-2.6.0/drivers/acpi/hardware/hwregs.c 2003-07-27 12:14:38.000000000 -0700
++++ 25/drivers/acpi/hardware/hwregs.c  2003-12-28 23:21:33.000000000 -0800
+@@ -418,16 +418,14 @@ acpi_set_register (
+               ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n",
+                       register_value,
+-                      ACPI_HIDWORD (acpi_gbl_FADT->xpm2_cnt_blk.address),
+-                      ACPI_LODWORD (acpi_gbl_FADT->xpm2_cnt_blk.address)));
++                      ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address)));
+               ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position,
+                               bit_reg_info->access_bit_mask, value);
+               ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n",
+                       register_value,
+-                      ACPI_HIDWORD (acpi_gbl_FADT->xpm2_cnt_blk.address),
+-                      ACPI_LODWORD (acpi_gbl_FADT->xpm2_cnt_blk.address)));
++                      ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address)));
+               status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+                                  ACPI_REGISTER_PM2_CONTROL, (u8) (register_value));
+@@ -763,8 +761,7 @@ acpi_hw_low_level_read (
+       ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
+                       *value, width,
+-                      ACPI_HIDWORD (reg->address),
+-                      ACPI_LODWORD (reg->address),
++                      ACPI_FORMAT_UINT64 (reg->address),
+                       acpi_ut_get_region_name (reg->address_space_id)));
+       return (status);
+@@ -850,8 +847,7 @@ acpi_hw_low_level_write (
+       ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
+                       value, width,
+-                      ACPI_HIDWORD (reg->address),
+-                      ACPI_LODWORD (reg->address),
++                      ACPI_FORMAT_UINT64 (reg->address),
+                       acpi_ut_get_region_name (reg->address_space_id)));
+       return (status);
+--- linux-2.6.0/drivers/acpi/hardware/hwsleep.c        2003-06-22 12:04:44.000000000 -0700
++++ 25/drivers/acpi/hardware/hwsleep.c 2003-12-28 23:21:33.000000000 -0800
+@@ -181,6 +181,13 @@ acpi_enter_sleep_state_prep (
+               return_ACPI_STATUS (status);
+       }
++      /* Set the system indicators to show the desired sleep state. */
++
++      status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL);
++      if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
++               ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
++      }
++
+       return_ACPI_STATUS (AE_OK);
+ }
+@@ -220,27 +227,28 @@ acpi_enter_sleep_state (
+               return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
+       }
+-
+       sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
+       sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE);
+-      /* Clear wake status */
++      if (sleep_state != ACPI_STATE_S5) {
++              /* Clear wake status */
+-      status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+-      if (ACPI_FAILURE (status)) {
+-              return_ACPI_STATUS (status);
+-      }
++              status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
++              if (ACPI_FAILURE (status)) {
++                      return_ACPI_STATUS (status);
++              }
+-      status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK);
+-      if (ACPI_FAILURE (status)) {
+-              return_ACPI_STATUS (status);
+-      }
++              status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
++              if (ACPI_FAILURE (status)) {
++                      return_ACPI_STATUS (status);
++              }
+-      /* Disable BM arbitration */
++              /* Disable BM arbitration */
+-      status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
+-      if (ACPI_FAILURE (status)) {
+-              return_ACPI_STATUS (status);
++              status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
++              if (ACPI_FAILURE (status)) {
++                      return_ACPI_STATUS (status);
++              }
+       }
+       status = acpi_hw_disable_non_wakeup_gpes();
+@@ -297,11 +305,13 @@ acpi_enter_sleep_state (
+               return_ACPI_STATUS (status);
+       }
+-      /*
+-       * Wait a second, then try again. This is to get S4/5 to work on all machines.
+-       */
+       if (sleep_state > ACPI_STATE_S3) {
+               /*
++               * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that
++               * we are still executing!)
++               *
++               * Wait ten seconds, then try again. This is to get S4/S5 to work on all machines.
++               *
+                * We wait so long to allow chipsets that poll this reg very slowly to
+                * still read the right value. Ideally, this entire block would go
+                * away entirely.
+@@ -354,6 +364,7 @@ acpi_enter_sleep_state_s4bios (
+       ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios");
++
+       acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+       acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK);
+@@ -389,15 +400,38 @@ acpi_enter_sleep_state_s4bios (
+ acpi_status
+ acpi_leave_sleep_state (
+-      u8                          sleep_state)
++      u8                              sleep_state)
+ {
+-      struct acpi_object_list     arg_list;
+-      union acpi_object           arg;
+-      acpi_status                 status;
++      struct acpi_object_list         arg_list;
++      union acpi_object               arg;
++      acpi_status                     status;
++      struct acpi_bit_register_info   *sleep_type_reg_info;
++      struct acpi_bit_register_info   *sleep_enable_reg_info;
++      u32                             pm1x_control;
+       ACPI_FUNCTION_TRACE ("acpi_leave_sleep_state");
++      /* Some machines require SLP_TYPE and SLP_EN to be cleared */
++
++      sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
++      sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE);
++
++      /* Get current value of PM1A control */
++
++      status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
++                       ACPI_REGISTER_PM1_CONTROL, &pm1x_control);
++      if (ACPI_SUCCESS (status)) {
++              /* Clear SLP_TYP and SLP_EN */
++
++              pm1x_control &= ~(sleep_type_reg_info->access_bit_mask |
++                                 sleep_enable_reg_info->access_bit_mask);
++
++              acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
++                              ACPI_REGISTER_PM1A_CONTROL, pm1x_control);
++              acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
++                              ACPI_REGISTER_PM1B_CONTROL, pm1x_control);
++      }
+       /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
+@@ -407,12 +441,17 @@ acpi_leave_sleep_state (
+       arg_list.count = 1;
+       arg_list.pointer = &arg;
+-
+       arg.type = ACPI_TYPE_INTEGER;
+-      arg.integer.value = sleep_state;
+       /* Ignore any errors from these methods */
++      arg.integer.value = 0;
++      status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL);
++      if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
++              ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
++      }
++
++      arg.integer.value = sleep_state;
+       status = acpi_evaluate_object (NULL, "\\_BFS", &arg_list, NULL);
+       if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
+               ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status)));
+@@ -430,8 +469,8 @@ acpi_leave_sleep_state (
+               return_ACPI_STATUS (status);
+       }
+-      /* Disable BM arbitration */
+-      status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK);
++      /* Enable BM arbitration */
++      status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK);
+       return_ACPI_STATUS (status);
+ }
+--- linux-2.6.0/drivers/acpi/Kconfig   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/acpi/Kconfig    2003-12-28 23:21:57.000000000 -0800
+@@ -251,12 +251,6 @@ config ACPI_SYSTEM
+         This driver will enable your system to shut down using ACPI, and
+         dump your ACPI DSDT table using /proc/acpi/dsdt.
+-config ACPI_EFI
+-      bool
+-      depends on ACPI_INTERPRETER
+-      depends on IA64
+-      default y
+-
+ config ACPI_RELAXED_AML
+       bool "Relaxed AML"
+       depends on ACPI_INTERPRETER
+@@ -269,5 +263,23 @@ config ACPI_RELAXED_AML
+         particular, many Toshiba laptops require this for correct operation
+         of the AC module.
++config X86_PM_TIMER
++      bool "Power Management Timer Support"
++      depends on X86 && ACPI
++      depends on ACPI_BOOT && EXPERIMENTAL
++      default n
++      help
++        The Power Management Timer is available on all ACPI-capable,
++        in most cases even if ACPI is unusable or blacklisted.
++
++        This timing source is not affected by powermanagement features
++        like aggressive processor idling, throttling, frequency and/or
++        voltage scaling, unlike the commonly used Time Stamp Counter
++        (TSC) timing source.
++
++        So, if you see messages like 'Losing too many ticks!' in the
++        kernel logs, and/or you are using a this on a notebook which
++        does not yet have an HPET, you should say "Y" here.
++
+ endmenu
+--- linux-2.6.0/drivers/acpi/namespace/nsaccess.c      2003-06-14 12:18:34.000000000 -0700
++++ 25/drivers/acpi/namespace/nsaccess.c       2003-12-28 23:21:33.000000000 -0800
+@@ -314,8 +314,8 @@ acpi_ns_lookup (
+       else {
+               prefix_node = scope_info->scope.node;
+               if (ACPI_GET_DESCRIPTOR_TYPE (prefix_node) != ACPI_DESC_TYPE_NAMED) {
+-                      ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "[%p] Not a namespace node\n",
+-                              prefix_node));
++                      ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p Not a namespace node [%s]\n",
++                                      prefix_node, acpi_ut_get_descriptor_name (prefix_node)));
+                       return_ACPI_STATUS (AE_AML_INTERNAL);
+               }
+@@ -379,7 +379,7 @@ acpi_ns_lookup (
+                       ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+                               "Searching relative to prefix scope [%4.4s] (%p)\n",
+-                              prefix_node->name.ascii, prefix_node));
++                              acpi_ut_get_node_name (prefix_node), prefix_node));
+                       /*
+                        * Handle multiple Parent Prefixes (carat) by just getting
+@@ -413,7 +413,7 @@ acpi_ns_lookup (
+                       if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
+                               ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+                                       "Search scope is [%4.4s], path has %d carat(s)\n",
+-                                      this_node->name.ascii, num_carats));
++                                      acpi_ut_get_node_name (this_node), num_carats));
+                       }
+               }
+--- linux-2.6.0/drivers/acpi/namespace/nsalloc.c       2003-06-14 12:18:21.000000000 -0700
++++ 25/drivers/acpi/namespace/nsalloc.c        2003-12-28 23:21:33.000000000 -0800
+@@ -271,7 +271,7 @@ acpi_ns_install_node (
+                * alphabetic placement.
+                */
+               previous_child_node = NULL;
+-              while (acpi_ns_compare_names (child_node->name.ascii, node->name.ascii) < 0) {
++              while (acpi_ns_compare_names (acpi_ut_get_node_name (child_node), acpi_ut_get_node_name (node)) < 0) {
+                       if (child_node->flags & ANOBJ_END_OF_PEER_LIST) {
+                               /* Last peer;  Clear end-of-list flag */
+@@ -335,8 +335,9 @@ acpi_ns_install_node (
+       node->type = (u8) type;
+       ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) added to %4.4s (%s) %p at %p\n",
+-              node->name.ascii, acpi_ut_get_type_name (node->type),
+-              parent_node->name.ascii, acpi_ut_get_type_name (parent_node->type), parent_node, node));
++              acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type),
++              acpi_ut_get_node_name (parent_node), acpi_ut_get_type_name (parent_node->type),
++              parent_node, node));
+       /*
+        * Increment the reference count(s) of all parents up to
+--- linux-2.6.0/drivers/acpi/namespace/nsdump.c        2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/acpi/namespace/nsdump.c 2003-12-28 23:21:33.000000000 -0800
+@@ -50,8 +50,8 @@
+ #define _COMPONENT          ACPI_NAMESPACE
+        ACPI_MODULE_NAME    ("nsdump")
+-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
++#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+ /*******************************************************************************
+  *
+@@ -76,7 +76,7 @@ acpi_ns_print_pathname (
+               return;
+       }
+-              /* Print the entire name */
++      /* Print the entire name */
+       ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "["));
+@@ -205,7 +205,7 @@ acpi_ns_dump_one_object (
+        * Now we can print out the pertinent information
+        */
+       acpi_os_printf ("%4.4s %-12s %p ",
+-                      this_node->name.ascii, acpi_ut_get_type_name (type), this_node);
++                      acpi_ut_get_node_name (this_node), acpi_ut_get_type_name (type), this_node);
+       dbg_level = acpi_dbg_level;
+       acpi_dbg_level = 0;
+@@ -250,8 +250,7 @@ acpi_ns_dump_one_object (
+               case ACPI_TYPE_INTEGER:
+                       acpi_os_printf ("= %8.8X%8.8X\n",
+-                                       ACPI_HIDWORD (obj_desc->integer.value),
+-                                       ACPI_LODWORD (obj_desc->integer.value));
++                                       ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+                       break;
+@@ -302,8 +301,7 @@ acpi_ns_dump_one_object (
+                       acpi_os_printf ("[%s]", acpi_ut_get_region_name (obj_desc->region.space_id));
+                       if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
+                               acpi_os_printf (" Addr %8.8X%8.8X Len %.4X\n",
+-                                               ACPI_HIDWORD (obj_desc->region.address),
+-                                               ACPI_LODWORD (obj_desc->region.address),
++                                               ACPI_FORMAT_UINT64 (obj_desc->region.address),
+                                                obj_desc->region.length);
+                       }
+                       else {
+@@ -324,7 +322,7 @@ acpi_ns_dump_one_object (
+                       if (obj_desc->buffer_field.buffer_obj &&
+                               obj_desc->buffer_field.buffer_obj->buffer.node) {
+                               acpi_os_printf ("Buf [%4.4s]",
+-                                              obj_desc->buffer_field.buffer_obj->buffer.node->name.ascii);
++                                              acpi_ut_get_node_name (obj_desc->buffer_field.buffer_obj->buffer.node));
+                       }
+                       break;
+@@ -332,29 +330,29 @@ acpi_ns_dump_one_object (
+               case ACPI_TYPE_LOCAL_REGION_FIELD:
+                       acpi_os_printf ("Rgn [%4.4s]",
+-                                      obj_desc->common_field.region_obj->region.node->name.ascii);
++                                      acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node));
+                       break;
+               case ACPI_TYPE_LOCAL_BANK_FIELD:
+                       acpi_os_printf ("Rgn [%4.4s] Bnk [%4.4s]",
+-                                      obj_desc->common_field.region_obj->region.node->name.ascii,
+-                                      obj_desc->bank_field.bank_obj->common_field.node->name.ascii);
++                                      acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node),
++                                      acpi_ut_get_node_name (obj_desc->bank_field.bank_obj->common_field.node));
+                       break;
+               case ACPI_TYPE_LOCAL_INDEX_FIELD:
+                       acpi_os_printf ("Idx [%4.4s] Dat [%4.4s]",
+-                                      obj_desc->index_field.index_obj->common_field.node->name.ascii,
+-                                      obj_desc->index_field.data_obj->common_field.node->name.ascii);
++                                      acpi_ut_get_node_name (obj_desc->index_field.index_obj->common_field.node),
++                                      acpi_ut_get_node_name (obj_desc->index_field.data_obj->common_field.node));
+                       break;
+               case ACPI_TYPE_LOCAL_ALIAS:
+-                      acpi_os_printf ("Target %4.4s (%p)\n", ((struct acpi_namespace_node *) obj_desc)->name.ascii, obj_desc);
++                      acpi_os_printf ("Target %4.4s (%p)\n", acpi_ut_get_node_name (obj_desc), obj_desc);
+                       break;
+               default:
+@@ -371,7 +369,7 @@ acpi_ns_dump_one_object (
+               case ACPI_TYPE_LOCAL_BANK_FIELD:
+               case ACPI_TYPE_LOCAL_INDEX_FIELD:
+-                      acpi_os_printf ("Off %.2X Len %.2X Acc %.2hd\n",
++                      acpi_os_printf (" Off %.3X Len %.2X Acc %.2hd\n",
+                                       (obj_desc->common_field.base_byte_offset * 8)
+                                               + obj_desc->common_field.start_field_bit_offset,
+                                       obj_desc->common_field.bit_length,
+@@ -408,8 +406,8 @@ acpi_ns_dump_one_object (
+               case ACPI_TYPE_INTEGER:
+-                      acpi_os_printf (" N:%X%X\n", ACPI_HIDWORD(obj_desc->integer.value),
+-                                       ACPI_LODWORD(obj_desc->integer.value));
++                      acpi_os_printf (" I:%8.8X8.8%X\n",
++                                      ACPI_FORMAT_UINT64 (obj_desc->integer.value));
+                       break;
+               case ACPI_TYPE_STRING:
+@@ -485,7 +483,8 @@ acpi_ns_dump_one_object (
+               default:
+-                      acpi_os_printf ("(String or Buffer ptr - not an object descriptor)\n");
++                      acpi_os_printf ("(String or Buffer ptr - not an object descriptor) [%s]\n",
++                                      acpi_ut_get_descriptor_name (obj_desc));
+                       bytes_to_dump = 16;
+                       break;
+               }
+@@ -581,7 +580,6 @@ acpi_ns_dump_objects (
+       info.owner_id = owner_id;
+       info.display_type = display_type;
+-
+       (void) acpi_ns_walk_namespace (type, start_handle, max_depth,
+                        ACPI_NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object,
+                        (void *) &info, NULL);
+@@ -628,7 +626,6 @@ acpi_ns_dump_tables (
+               ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n"));
+       }
+-
+       acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth,
+                       ACPI_UINT32_MAX, search_handle);
+       return_VOID;
+--- linux-2.6.0/drivers/acpi/namespace/nsdumpdv.c      2003-06-14 12:17:56.000000000 -0700
++++ 25/drivers/acpi/namespace/nsdumpdv.c       2003-12-28 23:21:33.000000000 -0800
+@@ -93,7 +93,7 @@ acpi_ns_dump_one_device (
+               ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "    HID: %s, ADR: %8.8X%8.8X, Status: %X\n",
+                                 info->hardware_id.value,
+-                                ACPI_HIDWORD (info->address), ACPI_LODWORD (info->address),
++                                ACPI_FORMAT_UINT64 (info->address),
+                                 info->current_status));
+               ACPI_MEM_FREE (info);
+       }
+--- linux-2.6.0/drivers/acpi/namespace/nsinit.c        2003-06-14 12:18:07.000000000 -0700
++++ 25/drivers/acpi/namespace/nsinit.c 2003-12-28 23:21:33.000000000 -0800
+@@ -144,10 +144,17 @@ acpi_ns_initialize_devices (
+       ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Executing all Device _STA and_INI methods:"));
+-      /* Walk namespace for all objects of type Device */
++      status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
++      if (ACPI_FAILURE (status)) {
++              return_ACPI_STATUS (status);
++      }
++
++      /* Walk namespace for all objects of type Device or Processor */
+-      status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+-                        ACPI_UINT32_MAX, FALSE, acpi_ns_init_one_device, &info, NULL);
++      status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
++                        ACPI_UINT32_MAX, TRUE, acpi_ns_init_one_device, &info, NULL);
++
++      (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+       if (ACPI_FAILURE (status)) {
+               ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
+@@ -290,7 +297,8 @@ acpi_ns_init_one_object (
+               ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "\n"));
+               ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+                               "Could not execute arguments for [%4.4s] (%s), %s\n",
+-                              node->name.ascii, acpi_ut_get_type_name (type), acpi_format_exception (status)));
++                              acpi_ut_get_node_name (node), acpi_ut_get_type_name (type),
++                              acpi_format_exception (status)));
+       }
+       /* Print a dot for each object unless we are going to print the entire pathname */
+@@ -338,45 +346,48 @@ acpi_ns_init_one_device (
+       ACPI_FUNCTION_TRACE ("ns_init_one_device");
+-      if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) {
+-              ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
+-      }
+-
+-      info->device_count++;
+-
+-      status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+-      if (ACPI_FAILURE (status)) {
+-              return_ACPI_STATUS (status);
+-      }
+-
+       node = acpi_ns_map_handle_to_node (obj_handle);
+       if (!node) {
+-              (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+               return_ACPI_STATUS (AE_BAD_PARAMETER);
+       }
+-      status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+-      if (ACPI_FAILURE (status)) {
+-              return_ACPI_STATUS (status);
++      /*
++       * We will run _STA/_INI on Devices and Processors only
++       */
++      if ((node->type != ACPI_TYPE_DEVICE) &&
++              (node->type != ACPI_TYPE_PROCESSOR)) {
++              return_ACPI_STATUS (AE_OK);
+       }
++      if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) {
++              ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
++      }
++
++      info->device_count++;
++
+       /*
+        * Run _STA to determine if we can run _INI on the device.
+        */
+       ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, node, "_STA"));
+       status = acpi_ut_execute_STA (node, &flags);
++
+       if (ACPI_FAILURE (status)) {
+-              /* Ignore error and move on to next device */
++              if (node->type == ACPI_TYPE_DEVICE) {
++                      /* Ignore error and move on to next device */
+-              return_ACPI_STATUS (AE_OK);
+-      }
++                      return_ACPI_STATUS (AE_OK);
++              }
+-      info->num_STA++;
++              /* _STA is not required for Processor objects */
++      }
++      else {
++              info->num_STA++;
+-      if (!(flags & 0x01)) {
+-              /* don't look at children of a not present device */
++              if (!(flags & 0x01)) {
++                      /* Don't look at children of a not present device */
+-              return_ACPI_STATUS(AE_CTRL_DEPTH);
++                      return_ACPI_STATUS(AE_CTRL_DEPTH);
++              }
+       }
+       /*
+--- linux-2.6.0/drivers/acpi/namespace/nsobject.c      2003-06-14 12:18:07.000000000 -0700
++++ 25/drivers/acpi/namespace/nsobject.c       2003-12-28 23:21:33.000000000 -0800
+@@ -104,7 +104,8 @@ acpi_ns_attach_object (
+       if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
+               /* Not a name handle */
+-              ACPI_REPORT_ERROR (("ns_attach_object: Invalid handle\n"));
++              ACPI_REPORT_ERROR (("ns_attach_object: Invalid handle %p [%s]\n",
++                              node, acpi_ut_get_descriptor_name (node)));
+               return_ACPI_STATUS (AE_BAD_PARAMETER);
+       }
+@@ -151,7 +152,7 @@ acpi_ns_attach_object (
+       }
+       ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
+-              obj_desc, node, node->name.ascii));
++              obj_desc, node, acpi_ut_get_node_name (node)));
+       /* Detach an existing attached object if present */
+@@ -234,7 +235,7 @@ acpi_ns_detach_object (
+       node->type = ACPI_TYPE_ANY;
+       ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
+-              node, node->name.ascii, obj_desc));
++              node, acpi_ut_get_node_name (node), obj_desc));
+       /* Remove one reference on the object (and all subobjects) */
+--- linux-2.6.0/drivers/acpi/namespace/nssearch.c      2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/acpi/namespace/nssearch.c       2003-12-28 23:21:33.000000000 -0800
+@@ -119,7 +119,7 @@ acpi_ns_search_node (
+                       ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+                               "Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
+                               (char *) &target_name, acpi_ut_get_type_name (next_node->type),
+-                              next_node, node->name.ascii, node));
++                              next_node, acpi_ut_get_node_name (node), node));
+                       *return_node = next_node;
+                       return_ACPI_STATUS (AE_OK);
+@@ -145,7 +145,7 @@ acpi_ns_search_node (
+       ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+               "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
+               (char *) &target_name, acpi_ut_get_type_name (type),
+-              node->name.ascii, node, node->child));
++              acpi_ut_get_node_name (node), node, node->child));
+       return_ACPI_STATUS (AE_NOT_FOUND);
+ }
+--- linux-2.6.0/drivers/acpi/namespace/nsutils.c       2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/acpi/namespace/nsutils.c        2003-12-28 23:21:33.000000000 -0800
+@@ -977,8 +977,8 @@ acpi_ns_find_parent_name (
+               parent_node = acpi_ns_get_parent_node (child_node);
+               if (parent_node) {
+                       ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Parent of %p [%4.4s] is %p [%4.4s]\n",
+-                              child_node, child_node->name.ascii,
+-                              parent_node, parent_node->name.ascii));
++                              child_node, acpi_ut_get_node_name (child_node),
++                              parent_node, acpi_ut_get_node_name (parent_node)));
+                       if (parent_node->name.integer) {
+                               return_VALUE ((acpi_name) parent_node->name.integer);
+@@ -986,7 +986,7 @@ acpi_ns_find_parent_name (
+               }
+               ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "unable to find parent of %p (%4.4s)\n",
+-                      child_node, child_node->name.ascii));
++                      child_node, acpi_ut_get_node_name (child_node)));
+       }
+       return_VALUE (ACPI_UNKNOWN_NAME);
+--- linux-2.6.0/drivers/acpi/namespace/nsxfname.c      2003-06-14 12:18:03.000000000 -0700
++++ 25/drivers/acpi/namespace/nsxfname.c       2003-12-28 23:21:33.000000000 -0800
+@@ -199,7 +199,7 @@ acpi_get_name (
+       /* Just copy the ACPI name from the Node and zero terminate it */
+-      ACPI_STRNCPY (buffer->pointer, node->name.ascii,
++      ACPI_STRNCPY (buffer->pointer, acpi_ut_get_node_name (node),
+                        ACPI_NAME_SIZE);
+       ((char *) buffer->pointer) [ACPI_NAME_SIZE] = 0;
+       status = AE_OK;
+--- linux-2.6.0/drivers/acpi/osl.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/acpi/osl.c      2003-12-28 23:21:45.000000000 -0800
+@@ -41,10 +41,7 @@
+ #include <acpi/acpi_bus.h>
+ #include <asm/uaccess.h>
+-#ifdef CONFIG_ACPI_EFI
+ #include <linux/efi.h>
+-u64 efi_mem_attributes (u64 phys_addr);
+-#endif
+ #define _COMPONENT            ACPI_OS_SERVICES
+@@ -140,22 +137,24 @@ acpi_os_free(void *ptr)
+ acpi_status
+ acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr)
+ {
+-#ifdef CONFIG_ACPI_EFI
+-      addr->pointer_type = ACPI_PHYSICAL_POINTER;
+-      if (efi.acpi20)
+-              addr->pointer.physical = (acpi_physical_address) virt_to_phys(efi.acpi20);
+-      else if (efi.acpi)
+-              addr->pointer.physical = (acpi_physical_address) virt_to_phys(efi.acpi);
+-      else {
+-              printk(KERN_ERR PREFIX "System description tables not found\n");
+-              return AE_NOT_FOUND;
+-      }
+-#else
+-      if (ACPI_FAILURE(acpi_find_root_pointer(flags, addr))) {
+-              printk(KERN_ERR PREFIX "System description tables not found\n");
+-              return AE_NOT_FOUND;
++      if (efi_enabled) {
++              addr->pointer_type = ACPI_PHYSICAL_POINTER;
++              if (efi.acpi20)
++                      addr->pointer.physical =
++                              (acpi_physical_address) virt_to_phys(efi.acpi20);
++              else if (efi.acpi)
++                      addr->pointer.physical =
++                              (acpi_physical_address) virt_to_phys(efi.acpi);
++              else {
++                      printk(KERN_ERR PREFIX "System description tables not found\n");
++                      return AE_NOT_FOUND;
++              }
++      } else {
++              if (ACPI_FAILURE(acpi_find_root_pointer(flags, addr))) {
++                      printk(KERN_ERR PREFIX "System description tables not found\n");
++                      return AE_NOT_FOUND;
++              }
+       }
+-#endif /*CONFIG_ACPI_EFI*/
+       return AE_OK;
+ }
+@@ -163,22 +162,22 @@ acpi_os_get_root_pointer(u32 flags, stru
+ acpi_status
+ acpi_os_map_memory(acpi_physical_address phys, acpi_size size, void **virt)
+ {
+-#ifdef CONFIG_ACPI_EFI
+-      if (EFI_MEMORY_WB & efi_mem_attributes(phys)) {
+-              *virt = phys_to_virt(phys);
++      if (efi_enabled) {
++              if (EFI_MEMORY_WB & efi_mem_attributes(phys)) {
++                      *virt = phys_to_virt(phys);
++              } else {
++                      *virt = ioremap(phys, size);
++              }
+       } else {
+-              *virt = ioremap(phys, size);
+-      }
+-#else
+-      if (phys > ULONG_MAX) {
+-              printk(KERN_ERR PREFIX "Cannot map memory that high\n");
+-              return AE_BAD_PARAMETER;
++              if (phys > ULONG_MAX) {
++                      printk(KERN_ERR PREFIX "Cannot map memory that high\n");
++                      return AE_BAD_PARAMETER;
++              }
++              /*
++               * ioremap checks to ensure this is in reserved space
++               */
++              *virt = ioremap((unsigned long) phys, size);
+       }
+-      /*
+-       * ioremap checks to ensure this is in reserved space
+-       */
+-      *virt = ioremap((unsigned long) phys, size);
+-#endif
+       if (!*virt)
+               return AE_NO_MEMORY;
+@@ -369,19 +368,17 @@ acpi_os_read_memory(
+ {
+       u32                     dummy;
+       void                    *virt_addr;
+-
+-#ifdef CONFIG_ACPI_EFI
+       int                     iomem = 0;
+-      if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
++      if (efi_enabled) {
++              if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
++                      virt_addr = phys_to_virt(phys_addr);
++              } else {
++                      iomem = 1;
++                      virt_addr = ioremap(phys_addr, width);
++              }
++      } else
+               virt_addr = phys_to_virt(phys_addr);
+-      } else {
+-              iomem = 1;
+-              virt_addr = ioremap(phys_addr, width);
+-      }
+-#else
+-      virt_addr = phys_to_virt(phys_addr);
+-#endif
+       if (!value)
+               value = &dummy;
+@@ -399,10 +396,10 @@ acpi_os_read_memory(
+               BUG();
+       }
+-#ifdef CONFIG_ACPI_EFI
+-      if (iomem)
+-              iounmap(virt_addr);
+-#endif
++      if (efi_enabled) {
++              if (iomem)
++                      iounmap(virt_addr);
++      }
+       return AE_OK;
+ }
+@@ -414,19 +411,17 @@ acpi_os_write_memory(
+       u32                     width)
+ {
+       void                    *virt_addr;
+-
+-#ifdef CONFIG_ACPI_EFI
+       int                     iomem = 0;
+-      if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
++      if (efi_enabled) {
++              if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) {
++                      virt_addr = phys_to_virt(phys_addr);
++              } else {
++                      iomem = 1;
++                      virt_addr = ioremap(phys_addr, width);
++              }
++      } else
+               virt_addr = phys_to_virt(phys_addr);
+-      } else {
+-              iomem = 1;
+-              virt_addr = ioremap(phys_addr, width);
+-      }
+-#else
+-      virt_addr = phys_to_virt(phys_addr);
+-#endif
+       switch (width) {
+       case 8:
+@@ -442,10 +437,8 @@ acpi_os_write_memory(
+               BUG();
+       }
+-#ifdef CONFIG_ACPI_EFI
+       if (iomem)
+               iounmap(virt_addr);
+-#endif
+       return AE_OK;
+ }
+--- linux-2.6.0/drivers/acpi/parser/psargs.c   2003-06-14 12:18:06.000000000 -0700
++++ 25/drivers/acpi/parser/psargs.c    2003-12-28 23:21:33.000000000 -0800
+@@ -490,7 +490,7 @@ union acpi_parse_object *
+ acpi_ps_get_next_field (
+       struct acpi_parse_state         *parser_state)
+ {
+-      u32                             aml_offset = ACPI_PTR_DIFF (parser_state->aml,
++      u32                             aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
+                        parser_state->aml_start);
+       union acpi_parse_object         *field;
+       u16                             opcode;
+@@ -677,7 +677,7 @@ acpi_ps_get_next_arg (
+                       /* Fill in bytelist data */
+-                      arg->common.value.size = ACPI_PTR_DIFF (parser_state->pkg_end,
++                      arg->common.value.size = (u32) ACPI_PTR_DIFF (parser_state->pkg_end,
+                                         parser_state->aml);
+                       arg->named.data = parser_state->aml;
+--- linux-2.6.0/drivers/acpi/parser/psparse.c  2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/acpi/parser/psparse.c   2003-12-28 23:21:33.000000000 -0800
+@@ -498,7 +498,7 @@ acpi_ps_parse_loop (
+               if (!op) {
+                       /* Get the next opcode from the AML stream */
+-                      walk_state->aml_offset = ACPI_PTR_DIFF (parser_state->aml,
++                      walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
+                                          parser_state->aml_start);
+                       walk_state->opcode   = acpi_ps_peek_opcode (parser_state);
+@@ -710,7 +710,7 @@ acpi_ps_parse_loop (
+                               while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
+                                               !walk_state->arg_count) {
+-                                      walk_state->aml_offset = ACPI_PTR_DIFF (parser_state->aml,
++                                      walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
+                                                          parser_state->aml_start);
+                                       status = acpi_ps_get_next_arg (walk_state, parser_state,
+                                                        GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
+--- linux-2.6.0/drivers/acpi/parser/psxface.c  2003-06-14 12:18:30.000000000 -0700
++++ 25/drivers/acpi/parser/psxface.c   2003-12-28 23:21:33.000000000 -0800
+@@ -127,7 +127,8 @@ acpi_psx_execute (
+       op = acpi_ps_create_scope_op ();
+       if (!op) {
+-              return_ACPI_STATUS (AE_NO_MEMORY);
++              status = AE_NO_MEMORY;
++              goto cleanup1;
+       }
+       /*
+@@ -142,20 +143,24 @@ acpi_psx_execute (
+       walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
+                          NULL, NULL, NULL);
+       if (!walk_state) {
+-              return_ACPI_STATUS (AE_NO_MEMORY);
++              status = AE_NO_MEMORY;
++              goto cleanup2;
+       }
+       status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start,
+                         obj_desc->method.aml_length, NULL, NULL, 1);
+       if (ACPI_FAILURE (status)) {
+-              acpi_ds_delete_walk_state (walk_state);
+-              return_ACPI_STATUS (status);
++              goto cleanup3;
+       }
+       /* Parse the AML */
+       status = acpi_ps_parse_aml (walk_state);
+       acpi_ps_delete_parse_tree (op);
++      if (ACPI_FAILURE (status)) {
++              goto cleanup1; /* Walk state is already deleted */
++
++      }
+       /*
+        * 2) Execute the method.  Performs second pass parse simultaneously
+@@ -168,7 +173,8 @@ acpi_psx_execute (
+       op = acpi_ps_create_scope_op ();
+       if (!op) {
+-              return_ACPI_STATUS (AE_NO_MEMORY);
++              status = AE_NO_MEMORY;
++              goto cleanup1;
+       }
+       /* Init new op with the method name and pointer back to the NS node */
+@@ -180,22 +186,30 @@ acpi_psx_execute (
+       walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
+       if (!walk_state) {
+-              return_ACPI_STATUS (AE_NO_MEMORY);
++              status = AE_NO_MEMORY;
++              goto cleanup2;
+       }
+       status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start,
+                         obj_desc->method.aml_length, params, return_obj_desc, 3);
+       if (ACPI_FAILURE (status)) {
+-              acpi_ds_delete_walk_state (walk_state);
+-              return_ACPI_STATUS (status);
++              goto cleanup3;
+       }
+       /*
+        * The walk of the parse tree is where we actually execute the method
+        */
+       status = acpi_ps_parse_aml (walk_state);
++      goto cleanup2; /* Walk state already deleted */
++
++
++cleanup3:
++      acpi_ds_delete_walk_state (walk_state);
++
++cleanup2:
+       acpi_ps_delete_parse_tree (op);
++cleanup1:
+       if (params) {
+               /* Take away the extra reference that we gave the parameters above */
+@@ -206,6 +220,10 @@ acpi_psx_execute (
+               }
+       }
++      if (ACPI_FAILURE (status)) {
++              return_ACPI_STATUS (status);
++      }
++
+       /*
+        * If the method has returned an object, signal this to the caller with
+        * a control exception code
+--- linux-2.6.0/drivers/acpi/pci_irq.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/acpi/pci_irq.c  2003-12-28 23:21:44.000000000 -0800
+@@ -237,7 +237,7 @@ acpi_pci_irq_add_prt (
+                           PCI Interrupt Routing Support
+    -------------------------------------------------------------------------- */
+-static int
++int
+ acpi_pci_irq_lookup (struct pci_bus *bus, int device, int pin)
+ {
+       struct acpi_prt_entry   *entry = NULL;
+--- linux-2.6.0/drivers/acpi/pci_link.c        2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/acpi/pci_link.c 2003-12-28 23:21:33.000000000 -0800
+@@ -99,7 +99,7 @@ acpi_pci_link_check_possible (
+       void                    *context)
+ {
+       struct acpi_pci_link    *link = (struct acpi_pci_link *) context;
+-      int                     i = 0;
++      u32                     i = 0;
+       ACPI_FUNCTION_TRACE("acpi_pci_link_check_possible");
+@@ -294,7 +294,10 @@ acpi_pci_link_try_get_current (
+       if (!link->irq.active) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No active IRQ resource found\n"));
+-              printk(KERN_WARNING "_CRS returns NULL! Using IRQ %d for device (%s [%s]).\n", irq, acpi_device_name(link->device), acpi_device_bid(link->device));
++              printk(KERN_WARNING "_CRS returns NULL! Using IRQ %d for"
++                      "device (%s [%s]).\n", irq,
++                      acpi_device_name(link->device),
++                      acpi_device_bid(link->device));
+               link->irq.active = irq;
+       }
+       
+@@ -429,30 +432,67 @@ retry_programming:
+                             PCI Link IRQ Management
+    -------------------------------------------------------------------------- */
+-#define ACPI_MAX_IRQS         256
+-#define ACPI_MAX_ISA_IRQ      16
+-
+ /*
+- * IRQ penalties are used to promote PCI IRQ balancing.  We set each ISA-
+- * possible IRQ (0-15) with a default penalty relative to its feasibility
+- * for PCI's use:
++ * "acpi_irq_balance" (default in APIC mode) enables ACPI to use PIC Interrupt
++ * Link Devices to move the PIRQs around to minimize sharing.
++ * 
++ * "acpi_irq_nobalance" (default in PIC mode) tells ACPI not to move any PIC IRQs
++ * that the BIOS has already set to active.  This is necessary because
++ * ACPI has no automatic means of knowing what ISA IRQs are used.  Note that
++ * if the BIOS doesn't set a Link Device active, ACPI needs to program it
++ * even if acpi_irq_nobalance is set.
++ *
++ * A tables of penalties avoids directing PCI interrupts to well known
++ * ISA IRQs. Boot params are available to over-ride the default table:
+  *
+- *   Never use:               0, 1, 2 (timer, keyboard, and cascade)
+- *   Avoid using:     13, 14, and 15 (FP error and IDE)
+- *   Penalize:                3, 4, 6, 7, 12 (known ISA uses)
++ * List interrupts that are free for PCI use.
++ * acpi_irq_pci=n[,m]
+  *
+- * Thus we're left with IRQs 5, 9, 10, 11, and everything above 15 (IO[S]APIC)
+- * as 'best bets' for PCI use.
++ * List interrupts that should not be used for PCI:
++ * acpi_irq_isa=n[,m]
++ *
++ * Note that PCI IRQ routers have a list of possible IRQs,
++ * which may not include the IRQs this table says are available.
++ * 
++ * Since this heuristic can't tell the difference between a link
++ * that no device will attach to, vs. a link which may be shared
++ * by multiple active devices -- it is not optimal.
++ *
++ * If interrupt performance is that important, get an IO-APIC system
++ * with a pin dedicated to each device.  Or for that matter, an MSI
++ * enabled system.
+  */
++#define ACPI_MAX_IRQS         256
++#define ACPI_MAX_ISA_IRQ      16
++
++#define PIRQ_PENALTY_PCI_AVAILABLE    (0)
++#define PIRQ_PENALTY_PCI_POSSIBLE     (16*16)
++#define PIRQ_PENALTY_PCI_USING                (16*16*16)
++#define PIRQ_PENALTY_ISA_TYPICAL      (16*16*16*16)
++#define PIRQ_PENALTY_ISA_USED         (16*16*16*16*16)
++#define PIRQ_PENALTY_ISA_ALWAYS               (16*16*16*16*16*16)
++
+ static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
+-      1000000,  1000000,  1000000,    10000, 
+-        10000,        0,    10000,    10000,
+-        10000,        0,        0,        0, 
+-        10000,   100000,   100000,   100000,
++      PIRQ_PENALTY_ISA_ALWAYS,        /* IRQ0 timer */
++      PIRQ_PENALTY_ISA_ALWAYS,        /* IRQ1 keyboard */
++      PIRQ_PENALTY_ISA_ALWAYS,        /* IRQ2 cascade */
++      PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ3 serial */
++      PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ4 serial */
++      PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ5 sometimes SoundBlaster */
++      PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ6 */
++      PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ7 parallel, spurious */
++      PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ8 rtc, sometimes */
++      PIRQ_PENALTY_PCI_AVAILABLE,     /* IRQ9  PCI, often acpi */
++      PIRQ_PENALTY_PCI_AVAILABLE,     /* IRQ10 PCI */
++      PIRQ_PENALTY_PCI_AVAILABLE,     /* IRQ11 PCI */
++      PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ12 mouse */
++      PIRQ_PENALTY_ISA_USED,  /* IRQ13 fpe, sometimes */
++      PIRQ_PENALTY_ISA_USED,  /* IRQ14 ide0 */
++      PIRQ_PENALTY_ISA_USED,  /* IRQ15 ide1 */
++                      /* >IRQ15 */
+ };
+-
+ int
+ acpi_pci_link_check (void)
+ {
+@@ -473,20 +513,30 @@ acpi_pci_link_check (void)
+                       continue;
+               }
+-              if (link->irq.active)
+-                      acpi_irq_penalty[link->irq.active] += 100;
+-              else if (link->irq.possible_count) {
+-                      int penalty = 100 / link->irq.possible_count;
+-                      for (i=0; i<link->irq.possible_count; i++) {
++              /*
++               * reflect the possible and active irqs in the penalty table --
++               * useful for breaking ties.
++               */
++              if (link->irq.possible_count) {
++                      int penalty = PIRQ_PENALTY_PCI_POSSIBLE / link->irq.possible_count;
++
++                      for (i = 0; i < link->irq.possible_count; i++) {
+                               if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ)
+                                       acpi_irq_penalty[link->irq.possible[i]] += penalty;
+                       }
++
++              } else if (link->irq.active) {
++                      acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_POSSIBLE;
+               }
+       }
++      /* Add a penalty for the SCI */
++      acpi_irq_penalty[acpi_fadt.sci_int] += PIRQ_PENALTY_PCI_USING;
+       return_VALUE(0);
+ }
++static int acpi_irq_balance;  /* 0: static, 1: balance */
++
+ static int acpi_pci_link_allocate(struct acpi_pci_link* link) {
+       int irq;
+       int i;
+@@ -500,12 +550,14 @@ static int acpi_pci_link_allocate(struct
+               irq = link->irq.active;
+       } else {
+               irq = link->irq.possible[0];
++      }
++      if (acpi_irq_balance || !link->irq.active) {
+               /*
+                * Select the best IRQ.  This is done in reverse to promote
+                * the use of IRQs 9, 10, 11, and >15.
+                */
+-              for (i=(link->irq.possible_count-1); i>0; i--) {
++              for (i = (link->irq.possible_count - 1); i >= 0; i--) {
+                       if (acpi_irq_penalty[irq] > acpi_irq_penalty[link->irq.possible[i]])
+                               irq = link->irq.possible[i];
+               }
+@@ -518,13 +570,14 @@ static int acpi_pci_link_allocate(struct
+                       acpi_device_bid(link->device));
+               return_VALUE(-ENODEV);
+       } else {
+-              acpi_irq_penalty[link->irq.active] += 100;
++              acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
+               printk(PREFIX "%s [%s] enabled at IRQ %d\n", 
+                       acpi_device_name(link->device),
+                       acpi_device_bid(link->device), link->irq.active);
+       }
+       link->irq.setonboot = 1;
++
+       return_VALUE(0);
+ }
+@@ -607,9 +660,12 @@ acpi_pci_link_add (
+       if (result)
+               goto end;
++      /* query and set link->irq.active */
+       acpi_pci_link_get_current(link);
+-      printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device), acpi_device_bid(device));
++//#ifdef CONFIG_ACPI_DEBUG
++      printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device),
++              acpi_device_bid(device));
+       for (i = 0; i < link->irq.possible_count; i++) {
+               if (link->irq.active == link->irq.possible[i]) {
+                       printk(" *%d", link->irq.possible[i]);
+@@ -619,6 +675,7 @@ acpi_pci_link_add (
+                       printk(" %d", link->irq.possible[i]);
+       }
+       printk(")\n");
++//#endif /* CONFIG_ACPI_DEBUG */
+       /* TBD: Acquire/release lock */
+       list_add_tail(&link->node, &acpi_link.entries);
+@@ -654,6 +711,77 @@ acpi_pci_link_remove (
+       return_VALUE(0);
+ }
++/*
++ * modify acpi_irq_penalty[] from cmdline
++ */
++static int __init acpi_irq_penalty_update(char *str, int used)
++{
++      int i;
++
++      for (i = 0; i < 16; i++) {
++              int retval;
++              int irq;
++
++              retval = get_option(&str,&irq);
++
++              if (!retval)
++                      break;  /* no number found */
++
++              if (irq < 0)
++                      continue;
++              
++              if (irq >= ACPI_MAX_IRQS)
++                      continue;
++
++              if (used)
++                      acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
++              else
++                      acpi_irq_penalty[irq] = PIRQ_PENALTY_PCI_AVAILABLE;
++
++              if (retval != 2)        /* no next number */
++                      break;
++      }
++      return 1;
++}
++
++/*
++ * Over-ride default table to reserve additional IRQs for use by ISA
++ * e.g. acpi_irq_isa=5
++ * Useful for telling ACPI how not to interfere with your ISA sound card.
++ */
++static int __init acpi_irq_isa(char *str)
++{
++      return(acpi_irq_penalty_update(str, 1));
++}
++__setup("acpi_irq_isa=", acpi_irq_isa);
++
++/*
++ * Over-ride default table to free additional IRQs for use by PCI
++ * e.g. acpi_irq_pci=7,15
++ * Used for acpi_irq_balance to free up IRQs to reduce PCI IRQ sharing.
++ */
++static int __init acpi_irq_pci(char *str)
++{
++      return(acpi_irq_penalty_update(str, 0));
++}
++__setup("acpi_irq_pci=", acpi_irq_pci);
++
++static int __init acpi_irq_nobalance_set(char *str)
++{
++printk("ACPI STATIC SET\n");
++      acpi_irq_balance = 0;
++      return(1);
++}
++__setup("acpi_irq_nobalance", acpi_irq_nobalance_set);
++
++int __init acpi_irq_balance_set(char *str)
++{
++printk("ACPI BALANCE SET\n");
++      acpi_irq_balance = 1;
++      return(1);
++}
++__setup("acpi_irq_balance", acpi_irq_balance_set);
++
+ static int __init acpi_pci_link_init (void)
+ {
+--- linux-2.6.0/drivers/acpi/pci_root.c        2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/acpi/pci_root.c 2003-12-28 23:21:33.000000000 -0800
+@@ -62,8 +62,6 @@ struct acpi_pci_root {
+       acpi_handle             handle;
+       struct acpi_pci_id      id;
+       struct pci_bus          *bus;
+-      u64                     mem_tra;
+-      u64                     io_tra;
+ };
+ static LIST_HEAD(acpi_pci_roots);
+@@ -115,97 +113,6 @@ void acpi_pci_unregister_driver(struct a
+       }
+ }
+-void
+-acpi_pci_get_translations (
+-      struct acpi_pci_id      *id,
+-      u64                     *mem_tra,
+-      u64                     *io_tra)
+-{
+-      struct list_head        *node = NULL;
+-      struct acpi_pci_root    *entry;
+-
+-      /* TBD: Locking */
+-      list_for_each(node, &acpi_pci_roots) {
+-              entry = list_entry(node, struct acpi_pci_root, node);
+-              if ((id->segment == entry->id.segment)
+-                      && (id->bus == entry->id.bus)) {
+-                      *mem_tra = entry->mem_tra;
+-                      *io_tra = entry->io_tra;
+-                      return;
+-              }
+-      }
+-
+-      *mem_tra = 0;
+-      *io_tra = 0;
+-}
+-
+-
+-static u64
+-acpi_pci_root_bus_tra (
+-       struct acpi_resource   *resource,
+-       int                    type)
+-{
+-      struct acpi_resource_address16 *address16;
+-      struct acpi_resource_address32 *address32;
+-      struct acpi_resource_address64 *address64;
+-
+-      while (1) {
+-              switch (resource->id) {
+-              case ACPI_RSTYPE_END_TAG:
+-                      return 0;
+-
+-              case ACPI_RSTYPE_ADDRESS16:
+-                      address16 = (struct acpi_resource_address16 *) &resource->data;
+-                      if (type == address16->resource_type) {
+-                              return address16->address_translation_offset;
+-                      }
+-                      break;
+-
+-              case ACPI_RSTYPE_ADDRESS32:
+-                      address32 = (struct acpi_resource_address32 *) &resource->data;
+-                      if (type == address32->resource_type) {
+-                              return address32->address_translation_offset;
+-                      }
+-                      break;
+-
+-              case ACPI_RSTYPE_ADDRESS64:
+-                      address64 = (struct acpi_resource_address64 *) &resource->data;
+-                      if (type == address64->resource_type) {
+-                              return address64->address_translation_offset;
+-                      }
+-                      break;
+-              }
+-              resource = ACPI_PTR_ADD (struct acpi_resource,
+-                              resource, resource->length);
+-      }
+-
+-      return 0;
+-}
+-
+-
+-static int
+-acpi_pci_evaluate_crs (
+-      struct acpi_pci_root    *root)
+-{
+-      acpi_status             status;
+-      struct acpi_buffer      buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+-
+-      ACPI_FUNCTION_TRACE("acpi_pci_evaluate_crs");
+-
+-      status = acpi_get_current_resources (root->handle, &buffer);
+-      if (ACPI_FAILURE(status))
+-              return_VALUE(-ENODEV);
+-
+-      root->io_tra = acpi_pci_root_bus_tra ((struct acpi_resource *)
+-                      buffer.pointer, ACPI_IO_RANGE);
+-      root->mem_tra = acpi_pci_root_bus_tra ((struct acpi_resource *)
+-                      buffer.pointer, ACPI_MEMORY_RANGE);
+-
+-      acpi_os_free(buffer.pointer);
+-      return_VALUE(0);
+-}
+-
+-
+ static int
+ acpi_pci_root_add (
+       struct acpi_device      *device)
+@@ -288,10 +195,8 @@ acpi_pci_root_add (
+       root->id.function = device->pnp.bus_address & 0xFFFF;
+       /*
+-       * Evaluate _CRS to get root bridge resources
+        * TBD: Need PCI interface for enumeration/configuration of roots.
+        */
+-      acpi_pci_evaluate_crs(root);
+       /* TBD: Locking */
+       list_add_tail(&root->node, &acpi_pci_roots);
+--- linux-2.6.0/drivers/acpi/resources/rscalc.c        2003-06-14 12:18:22.000000000 -0700
++++ 25/drivers/acpi/resources/rscalc.c 2003-12-28 23:21:33.000000000 -0800
+@@ -696,7 +696,7 @@ acpi_rs_get_list_length (
+               default:
+                       /*
+                        * If we get here, everything is out of sync,
+-                       *  so exit with an error
++                       * exit with an error
+                        */
+                       return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
+               }
+@@ -704,7 +704,7 @@ acpi_rs_get_list_length (
+               /*
+                * Update the return value and counter
+                */
+-              buffer_size += ACPI_ALIGN_RESOURCE_SIZE(structure_size);
++              buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE (structure_size);
+               bytes_parsed += bytes_consumed;
+               /*
+--- linux-2.6.0/drivers/acpi/resources/rscreate.c      2003-06-14 12:18:07.000000000 -0700
++++ 25/drivers/acpi/resources/rscreate.c       2003-12-28 23:21:33.000000000 -0800
+@@ -331,7 +331,7 @@ acpi_rs_create_pci_routing_table (
+               /* Now align the current length */
+-              user_prt->length = ACPI_ROUND_UP_to_64_bITS (user_prt->length);
++              user_prt->length = (u32) ACPI_ROUND_UP_to_64_bITS (user_prt->length);
+               /*
+                * 4) Fourth subobject: Dereference the PRT.source_index
+--- linux-2.6.0/drivers/acpi/resources/rsdump.c        2003-06-14 12:18:22.000000000 -0700
++++ 25/drivers/acpi/resources/rsdump.c 2003-12-28 23:21:33.000000000 -0800
+@@ -899,24 +899,19 @@ acpi_rs_dump_address64 (
+                        "" : "not ");
+       acpi_os_printf ("  Granularity: %8.8X%8.8X\n",
+-                       ACPI_HIDWORD (address64_data->granularity),
+-                       ACPI_LODWORD (address64_data->granularity));
++                       ACPI_FORMAT_UINT64 (address64_data->granularity));
+       acpi_os_printf ("  Address range min: %8.8X%8.8X\n",
+-                       ACPI_HIDWORD (address64_data->min_address_range),
+-                       ACPI_HIDWORD (address64_data->min_address_range));
++                       ACPI_FORMAT_UINT64 (address64_data->min_address_range));
+       acpi_os_printf ("  Address range max: %8.8X%8.8X\n",
+-                       ACPI_HIDWORD (address64_data->max_address_range),
+-                       ACPI_HIDWORD (address64_data->max_address_range));
++                       ACPI_FORMAT_UINT64 (address64_data->max_address_range));
+       acpi_os_printf ("  Address translation offset: %8.8X%8.8X\n",
+-                       ACPI_HIDWORD (address64_data->address_translation_offset),
+-                       ACPI_HIDWORD (address64_data->address_translation_offset));
++                       ACPI_FORMAT_UINT64 (address64_data->address_translation_offset));
+       acpi_os_printf ("  Address Length: %8.8X%8.8X\n",
+-                       ACPI_HIDWORD (address64_data->address_length),
+-                       ACPI_HIDWORD (address64_data->address_length));
++                       ACPI_FORMAT_UINT64 (address64_data->address_length));
+       if(0xFF != address64_data->resource_source.index) {
+               acpi_os_printf ("  Resource Source Index: %X\n",
+@@ -1126,8 +1121,7 @@ acpi_rs_dump_irq_list (
+                       acpi_os_printf ("PCI IRQ Routing Table structure %X.\n", count++);
+                       acpi_os_printf ("  Address: %8.8X%8.8X\n",
+-                                       ACPI_HIDWORD (prt_element->address),
+-                                       ACPI_LODWORD (prt_element->address));
++                                       ACPI_FORMAT_UINT64 (prt_element->address));
+                       acpi_os_printf ("  Pin: %X\n", prt_element->pin);
+--- linux-2.6.0/drivers/acpi/resources/rsirq.c 2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/acpi/resources/rsirq.c  2003-12-28 23:21:33.000000000 -0800
+@@ -132,26 +132,28 @@ acpi_rs_irq_resource (
+               temp8 = *buffer;
+               /*
+-               * Check for HE, LL or HL
++               * Check for HE, LL interrupts
+                */
+-              if (temp8 & 0x01) {
++              switch (temp8 & 0x09) {
++              case 0x01: /* HE */
+                       output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE;
+                       output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH;
+-              }
+-              else {
+-                      if (temp8 & 0x8) {
+-                              output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE;
+-                              output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW;
+-                      }
+-                      else {
+-                              /*
+-                               * Only _LL and _HE polarity/trigger interrupts
+-                               * are allowed (ACPI spec v1.0b ection 6.4.2.1),
+-                               * so an error will occur if we reach this point
+-                               */
+-                              ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid interrupt polarity/trigger in resource list\n"));
+-                              return_ACPI_STATUS (AE_BAD_DATA);
+-                      }
++                      break;
++
++              case 0x08: /* LL */
++                      output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE;
++                      output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW;
++                      break;
++
++              default:
++                      /*
++                       * Only _LL and _HE polarity/trigger interrupts
++                       * are allowed (ACPI spec, section "IRQ Format")
++                       * so 0x00 and 0x09 are illegal.
++                       */
++                      ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
++                              "Invalid interrupt polarity/trigger in resource list, %X\n", temp8));
++                      return_ACPI_STATUS (AE_BAD_DATA);
+               }
+               /*
+@@ -419,7 +421,7 @@ acpi_rs_extended_irq_resource (
+                * Point the String pointer to the end of this structure.
+                */
+               output_struct->data.extended_irq.resource_source.string_ptr =
+-                              (char *)(output_struct + struct_size);
++                              (char *)((char *) output_struct + struct_size);
+               temp_ptr = (u8 *) output_struct->data.extended_irq.resource_source.string_ptr;
+--- linux-2.6.0/drivers/acpi/resources/rslist.c        2003-06-14 12:18:51.000000000 -0700
++++ 25/drivers/acpi/resources/rslist.c 2003-12-28 23:21:33.000000000 -0800
+@@ -312,8 +312,8 @@ acpi_rs_byte_stream_to_list (
+                * Set the Buffer to the next structure
+                */
+               resource = ACPI_CAST_PTR (struct acpi_resource, buffer);
+-              resource->length = ACPI_ALIGN_RESOURCE_SIZE(resource->length);
+-              buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size);
++              resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE (resource->length);
++              buffer += ACPI_ALIGN_RESOURCE_SIZE (structure_size);
+       } /*  end while */
+--- linux-2.6.0/drivers/acpi/scan.c    2003-06-14 12:18:08.000000000 -0700
++++ 25/drivers/acpi/scan.c     2003-12-28 23:21:33.000000000 -0800
+@@ -336,6 +336,9 @@ acpi_bus_register_driver (
+       ACPI_FUNCTION_TRACE("acpi_bus_register_driver");
++      if (acpi_disabled)
++              return_VALUE(-ENODEV);
++
+       if (driver) {
+               spin_lock(&acpi_device_lock);
+               list_add_tail(&driver->node, &acpi_bus_drivers);
+--- linux-2.6.0/drivers/acpi/sleep/proc.c      2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/acpi/sleep/proc.c       2003-12-28 23:21:33.000000000 -0800
+@@ -374,6 +374,9 @@ static int acpi_sleep_proc_init(void)
+ {
+       struct proc_dir_entry   *entry = NULL;
++      if (acpi_disabled)
++              return 0;
++ 
+       /* 'sleep' [R/W]*/
+       entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP,
+                                 S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+--- linux-2.6.0/drivers/acpi/tables.c  2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/acpi/tables.c   2003-12-28 23:21:33.000000000 -0800
+@@ -60,6 +60,9 @@ static char *acpi_table_signatures[ACPI_
+       [ACPI_HPET]             = "HPET",
+ };
++static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" };
++static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };
++
+ /* System Description Table (RSDT/XSDT) */
+ struct acpi_table_sdt {
+       unsigned long           pa;
+@@ -136,8 +139,14 @@ acpi_table_print_madt_entry (
+       {
+               struct acpi_table_int_src_ovr *p =
+                       (struct acpi_table_int_src_ovr*) header;
+-              printk(KERN_INFO PREFIX "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n",
+-                      p->bus, p->bus_irq, p->global_irq, p->flags.polarity, p->flags.trigger);
++              printk(KERN_INFO PREFIX "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n",
++                      p->bus, p->bus_irq, p->global_irq,
++                      mps_inti_flags_polarity[p->flags.polarity],
++                      mps_inti_flags_trigger[p->flags.trigger]);
++              if(p->flags.reserved)
++                      printk(KERN_INFO PREFIX "INT_SRC_OVR unexpected reserved flags: 0x%x\n",
++                              p->flags.reserved);
++
+       }
+               break;
+@@ -145,8 +154,9 @@ acpi_table_print_madt_entry (
+       {
+               struct acpi_table_nmi_src *p =
+                       (struct acpi_table_nmi_src*) header;
+-              printk(KERN_INFO PREFIX "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n",
+-                      p->flags.polarity, p->flags.trigger, p->global_irq);
++              printk(KERN_INFO PREFIX "NMI_SRC (%s %s global_irq %d)\n",
++                      mps_inti_flags_polarity[p->flags.polarity],
++                      mps_inti_flags_trigger[p->flags.trigger], p->global_irq);
+       }
+               break;
+@@ -154,8 +164,10 @@ acpi_table_print_madt_entry (
+       {
+               struct acpi_table_lapic_nmi *p =
+                       (struct acpi_table_lapic_nmi*) header;
+-              printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] polarity[0x%x] trigger[0x%x] lint[0x%x])\n",
+-                      p->acpi_id, p->flags.polarity, p->flags.trigger, p->lint);
++              printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n",
++                      p->acpi_id,
++                      mps_inti_flags_polarity[p->flags.polarity],
++                      mps_inti_flags_trigger[p->flags.trigger], p->lint);
+       }
+               break;
+@@ -190,8 +202,10 @@ acpi_table_print_madt_entry (
+       {
+               struct acpi_table_plat_int_src *p =
+                       (struct acpi_table_plat_int_src*) header;
+-              printk(KERN_INFO PREFIX "PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
+-                      p->flags.polarity, p->flags.trigger, p->type, p->id, p->eid, p->iosapic_vector, p->global_irq);
++              printk(KERN_INFO PREFIX "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
++                      mps_inti_flags_polarity[p->flags.polarity],
++                      mps_inti_flags_trigger[p->flags.trigger],
++                      p->type, p->id, p->eid, p->iosapic_vector, p->global_irq);
+       }
+               break;
+--- linux-2.6.0/drivers/acpi/tables/tbgetall.c 2003-06-14 12:18:29.000000000 -0700
++++ 25/drivers/acpi/tables/tbgetall.c  2003-12-28 23:21:33.000000000 -0800
+@@ -240,8 +240,7 @@ acpi_tb_get_required_tables (
+               if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) {
+                       ACPI_REPORT_WARNING (("%s, while getting table at %8.8X%8.8X\n",
+                               acpi_format_exception (status),
+-                              ACPI_HIDWORD (address.pointer.value),
+-                              ACPI_LODWORD (address.pointer.value)));
++                              ACPI_FORMAT_UINT64 (address.pointer.value)));
+               }
+       }
+--- linux-2.6.0/drivers/acpi/tables/tbget.c    2003-07-27 12:14:38.000000000 -0700
++++ 25/drivers/acpi/tables/tbget.c     2003-12-28 23:21:33.000000000 -0800
+@@ -148,8 +148,7 @@ acpi_tb_get_table_header (
+                                 (void *) &header);
+               if (ACPI_FAILURE (status)) {
+                       ACPI_REPORT_ERROR (("Could not map memory at %8.8X%8.8X for length %X\n",
+-                              ACPI_HIDWORD (address->pointer.physical),
+-                              ACPI_LODWORD (address->pointer.physical),
++                              ACPI_FORMAT_UINT64 (address->pointer.physical),
+                               sizeof (struct acpi_table_header)));
+                       return_ACPI_STATUS (status);
+               }
+@@ -365,8 +364,7 @@ acpi_tb_get_this_table (
+               if (ACPI_FAILURE (status)) {
+                       ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
+                               header->signature,
+-                              ACPI_HIDWORD (address->pointer.physical),
+-                              ACPI_LODWORD (address->pointer.physical), header->length));
++                              ACPI_FORMAT_UINT64 (address->pointer.physical), header->length));
+                       return (status);
+               }
+@@ -408,8 +406,7 @@ acpi_tb_get_this_table (
+       ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+               "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
+               full_table->signature,
+-              ACPI_HIDWORD (address->pointer.physical),
+-              ACPI_LODWORD (address->pointer.physical), full_table));
++              ACPI_FORMAT_UINT64 (address->pointer.physical), full_table));
+       return_ACPI_STATUS (status);
+ }
+@@ -458,6 +455,7 @@ acpi_tb_get_table_ptr (
+       if (instance == 1) {
+               /* Get the first */
++              *table_ptr_loc = NULL;
+               if (acpi_gbl_table_lists[table_type].next) {
+                       *table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer;
+               }
+--- linux-2.6.0/drivers/acpi/tables/tbrsdt.c   2003-07-27 12:14:38.000000000 -0700
++++ 25/drivers/acpi/tables/tbrsdt.c    2003-12-28 23:21:33.000000000 -0800
+@@ -278,8 +278,7 @@ acpi_tb_get_table_rsdt (
+       ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+               "RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n",
+               acpi_gbl_RSDP,
+-              ACPI_HIDWORD (address.pointer.value),
+-              ACPI_LODWORD (address.pointer.value)));
++              ACPI_FORMAT_UINT64 (address.pointer.value)));
+       /* Check the RSDT or XSDT signature */
+--- linux-2.6.0/drivers/acpi/tables/tbxface.c  2003-06-14 12:18:33.000000000 -0700
++++ 25/drivers/acpi/tables/tbxface.c   2003-12-28 23:21:33.000000000 -0800
+@@ -251,7 +251,7 @@ acpi_unload_table (
+       /* Find all tables of the requested type */
+       table_desc = acpi_gbl_table_lists[table_type].next;
+-      while (table_desc); {
++      while (table_desc) {
+               /*
+                * Delete all namespace entries owned by this table.  Note that these
+                * entries can appear anywhere in the namespace by virtue of the AML
+--- linux-2.6.0/drivers/acpi/tables/tbxfroot.c 2003-07-27 12:14:38.000000000 -0700
++++ 25/drivers/acpi/tables/tbxfroot.c  2003-12-28 23:21:33.000000000 -0800
+@@ -211,8 +211,7 @@ acpi_get_firmware_table (
+       ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+               "RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
+               acpi_gbl_RSDP,
+-              ACPI_HIDWORD (address.pointer.value),
+-              ACPI_LODWORD (address.pointer.value)));
++              ACPI_FORMAT_UINT64 (address.pointer.value)));
+       /* Insert processor_mode flags */
+--- linux-2.6.0/drivers/acpi/thermal.c 2003-07-27 12:14:38.000000000 -0700
++++ 25/drivers/acpi/thermal.c  2003-12-28 23:21:33.000000000 -0800
+@@ -467,6 +467,7 @@ acpi_thermal_critical (
+       if (result)
+               return_VALUE(result);
++      printk(KERN_EMERG "Critical temperature reached (%ld C), shutting down.\n", KELVIN_TO_CELSIUS(tz->temperature));
+       acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled);
+       acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF);
+--- linux-2.6.0/drivers/acpi/utilities/utalloc.c       2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/acpi/utilities/utalloc.c        2003-12-28 23:21:33.000000000 -0800
+@@ -902,71 +902,30 @@ acpi_ut_dump_allocations (
+                       descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
+                       if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
+-                              acpi_os_printf ("%p Len %04X %9.9s-%d ",
++                              acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
+                                                descriptor, element->size, element->module,
+-                                               element->line);
++                                               element->line, acpi_ut_get_descriptor_name (descriptor));
+-                              /* Most of the elements will be internal objects. */
++                              /* Most of the elements will be Operand objects. */
+                               switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
+                               case ACPI_DESC_TYPE_OPERAND:
+-                                      acpi_os_printf ("obj_type %12.12s R%hd",
++                                      acpi_os_printf ("%12.12s R%hd",
+                                                       acpi_ut_get_type_name (descriptor->object.common.type),
+                                                       descriptor->object.common.reference_count);
+                                       break;
+                               case ACPI_DESC_TYPE_PARSER:
+-                                      acpi_os_printf ("parse_obj aml_opcode %04hX",
++                                      acpi_os_printf ("aml_opcode %04hX",
+                                                       descriptor->op.asl.aml_opcode);
+                                       break;
+                               case ACPI_DESC_TYPE_NAMED:
+-                                      acpi_os_printf ("Node %4.4s",
+-                                                      descriptor->node.name.ascii);
+-                                      break;
+-
+-                              case ACPI_DESC_TYPE_STATE:
+-                                      acpi_os_printf ("Untyped state_obj");
+-                                      break;
+-
+-                              case ACPI_DESC_TYPE_STATE_UPDATE:
+-                                      acpi_os_printf ("UPDATE state_obj");
+-                                      break;
+-
+-                              case ACPI_DESC_TYPE_STATE_PACKAGE:
+-                                      acpi_os_printf ("PACKAGE state_obj");
+-                                      break;
+-
+-                              case ACPI_DESC_TYPE_STATE_CONTROL:
+-                                      acpi_os_printf ("CONTROL state_obj");
+-                                      break;
+-
+-                              case ACPI_DESC_TYPE_STATE_RPSCOPE:
+-                                      acpi_os_printf ("ROOT-PARSE-SCOPE state_obj");
+-                                      break;
+-
+-                              case ACPI_DESC_TYPE_STATE_PSCOPE:
+-                                      acpi_os_printf ("PARSE-SCOPE state_obj");
+-                                      break;
+-
+-                              case ACPI_DESC_TYPE_STATE_WSCOPE:
+-                                      acpi_os_printf ("WALK-SCOPE state_obj");
+-                                      break;
+-
+-                              case ACPI_DESC_TYPE_STATE_RESULT:
+-                                      acpi_os_printf ("RESULT state_obj");
+-                                      break;
+-
+-                              case ACPI_DESC_TYPE_STATE_NOTIFY:
+-                                      acpi_os_printf ("NOTIFY state_obj");
+-                                      break;
+-
+-                              case ACPI_DESC_TYPE_STATE_THREAD:
+-                                      acpi_os_printf ("THREAD state_obj");
++                                      acpi_os_printf ("%4.4s",
++                                                      acpi_ut_get_node_name (&descriptor->node));
+                                       break;
+                               default:
+-                                      /* All types should appear above */
+                                       break;
+                               }
+--- linux-2.6.0/drivers/acpi/utilities/utdebug.c       2003-06-14 12:18:24.000000000 -0700
++++ 25/drivers/acpi/utilities/utdebug.c        2003-12-28 23:21:33.000000000 -0800
+@@ -447,7 +447,7 @@ acpi_ut_value_exit (
+       acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
+                       "%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str,
+-                      ACPI_HIDWORD (value), ACPI_LODWORD (value));
++                      ACPI_FORMAT_UINT64 (value));
+       acpi_gbl_nesting_level--;
+ }
+--- linux-2.6.0/drivers/acpi/utilities/utdelete.c      2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/acpi/utilities/utdelete.c       2003-12-28 23:21:33.000000000 -0800
+@@ -140,7 +140,7 @@ acpi_ut_delete_internal_obj (
+               /* Walk the handler list for this device */
+-              handler_desc = object->device.address_space;
++              handler_desc = object->device.handler;
+               while (handler_desc) {
+                       next_desc = handler_desc->address_space.next;
+                       acpi_ut_remove_reference (handler_desc);
+@@ -193,7 +193,7 @@ acpi_ut_delete_internal_obj (
+                        * default handlers -- and therefore, we created the context object
+                        * locally, it was not created by an external caller.
+                        */
+-                      handler_desc = object->region.address_space;
++                      handler_desc = object->region.handler;
+                       if (handler_desc) {
+                               if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
+                                       obj_pointer = second_desc->extra.region_context;
+--- linux-2.6.0/drivers/acpi/utilities/uteval.c        2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/acpi/utilities/uteval.c 2003-12-28 23:21:33.000000000 -0800
+@@ -91,7 +91,7 @@ acpi_ut_evaluate_object (
+       if (ACPI_FAILURE (status)) {
+               if (status == AE_NOT_FOUND) {
+                       ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
+-                              prefix_node->name.ascii, path));
++                              acpi_ut_get_node_name (prefix_node), path));
+               }
+               else {
+                       ACPI_REPORT_METHOD_ERROR ("Method execution failed",
+@@ -544,7 +544,7 @@ acpi_ut_execute_STA (
+               if (AE_NOT_FOUND == status) {
+                       ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+                               "_STA on %4.4s was not found, assuming device is present\n",
+-                              device_node->name.ascii));
++                              acpi_ut_get_node_name (device_node)));
+                       *flags = 0x0F;
+                       status = AE_OK;
+--- linux-2.6.0/drivers/acpi/utilities/utglobal.c      2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/acpi/utilities/utglobal.c       2003-12-28 23:21:33.000000000 -0800
+@@ -358,7 +358,7 @@ struct acpi_fixed_event_info        acpi
+       /* ACPI_EVENT_GLOBAL        */  {ACPI_BITREG_GLOBAL_LOCK_STATUS,    ACPI_BITREG_GLOBAL_LOCK_ENABLE,  ACPI_BITMASK_GLOBAL_LOCK_STATUS,    ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
+       /* ACPI_EVENT_POWER_BUTTON  */  {ACPI_BITREG_POWER_BUTTON_STATUS,   ACPI_BITREG_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_STATUS,   ACPI_BITMASK_POWER_BUTTON_ENABLE},
+       /* ACPI_EVENT_SLEEP_BUTTON  */  {ACPI_BITREG_SLEEP_BUTTON_STATUS,   ACPI_BITREG_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_STATUS,   ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
+-      /* ACPI_EVENT_RTC           */  {ACPI_BITREG_RT_CLOCK_STATUS,       ACPI_BITREG_RT_CLOCK_ENABLE,     0,                                  0},
++      /* ACPI_EVENT_RTC           */  {ACPI_BITREG_RT_CLOCK_STATUS,       ACPI_BITREG_RT_CLOCK_ENABLE,     ACPI_BITMASK_RT_CLOCK_STATUS,       ACPI_BITMASK_RT_CLOCK_ENABLE},
+ };
+ /*****************************************************************************
+@@ -534,6 +534,99 @@ acpi_ut_get_object_type_name (
+ }
++/*****************************************************************************
++ *
++ * FUNCTION:    acpi_ut_get_node_name
++ *
++ * PARAMETERS:  Object               - A namespace node
++ *
++ * RETURN:      Pointer to a string
++ *
++ * DESCRIPTION: Validate the node and return the node's ACPI name.
++ *
++ ****************************************************************************/
++
++char *
++acpi_ut_get_node_name (
++      void                            *object)
++{
++      struct acpi_namespace_node      *node;
++
++
++      if (!object)
++      {
++              return ("NULL NODE");
++      }
++
++      node = (struct acpi_namespace_node *) object;
++
++      if (node->descriptor != ACPI_DESC_TYPE_NAMED)
++      {
++              return ("****");
++      }
++
++      if (!acpi_ut_valid_acpi_name (* (u32 *) node->name.ascii))
++      {
++              return ("----");
++      }
++
++      return (node->name.ascii);
++}
++
++
++/*****************************************************************************
++ *
++ * FUNCTION:    acpi_ut_get_descriptor_name
++ *
++ * PARAMETERS:  Object               - An ACPI object
++ *
++ * RETURN:      Pointer to a string
++ *
++ * DESCRIPTION: Validate object and return the descriptor type
++ *
++ ****************************************************************************/
++
++static const char                   *acpi_gbl_desc_type_names[] = /* printable names of descriptor types */
++{
++      /* 00 */ "Invalid",
++      /* 01 */ "Cached",
++      /* 02 */ "State-Generic",
++      /* 03 */ "State-Update",
++      /* 04 */ "State-Package",
++      /* 05 */ "State-Control",
++      /* 06 */ "State-root_parse_scope",
++      /* 07 */ "State-parse_scope",
++      /* 08 */ "State-walk_scope",
++      /* 09 */ "State-Result",
++      /* 10 */ "State-Notify",
++      /* 11 */ "State-Thread",
++      /* 12 */ "Walk",
++      /* 13 */ "Parser",
++      /* 14 */ "Operand",
++      /* 15 */ "Node"
++};
++
++
++char *
++acpi_ut_get_descriptor_name (
++      void                            *object)
++{
++
++      if (!object)
++      {
++              return ("NULL OBJECT");
++      }
++
++      if (ACPI_GET_DESCRIPTOR_TYPE (object) > ACPI_DESC_TYPE_MAX)
++      {
++              return ((char *) acpi_gbl_bad_type);
++      }
++
++      return ((char *) acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE (object)]);
++
++}
++
++
+ #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+ /*
+  * Strings and procedures used for debug only
+--- linux-2.6.0/drivers/acpi/utilities/utobject.c      2003-06-14 12:18:24.000000000 -0700
++++ 25/drivers/acpi/utilities/utobject.c       2003-12-28 23:21:33.000000000 -0800
+@@ -223,29 +223,10 @@ acpi_ut_valid_internal_object (
+               return (TRUE);
+-      case ACPI_DESC_TYPE_NAMED:
+-
+-              ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+-                      "**** Obj %p is a named obj, not ACPI obj\n", object));
+-              break;
+-
+-      case ACPI_DESC_TYPE_PARSER:
+-
+-              ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+-                      "**** Obj %p is a parser obj, not ACPI obj\n", object));
+-              break;
+-
+-      case ACPI_DESC_TYPE_CACHED:
+-
+-              ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+-                      "**** Obj %p has already been released to internal cache\n", object));
+-              break;
+-
+       default:
+-
+-              ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+-                      "**** Obj %p has unknown descriptor type %X\n", object,
+-                      ACPI_GET_DESCRIPTOR_TYPE (object)));
++              ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
++                              "%p is not not an ACPI operand obj [%s]\n",
++                              object, acpi_ut_get_descriptor_name (object)));
+               break;
+       }
+@@ -322,7 +303,8 @@ acpi_ut_delete_object_desc (
+       if (ACPI_GET_DESCRIPTOR_TYPE (object) != ACPI_DESC_TYPE_OPERAND) {
+               ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+-                      "Obj %p is not an ACPI object\n", object));
++                              "%p is not an ACPI Operand object [%s]\n", object,
++                              acpi_ut_get_descriptor_name (object)));
+               return_VOID;
+       }
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/base/class_simple.c     2003-12-28 23:22:59.000000000 -0800
+@@ -0,0 +1,123 @@
++/*
++ * class_simple.c - basic char device support
++ *
++ * Copyright (c) 2003 Greg Kroah-Hartman <greg@kroah.com>
++ * Copyright (c) 2003 IBM Corp.
++ *
++ * This file is released under the GPLv2
++ *
++ */
++
++#undef DEBUG
++
++#include <linux/device.h>
++#include <linux/kdev_t.h>
++#include <linux/err.h>
++
++struct simple_dev {
++      struct list_head node;
++      dev_t dev;
++      struct class_device class_dev;
++};
++#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
++
++static LIST_HEAD(simple_dev_list);
++static spinlock_t simple_dev_list_lock = SPIN_LOCK_UNLOCKED;
++
++static void release_simple_dev(struct class_device *class_dev)
++{
++      struct simple_dev *s_dev = to_simple_dev(class_dev);
++      kfree(s_dev);
++}
++
++static ssize_t show_dev(struct class_device *class_dev, char *buf)
++{
++      struct simple_dev *s_dev = to_simple_dev(class_dev);
++      return print_dev_t(buf, s_dev->dev);
++}
++static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
++
++/**
++ * simple_add_class_device - adds a class device to sysfs for a character driver
++ * @class: pointer to the struct class that this device should be registered to.
++ * @dev: the dev_t for the device to be added.
++ * @device: a pointer to a struct device that is assiociated with this class device.
++ * @fmt: string for the class device's name
++ *
++ * This function can be used by simple char device classes that do not
++ * implement their own class device registration.  A struct class_device will
++ * be created in sysfs, registered to the specified class.  A "dev" file will
++ * be created, showing the dev_t for the device.  The pointer to the struct
++ * class_device will be returned from the call.  Any further sysfs files that
++ * might be required can be created using this pointer.
++ * Note: the struct class passed to this function must have previously been
++ * registered with a call to register_class().
++ */
++struct class_device *simple_add_class_device(struct class *class, dev_t dev, struct device *device, const char *fmt, ...)
++{
++      va_list args;
++      struct simple_dev *s_dev;
++      int retval;
++
++      s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL);
++      if (!s_dev) {
++              retval = -ENOMEM;
++              goto error;
++      }
++      memset(s_dev, 0x00, sizeof(*s_dev));
++
++      class->release = &release_simple_dev;
++      s_dev->dev = dev;
++      s_dev->class_dev.dev = device;
++      s_dev->class_dev.class = class;
++
++      va_start(args,fmt);
++      vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args);
++      va_end(args);
++      retval = class_device_register(&s_dev->class_dev);
++      if (retval)
++              goto error;
++      class_device_create_file(&s_dev->class_dev, &class_device_attr_dev);
++      spin_lock(&simple_dev_list_lock);
++      list_add(&s_dev->node, &simple_dev_list);
++      spin_unlock(&simple_dev_list_lock);
++
++      return &s_dev->class_dev;
++
++error:
++      kfree(s_dev);
++      return ERR_PTR(retval);
++}
++EXPORT_SYMBOL(simple_add_class_device);
++
++/**
++ * simple_remove_class_device - removes a class device that was created with simple_add_class_device()
++ * @dev: the dev_t of the device that was previously registered.
++ *
++ * This call unregisters and cleans up a class device that was created with a
++ * call to simple_add_class_device()
++ */
++void simple_remove_class_device(dev_t dev)
++{
++      struct simple_dev *s_dev = NULL;
++      struct list_head *tmp;
++      int found = 0;
++
++      spin_lock(&simple_dev_list_lock);
++      list_for_each(tmp, &simple_dev_list) {
++              s_dev = list_entry(tmp, struct simple_dev, node);
++              if (s_dev->dev == dev) {
++                      found = 1;
++                      break;
++              }
++      }
++      if (found) {
++              list_del(&s_dev->node);
++              spin_unlock(&simple_dev_list_lock);
++              class_device_unregister(&s_dev->class_dev);
++      } else {
++              spin_unlock(&simple_dev_list_lock);
++      }
++}
++EXPORT_SYMBOL(simple_remove_class_device);
++
+--- linux-2.6.0/drivers/base/firmware_class.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/base/firmware_class.c   2003-12-28 23:22:41.000000000 -0800
+@@ -415,18 +415,22 @@ struct firmware_work {
+       void (*cont)(const struct firmware *fw, void *context);
+ };
+-static void
++static int
+ request_firmware_work_func(void *arg)
+ {
+       struct firmware_work *fw_work = arg;
+       const struct firmware *fw;
+-      if (!arg)
+-              return;
++      if (!arg) {
++              WARN_ON(1);
++              return 0;
++      }
++      daemonize("%s/%s", "firmware", fw_work->name);
+       request_firmware(&fw, fw_work->name, fw_work->device);
+       fw_work->cont(fw, fw_work->context);
+       release_firmware(fw);
+       module_put(fw_work->module);
+       kfree(fw_work);
++      return 0;
+ }
+ /**
+@@ -451,6 +455,8 @@ request_firmware_nowait(
+ {
+       struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
+                                               GFP_ATOMIC);
++      int ret;
++
+       if (!fw_work)
+               return -ENOMEM;
+       if (!try_module_get(module)) {
+@@ -465,9 +471,14 @@ request_firmware_nowait(
+               .context = context,
+               .cont = cont,
+       };
+-      INIT_WORK(&fw_work->work, request_firmware_work_func, fw_work);
+-      schedule_work(&fw_work->work);
++      ret = kernel_thread(request_firmware_work_func, fw_work,
++                          CLONE_FS | CLONE_FILES);
++      
++      if (ret < 0) {
++              fw_work->cont(NULL, fw_work->context);
++              return ret;
++      }
+       return 0;
+ }
+--- linux-2.6.0/drivers/base/Makefile  2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/base/Makefile   2003-12-28 23:22:59.000000000 -0800
+@@ -1,7 +1,7 @@
+ # Makefile for the Linux device tree
+ obj-y                 := core.o sys.o interface.o bus.o \
+-                         driver.o class.o platform.o \
++                         driver.o class.o class_simple.o platform.o \
+                          cpu.o firmware.o init.o map.o
+ obj-y                 += power/
+ obj-$(CONFIG_FW_LOADER)       += firmware_class.o
+--- linux-2.6.0/drivers/base/node.c    2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/base/node.c     2003-12-28 23:22:10.000000000 -0800
+@@ -18,18 +18,16 @@ static struct sysdev_class node_class = 
+ static ssize_t node_read_cpumap(struct sys_device * dev, char * buf)
+ {
+       struct node *node_dev = to_node(dev);
+-      cpumask_t tmp = node_dev->cpumap;
+-      int k, len = 0;
++      cpumask_t mask = node_dev->cpumap;
++      int len;
+-      for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
+-              int j = sprintf(buf, "%04hx", (u16)cpus_coerce(tmp));
+-              len += j;
+-              buf += j;
+-              cpus_shift_right(tmp, tmp, 16);
+-      }
+-        len += sprintf(buf, "\n");
++      /* FIXME - someone should pass us a buffer size (count) or
++       * use seq_file or something to avoid buffer overrun risk. */
++      len = cpumask_snprintf(buf, 99 /* XXX FIXME */, mask);
++      len += sprintf(buf + len, "\n");
+       return len;
+ }
++
+ static SYSDEV_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
+ #define K(x) ((x) << (PAGE_SHIFT - 10))
+--- linux-2.6.0/drivers/base/platform.c        2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/base/platform.c 2003-12-28 23:22:30.000000000 -0800
+@@ -14,8 +14,8 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+-struct device legacy_bus = {
+-      .bus_id         = "legacy",
++struct device platform_bus = {
++      .bus_id         = "platform",
+ };
+ /**
+@@ -29,7 +29,7 @@ int platform_device_register(struct plat
+               return -EINVAL;
+       if (!pdev->dev.parent)
+-              pdev->dev.parent = &legacy_bus;
++              pdev->dev.parent = &platform_bus;
+       pdev->dev.bus = &platform_bus_type;
+       
+@@ -105,11 +105,11 @@ struct bus_type platform_bus_type = {
+ int __init platform_bus_init(void)
+ {
+-      device_register(&legacy_bus);
++      device_register(&platform_bus);
+       return bus_register(&platform_bus_type);
+ }
+-EXPORT_SYMBOL(legacy_bus);
++EXPORT_SYMBOL(platform_bus);
+ EXPORT_SYMBOL(platform_bus_type);
+ EXPORT_SYMBOL(platform_device_register);
+ EXPORT_SYMBOL(platform_device_unregister);
+--- linux-2.6.0/drivers/block/acsi.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/acsi.c    2003-12-28 23:21:17.000000000 -0800
+@@ -359,10 +359,9 @@ static void copy_from_acsibuffer( void )
+ static void do_end_requests( void );
+ static void do_acsi_request( request_queue_t * );
+ static void redo_acsi_request( void );
+-static int acsi_ioctl( struct inode *inode, struct file *file, unsigned int
++static int acsi_ioctl(struct block_device *bdev, struct file *file, unsigned int
+                        cmd, unsigned long arg );
+-static int acsi_open( struct inode * inode, struct file * filp );
+-static int acsi_release( struct inode * inode, struct file * file );
++static int acsi_open(struct block_device *bdev, struct file *filp);
+ static void acsi_prevent_removal(struct acsi_info_struct *aip, int flag );
+ static int acsi_change_blk_size( int target, int lun);
+ static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd );
+@@ -1081,10 +1080,10 @@ static void redo_acsi_request( void )
+  ***********************************************************************/
+-static int acsi_ioctl( struct inode *inode, struct file *file,
+-                                         unsigned int cmd, unsigned long arg )
++static int acsi_ioctl(struct block_device *bdev, struct file *file,
++                    unsigned int cmd, unsigned long arg )
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
++      struct gendisk *disk = bdev->bd_disk;
+       struct acsi_info_struct *aip = disk->private_data;
+       switch (cmd) {
+         case HDIO_GETGEO:
+@@ -1096,7 +1095,7 @@ static int acsi_ioctl( struct inode *ino
+           put_user( 64, &geo->heads );
+           put_user( 32, &geo->sectors );
+           put_user( aip->size >> 11, &geo->cylinders );
+-              put_user(get_start_sect(inode->i_bdev), &geo->start);
++              put_user(get_start_sect(bdev), &geo->start);
+               return 0;
+         }
+         case SCSI_IOCTL_GET_IDLUN:
+@@ -1126,16 +1125,16 @@ static int acsi_ioctl( struct inode *ino
+  *
+  */
+-static int acsi_open( struct inode * inode, struct file * filp )
++static int acsi_open(struct block_device *bdev, struct file *filp)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
++      struct gendisk *disk = bdev->bd_disk;
+       struct acsi_info_struct *aip = disk->private_data;
+       if (aip->access_count == 0 && aip->removable) {
+ #if 0
+               aip->changed = 1;       /* safety first */
+ #endif
+-              check_disk_change( inode->i_bdev );
++              check_disk_change(bdev);
+               if (aip->changed)       /* revalidate was not successful (no medium) */
+                       return -ENXIO;
+               acsi_prevent_removal(aip, 1);
+@@ -1143,10 +1142,11 @@ static int acsi_open( struct inode * ino
+       aip->access_count++;
+       if (filp && filp->f_mode) {
+-              check_disk_change( inode->i_bdev );
++              check_disk_change(bdev);
+               if (filp->f_mode & 2) {
+                       if (aip->read_only) {
+-                              acsi_release( inode, filp );
++                              if (--aip->access_count == 0 && aip->removable)
++                                      acsi_prevent_removal(aip, 0);
+                               return -EROFS;
+                       }
+               }
+@@ -1160,9 +1160,8 @@ static int acsi_open( struct inode * ino
+  * be forgotten about...
+  */
+-static int acsi_release( struct inode * inode, struct file * file )
++static int acsi_release(struct gendisk *disk)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct acsi_info_struct *aip = disk->private_data;
+       if (--aip->access_count == 0 && aip->removable)
+               acsi_prevent_removal(aip, 0);
+@@ -1328,8 +1327,6 @@ static int acsi_mode_sense( int target, 
+  ********************************************************************/
+-extern struct block_device_operations acsi_fops;
+-
+ static struct gendisk *acsi_gendisk[MAX_DEV];
+ #define MAX_SCSI_DEVICE_CODE 10
+--- linux-2.6.0/drivers/block/amiflop.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/amiflop.c 2003-12-28 23:21:17.000000000 -0800
+@@ -1434,10 +1434,11 @@ static void do_fd_request(request_queue_
+       redo_fd_request();
+ }
+-static int fd_ioctl(struct inode *inode, struct file *filp,
++static int fd_ioctl(struct block_device *bdev, struct file *filp,
+                   unsigned int cmd, unsigned long param)
+ {
+-      int drive = iminor(inode) & 3;
++      struct amiga_floppy_struct *floppy = bdev->bd_disk->private_data;
++      int drive = floppy - unit;
+       static struct floppy_struct getprm;
+       switch(cmd){
+@@ -1459,7 +1460,7 @@ static int fd_ioctl(struct inode *inode,
+                       rel_fdc();
+                       return -EBUSY;
+               }
+-              fsync_bdev(inode->i_bdev);
++              fsync_bdev(bdev);
+               if (fd_motor_on(drive) == 0) {
+                       rel_fdc();
+                       return -ENODEV;
+@@ -1488,7 +1489,7 @@ static int fd_ioctl(struct inode *inode,
+               break;
+       case FDFMTEND:
+               floppy_off(drive);
+-              invalidate_bdev(inode->i_bdev, 0);
++              invalidate_bdev(bdev, 0);
+               break;
+       case FDGETPRM:
+               memset((void *)&getprm, 0, sizeof (getprm));
+@@ -1559,10 +1560,11 @@ static void fd_probe(int dev)
+  * /dev/PS0 etc), and disallows simultaneous access to the same
+  * drive with different device numbers.
+  */
+-static int floppy_open(struct inode *inode, struct file *filp)
++static int floppy_open(struct block_device *bdev, struct file *filp)
+ {
+-      int drive = iminor(inode) & 3;
+-      int system =  (iminor(inode) & 4) >> 2;
++      struct amiga_floppy_struct *p = bdev->bd_disk->private_data;
++      int drive = p - unit;
++      int system =  (MINOR(bdev->bd_dev) & 4) >> 2;
+       int old_dev;
+       unsigned long flags;
+@@ -1572,7 +1574,7 @@ static int floppy_open(struct inode *ino
+               return -EBUSY;
+       if (filp && filp->f_mode & 3) {
+-              check_disk_change(inode->i_bdev);
++              check_disk_change(bdev);
+               if (filp->f_mode & 2 ) {
+                       int wrprot;
+@@ -1607,9 +1609,10 @@ static int floppy_open(struct inode *ino
+       return 0;
+ }
+-static int floppy_release(struct inode * inode, struct file * filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-      int drive = iminor(inode) & 3;
++      struct amiga_floppy_struct *p = disk->private_data;
++      int drive = p - unit;
+       if (unit[drive].dirty == 1) {
+               del_timer (flush_track_timer + drive);
+--- linux-2.6.0/drivers/block/as-iosched.c     2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/block/as-iosched.c      2003-12-28 23:21:59.000000000 -0800
+@@ -70,6 +70,7 @@
+ /* Bits in as_io_context.state */
+ enum as_io_states {
+       AS_TASK_RUNNING=0,      /* Process has not exitted */
++      AS_TASK_IOSTARTED,      /* Process has started some IO */
+       AS_TASK_IORUNNING,      /* Process has completed some IO */
+ };
+@@ -99,7 +100,14 @@ struct as_data {
+       sector_t last_sector[2];        /* last REQ_SYNC & REQ_ASYNC sectors */
+       struct list_head *dispatch;     /* driver dispatch queue */
+       struct list_head *hash;         /* request hash */
+-      unsigned long new_success; /* anticipation success on new proc */
++
++      unsigned long exit_prob;        /* probability a task will exit while
++                                         being waited on */
++      unsigned long new_ttime_total;  /* mean thinktime on new proc */
++      unsigned long new_ttime_mean;
++      u64 new_seek_total;             /* mean seek on new proc */
++      sector_t new_seek_mean;
++
+       unsigned long current_batch_expires;
+       unsigned long last_check_fifo[2];
+       int changed_batch;              /* 1: waiting for old batch to end */
+@@ -137,6 +145,10 @@ enum arq_state {
+                                  scheduler */
+       AS_RQ_DISPATCHED,       /* On the dispatch list. It belongs to the
+                                  driver now */
++      AS_RQ_PRESCHED,         /* Debug poisoning for requests being used */
++      AS_RQ_REMOVED,
++      AS_RQ_MERGED,
++      AS_RQ_POSTSCHED,        /* when they shouldn't be */
+ };
+ struct as_rq {
+@@ -183,6 +195,7 @@ static void free_as_io_context(struct as
+ /* Called when the task exits */
+ static void exit_as_io_context(struct as_io_context *aic)
+ {
++      WARN_ON(!test_bit(AS_TASK_RUNNING, &aic->state));
+       clear_bit(AS_TASK_RUNNING, &aic->state);
+ }
+@@ -585,18 +598,11 @@ static void as_antic_stop(struct as_data
+       int status = ad->antic_status;
+       if (status == ANTIC_WAIT_REQ || status == ANTIC_WAIT_NEXT) {
+-              struct as_io_context *aic;
+-
+               if (status == ANTIC_WAIT_NEXT)
+                       del_timer(&ad->antic_timer);
+               ad->antic_status = ANTIC_FINISHED;
+               /* see as_work_handler */
+               kblockd_schedule_work(&ad->antic_work);
+-
+-              aic = ad->io_context->aic;
+-              if (aic->seek_samples == 0)
+-                      /* new process */
+-                      ad->new_success = (ad->new_success * 3) / 4 + 256;
+       }
+ }
+@@ -612,14 +618,15 @@ static void as_antic_timeout(unsigned lo
+       spin_lock_irqsave(q->queue_lock, flags);
+       if (ad->antic_status == ANTIC_WAIT_REQ
+                       || ad->antic_status == ANTIC_WAIT_NEXT) {
+-              struct as_io_context *aic;
++              struct as_io_context *aic = ad->io_context->aic;
++
+               ad->antic_status = ANTIC_FINISHED;
+               kblockd_schedule_work(&ad->antic_work);
+-              aic = ad->io_context->aic;
+-              if (aic->seek_samples == 0)
+-                      /* new process */
+-                      ad->new_success = (ad->new_success * 3) / 4;
++              if (aic->ttime_samples == 0) {
++                      /* process anticipated on has exitted or timed out*/
++                      ad->exit_prob = (7*ad->exit_prob + 256)/8;
++              }
+       }
+       spin_unlock_irqrestore(q->queue_lock, flags);
+ }
+@@ -633,7 +640,7 @@ static int as_close_req(struct as_data *
+       unsigned long delay;    /* milliseconds */
+       sector_t last = ad->last_sector[ad->batch_data_dir];
+       sector_t next = arq->request->sector;
+-      sector_t delta; /* acceptable close offset (in sectors) */
++      sector_t delta; /* acceptable close offset (in sectors) */
+       if (ad->antic_status == ANTIC_OFF || !ad->ioc_finished)
+               delay = 0;
+@@ -650,6 +657,7 @@ static int as_close_req(struct as_data *
+       return (last - (delta>>1) <= next) && (next <= last + delta);
+ }
++static void as_update_thinktime(struct as_data *ad, struct as_io_context *aic, unsigned long ttime);
+ /*
+  * as_can_break_anticipation returns true if we have been anticipating this
+  * request.
+@@ -667,9 +675,27 @@ static int as_can_break_anticipation(str
+ {
+       struct io_context *ioc;
+       struct as_io_context *aic;
++      sector_t s;
++
++      ioc = ad->io_context;
++      BUG_ON(!ioc);
++
++      if (arq && ioc == arq->io_context) {
++              /* request from same process */
++              return 1;
++      }
+       if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, arq)) {
+               /* close request */
++              struct as_io_context *aic = ioc->aic;
++              if (aic) {
++                      unsigned long thinktime;
++                      spin_lock(&aic->lock);
++                      thinktime = jiffies - aic->last_end_request;
++                      aic->last_end_request = jiffies;
++                      as_update_thinktime(ad, aic, thinktime);
++                      spin_unlock(&aic->lock);
++              }
+               return 1;
+       }
+@@ -681,20 +707,14 @@ static int as_can_break_anticipation(str
+               return 1;
+       }
+-      ioc = ad->io_context;
+-      BUG_ON(!ioc);
+-
+-      if (arq && ioc == arq->io_context) {
+-              /* request from same process */
+-              return 1;
+-      }
+-
+       aic = ioc->aic;
+       if (!aic)
+               return 0;
+       if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
+               /* process anticipated on has exitted */
++              if (aic->ttime_samples == 0)
++                      ad->exit_prob = (7*ad->exit_prob + 256)/8;
+               return 1;
+       }
+@@ -708,28 +728,36 @@ static int as_can_break_anticipation(str
+               return 1;
+       }
+-      if (ad->new_success < 256 &&
+-                      (aic->seek_samples == 0 || aic->ttime_samples == 0)) {
+-              /*
+-               * Process has just started IO and we have a bad history of
+-               * success anticipating on new processes!
+-               */
+-              return 1;
+-      }
+-
+-      if (aic->ttime_mean > ad->antic_expire) {
++      if (aic->ttime_samples == 0) {
++              if (ad->new_ttime_mean > ad->antic_expire)
++                      return 1;
++              if (ad->exit_prob > 128)
++                      return 1;
++      } else if (aic->ttime_mean > ad->antic_expire) {
+               /* the process thinks too much between requests */
+               return 1;
+       }
+-      if (arq && aic->seek_samples) {
+-              sector_t s;
+-              if (ad->last_sector[REQ_SYNC] < arq->request->sector)
+-                      s = arq->request->sector - ad->last_sector[REQ_SYNC];
+-              else
+-                      s = ad->last_sector[REQ_SYNC] - arq->request->sector;
++      if (!arq)
++              return 0;
++
++      if (ad->last_sector[REQ_SYNC] < arq->request->sector)
++              s = arq->request->sector - ad->last_sector[REQ_SYNC];
++      else
++              s = ad->last_sector[REQ_SYNC] - arq->request->sector;
++
++      if (aic->seek_samples == 0) {
++              /*
++               * Process has just started IO. Use past statistics to
++               * guage success possibility
++               */
++              if (ad->new_seek_mean/2 > s) {
++                      /* this request is better than what we're expecting */
++                      return 1;
++              }
+-              if (aic->seek_mean > (s>>1)) {
++      } else {
++              if (aic->seek_mean/2 > s) {
+                       /* this request is better than what we're expecting */
+                       return 1;
+               }
+@@ -774,12 +802,51 @@ static int as_can_anticipate(struct as_d
+       return 1;
+ }
++static void as_update_thinktime(struct as_data *ad, struct as_io_context *aic, unsigned long ttime)
++{
++      /* fixed point: 1.0 == 1<<8 */
++      if (aic->ttime_samples == 0) {
++              ad->new_ttime_total = (7*ad->new_ttime_total + 256*ttime) / 8;
++              ad->new_ttime_mean = ad->new_ttime_total / 256;
++
++              ad->exit_prob = (7*ad->exit_prob)/8;
++      }
++      aic->ttime_samples = (7*aic->ttime_samples + 256) / 8;
++      aic->ttime_total = (7*aic->ttime_total + 256*ttime) / 8;
++      aic->ttime_mean = (aic->ttime_total + 128) / aic->ttime_samples;
++}
++
++static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic, sector_t sdist)
++{
++      u64 total;
++
++      if (aic->seek_samples == 0) {
++              ad->new_seek_total = (7*ad->new_seek_total + 256*(u64)sdist)/8;
++              ad->new_seek_mean = ad->new_seek_total / 256;
++      }
++
++      /*
++       * Don't allow the seek distance to get too large from the
++       * odd fragment, pagein, etc
++       */
++      if (aic->seek_samples <= 60) /* second&third seek */
++              sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*1024);
++      else
++              sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*64);
++
++      aic->seek_samples = (7*aic->seek_samples + 256) / 8;
++      aic->seek_total = (7*aic->seek_total + (u64)256*sdist) / 8;
++      total = aic->seek_total + (aic->seek_samples/2);
++      do_div(total, aic->seek_samples);
++      aic->seek_mean = (sector_t)total;
++}
++
+ /*
+  * as_update_iohist keeps a decaying histogram of IO thinktimes, and
+  * updates @aic->ttime_mean based on that. It is called when a new
+  * request is queued.
+  */
+-static void as_update_iohist(struct as_io_context *aic, struct request *rq)
++static void as_update_iohist(struct as_data *ad, struct as_io_context *aic, struct request *rq)
+ {
+       struct as_rq *arq = RQ_DATA(rq);
+       int data_dir = arq->is_sync;
+@@ -790,60 +857,29 @@ static void as_update_iohist(struct as_i
+               return;
+       if (data_dir == REQ_SYNC) {
++              unsigned long in_flight = atomic_read(&aic->nr_queued)
++                                      + atomic_read(&aic->nr_dispatched);
+               spin_lock(&aic->lock);
+-
+-              if (test_bit(AS_TASK_IORUNNING, &aic->state)
+-                              && !atomic_read(&aic->nr_queued)
+-                              && !atomic_read(&aic->nr_dispatched)) {
++              if (test_bit(AS_TASK_IORUNNING, &aic->state) ||
++                      test_bit(AS_TASK_IOSTARTED, &aic->state)) {
+                       /* Calculate read -> read thinktime */
+-                      thinktime = jiffies - aic->last_end_request;
+-                      thinktime = min(thinktime, MAX_THINKTIME-1);
+-                      /* fixed point: 1.0 == 1<<8 */
+-                      aic->ttime_samples += 256;
+-                      aic->ttime_total += 256*thinktime;
+-                      if (aic->ttime_samples)
+-                              /* fixed point factor is cancelled here */
+-                              aic->ttime_mean = (aic->ttime_total + 128)
+-                                                      / aic->ttime_samples;
+-                      aic->ttime_samples = (aic->ttime_samples>>1)
+-                                              + (aic->ttime_samples>>2);
+-                      aic->ttime_total = (aic->ttime_total>>1)
+-                                              + (aic->ttime_total>>2);
+-              }
+-
+-              /* Calculate read -> read seek distance */
+-              if (!aic->seek_samples)
+-                      seek_dist = 0;
+-              else if (aic->last_request_pos < rq->sector)
+-                      seek_dist = rq->sector - aic->last_request_pos;
+-              else
+-                      seek_dist = aic->last_request_pos - rq->sector;
+-
++                      if (test_bit(AS_TASK_IORUNNING, &aic->state)
++                                                      && in_flight == 0) {
++                              thinktime = jiffies - aic->last_end_request;
++                              thinktime = min(thinktime, MAX_THINKTIME-1);
++                      } else
++                              thinktime = 0;
++                      as_update_thinktime(ad, aic, thinktime);
++
++                      /* Calculate read -> read seek distance */
++                      if (aic->last_request_pos < rq->sector)
++                              seek_dist = rq->sector - aic->last_request_pos;
++                      else
++                              seek_dist = aic->last_request_pos - rq->sector;
++                      as_update_seekdist(ad, aic, seek_dist);
++              }
+               aic->last_request_pos = rq->sector + rq->nr_sectors;
+-
+-              /*
+-               * Don't allow the seek distance to get too large from the
+-               * odd fragment, pagein, etc
+-               */
+-              if (aic->seek_samples < 400) /* second&third seek */
+-                      seek_dist = min(seek_dist, (aic->seek_mean * 4)
+-                                                      + 2*1024*1024);
+-              else
+-                      seek_dist = min(seek_dist, (aic->seek_mean * 4)
+-                                                      + 2*1024*64);
+-
+-              aic->seek_samples += 256;
+-              aic->seek_total += (u64)256*seek_dist;
+-              if (aic->seek_samples) {
+-                      u64 total = aic->seek_total + (aic->seek_samples>>1);
+-                      do_div(total, aic->seek_samples);
+-                      aic->seek_mean = (sector_t)total;
+-              }
+-              aic->seek_samples = (aic->seek_samples>>1)
+-                                      + (aic->seek_samples>>2);
+-              aic->seek_total = (aic->seek_total>>1)
+-                                      + (aic->seek_total>>2);
+-
++              set_bit(AS_TASK_IOSTARTED, &aic->state);
+               spin_unlock(&aic->lock);
+       }
+ }
+@@ -908,15 +944,25 @@ static void as_completed_request(request
+ {
+       struct as_data *ad = q->elevator.elevator_data;
+       struct as_rq *arq = RQ_DATA(rq);
+-      struct as_io_context *aic;
+       WARN_ON(!list_empty(&rq->queuelist));
+-      if (unlikely(arq->state != AS_RQ_DISPATCHED))
+-              return;
++      if (arq->state == AS_RQ_PRESCHED) {
++              WARN_ON(arq->io_context);
++              goto out;
++      }
++
++      if (arq->state == AS_RQ_MERGED)
++              goto out_ioc;
++
++      if (arq->state != AS_RQ_REMOVED) {
++              printk("arq->state %d\n", arq->state);
++              WARN_ON(1);
++              goto out;
++      }
+       if (!blk_fs_request(rq))
+-              return;
++              goto out;
+       if (ad->changed_batch && ad->nr_dispatched == 1) {
+               kblockd_schedule_work(&ad->antic_work);
+@@ -940,10 +986,7 @@ static void as_completed_request(request
+               ad->new_batch = 0;
+       }
+-      if (!arq->io_context)
+-              return;
+-
+-      if (ad->io_context == arq->io_context) {
++      if (ad->io_context == arq->io_context && ad->io_context) {
+               ad->antic_start = jiffies;
+               ad->ioc_finished = 1;
+               if (ad->antic_status == ANTIC_WAIT_REQ) {
+@@ -955,18 +998,23 @@ static void as_completed_request(request
+               }
+       }
+-      aic = arq->io_context->aic;
+-      if (!aic)
+-              return;
++out_ioc:
++      if (!arq->io_context)
++              goto out;
+-      spin_lock(&aic->lock);
+       if (arq->is_sync == REQ_SYNC) {
+-              set_bit(AS_TASK_IORUNNING, &aic->state);
+-              aic->last_end_request = jiffies;
++              struct as_io_context *aic = arq->io_context->aic;
++              if (aic) {
++                      spin_lock(&aic->lock);
++                      set_bit(AS_TASK_IORUNNING, &aic->state);
++                      aic->last_end_request = jiffies;
++                      spin_unlock(&aic->lock);
++              }
+       }
+-      spin_unlock(&aic->lock);
+       put_io_context(arq->io_context);
++out:
++      arq->state = AS_RQ_POSTSCHED;
+ }
+ /*
+@@ -1035,14 +1083,14 @@ static void as_remove_request(request_qu
+       struct as_rq *arq = RQ_DATA(rq);
+       if (unlikely(arq->state == AS_RQ_NEW))
+-              return;
+-
+-      if (!arq) {
+-              WARN_ON(1);
+-              return;
+-      }
++              goto out;
+       if (ON_RB(&arq->rb_node)) {
++              if (arq->state != AS_RQ_QUEUED) {
++                      printk("arq->state %d\n", arq->state);
++                      WARN_ON(1);
++                      goto out;
++              }
+               /*
+                * We'll lose the aliased request(s) here. I don't think this
+                * will ever happen, but if it does, hopefully someone will
+@@ -1050,8 +1098,16 @@ static void as_remove_request(request_qu
+                */
+               WARN_ON(!list_empty(&rq->queuelist));
+               as_remove_queued_request(q, rq);
+-      } else
++      } else {
++              if (arq->state != AS_RQ_DISPATCHED) {
++                      printk("arq->state %d\n", arq->state);
++                      WARN_ON(1);
++                      goto out;
++              }
+               as_remove_dispatched_request(q, rq);
++      }
++out:
++      arq->state = AS_RQ_REMOVED;
+ }
+ /*
+@@ -1229,9 +1285,9 @@ static int as_dispatch_request(struct as
+                        */
+                       goto dispatch_writes;
+-              if (ad->batch_data_dir == REQ_ASYNC) {
++              if (ad->batch_data_dir == REQ_ASYNC) {
+                       WARN_ON(ad->new_batch);
+-                      ad->changed_batch = 1;
++                      ad->changed_batch = 1;
+               }
+               ad->batch_data_dir = REQ_SYNC;
+               arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next);
+@@ -1247,8 +1303,8 @@ static int as_dispatch_request(struct as
+ dispatch_writes:
+               BUG_ON(RB_EMPTY(&ad->sort_list[REQ_ASYNC]));
+-              if (ad->batch_data_dir == REQ_SYNC) {
+-                      ad->changed_batch = 1;
++              if (ad->batch_data_dir == REQ_SYNC) {
++                      ad->changed_batch = 1;
+                       /*
+                        * new_batch might be 1 when the queue runs out of
+@@ -1291,8 +1347,6 @@ fifo_expired:
+                       ad->new_batch = 1;
+               ad->changed_batch = 0;
+-
+-              arq->request->flags |= REQ_SOFTBARRIER;
+       }
+       /*
+@@ -1369,8 +1423,8 @@ static void as_add_request(struct as_dat
+       arq->io_context = as_get_io_context();
+       if (arq->io_context) {
++              as_update_iohist(ad, arq->io_context->aic, arq->request);
+               atomic_inc(&arq->io_context->aic->nr_queued);
+-              as_update_iohist(arq->io_context->aic, arq->request);
+       }
+       alias = as_add_arq_rb(ad, arq);
+@@ -1391,6 +1445,7 @@ static void as_add_request(struct as_dat
+       } else {
+               as_add_aliased_request(ad, arq, alias);
++
+               /*
+                * have we been anticipating this request?
+                * or does it come from the same process as the one we are
+@@ -1416,6 +1471,11 @@ static void as_requeue_request(request_q
+       struct as_rq *arq = RQ_DATA(rq);
+       if (arq) {
++              if (arq->state != AS_RQ_REMOVED) {
++                      printk("arq->state %d\n", arq->state);
++                      WARN_ON(1);
++              }
++
+               arq->state = AS_RQ_DISPATCHED;
+               if (arq->io_context && arq->io_context->aic)
+                       atomic_inc(&arq->io_context->aic->nr_dispatched);
+@@ -1427,8 +1487,6 @@ static void as_requeue_request(request_q
+       /* Stop anticipating - let this request get through */
+       as_antic_stop(ad);
+-
+-      return;
+ }
+ static void
+@@ -1437,10 +1495,20 @@ as_insert_request(request_queue_t *q, st
+       struct as_data *ad = q->elevator.elevator_data;
+       struct as_rq *arq = RQ_DATA(rq);
++      if (arq) {
++              if (arq->state != AS_RQ_PRESCHED) {
++                      printk("arq->state: %d\n", arq->state);
++                      WARN_ON(1);
++              }
++              arq->state = AS_RQ_NEW;
++      }
++
+       /* barriers must flush the reorder queue */
+       if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
+-                      && where == ELEVATOR_INSERT_SORT))
++                      && where == ELEVATOR_INSERT_SORT)) {
++              WARN_ON(1);
+               where = ELEVATOR_INSERT_BACK;
++      }
+       switch (where) {
+               case ELEVATOR_INSERT_BACK:
+@@ -1675,7 +1743,8 @@ as_merged_requests(request_queue_t *q, s
+        * kill knowledge of next, this one is a goner
+        */
+       as_remove_queued_request(q, next);
+-      put_io_context(anext->io_context);
++
++      anext->state = AS_RQ_MERGED;
+ }
+ /*
+@@ -1708,6 +1777,11 @@ static void as_put_request(request_queue
+               return;
+       }
++      if (arq->state != AS_RQ_POSTSCHED && arq->state != AS_RQ_PRESCHED) {
++              printk("arq->state %d\n", arq->state);
++              WARN_ON(1);
++      }
++
+       mempool_free(arq, ad->arq_pool);
+       rq->elevator_private = NULL;
+ }
+@@ -1721,7 +1795,7 @@ static int as_set_request(request_queue_
+               memset(arq, 0, sizeof(*arq));
+               RB_CLEAR(&arq->rb_node);
+               arq->request = rq;
+-              arq->state = AS_RQ_NEW;
++              arq->state = AS_RQ_PRESCHED;
+               arq->io_context = NULL;
+               INIT_LIST_HEAD(&arq->hash);
+               arq->on_hash = 0;
+@@ -1823,8 +1897,6 @@ static int as_init(request_queue_t *q, e
+       if (ad->write_batch_count < 2)
+               ad->write_batch_count = 2;
+-      ad->new_success = 512;
+-
+       return 0;
+ }
+@@ -1860,6 +1932,17 @@ as_var_store(unsigned long *var, const c
+       return count;
+ }
++static ssize_t as_est_show(struct as_data *ad, char *page)
++{
++      int pos = 0;
++
++      pos += sprintf(page+pos, "%lu %% exit probability\n", 100*ad->exit_prob/256);
++      pos += sprintf(page+pos, "%lu ms new thinktime\n", ad->new_ttime_mean);
++      pos += sprintf(page+pos, "%llu sectors new seek distance\n", (unsigned long long)ad->new_seek_mean);
++
++      return pos;
++}
++
+ #define SHOW_FUNCTION(__FUNC, __VAR)                                  \
+ static ssize_t __FUNC(struct as_data *ad, char *page)         \
+ {                                                                     \
+@@ -1891,6 +1974,10 @@ STORE_FUNCTION(as_write_batchexpire_stor
+                       &ad->batch_expire[REQ_ASYNC], 0, INT_MAX);
+ #undef STORE_FUNCTION
++static struct as_fs_entry as_est_entry = {
++      .attr = {.name = "est_time", .mode = S_IRUGO },
++      .show = as_est_show,
++};
+ static struct as_fs_entry as_readexpire_entry = {
+       .attr = {.name = "read_expire", .mode = S_IRUGO | S_IWUSR },
+       .show = as_readexpire_show,
+@@ -1918,6 +2005,7 @@ static struct as_fs_entry as_write_batch
+ };
+ static struct attribute *default_attrs[] = {
++      &as_est_entry.attr,
+       &as_readexpire_entry.attr,
+       &as_writeexpire_entry.attr,
+       &as_anticexpire_entry.attr,
+--- linux-2.6.0/drivers/block/ataflop.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/ataflop.c 2003-12-28 23:21:17.000000000 -0800
+@@ -364,13 +364,12 @@ static void finish_fdc_done( int dummy )
+ static __inline__ void copy_buffer( void *from, void *to);
+ static void setup_req_params( int drive );
+ static void redo_fd_request( void);
+-static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int
++static int fd_ioctl(struct block_device *bdev, struct file *filp, unsigned int
+                      cmd, unsigned long param);
+ static void fd_probe( int drive );
+ static int fd_test_drive_present( int drive );
+ static void config_types( void );
+-static int floppy_open( struct inode *inode, struct file *filp );
+-static int floppy_release( struct inode * inode, struct file * filp );
++static int floppy_open(struct block_device *bdev, struct file *filp );
+ /************************* End of Prototypes **************************/
+@@ -1496,10 +1495,10 @@ void do_fd_request(request_queue_t * q)
+       atari_enable_irq( IRQ_MFP_FDC );
+ }
+-static int fd_ioctl(struct inode *inode, struct file *filp,
++static int fd_ioctl(struct block_device *bdev, struct file *filp,
+                   unsigned int cmd, unsigned long param)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
++      struct gendisk *disk = bdev->bd_disk;
+       struct atari_floppy_struct *floppy = disk->private_data;
+       int drive = floppy - unit;
+       int type = floppy->type;
+@@ -1673,7 +1672,7 @@ static int fd_ioctl(struct inode *inode,
+               /* invalidate the buffer track to force a reread */
+               BufferDrive = -1;
+               set_bit(drive, &fake_change);
+-              check_disk_change(inode->i_bdev);
++              check_disk_change(bdev);
+               return 0;
+       default:
+               return -EINVAL;
+@@ -1816,10 +1815,10 @@ static void __init config_types( void )
+  * drive with different device numbers.
+  */
+-static int floppy_open( struct inode *inode, struct file *filp )
++static int floppy_open(struct block_device *bdev, struct file *filp )
+ {
+-      struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data;
+-      int type  = iminor(inode) >> 2;
++      struct atari_floppy_struct *p = bdev->bd_disk->private_data;
++      int type  = MINOR(bdev->bd_dev) >> 2;
+       DPRINT(("fd_open: type=%d\n",type));
+       if (p->ref && p->type != type)
+@@ -1839,14 +1838,13 @@ static int floppy_open( struct inode *in
+               return 0;
+       if (filp->f_mode & 3) {
+-              check_disk_change(inode->i_bdev);
++              check_disk_change(bdev);
+               if (filp->f_mode & 2) {
+                       if (p->wpstat) {
+                               if (p->ref < 0)
+                                       p->ref = 0;
+                               else
+                                       p->ref--;
+-                              floppy_release(inode, filp);
+                               return -EROFS;
+                       }
+               }
+@@ -1855,9 +1853,9 @@ static int floppy_open( struct inode *in
+ }
+-static int floppy_release( struct inode * inode, struct file * filp )
++static int floppy_release(struct gendisk *disk)
+ {
+-      struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data;
++      struct atari_floppy_struct *p = disk->private_data;
+       if (p->ref < 0)
+               p->ref = 0;
+       else if (!p->ref--) {
+--- linux-2.6.0/drivers/block/cciss.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/cciss.c   2003-12-28 23:21:17.000000000 -0800
+@@ -112,9 +112,9 @@ static struct board_type products[] = {
+ static ctlr_info_t *hba[MAX_CTLR];
+ static void do_cciss_request(request_queue_t *q);
+-static int cciss_open(struct inode *inode, struct file *filep);
+-static int cciss_release(struct inode *inode, struct file *filep);
+-static int cciss_ioctl(struct inode *inode, struct file *filep, 
++static int cciss_open(struct block_device *bdev, struct file *filep);
++static int cciss_release(struct gendisk *disk);
++static int cciss_ioctl(struct block_device *bdev, struct file *filep,
+               unsigned int cmd, unsigned long arg);
+ static int revalidate_allvol(ctlr_info_t *host);
+@@ -362,13 +362,13 @@ static inline drive_info_struct *get_drv
+ /*
+  * Open.  Make sure the device is really there.
+  */
+-static int cciss_open(struct inode *inode, struct file *filep)
++static int cciss_open(struct block_device *bdev, struct file *filep)
+ {
+-      ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
+-      drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);
++      ctlr_info_t *host = get_host(bdev->bd_disk);
++      drive_info_struct *drv = get_drv(bdev->bd_disk);
+ #ifdef CCISS_DEBUG
+-      printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
++      printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name);
+ #endif /* CCISS_DEBUG */ 
+       /*
+@@ -378,7 +378,7 @@ static int cciss_open(struct inode *inod
+        * for "raw controller".
+        */
+       if (drv->nr_blocks == 0) {
+-              if (iminor(inode) != 0)
++              if (bdev != bdev->bd_contains || drv != host->drv)
+                       return -ENXIO;
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+@@ -390,13 +390,13 @@ static int cciss_open(struct inode *inod
+ /*
+  * Close.  Sync first.
+  */
+-static int cciss_release(struct inode *inode, struct file *filep)
++static int cciss_release(struct gendisk *disk)
+ {
+-      ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
+-      drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);
++      ctlr_info_t *host = get_host(disk);
++      drive_info_struct *drv = get_drv(disk);
+ #ifdef CCISS_DEBUG
+-      printk(KERN_DEBUG "cciss_release %s\n", inode->i_bdev->bd_disk->disk_name);
++      printk(KERN_DEBUG "cciss_release %s\n", disk->disk_name);
+ #endif /* CCISS_DEBUG */
+       drv->usage_count--;
+@@ -407,10 +407,9 @@ static int cciss_release(struct inode *i
+ /*
+  * ioctl 
+  */
+-static int cciss_ioctl(struct inode *inode, struct file *filep, 
++static int cciss_ioctl(struct block_device *bdev, struct file *filep,
+               unsigned int cmd, unsigned long arg)
+ {
+-      struct block_device *bdev = inode->i_bdev;
+       struct gendisk *disk = bdev->bd_disk;
+       ctlr_info_t *host = get_host(disk);
+       drive_info_struct *drv = get_drv(disk);
+@@ -433,7 +432,7 @@ static int cciss_ioctl(struct inode *ino
+                         driver_geo.sectors = 0x3f;
+                         driver_geo.cylinders = (int)drv->nr_blocks / (0xff*0x3f);
+                 }
+-                driver_geo.start= get_start_sect(inode->i_bdev);
++                driver_geo.start= get_start_sect(bdev);
+                 if (copy_to_user((void *) arg, &driver_geo,
+                                 sizeof( struct hd_geometry)))
+                         return  -EFAULT;
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/block/cfq-iosched.c     2003-12-28 23:21:35.000000000 -0800
+@@ -0,0 +1,707 @@
++/*
++ *  linux/drivers/block/cfq-iosched.c
++ *
++ *  CFQ, or complete fairness queueing, disk scheduler.
++ *
++ *  Based on ideas from a previously unfinished io
++ *  scheduler (round robin per-process disk scheduling) and Andrea Arcangeli.
++ *
++ *  Copyright (C) 2003 Jens Axboe <axboe@suse.de>
++ */
++#include <linux/kernel.h>
++#include <linux/fs.h>
++#include <linux/blkdev.h>
++#include <linux/elevator.h>
++#include <linux/bio.h>
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/compiler.h>
++#include <linux/hash.h>
++#include <linux/rbtree.h>
++#include <linux/mempool.h>
++
++/*
++ * tunables
++ */
++static int cfq_quantum = 4;
++static int cfq_queued = 8;
++
++#define CFQ_QHASH_SHIFT               6
++#define CFQ_QHASH_ENTRIES     (1 << CFQ_QHASH_SHIFT)
++#define list_entry_qhash(entry)       list_entry((entry), struct cfq_queue, cfq_hash)
++
++#define CFQ_MHASH_SHIFT               8
++#define CFQ_MHASH_BLOCK(sec)  ((sec) >> 3)
++#define CFQ_MHASH_ENTRIES     (1 << CFQ_MHASH_SHIFT)
++#define CFQ_MHASH_FN(sec)     (hash_long(CFQ_MHASH_BLOCK((sec)),CFQ_MHASH_SHIFT))
++#define ON_MHASH(crq)         !list_empty(&(crq)->hash)
++#define rq_hash_key(rq)               ((rq)->sector + (rq)->nr_sectors)
++#define list_entry_hash(ptr)  list_entry((ptr), struct cfq_rq, hash)
++
++#define list_entry_cfqq(ptr)  list_entry((ptr), struct cfq_queue, cfq_list)
++
++#define RQ_DATA(rq)           ((struct cfq_rq *) (rq)->elevator_private)
++
++static kmem_cache_t *crq_pool;
++static kmem_cache_t *cfq_pool;
++static mempool_t *cfq_mpool;
++
++struct cfq_data {
++      struct list_head rr_list;
++      struct list_head *dispatch;
++      struct list_head *cfq_hash;
++
++      struct list_head *crq_hash;
++
++      unsigned int busy_queues;
++      unsigned int max_queued;
++
++      mempool_t *crq_pool;
++};
++
++struct cfq_queue {
++      struct list_head cfq_hash;
++      struct list_head cfq_list;
++      struct rb_root sort_list;
++      int pid;
++      int queued[2];
++#if 0
++      /*
++       * with a simple addition like this, we can do io priorities. almost.
++       * does need a split request free list, too.
++       */
++      int io_prio
++#endif
++};
++
++struct cfq_rq {
++      struct rb_node rb_node;
++      sector_t rb_key;
++
++      struct request *request;
++
++      struct cfq_queue *cfq_queue;
++
++      struct list_head hash;
++};
++
++static void cfq_put_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq);
++static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *cfqd, int pid);
++static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq);
++
++/*
++ * lots of deadline iosched dupes, can be abstracted later...
++ */
++static inline void __cfq_del_crq_hash(struct cfq_rq *crq)
++{
++      list_del_init(&crq->hash);
++}
++
++static inline void cfq_del_crq_hash(struct cfq_rq *crq)
++{
++      if (ON_MHASH(crq))
++              __cfq_del_crq_hash(crq);
++}
++
++static void cfq_remove_merge_hints(request_queue_t *q, struct cfq_rq *crq)
++{
++      cfq_del_crq_hash(crq);
++
++      if (q->last_merge == crq->request)
++              q->last_merge = NULL;
++}
++
++static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq)
++{
++      struct request *rq = crq->request;
++
++      BUG_ON(ON_MHASH(crq));
++
++      list_add(&crq->hash, &cfqd->crq_hash[CFQ_MHASH_FN(rq_hash_key(rq))]);
++}
++
++static struct request *cfq_find_rq_hash(struct cfq_data *cfqd, sector_t offset)
++{
++      struct list_head *hash_list = &cfqd->crq_hash[CFQ_MHASH_FN(offset)];
++      struct list_head *entry, *next = hash_list->next;
++
++      while ((entry = next) != hash_list) {
++              struct cfq_rq *crq = list_entry_hash(entry);
++              struct request *__rq = crq->request;
++
++              next = entry->next;
++
++              BUG_ON(!ON_MHASH(crq));
++
++              if (!rq_mergeable(__rq)) {
++                      __cfq_del_crq_hash(crq);
++                      continue;
++              }
++
++              if (rq_hash_key(__rq) == offset)
++                      return __rq;
++      }
++
++      return NULL;
++}
++
++/*
++ * rb tree support functions
++ */
++#define RB_NONE               (2)
++#define RB_EMPTY(node)        ((node)->rb_node == NULL)
++#define RB_CLEAR(node)        ((node)->rb_color = RB_NONE)
++#define RB_CLEAR_ROOT(root)   ((root)->rb_node = NULL)
++#define ON_RB(node)   ((node)->rb_color != RB_NONE)
++#define rb_entry_crq(node)    rb_entry((node), struct cfq_rq, rb_node)
++#define rq_rb_key(rq)         (rq)->sector
++
++static inline void cfq_del_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
++{
++      if (ON_RB(&crq->rb_node)) {
++              cfqq->queued[rq_data_dir(crq->request)]--;
++              rb_erase(&crq->rb_node, &cfqq->sort_list);
++              crq->cfq_queue = NULL;
++      }
++}
++
++static struct cfq_rq *
++__cfq_add_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
++{
++      struct rb_node **p = &cfqq->sort_list.rb_node;
++      struct rb_node *parent = NULL;
++      struct cfq_rq *__crq;
++
++      while (*p) {
++              parent = *p;
++              __crq = rb_entry_crq(parent);
++
++              if (crq->rb_key < __crq->rb_key)
++                      p = &(*p)->rb_left;
++              else if (crq->rb_key > __crq->rb_key)
++                      p = &(*p)->rb_right;
++              else
++                      return __crq;
++      }
++
++      rb_link_node(&crq->rb_node, parent, p);
++      return 0;
++}
++
++static void
++cfq_add_crq_rb(struct cfq_data *cfqd, struct cfq_queue *cfqq,struct cfq_rq *crq)
++{
++      struct request *rq = crq->request;
++      struct cfq_rq *__alias;
++
++      crq->rb_key = rq_rb_key(rq);
++      cfqq->queued[rq_data_dir(rq)]++;
++retry:
++      __alias = __cfq_add_crq_rb(cfqq, crq);
++      if (!__alias) {
++              rb_insert_color(&crq->rb_node, &cfqq->sort_list);
++              crq->cfq_queue = cfqq;
++              return;
++      }
++
++      cfq_del_crq_rb(cfqq, __alias);
++      cfq_dispatch_sort(cfqd->dispatch, __alias);
++      goto retry;
++}
++
++static struct request *
++cfq_find_rq_rb(struct cfq_data *cfqd, sector_t sector)
++{
++      struct cfq_queue *cfqq = cfq_find_cfq_hash(cfqd, current->tgid);
++      struct rb_node *n;
++
++      if (!cfqq)
++              goto out;
++
++      n = cfqq->sort_list.rb_node;
++      while (n) {
++              struct cfq_rq *crq = rb_entry_crq(n);
++
++              if (sector < crq->rb_key)
++                      n = n->rb_left;
++              else if (sector > crq->rb_key)
++                      n = n->rb_right;
++              else
++                      return crq->request;
++      }
++
++out:
++      return NULL;
++}
++
++static void cfq_remove_request(request_queue_t *q, struct request *rq)
++{
++      struct cfq_data *cfqd = q->elevator.elevator_data;
++      struct cfq_rq *crq = RQ_DATA(rq);
++
++      if (crq) {
++              struct cfq_queue *cfqq = crq->cfq_queue;
++
++              cfq_remove_merge_hints(q, crq);
++              list_del_init(&rq->queuelist);
++
++              if (cfqq) {
++                      cfq_del_crq_rb(cfqq, crq);
++
++                      if (RB_EMPTY(&cfqq->sort_list))
++                              cfq_put_queue(cfqd, cfqq);
++              }
++      }
++}
++
++static int
++cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
++{
++      struct cfq_data *cfqd = q->elevator.elevator_data;
++      struct request *__rq;
++      int ret;
++
++      ret = elv_try_last_merge(q, bio);
++      if (ret != ELEVATOR_NO_MERGE) {
++              __rq = q->last_merge;
++              goto out_insert;
++      }
++
++      __rq = cfq_find_rq_hash(cfqd, bio->bi_sector);
++      if (__rq) {
++              BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
++
++              if (elv_rq_merge_ok(__rq, bio)) {
++                      ret = ELEVATOR_BACK_MERGE;
++                      goto out;
++              }
++      }
++
++      __rq = cfq_find_rq_rb(cfqd, bio->bi_sector + bio_sectors(bio));
++      if (__rq) {
++              if (elv_rq_merge_ok(__rq, bio)) {
++                      ret = ELEVATOR_FRONT_MERGE;
++                      goto out;
++              }
++      }
++
++      return ELEVATOR_NO_MERGE;
++out:
++      q->last_merge = __rq;
++out_insert:
++      *req = __rq;
++      return ret;
++}
++
++static void cfq_merged_request(request_queue_t *q, struct request *req)
++{
++      struct cfq_data *cfqd = q->elevator.elevator_data;
++      struct cfq_rq *crq = RQ_DATA(req);
++
++      cfq_del_crq_hash(crq);
++      cfq_add_crq_hash(cfqd, crq);
++
++      if (ON_RB(&crq->rb_node) && (rq_rb_key(req) != crq->rb_key)) {
++              struct cfq_queue *cfqq = crq->cfq_queue;
++
++              cfq_del_crq_rb(cfqq, crq);
++              cfq_add_crq_rb(cfqd, cfqq, crq);
++      }
++
++      q->last_merge = req;
++}
++
++static void
++cfq_merged_requests(request_queue_t *q, struct request *req,
++                  struct request *next)
++{
++      cfq_merged_request(q, req);
++      cfq_remove_request(q, next);
++}
++
++static void cfq_dispatch_sort(struct list_head *head, struct cfq_rq *crq)
++{
++      struct list_head *entry = head;
++      struct request *__rq;
++
++      if (!list_empty(head)) {
++              __rq = list_entry_rq(head->next);
++
++              if (crq->request->sector < __rq->sector) {
++                      entry = head->prev;
++                      goto link;
++              }
++      }
++
++      while ((entry = entry->prev) != head) {
++              __rq = list_entry_rq(entry);
++
++              if (crq->request->sector <= __rq->sector)
++                      break;
++      }
++
++link:
++      list_add_tail(&crq->request->queuelist, entry);
++}
++
++static inline void
++__cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd,
++                      struct cfq_queue *cfqq)
++{
++      struct cfq_rq *crq = rb_entry_crq(rb_first(&cfqq->sort_list));
++
++      cfq_del_crq_rb(cfqq, crq);
++      cfq_remove_merge_hints(q, crq);
++      cfq_dispatch_sort(cfqd->dispatch, crq);
++}
++
++static int cfq_dispatch_requests(request_queue_t *q, struct cfq_data *cfqd)
++{
++      struct cfq_queue *cfqq;
++      struct list_head *entry, *tmp;
++      int ret, queued, good_queues;
++
++      if (list_empty(&cfqd->rr_list))
++              return 0;
++
++      queued = ret = 0;
++restart:
++      good_queues = 0;
++      list_for_each_safe(entry, tmp, &cfqd->rr_list) {
++              cfqq = list_entry_cfqq(cfqd->rr_list.next);
++
++              BUG_ON(RB_EMPTY(&cfqq->sort_list));
++
++              __cfq_dispatch_requests(q, cfqd, cfqq);
++
++              if (RB_EMPTY(&cfqq->sort_list))
++                      cfq_put_queue(cfqd, cfqq);
++              else
++                      good_queues++;
++
++              queued++;
++              ret = 1;
++      }
++
++      if ((queued < cfq_quantum) && good_queues)
++              goto restart;
++
++      return ret;
++}
++
++static struct request *cfq_next_request(request_queue_t *q)
++{
++      struct cfq_data *cfqd = q->elevator.elevator_data;
++      struct request *rq;
++
++      if (!list_empty(cfqd->dispatch)) {
++              struct cfq_rq *crq;
++dispatch:
++              rq = list_entry_rq(cfqd->dispatch->next);
++
++              BUG_ON(q->last_merge == rq);
++              crq = RQ_DATA(rq);
++              if (crq)
++                      BUG_ON(ON_MHASH(crq));
++
++              return rq;
++      }
++
++      if (cfq_dispatch_requests(q, cfqd))
++              goto dispatch;
++
++      return NULL;
++}
++
++static inline struct cfq_queue *
++__cfq_find_cfq_hash(struct cfq_data *cfqd, int pid, const int hashval)
++{
++      struct list_head *hash_list = &cfqd->cfq_hash[hashval];
++      struct list_head *entry;
++
++      list_for_each(entry, hash_list) {
++              struct cfq_queue *__cfqq = list_entry_qhash(entry);
++
++              if (__cfqq->pid == pid)
++                      return __cfqq;
++      }
++
++      return NULL;
++}
++
++static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *cfqd, int pid)
++{
++      const int hashval = hash_long(current->tgid, CFQ_QHASH_SHIFT);
++
++      return __cfq_find_cfq_hash(cfqd, pid, hashval);
++}
++
++static void cfq_put_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
++{
++      cfqd->busy_queues--;
++      list_del(&cfqq->cfq_list);
++      list_del(&cfqq->cfq_hash);
++      mempool_free(cfqq, cfq_mpool);
++}
++
++static struct cfq_queue *cfq_get_queue(struct cfq_data *cfqd, int pid)
++{
++      const int hashval = hash_long(current->tgid, CFQ_QHASH_SHIFT);
++      struct cfq_queue *cfqq = __cfq_find_cfq_hash(cfqd, pid, hashval);
++
++      if (!cfqq) {
++              cfqq = mempool_alloc(cfq_mpool, GFP_NOIO);
++
++              INIT_LIST_HEAD(&cfqq->cfq_hash);
++              INIT_LIST_HEAD(&cfqq->cfq_list);
++              RB_CLEAR_ROOT(&cfqq->sort_list);
++
++              cfqq->pid = pid;
++              cfqq->queued[0] = cfqq->queued[1] = 0;
++              list_add(&cfqq->cfq_hash, &cfqd->cfq_hash[hashval]);
++      }
++
++      return cfqq;
++}
++
++static void cfq_enqueue(struct cfq_data *cfqd, struct cfq_rq *crq)
++{
++      struct cfq_queue *cfqq;
++
++      cfqq = cfq_get_queue(cfqd, current->tgid);
++
++      cfq_add_crq_rb(cfqd, cfqq, crq);
++
++      if (list_empty(&cfqq->cfq_list)) {
++              list_add(&cfqq->cfq_list, &cfqd->rr_list);
++              cfqd->busy_queues++;
++      }
++}
++
++static void
++cfq_insert_request(request_queue_t *q, struct request *rq, int where)
++{
++      struct cfq_data *cfqd = q->elevator.elevator_data;
++      struct cfq_rq *crq = RQ_DATA(rq);
++
++      switch (where) {
++              case ELEVATOR_INSERT_BACK:
++                      while (cfq_dispatch_requests(q, cfqd))
++                              ;
++                      list_add_tail(&rq->queuelist, cfqd->dispatch);
++                      break;
++              case ELEVATOR_INSERT_FRONT:
++                      list_add(&rq->queuelist, cfqd->dispatch);
++                      break;
++              case ELEVATOR_INSERT_SORT:
++                      BUG_ON(!blk_fs_request(rq));
++                      cfq_enqueue(cfqd, crq);
++                      break;
++              default:
++                      printk("%s: bad insert point %d\n", __FUNCTION__,where);
++                      return;
++      }
++
++      if (rq_mergeable(rq)) {
++              cfq_add_crq_hash(cfqd, crq);
++
++              if (!q->last_merge)
++                      q->last_merge = rq;
++      }
++}
++
++static int cfq_queue_empty(request_queue_t *q)
++{
++      struct cfq_data *cfqd = q->elevator.elevator_data;
++
++      if (list_empty(cfqd->dispatch) && list_empty(&cfqd->rr_list))
++              return 1;
++
++      return 0;
++}
++
++static struct request *
++cfq_former_request(request_queue_t *q, struct request *rq)
++{
++      struct cfq_rq *crq = RQ_DATA(rq);
++      struct rb_node *rbprev = rb_prev(&crq->rb_node);
++
++      if (rbprev)
++              return rb_entry_crq(rbprev)->request;
++
++      return NULL;
++}
++
++static struct request *
++cfq_latter_request(request_queue_t *q, struct request *rq)
++{
++      struct cfq_rq *crq = RQ_DATA(rq);
++      struct rb_node *rbnext = rb_next(&crq->rb_node);
++
++      if (rbnext)
++              return rb_entry_crq(rbnext)->request;
++
++      return NULL;
++}
++
++static int cfq_may_queue(request_queue_t *q, int rw)
++{
++      struct cfq_data *cfqd = q->elevator.elevator_data;
++      struct cfq_queue *cfqq;
++      int ret = 1;
++
++      if (!cfqd->busy_queues)
++              goto out;
++
++      cfqq = cfq_find_cfq_hash(cfqd, current->tgid);
++      if (cfqq) {
++              int limit = (q->nr_requests - cfq_queued) / cfqd->busy_queues;
++
++              if (limit < 3)
++                      limit = 3;
++              else if (limit > cfqd->max_queued)
++                      limit = cfqd->max_queued;
++
++              if (cfqq->queued[rw] > limit)
++                      ret = 0;
++      }
++out:
++      return ret;
++}
++
++static void cfq_put_request(request_queue_t *q, struct request *rq)
++{
++      struct cfq_data *cfqd = q->elevator.elevator_data;
++      struct cfq_rq *crq = RQ_DATA(rq);
++
++      if (crq) {
++              BUG_ON(q->last_merge == rq);
++              BUG_ON(ON_MHASH(crq));
++
++              mempool_free(crq, cfqd->crq_pool);
++              rq->elevator_private = NULL;
++      }
++}
++
++static int cfq_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
++{
++      struct cfq_data *cfqd = q->elevator.elevator_data;
++      struct cfq_rq *crq = mempool_alloc(cfqd->crq_pool, gfp_mask);
++
++      if (crq) {
++              RB_CLEAR(&crq->rb_node);
++              crq->request = rq;
++              crq->cfq_queue = NULL;
++              INIT_LIST_HEAD(&crq->hash);
++              rq->elevator_private = crq;
++              return 0;
++      }
++
++      return 1;
++}
++
++static void cfq_exit(request_queue_t *q, elevator_t *e)
++{
++      struct cfq_data *cfqd = e->elevator_data;
++
++      e->elevator_data = NULL;
++      mempool_destroy(cfqd->crq_pool);
++      kfree(cfqd->crq_hash);
++      kfree(cfqd->cfq_hash);
++      kfree(cfqd);
++}
++
++static int cfq_init(request_queue_t *q, elevator_t *e)
++{
++      struct cfq_data *cfqd;
++      int i;
++
++      cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL);
++      if (!cfqd)
++              return -ENOMEM;
++
++      memset(cfqd, 0, sizeof(*cfqd));
++      INIT_LIST_HEAD(&cfqd->rr_list);
++
++      cfqd->crq_hash = kmalloc(sizeof(struct list_head) * CFQ_MHASH_ENTRIES, GFP_KERNEL);
++      if (!cfqd->crq_hash)
++              goto out_crqhash;
++
++      cfqd->cfq_hash = kmalloc(sizeof(struct list_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL);
++      if (!cfqd->cfq_hash)
++              goto out_cfqhash;
++
++      cfqd->crq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, crq_pool);
++      if (!cfqd->crq_pool)
++              goto out_crqpool;
++
++      for (i = 0; i < CFQ_MHASH_ENTRIES; i++)
++              INIT_LIST_HEAD(&cfqd->crq_hash[i]);
++      for (i = 0; i < CFQ_QHASH_ENTRIES; i++)
++              INIT_LIST_HEAD(&cfqd->cfq_hash[i]);
++
++      cfqd->dispatch = &q->queue_head;
++      e->elevator_data = cfqd;
++
++      /*
++       * just set it to some high value, we want anyone to be able to queue
++       * some requests. fairness is handled differently
++       */
++      cfqd->max_queued = q->nr_requests;
++      q->nr_requests = 8192;
++
++      return 0;
++out_crqpool:
++      kfree(cfqd->cfq_hash);
++out_cfqhash:
++      kfree(cfqd->crq_hash);
++out_crqhash:
++      kfree(cfqd);
++      return -ENOMEM;
++}
++
++static int __init cfq_slab_setup(void)
++{
++      crq_pool = kmem_cache_create("crq_pool", sizeof(struct cfq_rq), 0, 0,
++                                      NULL, NULL);
++
++      if (!crq_pool)
++              panic("cfq_iosched: can't init crq pool\n");
++
++      cfq_pool = kmem_cache_create("cfq_pool", sizeof(struct cfq_queue), 0, 0,
++                                      NULL, NULL);
++
++      if (!cfq_pool)
++              panic("cfq_iosched: can't init cfq pool\n");
++
++      cfq_mpool = mempool_create(64, mempool_alloc_slab, mempool_free_slab, cfq_pool);
++
++      if (!cfq_mpool)
++              panic("cfq_iosched: can't init cfq mpool\n");
++
++      return 0;
++}
++
++subsys_initcall(cfq_slab_setup);
++
++elevator_t iosched_cfq = {
++      .elevator_name =                "cfq",
++      .elevator_merge_fn =            cfq_merge,
++      .elevator_merged_fn =           cfq_merged_request,
++      .elevator_merge_req_fn =        cfq_merged_requests,
++      .elevator_next_req_fn =         cfq_next_request,
++      .elevator_add_req_fn =          cfq_insert_request,
++      .elevator_remove_req_fn =       cfq_remove_request,
++      .elevator_queue_empty_fn =      cfq_queue_empty,
++      .elevator_former_req_fn =       cfq_former_request,
++      .elevator_latter_req_fn =       cfq_latter_request,
++      .elevator_set_req_fn =          cfq_set_request,
++      .elevator_put_req_fn =          cfq_put_request,
++      .elevator_may_queue_fn =        cfq_may_queue,
++      .elevator_init_fn =             cfq_init,
++      .elevator_exit_fn =             cfq_exit,
++};
++
++EXPORT_SYMBOL(iosched_cfq);
+--- linux-2.6.0/drivers/block/cpqarray.c       2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/cpqarray.c        2003-12-28 23:21:17.000000000 -0800
+@@ -128,9 +128,9 @@ static int sendcmd(
+       unsigned int blkcnt,
+       unsigned int log_unit );
+-static int ida_open(struct inode *inode, struct file *filep);
+-static int ida_release(struct inode *inode, struct file *filep);
+-static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
++static int ida_open(struct block_device *bdev, struct file *filep);
++static int ida_release(struct gendisk *disk);
++static int ida_ioctl(struct block_device *bdev, struct file *filep, unsigned int cmd, unsigned long arg);
+ static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io);
+ static void do_ida_request(request_queue_t *q);
+@@ -715,12 +715,12 @@ DBGINFO(
+ /*
+  * Open.  Make sure the device is really there.
+  */
+-static int ida_open(struct inode *inode, struct file *filep)
++static int ida_open(struct block_device *bdev, struct file *filep)
+ {
+-      drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
+-      ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
++      drv_info_t *drv = get_drv(bdev->bd_disk);
++      ctlr_info_t *host = get_host(bdev->bd_disk);
+-      DBGINFO(printk("ida_open %s\n", inode->i_bdev->bd_disk->disk_name));
++      DBGINFO(printk("ida_open %s\n", bdev->bd_disk->disk_name));
+       /*
+        * Root is allowed to open raw volume zero even if it's not configured
+        * so array config can still work.  I don't think I really like this,
+@@ -740,9 +740,9 @@ static int ida_open(struct inode *inode,
+ /*
+  * Close.  Sync first.
+  */
+-static int ida_release(struct inode *inode, struct file *filep)
++static int ida_release(struct gendisk *disk)
+ {
+-      ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
++      ctlr_info_t *host = get_host(disk);
+       host->usage_count--;
+       return 0;
+ }
+@@ -1022,10 +1022,10 @@ static void ida_timer(unsigned long tdat
+  *  ida_ioctl does some miscellaneous stuff like reporting drive geometry,
+  *  setting readahead and submitting commands from userspace to the controller.
+  */
+-static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
++static int ida_ioctl(struct block_device *bdev, struct file *filep, unsigned int cmd, unsigned long arg)
+ {
+-      drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
+-      ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
++      drv_info_t *drv = get_drv(bdev->bd_disk);
++      ctlr_info_t *host = get_host(bdev->bd_disk);
+       int error;
+       int diskinfo[4];
+       struct hd_geometry *geo = (struct hd_geometry *)arg;
+@@ -1046,7 +1046,7 @@ static int ida_ioctl(struct inode *inode
+               put_user(diskinfo[0], &geo->heads);
+               put_user(diskinfo[1], &geo->sectors);
+               put_user(diskinfo[2], &geo->cylinders);
+-              put_user(get_start_sect(inode->i_bdev), &geo->start);
++              put_user(get_start_sect(bdev), &geo->start);
+               return 0;
+       case IDAGETDRVINFO:
+               if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t)))
+@@ -1076,7 +1076,7 @@ out_passthru:
+               put_user(host->ctlr_sig, (int*)arg);
+               return 0;
+       case IDAREVALIDATEVOLS:
+-              if (iminor(inode) != 0)
++              if (bdev != bdev->bd_contains || drv != host->drv)
+                       return -ENXIO;
+               return revalidate_allvol(host);
+       case IDADRIVERVERSION:
+--- linux-2.6.0/drivers/block/cryptoloop.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/cryptoloop.c      2003-12-28 23:21:53.000000000 -0800
+@@ -87,43 +87,49 @@ typedef int (*encdec_ecb_t)(struct crypt
+ static int
+-cryptoloop_transfer_ecb(struct loop_device *lo, int cmd, char *raw_buf,
+-                   char *loop_buf, int size, sector_t IV)
++cryptoloop_transfer_ecb(struct loop_device *lo, int cmd,
++                      struct page *raw_page, unsigned raw_off,
++                      struct page *loop_page, unsigned loop_off,
++                      int size, sector_t IV)
+ {
+       struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data;
+       struct scatterlist sg_out = { 0, };
+       struct scatterlist sg_in = { 0, };
+       encdec_ecb_t encdecfunc;
+-      char const *in;
+-      char *out;
++      struct page *in_page, *out_page;
++      unsigned in_offs, out_offs;
+       if (cmd == READ) {
+-              in = raw_buf;
+-              out = loop_buf;
++              in_page = raw_page;
++              in_offs = raw_off;
++              out_page = loop_page;
++              out_offs = loop_off;
+               encdecfunc = tfm->crt_u.cipher.cit_decrypt;
+       } else {
+-              in = loop_buf;
+-              out = raw_buf;
++              in_page = loop_page;
++              in_offs = loop_off;
++              out_page = raw_page;
++              out_offs = raw_off;
+               encdecfunc = tfm->crt_u.cipher.cit_encrypt;
+       }
+       while (size > 0) {
+               const int sz = min(size, LOOP_IV_SECTOR_SIZE);
+-              sg_in.page = virt_to_page(in);
+-              sg_in.offset = (unsigned long)in & ~PAGE_MASK;
++              sg_in.page = in_page;
++              sg_in.offset = in_offs;
+               sg_in.length = sz;
+-              sg_out.page = virt_to_page(out);
+-              sg_out.offset = (unsigned long)out & ~PAGE_MASK;
++              sg_out.page = out_page;
++              sg_out.offset = out_offs;
+               sg_out.length = sz;
+               encdecfunc(tfm, &sg_out, &sg_in, sz);
+               size -= sz;
+-              in += sz;
+-              out += sz;
++              in_offs += sz;
++              out_offs += sz;
+       }
+       return 0;
+@@ -135,24 +141,30 @@ typedef int (*encdec_cbc_t)(struct crypt
+                       unsigned int nsg, u8 *iv);
+ static int
+-cryptoloop_transfer_cbc(struct loop_device *lo, int cmd, char *raw_buf,
+-                   char *loop_buf, int size, sector_t IV)
++cryptoloop_transfer_cbc(struct loop_device *lo, int cmd,
++                      struct page *raw_page, unsigned raw_off,
++                      struct page *loop_page, unsigned loop_off,
++                      int size, sector_t IV)
+ {
+       struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data;
+       struct scatterlist sg_out = { 0, };
+       struct scatterlist sg_in = { 0, };
+       encdec_cbc_t encdecfunc;
+-      char const *in;
+-      char *out;
++      struct page *in_page, *out_page;
++      unsigned in_offs, out_offs;
+       if (cmd == READ) {
+-              in = raw_buf;
+-              out = loop_buf;
++              in_page = raw_page;
++              in_offs = raw_off;
++              out_page = loop_page;
++              out_offs = loop_off;
+               encdecfunc = tfm->crt_u.cipher.cit_decrypt_iv;
+       } else {
+-              in = loop_buf;
+-              out = raw_buf;
++              in_page = loop_page;
++              in_offs = loop_off;
++              out_page = raw_page;
++              out_offs = raw_off;
+               encdecfunc = tfm->crt_u.cipher.cit_encrypt_iv;
+       }
+@@ -161,39 +173,43 @@ cryptoloop_transfer_cbc(struct loop_devi
+               u32 iv[4] = { 0, };
+               iv[0] = cpu_to_le32(IV & 0xffffffff);
+-              sg_in.page = virt_to_page(in);
+-              sg_in.offset = offset_in_page(in);
++              sg_in.page = in_page;
++              sg_in.offset = in_offs;
+               sg_in.length = sz;
+-              sg_out.page = virt_to_page(out);
+-              sg_out.offset = offset_in_page(out);
++              sg_out.page = out_page;
++              sg_out.offset = out_offs;
+               sg_out.length = sz;
+               encdecfunc(tfm, &sg_out, &sg_in, sz, (u8 *)iv);
+               IV++;
+               size -= sz;
+-              in += sz;
+-              out += sz;
++              in_offs += sz;
++              out_offs += sz;
+       }
+       return 0;
+ }
+ static int
+-cryptoloop_transfer(struct loop_device *lo, int cmd, char *raw_buf,
+-                   char *loop_buf, int size, sector_t IV)
++cryptoloop_transfer(struct loop_device *lo, int cmd,
++                  struct page *raw_page, unsigned raw_off,
++                  struct page *loop_page, unsigned loop_off,
++                  int size, sector_t IV)
+ {
+       struct crypto_tfm *tfm = (struct crypto_tfm *) lo->key_data;
+       if(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB)
+       {
+               lo->transfer = cryptoloop_transfer_ecb;
+-              return cryptoloop_transfer_ecb(lo, cmd, raw_buf, loop_buf, size, IV);
++              return cryptoloop_transfer_ecb(lo, cmd, raw_page, raw_off,
++                                             loop_page, loop_off, size, IV);
+       }       
+       if(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_CBC)
+       {       
+               lo->transfer = cryptoloop_transfer_cbc;
+-              return cryptoloop_transfer_cbc(lo, cmd, raw_buf, loop_buf, size, IV);
++              return cryptoloop_transfer_cbc(lo, cmd, raw_page, raw_off,
++                                             loop_page, loop_off, size, IV);
+       }
+       
+       /*  This is not supposed to happen */
+--- linux-2.6.0/drivers/block/DAC960.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/DAC960.c  2003-12-28 23:22:28.000000000 -0800
+@@ -67,9 +67,9 @@ static long disk_size(DAC960_Controller_
+       }
+ }
+-static int DAC960_open(struct inode *inode, struct file *file)
++static int DAC960_open(struct block_device *bdev, struct file *file)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
++      struct gendisk *disk = bdev->bd_disk;
+       DAC960_Controller_T *p = disk->queue->queuedata;
+       int drive_nr = (long)disk->private_data;
+@@ -84,17 +84,17 @@ static int DAC960_open(struct inode *ino
+                       return -ENXIO;
+       }
+-      check_disk_change(inode->i_bdev);
++      check_disk_change(bdev);
+       if (!get_capacity(p->disks[drive_nr]))
+               return -ENXIO;
+       return 0;
+ }
+-static int DAC960_ioctl(struct inode *inode, struct file *file,
++static int DAC960_ioctl(struct block_device *bdev, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
++      struct gendisk *disk = bdev->bd_disk;
+       DAC960_Controller_T *p = disk->queue->queuedata;
+       int drive_nr = (long)disk->private_data;
+       struct hd_geometry g, *loc = (struct hd_geometry *)arg;
+@@ -128,7 +128,7 @@ static int DAC960_ioctl(struct inode *in
+               g.cylinders = i->ConfigurableDeviceSize / (g.heads * g.sectors);
+       }
+       
+-      g.start = get_start_sect(inode->i_bdev);
++      g.start = get_start_sect(bdev);
+       return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
+ }
+@@ -2474,7 +2474,6 @@ static boolean DAC960_V2_ReportDeviceCon
+ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
+ {
+   int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
+-  struct request_queue *RequestQueue;
+   int n;
+   /*
+@@ -2483,26 +2482,22 @@ static boolean DAC960_RegisterBlockDevic
+   if (register_blkdev(MajorNumber, "dac960") < 0)
+       return false;
+-  /*
+-    Initialize the I/O Request Queue.
+-  */
+-  RequestQueue = blk_init_queue(DAC960_RequestFunction,&Controller->queue_lock);
+-  if (!RequestQueue) {
+-      unregister_blkdev(MajorNumber, "dac960");
+-      return false;
+-  }
+-  Controller->RequestQueue = RequestQueue;
+-  blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit);
+-  RequestQueue->queuedata = Controller;
+-  blk_queue_max_hw_segments(RequestQueue,
+-                          Controller->DriverScatterGatherLimit);
+-  blk_queue_max_phys_segments(RequestQueue,
+-                          Controller->DriverScatterGatherLimit);
+-  blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
+-
+   for (n = 0; n < DAC960_MaxLogicalDrives; n++) {
+       struct gendisk *disk = Controller->disks[n];
++      struct request_queue *RequestQueue;
++      /* for now, let all request queues share controller's lock */
++      RequestQueue = blk_init_queue(DAC960_RequestFunction,&Controller->queue_lock);
++      if (!RequestQueue) {
++              printk("DAC960: failure to allocate request queue\n");
++              continue;
++      }
++      Controller->RequestQueue[n] = RequestQueue;
++      blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit);
++      RequestQueue->queuedata = Controller;
++      blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit);
++      blk_queue_max_phys_segments(RequestQueue, Controller->DriverScatterGatherLimit);
++      blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
+       disk->queue = RequestQueue;
+       sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n);
+       sprintf(disk->devfs_name, "rd/host%d/target%d", Controller->ControllerNumber, n);
+@@ -2527,17 +2522,17 @@ static void DAC960_UnregisterBlockDevice
+   int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
+   int disk;
+-  for (disk = 0; disk < DAC960_MaxLogicalDrives; disk++)
+-        del_gendisk(Controller->disks[disk]);
++  /* does order matter when deleting gendisk and cleanup in request queue? */
++  for (disk = 0; disk < DAC960_MaxLogicalDrives; disk++) {
++      del_gendisk(Controller->disks[disk]);
++      blk_cleanup_queue(Controller->RequestQueue[disk]);
++      Controller->RequestQueue[disk] = NULL;
++  }
+   /*
+     Unregister the Block Device Major Number for this DAC960 Controller.
+   */
+   unregister_blkdev(MajorNumber, "dac960");
+-  /*
+-    Remove the I/O Request Queue.
+-  */
+-  blk_cleanup_queue(Controller->RequestQueue);
+ }
+ /*
+@@ -3253,58 +3248,83 @@ static void DAC960_V2_QueueReadWriteComm
+ }
++static int DAC960_process_queue(DAC960_Controller_T *Controller, struct request_queue *req_q)
++{
++      struct request *Request;
++      DAC960_Command_T *Command;
++
++   while(1) {
++      Request = elv_next_request(req_q);
++      if (!Request)
++              return 1;
++
++      Command = DAC960_AllocateCommand(Controller);
++      if (Command == NULL)
++              return 0;
++
++      if (rq_data_dir(Request) == READ) {
++              Command->DmaDirection = PCI_DMA_FROMDEVICE;
++              Command->CommandType = DAC960_ReadCommand;
++      } else {
++              Command->DmaDirection = PCI_DMA_TODEVICE;
++              Command->CommandType = DAC960_WriteCommand;
++      }
++      Command->Completion = Request->waiting;
++      Command->LogicalDriveNumber = (long)Request->rq_disk->private_data;
++      Command->BlockNumber = Request->sector;
++      Command->BlockCount = Request->nr_sectors;
++      Command->Request = Request;
++      blkdev_dequeue_request(Request);
++      Command->SegmentCount = blk_rq_map_sg(req_q,
++                Command->Request, Command->cmd_sglist);
++      /* pci_map_sg MAY change the value of SegCount */
++      Command->SegmentCount = pci_map_sg(Controller->PCIDevice, Command->cmd_sglist,
++               Command->SegmentCount, Command->DmaDirection);
++
++      DAC960_QueueReadWriteCommand(Command);
++  }
++}
++
+ /*
+   DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
+   I/O Request Queue and queues it to the Controller.  WaitForCommand is true if
+   this function should wait for a Command to become available if necessary.
+   This function returns true if an I/O Request was queued and false otherwise.
+ */
+-
+-static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
+-                                   boolean WaitForCommand)
++static void DAC960_ProcessRequest(DAC960_Controller_T *controller)
+ {
+-  struct request_queue *RequestQueue = Controller->RequestQueue;
+-  struct request *Request;
+-  DAC960_Command_T *Command;
++      int i;
+-  if (!Controller->ControllerInitialized)
+-     return false;
++      if (!controller->ControllerInitialized)
++              return;
+-  while (true) {
+-      Request = elv_next_request(RequestQueue);
+-      if (!Request)
+-            return false;
++      /* Do this better later! */
++      for (i = controller->req_q_index; i < DAC960_MaxLogicalDrives; i++) {
++              struct request_queue *req_q = controller->RequestQueue[i];
+-      Command = DAC960_AllocateCommand(Controller);
+-      if (Command != NULL)
+-          break;
++              if (req_q == NULL)
++                      continue;
+-      if (!WaitForCommand)
+-          return false;
++              if (!DAC960_process_queue(controller, req_q)) {
++                      controller->req_q_index = i;
++                      return;
++              }
++      }
+-      DAC960_WaitForCommand(Controller);
+-  }
+-  if (rq_data_dir(Request) == READ) {
+-    Command->DmaDirection = PCI_DMA_FROMDEVICE;
+-    Command->CommandType = DAC960_ReadCommand;
+-  } else {
+-    Command->DmaDirection = PCI_DMA_TODEVICE;
+-    Command->CommandType = DAC960_WriteCommand;
+-  }
+-  Command->Completion = Request->waiting;
+-  Command->LogicalDriveNumber = (long)Request->rq_disk->private_data;
+-  Command->BlockNumber = Request->sector;
+-  Command->BlockCount = Request->nr_sectors;
+-  Command->Request = Request;
+-  blkdev_dequeue_request(Request);
+-  Command->SegmentCount = blk_rq_map_sg(Controller->RequestQueue,
+-                Command->Request, Command->cmd_sglist);
+-  /* pci_map_sg MAY change the value of SegCount */
+-  Command->SegmentCount = pci_map_sg(Controller->PCIDevice, Command->cmd_sglist,
+-               Command->SegmentCount, Command->DmaDirection);
++      if (controller->req_q_index == 0)
++              return;
+-  DAC960_QueueReadWriteCommand(Command);
+-  return true;
++      for (i = 0; i < controller->req_q_index; i++) {
++              struct request_queue *req_q = controller->RequestQueue[i];
++
++              if (req_q == NULL)
++                      continue;
++
++              if (!DAC960_process_queue(controller, req_q)) {
++                      controller->req_q_index = i;
++                      return;
++              }
++      }
+ }
+@@ -3321,6 +3341,7 @@ static void DAC960_queue_partial_rw(DAC9
+ {
+   DAC960_Controller_T *Controller = Command->Controller;
+   struct request *Request = Command->Request;
++  struct request_queue *req_q = Controller->RequestQueue[Command->LogicalDriveNumber];
+   if (Command->DmaDirection == PCI_DMA_FROMDEVICE)
+     Command->CommandType = DAC960_ReadRetryCommand;
+@@ -3333,11 +3354,9 @@ static void DAC960_queue_partial_rw(DAC9
+    * code should almost never be called, just go with a
+    * simple coding.
+    */
+-  (void)blk_rq_map_sg(Controller->RequestQueue, Command->Request,
+-                                        Command->cmd_sglist);
++  (void)blk_rq_map_sg(req_q, Command->Request, Command->cmd_sglist);
+-  (void)pci_map_sg(Controller->PCIDevice, Command->cmd_sglist, 1,
+-                                      Command->DmaDirection);
++  (void)pci_map_sg(Controller->PCIDevice, Command->cmd_sglist, 1, Command->DmaDirection);
+   /*
+    * Resubmitting the request sector at a time is really tedious.
+    * But, this should almost never happen.  So, we're willing to pay
+@@ -3357,9 +3376,7 @@ static void DAC960_queue_partial_rw(DAC9
+ static void DAC960_RequestFunction(struct request_queue *RequestQueue)
+ {
+-      int i = 0;
+-      while (DAC960_ProcessRequest(RequestQueue->queuedata, (i++ == 0)))
+-              ;
++      DAC960_ProcessRequest(RequestQueue->queuedata);
+ }
+ /*
+@@ -5205,8 +5222,7 @@ static irqreturn_t DAC960_BA_InterruptHa
+     Attempt to remove additional I/O Requests from the Controller's
+     I/O Request Queue and queue them to the Controller.
+   */
+-  while (DAC960_ProcessRequest(Controller, false))
+-        ;
++  DAC960_ProcessRequest(Controller);
+   spin_unlock_irqrestore(&Controller->queue_lock, flags);
+   return IRQ_HANDLED;
+ }
+@@ -5249,8 +5265,7 @@ static irqreturn_t DAC960_LP_InterruptHa
+     Attempt to remove additional I/O Requests from the Controller's
+     I/O Request Queue and queue them to the Controller.
+   */
+-  while (DAC960_ProcessRequest(Controller, false))
+-        ;
++  DAC960_ProcessRequest(Controller);
+   spin_unlock_irqrestore(&Controller->queue_lock, flags);
+   return IRQ_HANDLED;
+ }
+@@ -5289,8 +5304,7 @@ static irqreturn_t DAC960_LA_InterruptHa
+     Attempt to remove additional I/O Requests from the Controller's
+     I/O Request Queue and queue them to the Controller.
+   */
+-  while (DAC960_ProcessRequest(Controller, false))
+-        ;
++  DAC960_ProcessRequest(Controller);
+   spin_unlock_irqrestore(&Controller->queue_lock, flags);
+   return IRQ_HANDLED;
+ }
+@@ -5329,8 +5343,7 @@ static irqreturn_t DAC960_PG_InterruptHa
+     Attempt to remove additional I/O Requests from the Controller's
+     I/O Request Queue and queue them to the Controller.
+   */
+-  while (DAC960_ProcessRequest(Controller, false))
+-        ;
++  DAC960_ProcessRequest(Controller);
+   spin_unlock_irqrestore(&Controller->queue_lock, flags);
+   return IRQ_HANDLED;
+ }
+@@ -5365,8 +5378,7 @@ static irqreturn_t DAC960_PD_InterruptHa
+     Attempt to remove additional I/O Requests from the Controller's
+     I/O Request Queue and queue them to the Controller.
+   */
+-  while (DAC960_ProcessRequest(Controller, false))
+-        ;
++  DAC960_ProcessRequest(Controller);
+   spin_unlock_irqrestore(&Controller->queue_lock, flags);
+   return IRQ_HANDLED;
+ }
+@@ -5440,8 +5452,7 @@ static irqreturn_t DAC960_P_InterruptHan
+     Attempt to remove additional I/O Requests from the Controller's
+     I/O Request Queue and queue them to the Controller.
+   */
+-  while (DAC960_ProcessRequest(Controller, false))
+-        ;
++  DAC960_ProcessRequest(Controller);
+   spin_unlock_irqrestore(&Controller->queue_lock, flags);
+   return IRQ_HANDLED;
+ }
+--- linux-2.6.0/drivers/block/DAC960.h 2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/block/DAC960.h  2003-12-28 23:22:28.000000000 -0800
+@@ -2333,7 +2333,8 @@ typedef struct DAC960_Controller
+   DAC960_Command_T *FreeCommands;
+   unsigned char *CombinedStatusBuffer;
+   unsigned char *CurrentStatusBuffer;
+-  struct request_queue *RequestQueue;
++  struct request_queue *RequestQueue[DAC960_MaxLogicalDrives];
++  int req_q_index;
+   spinlock_t queue_lock;
+   wait_queue_head_t CommandWaitQueue;
+   wait_queue_head_t HealthStatusWaitQueue;
+--- linux-2.6.0/drivers/block/floppy98.c       2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/floppy98.c        2003-12-28 23:22:57.000000000 -0800
+@@ -2594,7 +2594,7 @@ static void copy_buffer(int ssize, int m
+                              current_count_sectors);
+                       if (CT(COMMAND) == FD_READ)
+                               printk("read\n");
+-                      if (CT(COMMAND) == FD_READ)
++                      if (CT(COMMAND) == FD_WRITE)
+                               printk("write\n");
+                       break;
+               }
+@@ -2925,7 +2925,7 @@ static int make_raw_rw_request(void)
+                              current_count_sectors);
+                       if (CT(COMMAND) == FD_READ)
+                               printk("read\n");
+-                      if (CT(COMMAND) == FD_READ)
++                      if (CT(COMMAND) == FD_WRITE)
+                               printk("write\n");
+                       return 0;
+               }
+@@ -3484,14 +3484,14 @@ static int get_floppy_geometry(int drive
+       return 0;
+ }
+-static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
++static int fd_ioctl(struct block_device *bdev, struct file *filp, unsigned int cmd,
+                   unsigned long param)
+ {
+ #define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data)
+ #define OUT(c,x) case c: outparam = (const char *) (x); break
+ #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
+-      int drive = (long)inode->i_bdev->bd_disk->private_data;
++      int drive = (long)bdev->bd_disk->private_data;
+       int i, type = ITYPE(UDRS->fd_device);
+       int ret;
+       int size;
+@@ -3566,11 +3566,11 @@ static int fd_ioctl(struct inode *inode,
+                       current_type[drive] = NULL;
+                       floppy_sizes[drive] = MAX_DISK_SIZE << 1;
+                       UDRS->keep_data = 0;
+-                      return invalidate_drive(inode->i_bdev);
++                      return invalidate_drive(bdev);
+               case FDSETPRM:
+               case FDDEFPRM:
+                       return set_geometry(cmd, & inparam.g,
+-                                          drive, type, inode->i_bdev);
++                                          drive, type, bdev);
+               case FDGETPRM:
+                       ECALL(get_floppy_geometry(drive, type, 
+                                                 (struct floppy_struct**)
+@@ -3625,7 +3625,7 @@ static int fd_ioctl(struct inode *inode,
+               case FDFMTEND:
+               case FDFLUSH:
+                       LOCK_FDC(drive,1);
+-                      return invalidate_drive(inode->i_bdev);
++                      return invalidate_drive(bdev);
+               case FDSETEMSGTRESH:
+                       UDP->max_errors.reporting =
+@@ -3735,9 +3735,9 @@ static void __init config_types(void)
+               printk("\n");
+ }
+-static int floppy_release(struct inode * inode, struct file * filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-      int drive = (long)inode->i_bdev->bd_disk->private_data;
++      int drive = (long)disk->private_data;
+       down(&open_lock);
+       if (UDRS->fd_ref < 0)
+@@ -3758,11 +3758,10 @@ static int floppy_release(struct inode *
+  * /dev/PS0 etc), and disallows simultaneous access to the same
+  * drive with different device numbers.
+  */
+-#define RETERR(x) do{floppy_release(inode,filp); return -(x);}while(0)
+-static int floppy_open(struct inode * inode, struct file * filp)
++static int floppy_open(struct block_device *bdev, struct file *filp)
+ {
+-      int drive = (long)inode->i_bdev->bd_disk->private_data;
++      int drive = (long)bdev->bd_disk->private_data;
+       int old_dev;
+       int try;
+       int res = -EBUSY;
+@@ -3789,7 +3788,7 @@ static int floppy_open(struct inode * in
+       down(&open_lock);
+       old_dev = UDRS->fd_device;
+-      if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev)
++      if (opened_bdev[drive] && opened_bdev[drive] != bdev)
+               goto out2;
+       if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
+@@ -3809,7 +3808,7 @@ static int floppy_open(struct inode * in
+       else
+               UDRS->fd_ref++;
+-      opened_bdev[drive] = inode->i_bdev;
++      opened_bdev[drive] = bdev;
+       res = -ENXIO;
+@@ -3844,9 +3843,9 @@ static int floppy_open(struct inode * in
+               }
+       }
+-      UDRS->fd_device = iminor(inode);
+-      set_capacity(disks[drive], floppy_sizes[iminor(inode)]);
+-      if (old_dev != -1 && old_dev != iminor(inode)) {
++      UDRS->fd_device = MINOR(bdev->bd_dev);
++      set_capacity(disks[drive], floppy_sizes[MINOR(bdev->bd_dev)]);
++      if (old_dev != -1 && old_dev != MINOR(bdev->bd_dev)) {
+               if (buffer_drive == drive)
+                       buffer_track = -1;
+       }
+@@ -3859,8 +3858,7 @@ static int floppy_open(struct inode * in
+       /* Allow ioctls if we have write-permissions even if read-only open.
+        * Needed so that programs such as fdrawcmd still can work on write
+        * protected disks */
+-      if ((filp->f_mode & 2) || 
+-          (inode->i_sb && (permission(inode,2) == 0)))
++      if ((filp->f_mode & 2) || permission(filp->f_dentry->d_inode,2) == 0)
+           filp->private_data = (void*) 8;
+       if (UFDCS->rawcmd == 1)
+@@ -3873,7 +3871,7 @@ static int floppy_open(struct inode * in
+       if (!(filp->f_flags & O_NDELAY)) {
+               if (filp->f_mode & 3) {
+                       UDRS->last_checked = 0;
+-                      check_disk_change(inode->i_bdev);
++                      check_disk_change(bdev);
+                       if (UTESTF(FD_DISK_CHANGED))
+                               goto out;
+               }
+--- linux-2.6.0/drivers/block/floppy.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/floppy.c  2003-12-28 23:22:57.000000000 -0800
+@@ -2563,7 +2563,7 @@ static void copy_buffer(int ssize, int m
+                              current_count_sectors);
+                       if (CT(COMMAND) == FD_READ)
+                               printk("read\n");
+-                      if (CT(COMMAND) == FD_READ)
++                      if (CT(COMMAND) == FD_WRITE)
+                               printk("write\n");
+                       break;
+               }
+@@ -2894,7 +2894,7 @@ static int make_raw_rw_request(void)
+                              current_count_sectors);
+                       if (CT(COMMAND) == FD_READ)
+                               printk("read\n");
+-                      if (CT(COMMAND) == FD_READ)
++                      if (CT(COMMAND) == FD_WRITE)
+                               printk("write\n");
+                       return 0;
+               }
+@@ -3456,14 +3456,14 @@ static int get_floppy_geometry(int drive
+       return 0;
+ }
+-static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
++static int fd_ioctl(struct block_device *bdev, struct file *filp, unsigned int cmd,
+                   unsigned long param)
+ {
+ #define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data)
+ #define OUT(c,x) case c: outparam = (const char *) (x); break
+ #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
+-      int drive = (long)inode->i_bdev->bd_disk->private_data;
++      int drive = (long)bdev->bd_disk->private_data;
+       int i, type = ITYPE(UDRS->fd_device);
+       int ret;
+       int size;
+@@ -3539,11 +3539,11 @@ static int fd_ioctl(struct inode *inode,
+                       current_type[drive] = NULL;
+                       floppy_sizes[drive] = MAX_DISK_SIZE << 1;
+                       UDRS->keep_data = 0;
+-                      return invalidate_drive(inode->i_bdev);
++                      return invalidate_drive(bdev);
+               case FDSETPRM:
+               case FDDEFPRM:
+                       return set_geometry(cmd, & inparam.g,
+-                                          drive, type, inode->i_bdev);
++                                          drive, type, bdev);
+               case FDGETPRM:
+                       ECALL(get_floppy_geometry(drive, type, 
+                                                 (struct floppy_struct**)
+@@ -3574,7 +3574,7 @@ static int fd_ioctl(struct inode *inode,
+               case FDFMTEND:
+               case FDFLUSH:
+                       LOCK_FDC(drive,1);
+-                      return invalidate_drive(inode->i_bdev);
++                      return invalidate_drive(bdev);
+               case FDSETEMSGTRESH:
+                       UDP->max_errors.reporting =
+@@ -3685,9 +3685,9 @@ static void __init config_types(void)
+               printk("\n");
+ }
+-static int floppy_release(struct inode * inode, struct file * filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-      int drive = (long)inode->i_bdev->bd_disk->private_data;
++      int drive = (long)disk->private_data;
+       down(&open_lock);
+       if (UDRS->fd_ref < 0)
+@@ -3708,9 +3708,9 @@ static int floppy_release(struct inode *
+  * /dev/PS0 etc), and disallows simultaneous access to the same
+  * drive with different device numbers.
+  */
+-static int floppy_open(struct inode * inode, struct file * filp)
++static int floppy_open(struct block_device *bdev, struct file * filp)
+ {
+-      int drive = (long)inode->i_bdev->bd_disk->private_data;
++      int drive = (long)bdev->bd_disk->private_data;
+       int old_dev;
+       int try;
+       int res = -EBUSY;
+@@ -3719,7 +3719,7 @@ static int floppy_open(struct inode * in
+       filp->private_data = (void*) 0;
+       down(&open_lock);
+       old_dev = UDRS->fd_device;
+-      if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev)
++      if (opened_bdev[drive] && opened_bdev[drive] != bdev)
+               goto out2;
+       if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
+@@ -3739,7 +3739,7 @@ static int floppy_open(struct inode * in
+       else
+               UDRS->fd_ref++;
+-      opened_bdev[drive] = inode->i_bdev;
++      opened_bdev[drive] = bdev;
+       res = -ENXIO;
+@@ -3774,9 +3774,9 @@ static int floppy_open(struct inode * in
+               }
+       }
+-      UDRS->fd_device = iminor(inode);
+-      set_capacity(disks[drive], floppy_sizes[iminor(inode)]);
+-      if (old_dev != -1 && old_dev != iminor(inode)) {
++      UDRS->fd_device = MINOR(bdev->bd_dev);
++      set_capacity(disks[drive], floppy_sizes[MINOR(bdev->bd_dev)]);
++      if (old_dev != -1 && old_dev != MINOR(bdev->bd_dev)) {
+               if (buffer_drive == drive)
+                       buffer_track = -1;
+       }
+@@ -3784,8 +3784,7 @@ static int floppy_open(struct inode * in
+       /* Allow ioctls if we have write-permissions even if read-only open.
+        * Needed so that programs such as fdrawcmd still can work on write
+        * protected disks */
+-      if ((filp->f_mode & 2) || 
+-          (inode->i_sb && (permission(inode,2, NULL) == 0)))
++      if ((filp->f_mode & 2) || permission(filp->f_dentry->d_inode,2,NULL) == 0)
+           filp->private_data = (void*) 8;
+       if (UFDCS->rawcmd == 1)
+@@ -3794,7 +3793,7 @@ static int floppy_open(struct inode * in
+       if (!(filp->f_flags & O_NDELAY)) {
+               if (filp->f_mode & 3) {
+                       UDRS->last_checked = 0;
+-                      check_disk_change(inode->i_bdev);
++                      check_disk_change(bdev);
+                       if (UTESTF(FD_DISK_CHANGED))
+                               goto out;
+               }
+--- linux-2.6.0/drivers/block/genhd.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/genhd.c   2003-12-28 23:21:42.000000000 -0800
+@@ -296,7 +296,9 @@ extern int blk_dev_init(void);
+ static struct kobject *base_probe(dev_t dev, int *part, void *data)
+ {
+-      request_module("block-major-%d", MAJOR(dev));
++      if (request_module("block-major-%d-%d", MAJOR(dev), MINOR(dev)) > 0)
++              /* Make old-style 2.4 aliases work */
++              request_module("block-major-%d", MAJOR(dev));
+       return NULL;
+ }
+--- linux-2.6.0/drivers/block/ioctl.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/ioctl.c   2003-12-28 23:21:22.000000000 -0800
+@@ -132,10 +132,9 @@ static int put_u64(unsigned long arg, u6
+       return put_user(val, (u64 *)arg);
+ }
+-int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
++int blkdev_ioctl(struct block_device *bdev, struct file *file, unsigned cmd,
+                       unsigned long arg)
+ {
+-      struct block_device *bdev = inode->i_bdev;
+       struct gendisk *disk = bdev->bd_disk;
+       struct backing_dev_info *bdi;
+       int holder;
+@@ -194,7 +193,7 @@ int blkdev_ioctl(struct inode *inode, st
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EACCES;
+               if (disk->fops->ioctl) {
+-                      ret = disk->fops->ioctl(inode, file, cmd, arg);
++                      ret = disk->fops->ioctl(bdev, file, cmd, arg);
+                       if (ret != -EINVAL)
+                               return ret;
+               }
+@@ -203,7 +202,7 @@ int blkdev_ioctl(struct inode *inode, st
+               return 0;
+       case BLKROSET:
+               if (disk->fops->ioctl) {
+-                      ret = disk->fops->ioctl(inode, file, cmd, arg);
++                      ret = disk->fops->ioctl(bdev, file, cmd, arg);
+                       if (ret != -EINVAL)
+                               return ret;
+               }
+@@ -215,7 +214,7 @@ int blkdev_ioctl(struct inode *inode, st
+               return 0;
+       default:
+               if (disk->fops->ioctl)
+-                      return disk->fops->ioctl(inode, file, cmd, arg);
++                      return disk->fops->ioctl(bdev, file, cmd, arg);
+       }
+       return -ENOTTY;
+ }
+--- linux-2.6.0/drivers/block/Kconfig.iosched  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/Kconfig.iosched   2003-12-28 23:21:35.000000000 -0800
+@@ -27,3 +27,10 @@ config IOSCHED_DEADLINE
+         a disk at any one time, its behaviour is almost identical to the
+         anticipatory I/O scheduler and so is a good choice.
++config IOSCHED_CFQ
++      bool "CFQ I/O scheduler" if EMBEDDED
++      default y
++      ---help---
++        The CFQ I/O scheduler tries to distribute bandwidth equally
++        among all processes in the system. It should provide a fair
++        working environment, suitable for desktop systems.
+--- linux-2.6.0/drivers/block/ll_rw_blk.c      2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/block/ll_rw_blk.c       2003-12-28 23:26:41.000000000 -0800
+@@ -517,10 +517,10 @@ init_tag_map(request_queue_t *q, struct 
+ {
+       int bits, i;
+-      if (depth > q->nr_requests * 2) {
+-              depth = q->nr_requests * 2;
+-              printk(KERN_ERR "%s: adjusted depth to %d\n",
+-                              __FUNCTION__, depth);
++      if (depth > q->nr_requests / 2) {
++              q->nr_requests = depth * 2;
++              printk(KERN_INFO "%s: large TCQ depth: adjusted nr_requests "
++                               "to %lu\n", __FUNCTION__, q->nr_requests);
+       }
+       tags->tag_index = kmalloc(depth * sizeof(struct request *), GFP_ATOMIC);
+@@ -780,11 +780,6 @@ static char *rq_flags[] = {
+       "REQ_PM_SUSPEND",
+       "REQ_PM_RESUME",
+       "REQ_PM_SHUTDOWN",
+-      "REQ_IDETAPE_PC1",
+-      "REQ_IDETAPE_PC2",
+-      "REQ_IDETAPE_READ",
+-      "REQ_IDETAPE_WRITE",
+-      "REQ_IDETAPE_READ_BUFFER",
+ };
+ void blk_dump_rq_flags(struct request *rq, char *msg)
+@@ -1335,6 +1330,8 @@ static elevator_t *chosen_elevator =
+       &iosched_as;
+ #elif defined(CONFIG_IOSCHED_DEADLINE)
+       &iosched_deadline;
++#elif defined(CONFIG_IOSCHED_CFQ)
++      &iosched_cfq;
+ #elif defined(CONFIG_IOSCHED_NOOP)
+       &elevator_noop;
+ #else
+@@ -1353,6 +1350,10 @@ static int __init elevator_setup(char *s
+       if (!strcmp(str, "as"))
+               chosen_elevator = &iosched_as;
+ #endif
++#ifdef CONFIG_IOSCHED_CFQ
++      if (!strcmp(str, "cfq"))
++              chosen_elevator = &iosched_cfq;
++#endif
+ #ifdef CONFIG_IOSCHED_NOOP
+       if (!strcmp(str, "noop"))
+               chosen_elevator = &elevator_noop;
+@@ -1875,29 +1876,52 @@ void blk_put_request(struct request *req
+               spin_unlock_irqrestore(q->queue_lock, flags);
+       }
+ }
+-
+ EXPORT_SYMBOL(blk_put_request);
+ /**
+- * blk_congestion_wait - wait for a queue to become uncongested
++ * blk_congestion_wait_wq - wait for a queue to become uncongested,
+  * @rw: READ or WRITE
+  * @timeout: timeout in jiffies
++ * @wait : wait queue entry to use for waiting or async notification
++ * (NULL defaults to synchronous behaviour)
+  *
+  * Waits for up to @timeout jiffies for a queue (any queue) to exit congestion.
+  * If no queues are congested then just wait for the next request to be
+  * returned.
++ *
++ * If the wait queue parameter specifies an async i/o callback,
++ * then instead of blocking, just register the callback on the wait
++ * queue for async notification when the queue gets uncongested.
+  */
+-void blk_congestion_wait(int rw, long timeout)
++int blk_congestion_wait_wq(int rw, long timeout, wait_queue_t *wait)
+ {
+-      DEFINE_WAIT(wait);
+       wait_queue_head_t *wqh = &congestion_wqh[rw];
++      DEFINE_WAIT(local_wait);
++
++      if (!wait)
++              wait = &local_wait;
+       blk_run_queues();
+-      prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
++      prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
++      if (!is_sync_wait(wait)) {
++              /*
++               * if we've queued an async wait queue
++               * callback do not block; just tell the
++               * caller to return and retry later when
++               * the callback is notified
++               */
++              return -EIOCBRETRY;
++      }
+       io_schedule_timeout(timeout);
+-      finish_wait(wqh, &wait);
++      finish_wait(wqh, wait);
++      return 0;
+ }
++EXPORT_SYMBOL(blk_congestion_wait_wq);
++void blk_congestion_wait(int rw, long timeout)
++{
++      blk_congestion_wait_wq(rw, timeout, NULL);
++}
+ EXPORT_SYMBOL(blk_congestion_wait);
+ /*
+--- linux-2.6.0/drivers/block/loop.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/loop.c    2003-12-28 23:21:54.000000000 -0800
+@@ -55,6 +55,7 @@
+ #include <linux/errno.h>
+ #include <linux/major.h>
+ #include <linux/wait.h>
++#include <linux/blkdev.h>
+ #include <linux/blkpg.h>
+ #include <linux/init.h>
+ #include <linux/devfs_fs_kernel.h>
+@@ -75,24 +76,34 @@ static struct gendisk **disks;
+ /*
+  * Transfer functions
+  */
+-static int transfer_none(struct loop_device *lo, int cmd, char *raw_buf,
+-                       char *loop_buf, int size, sector_t real_block)
++static int transfer_none(struct loop_device *lo, int cmd,
++                       struct page *raw_page, unsigned raw_off,
++                       struct page *loop_page, unsigned loop_off,
++                       int size, sector_t real_block)
+ {
+-      if (raw_buf != loop_buf) {
+-              if (cmd == READ)
+-                      memcpy(loop_buf, raw_buf, size);
+-              else
+-                      memcpy(raw_buf, loop_buf, size);
+-      }
++      char *raw_buf = kmap_atomic(raw_page, KM_USER0) + raw_off;
++      char *loop_buf = kmap_atomic(loop_page, KM_USER1) + loop_off;
++
++      if (cmd == READ)
++              memcpy(loop_buf, raw_buf, size);
++      else
++              memcpy(raw_buf, loop_buf, size);
++      kunmap_atomic(raw_buf, KM_USER0);
++      kunmap_atomic(loop_buf, KM_USER1);
++      cond_resched();
+       return 0;
+ }
+-static int transfer_xor(struct loop_device *lo, int cmd, char *raw_buf,
+-                      char *loop_buf, int size, sector_t real_block)
+-{
+-      char    *in, *out, *key;
+-      int     i, keysize;
++static int transfer_xor(struct loop_device *lo, int cmd,
++                      struct page *raw_page, unsigned raw_off,
++                      struct page *loop_page, unsigned loop_off,
++                      int size, sector_t real_block)
++{
++      char *raw_buf = kmap_atomic(raw_page, KM_USER0) + raw_off;
++      char *loop_buf = kmap_atomic(loop_page, KM_USER1) + loop_off;
++      char *in, *out, *key;
++      int i, keysize;
+       if (cmd == READ) {
+               in = raw_buf;
+@@ -106,6 +117,10 @@ static int transfer_xor(struct loop_devi
+       keysize = lo->lo_encrypt_key_size;
+       for (i = 0; i < size; i++)
+               *out++ = *in++ ^ key[(i & 511) % keysize];
++
++      kunmap_atomic(raw_buf, KM_USER0);
++      kunmap_atomic(loop_buf, KM_USER1);
++      cond_resched();
+       return 0;
+ }
+@@ -140,8 +155,7 @@ figure_loop_size(struct loop_device *lo)
+       sector_t x;
+       /* Compute loopsize in bytes */
+-      size = i_size_read(lo->lo_backing_file->f_dentry->
+-                              d_inode->i_mapping->host);
++      size = i_size_read(lo->lo_backing_file->f_mapping->host);
+       offset = lo->lo_offset;
+       loopsize = size - offset;
+       if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize)
+@@ -162,32 +176,33 @@ figure_loop_size(struct loop_device *lo)
+ }
+ static inline int
+-lo_do_transfer(struct loop_device *lo, int cmd, char *rbuf,
+-             char *lbuf, int size, sector_t rblock)
++lo_do_transfer(struct loop_device *lo, int cmd,
++             struct page *rpage, unsigned roffs,
++             struct page *lpage, unsigned loffs,
++             int size, sector_t rblock)
+ {
+       if (!lo->transfer)
+               return 0;
+-      return lo->transfer(lo, cmd, rbuf, lbuf, size, rblock);
++      return lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock);
+ }
+ static int
+ do_lo_send(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos)
+ {
+       struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */
+-      struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++      struct address_space *mapping = file->f_mapping;
+       struct address_space_operations *aops = mapping->a_ops;
+       struct page *page;
+-      char *kaddr, *data;
+       pgoff_t index;
+-      unsigned size, offset;
++      unsigned size, offset, bv_offs;
+       int len;
+       int ret = 0;
+       down(&mapping->host->i_sem);
+       index = pos >> PAGE_CACHE_SHIFT;
+       offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1);
+-      data = kmap(bvec->bv_page) + bvec->bv_offset;
++      bv_offs = bvec->bv_offset;
+       len = bvec->bv_len;
+       while (len > 0) {
+               sector_t IV;
+@@ -204,25 +219,28 @@ do_lo_send(struct loop_device *lo, struc
+                       goto fail;
+               if (aops->prepare_write(file, page, offset, offset+size))
+                       goto unlock;
+-              kaddr = kmap(page);
+-              transfer_result = lo_do_transfer(lo, WRITE, kaddr + offset,
+-                                               data, size, IV);
++              transfer_result = lo_do_transfer(lo, WRITE, page, offset,
++                                               bvec->bv_page, bv_offs,
++                                               size, IV);
+               if (transfer_result) {
++                      char *kaddr;
++
+                       /*
+                        * The transfer failed, but we still write the data to
+                        * keep prepare/commit calls balanced.
+                        */
+                       printk(KERN_ERR "loop: transfer error block %llu\n",
+                              (unsigned long long)index);
++                      kaddr = kmap_atomic(page, KM_USER0);
+                       memset(kaddr + offset, 0, size);
++                      kunmap_atomic(kaddr, KM_USER0);
+               }
+               flush_dcache_page(page);
+-              kunmap(page);
+               if (aops->commit_write(file, page, offset, offset+size))
+                       goto unlock;
+               if (transfer_result)
+                       goto unlock;
+-              data += size;
++              bv_offs += size;
+               len -= size;
+               offset = 0;
+               index++;
+@@ -232,7 +250,6 @@ do_lo_send(struct loop_device *lo, struc
+       }
+       up(&mapping->host->i_sem);
+ out:
+-      kunmap(bvec->bv_page);
+       return ret;
+ unlock:
+@@ -247,12 +264,10 @@ fail:
+ static int
+ lo_send(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
+ {
+-      unsigned vecnr;
+-      int ret = 0;
+-
+-      for (vecnr = 0; vecnr < bio->bi_vcnt; vecnr++) {
+-              struct bio_vec *bvec = &bio->bi_io_vec[vecnr];
++      struct bio_vec *bvec;
++      int i, ret = 0;
++      bio_for_each_segment(bvec, bio, i) {
+               ret = do_lo_send(lo, bvec, bsize, pos);
+               if (ret < 0)
+                       break;
+@@ -263,7 +278,8 @@ lo_send(struct loop_device *lo, struct b
+ struct lo_read_data {
+       struct loop_device *lo;
+-      char *data;
++      struct page *page;
++      unsigned offset;
+       int bsize;
+ };
+@@ -271,7 +287,6 @@ static int
+ lo_read_actor(read_descriptor_t *desc, struct page *page,
+             unsigned long offset, unsigned long size)
+ {
+-      char *kaddr;
+       unsigned long count = desc->count;
+       struct lo_read_data *p = (struct lo_read_data*)desc->buf;
+       struct loop_device *lo = p->lo;
+@@ -282,18 +297,16 @@ lo_read_actor(read_descriptor_t *desc, s
+       if (size > count)
+               size = count;
+-      kaddr = kmap(page);
+-      if (lo_do_transfer(lo, READ, kaddr + offset, p->data, size, IV)) {
++      if (lo_do_transfer(lo, READ, page, offset, p->page, p->offset, size, IV)) {
+               size = 0;
+               printk(KERN_ERR "loop: transfer error block %ld\n",
+                      page->index);
+               desc->error = -EINVAL;
+       }
+-      kunmap(page);
+       
+       desc->count = count - size;
+       desc->written += size;
+-      p->data += size;
++      p->offset += size;
+       return size;
+ }
+@@ -306,24 +319,22 @@ do_lo_receive(struct loop_device *lo,
+       int retval;
+       cookie.lo = lo;
+-      cookie.data = kmap(bvec->bv_page) + bvec->bv_offset;
++      cookie.page = bvec->bv_page;
++      cookie.offset = bvec->bv_offset;
+       cookie.bsize = bsize;
+       file = lo->lo_backing_file;
+       retval = file->f_op->sendfile(file, &pos, bvec->bv_len,
+                       lo_read_actor, &cookie);
+-      kunmap(bvec->bv_page);
+       return (retval < 0)? retval: 0;
+ }
+ static int
+ lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
+ {
+-      unsigned vecnr;
+-      int ret = 0;
+-
+-      for (vecnr = 0; vecnr < bio->bi_vcnt; vecnr++) {
+-              struct bio_vec *bvec = &bio->bi_io_vec[vecnr];
++      struct bio_vec *bvec;
++      int i, ret = 0;
++      bio_for_each_segment(bvec, bio, i) {
+               ret = do_lo_receive(lo, bvec, bsize, pos);
+               if (ret < 0)
+                       break;
+@@ -345,23 +356,6 @@ static int do_bio_filebacked(struct loop
+       return ret;
+ }
+-static int loop_end_io_transfer(struct bio *, unsigned int, int);
+-
+-static void loop_put_buffer(struct bio *bio)
+-{
+-      /*
+-       * check bi_end_io, may just be a remapped bio
+-       */
+-      if (bio && bio->bi_end_io == loop_end_io_transfer) {
+-              int i;
+-
+-              for (i = 0; i < bio->bi_vcnt; i++)
+-                      __free_page(bio->bi_io_vec[i].bv_page);
+-
+-              bio_put(bio);
+-      }
+-}
+-
+ /*
+  * Add bio to back of pending list
+  */
+@@ -399,129 +393,8 @@ static struct bio *loop_get_bio(struct l
+       return bio;
+ }
+-/*
+- * if this was a WRITE lo->transfer stuff has already been done. for READs,
+- * queue it for the loop thread and let it do the transfer out of
+- * bi_end_io context (we don't want to do decrypt of a page with irqs
+- * disabled)
+- */
+-static int loop_end_io_transfer(struct bio *bio, unsigned int bytes_done, int err)
+-{
+-      struct bio *rbh = bio->bi_private;
+-      struct loop_device *lo = rbh->bi_bdev->bd_disk->private_data;
+-
+-      if (bio->bi_size)
+-              return 1;
+-
+-      if (err || bio_rw(bio) == WRITE) {
+-              bio_endio(rbh, rbh->bi_size, err);
+-              if (atomic_dec_and_test(&lo->lo_pending))
+-                      up(&lo->lo_bh_mutex);
+-              loop_put_buffer(bio);
+-      } else
+-              loop_add_bio(lo, bio);
+-
+-      return 0;
+-}
+-
+-static struct bio *loop_copy_bio(struct bio *rbh)
+-{
+-      struct bio *bio;
+-      struct bio_vec *bv;
+-      int i;
+-
+-      bio = bio_alloc(__GFP_NOWARN, rbh->bi_vcnt);
+-      if (!bio)
+-              return NULL;
+-
+-      /*
+-       * iterate iovec list and alloc pages
+-       */
+-      __bio_for_each_segment(bv, rbh, i, 0) {
+-              struct bio_vec *bbv = &bio->bi_io_vec[i];
+-
+-              bbv->bv_page = alloc_page(__GFP_NOWARN|__GFP_HIGHMEM);
+-              if (bbv->bv_page == NULL)
+-                      goto oom;
+-
+-              bbv->bv_len = bv->bv_len;
+-              bbv->bv_offset = bv->bv_offset;
+-      }
+-
+-      bio->bi_vcnt = rbh->bi_vcnt;
+-      bio->bi_size = rbh->bi_size;
+-
+-      return bio;
+-
+-oom:
+-      while (--i >= 0)
+-              __free_page(bio->bi_io_vec[i].bv_page);
+-
+-      bio_put(bio);
+-      return NULL;
+-}
+-
+-static struct bio *loop_get_buffer(struct loop_device *lo, struct bio *rbh)
+-{
+-      struct bio *bio;
+-
+-      /*
+-       * When called on the page reclaim -> writepage path, this code can
+-       * trivially consume all memory.  So we drop PF_MEMALLOC to avoid
+-       * stealing all the page reserves and throttle to the writeout rate.
+-       * pdflush will have been woken by page reclaim.  Let it do its work.
+-       */
+-      do {
+-              int flags = current->flags;
+-
+-              current->flags &= ~PF_MEMALLOC;
+-              bio = loop_copy_bio(rbh);
+-              if (flags & PF_MEMALLOC)
+-                      current->flags |= PF_MEMALLOC;
+-
+-              if (bio == NULL)
+-                      blk_congestion_wait(WRITE, HZ/10);
+-      } while (bio == NULL);
+-
+-      bio->bi_end_io = loop_end_io_transfer;
+-      bio->bi_private = rbh;
+-      bio->bi_sector = rbh->bi_sector + (lo->lo_offset >> 9);
+-      bio->bi_rw = rbh->bi_rw;
+-      bio->bi_bdev = lo->lo_device;
+-
+-      return bio;
+-}
+-
+-static int loop_transfer_bio(struct loop_device *lo,
+-                           struct bio *to_bio, struct bio *from_bio)
+-{
+-      sector_t IV;
+-      struct bio_vec *from_bvec, *to_bvec;
+-      char *vto, *vfrom;
+-      int ret = 0, i;
+-
+-      IV = from_bio->bi_sector + (lo->lo_offset >> 9);
+-
+-      __bio_for_each_segment(from_bvec, from_bio, i, 0) {
+-              to_bvec = &to_bio->bi_io_vec[i];
+-
+-              kmap(from_bvec->bv_page);
+-              kmap(to_bvec->bv_page);
+-              vfrom = page_address(from_bvec->bv_page) + from_bvec->bv_offset;
+-              vto = page_address(to_bvec->bv_page) + to_bvec->bv_offset;
+-              ret |= lo_do_transfer(lo, bio_data_dir(to_bio), vto, vfrom,
+-                                      from_bvec->bv_len, IV);
+-              kunmap(from_bvec->bv_page);
+-              kunmap(to_bvec->bv_page);
+-              IV += from_bvec->bv_len >> 9;
+-      }
+-
+-      return ret;
+-}
+-              
+ static int loop_make_request(request_queue_t *q, struct bio *old_bio)
+ {
+-      struct bio *new_bio = NULL;
+       struct loop_device *lo = q->queuedata;
+       int rw = bio_rw(old_bio);
+@@ -543,31 +416,11 @@ static int loop_make_request(request_que
+               printk(KERN_ERR "loop: unknown command (%x)\n", rw);
+               goto err;
+       }
+-
+-      /*
+-       * file backed, queue for loop_thread to handle
+-       */
+-      if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
+-              loop_add_bio(lo, old_bio);
+-              return 0;
+-      }
+-
+-      /*
+-       * piggy old buffer on original, and submit for I/O
+-       */
+-      new_bio = loop_get_buffer(lo, old_bio);
+-      if (rw == WRITE) {
+-              if (loop_transfer_bio(lo, new_bio, old_bio))
+-                      goto err;
+-      }
+-
+-      generic_make_request(new_bio);
++      loop_add_bio(lo, old_bio);
+       return 0;
+-
+ err:
+       if (atomic_dec_and_test(&lo->lo_pending))
+               up(&lo->lo_bh_mutex);
+-      loop_put_buffer(new_bio);
+ out:
+       bio_io_error(old_bio, old_bio->bi_size);
+       return 0;
+@@ -580,20 +433,8 @@ static inline void loop_handle_bio(struc
+ {
+       int ret;
+-      /*
+-       * For block backed loop, we know this is a READ
+-       */
+-      if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
+-              ret = do_bio_filebacked(lo, bio);
+-              bio_endio(bio, bio->bi_size, ret);
+-      } else {
+-              struct bio *rbh = bio->bi_private;
+-
+-              ret = loop_transfer_bio(lo, bio, rbh);
+-
+-              bio_endio(rbh, rbh->bi_size, ret);
+-              loop_put_buffer(bio);
+-      }
++      ret = do_bio_filebacked(lo, bio);
++      bio_endio(bio, bio->bi_size, ret);
+ }
+ /*
+@@ -660,6 +501,7 @@ static int loop_set_fd(struct loop_devic
+       struct file     *file;
+       struct inode    *inode;
+       struct block_device *lo_device = NULL;
++      struct address_space *mapping;
+       unsigned lo_blocksize;
+       int             lo_flags = 0;
+       int             error;
+@@ -676,35 +518,27 @@ static int loop_set_fd(struct loop_devic
+       if (!file)
+               goto out;
+-      error = -EINVAL;
+-      inode = file->f_dentry->d_inode;
++      mapping = file->f_mapping;
++      inode = mapping->host;
+       if (!(file->f_mode & FMODE_WRITE))
+               lo_flags |= LO_FLAGS_READ_ONLY;
+-      if (S_ISBLK(inode->i_mode)) {
+-              lo_device = inode->i_bdev;
+-              if (lo_device == bdev) {
+-                      error = -EBUSY;
+-                      goto out;
+-              }
+-              lo_blocksize = block_size(lo_device);
+-              if (bdev_read_only(lo_device))
+-                      lo_flags |= LO_FLAGS_READ_ONLY;
+-      } else if (S_ISREG(inode->i_mode)) {
+-              struct address_space_operations *aops = inode->i_mapping->a_ops;
++      error = -EINVAL;
++
++      if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) {
++              struct address_space_operations *aops = mapping->a_ops;
+               /*
+                * If we can't read - sorry. If we only can't write - well,
+                * it's going to be read-only.
+                */
+-              if (!inode->i_fop->sendfile)
++              if (!lo_file->f_op->sendfile)
+                       goto out_putf;
+               if (!aops->prepare_write || !aops->commit_write)
+                       lo_flags |= LO_FLAGS_READ_ONLY;
+               lo_blocksize = inode->i_blksize;
+-              lo_flags |= LO_FLAGS_DO_BMAP;
+               error = 0;
+       } else
+               goto out_putf;
+@@ -728,9 +562,8 @@ static int loop_set_fd(struct loop_devic
+               fput(file);
+               goto out_putf;
+       }
+-      lo->old_gfp_mask = mapping_gfp_mask(inode->i_mapping);
+-      mapping_set_gfp_mask(inode->i_mapping,
+-                           lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
++      lo->old_gfp_mask = mapping_gfp_mask(mapping);
++      mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
+       set_blocksize(bdev, lo_blocksize);
+@@ -743,20 +576,6 @@ static int loop_set_fd(struct loop_devic
+       blk_queue_make_request(lo->lo_queue, loop_make_request);
+       lo->lo_queue->queuedata = lo;
+-      /*
+-       * we remap to a block device, make sure we correctly stack limits
+-       */
+-      if (S_ISBLK(inode->i_mode)) {
+-              request_queue_t *q = bdev_get_queue(lo_device);
+-
+-              blk_queue_max_sectors(lo->lo_queue, q->max_sectors);
+-              blk_queue_max_phys_segments(lo->lo_queue,q->max_phys_segments);
+-              blk_queue_max_hw_segments(lo->lo_queue, q->max_hw_segments);
+-              blk_queue_max_segment_size(lo->lo_queue, q->max_segment_size);
+-              blk_queue_segment_boundary(lo->lo_queue, q->seg_boundary_mask);
+-              blk_queue_merge_bvec(lo->lo_queue, q->merge_bvec_fn);
+-      }
+-
+       kernel_thread(loop_thread, lo, CLONE_KERNEL);
+       down(&lo->lo_sem);
+@@ -846,7 +665,7 @@ static int loop_clr_fd(struct loop_devic
+       memset(lo->lo_file_name, 0, LO_NAME_SIZE);
+       invalidate_bdev(bdev, 0);
+       set_capacity(disks[lo->lo_number], 0);
+-      mapping_set_gfp_mask(filp->f_dentry->d_inode->i_mapping, gfp);
++      mapping_set_gfp_mask(filp->f_mapping, gfp);
+       lo->lo_state = Lo_unbound;
+       fput(filp);
+       /* This is safe: open() is still holding a reference. */
+@@ -1056,19 +875,19 @@ loop_get_status64(struct loop_device *lo
+       return err;
+ }
+-static int lo_ioctl(struct inode * inode, struct file * file,
++static int lo_ioctl(struct block_device *bdev, struct file *file,
+       unsigned int cmd, unsigned long arg)
+ {
+-      struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
++      struct loop_device *lo = bdev->bd_disk->private_data;
+       int err;
+       down(&lo->lo_ctl_mutex);
+       switch (cmd) {
+       case LOOP_SET_FD:
+-              err = loop_set_fd(lo, file, inode->i_bdev, arg);
++              err = loop_set_fd(lo, file, bdev, arg);
+               break;
+       case LOOP_CLR_FD:
+-              err = loop_clr_fd(lo, inode->i_bdev);
++              err = loop_clr_fd(lo, bdev);
+               break;
+       case LOOP_SET_STATUS:
+               err = loop_set_status_old(lo, (struct loop_info *) arg);
+@@ -1089,9 +908,9 @@ static int lo_ioctl(struct inode * inode
+       return err;
+ }
+-static int lo_open(struct inode *inode, struct file *file)
++static int lo_open(struct block_device *bdev, struct file *file)
+ {
+-      struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
++      struct loop_device *lo = bdev->bd_disk->private_data;
+       down(&lo->lo_ctl_mutex);
+       lo->lo_refcnt++;
+@@ -1100,9 +919,9 @@ static int lo_open(struct inode *inode, 
+       return 0;
+ }
+-static int lo_release(struct inode *inode, struct file *file)
++static int lo_release(struct gendisk *disk)
+ {
+-      struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
++      struct loop_device *lo = disk->private_data;
+       down(&lo->lo_ctl_mutex);
+       --lo->lo_refcnt;
+@@ -1124,6 +943,7 @@ static struct block_device_operations lo
+ MODULE_PARM(max_loop, "i");
+ MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)");
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
+ int loop_register_transfer(struct loop_func_table *funcs)
+ {
+@@ -1212,14 +1032,18 @@ int __init loop_init(void)
+               sprintf(disk->devfs_name, "loop/%d", i);
+               disk->private_data = lo;
+               disk->queue = lo->lo_queue;
+-              add_disk(disk);
+       }
++
++      /* We cannot fail after we call this, so another loop!*/
++      for (i = 0; i < max_loop; i++)
++              add_disk(disks[i]);
+       printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop);
+       return 0;
+ out_mem4:
+       while (i--)
+               blk_put_queue(loop_dev[i].lo_queue);
++      devfs_remove("loop");
+       i = max_loop;
+ out_mem3:
+       while (i--)
+--- linux-2.6.0/drivers/block/Makefile 2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/Makefile  2003-12-28 23:21:35.000000000 -0800
+@@ -18,6 +18,7 @@ obj-y        := elevator.o ll_rw_blk.o ioctl.o 
+ obj-$(CONFIG_IOSCHED_NOOP)    += noop-iosched.o
+ obj-$(CONFIG_IOSCHED_AS)      += as-iosched.o
+ obj-$(CONFIG_IOSCHED_DEADLINE)        += deadline-iosched.o
++obj-$(CONFIG_IOSCHED_CFQ)     += cfq-iosched.o
+ obj-$(CONFIG_MAC_FLOPPY)      += swim3.o
+ obj-$(CONFIG_BLK_DEV_FD)      += floppy.o
+ obj-$(CONFIG_BLK_DEV_FD98)    += floppy98.o
+--- linux-2.6.0/drivers/block/nbd.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/nbd.c     2003-12-28 23:21:12.000000000 -0800
+@@ -535,10 +535,10 @@ static void do_nbd_request(request_queue
+       return;
+ }
+-static int nbd_ioctl(struct inode *inode, struct file *file,
++static int nbd_ioctl(struct block_device *bdev, struct file *file,
+                    unsigned int cmd, unsigned long arg)
+ {
+-      struct nbd_device *lo = inode->i_bdev->bd_disk->private_data;
++      struct nbd_device *lo = bdev->bd_disk->private_data;
+       int error;
+       struct request sreq ;
+@@ -593,7 +593,7 @@ static int nbd_ioctl(struct inode *inode
+               error = -EINVAL;
+               file = fget(arg);
+               if (file) {
+-                      inode = file->f_dentry->d_inode;
++                      struct inode *inode = file->f_dentry->d_inode;
+                       if (inode->i_sock) {
+                               lo->file = file;
+                               lo->sock = SOCKET_I(inode);
+@@ -606,20 +606,20 @@ static int nbd_ioctl(struct inode *inode
+       case NBD_SET_BLKSIZE:
+               lo->blksize = arg;
+               lo->bytesize &= ~(lo->blksize-1);
+-              inode->i_bdev->bd_inode->i_size = lo->bytesize;
+-              set_blocksize(inode->i_bdev, lo->blksize);
++              bdev->bd_inode->i_size = lo->bytesize;
++              set_blocksize(bdev, lo->blksize);
+               set_capacity(lo->disk, lo->bytesize >> 9);
+               return 0;
+       case NBD_SET_SIZE:
+               lo->bytesize = arg & ~(lo->blksize-1);
+-              inode->i_bdev->bd_inode->i_size = lo->bytesize;
+-              set_blocksize(inode->i_bdev, lo->blksize);
++              bdev->bd_inode->i_size = lo->bytesize;
++              set_blocksize(bdev, lo->blksize);
+               set_capacity(lo->disk, lo->bytesize >> 9);
+               return 0;
+       case NBD_SET_SIZE_BLOCKS:
+               lo->bytesize = ((u64) arg) * lo->blksize;
+-              inode->i_bdev->bd_inode->i_size = lo->bytesize;
+-              set_blocksize(inode->i_bdev, lo->blksize);
++              bdev->bd_inode->i_size = lo->bytesize;
++              set_blocksize(bdev, lo->blksize);
+               set_capacity(lo->disk, lo->bytesize >> 9);
+               return 0;
+       case NBD_DO_IT:
+@@ -664,11 +664,11 @@ static int nbd_ioctl(struct inode *inode
+       case NBD_PRINT_DEBUG:
+ #ifdef PARANOIA
+               printk(KERN_INFO "%s: next = %p, prev = %p. Global: in %d, out %d\n",
+-                      inode->i_bdev->bd_disk->disk_name, lo->queue_head.next,
++                      bdev->bd_disk->disk_name, lo->queue_head.next,
+                       lo->queue_head.prev, requests_in, requests_out);
+ #else
+               printk(KERN_INFO "%s: next = %p, prev = %p\n",
+-                      inode->i_bdev->bd_disk->disk_name,
++                      bdev->bd_disk->disk_name,
+                       lo->queue_head.next, lo->queue_head.prev);
+ #endif
+               return 0;
+--- linux-2.6.0/drivers/block/paride/pcd.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/paride/pcd.c      2003-12-28 23:21:17.000000000 -0800
+@@ -243,23 +243,23 @@ static int pcd_warned;           /* Have we logge
+ /* kernel glue structures */
+-static int pcd_block_open(struct inode *inode, struct file *file)
++static int pcd_block_open(struct block_device *bdev, struct file *file)
+ {
+-      struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
+-      return cdrom_open(&cd->info, inode, file);
++      struct pcd_unit *cd = bdev->bd_disk->private_data;
++      return cdrom_open(&cd->info, bdev, file);
+ }
+-static int pcd_block_release(struct inode *inode, struct file *file)
++static int pcd_block_release(struct gendisk *disk)
+ {
+-      struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
+-      return cdrom_release(&cd->info, file);
++      struct pcd_unit *cd = disk->private_data;
++      return cdrom_release(&cd->info);
+ }
+-static int pcd_block_ioctl(struct inode *inode, struct file *file,
++static int pcd_block_ioctl(struct block_device *bdev, struct file *file,
+                               unsigned cmd, unsigned long arg)
+ {
+-      struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
+-      return cdrom_ioctl(&cd->info, inode, cmd, arg);
++      struct pcd_unit *cd = bdev->bd_disk->private_data;
++      return cdrom_ioctl(&cd->info, bdev, cmd, arg);
+ }
+ static int pcd_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0/drivers/block/paride/pd.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/paride/pd.c       2003-12-28 23:21:17.000000000 -0800
+@@ -236,11 +236,11 @@ MODULE_PARM(drive3, "1-8i");
+ #define IDE_EJECT             0xed
+ void pd_setup(char *str, int *ints);
+-static int pd_open(struct inode *inode, struct file *file);
++static int pd_open(struct block_device *bdev, struct file *file);
+ static void do_pd_request(request_queue_t * q);
+-static int pd_ioctl(struct inode *inode, struct file *file,
++static int pd_ioctl(struct block_device *bdev, struct file *file,
+                   unsigned int cmd, unsigned long arg);
+-static int pd_release(struct inode *inode, struct file *file);
++static int pd_release(struct gendisk *disk);
+ static int pd_revalidate(struct gendisk *p);
+ static int pd_detect(void);
+ static void do_pd_read(void);
+@@ -304,8 +304,6 @@ static char *pd_errs[17] = { "ERR", "IND
+ /* kernel glue structures */
+-extern struct block_device_operations pd_fops;
+-
+ static struct block_device_operations pd_fops = {
+       .owner          = THIS_MODULE,
+       .open           = pd_open,
+@@ -337,9 +335,9 @@ static void pd_init_units(void)
+       }
+ }
+-static int pd_open(struct inode *inode, struct file *file)
++static int pd_open(struct block_device *bdev, struct file *file)
+ {
+-      struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
++      struct pd_unit *disk = bdev->bd_disk->private_data;
+       disk->access++;
+@@ -350,10 +348,10 @@ static int pd_open(struct inode *inode, 
+       return 0;
+ }
+-static int pd_ioctl(struct inode *inode, struct file *file,
++static int pd_ioctl(struct block_device *bdev, struct file *file,
+        unsigned int cmd, unsigned long arg)
+ {
+-      struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
++      struct pd_unit *disk = bdev->bd_disk->private_data;
+       struct hd_geometry *geo = (struct hd_geometry *) arg;
+       struct hd_geometry g;
+@@ -372,7 +370,7 @@ static int pd_ioctl(struct inode *inode,
+                       g.sectors = disk->sectors;
+                       g.cylinders = disk->cylinders;
+               }
+-              g.start = get_start_sect(inode->i_bdev);
++              g.start = get_start_sect(bdev);
+               if (copy_to_user(geo, &g, sizeof(struct hd_geometry)))
+                       return -EFAULT;
+               return 0;
+@@ -381,9 +379,9 @@ static int pd_ioctl(struct inode *inode,
+       }
+ }
+-static int pd_release(struct inode *inode, struct file *file)
++static int pd_release(struct gendisk *p)
+ {
+-      struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
++      struct pd_unit *disk = p->private_data;
+       if (!--disk->access && disk->removable)
+               pd_doorlock(disk, IDE_DOORUNLOCK);
+--- linux-2.6.0/drivers/block/paride/pf.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/paride/pf.c       2003-12-28 23:21:17.000000000 -0800
+@@ -222,12 +222,12 @@ MODULE_PARM(drive3, "1-7i");
+ #define ATAPI_READ_10         0x28
+ #define ATAPI_WRITE_10                0x2a
+-static int pf_open(struct inode *inode, struct file *file);
++static int pf_open(struct block_device *bdev, struct file *file);
+ static void do_pf_request(request_queue_t * q);
+-static int pf_ioctl(struct inode *inode, struct file *file,
++static int pf_ioctl(struct block_device *bdev, struct file *file,
+                   unsigned int cmd, unsigned long arg);
+-static int pf_release(struct inode *inode, struct file *file);
++static int pf_release(struct gendisk *disk);
+ static int pf_detect(void);
+ static void do_pf_read(void);
+@@ -315,9 +315,9 @@ void pf_init_units(void)
+       }
+ }
+-static int pf_open(struct inode *inode, struct file *file)
++static int pf_open(struct block_device *bdev, struct file *file)
+ {
+-      struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
++      struct pf_unit *pf = bdev->bd_disk->private_data;
+       pf_identify(pf);
+@@ -334,9 +334,9 @@ static int pf_open(struct inode *inode, 
+       return 0;
+ }
+-static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++static int pf_ioctl(struct block_device *bdev, struct file *file, unsigned int cmd, unsigned long arg)
+ {
+-      struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
++      struct pf_unit *pf = bdev->bd_disk->private_data;
+       struct hd_geometry *geo = (struct hd_geometry *) arg;
+       struct hd_geometry g;
+       sector_t capacity;
+@@ -365,9 +365,9 @@ static int pf_ioctl(struct inode *inode,
+       return 0;
+ }
+-static int pf_release(struct inode *inode, struct file *file)
++static int pf_release(struct gendisk *disk)
+ {
+-      struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
++      struct pf_unit *pf = disk->private_data;
+       if (pf->access <= 0)
+               return -EINVAL;
+--- linux-2.6.0/drivers/block/ps2esdi.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/ps2esdi.c 2003-12-28 23:21:12.000000000 -0800
+@@ -81,7 +81,7 @@ static void (*current_int_handler) (u_in
+ static void ps2esdi_normal_interrupt_handler(u_int);
+ static void ps2esdi_initial_reset_int_handler(u_int);
+ static void ps2esdi_geometry_int_handler(u_int);
+-static int ps2esdi_ioctl(struct inode *inode, struct file *file,
++static int ps2esdi_ioctl(struct block_device *bdev, struct file *file,
+                        u_int cmd, u_long arg);
+ static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
+@@ -1059,10 +1059,10 @@ static void dump_cmd_complete_status(u_i
+ }
+-static int ps2esdi_ioctl(struct inode *inode,
++static int ps2esdi_ioctl(struct block_device *bdev,
+                        struct file *file, u_int cmd, u_long arg)
+ {
+-      struct ps2esdi_i_struct *p = inode->i_bdev->bd_disk->private_data;
++      struct ps2esdi_i_struct *p = bdev->bd_disk->private_data;
+       struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg;
+       int err;
+@@ -1073,7 +1073,7 @@ static int ps2esdi_ioctl(struct inode *i
+       put_user(p->head, (char *) &geometry->heads);
+       put_user(p->sect, (char *) &geometry->sectors);
+       put_user(p->cyl, (short *) &geometry->cylinders);
+-      put_user(get_start_sect(inode->i_bdev), (long *) &geometry->start);
++      put_user(get_start_sect(bdev), (long *) &geometry->start);
+       return 0;
+ }
+--- linux-2.6.0/drivers/block/rd.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/rd.c      2003-12-28 23:21:41.000000000 -0800
+@@ -1,15 +1,15 @@
+ /*
+  * ramdisk.c - Multiple RAM disk driver - gzip-loading version - v. 0.8 beta.
+- * 
+- * (C) Chad Page, Theodore Ts'o, et. al, 1995. 
++ *
++ * (C) Chad Page, Theodore Ts'o, et. al, 1995.
+  *
+  * This RAM disk is designed to have filesystems created on it and mounted
+- * just like a regular floppy disk.  
+- *  
++ * just like a regular floppy disk.
++ *
+  * It also does something suggested by Linus: use the buffer cache as the
+  * RAM disk data.  This makes it possible to dynamically allocate the RAM disk
+- * buffer - with some consequences I have to deal with as I write this. 
+- * 
++ * buffer - with some consequences I have to deal with as I write this.
++ *
+  * This code is based on the original ramdisk.c, written mostly by
+  * Theodore Ts'o (TYT) in 1991.  The code was largely rewritten by
+  * Chad Page to use the buffer cache to store the RAM disk data in
+@@ -33,7 +33,7 @@
+  *
+  *  Added initrd: Werner Almesberger & Hans Lermen, Feb '96
+  *
+- * 4/25/96 : Made RAM disk size a parameter (default is now 4 MB) 
++ * 4/25/96 : Made RAM disk size a parameter (default is now 4 MB)
+  *            - Chad Page
+  *
+  * Add support for fs images split across >1 disk, Paul Gortmaker, Mar '98
+@@ -60,7 +60,7 @@
+ #include <asm/uaccess.h>
+ /* The RAM disk size is now a parameter */
+-#define NUM_RAMDISKS 16               /* This cannot be overridden (yet) */ 
++#define NUM_RAMDISKS 16               /* This cannot be overridden (yet) */
+ /* Various static variables go here.  Most are used only in the RAM disk code.
+  */
+@@ -73,7 +73,7 @@ static struct request_queue *rd_queue[NU
+  * Parameters for the boot-loading of the RAM disk.  These are set by
+  * init/main.c (from arguments to the kernel command line) or from the
+  * architecture-specific setup routine (from the stored boot sector
+- * information). 
++ * information).
+  */
+ int rd_size = CONFIG_BLK_DEV_RAM_SIZE;                /* Size of the RAM disks */
+ /*
+@@ -94,7 +94,7 @@ int rd_blocksize = BLOCK_SIZE;                       /* bloc
+  *               2000 Transmeta Corp.
+  * aops copied from ramfs.
+  */
+-static int ramdisk_readpage(struct file *file, struct page * page)
++static int ramdisk_readpage(struct file *file, struct page *page)
+ {
+       if (!PageUptodate(page)) {
+               void *kaddr = kmap_atomic(page, KM_USER0);
+@@ -108,7 +108,8 @@ static int ramdisk_readpage(struct file 
+       return 0;
+ }
+-static int ramdisk_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
++static int ramdisk_prepare_write(struct file *file, struct page *page,
++                              unsigned offset, unsigned to)
+ {
+       if (!PageUptodate(page)) {
+               void *kaddr = kmap_atomic(page, KM_USER0);
+@@ -122,7 +123,8 @@ static int ramdisk_prepare_write(struct 
+       return 0;
+ }
+-static int ramdisk_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
++static int ramdisk_commit_write(struct file *file, struct page *page,
++                              unsigned offset, unsigned to)
+ {
+       return 0;
+ }
+@@ -212,7 +214,7 @@ static int rd_blkdev_pagecache_IO(int rw
+  * 19-JAN-1998  Richard Gooch <rgooch@atnf.csiro.au>  Added devfs support
+  *
+  */
+-static int rd_make_request(request_queue_t * q, struct bio *bio)
++static int rd_make_request(request_queue_t *q, struct bio *bio)
+ {
+       struct block_device *bdev = bio->bi_bdev;
+       struct address_space * mapping = bdev->bd_inode->i_mapping;
+@@ -242,17 +244,19 @@ fail:
+       return 0;
+ } 
+-static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++static int rd_ioctl(struct block_device *bdev, struct file *file,
++                      unsigned int cmd, unsigned long arg)
+ {
+       int error;
+-      struct block_device *bdev = inode->i_bdev;
+       if (cmd != BLKFLSBUF)
+               return -EINVAL;
+-      /* special: we want to release the ramdisk memory,
+-         it's not like with the other blockdevices where
+-         this ioctl only flushes away the buffer cache. */
++      /*
++       * special: we want to release the ramdisk memory, it's not like with
++       * the other blockdevices where this ioctl only flushes away the buffer
++       * cache
++       */
+       error = -EBUSY;
+       down(&bdev->bd_sem);
+       if (bdev->bd_openers <= 2) {
+@@ -268,16 +272,15 @@ static struct backing_dev_info rd_backin
+       .memory_backed  = 1,    /* Does not contribute to dirty memory */
+ };
+-static int rd_open(struct inode * inode, struct file * filp)
++static int rd_open(struct block_device *bdev, struct file *filp)
+ {
+-      unsigned unit = iminor(inode);
++      unsigned unit = MINOR(bdev->bd_dev);
+       /*
+        * Immunize device against invalidate_buffers() and prune_icache().
+        */
+       if (rd_bdev[unit] == NULL) {
+-              struct block_device *bdev = inode->i_bdev;
+-              inode = igrab(bdev->bd_inode);
++              struct inode *inode = igrab(bdev->bd_inode);
+               rd_bdev[unit] = bdev;
+               bdev->bd_openers++;
+               bdev->bd_block_size = rd_blocksize;
+@@ -295,12 +298,14 @@ static struct block_device_operations rd
+       .ioctl =        rd_ioctl,
+ };
+-/* Before freeing the module, invalidate all of the protected buffers! */
+-static void __exit rd_cleanup (void)
++/*
++ * Before freeing the module, invalidate all of the protected buffers!
++ */
++static void __exit rd_cleanup(void)
+ {
+       int i;
+-      for (i = 0 ; i < NUM_RAMDISKS; i++) {
++      for (i = 0; i < NUM_RAMDISKS; i++) {
+               struct block_device *bdev = rd_bdev[i];
+               rd_bdev[i] = NULL;
+               if (bdev) {
+@@ -311,17 +316,19 @@ static void __exit rd_cleanup (void)
+               put_disk(rd_disks[i]);
+       }
+       devfs_remove("rd");
+-      unregister_blkdev(RAMDISK_MAJOR, "ramdisk" );
++      unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
+ }
+-/* This is the registration and initialization section of the RAM disk driver */
+-static int __init rd_init (void)
++/*
++ * This is the registration and initialization section of the RAM disk driver
++ */
++static int __init rd_init(void)
+ {
+       int i;
+       int err = -ENOMEM;
+       if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 ||
+-          (rd_blocksize & (rd_blocksize-1))) {
++                      (rd_blocksize & (rd_blocksize-1))) {
+               printk("RAMDISK: wrong blocksize %d, reverting to defaults\n",
+                      rd_blocksize);
+               rd_blocksize = BLOCK_SIZE;
+@@ -362,8 +369,8 @@ static int __init rd_init (void)
+       /* rd_size is given in kB */
+       printk("RAMDISK driver initialized: "
+-             "%d RAM disks of %dK size %d blocksize\n",
+-             NUM_RAMDISKS, rd_size, rd_blocksize);
++              "%d RAM disks of %dK size %d blocksize\n",
++              NUM_RAMDISKS, rd_size, rd_blocksize);
+       return 0;
+ out_queue:
+--- linux-2.6.0/drivers/block/scsi_ioctl.c     2003-12-17 21:20:02.000000000 -0800
++++ 25/drivers/block/scsi_ioctl.c      2003-12-28 23:26:36.000000000 -0800
+@@ -312,7 +312,7 @@ static int sg_scsi_ioctl(request_queue_t
+               return -EFAULT;
+       if (in_len > PAGE_SIZE || out_len > PAGE_SIZE)
+               return -EINVAL;
+-      if (get_user(opcode, sic->data))
++      if (get_user(opcode, (int *)sic->data))
+               return -EFAULT;
+       bytes = max(in_len, out_len);
+--- linux-2.6.0/drivers/block/swim3.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/swim3.c   2003-12-28 23:21:17.000000000 -0800
+@@ -239,10 +239,9 @@ static int grab_drive(struct floppy_stat
+                     int interruptible);
+ static void release_drive(struct floppy_state *fs);
+ static int fd_eject(struct floppy_state *fs);
+-static int floppy_ioctl(struct inode *inode, struct file *filp,
++static int floppy_ioctl(struct block_device *bdev, struct file *filp,
+                       unsigned int cmd, unsigned long param);
+-static int floppy_open(struct inode *inode, struct file *filp);
+-static int floppy_release(struct inode *inode, struct file *filp);
++static int floppy_open(struct block_device *bdev, struct file *filp);
+ static int floppy_check_change(struct gendisk *disk);
+ static int floppy_revalidate(struct gendisk *disk);
+ static int swim3_add_device(struct device_node *swims);
+@@ -811,10 +810,10 @@ static int fd_eject(struct floppy_state 
+ static struct floppy_struct floppy_type =
+       { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL };    /*  7 1.44MB 3.5"   */
+-static int floppy_ioctl(struct inode *inode, struct file *filp,
++static int floppy_ioctl(struct block_device *bdev, struct file *filp,
+                       unsigned int cmd, unsigned long param)
+ {
+-      struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++      struct floppy_state *fs = bdev->bd_disk->private_data;
+       int err;
+               
+       if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
+@@ -838,9 +837,9 @@ static int floppy_ioctl(struct inode *in
+       return -ENOTTY;
+ }
+-static int floppy_open(struct inode *inode, struct file *filp)
++static int floppy_open(struct block_device *bdev, struct file *filp)
+ {
+-      struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++      struct floppy_state *fs = bdev->bd_disk->private_data;
+       volatile struct swim3 *sw = fs->swim3;
+       int n, err = 0;
+@@ -876,7 +875,7 @@ static int floppy_open(struct inode *ino
+       if (err == 0 && (filp->f_flags & O_NDELAY) == 0
+           && (filp->f_mode & 3)) {
+-              check_disk_change(inode->i_bdev);
++              check_disk_change(bdev);
+               if (fs->ejected)
+                       err = -ENXIO;
+       }
+@@ -904,9 +903,9 @@ static int floppy_open(struct inode *ino
+       return 0;
+ }
+-static int floppy_release(struct inode *inode, struct file *filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-      struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++      struct floppy_state *fs = disk->private_data;
+       volatile struct swim3 *sw = fs->swim3;
+       if (fs->ref_count > 0 && --fs->ref_count == 0) {
+               swim3_action(fs, MOTOR_OFF);
+--- linux-2.6.0/drivers/block/swim_iop.c       2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/swim_iop.c        2003-12-28 23:21:17.000000000 -0800
+@@ -98,10 +98,10 @@ static void swimiop_receive(struct iop_m
+ static void swimiop_status_update(int, struct swim_drvstatus *);
+ static int swimiop_eject(struct floppy_state *fs);
+-static int floppy_ioctl(struct inode *inode, struct file *filp,
++static int floppy_ioctl(struct block_device *bdev, struct file *filp,
+                       unsigned int cmd, unsigned long param);
+-static int floppy_open(struct inode *inode, struct file *filp);
+-static int floppy_release(struct inode *inode, struct file *filp);
++static int floppy_open(struct block_device *bdev, struct file *filp);
++static int floppy_release(struct gendisk *disk);
+ static int floppy_check_change(struct gendisk *disk);
+ static int floppy_revalidate(struct gendisk *disk);
+ static int grab_drive(struct floppy_state *fs, enum swim_state state,
+@@ -348,10 +348,10 @@ static int swimiop_eject(struct floppy_s
+ static struct floppy_struct floppy_type =
+       { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL };    /*  7 1.44MB 3.5"   */
+-static int floppy_ioctl(struct inode *inode, struct file *filp,
++static int floppy_ioctl(struct block_device *bdev, struct file *filp,
+                       unsigned int cmd, unsigned long param)
+ {
+-      struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++      struct floppy_state *fs = bdev->bd_disk->private_data;
+       int err;
+       if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
+@@ -372,15 +372,15 @@ static int floppy_ioctl(struct inode *in
+       return -ENOTTY;
+ }
+-static int floppy_open(struct inode *inode, struct file *filp)
++static int floppy_open(struct block_device *bdev, struct file *filp)
+ {
+-      struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++      struct floppy_state *fs = bdev->bd_disk->private_data;
+       if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
+               return -EBUSY;
+       if ((filp->f_flags & O_NDELAY) == 0 && (filp->f_mode & 3)) {
+-              check_disk_change(inode->i_bdev);
++              check_disk_change(bdev);
+               if (fs->ejected)
+                       return -ENXIO;
+       }
+@@ -396,9 +396,9 @@ static int floppy_open(struct inode *ino
+       return 0;
+ }
+-static int floppy_release(struct inode *inode, struct file *filp)
++static int floppy_release(struct gendisk *disk)
+ {
+-      struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
++      struct floppy_state *fs = disk->private_data;
+       if (fs->ref_count > 0)
+               fs->ref_count--;
+       return 0;
+--- linux-2.6.0/drivers/block/umem.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/umem.c    2003-12-28 23:21:14.000000000 -0800
+@@ -153,7 +153,6 @@ struct cardinfo {
+ };
+ static struct cardinfo cards[MM_MAXCARDS];
+-static struct block_device_operations mm_fops;
+ static struct timer_list battery_timer;
+ static int num_cards = 0;
+@@ -818,10 +817,10 @@ static int mm_revalidate(struct gendisk 
+ --                            mm_ioctl
+ -----------------------------------------------------------------------------------
+ */
+-static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
++static int mm_ioctl(struct block_device *bdev, struct file *f, unsigned int cmd, unsigned long arg)
+ {
+       if (cmd == HDIO_GETGEO) {
+-              struct cardinfo *card = i->i_bdev->bd_disk->private_data;
++              struct cardinfo *card = bdev->bd_disk->private_data;
+               int size = card->mm_size * (1024 / MM_HARDSECT);
+               struct hd_geometry geo;
+               /*
+@@ -831,7 +830,7 @@ static int mm_ioctl(struct inode *i, str
+                */
+               geo.heads     = 64;
+               geo.sectors   = 32;
+-              geo.start     = get_start_sect(i->i_bdev);
++              geo.start     = get_start_sect(bdev);
+               geo.cylinders = size / (geo.heads * geo.sectors);
+               if (copy_to_user((void *) arg, &geo, sizeof(geo)))
+--- linux-2.6.0/drivers/block/xd.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/xd.c      2003-12-28 23:21:12.000000000 -0800
+@@ -322,9 +322,9 @@ static void do_xd_request (request_queue
+ }
+ /* xd_ioctl: handle device ioctl's */
+-static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
++static int xd_ioctl (struct block_device *bdev,struct file *file,u_int cmd,u_long arg)
+ {
+-      XD_INFO *p = inode->i_bdev->bd_disk->private_data;
++      XD_INFO *p = bdev->bd_disk->private_data;
+       switch (cmd) {
+               case HDIO_GETGEO:
+@@ -334,7 +334,7 @@ static int xd_ioctl (struct inode *inode
+                       g.heads = p->heads;
+                       g.sectors = p->sectors;
+                       g.cylinders = p->cylinders;
+-                      g.start = get_start_sect(inode->i_bdev);
++                      g.start = get_start_sect(bdev);
+                       return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
+               }
+               case HDIO_SET_DMA:
+--- linux-2.6.0/drivers/block/xd.h     2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/xd.h      2003-12-28 23:21:12.000000000 -0800
+@@ -105,7 +105,7 @@ static u_char xd_detect (u_char *control
+ static u_char xd_initdrives (void (*init_drive)(u_char drive));
+ static void do_xd_request (request_queue_t * q);
+-static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);
++static int xd_ioctl (struct block_device *bdev,struct file *file,unsigned int cmd,unsigned long arg);
+ static int xd_readwrite (u_char operation,XD_INFO *disk,char *buffer,u_int block,u_int count);
+ static void xd_recalibrate (u_char drive);
+--- linux-2.6.0/drivers/block/z2ram.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/block/z2ram.c   2003-12-28 23:21:17.000000000 -0800
+@@ -67,7 +67,6 @@ static int current_device   = -1;
+ static spinlock_t z2ram_lock = SPIN_LOCK_UNLOCKED;
+-static struct block_device_operations z2_fops;
+ static struct gendisk *z2ram_gendisk;
+ static void do_z2_request(request_queue_t *q)
+@@ -141,7 +140,7 @@ get_chipram( void )
+ }
+ static int
+-z2_open( struct inode *inode, struct file *filp )
++z2_open( struct block_device *bdev, struct file *filp )
+ {
+     int device;
+     int max_z2_map = ( Z2RAM_SIZE / Z2RAM_CHUNKSIZE ) *
+@@ -150,7 +149,7 @@ z2_open( struct inode *inode, struct fil
+       sizeof( z2ram_map[0] );
+     int rc = -ENOMEM;
+-    device = iminor(inode);
++    device = MINOR(bdev->bd_dev);
+     if ( current_device != -1 && current_device != device )
+     {
+@@ -301,8 +300,7 @@ err_out:
+     return rc;
+ }
+-static int
+-z2_release( struct inode *inode, struct file *filp )
++static int z2_release(struct gendisk *disk)
+ {
+     if ( current_device == -1 )
+       return 0;     
+--- linux-2.6.0/drivers/bluetooth/bluecard_cs.c        2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/bluetooth/bluecard_cs.c 2003-12-28 23:22:54.000000000 -0800
+@@ -869,7 +869,7 @@ dev_link_t *bluecard_attach(void)
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != CS_SUCCESS) {
+               cs_error(link->handle, RegisterClient, ret);
+               bluecard_detach(link);
+@@ -898,7 +898,7 @@ void bluecard_detach(dev_link_t *link)
+               bluecard_release(link);
+       if (link->handle) {
+-              ret = CardServices(DeregisterClient, link->handle);
++              ret = pcmcia_deregister_client(link->handle);
+               if (ret != CS_SUCCESS)
+                       cs_error(link->handle, DeregisterClient, ret);
+       }
+@@ -910,25 +910,21 @@ void bluecard_detach(dev_link_t *link)
+ }
+-static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
++static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
+ {
+       int i;
+-      i = CardServices(fn, handle, tuple);
++      i = pcmcia_get_first_tuple(handle, tuple);
+       if (i != CS_SUCCESS)
+               return CS_NO_MORE_ITEMS;
+-      i = CardServices(GetTupleData, handle, tuple);
++      i = pcmcia_get_tuple_data(handle, tuple);
+       if (i != CS_SUCCESS)
+               return i;
+-      return CardServices(ParseTuple, handle, tuple, parse);
++      return pcmcia_parse_tuple(handle, tuple, parse);
+ }
+-
+-#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+-#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
+-
+ void bluecard_config(dev_link_t *link)
+ {
+       client_handle_t handle = link->handle;
+@@ -956,7 +952,7 @@ void bluecard_config(dev_link_t *link)
+       /* Configure card */
+       link->state |= DEV_CONFIG;
+-      i = CardServices(GetConfigurationInfo, handle, &config);
++      i = pcmcia_get_configuration_info(handle, &config);
+       link->conf.Vcc = config.Vcc;
+       link->conf.ConfigIndex = 0x20;
+@@ -965,7 +961,7 @@ void bluecard_config(dev_link_t *link)
+       for (n = 0; n < 0x400; n += 0x40) {
+               link->io.BasePort1 = n ^ 0x300;
+-              i = CardServices(RequestIO, link->handle, &link->io);
++              i = pcmcia_request_io(link->handle, &link->io);
+               if (i == CS_SUCCESS)
+                       break;
+       }
+@@ -975,13 +971,13 @@ void bluecard_config(dev_link_t *link)
+               goto failed;
+       }
+-      i = CardServices(RequestIRQ, link->handle, &link->irq);
++      i = pcmcia_request_irq(link->handle, &link->irq);
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestIRQ, i);
+               link->irq.AssignedIRQ = 0;
+       }
+-      i = CardServices(RequestConfiguration, link->handle, &link->conf);
++      i = pcmcia_request_configuration(link->handle, &link->conf);
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestConfiguration, i);
+               goto failed;
+@@ -1013,9 +1009,9 @@ void bluecard_release(dev_link_t *link)
+       link->dev = NULL;
+-      CardServices(ReleaseConfiguration, link->handle);
+-      CardServices(ReleaseIO, link->handle, &link->io);
+-      CardServices(ReleaseIRQ, link->handle, &link->irq);
++      pcmcia_release_configuration(link->handle);
++      pcmcia_release_io(link->handle, &link->io);
++      pcmcia_release_irq(link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+ }
+@@ -1043,14 +1039,14 @@ int bluecard_event(event_t event, int pr
+               /* Fall through... */
+       case CS_EVENT_RESET_PHYSICAL:
+               if (link->state & DEV_CONFIG)
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               break;
+       case CS_EVENT_PM_RESUME:
+               link->state &= ~DEV_SUSPEND;
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (DEV_OK(link))
+-                      CardServices(RequestConfiguration, link->handle, &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+               break;
+       }
+--- linux-2.6.0/drivers/bluetooth/bt3c_cs.c    2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/bluetooth/bt3c_cs.c     2003-12-28 23:22:54.000000000 -0800
+@@ -615,7 +615,7 @@ dev_link_t *bt3c_attach(void)
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != CS_SUCCESS) {
+               cs_error(link->handle, RegisterClient, ret);
+               bt3c_detach(link);
+@@ -644,7 +644,7 @@ void bt3c_detach(dev_link_t *link)
+               bt3c_release(link);
+       if (link->handle) {
+-              ret = CardServices(DeregisterClient, link->handle);
++              ret = pcmcia_deregister_client(link->handle);
+               if (ret != CS_SUCCESS)
+                       cs_error(link->handle, DeregisterClient, ret);
+       }
+@@ -655,25 +655,30 @@ void bt3c_detach(dev_link_t *link)
+       kfree(info);
+ }
+-
+-static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
++static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
+ {
+       int i;
+-      i = CardServices(fn, handle, tuple);
+-      if (i != CS_SUCCESS)
+-              return CS_NO_MORE_ITEMS;
+-
+-      i = CardServices(GetTupleData, handle, tuple);
++      i = pcmcia_get_tuple_data(handle, tuple);
+       if (i != CS_SUCCESS)
+               return i;
+-      return CardServices(ParseTuple, handle, tuple, parse);
++      return pcmcia_parse_tuple(handle, tuple, parse);
+ }
++static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
++{
++      if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
++              return CS_NO_MORE_ITEMS;
++      return get_tuple(handle, tuple, parse);
++}
+-#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+-#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
++static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
++{
++      if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
++              return CS_NO_MORE_ITEMS;
++      return get_tuple(handle, tuple, parse);
++}
+ void bt3c_config(dev_link_t *link)
+ {
+@@ -704,7 +709,7 @@ void bt3c_config(dev_link_t *link)
+       /* Configure card */
+       link->state |= DEV_CONFIG;
+-      i = CardServices(GetConfigurationInfo, handle, &config);
++      i = pcmcia_get_configuration_info(handle, &config);
+       link->conf.Vcc = config.Vcc;
+       /* First pass: look for a config entry that looks normal. */
+@@ -725,7 +730,7 @@ void bt3c_config(dev_link_t *link)
+                               link->conf.ConfigIndex = cf->index;
+                               link->io.BasePort1 = cf->io.win[0].base;
+                               link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
+-                              i = CardServices(RequestIO, link->handle, &link->io);
++                              i = pcmcia_request_io(link->handle, &link->io);
+                               if (i == CS_SUCCESS)
+                                       goto found_port;
+                       }
+@@ -744,7 +749,7 @@ next_entry:
+                       for (j = 0; j < 5; j++) {
+                               link->io.BasePort1 = base[j];
+                               link->io.IOAddrLines = base[j] ? 16 : 3;
+-                              i = CardServices(RequestIO, link->handle, &link->io);
++                              i = pcmcia_request_io(link->handle, &link->io);
+                               if (i == CS_SUCCESS)
+                                       goto found_port;
+                       }
+@@ -759,13 +764,13 @@ found_port:
+               goto failed;
+       }
+-      i = CardServices(RequestIRQ, link->handle, &link->irq);
++      i = pcmcia_request_irq(link->handle, &link->irq);
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestIRQ, i);
+               link->irq.AssignedIRQ = 0;
+       }
+-      i = CardServices(RequestConfiguration, link->handle, &link->conf);
++      i = pcmcia_request_configuration(link->handle, &link->conf);
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestConfiguration, i);
+               goto failed;
+@@ -797,9 +802,9 @@ void bt3c_release(dev_link_t *link)
+       link->dev = NULL;
+-      CardServices(ReleaseConfiguration, link->handle);
+-      CardServices(ReleaseIO, link->handle, &link->io);
+-      CardServices(ReleaseIRQ, link->handle, &link->irq);
++      pcmcia_release_configuration(link->handle);
++      pcmcia_release_io(link->handle, &link->io);
++      pcmcia_release_irq(link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+ }
+@@ -827,14 +832,14 @@ int bt3c_event(event_t event, int priori
+               /* Fall through... */
+       case CS_EVENT_RESET_PHYSICAL:
+               if (link->state & DEV_CONFIG)
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               break;
+       case CS_EVENT_PM_RESUME:
+               link->state &= ~DEV_SUSPEND;
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (DEV_OK(link))
+-                      CardServices(RequestConfiguration, link->handle, &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+               break;
+       }
+--- linux-2.6.0/drivers/bluetooth/btuart_cs.c  2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/bluetooth/btuart_cs.c   2003-12-28 23:22:54.000000000 -0800
+@@ -622,7 +622,7 @@ dev_link_t *btuart_attach(void)
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != CS_SUCCESS) {
+               cs_error(link->handle, RegisterClient, ret);
+               btuart_detach(link);
+@@ -651,7 +651,7 @@ void btuart_detach(dev_link_t *link)
+               btuart_release(link);
+       if (link->handle) {
+-              ret = CardServices(DeregisterClient, link->handle);
++              ret = pcmcia_deregister_client(link->handle);
+               if (ret != CS_SUCCESS)
+                       cs_error(link->handle, DeregisterClient, ret);
+       }
+@@ -662,25 +662,30 @@ void btuart_detach(dev_link_t *link)
+       kfree(info);
+ }
+-
+-static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
++static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
+ {
+       int i;
+-      i = CardServices(fn, handle, tuple);
+-      if (i != CS_SUCCESS)
+-              return CS_NO_MORE_ITEMS;
+-
+-      i = CardServices(GetTupleData, handle, tuple);
++      i = pcmcia_get_tuple_data(handle, tuple);
+       if (i != CS_SUCCESS)
+               return i;
+-      return CardServices(ParseTuple, handle, tuple, parse);
++      return pcmcia_parse_tuple(handle, tuple, parse);
+ }
++static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
++{
++      if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
++              return CS_NO_MORE_ITEMS;
++      return get_tuple(handle, tuple, parse);
++}
+-#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+-#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
++static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
++{
++      if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
++              return CS_NO_MORE_ITEMS;
++      return get_tuple(handle, tuple, parse);
++}
+ void btuart_config(dev_link_t *link)
+ {
+@@ -711,7 +716,7 @@ void btuart_config(dev_link_t *link)
+       /* Configure card */
+       link->state |= DEV_CONFIG;
+-      i = CardServices(GetConfigurationInfo, handle, &config);
++      i = pcmcia_get_configuration_info(handle, &config);
+       link->conf.Vcc = config.Vcc;
+       /* First pass: look for a config entry that looks normal. */
+@@ -732,7 +737,7 @@ void btuart_config(dev_link_t *link)
+                               link->conf.ConfigIndex = cf->index;
+                               link->io.BasePort1 = cf->io.win[0].base;
+                               link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
+-                              i = CardServices(RequestIO, link->handle, &link->io);
++                              i = pcmcia_request_io(link->handle, &link->io);
+                               if (i == CS_SUCCESS)
+                                       goto found_port;
+                       }
+@@ -752,7 +757,7 @@ next_entry:
+                       for (j = 0; j < 5; j++) {
+                               link->io.BasePort1 = base[j];
+                               link->io.IOAddrLines = base[j] ? 16 : 3;
+-                              i = CardServices(RequestIO, link->handle, &link->io);
++                              i = pcmcia_request_io(link->handle, &link->io);
+                               if (i == CS_SUCCESS)
+                                       goto found_port;
+                       }
+@@ -767,13 +772,13 @@ found_port:
+               goto failed;
+       }
+-      i = CardServices(RequestIRQ, link->handle, &link->irq);
++      i = pcmcia_request_irq(link->handle, &link->irq);
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestIRQ, i);
+               link->irq.AssignedIRQ = 0;
+       }
+-      i = CardServices(RequestConfiguration, link->handle, &link->conf);
++      i = pcmcia_request_configuration(link->handle, &link->conf);
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestConfiguration, i);
+               goto failed;
+@@ -805,9 +810,9 @@ void btuart_release(dev_link_t *link)
+       link->dev = NULL;
+-      CardServices(ReleaseConfiguration, link->handle);
+-      CardServices(ReleaseIO, link->handle, &link->io);
+-      CardServices(ReleaseIRQ, link->handle, &link->irq);
++      pcmcia_release_configuration(link->handle);
++      pcmcia_release_io(link->handle, &link->io);
++      pcmcia_release_irq(link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+ }
+@@ -835,14 +840,14 @@ int btuart_event(event_t event, int prio
+               /* Fall through... */
+       case CS_EVENT_RESET_PHYSICAL:
+               if (link->state & DEV_CONFIG)
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               break;
+       case CS_EVENT_PM_RESUME:
+               link->state &= ~DEV_SUSPEND;
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (DEV_OK(link))
+-                      CardServices(RequestConfiguration, link->handle, &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+               break;
+       }
+--- linux-2.6.0/drivers/bluetooth/dtl1_cs.c    2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/bluetooth/dtl1_cs.c     2003-12-28 23:22:54.000000000 -0800
+@@ -601,7 +601,7 @@ dev_link_t *dtl1_attach(void)
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != CS_SUCCESS) {
+               cs_error(link->handle, RegisterClient, ret);
+               dtl1_detach(link);
+@@ -630,7 +630,7 @@ void dtl1_detach(dev_link_t *link)
+               dtl1_release(link);
+       if (link->handle) {
+-              ret = CardServices(DeregisterClient, link->handle);
++              ret = pcmcia_deregister_client(link->handle);
+               if (ret != CS_SUCCESS)
+                       cs_error(link->handle, DeregisterClient, ret);
+       }
+@@ -641,25 +641,30 @@ void dtl1_detach(dev_link_t *link)
+       kfree(info);
+ }
+-
+-static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
++static int get_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
+ {
+       int i;
+-      i = CardServices(fn, handle, tuple);
+-      if (i != CS_SUCCESS)
+-              return CS_NO_MORE_ITEMS;
+-
+-      i = CardServices(GetTupleData, handle, tuple);
++      i = pcmcia_get_tuple_data(handle, tuple);
+       if (i != CS_SUCCESS)
+               return i;
+-      return CardServices(ParseTuple, handle, tuple, parse);
++      return pcmcia_parse_tuple(handle, tuple, parse);
+ }
++static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
++{
++      if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
++              return CS_NO_MORE_ITEMS;
++      return get_tuple(handle, tuple, parse);
++}
+-#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+-#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
++static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
++{
++      if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
++              return CS_NO_MORE_ITEMS;
++      return get_tuple(handle, tuple, parse);
++}
+ void dtl1_config(dev_link_t *link)
+ {
+@@ -689,7 +694,7 @@ void dtl1_config(dev_link_t *link)
+       /* Configure card */
+       link->state |= DEV_CONFIG;
+-      i = CardServices(GetConfigurationInfo, handle, &config);
++      i = pcmcia_get_configuration_info(handle, &config);
+       link->conf.Vcc = config.Vcc;
+       tuple.TupleData = (cisdata_t *)buf;
+@@ -707,7 +712,7 @@ void dtl1_config(dev_link_t *link)
+                       link->io.BasePort1 = cf->io.win[0].base;
+                       link->io.NumPorts1 = cf->io.win[0].len; /*yo */
+                       link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
+-                      i = CardServices(RequestIO, link->handle, &link->io);
++                      i = pcmcia_request_io(link->handle, &link->io);
+                       if (i == CS_SUCCESS)
+                               break;
+               }
+@@ -719,13 +724,13 @@ void dtl1_config(dev_link_t *link)
+               goto failed;
+       }
+-      i = CardServices(RequestIRQ, link->handle, &link->irq);
++      i = pcmcia_request_irq(link->handle, &link->irq);
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestIRQ, i);
+               link->irq.AssignedIRQ = 0;
+       }
+-      i = CardServices(RequestConfiguration, link->handle, &link->conf);
++      i = pcmcia_request_configuration(link->handle, &link->conf);
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestConfiguration, i);
+               goto failed;
+@@ -757,9 +762,9 @@ void dtl1_release(dev_link_t *link)
+       link->dev = NULL;
+-      CardServices(ReleaseConfiguration, link->handle);
+-      CardServices(ReleaseIO, link->handle, &link->io);
+-      CardServices(ReleaseIRQ, link->handle, &link->irq);
++      pcmcia_release_configuration(link->handle);
++      pcmcia_release_io(link->handle, &link->io);
++      pcmcia_release_irq(link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+ }
+@@ -787,14 +792,14 @@ int dtl1_event(event_t event, int priori
+               /* Fall through... */
+       case CS_EVENT_RESET_PHYSICAL:
+               if (link->state & DEV_CONFIG)
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               break;
+       case CS_EVENT_PM_RESUME:
+               link->state &= ~DEV_SUSPEND;
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (DEV_OK(link))
+-                      CardServices(RequestConfiguration, link->handle, &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+               break;
+       }
+--- linux-2.6.0/drivers/cdrom/aztcd.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/cdrom/aztcd.c   2003-12-28 23:21:17.000000000 -0800
+@@ -330,10 +330,10 @@ static int aztGetToc(int multi);
+ /* Kernel Interface Functions */
+ static int check_aztcd_media_change(struct gendisk *disk);
+-static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
++static int aztcd_ioctl(struct block_device *bdev, struct file *fp, unsigned int cmd,
+                      unsigned long arg);
+-static int aztcd_open(struct inode *ip, struct file *fp);
+-static int aztcd_release(struct inode *inode, struct file *file);
++static int aztcd_open(struct block_device *bdev, struct file *fp);
++static int aztcd_release(struct gendisk *disk);
+ static struct block_device_operations azt_fops = {
+       .owner          = THIS_MODULE,
+@@ -1153,7 +1153,7 @@ static int check_aztcd_media_change(stru
+ /*
+  * Kernel IO-controls
+ */
+-static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
++static int aztcd_ioctl(struct block_device *bdev, struct file *fp, unsigned int cmd,
+                      unsigned long arg)
+ {
+       int i;
+@@ -1171,8 +1171,6 @@ static int aztcd_ioctl(struct inode *ip,
+              cmd, jiffies);
+       printk("aztcd Status %x\n", getAztStatus());
+ #endif
+-      if (!ip)
+-              RETURNM("aztcd_ioctl 1", -EINVAL);
+       if (getAztStatus() < 0)
+               RETURNM("aztcd_ioctl 2", -EIO);
+       if ((!aztTocUpToDate) || (aztDiskChanged)) {
+@@ -1624,7 +1622,7 @@ static void azt_invalidate_buffers(void)
+ /*
+  * Open the device special file.  Check that a disk is in.
+  */
+-static int aztcd_open(struct inode *ip, struct file *fp)
++static int aztcd_open(struct block_device *bdev, struct file *fp)
+ {
+       int st;
+@@ -1673,12 +1671,11 @@ static int aztcd_open(struct inode *ip, 
+ /*
+  * On close, we flush all azt blocks from the buffer cache.
+  */
+-static int aztcd_release(struct inode *inode, struct file *file)
++static int aztcd_release(struct gendisk *disk)
+ {
+ #ifdef AZT_DEBUG
+       printk("aztcd: executing aztcd_release\n");
+-      printk("inode: %p, device: %s    file: %p\n", inode,
+-             inode->i_bdev->bd_disk->disk_name, file);
++      printk("disk: %p, device: %s\n", disk, disk->disk_name);
+ #endif
+       if (!--azt_open_count) {
+               azt_invalidate_buffers();
+--- linux-2.6.0/drivers/cdrom/cdrom.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/cdrom/cdrom.c   2003-12-28 23:22:35.000000000 -0800
+@@ -228,10 +228,16 @@
+    3.12 Oct 18, 2000 - Jens Axboe <axboe@suse.de>
+   -- Use quiet bit on packet commands not known to work
++   3.20 Dec 17, 2003 - Jens Axboe <axboe@suse.de>
++  -- Various fixes and lots of cleanups not listed :-)
++  -- Locking fixes
++  -- Mt Rainier support
++  -- DVD-RAM write open fixes
++
+ -------------------------------------------------------------------------*/
+-#define REVISION "Revision: 3.12"
+-#define VERSION "Id: cdrom.c 3.12 2000/10/18"
++#define REVISION "Revision: 3.20"
++#define VERSION "Id: cdrom.c 3.20 2003/12/17"
+ /* I use an error-log mask to give fine grain control over the type of
+    messages dumped to the system logs.  The available masks include: */
+@@ -282,11 +288,25 @@ static int autoeject;
+ static int lockdoor = 1;
+ /* will we ever get to use this... sigh. */
+ static int check_media_type;
++/* automatically restart mrw format */
++static int mrw_format_restart = 1;
+ MODULE_PARM(debug, "i");
+ MODULE_PARM(autoclose, "i");
+ MODULE_PARM(autoeject, "i");
+ MODULE_PARM(lockdoor, "i");
+ MODULE_PARM(check_media_type, "i");
++MODULE_PARM(mrw_format_restart, "i");
++
++static spinlock_t cdrom_lock = SPIN_LOCK_UNLOCKED;
++
++static const char *mrw_format_status[] = {
++      "not mrw",
++      "bgformat inactive",
++      "bgformat active",
++      "mrw complete",
++};
++
++static const char *mrw_address_space[] = { "DMA", "GAA" };
+ #if (ERRLOGMASK!=CD_NOTHING)
+ #define cdinfo(type, fmt, args...) \
+@@ -325,6 +345,10 @@ int cdrom_get_last_written(struct cdrom_
+ static int cdrom_get_next_writable(struct cdrom_device_info *, long *);
+ static void cdrom_count_tracks(struct cdrom_device_info *, tracktype*);
++static int cdrom_mrw_exit(struct cdrom_device_info *cdi);
++
++static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di);
++
+ #ifdef CONFIG_SYSCTL
+ static void cdrom_sysctl_register(void);
+ #endif /* CONFIG_SYSCTL */ 
+@@ -347,13 +371,14 @@ int register_cdrom(struct cdrom_device_i
+       if (cdo->open == NULL || cdo->release == NULL)
+               return -2;
+-      if ( !banner_printed ) {
++      if (!banner_printed) {
+               printk(KERN_INFO "Uniform CD-ROM driver " REVISION "\n");
+               banner_printed = 1;
+ #ifdef CONFIG_SYSCTL
+               cdrom_sysctl_register();
+ #endif /* CONFIG_SYSCTL */ 
+       }
++
+       ENSURE(drive_status, CDC_DRIVE_STATUS );
+       ENSURE(media_changed, CDC_MEDIA_CHANGED);
+       ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY);
+@@ -367,6 +392,7 @@ int register_cdrom(struct cdrom_device_i
+       ENSURE(generic_packet, CDC_GENERIC_PACKET);
+       cdi->mc_flags = 0;
+       cdo->n_minors = 0;
++      cdi->for_data = 0;
+         cdi->options = CDO_USE_FFLAGS;
+       
+       if (autoclose==1 && CDROM_CAN(CDC_CLOSE_TRAY))
+@@ -378,9 +404,14 @@ int register_cdrom(struct cdrom_device_i
+       if (check_media_type==1)
+               cdi->options |= (int) CDO_CHECK_TYPE;
++      if (CDROM_CAN(CDC_MRW_W))
++              cdi->exit = cdrom_mrw_exit;
++
+       cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
++      spin_lock(&cdrom_lock);
+       cdi->next = topCdromPtr;        
+       topCdromPtr = cdi;
++      spin_unlock(&cdrom_lock);
+       return 0;
+ }
+ #undef ENSURE
+@@ -391,23 +422,310 @@ int unregister_cdrom(struct cdrom_device
+       cdinfo(CD_OPEN, "entering unregister_cdrom\n"); 
+       prev = NULL;
++      spin_lock(&cdrom_lock);
+       cdi = topCdromPtr;
+       while (cdi && cdi != unreg) {
+               prev = cdi;
+               cdi = cdi->next;
+       }
+-      if (cdi == NULL)
++      if (cdi == NULL) {
++              spin_unlock(&cdrom_lock);
+               return -2;
++      }
+       if (prev)
+               prev->next = cdi->next;
+       else
+               topCdromPtr = cdi->next;
++
++      spin_unlock(&cdrom_lock);
++
++      if (cdi->exit)
++              cdi->exit(cdi);
++
+       cdi->ops->n_minors--;
+       cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
+       return 0;
+ }
++int cdrom_get_media_event(struct cdrom_device_info *cdi,
++                        struct media_event_desc *med)
++{
++      struct cdrom_generic_command cgc;
++      unsigned char buffer[8];
++      struct event_header *eh = (struct event_header *) buffer;
++
++      init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
++      cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION;
++      cgc.cmd[1] = 1;         /* IMMED */
++      cgc.cmd[4] = 1 << 4;    /* media event */
++      cgc.cmd[8] = sizeof(buffer);
++      cgc.quiet = 1;
++
++      if (cdi->ops->generic_packet(cdi, &cgc))
++              return 1;
++
++      if (be16_to_cpu(eh->data_len) < sizeof(*med))
++              return 1;
++
++      memcpy(med, &buffer[sizeof(*eh)], sizeof(*med));
++      return 0;
++}
++
++/*
++ * the first prototypes used 0x2c as the page code for the mrw mode page,
++ * subsequently this was changed to 0x03. probe the one used by this drive
++ */
++int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi)
++{
++      struct cdrom_generic_command cgc;
++      char buffer[16];
++
++      init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
++
++      cgc.timeout = HZ;
++      cgc.quiet = 1;
++
++      if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) {
++              cdi->mrw_mode_page = MRW_MODE_PC;
++              return 0;
++      } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) {
++              cdi->mrw_mode_page = MRW_MODE_PC_PRE1;
++              return 0;
++      }
++
++      printk(KERN_ERR "cdrom: %s: unknown mrw mode page\n", cdi->name);
++      return 1;
++}
++
++int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
++{
++      struct cdrom_generic_command cgc;
++      struct mrw_feature_desc *mfd;
++      unsigned char buffer[16];
++      int ret;
++
++      init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
++
++      cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
++      cgc.cmd[3] = CDF_MRW;
++      cgc.cmd[8] = sizeof(buffer);
++      cgc.quiet = 1;
++
++      if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
++              return ret;
++
++      mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)];
++      *write = mfd->write;
++
++      if ((ret = cdrom_mrw_probe_pc(cdi)))
++              return ret;
++
++      return 0;
++}
++
++static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont)
++{
++      struct cdrom_generic_command cgc;
++      unsigned char buffer[12];
++      int ret;
++
++      printk(KERN_INFO "cdrom: %sstarting format\n", cont ? "Re" : "");
++
++      /*
++       * FmtData bit set (bit 4), format type is 1
++       */
++      init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE);
++      cgc.cmd[0] = GPCMD_FORMAT_UNIT;
++      cgc.cmd[1] = (1 << 4) | 1;
++
++      cgc.timeout = 5 * 60 * HZ;
++
++      /*
++       * 4 byte format list header, 8 byte format list descriptor
++       */
++      buffer[1] = 1 << 1;
++      buffer[3] = 8;
++
++      /*
++       * nr_blocks field
++       */
++      buffer[4] = 0xff;
++      buffer[5] = 0xff;
++      buffer[6] = 0xff;
++      buffer[7] = 0xff;
++
++      buffer[8] = 0x24 << 2;
++      buffer[11] = cont;
++
++      ret = cdi->ops->generic_packet(cdi, &cgc);
++      if (ret)
++              printk(KERN_INFO "cdrom: bgformat failed\n");
++
++      return ret;
++}
++
++static int cdrom_mrw_bgformat_susp(struct cdrom_device_info *cdi, int immed)
++{
++      struct cdrom_generic_command cgc;
++
++      init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
++      cgc.cmd[0] = GPCMD_CLOSE_TRACK;
++
++      /*
++       * Session = 1, Track = 0
++       */
++      cgc.cmd[1] = !!immed;
++      cgc.cmd[2] = 1 << 1;
++
++      cgc.timeout = 5 * 60 * HZ;
++
++      return cdi->ops->generic_packet(cdi, &cgc);
++}
++
++static int cdrom_flush_cache(struct cdrom_device_info *cdi)
++{
++      struct cdrom_generic_command cgc;
++
++      init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
++      cgc.cmd[0] = GPCMD_FLUSH_CACHE;
++
++      cgc.timeout = 5 * 60 * HZ;
++
++      return cdi->ops->generic_packet(cdi, &cgc);
++}
++
++static int cdrom_mrw_exit(struct cdrom_device_info *cdi)
++{
++      disc_information di;
++      int ret = 0;
++
++      if (cdrom_get_disc_info(cdi, &di))
++              return 1;
++
++      if (di.mrw_status == CDM_MRW_BGFORMAT_ACTIVE) {
++              printk(KERN_INFO "cdrom: issuing MRW back ground format suspend\n");
++              ret = cdrom_mrw_bgformat_susp(cdi, 0);
++      }
++
++      if (!ret)
++              ret = cdrom_flush_cache(cdi);
++
++      return ret;
++}
++
++static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space)
++{
++      struct cdrom_generic_command cgc;
++      struct mode_page_header *mph;
++      char buffer[16];
++      int ret, offset, size;
++
++      init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
++
++      cgc.buffer = buffer;
++      cgc.buflen = sizeof(buffer);
++
++      if ((ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0)))
++              return ret;
++
++      mph = (struct mode_page_header *) buffer;
++      offset = be16_to_cpu(mph->desc_length);
++      size = be16_to_cpu(mph->mode_data_length) + 2;
++
++      buffer[offset + 3] = space;
++      cgc.buflen = size;
++
++      if ((ret = cdrom_mode_select(cdi, &cgc)))
++              return ret;
++
++      printk(KERN_INFO "cdrom: %s: mrw address space %s selected\n", cdi->name, mrw_address_space[space]);
++      return 0;
++}
++
++static int cdrom_media_erasable(struct cdrom_device_info *cdi)
++{
++      disc_information di;
++
++      if (cdrom_get_disc_info(cdi, &di))
++              return 0;
++
++      return di.erasable;
++}
++
++/*
++ * FIXME: check RO bit
++ */
++static int cdrom_dvdram_open_write(struct cdrom_device_info *cdi)
++{
++      return !cdrom_media_erasable(cdi);
++}
++
++static int cdrom_mrw_open_write(struct cdrom_device_info *cdi)
++{
++      disc_information di;
++      int ret;
++
++      /*
++       * always reset to DMA lba space on open
++       */
++      if (cdrom_mrw_set_lba_space(cdi, MRW_LBA_DMA)) {
++              printk(KERN_ERR "cdrom: failed setting lba address space\n");
++              return 1;
++      }
++
++      if (cdrom_get_disc_info(cdi, &di))
++              return 1;
++
++      if (!di.erasable)
++              return 1;
++
++      /*
++       * mrw_status
++       * 0    -       not MRW formatted
++       * 1    -       MRW bgformat started, but not running or complete
++       * 2    -       MRW bgformat in progress
++       * 3    -       MRW formatting complete
++       */
++      ret = 0;
++      printk(KERN_INFO "cdrom open: mrw_status '%s'\n", mrw_format_status[di.mrw_status]);
++      if (!di.mrw_status)
++              ret = 1;
++      else if (di.mrw_status == CDM_MRW_BGFORMAT_INACTIVE && mrw_format_restart)
++              ret = cdrom_mrw_bgformat(cdi, 1);
++
++      return ret;
++}
++
++/*
++ * returns 0 for ok to open write, non-0 to disallow
++ */
++static int cdrom_open_write(struct cdrom_device_info *cdi)
++{
++      int ret = 1;
++
++      if (CDROM_CAN(CDC_MRW_W))
++              ret = cdrom_mrw_open_write(cdi);
++      else if (CDROM_CAN(CDC_DVD_RAM))
++              ret = cdrom_dvdram_open_write(cdi);
++      /*
++       * needs to really check whether media is writeable
++       */
++      else if (CDROM_CAN(CDC_MO_DRIVE))
++              ret = 0;
++
++      return ret;
++}
++
++static int cdrom_close_write(struct cdrom_device_info *cdi)
++{
++#if 0
++      return cdrom_flush_cache(cdi);
++#else
++      return 0;
++#endif
++}
++
+ /* We use the open-option O_NONBLOCK to indicate that the
+  * purpose of opening is only for subsequent ioctl() calls; no device
+  * integrity checks are performed.
+@@ -416,28 +734,34 @@ int unregister_cdrom(struct cdrom_device
+  * is in their own interest: device control becomes a lot easier
+  * this way.
+  */
+-int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp)
++int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, struct file *fp)
+ {
+       int ret;
+       cdinfo(CD_OPEN, "entering cdrom_open\n"); 
++      cdi->use_count++;
++      ret = -EROFS;
++      if (fp->f_mode & FMODE_WRITE) {
++              if (!CDROM_CAN(CDC_RAM))
++                      goto out;
++              if (cdrom_open_write(cdi))
++                      goto out;
++      }
++
+       /* if this was a O_NONBLOCK open and we should honor the flags,
+        * do a quick open without drive/disc integrity checks. */
+       if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS))
+               ret = cdi->ops->open(cdi, 1);
+-      else {
+-              if ((fp->f_mode & FMODE_WRITE) && !CDROM_CAN(CDC_DVD_RAM))
+-                      return -EROFS;
+-
++      else
+               ret = open_for_data(cdi);
+-      }
+-
+-      if (!ret) cdi->use_count++;
+       cdinfo(CD_OPEN, "Use count for \"/dev/%s\" now %d\n", cdi->name, cdi->use_count);
+       /* Do this on open.  Don't wait for mount, because they might
+           not be mounting, but opening with O_NONBLOCK */
+-      check_disk_change(ip->i_bdev);
++      check_disk_change(bdev);
++out:
++      if (ret)
++              cdi->use_count--;
+       return ret;
+ }
+@@ -525,11 +849,12 @@ int open_for_data(struct cdrom_device_in
+               cdinfo(CD_OPEN, "open device failed.\n"); 
+               goto clean_up_and_return;
+       }
+-      if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
++      if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK)) {
+                       cdo->lock_door(cdi, 1);
+                       cdinfo(CD_OPEN, "door locked.\n");
+       }
+       cdinfo(CD_OPEN, "device opened successfully.\n"); 
++      cdi->for_data = 1;
+       return ret;
+       /* Something failed.  Try to unlock the drive, because some drivers
+@@ -603,32 +928,39 @@ int check_for_audio_disc(struct cdrom_de
+       return 0;
+ }
+-
+ /* Admittedly, the logic below could be performed in a nicer way. */
+-int cdrom_release(struct cdrom_device_info *cdi, struct file *fp)
++int cdrom_release(struct cdrom_device_info *cdi)
+ {
+       struct cdrom_device_ops *cdo = cdi->ops;
+-      int opened_for_data;
+       cdinfo(CD_CLOSE, "entering cdrom_release\n"); 
+       if (cdi->use_count > 0)
+               cdi->use_count--;
+-      if (cdi->use_count == 0)
+-              cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
+-      if (cdi->use_count == 0 &&
+-          cdo->capability & CDC_LOCK && !keeplocked) {
++
++      if (cdi->use_count) {
++              cdo->release(cdi);
++              return 0;
++      }
++
++      cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
++      if ((cdo->capability & CDC_LOCK) && !keeplocked) {
+               cdinfo(CD_CLOSE, "Unlocking door!\n");
+               cdo->lock_door(cdi, 0);
+       }
+-      opened_for_data = !(cdi->options & CDO_USE_FFLAGS) ||
+-              !(fp && fp->f_flags & O_NONBLOCK);
++
++      /*
++       * flush cache on last write release
++       */
++      if (CDROM_CAN(CDC_RAM) && !cdi->use_count && cdi->for_data)
++              cdrom_close_write(cdi);
++
+       cdo->release(cdi);
+-      if (cdi->use_count == 0) {      /* last process that closes dev*/
+-              if (opened_for_data &&
+-                  cdi->options & CDO_AUTO_EJECT && CDROM_CAN(CDC_OPEN_TRAY))
+-                      cdo->tray_move(cdi, 1);
+-      }
++      if (cdi->for_data &&
++          cdi->options & CDO_AUTO_EJECT && CDROM_CAN(CDC_OPEN_TRAY))
++              cdo->tray_move(cdi, 1);
++
++      cdi->for_data = 0;
+       return 0;
+ }
+@@ -1433,14 +1765,14 @@ static int cdrom_read_block(struct cdrom
+  * these days. ATAPI / SCSI specific code now mainly resides in
+  * mmc_ioct().
+  */
+-int cdrom_ioctl(struct cdrom_device_info *cdi, struct inode *ip,
++int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
+               unsigned int cmd, unsigned long arg)
+ {
+       struct cdrom_device_ops *cdo = cdi->ops;
+       int ret;
+       /* Try the generic SCSI command ioctl's first.. */
+-      ret = scsi_cmd_ioctl(ip->i_bdev, cmd, arg);
++      ret = scsi_cmd_ioctl(bdev, cmd, arg);
+       if (ret != -ENOTTY)
+               return ret;
+@@ -1593,7 +1925,7 @@ int cdrom_ioctl(struct cdrom_device_info
+               cdinfo(CD_DO_IOCTL, "entering CDROM_RESET\n");
+               if (!CDROM_CAN(CDC_RESET))
+                       return -ENOSYS;
+-              invalidate_bdev(ip->i_bdev, 0);
++              invalidate_bdev(bdev, 0);
+               return cdo->reset(cdi);
+               }
+@@ -2203,7 +2535,6 @@ static int cdrom_get_disc_info(struct cd
+       return cdo->generic_packet(cdi, &cgc);
+ }
+-
+ /* return the last written block on the CD-R media. this is for the udf
+    file system. */
+ int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written)
+@@ -2310,6 +2641,8 @@ EXPORT_SYMBOL(cdrom_number_of_slots);
+ EXPORT_SYMBOL(cdrom_mode_select);
+ EXPORT_SYMBOL(cdrom_mode_sense);
+ EXPORT_SYMBOL(init_cdrom_command);
++EXPORT_SYMBOL(cdrom_get_media_event);
++EXPORT_SYMBOL(cdrom_is_mrw);
+ #ifdef CONFIG_SYSCTL
+@@ -2406,6 +2739,14 @@ int cdrom_sysctl_info(ctl_table *ctl, in
+       for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
+           pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_RAM) != 0);
++      pos += sprintf(info+pos, "\nCan read MRW:");
++      for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
++          pos += sprintf(info+pos, "\t\t%d", CDROM_CAN(CDC_MRW) != 0);
++
++      pos += sprintf(info+pos, "\nCan write MRW:");
++      for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
++          pos += sprintf(info+pos, "\t\t%d", CDROM_CAN(CDC_MRW_W) != 0);
++
+       strcpy(info+pos,"\n\n");
+               
+         return proc_dostring(ctl, write, filp, buffer, lenp);
+--- linux-2.6.0/drivers/cdrom/cdu31a.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/cdrom/cdu31a.c  2003-12-28 23:21:17.000000000 -0800
+@@ -3167,20 +3167,20 @@ static struct cdrom_device_info scd_info
+       .name           = "cdu31a"
+ };
+-static int scd_block_open(struct inode *inode, struct file *file)
++static int scd_block_open(struct block_device *bdev, struct file *file)
+ {
+-      return cdrom_open(&scd_info, inode, file);
++      return cdrom_open(&scd_info, bdev, file);
+ }
+-static int scd_block_release(struct inode *inode, struct file *file)
++static int scd_block_release(struct gendisk *disk)
+ {
+-      return cdrom_release(&scd_info, file);
++      return cdrom_release(&scd_info);
+ }
+-static int scd_block_ioctl(struct inode *inode, struct file *file,
++static int scd_block_ioctl(struct block_device *bdev, struct file *file,
+                               unsigned cmd, unsigned long arg)
+ {
+-      return cdrom_ioctl(&scd_info, inode, cmd, arg);
++      return cdrom_ioctl(&scd_info, bdev, cmd, arg);
+ }
+ static int scd_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0/drivers/cdrom/cm206.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/cdrom/cm206.c   2003-12-28 23:21:17.000000000 -0800
+@@ -1350,20 +1350,20 @@ static struct cdrom_device_info cm206_in
+       .name           = "cm206",
+ };
+-static int cm206_block_open(struct inode *inode, struct file *file)
++static int cm206_block_open(struct block_device *bdev, struct file *file)
+ {
+-      return cdrom_open(&cm206_info, inode, file);
++      return cdrom_open(&cm206_info, bdev, file);
+ }
+-static int cm206_block_release(struct inode *inode, struct file *file)
++static int cm206_block_release(struct gendisk *disk)
+ {
+-      return cdrom_release(&cm206_info, file);
++      return cdrom_release(&cm206_info);
+ }
+-static int cm206_block_ioctl(struct inode *inode, struct file *file,
++static int cm206_block_ioctl(struct block_device *bdev, struct file *file,
+                               unsigned cmd, unsigned long arg)
+ {
+-      return cdrom_ioctl(&cm206_info, inode, cmd, arg);
++      return cdrom_ioctl(&cm206_info, bdev, cmd, arg);
+ }
+ static int cm206_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0/drivers/cdrom/gscd.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/cdrom/gscd.c    2003-12-28 23:21:17.000000000 -0800
+@@ -91,10 +91,10 @@ static void gscd_bin2bcd(unsigned char *
+ /* Schnittstellen zum Kern/FS */
+ static void __do_gscd_request(unsigned long dummy);
+-static int gscd_ioctl(struct inode *, struct file *, unsigned int,
++static int gscd_ioctl(struct block_device *, struct file *, unsigned int,
+                     unsigned long);
+-static int gscd_open(struct inode *, struct file *);
+-static int gscd_release(struct inode *, struct file *);
++static int gscd_open(struct block_device *, struct file *);
++static int gscd_release(struct gendisk *disk);
+ static int check_gscd_med_chg(struct gendisk *disk);
+ /*      GoldStar Funktionen    */
+@@ -190,8 +190,8 @@ __setup("gscd=", gscd_setup);
+ #endif
+-static int gscd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
+-                    unsigned long arg)
++static int gscd_ioctl(struct block_device *bdev, struct file *fp,
++                      unsigned int cmd, unsigned long arg)
+ {
+       unsigned char to_do[10];
+       unsigned char dummy;
+@@ -338,7 +338,7 @@ static void gscd_read_cmd(struct request
+  * Open the device special file.  Check that a disk is in.
+  */
+-static int gscd_open(struct inode *ip, struct file *fp)
++static int gscd_open(struct block_device *bdev, struct file *fp)
+ {
+       int st;
+@@ -368,7 +368,7 @@ static int gscd_open(struct inode *ip, s
+  * On close, we flush all gscd blocks from the buffer cache.
+  */
+-static int gscd_release(struct inode *inode, struct file *file)
++static int gscd_release(struct gendisk *disk)
+ {
+ #ifdef GSCD_DEBUG
+--- linux-2.6.0/drivers/cdrom/mcd.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/cdrom/mcd.c     2003-12-28 23:21:17.000000000 -0800
+@@ -214,20 +214,20 @@ static struct cdrom_device_info mcd_info
+       .name           = "mcd",
+ };
+-static int mcd_block_open(struct inode *inode, struct file *file)
++static int mcd_block_open(struct block_device *bdev, struct file *file)
+ {
+-      return cdrom_open(&mcd_info, inode, file);
++      return cdrom_open(&mcd_info, bdev, file);
+ }
+-static int mcd_block_release(struct inode *inode, struct file *file)
++static int mcd_block_release(struct gendisk *disk)
+ {
+-      return cdrom_release(&mcd_info, file);
++      return cdrom_release(&mcd_info);
+ }
+-static int mcd_block_ioctl(struct inode *inode, struct file *file,
++static int mcd_block_ioctl(struct block_device *bdev, struct file *file,
+                               unsigned cmd, unsigned long arg)
+ {
+-      return cdrom_ioctl(&mcd_info, inode, cmd, arg);
++      return cdrom_ioctl(&mcd_info, bdev, cmd, arg);
+ }
+ static int mcd_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0/drivers/cdrom/mcdx.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/cdrom/mcdx.c    2003-12-28 23:21:17.000000000 -0800
+@@ -221,23 +221,23 @@ struct s_drive_stuff {
+ int mcdx_init(void);
+ void do_mcdx_request(request_queue_t * q);
+-static int mcdx_block_open(struct inode *inode, struct file *file)
++static int mcdx_block_open(struct block_device *bdev, struct file *file)
+ {
+-      struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
+-      return cdrom_open(&p->info, inode, file);
++      struct s_drive_stuff *p = bdev->bd_disk->private_data;
++      return cdrom_open(&p->info, bdev, file);
+ }
+-static int mcdx_block_release(struct inode *inode, struct file *file)
++static int mcdx_block_release(struct gendisk *disk)
+ {
+-      struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
+-      return cdrom_release(&p->info, file);
++      struct s_drive_stuff *p = disk->private_data;
++      return cdrom_release(&p->info);
+ }
+-static int mcdx_block_ioctl(struct inode *inode, struct file *file,
++static int mcdx_block_ioctl(struct block_device *bdev, struct file *file,
+                               unsigned cmd, unsigned long arg)
+ {
+-      struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
+-      return cdrom_ioctl(&p->info, inode, cmd, arg);
++      struct s_drive_stuff *p = bdev->bd_disk->private_data;
++      return cdrom_ioctl(&p->info, bdev, cmd, arg);
+ }
+ static int mcdx_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0/drivers/cdrom/optcd.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/cdrom/optcd.c   2003-12-28 23:21:17.000000000 -0800
+@@ -1713,16 +1713,13 @@ static int cdromreset(void)
+ /* VFS calls */
+-static int opt_ioctl(struct inode *ip, struct file *fp,
++static int opt_ioctl(struct block_device *bdev, struct file *fp,
+                      unsigned int cmd, unsigned long arg)
+ {
+       int status, err, retval = 0;
+       DEBUG((DEBUG_VFS, "starting opt_ioctl"));
+-      if (!ip)
+-              return -EINVAL;
+-
+       if (cmd == CDROMRESET)
+               return cdromreset();
+@@ -1844,7 +1841,7 @@ static int opt_ioctl(struct inode *ip, s
+ static int open_count = 0;
+ /* Open device special file; check that a disk is in. */
+-static int opt_open(struct inode *ip, struct file *fp)
++static int opt_open(struct block_device *bdev, struct file *fp)
+ {
+       DEBUG((DEBUG_VFS, "starting opt_open"));
+@@ -1904,13 +1901,12 @@ err_out:
+ /* Release device special file; flush all blocks from the buffer cache */
+-static int opt_release(struct inode *ip, struct file *fp)
++static int opt_release(struct gendisk *disk)
+ {
+       int status;
+       DEBUG((DEBUG_VFS, "executing opt_release"));
+-      DEBUG((DEBUG_VFS, "inode: %p, device: %s, file: %p\n",
+-              ip, ip->i_bdev->bd_disk->disk_name, fp));
++      DEBUG((DEBUG_VFS, "disk: %p, device: %s\n", disk, disk->disk_name));
+       if (!--open_count) {
+               toc_uptodate = 0;
+--- linux-2.6.0/drivers/cdrom/sbpcd.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/cdrom/sbpcd.c   2003-12-28 23:21:17.000000000 -0800
+@@ -5356,23 +5356,23 @@ static int sbp_data(struct request *req)
+ }
+ /*==========================================================================*/
+-static int sbpcd_block_open(struct inode *inode, struct file *file)
++static int sbpcd_block_open(struct block_device *bdev, struct file *file)
+ {
+-      struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
+-      return cdrom_open(p->sbpcd_infop, inode, file);
++      struct sbpcd_drive *p = bdev->bd_disk->private_data;
++      return cdrom_open(p->sbpcd_infop, bdev, file);
+ }
+-static int sbpcd_block_release(struct inode *inode, struct file *file)
++static int sbpcd_block_release(struct gendisk *disk)
+ {
+-      struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
+-      return cdrom_release(p->sbpcd_infop, file);
++      struct sbpcd_drive *p = disk->private_data;
++      return cdrom_release(p->sbpcd_infop);
+ }
+-static int sbpcd_block_ioctl(struct inode *inode, struct file *file,
++static int sbpcd_block_ioctl(struct block_device *bdev, struct file *file,
+                               unsigned cmd, unsigned long arg)
+ {
+-      struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
+-      return cdrom_ioctl(p->sbpcd_infop, inode, cmd, arg);
++      struct sbpcd_drive *p = bdev->bd_disk->private_data;
++      return cdrom_ioctl(p->sbpcd_infop, bdev, cmd, arg);
+ }
+ static int sbpcd_block_media_changed(struct gendisk *disk)
+--- linux-2.6.0/drivers/cdrom/sjcd.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/cdrom/sjcd.c    2003-12-28 23:21:17.000000000 -0800
+@@ -713,16 +713,13 @@ static int sjcd_tray_open(void)
+ /*
+  * Do some user commands.
+  */
+-static int sjcd_ioctl(struct inode *ip, struct file *fp,
++static int sjcd_ioctl(struct block_device *bdev, struct file *fp,
+                     unsigned int cmd, unsigned long arg)
+ {
+ #if defined( SJCD_TRACE )
+       printk("SJCD:ioctl\n");
+ #endif
+-      if (ip == NULL)
+-              return (-EINVAL);
+-
+       sjcd_get_status();
+       if (!sjcd_status_valid)
+               return (-EIO);
+@@ -1526,7 +1523,7 @@ static void do_sjcd_request(request_queu
+ /*
+  * Open the device special file. Check disk is in.
+  */
+-static int sjcd_open(struct inode *ip, struct file *fp)
++static int sjcd_open(struct block_device *bdev, struct file *fp)
+ {
+       /*
+        * Check the presence of device.
+@@ -1611,7 +1608,7 @@ static int sjcd_open(struct inode *ip, s
+ /*
+  * On close, we flush all sjcd blocks from the buffer cache.
+  */
+-static int sjcd_release(struct inode *inode, struct file *file)
++static int sjcd_release(struct gendisk *disk)
+ {
+       int s;
+--- linux-2.6.0/drivers/cdrom/sonycd535.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/cdrom/sonycd535.c       2003-12-28 23:21:17.000000000 -0800
+@@ -201,7 +201,7 @@
+ static int read_subcode(void);
+ static void sony_get_toc(void);
+-static int cdu_open(struct inode *inode, struct file *filp);
++static int cdu_open(struct block_device *bdev, struct file *filp);
+ static inline unsigned int int_to_bcd(unsigned int val);
+ static unsigned int bcd_to_int(unsigned int bcd);
+ static int do_sony_cmd(Byte * cmd, int nCmd, Byte status[2],
+@@ -1061,7 +1061,7 @@ sony_get_subchnl_info(long arg)
+  * The big ugly ioctl handler.
+  */
+ static int
+-cdu_ioctl(struct inode *inode,
++cdu_ioctl(struct block_device *bdev,
+                 struct file *file,
+                 unsigned int cmd,
+                 unsigned long arg)
+@@ -1360,9 +1360,7 @@ cdu_ioctl(struct inode *inode,
+  * Open the drive for operations.  Spin the drive up and read the table of
+  * contents if these have not already been done.
+  */
+-static int
+-cdu_open(struct inode *inode,
+-               struct file *filp)
++static int cdu_open(struct block_device *bdev, struct file *filp)
+ {
+       Byte status[2], cmd_buff[2];
+@@ -1385,7 +1383,7 @@ cdu_open(struct inode *inode,
+               sony_inuse = 0;
+               return -EIO;
+       }
+-      check_disk_change(inode->i_bdev);
++      check_disk_change(bdev);
+       sony_usage++;
+ #ifdef LOCK_DOORS
+@@ -1402,9 +1400,7 @@ cdu_open(struct inode *inode,
+  * Close the drive.  Spin it down if no task is using it.  The spin
+  * down will fail if playing audio, so audio play is OK.
+  */
+-static int
+-cdu_release(struct inode *inode,
+-                      struct file *filp)
++static int cdu_release(struct gendisk *disk)
+ {
+       Byte status[2], cmd_no;
+--- linux-2.6.0/drivers/char/agp/alpha-agp.c   2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/agp/alpha-agp.c    2003-12-28 23:22:12.000000000 -0800
+@@ -13,7 +13,7 @@
+ static struct page *alpha_core_agp_vm_nopage(struct vm_area_struct *vma,
+                                            unsigned long address,
+-                                           int write_access)
++                                           int *type)
+ {
+       alpha_agp_info *agp = agp_bridge->dev_private_data;
+       dma_addr_t dma_addr;
+@@ -30,6 +30,8 @@ static struct page *alpha_core_agp_vm_no
+        */
+       page = virt_to_page(__va(pa));
+       get_page(page);
++      if (type)
++              *type = VM_FAULT_MINOR;
+       return page;
+ }
+--- linux-2.6.0/drivers/char/drm/drmP.h        2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/drm/drmP.h 2003-12-28 23:22:12.000000000 -0800
+@@ -760,16 +760,16 @@ extern int            DRM(fasync)(int fd, stru
+                               /* Mapping support (drm_vm.h) */
+ extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
+                                  unsigned long address,
+-                                 int write_access);
++                                 int *type);
+ extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
+                                      unsigned long address,
+-                                     int write_access);
++                                     int *type);
+ extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
+                                      unsigned long address,
+-                                     int write_access);
++                                     int *type);
+ extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
+                                     unsigned long address,
+-                                    int write_access);
++                                    int *type);
+ extern void        DRM(vm_open)(struct vm_area_struct *vma);
+ extern void        DRM(vm_close)(struct vm_area_struct *vma);
+ extern void        DRM(vm_shm_close)(struct vm_area_struct *vma);
+--- linux-2.6.0/drivers/char/drm/drm_vm.h      2003-07-13 21:44:34.000000000 -0700
++++ 25/drivers/char/drm/drm_vm.h       2003-12-28 23:22:12.000000000 -0800
+@@ -76,7 +76,7 @@ struct vm_operations_struct   DRM(vm_sg_
+  */
+ struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
+                           unsigned long address,
+-                          int write_access)
++                          int *type)
+ {
+ #if __REALLY_HAVE_AGP
+       drm_file_t *priv  = vma->vm_file->private_data;
+@@ -133,6 +133,8 @@ struct page *DRM(vm_nopage)(struct vm_ar
+                         baddr, __va(agpmem->memory->memory[offset]), offset,
+                         atomic_read(&page->count));
++              if (type)
++                      *type = VM_FAULT_MINOR;
+               return page;
+         }
+ vm_nopage_error:
+@@ -154,7 +156,7 @@ vm_nopage_error:
+  */
+ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
+                               unsigned long address,
+-                              int write_access)
++                              int *type)
+ {
+       drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
+       unsigned long    offset;
+@@ -170,6 +172,8 @@ struct page *DRM(vm_shm_nopage)(struct v
+       if (!page)
+               return NOPAGE_OOM;
+       get_page(page);
++      if (type)
++              *type = VM_FAULT_MINOR;
+       DRM_DEBUG("shm_nopage 0x%lx\n", address);
+       return page;
+@@ -268,7 +272,7 @@ void DRM(vm_shm_close)(struct vm_area_st
+  */
+ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
+                               unsigned long address,
+-                              int write_access)
++                              int *type)
+ {
+       drm_file_t       *priv   = vma->vm_file->private_data;
+       drm_device_t     *dev    = priv->dev;
+@@ -287,6 +291,8 @@ struct page *DRM(vm_dma_nopage)(struct v
+                            (offset & (~PAGE_MASK))));
+       get_page(page);
++      if (type)
++              *type = VM_FAULT_MINOR;
+       DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr);
+       return page;
+@@ -304,7 +310,7 @@ struct page *DRM(vm_dma_nopage)(struct v
+  */
+ struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
+                              unsigned long address,
+-                             int write_access)
++                             int *type)
+ {
+       drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
+       drm_file_t *priv = vma->vm_file->private_data;
+@@ -325,6 +331,8 @@ struct page *DRM(vm_sg_nopage)(struct vm
+       page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
+       page = entry->pagelist[page_offset];
+       get_page(page);
++      if (type)
++              *type = VM_FAULT_MINOR;
+       return page;
+ }
+--- linux-2.6.0/drivers/char/keyboard.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/char/keyboard.c 2003-12-28 23:21:28.000000000 -0800
+@@ -941,16 +941,16 @@ static unsigned short x86_keycodes[256] 
+        32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+        64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+-       80, 81, 82, 83, 43, 85, 86, 87, 88,115,119,120,121,375,123, 90,
+-      284,285,309,298,312, 91,327,328,329,331,333,335,336,337,338,339,
+-      367,288,302,304,350, 92,334,512,116,377,109,111,373,347,348,349,
+-      360, 93, 94, 95, 98,376,100,101,321,316,354,286,289,102,351,355,
++       80, 81, 82, 83, 84, 93, 86, 87, 88, 94, 95, 85,259,375,260, 90,
++      284,285,309,311,312, 91,327,328,329,331,333,335,336,337,338,339,
++      367,288,302,304,350, 89,334,326,116,377,109,111,126,347,348,349,
++      360,261,262,263,298,376,100,101,321,316,373,286,289,102,351,355,
+       103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361,
+-      291,108,381,281,290,272,292,305,280, 99,112,257,258,359,270,114,
+-      118,117,125,374,379,115,112,125,121,123,264,265,266,267,268,269,
+-      271,273,276,277,278,282,283,295,296,297,299,300,301,293,303,307,
+-      308,310,313,314,315,317,318,319,320,357,322,323,324,325,326,330,
+-      332,340,365,342,343,344,345,346,356,113,341,368,369,370,371,372 };
++      291,108,381,281,290,272,292,305,280, 99,112,257,258,359,113,114,
++      264,117,271,374,379,115,125,273,121,123, 92,265,266,267,268,269,
++      120,119,118,277,278,282,283,295,296,297,299,300,301,293,303,307,
++      308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
++      332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
+ #ifdef CONFIG_MAC_EMUMOUSEBTN
+ extern int mac_hid_mouse_emulate_buttons(int, int, int);
+@@ -972,11 +972,18 @@ static int emulate_raw(struct vc_data *v
+       if (keycode > 255 || !x86_keycodes[keycode])
+               return -1; 
+-      if (keycode == KEY_PAUSE) {
+-              put_queue(vc, 0xe1);
+-              put_queue(vc, 0x1d | up_flag);
+-              put_queue(vc, 0x45 | up_flag);
+-              return 0;
++      switch (keycode) {
++              case KEY_PAUSE:
++                      put_queue(vc, 0xe1);
++                      put_queue(vc, 0x1d | up_flag);
++                      put_queue(vc, 0x45 | up_flag);
++                      return 0;
++              case KEY_LANG1:
++                      if (!up_flag) put_queue(vc, 0xf1);
++                      return 0;
++              case KEY_LANG2:
++                      if (!up_flag) put_queue(vc, 0xf2);
++                      return 0;
+       } 
+       if (keycode == KEY_SYSRQ && sysrq_alt) {
+@@ -1052,6 +1059,9 @@ void kbd_keycode(unsigned int keycode, i
+       }
+       if (sysrq_down && down && !rep) {
+               handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty);
++#ifdef CONFIG_KGDB_SYSRQ
++                sysrq_down = 0;        /* in case we miss the "up" event */
++#endif
+               return;
+       }
+ #endif
+--- linux-2.6.0/drivers/char/mem.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/char/mem.c      2003-12-28 23:22:59.000000000 -0800
+@@ -24,6 +24,7 @@
+ #include <linux/smp_lock.h>
+ #include <linux/devfs_fs_kernel.h>
+ #include <linux/ptrace.h>
++#include <linux/device.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -40,6 +41,7 @@ extern void fbmem_init(void);
+ extern void tapechar_init(void);
+ #endif
++#ifdef pgprot_noncached
+ /*
+  * Architectures vary in how they handle caching for addresses
+  * outside of main memory.
+@@ -65,19 +67,21 @@ static inline int uncached_access(struct
+         && addr >= __pa(high_memory);
+ #elif defined(CONFIG_IA64)
+       /*
+-       * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
++       * On ia64, we ignore O_SYNC because we cannot tolerate memory
++       * attribute aliases.
+        */
+       return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
+ #else
+       /*
+-       * Accessing memory above the top the kernel knows about or through a file pointer
+-       * that was marked O_SYNC will be done non-cached.
++       * Accessing memory above the top the kernel knows about or through a
++       * file pointer that was marked O_SYNC will be done non-cached.
+        */
+       if (file->f_flags & O_SYNC)
+               return 1;
+       return addr >= __pa(high_memory);
+ #endif
+ }
++#endif                /* pgprot_noncached */
+ #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE
+ static inline int valid_phys_addr_range(unsigned long addr, size_t *count)
+@@ -167,28 +171,24 @@ static ssize_t write_mem(struct file * f
+       return do_write_mem(file, __va(p), p, buf, count, ppos);
+ }
+-static int mmap_mem(struct file * file, struct vm_area_struct * vma)
++static int mmap_mem(struct file *file, struct vm_area_struct *vma)
+ {
+       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+-      int uncached;
+-      uncached = uncached_access(file, offset);
+ #ifdef pgprot_noncached
+-      if (uncached)
++      if (uncached_access(file, offset))
+               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ #endif
+-      /* Don't try to swap out physical pages.. */
+-      vma->vm_flags |= VM_RESERVED;
+-
+       /*
+-       * Don't dump addresses that are not real memory to a core file.
++       * Don't try to swap out physical pages..
++       * And treat /dev/mem mappings as "IO" regions: they may not
++       * describe valid pageframes.
+        */
+-      if (uncached)
+-              vma->vm_flags |= VM_IO;
++      vma->vm_flags |= VM_RESERVED|VM_IO;
+-      if (remap_page_range(vma, vma->vm_start, offset, vma->vm_end-vma->vm_start,
+-                           vma->vm_page_prot))
++      if (remap_page_range(vma, vma->vm_start, offset,
++                      vma->vm_end-vma->vm_start, vma->vm_page_prot))
+               return -EAGAIN;
+       return 0;
+ }
+@@ -676,6 +676,10 @@ static const struct {
+       {11,"kmsg",    S_IRUGO | S_IWUSR,           &kmsg_fops},
+ };
++static struct class mem_class = {
++      .name   = "mem",
++};
++
+ static int __init chr_dev_init(void)
+ {
+       int i;
+@@ -683,7 +687,11 @@ static int __init chr_dev_init(void)
+       if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
+               printk("unable to get major %d for memory devs\n", MEM_MAJOR);
++      class_register(&mem_class);
+       for (i = 0; i < ARRAY_SIZE(devlist); i++) {
++              simple_add_class_device(&mem_class,
++                                      MKDEV(MEM_MAJOR, devlist[i].minor),
++                                      NULL, devlist[i].name);
+               devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor),
+                               S_IFCHR | devlist[i].mode, devlist[i].name);
+       }
+--- linux-2.6.0/drivers/char/misc.c    2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/char/misc.c     2003-12-28 23:23:00.000000000 -0800
+@@ -47,7 +47,7 @@
+ #include <linux/devfs_fs_kernel.h>
+ #include <linux/stat.h>
+ #include <linux/init.h>
+-
++#include <linux/device.h>
+ #include <linux/tty.h>
+ #include <linux/kmod.h>
+@@ -180,6 +180,15 @@ fail:
+       return err;
+ }
++/*
++ * TODO for 2.7:
++ *  - add a struct class_device to struct miscdevice and make all usages of
++ *    them dynamic.
++ */
++static struct class misc_class = {
++      .name   = "misc",
++};
++
+ static struct file_operations misc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = misc_open,
+@@ -234,6 +243,8 @@ int misc_register(struct miscdevice * mi
+                               "misc/%s", misc->name);
+       }
++      simple_add_class_device(&misc_class, MKDEV(MISC_MAJOR, misc->minor),
++                              misc->dev, misc->name);
+       devfs_mk_cdev(MKDEV(MISC_MAJOR, misc->minor),
+                       S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP, misc->devfs_name);
+@@ -265,6 +276,7 @@ int misc_deregister(struct miscdevice * 
+       down(&misc_sem);
+       list_del(&misc->list);
++      simple_remove_class_device(MKDEV(MISC_MAJOR, misc->minor));
+       devfs_remove(misc->devfs_name);
+       if (i < DYNAMIC_MINORS && i>0) {
+               misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
+@@ -285,6 +297,7 @@ static int __init misc_init(void)
+       if (ent)
+               ent->proc_fops = &misc_proc_fops;
+ #endif
++      class_register(&misc_class);
+ #ifdef CONFIG_MVME16x
+       rtc_MK48T08_init();
+ #endif
+@@ -319,4 +332,4 @@ static int __init misc_init(void)
+       }
+       return 0;
+ }
+-module_init(misc_init);
++subsys_initcall(misc_init);
+--- linux-2.6.0/drivers/char/pcmcia/synclink_cs.c      2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/char/pcmcia/synclink_cs.c       2003-12-28 23:22:54.000000000 -0800
+@@ -244,7 +244,6 @@ typedef struct _mgslpc_info {
+       char netname[10];
+       struct net_device *netdev;
+       struct net_device_stats netstats;
+-      struct net_device netdevice;
+ #endif
+ } MGSLPC_INFO;
+@@ -592,7 +591,7 @@ static dev_link_t *mgslpc_attach(void)
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != CS_SUCCESS) {
+           cs_error(link->handle, RegisterClient, ret);
+           mgslpc_detach(link);
+@@ -607,8 +606,8 @@ static dev_link_t *mgslpc_attach(void)
+ /* Card has been inserted.
+  */
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void mgslpc_config(dev_link_t *link)
+ {
+@@ -631,9 +630,9 @@ static void mgslpc_config(dev_link_t *li
+     tuple.TupleData = buf;
+     tuple.TupleDataMax = sizeof(buf);
+     tuple.TupleOffset = 0;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     link->conf.Present = parse.config.rmask[0];
+     
+@@ -641,17 +640,17 @@ static void mgslpc_config(dev_link_t *li
+     link->state |= DEV_CONFIG;
+     /* Look up the current Vcc */
+-    CS_CHECK(GetConfigurationInfo, handle, &conf);
++    CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
+     link->conf.Vcc = conf.Vcc;
+     /* get CIS configuration entry */
+     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     cfg = &(parse.cftable_entry);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
+     if (cfg->index == 0)
+@@ -672,7 +671,7 @@ static void mgslpc_config(dev_link_t *li
+           link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+           link->io.BasePort1 = io->win[0].base;
+           link->io.NumPorts1 = io->win[0].len;
+-          CS_CHECK(RequestIO, link->handle, &link->io);
++          CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
+     }
+     link->conf.Attributes = CONF_ENABLE_IRQ;
+@@ -684,9 +683,9 @@ static void mgslpc_config(dev_link_t *li
+     link->irq.Attributes |= IRQ_HANDLE_PRESENT;
+     link->irq.Handler     = mgslpc_isr;
+     link->irq.Instance    = info;
+-    CS_CHECK(RequestIRQ, link->handle, &link->irq);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+-    CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+     info->io_base = link->io.BasePort1;
+     info->irq_level = link->irq.AssignedIRQ;
+@@ -728,11 +727,11 @@ static void mgslpc_release(u_long arg)
+     link->dev = NULL;
+     link->state &= ~DEV_CONFIG;
+-    CardServices(ReleaseConfiguration, link->handle);
++    pcmcia_release_configuration(link->handle);
+     if (link->io.NumPorts1)
+-          CardServices(ReleaseIO, link->handle, &link->io);
++          pcmcia_release_io(link->handle, &link->io);
+     if (link->irq.AssignedIRQ)
+-          CardServices(ReleaseIRQ, link->handle, &link->irq);
++          pcmcia_release_irq(link->handle, &link->irq);
+     if (link->state & DEV_STALE_LINK)
+           mgslpc_detach(link);
+ }
+@@ -763,7 +762,7 @@ static void mgslpc_detach(dev_link_t *li
+     /* Break the link with Card Services */
+     if (link->handle)
+-          CardServices(DeregisterClient, link->handle);
++          pcmcia_deregister_client(link->handle);
+     
+     /* Unlink device structure, and free it */
+     *linkp = link->next;
+@@ -798,14 +797,14 @@ static int mgslpc_event(event_t event, i
+           /* Mark the device as stopped, to block IO until later */
+           info->stop = 1;
+           if (link->state & DEV_CONFIG)
+-                  CardServices(ReleaseConfiguration, link->handle);
++                  pcmcia_release_configuration(link->handle);
+           break;
+     case CS_EVENT_PM_RESUME:
+           link->state &= ~DEV_SUSPEND;
+           /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+           if (link->state & DEV_CONFIG)
+-                  CardServices(RequestConfiguration, link->handle, &link->conf);
++                  pcmcia_request_configuration(link->handle, &link->conf);
+           info->stop = 0;
+           break;
+     }
+@@ -4206,35 +4205,46 @@ void tx_timeout(unsigned long context)
+ #ifdef CONFIG_SYNCLINK_SYNCPPP
+ /* syncppp net device routines
+  */
++ 
++static void mgslpc_setup(struct net_device *dev)
++{
++      dev->open = mgslpc_sppp_open;
++      dev->stop = mgslpc_sppp_close;
++      dev->hard_start_xmit = mgslpc_sppp_tx;
++      dev->do_ioctl = mgslpc_sppp_ioctl;
++      dev->get_stats = mgslpc_net_stats;
++      dev->tx_timeout = mgslpc_sppp_tx_timeout;
++      dev->watchdog_timeo = 10*HZ;
++}
+ void mgslpc_sppp_init(MGSLPC_INFO *info)
+ {
+       struct net_device *d;
+       sprintf(info->netname,"mgslp%d",info->line);
++ 
++      d = alloc_netdev(0, info->netname, mgslpc_setup);
++      if (!d) {
++              printk(KERN_WARNING "%s: alloc_netdev failed.\n",
++                                              info->netname);
++              return;
++      }
+       info->if_ptr = &info->pppdev;
+-      info->netdev = info->pppdev.dev = &info->netdevice;
++      info->netdev = info->pppdev.dev = d;
+       sppp_attach(&info->pppdev);
+-      d = info->netdev;
+-      strcpy(d->name,info->netname);
+       d->base_addr = info->io_base;
+       d->irq = info->irq_level;
+       d->priv = info;
+-      d->init = NULL;
+-      d->open = mgslpc_sppp_open;
+-      d->stop = mgslpc_sppp_close;
+-      d->hard_start_xmit = mgslpc_sppp_tx;
+-      d->do_ioctl = mgslpc_sppp_ioctl;
+-      d->get_stats = mgslpc_net_stats;
+-      d->tx_timeout = mgslpc_sppp_tx_timeout;
+-      d->watchdog_timeo = 10*HZ;
+       if (register_netdev(d)) {
+               printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
+               sppp_detach(info->netdev);
++              info->netdev = NULL;
++              info->pppdev.dev = NULL;
++              free_netdev(d);
+               return;
+       }
+@@ -4246,8 +4256,11 @@ void mgslpc_sppp_delete(MGSLPC_INFO *inf
+ {
+       if (debug_level >= DEBUG_LEVEL_INFO)
+               printk("mgslpc_sppp_delete(%s)\n",info->netname);       
+-      sppp_detach(info->netdev);
+       unregister_netdev(info->netdev);
++      sppp_detach(info->netdev);
++      free_netdev(info->netdev);
++      info->netdev = NULL;
++      info->pppdev.dev = NULL;
+ }
+ int mgslpc_sppp_open(struct net_device *d)
+--- linux-2.6.0/drivers/char/ppdev.c   2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/ppdev.c    2003-12-28 23:22:57.000000000 -0800
+@@ -67,6 +67,7 @@
+ #include <asm/uaccess.h>
+ #include <linux/ppdev.h>
+ #include <linux/smp_lock.h>
++#include <linux/device.h>
+ #define PP_VERSION "ppdev: user-space parallel port driver"
+ #define CHRDEV "ppdev"
+@@ -782,4 +783,4 @@ module_init(ppdev_init);
+ module_exit(ppdev_cleanup);
+ MODULE_LICENSE("GPL");
+-
++MODULE_ALIAS_CHARDEV_MAJOR(PP_MAJOR);
+--- linux-2.6.0/drivers/char/raw.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/char/raw.c      2003-12-28 23:21:18.000000000 -0800
+@@ -74,6 +74,7 @@ static int raw_open(struct inode *inode,
+                       goto out;
+               }
+               filp->f_flags |= O_DIRECT;
++              filp->f_mapping = bdev->bd_inode->i_mapping;
+               if (++raw_devices[minor].inuse == 1)
+                       filp->f_dentry->d_inode->i_mapping =
+                               bdev->bd_inode->i_mapping;
+--- linux-2.6.0/drivers/char/sn_serial.c       2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/char/sn_serial.c        2003-12-28 23:21:38.000000000 -0800
+@@ -21,8 +21,9 @@
+ #include <linux/sysrq.h>
+ #include <linux/circ_buf.h>
+ #include <linux/serial_reg.h>
++#include <asm/uaccess.h>
+ #include <asm/sn/sn_sal.h>
+-#include <asm/sn/pci/pciio.h>         /* this is needed for get_console_nasid */
++#include <asm/sn/pci/pciio.h>
+ #include <asm/sn/simulator.h>
+ #include <asm/sn/sn2/sn_private.h>
+@@ -771,7 +772,7 @@ sn_sal_read_proc(char *page, char **star
+       off_t   begin = 0;
+       len += sprintf(page, "sn_serial: nasid:%d irq:%d tx:%d rx:%d\n",
+-                     get_console_nasid(), sn_sal_irq,
++                     ia64_sn_get_console_nasid(), sn_sal_irq,
+                      sn_total_tx_count, sn_total_rx_count);
+       *eof = 1;
+@@ -813,6 +814,9 @@ sn_sal_switch_to_asynch(void)
+ {
+       unsigned long flags;
++      if (sn_sal_is_asynch)
++              return;
++
+       sn_debug_printf("sn_serial: about to switch to asynchronous console\n");
+       /* without early_printk, we may be invoked late enough to race
+--- linux-2.6.0/drivers/char/sx.c      2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/char/sx.c       2003-12-28 23:22:46.000000000 -0800
+@@ -509,13 +509,13 @@ static int sx_busy_wait_eq (struct sx_bo
+       func_enter ();
+-      for (i=0; i < TIMEOUT_1 > 0;i++) 
++      for (i=0; i < TIMEOUT_1 ;i++)
+               if ((read_sx_byte (board, offset) & mask) == correctval) {
+                       func_exit ();
+                       return 1;
+               }
+-      for (i=0; i < TIMEOUT_2 > 0;i++) {
++      for (i=0; i < TIMEOUT_2 ;i++) {
+               if ((read_sx_byte (board, offset) & mask) == correctval) {
+                       func_exit ();
+                       return 1;
+@@ -535,13 +535,13 @@ static int sx_busy_wait_neq (struct sx_b
+       func_enter ();
+-      for (i=0; i < TIMEOUT_1 > 0;i++) 
++      for (i=0; i < TIMEOUT_1 ;i++)
+               if ((read_sx_byte (board, offset) & mask) != badval) {
+                       func_exit ();
+                       return 1;
+               }
+-      for (i=0; i < TIMEOUT_2 > 0;i++) {
++      for (i=0; i < TIMEOUT_2 ;i++) {
+               if ((read_sx_byte (board, offset) & mask) != badval) {
+                       func_exit ();
+                       return 1;
+--- linux-2.6.0/drivers/char/synclink.c        2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/char/synclink.c 2003-12-28 23:21:00.000000000 -0800
+@@ -327,7 +327,6 @@ struct mgsl_struct {
+       char netname[10];
+       struct net_device *netdev;
+       struct net_device_stats netstats;
+-      struct net_device netdevice;
+ #endif
+ };
+@@ -737,8 +736,8 @@ int mgsl_ioctl_common(struct mgsl_struct
+ #ifdef CONFIG_SYNCLINK_SYNCPPP
+ /* SPPP/HDLC stuff */
+-void mgsl_sppp_init(struct mgsl_struct *info);
+-void mgsl_sppp_delete(struct mgsl_struct *info);
++static void mgsl_sppp_init(struct mgsl_struct *info);
++static void mgsl_sppp_delete(struct mgsl_struct *info);
+ int mgsl_sppp_open(struct net_device *d);
+ int mgsl_sppp_close(struct net_device *d);
+ void mgsl_sppp_tx_timeout(struct net_device *d);
+@@ -7820,36 +7819,45 @@ int usc_loopmode_send_active( struct mgs
+ #ifdef CONFIG_SYNCLINK_SYNCPPP
+ /* syncppp net device routines
+  */
++static void mgsl_setup(struct net_device *dev)
++{
++      dev->open = mgsl_sppp_open;
++      dev->stop = mgsl_sppp_close;
++      dev->hard_start_xmit = mgsl_sppp_tx;
++      dev->do_ioctl = mgsl_sppp_ioctl;
++      dev->get_stats = mgsl_net_stats;
++      dev->tx_timeout = mgsl_sppp_tx_timeout;
++      dev->watchdog_timeo = 10*HZ;
++}
+-void mgsl_sppp_init(struct mgsl_struct *info)
++static void mgsl_sppp_init(struct mgsl_struct *info)
+ {
+       struct net_device *d;
+       sprintf(info->netname,"mgsl%d",info->line);
++      d = alloc_netdev(0, info->netname, mgsl_setup);
++      if (!d) {
++              printk(KERN_WARNING "%s: alloc_netdev failed.\n",
++                                              info->netname);
++              return;
++      }
++
+       info->if_ptr = &info->pppdev;
+-      info->netdev = info->pppdev.dev = &info->netdevice;
++      info->netdev = info->pppdev.dev = d;
+       sppp_attach(&info->pppdev);
+-      d = info->netdev;
+-      strcpy(d->name,info->netname);
+       d->base_addr = info->io_base;
+       d->irq = info->irq_level;
+       d->dma = info->dma_level;
+       d->priv = info;
+-      d->init = NULL;
+-      d->open = mgsl_sppp_open;
+-      d->stop = mgsl_sppp_close;
+-      d->hard_start_xmit = mgsl_sppp_tx;
+-      d->do_ioctl = mgsl_sppp_ioctl;
+-      d->get_stats = mgsl_net_stats;
+-      d->tx_timeout = mgsl_sppp_tx_timeout;
+-      d->watchdog_timeo = 10*HZ;
+       if (register_netdev(d)) {
+               printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
+               sppp_detach(info->netdev);
++              info->netdev = NULL;
++              free_netdev(d);
+               return;
+       }
+@@ -7861,8 +7869,11 @@ void mgsl_sppp_delete(struct mgsl_struct
+ {
+       if (debug_level >= DEBUG_LEVEL_INFO)
+               printk("mgsl_sppp_delete(%s)\n",info->netname); 
+-      sppp_detach(info->netdev);
+       unregister_netdev(info->netdev);
++      sppp_detach(info->netdev);
++      free_netdev(info->netdev);
++      info->netdev = NULL;
++      info->pppdev.dev = NULL;
+ }
+ int mgsl_sppp_open(struct net_device *d)
+--- linux-2.6.0/drivers/char/synclinkmp.c      2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/char/synclinkmp.c       2003-12-28 23:21:00.000000000 -0800
+@@ -289,7 +289,6 @@ typedef struct _synclinkmp_info {
+       char netname[10];
+       struct net_device *netdev;
+       struct net_device_stats netstats;
+-      struct net_device netdevice;
+ #endif
+ } SLMP_INFO;
+@@ -1627,35 +1626,44 @@ static void set_break(struct tty_struct 
+ /* syncppp support and callbacks */
++static void cb_setup(struct net_device *dev)
++{
++      dev->open = sppp_cb_open;
++      dev->stop = sppp_cb_close;
++      dev->hard_start_xmit = sppp_cb_tx;
++      dev->do_ioctl = sppp_cb_ioctl;
++      dev->get_stats = sppp_cb_net_stats;
++      dev->tx_timeout = sppp_cb_tx_timeout;
++      dev->watchdog_timeo = 10*HZ;
++}
++
+ static void sppp_init(SLMP_INFO *info)
+ {
+       struct net_device *d;
+       sprintf(info->netname,"mgslm%dp%d",info->adapter_num,info->port_num);
++      d = alloc_netdev(0, info->netname, cb_setup);
++      if (!d) {
++              printk(KERN_WARNING "%s: alloc_netdev failed.\n",
++                                              info->netname);
++              return;
++      }
++
+       info->if_ptr = &info->pppdev;
+-      info->netdev = info->pppdev.dev = &info->netdevice;
++      info->netdev = info->pppdev.dev = d;
+       sppp_attach(&info->pppdev);
+-      d = info->netdev;
+-      strcpy(d->name,info->netname);
+-      d->base_addr = 0;
+       d->irq = info->irq_level;
+-      d->dma = 0;
+       d->priv = info;
+-      d->init = NULL;
+-      d->open = sppp_cb_open;
+-      d->stop = sppp_cb_close;
+-      d->hard_start_xmit = sppp_cb_tx;
+-      d->do_ioctl = sppp_cb_ioctl;
+-      d->get_stats = sppp_cb_net_stats;
+-      d->tx_timeout = sppp_cb_tx_timeout;
+-      d->watchdog_timeo = 10*HZ;
+       if (register_netdev(d)) {
+               printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
+               sppp_detach(info->netdev);
++              info->netdev = NULL;
++              info->pppdev.dev = NULL;
++              free_netdev(d);
+               return;
+       }
+@@ -1667,8 +1675,11 @@ static void sppp_delete(SLMP_INFO *info)
+ {
+       if (debug_level >= DEBUG_LEVEL_INFO)
+               printk("sppp_delete(%s)\n",info->netname);
+-      sppp_detach(info->netdev);
+       unregister_netdev(info->netdev);
++      sppp_detach(info->netdev);
++      free_netdev(info->netdev);
++      info->netdev = NULL;
++      info->pppdev.dev = NULL;
+ }
+ static int sppp_cb_open(struct net_device *d)
+--- linux-2.6.0/drivers/char/sysrq.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/char/sysrq.c    2003-12-28 23:21:07.000000000 -0800
+@@ -35,6 +35,25 @@
+ #include <linux/spinlock.h>
+ #include <asm/ptrace.h>
++#ifdef CONFIG_KGDB_SYSRQ
++
++#define  GDB_OP &kgdb_op
++static void kgdb_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
++{
++      printk("kgdb sysrq\n");
++      breakpoint();
++}
++
++static struct sysrq_key_op kgdb_op = {
++      .handler        = kgdb_sysrq,
++      .help_msg       = "kGdb|Fgdb",
++      .action_msg     = "Debug breakpoint\n",
++};
++
++#else
++#define  GDB_OP NULL
++#endif
++
+ extern void reset_vc(unsigned int);
+@@ -238,8 +257,8 @@ static struct sysrq_key_op *sysrq_key_ta
+ /* c */ NULL,
+ /* d */       NULL,
+ /* e */       &sysrq_term_op,
+-/* f */       NULL,
+-/* g */       NULL,
++/* f */       GDB_OP,
++/* g */       GDB_OP,
+ /* h */       NULL,
+ /* i */       &sysrq_kill_op,
+ /* j */       NULL,
+--- linux-2.6.0/drivers/char/tty_io.c  2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/char/tty_io.c   2003-12-28 23:22:59.000000000 -0800
+@@ -2069,80 +2069,10 @@ static void tty_default_put_char(struct 
+       tty->driver->write(tty, 0, &ch, 1);
+ }
+-struct tty_dev {
+-      struct list_head node;
+-      dev_t dev;
+-      struct class_device class_dev;
+-};
+-#define to_tty_dev(d) container_of(d, struct tty_dev, class_dev)
+-
+-static void release_tty_dev(struct class_device *class_dev)
+-{
+-      struct tty_dev *tty_dev = to_tty_dev(class_dev);
+-      kfree(tty_dev);
+-}
+-
+ static struct class tty_class = {
+-      .name           = "tty",
+-      .release        = &release_tty_dev,
++      .name   = "tty",
+ };
+-static LIST_HEAD(tty_dev_list);
+-static spinlock_t tty_dev_list_lock = SPIN_LOCK_UNLOCKED;
+-
+-static ssize_t show_dev(struct class_device *class_dev, char *buf)
+-{
+-      struct tty_dev *tty_dev = to_tty_dev(class_dev);
+-      return print_dev_t(buf, tty_dev->dev);
+-}
+-static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
+-
+-static void tty_add_class_device(char *name, dev_t dev, struct device *device)
+-{
+-      struct tty_dev *tty_dev = NULL;
+-      int retval;
+-
+-      tty_dev = kmalloc(sizeof(*tty_dev), GFP_KERNEL);
+-      if (!tty_dev)
+-              return;
+-      memset(tty_dev, 0x00, sizeof(*tty_dev));
+-
+-      tty_dev->class_dev.dev = device;
+-      tty_dev->class_dev.class = &tty_class;
+-      snprintf(tty_dev->class_dev.class_id, BUS_ID_SIZE, "%s", name);
+-      retval = class_device_register(&tty_dev->class_dev);
+-      if (retval)
+-              goto error;
+-      class_device_create_file (&tty_dev->class_dev, &class_device_attr_dev);
+-      tty_dev->dev = dev;
+-      spin_lock(&tty_dev_list_lock);
+-      list_add(&tty_dev->node, &tty_dev_list);
+-      spin_unlock(&tty_dev_list_lock);
+-      return;
+-error:
+-      kfree(tty_dev);
+-}
+-
+-static void tty_remove_class_device(dev_t dev)
+-{
+-      struct tty_dev *tty_dev = NULL;
+-      struct list_head *tmp;
+-      int found = 0;
+-
+-      spin_lock(&tty_dev_list_lock);
+-      list_for_each (tmp, &tty_dev_list) {
+-              tty_dev = list_entry(tmp, struct tty_dev, node);
+-              if (tty_dev->dev == dev) {
+-                      list_del(&tty_dev->node);
+-                      found = 1;
+-                      break;
+-              }
+-      }
+-      spin_unlock(&tty_dev_list_lock);
+-      if (found)
+-              class_device_unregister(&tty_dev->class_dev);
+-}
+-
+ /**
+  * tty_register_device - register a tty device
+  * @driver: the tty driver that describes the tty device
+@@ -2174,7 +2104,7 @@ void tty_register_device(struct tty_driv
+       if (driver->type != TTY_DRIVER_TYPE_PTY) {
+               char name[64];
+               tty_line_name(driver, index, name);
+-              tty_add_class_device(name, dev, device);
++              simple_add_class_device(&tty_class, dev, device, name);
+       }
+ }
+@@ -2189,7 +2119,7 @@ void tty_register_device(struct tty_driv
+ void tty_unregister_device(struct tty_driver *driver, unsigned index)
+ {
+       devfs_remove("%s%d", driver->devfs_name, index + driver->name_base);
+-      tty_remove_class_device(MKDEV(driver->major, driver->minor_start) + index);
++      simple_remove_class_device(MKDEV(driver->major, driver->minor_start) + index);
+ }
+ EXPORT_SYMBOL(tty_register_device);
+@@ -2431,7 +2361,7 @@ static int __init tty_init(void)
+           register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
+               panic("Couldn't register /dev/tty driver\n");
+       devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
+-      tty_add_class_device ("tty", MKDEV(TTYAUX_MAJOR, 0), NULL);
++      simple_add_class_device(&tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
+       strcpy(console_cdev.kobj.name, "dev.console");
+       cdev_init(&console_cdev, &console_fops);
+@@ -2439,7 +2369,7 @@ static int __init tty_init(void)
+           register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
+               panic("Couldn't register /dev/console driver\n");
+       devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
+-      tty_add_class_device ("console", MKDEV(TTYAUX_MAJOR, 1), NULL);
++      simple_add_class_device(&tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
+       tty_kobj.kset = tty_cdev.kobj.kset;
+       kobject_register(&tty_kobj);
+@@ -2451,7 +2381,7 @@ static int __init tty_init(void)
+           register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
+               panic("Couldn't register /dev/ptmx driver\n");
+       devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
+-      tty_add_class_device ("ptmx", MKDEV(TTYAUX_MAJOR, 2), NULL);
++      simple_add_class_device(&tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
+ #endif
+       
+ #ifdef CONFIG_VT
+@@ -2461,7 +2391,7 @@ static int __init tty_init(void)
+           register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
+               panic("Couldn't register /dev/tty0 driver\n");
+       devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
+-      tty_add_class_device ("tty0", MKDEV(TTY_MAJOR, 0), NULL);
++      simple_add_class_device(&tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
+       vty_init();
+ #endif
+--- linux-2.6.0/drivers/char/vt_ioctl.c        2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/char/vt_ioctl.c 2003-12-28 23:22:23.000000000 -0800
+@@ -332,7 +332,7 @@ do_fontx_ioctl(int cmd, struct consolefo
+ }
+ static inline int 
+-do_unimap_ioctl(int cmd, struct unimapdesc *user_ud,int perm)
++do_unimap_ioctl(int cmd, struct unimapdesc *user_ud, int perm, unsigned int console)
+ {
+       struct unimapdesc tmp;
+       int i = 0; 
+@@ -348,9 +348,11 @@ do_unimap_ioctl(int cmd, struct unimapde
+       case PIO_UNIMAP:
+               if (!perm)
+                       return -EPERM;
+-              return con_set_unimap(fg_console, tmp.entry_ct, tmp.entries);
++              return con_set_unimap(console, tmp.entry_ct, tmp.entries);
+       case GIO_UNIMAP:
+-              return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries);
++              if (!perm && fg_console != console)
++                      return -EPERM;
++              return con_get_unimap(console, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries);
+       }
+       return 0;
+ }
+@@ -966,13 +968,13 @@ int vt_ioctl(struct tty_struct *tty, str
+                       return -EPERM;
+               i = copy_from_user(&ui, (void *)arg, sizeof(struct unimapinit));
+               if (i) return -EFAULT;
+-              con_clear_unimap(fg_console, &ui);
++              con_clear_unimap(console, &ui);
+               return 0;
+             }
+       case PIO_UNIMAP:
+       case GIO_UNIMAP:
+-              return do_unimap_ioctl(cmd, (struct unimapdesc *)arg, perm);
++              return do_unimap_ioctl(cmd, (struct unimapdesc *)arg, perm, console);
+       case VT_LOCKSWITCH:
+               if (!capable(CAP_SYS_TTY_CONFIG))
+--- linux-2.6.0/drivers/char/watchdog/i810-tco.c       2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/watchdog/i810-tco.c        2003-12-28 23:22:09.000000000 -0800
+@@ -232,9 +232,8 @@ static ssize_t i810tco_write (struct fil
+               /* someone wrote to us, we should reload the timer */
+               tco_timer_reload ();
+-              return 1;
+       }
+-      return 0;
++      return len;
+ }
+ static int i810tco_ioctl (struct inode *inode, struct file *file,
+--- linux-2.6.0/drivers/char/watchdog/ib700wdt.c       2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/watchdog/ib700wdt.c        2003-12-28 23:22:09.000000000 -0800
+@@ -161,9 +161,8 @@ ibwdt_write(struct file *file, const cha
+                       }
+               }
+               ibwdt_ping();
+-              return 1;
+       }
+-      return 0;
++      return count;
+ }
+ static int
+--- linux-2.6.0/drivers/char/watchdog/indydog.c        2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/char/watchdog/indydog.c 2003-12-28 23:22:09.000000000 -0800
+@@ -113,9 +113,8 @@ static ssize_t indydog_write(struct file
+                       }
+               }
+               indydog_ping();
+-              return 1;
+       }
+-      return 0;
++      return len;
+ }
+ static int indydog_ioctl(struct inode *inode, struct file *file,
+--- linux-2.6.0/drivers/char/watchdog/Kconfig  2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/char/watchdog/Kconfig   2003-12-28 23:23:06.000000000 -0800
+@@ -17,7 +17,7 @@ config WATCHDOG
+         implementation entirely in software (which can sometimes fail to
+         reboot the machine) and a driver for hardware watchdog boards, which
+         are more robust and can also keep track of the temperature inside
+-        your computer. For details, read <file:Documentation/watchdog.txt>
++        your computer. For details, read <file:Documentation/watchdog/watchdog.txt>
+         in the kernel source.
+         The watchdog is usually used together with the watchdog daemon
+@@ -114,7 +114,7 @@ config PCWATCHDOG
+         This card simply watches your kernel to make sure it doesn't freeze,
+         and if it does, it reboots your computer after a certain amount of
+         time. This driver is like the WDT501 driver but for different
+-        hardware. Please read <file:Documentation/pcwd-watchdog.txt>. The PC
++        hardware. Please read <file:Documentation/watchdog/pcwd-watchdog.txt>. The PC
+         watchdog cards can be ordered from <http://www.berkprod.com/>.
+         To compile this driver as a module, choose M here: the
+@@ -276,6 +276,21 @@ config W83877F_WDT
+         Most people will say N.
++config W83627HF_WDT
++      tristate "W83627HF Watchdog Timer"
++      depends on WATCHDOG
++      ---help---
++        This is the driver for the hardware watchdog on the W83627HF chipset
++        as used in Advantech PC-9578 and Tyan S2721-533 motherboards
++        (and likely others).  This watchdog simply watches your kernel to
++        make sure it doesn't freeze, and if it does, it reboots your computer
++        after a certain amount of time.
++
++        To compile this driver as a module, choose M here: the
++        module will be called w83627hf_wdt.
++
++        Most people will say N.
++
+ config MACHZ_WDT
+       tristate "ZF MachZ Watchdog"
+       depends on WATCHDOG
+--- linux-2.6.0/drivers/char/watchdog/machzwd.c        2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/watchdog/machzwd.c 2003-12-28 23:22:09.000000000 -0800
+@@ -343,10 +343,9 @@ static ssize_t zf_write(struct file *fil
+               next_heartbeat = jiffies + ZF_USER_TIMEO;
+               dprintk("user ping at %ld\n", jiffies);
+               
+-              return 1;
+       }
+-      return 0;
++      return count;
+ }
+ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+--- linux-2.6.0/drivers/char/watchdog/Makefile 2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/watchdog/Makefile  2003-12-28 23:22:31.000000000 -0800
+@@ -25,6 +25,7 @@ obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_
+ obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
+ obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
+ obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
++obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
+ obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
+ obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
+ obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
+--- linux-2.6.0/drivers/char/watchdog/mixcomwd.c       2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/char/watchdog/mixcomwd.c        2003-12-28 23:22:09.000000000 -0800
+@@ -156,9 +156,8 @@ static ssize_t mixcomwd_write(struct fil
+                       }
+               }
+               mixcomwd_ping();
+-              return 1;
+       }
+-      return 0;
++      return len;
+ }
+ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
+--- linux-2.6.0/drivers/char/watchdog/pcwd.c   2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/watchdog/pcwd.c    2003-12-28 23:22:09.000000000 -0800
+@@ -419,9 +419,8 @@ static ssize_t pcwd_write(struct file *f
+                       }
+               }
+               pcwd_send_heartbeat();
+-              return 1;
+       }
+-      return 0;
++      return len;
+ }
+ static int pcwd_open(struct inode *ino, struct file *filep)
+--- linux-2.6.0/drivers/char/watchdog/sa1100_wdt.c     2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/char/watchdog/sa1100_wdt.c      2003-12-28 23:22:09.000000000 -0800
+@@ -106,7 +106,7 @@ static ssize_t sa1100dog_write(struct fi
+               OSMR3 = OSCR + pre_margin;
+       }
+-      return len ? 1 : 0;
++      return len;
+ }
+ static struct watchdog_info ident = {
+--- linux-2.6.0/drivers/char/watchdog/softdog.c        2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/char/watchdog/softdog.c 2003-12-28 23:22:09.000000000 -0800
+@@ -155,9 +155,8 @@ static ssize_t softdog_write(struct file
+                       }
+               }
+               mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
+-              return 1;
+       }
+-      return 0;
++      return len;
+ }
+ static int softdog_ioctl(struct inode *inode, struct file *file,
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/char/watchdog/w83627hf_wdt.c    2003-12-28 23:22:31.000000000 -0800
+@@ -0,0 +1,324 @@
++/*
++ *    w83627hf WDT driver
++ *
++ *    (c) Copyright 2003 Pádraig Brady <P@draigBrady.com>
++ *
++ *    Based on advantechwdt.c which is based on wdt.c.
++ *    Original copyright messages:
++ *
++ *    (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
++ *
++ *    (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
++ *                            http://www.redhat.com
++ *
++ *    This program is free software; you can redistribute it and/or
++ *    modify it under the terms of the GNU General Public License
++ *    as published by the Free Software Foundation; either version
++ *    2 of the License, or (at your option) any later version.
++ *
++ *    Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
++ *    warranty for any of this software. This material is provided
++ *    "AS-IS" and at no charge.
++ *
++ *    (c) Copyright 1995    Alan Cox <alan@redhat.com>
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/types.h>
++#include <linux/miscdevice.h>
++#include <linux/watchdog.h>
++#include <linux/fs.h>
++#include <linux/ioport.h>
++#include <linux/notifier.h>
++#include <linux/reboot.h>
++#include <linux/init.h>
++
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/system.h>
++
++#define WATCHDOG_NAME "w83627hf WDT"
++#define PFX WATCHDOG_NAME ": "
++#define WATCHDOG_TIMEOUT 60           /* 60 sec default timeout */
++
++static unsigned long wdt_is_open;
++static char expect_close;
++
++/* You must set this - there is no sane way to probe for this board. */
++static int wdt_io = 0x2E;
++module_param(wdt_io, int, 0);
++MODULE_PARM_DESC(wdt_io, "w83627hf WDT io port (default 0x2E)");
++
++static int timeout = WATCHDOG_TIMEOUT;        /* in seconds */
++module_param(timeout, int, 0);
++MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
++
++#ifdef CONFIG_WATCHDOG_NOWAYOUT
++static int nowayout = 1;
++#else
++static int nowayout = 0;
++#endif
++
++module_param(nowayout, int, 0);
++MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
++
++/*
++ *    Kernel methods.
++ */
++
++#define WDT_EFER (wdt_io+0)   /* Extended Function Enable Registers */
++#define WDT_EFIR (wdt_io+0)   /* Extended Function Index Register (same as EFER) */
++#define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */
++
++static void
++wdt_ctrl(int timeout)
++{
++      outb_p(0x87, WDT_EFER); /* Enter extended function mode */
++      outb_p(0x87, WDT_EFER); /* Again according to manual */
++
++      outb_p(0x07, WDT_EFER); /* point to logical device number reg */
++      outb_p(0x08, WDT_EFDR); /* select logical device 8 (GPIO2) */
++      outb_p(0x30, WDT_EFER); /* select CR30 */
++      outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */
++
++      outb_p(0xF6, WDT_EFER);    /* Select CRF6 */
++      outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF6 */
++
++      outb_p(0xAA, WDT_EFER); /* Leave extended function mode */
++}
++
++static void
++wdt_ping(void)
++{
++      wdt_ctrl(timeout);
++}
++
++static void
++wdt_disable(void)
++{
++      wdt_ctrl(0);
++}
++
++static ssize_t
++wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
++{
++      /*  Can't seek (pwrite) on this device  */
++      if (ppos != &file->f_pos)
++              return -ESPIPE;
++
++      if (count) {
++              if (!nowayout) {
++                      size_t i;
++
++                      expect_close = 0;
++
++                      for (i = 0; i != count; i++) {
++                              char c;
++                              if (get_user(c, buf+i))
++                                      return -EFAULT;
++                              if (c == 'V')
++                                      expect_close = 42;
++                      }
++              }
++              wdt_ping();
++      }
++      return count;
++}
++
++static int
++wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
++        unsigned long arg)
++{
++      int new_timeout;
++      static struct watchdog_info ident = {
++              .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
++              .firmware_version = 1,
++              .identity = "Advantech WDT",
++      };
++
++      switch (cmd) {
++      case WDIOC_GETSUPPORT:
++        if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
++          return -EFAULT;
++        break;
++
++      case WDIOC_GETSTATUS:
++      case WDIOC_GETBOOTSTATUS:
++        return put_user(0, (int *)arg);
++
++      case WDIOC_KEEPALIVE:
++        wdt_ping();
++        break;
++
++      case WDIOC_SETTIMEOUT:
++        if (get_user(new_timeout, (int *)arg))
++                return -EFAULT;
++        if ((new_timeout < 1) || (new_timeout > 63))
++                return -EINVAL;
++        timeout = new_timeout;
++        wdt_ping();
++        /* Fall */
++
++      case WDIOC_GETTIMEOUT:
++        return put_user(timeout, (int *)arg);
++
++      case WDIOC_SETOPTIONS:
++      {
++        int options, retval = -EINVAL;
++
++        if (get_user(options, (int *)arg))
++          return -EFAULT;
++
++        if (options & WDIOS_DISABLECARD) {
++          wdt_disable();
++          retval = 0;
++        }
++
++        if (options & WDIOS_ENABLECARD) {
++          wdt_ping();
++          retval = 0;
++        }
++
++        return retval;
++      }
++
++      default:
++        return -ENOTTY;
++      }
++      return 0;
++}
++
++static int
++wdt_open(struct inode *inode, struct file *file)
++{
++      if (test_and_set_bit(0, &wdt_is_open))
++              return -EBUSY;
++      /*
++       *      Activate
++       */
++
++      wdt_ping();
++      return 0;
++}
++
++static int
++wdt_close(struct inode *inode, struct file *file)
++{
++      if (expect_close == 42) {
++              wdt_disable();
++      } else {
++              printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
++              wdt_ping();
++      }
++      clear_bit(0, &wdt_is_open);
++      expect_close = 0;
++      return 0;
++}
++
++/*
++ *    Notifier for system down
++ */
++
++static int
++wdt_notify_sys(struct notifier_block *this, unsigned long code,
++      void *unused)
++{
++      if (code == SYS_DOWN || code == SYS_HALT) {
++              /* Turn the WDT off */
++              wdt_disable();
++      }
++      return NOTIFY_DONE;
++}
++
++/*
++ *    Kernel Interfaces
++ */
++
++static struct file_operations wdt_fops = {
++      .owner          = THIS_MODULE,
++      .llseek         = no_llseek,
++      .write          = wdt_write,
++      .ioctl          = wdt_ioctl,
++      .open           = wdt_open,
++      .release        = wdt_close,
++};
++
++static struct miscdevice wdt_miscdev = {
++      .minor = WATCHDOG_MINOR,
++      .name = "watchdog",
++      .fops = &wdt_fops,
++};
++
++/*
++ *    The WDT needs to learn about soft shutdowns in order to
++ *    turn the timebomb registers off.
++ */
++
++static struct notifier_block wdt_notifier = {
++      .notifier_call = wdt_notify_sys,
++      .next = NULL,
++      .priority = 0,
++};
++
++static int __init
++wdt_init(void)
++{
++      int ret;
++
++      printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n");
++
++      if (timeout < 1 || timeout > 63) {
++              timeout = WATCHDOG_TIMEOUT;
++              printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n",
++                      timeout);
++      }
++
++      if (!request_region(wdt_io, 1, WATCHDOG_NAME)) {
++              printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
++                      wdt_io);
++              ret = -EIO;
++              goto out;
++      }
++
++      ret = register_reboot_notifier(&wdt_notifier);
++      if (ret != 0) {
++              printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
++                      ret);
++              goto unreg_regions;
++      }
++
++      ret = misc_register(&wdt_miscdev);
++      if (ret != 0) {
++              printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
++                      WATCHDOG_MINOR, ret);
++              goto unreg_reboot;
++      }
++
++      printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
++              timeout, nowayout);
++
++out:
++      return ret;
++unreg_reboot:
++      unregister_reboot_notifier(&wdt_notifier);
++unreg_regions:
++      release_region(wdt_io, 1);
++      goto out;
++}
++
++static void __exit
++wdt_exit(void)
++{
++      misc_deregister(&wdt_miscdev);
++      unregister_reboot_notifier(&wdt_notifier);
++      release_region(wdt_io,1);
++}
++
++module_init(wdt_init);
++module_exit(wdt_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Pádraig Brady <P@draigBrady.com>");
++MODULE_DESCRIPTION("w38627hf WDT driver");
++
+--- linux-2.6.0/drivers/char/watchdog/wdt.c    2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/char/watchdog/wdt.c     2003-12-28 23:22:09.000000000 -0800
+@@ -265,9 +265,8 @@ static ssize_t wdt_write(struct file *fi
+                       }
+               }
+               wdt_ping();
+-              return 1;
+       }
+-      return 0;
++      return count;
+ }
+ /**
+--- linux-2.6.0/drivers/i2c/i2c-core.c 2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/i2c/i2c-core.c  2003-12-28 23:22:30.000000000 -0800
+@@ -136,10 +136,10 @@ int i2c_add_adapter(struct i2c_adapter *
+       /* Add the adapter to the driver core.
+        * If the parent pointer is not set up,
+-       * we add this adapter to the legacy bus.
++       * we add this adapter to the host bus.
+        */
+       if (adap->dev.parent == NULL)
+-              adap->dev.parent = &legacy_bus;
++              adap->dev.parent = &platform_bus;
+       sprintf(adap->dev.bus_id, "i2c-%d", adap->nr);
+       adap->dev.driver = &i2c_adapter_driver;
+       adap->dev.release = &i2c_adapter_dev_release;
+--- linux-2.6.0/drivers/i2c/i2c-dev.c  2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/i2c/i2c-dev.c   2003-12-28 23:22:30.000000000 -0800
+@@ -223,7 +223,7 @@ int i2cdev_ioctl (struct inode *inode, s
+               /* Put an arbritrary limit on the number of messages that can
+                * be sent at once */
+-              if (rdwr_arg.nmsgs > 42)
++              if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
+                       return -EINVAL;
+               
+               rdwr_pa = (struct i2c_msg *)
+@@ -447,7 +447,7 @@ static int i2cdev_attach_adapter(struct 
+       /* register this i2c device with the driver core */
+       i2c_dev->adap = adap;
+-      if (adap->dev.parent == &legacy_bus)
++      if (adap->dev.parent == &platform_bus)
+               i2c_dev->class_dev.dev = &adap->dev;
+       else
+               i2c_dev->class_dev.dev = adap->dev.parent;
+--- linux-2.6.0/drivers/ide/arm/icside.c       2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/ide/arm/icside.c        2003-12-28 23:21:46.000000000 -0800
+@@ -214,7 +214,7 @@ static void icside_maskproc(ide_drive_t 
+ #define NR_ENTRIES 256
+ #define TABLE_SIZE (NR_ENTRIES * 8)
+-static void ide_build_sglist(ide_drive_t *drive, struct request *rq)
++static void icside_build_sglist(ide_drive_t *drive, struct request *rq)
+ {
+       ide_hwif_t *hwif = drive->hwif;
+       struct icside_state *state = hwif->hwif_data;
+@@ -543,7 +543,7 @@ icside_dma_common(ide_drive_t *drive, st
+       BUG_ON(hwif->sg_dma_active);
+       BUG_ON(dma_channel_active(hwif->hw.dma));
+-      ide_build_sglist(drive, rq);
++      icside_build_sglist(drive, rq);
+       /*
+        * Ensure that we have the right interrupt routed.
+--- linux-2.6.0/drivers/ide/ide.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/ide/ide.c       2003-12-28 23:22:32.000000000 -0800
+@@ -458,7 +458,7 @@ void ide_probe_module (void)
+ EXPORT_SYMBOL(ide_probe_module);
+-static int ide_open (struct inode * inode, struct file * filp)
++static int ide_open (struct block_device *bdev, struct file * filp)
+ {
+       return -ENXIO;
+ }
+@@ -1632,12 +1632,12 @@ int generic_ide_ioctl(struct block_devic
+ #endif /* CONFIG_IDE_TASK_IOCTL */
+               case HDIO_DRIVE_CMD:
+-                      if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
++                      if (!capable(CAP_SYS_RAWIO))
+                               return -EACCES;
+                       return ide_cmd_ioctl(drive, cmd, arg);
+               case HDIO_DRIVE_TASK:
+-                      if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
++                      if (!capable(CAP_SYS_RAWIO))
+                               return -EACCES;
+                       return ide_task_ioctl(drive, cmd, arg);
+--- linux-2.6.0/drivers/ide/ide-cd.c   2003-12-17 21:20:02.000000000 -0800
++++ 25/drivers/ide/ide-cd.c    2003-12-28 23:22:35.000000000 -0800
+@@ -291,10 +291,13 @@
+  *                    - Use extended sense on drives that support it for
+  *                      correctly reporting tray status -- from
+  *                      Michael D Johnson <johnsom@orst.edu>
++ * 4.60  Dec 17, 2003 - Add mt rainier support
++ *                    - Bump timeout for packet commands, matches sr
++ *                    - Odd stuff
+  *
+  *************************************************************************/
+  
+-#define IDECD_VERSION "4.59-ac1"
++#define IDECD_VERSION "4.60"
+ #include <linux/config.h>
+ #include <linux/module.h>
+@@ -774,11 +777,36 @@ static int cdrom_decode_status(ide_drive
+               if (sense_key == NOT_READY) {
+                       /* Tray open. */
+-                      cdrom_saw_media_change (drive);
++                      if (rq_data_dir(rq) == READ) {
++                              cdrom_saw_media_change (drive);
+-                      /* Fail the request. */
+-                      printk ("%s: tray open\n", drive->name);
+-                      do_end_request = 1;
++                              /* Fail the request. */
++                              printk ("%s: tray open\n", drive->name);
++                              do_end_request = 1;
++                      } else {
++                              struct cdrom_info *info = drive->driver_data;
++
++                              /* allow the drive 5 seconds to recover, some
++                               * devices will return this error while flushing
++                               * data from cache */
++                              if (!rq->errors)
++                                      info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY;
++                              rq->errors = 1;
++                              if (time_after(jiffies, info->write_timeout))
++                                      do_end_request = 1;
++                              else {
++                                      unsigned long flags;
++
++                                      /*
++                                       * take a breather relying on the
++                                       * unplug timer to kick us again
++                                       */
++                                      spin_lock_irqsave(&ide_lock, flags);
++                                      blk_plug_device(drive->queue);
++                                      spin_unlock_irqrestore(&ide_lock,flags);
++                                      return 1;
++                              }
++                      }
+               } else if (sense_key == UNIT_ATTENTION) {
+                       /* Media change. */
+                       cdrom_saw_media_change (drive);
+@@ -844,9 +872,13 @@ static int cdrom_timer_expiry(ide_drive_
+               case GPCMD_BLANK:
+               case GPCMD_FORMAT_UNIT:
+               case GPCMD_RESERVE_RZONE_TRACK:
+-                      wait = WAIT_CMD;
++              case GPCMD_CLOSE_TRACK:
++              case GPCMD_FLUSH_CACHE:
++                      wait = ATAPI_WAIT_PC;
+                       break;
+               default:
++                      if (!(rq->flags & REQ_QUIET))
++                              printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]);
+                       wait = 0;
+                       break;
+       }
+@@ -894,7 +926,7 @@ static ide_startstop_t cdrom_start_packe
+  
+       if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
+               /* packet command */
+-              ide_execute_command(drive, WIN_PACKETCMD, handler, WAIT_CMD, cdrom_timer_expiry);
++              ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry);
+               return ide_started;
+       } else {
+               /* packet command */
+@@ -1167,7 +1199,7 @@ static ide_startstop_t cdrom_read_intr (
+       }
+       /* Done moving data!  Wait for another interrupt. */
+-      ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL);
++      ide_set_handler(drive, &cdrom_read_intr, ATAPI_WAIT_PC, NULL);
+       return ide_started;
+ }
+@@ -1277,7 +1309,7 @@ static ide_startstop_t cdrom_start_read_
+               (65534 / CD_FRAMESIZE) : 65535);
+       /* Set up the command */
+-      rq->timeout = WAIT_CMD;
++      rq->timeout = ATAPI_WAIT_PC;
+       /* Send the command to the drive and return. */
+       return cdrom_transfer_packet_command(drive, rq, &cdrom_read_intr);
+@@ -1286,7 +1318,7 @@ static ide_startstop_t cdrom_start_read_
+ #define IDECD_SEEK_THRESHOLD  (1000)                  /* 1000 blocks */
+ #define IDECD_SEEK_TIMER      (5 * WAIT_MIN_SLEEP)    /* 100 ms */
+-#define IDECD_SEEK_TIMEOUT     WAIT_CMD                       /* 10 sec */
++#define IDECD_SEEK_TIMEOUT    (2 * ATAPI_WAIT_PC)     /* 20 sec */
+ static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive)
+ {
+@@ -1326,7 +1358,7 @@ static ide_startstop_t cdrom_start_seek_
+       rq->cmd[0] = GPCMD_SEEK;
+       put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]);
+-      rq->timeout = WAIT_CMD;
++      rq->timeout = ATAPI_WAIT_PC;
+       return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr);
+ }
+@@ -1502,7 +1534,7 @@ confused:
+       }
+       /* Now we wait for another interrupt. */
+-      ide_set_handler(drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
++      ide_set_handler(drive, &cdrom_pc_intr, ATAPI_WAIT_PC, cdrom_timer_expiry);
+       return ide_started;
+ }
+@@ -1511,7 +1543,7 @@ static ide_startstop_t cdrom_do_pc_conti
+       struct request *rq = HWGROUP(drive)->rq;
+       if (!rq->timeout)
+-              rq->timeout = WAIT_CMD;
++              rq->timeout = ATAPI_WAIT_PC;
+       /* Send the command to the drive and return. */
+       return cdrom_transfer_packet_command(drive, rq, &cdrom_pc_intr);
+@@ -1716,11 +1748,8 @@ static ide_startstop_t cdrom_newpc_intr(
+       /*
+        * If DRQ is clear, the command has completed.
+        */
+-      if ((stat & DRQ_STAT) == 0) {
+-              if (rq->data_len)
+-                      printk("%s: %u residual after xfer\n", __FUNCTION__, rq->data_len);
++      if ((stat & DRQ_STAT) == 0)
+               goto end_request;
+-      }
+       /*
+        * check which way to transfer data
+@@ -1826,10 +1855,8 @@ static ide_startstop_t cdrom_write_intr(
+               }
+       }
+-      if (cdrom_decode_status(drive, 0, &stat)) {
+-              printk("ide-cd: write_intr decode_status bad\n");
++      if (cdrom_decode_status(drive, 0, &stat))
+               return ide_stopped;
+-      }
+       /*
+        * using dma, transfer is complete now
+@@ -1904,7 +1931,7 @@ static ide_startstop_t cdrom_write_intr(
+       }
+       /* re-arm handler */
+-      ide_set_handler(drive, &cdrom_write_intr, 5 * WAIT_CMD, NULL);
++      ide_set_handler(drive, &cdrom_write_intr, ATAPI_WAIT_PC, NULL);
+       return ide_started;
+ }
+@@ -1915,7 +1942,7 @@ static ide_startstop_t cdrom_start_write
+ #if 0 /* the immediate bit */
+       rq->cmd[1] = 1 << 3;
+ #endif
+-      rq->timeout = 2 * WAIT_CMD;
++      rq->timeout = ATAPI_WAIT_PC;
+       return cdrom_transfer_packet_command(drive, rq, cdrom_write_intr);
+ }
+@@ -1956,7 +1983,7 @@ static ide_startstop_t cdrom_do_newpc_co
+       struct request *rq = HWGROUP(drive)->rq;
+       if (!rq->timeout)
+-              rq->timeout = WAIT_CMD;
++              rq->timeout = ATAPI_WAIT_PC;
+       return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
+ }
+@@ -2242,6 +2269,7 @@ static int cdrom_read_toc(ide_drive_t *d
+               struct atapi_toc_header hdr;
+               struct atapi_toc_entry  ent;
+       } ms_tmp;
++      long last_written;
+       if (toc == NULL) {
+               /* Try to allocate space. */
+@@ -2261,6 +2289,13 @@ static int cdrom_read_toc(ide_drive_t *d
+       if (CDROM_STATE_FLAGS(drive)->toc_valid)
+               return 0;
++      /* Try to get the total cdrom capacity. */
++      stat = cdrom_read_capacity(drive, &toc->capacity, sense);
++      if (stat)
++              toc->capacity = 0x1fffff;
++
++      set_capacity(drive->disk, toc->capacity * SECTORS_PER_FRAME);
++
+       /* First read just the header, so we know how long the TOC is. */
+       stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
+                                   sizeof(struct atapi_toc_header), sense);
+@@ -2368,13 +2403,11 @@ static int cdrom_read_toc(ide_drive_t *d
+       toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
+       /* Now try to get the total cdrom capacity. */
+-      stat = cdrom_get_last_written(cdi, (long *) &toc->capacity);
+-      if (stat || !toc->capacity)
+-              stat = cdrom_read_capacity(drive, &toc->capacity, sense);
+-      if (stat)
+-              toc->capacity = 0x1fffff;
+-
+-      set_capacity(drive->disk, toc->capacity * SECTORS_PER_FRAME);
++      stat = cdrom_get_last_written(cdi, &last_written);
++      if (!stat && last_written) {
++              toc->capacity = last_written;
++              set_capacity(drive->disk, toc->capacity * SECTORS_PER_FRAME);
++      }
+       /* Remember that we've read this stuff. */
+       CDROM_STATE_FLAGS(drive)->toc_valid = 1;
+@@ -2483,7 +2516,7 @@ static int ide_cdrom_packet(struct cdrom
+       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+       if (cgc->timeout <= 0)
+-              cgc->timeout = WAIT_CMD;
++              cgc->timeout = ATAPI_WAIT_PC;
+       /* here we queue the commands from the uniform CD-ROM
+          layer. the packet must be complete, as we do not
+@@ -2688,37 +2721,49 @@ int ide_cdrom_select_speed (struct cdrom
+         return 0;
+ }
++/*
++ * add logic to try GET_EVENT command first to check for media and tray
++ * status. this should be supported by newer cd-r/w and all DVD etc
++ * drives
++ */
+ static
+ int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
+ {
+       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
++      struct media_event_desc med;
++      struct request_sense sense;
++      int stat;
+-      if (slot_nr == CDSL_CURRENT) {
+-              struct request_sense sense;
+-              int stat = cdrom_check_status(drive, &sense);
+-              if (stat == 0 || sense.sense_key == UNIT_ATTENTION)
+-                      return CDS_DISC_OK;
++      if (slot_nr != CDSL_CURRENT)
++              return -EINVAL;
+-              if (sense.sense_key == NOT_READY && sense.asc == 0x04 &&
+-                  sense.ascq == 0x04)
+-                      return CDS_DISC_OK;
++      stat = cdrom_check_status(drive, &sense);
++      if (!stat || sense.sense_key == UNIT_ATTENTION)
++              return CDS_DISC_OK;
++      if (!cdrom_get_media_event(cdi, &med)) {
++              if (med.media_present)
++                      return CDS_DISC_OK;
++              if (med.door_open)
++                      return CDS_TRAY_OPEN;
++      }
+-              /*
+-               * If not using Mt Fuji extended media tray reports,
+-               * just return TRAY_OPEN since ATAPI doesn't provide
+-               * any other way to detect this...
+-               */
+-              if (sense.sense_key == NOT_READY) {
+-                      if (sense.asc == 0x3a && sense.ascq == 1)
+-                              return CDS_NO_DISC;
+-                      else
+-                              return CDS_TRAY_OPEN;
+-              }
++      if (sense.sense_key == NOT_READY && sense.asc == 0x04 && sense.ascq == 0x04)
++              return CDS_DISC_OK;
+-              return CDS_DRIVE_NOT_READY;
++      /*
++       * If not using Mt Fuji extended media tray reports,
++       * just return TRAY_OPEN since ATAPI doesn't provide
++       * any other way to detect this...
++       */
++      if (sense.sense_key == NOT_READY) {
++              if (sense.asc == 0x3a && sense.ascq == 1)
++                      return CDS_NO_DISC;
++              else
++                      return CDS_TRAY_OPEN;
+       }
+-      return -EINVAL;
++
++      return CDS_DRIVE_NOT_READY;
+ }
+ static
+@@ -2826,7 +2871,8 @@ static struct cdrom_device_ops ide_cdrom
+                               CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET |
+                               CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_CD_R |
+                               CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM |
+-                              CDC_GENERIC_PACKET | CDC_MO_DRIVE,
++                              CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW |
++                              CDC_MRW_W | CDC_RAM,
+       .generic_packet         = ide_cdrom_packet,
+ };
+@@ -2861,6 +2907,10 @@ static int ide_cdrom_register (ide_drive
+               devinfo->mask |= CDC_CLOSE_TRAY;
+       if (!CDROM_CONFIG_FLAGS(drive)->mo_drive)
+               devinfo->mask |= CDC_MO_DRIVE;
++      if (!CDROM_CONFIG_FLAGS(drive)->mrw)
++              devinfo->mask |= CDC_MRW;
++      if (!CDROM_CONFIG_FLAGS(drive)->mrw_w)
++              devinfo->mask |= CDC_MRW_W;
+       return register_cdrom(devinfo);
+ }
+@@ -2881,14 +2931,6 @@ int ide_cdrom_get_capabilities(ide_drive
+           !strcmp(drive->id->model, "WPI CDS-32X")))
+               size -= sizeof(cap->pad);
+-      /* we have to cheat a little here. the packet will eventually
+-       * be queued with ide_cdrom_packet(), which extracts the
+-       * drive from cdi->handle. Since this device hasn't been
+-       * registered with the Uniform layer yet, it can't do this.
+-       * Same goes for cdi->ops.
+-       */
+-      cdi->handle = (ide_drive_t *) drive;
+-      cdi->ops = &ide_cdrom_dops;
+       init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
+       do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
+               stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
+@@ -2904,23 +2946,43 @@ int ide_cdrom_probe_capabilities (ide_dr
+       struct cdrom_info *info = drive->driver_data;
+       struct cdrom_device_info *cdi = &info->devinfo;
+       struct atapi_capabilities_page cap;
+-      int nslots = 1;
++      int nslots = 1, mrw_write = 0;
+       if (drive->media == ide_optical) {
+               CDROM_CONFIG_FLAGS(drive)->mo_drive = 1;
++              CDROM_CONFIG_FLAGS(drive)->ram = 1;
+               printk("%s: ATAPI magneto-optical drive\n", drive->name);
+               return nslots;
+       }
+-      if (CDROM_CONFIG_FLAGS(drive)->nec260) {
+-              CDROM_CONFIG_FLAGS(drive)->no_eject = 0;                       
+-              CDROM_CONFIG_FLAGS(drive)->audio_play = 1;       
++      if (CDROM_CONFIG_FLAGS(drive)->nec260 ||
++          !strcmp(drive->id->model,"STINGRAY 8422 IDE 8X CD-ROM 7-27-95")) {
++              CDROM_CONFIG_FLAGS(drive)->no_eject = 0;
++              CDROM_CONFIG_FLAGS(drive)->audio_play = 1;
+               return nslots;
+       }
++      /*
++       * we have to cheat a little here. the packet will eventually
++       * be queued with ide_cdrom_packet(), which extracts the
++       * drive from cdi->handle. Since this device hasn't been
++       * registered with the Uniform layer yet, it can't do this.
++       * Same goes for cdi->ops.
++       */
++      cdi->handle = (ide_drive_t *) drive;
++      cdi->ops = &ide_cdrom_dops;
++
+       if (ide_cdrom_get_capabilities(drive, &cap))
+               return 0;
++      if (!cdrom_is_mrw(cdi, &mrw_write)) {
++              CDROM_CONFIG_FLAGS(drive)->mrw = 1;
++              if (mrw_write) {
++                      CDROM_CONFIG_FLAGS(drive)->mrw_w = 1;
++                      CDROM_CONFIG_FLAGS(drive)->ram = 1;
++              }
++      }
++
+       if (cap.lock == 0)
+               CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1;
+       if (cap.eject)
+@@ -2933,8 +2995,10 @@ int ide_cdrom_probe_capabilities (ide_dr
+               CDROM_CONFIG_FLAGS(drive)->test_write = 1;
+       if (cap.dvd_ram_read || cap.dvd_r_read || cap.dvd_rom)
+               CDROM_CONFIG_FLAGS(drive)->dvd = 1;
+-      if (cap.dvd_ram_write)
++      if (cap.dvd_ram_write) {
+               CDROM_CONFIG_FLAGS(drive)->dvd_ram = 1;
++              CDROM_CONFIG_FLAGS(drive)->ram = 1;
++      }
+       if (cap.dvd_r_write)
+               CDROM_CONFIG_FLAGS(drive)->dvd_r = 1;
+       if (cap.audio_play)
+@@ -2998,6 +3062,9 @@ int ide_cdrom_probe_capabilities (ide_dr
+               (CDROM_CONFIG_FLAGS(drive)->cd_r)? "-R" : "", 
+               (CDROM_CONFIG_FLAGS(drive)->cd_rw)? "/RW" : "");
++      if (CDROM_CONFIG_FLAGS(drive)->mrw || CDROM_CONFIG_FLAGS(drive)->mrw_w)
++              printk(" CD-MR%s", CDROM_CONFIG_FLAGS(drive)->mrw_w ? "W" : "");
++
+         if (CDROM_CONFIG_FLAGS(drive)->is_changer) 
+               printk(" changer w/%d slots", nslots);
+         else  
+@@ -3105,14 +3172,11 @@ int ide_cdrom_setup (ide_drive_t *drive)
+       struct cdrom_device_info *cdi = &info->devinfo;
+       int nslots;
+-      /*
+-       * default to read-only always and fix latter at the bottom
+-       */
+-      set_disk_ro(drive->disk, 1);
+-      blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
+-
+       blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
+       blk_queue_dma_alignment(drive->queue, 3);
++      drive->queue->unplug_delay = (1 * HZ) / 1000;
++      if (!drive->queue->unplug_delay)
++              drive->queue->unplug_delay = 1;
+       drive->special.all      = 0;
+       drive->ready_stat       = 0;
+@@ -3215,8 +3279,11 @@ int ide_cdrom_setup (ide_drive_t *drive)
+       nslots = ide_cdrom_probe_capabilities (drive);
+-      if (CDROM_CONFIG_FLAGS(drive)->dvd_ram)
+-              set_disk_ro(drive->disk, 0);
++      /*
++       * set correct block size and read-only for non-ram media
++       */
++      set_disk_ro(drive->disk, !CDROM_CONFIG_FLAGS(drive)->ram);
++      blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
+ #if 0
+       drive->dsc_overlap = (HWIF(drive)->no_dsc) ? 0 : 1;
+@@ -3335,39 +3402,39 @@ static ide_driver_t ide_cdrom_driver = {
+       .complete_power_step    = ide_cdrom_complete_power_step,
+ };
+-static int idecd_open(struct inode * inode, struct file * file)
++static int idecd_open(struct block_device *bdev, struct file * file)
+ {
+-      ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++      ide_drive_t *drive = bdev->bd_disk->private_data;
+       struct cdrom_info *info = drive->driver_data;
+       int rc = -ENOMEM;
+       drive->usage++;
+       if (!info->buffer)
+-              info->buffer = (char *) kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL);
+-        if (!info->buffer || (rc = cdrom_open(&info->devinfo, inode, file)))
++              info->buffer = kmalloc(SECTOR_BUFFER_SIZE,
++                                      GFP_KERNEL|__GFP_REPEAT);
++        if (!info->buffer || (rc = cdrom_open(&info->devinfo, bdev, file)))
+               drive->usage--;
+       return rc;
+ }
+-static int idecd_release(struct inode * inode, struct file * file)
++static int idecd_release(struct gendisk *disk)
+ {
+-      ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++      ide_drive_t *drive = disk->private_data;
+       struct cdrom_info *info = drive->driver_data;
+-      cdrom_release (&info->devinfo, file);
++      cdrom_release(&info->devinfo);
+       drive->usage--;
+       return 0;
+ }
+-static int idecd_ioctl (struct inode *inode, struct file *file,
++static int idecd_ioctl (struct block_device *bdev, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+ {
+-      struct block_device *bdev = inode->i_bdev;
+       ide_drive_t *drive = bdev->bd_disk->private_data;
+       int err = generic_ide_ioctl(bdev, cmd, arg);
+       if (err == -EINVAL) {
+               struct cdrom_info *info = drive->driver_data;
+-              err = cdrom_ioctl(&info->devinfo, inode, cmd, arg);
++              err = cdrom_ioctl(&info->devinfo, bdev, cmd, arg);
+       }
+       return err;
+ }
+--- linux-2.6.0/drivers/ide/ide-cd.h   2003-12-17 21:20:02.000000000 -0800
++++ 25/drivers/ide/ide-cd.h    2003-12-28 23:22:35.000000000 -0800
+@@ -35,6 +35,12 @@
+ #define NO_DOOR_LOCKING 0
+ #endif
++/*
++ * typical timeout for packet command
++ */
++#define ATAPI_WAIT_PC         (60 * HZ)
++#define ATAPI_WAIT_WRITE_BUSY (10 * HZ)
++
+ /************************************************************************/
+ #define SECTOR_BITS           9
+@@ -75,6 +81,9 @@ struct ide_cd_config_flags {
+       __u8 dvd                : 1; /* Drive is a DVD-ROM */
+       __u8 dvd_r              : 1; /* Drive can write DVD-R */
+       __u8 dvd_ram            : 1; /* Drive can write DVD-RAM */
++      __u8 mrw                : 1; /* drive can read mrw */
++      __u8 mrw_w              : 1; /* drive can write mrw */
++      __u8 ram                : 1; /* generic WRITE (dvd-ram/mrw) */
+       __u8 test_write         : 1; /* Drive can fake writes */
+       __u8 supp_disc_present  : 1; /* Changer can report exact contents
+                                       of slots. */
+@@ -482,6 +491,8 @@ struct cdrom_info {
+         /* Per-device info needed by cdrom.c generic driver. */
+         struct cdrom_device_info devinfo;
++
++      unsigned long write_timeout;
+ };
+ /****************************************************************************
+--- linux-2.6.0/drivers/ide/ide-disk.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/ide/ide-disk.c  2003-12-28 23:21:17.000000000 -0800
+@@ -1734,9 +1734,9 @@ static ide_driver_t idedisk_driver = {
+       .complete_power_step    = idedisk_complete_power_step,
+ };
+-static int idedisk_open(struct inode *inode, struct file *filp)
++static int idedisk_open(struct block_device *bdev, struct file *filp)
+ {
+-      ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++      ide_drive_t *drive = bdev->bd_disk->private_data;
+       drive->usage++;
+       if (drive->removable && drive->usage == 1) {
+               ide_task_t args;
+@@ -1744,7 +1744,7 @@ static int idedisk_open(struct inode *in
+               memset(&args, 0, sizeof(ide_task_t));
+               args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK;
+               args.command_type = ide_cmd_type_parser(&args);
+-              check_disk_change(inode->i_bdev);
++              check_disk_change(bdev);
+               /*
+                * Ignore the return code from door_lock,
+                * since the open() has already succeeded,
+@@ -1782,9 +1782,9 @@ static int ide_cacheflush_p(ide_drive_t 
+       return 0;
+ }
+-static int idedisk_release(struct inode *inode, struct file *filp)
++static int idedisk_release(struct gendisk *disk)
+ {
+-      ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++      ide_drive_t *drive = disk->private_data;
+       if (drive->removable && drive->usage == 1) {
+               ide_task_t args;
+               memset(&args, 0, sizeof(ide_task_t));
+@@ -1798,10 +1798,9 @@ static int idedisk_release(struct inode 
+       return 0;
+ }
+-static int idedisk_ioctl(struct inode *inode, struct file *file,
++static int idedisk_ioctl(struct block_device *bdev, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+ {
+-      struct block_device *bdev = inode->i_bdev;
+       return generic_ide_ioctl(bdev, cmd, arg);
+ }
+--- linux-2.6.0/drivers/ide/ide-dma.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/ide/ide-dma.c   2003-12-28 23:22:33.000000000 -0800
+@@ -200,8 +200,8 @@ EXPORT_SYMBOL_GPL(ide_dma_intr);
+  *    kernel provide the necessary cache management so that we can
+  *    operate in a portable fashion
+  */
+- 
+-static int ide_build_sglist (ide_drive_t *drive, struct request *rq)
++
++int ide_build_sglist(ide_drive_t *drive, struct request *rq)
+ {
+       ide_hwif_t *hwif = HWIF(drive);
+       struct scatterlist *sg = hwif->sg_table;
+@@ -220,6 +220,8 @@ static int ide_build_sglist (ide_drive_t
+       return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
+ }
++EXPORT_SYMBOL_GPL(ide_build_sglist);
++
+ /**
+  *    ide_raw_build_sglist    -       map IDE scatter gather for DMA
+  *    @drive: the drive to build the DMA table for
+@@ -230,8 +232,8 @@ static int ide_build_sglist (ide_drive_t
+  *    of the  kernel provide the necessary cache management so that we can
+  *    operate in a portable fashion
+  */
+- 
+-static int ide_raw_build_sglist (ide_drive_t *drive, struct request *rq)
++
++int ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
+ {
+       ide_hwif_t *hwif = HWIF(drive);
+       struct scatterlist *sg = hwif->sg_table;
+@@ -270,6 +272,8 @@ static int ide_raw_build_sglist (ide_dri
+       return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
+ }
++EXPORT_SYMBOL_GPL(ide_raw_build_sglist);
++
+ /**
+  *    ide_build_dmatable      -       build IDE DMA table
+  *
+@@ -925,11 +929,13 @@ int ide_release_iomio_dma (ide_hwif_t *h
+  */
+ int ide_release_dma (ide_hwif_t *hwif)
+ {
++      if (hwif->mmio == 2)
++              return 1;
+       if (hwif->chipset == ide_etrax100)
+               return 1;
+       ide_release_dma_engine(hwif);
+-      if (hwif->mmio)
++      if (hwif->mmio == 1)
+               return ide_release_mmio_dma(hwif);
+       return ide_release_iomio_dma(hwif);
+ }
+@@ -986,6 +992,21 @@ fail:
+       return 1;
+ }
++int ide_mapped_mmio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
++{
++      printk(KERN_INFO "    %s: MMIO-DMA ", hwif->name);
++
++      hwif->dma_base = base;
++      if (hwif->cds->extra && hwif->channel == 0)
++              hwif->dma_extra = hwif->cds->extra;
++
++      if(hwif->mate)
++              hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
++      else
++              hwif->dma_master = base;
++      return 0;
++}
++
+ int ide_iomio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
+ {
+       printk(KERN_INFO "    %s: BM-DMA at 0x%04lx-0x%04lx",
+@@ -1020,7 +1041,9 @@ int ide_iomio_dma (ide_hwif_t *hwif, uns
+  */
+ int ide_dma_iobase (ide_hwif_t *hwif, unsigned long base, unsigned int ports)
+ {
+-      if (hwif->mmio)
++      if (hwif->mmio == 2)
++              return ide_mapped_mmio_dma(hwif, base,ports);
++      if (hwif->mmio == 1)
+               return ide_mmio_dma(hwif, base, ports);
+       return ide_iomio_dma(hwif, base, ports);
+ }
+--- linux-2.6.0/drivers/ide/ide-floppy.c       2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/ide/ide-floppy.c        2003-12-28 23:21:17.000000000 -0800
+@@ -1866,9 +1866,9 @@ static ide_driver_t idefloppy_driver = {
+       .drives                 = LIST_HEAD_INIT(idefloppy_driver.drives),
+ };
+-static int idefloppy_open(struct inode *inode, struct file *filp)
++static int idefloppy_open(struct block_device *bdev, struct file *filp)
+ {
+-      ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++      ide_drive_t *drive = bdev->bd_disk->private_data;
+       idefloppy_floppy_t *floppy = drive->driver_data;
+       idefloppy_pc_t pc;
+@@ -1908,7 +1908,7 @@ static int idefloppy_open(struct inode *
+                       idefloppy_create_prevent_cmd(&pc, 1);
+                       (void) idefloppy_queue_pc_tail(drive, &pc);
+               }
+-              check_disk_change(inode->i_bdev);
++              check_disk_change(bdev);
+       } else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags)) {
+               drive->usage--;
+               return -EBUSY;
+@@ -1916,9 +1916,9 @@ static int idefloppy_open(struct inode *
+       return 0;
+ }
+-static int idefloppy_release(struct inode *inode, struct file *filp)
++static int idefloppy_release(struct gendisk *disk)
+ {
+-      ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++      ide_drive_t *drive = disk->private_data;
+       idefloppy_pc_t pc;
+       
+       debug_log(KERN_INFO "Reached idefloppy_release\n");
+@@ -1938,10 +1938,9 @@ static int idefloppy_release(struct inod
+       return 0;
+ }
+-static int idefloppy_ioctl(struct inode *inode, struct file *file,
++static int idefloppy_ioctl(struct block_device *bdev, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+ {
+-      struct block_device *bdev = inode->i_bdev;
+       ide_drive_t *drive = bdev->bd_disk->private_data;
+       idefloppy_floppy_t *floppy = drive->driver_data;
+       int err = generic_ide_ioctl(bdev, cmd, arg);
+--- linux-2.6.0/drivers/ide/ide-io.c   2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/ide/ide-io.c    2003-12-28 23:26:29.000000000 -0800
+@@ -54,37 +54,6 @@
+ #include <asm/io.h>
+ #include <asm/bitops.h>
+-#if (DISK_RECOVERY_TIME > 0)
+-
+-#error So the User Has To Fix the Compilation And Stop Hacking Port 0x43. Does anyone ever use this anyway ??
+-
+-/*
+- * For really screwy hardware (hey, at least it *can* be used with Linux)
+- * we can enforce a minimum delay time between successive operations.
+- */
+-static unsigned long read_timer (ide_hwif_t *hwif)
+-{
+-      unsigned long t, flags;
+-      int i;
+-      
+-      /* FIXME this is completely unsafe! */
+-      local_irq_save(flags);
+-      t = jiffies * 11932;
+-      outb_p(0, 0x43);
+-      i = inb_p(0x40);
+-      i |= inb_p(0x40) << 8;
+-      local_irq_restore(flags);
+-      return (t - i);
+-}
+-#endif /* DISK_RECOVERY_TIME */
+-
+-static inline void set_recovery_timer (ide_hwif_t *hwif)
+-{
+-#if (DISK_RECOVERY_TIME > 0)
+-      hwif->last_time = read_timer(hwif);
+-#endif /* DISK_RECOVERY_TIME */
+-}
+-
+ /**
+  *    ide_end_request         -       complete an IDE I/O
+  *    @drive: IDE device for the I/O
+@@ -653,10 +622,6 @@ ide_startstop_t start_request (ide_drive
+       if (block == 0 && drive->remap_0_to_1 == 1)
+               block = 1;  /* redirect MBR access to EZ-Drive partn table */
+-#if (DISK_RECOVERY_TIME > 0)
+-      while ((read_timer() - HWIF(drive)->last_time) < DISK_RECOVERY_TIME);
+-#endif
+-
+       if (blk_pm_suspend_request(rq) &&
+           rq->pm->pm_step == ide_pm_state_start_suspend)
+               /* Mark drive blocked when starting the suspend sequence. */
+@@ -1116,7 +1081,6 @@ void ide_timer_expiry (unsigned long dat
+                                       startstop =
+                                       DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG));
+                       }
+-                      set_recovery_timer(hwif);
+                       drive->service_time = jiffies - drive->service_start;
+                       spin_lock_irq(&ide_lock);
+                       enable_irq(hwif->irq);
+@@ -1313,7 +1277,6 @@ irqreturn_t ide_intr (int irq, void *dev
+        * same irq as is currently being serviced here, and Linux
+        * won't allow another of the same (on any CPU) until we return.
+        */
+-      set_recovery_timer(HWIF(drive));
+       drive->service_time = jiffies - drive->service_start;
+       if (startstop == ide_stopped) {
+               if (hwgroup->handler == NULL) { /* paranoia */
+--- linux-2.6.0/drivers/ide/ide-tape.c 2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/ide/ide-tape.c  2003-12-28 23:26:27.000000000 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * linux/drivers/ide/ide-tape.c               Version 1.17b   Oct, 2002
++ * linux/drivers/ide/ide-tape.c               Version 1.19    Nov, 2003
+  *
+  * Copyright (C) 1995 - 1999 Gadi Oxman <gadio@netvision.net.il>
+  *
+@@ -422,7 +422,7 @@
+  *            sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
+  */
+-#define IDETAPE_VERSION "1.17b-ac1"
++#define IDETAPE_VERSION "1.19"
+ #include <linux/config.h>
+ #include <linux/module.h>
+@@ -450,9 +450,6 @@
+ #include <asm/unaligned.h>
+ #include <asm/bitops.h>
+-
+-#define NO_LONGER_REQUIRED    (1)
+-
+ /*
+  *    OnStream support
+  */
+@@ -652,9 +649,11 @@ typedef struct {
+ #define IDETAPE_PC_STACK              (10 + IDETAPE_MAX_PC_RETRIES)
+ /*
+- *    Some tape drives require a long irq timeout
++ * Some drives (for example, Seagate STT3401A Travan) require a very long
++ * timeout, because they don't return an interrupt or clear their busy bit
++ * until after the command completes (even retension commands).
+  */
+-#define IDETAPE_WAIT_CMD              (60*HZ)
++#define IDETAPE_WAIT_CMD              (900*HZ)
+ /*
+  *    The following parameter is used to select the point in the internal
+@@ -1032,6 +1031,10 @@ typedef struct {
+       /* the door is currently locked */
+       int door_locked;
++      /* the tape hardware is write protected */
++      char drv_write_prot;
++      /* the tape is write protected (hardware or opened as read-only) */
++      char write_prot;
+       /*
+        * OnStream flags
+@@ -1164,6 +1167,8 @@ typedef struct {
+ #define IDETAPE_DRQ_INTERRUPT         6       /* DRQ interrupt device */
+ #define IDETAPE_READ_ERROR            7
+ #define IDETAPE_PIPELINE_ACTIVE               8       /* pipeline active */
++/* 0 = no tape is loaded, so we don't rewind after ejecting */
++#define IDETAPE_MEDIUM_PRESENT                9
+ /*
+  *    Supported ATAPI tape drives packet commands
+@@ -1211,10 +1216,14 @@ typedef struct {
+  *    requests to the tail of our block device request queue and wait
+  *    for their completion.
+  */
+-#define idetape_request(rq) \
+-      ((rq)->flags & (REQ_IDETAPE_PC1 | REQ_IDETAPE_PC2 | \
+-                      REQ_IDETAPE_READ | REQ_IDETAPE_WRITE | \
+-                      REQ_IDETAPE_READ_BUFFER))
++
++enum {
++      REQ_IDETAPE_PC1         = (1 << 0), /* packet command (first stage) */
++      REQ_IDETAPE_PC2         = (1 << 1), /* packet command (second stage) */
++      REQ_IDETAPE_READ        = (1 << 2),
++      REQ_IDETAPE_WRITE       = (1 << 3),
++      REQ_IDETAPE_READ_BUFFER = (1 << 4),
++};
+ /*
+  *    Error codes which are returned in rq->errors to the higher part
+@@ -1665,6 +1674,20 @@ static void idetape_analyze_error (ide_d
+               idetape_update_buffers(pc);
+       }
++      /*
++       * If error was the result of a zero-length read or write command,
++       * with sense key=5, asc=0x22, ascq=0, let it slide.  Some drives
++       * (i.e. Seagate STT3401A Travan) don't support 0-length read/writes.
++       */
++      if ((pc->c[0] == IDETAPE_READ_CMD || pc->c[0] == IDETAPE_WRITE_CMD)
++          && pc->c[4] == 0 && pc->c[3] == 0 && pc->c[2] == 0) { /* length==0 */
++              if (result->sense_key == 5) {
++                      /* don't report an error, everything's ok */
++                      pc->error = 0;
++                      /* don't retry read/write */
++                      set_bit(PC_ABORT, &pc->flags);
++              }
++      }
+       if (pc->c[0] == IDETAPE_READ_CMD && result->filemark) {
+               pc->error = IDETAPE_ERROR_FILEMARK;
+               set_bit(PC_ABORT, &pc->flags);
+@@ -1805,10 +1828,15 @@ static void idetape_remove_stage_head (i
+       }
+ }
+-static void idetape_abort_pipeline (ide_drive_t *drive, idetape_stage_t *last_stage)
++/*
++ * This will free all the pipeline stages starting from new_last_stage->next
++ * to the end of the list, and point tape->last_stage to new_last_stage.
++ */
++static void idetape_abort_pipeline(ide_drive_t *drive,
++                                 idetape_stage_t *new_last_stage)
+ {
+       idetape_tape_t *tape = drive->driver_data;
+-      idetape_stage_t *stage = tape->next_stage;
++      idetape_stage_t *stage = new_last_stage->next;
+       idetape_stage_t *nstage;
+ #if IDETAPE_DEBUG_LOG
+@@ -1822,9 +1850,9 @@ static void idetape_abort_pipeline (ide_
+               --tape->nr_pending_stages;
+               stage = nstage;
+       }
+-      tape->last_stage = last_stage;
+-      if (last_stage)
+-              last_stage->next = NULL;
++      if (new_last_stage)
++              new_last_stage->next = NULL;
++      tape->last_stage = new_last_stage;
+       tape->next_stage = NULL;
+ }
+@@ -1868,7 +1896,7 @@ static int idetape_end_request(ide_drive
+               tape->active_stage = NULL;
+               tape->active_data_request = NULL;
+               tape->nr_pending_stages--;
+-              if (rq->flags & REQ_IDETAPE_WRITE) {
++              if (rq->cmd[0] & REQ_IDETAPE_WRITE) {
+ #if ONSTREAM_DEBUG
+                       if (tape->debug_level >= 2) {
+                               if (tape->onstream) {
+@@ -1914,7 +1942,7 @@ static int idetape_end_request(ide_drive
+                                       }
+                               }
+                       }
+-              } else if (rq->flags & REQ_IDETAPE_READ) {
++              } else if (rq->cmd[0] & REQ_IDETAPE_READ) {
+                       if (error == IDETAPE_ERROR_EOD) {
+                               set_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
+                               idetape_abort_pipeline(drive, active_stage);
+@@ -1972,6 +2000,13 @@ static void idetape_create_request_sense
+       pc->callback = &idetape_request_sense_callback;
+ }
++static void idetape_init_rq(struct request *rq, u8 cmd)
++{
++      memset(rq, 0, sizeof(*rq));
++      rq->flags = REQ_SPECIAL;
++      rq->cmd[0] = cmd;
++}
++
+ /*
+  *    idetape_queue_pc_head generates a new packet command request in front
+  *    of the request queue, before the current request, so that it will be
+@@ -1993,8 +2028,7 @@ static void idetape_create_request_sense
+  */
+ static void idetape_queue_pc_head (ide_drive_t *drive, idetape_pc_t *pc,struct request *rq)
+ {
+-      memset(rq, 0, sizeof(*rq));
+-      rq->flags = REQ_IDETAPE_PC1;
++      idetape_init_rq(rq, REQ_IDETAPE_PC1);
+       rq->buffer = (char *) pc;
+       (void) ide_do_drive_cmd(drive, rq, ide_preempt);
+ }
+@@ -2430,7 +2464,14 @@ static void idetape_create_mode_sense_cm
+       if (page_code != IDETAPE_BLOCK_DESCRIPTOR)
+               pc->c[1] = 8;   /* DBD = 1 - Don't return block descriptors */
+       pc->c[2] = page_code;
+-      pc->c[3] = 255;         /* Don't limit the returned information */
++      /*
++       * Changed pc->c[3] to 0 (255 will at best return unused info).
++       *
++       * For SCSI this byte is defined as subpage instead of high byte
++       * of length and some IDE drives seem to interpret it this way
++       * and return an error when 255 is used.
++       */
++      pc->c[3] = 0;
+       pc->c[4] = 255;         /* (We will just discard data in that case) */
+       if (page_code == IDETAPE_BLOCK_DESCRIPTOR)
+               pc->request_transfer = 12;
+@@ -2544,8 +2585,9 @@ static ide_startstop_t idetape_media_acc
+       if (status.b.dsc) {
+               if (status.b.check) {
+                       /* Error detected */
+-                      printk(KERN_ERR "ide-tape: %s: I/O error, ",tape->name);
+-
++                      if (pc->c[0] != IDETAPE_TEST_UNIT_READY_CMD)
++                              printk(KERN_ERR "ide-tape: %s: I/O error, ",
++                                              tape->name);
+                       /* Retry operation */
+                       return idetape_retry_pc(drive);
+               }
+@@ -2697,7 +2739,7 @@ static ide_startstop_t idetape_do_reques
+       if (tape->debug_level >= 5)
+               printk(KERN_INFO "ide-tape: rq_status: %d, "
+                       "dev: %s, cmd: %ld, errors: %d\n", rq->rq_status,
+-                       rq->rq_disk->disk_name, rq->flags, rq->errors);
++                       rq->rq_disk->disk_name, rq->cmd[0], rq->errors);
+ #endif
+       if (tape->debug_level >= 2)
+               printk(KERN_INFO "ide-tape: sector: %ld, "
+@@ -2705,11 +2747,11 @@ static ide_startstop_t idetape_do_reques
+                       rq->sector, rq->nr_sectors, rq->current_nr_sectors);
+ #endif /* IDETAPE_DEBUG_LOG */
+-      if (!idetape_request(rq)) {
++      if ((rq->flags & REQ_SPECIAL) == 0) {
+               /*
+                * We do not support buffer cache originated requests.
+                */
+-              printk(KERN_NOTICE "ide-tape: %s: Unsupported command in "
++              printk(KERN_NOTICE "ide-tape: %s: Unsupported request in "
+                       "request queue (%ld)\n", drive->name, rq->flags);
+               ide_end_request(drive, 0, 0);
+               return ide_stopped;
+@@ -2746,7 +2788,7 @@ static ide_startstop_t idetape_do_reques
+        */
+       if (tape->onstream)
+               status.b.dsc = 1;
+-      if (!drive->dsc_overlap && !(rq->flags & REQ_IDETAPE_PC2))
++      if (!drive->dsc_overlap && !(rq->cmd[0] & REQ_IDETAPE_PC2))
+               set_bit(IDETAPE_IGNORE_DSC, &tape->flags);
+       /*
+@@ -2760,7 +2802,7 @@ static ide_startstop_t idetape_do_reques
+       if (tape->tape_still_time > 100 && tape->tape_still_time < 200)
+               tape->measure_insert_time = 1;
+       if (tape->req_buffer_fill &&
+-          (rq->flags & (REQ_IDETAPE_WRITE | REQ_IDETAPE_READ))) {
++          (rq->cmd[0] & (REQ_IDETAPE_WRITE | REQ_IDETAPE_READ))) {
+               tape->req_buffer_fill = 0;
+               tape->writes_since_buffer_fill = 0;
+               tape->reads_since_buffer_fill = 0;
+@@ -2774,12 +2816,12 @@ static ide_startstop_t idetape_do_reques
+               tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time);
+       calculate_speeds(drive);
+       if (tape->onstream && tape->max_frames &&
+-          (((rq->flags & REQ_IDETAPE_WRITE) &&
++          (((rq->cmd[0] & REQ_IDETAPE_WRITE) &&
+               ( tape->cur_frames == tape->max_frames ||
+                 ( tape->speed_control && tape->cur_frames > 5 &&
+                        (tape->insert_speed > tape->max_insert_speed ||
+                         (0 /* tape->cur_frames > 30 && tape->tape_still_time > 200 */) ) ) ) ) ||
+-           ((rq->flags & REQ_IDETAPE_READ) &&
++           ((rq->cmd[0] & REQ_IDETAPE_READ) &&
+             ( tape->cur_frames == 0 ||
+               ( tape->speed_control && (tape->cur_frames < tape->max_frames - 5) &&
+                       tape->insert_speed > tape->max_insert_speed ) ) && rq->nr_sectors) ) ) {
+@@ -2787,7 +2829,7 @@ static ide_startstop_t idetape_do_reques
+               if (tape->debug_level >= 4)
+                       printk(KERN_INFO "ide-tape: postponing request, "
+                                       "cmd %ld, cur %d, max %d\n",
+-                              rq->flags, tape->cur_frames, tape->max_frames);
++                              rq->cmd[0], tape->cur_frames, tape->max_frames);
+ #endif
+               if (tape->postpone_cnt++ < 500) {
+                       status.b.dsc = 0;
+@@ -2808,7 +2850,7 @@ static ide_startstop_t idetape_do_reques
+               } else if ((signed long) (jiffies - tape->dsc_timeout) > 0) {
+                       printk(KERN_ERR "ide-tape: %s: DSC timeout\n",
+                               tape->name);
+-                      if (rq->flags & REQ_IDETAPE_PC2) {
++                      if (rq->cmd[0] & REQ_IDETAPE_PC2) {
+                               idetape_media_access_finished(drive);
+                               return ide_stopped;
+                       } else {
+@@ -2819,7 +2861,7 @@ static ide_startstop_t idetape_do_reques
+               idetape_postpone_request(drive);
+               return ide_stopped;
+       }
+-      if (rq->flags & REQ_IDETAPE_READ) {
++      if (rq->cmd[0] & REQ_IDETAPE_READ) {
+               tape->buffer_head++;
+ #if USE_IOTRACE
+               IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor);
+@@ -2836,7 +2878,7 @@ static ide_startstop_t idetape_do_reques
+               idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
+               goto out;
+       }
+-      if (rq->flags & REQ_IDETAPE_WRITE) {
++      if (rq->cmd[0] & REQ_IDETAPE_WRITE) {
+               tape->buffer_head++;
+ #if USE_IOTRACE
+               IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor);
+@@ -2854,19 +2896,19 @@ static ide_startstop_t idetape_do_reques
+               idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
+               goto out;
+       }
+-      if (rq->flags & REQ_IDETAPE_READ_BUFFER) {
++      if (rq->cmd[0] & REQ_IDETAPE_READ_BUFFER) {
+               tape->postpone_cnt = 0;
+               pc = idetape_next_pc_storage(drive);
+               idetape_create_read_buffer_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
+               goto out;
+       }
+-      if (rq->flags & REQ_IDETAPE_PC1) {
++      if (rq->cmd[0] & REQ_IDETAPE_PC1) {
+               pc = (idetape_pc_t *) rq->buffer;
+-              rq->flags &= ~(REQ_IDETAPE_PC1);
+-              rq->flags |= REQ_IDETAPE_PC2;
++              rq->cmd[0] &= ~(REQ_IDETAPE_PC1);
++              rq->cmd[0] |= REQ_IDETAPE_PC2;
+               goto out;
+       }
+-      if (rq->flags & REQ_IDETAPE_PC2) {
++      if (rq->cmd[0] & REQ_IDETAPE_PC2) {
+               idetape_media_access_finished(drive);
+               return ide_stopped;
+       }
+@@ -3163,7 +3205,7 @@ static void idetape_wait_for_request (id
+       idetape_tape_t *tape = drive->driver_data;
+ #if IDETAPE_DEBUG_BUGS
+-      if (rq == NULL || !idetape_request(rq)) {
++      if (rq == NULL || (rq->flags & REQ_SPECIAL) == 0) {
+               printk (KERN_ERR "ide-tape: bug: Trying to sleep on non-valid request\n");
+               return;
+       }
+@@ -3269,8 +3311,7 @@ static int __idetape_queue_pc_tail (ide_
+ {
+       struct request rq;
+-      memset(&rq, 0, sizeof(rq));
+-      rq.flags = REQ_IDETAPE_PC1;
++      idetape_init_rq(&rq, REQ_IDETAPE_PC1);
+       rq.buffer = (char *) pc;
+       return ide_do_drive_cmd(drive, &rq, ide_wait);
+ }
+@@ -3295,25 +3336,28 @@ static int idetape_wait_ready(ide_drive_
+ {
+       idetape_tape_t *tape = drive->driver_data;
+       idetape_pc_t pc;
++      int load_attempted = 0;
+       /*
+        * Wait for the tape to become ready
+        */
++      set_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags);
+       timeout += jiffies;
+       while (time_before(jiffies, timeout)) {
+               idetape_create_test_unit_ready_cmd(&pc);
+               if (!__idetape_queue_pc_tail(drive, &pc))
+                       return 0;
+-              if (tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2) {
++              if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2)
++                  || (tape->asc == 0x3A)) {   /* no media */
++                      if (load_attempted)
++                              return -ENOMEDIUM;
+                       idetape_create_load_unload_cmd(drive, &pc, IDETAPE_LU_LOAD_MASK);
+                       __idetape_queue_pc_tail(drive, &pc);
+-                      idetape_create_test_unit_ready_cmd(&pc);
+-                      if (!__idetape_queue_pc_tail(drive, &pc))
+-                              return 0;
+-              }
+-              if (!(tape->sense_key == 2 && tape->asc == 4 &&
+-                    (tape->ascq == 1 || tape->ascq == 8)))
+-                      break;
++                      load_attempted = 1;
++              /* not about to be ready */
++              } else if (!(tape->sense_key == 2 && tape->asc == 4 &&
++                           (tape->ascq == 1 || tape->ascq == 8)))
++                      return -EIO;
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(HZ / 10);
+       }
+@@ -3369,25 +3413,10 @@ static int idetape_read_position (ide_dr
+               printk(KERN_INFO "ide-tape: Reached idetape_read_position\n");
+ #endif /* IDETAPE_DEBUG_LOG */
+-#ifdef NO_LONGER_REQUIRED
+-      idetape_flush_tape_buffers(drive);
+-#endif
+       idetape_create_read_position_cmd(&pc);
+       if (idetape_queue_pc_tail(drive, &pc))
+               return -1;
+       position = tape->first_frame_position;
+-#ifdef NO_LONGER_REQUIRED
+-      if (tape->onstream) {
+-              if ((position != tape->last_frame_position - tape->blocks_in_buffer) &&
+-                  (position != tape->last_frame_position + tape->blocks_in_buffer)) {
+-                      if (tape->blocks_in_buffer == 0) {
+-                              printk("ide-tape: %s: correcting read position %d, %d, %d\n", tape->name, position, tape->last_frame_position, tape->blocks_in_buffer);
+-                              position = tape->last_frame_position;
+-                              tape->first_frame_position = position;
+-                      }
+-              }
+-      }
+-#endif
+       return position;
+ }
+@@ -3436,6 +3465,8 @@ static int __idetape_discard_read_pipeli
+       if (tape->chrdev_direction != idetape_direction_read)
+               return 0;
++
++      /* Remove merge stage. */
+       cnt = tape->merge_stage_size / tape->tape_block_size;
+       if (test_and_clear_bit(IDETAPE_FILEMARK, &tape->flags))
+               ++cnt;          /* Filemarks count as 1 sector */
+@@ -3444,9 +3475,12 @@ static int __idetape_discard_read_pipeli
+               __idetape_kfree_stage(tape->merge_stage);
+               tape->merge_stage = NULL;
+       }
++
++      /* Clear pipeline flags. */
+       clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
+       tape->chrdev_direction = idetape_direction_none;
+-      
++
++      /* Remove pipeline stages. */
+       if (tape->first_stage == NULL)
+               return 0;
+@@ -3546,8 +3580,7 @@ static int idetape_queue_rw_tail(ide_dri
+       }
+ #endif /* IDETAPE_DEBUG_BUGS */       
+-      memset(&rq, 0, sizeof(rq));
+-      rq.flags = cmd;
++      idetape_init_rq(&rq, cmd);
+       rq.special = (void *)bh;
+       rq.sector = tape->first_frame_position;
+       rq.nr_sectors = rq.current_nr_sectors = blocks;
+@@ -3596,8 +3629,7 @@ static void idetape_onstream_read_back_b
+                       printk(KERN_INFO "ide-tape: %s: read back logical block %d, data %x %x %x %x\n", tape->name, logical_blk_num, *p++, *p++, *p++, *p++);
+ #endif
+               rq = &stage->rq;
+-              memset(rq, 0, sizeof(*rq));
+-              rq->flags = REQ_IDETAPE_WRITE;
++              idetape_init_rq(rq, REQ_IDETAPE_WRITE);
+               rq->sector = tape->first_frame_position;
+               rq->nr_sectors = rq->current_nr_sectors = tape->capabilities.ctl;
+               idetape_init_stage(drive, stage, OS_FRAME_TYPE_DATA, logical_blk_num++);
+@@ -3871,8 +3903,7 @@ static int idetape_add_chrdev_write_requ
+               }
+       }
+       rq = &new_stage->rq;
+-      memset(rq, 0, sizeof(*rq));
+-      rq->flags = REQ_IDETAPE_WRITE;
++      idetape_init_rq(rq, REQ_IDETAPE_WRITE);
+       /* Doesn't actually matter - We always assume sequential access */
+       rq->sector = tape->first_frame_position;
+       rq->nr_sectors = rq->current_nr_sectors = blocks;
+@@ -4059,19 +4090,22 @@ static int idetape_initiate_read (ide_dr
+                *      Issue a read 0 command to ensure that DSC handshake
+                *      is switched from completion mode to buffer available
+                *      mode.
++               *      No point in issuing this if DSC overlap isn't supported,
++               *      some drives (Seagate STT3401A) will return an error.
+                */
+-              bytes_read = idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, 0, tape->merge_stage->bh);
+-              if (bytes_read < 0) {
+-                      __idetape_kfree_stage(tape->merge_stage);
+-                      tape->merge_stage = NULL;
+-                      tape->chrdev_direction = idetape_direction_none;
+-                      return bytes_read;
++              if (drive->dsc_overlap) {
++                      bytes_read = idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, 0, tape->merge_stage->bh);
++                      if (bytes_read < 0) {
++                              __idetape_kfree_stage(tape->merge_stage);
++                              tape->merge_stage = NULL;
++                              tape->chrdev_direction = idetape_direction_none;
++                              return bytes_read;
++                      }
+               }
+       }
+       if (tape->restart_speed_control_req)
+               idetape_restart_speed_control(drive);
+-      memset(&rq, 0, sizeof(rq));
+-      rq.flags = REQ_IDETAPE_READ;
++      idetape_init_rq(&rq, REQ_IDETAPE_READ);
+       rq.sector = tape->first_frame_position;
+       rq.nr_sectors = rq.current_nr_sectors = blocks;
+       if (!test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags) &&
+@@ -4898,6 +4932,10 @@ static ssize_t idetape_chrdev_write (str
+               return -ENXIO;
+       }
++      /* The drive is write protected. */
++      if (tape->write_prot)
++              return -EACCES;
++
+ #if IDETAPE_DEBUG_LOG
+       if (tape->debug_level >= 3)
+               printk(KERN_INFO "ide-tape: Reached idetape_chrdev_write, "
+@@ -4979,13 +5017,17 @@ static ssize_t idetape_chrdev_write (str
+                *      Issue a write 0 command to ensure that DSC handshake
+                *      is switched from completion mode to buffer available
+                *      mode.
++               *      No point in issuing this if DSC overlap isn't supported,
++               *      some drives (Seagate STT3401A) will return an error.
+                */
+-              retval = idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 0, tape->merge_stage->bh);
+-              if (retval < 0) {
+-                      __idetape_kfree_stage(tape->merge_stage);
+-                      tape->merge_stage = NULL;
+-                      tape->chrdev_direction = idetape_direction_none;
+-                      return retval;
++              if (drive->dsc_overlap) {
++                      retval = idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 0, tape->merge_stage->bh);
++                      if (retval < 0) {
++                              __idetape_kfree_stage(tape->merge_stage);
++                              tape->merge_stage = NULL;
++                              tape->chrdev_direction = idetape_direction_none;
++                              return retval;
++                      }
+               }
+ #if ONSTREAM_DEBUG
+               if (tape->debug_level >= 2)
+@@ -5141,7 +5183,7 @@ ok:
+  *    Note:
+  *
+  *            MTBSF and MTBSFM are not supported when the tape doesn't
+- *            supports spacing over filemarks in the reverse direction.
++ *            support spacing over filemarks in the reverse direction.
+  *            In this case, MTFSFM is also usually not supported (it is
+  *            supported in the rare case in which we crossed the filemark
+  *            during our read-ahead pipelined operation mode).
+@@ -5211,6 +5253,8 @@ static int idetape_mtioctop (ide_drive_t
+       }
+       switch (mt_op) {
+               case MTWEOF:
++                      if (tape->write_prot)
++                              return -EACCES;
+                       idetape_discard_read_pipeline(drive, 1);
+                       for (i = 0; i < mt_count; i++) {
+                               retval = idetape_write_filemark(drive);
+@@ -5231,9 +5275,21 @@ static int idetape_mtioctop (ide_drive_t
+                       return (idetape_queue_pc_tail(drive, &pc));
+               case MTUNLOAD:
+               case MTOFFL:
++                      /*
++                       * If door is locked, attempt to unlock before
++                       * attempting to eject.
++                       */
++                      if (tape->door_locked) {
++                              if (idetape_create_prevent_cmd(drive, &pc, 0))
++                                      if (!idetape_queue_pc_tail(drive, &pc))
++                                              tape->door_locked = DOOR_UNLOCKED;
++                      }
+                       idetape_discard_read_pipeline(drive, 0);
+                       idetape_create_load_unload_cmd(drive, &pc,!IDETAPE_LU_LOAD_MASK);
+-                      return (idetape_queue_pc_tail(drive, &pc));
++                      retval = idetape_queue_pc_tail(drive, &pc);
++                      if (!retval)
++                              clear_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags);
++                      return retval;
+               case MTNOP:
+                       idetape_discard_read_pipeline(drive, 0);
+                       return (idetape_flush_tape_buffers(drive));
+@@ -5409,6 +5465,8 @@ static int idetape_chrdev_ioctl (struct 
+                                       mtget.mt_gstat |= GMT_EOD(0xffffffff);
+                               if (position <= OS_DATA_STARTFRAME1)
+                                       mtget.mt_gstat |= GMT_BOT(0xffffffff);
++                      } else if (tape->drv_write_prot) {
++                              mtget.mt_gstat |= GMT_WR_PROT(0xffffffff);
+                       }
+                       if (copy_to_user((char *) arg,(char *) &mtget, sizeof(struct mtget)))
+                               return -EFAULT;
+@@ -5530,6 +5588,8 @@ ok:
+       return 1;
+ }
++static void idetape_get_blocksize_from_block_descriptor(ide_drive_t *drive);
++
+ /*
+  *    Our character device open function.
+  */
+@@ -5539,7 +5599,8 @@ static int idetape_chrdev_open (struct i
+       ide_drive_t *drive;
+       idetape_tape_t *tape;
+       idetape_pc_t pc;
+-                      
++      int retval;
++
+ #if IDETAPE_DEBUG_LOG
+       printk(KERN_INFO "ide-tape: Reached idetape_chrdev_open\n");
+ #endif /* IDETAPE_DEBUG_LOG */
+@@ -5552,11 +5613,7 @@ static int idetape_chrdev_open (struct i
+       if (test_and_set_bit(IDETAPE_BUSY, &tape->flags))
+               return -EBUSY;
+-      if (!tape->onstream) {  
+-              idetape_read_position(drive);
+-              if (!test_bit(IDETAPE_ADDRESS_VALID, &tape->flags))
+-                      (void) idetape_rewind_tape(drive);
+-      } else {
++      if (tape->onstream) {
+               if (minor & 64) {
+                       tape->tape_block_size = tape->stage_size = 32768 + 512;
+                       tape->raw = 1;
+@@ -5566,16 +5623,42 @@ static int idetape_chrdev_open (struct i
+               }
+                 idetape_onstream_mode_sense_tape_parameter_page(drive, tape->debug_level);
+       }
+-      if (idetape_wait_ready(drive, 60 * HZ)) {
++      retval = idetape_wait_ready(drive, 60 * HZ);
++      if (retval) {
+               clear_bit(IDETAPE_BUSY, &tape->flags);
+               printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name);
+-              return -EBUSY;
++              return retval;
+       }
+-      if (tape->onstream)
+-              idetape_read_position(drive);
++
++      idetape_read_position(drive);
++      if (!test_bit(IDETAPE_ADDRESS_VALID, &tape->flags))
++              (void)idetape_rewind_tape(drive);
++
+       if (tape->chrdev_direction != idetape_direction_read)
+               clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
++      /* Read block size and write protect status from drive. */
++      idetape_get_blocksize_from_block_descriptor(drive);
++
++      /* Set write protect flag if device is opened as read-only. */
++      if ((filp->f_flags & O_ACCMODE) == O_RDONLY)
++              tape->write_prot = 1;
++      else
++              tape->write_prot = tape->drv_write_prot;
++
++      /* Make sure drive isn't write protected if user wants to write. */
++      if (tape->write_prot) {
++              if ((filp->f_flags & O_ACCMODE) == O_WRONLY ||
++                  (filp->f_flags & O_ACCMODE) == O_RDWR) {
++                      clear_bit(IDETAPE_BUSY, &tape->flags);
++                      return -EROFS;
++              }
++      }
++
++      /*
++       * Lock the tape drive door so user can't eject.
++       * Analyze headers for OnStream drives.
++       */
+       if (tape->chrdev_direction == idetape_direction_none) {
+               if (idetape_create_prevent_cmd(drive, &pc, 1)) {
+                       if (!idetape_queue_pc_tail(drive, &pc)) {
+@@ -5638,7 +5721,7 @@ static int idetape_chrdev_release (struc
+               __idetape_kfree_stage(tape->cache_stage);
+               tape->cache_stage = NULL;
+       }
+-      if (minor < 128)
++      if (minor < 128 && test_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags))
+               (void) idetape_rewind_tape(drive);
+       if (tape->chrdev_direction == idetape_direction_none) {
+               if (tape->door_locked == DOOR_LOCKED) {
+@@ -6059,6 +6142,8 @@ static void idetape_get_blocksize_from_b
+       header = (idetape_mode_parameter_header_t *) pc.buffer;
+       block_descrp = (idetape_parameter_block_descriptor_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t));
+       tape->tape_block_size =( block_descrp->length[0]<<16) + (block_descrp->length[1]<<8) + block_descrp->length[2];
++      tape->drv_write_prot = (header->dsp & 0x80) >> 7;
++
+ #if IDETAPE_DEBUG_INFO
+       printk(KERN_INFO "ide-tape: Adjusted block size - %d\n", tape->tape_block_size);
+ #endif /* IDETAPE_DEBUG_INFO */
+@@ -6139,6 +6224,9 @@ static void idetape_setup (ide_drive_t *
+               }
+       }
+ #endif /* CONFIG_BLK_DEV_IDEPCI */
++      /* Seagate Travan drives do not support DSC overlap. */
++      if (strstr(drive->id->model, "Seagate STT3401"))
++              drive->dsc_overlap = 0;
+       tape->drive = drive;
+       tape->minor = minor;
+       tape->name[0] = 'h';
+@@ -6306,24 +6394,23 @@ static struct file_operations idetape_fo
+       .release        = idetape_chrdev_release,
+ };
+-static int idetape_open(struct inode *inode, struct file *filp)
++static int idetape_open(struct block_device *bdev, struct file *filp)
+ {
+-      ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++      ide_drive_t *drive = bdev->bd_disk->private_data;
+       drive->usage++;
+       return 0;
+ }
+-static int idetape_release(struct inode *inode, struct file *filp)
++static int idetape_release(struct gendisk *disk)
+ {
+-      ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++      ide_drive_t *drive = disk->private_data;
+       drive->usage--;
+       return 0;
+ }
+-static int idetape_ioctl(struct inode *inode, struct file *file,
++static int idetape_ioctl(struct block_device *bdev, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+ {
+-      struct block_device *bdev = inode->i_bdev;
+       ide_drive_t *drive = bdev->bd_disk->private_data;
+       int err = generic_ide_ioctl(bdev, cmd, arg);
+       if (err == -EINVAL)
+--- linux-2.6.0/drivers/ide/Kconfig    2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/ide/Kconfig     2003-12-28 23:21:46.000000000 -0800
+@@ -745,6 +745,14 @@ config BLK_DEV_SVWKS
+         This driver adds PIO/(U)DMA support for the ServerWorks OSB4/CSB5
+         chipsets.
++config BLK_DEV_SGIIOC4
++      tristate "Silicon Graphics IOC4 chipset support"
++      depends on IA64_SGI_SN2
++      help
++        This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4
++        chipset, which has one channel and can support two devices.
++        Please say Y here if you have an Altix System from SGI.
++
+ config BLK_DEV_SIIMAGE
+       tristate "Silicon Image chipset support"
+       help
+--- linux-2.6.0/drivers/ide/legacy/hd98.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/ide/legacy/hd98.c       2003-12-28 23:21:12.000000000 -0800
+@@ -652,10 +652,10 @@ static void do_hd_request (request_queue
+       enable_irq(HD_IRQ);
+ }
+-static int hd_ioctl(struct inode * inode, struct file * file,
++static int hd_ioctl(struct block_device *bdev, struct file *file,
+       unsigned int cmd, unsigned long arg)
+ {
+-      struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data;
++      struct hd_i_struct *disk = bdev->bd_disk->private_data;
+       struct hd_geometry *loc = (struct hd_geometry *) arg;
+       struct hd_geometry g; 
+@@ -666,7 +666,7 @@ static int hd_ioctl(struct inode * inode
+       g.heads = disk->head;
+       g.sectors = disk->sect;
+       g.cylinders = disk->cyl;
+-      g.start = get_start_sect(inode->i_bdev);
++      g.start = get_start_sect(bdev);
+       return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
+ }
+--- linux-2.6.0/drivers/ide/legacy/hd.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/ide/legacy/hd.c 2003-12-28 23:21:12.000000000 -0800
+@@ -656,10 +656,10 @@ static void do_hd_request (request_queue
+       enable_irq(HD_IRQ);
+ }
+-static int hd_ioctl(struct inode * inode, struct file * file,
++static int hd_ioctl(struct block_device *bdev, struct file *file,
+       unsigned int cmd, unsigned long arg)
+ {
+-      struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data;
++      struct hd_i_struct *disk = bdev->bd_disk->private_data;
+       struct hd_geometry *loc = (struct hd_geometry *) arg;
+       struct hd_geometry g; 
+@@ -670,7 +670,7 @@ static int hd_ioctl(struct inode * inode
+       g.heads = disk->head;
+       g.sectors = disk->sect;
+       g.cylinders = disk->cyl;
+-      g.start = get_start_sect(inode->i_bdev);
++      g.start = get_start_sect(bdev);
+       return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
+ }
+--- linux-2.6.0/drivers/ide/legacy/ide-cs.c    2003-08-22 19:23:40.000000000 -0700
++++ 25/drivers/ide/legacy/ide-cs.c     2003-12-28 23:22:53.000000000 -0800
+@@ -152,7 +152,7 @@ static dev_link_t *ide_attach(void)
+     client_reg.event_handler = &ide_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != CS_SUCCESS) {
+       cs_error(link->handle, RegisterClient, ret);
+       ide_detach(link);
+@@ -188,7 +188,7 @@ static void ide_detach(dev_link_t *link)
+       ide_release(link);
+     
+     if (link->handle) {
+-      ret = CardServices(DeregisterClient, link->handle);
++      ret = pcmcia_deregister_client(link->handle);
+       if (ret != CS_SUCCESS)
+           cs_error(link->handle, DeregisterClient, ret);
+     }
+@@ -207,11 +207,8 @@ static void ide_detach(dev_link_t *link)
+ ======================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq)
+ {
+@@ -241,16 +238,16 @@ void ide_config(dev_link_t *link)
+     tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
+     tuple.Attributes = 0;
+     tuple.DesiredTuple = CISTPL_CONFIG;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     link->conf.Present = parse.config.rmask[0];
+     tuple.DesiredTuple = CISTPL_MANFID;
+-    if (!CardServices(GetFirstTuple, handle, &tuple) &&
+-      !CardServices(GetTupleData, handle, &tuple) &&
+-      !CardServices(ParseTuple, handle, &tuple, &parse))
++    if (!pcmcia_get_first_tuple(handle, &tuple) &&
++      !pcmcia_get_tuple_data(handle, &tuple) &&
++      !pcmcia_parse_tuple(handle, &tuple, &parse))
+       is_kme = ((parse.manfid.manf == MANFID_KME) &&
+                 ((parse.manfid.card == PRODID_KME_KXLC005_A) ||
+                  (parse.manfid.card == PRODID_KME_KXLC005_B)));
+@@ -259,16 +256,16 @@ void ide_config(dev_link_t *link)
+     link->state |= DEV_CONFIG;
+     /* Not sure if this is right... look up the current Vcc */
+-    CS_CHECK(GetConfigurationInfo, handle, &conf);
++    CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
+     link->conf.Vcc = conf.Vcc;
+     
+     pass = io_base = ctl_base = 0;
+     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+     tuple.Attributes = 0;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     while (1) {
+-      CFG_CHECK(GetTupleData, handle, &tuple);
+-      CFG_CHECK(ParseTuple, handle, &tuple, &parse);
++      if (pcmcia_get_tuple_data(handle, &tuple) != 0) goto next_entry;
++      if (pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry;
+       /* Check for matching Vcc, unless we're desperate */
+       if (!pass) {
+@@ -299,13 +296,15 @@ void ide_config(dev_link_t *link)
+               link->io.NumPorts1 = 8;
+               link->io.BasePort2 = io->win[1].base;
+               link->io.NumPorts2 = (is_kme) ? 2 : 1;
+-              CFG_CHECK(RequestIO, link->handle, &link->io);
++              if (pcmcia_request_io(link->handle, &link->io) != 0)
++                      goto next_entry;
+               io_base = link->io.BasePort1;
+               ctl_base = link->io.BasePort2;
+           } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
+               link->io.NumPorts1 = io->win[0].len;
+               link->io.NumPorts2 = 0;
+-              CFG_CHECK(RequestIO, link->handle, &link->io);
++              if (pcmcia_request_io(link->handle, &link->io) != 0)
++                      goto next_entry;
+               io_base = link->io.BasePort1;
+               ctl_base = link->io.BasePort1+0x0e;
+           } else goto next_entry;
+@@ -316,16 +315,16 @@ void ide_config(dev_link_t *link)
+     next_entry:
+       if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
+       if (pass) {
+-          CS_CHECK(GetNextTuple, handle, &tuple);
+-      } else if (CardServices(GetNextTuple, handle, &tuple) != 0) {
+-          CS_CHECK(GetFirstTuple, handle, &tuple);
++          CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
++      } else if (pcmcia_get_next_tuple(handle, &tuple) != 0) {
++          CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+           memset(&dflt, 0, sizeof(dflt));
+           pass++;
+       }
+     }
+     
+-    CS_CHECK(RequestIRQ, handle, &link->irq);
+-    CS_CHECK(RequestConfiguration, handle, &link->conf);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
+     /* deal with brain dead IDE resource management */
+     release_region(link->io.BasePort1, link->io.NumPorts1);
+@@ -413,9 +412,9 @@ void ide_release(dev_link_t *link)
+     info->ndev = 0;
+     link->dev = NULL;
+     
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     
+     link->state &= ~DEV_CONFIG;
+@@ -452,14 +451,14 @@ int ide_event(event_t event, int priorit
+       /* Fall through... */
+     case CS_EVENT_RESET_PHYSICAL:
+       if (link->state & DEV_CONFIG)
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       break;
+     case CS_EVENT_PM_RESUME:
+       link->state &= ~DEV_SUSPEND;
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (DEV_OK(link))
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+       break;
+     }
+     return 0;
+--- linux-2.6.0/drivers/ide/pci/cmd640.c       2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ide/pci/cmd640.c        2003-12-28 23:26:28.000000000 -0800
+@@ -213,13 +213,13 @@ static unsigned int cmd640_chip_version;
+ static void put_cmd640_reg_pci1 (u16 reg, u8 val)
+ {
+-      outb_p((reg & 0xfc) | cmd640_key, 0xcf8);
++      outl_p((reg & 0xfc) | cmd640_key, 0xcf8);
+       outb_p(val, (reg & 3) | 0xcfc);
+ }
+ static u8 get_cmd640_reg_pci1 (u16 reg)
+ {
+-      outb_p((reg & 0xfc) | cmd640_key, 0xcf8);
++      outl_p((reg & 0xfc) | cmd640_key, 0xcf8);
+       return inb_p((reg & 3) | 0xcfc);
+ }
+--- linux-2.6.0/drivers/ide/pci/Makefile       2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/ide/pci/Makefile        2003-12-28 23:21:46.000000000 -0800
+@@ -21,6 +21,7 @@ obj-$(CONFIG_BLK_DEV_PDC202XX_NEW)   += pd
+ obj-$(CONFIG_BLK_DEV_PIIX)            += piix.o
+ obj-$(CONFIG_BLK_DEV_RZ1000)          += rz1000.o
+ obj-$(CONFIG_BLK_DEV_SVWKS)           += serverworks.o
++obj-$(CONFIG_BLK_DEV_SGIIOC4)         += sgiioc4.o
+ obj-$(CONFIG_BLK_DEV_SIIMAGE)         += siimage.o
+ obj-$(CONFIG_BLK_DEV_SIS5513)         += sis5513.o
+ obj-$(CONFIG_BLK_DEV_SL82C105)                += sl82c105.o
+--- linux-2.6.0/drivers/ide/pci/pdc202xx_new.c 2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/ide/pci/pdc202xx_new.c  2003-12-28 23:26:29.000000000 -0800
+@@ -36,60 +36,20 @@
+ #define PDC202_DEBUG_CABLE    0
+-#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
+-#include <linux/stat.h>
+-#include <linux/proc_fs.h>
+-
+-static u8 pdcnew_proc = 0;
+-#define PDC202_MAX_DEVS               5
+-static struct pci_dev *pdc202_devs[PDC202_MAX_DEVS];
+-static int n_pdc202_devs;
+-
+-static char * pdcnew_info(char *buf, struct pci_dev *dev)
+-{
+-      char *p = buf;
+-
+-      p += sprintf(p, "\n                                ");
+-      switch(dev->device) {
+-              case PCI_DEVICE_ID_PROMISE_20277:
+-                      p += sprintf(p, "SBFastTrak 133 Lite"); break;
+-              case PCI_DEVICE_ID_PROMISE_20276:
+-                      p += sprintf(p, "MBFastTrak 133 Lite"); break;
+-              case PCI_DEVICE_ID_PROMISE_20275:
+-                      p += sprintf(p, "MBUltra133"); break;
+-              case PCI_DEVICE_ID_PROMISE_20271:
+-                      p += sprintf(p, "FastTrak TX2000"); break;
+-              case PCI_DEVICE_ID_PROMISE_20270:
+-                      p += sprintf(p, "FastTrak LP/TX2/TX4"); break;
+-              case PCI_DEVICE_ID_PROMISE_20269:
+-                      p += sprintf(p, "Ultra133 TX2"); break;
+-              case PCI_DEVICE_ID_PROMISE_20268:
+-                      p += sprintf(p, "Ultra100 TX2"); break;
+-              default:
+-                      p += sprintf(p, "Ultra series"); break;
+-                      break;
+-      }
+-      p += sprintf(p, " Chipset.\n");
+-      return (char *)p;
+-}
+-
+-static int pdcnew_get_info (char *buffer, char **addr, off_t offset, int count)
+-{
+-      char *p = buffer;
+-      int i, len;
+-
+-      for (i = 0; i < n_pdc202_devs; i++) {
+-              struct pci_dev *dev     = pdc202_devs[i];
+-              p = pdcnew_info(buffer, dev);
+-      }
+-      /* p - buffer must be less than 4k! */
+-      len = (p - buffer) - offset;
+-      *addr = buffer + offset;
+-      
+-      return len > count ? count : len;
+-}
+-#endif  /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */
++struct pdcnew_name {
++      u16 dev_id;
++      const char *name;
++};
++static struct pdcnew_name __initdata pdcnew_names[] = {
++      { PCI_DEVICE_ID_PROMISE_20277, "SBFastTrak 133 Lite" },
++      { PCI_DEVICE_ID_PROMISE_20276, "MBFastTrak 133 Lite" },
++      { PCI_DEVICE_ID_PROMISE_20275, "MBUltra133", },
++      { PCI_DEVICE_ID_PROMISE_20271, "FastTrak TX2000", },
++      { PCI_DEVICE_ID_PROMISE_20270, "FastTrak LP/TX2/TX4", },
++      { PCI_DEVICE_ID_PROMISE_20269, "Ultra133 TX2" },
++      { PCI_DEVICE_ID_PROMISE_20268, "Ultra100 TX2" },
++};
+ static u8 pdcnew_ratemask (ide_drive_t *drive)
+ {
+@@ -515,6 +475,15 @@ void pdcnew_reset (ide_drive_t *drive)
+ static unsigned int __init init_chipset_pdcnew (struct pci_dev *dev, const char *name)
+ {
++      unsigned int i;
++
++      for (i = 0; i < ARRAY_SIZE(pdcnew_names); i++)
++              if (pdcnew_names[i].dev_id == dev->device) {
++                      printk(KERN_INFO "%s: %s on pci%s\n", name,
++                                       pdcnew_names[i].name, pci_name(dev));
++                      break;
++              }
++
+       if (dev->resource[PCI_ROM_RESOURCE].start) {
+               pci_write_config_dword(dev, PCI_ROM_ADDRESS,
+                       dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
+@@ -522,15 +491,6 @@ static unsigned int __init init_chipset_
+                       name, dev->resource[PCI_ROM_RESOURCE].start);
+       }
+-#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
+-      pdc202_devs[n_pdc202_devs++] = dev;
+-
+-      if (!pdcnew_proc) {
+-              pdcnew_proc = 1;
+-              ide_pci_register_host_proc(&pdcnew_procs[0]);
+-      }
+-#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */
+-
+       return dev->irq;
+ }
+--- linux-2.6.0/drivers/ide/pci/pdc202xx_new.h 2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/ide/pci/pdc202xx_new.h  2003-12-28 23:26:29.000000000 -0800
+@@ -5,8 +5,6 @@
+ #include <linux/pci.h>
+ #include <linux/ide.h>
+-#define DISPLAY_PDC202XX_TIMINGS
+-
+ #ifndef SPLIT_BYTE
+ #define SPLIT_BYTE(B,H,L)     ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
+ #endif
+@@ -162,27 +160,6 @@ static void decode_registers (u8 registe
+               set_2regs(0x13,(c));                    \
+       } while(0)
+-#define DISPLAY_PDC202XX_TIMINGS
+-
+-#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
+-#include <linux/stat.h>
+-#include <linux/proc_fs.h>
+-
+-static u8 pdcnew_proc;
+-
+-static int pdcnew_get_info(char *, char **, off_t, int);
+-
+-static ide_pci_host_proc_t pdcnew_procs[] __initdata = {
+-      {
+-              .name           = "pdcnew",
+-              .set            = 1,
+-              .get_info       = pdcnew_get_info,
+-              .parent         = NULL,
+-      },
+-};
+-#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */
+-
+-
+ static void init_setup_pdcnew(struct pci_dev *, ide_pci_device_t *);
+ static void init_setup_pdc20270(struct pci_dev *, ide_pci_device_t *);
+ static void init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d);
+--- linux-2.6.0/drivers/ide/pci/pdc202xx_old.c 2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/ide/pci/pdc202xx_old.c  2003-12-28 23:26:28.000000000 -0800
+@@ -361,16 +361,38 @@ static u8 pdc202xx_old_cable_detect (ide
+       return ((u8)(CIS & mask));
+ }
++/*
++ * Set the control register to use the 66MHz system
++ * clock for UDMA 3/4/5 mode operation when necessary.
++ *
++ * It may also be possible to leave the 66MHz clock on
++ * and readjust the timing parameters.
++ */
++static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif)
++{
++      unsigned long clock_reg = hwif->dma_master + 0x11;
++      u8 clock = hwif->INB(clock_reg);
++
++      hwif->OUTB(clock | (hwif->channel ? 0x08 : 0x02), clock_reg);
++}
++
++static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
++{
++      unsigned long clock_reg = hwif->dma_master + 0x11;
++      u8 clock = hwif->INB(clock_reg);
++
++      hwif->OUTB(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
++}
++
+ static int config_chipset_for_dma (ide_drive_t *drive)
+ {
+       struct hd_driveid *id   = drive->id;
+       ide_hwif_t *hwif        = HWIF(drive);
+       struct pci_dev *dev     = hwif->pci_dev;
+       u32 drive_conf          = 0;
+-      u8 mask                 = hwif->channel ? 0x08 : 0x02;
+       u8 drive_pci            = 0x60 + (drive->dn << 2);
+       u8 test1 = 0, test2 = 0, speed = -1;
+-      u8 AP = 0, CLKSPD = 0, cable = 0;
++      u8 AP = 0, cable = 0;
+       u8 ultra_66             = ((id->dma_ultra & 0x0010) ||
+                                  (id->dma_ultra & 0x0008)) ? 1 : 0;
+@@ -394,21 +416,6 @@ static int config_chipset_for_dma (ide_d
+                       BUG();
+       }
+-      CLKSPD = hwif->INB(hwif->dma_master + 0x11);
+-
+-      /*
+-       * Set the control register to use the 66Mhz system
+-       * clock for UDMA 3/4 mode operation. If one drive on
+-       * a channel is U66 capable but the other isn't we
+-       * fall back to U33 mode. The BIOS INT 13 hooks turn
+-       * the clock on then off for each read/write issued. I don't
+-       * do that here because it would require modifying the
+-       * kernel, separating the fop routines from the kernel or
+-       * somehow hooking the fops calls. It may also be possible to
+-       * leave the 66Mhz clock on and readjust the timing
+-       * parameters.
+-       */
+-
+       if ((ultra_66) && (cable)) {
+ #ifdef DEBUG
+               printk(KERN_DEBUG "ULTRA 66/100/133: %s channel of Ultra 66/100/133 "
+@@ -416,29 +423,12 @@ static int config_chipset_for_dma (ide_d
+                       hwif->channel ? "Secondary" : "Primary");
+               printk(KERN_DEBUG "         Switching to Ultra33 mode.\n");
+ #endif /* DEBUG */
+-              /* Primary   : zero out second bit */
+-              /* Secondary : zero out fourth bit */
+-              hwif->OUTB(CLKSPD & ~mask, (hwif->dma_master + 0x11));
+               printk(KERN_WARNING "Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary");
+               printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name);
+-      } else {
+-              if (ultra_66) {
+-                      /*
+-                       * check to make sure drive on same channel
+-                       * is u66 capable
+-                       */
+-                      if (hwif->drives[!(drive->dn%2)].id) {
+-                              if (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0078) {
+-                                      hwif->OUTB(CLKSPD | mask, (hwif->dma_master + 0x11));
+-                              } else {
+-                                      hwif->OUTB(CLKSPD & ~mask, (hwif->dma_master + 0x11));
+-                              }
+-                      } else { /* udma4 drive by itself */
+-                              hwif->OUTB(CLKSPD | mask, (hwif->dma_master + 0x11));
+-                      }
+-              }
+       }
++      pdc_old_disable_66MHz_clock(drive->hwif);
++
+       drive_pci = 0x60 + (drive->dn << 2);
+       pci_read_config_dword(dev, drive_pci, &drive_conf);
+       if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))
+@@ -536,6 +526,8 @@ static int pdc202xx_quirkproc (ide_drive
+ static int pdc202xx_old_ide_dma_begin(ide_drive_t *drive)
+ {
++      if (drive->current_speed > XFER_UDMA_2)
++              pdc_old_enable_66MHz_clock(drive->hwif);
+       if (drive->addressing == 1) {
+               struct request *rq      = HWGROUP(drive)->rq;
+               ide_hwif_t *hwif        = HWIF(drive);
+@@ -569,6 +561,8 @@ static int pdc202xx_old_ide_dma_end(ide_
+               clock = hwif->INB(high_16 + 0x11);
+               hwif->OUTB(clock & ~(hwif->channel ? 0x08:0x02), high_16+0x11);
+       }
++      if (drive->current_speed > XFER_UDMA_2)
++              pdc_old_disable_66MHz_clock(drive->hwif);
+       return __ide_dma_end(drive);
+ }
+@@ -757,10 +751,7 @@ static void __init init_hwif_pdc202xx (i
+       hwif->speedproc = &pdc202xx_tune_chipset;
+-      if (!hwif->dma_base) {
+-              hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+-              return;
+-      }
++      hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+       hwif->ultra_mask = 0x3f;
+       hwif->mwdma_mask = 0x07;
+--- linux-2.6.0/drivers/ide/pci/piix.c 2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/ide/pci/piix.c  2003-12-28 23:22:14.000000000 -0800
+@@ -768,8 +768,8 @@ static void __init piix_check_450nx(void
+               /* Only on the original revision: IDE DMA can hang */
+               if(rev == 0x00)
+                       no_piix_dma = 1;
+-              /* On all revisions PXB bus lock must be disabled for IDE */
+-              else if(cfg & (1<<14))
++              /* On all revisions below 5 PXB bus lock must be disabled for IDE */
++              else if(cfg & (1<<14) && rev < 5)
+                       no_piix_dma = 2;
+       }
+       if(no_piix_dma)
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/ide/pci/sgiioc4.c       2003-12-28 23:21:46.000000000 -0800
+@@ -0,0 +1,833 @@
++/*
++ * Copyright (c) 2003 Silicon Graphics, Inc.  All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License
++ * as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it would be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
++ *
++ * You should have received a copy of the GNU General Public
++ * License along with this program; if not, write the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
++ *
++ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
++ * Mountain View, CA  94043, or:
++ *
++ * http://www.sgi.com
++ *
++ * For further information regarding this notice, see:
++ *
++ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/delay.h>
++#include <linux/hdreg.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/timer.h>
++#include <linux/mm.h>
++#include <linux/ioport.h>
++#include <linux/blkdev.h>
++#include <asm/io.h>
++
++#include <linux/ide.h>
++
++/* IOC4 Specific Definitions */
++#define IOC4_CMD_OFFSET               0x100
++#define IOC4_CTRL_OFFSET      0x120
++#define IOC4_DMA_OFFSET               0x140
++#define IOC4_INTR_OFFSET      0x0
++
++#define IOC4_TIMING           0x00
++#define IOC4_DMA_PTR_L                0x01
++#define IOC4_DMA_PTR_H                0x02
++#define IOC4_DMA_ADDR_L               0x03
++#define IOC4_DMA_ADDR_H               0x04
++#define IOC4_BC_DEV           0x05
++#define IOC4_BC_MEM           0x06
++#define       IOC4_DMA_CTRL           0x07
++#define       IOC4_DMA_END_ADDR       0x08
++
++/* Bits in the IOC4 Control/Status Register */
++#define       IOC4_S_DMA_START        0x01
++#define       IOC4_S_DMA_STOP         0x02
++#define       IOC4_S_DMA_DIR          0x04
++#define       IOC4_S_DMA_ACTIVE       0x08
++#define       IOC4_S_DMA_ERROR        0x10
++#define       IOC4_ATA_MEMERR         0x02
++
++/* Read/Write Directions */
++#define       IOC4_DMA_WRITE          0x04
++#define       IOC4_DMA_READ           0x00
++
++/* Interrupt Register Offsets */
++#define IOC4_INTR_REG         0x03
++#define       IOC4_INTR_SET           0x05
++#define       IOC4_INTR_CLEAR         0x07
++
++#define IOC4_IDE_CACHELINE_SIZE       128
++#define IOC4_CMD_CTL_BLK_SIZE 0x20
++#define IOC4_SUPPORTED_FIRMWARE_REV 46
++
++typedef struct {
++      u32 timing_reg0;
++      u32 timing_reg1;
++      u32 low_mem_ptr;
++      u32 high_mem_ptr;
++      u32 low_mem_addr;
++      u32 high_mem_addr;
++      u32 dev_byte_count;
++      u32 mem_byte_count;
++      u32 status;
++} ioc4_dma_regs_t;
++
++/* Each Physical Region Descriptor Entry size is 16 bytes (2 * 64 bits) */
++/* IOC4 has only 1 IDE channel */
++#define IOC4_PRD_BYTES       16
++#define IOC4_PRD_ENTRIES     (PAGE_SIZE /(4*IOC4_PRD_BYTES))
++
++
++static void
++sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
++                      unsigned long ctrl_port, unsigned long irq_port)
++{
++      unsigned long reg = data_port;
++      int i;
++
++      /* Registers are word (32 bit) aligned */
++      for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
++              hw->io_ports[i] = reg + i * 4;
++
++      if (ctrl_port)
++              hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
++
++      if (irq_port)
++              hw->io_ports[IDE_IRQ_OFFSET] = irq_port;
++}
++
++static void
++sgiioc4_maskproc(ide_drive_t * drive, int mask)
++{
++      ide_hwif_t *hwif = HWIF(drive);
++      hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
++                 IDE_CONTROL_REG);
++}
++
++
++static int
++sgiioc4_checkirq(ide_hwif_t * hwif)
++{
++      u8 intr_reg =
++          hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4);
++
++      if (intr_reg & 0x03)
++              return 1;
++
++      return 0;
++}
++
++
++static int
++sgiioc4_clearirq(ide_drive_t * drive)
++{
++      u32 intr_reg;
++      ide_hwif_t *hwif = HWIF(drive);
++      unsigned long other_ir =
++          hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2);
++
++      /* Code to check for PCI error conditions */
++      intr_reg = hwif->INL(other_ir);
++      if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */
++              /*
++               * Using hwif->INB to read the IDE_STATUS_REG has a side effect
++               * of clearing the interrupt.  The first read should clear it
++               * if it is set.  The second read should return a "clear" status
++               * if it got cleared.  If not, then spin for a bit trying to
++               * clear it.
++               */
++              u8 stat = hwif->INB(IDE_STATUS_REG);
++              int count = 0;
++              stat = hwif->INB(IDE_STATUS_REG);
++              while ((stat & 0x80) && (count++ < 100)) {
++                      udelay(1);
++                      stat = hwif->INB(IDE_STATUS_REG);
++              }
++
++              if (intr_reg & 0x02) {
++                      /* Error when transferring DMA data on PCI bus */
++                      u32 pci_err_addr_low, pci_err_addr_high,
++                          pci_stat_cmd_reg;
++
++                      pci_err_addr_low =
++                              hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET]);
++                      pci_err_addr_high =
++                              hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + 4);
++                      pci_read_config_dword(hwif->pci_dev, PCI_COMMAND,
++                                            &pci_stat_cmd_reg);
++                      printk(KERN_ERR
++                             "%s(%s) : PCI Bus Error when doing DMA:"
++                                 " status-cmd reg is 0x%x\n",
++                             __FUNCTION__, drive->name, pci_stat_cmd_reg);
++                      printk(KERN_ERR
++                             "%s(%s) : PCI Error Address is 0x%x%x\n",
++                             __FUNCTION__, drive->name,
++                             pci_err_addr_high, pci_err_addr_low);
++                      /* Clear the PCI Error indicator */
++                      pci_write_config_dword(hwif->pci_dev, PCI_COMMAND,
++                                             0x00000146);
++              }
++
++              /* Clear the Interrupt, Error bits on the IOC4 */
++              hwif->OUTL(0x03, other_ir);
++
++              intr_reg = hwif->INL(other_ir);
++      }
++
++      return intr_reg & 3;
++}
++
++static int
++sgiioc4_ide_dma_begin(ide_drive_t * drive)
++{
++      ide_hwif_t *hwif = HWIF(drive);
++      unsigned int reg = hwif->INL(hwif->dma_base + IOC4_DMA_CTRL * 4);
++      unsigned int temp_reg = reg | IOC4_S_DMA_START;
++
++      hwif->OUTL(temp_reg, hwif->dma_base + IOC4_DMA_CTRL * 4);
++
++      return 0;
++}
++
++static u32
++sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
++{
++      u32     ioc4_dma;
++      int     count;
++
++      count = 0;
++      ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
++      while ((ioc4_dma & IOC4_S_DMA_STOP) && (count++ < 200)) {
++              udelay(1);
++              ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
++      }
++      return ioc4_dma;
++}
++
++/* Stops the IOC4 DMA Engine */
++static int
++sgiioc4_ide_dma_end(ide_drive_t * drive)
++{
++      u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0;
++      ide_hwif_t *hwif = HWIF(drive);
++      u64 dma_base = hwif->dma_base;
++      int dma_stat = 0;
++      unsigned long *ending_dma = (unsigned long *) hwif->dma_base2;
++
++      hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
++
++      ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
++
++      if (ioc4_dma & IOC4_S_DMA_STOP) {
++              printk(KERN_ERR
++                     "%s(%s): IOC4 DMA STOP bit is still 1 :"
++                     "ioc4_dma_reg 0x%x\n",
++                     __FUNCTION__, drive->name, ioc4_dma);
++              dma_stat = 1;
++      }
++
++      /*
++       * The IOC4 will DMA 1's to the ending dma area to indicate that
++       * previous data DMA is complete.  This is necessary because of relaxed
++       * ordering between register reads and DMA writes on the Altix.
++       */
++      while ((cnt++ < 200) && (!valid)) {
++              for (num = 0; num < 16; num++) {
++                      if (ending_dma[num]) {
++                              valid = 1;
++                              break;
++                      }
++              }
++              udelay(1);
++      }
++      if (!valid) {
++              printk(KERN_ERR "%s(%s) : DMA incomplete\n", __FUNCTION__,
++                     drive->name);
++              dma_stat = 1;
++      }
++
++      bc_dev = hwif->INL(dma_base + IOC4_BC_DEV * 4);
++      bc_mem = hwif->INL(dma_base + IOC4_BC_MEM * 4);
++
++      if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) {
++              if (bc_dev > bc_mem + 8) {
++                      printk(KERN_ERR
++                             "%s(%s): WARNING!! byte_count_dev %d "
++                             "!= byte_count_mem %d\n",
++                             __FUNCTION__, drive->name, bc_dev, bc_mem);
++              }
++      }
++
++      drive->waiting_for_dma = 0;
++      ide_destroy_dmatable(drive);
++
++      return dma_stat;
++}
++
++static int
++sgiioc4_ide_dma_check(ide_drive_t * drive)
++{
++      if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
++              printk(KERN_INFO
++                     "Couldnot set %s in Multimode-2 DMA mode | "
++                         "Drive %s using PIO instead\n",
++                     drive->name, drive->name);
++              drive->using_dma = 0;
++      } else
++              drive->using_dma = 1;
++
++      return 0;
++}
++
++static int
++sgiioc4_ide_dma_on(ide_drive_t * drive)
++{
++      drive->using_dma = 1;
++
++      return HWIF(drive)->ide_dma_host_on(drive);
++}
++
++static int
++sgiioc4_ide_dma_off(ide_drive_t * drive)
++{
++      printk(KERN_INFO "%s: DMA disabled\n", drive->name);
++
++      return HWIF(drive)->ide_dma_off_quietly(drive);
++}
++
++static int
++sgiioc4_ide_dma_off_quietly(ide_drive_t * drive)
++{
++      drive->using_dma = 0;
++
++      return HWIF(drive)->ide_dma_host_off(drive);
++}
++
++/* returns 1 if dma irq issued, 0 otherwise */
++static int
++sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
++{
++      return sgiioc4_checkirq(HWIF(drive));
++}
++
++static int
++sgiioc4_ide_dma_host_on(ide_drive_t * drive)
++{
++      if (drive->using_dma)
++              return 0;
++
++      return 1;
++}
++
++static int
++sgiioc4_ide_dma_host_off(ide_drive_t * drive)
++{
++      sgiioc4_clearirq(drive);
++
++      return 0;
++}
++
++static int
++sgiioc4_ide_dma_verbose(ide_drive_t * drive)
++{
++      if (drive->using_dma == 1)
++              printk(", UDMA(16)");
++      else
++              printk(", PIO");
++
++      return 1;
++}
++
++static int
++sgiioc4_ide_dma_lostirq(ide_drive_t * drive)
++{
++      HWIF(drive)->resetproc(drive);
++
++      return __ide_dma_lostirq(drive);
++}
++
++static void
++sgiioc4_resetproc(ide_drive_t * drive)
++{
++      sgiioc4_ide_dma_end(drive);
++      sgiioc4_clearirq(drive);
++}
++
++static u8
++sgiioc4_INB(unsigned long port)
++{
++      u8 reg = (u8) inb(port);
++
++      if ((port & 0xFFF) == 0x11C) {  /* Status register of IOC4 */
++              if (reg & 0x51) {       /* Not busy...check for interrupt */
++                      unsigned long other_ir = port - 0x110;
++                      unsigned int intr_reg = (u32) inl(other_ir);
++
++                      /* Clear the Interrupt, Error bits on the IOC4 */
++                      if (intr_reg & 0x03) {
++                              outl(0x03, other_ir);
++                              intr_reg = (u32) inl(other_ir);
++                      }
++              }
++      }
++
++      return reg;
++}
++
++/* Creates a dma map for the scatter-gather list entries */
++static void __init
++ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
++{
++      int num_ports = sizeof (ioc4_dma_regs_t);
++
++      printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name,
++             dma_base, dma_base + num_ports - 1);
++
++      if (!request_region(dma_base, num_ports, hwif->name)) {
++              printk(KERN_ERR
++                     "%s(%s) -- ERROR, Addresses 0x%p to 0x%p "
++                     "ALREADY in use\n",
++                     __FUNCTION__, hwif->name, (void *) dma_base,
++                     (void *) dma_base + num_ports - 1);
++              goto dma_alloc_failure;
++      }
++
++      hwif->dma_base = dma_base;
++      hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
++                                        IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
++                                        &hwif->dmatable_dma);
++
++      if (!hwif->dmatable_cpu)
++              goto dma_alloc_failure;
++
++      hwif->sg_table =
++          kmalloc(sizeof (struct scatterlist) * IOC4_PRD_ENTRIES, GFP_KERNEL);
++
++      if (!hwif->sg_table)
++              goto dma_sgalloc_failure;
++
++      hwif->dma_base2 = (unsigned long)
++              pci_alloc_consistent(hwif->pci_dev,
++                                   IOC4_IDE_CACHELINE_SIZE,
++                                   (dma_addr_t *) &(hwif->dma_status));
++
++      if (!hwif->dma_base2)
++              goto dma_base2alloc_failure;
++
++      return;
++
++dma_base2alloc_failure:
++      kfree(hwif->sg_table);
++
++dma_sgalloc_failure:
++      pci_free_consistent(hwif->pci_dev,
++                          IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
++                          hwif->dmatable_cpu, hwif->dmatable_dma);
++      printk(KERN_INFO
++             "%s() -- Error! Unable to allocate DMA Maps for drive %s\n",
++             __FUNCTION__, hwif->name);
++      printk(KERN_INFO
++             "Changing from DMA to PIO mode for Drive %s\n", hwif->name);
++
++dma_alloc_failure:
++      /* Disable DMA because we couldnot allocate any DMA maps */
++      hwif->autodma = 0;
++      hwif->atapi_dma = 0;
++}
++
++/* Initializes the IOC4 DMA Engine */
++static void
++sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
++{
++      u32 ioc4_dma;
++      ide_hwif_t *hwif = HWIF(drive);
++      u64 dma_base = hwif->dma_base;
++      u32 dma_addr, ending_dma_addr;
++
++      ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
++
++      if (ioc4_dma & IOC4_S_DMA_ACTIVE) {
++              printk(KERN_WARNING
++                      "%s(%s):Warning!! DMA from previous transfer was still active\n",
++                     __FUNCTION__, drive->name);
++              hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
++              ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
++
++              if (ioc4_dma & IOC4_S_DMA_STOP)
++                      printk(KERN_ERR
++                             "%s(%s) : IOC4 Dma STOP bit is still 1\n",
++                             __FUNCTION__, drive->name);
++      }
++
++      ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
++      if (ioc4_dma & IOC4_S_DMA_ERROR) {
++              printk(KERN_WARNING
++                     "%s(%s) : Warning!! - DMA Error during Previous"
++                     " transfer | status 0x%x\n",
++                     __FUNCTION__, drive->name, ioc4_dma);
++              hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
++              ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
++
++              if (ioc4_dma & IOC4_S_DMA_STOP)
++                      printk(KERN_ERR
++                             "%s(%s) : IOC4 DMA STOP bit is still 1\n",
++                             __FUNCTION__, drive->name);
++      }
++
++      /* Address of the Scatter Gather List */
++      dma_addr = cpu_to_le32(hwif->dmatable_dma);
++      hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4);
++
++      /* Address of the Ending DMA */
++      memset((unsigned int *) hwif->dma_base2, 0, IOC4_IDE_CACHELINE_SIZE);
++      ending_dma_addr = cpu_to_le32(hwif->dma_status);
++      hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4);
++
++      hwif->OUTL(dma_direction, dma_base + IOC4_DMA_CTRL * 4);
++      drive->waiting_for_dma = 1;
++}
++
++/* IOC4 Scatter Gather list Format                                     */
++/* 128 Bit entries to support 64 bit addresses in the future           */
++/* The Scatter Gather list Entry should be in the BIG-ENDIAN Format    */
++/* --------------------------------------------------------------------- */
++/* | Upper 32 bits - Zero           |         Lower 32 bits- address | */
++/* --------------------------------------------------------------------- */
++/* | Upper 32 bits - Zero         |EOL| 15 unused     | 16 Bit Length| */
++/* --------------------------------------------------------------------- */
++/* Creates the scatter gather list, DMA Table */
++static unsigned int
++sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
++{
++      ide_hwif_t *hwif = HWIF(drive);
++      unsigned int *table = hwif->dmatable_cpu;
++      unsigned int count = 0, i = 1;
++      struct scatterlist *sg;
++
++      if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
++              hwif->sg_nents = i = ide_raw_build_sglist(drive, rq);
++      else
++              hwif->sg_nents = i = ide_build_sglist(drive, rq);
++
++      if (!i)
++              return 0;       /* sglist of length Zero */
++
++      sg = hwif->sg_table;
++      while (i && sg_dma_len(sg)) {
++              dma_addr_t cur_addr;
++              int cur_len;
++              cur_addr = sg_dma_address(sg);
++              cur_len = sg_dma_len(sg);
++
++              while (cur_len) {
++                      if (count++ >= IOC4_PRD_ENTRIES) {
++                              printk(KERN_WARNING
++                                     "%s: DMA table too small\n",
++                                     drive->name);
++                              goto use_pio_instead;
++                      } else {
++                              u32 xcount, bcount =
++                                  0x10000 - (cur_addr & 0xffff);
++
++                              if (bcount > cur_len)
++                                      bcount = cur_len;
++
++                              /* put the addr, length in
++                               * the IOC4 dma-table format */
++                              *table = 0x0;
++                              table++;
++                              *table = cpu_to_be32(cur_addr);
++                              table++;
++                              *table = 0x0;
++                              table++;
++
++                              xcount = bcount & 0xffff;
++                              *table = cpu_to_be32(xcount);
++                              table++;
++
++                              cur_addr += bcount;
++                              cur_len -= bcount;
++                      }
++              }
++
++              sg++;
++              i--;
++      }
++
++      if (count) {
++              table--;
++              *table |= cpu_to_be32(0x80000000);
++              return count;
++      }
++
++use_pio_instead:
++      pci_unmap_sg(hwif->pci_dev, hwif->sg_table, hwif->sg_nents,
++                   hwif->sg_dma_direction);
++      hwif->sg_dma_active = 0;
++
++      return 0;               /* revert to PIO for this request */
++}
++
++static int
++sgiioc4_ide_dma_read(ide_drive_t * drive)
++{
++      struct request *rq = HWGROUP(drive)->rq;
++      unsigned int count = 0;
++
++      if (!(count = sgiioc4_build_dma_table(drive, rq, PCI_DMA_FROMDEVICE))) {
++              /* try PIO instead of DMA */
++              return 1;
++      }
++      /* Writes FROM the IOC4 TO Main Memory */
++      sgiioc4_configure_for_dma(IOC4_DMA_WRITE, drive);
++
++      return 0;
++}
++
++static int
++sgiioc4_ide_dma_write(ide_drive_t * drive)
++{
++      struct request *rq = HWGROUP(drive)->rq;
++      unsigned int count = 0;
++
++      if (!(count = sgiioc4_build_dma_table(drive, rq, PCI_DMA_TODEVICE))) {
++              /* try PIO instead of DMA */
++              return 1;
++      }
++
++      sgiioc4_configure_for_dma(IOC4_DMA_READ, drive);
++      /* Writes TO the IOC4 FROM Main Memory */
++
++      return 0;
++}
++
++static void __init
++ide_init_sgiioc4(ide_hwif_t * hwif)
++{
++      hwif->mmio = 2;
++      hwif->autodma = 1;
++      hwif->atapi_dma = 1;
++      hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
++      hwif->mwdma_mask = 0x2; /* Multimode-2 DMA  */
++      hwif->swdma_mask = 0x2;
++      hwif->identify = NULL;
++      hwif->tuneproc = NULL;  /* Sets timing for PIO mode */
++      hwif->speedproc = NULL; /* Sets timing for DMA &/or PIO modes */
++      hwif->selectproc = NULL;/* Use the default routine to select drive */
++      hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */
++      hwif->pre_reset = NULL; /* No HBA specific pre_set needed */
++      hwif->resetproc = &sgiioc4_resetproc;/* Reset DMA engine,
++                                              clear interrupts */
++      hwif->intrproc = NULL;  /* Enable or Disable interrupt from drive */
++      hwif->maskproc = &sgiioc4_maskproc;     /* Mask on/off NIEN register */
++      hwif->quirkproc = NULL;
++      hwif->busproc = NULL;
++
++      hwif->ide_dma_read = &sgiioc4_ide_dma_read;
++      hwif->ide_dma_write = &sgiioc4_ide_dma_write;
++      hwif->ide_dma_begin = &sgiioc4_ide_dma_begin;
++      hwif->ide_dma_end = &sgiioc4_ide_dma_end;
++      hwif->ide_dma_check = &sgiioc4_ide_dma_check;
++      hwif->ide_dma_on = &sgiioc4_ide_dma_on;
++      hwif->ide_dma_off = &sgiioc4_ide_dma_off;
++      hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
++      hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
++      hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
++      hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
++      hwif->ide_dma_bad_drive = &__ide_dma_bad_drive;
++      hwif->ide_dma_good_drive = &__ide_dma_good_drive;
++      hwif->ide_dma_count = &__ide_dma_count;
++      hwif->ide_dma_verbose = &sgiioc4_ide_dma_verbose;
++      hwif->ide_dma_retune = &__ide_dma_retune;
++      hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
++      hwif->ide_dma_timeout = &__ide_dma_timeout;
++      hwif->INB = &sgiioc4_INB;
++}
++
++static int __init
++sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
++{
++      unsigned long base, ctl, dma_base, irqport;
++      ide_hwif_t *hwif;
++      int h;
++
++      for (h = 0; h < MAX_HWIFS; ++h) {
++              hwif = &ide_hwifs[h];
++              /* Find an empty HWIF */
++              if (hwif->chipset == ide_unknown)
++                      break;
++      }
++
++      /*  Get the CmdBlk and CtrlBlk Base Registers */
++      base = pci_resource_start(dev, 0) + IOC4_CMD_OFFSET;
++      ctl = pci_resource_start(dev, 0) + IOC4_CTRL_OFFSET;
++      irqport = pci_resource_start(dev, 0) + IOC4_INTR_OFFSET;
++      dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;
++
++      if (!request_region(base, IOC4_CMD_CTL_BLK_SIZE, hwif->name)) {
++              printk(KERN_ERR
++                      "%s : %s -- ERROR, Port Addresses "
++                      "0x%p to 0x%p ALREADY in use\n",
++                     __FUNCTION__, hwif->name, (void *) base,
++                     (void *) base + IOC4_CMD_CTL_BLK_SIZE);
++              return 1;
++      }
++
++      if (hwif->io_ports[IDE_DATA_OFFSET] != base) {
++              /* Initialize the IO registers */
++              sgiioc4_init_hwif_ports(&hwif->hw, base, ctl, irqport);
++              memcpy(hwif->io_ports, hwif->hw.io_ports,
++                     sizeof (hwif->io_ports));
++              hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
++      }
++
++      hwif->irq = dev->irq;
++      hwif->chipset = ide_pci;
++      hwif->pci_dev = dev;
++      hwif->channel = 0;      /* Single Channel chip */
++      hwif->cds = (struct ide_pci_device_s *) d;
++      hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */
++
++      /* Initializing chipset IRQ Registers */
++      hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4);
++
++      ide_init_sgiioc4(hwif);
++
++      if (dma_base)
++              ide_dma_sgiioc4(hwif, dma_base);
++      else
++              printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n",
++                     hwif->name, d->name);
++
++      probe_hwif_init(hwif);
++      return 0;
++}
++
++/* This ensures that we can build this for generic kernels without
++ * having all the SN2 code sync'd and merged.
++ */
++typedef enum pciio_endian_e {
++      PCIDMA_ENDIAN_BIG,
++      PCIDMA_ENDIAN_LITTLE
++} pciio_endian_t;
++pciio_endian_t __attribute__ ((weak)) snia_pciio_endian_set(struct pci_dev
++                                          *pci_dev, pciio_endian_t device_end,
++                                          pciio_endian_t desired_end);
++
++static unsigned int __init
++pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d)
++{
++      unsigned int class_rev;
++
++      if (pci_enable_device(dev)) {
++              printk(KERN_ERR
++                     "Failed to enable device %s at slot %s\n",
++                     d->name, dev->slot_name);
++              return 1;
++      }
++      pci_set_master(dev);
++
++      pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
++      class_rev &= 0xff;
++      printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n",
++                      d->name, dev->slot_name, class_rev);
++      if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) {
++              printk(KERN_ERR "Skipping %s IDE controller in slot %s: "
++                      "firmware is obsolete - please upgrade to revision"
++                      "46 or higher\n", d->name, dev->slot_name);
++              return 1;
++      }
++
++      /* Enable Byte Swapping in the PIC... */
++      if (snia_pciio_endian_set) {
++              snia_pciio_endian_set(dev, PCIDMA_ENDIAN_LITTLE,
++                                    PCIDMA_ENDIAN_BIG);
++      } else {
++              printk(KERN_ERR
++                     "Failed to set endianness for device %s at slot %s\n",
++                     d->name, dev->slot_name);
++              return 1;
++      }
++
++      return sgiioc4_ide_setup_pci_device(dev, d);
++}
++
++static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = {
++      {
++       /* Channel 0 */
++       .vendor = PCI_VENDOR_ID_SGI,
++       .device = PCI_DEVICE_ID_SGI_IOC4,
++       .name = "SGIIOC4",
++       .init_hwif = ide_init_sgiioc4,
++       .init_dma = ide_dma_sgiioc4,
++       .channels = 1,
++       .autodma = AUTODMA,
++       /* SGI IOC4 doesn't have enablebits. */
++       .bootable = ON_BOARD,
++      }
++};
++
++static int __devinit
++sgiioc4_init_one(struct pci_dev *dev, const struct pci_device_id *id)
++{
++      ide_pci_device_t *d = &sgiioc4_chipsets[id->driver_data];
++      if (dev->device != d->device) {
++              printk(KERN_ERR "Error in %s(dev 0x%p | id 0x%p )\n",
++                     __FUNCTION__, (void *) dev, (void *) id);
++              BUG();
++      }
++
++      if (pci_init_sgiioc4(dev, d))
++              return 0;
++
++      MOD_INC_USE_COUNT;
++
++      return 0;
++}
++
++static struct pci_device_id sgiioc4_pci_tbl[] = {
++      {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID,
++       PCI_ANY_ID, 0x0b4000, 0xFFFFFF, 0},
++      {0}
++};
++
++static struct pci_driver driver = {
++      .name = "SGI-IOC4 IDE",
++      .id_table = sgiioc4_pci_tbl,
++      .probe = sgiioc4_init_one,
++};
++
++static int
++sgiioc4_ide_init(void)
++{
++      return ide_pci_register_driver(&driver);
++}
++
++static void
++sgiioc4_ide_exit(void)
++{
++      ide_pci_unregister_driver(&driver);
++}
++
++module_init(sgiioc4_ide_init);
++module_exit(sgiioc4_ide_exit);
++
++MODULE_AUTHOR("Aniket Malatpure - Silicon Graphics Inc. (SGI)");
++MODULE_DESCRIPTION("PCI driver module for SGI IOC4 Base-IO Card");
++MODULE_LICENSE("GPL");
+--- linux-2.6.0/drivers/ide/pci/siimage.c      2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/ide/pci/siimage.c       2003-12-28 23:26:27.000000000 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * linux/drivers/ide/pci/siimage.c            Version 1.06    June 11, 2003
++ * linux/drivers/ide/pci/siimage.c            Version 1.09    Dec 7, 2003
+  *
+  * Copyright (C) 2001-2002    Andre Hedrick <andre@linux-ide.org>
+  * Copyright (C) 2003         Red Hat <alan@redhat.com>
+@@ -56,6 +56,7 @@ static int pdev_is_sata(struct pci_dev *
+       {
+               case PCI_DEVICE_ID_SII_3112:
+               case PCI_DEVICE_ID_SII_1210SA:
++              case PCI_DEVICE_ID_SII_3114:
+                       return 1;
+               case PCI_DEVICE_ID_SII_680:
+                       return 0;
+@@ -266,7 +267,7 @@ static byte siimage_taskfile_timing (ide
+ static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted)
+ {
+       ide_hwif_t *hwif        = HWIF(drive);
+-      u32 speedt              = 0;
++      u16 speedt              = 0;
+       u16 speedp              = 0;
+       unsigned long addr      = siimage_seldev(drive, 0x04);
+       unsigned long tfaddr    = siimage_selreg(hwif, 0x02);
+@@ -1047,6 +1048,27 @@ static void __init init_mmio_iops_siimag
+       hwif->mmio                      = 2;
+ }
++static int is_dev_seagate_sata(ide_drive_t *drive)
++{
++      const char *s = &drive->id->model[0];
++      unsigned len;
++
++      if (!drive->present)
++              return 0;
++
++      len = strnlen(s, sizeof(drive->id->model));
++
++      if ((len > 4) && (!memcmp(s, "ST", 2))) {
++              if ((!memcmp(s + len - 2, "AS", 2)) ||
++                  (!memcmp(s + len - 3, "ASL", 3))) {
++                      printk(KERN_INFO "%s: applying pessimistic Seagate "
++                                       "errata fix\n", drive->name);
++                      return 1;
++              }
++      }
++      return 0;
++}
++
+ /**
+  *    init_iops_siimage       -       set up iops
+  *    @hwif: interface to set up
+@@ -1068,7 +1090,7 @@ static void __init init_iops_siimage (id
+       hwif->hwif_data = 0;
+       hwif->rqsize = 128;
+-      if (is_sata(hwif))
++      if (is_sata(hwif) && is_dev_seagate_sata(&hwif->drives[0]))
+               hwif->rqsize = 15;
+       if (pci_get_drvdata(dev) == NULL)
+@@ -1179,6 +1201,7 @@ static struct pci_device_id siimage_pci_
+       { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+       { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
++      { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
+       { 0, },
+ };
+--- linux-2.6.0/drivers/ide/pci/siimage.h      2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/ide/pci/siimage.h       2003-12-28 23:26:27.000000000 -0800
+@@ -82,6 +82,16 @@ static ide_pci_device_t siimage_chipsets
+               .enablebits     = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+               .bootable       = ON_BOARD,
+               .extra          = 0,
++      },{     /* 3 */
++              .vendor         = PCI_VENDOR_ID_CMD,
++              .device         = PCI_DEVICE_ID_SII_3114,
++              .name           = "SiI3114 Serial ATA",
++              .init_chipset   = init_chipset_siimage,
++              .init_iops      = init_iops_siimage,
++              .init_hwif      = init_hwif_siimage,
++              .channels       = 2,
++              .autodma        = AUTODMA,
++              .bootable       = ON_BOARD,
+       },{
+               .vendor         = 0,
+               .device         = 0,
+--- linux-2.6.0/drivers/ide/setup-pci.c        2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/ide/setup-pci.c 2003-12-28 23:22:14.000000000 -0800
+@@ -474,6 +474,11 @@ fixup_address:
+  *    state
+  */
+  
++#ifndef CONFIG_BLK_DEV_IDEDMA_PCI
++static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
++{
++}
++#else
+ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
+ {
+       u16 pcicmd;
+@@ -516,6 +521,7 @@ static void ide_hwif_setup_dma(struct pc
+               }
+       }
+ }
++#endif /* CONFIG_BLK_DEV_IDEDMA_PCI*/
+ /**
+  *    ide_setup_pci_controller        -       set up IDE PCI
+--- linux-2.6.0/drivers/ieee1394/dma.c 2003-07-27 12:14:38.000000000 -0700
++++ 25/drivers/ieee1394/dma.c  2003-12-28 23:22:12.000000000 -0800
+@@ -187,7 +187,7 @@ void dma_region_sync(struct dma_region *
+ /* nopage() handler for mmap access */
+ static struct page*
+-dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int write_access)
++dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int *type)
+ {
+       unsigned long offset;
+       unsigned long kernel_virt_addr;
+@@ -202,6 +202,8 @@ dma_region_pagefault(struct vm_area_stru
+           (address > (unsigned long) area->vm_start + (PAGE_SIZE * dma->n_pages)) )
+               goto out;
++      if (type)
++              *type = VM_FAULT_MINOR;
+       offset = address - area->vm_start;
+       kernel_virt_addr = (unsigned long) dma->kvirt + offset;
+       ret = vmalloc_to_page((void*) kernel_virt_addr);
+--- linux-2.6.0/drivers/ieee1394/eth1394.c     2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ieee1394/eth1394.c      2003-12-28 23:23:03.000000000 -0800
+@@ -89,7 +89,7 @@
+ #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
+ static char version[] __devinitdata =
+-      "$Rev: 1043 $ Ben Collins <bcollins@debian.org>";
++      "$Rev: 1079 $ Ben Collins <bcollins@debian.org>";
+ struct fragment_info {
+       struct list_head list;
+@@ -220,7 +220,7 @@ static int ether1394_init_bc(struct net_
+                       priv->iso = hpsb_iso_recv_init(priv->host, 16 * 4096,
+                                                      16, priv->broadcast_channel,
+-                                                     1, ether1394_iso);
++                                                     HPSB_ISO_DMA_PACKET_PER_BUFFER, 1, ether1394_iso);
+                       if (priv->iso == NULL) {
+                               ETH1394_PRINT(KERN_ERR, dev->name,
+                                             "failed to change broadcast "
+@@ -375,8 +375,8 @@ static void ether1394_reset_priv (struct
+       }
+ }
+-/* This function is called by register_netdev */
+-static int ether1394_init_dev (struct net_device *dev)
++/* This function is called right before register_netdev */
++static void ether1394_init_dev (struct net_device *dev)
+ {
+       /* Our functions */
+       dev->open               = ether1394_open;
+@@ -403,8 +403,6 @@ static int ether1394_init_dev (struct ne
+       dev->type               = ARPHRD_IEEE1394;
+       ether1394_reset_priv (dev, 1);
+-
+-      return 0;
+ }
+ /*
+@@ -437,8 +435,6 @@ static void ether1394_add_host (struct h
+       SET_MODULE_OWNER(dev);
+-      dev->init = ether1394_init_dev;
+-
+       priv = (struct eth1394_priv *)dev->priv;
+       spin_lock_init(&priv->lock);
+@@ -459,6 +455,8 @@ static void ether1394_add_host (struct h
+               goto out;
+         }
++      ether1394_init_dev(dev);
++
+       if (register_netdev (dev)) {
+               ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n");
+               goto out;
+@@ -475,7 +473,7 @@ static void ether1394_add_host (struct h
+       priv->broadcast_channel = host->csr.broadcast_channel & 0x3f;
+       priv->iso = hpsb_iso_recv_init(host, 16 * 4096, 16, priv->broadcast_channel,
+-                                     1, ether1394_iso);
++                                      HPSB_ISO_DMA_PACKET_PER_BUFFER, 1, ether1394_iso);
+       if (priv->iso == NULL) {
+               priv->bc_state = ETHER1394_BC_CLOSED;
+       }
+@@ -483,7 +481,7 @@ static void ether1394_add_host (struct h
+ out:
+       if (dev != NULL)
+-              kfree(dev);
++              free_netdev(dev);
+       if (hi)
+               hpsb_destroy_hostinfo(&eth1394_highlevel, host);
+@@ -1258,7 +1256,7 @@ static inline struct hpsb_packet *ether1
+ {
+       struct hpsb_packet *p;
+-      p = alloc_hpsb_packet(0);
++      p = hpsb_alloc_packet(0);
+       if (p) {
+               p->host = host;
+               p->data = NULL;
+@@ -1327,7 +1325,7 @@ static inline void ether1394_free_packet
+       if (packet->tcode != TCODE_STREAM_DATA)
+               hpsb_free_tlabel(packet);
+       packet->data = NULL;
+-      free_hpsb_packet(packet);
++      hpsb_free_packet(packet);
+ }
+ static void ether1394_complete_cb(void *__ptask);
+@@ -1349,7 +1347,7 @@ static int ether1394_send_packet(struct 
+                                              ptask->dest_node,
+                                              ptask->addr, ptask->skb->data,
+                                              tx_len)) {
+-              free_hpsb_packet(packet);
++              hpsb_free_packet(packet);
+               return -1;
+       }
+@@ -1357,7 +1355,7 @@ static int ether1394_send_packet(struct 
+       hpsb_set_packet_complete_task(ptask->packet, ether1394_complete_cb,
+                                     ptask);
+-      if (!hpsb_send_packet(packet)) {
++      if (hpsb_send_packet(packet) < 0) {
+               ether1394_free_packet(packet);
+               return -1;
+       }
+@@ -1599,7 +1597,7 @@ static int ether1394_ethtool_ioctl(struc
+               case ETHTOOL_GDRVINFO: {
+                       struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+                       strcpy (info.driver, driver_name);
+-                      strcpy (info.version, "$Rev: 1043 $");
++                      strcpy (info.version, "$Rev: 1079 $");
+                       /* FIXME XXX provide sane businfo */
+                       strcpy (info.bus_info, "ieee1394");
+                       if (copy_to_user (useraddr, &info, sizeof (info)))
+--- linux-2.6.0/drivers/ieee1394/highlevel.c   2003-11-26 13:53:35.000000000 -0800
++++ 25/drivers/ieee1394/highlevel.c    2003-12-28 23:23:03.000000000 -0800
+@@ -26,6 +26,7 @@
+ #include "hosts.h"
+ #include "ieee1394_core.h"
+ #include "highlevel.h"
++#include "nodemgr.h"
+ struct hl_host_info {
+@@ -227,10 +228,17 @@ struct hpsb_host *hpsb_get_host_bykey(st
+       return host;
+ }
++static int highlevel_for_each_host_reg(struct hpsb_host *host, void *__data)
++{
++      struct hpsb_highlevel *hl = __data;
++
++      hl->add_host(host);
++
++      return 0;
++}
+ void hpsb_register_highlevel(struct hpsb_highlevel *hl)
+ {
+-      struct list_head *lh;
+       unsigned long flags;
+         INIT_LIST_HEAD(&hl->addr_list);
+@@ -242,21 +250,25 @@ void hpsb_register_highlevel(struct hpsb
+         list_add_tail(&hl->hl_list, &hl_drivers);
+       write_unlock_irqrestore(&hl_drivers_lock, flags);
+-      if (hl->add_host) {
+-              down(&hpsb_hosts_lock);
+-              list_for_each (lh, &hpsb_hosts) {
+-                      struct hpsb_host *host = list_entry(lh, struct hpsb_host, host_list);
+-                      hl->add_host(host);
+-              }
+-              up(&hpsb_hosts_lock);
+-      }
++      if (hl->add_host)
++              nodemgr_for_each_host(hl, highlevel_for_each_host_reg);
+         return;
+ }
++static int highlevel_for_each_host_unreg(struct hpsb_host *host, void *__data)
++{
++      struct hpsb_highlevel *hl = __data;
++
++      hl->remove_host(host);
++      hpsb_destroy_hostinfo(hl, host);
++
++      return 0;
++}
++
+ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl)
+ {
+-        struct list_head *lh, *next;
++      struct list_head *lh, *next;
+         struct hpsb_address_serve *as;
+       unsigned long flags;
+@@ -272,16 +284,8 @@ void hpsb_unregister_highlevel(struct hp
+         list_del(&hl->hl_list);
+       write_unlock_irqrestore(&hl_drivers_lock, flags);
+-        if (hl->remove_host) {
+-              down(&hpsb_hosts_lock);
+-              list_for_each(lh, &hpsb_hosts) {
+-                      struct hpsb_host *host = list_entry(lh, struct hpsb_host, host_list);
+-
+-                      hl->remove_host(host);
+-                      hpsb_destroy_hostinfo(hl, host);
+-              }
+-              up(&hpsb_hosts_lock);
+-      }
++        if (hl->remove_host)
++              nodemgr_for_each_host(hl, highlevel_for_each_host_unreg);
+ }
+ int hpsb_register_addrspace(struct hpsb_highlevel *hl,
+--- linux-2.6.0/drivers/ieee1394/highlevel.h   2003-08-08 22:55:11.000000000 -0700
++++ 25/drivers/ieee1394/highlevel.h    2003-12-28 23:23:03.000000000 -0800
+@@ -92,8 +92,6 @@ struct hpsb_address_ops {
+ };
+-void init_hpsb_highlevel(void);
+-
+ void highlevel_add_host(struct hpsb_host *host);
+ void highlevel_remove_host(struct hpsb_host *host);
+ void highlevel_host_reset(struct hpsb_host *host);
+@@ -180,4 +178,7 @@ int hpsb_set_hostinfo(struct hpsb_highle
+ /* Retrieve hpsb_host using a highlevel handle and a key */
+ struct hpsb_host *hpsb_get_host_bykey(struct hpsb_highlevel *hl, unsigned long key);
++/* Initialize the highlevel system */
++void init_hpsb_highlevel(void);
++
+ #endif /* IEEE1394_HIGHLEVEL_H */
+--- linux-2.6.0/drivers/ieee1394/hosts.c       2003-11-26 13:53:35.000000000 -0800
++++ 25/drivers/ieee1394/hosts.c        2003-12-28 23:23:03.000000000 -0800
+@@ -16,14 +16,14 @@
+ #include <linux/list.h>
+ #include <linux/init.h>
+ #include <linux/slab.h>
++#include <linux/pci.h>
+ #include "ieee1394_types.h"
+ #include "hosts.h"
+ #include "ieee1394_core.h"
+ #include "highlevel.h"
++#include "nodemgr.h"
+-LIST_HEAD(hpsb_hosts);
+-DECLARE_MUTEX(hpsb_hosts_lock);
+ static int dummy_transmit_packet(struct hpsb_host *h, struct hpsb_packet *p)
+ {
+@@ -46,54 +46,14 @@ static struct hpsb_host_driver dummy_dri
+       .isoctl =          dummy_isoctl
+ };
+-/**
+- * hpsb_ref_host - increase reference count for host controller.
+- * @host: the host controller
+- *
+- * Increase the reference count for the specified host controller.
+- * When holding a reference to a host, the memory allocated for the
+- * host struct will not be freed and the host is guaranteed to be in a
+- * consistent state.  The driver may be unloaded or the controller may
+- * be removed (PCMCIA), but the host struct will remain valid.
+- */
+-
+-int hpsb_ref_host(struct hpsb_host *host)
++static int alloc_hostnum_cb(struct hpsb_host *host, void *__data)
+ {
+-        struct list_head *lh;
+-        int retval = 0;
+-
+-      down(&hpsb_hosts_lock);
+-        list_for_each(lh, &hpsb_hosts) {
+-                if (host == list_entry(lh, struct hpsb_host, host_list)) {
+-                      if (try_module_get(host->driver->owner)) {
+-                              atomic_inc(&host->refcount);
+-                              retval = 1;
+-                      }
+-                      break;
+-              }
+-        }
+-      up(&hpsb_hosts_lock);
+-
+-        return retval;
+-}
++      int *hostnum = __data;
+-/**
+- * hpsb_unref_host - decrease reference count for host controller.
+- * @host: the host controller
+- *
+- * Decrease the reference count for the specified host controller.
+- * When the reference count reaches zero, the memory allocated for the
+- * &hpsb_host will be freed.
+- */
+-
+-void hpsb_unref_host(struct hpsb_host *host)
+-{
+-      module_put(host->driver->owner);
++      if (host->id == *hostnum)
++              return 1;
+-      down(&hpsb_hosts_lock);
+-        if (atomic_dec_and_test(&host->refcount) && host->is_shutdown)
+-              device_unregister(&host->device);
+-      up(&hpsb_hosts_lock);
++      return 0;
+ }
+ /**
+@@ -108,19 +68,16 @@ void hpsb_unref_host(struct hpsb_host *h
+  * driver specific parts, enable the controller and make it available
+  * to the general subsystem using hpsb_add_host().
+  *
+- * The &hpsb_host is allocated with an single initial reference
+- * belonging to the driver.  Once the driver is done with the struct,
+- * for example, when the driver is unloaded, it should release this
+- * reference using hpsb_unref_host().
+- *
+  * Return Value: a pointer to the &hpsb_host if succesful, %NULL if
+  * no memory was available.
+  */
+-struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra)
++struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
++                                struct device *dev)
+ {
+         struct hpsb_host *h;
+       int i;
++      int hostnum = 0;
+         h = kmalloc(sizeof(struct hpsb_host) + extra, SLAB_KERNEL);
+         if (!h) return NULL;
+@@ -128,7 +85,6 @@ struct hpsb_host *hpsb_alloc_host(struct
+       h->hostdata = h + 1;
+         h->driver = drv;
+-      atomic_set(&h->refcount, 1);
+         INIT_LIST_HEAD(&h->pending_packets);
+         spin_lock_init(&h->pending_pkt_lock);
+@@ -146,53 +102,35 @@ struct hpsb_host *hpsb_alloc_host(struct
+         h->topology_map = h->csr.topology_map + 3;
+         h->speed_map = (u8 *)(h->csr.speed_map + 2);
+-      return h;
+-}
+-
+-static int alloc_hostnum(void)
+-{
+-      int hostnum = 0;
+-
+       while (1) {
+-              struct list_head *lh;
+-              int found = 0;
+-
+-              list_for_each(lh, &hpsb_hosts) {
+-                      struct hpsb_host *host = list_entry(lh, struct hpsb_host, host_list);
+-
+-                      if (host->id == hostnum) {
+-                              found = 1;
+-                              break;
+-                      }
++              if (!nodemgr_for_each_host(&hostnum, alloc_hostnum_cb)) {
++                      h->id = hostnum;
++                      break;
+               }
+-              if (!found)
+-                      return hostnum;
+-
+               hostnum++;
+       }
+-      return 0;
++      memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device));
++      h->device.parent = dev;
++      snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id);
++      device_register(&h->device);
++
++      return h;
+ }
+ void hpsb_add_host(struct hpsb_host *host)
+ {
+-      down(&hpsb_hosts_lock);
+-      host->id = alloc_hostnum();
+-        list_add_tail(&host->host_list, &hpsb_hosts);
+-      up(&hpsb_hosts_lock);
+-
+         highlevel_add_host(host);
+         host->driver->devctl(host, RESET_BUS, LONG_RESET);
+ }
+ void hpsb_remove_host(struct hpsb_host *host)
+ {
+-      down(&hpsb_hosts_lock);
+         host->is_shutdown = 1;
+         host->driver = &dummy_driver;
+-      list_del(&host->host_list);
+-      up(&hpsb_hosts_lock);
+         highlevel_remove_host(host);
++
++      device_unregister(&host->device);
+ }
+--- linux-2.6.0/drivers/ieee1394/hosts.h       2003-07-27 12:14:38.000000000 -0700
++++ 25/drivers/ieee1394/hosts.h        2003-12-28 23:23:03.000000000 -0800
+@@ -29,8 +29,6 @@ struct hpsb_host {
+         atomic_t generation;
+-      atomic_t refcount;
+-
+         struct list_head pending_packets;
+         spinlock_t pending_pkt_lock;
+       struct timer_list timeout;
+@@ -165,7 +163,7 @@ struct hpsb_host_driver {
+          * packet->type == raw) and do byte-swapping as necessary or instruct
+          * the hardware to do so.  It can return immediately after the packet
+          * was queued for sending.  After sending, hpsb_sent_packet() has to be
+-         * called.  Return 0 for failure.
++         * called.  Return 0 on success, negative errno on failure.
+          * NOTE: The function must be callable in interrupt context.
+          */
+         int (*transmit_packet) (struct hpsb_host *host, 
+@@ -195,22 +193,8 @@ struct hpsb_host_driver {
+ };
+-extern struct list_head hpsb_hosts;
+-extern struct semaphore hpsb_hosts_lock;
+-
+-
+-/*
+- * In order to prevent hosts from unloading, use hpsb_ref_host().  This prevents
+- * the host from going away (e.g. makes module unloading of the driver
+- * impossible), but still can not guarantee it (e.g. PC-Card being pulled by the
+- * user).  hpsb_ref_host() returns false if host could not be locked.  If it is
+- * successful, host is valid as a pointer until hpsb_unref_host() (not just
+- * until after remove_host).
+- */
+-int hpsb_ref_host(struct hpsb_host *host);
+-void hpsb_unref_host(struct hpsb_host *host);
+-
+-struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra);
++struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
++                                struct device *dev);
+ void hpsb_add_host(struct hpsb_host *host);
+ void hpsb_remove_host(struct hpsb_host *h);
+--- linux-2.6.0/drivers/ieee1394/ieee1394_core.c       2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ieee1394/ieee1394_core.c        2003-12-28 23:23:03.000000000 -0800
+@@ -109,7 +109,7 @@ void hpsb_set_packet_complete_task(struc
+ }
+ /**
+- * alloc_hpsb_packet - allocate new packet structure
++ * hpsb_alloc_packet - allocate new packet structure
+  * @data_size: size of the data block to be allocated
+  *
+  * This function allocates, initializes and returns a new &struct hpsb_packet.
+@@ -128,7 +128,7 @@ void hpsb_set_packet_complete_task(struc
+  * Return value: A pointer to a &struct hpsb_packet or NULL on allocation
+  * failure.
+  */
+-struct hpsb_packet *alloc_hpsb_packet(size_t data_size)
++struct hpsb_packet *hpsb_alloc_packet(size_t data_size)
+ {
+         struct hpsb_packet *packet = NULL;
+         void *data = NULL;
+@@ -152,25 +152,23 @@ struct hpsb_packet *alloc_hpsb_packet(si
+         }
+         INIT_LIST_HEAD(&packet->list);
+-        sema_init(&packet->state_change, 0);
+       packet->complete_routine = NULL;
+       packet->complete_data = NULL;
+         packet->state = hpsb_unused;
+         packet->generation = -1;
+-        packet->data_be = 1;
+         return packet;
+ }
+ /**
+- * free_hpsb_packet - free packet and data associated with it
++ * hpsb_free_packet - free packet and data associated with it
+  * @packet: packet to free (is NULL safe)
+  *
+  * This function will free packet->data, packet->header and finally the packet
+  * itself.
+  */
+-void free_hpsb_packet(struct hpsb_packet *packet)
++void hpsb_free_packet(struct hpsb_packet *packet)
+ {
+         if (!packet) return;
+@@ -420,14 +418,12 @@ void hpsb_packet_sent(struct hpsb_host *
+         if (packet->no_waiter) {
+                 /* must not have a tlabel allocated */
+-                free_hpsb_packet(packet);
++                hpsb_free_packet(packet);
+                 return;
+         }
+         if (ackcode != ACK_PENDING || !packet->expect_response) {
+                 packet->state = hpsb_complete;
+-                up(&packet->state_change);
+-                up(&packet->state_change);
+                 run_packet_complete(packet);
+                 return;
+         }
+@@ -439,7 +435,6 @@ void hpsb_packet_sent(struct hpsb_host *
+         list_add_tail(&packet->list, &host->pending_packets);
+         spin_unlock_irqrestore(&host->pending_pkt_lock, flags);
+-        up(&packet->state_change);
+       mod_timer(&host->timeout, jiffies + host->timeout_interval);
+ }
+@@ -465,7 +460,7 @@ int hpsb_send_phy_config(struct hpsb_hos
+               return -EINVAL;
+       }
+-      packet = alloc_hpsb_packet(0);
++      packet = hpsb_alloc_packet(0);
+       if (!packet)
+               return -ENOMEM;
+@@ -485,16 +480,8 @@ int hpsb_send_phy_config(struct hpsb_hos
+       packet->generation = get_hpsb_generation(host);
+-      if (!hpsb_send_packet(packet)) {
+-              retval = -EINVAL;
+-              goto fail;
+-      }
+-
+-      down(&packet->state_change);
+-      down(&packet->state_change);
+-
+-fail:
+-      free_hpsb_packet(packet);
++      retval = hpsb_send_packet_and_wait(packet);
++      hpsb_free_packet(packet);
+       return retval;
+ }
+@@ -504,23 +491,24 @@ fail:
+  * @packet: packet to send
+  *
+  * The packet is sent through the host specified in the packet->host field.
+- * Before sending, the packet's transmit speed is automatically determined using
+- * the local speed map when it is an async, non-broadcast packet.
++ * Before sending, the packet's transmit speed is automatically determined
++ * using the local speed map when it is an async, non-broadcast packet.
+  *
+  * Possibilities for failure are that host is either not initialized, in bus
+  * reset, the packet's generation number doesn't match the current generation
+  * number or the host reports a transmit error.
+  *
+- * Return value: False (0) on failure, true (1) otherwise.
++ * Return value: 0 on success, negative errno on failure.
+  */
+ int hpsb_send_packet(struct hpsb_packet *packet)
+ {
+         struct hpsb_host *host = packet->host;
+-        if (host->is_shutdown || host->in_bus_reset
+-            || (packet->generation != get_hpsb_generation(host))) {
+-                return 0;
+-        }
++        if (host->is_shutdown)
++              return -EINVAL;
++      if (host->in_bus_reset ||
++          (packet->generation != get_hpsb_generation(host)))
++                return -EAGAIN;
+         packet->state = hpsb_queued;
+@@ -532,23 +520,13 @@ int hpsb_send_packet(struct hpsb_packet 
+                 data = kmalloc(packet->header_size + packet->data_size, GFP_ATOMIC);
+                 if (!data) {
+                         HPSB_ERR("unable to allocate memory for concatenating header and data");
+-                        return 0;
++                        return -ENOMEM;
+                 }
+                 memcpy(data, packet->header, packet->header_size);
+                 if (packet->data_size)
+-                {
+-                        if (packet->data_be) {
+-                                memcpy(((u8*)data)+packet->header_size, packet->data, packet->data_size);
+-                        } else {
+-                                int i;
+-                                quadlet_t *my_data=(quadlet_t*) ((u8*) data + packet->data_size);
+-                                for (i=0; i < packet->data_size/4; i++) {
+-                                        my_data[i] = cpu_to_be32(packet->data[i]);
+-                                }
+-                        }
+-                }
++                      memcpy(((u8*)data)+packet->header_size, packet->data, packet->data_size);
+                 dump_packet("send packet local:", packet->header,
+                             packet->header_size);
+@@ -558,7 +536,7 @@ int hpsb_send_packet(struct hpsb_packet 
+                 kfree(data);
+-                return 1;
++                return 0;
+         }
+         if (packet->type == hpsb_async && packet->node_id != ALL_NODES) {
+@@ -584,10 +562,33 @@ int hpsb_send_packet(struct hpsb_packet 
+         return host->driver->transmit_packet(host, packet);
+ }
++/* We could just use complete() directly as the packet complete
++ * callback, but this is more typesafe, in the sense that we get a
++ * compiler error if the prototype for complete() changes. */
++
++static void complete_packet(void *data)
++{
++      complete((struct completion *) data);
++}
++
++int hpsb_send_packet_and_wait(struct hpsb_packet *packet)
++{
++      struct completion done;
++      int retval;
++
++      init_completion(&done);
++      hpsb_set_packet_complete_task(packet, complete_packet, &done);
++      retval = hpsb_send_packet(packet);
++      if (retval == 0)
++              wait_for_completion(&done);
++
++      return retval;
++}
++
+ static void send_packet_nocare(struct hpsb_packet *packet)
+ {
+-        if (!hpsb_send_packet(packet)) {
+-                free_hpsb_packet(packet);
++        if (hpsb_send_packet(packet) < 0) {
++                hpsb_free_packet(packet);
+         }
+ }
+@@ -668,7 +669,6 @@ void handle_packet_response(struct hpsb_
+         }
+         packet->state = hpsb_complete;
+-        up(&packet->state_change);
+       run_packet_complete(packet);
+ }
+@@ -680,7 +680,7 @@ static struct hpsb_packet *create_reply_
+         dsize += (dsize % 4 ? 4 - (dsize % 4) : 0);
+-        p = alloc_hpsb_packet(dsize);
++        p = hpsb_alloc_packet(dsize);
+         if (p == NULL) {
+                 /* FIXME - send data_error response */
+                 return NULL;
+@@ -820,6 +820,8 @@ static void handle_incoming_packet(struc
+                 if (rcode >= 0) {
+                         fill_async_readblock_resp(packet, rcode, length);
+                         send_packet_nocare(packet);
++                } else {
++                        hpsb_free_packet(packet);
+                 }
+                 break;
+@@ -874,7 +876,7 @@ static void handle_incoming_packet(struc
+                 if (rcode >= 0) {
+                         send_packet_nocare(packet);
+                 } else {
+-                        free_hpsb_packet(packet);
++                        hpsb_free_packet(packet);
+                 }
+                 break;
+         }
+@@ -949,7 +951,6 @@ void abort_requests(struct hpsb_host *ho
+                 list_del(&packet->list);
+                 packet->state = hpsb_complete;
+                 packet->ack_code = ACKX_ABORTED;
+-                up(&packet->state_change);
+               run_packet_complete(packet);
+         }
+ }
+@@ -987,7 +988,6 @@ void abort_timedouts(unsigned long __opa
+                 list_del(&packet->list);
+                 packet->state = hpsb_complete;
+                 packet->ack_code = ACKX_TIMEOUT;
+-                up(&packet->state_change);
+               run_packet_complete(packet);
+         }
+ }
+@@ -1171,19 +1171,22 @@ static int ieee1394_dispatch_open(struct
+ static int __init ieee1394_init(void)
+ {
+-      hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet),
+-                                            0, 0, NULL, NULL);
+-
+       devfs_mk_dir("ieee1394");
+-
+       if (register_chrdev(IEEE1394_MAJOR, "ieee1394", &ieee1394_chardev_ops)) {
+               HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR);
+-              devfs_remove("ieee1394");
+               return -ENODEV;
+       }
++      devfs_mk_dir("ieee1394");
++
++      hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet),
++                                            0, 0, NULL, NULL);
++
++      bus_register(&ieee1394_bus_type);
++
+       init_hpsb_highlevel();
+       init_csr();
++
+       if (!disable_nodemgr)
+               init_ieee1394_nodemgr();
+       else
+@@ -1198,6 +1201,9 @@ static void __exit ieee1394_cleanup(void
+               cleanup_ieee1394_nodemgr();
+       cleanup_csr();
++
++      bus_unregister(&ieee1394_bus_type);
++
+       kmem_cache_destroy(hpsb_packet_cache);
+       unregister_chrdev(IEEE1394_MAJOR, "ieee1394");
+@@ -1213,16 +1219,15 @@ module_exit(ieee1394_cleanup);
+ EXPORT_SYMBOL(hpsb_alloc_host);
+ EXPORT_SYMBOL(hpsb_add_host);
+ EXPORT_SYMBOL(hpsb_remove_host);
+-EXPORT_SYMBOL(hpsb_ref_host);
+-EXPORT_SYMBOL(hpsb_unref_host);
+ /** ieee1394_core.c **/
+ EXPORT_SYMBOL(hpsb_speedto_str);
+ EXPORT_SYMBOL(hpsb_set_packet_complete_task);
+-EXPORT_SYMBOL(alloc_hpsb_packet);
+-EXPORT_SYMBOL(free_hpsb_packet);
++EXPORT_SYMBOL(hpsb_alloc_packet);
++EXPORT_SYMBOL(hpsb_free_packet);
+ EXPORT_SYMBOL(hpsb_send_phy_config);
+ EXPORT_SYMBOL(hpsb_send_packet);
++EXPORT_SYMBOL(hpsb_send_packet_and_wait);
+ EXPORT_SYMBOL(hpsb_reset_bus);
+ EXPORT_SYMBOL(hpsb_bus_reset);
+ EXPORT_SYMBOL(hpsb_selfid_received);
+@@ -1282,6 +1287,7 @@ EXPORT_SYMBOL(hpsb_node_lock);
+ EXPORT_SYMBOL(hpsb_register_protocol);
+ EXPORT_SYMBOL(hpsb_unregister_protocol);
+ EXPORT_SYMBOL(ieee1394_bus_type);
++EXPORT_SYMBOL(nodemgr_for_each_host);
+ /** csr.c **/
+ EXPORT_SYMBOL(hpsb_update_config_rom);
+--- linux-2.6.0/drivers/ieee1394/ieee1394_core.h       2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ieee1394/ieee1394_core.h        2003-12-28 23:23:03.000000000 -0800
+@@ -40,11 +40,6 @@ struct hpsb_packet {
+         unsigned expect_response:1;
+         unsigned no_waiter:1;
+-        /* Data big endianness flag - may vary from request to request.  The
+-         * header is always in machine byte order.
+-         * Not really used currently.  */
+-        unsigned data_be:1;
+-
+         /* Speed to transmit with: 0 = 100Mbps, 1 = 200Mbps, 2 = 400Mbps */
+         unsigned speed_code:2;
+@@ -64,9 +59,6 @@ struct hpsb_packet {
+         struct hpsb_host *host;
+         unsigned int generation;
+-        /* Very core internal, don't care. */
+-        struct semaphore state_change;
+-
+       /* Function (and possible data to pass to it) to call when this
+        * packet is completed.  */
+       void (*complete_routine)(void *);
+@@ -90,8 +82,8 @@ static inline struct hpsb_packet *driver
+ void abort_timedouts(unsigned long __opaque);
+ void abort_requests(struct hpsb_host *host);
+-struct hpsb_packet *alloc_hpsb_packet(size_t data_size);
+-void free_hpsb_packet(struct hpsb_packet *packet);
++struct hpsb_packet *hpsb_alloc_packet(size_t data_size);
++void hpsb_free_packet(struct hpsb_packet *packet);
+ /*
+@@ -108,15 +100,23 @@ static inline unsigned int get_hpsb_gene
+ }
+ /*
+- * Send a PHY configuration packet.
++ * Send a PHY configuration packet, return 0 on success, negative
++ * errno on failure.
+  */
+ int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt);
+ /*
+- * Queue packet for transmitting, return 0 for failure.
++ * Queue packet for transmitting, return 0 on success, negative errno
++ * on failure.
+  */
+ int hpsb_send_packet(struct hpsb_packet *packet);
++/*
++ * Queue packet for transmitting, and block until the transaction
++ * completes. Return 0 on success, negative errno on failure.
++ */
++int hpsb_send_packet_and_wait(struct hpsb_packet *packet);
++
+ /* Initiate bus reset on the given host.  Returns 1 if bus reset already in
+  * progress, 0 otherwise. */
+ int hpsb_reset_bus(struct hpsb_host *host, int type);
+--- linux-2.6.0/drivers/ieee1394/ieee1394_transactions.c       2003-11-26 13:53:35.000000000 -0800
++++ 25/drivers/ieee1394/ieee1394_transactions.c        2003-12-28 23:23:03.000000000 -0800
+@@ -263,7 +263,7 @@ struct hpsb_packet *hpsb_make_readpacket
+       if (length == 0)
+               return NULL;
+-      packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0));
++      packet = hpsb_alloc_packet(length + (length % 4 ? 4 - (length % 4) : 0));
+       if (!packet)
+               return NULL;
+@@ -271,7 +271,7 @@ struct hpsb_packet *hpsb_make_readpacket
+       packet->node_id = node;
+       if (hpsb_get_tlabel(packet)) {
+-              free_hpsb_packet(packet);
++              hpsb_free_packet(packet);
+               return NULL;
+       }
+@@ -291,7 +291,7 @@ struct hpsb_packet *hpsb_make_writepacke
+       if (length == 0)
+               return NULL;
+-      packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0));
++      packet = hpsb_alloc_packet(length + (length % 4 ? 4 - (length % 4) : 0));
+       if (!packet)
+               return NULL;
+@@ -302,7 +302,7 @@ struct hpsb_packet *hpsb_make_writepacke
+       packet->node_id = node;
+       if (hpsb_get_tlabel(packet)) {
+-              free_hpsb_packet(packet);
++              hpsb_free_packet(packet);
+               return NULL;
+       }
+@@ -325,7 +325,7 @@ struct hpsb_packet *hpsb_make_streampack
+       if (length == 0)
+               return NULL;
+-      packet = alloc_hpsb_packet(length + (length % 4 ? 4 - (length % 4) : 0));
++      packet = hpsb_alloc_packet(length + (length % 4 ? 4 - (length % 4) : 0));
+       if (!packet)
+               return NULL;
+@@ -335,7 +335,7 @@ struct hpsb_packet *hpsb_make_streampack
+       packet->host = host;
+     
+       if (hpsb_get_tlabel(packet)) {
+-              free_hpsb_packet(packet);
++              hpsb_free_packet(packet);
+               return NULL;
+       }
+@@ -353,13 +353,13 @@ struct hpsb_packet *hpsb_make_lockpacket
+       struct hpsb_packet *p;
+       u32 length;
+-      p = alloc_hpsb_packet(8);
++      p = hpsb_alloc_packet(8);
+       if (!p) return NULL;
+       p->host = host;
+       p->node_id = node;
+       if (hpsb_get_tlabel(p)) {
+-              free_hpsb_packet(p);
++              hpsb_free_packet(p);
+               return NULL;
+       }
+@@ -390,13 +390,13 @@ struct hpsb_packet *hpsb_make_lock64pack
+       struct hpsb_packet *p;
+       u32 length;
+-      p = alloc_hpsb_packet(16);
++      p = hpsb_alloc_packet(16);
+       if (!p) return NULL;
+       p->host = host;
+       p->node_id = node;
+       if (hpsb_get_tlabel(p)) {
+-              free_hpsb_packet(p);
++              hpsb_free_packet(p);
+               return NULL;
+       }
+@@ -429,7 +429,7 @@ struct hpsb_packet *hpsb_make_phypacket(
+ {
+         struct hpsb_packet *p; 
+-        p = alloc_hpsb_packet(0); 
++        p = hpsb_alloc_packet(0); 
+         if (!p) return NULL; 
+         p->host = host; 
+@@ -444,7 +444,7 @@ struct hpsb_packet *hpsb_make_isopacket(
+ {
+       struct hpsb_packet *p;
+-      p = alloc_hpsb_packet(length);
++      p = hpsb_alloc_packet(length);
+       if (!p) return NULL;
+       p->host = host;
+@@ -478,13 +478,10 @@ int hpsb_read(struct hpsb_host *host, no
+         }
+       packet->generation = generation;
+-        if (!hpsb_send_packet(packet)) {
+-              retval = -EINVAL;
++        retval = hpsb_send_packet_and_wait(packet);
++      if (retval < 0)
+               goto hpsb_read_fail;
+-      }
+-        down(&packet->state_change);
+-        down(&packet->state_change);
+         retval = hpsb_packet_success(packet);
+         if (retval == 0) {
+@@ -497,7 +494,7 @@ int hpsb_read(struct hpsb_host *host, no
+ hpsb_read_fail:
+         hpsb_free_tlabel(packet);
+-        free_hpsb_packet(packet);
++        hpsb_free_packet(packet);
+         return retval;
+ }
+@@ -520,18 +517,15 @@ int hpsb_write(struct hpsb_host *host, n
+               return -ENOMEM;
+       packet->generation = generation;
+-        if (!hpsb_send_packet(packet)) {
+-              retval = -EINVAL;
++        retval = hpsb_send_packet_and_wait(packet);
++      if (retval < 0)
+               goto hpsb_write_fail;
+-      }
+-        down(&packet->state_change);
+-        down(&packet->state_change);
+         retval = hpsb_packet_success(packet);
+ hpsb_write_fail:
+         hpsb_free_tlabel(packet);
+-        free_hpsb_packet(packet);
++        hpsb_free_packet(packet);
+         return retval;
+ }
+@@ -550,12 +544,10 @@ int hpsb_lock(struct hpsb_host *host, no
+                 return -ENOMEM;
+       packet->generation = generation;
+-        if (!hpsb_send_packet(packet)) {
+-              retval = -EINVAL;
++        retval = hpsb_send_packet_and_wait(packet);
++      if (retval < 0)
+               goto hpsb_lock_fail;
+-      }
+-        down(&packet->state_change);
+-        down(&packet->state_change);
++
+         retval = hpsb_packet_success(packet);
+         if (retval == 0) {
+@@ -564,7 +556,7 @@ int hpsb_lock(struct hpsb_host *host, no
+ hpsb_lock_fail:
+         hpsb_free_tlabel(packet);
+-        free_hpsb_packet(packet);
++        hpsb_free_packet(packet);
+         return retval;
+ }
+@@ -582,12 +574,10 @@ int hpsb_lock64(struct hpsb_host *host, 
+               return -ENOMEM;
+       packet->generation = generation;
+-      if (!hpsb_send_packet(packet)) {
+-              retval = -EINVAL;
++      retval = hpsb_send_packet_and_wait(packet);
++      if (retval < 0)
+               goto hpsb_lock64_fail;
+-      }
+-      down(&packet->state_change);
+-      down(&packet->state_change);
++
+       retval = hpsb_packet_success(packet);
+       if (retval == 0)
+@@ -595,7 +585,7 @@ int hpsb_lock64(struct hpsb_host *host, 
+ hpsb_lock64_fail:
+       hpsb_free_tlabel(packet);
+-      free_hpsb_packet(packet);
++      hpsb_free_packet(packet);
+         return retval;
+ }
+@@ -626,10 +616,9 @@ int hpsb_send_gasp(struct hpsb_host *hos
+       packet->no_waiter = 1;
+-      if (!hpsb_send_packet(packet)) {
+-              free_hpsb_packet(packet);
+-              retval = -EINVAL;
+-      }
++      retval = hpsb_send_packet(packet);
++      if (retval < 0)
++              hpsb_free_packet(packet);
+       return retval;
+ }
+--- linux-2.6.0/drivers/ieee1394/iso.c 2003-07-27 12:14:38.000000000 -0700
++++ 25/drivers/ieee1394/iso.c  2003-12-28 23:23:03.000000000 -0800
+@@ -40,6 +40,7 @@ static struct hpsb_iso* hpsb_iso_common_
+                                            unsigned int data_buf_size,
+                                            unsigned int buf_packets,
+                                            int channel,
++                                           int dma_mode,
+                                            int irq_interval,
+                                            void (*callback)(struct hpsb_iso*))
+ {
+@@ -58,8 +59,13 @@ static struct hpsb_iso* hpsb_iso_common_
+       if (buf_packets < 2)
+               buf_packets = 2;
+-      if (irq_interval < 1 || irq_interval > buf_packets / 2)
+-              irq_interval = buf_packets / 2;
++      if ((dma_mode < HPSB_ISO_DMA_DEFAULT) || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER))
++              dma_mode=HPSB_ISO_DMA_DEFAULT;
++
++      if (irq_interval == 0)     /* really interrupt for each packet*/
++              irq_interval = 1;
++      else if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
++              irq_interval = buf_packets / 4;
+       if (channel < -1 || channel >= 64)
+               return NULL;
+@@ -83,6 +89,7 @@ static struct hpsb_iso* hpsb_iso_common_
+       init_waitqueue_head(&iso->waitq);
+       iso->channel = channel;
+       iso->irq_interval = irq_interval;
++      iso->dma_mode = dma_mode;
+       dma_region_init(&iso->data_buf);
+       iso->buf_size = round_up_to_page(data_buf_size);
+       iso->buf_packets = buf_packets;
+@@ -136,7 +143,7 @@ struct hpsb_iso* hpsb_iso_xmit_init(stru
+ {
+       struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT,
+                                                   data_buf_size, buf_packets,
+-                                                  channel, irq_interval, callback);
++                                                  channel, HPSB_ISO_DMA_DEFAULT, irq_interval, callback);
+       if (!iso)
+               return NULL;
+@@ -158,12 +165,13 @@ struct hpsb_iso* hpsb_iso_recv_init(stru
+                                   unsigned int data_buf_size,
+                                   unsigned int buf_packets,
+                                   int channel,
++                                  int dma_mode,
+                                   int irq_interval,
+                                   void (*callback)(struct hpsb_iso*))
+ {
+       struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV,
+                                                   data_buf_size, buf_packets,
+-                                                  channel, irq_interval, callback);
++                                                  channel, dma_mode, irq_interval, callback);
+       if (!iso)
+               return NULL;
+--- linux-2.6.0/drivers/ieee1394/iso.h 2003-07-27 12:14:38.000000000 -0700
++++ 25/drivers/ieee1394/iso.h  2003-12-28 23:23:03.000000000 -0800
+@@ -51,6 +51,14 @@ struct hpsb_iso_packet_info {
+ enum hpsb_iso_type { HPSB_ISO_RECV = 0, HPSB_ISO_XMIT = 1 };
++/* The mode of the dma when receiving iso data. Must be supported by chip */
++enum raw1394_iso_dma_recv_mode {
++      HPSB_ISO_DMA_DEFAULT = -1,
++      HPSB_ISO_DMA_OLD_ABI = 0,
++      HPSB_ISO_DMA_BUFFERFILL = 1,
++      HPSB_ISO_DMA_PACKET_PER_BUFFER = 2
++};
++
+ struct hpsb_iso {
+       enum hpsb_iso_type type;
+@@ -68,6 +76,8 @@ struct hpsb_iso {
+       int speed; /* IEEE1394_SPEED_100, 200, or 400 */
+       int channel; /* -1 if multichannel */
++      int dma_mode; /* dma receive mode */
++
+       /* greatest # of packets between interrupts - controls
+          the maximum latency of the buffer */
+@@ -139,6 +149,7 @@ struct hpsb_iso* hpsb_iso_recv_init(stru
+                                   unsigned int data_buf_size,
+                                   unsigned int buf_packets,
+                                   int channel,
++                                  int dma_mode,
+                                   int irq_interval,
+                                   void (*callback)(struct hpsb_iso*));
+--- linux-2.6.0/drivers/ieee1394/Kconfig       2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/ieee1394/Kconfig        2003-12-28 23:23:03.000000000 -0800
+@@ -1,7 +1,7 @@
+ # -*- shell-script -*-
+ menu "IEEE 1394 (FireWire) support (EXPERIMENTAL)"
+-      depends on PCI && EXPERIMENTAL
++      depends on EXPERIMENTAL
+ config IEEE1394
+       tristate "IEEE 1394 (FireWire) support (EXPERIMENTAL)"
+@@ -15,7 +15,7 @@ config IEEE1394
+         is the core support only, you will also need to select a driver for
+         your IEEE 1394 adapter.
+-        To compile this driver as a module, choose M here: the
++        To compile this driver as a module, say M here: the
+         module will be called ieee1394.
+ comment "Subsystem Options"
+@@ -56,13 +56,13 @@ comment "Texas Instruments PCILynx requi
+ config IEEE1394_PCILYNX
+       tristate "Texas Instruments PCILynx support"
+-      depends on IEEE1394 && I2C_ALGOBIT
++      depends on PCI && IEEE1394 && I2C_ALGOBIT
+       help
+         Say Y here if you have an IEEE-1394 controller with the Texas
+         Instruments PCILynx chip.  Note: this driver is written for revision
+         2 of this chip and may not work with revision 0.
+-        To compile this driver as a module, choose M here: the
++        To compile this driver as a module, say M here: the
+         module will be called pcilynx.
+ # Non-maintained pcilynx options
+@@ -72,7 +72,7 @@ config IEEE1394_PCILYNX
+ # fi
+ config IEEE1394_OHCI1394
+       tristate "OHCI-1394 support"
+-      depends on IEEE1394
++      depends on PCI && IEEE1394
+       help
+         Enable this driver if you have an IEEE 1394 controller based on the
+         OHCI-1394 specification. The current driver is only tested with OHCI
+@@ -80,7 +80,7 @@ config IEEE1394_OHCI1394
+         use one of these chipsets.  It should work with any OHCI-1394
+         compliant card, however.
+-        To compile this driver as a module, choose M here: the
++        To compile this driver as a module, say M here: the
+         module will be called ohci1394.
+ comment "Protocol Drivers"
+@@ -122,7 +122,7 @@ config IEEE1394_DV1394
+         The user-space API for dv1394 is documented in dv1394.h.
+-        To compile this driver as a module, choose M here: the
++        To compile this driver as a module, say M here: the
+         module will be called dv1394.
+ config IEEE1394_RAWIO
+@@ -134,7 +134,7 @@ config IEEE1394_RAWIO
+         direct communication of user programs with the IEEE 1394 bus and
+         thus with the attached peripherals.
+-        To compile this driver as a module, choose M here: the
++        To compile this driver as a module, say M here: the
+         module will be called raw1394.
+ config IEEE1394_CMP
+@@ -144,7 +144,7 @@ config IEEE1394_CMP
+         This option enables the Connection Management Procedures
+         (IEC61883-1) driver, which implements input and output plugs.
+-        To compile this driver as a module, choose M here: the
++        To compile this driver as a module, say M here: the
+         module will be called cmp.
+ config IEEE1394_AMDTP
+@@ -157,7 +157,7 @@ config IEEE1394_AMDTP
+         The userspace interface is documented in amdtp.h.
+-        To compile this driver as a module, choose M here: the
++        To compile this driver as a module, say M here: the
+         module will be called amdtp.
+ endmenu
+--- linux-2.6.0/drivers/ieee1394/nodemgr.c     2003-11-26 13:53:35.000000000 -0800
++++ 25/drivers/ieee1394/nodemgr.c      2003-12-28 23:23:03.000000000 -0800
+@@ -516,8 +516,7 @@ static struct device nodemgr_dev_templat
+       .driver_data    = &nodemgr_driverdata_ne,
+ };
+-
+-static struct device nodemgr_dev_template_host = {
++struct device nodemgr_dev_template_host = {
+       .bus            = &ieee1394_bus_type,
+       .release        = nodemgr_release_host,
+       .driver         = &nodemgr_driver_host,
+@@ -1255,36 +1254,6 @@ void hpsb_unregister_protocol(struct hps
+ }
+-/* Searches the list of ud's that match a ne as the parent. If the ud has
+- * a driver associated with it, we call that driver's update function
+- * with the ud as the argument. */
+-static int nodemgr_driver_search_cb(struct device *dev, void *__data)
+-{
+-      struct node_entry *ne = __data;
+-      struct unit_directory *ud;
+-
+-      if (dev->driver_data == &nodemgr_driverdata_ne ||
+-          dev->driver_data == &nodemgr_driverdata_host)
+-              return 0;
+-
+-      ud = container_of(dev, struct unit_directory, device);
+-
+-      if (&ne->device != ud->device.parent)
+-              return 0;
+-
+-      if (ud->device.driver) {
+-              struct hpsb_protocol_driver *pdrv;
+-
+-              pdrv = container_of(ud->device.driver,
+-                              struct hpsb_protocol_driver, driver);
+-
+-              if (pdrv->update)
+-                      pdrv->update(ud);
+-      }
+-
+-      return 0;
+-}
+-
+ /*
+  * This function updates nodes that were present on the bus before the
+  * reset and still are after the reset.  The nodeid and the config rom
+@@ -1480,9 +1449,24 @@ static int nodemgr_probe_ne_cb(struct de
+               ne->needs_probe = 0;
+               return 1;
+       } else {
++              struct list_head *lh;
++
+               /* Update unit_dirs with attached drivers */
+-              bus_for_each_dev(&ieee1394_bus_type, NULL, ne,
+-                               nodemgr_driver_search_cb);
++              list_for_each(lh, &dev->children) {
++                      struct unit_directory *ud;
++                      
++                      ud = container_of(list_to_dev(lh), struct unit_directory, device);
++
++                      if (ud->device.driver) {
++                              struct hpsb_protocol_driver *pdrv;
++
++                              pdrv = container_of(ud->device.driver,
++                                                  struct hpsb_protocol_driver, driver);
++
++                              if (pdrv->update)
++                                      pdrv->update(ud);
++                      }
++              }
+       }
+       return 0;
+ }
+@@ -1664,7 +1648,6 @@ static int nodemgr_host_thread(void *__h
+       allow_signal(SIGTERM);
+       /* Setup our device-model entries */
+-      device_register(&host->device);
+       nodemgr_create_host_dev_files(host);
+       /* Sit and wait for a signal to probe the nodes on the bus. This
+@@ -1753,6 +1736,34 @@ struct node_entry *hpsb_nodeid_get_entry
+       return ne;
+ }
++struct for_each_host_struct {
++      int (*cb)(struct hpsb_host *, void *);
++      void *data;
++};
++
++static int nodemgr_for_each_host_cb(struct device *dev, void *__data)
++{
++      struct for_each_host_struct *host_data = __data;
++      struct hpsb_host *host;
++
++      if (dev->driver_data != &nodemgr_driverdata_host)
++              return 0;
++
++      host = container_of(dev, struct hpsb_host, device);
++
++      return host_data->cb(host, host_data->data);
++}
++
++int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *))
++{
++      struct for_each_host_struct host_data;
++
++      host_data.cb = cb;
++      host_data.data = __data;
++
++      return bus_for_each_dev(&ieee1394_bus_type, NULL, &host_data, nodemgr_for_each_host_cb);
++}
++
+ /* The following four convenience functions use a struct node_entry
+  * for addressing a node on the bus.  They are intended for use by any
+  * process context, not just the nodemgr thread, so we need to be a
+@@ -1821,11 +1832,6 @@ static void nodemgr_add_host(struct hpsb
+       init_completion(&hi->exited);
+         sema_init(&hi->reset_sem, 0);
+-      memcpy(&host->device, &nodemgr_dev_template_host,
+-             sizeof(host->device));
+-      host->device.parent = &host->pdev->dev;
+-      snprintf(host->device.bus_id, BUS_ID_SIZE, "fw-host%d", host->id);
+-
+       sprintf(hi->daemon_name, "knodemgrd_%d", host->id);
+       hi->pid = kernel_thread(nodemgr_host_thread, hi, CLONE_KERNEL);
+@@ -1879,7 +1885,6 @@ static struct hpsb_highlevel nodemgr_hig
+ void init_ieee1394_nodemgr(void)
+ {
+-      bus_register(&ieee1394_bus_type);
+       driver_register(&nodemgr_driver_host);
+       driver_register(&nodemgr_driver_ne);
+@@ -1892,5 +1897,4 @@ void cleanup_ieee1394_nodemgr(void)
+       driver_unregister(&nodemgr_driver_ne);
+       driver_unregister(&nodemgr_driver_host);
+-      bus_unregister(&ieee1394_bus_type);
+ }
+--- linux-2.6.0/drivers/ieee1394/nodemgr.h     2003-11-26 13:53:35.000000000 -0800
++++ 25/drivers/ieee1394/nodemgr.h      2003-12-28 23:23:03.000000000 -0800
+@@ -219,7 +219,16 @@ int hpsb_node_lock(struct node_entry *ne
+                  int extcode, quadlet_t *data, quadlet_t arg);
++/* Iterate the hosts, calling a given function with supplied data for each
++ * host. */
++int nodemgr_for_each_host(void *__data, int (*cb)(struct hpsb_host *, void *));
++
++
+ void init_ieee1394_nodemgr(void);
+ void cleanup_ieee1394_nodemgr(void);
++
++/* The template for a host device */
++extern struct device nodemgr_dev_template_host;
++
+ #endif /* _IEEE1394_NODEMGR_H */
+--- linux-2.6.0/drivers/ieee1394/ohci1394.c    2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ieee1394/ohci1394.c     2003-12-28 23:23:03.000000000 -0800
+@@ -134,7 +134,7 @@
+ #ifdef OHCI1394_DEBUG
+ #define DBGMSG(card, fmt, args...) \
+-printk(KERN_INFO "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
++printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
+ #else
+ #define DBGMSG(card, fmt, args...)
+ #endif
+@@ -158,10 +158,10 @@ printk(level "%s: " fmt "\n" , OHCI1394_
+ /* print card specific information */
+ #define PRINT(level, card, fmt, args...) \
+-printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
++printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
+ static char version[] __devinitdata =
+-      "$Rev: 1045 $ Ben Collins <bcollins@debian.org>";
++      "$Rev: 1087 $ Ben Collins <bcollins@debian.org>";
+ /* Module Parameters */
+ static int phys_dma = 1;
+@@ -845,7 +845,7 @@ static int ohci_transmit(struct hpsb_hos
+               PRINT(KERN_ERR, ohci->id, 
+                     "Transmit packet size %Zd is too big",
+                     packet->data_size);
+-              return 0;
++              return -EOVERFLOW;
+       }
+       /* Decide whether we have an iso, a request, or a response packet */
+@@ -862,7 +862,7 @@ static int ohci_transmit(struct hpsb_hos
+                       if (in_interrupt()) {
+                               PRINT(KERN_ERR, ohci->id, 
+                                     "legacy IT context cannot be initialized during interrupt");
+-                              return 0;
++                              return -EINVAL;
+                       }
+                       if (alloc_dma_trm_ctx(ohci, &ohci->it_legacy_context,
+@@ -870,7 +870,7 @@ static int ohci_transmit(struct hpsb_hos
+                                             OHCI1394_IsoXmitContextBase) < 0) {
+                               PRINT(KERN_ERR, ohci->id, 
+                                     "error initializing legacy IT context");
+-                              return 0;
++                              return -ENOMEM;
+                       }
+                       initialize_dma_trm_ctx(&ohci->it_legacy_context);
+@@ -890,7 +890,7 @@ static int ohci_transmit(struct hpsb_hos
+       spin_unlock_irqrestore(&d->lock,flags);
+-      return 1;
++      return 0;
+ }
+ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
+@@ -1113,8 +1113,8 @@ struct ohci_iso_recv {
+       struct ohci1394_iso_tasklet task;
+       int task_active;
+-      enum { BUFFER_FILL_MODE,
+-             PACKET_PER_BUFFER_MODE } dma_mode;
++      enum { BUFFER_FILL_MODE = 0,
++             PACKET_PER_BUFFER_MODE = 1 } dma_mode;
+       /* memory and PCI mapping for the DMA descriptors */
+       struct dma_prog_region prog;
+@@ -1175,7 +1175,8 @@ static int ohci_iso_recv_init(struct hps
+       /* use buffer-fill mode, unless irq_interval is 1
+          (note: multichannel requires buffer-fill) */
+-      if (iso->irq_interval == 1 && iso->channel != -1) {
++      if (((iso->irq_interval == 1 && iso->dma_mode == HPSB_ISO_DMA_OLD_ABI) ||
++           iso->dma_mode == HPSB_ISO_DMA_PACKET_PER_BUFFER) && iso->channel != -1) {
+               recv->dma_mode = PACKET_PER_BUFFER_MODE;
+       } else {
+               recv->dma_mode = BUFFER_FILL_MODE;
+@@ -1194,8 +1195,11 @@ static int ohci_iso_recv_init(struct hps
+               }
+               /* iso->irq_interval is in packets - translate that to blocks */
+-              /* (err, sort of... 1 is always the safest value) */
+-              recv->block_irq_interval = iso->irq_interval / recv->nblocks;
++              if (iso->irq_interval == 1)
++                      recv->block_irq_interval = 1;                   
++              else
++                      recv->block_irq_interval = iso->irq_interval *
++                                                      ((recv->nblocks+1)/iso->buf_packets);
+               if (recv->block_irq_interval*4 > recv->nblocks)
+                       recv->block_irq_interval = recv->nblocks/4;
+               if (recv->block_irq_interval < 1)
+@@ -1205,6 +1209,10 @@ static int ohci_iso_recv_init(struct hps
+               int max_packet_size;
+               recv->nblocks = iso->buf_packets;
++              recv->block_irq_interval = iso->irq_interval;
++              if (recv->block_irq_interval * 4 > iso->buf_packets)
++                      recv->block_irq_interval = iso->buf_packets / 4;
++              if (recv->block_irq_interval < 1)
+               recv->block_irq_interval = 1;
+               /* choose a buffer stride */
+@@ -3271,7 +3279,6 @@ do {                                             \
+ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
+                                       const struct pci_device_id *ent)
+ {
+-      static unsigned int card_id_counter = 0;
+       static int version_printed = 0;
+       struct hpsb_host *host;
+@@ -3282,15 +3289,14 @@ static int __devinit ohci1394_pci_probe(
+               PRINT_G(KERN_INFO, "%s", version);
+         if (pci_enable_device(dev))
+-              FAIL(-ENXIO, "Failed to enable OHCI hardware %d",
+-                      card_id_counter++);
++              FAIL(-ENXIO, "Failed to enable OHCI hardware");
+         pci_set_master(dev);
+-      host = hpsb_alloc_host(&ohci1394_driver, sizeof(struct ti_ohci));
++      host = hpsb_alloc_host(&ohci1394_driver, sizeof(struct ti_ohci), &dev->dev);
+       if (!host) FAIL(-ENOMEM, "Failed to allocate host structure");
+       ohci = host->hostdata;
+-      ohci->id = card_id_counter++;
++      ohci->id = host->id;
+       ohci->dev = dev;
+       ohci->host = host;
+       ohci->init_state = OHCI_INIT_ALLOC_HOST;
+@@ -3462,11 +3468,14 @@ static int __devinit ohci1394_pci_probe(
+ static void ohci1394_pci_remove(struct pci_dev *pdev)
+ {
+       struct ti_ohci *ohci;
++      struct device *dev;
+       ohci = pci_get_drvdata(pdev);
+       if (!ohci)
+               return;
++      dev = get_device(&ohci->host->device);
++
+       switch (ohci->init_state) {
+       case OHCI_INIT_DONE:
+               hpsb_remove_host(ohci->host);
+@@ -3489,7 +3498,7 @@ static void ohci1394_pci_remove(struct p
+               /* Disable IRM Contender */
+               set_phy_reg(ohci, 4, ~0xc0 & get_phy_reg(ohci, 4));
+-              
++
+               /* Clear link control register */
+               reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);
+@@ -3521,7 +3530,7 @@ static void ohci1394_pci_remove(struct p
+                                   ohci->selfid_buf_cpu,
+                                   ohci->selfid_buf_bus);
+               OHCI_DMA_FREE("consistent selfid_buf");
+-              
++
+       case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER:
+               pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN,
+                                   ohci->csr_config_rom_cpu,
+@@ -3555,8 +3564,10 @@ static void ohci1394_pci_remove(struct p
+       case OHCI_INIT_ALLOC_HOST:
+               pci_set_drvdata(ohci->dev, NULL);
+-              hpsb_unref_host(ohci->host);
+       }
++
++      if (dev)
++              put_device(dev);
+ }
+--- linux-2.6.0/drivers/ieee1394/oui.db        2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/ieee1394/oui.db 2003-12-28 23:23:03.000000000 -0800
+@@ -1612,7 +1612,7 @@
+ 000658 Helmut Fischer GmbH & Co. KG
+ 000659 EAL (Apeldoorn) B.V.
+ 00065A Strix Systems
+-00065B Dell Inc.
++00065B Dell Computer Corp.
+ 00065C Malachite Technologies, Inc.
+ 00065D Heidelberg Web Systems
+ 00065E Photuris, Inc.
+@@ -3965,7 +3965,7 @@
+ 00B0C2 Cisco Systems, Inc.
+ 00B0C7 Tellabs Operations, Inc.
+ 00B0CE TECHNOLOGY RESCUE
+-00B0D0 Dell Inc.
++00B0D0 Dell Computer Corp.
+ 00B0DB Nextcell, Inc.
+ 00B0DF Reliable Data Technology, Inc.
+ 00B0E7 British Federal Ltd.
+@@ -4054,7 +4054,7 @@
+ 00C04C DEPARTMENT OF FOREIGN AFFAIRS
+ 00C04D MITEC, INC.
+ 00C04E COMTROL CORPORATION
+-00C04F Dell Inc.
++00C04F DELL COMPUTER CORPORATION
+ 00C050 TOYO DENKI SEIZO K.K.
+ 00C051 ADVANCED INTEGRATION RESEARCH
+ 00C052 BURR-BROWN
+--- linux-2.6.0/drivers/ieee1394/pcilynx.c     2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ieee1394/pcilynx.c      2003-12-28 23:23:03.000000000 -0800
+@@ -521,10 +521,6 @@ static void send_next(struct ti_lynx *ly
+                 break;
+         }                
+-        if (!packet->data_be) {
+-                pcl.buffer[1].control |= PCL_BIGENDIAN;
+-        }
+-
+         put_pcl(lynx, d->pcl, &pcl);
+         run_pcl(lynx, d->pcl_start, d->channel);
+ }
+@@ -540,7 +536,7 @@ static int lynx_transmit(struct hpsb_hos
+         if (packet->data_size >= 4096) {
+                 PRINT(KERN_ERR, lynx->id, "transmit packet data too big (%Zd)",
+                       packet->data_size);
+-                return 0;
++                return -EOVERFLOW;
+         }
+         switch (packet->type) {
+@@ -554,7 +550,7 @@ static int lynx_transmit(struct hpsb_hos
+         default:
+                 PRINT(KERN_ERR, lynx->id, "invalid packet type %d",
+                       packet->type);
+-                return 0;
++                return -EINVAL;
+         }
+         if (packet->tcode == TCODE_WRITEQ
+@@ -570,7 +566,7 @@ static int lynx_transmit(struct hpsb_hos
+         spin_unlock_irqrestore(&d->queue_lock, flags);
+-        return 1;
++        return 0;
+ }
+@@ -1120,7 +1116,7 @@ static ssize_t mem_read(struct file *fil
+         retval = copy_to_user(buffer, md->lynx->mem_dma_buffer, count);
+         up(&md->lynx->mem_dma_mutex);
+-        if (retval < 0) return retval;
++      if (retval) return -EFAULT;
+         *offset += count;
+         return count;
+ }
+@@ -1141,14 +1137,17 @@ static ssize_t mem_write(struct file *fi
+         /* FIXME: dereferencing pointers to PCI mem doesn't work everywhere */
+         switch (md->type) {
+         case aux:
+-                copy_from_user(md->lynx->aux_port+(*offset), buffer, count);
++              if (copy_from_user(md->lynx->aux_port+(*offset), buffer, count))
++                      return -EFAULT;
+                 break;
+         case ram:
+-                copy_from_user(md->lynx->local_ram+(*offset), buffer, count);
++              if (copy_from_user(md->lynx->local_ram+(*offset), buffer, count))
++                      return -EFAULT;
+                 break;
+         case rom:
+                 /* the ROM may be writeable */
+-                copy_from_user(md->lynx->local_rom+(*offset), buffer, count);
++              if (copy_from_user(md->lynx->local_rom+(*offset), buffer, count))
++                      return -EFAULT;
+                 break;
+         }
+@@ -1443,12 +1442,15 @@ static void iso_rcv_bh(struct ti_lynx *l
+ static void remove_card(struct pci_dev *dev)
+ {
+         struct ti_lynx *lynx;
++      struct device *lynx_dev;
+         int i;
+         lynx = pci_get_drvdata(dev);
+         if (!lynx) return;
+         pci_set_drvdata(dev, NULL);
++      lynx_dev = get_device(&lynx->host->device);
++
+         switch (lynx->state) {
+         case is_host:
+                 reg_write(lynx, PCI_INT_ENABLE, 0);
+@@ -1498,7 +1500,9 @@ static void remove_card(struct pci_dev *
+         }
+       tasklet_kill(&lynx->iso_rcv.tq);
+-      hpsb_unref_host(lynx->host);
++
++      if (lynx_dev)
++              put_device(lynx_dev);
+ }
+@@ -1535,7 +1539,7 @@ static int __devinit add_card(struct pci
+         error = -ENOMEM;
+-      host = hpsb_alloc_host(&lynx_driver, sizeof(struct ti_lynx));
++      host = hpsb_alloc_host(&lynx_driver, sizeof(struct ti_lynx), &dev->dev);
+         if (!host) FAIL("failed to allocate control structure memory");
+         lynx = host->hostdata;
+--- linux-2.6.0/drivers/ieee1394/raw1394.c     2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ieee1394/raw1394.c      2003-12-28 23:23:03.000000000 -0800
+@@ -128,7 +128,7 @@ static void free_pending_request(struct 
+         } else if (req->free_data) {
+                 kfree(req->data);
+         }
+-        free_hpsb_packet(req->packet);
++        hpsb_free_packet(req->packet);
+         kfree(req);
+ }
+@@ -558,7 +558,7 @@ static int state_initialized(struct file
+                                 lh = lh->next;
+                         }
+                         hi = list_entry(lh, struct host_info, list);
+-                        hpsb_ref_host(hi->host); // XXX Need to handle failure case
++                      get_device(&hi->host->device); // XXX Need to handle failure case
+                         list_add_tail(&fi->list, &hi->file_info_list);
+                         fi->host = hi->host;
+                         fi->state = connected;
+@@ -782,7 +782,7 @@ static int handle_async_request(struct f
+       packet->generation = req->req.generation;
+-        if (!hpsb_send_packet(packet)) {
++        if (hpsb_send_packet(packet) < 0) {
+                 req->req.error = RAW1394_ERROR_SEND_ERROR;
+                 req->req.length = 0;
+                 hpsb_free_tlabel(packet);
+@@ -823,7 +823,7 @@ static int handle_iso_send(struct file_i
+       /* Update the generation of the packet just before sending. */
+       packet->generation = req->req.generation;
+-        if (!hpsb_send_packet(packet)) {
++        if (hpsb_send_packet(packet) < 0) {
+                 req->req.error = RAW1394_ERROR_SEND_ERROR;
+                 queue_complete_req(req);
+         }
+@@ -846,7 +846,7 @@ static int handle_async_send(struct file
+                 return sizeof(struct raw1394_request);
+         } 
+-        packet = alloc_hpsb_packet(req->req.length-header_length);
++        packet = hpsb_alloc_packet(req->req.length-header_length);
+         req->packet = packet;
+         if (!packet) return -ENOMEM;
+@@ -885,7 +885,7 @@ static int handle_async_send(struct file
+         /* Update the generation of the packet just before sending. */
+         packet->generation = req->req.generation;
+-        if (!hpsb_send_packet(packet)) {
++        if (hpsb_send_packet(packet) < 0) {
+                 req->req.error = RAW1394_ERROR_SEND_ERROR;
+                 queue_complete_req(req);
+         }
+@@ -1797,6 +1797,106 @@ static int arm_unregister(struct file_in
+         return sizeof(struct raw1394_request);
+ }
++/* Copy data from ARM buffer(s) to user buffer. */
++static int arm_get_buf(struct file_info *fi, struct pending_request *req)
++{
++      struct arm_addr  *arm_addr = NULL;
++      unsigned long flags;
++      unsigned long offset;
++
++      struct list_head *entry;
++
++      DBGMSG("arm_get_buf "
++             "addr(Offset): %04X %08X length: %u",
++             (u32) ((req->req.address >> 32) & 0xFFFF),
++             (u32) (req->req.address & 0xFFFFFFFF),
++             (u32) req->req.length);
++
++      spin_lock_irqsave(&host_info_lock, flags);
++      entry = fi->addr_list.next;
++      while (entry != &(fi->addr_list)) {
++              arm_addr = list_entry(entry, struct arm_addr, addr_list);
++              if ((arm_addr->start <= req->req.address) &&
++                  (arm_addr->end > req->req.address)) {
++                      if (req->req.address + req->req.length <= arm_addr->end) {
++                              offset = req->req.address - arm_addr->start;
++
++                              DBGMSG("arm_get_buf copy_to_user( %08X, %08X, %u )",
++                                     (u32) req->req.recvb,
++                                     (u32) (arm_addr->addr_space_buffer+offset),
++                                     (u32) req->req.length);
++
++                              if (copy_to_user(int2ptr(req->req.recvb), arm_addr->addr_space_buffer+offset, req->req.length)) {
++                                      spin_unlock_irqrestore(&host_info_lock, flags);
++                                      return (-EFAULT);
++                              }
++
++                              spin_unlock_irqrestore(&host_info_lock, flags);
++                              free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
++                              return sizeof(struct raw1394_request);
++                      } else {
++                              DBGMSG("arm_get_buf request exceeded mapping");
++                              spin_unlock_irqrestore(&host_info_lock, flags);
++                              return (-EINVAL);
++                      }
++              }
++              entry = entry->next;
++      }
++      spin_unlock_irqrestore(&host_info_lock, flags);
++      return (-EINVAL);
++}
++
++
++/* Copy data from user buffer to ARM buffer(s). */
++static int arm_set_buf(struct file_info *fi, struct pending_request *req)
++{
++      struct arm_addr  *arm_addr = NULL;
++      unsigned long flags;
++      unsigned long offset;
++
++      struct list_head *entry;
++
++      DBGMSG("arm_set_buf "
++             "addr(Offset): %04X %08X length: %u",
++             (u32) ((req->req.address >> 32) & 0xFFFF),
++             (u32) (req->req.address & 0xFFFFFFFF),
++             (u32) req->req.length);
++
++
++      spin_lock_irqsave(&host_info_lock, flags);
++      entry = fi->addr_list.next;
++      while (entry != &(fi->addr_list)) {
++              arm_addr = list_entry(entry, struct arm_addr, addr_list);
++              if ((arm_addr->start <= req->req.address) &&
++                  (arm_addr->end > req->req.address)) {
++                      if (req->req.address + req->req.length <= arm_addr->end) {
++                              offset = req->req.address - arm_addr->start;
++
++                              DBGMSG("arm_set_buf copy_from_user( %08X, %08X, %u )",
++                                     (u32) (arm_addr->addr_space_buffer+offset),
++                                     (u32) req->req.sendb,
++                                     (u32) req->req.length);
++
++                              if (copy_from_user(arm_addr->addr_space_buffer+offset, int2ptr(req->req.sendb), req->req.length)) {
++                                      spin_unlock_irqrestore(&host_info_lock, flags);
++                                      return (-EFAULT);
++                              }
++
++                              spin_unlock_irqrestore(&host_info_lock, flags);
++                              free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */
++                              return sizeof(struct raw1394_request);
++                      } else {
++                              DBGMSG("arm_set_buf request exceeded mapping");
++                              spin_unlock_irqrestore(&host_info_lock, flags);
++                              return (-EINVAL);
++                      }
++              }
++              entry = entry->next;
++      }
++      spin_unlock_irqrestore(&host_info_lock, flags);
++      return (-EINVAL);
++}
++
+ static int reset_notification(struct file_info *fi, struct pending_request *req)
+ {
+         DBGMSG("reset_notification called - switch %s ",
+@@ -1829,9 +1929,8 @@ static int write_phypacket(struct file_i
+         spin_unlock_irq(&fi->reqlists_lock);
+         packet->generation = req->req.generation;
+         retval = hpsb_send_packet(packet);
+-        DBGMSG("write_phypacket send_packet called => retval: %d ",
+-                retval);
+-        if (! retval) {
++        DBGMSG("write_phypacket send_packet called => retval: %d ", retval);
++        if (retval < 0) {
+                 req->req.error = RAW1394_ERROR_SEND_ERROR;
+                 req->req.length = 0;
+                 queue_complete_req(req);
+@@ -1912,6 +2011,12 @@ static int state_connected(struct file_i
+         case RAW1394_REQ_ARM_UNREGISTER:
+                 return arm_unregister(fi, req);
++        case RAW1394_REQ_ARM_SET_BUF:
++                return arm_set_buf(fi, req);
++
++        case RAW1394_REQ_ARM_GET_BUF:
++                return arm_get_buf(fi, req);
++
+         case RAW1394_REQ_RESET_NOTIFY:
+                 return reset_notification(fi, req);
+@@ -2137,6 +2242,7 @@ static int raw1394_iso_recv_init(struct 
+                                           stat.config.data_buf_size,
+                                           stat.config.buf_packets,
+                                           stat.config.channel,
++                                          stat.config.dma_mode,
+                                           stat.config.irq_interval,
+                                           rawiso_activity_cb);
+       if (!fi->iso_handle)
+@@ -2489,7 +2595,7 @@ static int raw1394_release(struct inode 
+                 list_del(&fi->list);
+                 spin_unlock_irq(&host_info_lock);
+-                hpsb_unref_host(fi->host);
++              put_device(&fi->host->device);
+         }
+         kfree(fi);
+--- linux-2.6.0/drivers/ieee1394/raw1394.h     2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/ieee1394/raw1394.h      2003-12-28 23:23:03.000000000 -0800
+@@ -30,6 +30,8 @@
+ #define RAW1394_REQ_ARM_REGISTER    300
+ #define RAW1394_REQ_ARM_UNREGISTER  301
++#define RAW1394_REQ_ARM_SET_BUF     302
++#define RAW1394_REQ_ARM_GET_BUF     303
+ #define RAW1394_REQ_RESET_NOTIFY    400
+@@ -149,6 +151,9 @@ struct raw1394_iso_config {
+       /* xmit only - iso transmission speed */
+       __u8 speed;
++      /* The mode of the dma when receiving iso data. Must be supported by chip */
++      __u8 dma_mode;
++
+       /* max. latency of buffer, in packets (-1 if you don't care) */
+       __s32 irq_interval;
+ };
+--- linux-2.6.0/drivers/ieee1394/sbp2.c        2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/ieee1394/sbp2.c 2003-12-28 23:23:03.000000000 -0800
+@@ -77,7 +77,7 @@
+ #include "sbp2.h"
+ static char version[] __devinitdata =
+-      "$Rev: 1034 $ Ben Collins <bcollins@debian.org>";
++      "$Rev: 1082 $ Ben Collins <bcollins@debian.org>";
+ /*
+  * Module load parameter definitions
+@@ -361,38 +361,34 @@ static int sbp2util_down_timeout(atomic_
+ static void sbp2_free_packet(struct hpsb_packet *packet)
+ {
+       hpsb_free_tlabel(packet);
+-      free_hpsb_packet(packet);
++      hpsb_free_packet(packet);
+ }
+-/*
+- * This function is called to retrieve a block write packet from our
+- * packet pool. This function is used in place of calling
+- * alloc_hpsb_packet (which costs us three kmallocs). Instead we just pull
+- * out a free request packet and re-initialize values in it. I'm sure this
+- * can still stand some more optimization.
++/* This is much like hpsb_node_write(), except it ignores the response
++ * subaction and returns immediately. Can be used from interrupts.
+  */
+-static struct hpsb_packet *
+-sbp2util_allocate_write_packet(struct sbp2scsi_host_info *hi,
+-                             struct node_entry *ne, u64 addr,
+-                             size_t data_size,
+-                             quadlet_t *data)
++int sbp2util_node_write_no_wait(struct node_entry *ne, u64 addr,
++                              quadlet_t *buffer, size_t length)
+ {
+       struct hpsb_packet *packet;
+-      packet = hpsb_make_writepacket(hi->host, ne->nodeid,
+-                                     addr, data, data_size);
+-
++      packet = hpsb_make_writepacket(ne->host, ne->nodeid,
++                                     addr, buffer, length);
+         if (!packet)
+-                return NULL;
++                return -ENOMEM;
+       hpsb_set_packet_complete_task(packet, (void (*)(void*))sbp2_free_packet,
+                                     packet);
+       hpsb_node_fill_packet(ne, packet);
+-      return packet;
+-}
++        if (hpsb_send_packet(packet) < 0) {
++              sbp2_free_packet(packet);
++              return -EIO;
++      }
++      return 0;
++}
+ /*
+  * This function is called to create a pool of command orbs used for
+@@ -1734,35 +1730,26 @@ static int sbp2_max_speed_and_size(struc
+  */
+ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait) 
+ {
+-      struct sbp2scsi_host_info *hi = scsi_id->hi;
+-      struct hpsb_packet *packet;
+       quadlet_t data;
+-      
++      u64 addr;
++      int retval;
++
+       SBP2_DEBUG("sbp2_agent_reset");
+       /*
+        * Ok, let's write to the target's management agent register
+        */
+       data = ntohl(SBP2_AGENT_RESET_DATA);
+-      packet = sbp2util_allocate_write_packet(hi, scsi_id->ne,
+-                                              scsi_id->sbp2_command_block_agent_addr +
+-                                              SBP2_AGENT_RESET_OFFSET,
+-                                              4, &data);
+-
+-      if (!packet) {
+-              SBP2_ERR("sbp2util_allocate_write_packet failed");
+-              return(-ENOMEM);
+-      }
++      addr = scsi_id->sbp2_command_block_agent_addr + SBP2_AGENT_RESET_OFFSET;
+-      if (!hpsb_send_packet(packet)) {
+-              SBP2_ERR("hpsb_send_packet failed");
+-              sbp2_free_packet(packet); 
+-              return(-EIO);
+-      }
++      if (wait)
++              retval = hpsb_node_write(scsi_id->ne, addr, &data, 4);
++      else
++              retval = sbp2util_node_write_no_wait(scsi_id->ne, addr, &data, 4);
+-      if (wait) {
+-              down(&packet->state_change);
+-              down(&packet->state_change);
++      if (retval < 0) {
++              SBP2_ERR("hpsb_node_write failed.\n");
++              return -EIO;
+       }
+       /*
+@@ -2032,8 +2019,9 @@ static int sbp2_link_orb_command(struct 
+                                struct sbp2_command_info *command)
+ {
+       struct sbp2scsi_host_info *hi = scsi_id->hi;
+-        struct hpsb_packet *packet;
+       struct sbp2_command_orb *command_orb = &command->command_orb;
++      struct node_entry *ne = scsi_id->ne;
++      u64 addr;
+       outstanding_orb_incr;
+       SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x",
+@@ -2049,40 +2037,30 @@ static int sbp2_link_orb_command(struct 
+        * Check to see if there are any previous orbs to use
+        */
+       if (scsi_id->last_orb == NULL) {
+-      
++              quadlet_t data[2];
++
+               /*
+                * Ok, let's write to the target's management agent register
+                */
+-              if (hpsb_node_entry_valid(scsi_id->ne)) {
+-
+-                      packet = sbp2util_allocate_write_packet(hi, scsi_id->ne,
+-                                                              scsi_id->sbp2_command_block_agent_addr +
+-                                                              SBP2_ORB_POINTER_OFFSET, 8, NULL);
+-              
+-                      if (!packet) {
+-                              SBP2_ERR("sbp2util_allocate_write_packet failed");
+-                              return(-ENOMEM);
+-                      }
+-              
+-                      packet->data[0] = ORB_SET_NODE_ID(hi->host->node_id);
+-                      packet->data[1] = command->command_orb_dma;
+-                      sbp2util_cpu_to_be32_buffer(packet->data, 8);
+-              
+-                      SBP2_ORB_DEBUG("write command agent, command orb %p", command_orb);
++              addr = scsi_id->sbp2_command_block_agent_addr + SBP2_ORB_POINTER_OFFSET;
++              data[0] = ORB_SET_NODE_ID(hi->host->node_id);
++              data[1] = command->command_orb_dma;
++              sbp2util_cpu_to_be32_buffer(data, 8);
+-                      if (!hpsb_send_packet(packet)) {
+-                              SBP2_ERR("hpsb_send_packet failed");
+-                              sbp2_free_packet(packet); 
+-                              return(-EIO);
+-                      }
++              SBP2_ORB_DEBUG("write command agent, command orb %p", command_orb);
+-                      SBP2_ORB_DEBUG("write command agent complete");
++              if (sbp2util_node_write_no_wait(ne, addr, data, 8) < 0) {
++                      SBP2_ERR("sbp2util_node_write_no_wait failed.\n");
++                      return -EIO;
+               }
++              SBP2_ORB_DEBUG("write command agent complete");
++
+               scsi_id->last_orb = command_orb;
+               scsi_id->last_orb_dma = command->command_orb_dma;
+       } else {
++              quadlet_t data;
+               /*
+                * We have an orb already sent (maybe or maybe not
+@@ -2102,25 +2080,14 @@ static int sbp2_link_orb_command(struct 
+               /*
+                * Ring the doorbell
+                */
+-              if (hpsb_node_entry_valid(scsi_id->ne)) {
+-                      quadlet_t data = cpu_to_be32(command->command_orb_dma);
++              data = cpu_to_be32(command->command_orb_dma);
++              addr = scsi_id->sbp2_command_block_agent_addr + SBP2_DOORBELL_OFFSET;
+-                      packet = sbp2util_allocate_write_packet(hi, scsi_id->ne,
+-                                      scsi_id->sbp2_command_block_agent_addr +
+-                                      SBP2_DOORBELL_OFFSET, 4, &data);
+-      
+-                      if (!packet) {
+-                              SBP2_ERR("sbp2util_allocate_write_packet failed");
+-                              return(-ENOMEM);
+-                      }
++              SBP2_ORB_DEBUG("ring doorbell, command orb %p", command_orb);
+-                      SBP2_ORB_DEBUG("ring doorbell, command orb %p", command_orb);
+-
+-                      if (!hpsb_send_packet(packet)) {
+-                              SBP2_ERR("hpsb_send_packet failed");
+-                              sbp2_free_packet(packet);
+-                              return(-EIO);
+-                      }
++              if (sbp2util_node_write_no_wait(ne, addr, &data, 4) < 0) {
++                      SBP2_ERR("sbp2util_node_write_no_wait failed");
++                      return(-EIO);
+               }
+               scsi_id->last_orb = command_orb;
+--- linux-2.6.0/drivers/input/gameport/Kconfig 2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/gameport/Kconfig  2003-12-28 23:23:04.000000000 -0800
+@@ -19,6 +19,22 @@ config GAMEPORT
+         To compile this driver as a module, choose M here: the
+         module will be called gameport.
++
++# Yes, SOUND_GAMEPORT looks a bit odd. Yes, it ends up being turned on
++# in every .config. Please don't touch it. It is here to handle an
++# unusual dependency between GAMEPORT and sound drivers.
++#
++# Some sound drivers call gameport functions. If GAMEPORT is
++# not selected, empty stubs are provided for the functions and all is
++# well.
++# If GAMEPORT is built in, everything is fine.
++# If GAMEPORT is a module, however, it would need to be loaded for the
++# sound driver to be able to link properly. Therefore, the sound
++# driver must be a module as well in that case. Since there's no way
++# to express that directly in Kconfig, we use SOUND_GAMEPORT to
++# express it. SOUND_GAMEPORT boils down to "if GAMEPORT is 'm',
++# anything that depends on SOUND_GAMEPORT must be 'm' as well. if
++# GAMEPORT is 'y' or 'n', it can be anything".
+ config SOUND_GAMEPORT
+       tristate
+       default y if GAMEPORT!=m
+--- linux-2.6.0/drivers/input/input.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/input/input.c   2003-12-28 23:21:26.000000000 -0800
+@@ -447,9 +447,10 @@ void input_register_device(struct input_
+       list_add_tail(&dev->node, &input_dev_list);
+       list_for_each_entry(handler, &input_handler_list, node)
+-              if ((id = input_match_device(handler->id_table, dev)))
+-                      if ((handle = handler->connect(handler, dev, id)))
+-                              input_link_handle(handle);
++              if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
++                      if ((id = input_match_device(handler->id_table, dev)))
++                              if ((handle = handler->connect(handler, dev, id)))
++                                      input_link_handle(handle);
+ #ifdef CONFIG_HOTPLUG
+       input_call_hotplug("add", dev);
+@@ -507,9 +508,10 @@ void input_register_handler(struct input
+       list_add_tail(&handler->node, &input_handler_list);
+       
+       list_for_each_entry(dev, &input_dev_list, node)
+-              if ((id = input_match_device(handler->id_table, dev)))
+-                      if ((handle = handler->connect(handler, dev, id)))
+-                              input_link_handle(handle);
++              if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
++                      if ((id = input_match_device(handler->id_table, dev)))
++                              if ((handle = handler->connect(handler, dev, id)))
++                                      input_link_handle(handle);
+ #ifdef CONFIG_PROC_FS
+       input_devices_state++;
+--- linux-2.6.0/drivers/input/joydev.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/input/joydev.c  2003-12-28 23:21:26.000000000 -0800
+@@ -380,10 +380,6 @@ static struct input_handle *joydev_conne
+       struct joydev *joydev;
+       int i, j, t, minor;
+-      /* Avoid tablets */
+-        if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
+-              return NULL;
+-
+       for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
+       if (minor == JOYDEV_MINORS) {
+               printk(KERN_ERR "joydev: no more free joydev devices\n");
+@@ -464,6 +460,15 @@ static void joydev_disconnect(struct inp
+               joydev_free(joydev);
+ }
++static struct input_device_id joydev_blacklist[] = {
++      {
++              .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
++              .evbit = { BIT(EV_KEY) },
++              .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
++      },      /* Avoid itouchpads, touchscreens and tablets */
++      { },    /* Terminating entry */
++};
++
+ static struct input_device_id joydev_ids[] = {
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+@@ -493,6 +498,7 @@ static struct input_handler joydev_handl
+       .minor =        JOYDEV_MINOR_BASE,
+       .name =         "joydev",
+       .id_table =     joydev_ids,
++      .blacklist =    joydev_blacklist,
+ };
+ static int __init joydev_init(void)
+--- linux-2.6.0/drivers/input/keyboard/atkbd.c 2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/input/keyboard/atkbd.c  2003-12-28 23:21:31.000000000 -0800
+@@ -48,33 +48,30 @@ static int atkbd_softrepeat;
+  */
+ static unsigned char atkbd_set2_keycode[512] = {
+-        0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41, 85,
+-        0, 56, 42,182, 29, 16,  2, 89,  0,  0, 44, 31, 30, 17,  3, 90,
+-        0, 46, 45, 32, 18,  5,  4, 91, 90, 57, 47, 33, 20, 19,  6,  0,
+-       91, 49, 48, 35, 34, 21,  7,  0,  0,  0, 50, 36, 22,  8,  9,  0,
++
++        0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
++        0, 56, 42,182, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
++        0, 46, 45, 32, 18,  5,  4,186,  0, 57, 47, 33, 20, 19,  6, 85,
++        0, 49, 48, 35, 34, 21,  7, 89,  0,  0, 50, 36, 22,  8,  9, 90,
+         0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
+-      122, 89, 40,120, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0,  0,
+-       85, 86, 90, 91, 92, 93, 14, 94, 95, 79,183, 75, 71,121,  0,123,
++        0,181, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0,194,
++        0, 86,193,192,184,  0, 14,185,  0, 79,182, 75, 71,124,  0,  0,
+        82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
+-        0,  0,  0, 65, 99,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+-        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+-        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+-        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+-        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+-        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
++
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+-        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255,
+-        0,  0, 92, 90, 85,  0,137,  0,  0,  0,  0, 91, 89,144,115,  0,
+-      217,100,255,  0, 97,165,164,  0,156,  0,  0,140,115,  0,  0,125,
+-      173,114,  0,113,152,163,151,126,128,166,  0,140,  0,147,  0,127,
+-      159,167,115,160,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
+-      157,  0,114,166,168,  0,  0,213,155,  0, 98,113,  0,163,  0,138,
+-      226,  0,  0,  0,  0,  0,153,140,  0,255, 96,  0,  0,  0,143,  0,
+-      133,  0,116,  0,143,  0,174,133,  0,107,  0,105,102,  0,  0,112,
+-      110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119
++      217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
++      173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
++      159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
++      157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
++      226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
++        0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
++      110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
++
++        0,  0,  0, 65, 99,
+ };
+ static unsigned char atkbd_set3_keycode[512] = {
++
+         0,  0,  0,  0,  0,  0,  0, 59,  1,138,128,129,130, 15, 41, 60,
+       131, 29, 42, 86, 58, 16,  2, 61,133, 56, 44, 31, 30, 17,  3, 62,
+       134, 46, 45, 32, 18,  5,  4, 63,135, 57, 47, 33, 20, 19,  6, 64,
+@@ -83,25 +80,21 @@ static unsigned char atkbd_set3_keycode[
+       113,114, 40, 84, 26, 13, 87, 99, 97, 54, 28, 27, 43, 84, 88, 70,
+       108,105,119,103,111,107, 14,110,  0, 79,106, 75, 71,109,102,104,
+        82, 83, 80, 76, 77, 72, 69, 98,  0, 96, 81,  0, 78, 73, 55, 85,
++
+        89, 90, 91, 92, 74,185,184,182,  0,  0,  0,125,126,127,112,  0,
+         0,139,150,163,165,115,152,150,166,140,160,154,113,114,167,168,
+-      148,149,147,140,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+-        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+-        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+-        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+-        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+-        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,255
++      148,149,147,140
+ };
+ static unsigned char atkbd_unxlate_table[128] = {
+-        0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
+-       21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
+-       35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
+-       50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
+-       11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
+-      114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
+-       71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
+-       19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
++          0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
++         21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
++         35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
++         50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
++         11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
++        114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
++         71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
++         19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
+ };
+ #define ATKBD_CMD_SETLEDS     0x10ed
+@@ -125,6 +118,9 @@ static unsigned char atkbd_unxlate_table
+ #define ATKBD_RET_EMULX               0x80
+ #define ATKBD_RET_EMUL1               0xe1
+ #define ATKBD_RET_RELEASE     0xf0
++#define ATKBD_RET_HANGUEL     0xf1
++#define ATKBD_RET_HANJA               0xf2
++#define ATKBD_RET_ERR         0xff
+ #define ATKBD_KEY_UNKNOWN       0
+ #define ATKBD_KEY_NULL                255
+@@ -156,6 +152,17 @@ struct atkbd {
+       unsigned long time;
+ };
++static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int code, int value)
++{
++      input_regs(dev, regs);
++      if (value == 3) {
++              input_report_key(dev, code, 1);
++              input_report_key(dev, code, 0);
++      } else
++              input_event(dev, EV_KEY, code, value);
++      input_sync(dev);
++}
++
+ /*
+  * atkbd_interrupt(). Here takes place processing of data received from
+  * the keyboard into events.
+@@ -184,47 +191,37 @@ static irqreturn_t atkbd_interrupt(struc
+               atkbd->resend = 0;
+ #endif
+-      switch (code) {
+-              case ATKBD_RET_ACK:
+-                      atkbd->ack = 1;
+-                      goto out;
+-              case ATKBD_RET_NAK:
+-                      atkbd->ack = -1;
+-                      goto out;
+-      }
+-
+-      if (atkbd->translated) do {
+-
+-              if (atkbd->emul != 1) {
+-                      if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1)
+-                              break;
+-                      if (code == ATKBD_RET_BAT) {
+-                              if (!atkbd->bat_xl)
+-                                      break;
+-                              atkbd->bat_xl = 0;
+-                      }
+-                      if (code == (ATKBD_RET_BAT & 0x7f))
+-                              atkbd->bat_xl = 1;
++      if (!atkbd->ack)
++              switch (code) {
++                      case ATKBD_RET_ACK:
++                              atkbd->ack = 1;
++                              goto out;
++                      case ATKBD_RET_NAK:
++                              atkbd->ack = -1;
++                              goto out;
+               }
+-              if (code < 0x80) {
+-                      code = atkbd_unxlate_table[code];
+-                      break;
+-              }
+-
+-              if (atkbd->cmdcnt)
+-                      break;
+-
+-              code = atkbd_unxlate_table[code & 0x7f];
+-              atkbd->release = 1;
+-
+-      } while (0);
+-
+       if (atkbd->cmdcnt) {
+               atkbd->cmdbuf[--atkbd->cmdcnt] = code;
+               goto out;
+       }
++      if (atkbd->translated) {
++
++              if (atkbd->emul ||
++                  !(code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 ||
++                    code == ATKBD_RET_HANGUEL || code == ATKBD_RET_HANJA ||
++                    code == ATKBD_RET_ERR ||
++                   (code == ATKBD_RET_BAT && !atkbd->bat_xl))) {
++                      atkbd->release = code >> 7;
++                      code &= 0x7f;
++              }
++
++              if (!atkbd->emul &&
++                   (code & 0x7f) == (ATKBD_RET_BAT & 0x7f))
++                      atkbd->bat_xl = !atkbd->release;
++      }
++
+       switch (code) {
+               case ATKBD_RET_BAT:
+                       serio_rescan(atkbd->serio);
+@@ -238,22 +235,33 @@ static irqreturn_t atkbd_interrupt(struc
+               case ATKBD_RET_RELEASE:
+                       atkbd->release = 1;
+                       goto out;
++              case ATKBD_RET_HANGUEL:
++                      atkbd_report_key(&atkbd->dev, regs, KEY_LANG1, 3);
++                      goto out;
++              case ATKBD_RET_HANJA:
++                      atkbd_report_key(&atkbd->dev, regs, KEY_LANG2, 3);
++                      goto out;
++              case ATKBD_RET_ERR:
++                      printk(KERN_WARNING "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
++                      goto out;
+       }
++      if (atkbd->set != 3)
++              code = (code & 0x7f) | ((code & 0x80) << 1);
+       if (atkbd->emul) {
+               if (--atkbd->emul)
+                       goto out;
+-              code |= 0x100;
++              code |= (atkbd->set != 3) ? 0x80 : 0x100;
+       }
+       switch (atkbd->keycode[code]) {
+               case ATKBD_KEY_NULL:
+                       break;
+               case ATKBD_KEY_UNKNOWN:
+-                      printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x, data %#x, on %s).\n",
++                      printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n",
+                               atkbd->release ? "released" : "pressed",
+                               atkbd->translated ? "translated" : "raw", 
+-                              atkbd->set, code, data, serio->phys);
++                              atkbd->set, code, serio->phys);
+                       break;
+               default:
+                       value = atkbd->release ? 0 :
+@@ -273,9 +281,7 @@ static irqreturn_t atkbd_interrupt(struc
+                                       break;
+                       }
+-                      input_regs(&atkbd->dev, regs);
+-                      input_event(&atkbd->dev, EV_KEY, atkbd->keycode[code], value);
+-                      input_sync(&atkbd->dev);
++                      atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value);
+       }
+       atkbd->release = 0;
+@@ -369,10 +375,11 @@ static int atkbd_command(struct atkbd *a
+ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+ {
+       struct atkbd *atkbd = dev->private;
+-      struct { int p; u8 v; } period[] =      
+-              { {30, 0x00}, {25, 0x02}, {20, 0x04}, {15, 0x08}, {10, 0x0c}, {7, 0x10}, {5, 0x14}, {0, 0x14} };
+-      struct { int d; u8 v; } delay[] =
+-              { {1000, 0x60}, {750, 0x40}, {500, 0x20}, {250, 0x00}, {0, 0x00} };
++      const short period[32] =
++              { 33,  37,  42,  46,  50,  54,  58,  63,  67,  75,  83,  92, 100, 109, 116, 125,
++               133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 };
++      const short delay[4] =
++              { 250, 500, 750, 1000 };
+       char param[2];
+       int i, j;
+@@ -406,11 +413,11 @@ static int atkbd_event(struct input_dev 
+                       if (atkbd_softrepeat) return 0;
+                       i = j = 0;
+-                      while (period[i].p > dev->rep[REP_PERIOD]) i++;
+-                      while (delay[j].d > dev->rep[REP_DELAY]) j++;
+-                      dev->rep[REP_PERIOD] = period[i].p;
+-                      dev->rep[REP_DELAY] = delay[j].d;
+-                      param[0] = period[i].v | delay[j].v;
++                      while (i < 32 && period[i] < dev->rep[REP_PERIOD]) i++;
++                      while (j < 4 && delay[j] < dev->rep[REP_DELAY]) j++;
++                      dev->rep[REP_PERIOD] = period[i];
++                      dev->rep[REP_DELAY] = delay[j];
++                      param[0] = i | (j << 5);
+                       atkbd_command(atkbd, param, ATKBD_CMD_SETREP);
+                       return 0;
+@@ -578,6 +585,7 @@ static void atkbd_disconnect(struct seri
+       struct atkbd *atkbd = serio->private;
+       input_unregister_device(&atkbd->dev);
+       serio_close(serio);
++      serio->private = NULL;
+       kfree(atkbd);
+ }
+@@ -623,6 +631,7 @@ static void atkbd_connect(struct serio *
+               atkbd->dev.rep[REP_PERIOD] = 33;
+       }
++      atkbd->ack = 1;
+       atkbd->serio = serio;
+       init_input_dev(&atkbd->dev);
+@@ -636,6 +645,7 @@ static void atkbd_connect(struct serio *
+       serio->private = atkbd;
+       if (serio_open(serio, dev)) {
++              serio->private = NULL;
+               kfree(atkbd);
+               return;
+       }
+@@ -644,6 +654,7 @@ static void atkbd_connect(struct serio *
+               if (atkbd_probe(atkbd)) {
+                       serio_close(serio);
++                      serio->private = NULL;
+                       kfree(atkbd);
+                       return;
+               }
+@@ -665,16 +676,22 @@ static void atkbd_connect(struct serio *
+       sprintf(atkbd->phys, "%s/input0", serio->phys);
+-      if (atkbd->set == 3)
+-              memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
+-      else
++      if (atkbd->translated) {
++              for (i = 0; i < 128; i++) {
++                      atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
++                      atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
++              }
++      } else if (atkbd->set == 2) {
+               memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
++      } else {
++              memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
++      }
+       atkbd->dev.name = atkbd->name;
+       atkbd->dev.phys = atkbd->phys;
+       atkbd->dev.id.bustype = BUS_I8042;
+       atkbd->dev.id.vendor = 0x0001;
+-      atkbd->dev.id.product = atkbd->set;
++      atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set;
+       atkbd->dev.id.version = atkbd->id;
+       for (i = 0; i < 512; i++)
+@@ -686,10 +703,62 @@ static void atkbd_connect(struct serio *
+       printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys);
+ }
++/*
++ * atkbd_reconnect() tries to restore keyboard into a sane state and is
++ * most likely called on resume.
++ */
++
++static int atkbd_reconnect(struct serio *serio)
++{
++      struct atkbd *atkbd = serio->private;
++      struct serio_dev *dev = serio->dev;
++      int i;
++
++        if (!dev) {
++                printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n");
++                return -1;
++        }
++
++      if (atkbd->write) {
++              if (atkbd_probe(atkbd))
++                      return -1;
++
++              atkbd->set = atkbd_set_3(atkbd);
++              atkbd_enable(atkbd);
++      } else {
++              atkbd->set = 2;
++              atkbd->id = 0xab00;
++      }
++
++      /*
++       * Here we probably should check if the keyboard has the same set that
++         * it had before and bail out if it's different. But this will most likely
++         * cause new keyboard device be created... and for the user it will look
++         * like keyboard is lost
++       */
++
++      if (atkbd->translated) {
++              for (i = 0; i < 128; i++) {
++                      atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
++                      atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
++              }
++      } else if (atkbd->set == 2) {
++              memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
++      } else {
++              memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
++      }
++
++      for (i = 0; i < 512; i++)
++              if (atkbd->keycode[i] && atkbd->keycode[i] < 255)
++                      set_bit(atkbd->keycode[i], atkbd->dev.keybit);
++
++      return 0;
++}
+ static struct serio_dev atkbd_dev = {
+       .interrupt =    atkbd_interrupt,
+       .connect =      atkbd_connect,
++      .reconnect =    atkbd_reconnect,
+       .disconnect =   atkbd_disconnect,
+       .cleanup =      atkbd_cleanup,
+ };
+@@ -709,9 +778,17 @@ static int __init atkbd_setup_reset(char
+         if (ints[0] > 0) atkbd_reset = ints[1];
+         return 1;
+ }
++static int __init atkbd_setup_softrepeat(char *str)
++{
++        int ints[4];
++        str = get_options(str, ARRAY_SIZE(ints), ints);
++        if (ints[0] > 0) atkbd_softrepeat = ints[1];
++        return 1;
++}
+ __setup("atkbd_set=", atkbd_setup_set);
+ __setup("atkbd_reset", atkbd_setup_reset);
++__setup("atkbd_softrepeat=", atkbd_setup_softrepeat);
+ #endif
+ int __init atkbd_init(void)
+--- linux-2.6.0/drivers/input/mousedev.c       2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/mousedev.c        2003-12-28 23:21:31.000000000 -0800
+@@ -53,12 +53,14 @@ struct mousedev_list {
+       struct fasync_struct *fasync;
+       struct mousedev *mousedev;
+       struct list_head node;
+-      int dx, dy, dz, oldx, oldy;
+-      signed char ps2[6];
++      int dx, dy, dz;
++      int old_x[4], old_y[4];
+       unsigned long buttons;
++      signed char ps2[6];
+       unsigned char ready, buffer, bufsiz;
+       unsigned char mode, imexseq, impsseq;
+-      int finger;
++      unsigned int pkt_count;
++      unsigned char touch;
+ };
+ #define MOUSEDEV_SEQ_LEN      6
+@@ -74,49 +76,49 @@ static struct mousedev mousedev_mix;
+ static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X;
+ static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y;
++#define fx(i)  (list->old_x[(list->pkt_count - (i)) & 03])
++#define fy(i)  (list->old_y[(list->pkt_count - (i)) & 03])
++
+ static void mousedev_abs_event(struct input_handle *handle, struct mousedev_list *list, unsigned int code, int value)
+ {
+       int size;
++      int touchpad;
+       /* Ignore joysticks */
+       if (test_bit(BTN_TRIGGER, handle->dev->keybit))
+               return;
+-      /* Handle touchpad data */
+-      if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
++      touchpad = test_bit(BTN_TOOL_FINGER, handle->dev->keybit);
+-              if (list->finger && list->finger < 3)
+-                      list->finger++;
+-
+-              switch (code) {
+-                      case ABS_X:
+-                              if (list->finger == 3)
+-                                      list->dx += (value - list->oldx) / 8;
+-                              list->oldx = value;
+-                              return;
+-                      case ABS_Y:
+-                              if (list->finger == 3)
+-                                      list->dy -= (value - list->oldy) / 8;
+-                              list->oldy = value;
+-                              return;
+-              }
+-              return;
+-      }
+-
+-      /* Handle tablet data */
+       switch (code) {
+               case ABS_X:
+-                      size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
+-                      if (size == 0) size = xres;
+-                      list->dx += (value * xres - list->oldx) / size;
+-                      list->oldx += list->dx * size;
+-                      return;
++                      if (touchpad) {
++                              if (list->touch) {
++                                      fx(0) = value;
++                                      if (list->pkt_count >= 2)
++                                              list->dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
++                              }
++                      } else {
++                              size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
++                              if (size == 0) size = xres;
++                              list->dx += (value * xres - list->old_x[0]) / size;
++                              list->old_x[0] += list->dx * size;
++                      }
++                      break;
+               case ABS_Y:
+-                      size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
+-                      if (size == 0) size = yres;
+-                      list->dy -= (value * yres - list->oldy) / size;
+-                      list->oldy -= list->dy * size;
+-                      return;
++                      if (touchpad) {
++                              if (list->touch) {
++                                      fy(0) = value;
++                                      if (list->pkt_count >= 2)
++                                              list->dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
++                              }
++                      } else {
++                              size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
++                              if (size == 0) size = yres;
++                              list->dy -= (value * yres - list->old_y[0]) / size;
++                              list->old_y[0] -= list->dy * size;
++                      }
++                      break;
+       }
+ }
+@@ -146,12 +148,16 @@ static void mousedev_event(struct input_
+                                       break;
+                               case EV_KEY:
++                                      if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
++                                              /* Handle touchpad data */
++                                              list->touch = value;
++                                              if (!list->touch)
++                                                      list->pkt_count = 0;
++                                              break;
++                                      }
++
+                                       switch (code) {
+-                                              case BTN_TOUCH: /* Handle touchpad data */
+-                                                      if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
+-                                                              list->finger = value;
+-                                                              return;
+-                                                      }
++                                              case BTN_TOUCH:
+                                               case BTN_0:
+                                               case BTN_FORWARD:
+                                               case BTN_LEFT:   index = 0; break;
+@@ -178,6 +184,16 @@ static void mousedev_event(struct input_
+                               case EV_SYN:
+                                       switch (code) {
+                                               case SYN_REPORT:
++                                                      if (list->touch) {
++                                                              list->pkt_count++;
++                                                              /* Input system eats duplicate events,
++                                                               * but we need all of them to do correct
++                                                               * averaging so apply present one forward
++                                                               */
++                                                              fx(0) = fx(1);
++                                                              fy(0) = fy(1);
++                                                      }
++
+                                                       list->ready = 1;
+                                                       kill_fasync(&list->fasync, SIGIO, POLL_IN);
+                                                       wake = 1;
+--- linux-2.6.0/drivers/input/mouse/Kconfig    2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/input/mouse/Kconfig     2003-12-28 23:21:30.000000000 -0800
+@@ -23,27 +23,18 @@ config MOUSE_PS2
+         mice with wheels and extra buttons, Microsoft, Logitech or Genius
+         compatible.
++        Synaptics TouchPad users might be interested in a specialized
++        XFree86 driver at:
++              http://w1.894.telia.com/~u89404340/touchpad/index.html
++        and a new verion of GPM at:
++              http://www.geocities.com/dt_or/gpm/gpm.html
++        to take advantage of the advanced features of the touchpad.
++
+         If unsure, say Y.
+         To compile this driver as a module, choose M here: the
+         module will be called psmouse.
+-config MOUSE_PS2_SYNAPTICS
+-      bool "Synaptics TouchPad"
+-      default n
+-      depends on INPUT && INPUT_MOUSE && MOUSE_PS2
+-      ---help---
+-        Say Y here if you have a Synaptics TouchPad connected to your system.
+-        This touchpad is found on many modern laptop computers.
+-
+-        Note that you also need a user space driver to interpret the data
+-        generated by the kernel. A compatible driver for XFree86 is available
+-        from http://w1.894.telia.com/~u89404340/touchpad/index.html
+-
+-        The gpm program is not yet able to interpret the data from this
+-        driver, so if you need to use the touchpad in the console, you have to
+-        say N for now.
+-
+ config MOUSE_SERIAL
+       tristate "Serial mouse"
+       depends on INPUT && INPUT_MOUSE
+--- linux-2.6.0/drivers/input/mouse/logips2pp.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/input/mouse/logips2pp.c 2003-12-28 23:21:28.000000000 -0800
+@@ -10,6 +10,7 @@
+  */
+ #include <linux/input.h>
++#include <linux/serio.h>
+ #include "psmouse.h"
+ #include "logips2pp.h"
+@@ -142,7 +143,7 @@ void ps2pp_set_800dpi(struct psmouse *ps
+  * touchpad.
+  */
+-int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param)
++static int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param)
+ {
+       int i;
+       static int logitech_4btn[] = { 12, 40, 41, 42, 43, 52, 73, 80, -1 };
+@@ -226,3 +227,22 @@ int ps2pp_detect_model(struct psmouse *p
+       return 0;
+ }
++
++/*
++ * Logitech magic init.
++ */
++int ps2pp_detect(struct psmouse *psmouse)
++{
++      unsigned char param[4];
++
++      param[0] = 0;
++      psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
++      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
++      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
++      param[1] = 0;
++      psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
++
++      return param[1] != 0 ? ps2pp_detect_model(psmouse, param) : 0;
++}
++
+--- linux-2.6.0/drivers/input/mouse/logips2pp.h        2003-06-22 12:04:44.000000000 -0700
++++ 25/drivers/input/mouse/logips2pp.h 2003-12-28 23:21:28.000000000 -0800
+@@ -13,5 +13,5 @@
+ struct psmouse;
+ void ps2pp_process_packet(struct psmouse *psmouse);
+ void ps2pp_set_800dpi(struct psmouse *psmouse);
+-int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param);
++int ps2pp_detect(struct psmouse *psmouse);
+ #endif
+--- linux-2.6.0/drivers/input/mouse/psmouse-base.c     2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/input/mouse/psmouse-base.c      2003-12-28 23:21:30.000000000 -0800
+@@ -12,35 +12,44 @@
+ #include <linux/delay.h>
+ #include <linux/module.h>
++#include <linux/moduleparam.h>
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
+ #include <linux/input.h>
+ #include <linux/serio.h>
+ #include <linux/init.h>
+-#include <linux/pm.h>
+ #include "psmouse.h"
+ #include "synaptics.h"
+ #include "logips2pp.h"
+ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+ MODULE_DESCRIPTION("PS/2 mouse driver");
+-MODULE_PARM(psmouse_noext, "1i");
+-MODULE_PARM_DESC(psmouse_noext, "Disable any protocol extensions. Useful for KVM switches.");
+-MODULE_PARM(psmouse_resolution, "i");
+-MODULE_PARM_DESC(psmouse_resolution, "Resolution, in dpi.");
+-MODULE_PARM(psmouse_rate, "i");
+-MODULE_PARM_DESC(psmouse_rate, "Report rate, in reports per second.");
+-MODULE_PARM(psmouse_smartscroll, "i");
+-MODULE_PARM_DESC(psmouse_smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
+-MODULE_PARM(psmouse_resetafter, "i");
+-MODULE_PARM_DESC(psmouse_resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never).");
+ MODULE_LICENSE("GPL");
+ static int psmouse_noext;
++module_param(psmouse_noext, int, 0);
++MODULE_PARM_DESC(psmouse_noext, "[DEPRECATED] Disable any protocol extensions. Useful for KVM switches.");
++
++static char *psmouse_proto;
++static unsigned int psmouse_max_proto = -1UL;
++module_param(psmouse_proto, charp, 0);
++MODULE_PARM_DESC(psmouse_proto, "Highest protocol extension to probe (bare, imps, exps). Useful for KVM switches.");
++
+ int psmouse_resolution = 200;
++module_param(psmouse_resolution, uint, 0);
++MODULE_PARM_DESC(psmouse_resolution, "Resolution, in dpi.");
++
+ unsigned int psmouse_rate = 100;
++module_param(psmouse_rate, uint, 0);
++MODULE_PARM_DESC(psmouse_rate, "Report rate, in reports per second.");
++
+ int psmouse_smartscroll = 1;
++module_param(psmouse_smartscroll, bool, 0);
++MODULE_PARM_DESC(psmouse_smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
++
+ unsigned int psmouse_resetafter;
++module_param(psmouse_resetafter, uint, 0);
++MODULE_PARM_DESC(psmouse_resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never).");
+ static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
+@@ -139,7 +148,8 @@ static irqreturn_t psmouse_interrupt(str
+               goto out;
+       }
+-      if (psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
++      if (psmouse->state == PSMOUSE_ACTIVATED &&
++          psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
+               printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n",
+                      psmouse->name, psmouse->phys, psmouse->pktcnt);
+               psmouse->pktcnt = 0;
+@@ -257,46 +267,12 @@ int psmouse_command(struct psmouse *psmo
+ }
+ /*
+- * psmouse_extensions() probes for any extensions to the basic PS/2 protocol
+- * the mouse may have.
++ * Genius NetMouse magic init.
+  */
+-
+-static int psmouse_extensions(struct psmouse *psmouse)
++static int genius_detect(struct psmouse *psmouse)
+ {
+       unsigned char param[4];
+-      param[0] = 0;
+-      psmouse->vendor = "Generic";
+-      psmouse->name = "Mouse";
+-      psmouse->model = 0;
+-
+-      if (psmouse_noext)
+-              return PSMOUSE_PS2;
+-
+-/*
+- * Try Synaptics TouchPad magic ID
+- */
+-
+-       param[0] = 0;
+-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+-       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+-       psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+-
+-       if (param[1] == 0x47) {
+-              psmouse->vendor = "Synaptics";
+-              psmouse->name = "TouchPad";
+-              if (!synaptics_init(psmouse))
+-                      return PSMOUSE_SYNAPTICS;
+-              else
+-                      return PSMOUSE_PS2;
+-       }
+-
+-/*
+- * Try Genius NetMouse magic init.
+- */
+-
+       param[0] = 3;
+       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+       psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+@@ -304,65 +280,99 @@ static int psmouse_extensions(struct psm
+       psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+       psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
+-      if (param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55) {
+-
+-              set_bit(BTN_EXTRA, psmouse->dev.keybit);
+-              set_bit(BTN_SIDE, psmouse->dev.keybit);
+-              set_bit(REL_WHEEL, psmouse->dev.relbit);
+-
+-              psmouse->vendor = "Genius";
+-              psmouse->name = "Wheel Mouse";
+-              return PSMOUSE_GENPS;
+-      }
++      return param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55;
++}
+ /*
+- * Try Logitech magic ID.
++ * IntelliMouse magic init.
+  */
++static int intellimouse_detect(struct psmouse *psmouse)
++{
++      unsigned char param[2];
+-      param[0] = 0;
+-      psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
+-      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+-      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+-      psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+-      param[1] = 0;
+-      psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
++      param[0] = 200;
++      psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
++      param[0] = 100;
++      psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
++      param[0] =  80;
++      psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
++      psmouse_command(psmouse, param, PSMOUSE_CMD_GETID);
+-      if (param[1]) {
+-              int type = ps2pp_detect_model(psmouse, param);
+-              if (type)
+-                      return type;
+-      }
++      return param[0] == 3;
++}
+ /*
+- * Try IntelliMouse magic init.
++ * Try IntelliMouse/Explorer magic init.
+  */
++static int im_explorer_detect(struct psmouse *psmouse)
++{
++      unsigned char param[2];
+       param[0] = 200;
+       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+-      param[0] = 100;
++      param[0] = 200;
+       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+       param[0] =  80;
+       psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+       psmouse_command(psmouse, param, PSMOUSE_CMD_GETID);
+-      
+-      if (param[0] == 3) {
+-              set_bit(REL_WHEEL, psmouse->dev.relbit);
++      return param[0] == 4;
++}
+ /*
+- * Try IntelliMouse/Explorer magic init.
++ * psmouse_extensions() probes for any extensions to the basic PS/2 protocol
++ * the mouse may have.
++ */
++
++static int psmouse_extensions(struct psmouse *psmouse)
++{
++      int synaptics_hardware = 0;
++
++      psmouse->vendor = "Generic";
++      psmouse->name = "Mouse";
++      psmouse->model = 0;
++
++/*
++ * Try Synaptics TouchPad
+  */
++      if (psmouse_max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {
++              synaptics_hardware = 1;
++              psmouse->vendor = "Synaptics";
++              psmouse->name = "TouchPad";
+-              param[0] = 200;
+-              psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+-              param[0] = 200;
+-              psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+-              param[0] =  80;
+-              psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE);
+-              psmouse_command(psmouse, param, PSMOUSE_CMD_GETID);
++              if (psmouse_max_proto > PSMOUSE_IMEX) {
++                      if (synaptics_init(psmouse) == 0)
++                              return PSMOUSE_SYNAPTICS;
++/*
++ * Some Synaptics touchpads can emulate extended protocols (like IMPS/2).
++ * Unfortunately Logitech/Genius probes confuse some firmware versions so
++ * we'll have to skip them.
++ */
++                      psmouse_max_proto = PSMOUSE_IMEX;
++              }
++      }
+-              if (param[0] == 4) {
++      if (psmouse_max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
++              set_bit(BTN_EXTRA, psmouse->dev.keybit);
++              set_bit(BTN_SIDE, psmouse->dev.keybit);
++              set_bit(REL_WHEEL, psmouse->dev.relbit);
++              psmouse->vendor = "Genius";
++              psmouse->name = "Wheel Mouse";
++              return PSMOUSE_GENPS;
++      }
++
++      if (psmouse_max_proto > PSMOUSE_IMEX) {
++              int type = ps2pp_detect(psmouse);
++              if (type)
++                      return type;
++      }
++
++      if (psmouse_max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {
++              set_bit(REL_WHEEL, psmouse->dev.relbit);
++
++              if (psmouse_max_proto >= PSMOUSE_IMEX &&
++                                      im_explorer_detect(psmouse)) {
+                       set_bit(BTN_SIDE, psmouse->dev.keybit);
+                       set_bit(BTN_EXTRA, psmouse->dev.keybit);
+@@ -378,6 +388,15 @@ static int psmouse_extensions(struct psm
+  * Okay, all failed, we have a standard mouse here. The number of the buttons
+  * is still a question, though. We assume 3.
+  */
++      if (synaptics_hardware) {
++/*
++ * We detected Synaptics hardware but it did not respond to IMPS/2 probes.
++ * We need to reset the touchpad because if there is a track point on the
++ * pass through port it could get disabled while probing for protocol
++ * extensions.
++ */
++              psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS);
++      }
+       return PSMOUSE_PS2;
+ }
+@@ -468,7 +487,7 @@ static void psmouse_initialize(struct ps
+  * We set the mouse report rate, resolution and scaling.
+  */
+-      if (!psmouse_noext) {
++      if (psmouse_max_proto != PSMOUSE_PS2) {
+               psmouse_set_rate(psmouse);
+               psmouse_set_resolution(psmouse);
+               psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+@@ -513,45 +532,30 @@ static void psmouse_disconnect(struct se
+       struct psmouse *psmouse = serio->private;
+       psmouse->state = PSMOUSE_IGNORE;
+-      synaptics_disconnect(psmouse);
+-      input_unregister_device(&psmouse->dev);
+-      serio_close(serio);
+-      kfree(psmouse);
+-}
+-
+-/*
+- * Reinitialize mouse hardware after software suspend.
+- */
+-
+-static int psmouse_pm_callback(struct pm_dev *dev, pm_request_t request, void *data)
+-{
+-      struct psmouse *psmouse = dev->data;
+-      struct serio_dev *ser_dev = psmouse->serio->dev;
+-
+-      synaptics_disconnect(psmouse);
+-      /* We need to reopen the serio port to reinitialize the i8042 controller */
+-      serio_close(psmouse->serio);
+-      serio_open(psmouse->serio, ser_dev);
++      if (psmouse->ptport) {
++              if (psmouse->ptport->deactivate)
++                      psmouse->ptport->deactivate(psmouse);
++              __serio_unregister_port(&psmouse->ptport->serio); /* we have serio_sem */
++              kfree(psmouse->ptport);
++              psmouse->ptport = NULL;
++      }
+-      /* Probe and re-initialize the mouse */
+-      psmouse_probe(psmouse);
+-      psmouse_initialize(psmouse);
+-      synaptics_pt_init(psmouse);
+-      psmouse_activate(psmouse);
++      if (psmouse->disconnect)
++              psmouse->disconnect(psmouse);
+-      return 0;
++      input_unregister_device(&psmouse->dev);
++      serio_close(serio);
++      kfree(psmouse);
+ }
+ /*
+  * psmouse_connect() is a callback from the serio module when
+  * an unhandled serio port is found.
+  */
+-
+ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
+ {
+       struct psmouse *psmouse;
+-      struct pm_dev *pmdev;
+       
+       if ((serio->type & SERIO_TYPE) != SERIO_8042 &&
+           (serio->type & SERIO_TYPE) != SERIO_PS_PSTHRU)
+@@ -572,7 +576,6 @@ static void psmouse_connect(struct serio
+       psmouse->dev.private = psmouse;
+       serio->private = psmouse;
+-
+       if (serio_open(serio, dev)) {
+               kfree(psmouse);
+               return;
+@@ -584,12 +587,6 @@ static void psmouse_connect(struct serio
+               return;
+       }
+       
+-      pmdev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, psmouse_pm_callback);
+-      if (pmdev) {
+-              psmouse->dev.pm_dev = pmdev;
+-              pmdev->data = psmouse;
+-      }
+-
+       sprintf(psmouse->devname, "%s %s %s",
+               psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
+       sprintf(psmouse->phys, "%s/input0",
+@@ -608,59 +605,87 @@ static void psmouse_connect(struct serio
+       psmouse_initialize(psmouse);
+-      synaptics_pt_init(psmouse);
++      if (psmouse->ptport) {
++              printk(KERN_INFO "serio: %s port at %s\n", psmouse->ptport->serio.name, psmouse->phys);
++              __serio_register_port(&psmouse->ptport->serio); /* we have serio_sem */
++              if (psmouse->ptport->activate)
++                      psmouse->ptport->activate(psmouse);
++      }
++
++      psmouse_activate(psmouse);
++}
++
++
++static int psmouse_reconnect(struct serio *serio)
++{
++      struct psmouse *psmouse = serio->private;
++      struct serio_dev *dev = serio->dev;
++      int old_type = psmouse->type;
++
++      if (!dev) {
++              printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");
++              return -1;
++      }
++
++      psmouse->state = PSMOUSE_NEW_DEVICE;
++      psmouse->type = psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = 0;
++      if (psmouse->reconnect) {
++             if (psmouse->reconnect(psmouse))
++                      return -1;
++      } else if (psmouse_probe(psmouse) != old_type)
++              return -1;
++
++      /* ok, the device type (and capabilities) match the old one,
++       * we can continue using it, complete intialization
++       */
++      psmouse->type = old_type;
++      psmouse_initialize(psmouse);
++
++      if (psmouse->ptport) {
++                      if (psmouse_reconnect(&psmouse->ptport->serio)) {
++                      __serio_unregister_port(&psmouse->ptport->serio);
++                      __serio_register_port(&psmouse->ptport->serio);
++                      if (psmouse->ptport->activate)
++                              psmouse->ptport->activate(psmouse);
++              }
++      }
+       psmouse_activate(psmouse);
++      return 0;
+ }
++
+ static struct serio_dev psmouse_dev = {
+       .interrupt =    psmouse_interrupt,
+       .connect =      psmouse_connect,
++      .reconnect =    psmouse_reconnect,
+       .disconnect =   psmouse_disconnect,
+       .cleanup =      psmouse_cleanup,
+ };
+-#ifndef MODULE
+-static int __init psmouse_noext_setup(char *str)
+-{
+-      psmouse_noext = 1;
+-      return 1;
+-}
+-
+-static int __init psmouse_resolution_setup(char *str)
+-{
+-      get_option(&str, &psmouse_resolution);
+-      return 1;
+-}
+-
+-static int __init psmouse_smartscroll_setup(char *str)
++static inline void psmouse_parse_proto(void)
+ {
+-      get_option(&str, &psmouse_smartscroll);
+-      return 1;
+-}
+-
+-static int __init psmouse_resetafter_setup(char *str)
+-{
+-      get_option(&str, &psmouse_resetafter);
+-      return 1;
+-}
++      if (psmouse_noext) {
++              printk(KERN_WARNING "psmouse: 'psmouse_noext' option is deprecated, please use 'psmouse_proto'\n");
++              psmouse_max_proto = PSMOUSE_PS2;
++      }
+-static int __init psmouse_rate_setup(char *str)
+-{
+-      get_option(&str, &psmouse_rate);
+-      return 1;
++      /* even is psmouse_noext is present psmouse_proto overrides it */
++      if (psmouse_proto) {
++              if (!strcmp(psmouse_proto, "bare"))
++                      psmouse_max_proto = PSMOUSE_PS2;
++              else if (!strcmp(psmouse_proto, "imps"))
++                      psmouse_max_proto = PSMOUSE_IMPS;
++              else if (!strcmp(psmouse_proto, "exps"))
++                      psmouse_max_proto = PSMOUSE_IMEX;
++              else
++                      printk(KERN_ERR "psmouse: unknown protocol type '%s'\n", psmouse_proto);
++      }
+ }
+-__setup("psmouse_noext", psmouse_noext_setup);
+-__setup("psmouse_resolution=", psmouse_resolution_setup);
+-__setup("psmouse_smartscroll=", psmouse_smartscroll_setup);
+-__setup("psmouse_resetafter=", psmouse_resetafter_setup);
+-__setup("psmouse_rate=", psmouse_rate_setup);
+-
+-#endif
+-
+ int __init psmouse_init(void)
+ {
++      psmouse_parse_proto();
+       serio_register_device(&psmouse_dev);
+       return 0;
+ }
+--- linux-2.6.0/drivers/input/mouse/psmouse.h  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/input/mouse/psmouse.h   2003-12-28 23:21:27.000000000 -0800
+@@ -22,10 +22,20 @@
+ #define PSMOUSE_ACTIVATED     1
+ #define PSMOUSE_IGNORE                2
++struct psmouse;
++
++struct psmouse_ptport {
++      struct serio serio;
++
++      void (*activate)(struct psmouse *parent);
++      void (*deactivate)(struct psmouse *parent);
++};
++
+ struct psmouse {
+       void *private;
+       struct input_dev dev;
+       struct serio *serio;
++      struct psmouse_ptport *ptport;
+       char *vendor;
+       char *name;
+       unsigned char cmdbuf[8];
+@@ -41,6 +51,9 @@ struct psmouse {
+       char error;
+       char devname[64];
+       char phys[32];
++
++      int (*reconnect)(struct psmouse *psmouse);
++      void (*disconnect)(struct psmouse *psmouse);
+ };
+ #define PSMOUSE_PS2           1
+--- linux-2.6.0/drivers/input/mouse/synaptics.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/input/mouse/synaptics.c 2003-12-28 23:21:31.000000000 -0800
+@@ -2,7 +2,8 @@
+  * Synaptics TouchPad PS/2 mouse driver
+  *
+  *   2003 Dmitry Torokhov <dtor@mail.ru>
+- *     Added support for pass-through port
++ *     Added support for pass-through port. Special thanks to Peter Berg Larsen
++ *     for explaining various Synaptics quirks.
+  *
+  *   2003 Peter Osterlund <petero2@telia.com>
+  *     Ported to 2.5 input device infrastructure.
+@@ -194,9 +195,7 @@ static void print_ident(struct synaptics
+ static int synaptics_query_hardware(struct psmouse *psmouse)
+ {
+-      struct synaptics_data *priv = psmouse->private;
+       int retries = 0;
+-      int mode;
+       while ((retries++ < 3) && synaptics_reset(psmouse))
+               printk(KERN_ERR "synaptics reset failed\n");
+@@ -208,7 +207,14 @@ static int synaptics_query_hardware(stru
+       if (synaptics_capability(psmouse))
+               return -1;
+-      mode = SYN_BIT_ABSOLUTE_MODE | SYN_BIT_HIGH_RATE;
++      return 0;
++}
++
++static int synaptics_set_mode(struct psmouse *psmouse, int mode)
++{
++      struct synaptics_data *priv = psmouse->private;
++
++      mode |= SYN_BIT_ABSOLUTE_MODE | SYN_BIT_HIGH_RATE;
+       if (SYN_ID_MAJOR(priv->identity) >= 4)
+               mode |= SYN_BIT_DISABLE_GESTURE;
+       if (SYN_CAP_EXTENDED(priv->capabilities))
+@@ -265,49 +271,38 @@ static void synaptics_pass_pt_packet(str
+       }
+ }
+-int synaptics_pt_init(struct psmouse *psmouse)
++static void synaptics_pt_activate(struct psmouse *psmouse)
+ {
+-      struct synaptics_data *priv = psmouse->private;
+-      struct serio *port;
+-      struct psmouse *child;
++      struct psmouse *child = psmouse->ptport->serio.private;
+-      if (psmouse->type != PSMOUSE_SYNAPTICS)
+-              return -1;
+-      if (!SYN_CAP_EXTENDED(priv->capabilities))
+-              return -1;
+-      if (!SYN_CAP_PASS_THROUGH(priv->capabilities))
+-              return -1;
++      /* adjust the touchpad to child's choice of protocol */
++      if (child && child->type >= PSMOUSE_GENPS) {
++              if (synaptics_set_mode(psmouse, SYN_BIT_FOUR_BYTE_CLIENT))
++                      printk(KERN_INFO "synaptics: failed to enable 4-byte guest protocol\n");
++      }
++}
+-      priv->ptport = port = kmalloc(sizeof(struct serio), GFP_KERNEL);
++static void synaptics_pt_create(struct psmouse *psmouse)
++{
++      struct psmouse_ptport *port;
++
++      psmouse->ptport = port = kmalloc(sizeof(struct psmouse_ptport), GFP_KERNEL);
+       if (!port) {
+-              printk(KERN_ERR "synaptics: not enough memory to allocate serio port\n");
+-              return -1;
++              printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n");
++              return;
+       }
+-      memset(port, 0, sizeof(struct serio));
+-      port->type = SERIO_PS_PSTHRU;
+-      port->name = "Synaptics pass-through";
+-      port->phys = "synaptics-pt/serio0";
+-      port->write = synaptics_pt_write;
+-      port->open = synaptics_pt_open;
+-      port->close = synaptics_pt_close;
+-      port->driver = psmouse;
++      memset(port, 0, sizeof(struct psmouse_ptport));
+-      printk(KERN_INFO "serio: %s port at %s\n", port->name, psmouse->phys);
+-      serio_register_slave_port(port);
++      port->serio.type = SERIO_PS_PSTHRU;
++      port->serio.name = "Synaptics pass-through";
++      port->serio.phys = "synaptics-pt/serio0";
++      port->serio.write = synaptics_pt_write;
++      port->serio.open = synaptics_pt_open;
++      port->serio.close = synaptics_pt_close;
++      port->serio.driver = psmouse;
+-      /* adjust the touchpad to child's choice of protocol */
+-      child = port->private;
+-      if (child && child->type >= PSMOUSE_GENPS) {
+-              if (synaptics_mode_cmd(psmouse, (SYN_BIT_ABSOLUTE_MODE |
+-                                               SYN_BIT_HIGH_RATE |
+-                                               SYN_BIT_DISABLE_GESTURE |
+-                                               SYN_BIT_FOUR_BYTE_CLIENT |
+-                                               SYN_BIT_W_MODE)))
+-                      printk(KERN_INFO "synaptics: failed to enable 4-byte guest protocol\n");
+-      }
+-
+-      return 0;
++      port->activate = synaptics_pt_activate;
+ }
+ /*****************************************************************************
+@@ -371,27 +366,82 @@ static void set_input_params(struct inpu
+       clear_bit(REL_Y, dev->relbit);
+ }
++static void synaptics_disconnect(struct psmouse *psmouse)
++{
++      synaptics_mode_cmd(psmouse, 0);
++      kfree(psmouse->private);
++}
++
++static int synaptics_reconnect(struct psmouse *psmouse)
++{
++      struct synaptics_data *priv = psmouse->private;
++      struct synaptics_data old_priv = *priv;
++
++      if (!synaptics_detect(psmouse))
++              return -1;
++
++      if (synaptics_query_hardware(psmouse)) {
++              printk(KERN_ERR "Unable to query Synaptics hardware.\n");
++              return -1;
++      }
++
++      if (old_priv.identity != priv->identity ||
++          old_priv.model_id != priv->model_id ||
++          old_priv.capabilities != priv->capabilities ||
++          old_priv.ext_cap != priv->ext_cap)
++              return -1;
++
++      if (synaptics_set_mode(psmouse, 0)) {
++              printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
++              return -1;
++      }
++
++      return 0;
++}
++
++int synaptics_detect(struct psmouse *psmouse)
++{
++      unsigned char param[4];
++
++      param[0] = 0;
++
++      psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++      psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++      psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++      psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
++      psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
++
++      return param[1] == 0x47;
++}
++
+ int synaptics_init(struct psmouse *psmouse)
+ {
+       struct synaptics_data *priv;
+-#ifndef CONFIG_MOUSE_PS2_SYNAPTICS
+-      return -1;
+-#endif
+-
+       psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
+       if (!priv)
+               return -1;
+       memset(priv, 0, sizeof(struct synaptics_data));
+       if (synaptics_query_hardware(psmouse)) {
+-              printk(KERN_ERR "Unable to query/initialize Synaptics hardware.\n");
++              printk(KERN_ERR "Unable to query Synaptics hardware.\n");
+               goto init_fail;
+       }
++      if (synaptics_set_mode(psmouse, 0)) {
++              printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
++              goto init_fail;
++      }
++
++      if (SYN_CAP_EXTENDED(priv->capabilities) && SYN_CAP_PASS_THROUGH(priv->capabilities))
++                      synaptics_pt_create(psmouse);
++
+       print_ident(priv);
+       set_input_params(&psmouse->dev, priv);
++      psmouse->disconnect = synaptics_disconnect;
++      psmouse->reconnect = synaptics_reconnect;
++
+       return 0;
+  init_fail:
+@@ -399,36 +449,13 @@ int synaptics_init(struct psmouse *psmou
+       return -1;
+ }
+-void synaptics_disconnect(struct psmouse *psmouse)
+-{
+-      struct synaptics_data *priv = psmouse->private;
+-
+-      if (psmouse->type == PSMOUSE_SYNAPTICS && priv) {
+-              synaptics_mode_cmd(psmouse, 0);
+-              if (priv->ptport) {
+-                      serio_unregister_slave_port(priv->ptport);
+-                      kfree(priv->ptport);
+-              }
+-              kfree(priv);
+-      }
+-}
+-
+ /*****************************************************************************
+  *    Functions to interpret the absolute mode packets
+  ****************************************************************************/
+ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw)
+ {
+-      hw->up    = 0;
+-      hw->down  = 0;
+-      hw->b0    = 0;
+-      hw->b1    = 0;
+-      hw->b2    = 0;
+-      hw->b3    = 0;
+-      hw->b4    = 0;
+-      hw->b5    = 0;
+-      hw->b6    = 0;
+-      hw->b7    = 0;
++      memset(hw, 0, sizeof(struct synaptics_hw_state));
+       if (SYN_MODEL_NEWABS(priv->model_id)) {
+               hw->x = (((buf[3] & 0x10) << 8) |
+@@ -526,16 +553,19 @@ static void synaptics_process_packet(str
+               finger_width = 0;
+       }
+-      /* Post events */
++      /* Post events
++       * BTN_TOUCH has to be first as mousedev relies on it when doing
++       * absolute -> relative conversion
++       */
++      if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1);
++      if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0);
++
+       if (hw.z > 0) {
+               input_report_abs(dev, ABS_X, hw.x);
+               input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y);
+       }
+       input_report_abs(dev, ABS_PRESSURE, hw.z);
+-      if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1);
+-      if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0);
+-
+       input_report_abs(dev, ABS_TOOL_WIDTH, finger_width);
+       input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1);
+       input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
+@@ -570,64 +600,47 @@ static void synaptics_process_packet(str
+       input_sync(dev);
+ }
++static int synaptics_validate_byte(struct psmouse *psmouse)
++{
++      static unsigned char newabs_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
++      static unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
++      static unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
++      static unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
++      struct synaptics_data *priv = psmouse->private;
++      int idx = psmouse->pktcnt - 1;
++
++      if (SYN_MODEL_NEWABS(priv->model_id))
++              return (psmouse->packet[idx] & newabs_mask[idx]) == newabs_rslt[idx];
++      else
++              return (psmouse->packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx];
++}
++
+ void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+ {
+       struct input_dev *dev = &psmouse->dev;
+       struct synaptics_data *priv = psmouse->private;
+-      unsigned char data = psmouse->packet[psmouse->pktcnt - 1];
+-      int newabs = SYN_MODEL_NEWABS(priv->model_id);
+       input_regs(dev, regs);
+-      switch (psmouse->pktcnt) {
+-      case 1:
+-              if (newabs ? ((data & 0xC8) != 0x80) : ((data & 0xC0) != 0xC0)) {
+-                      printk(KERN_WARNING "Synaptics driver lost sync at 1st byte\n");
+-                      goto bad_sync;
+-              }
+-              break;
+-      case 2:
+-              if (!newabs && ((data & 0x60) != 0x00)) {
+-                      printk(KERN_WARNING "Synaptics driver lost sync at 2nd byte\n");
+-                      goto bad_sync;
+-              }
+-              break;
+-      case 4:
+-              if (newabs ? ((data & 0xC8) != 0xC0) : ((data & 0xC0) != 0x80)) {
+-                      printk(KERN_WARNING "Synaptics driver lost sync at 4th byte\n");
+-                      goto bad_sync;
+-              }
+-              break;
+-      case 5:
+-              if (!newabs && ((data & 0x60) != 0x00)) {
+-                      printk(KERN_WARNING "Synaptics driver lost sync at 5th byte\n");
+-                      goto bad_sync;
+-              }
+-              break;
+-      default:
+-              if (psmouse->pktcnt < 6)
+-                      break;              /* Wait for full packet */
+-
++      if (psmouse->pktcnt >= 6) { /* Full packet received */
+               if (priv->out_of_sync) {
+                       priv->out_of_sync = 0;
+                       printk(KERN_NOTICE "Synaptics driver resynced.\n");
+               }
+-              if (priv->ptport && synaptics_is_pt_packet(psmouse->packet))
+-                      synaptics_pass_pt_packet(priv->ptport, psmouse->packet);
++              if (psmouse->ptport && psmouse->ptport->serio.dev && synaptics_is_pt_packet(psmouse->packet))
++                      synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
+               else
+                       synaptics_process_packet(psmouse);
+-
+               psmouse->pktcnt = 0;
+-              break;
+-      }
+-      return;
+- bad_sync:
+-      priv->out_of_sync++;
+-      psmouse->pktcnt = 0;
+-      if (psmouse_resetafter > 0 && priv->out_of_sync == psmouse_resetafter) {
+-              psmouse->state = PSMOUSE_IGNORE;
+-              serio_rescan(psmouse->serio);
++      } else if (psmouse->pktcnt && !synaptics_validate_byte(psmouse)) {
++              printk(KERN_WARNING "Synaptics driver lost sync at byte %d\n", psmouse->pktcnt);
++              psmouse->pktcnt = 0;
++              if (++priv->out_of_sync == psmouse_resetafter) {
++                      psmouse->state = PSMOUSE_IGNORE;
++                      printk(KERN_NOTICE "synaptics: issuing reconnect request\n");
++                      serio_reconnect(psmouse->serio);
++              }
+       }
+ }
+--- linux-2.6.0/drivers/input/mouse/synaptics.h        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/input/mouse/synaptics.h 2003-12-28 23:21:27.000000000 -0800
+@@ -9,11 +9,9 @@
+ #ifndef _SYNAPTICS_H
+ #define _SYNAPTICS_H
+-
+ extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
++extern int synaptics_detect(struct psmouse *psmouse);
+ extern int synaptics_init(struct psmouse *psmouse);
+-extern int synaptics_pt_init(struct psmouse *psmouse);
+-extern void synaptics_disconnect(struct psmouse *psmouse);
+ /* synaptics queries */
+ #define SYN_QUE_IDENTIFY              0x00
+@@ -105,8 +103,6 @@ struct synaptics_data {
+       /* Data for normal processing */
+       unsigned int out_of_sync;               /* # of packets out of sync */
+       int old_w;                              /* Previous w value */
+-      
+-      struct serio *ptport;                   /* pass-through port */
+ };
+ #endif /* _SYNAPTICS_H */
+--- linux-2.6.0/drivers/input/serio/i8042.c    2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/input/serio/i8042.c     2003-12-28 23:21:30.000000000 -0800
+@@ -12,11 +12,14 @@
+ #include <linux/delay.h>
+ #include <linux/module.h>
++#include <linux/moduleparam.h>
+ #include <linux/interrupt.h>
+ #include <linux/ioport.h>
+ #include <linux/config.h>
+ #include <linux/reboot.h>
+ #include <linux/init.h>
++#include <linux/sysdev.h>
++#include <linux/pm.h>
+ #include <linux/serio.h>
+ #include <asm/io.h>
+@@ -25,19 +28,23 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@s
+ MODULE_DESCRIPTION("i8042 keyboard and mouse controller driver");
+ MODULE_LICENSE("GPL");
+-MODULE_PARM(i8042_noaux, "1i");
+-MODULE_PARM(i8042_nomux, "1i");
+-MODULE_PARM(i8042_unlock, "1i");
+-MODULE_PARM(i8042_reset, "1i");
+-MODULE_PARM(i8042_direct, "1i");
+-MODULE_PARM(i8042_dumbkbd, "1i");
+-
+-static int i8042_reset;
+-static int i8042_noaux;
+-static int i8042_nomux;
+-static int i8042_unlock;
+-static int i8042_direct;
+-static int i8042_dumbkbd;
++static unsigned int i8042_noaux;
++module_param(i8042_noaux, bool, 0);
++
++static unsigned int i8042_nomux;
++module_param(i8042_nomux, bool, 0);
++
++static unsigned int i8042_unlock;
++module_param(i8042_unlock, bool, 0);
++
++static unsigned int i8042_reset;
++module_param(i8042_reset, bool, 0);
++
++static unsigned int i8042_direct;
++module_param(i8042_direct, bool, 0);
++
++static unsigned int i8042_dumbkbd;
++module_param(i8042_dumbkbd, bool, 0);
+ #undef DEBUG
+ #include "i8042.h"
+@@ -59,6 +66,9 @@ static struct serio i8042_aux_port;
+ static unsigned char i8042_initial_ctr;
+ static unsigned char i8042_ctr;
+ static unsigned char i8042_mux_open;
++static unsigned char i8042_mux_present;
++static unsigned char i8042_sysdev_initialized;
++static struct pm_dev *i8042_pm_dev;
+ struct timer_list i8042_timer;
+ /*
+@@ -214,16 +224,41 @@ static int i8042_aux_write(struct serio 
+ }
+ /*
+- * i8042_open() is called when a port is open by the higher layer.
+- * It allocates the interrupt and enables it in the chip.
++ * i8042_activate_port() enables port on a chip.
+  */
+-static int i8042_open(struct serio *port)
++static int i8042_activate_port(struct serio *port)
+ {
+       struct i8042_values *values = port->driver;
+       i8042_flush();
++      /*
++       * Enable port again here because it is disabled if we are
++       * resuming (normally it is enabled already).
++       */
++      i8042_ctr &= ~values->disable;
++
++      i8042_ctr |= values->irqen;
++
++      if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
++              i8042_ctr &= ~values->irqen;
++              return -1;
++      }
++
++      return 0;
++}
++
++
++/*
++ * i8042_open() is called when a port is open by the higher layer.
++ * It allocates the interrupt and calls i8042_enable_port.
++ */
++
++static int i8042_open(struct serio *port)
++{
++      struct i8042_values *values = port->driver;
++
+       if (values->mux != -1)
+               if (i8042_mux_open++)
+                       return 0;
+@@ -231,21 +266,26 @@ static int i8042_open(struct serio *port
+       if (request_irq(values->irq, i8042_interrupt,
+                       SA_SHIRQ, "i8042", i8042_request_irq_cookie)) {
+               printk(KERN_ERR "i8042.c: Can't get irq %d for %s, unregistering the port.\n", values->irq, values->name);
+-              values->exists = 0;
+-              serio_unregister_port(port);
+-              return -1;
++              goto irq_fail;
+       }
+-      i8042_ctr |= values->irqen;
+-
+-      if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+-              printk(KERN_ERR "i8042.c: Can't write CTR while opening %s.\n", values->name);
+-              return -1;
++      if (i8042_activate_port(port)) {
++              printk(KERN_ERR "i8042.c: Can't activate %s, unregistering the port\n", values->name);
++              goto activate_fail;
+       }
+       i8042_interrupt(0, NULL, NULL);
+       return 0;
++
++activate_fail:
++      free_irq(values->irq, i8042_request_irq_cookie);
++
++irq_fail:
++      values->exists = 0;
++      serio_unregister_port_delayed(port);
++
++      return -1;
+ }
+ /*
+@@ -393,145 +433,78 @@ static irqreturn_t i8042_interrupt(int i
+ }
+ /*
+- * i8042_controller init initializes the i8042 controller, and,
+- * most importantly, sets it into non-xlated mode if that's
+- * desired.
++ * i8042_enable_mux_mode checks whether the controller has an active
++ * multiplexor and puts the chip into Multiplexed (as opposed to
++ * Legacy) mode.
+  */
+-      
+-static int __init i8042_controller_init(void)
++
++static int i8042_enable_mux_mode(struct i8042_values *values, unsigned char *mux_version)
+ {
++      unsigned char param;
+ /*
+- * Test the i8042. We need to know if it thinks it's working correctly
+- * before doing anything else.
++ * Get rid of bytes in the queue.
+  */
+       i8042_flush();
+-      if (i8042_reset) {
+-
+-              unsigned char param;
+-
+-              if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
+-                      printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
+-                      return -1;
+-              }
+-
+-              if (param != I8042_RET_CTL_TEST) {
+-                      printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
+-                               param, I8042_RET_CTL_TEST);
+-                      return -1;
+-              }
+-      }
+-
+ /*
+- * Save the CTR for restoral on unload / reboot.
++ * Internal loopback test - send three bytes, they should come back from the
++ * mouse interface, the last should be version. Note that we negate mouseport
++ * command responses for the i8042_check_aux() routine.
+  */
+-      if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
+-              printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n");
++      param = 0xf0;
++      if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0x0f)
+               return -1;
+-      }
+-
+-      i8042_initial_ctr = i8042_ctr;
+-
+-/*
+- * Disable the keyboard interface and interrupt. 
+- */
+-
+-      i8042_ctr |= I8042_CTR_KBDDIS;
+-      i8042_ctr &= ~I8042_CTR_KBDINT;
+-
+-/*
+- * Handle keylock.
+- */
+-
+-      if (~i8042_read_status() & I8042_STR_KEYLOCK) {
+-              if (i8042_unlock)
+-                      i8042_ctr |= I8042_CTR_IGNKEYLOCK;
+-               else
+-                      printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
+-      }
+-
+-/*
+- * If the chip is configured into nontranslated mode by the BIOS, don't
+- * bother enabling translating and be happy.
+- */
+-
+-      if (~i8042_ctr & I8042_CTR_XLATE)
+-              i8042_direct = 1;
+-
+-/*
+- * Set nontranslated mode for the kbd interface if requested by an option.
+- * After this the kbd interface becomes a simple serial in/out, like the aux
+- * interface is. We don't do this by default, since it can confuse notebook
+- * BIOSes.
+- */
+-
+-      if (i8042_direct) {
+-              i8042_ctr &= ~I8042_CTR_XLATE;
+-              i8042_kbd_port.type = SERIO_8042;
+-      }
+-
+-/*
+- * Write CTR back.
+- */
+-
+-      if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+-              printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n");
++      param = 0x56;
++      if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa9)
+               return -1;
+-      }
++      param = 0xa4;
++      if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b)
++              return -1;
++
++      if (mux_version)
++              *mux_version = ~param;
+       return 0;
+ }
++
+ /*
+- * Here we try to reset everything back to a state in which the BIOS will be
+- * able to talk to the hardware when rebooting.
++ * i8042_enable_mux_ports enables 4 individual AUX ports after
++ * the controller has been switched into Multiplexed mode
+  */
+-void i8042_controller_cleanup(void)
++static int i8042_enable_mux_ports(struct i8042_values *values)
+ {
++      unsigned char param;
+       int i;
+-
+-      i8042_flush();
+-
+ /*
+- * Reset anything that is connected to the ports.
+- */
+-
+-      if (i8042_kbd_values.exists)
+-              serio_cleanup(&i8042_kbd_port);
+-
+-      if (i8042_aux_values.exists)
+-              serio_cleanup(&i8042_aux_port);
+-
+-      for (i = 0; i < 4; i++)
+-              if (i8042_mux_values[i].exists)
+-                      serio_cleanup(i8042_mux_port + i);
+-
+-/*
+- * Reset the controller.
++ * Disable all muxed ports by disabling AUX.
+  */
+-      if (i8042_reset) {
+-              unsigned char param;
++      i8042_ctr |= I8042_CTR_AUXDIS;
++      i8042_ctr &= ~I8042_CTR_AUXINT;
+-              if (i8042_command(&param, I8042_CMD_CTL_TEST))
+-                      printk(KERN_ERR "i8042.c: i8042 controller reset timeout.\n");
++      if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
++              printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n");
++              return -1;
+       }
+ /*
+- * Restore the original control register setting.
++ * Enable all muxed ports.
+  */
+-      i8042_ctr = i8042_initial_ctr;
+-
+-      if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
+-              printk(KERN_WARNING "i8042.c: Can't restore CTR.\n");
++      for (i = 0; i < 4; i++) {
++              i8042_command(&param, I8042_CMD_MUX_PFX + i);
++              i8042_command(&param, I8042_CMD_AUX_ENABLE);
++      }
++      return 0;
+ }
++
+ /*
+  * i8042_check_mux() checks whether the controller supports the PS/2 Active
+  * Multiplexing specification by Synaptics, Phoenix, Insyde and
+@@ -540,66 +513,31 @@ void i8042_controller_cleanup(void)
+ static int __init i8042_check_mux(struct i8042_values *values)
+ {
+-      unsigned char param;
+       static int i8042_check_mux_cookie;
+-      int i;
++      unsigned char mux_version;
+ /*
+  * Check if AUX irq is available.
+  */
+-
+       if (request_irq(values->irq, i8042_interrupt, SA_SHIRQ,
+                               "i8042", &i8042_check_mux_cookie))
+                 return -1;
+       free_irq(values->irq, &i8042_check_mux_cookie);
+-/*
+- * Get rid of bytes in the queue.
+- */
+-
+-      i8042_flush();
+-
+-/*
+- * Internal loopback test - send three bytes, they should come back from the
+- * mouse interface, the last should be version. Note that we negate mouseport
+- * command responses for the i8042_check_aux() routine.
+- */
+-
+-      param = 0xf0;
+-      if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0x0f)
+-              return -1;
+-      param = 0x56;
+-      if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa9)
+-              return -1;
+-      param = 0xa4;
+-      if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b)
++      if (i8042_enable_mux_mode(values, &mux_version))
+               return -1;
+       printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
+-              (~param >> 4) & 0xf, ~param & 0xf);
+-
+-/*
+- * Disable all muxed ports by disabling AUX.
+- */
+-
+-      i8042_ctr |= I8042_CTR_AUXDIS;
+-      i8042_ctr &= ~I8042_CTR_AUXINT;
++              (mux_version >> 4) & 0xf, mux_version & 0xf);
+-      if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
++      if (i8042_enable_mux_ports(values))
+               return -1;
+-/*
+- * Enable all muxed ports.
+- */
+-
+-      for (i = 0; i < 4; i++) {
+-              i8042_command(&param, I8042_CMD_MUX_PFX + i);
+-              i8042_command(&param, I8042_CMD_AUX_ENABLE);
+-      }
+-
++      i8042_mux_present = 1;
+       return 0;
+ }
++
+ /*
+  * i8042_check_aux() applies as much paranoia as it can at detecting
+  * the presence of an AUX interface.
+@@ -675,6 +613,7 @@ static int __init i8042_check_aux(struct
+       return 0;
+ }
++
+ /*
+  * i8042_port_register() marks the device as existing,
+  * registers it, and reports to the user.
+@@ -691,63 +630,205 @@ static int __init i8042_port_register(st
+               return -1; 
+       }
+-      serio_register_port(port);
+-
+       printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
+              values->name,
+              (unsigned long) I8042_DATA_REG,
+              (unsigned long) I8042_COMMAND_REG,
+              values->irq);
++      serio_register_port(port);
++
+       return 0;
+ }
++
+ static void i8042_timer_func(unsigned long data)
+ {
+       i8042_interrupt(0, NULL, NULL);
+       mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
+ }
+-#ifndef MODULE
+-static int __init i8042_setup_reset(char *str)
+-{
+-      i8042_reset = 1;
+-      return 1;
+-}
+-static int __init i8042_setup_noaux(char *str)
+-{
+-      i8042_noaux = 1;
+-      i8042_nomux = 1;
+-      return 1;
+-}
+-static int __init i8042_setup_nomux(char *str)
+-{
+-      i8042_nomux = 1;
+-      return 1;
+-}
+-static int __init i8042_setup_unlock(char *str)
++
++/*
++ * i8042_controller init initializes the i8042 controller, and,
++ * most importantly, sets it into non-xlated mode if that's
++ * desired.
++ */
++
++static int i8042_controller_init(void)
+ {
+-      i8042_unlock = 1;
+-      return 1;
++
++      if (i8042_noaux)
++              i8042_nomux = 1;
++/*
++ * Test the i8042. We need to know if it thinks it's working correctly
++ * before doing anything else.
++ */
++
++      i8042_flush();
++
++      if (i8042_reset) {
++
++              unsigned char param;
++
++              if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
++                      printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
++                      return -1;
++              }
++
++              if (param != I8042_RET_CTL_TEST) {
++                      printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
++                               param, I8042_RET_CTL_TEST);
++                      return -1;
++              }
++      }
++
++/*
++ * Save the CTR for restoral on unload / reboot.
++ */
++
++      if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
++              printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n");
++              return -1;
++      }
++
++      i8042_initial_ctr = i8042_ctr;
++
++/*
++ * Disable the keyboard interface and interrupt.
++ */
++
++      i8042_ctr |= I8042_CTR_KBDDIS;
++      i8042_ctr &= ~I8042_CTR_KBDINT;
++
++/*
++ * Handle keylock.
++ */
++
++      if (~i8042_read_status() & I8042_STR_KEYLOCK) {
++              if (i8042_unlock)
++                      i8042_ctr |= I8042_CTR_IGNKEYLOCK;
++               else
++                      printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
++      }
++
++/*
++ * If the chip is configured into nontranslated mode by the BIOS, don't
++ * bother enabling translating and be happy.
++ */
++
++      if (~i8042_ctr & I8042_CTR_XLATE)
++              i8042_direct = 1;
++
++/*
++ * Set nontranslated mode for the kbd interface if requested by an option.
++ * After this the kbd interface becomes a simple serial in/out, like the aux
++ * interface is. We don't do this by default, since it can confuse notebook
++ * BIOSes.
++ */
++
++      if (i8042_direct) {
++              i8042_ctr &= ~I8042_CTR_XLATE;
++              i8042_kbd_port.type = SERIO_8042;
++      }
++
++/*
++ * Write CTR back.
++ */
++
++      if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
++              printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n");
++              return -1;
++      }
++
++      return 0;
+ }
+-static int __init i8042_setup_direct(char *str)
++
++
++/*
++ * Here we try to reset everything back to a state in which the BIOS will be
++ * able to talk to the hardware when rebooting.
++ */
++
++void i8042_controller_cleanup(void)
+ {
+-      i8042_direct = 1;
+-      return 1;
++      int i;
++
++      i8042_flush();
++
++/*
++ * Reset anything that is connected to the ports.
++ */
++
++      if (i8042_kbd_values.exists)
++              serio_cleanup(&i8042_kbd_port);
++
++      if (i8042_aux_values.exists)
++              serio_cleanup(&i8042_aux_port);
++
++      for (i = 0; i < 4; i++)
++              if (i8042_mux_values[i].exists)
++                      serio_cleanup(i8042_mux_port + i);
++
++/*
++ * Reset the controller.
++ */
++
++      if (i8042_reset) {
++              unsigned char param;
++
++              if (i8042_command(&param, I8042_CMD_CTL_TEST))
++                      printk(KERN_ERR "i8042.c: i8042 controller reset timeout.\n");
++      }
++
++/*
++ * Restore the original control register setting.
++ */
++
++      i8042_ctr = i8042_initial_ctr;
++
++      if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
++              printk(KERN_WARNING "i8042.c: Can't restore CTR.\n");
++
+ }
+-static int __init i8042_setup_dumbkbd(char *str)
++
++
++/*
++ * Here we try to reset everything back to a state in which suspended
++ */
++
++static int i8042_controller_resume(void)
+ {
+-      i8042_dumbkbd = 1;
+-      return 1;
++      int i;
++
++      if (i8042_controller_init()) {
++              printk(KERN_ERR "i8042: resume failed\n");
++              return -1;
++      }
++
++      if (i8042_mux_present)
++              if (i8042_enable_mux_mode(&i8042_aux_values, NULL) ||
++                  i8042_enable_mux_ports(&i8042_aux_values)) {
++                      printk(KERN_WARNING "i8042: failed to resume active multiplexor, mouse won't wotk.\n");
++              }
++
++/*
++ * Reconnect anything that was connected to the ports.
++ */
++
++      if (i8042_kbd_values.exists && i8042_activate_port(&i8042_kbd_port) == 0)
++              serio_reconnect(&i8042_kbd_port);
++
++      if (i8042_aux_values.exists && i8042_activate_port(&i8042_aux_port) == 0)
++              serio_reconnect(&i8042_aux_port);
++
++      for (i = 0; i < 4; i++)
++              if (i8042_mux_values[i].exists && i8042_activate_port(i8042_mux_port + i) == 0)
++                      serio_reconnect(i8042_mux_port + i);
++
++      return 0;
+ }
+-__setup("i8042_reset", i8042_setup_reset);
+-__setup("i8042_noaux", i8042_setup_noaux);
+-__setup("i8042_nomux", i8042_setup_nomux);
+-__setup("i8042_unlock", i8042_setup_unlock);
+-__setup("i8042_direct", i8042_setup_direct);
+-__setup("i8042_dumbkbd", i8042_setup_dumbkbd);
+-#endif
+ /*
+  * We need to reset the 8042 back to original mode on system shutdown,
+@@ -769,6 +850,35 @@ static struct notifier_block i8042_notif
+         0
+ };
++/*
++ * Resume handler for the new PM scheme (driver model)
++ */
++static int i8042_resume(struct sys_device *dev)
++{
++      return i8042_controller_resume();
++}
++
++static struct sysdev_class kbc_sysclass = {
++       set_kset_name("i8042"),
++       .resume = i8042_resume,
++};
++
++static struct sys_device device_i8042 = {
++       .id     = 0,
++       .cls    = &kbc_sysclass,
++};
++
++/*
++ * Resume handler for the old PM scheme (APM)
++ */
++static int i8042_pm_callback(struct pm_dev *dev, pm_request_t request, void *dummy)
++{
++      if (request == PM_RESUME)
++              return i8042_controller_resume();
++
++      return 0;
++}
++
+ static void __init i8042_init_mux_values(struct i8042_values *values, struct serio *port, int index)
+ {
+       memcpy(port, &i8042_aux_port, sizeof(struct serio));
+@@ -817,6 +927,15 @@ int __init i8042_init(void)
+       i8042_timer.function = i8042_timer_func;
+       mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
++        if (sysdev_class_register(&kbc_sysclass) == 0) {
++                if (sys_device_register(&device_i8042) == 0)
++                      i8042_sysdev_initialized = 1;
++              else
++                      sysdev_class_unregister(&kbc_sysclass);
++        }
++
++      i8042_pm_dev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, i8042_pm_callback);
++
+       register_reboot_notifier(&i8042_notifier);
+       return 0;
+@@ -828,6 +947,14 @@ void __exit i8042_exit(void)
+       unregister_reboot_notifier(&i8042_notifier);
++      if (i8042_pm_dev)
++              pm_unregister(i8042_pm_dev);
++
++      if (i8042_sysdev_initialized) {
++              sys_device_unregister(&device_i8042);
++              sysdev_class_unregister(&kbc_sysclass);
++      }
++
+       del_timer(&i8042_timer);
+       i8042_controller_cleanup();
+--- linux-2.6.0/drivers/input/serio/serio.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/input/serio/serio.c     2003-12-28 23:21:30.000000000 -0800
+@@ -49,14 +49,17 @@ MODULE_LICENSE("GPL");
+ EXPORT_SYMBOL(serio_interrupt);
+ EXPORT_SYMBOL(serio_register_port);
+-EXPORT_SYMBOL(serio_register_slave_port);
++EXPORT_SYMBOL(serio_register_port_delayed);
++EXPORT_SYMBOL(__serio_register_port);
+ EXPORT_SYMBOL(serio_unregister_port);
+-EXPORT_SYMBOL(serio_unregister_slave_port);
++EXPORT_SYMBOL(serio_unregister_port_delayed);
++EXPORT_SYMBOL(__serio_unregister_port);
+ EXPORT_SYMBOL(serio_register_device);
+ EXPORT_SYMBOL(serio_unregister_device);
+ EXPORT_SYMBOL(serio_open);
+ EXPORT_SYMBOL(serio_close);
+ EXPORT_SYMBOL(serio_rescan);
++EXPORT_SYMBOL(serio_reconnect);
+ struct serio_event {
+       int type;
+@@ -82,11 +85,23 @@ static void serio_find_dev(struct serio 
+       }
+ }
+-#define SERIO_RESCAN  1
++#define SERIO_RESCAN          1
++#define SERIO_RECONNECT               2
++#define SERIO_REGISTER_PORT   3
++#define SERIO_UNREGISTER_PORT 4
+ static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
+ static DECLARE_COMPLETION(serio_exited);
++static void serio_invalidate_pending_events(struct serio *serio)
++{
++      struct serio_event *event;
++
++      list_for_each_entry(event, &serio_event_list, node)
++              if (event->serio == serio)
++                      event->serio = NULL;
++}
++
+ void serio_handle_events(void)
+ {
+       struct list_head *node, *next;
+@@ -95,17 +110,35 @@ void serio_handle_events(void)
+       list_for_each_safe(node, next, &serio_event_list) {
+               event = container_of(node, struct serio_event, node);   
++              down(&serio_sem);
++              if (event->serio == NULL)
++                      goto event_done;
++
+               switch (event->type) {
++                      case SERIO_REGISTER_PORT :
++                              __serio_register_port(event->serio);
++                              break;
++
++                      case SERIO_UNREGISTER_PORT :
++                              __serio_unregister_port(event->serio);
++                              break;
++
++                      case SERIO_RECONNECT :
++                              if (event->serio->dev && event->serio->dev->reconnect)
++                                      if (event->serio->dev->reconnect(event->serio) == 0)
++                                              break;
++                              /* reconnect failed - fall through to rescan */
++
+                       case SERIO_RESCAN :
+-                              down(&serio_sem);
+                               if (event->serio->dev && event->serio->dev->disconnect)
+                                       event->serio->dev->disconnect(event->serio);
+                               serio_find_dev(event->serio);
+-                              up(&serio_sem);
+                               break;
+                       default:
+                               break;
+               }
++event_done:
++              up(&serio_sem);
+               list_del_init(node);
+               kfree(event);
+       }
+@@ -130,18 +163,27 @@ static int serio_thread(void *nothing)
+       complete_and_exit(&serio_exited, 0);
+ }
+-void serio_rescan(struct serio *serio)
++static void serio_queue_event(struct serio *serio, int event_type)
+ {
+       struct serio_event *event;
+-      if (!(event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC)))
+-              return;
++      if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
++              event->type = event_type;
++              event->serio = serio;
++
++              list_add_tail(&event->node, &serio_event_list);
++              wake_up(&serio_wait);
++      }
++}
+-      event->type = SERIO_RESCAN;
+-      event->serio = serio;
++void serio_rescan(struct serio *serio)
++{
++      serio_queue_event(serio, SERIO_RESCAN);
++}
+-      list_add_tail(&event->node, &serio_event_list);
+-      wake_up(&serio_wait);
++void serio_reconnect(struct serio *serio)
++{
++      serio_queue_event(serio, SERIO_RECONNECT);
+ }
+ irqreturn_t serio_interrupt(struct serio *serio,
+@@ -163,17 +205,26 @@ irqreturn_t serio_interrupt(struct serio
+ void serio_register_port(struct serio *serio)
+ {
+       down(&serio_sem);
+-      list_add_tail(&serio->node, &serio_list);
+-      serio_find_dev(serio);
++      __serio_register_port(serio);
+       up(&serio_sem);
+ }
+ /*
+- * Same as serio_register_port but does not try to acquire serio_sem.
+- * Should be used when registering a serio from other input device's
++ * Submits register request to kseriod for subsequent execution.
++ * Can be used when it is not obvious whether the serio_sem is
++ * taken or not and when delayed execution is feasible.
++ */
++void serio_register_port_delayed(struct serio *serio)
++{
++      serio_queue_event(serio, SERIO_REGISTER_PORT);
++}
++
++/*
++ * Should only be called directly if serio_sem has already been taken,
++ * for example when unregistering a serio from other input device's
+  * connect() function.
+  */
+-void serio_register_slave_port(struct serio *serio)
++void __serio_register_port(struct serio *serio)
+ {
+       list_add_tail(&serio->node, &serio_list);
+       serio_find_dev(serio);
+@@ -182,19 +233,28 @@ void serio_register_slave_port(struct se
+ void serio_unregister_port(struct serio *serio)
+ {
+       down(&serio_sem);
+-      list_del_init(&serio->node);
+-      if (serio->dev && serio->dev->disconnect)
+-              serio->dev->disconnect(serio);
++      __serio_unregister_port(serio);
+       up(&serio_sem);
+ }
+ /*
+- * Same as serio_unregister_port but does not try to acquire serio_sem.
+- * Should be used when unregistering a serio from other input device's
++ * Submits unregister request to kseriod for subsequent execution.
++ * Can be used when it is not obvious whether the serio_sem is
++ * taken or not and when delayed execution is feasible.
++ */
++void serio_unregister_port_delayed(struct serio *serio)
++{
++      serio_queue_event(serio, SERIO_UNREGISTER_PORT);
++}
++
++/*
++ * Should only be called directly if serio_sem has already been taken,
++ * for example when unregistering a serio from other input device's
+  * disconnect() function.
+  */
+-void serio_unregister_slave_port(struct serio *serio)
++void __serio_unregister_port(struct serio *serio)
+ {
++      serio_invalidate_pending_events(serio);
+       list_del_init(&serio->node);
+       if (serio->dev && serio->dev->disconnect)
+               serio->dev->disconnect(serio);
+--- linux-2.6.0/drivers/isdn/eicon/eicon_mod.c 2003-06-14 12:17:58.000000000 -0700
++++ 25/drivers/isdn/eicon/eicon_mod.c  2003-12-28 23:22:43.000000000 -0800
+@@ -29,6 +29,7 @@
+ #include <linux/init.h>
+ #ifdef CONFIG_MCA
+ #include <linux/mca.h>
++#include <linux/mca-legacy.h>
+ #endif /* CONFIG_MCA */
+ #include "eicon.h"
+--- linux-2.6.0/drivers/isdn/eicon/Kconfig     2003-06-14 12:18:20.000000000 -0700
++++ 25/drivers/isdn/eicon/Kconfig      2003-12-28 23:22:04.000000000 -0800
+@@ -13,7 +13,7 @@ config ISDN_DRV_EICON
+ choice
+       prompt "Eicon active card support"
+       optional
+-      depends on ISDN_DRV_EICON && ISDN
++      depends on ISDN_DRV_EICON && ISDN && m
+ config ISDN_DRV_EICON_DIVAS
+       tristate "Eicon driver"
+--- linux-2.6.0/drivers/isdn/hardware/avm/avm_cs.c     2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/isdn/hardware/avm/avm_cs.c      2003-12-28 23:22:54.000000000 -0800
+@@ -186,7 +186,7 @@ static dev_link_t *avmcs_attach(void)
+     client_reg.event_handler = &avmcs_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != 0) {
+       cs_error(link->handle, RegisterClient, ret);
+       avmcs_detach(link);
+@@ -232,7 +232,7 @@ static void avmcs_detach(dev_link_t *lin
+     /* Break the link with Card Services */
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     
+     /* Unlink device structure, free pieces */
+     *linkp = link->next;
+@@ -251,19 +251,29 @@ static void avmcs_detach(dev_link_t *lin
+     
+ ======================================================================*/
+-static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple,
++static int get_tuple(client_handle_t handle, tuple_t *tuple,
+                    cisparse_t *parse)
+ {
+-    int i;
+-    i = CardServices(fn, handle, tuple);
++    int i = pcmcia_get_tuple_data(handle, tuple);
+     if (i != CS_SUCCESS) return i;
+-    i = CardServices(GetTupleData, handle, tuple);
++    return pcmcia_parse_tuple(handle, tuple, parse);
++}
++
++static int first_tuple(client_handle_t handle, tuple_t *tuple,
++                   cisparse_t *parse)
++{
++    int i = pcmcia_get_first_tuple(handle, tuple);
+     if (i != CS_SUCCESS) return i;
+-    return CardServices(ParseTuple, handle, tuple, parse);
++    return get_tuple(handle, tuple, parse);
+ }
+-#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+-#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
++static int next_tuple(client_handle_t handle, tuple_t *tuple,
++                   cisparse_t *parse)
++{
++    int i = pcmcia_get_next_tuple(handle, tuple);
++    if (i != CS_SUCCESS) return i;
++    return get_tuple(handle, tuple, parse);
++}
+ static void avmcs_config(dev_link_t *link)
+ {
+@@ -287,14 +297,14 @@ static void avmcs_config(dev_link_t *lin
+     */
+     do {
+       tuple.DesiredTuple = CISTPL_CONFIG;
+-      i = CardServices(GetFirstTuple, handle, &tuple);
++      i = pcmcia_get_first_tuple(handle, &tuple);
+       if (i != CS_SUCCESS) break;
+       tuple.TupleData = buf;
+       tuple.TupleDataMax = 64;
+       tuple.TupleOffset = 0;
+-      i = CardServices(GetTupleData, handle, &tuple);
++      i = pcmcia_get_tuple_data(handle, &tuple);
+       if (i != CS_SUCCESS) break;
+-      i = CardServices(ParseTuple, handle, &tuple, &parse);
++      i = pcmcia_parse_tuple(handle, &tuple, &parse);
+       if (i != CS_SUCCESS) break;
+       link->conf.ConfigBase = parse.config.base;
+     } while (0);
+@@ -337,7 +347,7 @@ static void avmcs_config(dev_link_t *lin
+                 printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
+                       link->io.BasePort1,
+                       link->io.BasePort1+link->io.NumPorts1-1);
+-              i = CardServices(RequestIO, link->handle, &link->io);
++              i = pcmcia_request_io(link->handle, &link->io);
+               if (i == CS_SUCCESS) goto found_port;
+           }
+           i = next_tuple(handle, &tuple, &parse);
+@@ -352,21 +362,21 @@ found_port:
+       /*
+        * allocate an interrupt line
+        */
+-      i = CardServices(RequestIRQ, link->handle, &link->irq);
++      i = pcmcia_request_irq(link->handle, &link->irq);
+       if (i != CS_SUCCESS) {
+           cs_error(link->handle, RequestIRQ, i);
+-          CardServices(ReleaseIO, link->handle, &link->io);
++          pcmcia_release_io(link->handle, &link->io);
+           break;
+       }
+       
+       /*
+          * configure the PCMCIA socket
+         */
+-      i = CardServices(RequestConfiguration, link->handle, &link->conf);
++      i = pcmcia_request_configuration(link->handle, &link->conf);
+       if (i != CS_SUCCESS) {
+           cs_error(link->handle, RequestConfiguration, i);
+-          CardServices(ReleaseIO, link->handle, &link->io);
+-          CardServices(ReleaseIRQ, link->handle, &link->irq);
++          pcmcia_release_io(link->handle, &link->io);
++          pcmcia_release_irq(link->handle, &link->irq);
+           break;
+       }
+@@ -437,9 +447,9 @@ static void avmcs_release(dev_link_t *li
+     link->dev = NULL;
+     
+     /* Don't bother checking to see if these succeed or not */
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     link->state &= ~DEV_CONFIG;
+     
+     if (link->state & DEV_STALE_LINK)
+@@ -481,14 +491,14 @@ static int avmcs_event(event_t event, in
+       /* Fall through... */
+     case CS_EVENT_RESET_PHYSICAL:
+       if (link->state & DEV_CONFIG)
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       break;
+     case CS_EVENT_PM_RESUME:
+       link->state &= ~DEV_SUSPEND;
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG)
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+       break;
+     }
+     return 0;
+--- linux-2.6.0/drivers/isdn/hisax/avma1_cs.c  2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/isdn/hisax/avma1_cs.c   2003-12-28 23:22:54.000000000 -0800
+@@ -204,7 +204,7 @@ static dev_link_t *avma1cs_attach(void)
+     client_reg.event_handler = &avma1cs_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != 0) {
+       cs_error(link->handle, RegisterClient, ret);
+       avma1cs_detach(link);
+@@ -252,7 +252,7 @@ static void avma1cs_detach(dev_link_t *l
+     /* Break the link with Card Services */
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     
+     /* Unlink device structure, free pieces */
+     *linkp = link->next;
+@@ -271,19 +271,29 @@ static void avma1cs_detach(dev_link_t *l
+     
+ ======================================================================*/
+-static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple,
++static int get_tuple(client_handle_t handle, tuple_t *tuple,
+                    cisparse_t *parse)
+ {
+-    int i;
+-    i = CardServices(fn, handle, tuple);
++    int i = pcmcia_get_tuple_data(handle, tuple);
+     if (i != CS_SUCCESS) return i;
+-    i = CardServices(GetTupleData, handle, tuple);
++    return pcmcia_parse_tuple(handle, tuple, parse);
++}
++
++static int first_tuple(client_handle_t handle, tuple_t *tuple,
++                   cisparse_t *parse)
++{
++    int i = pcmcia_get_first_tuple(handle, tuple);
+     if (i != CS_SUCCESS) return i;
+-    return CardServices(ParseTuple, handle, tuple, parse);
++    return get_tuple(handle, tuple, parse);
+ }
+-#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+-#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
++static int next_tuple(client_handle_t handle, tuple_t *tuple,
++                   cisparse_t *parse)
++{
++    int i = pcmcia_get_next_tuple(handle, tuple);
++    if (i != CS_SUCCESS) return i;
++    return get_tuple(handle, tuple, parse);
++}
+ static void avma1cs_config(dev_link_t *link)
+ {
+@@ -308,14 +318,14 @@ static void avma1cs_config(dev_link_t *l
+     */
+     do {
+       tuple.DesiredTuple = CISTPL_CONFIG;
+-      i = CardServices(GetFirstTuple, handle, &tuple);
++      i = pcmcia_get_first_tuple(handle, &tuple);
+       if (i != CS_SUCCESS) break;
+       tuple.TupleData = buf;
+       tuple.TupleDataMax = 64;
+       tuple.TupleOffset = 0;
+-      i = CardServices(GetTupleData, handle, &tuple);
++      i = pcmcia_get_tuple_data(handle, &tuple);
+       if (i != CS_SUCCESS) break;
+-      i = CardServices(ParseTuple, handle, &tuple, &parse);
++      i = pcmcia_parse_tuple(handle, &tuple, &parse);
+       if (i != CS_SUCCESS) break;
+       link->conf.ConfigBase = parse.config.base;
+     } while (0);
+@@ -358,7 +368,7 @@ static void avma1cs_config(dev_link_t *l
+                 printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
+                       link->io.BasePort1,
+                       link->io.BasePort1+link->io.NumPorts1 - 1);
+-              i = CardServices(RequestIO, link->handle, &link->io);
++              i = pcmcia_request_io(link->handle, &link->io);
+               if (i == CS_SUCCESS) goto found_port;
+           }
+           i = next_tuple(handle, &tuple, &parse);
+@@ -373,21 +383,21 @@ found_port:
+       /*
+        * allocate an interrupt line
+        */
+-      i = CardServices(RequestIRQ, link->handle, &link->irq);
++      i = pcmcia_request_irq(link->handle, &link->irq);
+       if (i != CS_SUCCESS) {
+           cs_error(link->handle, RequestIRQ, i);
+-          CardServices(ReleaseIO, link->handle, &link->io);
++          pcmcia_release_io(link->handle, &link->io);
+           break;
+       }
+       
+       /*
+          * configure the PCMCIA socket
+         */
+-      i = CardServices(RequestConfiguration, link->handle, &link->conf);
++      i = pcmcia_request_configuration(link->handle, &link->conf);
+       if (i != CS_SUCCESS) {
+           cs_error(link->handle, RequestConfiguration, i);
+-          CardServices(ReleaseIO, link->handle, &link->io);
+-          CardServices(ReleaseIRQ, link->handle, &link->irq);
++          pcmcia_release_io(link->handle, &link->io);
++          pcmcia_release_irq(link->handle, &link->irq);
+           break;
+       }
+@@ -445,9 +455,9 @@ static void avma1cs_release(dev_link_t *
+     link->dev = NULL;
+     
+     /* Don't bother checking to see if these succeed or not */
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     link->state &= ~DEV_CONFIG;
+     
+     if (link->state & DEV_STALE_LINK)
+@@ -490,14 +500,14 @@ static int avma1cs_event(event_t event, 
+       /* Fall through... */
+     case CS_EVENT_RESET_PHYSICAL:
+       if (link->state & DEV_CONFIG)
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       break;
+     case CS_EVENT_PM_RESUME:
+       link->state &= ~DEV_SUSPEND;
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG)
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+       break;
+     }
+     return 0;
+--- linux-2.6.0/drivers/isdn/hisax/elsa_cs.c   2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/isdn/hisax/elsa_cs.c    2003-12-28 23:22:54.000000000 -0800
+@@ -235,7 +235,7 @@ static dev_link_t *elsa_cs_attach(void)
+     client_reg.event_handler = &elsa_cs_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != CS_SUCCESS) {
+         cs_error(link->handle, RegisterClient, ret);
+         elsa_cs_detach(link);
+@@ -286,7 +286,7 @@ static void elsa_cs_detach(dev_link_t *l
+     /* Break the link with Card Services */
+     if (link->handle) {
+-        ret = CardServices(DeregisterClient, link->handle);
++        ret = pcmcia_deregister_client(link->handle);
+       if (ret != CS_SUCCESS)
+           cs_error(link->handle, DeregisterClient, ret);
+     }
+@@ -304,19 +304,29 @@ static void elsa_cs_detach(dev_link_t *l
+     device available to the system.
+ ======================================================================*/
+-static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple,
++static int get_tuple(client_handle_t handle, tuple_t *tuple,
+                      cisparse_t *parse)
+ {
+-    int i;
+-    i = CardServices(fn, handle, tuple);
++    int i = pcmcia_get_tuple_data(handle, tuple);
+     if (i != CS_SUCCESS) return i;
+-    i = CardServices(GetTupleData, handle, tuple);
++    return pcmcia_parse_tuple(handle, tuple, parse);
++}
++
++static int first_tuple(client_handle_t handle, tuple_t *tuple,
++                     cisparse_t *parse)
++{
++    int i = pcmcia_get_first_tuple(handle, tuple);
+     if (i != CS_SUCCESS) return i;
+-    return CardServices(ParseTuple, handle, tuple, parse);
++    return get_tuple(handle, tuple, parse);
+ }
+-#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+-#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
++static int next_tuple(client_handle_t handle, tuple_t *tuple,
++                     cisparse_t *parse)
++{
++    int i = pcmcia_get_next_tuple(handle, tuple);
++    if (i != CS_SUCCESS) return i;
++    return get_tuple(handle, tuple, parse);
++}
+ static void elsa_cs_config(dev_link_t *link)
+ {
+@@ -362,14 +372,14 @@ static void elsa_cs_config(dev_link_t *l
+             printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
+             link->conf.ConfigIndex = cf->index;
+             link->io.BasePort1 = cf->io.win[0].base;
+-            i = CardServices(RequestIO, link->handle, &link->io);
++            i = pcmcia_request_io(link->handle, &link->io);
+             if (i == CS_SUCCESS) break;
+         } else {
+           printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
+           link->conf.ConfigIndex = cf->index;
+           for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
+             link->io.BasePort1 = j;
+-            i = CardServices(RequestIO, link->handle, &link->io);
++            i = pcmcia_request_io(link->handle, &link->io);
+             if (i == CS_SUCCESS) break;
+           }
+           break;
+@@ -382,14 +392,14 @@ static void elsa_cs_config(dev_link_t *l
+       goto cs_failed;
+     }
+-    i = CardServices(RequestIRQ, link->handle, &link->irq);
++    i = pcmcia_request_irq(link->handle, &link->irq);
+     if (i != CS_SUCCESS) {
+         link->irq.AssignedIRQ = 0;
+       last_fn = RequestIRQ;
+         goto cs_failed;
+     }
+-    i = CardServices(RequestConfiguration, link->handle, &link->conf);
++    i = pcmcia_request_configuration(link->handle, &link->conf);
+     if (i != CS_SUCCESS) {
+       last_fn = RequestConfiguration;
+       goto cs_failed;
+@@ -447,10 +457,10 @@ static void elsa_cs_release(dev_link_t *
+     /* Don't bother checking to see if these succeed or not */
+     if (link->win)
+-        CardServices(ReleaseWindow, link->win);
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++        pcmcia_release_window(link->win);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     link->state &= ~DEV_CONFIG;
+     if (link->state & DEV_STALE_LINK)
+@@ -499,14 +509,14 @@ static int elsa_cs_event(event_t event, 
+         /* Mark the device as stopped, to block IO until later */
+         dev->busy = 1;
+         if (link->state & DEV_CONFIG)
+-            CardServices(ReleaseConfiguration, link->handle);
++            pcmcia_release_configuration(link->handle);
+         break;
+     case CS_EVENT_PM_RESUME:
+         link->state &= ~DEV_SUSPEND;
+         /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+         if (link->state & DEV_CONFIG)
+-            CardServices(RequestConfiguration, link->handle, &link->conf);
++            pcmcia_request_configuration(link->handle, &link->conf);
+         dev->busy = 0;
+         break;
+     }
+--- linux-2.6.0/drivers/isdn/hisax/sedlbauer_cs.c      2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/isdn/hisax/sedlbauer_cs.c       2003-12-28 23:22:54.000000000 -0800
+@@ -247,7 +247,7 @@ static dev_link_t *sedlbauer_attach(void
+     client_reg.event_handler = &sedlbauer_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != CS_SUCCESS) {
+       cs_error(link->handle, RegisterClient, ret);
+       sedlbauer_detach(link);
+@@ -295,7 +295,7 @@ static void sedlbauer_detach(dev_link_t 
+     /* Break the link with Card Services */
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     
+     /* Unlink device structure, and free it */
+     *linkp = link->next;
+@@ -310,12 +310,8 @@ static void sedlbauer_detach(dev_link_t 
+     device available to the system.
+     
+ ======================================================================*/
+-
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void sedlbauer_config(dev_link_t *link)
+ {
+@@ -341,9 +337,9 @@ static void sedlbauer_config(dev_link_t 
+     tuple.TupleData = buf;
+     tuple.TupleDataMax = sizeof(buf);
+     tuple.TupleOffset = 0;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     link->conf.Present = parse.config.rmask[0];
+     
+@@ -351,7 +347,7 @@ static void sedlbauer_config(dev_link_t 
+     link->state |= DEV_CONFIG;
+     /* Look up the current Vcc */
+-    CS_CHECK(GetConfigurationInfo, handle, &conf);
++    CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
+     link->conf.Vcc = conf.Vcc;
+     /*
+@@ -367,12 +363,13 @@ static void sedlbauer_config(dev_link_t 
+       will only use the CIS to fill in implementation-defined details.
+     */
+     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     while (1) {
+       cistpl_cftable_entry_t dflt = { 0 };
+       cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+-      CFG_CHECK(GetTupleData, handle, &tuple);
+-      CFG_CHECK(ParseTuple, handle, &tuple, &parse);
++      if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++              pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
++          goto next_entry;
+       if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
+       if (cfg->index == 0) goto next_entry;
+@@ -425,7 +422,8 @@ static void sedlbauer_config(dev_link_t 
+               link->io.NumPorts2 = io->win[1].len;
+           }
+           /* This reserves IO space but doesn't actually enable it */
+-          CFG_CHECK(RequestIO, link->handle, &link->io);
++          if (pcmcia_request_io(link->handle, &link->io) != 0)
++              goto next_entry;
+       }
+       /*
+@@ -451,10 +449,11 @@ static void sedlbauer_config(dev_link_t 
+                 req.Size = 0x1000;
+ */
+           req.AccessSpeed = 0;
+-          link->win = (window_handle_t)link->handle;
+-          CFG_CHECK(RequestWindow, &link->win, &req);
++          if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
++              goto next_entry;
+           map.Page = 0; map.CardOffset = mem->win[0].card_addr;
+-          CFG_CHECK(MapMemPage, link->win, &map);
++          if (pcmcia_map_mem_page(link->win, &map) != 0)
++              goto next_entry;
+       }
+       /* If we got this far, we're cool! */
+       break;
+@@ -462,9 +461,9 @@ static void sedlbauer_config(dev_link_t 
+     next_entry:
+ /* new in dummy.cs 2001/01/28 MN 
+         if (link->io.NumPorts1)
+-           CardServices(ReleaseIO, link->handle, &link->io);
++           pcmcia_release_io(link->handle, &link->io);
+ */
+-      CS_CHECK(GetNextTuple, handle, &tuple);
++      CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
+     }
+     
+     /*
+@@ -473,14 +472,14 @@ static void sedlbauer_config(dev_link_t 
+        irq structure is initialized.
+     */
+     if (link->conf.Attributes & CONF_ENABLE_IRQ)
+-      CS_CHECK(RequestIRQ, link->handle, &link->irq);
++      CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+       
+     /*
+        This actually configures the PCMCIA socket -- setting up
+        the I/O windows and the interrupt mapping, and putting the
+        card and host interface into "Memory and IO" mode.
+     */
+-    CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+     /*
+       At this point, the dev_node_t structure(s) need to be
+@@ -545,12 +544,12 @@ static void sedlbauer_release(dev_link_t
+     
+     /* Don't bother checking to see if these succeed or not */
+     if (link->win)
+-      CardServices(ReleaseWindow, link->win);
+-    CardServices(ReleaseConfiguration, link->handle);
++      pcmcia_release_window(link->win);
++    pcmcia_release_configuration(link->handle);
+     if (link->io.NumPorts1)
+-      CardServices(ReleaseIO, link->handle, &link->io);
++      pcmcia_release_io(link->handle, &link->io);
+     if (link->irq.AssignedIRQ)
+-      CardServices(ReleaseIRQ, link->handle, &link->irq);
++      pcmcia_release_irq(link->handle, &link->irq);
+     link->state &= ~DEV_CONFIG;
+     
+     if (link->state & DEV_STALE_LINK)
+@@ -597,14 +596,14 @@ static int sedlbauer_event(event_t event
+       /* Mark the device as stopped, to block IO until later */
+       dev->stop = 1;
+       if (link->state & DEV_CONFIG)
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       break;
+     case CS_EVENT_PM_RESUME:
+       link->state &= ~DEV_SUSPEND;
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG)
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+       dev->stop = 0;
+       /*
+         In a normal driver, additional code may go here to restore
+--- linux-2.6.0/drivers/isdn/i4l/isdn_ppp_ccp.c        2003-06-22 12:04:44.000000000 -0700
++++ 25/drivers/isdn/i4l/isdn_ppp_ccp.c 2003-12-28 23:22:27.000000000 -0800
+@@ -557,7 +557,7 @@ ippp_ccp_send_ccp(struct ippp_ccp *ccp, 
+ }
+ static LIST_HEAD(ipc_head);
+-static spinlock_t ipc_head_lock;
++static spinlock_t ipc_head_lock = SPIN_LOCK_UNLOCKED;
+ int
+ ippp_ccp_set_compressor(struct ippp_ccp *ccp, int unit,
+--- linux-2.6.0/drivers/md/dm.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/md/dm.c 2003-12-28 23:22:20.000000000 -0800
+@@ -160,20 +160,16 @@ static void __exit dm_exit(void)
+ /*
+  * Block device functions
+  */
+-static int dm_blk_open(struct inode *inode, struct file *file)
++static int dm_blk_open(struct block_device *bdev, struct file *file)
+ {
+-      struct mapped_device *md;
+-
+-      md = inode->i_bdev->bd_disk->private_data;
++      struct mapped_device *md = bdev->bd_disk->private_data;
+       dm_get(md);
+       return 0;
+ }
+-static int dm_blk_close(struct inode *inode, struct file *file)
++static int dm_blk_close(struct gendisk *disk)
+ {
+-      struct mapped_device *md;
+-
+-      md = inode->i_bdev->bd_disk->private_data;
++      struct mapped_device *md = disk->private_data;
+       dm_put(md);
+       return 0;
+ }
+@@ -666,6 +662,20 @@ static void event_callback(void *context
+       up_write(&md->lock);
+ }
++static void __set_size(struct gendisk *disk, sector_t size)
++{
++      struct block_device *bdev;
++
++      set_capacity(disk, size);
++      bdev = bdget_disk(disk, 0);
++      if (bdev) {
++              down(&bdev->bd_inode->i_sem);
++              i_size_write(bdev->bd_inode, size << SECTOR_SHIFT);
++              up(&bdev->bd_inode->i_sem);
++              bdput(bdev);
++      }
++}
++
+ static int __bind(struct mapped_device *md, struct dm_table *t)
+ {
+       request_queue_t *q = md->queue;
+@@ -673,7 +683,7 @@ static int __bind(struct mapped_device *
+       md->map = t;
+       size = dm_table_get_size(t);
+-      set_capacity(md->disk, size);
++      __set_size(md->disk, size);
+       if (size == 0)
+               return 0;
+@@ -692,7 +702,6 @@ static void __unbind(struct mapped_devic
+       dm_table_event_callback(md->map, NULL, NULL);
+       dm_table_put(md->map);
+       md->map = NULL;
+-      set_capacity(md->disk, 0);
+ }
+ /*
+--- linux-2.6.0/drivers/md/dm.h        2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/md/dm.h 2003-12-28 23:22:20.000000000 -0800
+@@ -95,7 +95,7 @@ int dm_suspended(struct mapped_device *m
+  * Functions for manipulating a table.  Tables are also reference
+  * counted.
+  *---------------------------------------------------------------*/
+-int dm_table_create(struct dm_table **result, int mode);
++int dm_table_create(struct dm_table **result, int mode, unsigned num_targets);
+ void dm_table_get(struct dm_table *t);
+ void dm_table_put(struct dm_table *t);
+--- linux-2.6.0/drivers/md/dm-ioctl-v1.c       2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/md/dm-ioctl-v1.c        2003-12-28 23:22:20.000000000 -0800
+@@ -566,7 +566,7 @@ static int create(struct dm_ioctl *param
+       if (r)
+               return r;
+-      r = dm_table_create(&t, get_mode(param));
++      r = dm_table_create(&t, get_mode(param), param->target_count);
+       if (r)
+               return r;
+@@ -894,7 +894,7 @@ static int reload(struct dm_ioctl *param
+       struct mapped_device *md;
+       struct dm_table *t;
+-      r = dm_table_create(&t, get_mode(param));
++      r = dm_table_create(&t, get_mode(param), param->target_count);
+       if (r)
+               return r;
+--- linux-2.6.0/drivers/md/dm-ioctl-v4.c       2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/md/dm-ioctl-v4.c        2003-12-28 23:22:20.000000000 -0800
+@@ -872,7 +872,7 @@ static int table_load(struct dm_ioctl *p
+       struct hash_cell *hc;
+       struct dm_table *t;
+-      r = dm_table_create(&t, get_mode(param));
++      r = dm_table_create(&t, get_mode(param), param->target_count);
+       if (r)
+               return r;
+--- linux-2.6.0/drivers/md/dm-table.c  2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/md/dm-table.c   2003-12-28 23:22:21.000000000 -0800
+@@ -12,6 +12,7 @@
+ #include <linux/namei.h>
+ #include <linux/ctype.h>
+ #include <linux/slab.h>
++#include <linux/interrupt.h>
+ #include <asm/atomic.h>
+ #define MAX_DEPTH 16
+@@ -202,7 +203,7 @@ static int alloc_targets(struct dm_table
+       return 0;
+ }
+-int dm_table_create(struct dm_table **result, int mode)
++int dm_table_create(struct dm_table **result, int mode, unsigned num_targets)
+ {
+       struct dm_table *t = kmalloc(sizeof(*t), GFP_NOIO);
+@@ -213,8 +214,12 @@ int dm_table_create(struct dm_table **re
+       INIT_LIST_HEAD(&t->devices);
+       atomic_set(&t->holders, 1);
+-      /* allocate a single nodes worth of targets to begin with */
+-      if (alloc_targets(t, KEYS_PER_NODE)) {
++      if (!num_targets)
++              num_targets = KEYS_PER_NODE;
++
++      num_targets = dm_round_up(num_targets, KEYS_PER_NODE);
++
++      if (alloc_targets(t, num_targets)) {
+               kfree(t);
+               t = NULL;
+               return -ENOMEM;
+@@ -626,6 +631,16 @@ static int split_args(int *argc, char **
+       return 0;
+ }
++static void set_default_limits(struct io_restrictions *rs)
++{
++      rs->max_sectors = MAX_SECTORS;
++      rs->max_phys_segments = MAX_PHYS_SEGMENTS;
++      rs->max_hw_segments = MAX_HW_SEGMENTS;
++      rs->hardsect_size = 1 << SECTOR_SHIFT;
++      rs->max_segment_size = MAX_SEGMENT_SIZE;
++      rs->seg_boundary_mask = -1;
++}
++
+ int dm_table_add_target(struct dm_table *t, const char *type,
+                       sector_t start, sector_t len, char *params)
+ {
+@@ -638,6 +653,7 @@ int dm_table_add_target(struct dm_table 
+       tgt = t->targets + t->num_targets;
+       memset(tgt, 0, sizeof(*tgt));
++      set_default_limits(&tgt->limits);
+       tgt->type = dm_get_target_type(type);
+       if (!tgt->type) {
+@@ -731,22 +747,28 @@ int dm_table_complete(struct dm_table *t
+       return r;
+ }
+-static spinlock_t _event_lock = SPIN_LOCK_UNLOCKED;
++static DECLARE_MUTEX(_event_lock);
+ void dm_table_event_callback(struct dm_table *t,
+                            void (*fn)(void *), void *context)
+ {
+-      spin_lock_irq(&_event_lock);
++      down(&_event_lock);
+       t->event_fn = fn;
+       t->event_context = context;
+-      spin_unlock_irq(&_event_lock);
++      up(&_event_lock);
+ }
+ void dm_table_event(struct dm_table *t)
+ {
+-      spin_lock(&_event_lock);
++      /*
++       * You can no longer call dm_table_event() from interrupt
++       * context, use a bottom half instead.
++       */
++      BUG_ON(in_interrupt());
++
++      down(&_event_lock);
+       if (t->event_fn)
+               t->event_fn(t->event_context);
+-      spin_unlock(&_event_lock);
++      up(&_event_lock);
+ }
+ sector_t dm_table_get_size(struct dm_table *t)
+--- linux-2.6.0/drivers/md/Kconfig     2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/md/Kconfig      2003-12-28 23:22:20.000000000 -0800
+@@ -138,6 +138,7 @@ config BLK_DEV_DM
+ config DM_IOCTL_V4
+       bool "ioctl interface version 4"
+       depends on BLK_DEV_DM
++      default y
+       ---help---
+         Recent tools use a new version of the ioctl interface, only
+           select this option if you intend using such tools.
+--- linux-2.6.0/drivers/md/linear.c    2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/md/linear.c     2003-12-28 23:22:19.000000000 -0800
+@@ -113,8 +113,17 @@ static int linear_run (mddev_t *mddev)
+               }
+               disk->rdev = rdev;
++
+               blk_queue_stack_limits(mddev->queue,
+                                      rdev->bdev->bd_disk->queue);
++              /* as we don't honour merge_bvec_fn, we must never risk
++               * violating it, so limit ->max_sector to one PAGE, as
++               * a one page request is never in violation.
++               */
++              if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
++                  mddev->queue->max_sectors > (PAGE_SIZE>>9))
++                      mddev->queue->max_sectors = (PAGE_SIZE>>9);
++
+               disk->size = rdev->size;
+               mddev->array_size += rdev->size;
+--- linux-2.6.0/drivers/md/md.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/md/md.c 2003-12-28 23:21:17.000000000 -0800
+@@ -2360,11 +2360,10 @@ static int set_disk_faulty(mddev_t *mdde
+       return 1;
+ }
+-static int md_ioctl(struct inode *inode, struct file *file,
++static int md_ioctl(struct block_device *bdev, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+ {
+       char b[BDEVNAME_SIZE];
+-      unsigned int minor = iminor(inode);
+       int err = 0;
+       struct hd_geometry *loc = (struct hd_geometry *) arg;
+       mddev_t *mddev = NULL;
+@@ -2372,11 +2371,6 @@ static int md_ioctl(struct inode *inode,
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+-      if (minor >= MAX_MD_DEVS) {
+-              MD_BUG();
+-              return -EINVAL;
+-      }
+-
+       /*
+        * Commands dealing with the RAID driver but not any
+        * particular array:
+@@ -2405,7 +2399,7 @@ static int md_ioctl(struct inode *inode,
+        * Commands creating/starting a new array:
+        */
+-      mddev = inode->i_bdev->bd_inode->u.generic_ip;
++      mddev = bdev->bd_inode->u.generic_ip;
+       if (!mddev) {
+               BUG();
+@@ -2527,7 +2521,7 @@ static int md_ioctl(struct inode *inode,
+                                               (short *) &loc->cylinders);
+                       if (err)
+                               goto abort_unlock;
+-                      err = put_user (get_start_sect(inode->i_bdev),
++                      err = put_user (get_start_sect(bdev),
+                                               (long *) &loc->start);
+                       goto done_unlock;
+       }
+@@ -2605,12 +2599,12 @@ abort:
+       return err;
+ }
+-static int md_open(struct inode *inode, struct file *file)
++static int md_open(struct block_device *bdev, struct file *file)
+ {
+       /*
+        * Succeed if we can find or allocate a mddev structure.
+        */
+-      mddev_t *mddev = mddev_find(iminor(inode));
++      mddev_t *mddev = mddev_find(MINOR(bdev->bd_dev));
+       int err = -ENOMEM;
+       if (!mddev)
+@@ -2621,16 +2615,16 @@ static int md_open(struct inode *inode, 
+       err = 0;
+       mddev_unlock(mddev);
+-      inode->i_bdev->bd_inode->u.generic_ip = mddev_get(mddev);
++      bdev->bd_inode->u.generic_ip = mddev_get(mddev);
+  put:
+       mddev_put(mddev);
+  out:
+       return err;
+ }
+-static int md_release(struct inode *inode, struct file * file)
++static int md_release(struct gendisk *disk)
+ {
+-      mddev_t *mddev = inode->i_bdev->bd_inode->u.generic_ip;
++      mddev_t *mddev = disk->private_data;
+       if (!mddev)
+               BUG();
+--- linux-2.6.0/drivers/md/multipath.c 2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/md/multipath.c  2003-12-28 23:22:19.000000000 -0800
+@@ -273,6 +273,17 @@ static int multipath_add_disk(mddev_t *m
+                       p->rdev = rdev;
+                       blk_queue_stack_limits(mddev->queue,
+                                              rdev->bdev->bd_disk->queue);
++
++              /* as we don't honour merge_bvec_fn, we must never risk
++               * violating it, so limit ->max_sector to one PAGE, as
++               * a one page request is never in violation.
++               * (Note: it is very unlikely that a device with
++               * merge_bvec_fn will be involved in multipath.)
++               */
++                      if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
++                          mddev->queue->max_sectors > (PAGE_SIZE>>9))
++                              mddev->queue->max_sectors = (PAGE_SIZE>>9);
++
+                       conf->working_disks++;
+                       rdev->raid_disk = path;
+                       rdev->in_sync = 1;
+@@ -410,8 +421,16 @@ static int multipath_run (mddev_t *mddev
+               disk = conf->multipaths + disk_idx;
+               disk->rdev = rdev;
++
+               blk_queue_stack_limits(mddev->queue,
+                                      rdev->bdev->bd_disk->queue);
++              /* as we don't honour merge_bvec_fn, we must never risk
++               * violating it, not that we ever expect a device with
++               * a merge_bvec_fn to be involved in multipath */
++              if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
++                  mddev->queue->max_sectors > (PAGE_SIZE>>9))
++                      mddev->queue->max_sectors = (PAGE_SIZE>>9);
++
+               if (!rdev->faulty) 
+                       conf->working_disks++;
+       }
+--- linux-2.6.0/drivers/md/raid0.c     2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/md/raid0.c      2003-12-28 23:22:19.000000000 -0800
+@@ -112,8 +112,18 @@ static int create_strip_zones (mddev_t *
+                       goto abort;
+               }
+               zone->dev[j] = rdev1;
++
+               blk_queue_stack_limits(mddev->queue,
+                                      rdev1->bdev->bd_disk->queue);
++              /* as we don't honour merge_bvec_fn, we must never risk
++               * violating it, so limit ->max_sector to one PAGE, as
++               * a one page request is never in violation.
++               */
++
++              if (rdev1->bdev->bd_disk->queue->merge_bvec_fn &&
++                  mddev->queue->max_sectors > (PAGE_SIZE>>9))
++                      mddev->queue->max_sectors = (PAGE_SIZE>>9);
++
+               if (!smallest || (rdev1->size <smallest->size))
+                       smallest = rdev1;
+               cnt++;
+@@ -301,6 +311,22 @@ static int raid0_run (mddev_t *mddev)
+               conf->hash_spacing++;
+       }
++      /* calculate the max read-ahead size.
++       * For read-ahead of large files to be effective, we need to
++       * readahead at least a whole stripe. i.e. number of devices
++       * multiplied by chunk size.
++       * If an individual device has an ra_pages greater than the
++       * chunk size, then we will not drive that device as hard as it
++       * wants.  We consider this a configuration error: a larger
++       * chunksize should be used in that case.
++       */
++      {
++              int stripe = mddev->raid_disks * mddev->chunk_size / PAGE_CACHE_SIZE;
++              if (mddev->queue->backing_dev_info.ra_pages < stripe)
++                      mddev->queue->backing_dev_info.ra_pages = stripe;
++      }
++
++
+       blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec);
+       return 0;
+--- linux-2.6.0/drivers/md/raid1.c     2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/md/raid1.c      2003-12-28 23:23:02.000000000 -0800
+@@ -56,7 +56,8 @@ static void r1bio_pool_free(void *r1_bio
+       kfree(r1_bio);
+ }
+-#define RESYNC_BLOCK_SIZE (64*1024)
++//#define RESYNC_BLOCK_SIZE (64*1024)
++#define RESYNC_BLOCK_SIZE PAGE_SIZE
+ #define RESYNC_SECTORS (RESYNC_BLOCK_SIZE >> 9)
+ #define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE)
+ #define RESYNC_WINDOW (2048*1024)
+@@ -677,8 +678,17 @@ static int raid1_add_disk(mddev_t *mddev
+       for (mirror=0; mirror < mddev->raid_disks; mirror++)
+               if ( !(p=conf->mirrors+mirror)->rdev) {
+                       p->rdev = rdev;
++
+                       blk_queue_stack_limits(mddev->queue,
+                                              rdev->bdev->bd_disk->queue);
++                      /* as we don't honour merge_bvec_fn, we must never risk
++                       * violating it, so limit ->max_sector to one PAGE, as
++                       * a one page request is never in violation.
++                       */
++                      if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
++                          mddev->queue->max_sectors > (PAGE_SIZE>>9))
++                              mddev->queue->max_sectors = (PAGE_SIZE>>9);
++
+                       p->head_position = 0;
+                       rdev->raid_disk = mirror;
+                       found = 1;
+@@ -1077,8 +1087,17 @@ static int run(mddev_t *mddev)
+               disk = conf->mirrors + disk_idx;
+               disk->rdev = rdev;
++
+               blk_queue_stack_limits(mddev->queue,
+                                      rdev->bdev->bd_disk->queue);
++              /* as we don't honour merge_bvec_fn, we must never risk
++               * violating it, so limit ->max_sector to one PAGE, as
++               * a one page request is never in violation.
++               */
++              if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
++                  mddev->queue->max_sectors > (PAGE_SIZE>>9))
++                      mddev->queue->max_sectors = (PAGE_SIZE>>9);
++
+               disk->head_position = 0;
+               if (!rdev->faulty && rdev->in_sync)
+                       conf->working_disks++;
+--- linux-2.6.0/drivers/md/raid5.c     2003-12-17 21:20:02.000000000 -0800
++++ 25/drivers/md/raid5.c      2003-12-28 23:22:19.000000000 -0800
+@@ -1587,6 +1587,16 @@ memory = conf->max_nr_stripes * (sizeof(
+       print_raid5_conf(conf);
++      /* read-ahead size must cover a whole stripe, which is
++       * (n-1) * chunksize where 'n' is the number of raid devices
++       */
++      {
++              int stripe = (mddev->raid_disks-1) * mddev->chunk_size
++                      / PAGE_CACHE_SIZE;
++              if (mddev->queue->backing_dev_info.ra_pages < stripe)
++                      mddev->queue->backing_dev_info.ra_pages = stripe;
++      }
++
+       /* Ok, everything is just fine now */
+       mddev->array_size =  mddev->size * (mddev->raid_disks - 1);
+       return 0;
+--- linux-2.6.0/drivers/media/common/saa7146_core.c    2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/media/common/saa7146_core.c     2003-12-28 23:22:37.000000000 -0800
+@@ -45,10 +45,65 @@ static void dump_registers(struct saa714
+ #endif
+ /****************************************************************************
++ * gpio and debi helper functions
++ ****************************************************************************/
++
++/* write "data" to the gpio-pin "pin" */
++void saa7146_set_gpio(struct saa7146_dev *dev, u8 pin, u8 data)
++{
++      u32 value = 0;
++
++      /* sanity check */
++      if(pin > 3)
++              return;
++
++      /* read old register contents */
++      value = saa7146_read(dev, GPIO_CTRL );
++      
++      value &= ~(0xff << (8*pin));
++      value |= (data << (8*pin));
++
++      saa7146_write(dev, GPIO_CTRL, value);
++}
++
++/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
++int saa7146_wait_for_debi_done(struct saa7146_dev *dev)
++{
++      int start;
++
++      /* wait for registers to be programmed */
++      start = jiffies;
++      while (1) {
++                if (saa7146_read(dev, MC2) & 2)
++                        break;
++              if (jiffies-start > HZ/20) {
++                      DEB_S(("timed out while waiting for registers getting programmed\n"));
++                      return -ETIMEDOUT;
++              }
++      }
++
++      /* wait for transfer to complete */
++      start = jiffies;
++      while (1) {
++              if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
++                      break;
++              saa7146_read(dev, MC2);
++              if (jiffies-start > HZ/4) {
++                      DEB_S(("timed out while waiting for transfer completion\n"));
++                      return -ETIMEDOUT;
++              }
++      }
++
++      return 0;
++}
++
++/****************************************************************************
+  * general helper functions
+  ****************************************************************************/
+-/* this is videobuf_vmalloc_to_sg() from video-buf.c */
++/* this is videobuf_vmalloc_to_sg() from video-buf.c 
++   make sure virt has been allocated with vmalloc_32(), otherwise the BUG()
++   may be triggered on highmem machines */
+ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
+ {
+       struct scatterlist *sglist;
+@@ -84,7 +139,7 @@ char *saa7146_vmalloc_build_pgtable(stru
+ {
+       struct scatterlist *slist = NULL;
+       int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
+-      char *mem = vmalloc(length);
++      char *mem = vmalloc_32(length);
+       int slen = 0;
+       if (NULL == mem) {
+@@ -103,7 +158,9 @@ char *saa7146_vmalloc_build_pgtable(stru
+       }
+       
+       slen = pci_map_sg(pci,slist,pages,PCI_DMA_FROMDEVICE);
+-      saa7146_pgtable_build_single(pci, pt, slist, slen);
++      if (0 != saa7146_pgtable_build_single(pci, pt, slist, slen)) {
++              return NULL;
++      }
+       /* fixme: here's a memory leak: slist never gets freed by any other
+          function ...*/
+@@ -139,7 +196,7 @@ int saa7146_pgtable_alloc(struct pci_dev
+       return 0;
+ }
+-void saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt,
++int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt,
+       struct scatterlist *list, int sglen  )
+ {
+       u32   *ptr, fill;
+@@ -148,6 +205,11 @@ void saa7146_pgtable_build_single(struct
+       BUG_ON( 0 == sglen);
++      if (list->offset > PAGE_SIZE) {
++              DEB_D(("offset > PAGE_SIZE. this should not happen."));
++              return -EINVAL;
++      }
++      
+       /* if we have a user buffer, the first page may not be
+          aligned to a page boundary. */
+       pt->offset = list->offset;
+@@ -177,6 +239,7 @@ void saa7146_pgtable_build_single(struct
+               printk("ptr1 %d: 0x%08x\n",i,ptr[i]);
+       }
+ */
++      return 0;
+ }
+ /********************************************************************************/
+@@ -322,7 +385,7 @@ static int saa7146_init_one(struct pci_d
+       saa7146_write(dev, MC1, MASK_31);
+ */
+-      /* disable alle irqs */
++      /* disable all irqs */
+       saa7146_write(dev, IER, 0);
+       /* shut down all dma transfers */
+@@ -381,8 +444,8 @@ static int saa7146_init_one(struct pci_d
+       dev->module = THIS_MODULE;
+       init_waitqueue_head(&dev->i2c_wq);
+-      /* set some default values */
+-      saa7146_write(dev, BCS_CTRL, 0x80400040);
++      /* set some sane pci arbitrition values */
++      saa7146_write(dev, PCI_BT_V1, 0x1c00101f); 
+       if( 0 != ext->probe) {
+               if( 0 != ext->probe(dev) ) {
+@@ -508,6 +571,7 @@ EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc)
+ EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
+ EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
+ EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
++EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
+ EXPORT_SYMBOL_GPL(saa7146_setgpio);
+--- linux-2.6.0/drivers/media/common/saa7146_fops.c    2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/common/saa7146_fops.c     2003-12-28 23:22:37.000000000 -0800
+@@ -86,7 +86,7 @@ void saa7146_buffer_next(struct saa7146_
+               return;
+       }
+-      DEB_EE(("dev:%p, dmaq:%p, vbi:%d\n", dev, q, vbi));
++      DEB_INT(("dev:%p, dmaq:%p, vbi:%d\n", dev, q, vbi));
+ #if DEBUG_SPINLOCKS
+       BUG_ON(!spin_is_locked(&dev->slock));
+@@ -98,10 +98,10 @@ void saa7146_buffer_next(struct saa7146_
+               if (!list_empty(&q->queue))
+                       next = list_entry(q->queue.next,struct saa7146_buf, vb.queue);
+               q->curr = buf;
+-              DEB_D(("next buffer: buf:%p, prev:%p, next:%p\n", buf, q->queue.prev,q->queue.next));
++              DEB_INT(("next buffer: buf:%p, prev:%p, next:%p\n", buf, q->queue.prev,q->queue.next));
+               buf->activate(dev,buf,next);
+       } else {
+-              DEB_D(("no next buffer. stopping.\n"));
++              DEB_INT(("no next buffer. stopping.\n"));
+               if( 0 != vbi ) {
+                       /* turn off video-dma3 */
+                       saa7146_write(dev,MC1, MASK_20);
+@@ -229,10 +229,10 @@ static int fops_open(struct inode *inode
+       if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+               DEB_S(("initializing vbi...\n"));
+-              saa7146_vbi_uops.open(dev,fh);
++              saa7146_vbi_uops.open(dev,file);
+       } else {
+               DEB_S(("initializing video...\n"));
+-              saa7146_video_uops.open(dev,fh);
++              saa7146_video_uops.open(dev,file);
+       }
+       result = 0;
+@@ -255,9 +255,9 @@ static int fops_release(struct inode *in
+               return -ERESTARTSYS;
+       if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+-              saa7146_vbi_uops.release(dev,fh,file);
++              saa7146_vbi_uops.release(dev,file);
+       } else {
+-              saa7146_video_uops.release(dev,fh,file);
++              saa7146_video_uops.release(dev,file);
+       }
+       module_put(dev->ext->module);
+@@ -372,7 +372,7 @@ void vv_callback(struct saa7146_dev *dev
+ {
+       u32 isr = status;
+       
+-      DEB_EE(("dev:%p, isr:0x%08x\n",dev,(u32)status));
++      DEB_INT(("dev:%p, isr:0x%08x\n",dev,(u32)status));
+       if (0 != (isr & (MASK_27))) {
+               DEB_INT(("irq: RPS0 (0x%08x).\n",isr));
+@@ -410,6 +410,12 @@ int saa7146_vv_init(struct saa7146_dev* 
+       DEB_EE(("dev:%p\n",dev));
+       
++      /* set default values for video parts of the saa7146 */
++      saa7146_write(dev, BCS_CTRL, 0x80400040);
++
++      /* enable video-port pins */
++      saa7146_write(dev, MC1, (MASK_10 | MASK_26));
++
+       /* save per-device extension data (one extension can
+          handle different devices that might need different
+          configuration data) */
+--- linux-2.6.0/drivers/media/common/saa7146_hlp.c     2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/media/common/saa7146_hlp.c      2003-12-28 23:22:37.000000000 -0800
+@@ -660,24 +660,6 @@ void saa7146_set_hps_source_and_sync(str
+       vv->current_hps_sync = sync;
+ } 
+-/* write "data" to the gpio-pin "pin" */
+-void saa7146_set_gpio(struct saa7146_dev *dev, u8 pin, u8 data)
+-{
+-      u32 value = 0;
+-
+-      /* sanity check */
+-      if(pin > 3)
+-              return;
+-
+-      /* read old register contents */
+-      value = saa7146_read(dev, GPIO_CTRL );
+-      
+-      value &= ~(0xff << (8*pin));
+-      value |= (data << (8*pin));
+-
+-      saa7146_write(dev, GPIO_CTRL, value);
+-}
+-
+ /* reprogram hps, enable(1) / disable(0) video */
+ void saa7146_set_overlay(struct saa7146_dev *dev, struct saa7146_fh *fh, int v)
+ {
+@@ -710,13 +692,15 @@ void saa7146_write_out_dma(struct saa714
+       /* calculate starting address */
+       where  = (which-1)*0x18;
++/*
+       if( 0 != (dev->ext_vv_data->flags & SAA7146_EXT_SWAP_ODD_EVEN)) {
+               saa7146_write(dev, where,       vdma->base_even);
+               saa7146_write(dev, where+0x04,  vdma->base_odd);
+       } else {
++*/
+               saa7146_write(dev, where,       vdma->base_odd);
+               saa7146_write(dev, where+0x04,  vdma->base_even);
+-      }
++//    }
+       saa7146_write(dev, where+0x08,  vdma->prot_addr);
+       saa7146_write(dev, where+0x0c,  vdma->pitch);
+       saa7146_write(dev, where+0x10,  vdma->base_page);
+@@ -971,12 +955,13 @@ static void program_capture_engine(struc
+       unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
+       unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
++/*
+       if( 0 != (dev->ext_vv_data->flags & SAA7146_EXT_SWAP_ODD_EVEN)) {
+               unsigned long tmp = e_wait;
+               e_wait = o_wait;
+               o_wait = tmp;
+       }
+-
++*/
+       /* wait for o_fid_a/b / e_fid_a/b toggle only if rps register 0 is not set*/
+       WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | o_wait);
+       WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | e_wait);
+--- linux-2.6.0/drivers/media/common/saa7146_i2c.c     2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/media/common/saa7146_i2c.c      2003-12-28 23:22:37.000000000 -0800
+@@ -186,7 +186,7 @@ static int saa7146_i2c_writeout(struct s
+ {
+       u32 status = 0, mc2 = 0;
+       int trial = 0;
+-      int timeout;
++      unsigned long timeout;
+       /* write out i2c-command */
+       DEB_I2C(("before: 0x%08x (status: 0x%08x), %d\n",*dword,saa7146_read(dev, I2C_STATUS), dev->i2c_op));
+@@ -218,7 +218,7 @@ static int saa7146_i2c_writeout(struct s
+                       if( 0 != mc2 ) {
+                               break;
+                       }
+-                      if (jiffies > timeout) {
++                      if (time_after(jiffies,timeout)) {
+                               printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for MC2\n");
+                               return -EIO;
+                       }
+@@ -233,7 +233,7 @@ static int saa7146_i2c_writeout(struct s
+                       status = saa7146_i2c_status(dev);
+                       if ((status & 0x3) != 1)
+                               break;
+-                      if (jiffies > timeout) {
++                      if (time_after(jiffies,timeout)) {
+                               /* this is normal when probing the bus
+                                * (no answer from nonexisistant device...)
+                                */
+@@ -301,7 +301,8 @@ int saa7146_i2c_transfer(struct saa7146_
+               goto out;
+       }
+-        if (count > 3) short_delay = 1;
++      if ( count > 3 || 0 != (SAA7146_I2C_SHORT_DELAY & dev->ext->flags) )
++              short_delay = 1;
+   
+       do {
+               /* reset the i2c-device if necessary */
+@@ -403,19 +404,29 @@ int saa7146_i2c_adapter_prepare(struct s
+ {
+       DEB_EE(("bitrate: 0x%08x\n",bitrate));
+       
++      /* enable i2c-port pins */
++      saa7146_write(dev, MC1, (MASK_08 | MASK_24));
++
+       dev->i2c_bitrate = bitrate;
+       saa7146_i2c_reset(dev);
+       if( NULL != i2c_adapter ) {
+               memset(i2c_adapter,0,sizeof(struct i2c_adapter));
+               strcpy(i2c_adapter->name, dev->name);   
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++              i2c_adapter->data = dev;
++#else
+               i2c_set_adapdata(i2c_adapter,dev);
+-              i2c_adapter->class         = I2C_ADAP_CLASS_TV_ANALOG;
++#endif
+               i2c_adapter->algo          = &saa7146_algo;
+               i2c_adapter->algo_data     = NULL;
+               i2c_adapter->id            = I2C_ALGO_SAA7146;
+               i2c_adapter->timeout = SAA7146_I2C_TIMEOUT;
+               i2c_adapter->retries = SAA7146_I2C_RETRIES;
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++#else
++              i2c_adapter->class = I2C_ADAP_CLASS_TV_ANALOG;
++#endif
+       }
+       
+       return 0;
+--- linux-2.6.0/drivers/media/common/saa7146_vbi.c     2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/common/saa7146_vbi.c      2003-12-28 23:22:37.000000000 -0800
+@@ -41,7 +41,11 @@ static int vbi_workaround(struct saa7146
+       /* wait for vbi_a or vbi_b*/
+       if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
+               DEB_D(("...using port b\n"));
++              WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_E_FID_B);
++              WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_O_FID_B);
++/*
+               WRITE_RPS1(CMD_PAUSE | MASK_09);
++*/
+       } else {
+               DEB_D(("...using port a\n"));
+               WRITE_RPS1(CMD_PAUSE | MASK_10);
+@@ -137,10 +141,10 @@ void saa7146_set_vbi_capture(struct saa7
+       unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
+ /*
+-      vdma3.base_even = (u32)dev->ov_fb.base+2048*70;
+-      vdma3.base_odd  = (u32)dev->ov_fb.base;
+-      vdma3.prot_addr = (u32)dev->ov_fb.base+2048*164;
+-      vdma3.pitch     = 2048;
++      vdma3.base_even = 0xc8000000+2560*70;
++      vdma3.base_odd  = 0xc8000000;
++      vdma3.prot_addr = 0xc8000000+2560*164;
++      vdma3.pitch     = 2560;
+       vdma3.base_page = 0;
+       vdma3.num_line_byte = (64<<16)|((vbi_pixel_to_capture)<<0); // set above!
+ */
+@@ -244,7 +248,9 @@ static int buffer_prepare(struct file *f
+               err = videobuf_iolock(dev->pci,&buf->vb,NULL);
+               if (err)
+                       goto oops;
+-              saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen);
++              err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen);
++              if (0 != err)
++                      return err;
+       }
+       buf->vb.state = STATE_PREPARED;
+       buf->activate = buffer_activate;
+@@ -303,7 +309,7 @@ static struct videobuf_queue_ops vbi_qop
+ /* ------------------------------------------------------------------ */
+-static void vbi_stop(struct saa7146_fh *fh)
++static void vbi_stop(struct saa7146_fh *fh, struct file *file)
+ {
+       struct saa7146_dev *dev = fh->dev;
+       struct saa7146_vv *vv = dev->vv_data;
+@@ -321,23 +327,29 @@ static void vbi_stop(struct saa7146_fh *
+       /* shut down dma 3 transfers */
+       saa7146_write(dev, MC1, MASK_20);
++      if (vv->vbi_q.curr) {
++              saa7146_buffer_finish(dev,&vv->vbi_q,STATE_DONE);
++      }
++
++      videobuf_queue_cancel(file,&fh->vbi_q);
++
+       vv->vbi_streaming = NULL;
+       del_timer(&vv->vbi_q.timeout);
+       del_timer(&fh->vbi_read_timeout);
+-      DEB_VBI(("out\n"));
+       spin_unlock_irqrestore(&dev->slock, flags);
+ }
+ static void vbi_read_timeout(unsigned long data)
+ {
+-      struct saa7146_fh *fh = (struct saa7146_fh *)data;
++      struct file *file = (struct file*)data;
++      struct saa7146_fh *fh = file->private_data;
+       struct saa7146_dev *dev = fh->dev;
+       
+       DEB_VBI(("dev:%p, fh:%p\n",dev, fh));
+-      vbi_stop(fh);
++      vbi_stop(fh, file);
+ }
+ static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
+@@ -354,10 +366,21 @@ static void vbi_init(struct saa7146_dev 
+       init_waitqueue_head(&vv->vbi_wq);
+ }
+-static void vbi_open(struct saa7146_dev *dev, struct saa7146_fh *fh)
++static void vbi_open(struct saa7146_dev *dev, struct file *file)
+ {
++      struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
++      
++      u32 arbtr_ctrl  = saa7146_read(dev, PCI_BT_V1);
++      int ret = 0;
++      
+       DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
++      /* adjust arbitrition control for video dma 3 */
++      arbtr_ctrl &= ~0x1f0000;
++      arbtr_ctrl |=  0x1d0000;
++      saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
++      saa7146_write(dev, MC2, (MASK_04|MASK_20));             
++      
+       memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt));
+       fh->vbi_fmt.sampling_rate       = 27000000;
+@@ -380,21 +403,32 @@ static void vbi_open(struct saa7146_dev 
+       init_timer(&fh->vbi_read_timeout);
+       fh->vbi_read_timeout.function = vbi_read_timeout;
+-      fh->vbi_read_timeout.data = (unsigned long)fh;
++      fh->vbi_read_timeout.data = (unsigned long)file;
+-      /* fixme: enable this again, if the dvb-c w/ analog module work properly */
+-/*
+-      vbi_workaround(dev);
+-*/
++      /* initialize the brs */
++      if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
++              saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
++      } else {
++              saa7146_write(dev, BRS_CTRL, 0x00000001);
++
++              if (0 != (ret = vbi_workaround(dev))) {
++                      DEB_VBI(("vbi workaround failed!\n"));
++                      /* return ret;*/
++              }
++      }
++
++      /* upload brs register */
++      saa7146_write(dev, MC2, (MASK_08|MASK_24));             
+ }
+-static void vbi_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *file)
++static void vbi_close(struct saa7146_dev *dev, struct file *file)
+ {
++      struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
+       struct saa7146_vv *vv = dev->vv_data;
+       DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
+       if( fh == vv->vbi_streaming ) {
+-              vbi_stop(fh);
++              vbi_stop(fh, file);
+       }
+ }
+--- linux-2.6.0/drivers/media/common/saa7146_video.c   2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/common/saa7146_video.c    2003-12-28 23:22:37.000000000 -0800
+@@ -116,7 +116,7 @@ static int try_win(struct saa7146_dev *d
+               DEB_D(("no fb fmt set.\n"));
+               return -EINVAL;
+       }
+-      if (win->w.width < 64 || win->w.height <  64) {
++      if (win->w.width < 48 || win->w.height <  32) {
+               DEB_D(("min width/height. (%d,%d)\n",win->w.width,win->w.height));
+               return -EINVAL;
+       }
+@@ -661,7 +661,7 @@ static int saa7146_pgtable_build(struct 
+ */                            
+       } else {
+               struct saa7146_pgtable *pt = &buf->pt[0];
+-              saa7146_pgtable_build_single(pci, pt, list, length);
++              return saa7146_pgtable_build_single(pci, pt, list, length);
+       }
+       return 0;
+@@ -704,7 +704,7 @@ static int video_begin(struct saa7146_fh
+       return 0;
+ }
+-static int video_end(struct saa7146_fh *fh)
++static int video_end(struct saa7146_fh *fh, struct file *file)
+ {
+       struct saa7146_dev *dev = fh->dev;
+       struct saa7146_vv *vv = dev->vv_data;
+@@ -735,82 +735,9 @@ static int video_end(struct saa7146_fh *
+       saa7146_write(dev, MC1, 0x00700000);
+       vv->streaming = NULL;
+-      spin_unlock_irqrestore(&dev->slock, flags);
+-      
+-      return 0;
+-}
+-
+-/* capturing to framebuffer */
+-
+-int overlay_reqbufs(struct saa7146_dev *dev, struct v4l2_requestbuffers *req)
+-{
+-/*    struct saa7146_fh *fh = file->private_data;
+-
+-      if (req->count > VIDEO_MAX_FRAME)
+-              req->count = VIDEO_MAX_FRAME;
+-
+-      *size = fh->video_fmt.sizeimage;
+-
+-*/
+-      return 0;
+-}
+-int overlay_querybuf(struct saa7146_dev *dev, struct v4l2_buffer *buf)
+-{
+-      return 0;
+-}
+-int overlay_qbuf(struct saa7146_dev *dev, struct v4l2_buffer *b)
+-{
+-/*    if (b->index < 0 || b->index >= VIDEO_MAX_FRAME) {
+-              DEB_D(("index %d out of bounds.\n",b->index));
+-              goto -EINVAL;
+-      }
+-      
+-      buf = q->bufs[b->index];
+-      if (NULL == buf) {
+-              printk("videobuf_qbuf: NULL == buf\n");
+-              goto done;
+-      }
+-      if (0 == buf->baddr) {
+-              printk("videobuf_qbuf: 0 == buf->baddr\n");
+-              goto done;
+-      }
+-      if (buf->state == STATE_QUEUED ||
+-          buf->state == STATE_ACTIVE) {
+-              printk("videobuf_qbuf: already queued or activated.\n");
+-              goto done;
+-      }
+-      field = videobuf_next_field(q);
+-      retval = q->ops->buf_prepare(file,buf,field);
+-      if (0 != retval) {
+-              printk("videobuf_qbuf: buf_prepare() failed.\n");
+-              goto done;
+-      }
+-      
+-      list_add_tail(&buf->stream,&q->stream);
+-      if (q->streaming) {
+-              spin_lock_irqsave(q->irqlock,flags);
+-              q->ops->buf_queue(file,buf);
+-              spin_unlock_irqrestore(q->irqlock,flags);
+-      }
+-      retval = 0;
++      spin_unlock_irqrestore(&dev->slock, flags);
+       
+- done:
+-      up(&q->lock);
+-      return retval;
+-*/
+-      return 0;
+-}
+-int overlay_dqbuf(struct saa7146_dev *dev, struct v4l2_buffer *buf)
+-{
+-      return 0;
+-}
+-int overlay_streamon(struct saa7146_dev *dev)
+-{
+-      return 0;
+-}
+-int overlay_streamoff(struct saa7146_dev *dev)
+-{
+       return 0;
+ }
+@@ -818,7 +745,7 @@ int overlay_streamoff(struct saa7146_dev
+ /*
+  * This function is _not_ called directly, but from
+  * video_generic_ioctl (and maybe others).  userspace
+- * copying is done already, arg is a kernel fhinter.
++ * copying is done already, arg is a kernel pointer.
+  */
+ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg)
+@@ -1141,38 +1068,24 @@ int saa7146_video_do_ioctl(struct inode 
+       case VIDIOC_REQBUFS: {
+               struct v4l2_requestbuffers *req = arg;
+               DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type));
+-/*
+-              if( req->type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+-                      return overlay_reqbufs(dev,req);
+-              } 
+-*/
+               return videobuf_reqbufs(file,q,req);
+       }
+       case VIDIOC_QUERYBUF: {
+               struct v4l2_buffer *buf = arg;
+               DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset));
+-/*            if( buf->type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+-                      return overlay_querybuf(dev,buf);
+-              } 
+- */           return videobuf_querybuf(q,buf);
++              return videobuf_querybuf(q,buf);
+       }
+       case VIDIOC_QBUF: {
+               struct v4l2_buffer *buf = arg;
+               int ret = 0;
+-/*            if( buf->type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+-                      return overlay_qbuf(dev,buf);
+-              } 
+- */           ret = videobuf_qbuf(file,q,buf);
++              ret = videobuf_qbuf(file,q,buf);
+               DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index));
+               return ret;
+       }
+       case VIDIOC_DQBUF: {
+               struct v4l2_buffer *buf = arg;
+               int ret = 0;
+-/*            if( buf->type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+-                      return overlay_dqbuf(dev,buf);
+-              } 
+- */           ret = videobuf_dqbuf(file,q,buf);
++              ret = videobuf_dqbuf(file,q,buf);
+               DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index));
+               return ret;
+       }
+@@ -1180,29 +1093,18 @@ int saa7146_video_do_ioctl(struct inode 
+               int *type = arg;
+               DEB_D(("VIDIOC_STREAMON, type:%d\n",*type));
+-              if( 0 != ops->capture_begin ) {
+-                      if( 0 != (err = ops->capture_begin(fh))) {
++              if( 0 != (err = video_begin(fh))) {
+                               return err;
+                       }
+-              }
+-/*            if( *type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+-                      err = overlay_streamon(dev);
+-              } else { */
+               err = videobuf_streamon(file,q);
+-/*            } */
+               return err;
+       }
+       case VIDIOC_STREAMOFF: {
+               int *type = arg;
+               DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type));
+-              if( 0 != ops->capture_end ) {
+-                      ops->capture_end(fh);
+-              }
+-/*            if( *type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+-                      return overlay_streamoff(dev);
+-              } 
+- */           err = videobuf_streamoff(file,q);
++              err = videobuf_streamoff(file,q);
++              video_end(fh, file);
+               return err;
+       }
+       case VIDIOCGMBUF:
+@@ -1267,8 +1169,8 @@ static int buffer_prepare(struct file *f
+       DEB_CAP(("vbuf:%p\n",vb));
+       /* sanity checks */
+-      if (fh->video_fmt.width  < 64 ||
+-          fh->video_fmt.height < 64 ||
++      if (fh->video_fmt.width  < 48 ||
++          fh->video_fmt.height < 32 ||
+           fh->video_fmt.width  > vv->standard->h_max_out ||
+           fh->video_fmt.height > vv->standard->v_max_out) {
+               DEB_D(("w (%d) / h (%d) out of bounds.\n",fh->video_fmt.width,fh->video_fmt.height));
+@@ -1407,8 +1309,9 @@ static void video_init(struct saa7146_de
+ }
+-static void video_open(struct saa7146_dev *dev, struct saa7146_fh *fh)
++static void video_open(struct saa7146_dev *dev, struct file *file)
+ {
++      struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
+       struct saa7146_format *sfmt;
+       fh->video_fmt.width = 384;
+@@ -1429,8 +1332,9 @@ static void video_open(struct saa7146_de
+ }
+-static void video_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *file)
++static void video_close(struct saa7146_dev *dev, struct file *file)
+ {
++      struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
+       struct saa7146_vv *vv = dev->vv_data;
+       unsigned long flags;
+       
+@@ -1443,10 +1347,8 @@ static void video_close(struct saa7146_d
+       }
+       
+       if( fh == vv->streaming ) {
+-              video_end(fh);          
++              video_end(fh, file);            
+       }
+-
+-      videobuf_queue_cancel(file,&fh->video_q);
+ }
+@@ -1489,7 +1391,7 @@ static ssize_t video_read(struct file *f
+               return -EAGAIN;
+       }
+       ret = videobuf_read_one(file,&fh->video_q , data, count, ppos);
+-      video_end(fh);
++      video_end(fh, file);
+       /* restart overlay if it was active before */
+       if( 0 != restart_overlay ) {
+@@ -1505,6 +1407,4 @@ struct saa7146_use_ops saa7146_video_uop
+       .release = video_close,
+       .irq_done = video_irq_done,
+       .read = video_read,
+-      .capture_begin = video_begin,
+-      .capture_end = video_end,
+ };
+--- linux-2.6.0/drivers/media/dvb/b2c2/skystar2.c      2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/media/dvb/b2c2/skystar2.c       2003-12-28 23:22:38.000000000 -0800
+@@ -2,7 +2,19 @@
+  * skystar2.c - driver for the Technisat SkyStar2 PCI DVB card
+  *              based on the FlexCopII by B2C2,Inc.
+  *
+- * Copyright (C) 2003  V.C. , skystar@moldova.cc
++ * Copyright (C) 2003  Vadim Catana, skystar@moldova.cc
++ *
++ * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
++ * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped 
++ *     Vincenzo Di Massa, hawk.it at tiscalinet.it
++ *    
++ * Converted to Linux coding style
++ * Misc reorganization, polishing, restyling
++ *     Roberto Ragusa, r.ragusa at libero.it
++ *       
++ * Added hardware filtering support, 
++ *     Niklas Peinecke, peinecke at gdv.uni-hannover.de
++ *
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public License
+@@ -27,7 +39,6 @@
+ #include "dvb_i2c.h"
+ #include "dvb_frontend.h"
+-#include "dvb_functions.h"
+ #include <linux/dvb/frontend.h>
+ #include <linux/dvb/dmx.h>
+@@ -38,14 +49,20 @@
+ #include "demux.h"
+ #include "dvb_net.h"
++#include "dvb_functions.h"
++
+ static int debug = 0;
+-#define dprintk(x...) do { if (debug) printk(x); } while (0)
++#define dprintk(x...) do { if (debug>=1) printk(x); } while (0)
++#define ddprintk(x...)        do { if (debug>=2) printk(x); } while (0)
++static int enable_hw_filters = 2;
+-#define SizeOfBufDMA1 0x3AC00
+-#define SizeOfBufDMA2 0x758
++#define SIZE_OF_BUF_DMA1      0x3ac00
++#define SIZE_OF_BUF_DMA2      0x758
+-struct dmaq {
++#define MAX_N_HW_FILTERS      (6+32)
++#define N_PID_SLOTS           256
++struct dmaq {
+       u32 bus_addr;
+       u32 head;
+       u32 tail;
+@@ -53,31 +70,19 @@ struct dmaq {
+       u8 *buffer;
+ };
+-struct packet_header {
+-
+-      u32 sync_byte;
+-      u32 transport_error_indicator;
+-      u32 payload_unit_start_indicator;
+-      u32 transport_priority;
+-      u32 pid;
+-      u32 transport_scrambling_control;
+-      u32 adaptation_field_control;
+-      u32 continuity_counter;
+-};
+ struct adapter {
+-
+       struct pci_dev *pdev;
+       u8 card_revision;
+       u32 b2c2_revision;
+-      u32 PidFilterMax;
+-      u32 MacFilterMax;
++      u32 pid_filter_max;
++      u32 mac_filter_max;
+       u32 irq;
+       unsigned long io_mem;
+       unsigned long io_port;
+       u8 mac_addr[8];
+-      u32 dwSramType;
++      u32 dw_sram_type;
+       struct dvb_adapter *dvb_adapter;
+       struct dvb_demux demux;
+@@ -95,44 +100,42 @@ struct adapter {
+       u32 dma_ctrl;
+       u32 dma_status;
+-      u32 capturing;
++      int capturing;
+       spinlock_t lock;
+-      u16 pids[0x27];
++      int useable_hw_filters;
++      u16 hw_pids[MAX_N_HW_FILTERS];
++      u16 pid_list[N_PID_SLOTS];
++      int pid_rc[N_PID_SLOTS];        // ref counters for the pids
++      int pid_count;
++      int whole_bandwidth_count;
+       u32 mac_filter;
+ };
+-#define WriteRegDW(adapter,reg,value) writel(value, adapter->io_mem + reg)
+-#define ReadRegDW(adapter,reg) readl(adapter->io_mem + reg)
++#define write_reg_dw(adapter,reg,value) writel(value, adapter->io_mem + reg)
++#define read_reg_dw(adapter,reg) readl(adapter->io_mem + reg)
+-static void WriteRegOp(struct adapter *adapter, u32 reg, u32 operation, u32 andvalue, u32 orvalue)
++static void write_reg_bitfield(struct adapter *adapter, u32 reg, u32 zeromask, u32 orvalue)
+ {
+       u32 tmp;
+-      tmp = ReadRegDW(adapter, reg);
+-
+-      if (operation == 1)
+-              tmp = tmp | orvalue;
+-      if (operation == 2)
+-              tmp = tmp & andvalue;
+-      if (operation == 3)
+-              tmp = (tmp & andvalue) | orvalue;
+-
+-      WriteRegDW(adapter, reg, tmp);
++      tmp = read_reg_dw(adapter, reg);
++      tmp = (tmp & ~zeromask) | orvalue;
++      write_reg_dw(adapter, reg, tmp);
+ }
+ /* i2c functions */
+-static int i2cMainWriteForFlex2(struct adapter * adapter, u32 command, u8 * buf, u32 retries)
++static int i2c_main_write_for_flex2(struct adapter *adapter, u32 command, u8 *buf, int retries)
+ {
+-      u32 i;
++      int i;
+       u32 value;
+-      WriteRegDW(adapter, 0x100, 0);
+-      WriteRegDW(adapter, 0x100, command);
++      write_reg_dw(adapter, 0x100, 0);
++      write_reg_dw(adapter, 0x100, command);
+       for (i = 0; i < retries; i++) {
+-              value = ReadRegDW(adapter, 0x100);
++              value = read_reg_dw(adapter, 0x100);
+               if ((value & 0x40000000) == 0) {
+                       if ((value & 0x81000000) == 0x80000000) {
+@@ -141,11 +144,9 @@ static int i2cMainWriteForFlex2(struct a
+                               return 1;
+                       }
+-
+               } else {
+-
+-                      WriteRegDW(adapter, 0x100, 0);
+-                      WriteRegDW(adapter, 0x100, command);
++                      write_reg_dw(adapter, 0x100, 0);
++                      write_reg_dw(adapter, 0x100, command);
+               }
+       }
+@@ -153,7 +154,7 @@ static int i2cMainWriteForFlex2(struct a
+ }
+ /* device = 0x10000000 for tuner, 0x20000000 for eeprom */
+-static void i2cMainSetup(u32 device, u32 chip_addr, u8 op, u8 addr, u32 value, u32 len, u32 *command)
++static void i2c_main_setup(u32 device, u32 chip_addr, u8 op, u8 addr, u32 value, u32 len, u32 *command)
+ {
+       *command = device | ((len - 1) << 26) | (value << 16) | (addr << 8) | chip_addr;
+@@ -163,20 +164,20 @@ static void i2cMainSetup(u32 device, u32
+               *command = *command | 0x01000000;
+ }
+-static int FlexI2cRead4(struct adapter * adapter, u32 device, u32 chip_addr, u16 addr, u8 * buf, u8 len)
++static int flex_i2c_read4(struct adapter *adapter, u32 device, u32 chip_addr, u16 addr, u8 *buf, u8 len)
+ {
+       u32 command;
+       u32 value;
+       int result, i;
+-      i2cMainSetup(device, chip_addr, 1, addr, 0, len, &command);
++      i2c_main_setup(device, chip_addr, 1, addr, 0, len, &command);
+-      result = i2cMainWriteForFlex2(adapter, command, buf, 100000);
++      result = i2c_main_write_for_flex2(adapter, command, buf, 100000);
+       if ((result & 0xff) != 0) {
+               if (len > 1) {
+-                      value = ReadRegDW(adapter, 0x104);
++                      value = read_reg_dw(adapter, 0x104);
+                       for (i = 1; i < len; i++) {
+                               buf[i] = value & 0xff;
+@@ -188,7 +189,7 @@ static int FlexI2cRead4(struct adapter *
+       return result;
+ }
+-static int FlexI2cWrite4(struct adapter * adapter, u32 device, u32 chip_addr, u32 addr, u8 * buf, u8 len)
++static int flex_i2c_write4(struct adapter *adapter, u32 device, u32 chip_addr, u32 addr, u8 *buf, u8 len)
+ {
+       u32 command;
+       u32 value;
+@@ -202,12 +203,12 @@ static int FlexI2cWrite4(struct adapter 
+                       value = value | buf[i - 1];
+               }
+-              WriteRegDW(adapter, 0x104, value);
++              write_reg_dw(adapter, 0x104, value);
+       }
+-      i2cMainSetup(device, chip_addr, 0, addr, buf[0], len, &command);
++      i2c_main_setup(device, chip_addr, 0, addr, buf[0], len, &command);
+-      return i2cMainWriteForFlex2(adapter, command, 0, 100000);
++      return i2c_main_write_for_flex2(adapter, command, 0, 100000);
+ }
+ static void fixchipaddr(u32 device, u32 bus, u32 addr, u32 *ret)
+@@ -218,13 +219,13 @@ static void fixchipaddr(u32 device, u32 
+       *ret = bus;
+ }
+-static u32 FLEXI2C_read(struct adapter * adapter, u32 device, u32 bus, u32 addr, u8 * buf, u32 len)
++static u32 flex_i2c_read(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
+ {
+       u32 chipaddr;
+       u32 bytes_to_transfer;
+       u8 *start;
+-//  dprintk("%s:\n", __FUNCTION__);
++      ddprintk("%s:\n", __FUNCTION__);
+       start = buf;
+@@ -236,7 +237,7 @@ static u32 FLEXI2C_read(struct adapter *
+               fixchipaddr(device, bus, addr, &chipaddr);
+-              if (FlexI2cRead4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
++              if (flex_i2c_read4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
+                       return buf - start;
+               buf = buf + bytes_to_transfer;
+@@ -247,13 +248,13 @@ static u32 FLEXI2C_read(struct adapter *
+       return buf - start;
+ }
+-static u32 FLEXI2C_write(struct adapter * adapter, u32 device, u32 bus, u32 addr, u8 * buf, u32 len)
++static u32 flex_i2c_write(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
+ {
+       u32 chipaddr;
+       u32 bytes_to_transfer;
+       u8 *start;
+-//  dprintk("%s:\n", __FUNCTION__);
++      ddprintk("%s:\n", __FUNCTION__);
+       start = buf;
+@@ -265,7 +266,7 @@ static u32 FLEXI2C_write(struct adapter 
+               fixchipaddr(device, bus, addr, &chipaddr);
+-              if (FlexI2cWrite4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
++              if (flex_i2c_write4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
+                       return buf - start;
+               buf = buf + bytes_to_transfer;
+@@ -284,75 +285,81 @@ static int master_xfer(struct dvb_i2c_bu
+       if (down_interruptible(&tmp->i2c_sem))
+               return -ERESTARTSYS;
+-      if (0) {
+-              dprintk("%s:\n", __FUNCTION__);
++      ddprintk("%s: %d messages to transfer\n", __FUNCTION__, num);
+               for (i = 0; i < num; i++) {
+-                      printk("message %d: flags=%x, addr=0x%04x, buf=%p, len=%d \n", i, msgs[i].flags, msgs[i].addr, msgs[i].buf, msgs[i].len);
+-              }
+-      }
++              ddprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
++                       msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
+       
+-      /* allow only the vp310 frontend to access the bus */
+-      if ((msgs[0].addr != 0x0E) && (msgs[0].addr != 0x61)) {
++              /* allow only the mt312 and stv0299 frontends to access the bus */
++              if ((msgs[i].addr != 0x0e) && (msgs[i].addr != 0x68) && (msgs[i].addr != 0x61)) {
+               up(&tmp->i2c_sem);
+               return -EREMOTEIO;
+       }
++      }
+-      if ((num == 1) && (msgs[0].buf != NULL)) {
+-              if (msgs[0].flags == I2C_M_RD) {
+-                      ret = -EINVAL;
++      // read command
++      if ((num == 2) && (msgs[0].flags == 0) && (msgs[1].flags == I2C_M_RD) && (msgs[0].buf != NULL) && (msgs[1].buf != NULL)) {
+-              } else {
++              ret = flex_i2c_read(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
+-                      // single writes do have the reg addr in buf[0] and data in buf[1] to buf[n]
+-                      ret = FLEXI2C_write(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], &msgs[0].buf[1], msgs[0].len - 1);
++              up(&tmp->i2c_sem);
++
++              if (ret != msgs[1].len) {
++                      printk("%s: read error !\n", __FUNCTION__);
++
++                      for (i = 0; i < 2; i++) {
++                              printk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
++                                     msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
++              }
+-                      if (ret != msgs[0].len - 1)
+-                              ret = -EREMOTEIO;
+-                      else
+-                              ret = num;
++                      return -EREMOTEIO;
+               }
+-      } else if ((num == 2) && (msgs[1].buf != NULL)) {
++              return num;
++      }
++      // write command
++      for (i = 0; i < num; i++) {
+-              // i2c reads consist of a reg addr _write_ followed by a data read, so msg[1].flags has to be examined
+-              if (msgs[1].flags == I2C_M_RD) {
+-                      ret = FLEXI2C_read(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
++              if ((msgs[i].flags != 0) || (msgs[i].buf == NULL) || (msgs[i].len < 2))
++                      return -EINVAL;
+-              } else {
++              ret = flex_i2c_write(tmp, 0x10000000, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1);
+-                      ret = FLEXI2C_write(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
++              up(&tmp->i2c_sem);
++
++              if (ret != msgs[0].len - 1) {
++                      printk("%s: write error %i !\n", __FUNCTION__, ret);
++
++                      printk("message %d: flags=0x%x, addr=0x%x, buf[0]=0x%x, len=%d \n", i,
++                             msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
++
++                      return -EREMOTEIO;
+               }
+-              if (ret != msgs[1].len)
+-                      ret = -EREMOTEIO;
+-              else
+-                      ret = num;
++              return num;
+       }
+-      up(&tmp->i2c_sem);
++      printk("%s: unknown command format !\n", __FUNCTION__);
+-      /* master xfer functions always return the number of successfully
+-         transmitted messages, not the number of transmitted bytes.
+-         return -EREMOTEIO in case of failure. */
+-      return ret;
++      return -EINVAL;
+ }
+ /* SRAM (Skystar2 rev2.3 has one "ISSI IS61LV256" chip on board,
+    but it seems that FlexCopII can work with more than one chip) */
+-static void SRAMSetNetDest(struct adapter * adapter, u8 dest)
++static void sram_set_net_dest(struct adapter *adapter, u8 dest)
+ {
+       u32 tmp;
+       udelay(1000);
+-      tmp = (ReadRegDW(adapter, 0x714) & 0xFFFFFFFC) | (dest & 3);
++      tmp = (read_reg_dw(adapter, 0x714) & 0xfffffffc) | (dest & 3);
+       udelay(1000);
+-      WriteRegDW(adapter, 0x714, tmp);
+-      WriteRegDW(adapter, 0x714, tmp);
++      write_reg_dw(adapter, 0x714, tmp);
++      write_reg_dw(adapter, 0x714, tmp);
+       udelay(1000);
+@@ -360,19 +367,19 @@ static void SRAMSetNetDest(struct adapte
+ /*    return tmp; */
+ }
+-static void SRAMSetCaiDest(struct adapter * adapter, u8 dest)
++static void sram_set_cai_dest(struct adapter *adapter, u8 dest)
+ {
+       u32 tmp;
+       udelay(1000);
+-      tmp = (ReadRegDW(adapter, 0x714) & 0xFFFFFFF3) | ((dest & 3) << 2);
++      tmp = (read_reg_dw(adapter, 0x714) & 0xfffffff3) | ((dest & 3) << 2);
+       udelay(1000);
+       udelay(1000);
+-      WriteRegDW(adapter, 0x714, tmp);
+-      WriteRegDW(adapter, 0x714, tmp);
++      write_reg_dw(adapter, 0x714, tmp);
++      write_reg_dw(adapter, 0x714, tmp);
+       udelay(1000);
+@@ -380,19 +387,19 @@ static void SRAMSetCaiDest(struct adapte
+ /*    return tmp; */
+ }
+-static void SRAMSetCaoDest(struct adapter * adapter, u8 dest)
++static void sram_set_cao_dest(struct adapter *adapter, u8 dest)
+ {
+       u32 tmp;
+       udelay(1000);
+-      tmp = (ReadRegDW(adapter, 0x714) & 0xFFFFFFCF) | ((dest & 3) << 4);
++      tmp = (read_reg_dw(adapter, 0x714) & 0xffffffcf) | ((dest & 3) << 4);
+       udelay(1000);
+       udelay(1000);
+-      WriteRegDW(adapter, 0x714, tmp);
+-      WriteRegDW(adapter, 0x714, tmp);
++      write_reg_dw(adapter, 0x714, tmp);
++      write_reg_dw(adapter, 0x714, tmp);
+       udelay(1000);
+@@ -400,19 +407,19 @@ static void SRAMSetCaoDest(struct adapte
+ /*    return tmp; */
+ }
+-static void SRAMSetMediaDest(struct adapter * adapter, u8 dest)
++static void sram_set_media_dest(struct adapter *adapter, u8 dest)
+ {
+       u32 tmp;
+       udelay(1000);
+-      tmp = (ReadRegDW(adapter, 0x714) & 0xFFFFFF3F) | ((dest & 3) << 6);
++      tmp = (read_reg_dw(adapter, 0x714) & 0xffffff3f) | ((dest & 3) << 6);
+       udelay(1000);
+       udelay(1000);
+-      WriteRegDW(adapter, 0x714, tmp);
+-      WriteRegDW(adapter, 0x714, tmp);
++      write_reg_dw(adapter, 0x714, tmp);
++      write_reg_dw(adapter, 0x714, tmp);
+       udelay(1000);
+@@ -429,16 +436,17 @@ static void SRAMSetMediaDest(struct adap
+     bits 28-29 : memory bank selector
+     bit  31    : busy flag
+ */
+-static void FlexSramWrite(struct adapter *adapter, u32 bank, u32 addr, u8 * buf, u32 len)
++static void flex_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
+ {
+-      u32 i, command, retries;
++      int i, retries;
++      u32 command;
+       for (i = 0; i < len; i++) {
+               command = bank | addr | 0x04000000 | (*buf << 0x10);
+               retries = 2;
+-              while (((ReadRegDW(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
++              while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
+                       mdelay(1);
+                       retries--;
+               };
+@@ -446,23 +454,24 @@ static void FlexSramWrite(struct adapter
+               if (retries == 0)
+                       printk("%s: SRAM timeout\n", __FUNCTION__);
+-              WriteRegDW(adapter, 0x700, command);
++              write_reg_dw(adapter, 0x700, command);
+               buf++;
+               addr++;
+       }
+ }
+-static void FlexSramRead(struct adapter *adapter, u32 bank, u32 addr, u8 * buf, u32 len)
++static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
+ {
+-      u32 i, command, value, retries;
++      int i, retries;
++      u32 command, value;
+       for (i = 0; i < len; i++) {
+               command = bank | addr | 0x04008000;
+               retries = 10000;
+-              while (((ReadRegDW(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
++              while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
+                       mdelay(1);
+                       retries--;
+               };
+@@ -470,11 +479,11 @@ static void FlexSramRead(struct adapter 
+               if (retries == 0)
+                       printk("%s: SRAM timeout\n", __FUNCTION__);
+-              WriteRegDW(adapter, 0x700, command);
++              write_reg_dw(adapter, 0x700, command);
+               retries = 10000;
+-              while (((ReadRegDW(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
++              while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
+                       mdelay(1);
+                       retries--;
+               };
+@@ -482,7 +491,7 @@ static void FlexSramRead(struct adapter 
+               if (retries == 0)
+                       printk("%s: SRAM timeout\n", __FUNCTION__);
+-              value = ReadRegDW(adapter, 0x700) >> 0x10;
++              value = read_reg_dw(adapter, 0x700) >> 0x10;
+               *buf = (value & 0xff);
+@@ -491,47 +500,47 @@ static void FlexSramRead(struct adapter 
+       }
+ }
+-static void SRAM_writeChunk(struct adapter *adapter, u32 addr, u8 * buf, u16 len)
++static void sram_writeChunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
+ {
+       u32 bank;
+       bank = 0;
+-      if (adapter->dwSramType == 0x20000) {
+-              bank = (addr & 0x18000) << 0x0D;
++      if (adapter->dw_sram_type == 0x20000) {
++              bank = (addr & 0x18000) << 0x0d;
+       }
+-      if (adapter->dwSramType == 0x00000) {
+-              if ((addr >> 0x0F) == 0)
++      if (adapter->dw_sram_type == 0x00000) {
++              if ((addr >> 0x0f) == 0)
+                       bank = 0x20000000;
+               else
+                       bank = 0x10000000;
+       }
+-      FlexSramWrite(adapter, bank, addr & 0x7FFF, buf, len);
++      flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
+ }
+-static void SRAM_readChunk(struct adapter *adapter, u32 addr, u8 * buf, u16 len)
++static void sram_readChunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
+ {
+       u32 bank;
+       bank = 0;
+-      if (adapter->dwSramType == 0x20000) {
+-              bank = (addr & 0x18000) << 0x0D;
++      if (adapter->dw_sram_type == 0x20000) {
++              bank = (addr & 0x18000) << 0x0d;
+       }
+-      if (adapter->dwSramType == 0x00000) {
+-              if ((addr >> 0x0F) == 0)
++      if (adapter->dw_sram_type == 0x00000) {
++              if ((addr >> 0x0f) == 0)
+                       bank = 0x20000000;
+               else
+                       bank = 0x10000000;
+       }
+-      FlexSramRead(adapter, bank, addr & 0x7FFF, buf, len);
++      flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
+ }
+-static void SRAM_read(struct adapter *adapter, u32 addr, u8 * buf, u32 len)
++static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
+ {
+       u32 length;
+@@ -541,11 +550,11 @@ static void SRAM_read(struct adapter *ad
+               // check if the address range belongs to the same 
+               // 32K memory chip. If not, the data is read from 
+               // one chip at a time.
+-              if ((addr >> 0x0F) != ((addr + len - 1) >> 0x0F)) {
+-                      length = (((addr >> 0x0F) + 1) << 0x0F) - addr;
++              if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
++                      length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
+               }
+-              SRAM_readChunk(adapter, addr, buf, length);
++              sram_readChunk(adapter, addr, buf, length);
+               addr = addr + length;
+               buf = buf + length;
+@@ -553,7 +562,7 @@ static void SRAM_read(struct adapter *ad
+       }
+ }
+-static void SRAM_write(struct adapter *adapter, u32 addr, u8 * buf, u32 len)
++static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
+ {
+       u32 length;
+@@ -563,11 +572,11 @@ static void SRAM_write(struct adapter *a
+               // check if the address range belongs to the same 
+               // 32K memory chip. If not, the data is written to
+               // one chip at a time.
+-              if ((addr >> 0x0F) != ((addr + len - 1) >> 0x0F)) {
+-                      length = (((addr >> 0x0F) + 1) << 0x0F) - addr;
++              if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
++                      length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
+               }
+-              SRAM_writeChunk(adapter, addr, buf, length);
++              sram_writeChunk(adapter, addr, buf, length);
+               addr = addr + length;
+               buf = buf + length;
+@@ -575,92 +584,92 @@ static void SRAM_write(struct adapter *a
+       }
+ }
+-static void SRAM_setSize(struct adapter *adapter, u32 mask)
++static void sram_set_size(struct adapter *adapter, u32 mask)
+ {
+-      WriteRegDW(adapter, 0x71C, (mask | (~0x30000 & ReadRegDW(adapter, 0x71C))));
++      write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
+ }
+-static void SRAM_init(struct adapter *adapter)
++static void sram_init(struct adapter *adapter)
+ {
+       u32 tmp;
+-      tmp = ReadRegDW(adapter, 0x71C);
++      tmp = read_reg_dw(adapter, 0x71c);
+-      WriteRegDW(adapter, 0x71C, 1);
++      write_reg_dw(adapter, 0x71c, 1);
+-      if (ReadRegDW(adapter, 0x71C) != 0) {
+-              WriteRegDW(adapter, 0x71C, tmp);
++      if (read_reg_dw(adapter, 0x71c) != 0) {
++              write_reg_dw(adapter, 0x71c, tmp);
+-              adapter->dwSramType = tmp & 0x30000;
++              adapter->dw_sram_type = tmp & 0x30000;
+-              dprintk("%s: dwSramType = %x\n", __FUNCTION__, adapter->dwSramType);
++              ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
+       } else {
+-              adapter->dwSramType = 0x10000;
++              adapter->dw_sram_type = 0x10000;
+-              dprintk("%s: dwSramType = %x\n", __FUNCTION__, adapter->dwSramType);
++              ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
+       }
+       /* return value is never used? */
+-/*    return adapter->dwSramType; */
++/*    return adapter->dw_sram_type; */
+ }
+-static int SRAM_testLocation(struct adapter *adapter, u32 mask, u32 addr)
++static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
+ {
+       u8 tmp1, tmp2;
+       dprintk("%s: mask = %x, addr = %x\n", __FUNCTION__, mask, addr);
+-      SRAM_setSize(adapter, mask);
+-      SRAM_init(adapter);
++      sram_set_size(adapter, mask);
++      sram_init(adapter);
+-      tmp2 = 0xA5;
+-      tmp1 = 0x4F;
++      tmp2 = 0xa5;
++      tmp1 = 0x4f;
+-      SRAM_write(adapter, addr, &tmp2, 1);
+-      SRAM_write(adapter, addr + 4, &tmp1, 1);
++      sram_write(adapter, addr, &tmp2, 1);
++      sram_write(adapter, addr + 4, &tmp1, 1);
+       tmp2 = 0;
+       mdelay(20);
+-      SRAM_read(adapter, addr, &tmp2, 1);
+-      SRAM_read(adapter, addr, &tmp2, 1);
++      sram_read(adapter, addr, &tmp2, 1);
++      sram_read(adapter, addr, &tmp2, 1);
+-      dprintk("%s: wrote 0xA5, read 0x%2x\n", __FUNCTION__, tmp2);
++      dprintk("%s: wrote 0xa5, read 0x%2x\n", __FUNCTION__, tmp2);
+-      if (tmp2 != 0xA5)
++      if (tmp2 != 0xa5)
+               return 0;
+-      tmp2 = 0x5A;
+-      tmp1 = 0xF4;
++      tmp2 = 0x5a;
++      tmp1 = 0xf4;
+-      SRAM_write(adapter, addr, &tmp2, 1);
+-      SRAM_write(adapter, addr + 4, &tmp1, 1);
++      sram_write(adapter, addr, &tmp2, 1);
++      sram_write(adapter, addr + 4, &tmp1, 1);
+       tmp2 = 0;
+       mdelay(20);
+-      SRAM_read(adapter, addr, &tmp2, 1);
+-      SRAM_read(adapter, addr, &tmp2, 1);
++      sram_read(adapter, addr, &tmp2, 1);
++      sram_read(adapter, addr, &tmp2, 1);
+-      dprintk("%s: wrote 0x5A, read 0x%2x\n", __FUNCTION__, tmp2);
++      dprintk("%s: wrote 0x5a, read 0x%2x\n", __FUNCTION__, tmp2);
+-      if (tmp2 != 0x5A)
++      if (tmp2 != 0x5a)
+               return 0;
+       return 1;
+ }
+-static u32 SRAM_length(struct adapter * adapter)
++static u32 sram_length(struct adapter *adapter)
+ {
+-      if (adapter->dwSramType == 0x10000)
++      if (adapter->dw_sram_type == 0x10000)
+               return 32768;   //  32K
+-      if (adapter->dwSramType == 0x00000)
++      if (adapter->dw_sram_type == 0x00000)
+               return 65536;   //  64K        
+-      if (adapter->dwSramType == 0x20000)
++      if (adapter->dw_sram_type == 0x20000)
+               return 131072;  // 128K
+       return 32768;           // 32K
+@@ -674,103 +683,104 @@ static u32 SRAM_length(struct adapter * 
+    FlexCop works only with one bank at a time. The bank is selected
+    by bits 28-29 of the 0x700 register.
+   
+-   bank 0 covers addresses 0x00000-0x07FFF
+-   bank 1 covers addresses 0x08000-0x0FFFF
+-   bank 2 covers addresses 0x10000-0x17FFF
+-   bank 3 covers addresses 0x18000-0x1FFFF
++   bank 0 covers addresses 0x00000-0x07fff
++   bank 1 covers addresses 0x08000-0x0ffff
++   bank 2 covers addresses 0x10000-0x17fff
++   bank 3 covers addresses 0x18000-0x1ffff
+ */
+-static int SramDetectForFlex2(struct adapter *adapter)
++static int sram_detect_for_flex2(struct adapter *adapter)
+ {
+       u32 tmp, tmp2, tmp3;
+       dprintk("%s:\n", __FUNCTION__);
+-      tmp = ReadRegDW(adapter, 0x208);
+-      WriteRegDW(adapter, 0x208, 0);
++      tmp = read_reg_dw(adapter, 0x208);
++      write_reg_dw(adapter, 0x208, 0);
+-      tmp2 = ReadRegDW(adapter, 0x71C);
++      tmp2 = read_reg_dw(adapter, 0x71c);
+       dprintk("%s: tmp2 = %x\n", __FUNCTION__, tmp2);
+-      WriteRegDW(adapter, 0x71C, 1);
++      write_reg_dw(adapter, 0x71c, 1);
+-      tmp3 = ReadRegDW(adapter, 0x71C);
++      tmp3 = read_reg_dw(adapter, 0x71c);
+       dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3);
+-      WriteRegDW(adapter, 0x71C, tmp2);
++      write_reg_dw(adapter, 0x71c, tmp2);
+       // check for internal SRAM ???
+       tmp3--;
+       if (tmp3 != 0) {
+-              SRAM_setSize(adapter, 0x10000);
+-              SRAM_init(adapter);
+-              WriteRegDW(adapter, 0x208, tmp);
++              sram_set_size(adapter, 0x10000);
++              sram_init(adapter);
++              write_reg_dw(adapter, 0x208, tmp);
+               dprintk("%s: sram size = 32K\n", __FUNCTION__);
+               return 32;
+       }
+-      if (SRAM_testLocation(adapter, 0x20000, 0x18000) != 0) {
+-              SRAM_setSize(adapter, 0x20000);
+-              SRAM_init(adapter);
+-              WriteRegDW(adapter, 0x208, tmp);
++      if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
++              sram_set_size(adapter, 0x20000);
++              sram_init(adapter);
++              write_reg_dw(adapter, 0x208, tmp);
+               dprintk("%s: sram size = 128K\n", __FUNCTION__);
+               return 128;
+       }
+-      if (SRAM_testLocation(adapter, 0x00000, 0x10000) != 0) {
+-              SRAM_setSize(adapter, 0x00000);
+-              SRAM_init(adapter);
+-              WriteRegDW(adapter, 0x208, tmp);
++      if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
++              sram_set_size(adapter, 0x00000);
++              sram_init(adapter);
++              write_reg_dw(adapter, 0x208, tmp);
+               dprintk("%s: sram size = 64K\n", __FUNCTION__);
+               return 64;
+       }
+-      if (SRAM_testLocation(adapter, 0x10000, 0x00000) != 0) {
+-              SRAM_setSize(adapter, 0x10000);
+-              SRAM_init(adapter);
+-              WriteRegDW(adapter, 0x208, tmp);
++      if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
++              sram_set_size(adapter, 0x10000);
++              sram_init(adapter);
++              write_reg_dw(adapter, 0x208, tmp);
+               dprintk("%s: sram size = 32K\n", __FUNCTION__);
+               return 32;
+       }
+-      SRAM_setSize(adapter, 0x10000);
+-      SRAM_init(adapter);
+-      WriteRegDW(adapter, 0x208, tmp);
++      sram_set_size(adapter, 0x10000);
++      sram_init(adapter);
++      write_reg_dw(adapter, 0x208, tmp);
+       dprintk("%s: SRAM detection failed. Set to 32K \n", __FUNCTION__);
+       return 0;
+ }
+-static void SLL_detectSramSize(struct adapter *adapter)
++static void sll_detect_sram_size(struct adapter *adapter)
+ {
+-      SramDetectForFlex2(adapter);
++      sram_detect_for_flex2(adapter);
+ }
++
+ /* EEPROM (Skystar2 has one "24LC08B" chip on board) */
+ /*
+-static int EEPROM_write(struct adapter *adapter, u16 addr, u8 * buf, u16 len)
++static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
+ {
+-      return FLEXI2C_write(adapter, 0x20000000, 0x50, addr, buf, len);
++      return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
+ }
+ */
+-static int EEPROM_read(struct adapter *adapter, u16 addr, u8 * buf, u16 len)
++static int eeprom_read(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
+ {
+-      return FLEXI2C_read(adapter, 0x20000000, 0x50, addr, buf, len);
++      return flex_i2c_read(adapter, 0x20000000, 0x50, addr, buf, len);
+ }
+-u8 calc_LRC(u8 * buf, u32 len)
++u8 calc_lrc(u8 *buf, int len)
+ {
+-      u32 i;
++      int i;
+       u8 sum;
+       sum = 0;
+@@ -781,13 +791,13 @@ u8 calc_LRC(u8 * buf, u32 len)
+       return sum;
+ }
+-static int EEPROM_LRC_read(struct adapter *adapter, u32 addr, u32 len, u8 * buf, u32 retries)
++static int eeprom_lrc_read(struct adapter *adapter, u32 addr, u32 len, u8 *buf, int retries)
+ {
+       int i;
+       for (i = 0; i < retries; i++) {
+-              if (EEPROM_read(adapter, addr, buf, len) == len) {
+-                      if (calc_LRC(buf, len - 1) == buf[len - 1])
++              if (eeprom_read(adapter, addr, buf, len) == len) {
++                      if (calc_lrc(buf, len - 1) == buf[len - 1])
+                               return 1;
+               }
+       }
+@@ -796,13 +806,13 @@ static int EEPROM_LRC_read(struct adapte
+ }
+ /*
+-static int EEPROM_LRC_write(struct adapter *adapter, u32 addr, u32 len, u8 * wbuf, u8 * rbuf, u32 retries)
++static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
+ {
+       int i;
+       for (i = 0; i < retries; i++) {
+-              if (EEPROM_write(adapter, addr, wbuf, len) == len) {
+-                      if (EEPROM_LRC_read(adapter, addr, len, rbuf, retries) == 1)
++              if (eeprom_write(adapter, addr, wbuf, len) == len) {
++                      if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
+                               return 1;
+               }
+       }
+@@ -811,33 +821,11 @@ static int EEPROM_LRC_write(struct adapt
+ }
+ */
+-/* These functions could be called from the initialization routine 
+-   to unlock SkyStar2 cards, locked by "Europe On Line".
+-        
+-   in cards from "Europe On Line" the key is:
+-
+-       u8 key[20] = {
+-          0xB2, 0x01, 0x00, 0x00,
+-          0x00, 0x00, 0x00, 0x00,
+-          0x00, 0x00, 0x00, 0x00,
+-          0x00, 0x00, 0x00, 0x00,
+-       };
+-
+-       LRC = 0xB3;
+-
+-  in unlocked cards the key is:
+-
+-       u8 key[20] = {
+-          0xB2, 0x00, 0x00, 0x00,
+-          0x00, 0x00, 0x00, 0x00,
+-          0x00, 0x00, 0x00, 0x00,
+-          0x00, 0x00, 0x00, 0x00,
+-       };
+-      LRC = 0xB2;
+-*/
++/* These functions could be used to unlock SkyStar2 cards. */
++
+ /*
+-static int EEPROM_writeKey(struct adapter *adapter, u8 * key, u32 len)
++static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
+ {
+       u8 rbuf[20];
+       u8 wbuf[20];
+@@ -850,37 +838,38 @@ static int EEPROM_writeKey(struct adapte
+       wbuf[16] = 0;
+       wbuf[17] = 0;
+       wbuf[18] = 0;
+-      wbuf[19] = calc_LRC(wbuf, 19);
++      wbuf[19] = calc_lrc(wbuf, 19);
+-      return EEPROM_LRC_write(adapter, 0x3E4, 20, wbuf, rbuf, 4);
++      return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
+ }
+-*/
+-static int EEPROM_readKey(struct adapter *adapter, u8 * key, u32 len)
++
++static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
+ {
+       u8 buf[20];
+       if (len != 16)
+               return 0;
+-      if (EEPROM_LRC_read(adapter, 0x3E4, 20, buf, 4) == 0)
++      if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
+               return 0;
+       memcpy(key, buf, len);
+       return 1;
+ }
++*/
+-static int EEPROM_getMacAddr(struct adapter *adapter, char type, u8 * mac)
++static int eeprom_get_mac_addr(struct adapter *adapter, char type, u8 *mac)
+ {
+       u8 tmp[8];
+-      if (EEPROM_LRC_read(adapter, 0x3F8, 8, tmp, 4) != 0) {
++      if (eeprom_lrc_read(adapter, 0x3f8, 8, tmp, 4) != 0) {
+               if (type != 0) {
+                       mac[0] = tmp[0];
+                       mac[1] = tmp[1];
+                       mac[2] = tmp[2];
+-                      mac[3] = 0xFE;
+-                      mac[4] = 0xFF;
++                      mac[3] = 0xfe;
++                      mac[4] = 0xff;
+                       mac[5] = tmp[3];
+                       mac[6] = tmp[4];
+                       mac[7] = tmp[5];
+@@ -912,7 +901,7 @@ static int EEPROM_getMacAddr(struct adap
+ }
+ /*
+-static char EEPROM_setMacAddr(struct adapter *adapter, char type, u8 * mac)
++static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
+ {
+       u8 tmp[8];
+@@ -935,9 +924,9 @@ static char EEPROM_setMacAddr(struct ada
+       }
+       tmp[6] = 0;
+-      tmp[7] = calc_LRC(tmp, 7);
++      tmp[7] = calc_lrc(tmp, 7);
+-      if (EEPROM_write(adapter, 0x3F8, tmp, 8) == 8)
++      if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
+               return 1;
+       return 0;
+@@ -945,529 +934,319 @@ static char EEPROM_setMacAddr(struct ada
+ */
+ /* PID filter */
+-static void FilterEnableStream1Filter(struct adapter *adapter, u32 op)
+-{
+-      dprintk("%s: op=%x\n", __FUNCTION__, op);
+-
+-      if (op == 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00000001, 0);
+-
+-      } else {
+-              WriteRegOp(adapter, 0x208, 1, 0, 0x00000001);
++/* every flexcop has 6 "lower" hw PID filters     */
++/* these are enabled by setting bits 0-5 of 0x208 */
++/* for the 32 additional filters we have to select one */
++/* of them through 0x310 and modify through 0x314 */
++/* op: 0=disable, 1=enable */
++static void filter_enable_hw_filter(struct adapter *adapter, int id, u8 op)
++{
++      dprintk("%s: id=%d op=%d\n", __FUNCTION__, id, op);
++      if (id <= 5) {
++              u32 mask = (0x00000001 << id);
++              write_reg_bitfield(adapter, 0x208, mask, op ? mask : 0);
++      } else {
++              /* select */
++              write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
++              /* modify */
++              write_reg_bitfield(adapter, 0x314, 0x00006000, op ? 0x00004000 : 0);
+       }
+ }
+-static void FilterEnableStream2Filter(struct adapter *adapter, u32 op)
+-{
+-      dprintk("%s: op=%x\n", __FUNCTION__, op);
+-
+-      if (op == 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00000002, 0);
+-
+-      } else {
+-
+-              WriteRegOp(adapter, 0x208, 1, 0, 0x00000002);
++/* this sets the PID that should pass the specified filter */
++static void pid_set_hw_pid(struct adapter *adapter, int id, u16 pid)
++{
++      dprintk("%s: id=%d  pid=%d\n", __FUNCTION__, id, pid);
++      if (id <= 5) {
++              u32 adr = 0x300 + ((id & 6) << 1);
++              int shift = (id & 1) ? 16 : 0;
++              dprintk("%s: id=%d  addr=%x %c  pid=%d\n", __FUNCTION__, id, adr, (id & 1) ? 'h' : 'l', pid);
++              write_reg_bitfield(adapter, adr, (0x7fff) << shift, (pid & 0x1fff) << shift);
++      } else {
++              /* select */
++              write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
++              /* modify */
++              write_reg_bitfield(adapter, 0x314, 0x1fff, pid & 0x1fff);
+       }
+ }
+-static void FilterEnablePcrFilter(struct adapter *adapter, u32 op)
+-{
+-      dprintk("%s: op=%x\n", __FUNCTION__, op);
+-
+-      if (op == 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00000004, 0);
+-
+-      } else {
+-
+-              WriteRegOp(adapter, 0x208, 1, 0, 0x00000004);
+-      }
+-}
+-
+-static void FilterEnablePmtFilter(struct adapter *adapter, u32 op)
+-{
+-      dprintk("%s: op=%x\n", __FUNCTION__, op);
+-
+-      if (op == 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00000008, 0);
+-
+-      } else {
+-
+-              WriteRegOp(adapter, 0x208, 1, 0, 0x00000008);
+-      }
+-}
+-
+-static void FilterEnableEmmFilter(struct adapter *adapter, u32 op)
+-{
+-      dprintk("%s: op=%x\n", __FUNCTION__, op);
+-
+-      if (op == 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00000010, 0);
+-
+-      } else {
+-
+-              WriteRegOp(adapter, 0x208, 1, 0, 0x00000010);
+-      }
+-}
+-
+-static void FilterEnableEcmFilter(struct adapter *adapter, u32 op)
+-{
+-      dprintk("%s: op=%x\n", __FUNCTION__, op);
+-
+-      if (op == 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00000020, 0);
+-
+-      } else {
+-
+-              WriteRegOp(adapter, 0x208, 1, 0, 0x00000020);
+-      }
+-}
+ /*
+-static void FilterEnableNullFilter(struct adapter *adapter, u32 op)
++static void filter_enable_null_filter(struct adapter *adapter, u32 op)
+ {
+       dprintk("%s: op=%x\n", __FUNCTION__, op);
+-      if (op == 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00000040, 0);
+-
+-      } else {
+-
+-              WriteRegOp(adapter, 0x208, 1, 0, 0x00000040);
+-      }
++      write_reg_bitfield(adapter, 0x208, 0x00000040, op?0x00000040:0);
+ }
+ */
+-static void FilterEnableMaskFilter(struct adapter *adapter, u32 op)
++static void filter_enable_mask_filter(struct adapter *adapter, u32 op)
+ {
+       dprintk("%s: op=%x\n", __FUNCTION__, op);
+-      if (op == 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00000080, 0);
+-
+-      } else {
+-
+-              WriteRegOp(adapter, 0x208, 1, 0, 0x00000080);
+-      }
++      write_reg_bitfield(adapter, 0x208, 0x00000080, op ? 0x00000080 : 0);
+ }
+-static void CtrlEnableMAC(struct adapter *adapter, u32 op)
++static void ctrl_enable_mac(struct adapter *adapter, u32 op)
+ {
+-      if (op == 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00004000, 0);
+-
+-      } else {
+-
+-              WriteRegOp(adapter, 0x208, 1, 0, 0x00004000);
+-      }
++      write_reg_bitfield(adapter, 0x208, 0x00004000, op ? 0x00004000 : 0);
+ }
+-static int CASetMacDstAddrFilter(struct adapter *adapter, u8 * mac)
++static int ca_set_mac_dst_addr_filter(struct adapter *adapter, u8 *mac)
+ {
+       u32 tmp1, tmp2;
+       tmp1 = (mac[3] << 0x18) | (mac[2] << 0x10) | (mac[1] << 0x08) | mac[0];
+       tmp2 = (mac[5] << 0x08) | mac[4];
+-      WriteRegDW(adapter, 0x418, tmp1);
+-      WriteRegDW(adapter, 0x41C, tmp2);
++      write_reg_dw(adapter, 0x418, tmp1);
++      write_reg_dw(adapter, 0x41c, tmp2);
+       return 0;
+ }
+ /*
+-static void SetIgnoreMACFilter(struct adapter *adapter, u8 op)
++static void set_ignore_mac_filter(struct adapter *adapter, u8 op)
+ {
+       if (op != 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00004000, 0);
+-
++              write_reg_bitfield(adapter, 0x208, 0x00004000, 0);
+               adapter->mac_filter = 1;
+-
+       } else {
+-
+               if (adapter->mac_filter != 0) {
+                       adapter->mac_filter = 0;
+-
+-                      WriteRegOp(adapter, 0x208, 1, 0, 0x00004000);
++                      write_reg_bitfield(adapter, 0x208, 0x00004000, 0x00004000);
+               }
+       }
+ }
+ */
+ /*
+-static void CheckNullFilterEnable(struct adapter *adapter)
++static void check_null_filter_enable(struct adapter *adapter)
+ {
+-      FilterEnableNullFilter(adapter, 1);
+-      FilterEnableMaskFilter(adapter, 1);
++      filter_enable_null_filter(adapter, 1);
++      filter_enable_mask_filter(adapter, 1);
+ }
+ */
+-static void InitPIDsInfo(struct adapter *adapter)
+-{
+-      int i;
+-
+-      for (i = 0; i < 0x27; i++)
+-              adapter->pids[i] = 0x1FFF;
+-}
+-
+-static int CheckPID(struct adapter *adapter, u16 pid)
+-{
+-      u32 i;
+-
+-      if (pid == 0x1FFF)
+-              return 0;
+-
+-      for (i = 0; i < 0x27; i++) {
+-              if (adapter->pids[i] == pid)
+-                      return 1;
+-      }
+-
+-      return 0;
+-}
+-
+-static void PidSetGroupPID(struct adapter * adapter, u32 pid)
++static void pid_set_group_pid(struct adapter *adapter, u16 pid)
+ {
+       u32 value;
+       dprintk("%s: pid=%x\n", __FUNCTION__, pid);
+-
+-      value = (pid & 0x3FFF) | (ReadRegDW(adapter, 0x30C) & 0xFFFF0000);
+-
+-      WriteRegDW(adapter, 0x30C, value);
+-
+-      /* return value is never used? */
+-/*    return value; */
++      value = (pid & 0x3fff) | (read_reg_dw(adapter, 0x30c) & 0xffff0000);
++      write_reg_dw(adapter, 0x30c, value);
+ }
+-static void PidSetGroupMASK(struct adapter * adapter, u32 pid)
++static void pid_set_group_mask(struct adapter *adapter, u16 pid)
+ {
+       u32 value;
+       dprintk("%s: pid=%x\n", __FUNCTION__, pid);
+-
+-      value = ((pid & 0x3FFF) << 0x10) | (ReadRegDW(adapter, 0x30C) & 0xFFFF);
+-
+-      WriteRegDW(adapter, 0x30C, value);
+-
+-      /* return value is never used? */
+-/*    return value; */
++      value = ((pid & 0x3fff) << 0x10) | (read_reg_dw(adapter, 0x30c) & 0xffff);
++      write_reg_dw(adapter, 0x30c, value);
+ }
+-static void PidSetStream1PID(struct adapter * adapter, u32 pid)
+-{
+-      u32 value;
+-
+-      dprintk("%s: pid=%x\n", __FUNCTION__, pid);
+-
+-      value = (pid & 0x3FFF) | (ReadRegDW(adapter, 0x300) & 0xFFFFC000);
+-
+-      WriteRegDW(adapter, 0x300, value);
+-
+-      /* return value is never used? */
+-/*    return value; */
+-}
+-
+-static void PidSetStream2PID(struct adapter * adapter, u32 pid)
+-{
+-      u32 value;
+-
+-      dprintk("%s: pid=%x\n", __FUNCTION__, pid);
+-
+-      value = ((pid & 0x3FFF) << 0x10) | (ReadRegDW(adapter, 0x300) & 0xFFFF);
+-
+-      WriteRegDW(adapter, 0x300, value);
+-
+-      /* return value is never used? */
+-/*    return value; */
+-}
+-
+-static void PidSetPcrPID(struct adapter * adapter, u32 pid)
++/*
++static int pid_get_group_pid(struct adapter *adapter)
+ {
+-      u32 value;
+-
+-      dprintk("%s: pid=%x\n", __FUNCTION__, pid);
+-
+-      value = (pid & 0x3FFF) | (ReadRegDW(adapter, 0x304) & 0xFFFFC000);
+-
+-      WriteRegDW(adapter, 0x304, value);
+-
+-      /* return value is never used? */
+-/*    return value; */
++      return read_reg_dw(adapter, 0x30c) & 0x00001fff;
+ }
+-static void PidSetPmtPID(struct adapter * adapter, u32 pid)
++static int pid_get_group_mask(struct adapter *adapter)
+ {
+-      u32 value;
+-
+-      dprintk("%s: pid=%x\n", __FUNCTION__, pid);
+-
+-      value = ((pid & 0x3FFF) << 0x10) | (ReadRegDW(adapter, 0x304) & 0x3FFF);
+-
+-      WriteRegDW(adapter, 0x304, value);
+-
+-      /* return value is never used? */
+-/*    return value; */
+-}
+-
+-static void PidSetEmmPID(struct adapter * adapter, u32 pid)
+-{
+-      u32 value;
+-
+-      dprintk("%s: pid=%x\n", __FUNCTION__, pid);
+-
+-      value = (pid & 0xFFFF) | (ReadRegDW(adapter, 0x308) & 0xFFFF0000);
+-
+-      WriteRegDW(adapter, 0x308, value);
+-
+-      /* return value is never used? */
+-/*    return value; */
++      return (read_reg_dw(adapter, 0x30c) >> 0x10)& 0x00001fff;
+ }
++*/
+-static void PidSetEcmPID(struct adapter * adapter, u32 pid)
++/*
++static void reset_hardware_pid_filter(struct adapter *adapter)
+ {
+-      u32 value;
++      pid_set_stream1_pid(adapter, 0x1fff);
+-      dprintk("%s: pid=%x\n", __FUNCTION__, pid);
+-
+-      value = (pid << 0x10) | (ReadRegDW(adapter, 0x308) & 0xFFFF);
++      pid_set_stream2_pid(adapter, 0x1fff);
++      filter_enable_stream2_filter(adapter, 0);
+-      WriteRegDW(adapter, 0x308, value);
++      pid_set_pcr_pid(adapter, 0x1fff);
++      filter_enable_pcr_filter(adapter, 0);
+-      /* return value is never used? */
+-/*    return value; */
+-}
++      pid_set_pmt_pid(adapter, 0x1fff);
++      filter_enable_pmt_filter(adapter, 0);
+-static int PidGetStream1PID(struct adapter * adapter)
+-{
+-      return ReadRegDW(adapter, 0x300) & 0x00001FFF;
+-}
++      pid_set_ecm_pid(adapter, 0x1fff);
++      filter_enable_ecm_filter(adapter, 0);
+-static int PidGetStream2PID(struct adapter * adapter)
+-{
+-      return (ReadRegDW(adapter, 0x300) >> 0x10)& 0x00001FFF;
++      pid_set_emm_pid(adapter, 0x1fff);
++      filter_enable_emm_filter(adapter, 0);
+ }
++*/
+-static int PidGetPcrPID(struct adapter * adapter)
++static void init_pids(struct adapter *adapter)
+ {
+-      return ReadRegDW(adapter, 0x304) & 0x00001FFF;
+-}
++      int i;
+-static int PidGetPmtPID(struct adapter * adapter)
+-{
+-      return (ReadRegDW(adapter, 0x304) >> 0x10)& 0x00001FFF;
++      adapter->pid_count = 0;
++      adapter->whole_bandwidth_count = 0;
++      for (i = 0; i < adapter->useable_hw_filters; i++) {
++              dprintk("%s: setting filter %d to 0x1fff\n", __FUNCTION__, i);
++              adapter->hw_pids[i] = 0x1fff;
++              pid_set_hw_pid(adapter, i, 0x1fff);
+ }
+-static int PidGetEmmPID(struct adapter * adapter)
+-{
+-      return ReadRegDW(adapter, 0x308) & 0x00001FFF;
++      pid_set_group_pid(adapter, 0);
++      pid_set_group_mask(adapter, 0x1fe0);
+ }
+-static int PidGetEcmPID(struct adapter * adapter)
++static void open_whole_bandwidth(struct adapter *adapter)
+ {
+-      return (ReadRegDW(adapter, 0x308) >> 0x10)& 0x00001FFF;
++      dprintk("%s:\n", __FUNCTION__);
++      pid_set_group_pid(adapter, 0);
++      pid_set_group_mask(adapter, 0);
++/*
++      filter_enable_mask_filter(adapter, 1);
++*/
+ }
+-static int PidGetGroupPID(struct adapter * adapter)
++static void close_whole_bandwidth(struct adapter *adapter)
+ {
+-      return ReadRegDW(adapter, 0x30C) & 0x00001FFF;
++      dprintk("%s:\n", __FUNCTION__);
++      pid_set_group_pid(adapter, 0);
++      pid_set_group_mask(adapter, 0x1fe0);
++/*
++      filter_enable_mask_filter(adapter, 1);
++*/
+ }
+-static int PidGetGroupMASK(struct adapter * adapter)
++static void whole_bandwidth_inc(struct adapter *adapter)
+ {
+-      return (ReadRegDW(adapter, 0x30C) >> 0x10)& 0x00001FFF;
++      if (adapter->whole_bandwidth_count++ == 0)
++              open_whole_bandwidth(adapter);
+ }
+-/*
+-static void ResetHardwarePIDFilter(struct adapter *adapter)
++static void whole_bandwidth_dec(struct adapter *adapter)
+ {
+-      PidSetStream1PID(adapter, 0x1FFF);
+-
+-      PidSetStream2PID(adapter, 0x1FFF);
+-      FilterEnableStream2Filter(adapter, 0);
+-
+-      PidSetPcrPID(adapter, 0x1FFF);
+-      FilterEnablePcrFilter(adapter, 0);
+-
+-      PidSetPmtPID(adapter, 0x1FFF);
+-      FilterEnablePmtFilter(adapter, 0);
+-
+-      PidSetEcmPID(adapter, 0x1FFF);
+-      FilterEnableEcmFilter(adapter, 0);
+-
+-      PidSetEmmPID(adapter, 0x1FFF);
+-      FilterEnableEmmFilter(adapter, 0);
++      if (--adapter->whole_bandwidth_count <= 0)
++              close_whole_bandwidth(adapter);
+ }
+-*/
+-static void OpenWholeBandwidth(struct adapter *adapter)
++/* The specified PID has to be let through the
++   hw filters.
++   We try to allocate an hardware filter and open whole
++   bandwidth when allocation is impossible.
++   All pids<=0x1f pass through the group filter.
++   Returns 1 on success, -1 on error */
++static int add_hw_pid(struct adapter *adapter, u16 pid)
+ {
+-      PidSetGroupPID(adapter, 0);
+-
+-      PidSetGroupMASK(adapter, 0);
+-
+-      FilterEnableMaskFilter(adapter, 1);
+-}
++      int i;
+-static int AddHwPID(struct adapter *adapter, u32 pid)
+-{
+       dprintk("%s: pid=%d\n", __FUNCTION__, pid);
+-      if (pid <= 0x1F)
++      if (pid <= 0x1f)
+               return 1;
+-      if ((PidGetGroupMASK(adapter) == 0) && (PidGetGroupPID(adapter) == 0))
+-              return 0;
+-
+-      if (PidGetStream1PID(adapter) == 0x1FFF) {
+-              PidSetStream1PID(adapter, pid & 0xFFFF);
+-
+-              FilterEnableStream1Filter(adapter, 1);
+-
+-              return 1;
+-      }
+-
+-      if (PidGetStream2PID(adapter) == 0x1FFF) {
+-              PidSetStream2PID(adapter, (pid & 0xFFFF));
+-
+-              FilterEnableStream2Filter(adapter, 1);
+-
+-              return 1;
+-      }
+-
+-      if (PidGetPcrPID(adapter) == 0x1FFF) {
+-              PidSetPcrPID(adapter, (pid & 0xFFFF));
+-
+-              FilterEnablePcrFilter(adapter, 1);
+-
++      /* we can't use a filter for 0x2000, so no search */
++      if (pid != 0x2000) {
++              /* find an unused hardware filter */
++              for (i = 0; i < adapter->useable_hw_filters; i++) {
++                      dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
++                      if (adapter->hw_pids[i] == 0x1fff) {
++                              dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
++                              adapter->hw_pids[i] = pid;
++                              pid_set_hw_pid(adapter, i, pid);
++                              filter_enable_hw_filter(adapter, i, 1);
+               return 1;
+       }
+-
+-      if ((PidGetPmtPID(adapter) & 0x1FFF) == 0x1FFF) {
+-              PidSetPmtPID(adapter, (pid & 0xFFFF));
+-
+-              FilterEnablePmtFilter(adapter, 1);
+-
+-              return 1;
+       }
+-
+-      if ((PidGetEmmPID(adapter) & 0x1FFF) == 0x1FFF) {
+-              PidSetEmmPID(adapter, (pid & 0xFFFF));
+-
+-              FilterEnableEmmFilter(adapter, 1);
+-
+-              return 1;
+       }
+-
+-      if ((PidGetEcmPID(adapter) & 0x1FFF) == 0x1FFF) {
+-              PidSetEcmPID(adapter, (pid & 0xFFFF));
+-
+-              FilterEnableEcmFilter(adapter, 1);
+-
++      /* if we have not used a filter, this pid depends on whole bandwidth */
++      dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
++      whole_bandwidth_inc(adapter);
+               return 1;
+       }
+-      return -1;
+-}
+-
+-static int RemoveHwPID(struct adapter *adapter, u32 pid)
++/* returns -1 if the pid was not present in the filters */
++static int remove_hw_pid(struct adapter *adapter, u16 pid)
+ {
++      int i;
++
+       dprintk("%s: pid=%d\n", __FUNCTION__, pid);
+-      if (pid <= 0x1F)
++      if (pid <= 0x1f)
+               return 1;
+-      if (PidGetStream1PID(adapter) == pid) {
+-              PidSetStream1PID(adapter, 0x1FFF);
+-
++      /* we can't use a filter for 0x2000, so no search */
++      if (pid != 0x2000) {
++              for (i = 0; i < adapter->useable_hw_filters; i++) {
++                      dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
++                      if (adapter->hw_pids[i] == pid) {       // find the pid slot
++                              dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
++                              adapter->hw_pids[i] = 0x1fff;
++                              pid_set_hw_pid(adapter, i, 0x1fff);
++                              filter_enable_hw_filter(adapter, i, 0);
+               return 1;
+       }
+-
+-      if (PidGetStream2PID(adapter) == pid) {
+-              PidSetStream2PID(adapter, 0x1FFF);
+-
+-              FilterEnableStream2Filter(adapter, 0);
+-
+-              return 1;
+       }
+-
+-      if (PidGetPcrPID(adapter) == pid) {
+-              PidSetPcrPID(adapter, 0x1FFF);
+-
+-              FilterEnablePcrFilter(adapter, 0);
+-
+-              return 1;
+       }
+-
+-      if (PidGetPmtPID(adapter) == pid) {
+-              PidSetPmtPID(adapter, 0x1FFF);
+-
+-              FilterEnablePmtFilter(adapter, 0);
+-
++      /* if we have not used a filter, this pid depended on whole bandwith */
++      dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
++      whole_bandwidth_dec(adapter);
+               return 1;
+       }
+-      if (PidGetEmmPID(adapter) == pid) {
+-              PidSetEmmPID(adapter, 0x1FFF);
+-
+-              FilterEnableEmmFilter(adapter, 0);
+-
+-              return 1;
+-      }
+-
+-      if (PidGetEcmPID(adapter) == pid) {
+-              PidSetEcmPID(adapter, 0x1FFF);
+-
+-              FilterEnableEcmFilter(adapter, 0);
+-
+-              return 1;
+-      }
+-
+-      return -1;
+-}
+-
+-static int AddPID(struct adapter *adapter, u32 pid)
++/* Adds a PID to the filters.
++   Adding a pid more than once is possible, we keep reference counts.
++   Whole stream available through pid==0x2000.
++   Returns 1 on success, -1 on error */
++static int add_pid(struct adapter *adapter, u16 pid)
+ {
+       int i;
+       dprintk("%s: pid=%d\n", __FUNCTION__, pid);
+-      if (pid > 0x1FFE)
++      if (pid > 0x1ffe && pid != 0x2000)
+               return -1;
+-      if (CheckPID(adapter, pid) == 1)
++      // check if the pid is already present
++      for (i = 0; i < adapter->pid_count; i++)
++              if (adapter->pid_list[i] == pid) {
++                      adapter->pid_rc[i]++;   // increment ref counter
+               return 1;
++              }
+-      for (i = 0; i < 0x27; i++) {
+-              if (adapter->pids[i] == 0x1FFF) // find free pid filter
+-              {
+-                      adapter->pids[i] = pid;
+-
+-                      if (AddHwPID(adapter, pid) < 0)
+-                              OpenWholeBandwidth(adapter);
++      if (adapter->pid_count == N_PID_SLOTS)
++              return -1;      // no more pids can be added
++      adapter->pid_list[adapter->pid_count] = pid;    // register pid
++      adapter->pid_rc[adapter->pid_count] = 1;
++      adapter->pid_count++;
++      // hardware setting
++      add_hw_pid(adapter, pid);
+                       return 1;
+               }
+-      }
+-
+-      return -1;
+-}
+-static int RemovePID(struct adapter *adapter, u32 pid)
++/* Removes a PID from the filters. */
++static int remove_pid(struct adapter *adapter, u16 pid)
+ {
+-      u32 i;
++      int i;
+       dprintk("%s: pid=%d\n", __FUNCTION__, pid);
+-      if (pid > 0x1FFE)
++      if (pid > 0x1ffe && pid != 0x2000)
+               return -1;
+-      for (i = 0; i < 0x27; i++) {
+-              if (adapter->pids[i] == pid) {
+-                      adapter->pids[i] = 0x1FFF;
+-
+-                      RemoveHwPID(adapter, pid);
+-
++      // check if the pid is present (it must be!)
++      for (i = 0; i < adapter->pid_count; i++) {
++              if (adapter->pid_list[i] == pid) {
++                      adapter->pid_rc[i]--;
++                      if (adapter->pid_rc[i] <= 0) {
++                              // remove from the list
++                              adapter->pid_count--;
++                              adapter->pid_list[i]=adapter->pid_list[adapter->pid_count];
++                              adapter->pid_rc[i] = adapter->pid_rc[adapter->pid_count];
++                              // hardware setting
++                              remove_hw_pid(adapter, pid);
++                      }
+                       return 1;
+               }
+       }
+@@ -1475,21 +1254,16 @@ static int RemovePID(struct adapter *ada
+       return -1;
+ }
++
+ /* dma & irq */
+-static void CtrlEnableSmc(struct adapter *adapter, u32 op)
++static void ctrl_enable_smc(struct adapter *adapter, u32 op)
+ {
+-      if (op == 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00000800, 0);
+-
+-      } else {
+-
+-              WriteRegOp(adapter, 0x208, 1, 0, 0x00000800);
+-      }
++      write_reg_bitfield(adapter, 0x208, 0x00000800, op ? 0x00000800 : 0);
+ }
+-static void DmaEnableDisableIrq(struct adapter *adapter, u32 flag1, u32 flag2, u32 flag3)
++static void dma_enable_disable_irq(struct adapter *adapter, u32 flag1, u32 flag2, u32 flag3)
+ {
+-      adapter->dma_ctrl = adapter->dma_ctrl & 0x000F0000;
++      adapter->dma_ctrl = adapter->dma_ctrl & 0x000f0000;
+       if (flag1 == 0) {
+               if (flag2 == 0)
+@@ -1516,16 +1290,16 @@ static void DmaEnableDisableIrq(struct a
+       }
+ }
+-static void IrqDmaEnableDisableIrq(struct adapter * adapter, u32 op)
++static void irq_dma_enable_disable_irq(struct adapter *adapter, u32 op)
+ {
+       u32 value;
+-      value = ReadRegDW(adapter, 0x208) & 0xFFF0FFFF;
++      value = read_reg_dw(adapter, 0x208) & 0xfff0ffff;
+       if (op != 0)
+-              value = value | (adapter->dma_ctrl & 0x000F0000);
++              value = value | (adapter->dma_ctrl & 0x000f0000);
+-      WriteRegDW(adapter, 0x208, value);
++      write_reg_dw(adapter, 0x208, value);
+ }
+ /* FlexCopII has 2 dma channels. DMA1 is used to transfer TS data to
+@@ -1544,7 +1318,7 @@ static void IrqDmaEnableDisableIrq(struc
+        subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
+        when dma1 is enabled.
+-       the first 30 bits of register 0x00C contain the address of the second
++       the first 30 bits of register 0x00c contain the address of the second
+        subbuffer. the last 2 bits contain 1.
+        register 0x008 will contain the address of the subbuffer that was filled
+@@ -1559,13 +1333,13 @@ static void IrqDmaEnableDisableIrq(struc
+        subbuffer.  The last 2 bits contain 0, when dma1 is disabled and 1,
+        when dma1 is enabled.
+-       the first 30 bits of register 0x01C contain the address of the second
++       the first 30 bits of register 0x01c contain the address of the second
+        subbuffer. the last 2 bits contain 1.
+        register 0x018 contains the address of the subbuffer that was filled
+        with TS data, when FlexCopII generates an interrupt.
+ */
+-static int DmaInitDMA(struct adapter *adapter, u32 dma_channel)
++static int dma_init_dma(struct adapter *adapter, u32 dma_channel)
+ {
+       u32 subbuffers, subbufsize, subbuf0, subbuf1;
+@@ -1576,37 +1350,37 @@ static int DmaInitDMA(struct adapter *ad
+               subbufsize = (((adapter->dmaq1.buffer_size / 2) / 4) << 8) | subbuffers;
+-              subbuf0 = adapter->dmaq1.bus_addr & 0xFFFFFFFC;
++              subbuf0 = adapter->dmaq1.bus_addr & 0xfffffffc;
+-              subbuf1 = ((adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) & 0xFFFFFFFC) | 1;
++              subbuf1 = ((adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) & 0xfffffffc) | 1;
+               dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
+               udelay(1000);
+-              WriteRegDW(adapter, 0x000, subbuf0);
++              write_reg_dw(adapter, 0x000, subbuf0);
+               dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
+               udelay(1000);
+-              WriteRegDW(adapter, 0x004, subbufsize);
++              write_reg_dw(adapter, 0x004, subbufsize);
+               dprintk("%s: second subbuffer address = 0x%x\n", __FUNCTION__, subbuf1);
+               udelay(1000);
+-              WriteRegDW(adapter, 0x00C, subbuf1);
++              write_reg_dw(adapter, 0x00c, subbuf1);
+-              dprintk("%s: counter = 0x%x\n", __FUNCTION__, adapter->dmaq1.bus_addr & 0xFFFFFFFC);
+-              WriteRegDW(adapter, 0x008, adapter->dmaq1.bus_addr & 0xFFFFFFFC);
++              dprintk("%s: counter = 0x%x\n", __FUNCTION__, adapter->dmaq1.bus_addr & 0xfffffffc);
++              write_reg_dw(adapter, 0x008, adapter->dmaq1.bus_addr & 0xfffffffc);
+               udelay(1000);
+               if (subbuffers == 0)
+-                      DmaEnableDisableIrq(adapter, 0, 1, 0);
++                      dma_enable_disable_irq(adapter, 0, 1, 0);
+               else
+-                      DmaEnableDisableIrq(adapter, 0, 1, 1);
++                      dma_enable_disable_irq(adapter, 0, 1, 1);
+-              IrqDmaEnableDisableIrq(adapter, 1);
++              irq_dma_enable_disable_irq(adapter, 1);
+-              SRAMSetMediaDest(adapter, 1);
+-              SRAMSetNetDest(adapter, 1);
+-              SRAMSetCaiDest(adapter, 2);
+-              SRAMSetCaoDest(adapter, 2);
++              sram_set_media_dest(adapter, 1);
++              sram_set_net_dest(adapter, 1);
++              sram_set_cai_dest(adapter, 2);
++              sram_set_cao_dest(adapter, 2);
+       }
+       if (dma_channel == 1) {
+@@ -1616,39 +1390,35 @@ static int DmaInitDMA(struct adapter *ad
+               subbufsize = (((adapter->dmaq2.buffer_size / 2) / 4) << 8) | subbuffers;
+-              subbuf0 = adapter->dmaq2.bus_addr & 0xFFFFFFFC;
++              subbuf0 = adapter->dmaq2.bus_addr & 0xfffffffc;
+-              subbuf1 = ((adapter->dmaq2.bus_addr + adapter->dmaq2.buffer_size / 2) & 0xFFFFFFFC) | 1;
++              subbuf1 = ((adapter->dmaq2.bus_addr + adapter->dmaq2.buffer_size / 2) & 0xfffffffc) | 1;
+               dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
+               udelay(1000);
+-              WriteRegDW(adapter, 0x010, subbuf0);
++              write_reg_dw(adapter, 0x010, subbuf0);
+               dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
+               udelay(1000);
+-              WriteRegDW(adapter, 0x014, subbufsize);
++              write_reg_dw(adapter, 0x014, subbufsize);
+               dprintk("%s: second buffer address = 0x%x\n", __FUNCTION__, subbuf1);
+               udelay(1000);
+-              WriteRegDW(adapter, 0x01C, subbuf1);
++              write_reg_dw(adapter, 0x01c, subbuf1);
+-              SRAMSetCaiDest(adapter, 2);
++              sram_set_cai_dest(adapter, 2);
+       }
+       return 0;
+ }
+-static void CtrlEnableReceiveData(struct adapter *adapter, u32 op)
++static void ctrl_enable_receive_data(struct adapter *adapter, u32 op)
+ {
+       if (op == 0) {
+-              WriteRegOp(adapter, 0x208, 2, ~0x00008000, 0);
+-
++              write_reg_bitfield(adapter, 0x208, 0x00008000, 0);
+               adapter->dma_status = adapter->dma_status & ~0x00000004;
+-
+       } else {
+-
+-              WriteRegOp(adapter, 0x208, 1, 0, 0x00008000);
+-
++              write_reg_bitfield(adapter, 0x208, 0x00008000, 0x00008000);
+               adapter->dma_status = adapter->dma_status | 0x00000004;
+       }
+ }
+@@ -1656,7 +1426,7 @@ static void CtrlEnableReceiveData(struct
+ /* bit 0 of dma_mask is set to 1 if dma1 channel has to be enabled/disabled
+    bit 1 of dma_mask is set to 1 if dma2 channel has to be enabled/disabled
+ */
+-static void DmaStartStop0x2102(struct adapter *adapter, u32 dma_mask, u32 start_stop)
++static void dma_start_stop(struct adapter *adapter, u32 dma_mask, int start_stop)
+ {
+       u32 dma_enable, dma1_enable, dma2_enable;
+@@ -1679,83 +1449,82 @@ static void DmaStartStop0x2102(struct ad
+               }
+               // enable dma1 and dma2
+               if ((dma1_enable == 1) && (dma2_enable == 1)) {
+-                      WriteRegDW(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
+-                      WriteRegDW(adapter, 0x00C, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
+-                      WriteRegDW(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
++                      write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
++                      write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
++                      write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
+-                      CtrlEnableReceiveData(adapter, 1);
++                      ctrl_enable_receive_data(adapter, 1);
+                       return;
+               }
+               // enable dma1
+               if ((dma1_enable == 1) && (dma2_enable == 0)) {
+-                      WriteRegDW(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
+-                      WriteRegDW(adapter, 0x00C, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
++                      write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
++                      write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
+-                      CtrlEnableReceiveData(adapter, 1);
++                      ctrl_enable_receive_data(adapter, 1);
+                       return;
+               }
+               // enable dma2
+               if ((dma1_enable == 0) && (dma2_enable == 1)) {
+-                      WriteRegDW(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
++                      write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
+-                      CtrlEnableReceiveData(adapter, 1);
++                      ctrl_enable_receive_data(adapter, 1);
+                       return;
+               }
+               // start dma
+               if ((dma1_enable == 0) && (dma2_enable == 0)) {
+-                      CtrlEnableReceiveData(adapter, 1);
++                      ctrl_enable_receive_data(adapter, 1);
+                       return;
+               }
+       } else {
+-              dprintk("%s: stoping dma\n", __FUNCTION__);
++              dprintk("%s: stopping dma\n", __FUNCTION__);
+               dma_enable = adapter->dma_status & 0x00000003;
+               if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0)) {
+-                      dma_enable = dma_enable & 0xFFFFFFFE;
++                      dma_enable = dma_enable & 0xfffffffe;
+               }
+               if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0)) {
+-                      dma_enable = dma_enable & 0xFFFFFFFD;
++                      dma_enable = dma_enable & 0xfffffffd;
+               }
+               //stop dma
+               if ((dma_enable == 0) && ((adapter->dma_status & 4) != 0)) {
+-                      CtrlEnableReceiveData(adapter, 0);
++                      ctrl_enable_receive_data(adapter, 0);
+                       udelay(3000);
+               }
+               //disable dma1
+               if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0) && (adapter->dmaq1.bus_addr != 0)) {
+-                      WriteRegDW(adapter, 0x000, adapter->dmaq1.bus_addr);
+-                      WriteRegDW(adapter, 0x00C, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
++                      write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr);
++                      write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
+                       adapter->dma_status = adapter->dma_status & ~0x00000001;
+               }
+               //disable dma2
+               if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0) && (adapter->dmaq2.bus_addr != 0)) {
+-                      WriteRegDW(adapter, 0x010, adapter->dmaq2.bus_addr);
++                      write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr);
+                       adapter->dma_status = adapter->dma_status & ~0x00000002;
+               }
+       }
+ }
+-static void OpenStream(struct adapter *adapter, u32 pid)
++static void open_stream(struct adapter *adapter, u16 pid)
+ {
+       u32 dma_mask;
+-      if (adapter->capturing == 0)
+-              adapter->capturing = 1;
++      ++adapter->capturing;
+-      FilterEnableMaskFilter(adapter, 1);
++      filter_enable_mask_filter(adapter, 1);
+-      AddPID(adapter, pid);
++      add_pid(adapter, pid);
+       dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status);
+@@ -1779,23 +1548,22 @@ static void OpenStream(struct adapter *a
+               }
+               if (dma_mask != 0) {
+-                      IrqDmaEnableDisableIrq(adapter, 1);
++                      irq_dma_enable_disable_irq(adapter, 1);
+-                      DmaStartStop0x2102(adapter, dma_mask, 1);
++                      dma_start_stop(adapter, dma_mask, 1);
+               }
+       }
+ }
+-static void CloseStream(struct adapter *adapter, u32 pid)
++static void close_stream(struct adapter *adapter, u16 pid)
+ {
+-      u32 dma_mask;
+-
+-      if (adapter->capturing != 0)
+-              adapter->capturing = 0;
++      if (adapter->capturing > 0)
++              --adapter->capturing;
+       dprintk("%s: dma_status=%x\n", __FUNCTION__, adapter->dma_status);
+-      dma_mask = 0;
++      if (adapter->capturing == 0) {
++              u32 dma_mask = 0;
+       if ((adapter->dma_status & 1) != 0)
+               dma_mask = dma_mask | 0x00000001;
+@@ -1803,94 +1571,76 @@ static void CloseStream(struct adapter *
+               dma_mask = dma_mask | 0x00000002;
+       if (dma_mask != 0) {
+-              DmaStartStop0x2102(adapter, dma_mask, 0);
++                      dma_start_stop(adapter, dma_mask, 0);
+       }
+-
+-      RemovePID(adapter, pid);
++      }
++      remove_pid(adapter, pid);
+ }
+-static void InterruptServiceDMA1(struct adapter *adapter)
++static void interrupt_service_dma1(struct adapter *adapter)
+ {
+       struct dvb_demux *dvbdmx = &adapter->demux;
+-      struct packet_header packet_header;
+-      int nCurDmaCounter;
+-      u32 nNumBytesParsed;
+-      u32 nNumNewBytesTransferred;
+-      u32 dwDefaultPacketSize = 188;
+-      u8 gbTmpBuffer[188];
+-      u8 *pbDMABufCurPos;
++      int n_cur_dma_counter;
++      u32 n_num_bytes_parsed;
++      u32 n_num_new_bytes_transferred;
++      u32 dw_default_packet_size = 188;
++      u8 gb_tmp_buffer[188];
++      u8 *pb_dma_buf_cur_pos;
+-      nCurDmaCounter = readl(adapter->io_mem + 0x008) - adapter->dmaq1.bus_addr;
+-      nCurDmaCounter = (nCurDmaCounter / dwDefaultPacketSize) * dwDefaultPacketSize;
++      n_cur_dma_counter = readl(adapter->io_mem + 0x008) - adapter->dmaq1.bus_addr;
++      n_cur_dma_counter = (n_cur_dma_counter / dw_default_packet_size) * dw_default_packet_size;
+-      if ((nCurDmaCounter < 0) || (nCurDmaCounter > adapter->dmaq1.buffer_size)) {
++      if ((n_cur_dma_counter < 0) || (n_cur_dma_counter > adapter->dmaq1.buffer_size)) {
+               dprintk("%s: dma counter outside dma buffer\n", __FUNCTION__);
+               return;
+       }
+-      adapter->dmaq1.head = nCurDmaCounter;
++      adapter->dmaq1.head = n_cur_dma_counter;
+-      if (adapter->dmaq1.tail <= nCurDmaCounter) {
+-              nNumNewBytesTransferred = nCurDmaCounter - adapter->dmaq1.tail;
++      if (adapter->dmaq1.tail <= n_cur_dma_counter) {
++              n_num_new_bytes_transferred = n_cur_dma_counter - adapter->dmaq1.tail;
+       } else {
+-              nNumNewBytesTransferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + nCurDmaCounter;
++              n_num_new_bytes_transferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + n_cur_dma_counter;
+       }
+-//  dprintk("%s: nCurDmaCounter   = %d\n" , __FUNCTION__, nCurDmaCounter);
+-//    dprintk("%s: dmaq1.tail       = %d\n" , __FUNCTION__, adapter->dmaq1.tail):
+-//  dprintk("%s: BytesTransferred = %d\n" , __FUNCTION__, nNumNewBytesTransferred);
++      ddprintk("%s: n_cur_dma_counter = %d\n", __FUNCTION__, n_cur_dma_counter);
++      ddprintk("%s: dmaq1.tail        = %d\n", __FUNCTION__, adapter->dmaq1.tail);
++      ddprintk("%s: bytes_transferred = %d\n", __FUNCTION__, n_num_new_bytes_transferred);
+-      if (nNumNewBytesTransferred < dwDefaultPacketSize)
++      if (n_num_new_bytes_transferred < dw_default_packet_size)
+               return;
+-      nNumBytesParsed = 0;
++      n_num_bytes_parsed = 0;
+-      while (nNumBytesParsed < nNumNewBytesTransferred) {
+-              pbDMABufCurPos = adapter->dmaq1.buffer + adapter->dmaq1.tail;
++      while (n_num_bytes_parsed < n_num_new_bytes_transferred) {
++              pb_dma_buf_cur_pos = adapter->dmaq1.buffer + adapter->dmaq1.tail;
+               if (adapter->dmaq1.buffer + adapter->dmaq1.buffer_size < adapter->dmaq1.buffer + adapter->dmaq1.tail + 188) {
+-                      memcpy(gbTmpBuffer, adapter->dmaq1.buffer + adapter->dmaq1.tail, adapter->dmaq1.buffer_size - adapter->dmaq1.tail);
+-                      memcpy(gbTmpBuffer + (adapter->dmaq1.buffer_size - adapter->dmaq1.tail), adapter->dmaq1.buffer, (188 - (adapter->dmaq1.buffer_size - adapter->dmaq1.tail)));
++                      memcpy(gb_tmp_buffer, adapter->dmaq1.buffer + adapter->dmaq1.tail,
++                             adapter->dmaq1.buffer_size - adapter->dmaq1.tail);
++                      memcpy(gb_tmp_buffer + (adapter->dmaq1.buffer_size - adapter->dmaq1.tail), adapter->dmaq1.buffer,
++                             (188 - (adapter->dmaq1.buffer_size - adapter->dmaq1.tail)));
+-                      pbDMABufCurPos = gbTmpBuffer;
++                      pb_dma_buf_cur_pos = gb_tmp_buffer;
+               }
+               if (adapter->capturing != 0) {
+-                      u32 *dq = (u32 *) pbDMABufCurPos;
+-
+-                      packet_header.sync_byte = *dq & 0x000000FF;
+-                      packet_header.transport_error_indicator = *dq & 0x00008000;
+-                      packet_header.payload_unit_start_indicator = *dq & 0x00004000;
+-                      packet_header.transport_priority = *dq & 0x00002000;
+-                      packet_header.pid = ((*dq & 0x00FF0000) >> 0x10) | (*dq & 0x00001F00);
+-                      packet_header.transport_scrambling_control = *dq >> 0x1E;
+-                      packet_header.adaptation_field_control = (*dq & 0x30000000) >> 0x1C;
+-                      packet_header.continuity_counter = (*dq & 0x0F000000) >> 0x18;
+-
+-                      if ((packet_header.sync_byte == 0x47) && (packet_header.transport_error_indicator == 0) && (packet_header.pid != 0x1FFF)) {
+-                              if (CheckPID(adapter, packet_header.pid & 0x0000FFFF) != 0) {
+-                                      dvb_dmx_swfilter_packets(dvbdmx, pbDMABufCurPos, dwDefaultPacketSize / 188);
+-
+-                              } else {
+-
+-//                  dprintk("%s: pid=%x\n", __FUNCTION__, packet_header.pid);
+-                              }
+-                      }
++                      dvb_dmx_swfilter_packets(dvbdmx, pb_dma_buf_cur_pos, dw_default_packet_size / 188);
+               }
+-              nNumBytesParsed = nNumBytesParsed + dwDefaultPacketSize;
++              n_num_bytes_parsed = n_num_bytes_parsed + dw_default_packet_size;
+-              adapter->dmaq1.tail = adapter->dmaq1.tail + dwDefaultPacketSize;
++              adapter->dmaq1.tail = adapter->dmaq1.tail + dw_default_packet_size;
+               if (adapter->dmaq1.tail >= adapter->dmaq1.buffer_size)
+                       adapter->dmaq1.tail = adapter->dmaq1.tail - adapter->dmaq1.buffer_size;
+       };
+ }
+-static void InterruptServiceDMA2(struct adapter *adapter)
++static void interrupt_service_dma2(struct adapter *adapter)
+ {
+       printk("%s:\n", __FUNCTION__);
+ }
+@@ -1901,28 +1651,28 @@ static irqreturn_t isr(int irq, void *de
+       u32 value;
+-//  dprintk("%s:\n", __FUNCTION__);
++      ddprintk("%s:\n", __FUNCTION__);
+       spin_lock_irq(&tmp->lock);
+-      if (0 == ((value = ReadRegDW(tmp, 0x20C)) & 0x0F)) {
++      if (0 == ((value = read_reg_dw(tmp, 0x20c)) & 0x0f)) {
+               spin_unlock_irq(&tmp->lock);
+               return IRQ_NONE;
+       }
+       
+       while (value != 0) {
+               if ((value & 0x03) != 0)
+-                      InterruptServiceDMA1(tmp);
+-              if ((value & 0x0C) != 0)
+-                      InterruptServiceDMA2(tmp);
+-              value = ReadRegDW(tmp, 0x20C) & 0x0F;
++                      interrupt_service_dma1(tmp);
++              if ((value & 0x0c) != 0)
++                      interrupt_service_dma2(tmp);
++              value = read_reg_dw(tmp, 0x20c) & 0x0f;
+       }
+       spin_unlock_irq(&tmp->lock);
+       return IRQ_HANDLED;
+ }
+-static void Initdmaqueue(struct adapter *adapter)
++static void init_dma_queue(struct adapter *adapter)
+ {
+       dma_addr_t dma_addr;
+@@ -1933,19 +1683,19 @@ static void Initdmaqueue(struct adapter 
+       adapter->dmaq1.tail = 0;
+       adapter->dmaq1.buffer = 0;
+-      adapter->dmaq1.buffer = pci_alloc_consistent(adapter->pdev, SizeOfBufDMA1 + 0x80, &dma_addr);
++      adapter->dmaq1.buffer = pci_alloc_consistent(adapter->pdev, SIZE_OF_BUF_DMA1 + 0x80, &dma_addr);
+       if (adapter->dmaq1.buffer != 0) {
+-              memset(adapter->dmaq1.buffer, 0, SizeOfBufDMA1);
++              memset(adapter->dmaq1.buffer, 0, SIZE_OF_BUF_DMA1);
+               adapter->dmaq1.bus_addr = dma_addr;
+-              adapter->dmaq1.buffer_size = SizeOfBufDMA1;
++              adapter->dmaq1.buffer_size = SIZE_OF_BUF_DMA1;
+-              DmaInitDMA(adapter, 0);
++              dma_init_dma(adapter, 0);
+               adapter->dma_status = adapter->dma_status | 0x10000000;
+-              dprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq1.buffer, SizeOfBufDMA1);
++              ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq1.buffer, SIZE_OF_BUF_DMA1);
+       } else {
+@@ -1959,19 +1709,19 @@ static void Initdmaqueue(struct adapter 
+       adapter->dmaq2.tail = 0;
+       adapter->dmaq2.buffer = 0;
+-      adapter->dmaq2.buffer = pci_alloc_consistent(adapter->pdev, SizeOfBufDMA2 + 0x80, &dma_addr);
++      adapter->dmaq2.buffer = pci_alloc_consistent(adapter->pdev, SIZE_OF_BUF_DMA2 + 0x80, &dma_addr);
+       if (adapter->dmaq2.buffer != 0) {
+-              memset(adapter->dmaq2.buffer, 0, SizeOfBufDMA2);
++              memset(adapter->dmaq2.buffer, 0, SIZE_OF_BUF_DMA2);
+               adapter->dmaq2.bus_addr = dma_addr;
+-              adapter->dmaq2.buffer_size = SizeOfBufDMA2;
++              adapter->dmaq2.buffer_size = SIZE_OF_BUF_DMA2;
+-              DmaInitDMA(adapter, 1);
++              dma_init_dma(adapter, 1);
+               adapter->dma_status = adapter->dma_status | 0x20000000;
+-              dprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq2.buffer, (int) SizeOfBufDMA2);
++              ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq2.buffer, (int) SIZE_OF_BUF_DMA2);
+       } else {
+@@ -1979,10 +1729,10 @@ static void Initdmaqueue(struct adapter 
+       }
+ }
+-static void Freedmaqueue(struct adapter *adapter)
++static void free_dma_queue(struct adapter *adapter)
+ {
+       if (adapter->dmaq1.buffer != 0) {
+-              pci_free_consistent(adapter->pdev, SizeOfBufDMA1 + 0x80, adapter->dmaq1.buffer, adapter->dmaq1.bus_addr);
++              pci_free_consistent(adapter->pdev, SIZE_OF_BUF_DMA1 + 0x80, adapter->dmaq1.buffer, adapter->dmaq1.bus_addr);
+               adapter->dmaq1.bus_addr = 0;
+               adapter->dmaq1.head = 0;
+@@ -1992,7 +1742,7 @@ static void Freedmaqueue(struct adapter 
+       }
+       if (adapter->dmaq2.buffer != 0) {
+-              pci_free_consistent(adapter->pdev, SizeOfBufDMA2 + 0x80, adapter->dmaq2.buffer, adapter->dmaq2.bus_addr);
++              pci_free_consistent(adapter->pdev, SIZE_OF_BUF_DMA2 + 0x80, adapter->dmaq2.buffer, adapter->dmaq2.bus_addr);
+               adapter->dmaq2.bus_addr = 0;
+               adapter->dmaq2.head = 0;
+@@ -2002,16 +1752,16 @@ static void Freedmaqueue(struct adapter 
+       }
+ }
+-static void FreeAdapterObject(struct adapter *adapter)
++static void free_adapter_object(struct adapter *adapter)
+ {
+       dprintk("%s:\n", __FUNCTION__);
+-      CloseStream(adapter, 0);
++      close_stream(adapter, 0);
+       if (adapter->irq != 0)
+               free_irq(adapter->irq, adapter);
+-      Freedmaqueue(adapter);
++      free_dma_queue(adapter);
+       if (adapter->io_mem != 0)
+               iounmap((void *) adapter->io_mem);
+@@ -2022,7 +1772,7 @@ static void FreeAdapterObject(struct ada
+ static struct pci_driver skystar2_pci_driver;
+-static int ClaimAdapter(struct adapter *adapter)
++static int claim_adapter(struct adapter *adapter)
+ {
+       struct pci_dev *pdev = adapter->pdev;
+@@ -2062,20 +1812,58 @@ static int ClaimAdapter(struct adapter *
+ }
+ /*
+-static int SLL_reset_FlexCOP(struct adapter *adapter)
++static int sll_reset_flexcop(struct adapter *adapter)
+ {
+-      WriteRegDW(adapter, 0x208, 0);
+-      WriteRegDW(adapter, 0x210, 0xB2FF);
++      write_reg_dw(adapter, 0x208, 0);
++      write_reg_dw(adapter, 0x210, 0xb2ff);
+       return 0;
+ }
+ */
+-static int DriverInitialize(struct pci_dev * pdev)
++static void decide_how_many_hw_filters(struct adapter *adapter)
++{
++      int hw_filters;
++      int mod_option_hw_filters;
++
++      // FlexCop IIb & III have 6+32 hw filters    
++      // FlexCop II has 6 hw filters, every other should have at least 6
++      switch (adapter->b2c2_revision) {
++      case 0x82:              /* II */
++              hw_filters = 6;
++              break;
++      case 0xc3:              /* IIB */
++              hw_filters = 6 + 32;
++              break;
++      case 0xc0:              /* III */
++              hw_filters = 6 + 32;
++              break;
++      default:
++              hw_filters = 6;
++              break;
++      }
++      printk("%s: the chip has %i hardware filters", __FILE__, hw_filters);
++
++      mod_option_hw_filters = 0;
++      if (enable_hw_filters >= 1)
++              mod_option_hw_filters += 6;
++      if (enable_hw_filters >= 2)
++              mod_option_hw_filters += 32;
++
++      if (mod_option_hw_filters >= hw_filters) {
++              adapter->useable_hw_filters = hw_filters;
++      } else {
++              adapter->useable_hw_filters = mod_option_hw_filters;
++              printk(", but only %d will be used because of module option", mod_option_hw_filters);
++      }
++      printk("\n");
++      dprintk("%s: useable_hardware_filters set to %i\n", __FILE__, adapter->useable_hw_filters);
++}
++
++static int driver_initialize(struct pci_dev *pdev)
+ {
+       struct adapter *adapter;
+       u32 tmp;
+-      u8 key[16];
+       if (!(adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL))) {
+               dprintk("%s: out of memory!\n", __FUNCTION__);
+@@ -2090,113 +1878,114 @@ static int DriverInitialize(struct pci_d
+       adapter->pdev = pdev;
+       adapter->irq = pdev->irq;
+-      if ((ClaimAdapter(adapter)) != 1) {
+-              FreeAdapterObject(adapter);
++      if ((claim_adapter(adapter)) != 1) {
++              free_adapter_object(adapter);
+               return -ENODEV;
+       }
+-      IrqDmaEnableDisableIrq(adapter, 0);
++      irq_dma_enable_disable_irq(adapter, 0);
+       if (request_irq(pdev->irq, isr, 0x4000000, "Skystar2", adapter) != 0) {
+               dprintk("%s: unable to allocate irq=%d !\n", __FUNCTION__, pdev->irq);
+-              FreeAdapterObject(adapter);
++              free_adapter_object(adapter);
+               return -ENODEV;
+       }
+-      ReadRegDW(adapter, 0x208);
+-      WriteRegDW(adapter, 0x208, 0);
+-      WriteRegDW(adapter, 0x210, 0xB2FF);
+-      WriteRegDW(adapter, 0x208, 0x40);
+-
+-      InitPIDsInfo(adapter);
+-
+-      PidSetGroupPID(adapter, 0);
+-      PidSetGroupMASK(adapter, 0x1FE0);
+-      PidSetStream1PID(adapter, 0x1FFF);
+-      PidSetStream2PID(adapter, 0x1FFF);
+-      PidSetPmtPID(adapter, 0x1FFF);
+-      PidSetPcrPID(adapter, 0x1FFF);
+-      PidSetEcmPID(adapter, 0x1FFF);
+-      PidSetEmmPID(adapter, 0x1FFF);
++      read_reg_dw(adapter, 0x208);
++      write_reg_dw(adapter, 0x208, 0);
++      write_reg_dw(adapter, 0x210, 0xb2ff);
++      write_reg_dw(adapter, 0x208, 0x40);
+-      Initdmaqueue(adapter);
++      init_dma_queue(adapter);
+       if ((adapter->dma_status & 0x30000000) == 0) {
+-              FreeAdapterObject(adapter);
++              free_adapter_object(adapter);
+               return -ENODEV;
+       }
+-      adapter->b2c2_revision = (ReadRegDW(adapter, 0x204) >> 0x18);
+-
+-      if ((adapter->b2c2_revision != 0x82) && (adapter->b2c2_revision != 0xC3))
+-              if (adapter->b2c2_revision != 0x82) {
+-                      dprintk("%s: The revision of the FlexCopII chip on your card is - %d\n", __FUNCTION__, adapter->b2c2_revision);
+-                      dprintk("%s: This driver works now only with FlexCopII(rev.130) and FlexCopIIB(rev.195).\n", __FUNCTION__);
+-
+-                      FreeAdapterObject(adapter);
++      adapter->b2c2_revision = (read_reg_dw(adapter, 0x204) >> 0x18);
++      switch (adapter->b2c2_revision) {
++      case 0x82:
++              printk("%s: FlexCopII(rev.130) chip found\n", __FILE__);
++              break;
++      case 0xc3:
++              printk("%s: FlexCopIIB(rev.195) chip found\n", __FILE__);
++              break;
++      case 0xc0:
++              printk("%s: FlexCopIII(rev.192) chip found\n", __FILE__);
++              break;
++      default:
++              printk("%s: The revision of the FlexCop chip on your card is %d\n", __FILE__, adapter->b2c2_revision);
++              printk("%s: This driver works only with FlexCopII(rev.130), FlexCopIIB(rev.195) and FlexCopIII(rev.192).\n", __FILE__);
++              free_adapter_object(adapter);
++              pci_set_drvdata(pdev, NULL);
++              release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
++              release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+                       return -ENODEV;
+               }
+-      tmp = ReadRegDW(adapter, 0x204);
++      decide_how_many_hw_filters(adapter);
++
++      init_pids(adapter);
++
++      tmp = read_reg_dw(adapter, 0x204);
+-      WriteRegDW(adapter, 0x204, 0);
++      write_reg_dw(adapter, 0x204, 0);
+       mdelay(20);
+-      WriteRegDW(adapter, 0x204, tmp);
++      write_reg_dw(adapter, 0x204, tmp);
+       mdelay(10);
+-      tmp = ReadRegDW(adapter, 0x308);
+-      WriteRegDW(adapter, 0x308, 0x4000 | tmp);
++      tmp = read_reg_dw(adapter, 0x308);
++      write_reg_dw(adapter, 0x308, 0x4000 | tmp);
+-      adapter->dwSramType = 0x10000;
++      adapter->dw_sram_type = 0x10000;
+-      SLL_detectSramSize(adapter);
++      sll_detect_sram_size(adapter);
+-      dprintk("%s sram length = %d, sram type= %x\n", __FUNCTION__, SRAM_length(adapter), adapter->dwSramType);
++      dprintk("%s sram length = %d, sram type= %x\n", __FUNCTION__, sram_length(adapter), adapter->dw_sram_type);
+-      SRAMSetMediaDest(adapter, 1);
+-      SRAMSetNetDest(adapter, 1);
++      sram_set_media_dest(adapter, 1);
++      sram_set_net_dest(adapter, 1);
+-      CtrlEnableSmc(adapter, 0);
++      ctrl_enable_smc(adapter, 0);
+-      SRAMSetCaiDest(adapter, 2);
+-      SRAMSetCaoDest(adapter, 2);
++      sram_set_cai_dest(adapter, 2);
++      sram_set_cao_dest(adapter, 2);
+-      DmaEnableDisableIrq(adapter, 1, 0, 0);
++      dma_enable_disable_irq(adapter, 1, 0, 0);
+-      if (EEPROM_getMacAddr(adapter, 0, adapter->mac_addr) != 0) {
+-              printk("%s MAC address = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n", __FUNCTION__, adapter->mac_addr[0], adapter->mac_addr[1], adapter->mac_addr[2], adapter->mac_addr[3], adapter->mac_addr[4], adapter->mac_addr[5], adapter->mac_addr[6], adapter->mac_addr[7]
++      if (eeprom_get_mac_addr(adapter, 0, adapter->mac_addr) != 0) {
++              printk("%s MAC address = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n", __FUNCTION__, adapter->mac_addr[0],
++                     adapter->mac_addr[1], adapter->mac_addr[2], adapter->mac_addr[3], adapter->mac_addr[4], adapter->mac_addr[5],
++                     adapter->mac_addr[6], adapter->mac_addr[7]
+                   );
+-              CASetMacDstAddrFilter(adapter, adapter->mac_addr);
+-              CtrlEnableMAC(adapter, 1);
++              ca_set_mac_dst_addr_filter(adapter, adapter->mac_addr);
++              ctrl_enable_mac(adapter, 1);
+       }
+-      EEPROM_readKey(adapter, key, 16);
+-
+-      printk("%s key = \n %02x %02x %02x %02x \n %02x %02x %02x %02x \n %02x %02x %02x %02x \n %02x %02x %02x %02x \n", __FUNCTION__, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7], key[8], key[9], key[10], key[11], key[12], key[13], key[14], key[15]);
+-
+       adapter->lock = SPIN_LOCK_UNLOCKED;
+       return 0;
+ }
+-static void DriverHalt(struct pci_dev *pdev)
++static void driver_halt(struct pci_dev *pdev)
+ {
+       struct adapter *adapter;
+       adapter = pci_get_drvdata(pdev);
+-      IrqDmaEnableDisableIrq(adapter, 0);
++      irq_dma_enable_disable_irq(adapter, 0);
+-      CtrlEnableReceiveData(adapter, 0);
++      ctrl_enable_receive_data(adapter, 0);
+-      FreeAdapterObject(adapter);
++      free_adapter_object(adapter);
+       pci_set_drvdata(pdev, NULL);
+@@ -2212,7 +2001,7 @@ static int dvb_start_feed(struct dvb_dem
+       dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
+-      OpenStream(adapter, dvbdmxfeed->pid);
++      open_stream(adapter, dvbdmxfeed->pid);
+       return 0;
+ }
+@@ -2224,7 +2013,7 @@ static int dvb_stop_feed(struct dvb_demu
+       dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
+-      CloseStream(adapter, dvbdmxfeed->pid);
++      close_stream(adapter, dvbdmxfeed->pid);
+       return 0;
+ }
+@@ -2232,23 +2021,23 @@ static int dvb_stop_feed(struct dvb_demu
+ /* lnb control */
+ static void set_tuner_tone(struct adapter *adapter, u8 tone)
+ {
+-      u16 wzHalfPeriodFor45MHz[] = { 0x01FF, 0x0154, 0x00FF, 0x00CC };
++      u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc };
+       u16 ax;
+       dprintk("%s: %u\n", __FUNCTION__, tone);
+       switch (tone) {
+       case 1:
+-              ax = wzHalfPeriodFor45MHz[0];
++              ax = wz_half_period_for_45_mhz[0];
+               break;
+       case 2:
+-              ax = wzHalfPeriodFor45MHz[1];
++              ax = wz_half_period_for_45_mhz[1];
+               break;
+       case 3:
+-              ax = wzHalfPeriodFor45MHz[2];
++              ax = wz_half_period_for_45_mhz[2];
+               break;
+       case 4:
+-              ax = wzHalfPeriodFor45MHz[3];
++              ax = wz_half_period_for_45_mhz[3];
+               break;
+       default:
+@@ -2256,11 +2045,11 @@ static void set_tuner_tone(struct adapte
+       }
+       if (ax != 0) {
+-              WriteRegDW(adapter, 0x200, ((ax << 0x0F) + (ax & 0x7FFF)) | 0x40000000);
++              write_reg_dw(adapter, 0x200, ((ax << 0x0f) + (ax & 0x7fff)) | 0x40000000);
+       } else {
+-              WriteRegDW(adapter, 0x200, 0x40FF8000);
++              write_reg_dw(adapter, 0x200, 0x40ff8000);
+       }
+ }
+@@ -2270,7 +2059,7 @@ static void set_tuner_polarity(struct ad
+       dprintk("%s : polarity = %u \n", __FUNCTION__, polarity);
+-      var = ReadRegDW(adapter, 0x204);
++      var = read_reg_dw(adapter, 0x204);
+       if (polarity == 0) {
+               dprintk("%s: LNB power off\n", __FUNCTION__);
+@@ -2287,82 +2076,150 @@ static void set_tuner_polarity(struct ad
+               var = var | 4;
+       }
+-      WriteRegDW(adapter, 0x204, var);
++      write_reg_dw(adapter, 0x204, var);
+ }
+-static int flexcop_diseqc_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
++static void diseqc_send_bit(struct adapter *adapter, int data)
+ {
+-      struct adapter *adapter = fe->before_after_data;
++      set_tuner_tone(adapter, 1);
++      udelay(data ? 500 : 1000);
++      set_tuner_tone(adapter, 0);
++      udelay(data ? 1000 : 500);
++}
+-      switch (cmd) {
+-      case FE_SLEEP:
++
++static void diseqc_send_byte(struct adapter *adapter, int data)
+               {
+-                      printk("%s: FE_SLEEP\n", __FUNCTION__);
++      int i, par = 1, d;
+-                      set_tuner_polarity(adapter, 0);
++      for (i = 7; i >= 0; i--) {
++              d = (data >> i) & 1;
++              par ^= d;
++              diseqc_send_bit(adapter, d);
++      }
+-                      // return -EOPNOTSUPP, to make DVB core also send "FE_SLEEP" command to frontend.
+-                      return -EOPNOTSUPP;
++      diseqc_send_bit(adapter, par);
+               }
+-      case FE_SET_VOLTAGE:
+-              {
+-                      dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);
+-                      switch ((fe_sec_voltage_t) arg) {
+-                      case SEC_VOLTAGE_13:
++static int send_diseqc_msg(struct adapter *adapter, int len, u8 *msg, unsigned long burst)
++{
++      int i;
+-                              printk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13);
++      set_tuner_tone(adapter, 0);
++      mdelay(16);
+-                              set_tuner_polarity(adapter, 1);
++      for (i = 0; i < len; i++)
++              diseqc_send_byte(adapter, msg[i]);
+-                              break;
++      mdelay(16);
+-                      case SEC_VOLTAGE_18:
++      if (burst != -1) {
++              if (burst)
++                      diseqc_send_byte(adapter, 0xff);
++              else {
++                      set_tuner_tone(adapter, 1);
++                      udelay(12500);
++                      set_tuner_tone(adapter, 0);
++              }
++              dvb_delay(20);
++      }
+-                              printk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18);
++      return 0;
++}
+-                              set_tuner_polarity(adapter, 2);
++int soft_diseqc(struct adapter *adapter, unsigned int cmd, void *arg)
++{
++      switch (cmd) {
++      case FE_SET_TONE:
++              switch ((fe_sec_tone_mode_t) arg) {
++              case SEC_TONE_ON:
++                      set_tuner_tone(adapter, 1);
++                      break;
++              case SEC_TONE_OFF:
++                      set_tuner_tone(adapter, 0);
+                               break;
+-
+                       default:
+-
+                               return -EINVAL;
+                       };
++              break;
++      case FE_DISEQC_SEND_MASTER_CMD:
++              {
++                      struct dvb_diseqc_master_cmd *cmd = arg;
++
++                      send_diseqc_msg(adapter, cmd->msg_len, cmd->msg, 0);
+                       break;
+               }
+-      case FE_SET_TONE:
++      case FE_DISEQC_SEND_BURST:
++              send_diseqc_msg(adapter, 0, NULL, (unsigned long) arg);
++              break;
++
++      default:
++              return -EOPNOTSUPP;
++      };
++
++      return 0;
++}
++
++static int flexcop_diseqc_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
+               {
+-                      dprintk("%s: FE_SET_TONE\n", __FUNCTION__);
++      struct adapter *adapter = fe->before_after_data;
+-                      switch ((fe_sec_tone_mode_t) arg) {
+-                      case SEC_TONE_ON:
++      struct dvb_frontend_info info;
+-                              printk("%s: SEC_TONE_ON, %x\n", __FUNCTION__, SEC_TONE_ON);
++      fe->ioctl(fe, FE_GET_INFO, &info);
+-                              set_tuner_tone(adapter, 1);
++      // we must use different DiSEqC hw
+-                              break;
++      if (strcmp(info.name, "Zarlink MT312") == 0) {
++              //VP310 using mt312 driver for tuning only: diseqc not wired
++              //use FCII instead
++              if (!soft_diseqc(adapter, cmd, arg))
++                      return 0;
++      }
+-                      case SEC_TONE_OFF:
++      switch (cmd) {
++      case FE_SLEEP:
++              {
++                      dprintk("%s: FE_SLEEP\n", __FUNCTION__);
+-                              printk("%s: SEC_TONE_OFF, %x\n", __FUNCTION__, SEC_TONE_OFF);
++                      set_tuner_polarity(adapter, 0);
+-                              set_tuner_tone(adapter, 0);
++                      // return -EOPNOTSUPP, to make DVB core also send "FE_SLEEP" command to frontend.
++                      return -EOPNOTSUPP;
++              }
+-                              break;
++      case FE_SET_VOLTAGE:
++              {
++                      dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);
++
++                      switch ((fe_sec_voltage_t) arg) {
++                      case SEC_VOLTAGE_13:
++
++                              dprintk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13);
++
++                              set_tuner_polarity(adapter, 1);
++
++                              return 0;
++
++                      case SEC_VOLTAGE_18:
++
++                              dprintk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18);
++
++                              set_tuner_polarity(adapter, 2);
++
++                              return 0;
+                       default:
+                               return -EINVAL;
+                       };
+-
+-                      break;
+               }
++
+       default:
+               return -EOPNOTSUPP;
+@@ -2382,7 +2239,7 @@ static int skystar2_probe(struct pci_dev
+       if (pdev == NULL)
+               return -ENODEV;
+-      if (DriverInitialize(pdev) != 0)
++      if (driver_initialize(pdev) != 0)
+               return -ENODEV;
+       dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name);
+@@ -2390,7 +2247,7 @@ static int skystar2_probe(struct pci_dev
+       if (dvb_adapter == NULL) {
+               printk("%s: Error registering DVB adapter\n", __FUNCTION__);
+-              DriverHalt(pdev);
++              driver_halt(pdev);
+               return -ENODEV;
+       }
+@@ -2411,8 +2268,8 @@ static int skystar2_probe(struct pci_dev
+       dvbdemux = &adapter->demux;
+       dvbdemux->priv = (void *) adapter;
+-      dvbdemux->filternum = 32;
+-      dvbdemux->feednum = 32;
++      dvbdemux->filternum = N_PID_SLOTS;
++      dvbdemux->feednum = N_PID_SLOTS;
+       dvbdemux->start_feed = dvb_start_feed;
+       dvbdemux->stop_feed = dvb_stop_feed;
+       dvbdemux->write_to_decoder = 0;
+@@ -2422,7 +2279,7 @@ static int skystar2_probe(struct pci_dev
+       adapter->hw_frontend.source = DMX_FRONTEND_0;
+-      adapter->dmxdev.filternum = 32;
++      adapter->dmxdev.filternum = N_PID_SLOTS;
+       adapter->dmxdev.demux = &dvbdemux->dmx;
+       adapter->dmxdev.capabilities = 0;
+@@ -2475,13 +2332,13 @@ static void skystar2_remove(struct pci_d
+                       dvb_unregister_adapter(adapter->dvb_adapter);
+               }
+-
+-              DriverHalt(pdev);
++              driver_halt(pdev);
+       }
+ }
+ static struct pci_device_id skystar2_pci_tbl[] = {
+-      {0x000013D0, 0x00002103, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000},
++      {0x000013d0, 0x00002103, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000},
++      {0x000013d0, 0x00002200, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000},   //FCIII
+       {0,},
+ };
+@@ -2505,5 +2362,10 @@ static void skystar2_cleanup(void)
+ module_init(skystar2_init);
+ module_exit(skystar2_cleanup);
++MODULE_PARM(debug, "i");
++MODULE_PARM_DESC(debug, "enable verbose debug messages: supported values: 1 and 2");
++MODULE_PARM(enable_hw_filters, "i");
++MODULE_PARM_DESC(enable_hw_filters, "enable hardware filters: supported values: 0 (none), 1, 2");
++
+ MODULE_DESCRIPTION("Technisat SkyStar2 DVB PCI Driver");
+ MODULE_LICENSE("GPL");
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/media/dvb/bt8xx/bt878.c 2003-12-28 23:22:40.000000000 -0800
+@@ -0,0 +1,614 @@
++/*
++ * bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card
++ *
++ * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
++ *
++ * large parts based on the bttv driver
++ * Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
++ *                        & Marcus Metzler (mocm@thp.uni-koeln.de)
++ * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * 
++
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ * 
++
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
++ * 
++ */
++
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <asm/io.h>
++#include <linux/ioport.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++#include <linux/types.h>
++#include <linux/interrupt.h>
++#include <linux/kmod.h>
++#include <linux/vmalloc.h>
++#include <linux/init.h>
++
++#include "dmxdev.h"
++#include "dvbdev.h"
++#include "bt878.h"
++#include "dst-bt878.h"
++
++#include "dvb_functions.h"
++
++/**************************************/
++/* Miscellaneous utility  definitions */
++/**************************************/
++
++unsigned int bt878_verbose = 1;
++unsigned int bt878_debug = 0;
++MODULE_PARM(bt878_verbose, "i");
++MODULE_PARM_DESC(bt878_verbose,
++               "verbose startup messages, default is 1 (yes)");
++MODULE_PARM(bt878_debug, "i");
++MODULE_PARM_DESC(bt878_debug, "debug messages, default is 0 (no)");
++MODULE_LICENSE("GPL");
++
++int bt878_num;
++struct bt878 bt878[BT878_MAX];
++
++EXPORT_SYMBOL(bt878_debug);
++EXPORT_SYMBOL(bt878_verbose);
++EXPORT_SYMBOL(bt878_num);
++EXPORT_SYMBOL(bt878);
++
++#define btwrite(dat,adr)    bmtwrite((dat), (bt->bt878_mem+(adr)))
++#define btread(adr)         bmtread(bt->bt878_mem+(adr))
++
++#define btand(dat,adr)      btwrite((dat) & btread(adr), adr)
++#define btor(dat,adr)       btwrite((dat) | btread(adr), adr)
++#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
++
++#if defined(dprintk)
++#undef dprintk
++#endif
++#define dprintk if(bt878_debug) printk
++
++static void bt878_mem_free(struct bt878 *bt)
++{
++      if (bt->buf_cpu) {
++              pci_free_consistent(bt->dev, bt->buf_size, bt->buf_cpu,
++                                  bt->buf_dma);
++              bt->buf_cpu = NULL;
++      }
++
++      if (bt->risc_cpu) {
++              pci_free_consistent(bt->dev, bt->risc_size, bt->risc_cpu,
++                                  bt->risc_dma);
++              bt->risc_cpu = NULL;
++      }
++}
++
++static int bt878_mem_alloc(struct bt878 *bt)
++{
++      if (!bt->buf_cpu) {
++              bt->buf_size = 128 * 1024;
++
++              bt->buf_cpu =
++                  pci_alloc_consistent(bt->dev, bt->buf_size,
++                                       &bt->buf_dma);
++
++              if (!bt->buf_cpu)
++                      return -ENOMEM;
++
++              memset(bt->buf_cpu, 0, bt->buf_size);
++      }
++
++      if (!bt->risc_cpu) {
++              bt->risc_size = PAGE_SIZE;
++              bt->risc_cpu =
++                  pci_alloc_consistent(bt->dev, bt->risc_size,
++                                       &bt->risc_dma);
++
++              if (!bt->risc_cpu) {
++                      bt878_mem_free(bt);
++                      return -ENOMEM;
++              }
++
++              memset(bt->risc_cpu, 0, bt->risc_size);
++      }
++
++      return 0;
++}
++
++/* RISC instructions */
++#define RISC_WRITE            (0x01 << 28)
++#define RISC_JUMP             (0x07 << 28)
++#define RISC_SYNC             (0x08 << 28)
++
++/* RISC bits */
++#define RISC_WR_SOL           (1 << 27)
++#define RISC_WR_EOL           (1 << 26)
++#define RISC_IRQ              (1 << 24)
++#define RISC_STATUS(status)   ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16))
++#define RISC_SYNC_RESYNC      (1 << 15)
++#define RISC_SYNC_FM1         0x06
++#define RISC_SYNC_VRO         0x0C
++
++#define RISC_FLUSH()          bt->risc_pos = 0
++#define RISC_INSTR(instr)     bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr)
++
++static int bt878_make_risc(struct bt878 *bt)
++{
++      bt->block_bytes = bt->buf_size >> 4;
++      bt->block_count = 1 << 4;
++      bt->line_bytes = bt->block_bytes;
++      bt->line_count = bt->block_count;
++
++      while (bt->line_bytes > 4095) {
++              bt->line_bytes >>= 1;
++              bt->line_count <<= 1;
++      }
++
++      if (bt->line_count > 255) {
++              printk("bt878: buffer size error!\n");
++              return -EINVAL;
++      }
++      return 0;
++}
++
++
++static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin)
++{
++      u32 buf_pos = 0;
++      u32 line;
++
++      RISC_FLUSH();
++      RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin);
++      RISC_INSTR(0);
++
++      dprintk("bt878: risc len lines %u, bytes per line %u\n", 
++                      bt->line_count, bt->line_bytes);
++      for (line = 0; line < bt->line_count; line++) {
++              // At the beginning of every block we issue an IRQ with previous (finished) block number set
++              if (!(buf_pos % bt->block_bytes))
++                      RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
++                                 RISC_IRQ |
++                                 RISC_STATUS(((buf_pos /
++                                               bt->block_bytes) +
++                                              (bt->block_count -
++                                               1)) %
++                                             bt->block_count) | bt->
++                                 line_bytes);
++              else
++                      RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL |
++                                 bt->line_bytes);
++              RISC_INSTR(bt->buf_dma + buf_pos);
++              buf_pos += bt->line_bytes;
++      }
++
++      RISC_INSTR(RISC_SYNC | op_sync_orin | RISC_SYNC_VRO);
++      RISC_INSTR(0);
++
++      RISC_INSTR(RISC_JUMP);
++      RISC_INSTR(bt->risc_dma);
++
++      btwrite((bt->line_count << 16) | bt->line_bytes, BT878_APACK_LEN);
++}
++
++/*****************************/
++/* Start/Stop grabbing funcs */
++/*****************************/
++
++void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
++              u32 irq_err_ignore)
++{
++      u32 int_mask;
++
++      dprintk("bt878 debug: bt878_start (ctl=%8.8x)\n", controlreg);
++      /* complete the writing of the risc dma program now we have
++       * the card specifics
++       */
++      bt878_risc_program(bt, op_sync_orin);
++      controlreg &= ~0x1f;
++      controlreg |= 0x1b;
++
++      btwrite(cpu_to_le32(bt->risc_dma), BT878_ARISC_START);
++
++      /* original int mask had :
++       *    6    2    8    4    0
++       * 1111 1111 1000 0000 0000
++       * SCERR|OCERR|PABORT|RIPERR|FDSR|FTRGT|FBUS|RISCI
++       * Hacked for DST to:
++       * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI
++       */
++      int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT | 
++              BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT | 
++              BT878_AFBUS | BT878_ARISCI;
++
++
++      /* ignore pesky bits */
++      int_mask &= ~irq_err_ignore;
++      
++      btwrite(int_mask, BT878_AINT_MASK);
++      btwrite(controlreg, BT878_AGPIO_DMA_CTL);
++}
++
++void bt878_stop(struct bt878 *bt)
++{
++      u32 stat;
++      int i = 0;
++
++      dprintk("bt878 debug: bt878_stop\n");
++
++      btwrite(0, BT878_AINT_MASK);
++      btand(~0x13, BT878_AGPIO_DMA_CTL);
++
++      do {
++              stat = btread(BT878_AINT_STAT);
++              if (!(stat & BT878_ARISC_EN))
++                      break;
++              i++;
++      } while (i < 500);
++
++      dprintk("bt878(%d) debug: bt878_stop, i=%d, stat=0x%8.8x\n",
++              bt->nr, i, stat);
++}
++
++EXPORT_SYMBOL(bt878_start);
++EXPORT_SYMBOL(bt878_stop);
++
++/*****************************/
++/* Interrupt service routine */
++/*****************************/
++
++static irqreturn_t bt878_irq(int irq, void *dev_id, struct pt_regs *regs)
++{
++      u32 stat, astat, mask;
++      int count;
++      struct bt878 *bt;
++
++      bt = (struct bt878 *) dev_id;
++
++      count = 0;
++      while (1) {
++              stat = btread(BT878_AINT_STAT);
++              mask = btread(BT878_AINT_MASK);
++              if (!(astat = (stat & mask)))
++                      return IRQ_NONE;        /* this interrupt is not for me */
++/*            dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */
++              btwrite(astat, BT878_AINT_STAT);        /* try to clear interupt condition */
++
++
++              if (astat & (BT878_ASCERR | BT878_AOCERR)) {
++                      if (bt878_verbose) {
++                              printk("bt878(%d): irq%s%s risc_pc=%08x\n",
++                                     bt->nr,
++                                     (astat & BT878_ASCERR) ? " SCERR" :
++                                     "",
++                                     (astat & BT878_AOCERR) ? " OCERR" :
++                                     "", btread(BT878_ARISC_PC));
++                      }
++              }
++              if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) {
++                      if (bt878_verbose) {
++                              printk
++                                  ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
++                                   bt->nr,
++                                   (astat & BT878_APABORT) ? " PABORT" :
++                                   "",
++                                   (astat & BT878_ARIPERR) ? " RIPERR" :
++                                   "",
++                                   (astat & BT878_APPERR) ? " PPERR" :
++                                   "", btread(BT878_ARISC_PC));
++                      }
++              }
++              if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) {
++                      if (bt878_verbose) {
++                              printk
++                                  ("bt878(%d): irq%s%s%s risc_pc=%08x\n",
++                                   bt->nr,
++                                   (astat & BT878_AFDSR) ? " FDSR" : "",
++                                   (astat & BT878_AFTRGT) ? " FTRGT" :
++                                   "",
++                                   (astat & BT878_AFBUS) ? " FBUS" : "",
++                                   btread(BT878_ARISC_PC));
++                      }
++              }
++              if (astat & BT878_ARISCI) {
++                      bt->finished_block = (stat & BT878_ARISCS) >> 28;
++                      tasklet_schedule(&bt->tasklet);
++                      break;
++              }
++              count++;
++              if (count > 20) {
++                      btwrite(0, BT878_AINT_MASK);
++                      printk(KERN_ERR
++                             "bt878(%d): IRQ lockup, cleared int mask\n",
++                             bt->nr);
++                      break;
++              }
++      }
++      return IRQ_HANDLED;
++}
++
++extern int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data);
++extern int bttv_read_gpio(unsigned int card, unsigned long *data);
++extern int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data);
++
++int
++bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp)
++{
++      int retval;
++
++      retval = 0;
++      if (down_interruptible (&bt->gpio_lock))
++              return -ERESTARTSYS;
++      /* special gpio signal */
++      switch (cmd) {
++          case DST_IG_ENABLE:
++              // dprintk("dvb_bt8xx: dst enable mask 0x%02x enb 0x%02x \n", mp->dstg.enb.mask, mp->dstg.enb.enable);
++              retval = bttv_gpio_enable(bt->bttv_nr,
++                              mp->enb.mask,
++                              mp->enb.enable);
++              break;
++          case DST_IG_WRITE:
++              // dprintk("dvb_bt8xx: dst write gpio mask 0x%02x out 0x%02x\n", mp->dstg.outp.mask, mp->dstg.outp.highvals);
++              retval = bttv_write_gpio(bt->bttv_nr,
++                              mp->outp.mask,
++                              mp->outp.highvals);
++
++              break;
++          case DST_IG_READ:
++              /* read */
++              retval =  bttv_read_gpio(bt->bttv_nr, &mp->rd.value);
++              // dprintk("dvb_bt8xx: dst read gpio 0x%02x\n", (unsigned)mp->dstg.rd.value);
++              break;
++          case DST_IG_TS:
++              /* Set packet size */
++              bt->TS_Size = mp->psize;
++              break;
++
++          default:
++              retval = -EINVAL;
++              break;
++      }
++      up(&bt->gpio_lock);
++      return retval;
++}
++
++EXPORT_SYMBOL(bt878_device_control);
++
++struct bt878 *bt878_find_by_dvb_adap(struct dvb_adapter *adap)
++{
++      unsigned int card_nr;
++      
++      printk("bt878 find by dvb adap: checking \"%s\"\n",adap->name);
++      for (card_nr = 0; card_nr < bt878_num; card_nr++) {
++              if (bt878[card_nr].adap_ptr == adap)
++                      return &bt878[card_nr];
++      }
++      printk("bt878 find by dvb adap: NOT found \"%s\"\n",adap->name);
++      return NULL;
++}
++
++EXPORT_SYMBOL(bt878_find_by_dvb_adap);
++
++/***********************/
++/* PCI device handling */
++/***********************/
++
++static int __devinit bt878_probe(struct pci_dev *dev,
++                               const struct pci_device_id *pci_id)
++{
++      int result;
++      unsigned char lat;
++      struct bt878 *bt;
++#if defined(__powerpc__)
++      unsigned int cmd;
++#endif
++
++      printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
++             bt878_num);
++
++      bt = &bt878[bt878_num];
++      bt->dev = dev;
++      bt->nr = bt878_num;
++      bt->shutdown = 0;
++
++      bt->id = dev->device;
++      bt->irq = dev->irq;
++      bt->bt878_adr = pci_resource_start(dev, 0);
++      if (pci_enable_device(dev))
++              return -EIO;
++      if (!request_mem_region(pci_resource_start(dev, 0),
++                              pci_resource_len(dev, 0), "bt878")) {
++              return -EBUSY;
++      }
++
++      pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision);
++      pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
++      printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ",
++             bt878_num, bt->id, bt->revision, dev->bus->number,
++             PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
++      printk("irq: %d, latency: %d, memory: 0x%lx\n",
++             bt->irq, lat, bt->bt878_adr);
++
++
++#if defined(__powerpc__)
++      /* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
++      /* response on cards with no firmware is not enabled by OF */
++      pci_read_config_dword(dev, PCI_COMMAND, &cmd);
++      cmd = (cmd | PCI_COMMAND_MEMORY);
++      pci_write_config_dword(dev, PCI_COMMAND, cmd);
++#endif
++
++#ifdef __sparc__
++      bt->bt878_mem = (unsigned char *) bt->bt878_adr;
++#else
++      bt->bt878_mem = ioremap(bt->bt878_adr, 0x1000);
++#endif
++
++      /* clear interrupt mask */
++      btwrite(0, BT848_INT_MASK);
++
++      result = request_irq(bt->irq, bt878_irq,
++                           SA_SHIRQ | SA_INTERRUPT, "bt878",
++                           (void *) bt);
++      if (result == -EINVAL) {
++              printk(KERN_ERR "bt878(%d): Bad irq number or handler\n",
++                     bt878_num);
++              goto fail1;
++      }
++      if (result == -EBUSY) {
++              printk(KERN_ERR
++                     "bt878(%d): IRQ %d busy, change your PnP config in BIOS\n",
++                     bt878_num, bt->irq);
++              goto fail1;
++      }
++      if (result < 0)
++              goto fail1;
++
++      pci_set_master(dev);
++      pci_set_drvdata(dev, bt);
++
++/*        if(init_bt878(btv) < 0) {
++                bt878_remove(dev);
++                return -EIO;
++        }
++*/
++
++      if ((result = bt878_mem_alloc(bt))) {
++              printk("bt878: failed to allocate memory!\n");
++              goto fail2;
++      }
++
++      bt878_make_risc(bt);
++      btwrite(0, BT878_AINT_MASK);
++      bt878_num++;
++
++      return 0;
++
++      fail2:
++      free_irq(bt->irq, bt);
++      fail1:
++      release_mem_region(pci_resource_start(bt->dev, 0),
++                         pci_resource_len(bt->dev, 0));
++      return result;
++}
++
++static void __devexit bt878_remove(struct pci_dev *pci_dev)
++{
++      u8 command;
++      struct bt878 *bt = pci_get_drvdata(pci_dev);
++
++      if (bt878_verbose)
++              printk("bt878(%d): unloading\n", bt->nr);
++
++      /* turn off all capturing, DMA and IRQs */
++      btand(~13, BT878_AGPIO_DMA_CTL);
++
++      /* first disable interrupts before unmapping the memory! */
++      btwrite(0, BT878_AINT_MASK);
++      btwrite(~0x0UL, BT878_AINT_STAT);
++
++      /* disable PCI bus-mastering */
++      pci_read_config_byte(bt->dev, PCI_COMMAND, &command);
++      /* Should this be &=~ ?? */
++      command &= ~PCI_COMMAND_MASTER;
++      pci_write_config_byte(bt->dev, PCI_COMMAND, command);
++
++      free_irq(bt->irq, bt);
++      printk(KERN_DEBUG "bt878_mem: 0x%p.\n", bt->bt878_mem);
++      if (bt->bt878_mem)
++              iounmap(bt->bt878_mem);
++
++      release_mem_region(pci_resource_start(bt->dev, 0),
++                         pci_resource_len(bt->dev, 0));
++      /* wake up any waiting processes
++         because shutdown flag is set, no new processes (in this queue)
++         are expected
++       */
++      bt->shutdown = 1;
++      bt878_mem_free(bt);
++
++      pci_set_drvdata(pci_dev, NULL);
++      return;
++}
++
++static struct pci_device_id bt878_pci_tbl[] __devinitdata = {
++      {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BROOKTREE_878,
++       PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {0,}
++};
++
++MODULE_DEVICE_TABLE(pci, bt878_pci_tbl);
++
++static struct pci_driver bt878_pci_driver = {
++      .name   = "bt878",
++      .id_table = bt878_pci_tbl,
++      .probe  = bt878_probe,
++      .remove         = bt878_remove,
++};
++
++static int bt878_pci_driver_registered = 0;
++
++/* This will be used later by dvb-bt8xx to only use the audio
++ * dma of certain cards */
++int bt878_find_audio_dma(void)
++{
++      // pci_register_driver(&bt878_pci_driver);
++      bt878_pci_driver_registered = 1;
++      return 0;
++}
++
++EXPORT_SYMBOL(bt878_find_audio_dma);
++
++/*******************************/
++/* Module management functions */
++/*******************************/
++
++int bt878_init_module(void)
++{
++      bt878_num = 0;
++      bt878_pci_driver_registered = 0;
++
++      printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n",
++             (BT878_VERSION_CODE >> 16) & 0xff,
++             (BT878_VERSION_CODE >> 8) & 0xff,
++             BT878_VERSION_CODE & 0xff);
++/*
++        bt878_check_chipset();
++*/
++      /* later we register inside of bt878_find_audio_dma
++       * because we may want to ignore certain cards */
++      bt878_pci_driver_registered = 1;
++      return pci_module_init(&bt878_pci_driver);
++}
++
++void bt878_cleanup_module(void)
++{
++      if (bt878_pci_driver_registered) {
++              bt878_pci_driver_registered = 0;
++              pci_unregister_driver(&bt878_pci_driver);
++      }
++      return;
++}
++
++EXPORT_SYMBOL(bt878_init_module);
++EXPORT_SYMBOL(bt878_cleanup_module);
++module_init(bt878_init_module);
++module_exit(bt878_cleanup_module);
++
++/*
++ * Local variables:
++ * c-basic-offset: 8
++ * End:
++ */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/media/dvb/bt8xx/bt878.h 2003-12-28 23:22:37.000000000 -0800
+@@ -0,0 +1,145 @@
++/* 
++    bt878.h - Bt878 audio module (register offsets)
++
++    Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++*/
++
++#ifndef _BT878_H_
++#define _BT878_H_
++
++#include <linux/interrupt.h>
++#include <linux/pci.h>
++#include <linux/sched.h>
++#include <linux/spinlock.h>
++#include "bt848.h"
++
++#define BT878_VERSION_CODE 0x000000
++
++#define BT878_AINT_STAT               0x100
++#define BT878_ARISCS          (0xf<<28)
++#define BT878_ARISC_EN                (1<<27)
++#define BT878_ASCERR          (1<<19)
++#define BT878_AOCERR          (1<<18)
++#define BT878_APABORT         (1<<17)
++#define BT878_ARIPERR         (1<<16)
++#define BT878_APPERR          (1<<15)
++#define BT878_AFDSR           (1<<14)
++#define BT878_AFTRGT          (1<<13)
++#define BT878_AFBUS           (1<<12)
++#define BT878_ARISCI          (1<<11)
++#define BT878_AOFLOW          (1<<3)
++
++#define BT878_AINT_MASK               0x104
++
++#define BT878_AGPIO_DMA_CTL   0x10c
++#define BT878_A_GAIN          (0xf<<28)
++#define BT878_A_G2X           (1<<27)
++#define BT878_A_PWRDN         (1<<26)
++#define BT878_A_SEL           (3<<24)
++#define BT878_DA_SCE          (1<<23)
++#define BT878_DA_LRI          (1<<22)
++#define BT878_DA_MLB          (1<<21)
++#define BT878_DA_LRD          (0x1f<<16)
++#define BT878_DA_DPM          (1<<15)
++#define BT878_DA_SBR          (1<<14)
++#define BT878_DA_ES2          (1<<13)
++#define BT878_DA_LMT          (1<<12)
++#define BT878_DA_SDR          (0xf<<8)
++#define BT878_DA_IOM          (3<<6)
++#define BT878_DA_APP          (1<<5)
++#define BT878_ACAP_EN         (1<<4)
++#define BT878_PKTP            (3<<2)
++#define BT878_RISC_EN         (1<<1)
++#define BT878_FIFO_EN         1
++
++#define BT878_APACK_LEN               0x110
++#define BT878_AFP_LEN         (0xff<<16)
++#define BT878_ALP_LEN         0xfff
++
++#define BT878_ARISC_START     0x114
++
++#define BT878_ARISC_PC                0x120
++
++/* BT878 FUNCTION 0 REGISTERS */
++#define BT878_GPIO_DMA_CTL    0x10c
++
++/* Interrupt register */
++#define BT878_INT_STAT                0x100
++#define BT878_INT_MASK                0x104
++#define BT878_I2CRACK         (1<<25)
++#define BT878_I2CDONE         (1<<8)
++
++#define BT878_MAX 4
++
++#define BT878_RISC_SYNC_MASK  (1 << 15)
++
++extern int bt878_num;
++extern struct bt878 bt878[BT878_MAX];
++
++struct bt878 {
++      struct semaphore  gpio_lock;
++      unsigned int nr;
++      unsigned int bttv_nr;
++      struct dvb_adapter *adap_ptr;
++      struct pci_dev *dev;
++      unsigned int id;
++      unsigned int TS_Size;
++      unsigned char revision;
++      unsigned int irq;
++      unsigned long bt878_adr;
++      unsigned char *bt878_mem; /* function 1 */
++
++      volatile u32 finished_block;
++      volatile u32 last_block;
++      u32 block_count;
++      u32 block_bytes;
++      u32 line_bytes;
++      u32 line_count;
++
++      u32 buf_size;
++      u8 *buf_cpu;
++      dma_addr_t buf_dma;
++
++      u32 risc_size;
++      u32 *risc_cpu;
++      dma_addr_t risc_dma;
++      u32 risc_pos;
++
++      struct tasklet_struct tasklet;
++      int shutdown;   
++};
++
++void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
++              u32 irq_err_ignore);
++void bt878_stop(struct bt878 *bt);         
++
++#if defined(__powerpc__)      /* big-endian */
++extern __inline__ void io_st_le32(volatile unsigned *addr, unsigned val)
++{
++      __asm__ __volatile__("stwbrx %1,0,%2":"=m"(*addr):"r"(val),
++                           "r"(addr));
++      __asm__ __volatile__("eieio":::"memory");
++}
++
++#define bmtwrite(dat,adr)  io_st_le32((unsigned *)(adr),(dat))
++#define bmtread(adr)       ld_le32((unsigned *)(adr))
++#else
++#define bmtwrite(dat,adr)  writel((dat), (char *) (adr))
++#define bmtread(adr)       readl(adr)
++#endif
++
++#endif
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/media/dvb/bt8xx/dvb-bt8xx.c     2003-12-28 23:22:40.000000000 -0800
+@@ -0,0 +1,530 @@
++/*
++ * Bt8xx based DVB adapter driver 
++ *
++ * Copyright (C) 2002,2003 Florian Schirmer <schirmer@taytron.net>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++#include <asm/bitops.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++
++#include "dmxdev.h"
++#include "dvbdev.h"
++#include "dvb_demux.h"
++#include "dvb_frontend.h"
++
++#include "dvb-bt8xx.h"
++
++#include "dvb_functions.h"
++
++#include "bt878.h"
++
++/* ID THAT MUST GO INTO i2c ids */
++#ifndef  I2C_DRIVERID_DVB_BT878A
++# define I2C_DRIVERID_DVB_BT878A I2C_DRIVERID_EXP0+10
++#endif
++
++
++#define dprintk if (debug) printk
++
++extern int bttv_get_cardinfo(unsigned int card, int *type, int *cardid);
++extern struct pci_dev* bttv_get_pcidev(unsigned int card);
++
++static LIST_HEAD(card_list);
++static int debug = 0;
++
++static void dvb_bt8xx_task(unsigned long data)
++{
++      struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data;
++
++      //printk("%d ", finished_block);
++
++      while (card->bt->last_block != card->bt->finished_block) {
++              (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)(&card->demux, &card->bt->buf_cpu[card->bt->last_block * card->bt->block_bytes], card->bt->block_bytes);
++              card->bt->last_block = (card->bt->last_block + 1) % card->bt->block_count;
++      }
++}
++
++static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
++{
++      struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
++      struct dvb_bt8xx_card *card = dvbdmx->priv;
++
++      dprintk("dvb_bt8xx: start_feed\n");
++      
++      if (!dvbdmx->dmx.frontend)
++              return -EINVAL;
++
++      if (card->active)
++              return 0;
++              
++      card->active = 1;
++      
++//    bt878_start(card->bt, card->gpio_mode);
++
++      return 0;
++}
++
++static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
++{
++      struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
++      struct dvb_bt8xx_card *card = dvbdmx->priv;
++
++      dprintk("dvb_bt8xx: stop_feed\n");
++      
++      if (!dvbdmx->dmx.frontend)
++              return -EINVAL;
++              
++      if (!card->active)
++              return 0;
++
++//    bt878_stop(card->bt);
++
++      card->active = 0;
++
++      return 0;
++}
++
++static int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num)
++{
++      struct dvb_bt8xx_card *card = i2c->data;
++      int retval;
++
++      if (down_interruptible (&card->bt->gpio_lock))
++              return -ERESTARTSYS;
++
++      retval = i2c_transfer(card->i2c_adapter,
++                            (struct i2c_msg*) msgs,
++                            num);
++
++      up(&card->bt->gpio_lock);
++
++      return retval;
++}
++
++static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev)
++{
++      if ((adev->subsystem_vendor == bdev->subsystem_vendor) &&
++              (adev->subsystem_device == bdev->subsystem_device) &&
++              (adev->bus->number == bdev->bus->number) &&
++              (PCI_SLOT(adev->devfn) == PCI_SLOT(bdev->devfn)))
++              return 1;
++      return 0;
++}
++
++static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
++{
++      unsigned int card_nr;
++      
++      /* Hmm, n squared. Hope n is small */
++      for (card_nr = 0; card_nr < bt878_num; card_nr++) {
++              if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev))
++                      return &bt878[card_nr];
++      }
++      return NULL;
++}
++
++static int __init dvb_bt8xx_card_match(unsigned int bttv_nr, char *card_name, u32 gpio_mode, u32 op_sync_orin, u32 irq_err_ignore)
++{
++      struct dvb_bt8xx_card *card;
++      struct pci_dev* bttv_pci_dev;
++
++      dprintk("dvb_bt8xx: identified card%d as %s\n", bttv_nr, card_name);
++                      
++      if (!(card = kmalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL)))
++              return -ENOMEM;
++
++      memset(card, 0, sizeof(*card));
++      card->bttv_nr = bttv_nr;
++      strncpy(card->card_name, card_name, sizeof(card_name) - 1);
++      
++      if (!(bttv_pci_dev = bttv_get_pcidev(bttv_nr))) {
++              printk("dvb_bt8xx: no pci device for card %d\n", card->bttv_nr);
++              kfree(card);
++              return -EFAULT;
++      }
++
++      if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) {
++              printk("dvb_bt8xx: unable to determine DMA core of card %d\n", card->bttv_nr);
++      
++              kfree(card);
++              return -EFAULT;
++              
++      }
++      init_MUTEX(&card->bt->gpio_lock);
++      card->bt->bttv_nr = bttv_nr;
++      card->gpio_mode = gpio_mode;
++      card->op_sync_orin = op_sync_orin;
++      card->irq_err_ignore = irq_err_ignore;
++      list_add_tail(&card->list, &card_list);
++
++      return 0;
++}
++
++static struct dvb_bt8xx_card *dvb_bt8xx_find_by_i2c_adap(struct i2c_adapter *adap)
++{
++      struct dvb_bt8xx_card *card;
++      struct list_head *item;
++      
++      printk("find by i2c adap: checking \"%s\"\n",adap->name);
++      list_for_each(item, &card_list) {
++              card = list_entry(item, struct dvb_bt8xx_card, list);
++              if (card->i2c_adapter == adap)
++                      return card;
++      }
++      return NULL;
++}
++
++static struct dvb_bt8xx_card *dvb_bt8xx_find_by_pci(struct i2c_adapter *adap)
++{
++      struct dvb_bt8xx_card *card;
++      struct list_head *item;
++      struct device  *dev;
++      struct pci_dev *pci;
++      
++      printk("find by pci: checking \"%s\"\n",adap->name);
++      dev = adap->dev.parent;
++      if (NULL == dev) {
++              /* shoudn't happen with 2.6.0-test7 + newer */
++              printk("attach: Huh? i2c adapter not in sysfs tree?\n");
++              return 0;
++      }
++      pci = to_pci_dev(dev);
++      list_for_each(item, &card_list) {
++              card = list_entry(item, struct dvb_bt8xx_card, list);
++              if (is_pci_slot_eq(pci, card->bt->dev)) {
++                      return card;
++              }
++      }
++      return NULL;
++}
++
++static int dvb_bt8xx_attach(struct i2c_adapter *adap)
++{
++      struct dvb_bt8xx_card *card;
++      
++      printk("attach: checking \"%s\"\n",adap->name);
++
++      /* looking for bt878 cards ... */
++      if (adap->id != (I2C_ALGO_BIT | I2C_HW_B_BT848))
++              return 0;
++      card = dvb_bt8xx_find_by_pci(adap);
++      if (!card)
++              return 0;
++      card->i2c_adapter = adap;
++      printk("attach: \"%s\", to card %d\n",
++             adap->name, card->bttv_nr);
++      try_module_get(adap->owner);
++
++      return 0;
++}
++
++static void dvb_bt8xx_i2c_adap_free(struct i2c_adapter *adap)
++{
++      module_put(adap->owner);
++}
++
++static int dvb_bt8xx_detach(struct i2c_adapter *adap)
++{
++      struct dvb_bt8xx_card *card;
++
++      card = dvb_bt8xx_find_by_i2c_adap(adap);
++      if (!card)
++              return 0;
++
++      /* This should not happen. We have locked the module! */
++      printk("detach: \"%s\", for card %d removed\n",
++             adap->name, card->bttv_nr);
++      return 0;
++}
++
++static struct i2c_driver dvb_bt8xx_driver = {
++      .owner           = THIS_MODULE,
++      .name            = "dvb_bt8xx",
++        .id              = I2C_DRIVERID_DVB_BT878A,
++      .flags           = I2C_DF_NOTIFY,
++        .attach_adapter  = dvb_bt8xx_attach,
++        .detach_adapter  = dvb_bt8xx_detach,
++};
++
++static void __init dvb_bt8xx_get_adaps(void)
++{
++      i2c_add_driver(&dvb_bt8xx_driver);
++}
++
++static void __exit dvb_bt8xx_exit_adaps(void)
++{
++      i2c_del_driver(&dvb_bt8xx_driver);
++}
++
++static int __init dvb_bt8xx_load_card( struct dvb_bt8xx_card *card)
++{
++      int result;
++
++      if (!card->i2c_adapter) {
++              printk("dvb_bt8xx: unable to determine i2c adaptor of card %d, deleting\n", card->bttv_nr);
++
++              return -EFAULT;
++      
++      }
++
++      if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name)) < 0) {
++      
++              printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
++              
++              dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
++              return result;
++              
++      }
++      card->bt->adap_ptr = card->dvb_adapter;
++
++      if (!(dvb_register_i2c_bus(master_xfer, card, card->dvb_adapter, 0))) {
++              printk("dvb_bt8xx: dvb_register_i2c_bus of card%d failed\n", card->bttv_nr);
++
++              dvb_unregister_adapter(card->dvb_adapter);
++              dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
++
++              return -EFAULT;
++      }
++
++      memset(&card->demux, 0, sizeof(struct dvb_demux));
++
++      card->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
++
++      card->demux.priv = card;
++      card->demux.filternum = 256;
++      card->demux.feednum = 256;
++      card->demux.start_feed = dvb_bt8xx_start_feed;
++      card->demux.stop_feed = dvb_bt8xx_stop_feed;
++      card->demux.write_to_decoder = NULL;
++      
++      if ((result = dvb_dmx_init(&card->demux)) < 0) {
++              printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
++
++              dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
++              dvb_unregister_adapter(card->dvb_adapter);
++              dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
++              
++              return result;
++      }
++
++      card->dmxdev.filternum = 256;
++      card->dmxdev.demux = &card->demux.dmx;
++      card->dmxdev.capabilities = 0;
++      
++      if ((result = dvb_dmxdev_init(&card->dmxdev, card->dvb_adapter)) < 0) {
++              printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result);
++
++              dvb_dmx_release(&card->demux);
++              dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
++              dvb_unregister_adapter(card->dvb_adapter);
++              dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
++              
++              return result;
++      }
++
++      card->fe_hw.source = DMX_FRONTEND_0;
++
++      if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw)) < 0) {
++              printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
++
++              dvb_dmxdev_release(&card->dmxdev);
++              dvb_dmx_release(&card->demux);
++              dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
++              dvb_unregister_adapter(card->dvb_adapter);
++              dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
++              
++              return result;
++      }
++      
++      card->fe_mem.source = DMX_MEMORY_FE;
++
++      if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem)) < 0) {
++              printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
++
++              card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
++              dvb_dmxdev_release(&card->dmxdev);
++              dvb_dmx_release(&card->demux);
++              dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
++              dvb_unregister_adapter(card->dvb_adapter);
++              dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
++              
++              return result;
++      }
++
++      if ((result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw)) < 0) {
++              printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result);
++
++              card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
++              card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
++              dvb_dmxdev_release(&card->dmxdev);
++              dvb_dmx_release(&card->demux);
++              dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
++              dvb_unregister_adapter(card->dvb_adapter);
++              dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
++              
++              return result;
++      }
++
++      dvb_net_init(card->dvb_adapter, &card->dvbnet, &card->demux.dmx);
++
++      tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card);
++      
++      bt878_start(card->bt, card->gpio_mode, card->op_sync_orin, card->irq_err_ignore);
++
++      return 0;
++}
++
++static int __init dvb_bt8xx_load_all(void)
++{
++      struct dvb_bt8xx_card *card;
++      struct list_head *entry, *entry_safe;
++
++      list_for_each_safe(entry, entry_safe, &card_list) {
++              card = list_entry(entry, struct dvb_bt8xx_card, list);
++              if (dvb_bt8xx_load_card(card) < 0) {
++                      list_del(&card->list);
++                      kfree(card);
++                      continue;
++              }
++      }
++      return 0;
++
++}
++
++#define BT878_NEBULA  0x68
++#define BT878_TWINHAN_DST 0x71
++
++static int __init dvb_bt8xx_init(void)
++{
++      unsigned int card_nr = 0;
++      int card_id;
++      int card_type;
++
++      dprintk("dvb_bt8xx: enumerating available bttv cards...\n");
++      
++      while (bttv_get_cardinfo(card_nr, &card_type, &card_id) == 0) {
++              switch(card_id) {
++                      case 0x001C11BD:
++                              dvb_bt8xx_card_match(card_nr, "Pinnacle PCTV DVB-S",
++                                             0x0400C060, 0, 0);
++                              /* 26, 15, 14, 6, 5 
++                               * A_G2X  DA_DPM DA_SBR DA_IOM_DA 
++                               * DA_APP(parallel) */
++                              break;
++                      case 0x01010071:
++nebula:
++                              dvb_bt8xx_card_match(card_nr, "Nebula DigiTV DVB-T",
++                                           (1 << 26) | (1 << 14) | (1 << 5),
++                                           0, 0);
++                              /* A_PWRDN DA_SBR DA_APP (high speed serial) */
++                              break;
++                      case 0x07611461:
++                              dvb_bt8xx_card_match(card_nr, "Avermedia DVB-T",
++                                           (1 << 26) | (1 << 14) | (1 << 5),
++                                           0, 0);
++                              /* A_PWRDN DA_SBR DA_APP (high speed serial) */
++                              break;
++                      case 0x0:
++                              if (card_type == BT878_NEBULA ||
++                                      card_type == BT878_TWINHAN_DST)
++                                      goto dst;
++                              goto unknown_card;
++                      case 0x2611BD:
++                      case 0x11822:
++dst:
++                              dvb_bt8xx_card_match(card_nr, "DST DVB-S", 0x2204f2c,
++                                              BT878_RISC_SYNC_MASK,
++                                              BT878_APABORT | BT878_ARIPERR | BT878_APPERR | BT878_AFBUS);
++                              /* 25,21,14,11,10,9,8,3,2 then
++                               * 0x33 = 5,4,1,0
++                               * A_SEL=SML, DA_MLB, DA_SBR, 
++                               * DA_SDR=f, fifo trigger = 32 DWORDS
++                               * IOM = 0 == audio A/D
++                               * DPM = 0 == digital audio mode
++                               * == async data parallel port
++                               * then 0x33 (13 is set by start_capture)
++                               * DA_APP = async data parallel port, 
++                               * ACAP_EN = 1,
++                               * RISC+FIFO ENABLE */
++                              break;
++                      default:
++unknown_card:
++                              printk("%s: unknown card_id found %0X\n",
++                                      __FUNCTION__, card_id);
++                              if (card_type == BT878_NEBULA) {
++                                      printk("%s: bttv type set to nebula\n",
++                                              __FUNCTION__);
++                                      goto nebula;
++                              }
++                              if (card_type == BT878_TWINHAN_DST) {
++                                      printk("%s: bttv type set to Twinhan DST\n",
++                                              __FUNCTION__);
++                                      goto dst;
++                              }
++                              printk("%s: unknown card_type found %0X, NOT LOADED\n",
++                                      __FUNCTION__, card_type);
++                              printk("%s: unknown card_nr found %0X\n",
++                                      __FUNCTION__, card_nr);
++              }
++              card_nr++;
++      }
++      dvb_bt8xx_get_adaps();
++      dvb_bt8xx_load_all();
++
++      return 0;
++
++}
++
++static void __exit dvb_bt8xx_exit(void)
++{
++      struct dvb_bt8xx_card *card;
++      struct list_head *entry, *entry_safe;
++
++      dvb_bt8xx_exit_adaps();
++      list_for_each_safe(entry, entry_safe, &card_list) {
++              card = list_entry(entry, struct dvb_bt8xx_card, list);
++              
++              dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr);
++
++              bt878_stop(card->bt);
++              tasklet_kill(&card->bt->tasklet);
++              dvb_net_release(&card->dvbnet);
++              card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem);
++              card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw);
++              dvb_dmxdev_release(&card->dmxdev);
++              dvb_dmx_release(&card->demux);
++              dvb_unregister_i2c_bus(master_xfer, card->dvb_adapter, 0);
++              dvb_bt8xx_i2c_adap_free(card->i2c_adapter);
++              dvb_unregister_adapter(card->dvb_adapter);
++              
++              list_del(&card->list);
++              kfree(card);
++      }
++
++}
++
++module_init(dvb_bt8xx_init);
++module_exit(dvb_bt8xx_exit);
++MODULE_DESCRIPTION("Bt8xx based DVB adapter driver");
++MODULE_AUTHOR("Florian Schirmer <schirmer@taytron.net>");
++MODULE_LICENSE("GPL");
++MODULE_PARM(debug, "i");
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/media/dvb/bt8xx/dvb-bt8xx.h     2003-12-28 23:22:37.000000000 -0800
+@@ -0,0 +1,47 @@
++/*
++ * Bt8xx based DVB adapter driver 
++ *
++ * Copyright (C) 2002,2003 Florian Schirmer <schirmer@taytron.net>
++ * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de>
++ * Copyright (C) 1999-2001 Ralph  Metzler & Marcus Metzler for convergence integrated media GmbH
++ * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++#include <linux/i2c.h>
++#include "dvbdev.h"
++#include "dvb_net.h"
++
++struct dvb_bt8xx_card {
++
++      struct list_head list;
++      u8 active;
++      char card_name[32];
++      struct dvb_adapter *dvb_adapter;
++      struct bt878 *bt;
++      unsigned int bttv_nr;
++      struct dvb_demux demux;
++      struct dmxdev dmxdev;
++      struct dmx_frontend fe_hw;
++      struct dmx_frontend fe_mem;
++      u32 gpio_mode;
++      u32 op_sync_orin;
++      u32 irq_err_ignore;
++      struct i2c_adapter *i2c_adapter;
++      struct dvb_net dvbnet;
++                              
++};
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/media/dvb/bt8xx/Kconfig 2003-12-28 23:22:37.000000000 -0800
+@@ -0,0 +1,13 @@
++config DVB_BT8XX
++      tristate "Nebula/Pinnacle PCTV PCI cards"
++      depends on DVB_CORE && PCI && VIDEO_BT848
++      help
++        Support for PCI cards based on the Bt8xx PCI bridge. Examples are
++        the Nebula cards, the Pinnacle PCTV cards, and Twinhan DST cards.
++
++          Since these cards have no MPEG decoder onboard, they transmit
++        only compressed MPEG data over the PCI bus, so you need
++        an external software decoder to watch TV on your computer.
++
++        Say Y if you own such a device and want to use it.
++
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/media/dvb/bt8xx/Makefile        2003-12-28 23:22:40.000000000 -0800
+@@ -0,0 +1,5 @@
++
++obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o
++
++EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends
++
+--- linux-2.6.0/drivers/media/dvb/dvb-core/demux.h     2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/demux.h      2003-12-28 23:22:38.000000000 -0800
+@@ -44,6 +44,15 @@
+ #endif 
+ /*
++ * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
++ */ 
++
++#ifndef DMX_MAX_SECFEED_SIZE 
++#define DMX_MAX_SECFEED_SIZE 4096
++#endif 
++
++
++/*
+  * enum dmx_success: Success codes for the Demux Callback API. 
+  */ 
+@@ -143,9 +152,9 @@ struct dmx_section_feed { 
+         int check_crc;
+       u32 crc_val;
+-        u8 secbuf[4096];
+-        int secbufp;
+-        int seclen;
++        u8 *secbuf;
++        u8 secbuf_base[DMX_MAX_SECFEED_SIZE];
++        u16 secbufp, seclen, tsfeedp;
+         int (*set) (struct dmx_section_feed* feed, 
+                   u16 pid, 
+--- linux-2.6.0/drivers/media/dvb/dvb-core/dvb_demux.c 2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/dvb_demux.c  2003-12-28 23:22:38.000000000 -0800
+@@ -34,6 +34,11 @@
+ #include "dvb_functions.h"
+ #define NOBUFS  
++/* 
++** #define DVB_DEMUX_SECTION_LOSS_LOG to monitor payload loss in the syslog
++*/
++// #define DVB_DEMUX_SECTION_LOSS_LOG
++
+ LIST_HEAD(dmx_muxs);
+@@ -87,7 +92,7 @@ static inline u16 ts_pid(const u8 *buf)
+ }
+-static inline int payload(const u8 *tsp)
++static inline u8 payload(const u8 *tsp)
+ {
+       if (!(tsp[3]&0x10)) // no payload?
+               return 0;
+@@ -188,9 +193,7 @@ static inline int dvb_dmx_swfilter_secti
+       struct dvb_demux_filter *f = feed->filter;
+       struct dmx_section_feed *sec = &feed->feed.sec;
+       u8 *buf = sec->secbuf;
+-
+-      if (sec->secbufp != sec->seclen)
+-              return -1;
++      int section_syntax_indicator;
+       if (!sec->is_filtering)
+               return 0;
+@@ -198,15 +201,19 @@ static inline int dvb_dmx_swfilter_secti
+       if (!f)
+               return 0;
+-      if (sec->check_crc && demux->check_crc32(feed, sec->secbuf, sec->seclen))
++      if (sec->check_crc) {
++              section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0);
++              if (section_syntax_indicator &&
++                  demux->check_crc32(feed, sec->secbuf, sec->seclen))
+               return -1;
++      }
+       do {
+               if (dvb_dmx_swfilter_sectionfilter(feed, f) < 0)
+                       return -1;
+       } while ((f = f->next) && sec->is_filtering);
+-      sec->secbufp = sec->seclen = 0;
++      sec->seclen = 0;
+       memset(buf, 0, DVB_DEMUX_MASK_MAX);
+  
+@@ -214,128 +221,147 @@ static inline int dvb_dmx_swfilter_secti
+ }
+-static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf) 
++static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
+ {
+-      struct dvb_demux *demux = feed->demux;
+       struct dmx_section_feed *sec = &feed->feed.sec;
+-      int p, count;
+-      int ccok, rest;
+-      u8 cc;
+-
+-      if (!(count = payload(buf)))
+-              return -1;
+-
+-      p = 188-count;
+-
+-      cc = buf[3] & 0x0f;
+-      ccok = ((feed->cc+1) & 0x0f) == cc ? 1 : 0;
+-      feed->cc = cc;
+-
+-      if (buf[1] & 0x40) { // PUSI set
+-              // offset to start of first section is in buf[p] 
+-              if (p+buf[p]>187) // trash if it points beyond packet
+-                      return -1;
+-
+-              if (buf[p] && ccok) { // rest of previous section?
+-                      // did we have enough data in last packet to calc length?
+-                      int tmp = 3 - sec->secbufp;
+-                      if (tmp > 0 && tmp != 3) {
+-                              if (p + tmp >= 187)
+-                                      return -1;
+-
+-                              demux->memcopy (feed, sec->secbuf+sec->secbufp,
+-                                             buf+p+1, tmp);
+-
+-                              sec->seclen = section_length(sec->secbuf);
+-
+-                              if (sec->seclen > 4096) 
+-                                      return -1;
++#ifdef DVB_DEMUX_SECTION_LOSS_LOG
++      if(sec->secbufp < sec->tsfeedp)
++      {
++              int i, n = sec->tsfeedp - sec->secbufp;
++
++              /* section padding is done with 0xff bytes entirely.
++              ** due to speed reasons, we won't check all of them
++              ** but just first and last
++              */
++              if(sec->secbuf[0] != 0xff || sec->secbuf[n-1] != 0xff)
++              {
++                      printk("dvb_demux.c section ts padding loss: %d/%d\n", 
++                             n, sec->tsfeedp);
++                      printk("dvb_demux.c pad data:");
++                      for(i = 0; i < n; i++)
++                              printk(" %02x", sec->secbuf[i]);
++                      printk("\n");
+                       }
+-
+-                      rest = sec->seclen - sec->secbufp;
+-
+-                      if (rest == buf[p] && sec->seclen) {
+-                              demux->memcopy (feed, sec->secbuf + sec->secbufp,
+-                                             buf+p+1, buf[p]);
+-                              sec->secbufp += buf[p];
+-                              dvb_dmx_swfilter_section_feed(feed);
+                       }
+-              }
+-
+-              p += buf[p] + 1;                // skip rest of last section
+-              count = 188 - p;
++#endif
+-              while (count) {
++      sec->tsfeedp = sec->secbufp = sec->seclen = 0;
++      sec->secbuf = sec->secbuf_base;
++              }
+-                      sec->crc_val = ~0;
++/* 
++** Losless Section Demux 1.4 by Emard
++*/
++static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, const u8 *buf, u8 len)
++{
++      struct dvb_demux *demux = feed->demux;
++      struct dmx_section_feed *sec = &feed->feed.sec;
++      u16 limit, seclen, n;
+-                      if ((count>2) && // enough data to determine sec length?
+-                          ((sec->seclen = section_length(buf+p)) <= count)) {
+-                              if (sec->seclen>4096) 
+-                                      return -1;
++      if(sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
++              return 0;
+-                              demux->memcopy (feed, sec->secbuf, buf+p,
+-                                             sec->seclen);
++      if(sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE)
++      {
++#ifdef DVB_DEMUX_SECTION_LOSS_LOG
++              printk("dvb_demux.c section buffer full loss: %d/%d\n", 
++                     sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, DMX_MAX_SECFEED_SIZE);
++#endif
++              len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
++      }
+-                              sec->secbufp = sec->seclen;
+-                              p += sec->seclen;
+-                              count = 188 - p;
++      if(len <= 0)
++              return 0;
+-                              dvb_dmx_swfilter_section_feed(feed);
++      demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len);
++      sec->tsfeedp += len;
+-                              // filling bytes until packet end?
+-                              if (count && buf[p]==0xff) 
+-                                      count=0;
++      /* -----------------------------------------------------
++      ** Dump all the sections we can find in the data (Emard)
++      */
+-                      } else { // section continues to following TS packet
+-                              demux->memcopy(feed, sec->secbuf, buf+p, count);
+-                              sec->secbufp+=count;
+-                              count=0;
+-                      }
++      limit = sec->tsfeedp;
++      if(limit > DMX_MAX_SECFEED_SIZE)
++              return -1; /* internal error should never happen */
++
++      /* to be sure always set secbuf */
++      sec->secbuf = sec->secbuf_base + sec->secbufp;
++
++      for(n = 0; sec->secbufp + 2 < limit; n++)
++      {
++              seclen = section_length(sec->secbuf);
++              if(seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE 
++                 || seclen + sec->secbufp > limit)
++                      return 0;
++              sec->seclen = seclen;
++              sec->crc_val = ~0;
++              /* dump [secbuf .. secbuf+seclen) */
++              dvb_dmx_swfilter_section_feed(feed);
++              sec->secbufp += seclen; /* secbufp and secbuf moving together is */
++              sec->secbuf += seclen; /* redundand but saves pointer arithmetic */
+               }
+               return 0;
+       }
+-      // section continued below
+-      if (!ccok)
+-              return -1;
+-      if (!sec->secbufp) // any data in last ts packet?
+-              return -1;
++static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf) 
++{
++      u8 p, count;
++      int ccok;
++      u8 cc;
+-      // did we have enough data in last packet to calc section length?
+-      if (sec->secbufp < 3) {
+-              int tmp = 3 - sec->secbufp;
++      count = payload(buf);
+               
+-              if (tmp>count)
++      if (count == 0)  /* count == 0 if no payload or out of range */
+                       return -1;
+-              sec->crc_val = ~0;
+-
+-              demux->memcopy (feed, sec->secbuf + sec->secbufp, buf+p, tmp);
++      p = 188-count; /* payload start */
+-              sec->seclen = section_length(sec->secbuf);
+-
+-              if (sec->seclen > 4096) 
+-                      return -1;
++      cc = buf[3] & 0x0f;
++      ccok = ((feed->cc+1) & 0x0f) == cc ? 1 : 0;
++      feed->cc = cc;
++      if(ccok == 0)
++      {
++#ifdef DVB_DEMUX_SECTION_LOSS_LOG
++              printk("dvb_demux.c discontinuity detected %d bytes lost\n", count);
++              /* those bytes under sume circumstances will again be reported
++              ** in the following dvb_dmx_swfilter_section_new
++              */
++#endif
++              dvb_dmx_swfilter_section_new(feed);
++              return 0;
+       }
+-      rest = sec->seclen - sec->secbufp;
+-
+-      if (rest < 0)
+-              return -1;
+-
+-      if (rest <= count) {    // section completed in this TS packet
+-              demux->memcopy (feed, sec->secbuf + sec->secbufp, buf+p, rest);
+-              sec->secbufp += rest;
+-              dvb_dmx_swfilter_section_feed(feed);
+-      } else  {       // section continues in following ts packet
+-              demux->memcopy (feed, sec->secbuf + sec->secbufp, buf+p, count);
+-              sec->secbufp += count;
++      if(buf[1] & 0x40)
++      {
++              // PUSI=1 (is set), section boundary is here
++              if(count > 1 && buf[p] < count)
++              {
++                      const u8 *before = buf+p+1;
++                      u8 before_len = buf[p];
++                      const u8 *after = before+before_len;
++                      u8 after_len = count-1-before_len;
++
++                      dvb_dmx_swfilter_section_copy_dump(feed, before, before_len);
++                      dvb_dmx_swfilter_section_new(feed);
++                      dvb_dmx_swfilter_section_copy_dump(feed, after, after_len);
++              }
++#ifdef DVB_DEMUX_SECTION_LOSS_LOG
++              else
++                      if(count > 0)
++                              printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count);
++#endif
+       }
++      else
++      {
++              // PUSI=0 (is not set), no section boundary
++              const u8 *entire = buf+p;
++              u8 entire_len = count;
++              dvb_dmx_swfilter_section_copy_dump(feed, entire, entire_len);
++      }
+       return 0;
+ }
+@@ -439,6 +465,50 @@ bailout:
+       spin_unlock(&demux->lock);
+ }
++void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
++{
++      int p = 0,i, j;
++      u8 tmppack[188];
++      spin_lock(&demux->lock);
++
++      if ((i = demux->tsbufp)) {
++              if (count < (j=204-i)) {
++                      memcpy(&demux->tsbuf[i], buf, count);
++                      demux->tsbufp += count;
++                      goto bailout;
++              }
++              memcpy(&demux->tsbuf[i], buf, j);
++              if ((demux->tsbuf[0] == 0x47)|(demux->tsbuf[0]==0xB8))  {
++                      memcpy(tmppack, demux->tsbuf, 188);
++                      if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
++                      dvb_dmx_swfilter_packet(demux, tmppack);
++              }
++              demux->tsbufp = 0;
++              p += j;
++      }
++
++      while (p < count) {
++              if ((buf[p] == 0x47)|(buf[p] == 0xB8)) {
++                      if (count-p >= 204) {
++                              memcpy(tmppack, buf+p, 188);
++                              if (tmppack[0] == 0xB8) tmppack[0] = 0x47;
++                              dvb_dmx_swfilter_packet(demux, tmppack);
++                              p += 204;
++                      } else {
++                              i = count-p;
++                              memcpy(demux->tsbuf, buf+p, i);
++                              demux->tsbufp=i;
++                              goto bailout;
++                      }
++              } else { 
++                      p++;
++              }
++      }
++
++bailout:
++      spin_unlock(&demux->lock);
++}
++
+ static struct dvb_demux_filter * dvb_dmx_filter_alloc(struct dvb_demux *demux)
+ {
+@@ -848,6 +918,9 @@ static int dmx_section_feed_start_filter
+               up(&dvbdmx->mutex);
+               return -EINVAL;
+       }
++
++      dvbdmxfeed->feed.sec.tsfeedp = 0;
++      dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
+       dvbdmxfeed->feed.sec.secbufp=0;
+       dvbdmxfeed->feed.sec.seclen=0;
+       
+@@ -946,7 +1019,9 @@ static int dvbdmx_allocate_section_feed(
+       dvbdmxfeed->cb.sec=callback;
+       dvbdmxfeed->demux=dvbdmx;
+       dvbdmxfeed->pid=0xffff;
+-      dvbdmxfeed->feed.sec.secbufp=0;
++      dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
++      dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0;
++      dvbdmxfeed->feed.sec.tsfeedp = 0;
+       dvbdmxfeed->filter=0;
+       dvbdmxfeed->buffer=0;
+--- linux-2.6.0/drivers/media/dvb/dvb-core/dvb_demux.h 2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/dvb_demux.h  2003-12-28 23:22:38.000000000 -0800
+@@ -127,7 +127,7 @@ struct dvb_demux {
+ #define DMX_MAX_PID 0x2000
+       struct list_head feed_list;
+-        u8 tsbuf[188];
++        u8 tsbuf[204];
+         int tsbufp;
+       struct semaphore mutex;
+@@ -140,6 +140,7 @@ int dvb_dmx_release(struct dvb_demux *dv
+ void dvb_dmx_swfilter_packet(struct dvb_demux *dvbdmx, const u8 *buf);
+ void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, size_t count);
+ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
++void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count);
+ int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend);
+ int dvbdmx_disconnect_frontend(struct dmx_demux *demux);
+--- linux-2.6.0/drivers/media/dvb/dvb-core/dvb_filter.c        2003-07-02 14:53:14.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/dvb_filter.c 2003-12-28 23:22:38.000000000 -0800
+@@ -564,14 +564,18 @@ void dvb_filter_pes2ts_init(struct dvb_f
+       p2ts->priv=priv;
+ }
+-int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, int len)
++int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
++                    int len, int payload_start)
+ {
+       unsigned char *buf=p2ts->buf;
+       int ret=0, rest;
+       
+       //len=6+((pes[4]<<8)|pes[5]);
++      if (payload_start)
+       buf[1]|=0x40;
++      else
++              buf[1]&=~0x40;
+       while (len>=184) {
+               buf[3]=0x10|((p2ts->cc++)&0x0f);
+               memcpy(buf+4, pes, 184);
+--- linux-2.6.0/drivers/media/dvb/dvb-core/dvb_filter.h        2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/dvb_filter.h 2003-12-28 23:22:38.000000000 -0800
+@@ -37,7 +37,8 @@ struct dvb_filter_pes2ts {
+ void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, 
+                           dvb_filter_pes2ts_cb_t *cb, void *priv);
+-int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, int len);
++int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
++                    int len, int payload_start);
+ #define PROG_STREAM_MAP  0xBC
+--- linux-2.6.0/drivers/media/dvb/dvb-core/dvb_i2c.c   2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/dvb_i2c.c    2003-12-28 23:22:38.000000000 -0800
+@@ -51,6 +51,7 @@ static int register_i2c_client (struct d
+       client->detach = dev->detach;
+       client->owner = dev->owner;
++      client->data = dev->data;
+       INIT_LIST_HEAD(&client->list_head);
+--- linux-2.6.0/drivers/media/dvb/dvb-core/dvb_ksyms.c 2003-07-02 14:53:14.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/dvb_ksyms.c  2003-12-28 23:22:38.000000000 -0800
+@@ -18,6 +18,7 @@ EXPORT_SYMBOL(dvb_dmx_release);
+ EXPORT_SYMBOL(dvb_dmx_swfilter_packet);
+ EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
+ EXPORT_SYMBOL(dvb_dmx_swfilter);
++EXPORT_SYMBOL(dvb_dmx_swfilter_204);
+ EXPORT_SYMBOL(dvbdmx_connect_frontend);
+ EXPORT_SYMBOL(dvbdmx_disconnect_frontend);
+--- linux-2.6.0/drivers/media/dvb/dvb-core/dvb_ringbuffer.c    2003-07-02 14:53:14.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/dvb_ringbuffer.c     2003-12-28 23:22:38.000000000 -0800
+@@ -9,24 +9,18 @@
+  *                       & Marcus Metzler for convergence integrated media GmbH
+  *
+  * 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
++ * modify it under the terms of the GNU Lesser General Public License
++ * as published by the Free Software Foundation; either version 2.1
+  * of the License, or (at your option) any later version.
+  * 
+- *
+  * 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.
+- * 
++ * GNU Lesser General Public License for more details.
+  *
+- * You should have received a copy of the GNU General Public License
++ * You should have received a copy of the GNU Lesser General Public License
+  * along with this program; if not, write to the Free Software
+  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+- * 
+- *
+- * the project's page is at http://www.linuxtv.org/dvb/
+  */
+@@ -167,11 +161,11 @@ ssize_t dvb_ringbuffer_write(struct dvb_
+ }
+-EXPORT_SYMBOL_GPL(dvb_ringbuffer_init);
+-EXPORT_SYMBOL_GPL(dvb_ringbuffer_empty);
+-EXPORT_SYMBOL_GPL(dvb_ringbuffer_free);
+-EXPORT_SYMBOL_GPL(dvb_ringbuffer_avail);
+-EXPORT_SYMBOL_GPL(dvb_ringbuffer_flush);
+-EXPORT_SYMBOL_GPL(dvb_ringbuffer_flush_spinlock_wakeup);
+-EXPORT_SYMBOL_GPL(dvb_ringbuffer_read);
+-EXPORT_SYMBOL_GPL(dvb_ringbuffer_write);
++EXPORT_SYMBOL(dvb_ringbuffer_init);
++EXPORT_SYMBOL(dvb_ringbuffer_empty);
++EXPORT_SYMBOL(dvb_ringbuffer_free);
++EXPORT_SYMBOL(dvb_ringbuffer_avail);
++EXPORT_SYMBOL(dvb_ringbuffer_flush);
++EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
++EXPORT_SYMBOL(dvb_ringbuffer_read);
++EXPORT_SYMBOL(dvb_ringbuffer_write);
+--- linux-2.6.0/drivers/media/dvb/dvb-core/dvb_ringbuffer.h    2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/media/dvb/dvb-core/dvb_ringbuffer.h     2003-12-28 23:22:38.000000000 -0800
+@@ -16,7 +16,7 @@
+  * 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.
++ * GNU Lesser General Public License for more details.
+  * 
+  * You should have received a copy of the GNU Lesser General Public License
+  * along with this program; if not, write to the Free Software
+--- linux-2.6.0/drivers/media/dvb/frontends/alps_tdmb7.c       2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/dvb/frontends/alps_tdmb7.c        2003-12-28 23:22:38.000000000 -0800
+@@ -159,7 +159,7 @@ static int cx22700_init (struct dvb_i2c_
+       cx22700_writereg (i2c, 0x00, 0x02);   /*  soft reset */
+       cx22700_writereg (i2c, 0x00, 0x00);
+-      dvb_delay (HZ/100);
++      dvb_delay(10);
+       
+       for (i=0; i<sizeof(init_tab); i+=2)
+               cx22700_writereg (i2c, init_tab[i], init_tab[i+1]);
+@@ -281,15 +281,15 @@ static int cx22700_get_tps (struct dvb_i
+       val = cx22700_readreg (i2c, 0x02);
+-      if ((val >> 3) > 4)
++      if (((val >> 3) & 0x07) > 4)
+               p->code_rate_HP = FEC_AUTO;
+       else
+-              p->code_rate_HP = fec_tab[val >> 3];
++              p->code_rate_HP = fec_tab[(val >> 3) & 0x07];
+-      if ((val & 0x7) > 4)
++      if ((val & 0x07) > 4)
+               p->code_rate_LP = FEC_AUTO;
+       else
+-              p->code_rate_LP = fec_tab[val >> 3];
++              p->code_rate_LP = fec_tab[val & 0x07];
+       val = cx22700_readreg (i2c, 0x03);
+@@ -333,7 +333,7 @@ static int tdmb7_ioctl (struct dvb_front
+               if (sync & 0x10)
+                       *status |= FE_HAS_SYNC;
+-              if (sync & 0x10)
++              if (*status == 0x0f)
+                       *status |= FE_HAS_LOCK;
+               break;
+--- linux-2.6.0/drivers/media/dvb/frontends/cx24110.c  2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/dvb/frontends/cx24110.c   2003-12-28 23:22:38.000000000 -0800
+@@ -248,7 +248,7 @@ static int cx24108_set_tv_freq (struct d
+         cx24108_write(i2c,pll);
+         cx24110_writereg(i2c,0x56,0x7f);
+-      dvb_delay(HZ/10); /* wait a moment for the tuner pll to lock */
++      dvb_delay(10); /* wait a moment for the tuner pll to lock */
+       /* tuner pll lock can be monitored on GPIO pin 4 of cx24110 */
+         while (!(cx24110_readreg(i2c,0x66)&0x20)&&i<1000)
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/media/dvb/frontends/dst-bt878.h 2003-12-28 23:22:40.000000000 -0800
+@@ -0,0 +1,37 @@
++/*
++ * dst-bt878.h: part of the DST driver for the TwinHan DST Frontend
++ *
++ * Copyright (C) 2003 Jamie Honan
++ */
++
++struct dst_gpio_enable {
++      u32     mask;
++      u32     enable;
++};
++
++struct dst_gpio_output {
++      u32     mask;
++      u32     highvals;
++};
++
++struct dst_gpio_read {
++      unsigned long value;
++};
++
++union dst_gpio_packet {
++      struct dst_gpio_enable enb;
++      struct dst_gpio_output outp;
++      struct dst_gpio_read rd;
++      int    psize;
++};
++
++#define DST_IG_ENABLE 0
++#define DST_IG_WRITE  1
++#define DST_IG_READ   2
++#define DST_IG_TS       3
++
++struct bt878 ;
++
++int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp);
++
++struct bt878 *bt878_find_by_dvb_adap(struct dvb_adapter *adap);
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/media/dvb/frontends/dst.c       2003-12-28 23:22:37.000000000 -0800
+@@ -0,0 +1,1189 @@
++/* 
++    Frontend-driver for TwinHan DST Frontend
++
++    Copyright (C) 2003 Jamie Honan
++
++
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++
++*/    
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <asm/div64.h>
++#include <asm/delay.h>
++
++#include "dvb_frontend.h"
++#include "dvb_functions.h"
++#include "dst-bt878.h"
++
++unsigned int dst_debug = 0;
++unsigned int dst_verbose = 0;
++
++MODULE_PARM(dst_verbose, "i");
++MODULE_PARM_DESC(dst_verbose,
++               "verbose startup messages, default is 1 (yes)");
++MODULE_PARM(dst_debug, "i");
++MODULE_PARM_DESC(dst_debug, "debug messages, default is 0 (no)");
++
++unsigned int dst_type = (-1U);
++unsigned int dst_type_flags = (-1U);
++MODULE_PARM(dst_type, "i");
++MODULE_PARM_DESC(dst_type,
++              "Type of DST card, 0 Satellite, 1 terrestial TV, 2 Cable, default driver determined");
++MODULE_PARM(dst_type_flags, "i");
++MODULE_PARM_DESC(dst_type_flags,
++              "Type flags of DST card, bitfield 1=10 byte tuner, 2=TS is 204, 4=symdiv");
++
++#define dprintk       if (dst_debug) printk
++
++#define DST_TYPE_IS_SAT               0
++#define DST_TYPE_IS_TERR      1
++#define DST_TYPE_IS_CABLE     2
++
++#define DST_TYPE_HAS_NEWTUNE  1
++#define DST_TYPE_HAS_TS204    2
++#define DST_TYPE_HAS_SYMDIV   4
++
++#define HAS_LOCK      1
++#define ATTEMPT_TUNE  2
++#define HAS_POWER     4
++
++struct dst_data {
++      u8      tx_tuna[10];
++      u8      rx_tuna[10];
++      u8      rxbuffer[10];
++      u8      diseq_flags;
++      u8      dst_type;
++      u32     type_flags;
++      u32 frequency;     /* intermediate frequency in kHz for QPSK */
++        fe_spectral_inversion_t inversion;
++        u32   symbol_rate;  /* symbol rate in Symbols per second */
++      fe_code_rate_t  fec;
++      fe_sec_voltage_t voltage;
++      fe_sec_tone_mode_t tone;
++      u32 decode_freq;
++      u8  decode_lock;
++      u16 decode_strength;
++      u16 decode_snr;
++      unsigned long cur_jiff;
++      u8  k22;
++      fe_bandwidth_t bandwidth;
++      struct bt878 *bt;
++      struct dvb_i2c_bus *i2c;
++} ;
++
++static struct dvb_frontend_info dst_info_sat = {
++      .name                   = "DST SAT",
++      .type                   = FE_QPSK,
++      .frequency_min          = 950000,
++      .frequency_max          = 2150000,
++      .frequency_stepsize     = 1000,           /* kHz for QPSK frontends */
++      .frequency_tolerance    = 29500,
++      .symbol_rate_min        = 1000000,
++      .symbol_rate_max        = 45000000,
++/*     . symbol_rate_tolerance        =       ???,*/
++      .notifier_delay         = 50,                /* 1/20 s */
++      .caps = FE_CAN_INVERSION_AUTO |
++              FE_CAN_FEC_AUTO |
++              FE_CAN_QPSK
++};
++
++static struct dvb_frontend_info dst_info_cable = {
++      .name                   = "DST CABLE",
++      .type                   = FE_QAM,
++        .frequency_stepsize   = 62500,
++      .frequency_min          = 51000000,
++      .frequency_max          = 858000000,
++      .symbol_rate_min        = 1000000,
++      .symbol_rate_max        = 45000000,
++/*     . symbol_rate_tolerance        =       ???,*/
++      .notifier_delay         = 50,                /* 1/20 s */
++      .caps = FE_CAN_INVERSION_AUTO |
++              FE_CAN_FEC_AUTO |
++              FE_CAN_QAM_AUTO
++};
++
++static struct dvb_frontend_info dst_info_tv = {
++      .name                   = "DST TERR",
++      .type                   = FE_OFDM,
++      .frequency_min          = 137000000,
++      .frequency_max          = 858000000,
++      .frequency_stepsize     = 166667,
++      .caps = FE_CAN_INVERSION_AUTO |
++          FE_CAN_FEC_AUTO |
++          FE_CAN_QAM_AUTO |
++          FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
++};
++
++static void dst_packsize(struct dst_data *dst, int psize)
++{
++      union dst_gpio_packet bits;
++
++      bits.psize = psize;
++      bt878_device_control(dst->bt, DST_IG_TS, &bits);
++}
++
++static int dst_gpio_outb(struct dst_data *dst, u32 mask, u32 enbb, u32 outhigh)
++{
++      union dst_gpio_packet enb;
++      union dst_gpio_packet bits;
++      int err;
++
++      enb.enb.mask = mask;
++      enb.enb.enable = enbb;
++        if ((err = bt878_device_control(dst->bt, DST_IG_ENABLE, &enb)) < 0) {
++              dprintk ("%s: dst_gpio_enb error (err == %i, mask == 0x%02x, enb == 0x%02x)\n", __FUNCTION__, err, mask, enbb);
++              return -EREMOTEIO;
++      }
++
++      /* because complete disabling means no output, no need to do
++       * output packet */
++      if (enbb == 0)
++              return 0;
++
++      bits.outp.mask = enbb;
++      bits.outp.highvals = outhigh;
++
++        if ((err = bt878_device_control(dst->bt, DST_IG_WRITE, &bits)) < 0) {
++              dprintk ("%s: dst_gpio_outb error (err == %i, enbb == 0x%02x, outhigh == 0x%02x)\n", __FUNCTION__, err, enbb, outhigh);
++              return -EREMOTEIO;
++      }
++        return 0;
++}
++
++static int dst_gpio_inb(struct dst_data *dst, u8 *result)
++{
++      union dst_gpio_packet rd_packet;
++      int err;
++
++      *result = 0;
++
++        if ((err = bt878_device_control(dst->bt, DST_IG_READ, &rd_packet)) < 0) {
++              dprintk ("%s: dst_gpio_inb error (err == %i)\n", __FUNCTION__, err);
++              return -EREMOTEIO;
++      }
++      *result = (u8)rd_packet.rd.value;
++        return 0;
++}
++
++#define DST_I2C_ENABLE        1
++#define DST_8820      2
++
++static int
++dst_reset8820(struct dst_data *dst)
++{
++int retval;
++      /* pull 8820 gpio pin low, wait, high, wait, then low */
++      // dprintk ("%s: reset 8820\n", __FUNCTION__);
++      retval = dst_gpio_outb(dst, DST_8820, DST_8820, 0);
++      if (retval < 0)
++              return retval;
++      dvb_delay(10);
++      retval = dst_gpio_outb(dst, DST_8820, DST_8820, DST_8820);
++      if (retval < 0)
++              return retval;
++      /* wait for more feedback on what works here *
++      dvb_delay(10);
++      retval = dst_gpio_outb(dst, DST_8820, DST_8820, 0);
++      if (retval < 0)
++              return retval;
++      */
++      return 0;
++}
++
++static int
++dst_i2c_enable(struct dst_data *dst)
++{
++int retval;
++      /* pull I2C enable gpio pin low, wait */
++      // dprintk ("%s: i2c enable\n", __FUNCTION__);
++      retval = dst_gpio_outb(dst, ~0, DST_I2C_ENABLE, 0);
++      if (retval < 0)
++              return retval;
++      // dprintk ("%s: i2c enable delay\n", __FUNCTION__);
++      dvb_delay(33);
++      return 0;
++}
++
++static int
++dst_i2c_disable(struct dst_data *dst)
++{
++int retval;
++      /* release I2C enable gpio pin, wait */
++      // dprintk ("%s: i2c disable\n", __FUNCTION__);
++      retval = dst_gpio_outb(dst, ~0, 0, 0);
++      if (retval < 0)
++              return retval;
++      // dprintk ("%s: i2c disable delay\n", __FUNCTION__);
++      dvb_delay(33);
++      return 0;
++}
++
++static int
++dst_wait_dst_ready(struct dst_data *dst)
++{
++u8 reply;
++int retval;
++int i;
++      for (i = 0; i < 200; i++) {
++              retval = dst_gpio_inb(dst, &reply);
++              if (retval < 0)
++                      return retval;
++              if ((reply & DST_I2C_ENABLE) == 0) {
++                      dprintk ("%s: dst wait ready after %d\n", __FUNCTION__, i);
++                      return 1;
++              }
++              dvb_delay(5);
++      }
++      dprintk ("%s: dst wait NOT ready after %d\n", __FUNCTION__, i);
++      return 0;
++}
++
++#define DST_I2C_ADDR 0x55
++
++static int write_dst (struct dst_data *dst, u8 *data, u8 len)
++{
++      struct i2c_msg msg = {
++              .addr = DST_I2C_ADDR, .flags = 0, .buf = data, .len = len };
++      int err;
++      int cnt;
++
++      if (dst_debug && dst_verbose) {
++              u8 i;
++              dprintk("%s writing",__FUNCTION__);
++              for (i = 0 ; i < len ; i++) {
++                      dprintk(" 0x%02x", data[i]);
++              }
++              dprintk("\n");
++      }
++      dvb_delay(30);
++      for (cnt = 0; cnt < 4; cnt++) {
++              if ((err = dst->i2c->xfer (dst->i2c, &msg, 1)) < 0) {
++                      dprintk ("%s: write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]);
++                      dst_i2c_disable(dst);
++                      dvb_delay(500);
++                      dst_i2c_enable(dst);
++                      dvb_delay(500);
++                      continue;
++              } else
++                      break;
++      }
++      if (cnt >= 4)
++              return -EREMOTEIO;
++        return 0;
++}
++
++static int read_dst (struct dst_data *dst, u8 *ret, u8 len)
++{
++      struct i2c_msg msg = 
++              { .addr = DST_I2C_ADDR, .flags = I2C_M_RD, .buf = ret, .len = len };
++      int err;
++      int cnt;
++
++      for (cnt = 0; cnt < 4; cnt++) {
++              if ((err = dst->i2c->xfer (dst->i2c, &msg, 1)) < 0) {
++                      dprintk ("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]);
++                      dst_i2c_disable(dst);
++                      dst_i2c_enable(dst);
++                      continue;
++              } else
++                      break;
++      }
++      if (cnt >= 4)
++              return -EREMOTEIO;
++      dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]);
++      if (dst_debug && dst_verbose) {
++              for (err = 1; err < len; err++)
++                      dprintk(" 0x%x", ret[err]);
++              if (err > 1)
++                      dprintk("\n");
++      }
++      return 0;
++}
++
++static int dst_set_freq(struct dst_data *dst, u32 freq)
++{
++      u8 *val;
++
++      dst->frequency = freq;
++
++      // dprintk("%s: set frequency %u\n", __FUNCTION__, freq);
++      if (dst->dst_type == DST_TYPE_IS_SAT) {
++              freq = freq / 1000;
++              if (freq < 950 || freq > 2150)
++                      return -EINVAL;
++              val = &dst->tx_tuna[0];
++              val[2] = (freq >> 8) & 0x7f;
++              val[3] = (u8)freq;
++              val[4] = 1;
++              val[8] &= ~4;
++              if (freq < 1531)
++                      val[8] |= 4;
++      } else if (dst->dst_type == DST_TYPE_IS_TERR) {
++              freq = freq / 1000;
++              if (freq < 137000 || freq > 858000)
++                      return -EINVAL;
++              val = &dst->tx_tuna[0];
++              val[2] = (freq >> 16) & 0xff;
++              val[3] = (freq >> 8) & 0xff;
++              val[4] = (u8)freq;
++              val[5] = 0;
++              switch (dst->bandwidth) {
++              case BANDWIDTH_6_MHZ:
++                      val[6] = 6;
++                      break;
++
++              case BANDWIDTH_7_MHZ:
++              case BANDWIDTH_AUTO:
++                      val[6] = 7;
++                      break;
++
++              case BANDWIDTH_8_MHZ:
++                      val[6] = 8;
++                      break;
++              }
++
++              val[7] = 0;
++              val[8] = 0;
++      } else if (dst->dst_type == DST_TYPE_IS_CABLE) {
++              /* guess till will get one */
++              freq = freq / 1000;
++              val = &dst->tx_tuna[0];
++              val[2] = (freq >> 16) & 0xff;
++              val[3] = (freq >> 8) & 0xff;
++              val[4] = (u8)freq;
++      } else
++              return -EINVAL;
++      return 0;
++}
++
++static int dst_set_bandwidth(struct dst_data *dst, fe_bandwidth_t bandwidth)
++{
++      u8 *val;
++
++      dst->bandwidth = bandwidth;
++
++      if (dst->dst_type != DST_TYPE_IS_TERR)
++              return 0;
++
++      val = &dst->tx_tuna[0];
++        switch (bandwidth) {
++      case BANDWIDTH_6_MHZ:
++              val[6] = 6;
++              break;
++
++      case BANDWIDTH_7_MHZ:
++              val[6] = 7;
++              break;
++
++      case BANDWIDTH_8_MHZ:
++              val[6] = 8;
++              break;
++
++      default:
++              return -EINVAL;
++      }
++      return 0;
++}
++
++static int dst_set_inversion (struct dst_data *dst, fe_spectral_inversion_t inversion)
++{
++      u8 *val;
++
++      dst->inversion = inversion;
++
++      val = &dst->tx_tuna[0];
++
++      val[8] &= ~0x80;
++
++      switch (inversion) {
++      case INVERSION_OFF:
++              break;
++      case INVERSION_ON:
++              val[8] |= 0x80;
++              break;
++      case INVERSION_AUTO:
++              break;
++      default:
++              return -EINVAL;
++      }
++      return 0;
++}
++
++
++static int dst_set_fec (struct dst_data *dst, fe_code_rate_t fec)
++{
++      dst->fec = fec;
++      return 0;
++}
++
++static fe_code_rate_t dst_get_fec (struct dst_data *dst)
++{
++      return dst->fec;
++}
++
++static int dst_set_symbolrate (struct dst_data *dst, u32 srate)
++{
++      u8 *val;
++      u32 symcalc;
++      u64 sval;
++
++      dst->symbol_rate = srate;
++
++      if (dst->dst_type == DST_TYPE_IS_TERR) {
++              return 0;
++      }
++
++      // dprintk("%s: set srate %u\n", __FUNCTION__, srate);
++      srate /= 1000;
++      val = &dst->tx_tuna[0];
++
++      if (dst->type_flags & DST_TYPE_HAS_SYMDIV) {
++              sval = srate;
++              sval <<= 20;
++              do_div(sval, 88000);
++              symcalc = (u32)sval;
++              // dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc);
++              val[5] = (u8)(symcalc >> 12);
++              val[6] = (u8)(symcalc >> 4);
++              val[7] = (u8)(symcalc << 4);
++      } else {
++              val[5] = (u8)(srate >> 16) & 0x7f;
++              val[6] = (u8)(srate >> 8);
++              val[7] = (u8)srate;
++      }
++      val[8] &= ~0x20;
++      if (srate > 8000)
++              val[8] |= 0x20;
++      return 0;
++}
++
++
++static u8 dst_check_sum(u8 *buf, u32 len)
++{
++      u32 i;
++      u8  val = 0;
++      if (!len)
++              return 0;
++      for (i = 0; i < len; i++) {
++              val += buf[i];
++      }
++      return ((~val) + 1);
++}
++
++typedef struct dst_types {
++      char    *mstr;
++      int     offs;
++      u8      dst_type;
++      u32     type_flags;
++} DST_TYPES;
++
++struct dst_types dst_tlist[] = {
++      { "DST-020", 0,  DST_TYPE_IS_SAT,    DST_TYPE_HAS_SYMDIV },
++      { "DST-030", 0,  DST_TYPE_IS_SAT,    DST_TYPE_HAS_TS204|DST_TYPE_HAS_NEWTUNE },
++      { "DST-03T", 0,  DST_TYPE_IS_SAT,    DST_TYPE_HAS_SYMDIV|DST_TYPE_HAS_TS204},
++      { "DST-MOT", 0,  DST_TYPE_IS_SAT,    DST_TYPE_HAS_SYMDIV },
++      { "DST-CI",  1,  DST_TYPE_IS_SAT,    DST_TYPE_HAS_TS204|DST_TYPE_HAS_NEWTUNE },
++      { "DSTMCI",  1,  DST_TYPE_IS_SAT,    DST_TYPE_HAS_NEWTUNE },
++      { "DSTFCI",  1,  DST_TYPE_IS_SAT,    DST_TYPE_HAS_NEWTUNE },
++      { "DCTNEW",  1,  DST_TYPE_IS_CABLE,  DST_TYPE_HAS_NEWTUNE },
++      { "DCT_CI",  1,  DST_TYPE_IS_CABLE,  DST_TYPE_HAS_NEWTUNE|DST_TYPE_HAS_TS204 },
++      { "DTTDIG" , 1,  DST_TYPE_IS_TERR,   0} };
++/* DCTNEW and DCT-CI are guesses */
++
++static void dst_type_flags_print(u32 type_flags)
++{
++      printk("DST type flags :");
++      if (type_flags & DST_TYPE_HAS_NEWTUNE)
++              printk(" 0x%x newtuner", DST_TYPE_HAS_NEWTUNE);
++      if (type_flags & DST_TYPE_HAS_TS204)
++              printk(" 0x%x ts204", DST_TYPE_HAS_TS204);
++      if (type_flags & DST_TYPE_HAS_SYMDIV)
++              printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
++      printk("\n");
++}
++
++static int dst_type_print(u8 type)
++{
++      char *otype;
++      switch (type) {
++              case DST_TYPE_IS_SAT:
++                      otype = "satellite";
++                      break;
++              case DST_TYPE_IS_TERR:
++                      otype = "terrestial TV";
++                      break;
++              case DST_TYPE_IS_CABLE:
++                      otype = "terrestial TV";
++                      break;
++              default:
++                      printk("%s: invalid dst type %d\n",
++                              __FUNCTION__, type);
++                      return -EINVAL;
++      }
++      printk("DST type : %s\n", otype);
++      return 0;
++}
++
++static int dst_check_ci (struct dst_data *dst)
++{
++      u8 txbuf[8];
++      u8 rxbuf[8];
++      int retval;
++      int i;
++      struct dst_types *dsp;
++      u8 use_dst_type;
++      u32 use_type_flags;
++
++      memset(txbuf, 0, sizeof(txbuf));
++      txbuf[1] = 6;
++      txbuf[7] = dst_check_sum (txbuf, 7);
++ 
++      dst_i2c_enable(dst);
++      dst_reset8820(dst);
++      retval = write_dst (dst, txbuf, 8);
++      if (retval < 0) {
++              dst_i2c_disable(dst);
++              dprintk("%s: write not successful, maybe no card?\n", __FUNCTION__);
++              return retval;
++      }
++      dvb_delay(3);
++      retval = read_dst (dst, rxbuf, 1);
++      dst_i2c_disable(dst);
++      if (retval < 0) {
++              dprintk("%s: read not successful, maybe no card?\n", __FUNCTION__);
++              return retval;
++      }
++      if (rxbuf[0] != 0xff) {
++              dprintk("%s: write reply not 0xff, not ci (%02x)\n", __FUNCTION__, rxbuf[0]);
++              return retval;
++      }
++      if (!dst_wait_dst_ready(dst))
++              return 0;
++      // dst_i2c_enable(i2c); Dimitri
++      retval = read_dst (dst, rxbuf, 8);
++      dst_i2c_disable(dst);
++      if (retval < 0) {
++              dprintk("%s: read not successful\n", __FUNCTION__);
++              return retval;
++      }
++      if (rxbuf[7] != dst_check_sum (rxbuf, 7)) {
++              dprintk("%s: checksum failure\n", __FUNCTION__);
++              return retval;
++      }
++      rxbuf[7] = '\0';
++      for (i = 0, dsp = &dst_tlist[0]; i < sizeof(dst_tlist) / sizeof(dst_tlist[0]); i++, dsp++) {
++              if (!strncmp(&rxbuf[dsp->offs],
++                              dsp->mstr,
++                              strlen(dsp->mstr))) {
++                      use_type_flags = dsp->type_flags;
++                      use_dst_type = dsp->dst_type;
++                      printk("%s: recognize %s\n", __FUNCTION__, dsp->mstr);
++                      break;
++              }
++      }
++      if (i >= sizeof(dst_tlist) / sizeof(dst_tlist[0])) {
++              printk("%s: unable to recognize %s or %s\n", __FUNCTION__, &rxbuf[0], &rxbuf[1]);
++              printk("%s please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__);
++              use_dst_type = DST_TYPE_IS_SAT;
++              use_type_flags = DST_TYPE_HAS_SYMDIV;
++      }
++      switch (dst_type) {
++              case (-1U):
++                      /* not used */
++                      break;
++              case DST_TYPE_IS_SAT:
++              case DST_TYPE_IS_TERR:
++              case DST_TYPE_IS_CABLE:
++                      use_dst_type = (u8)dst_type;
++                      break;
++              default:
++                      printk("%s: invalid user override dst type %d, not used\n",
++                              __FUNCTION__, dst_type);
++                      break;
++      }
++      dst_type_print(use_dst_type);
++      if (dst_type_flags != (-1U)) {
++              printk("%s: user override dst type flags 0x%x\n",
++                              __FUNCTION__, dst_type_flags);
++              use_type_flags = dst_type_flags;
++      }
++      dst->type_flags = use_type_flags;
++      dst->dst_type= use_dst_type;
++      dst_type_flags_print(dst->type_flags);
++
++      if (dst->type_flags & DST_TYPE_HAS_TS204) {
++              dst_packsize(dst, 204);
++      }
++      return 0;
++}
++
++static int dst_command (struct dst_data *dst, u8 *data, u8 len)
++{
++      int retval;
++      u8 reply;
++
++      dst_i2c_enable(dst);
++      dst_reset8820(dst);
++      retval = write_dst (dst, data, len);
++      if (retval < 0) {
++              dst_i2c_disable(dst);
++              dprintk("%s: write not successful\n", __FUNCTION__);
++              return retval;
++      }
++      dvb_delay(33);
++      retval = read_dst (dst, &reply, 1);
++      dst_i2c_disable(dst);
++      if (retval < 0) {
++              dprintk("%s: read verify  not successful\n", __FUNCTION__);
++              return retval;
++      }
++      if (reply != 0xff) {
++              dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);
++              return 0;
++      }
++      if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
++              return 0;
++      if (!dst_wait_dst_ready(dst))
++              return 0;
++      // dst_i2c_enable(i2c); Per dimitri
++      retval = read_dst (dst, dst->rxbuffer, 8);
++      dst_i2c_disable(dst);
++      if (retval < 0) {
++              dprintk("%s: read not successful\n", __FUNCTION__);
++              return 0;
++      }
++      if (dst->rxbuffer[7] != dst_check_sum (dst->rxbuffer, 7)) {
++              dprintk("%s: checksum failure\n", __FUNCTION__);
++              return 0;
++      }
++      return 0;
++}
++
++static int dst_get_signal(struct dst_data *dst)
++{
++      int retval;
++      u8 get_signal[] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
++
++      if ((dst->diseq_flags & ATTEMPT_TUNE) == 0) {
++              dst->decode_lock = dst->decode_strength = dst->decode_snr = 0;
++              return 0;
++      }
++      if (0 == (dst->diseq_flags & HAS_LOCK)) {
++              dst->decode_lock = dst->decode_strength = dst->decode_snr = 0;
++              return 0;
++      }
++      if (time_after_eq(jiffies, dst->cur_jiff + (HZ/5))) {
++              retval =  dst_command(dst, get_signal, 8);
++              if (retval < 0)
++                      return retval;
++              if (dst->dst_type == DST_TYPE_IS_SAT) {
++                      dst->decode_lock = ((dst->rxbuffer[6] & 0x10) == 0) ?
++                                      1 : 0;
++                      dst->decode_strength = dst->rxbuffer[5] << 8;
++                      dst->decode_snr = dst->rxbuffer[2] << 8 |
++                              dst->rxbuffer[3];
++              } else if ((dst->dst_type == DST_TYPE_IS_TERR) ||
++                              (dst->dst_type == DST_TYPE_IS_CABLE)) {
++                      dst->decode_lock = (dst->rxbuffer[1]) ?
++                                      1 : 0;
++                      dst->decode_strength = dst->rxbuffer[4] << 8;
++                      dst->decode_snr = dst->rxbuffer[3] << 8;
++              }
++              dst->cur_jiff = jiffies;
++      }
++      return 0;
++}
++
++/*
++ * line22k0    0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
++ * line22k1    0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
++ * line22k2    0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
++ * tone        0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
++ * data        0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
++ * power_off   0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
++ * power_on    0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
++ * Diseqc 1    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
++ * Diseqc 2    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8 
++ * Diseqc 3    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4 
++ * Diseqc 4    0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0 
++ */
++
++static int dst_set_diseqc (struct dst_data *dst, u8 *cmd, u8 len)
++{
++      u8 paket[8] =  {0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
++
++      if (dst->dst_type == DST_TYPE_IS_TERR)
++              return 0;
++
++      if (len == 0 || len > 4)
++              return -EINVAL;
++      memcpy(&paket[3], cmd, len);
++      paket[7] = dst_check_sum (&paket[0], 7);
++      dst_command(dst, paket, 8);
++      return 0;
++}
++
++static int dst_tone_power_cmd (struct dst_data *dst)
++{
++      u8 paket[8] =  {0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00};
++
++      if (dst->dst_type == DST_TYPE_IS_TERR)
++              return 0;
++
++      if (dst->voltage == SEC_VOLTAGE_OFF) 
++              paket[4] = 0;
++      else
++              paket[4] = 1;
++      if (dst->tone == SEC_TONE_ON)
++              paket[2] = dst->k22;
++      else
++              paket[2] = 0;
++      paket[7] = dst_check_sum (&paket[0], 7);
++      dst_command(dst, paket, 8);
++      return 0;
++}
++
++static int dst_set_voltage (struct dst_data *dst, fe_sec_voltage_t voltage)
++{
++      u8 *val;
++      int need_cmd;
++
++      dst->voltage = voltage;
++
++      if (dst->dst_type == DST_TYPE_IS_TERR)
++              return 0;
++
++      need_cmd = 0;
++      val = &dst->tx_tuna[0];
++      val[8] &= ~0x40;
++      switch (voltage) {
++      case SEC_VOLTAGE_13:
++              if ((dst->diseq_flags & HAS_POWER) == 0)
++                      need_cmd = 1;
++              dst->diseq_flags |= HAS_POWER;
++              break;
++      case SEC_VOLTAGE_18:
++              if ((dst->diseq_flags & HAS_POWER) == 0)
++                      need_cmd = 1;
++              dst->diseq_flags |= HAS_POWER;
++              val[8] |= 0x40;
++              break;
++      case SEC_VOLTAGE_OFF:
++              need_cmd = 1;
++              dst->diseq_flags &= ~(HAS_POWER|HAS_LOCK|ATTEMPT_TUNE);
++              break;
++      default:
++              return -EINVAL;
++      }
++      if (need_cmd) {
++              dst_tone_power_cmd(dst);
++      }
++      return 0;
++}
++
++
++static int dst_set_tone (struct dst_data *dst, fe_sec_tone_mode_t tone)
++{
++      u8 *val;
++
++      dst->tone = tone;
++
++      if (dst->dst_type == DST_TYPE_IS_TERR)
++              return 0;
++
++      val = &dst->tx_tuna[0];
++
++      val[8] &= ~0x1;
++
++      switch (tone) {
++      case SEC_TONE_OFF:
++              break;
++      case SEC_TONE_ON:
++              val[8] |= 1;
++              break;
++      default:
++              return -EINVAL;
++      }
++      dst_tone_power_cmd(dst);
++      return 0;
++}
++
++static int dst_get_tuna (struct dst_data *dst)
++{
++int retval;
++      if ((dst->diseq_flags & ATTEMPT_TUNE) == 0)
++              return 0;
++      dst->diseq_flags &= ~(HAS_LOCK);
++      if (!dst_wait_dst_ready(dst))
++              return 0;
++      if (dst->type_flags & DST_TYPE_HAS_NEWTUNE) {
++              /* how to get variable length reply ???? */
++              retval = read_dst (dst, dst->rx_tuna, 10);
++      } else {
++              retval = read_dst (dst, &dst->rx_tuna[2], 8);
++      }
++      if (retval < 0) {
++              dprintk("%s: read not successful\n", __FUNCTION__);
++              return 0;
++      }
++      if (dst->type_flags & DST_TYPE_HAS_NEWTUNE) {
++              if (dst->rx_tuna[9] != dst_check_sum (&dst->rx_tuna[0], 9)) {
++                      dprintk("%s: checksum failure?\n", __FUNCTION__);
++                      return 0;
++              }
++      } else {
++              if (dst->rx_tuna[9] != dst_check_sum (&dst->rx_tuna[2], 7)) {
++                      dprintk("%s: checksum failure?\n", __FUNCTION__);
++                      return 0;
++              }
++      }
++      if (dst->rx_tuna[2] == 0 && dst->rx_tuna[3] == 0)
++              return 0;
++      dst->decode_freq = ((dst->rx_tuna[2] & 0x7f) << 8) +  dst->rx_tuna[3];
++
++      dst->decode_lock = 1;
++      /*
++      dst->decode_n1 = (dst->rx_tuna[4] << 8) +  
++                      (dst->rx_tuna[5]);
++
++      dst->decode_n2 = (dst->rx_tuna[8] << 8) +  
++                      (dst->rx_tuna[7]);
++      */
++      dst->diseq_flags |= HAS_LOCK;
++      /* dst->cur_jiff = jiffies; */
++      return 1;
++}
++
++static int dst_write_tuna (struct dst_data *dst)
++{
++      int retval;
++      u8 reply;
++
++      dprintk("%s: type_flags 0x%x \n", __FUNCTION__, dst->type_flags);
++      dst->decode_freq = 0;
++      dst->decode_lock = dst->decode_strength = dst->decode_snr = 0;
++      if (dst->dst_type == DST_TYPE_IS_SAT) {
++              if (!(dst->diseq_flags & HAS_POWER))
++                      dst_set_voltage (dst, SEC_VOLTAGE_13);
++      }
++      dst->diseq_flags &= ~(HAS_LOCK|ATTEMPT_TUNE);
++      dst_i2c_enable(dst);
++      if (dst->type_flags & DST_TYPE_HAS_NEWTUNE) {
++              dst_reset8820(dst);
++              dst->tx_tuna[9] = dst_check_sum (&dst->tx_tuna[0], 9);
++              retval = write_dst (dst, &dst->tx_tuna[0], 10);
++      } else {
++              dst->tx_tuna[9] = dst_check_sum (&dst->tx_tuna[2], 7);
++              retval = write_dst (dst, &dst->tx_tuna[2], 8);
++      }
++      if (retval < 0) {
++              dst_i2c_disable(dst);
++              dprintk("%s: write not successful\n", __FUNCTION__);
++              return retval;
++      }
++      dvb_delay(3);
++      retval = read_dst (dst, &reply, 1);
++      dst_i2c_disable(dst);
++      if (retval < 0) {
++              dprintk("%s: read verify  not successful\n", __FUNCTION__);
++              return retval;
++      }
++      if (reply != 0xff) {
++              dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply);
++              return 0;
++      }
++      dst->diseq_flags |= ATTEMPT_TUNE;
++      return dst_get_tuna(dst);
++}
++
++static void dst_init (struct dst_data *dst)
++{
++static u8 ini_satci_tuna[] = {  9, 0, 3, 0xb6, 1, 0,    0x73, 0x21, 0, 0 };
++static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 };
++static u8 ini_tvfta_tuna[] = { 0, 0,  3, 0xb6, 1, 7,    0x0,   0x0, 0, 0 };
++static u8 ini_tvci_tuna[] = { 9, 0,  3, 0xb6, 1, 7,    0x0,   0x0, 0, 0 };
++static u8 ini_cabfta_tuna[] = { 0, 0,  3, 0xb6, 1, 7,    0x0,   0x0, 0, 0 };
++static u8 ini_cabci_tuna[] = { 9, 0,  3, 0xb6, 1, 7,    0x0,   0x0, 0, 0 };
++      dst->inversion = INVERSION_ON;
++      dst->voltage = SEC_VOLTAGE_13;
++      dst->tone = SEC_TONE_OFF;
++      dst->symbol_rate = 29473000;
++      dst->fec = FEC_AUTO;
++      dst->diseq_flags = 0;
++      dst->k22 = 0x02;
++      dst->bandwidth = BANDWIDTH_7_MHZ;
++      dst->cur_jiff = jiffies;
++      if (dst->dst_type == DST_TYPE_IS_SAT) {
++              dst->frequency = 950000;
++              memcpy(dst->tx_tuna, ((dst->type_flags &  DST_TYPE_HAS_NEWTUNE )? 
++                                      ini_satci_tuna : ini_satfta_tuna),
++                              sizeof(ini_satfta_tuna));
++      } else if (dst->dst_type == DST_TYPE_IS_TERR) {
++              dst->frequency = 137000000;
++              memcpy(dst->tx_tuna, ((dst->type_flags &  DST_TYPE_HAS_NEWTUNE )? 
++                                      ini_tvci_tuna : ini_tvfta_tuna),
++                              sizeof(ini_tvfta_tuna));
++      } else if (dst->dst_type == DST_TYPE_IS_CABLE) {
++              dst->frequency = 51000000;
++              memcpy(dst->tx_tuna, ((dst->type_flags &  DST_TYPE_HAS_NEWTUNE )? 
++                                      ini_cabci_tuna : ini_cabfta_tuna),
++                              sizeof(ini_cabfta_tuna));
++      }
++}
++
++struct lkup {
++      unsigned int cmd;
++      char *desc;
++} looker[] = {
++      {FE_GET_INFO,                "FE_GET_INFO:"},
++      {FE_READ_STATUS,             "FE_READ_STATUS:" },
++      {FE_READ_BER,                "FE_READ_BER:" },
++      {FE_READ_SIGNAL_STRENGTH,    "FE_READ_SIGNAL_STRENGTH:" },
++      {FE_READ_SNR,                "FE_READ_SNR:" },
++      {FE_READ_UNCORRECTED_BLOCKS, "FE_READ_UNCORRECTED_BLOCKS:" },
++      {FE_SET_FRONTEND,            "FE_SET_FRONTEND:" },
++      {FE_GET_FRONTEND,            "FE_GET_FRONTEND:" },
++      {FE_SLEEP,                   "FE_SLEEP:" },
++      {FE_INIT,                    "FE_INIT:" },
++      {FE_RESET,                   "FE_RESET:" },
++      {FE_SET_TONE,                "FE_SET_TONE:" },
++      {FE_SET_VOLTAGE,             "FE_SET_VOLTAGE:" },
++      };
++
++static int dst_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
++{
++      struct dst_data *dst = fe->data;
++      int retval;
++      /*
++      char  *cc;
++                
++      cc = "FE_UNSUPP:";
++      for(retval = 0; retval < sizeof(looker) / sizeof(looker[0]); retval++) {
++              if (looker[retval].cmd == cmd) {
++                      cc = looker[retval].desc;
++                      break;
++              }
++      }
++      dprintk("%s cmd %s (0x%x)\n",__FUNCTION__, cc, cmd);
++      */
++      // printk("%s: dst %8.8x bt %8.8x i2c %8.8x\n", __FUNCTION__, dst, dst->bt, dst->i2c);
++      /* should be set by attach, but just in case */
++      dst->i2c = fe->i2c;
++        switch (cmd) {
++        case FE_GET_INFO: 
++      {
++           struct dvb_frontend_info *info;
++              info = &dst_info_sat;
++              if (dst->dst_type == DST_TYPE_IS_TERR)
++                      info = &dst_info_tv;
++              else if (dst->dst_type == DST_TYPE_IS_CABLE)
++                      info = &dst_info_cable;
++              memcpy (arg, info, sizeof(struct dvb_frontend_info));
++              break;
++      }
++        case FE_READ_STATUS:
++      {
++              fe_status_t *status = arg;
++
++              *status = 0;
++              if (dst->diseq_flags & HAS_LOCK) {
++                      dst_get_signal(dst);
++                      if (dst->decode_lock)
++                              *status |= FE_HAS_LOCK 
++                                      | FE_HAS_SIGNAL 
++                                      | FE_HAS_CARRIER
++                                      | FE_HAS_SYNC
++                                      | FE_HAS_VITERBI;
++              }
++              break;
++      }
++
++        case FE_READ_BER:
++      {
++              /* guess */
++              // *(u32*) arg = dst->decode_n1;
++              *(u32*) arg = 0;
++              return -EOPNOTSUPP; 
++      }
++
++        case FE_READ_SIGNAL_STRENGTH:
++      {
++              dst_get_signal(dst);
++              *((u16*) arg) = dst->decode_strength;
++              break;
++      }
++
++        case FE_READ_SNR:
++      {
++              dst_get_signal(dst);
++              *((u16*) arg) = dst->decode_snr;
++              break;
++      }
++
++      case FE_READ_UNCORRECTED_BLOCKS: 
++      {
++              *((u32*) arg) = 0;    /* the stv0299 can't measure BER and */
++              return -EOPNOTSUPP;   /* errors at the same time.... */
++      }
++
++        case FE_SET_FRONTEND:
++        {
++              struct dvb_frontend_parameters *p = arg;
++
++              dst_set_freq (dst, p->frequency);
++              dst_set_inversion (dst, p->inversion);
++              if (dst->dst_type == DST_TYPE_IS_SAT) {
++                      dst_set_fec (dst, p->u.qpsk.fec_inner);
++                      dst_set_symbolrate (dst, p->u.qpsk.symbol_rate);
++              } else if (dst->dst_type == DST_TYPE_IS_TERR) {
++                      dst_set_bandwidth(dst, p->u.ofdm.bandwidth);
++              } else if (dst->dst_type == DST_TYPE_IS_CABLE) {
++                      dst_set_fec (dst, p->u.qam.fec_inner);
++                      dst_set_symbolrate (dst, p->u.qam.symbol_rate);
++              }
++              dst_write_tuna (dst);
++
++                break;
++        }
++
++      case FE_GET_FRONTEND:
++      {
++              struct dvb_frontend_parameters *p = arg;
++
++
++              p->frequency = dst->decode_freq;
++              p->inversion = dst->inversion;
++              if (dst->dst_type == DST_TYPE_IS_SAT) {
++                      p->u.qpsk.symbol_rate = dst->symbol_rate;
++                      p->u.qpsk.fec_inner = dst_get_fec (dst);
++              } else if (dst->dst_type == DST_TYPE_IS_TERR) {
++                      p->u.ofdm.bandwidth = dst->bandwidth;
++              } else if (dst->dst_type == DST_TYPE_IS_CABLE) {
++                      p->u.qam.symbol_rate = dst->symbol_rate;
++                      p->u.qam.fec_inner = dst_get_fec (dst);
++                      p->u.qam.modulation = QAM_AUTO;
++              }
++              break;
++      }
++
++        case FE_SLEEP:
++              return 0;
++
++        case FE_INIT:
++              dst_init(dst);
++              break;
++
++      case FE_RESET:
++              break;
++
++      case FE_DISEQC_SEND_MASTER_CMD:
++      {
++              struct dvb_diseqc_master_cmd *cmd = (struct dvb_diseqc_master_cmd *)arg;
++              retval = dst_set_diseqc (dst, cmd->msg, cmd->msg_len);
++              if (retval < 0)
++                      return retval;
++              break;
++      }
++      case FE_SET_TONE:
++              retval = dst_set_tone (dst, (fe_sec_tone_mode_t) arg);
++              if (retval < 0)
++                      return retval;
++              break;
++      case FE_SET_VOLTAGE:
++              retval = dst_set_voltage (dst, (fe_sec_voltage_t) arg);
++              if (retval < 0)
++                      return retval;
++              break;
++      default:
++              return -EOPNOTSUPP;
++        };
++        
++        return 0;
++} 
++
++
++static int dst_attach (struct dvb_i2c_bus *i2c, void **data)
++{
++      struct dst_data *dst;
++      struct bt878 *bt;
++      struct dvb_frontend_info *info;
++
++      dprintk("%s: check ci\n", __FUNCTION__);
++      bt = bt878_find_by_dvb_adap(i2c->adapter);
++      if (!bt)
++              return -ENODEV;
++      dst = kmalloc(sizeof(struct dst_data), GFP_KERNEL);
++      if (dst == NULL) {
++              printk(KERN_INFO "%s: Out of memory.\n", __FUNCTION__);
++              return -ENOMEM;
++      }
++      memset(dst, 0, sizeof(*dst));
++      *data = dst;
++      dst->bt = bt;
++      dst->i2c = i2c;
++      if (dst_check_ci(dst) < 0) {
++              kfree(dst);
++              return -ENODEV;
++      }
++
++      dst_init (dst);
++      dprintk("%s: register dst %8.8x bt %8.8x i2c %8.8x\n", __FUNCTION__, 
++                      (u32)dst, (u32)(dst->bt), (u32)(dst->i2c));
++
++      info = &dst_info_sat;
++      if (dst->dst_type == DST_TYPE_IS_TERR)
++              info = &dst_info_tv;
++      else if (dst->dst_type == DST_TYPE_IS_CABLE)
++              info = &dst_info_cable;
++
++      dvb_register_frontend (dst_ioctl, i2c, dst, info);
++
++      return 0;
++}
++
++static void dst_detach (struct dvb_i2c_bus *i2c, void *data)
++{
++      dvb_unregister_frontend (dst_ioctl, i2c);
++      dprintk("%s: unregister dst %8.8x\n", __FUNCTION__, (u32)(data));
++      if (data)
++              kfree(data);
++}
++
++static int __init init_dst (void)
++{
++      return dvb_register_i2c_device (THIS_MODULE, dst_attach, dst_detach);
++}
++
++static void __exit exit_dst (void)
++{
++      dvb_unregister_i2c_device (dst_attach);
++}
++
++
++module_init(init_dst);
++module_exit(exit_dst);
++
++MODULE_DESCRIPTION("DST DVB-S Frontend");
++MODULE_AUTHOR("Jamie Honan");
++MODULE_LICENSE("GPL");
++
+--- linux-2.6.0/drivers/media/dvb/frontends/Kconfig    2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/dvb/frontends/Kconfig     2003-12-28 23:22:37.000000000 -0800
+@@ -1,6 +1,17 @@
+ comment "Supported Frontend Modules"
+       depends on DVB
++config DVB_TWINHAN_DST
++      tristate "TWINHAN DST based DVB-S frontend (QPSK)"
++      depends on DVB_CORE
++      help
++        Used in such cards as the VP-1020/1030, Twinhan DST,
++        VVmer TV@SAT. Say Y when you want to support frontends 
++        using this asic.
++
++        This module requires the dvb-bt8xx driver and dvb bt878
++        module.
++
+ config DVB_STV0299
+       tristate "STV0299 based DVB-S frontend (QPSK)"
+       depends on DVB_CORE
+@@ -145,3 +156,19 @@ config DVB_TDA1004X_FIRMWARE_FILE
+             wget http://www.technotrend.de/new/215/TTweb_215a_budget_20_05_2003.zip
+             unzip -j TTweb_215a_budget_20_05_2003.zip Software/Oem/PCI/App/ttlcdacc.dll
+             mv ttlcdacc.dll /etc/dvb/tda1004x.bin
++
++config DVB_SP887X_FIRMWARE_FILE
++        string "Full pathname of sp887x firmware file"
++        depends on DVB_SP887X
++        default "/etc/dvb/sc_main.mc"
++        help
++          This driver needs a copy of the Avermedia firmware. The version tested
++        is part of the Avermedia DVB-T 1.3.26.3 Application. This can be downloaded
++        from the Avermedia web site.
++        If the software is installed in Windows the file will be in the
++        /Program Files/AVerTV DVB-T/ directory and is called sc_main.mc.
++        Alternatively it can "extracted" from the install cab files but this will have
++        to be done in windows as I don't know of a linux version of extract.exe.
++        Copy this file to /etc/dvb/sc_main.mc. With this version of the file the first
++        10 bytes are discarded and the next 0x4000 loaded. This may change in future
++        versions.
+--- linux-2.6.0/drivers/media/dvb/frontends/Makefile   2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/dvb/frontends/Makefile    2003-12-28 23:22:37.000000000 -0800
+@@ -4,6 +4,7 @@
+ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
++obj-$(CONFIG_DVB_TWINHAN_DST) += dst.o
+ obj-$(CONFIG_DVB_STV0299) += stv0299.o
+ obj-$(CONFIG_DVB_ALPS_TDLB7) += alps_tdlb7.o
+ obj-$(CONFIG_DVB_ALPS_TDMB7) += alps_tdmb7.o
+--- linux-2.6.0/drivers/media/dvb/frontends/mt312.c    2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/dvb/frontends/mt312.c     2003-12-28 23:22:38.000000000 -0800
+@@ -39,11 +39,19 @@
+ #define MT312_DEBUG           0
+ #define MT312_SYS_CLK         90000000UL      /* 90 MHz */
++#define MT312_LPOWER_SYS_CLK  60000000UL      /* 60 MHz */
+ #define MT312_PLL_CLK         10000000UL      /* 10 MHz */
+ /* number of active frontends */
+ static int mt312_count = 0;
++#if MT312_DEBUG == 0
++#define dprintk(x...)
++#else
++static int debug = 0;
++#define dprintk if(debug == 1) printk
++#endif
++
+ static struct dvb_frontend_info mt312_info = {
+       .name = "Zarlink MT312",
+       .type = FE_QPSK,
+@@ -86,7 +94,7 @@ static int mt312_read(struct dvb_i2c_bus
+               return -EREMOTEIO;
+       }
+ #if MT312_DEBUG
+-      {
++      if(debug) {
+               int i;
+               printk(KERN_INFO "R(%d):", reg & 0x7f);
+               for (i = 0; i < count; i++)
+@@ -107,7 +115,7 @@ static int mt312_write(struct dvb_i2c_bu
+       struct i2c_msg msg;
+ #if MT312_DEBUG
+-      {
++      if(debug) {
+               int i;
+               printk(KERN_INFO "W(%d):", reg & 0x7f);
+               for (i = 0; i < count; i++)
+@@ -205,7 +213,7 @@ static int sl1935_set_tv_freq(struct dvb
+       if (freq < 1550000)
+               buf[3] |= 0x10;
+-      printk(KERN_INFO "synth dword = %02x%02x%02x%02x\n", buf[0],
++      dprintk(KERN_INFO "synth dword = %02x%02x%02x%02x\n", buf[0],
+              buf[1], buf[2], buf[3]);
+       return mt312_pll_write(i2c, I2C_ADDR_SL1935, buf, sizeof(buf));
+@@ -225,7 +233,7 @@ static int tsa5059_set_tv_freq(struct dv
+       if (freq < 1550000)
+               buf[3] |= 0x02;
+-      printk(KERN_INFO "synth dword = %02x%02x%02x%02x\n", buf[0],
++      dprintk(KERN_INFO "synth dword = %02x%02x%02x%02x\n", buf[0],
+              buf[1], buf[2], buf[3]);
+       return mt312_pll_write(i2c, I2C_ADDR_TSA5059, buf, sizeof(buf));
+@@ -236,13 +244,13 @@ static int mt312_reset(struct dvb_i2c_bu
+       return mt312_writereg(i2c, RESET, full ? 0x80 : 0x40);
+ }
+-static int mt312_init(struct dvb_i2c_bus *i2c, const long id)
++static int mt312_init(struct dvb_i2c_bus *i2c, const long id, u8 pll)
+ {
+       int ret;
+       u8 buf[2];
+       /* wake up */
+-      if ((ret = mt312_writereg(i2c, CONFIG, 0x8c)) < 0)
++      if ((ret = mt312_writereg(i2c, CONFIG, (pll == 60 ? 0x88 : 0x8c))) < 0)
+               return ret;
+       /* wait at least 150 usec */
+@@ -252,8 +260,17 @@ static int mt312_init(struct dvb_i2c_bus
+       if ((ret = mt312_reset(i2c, 1)) < 0)
+               return ret;
++// Per datasheet, write correct values. 09/28/03 ACCJr.
++// If we don't do this, we won't get FE_HAS_VITERBI in the VP310.
++      {
++              u8 buf_def[8]={0x14, 0x12, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00};
++
++              if ((ret = mt312_write(i2c, VIT_SETUP, buf_def, sizeof(buf_def))) < 0)
++                      return ret;
++      }
++
+       /* SYS_CLK */
+-      buf[0] = mt312_div(MT312_SYS_CLK * 2, 1000000);
++      buf[0] = mt312_div((pll == 60 ? MT312_LPOWER_SYS_CLK : MT312_SYS_CLK) * 2, 1000000);
+       /* DISEQC_RATIO */
+       buf[1] = mt312_div(MT312_PLL_CLK, 15000 * 4);
+@@ -370,16 +387,18 @@ static int mt312_set_voltage(struct dvb_
+       return mt312_writereg(i2c, DISEQC_MODE, volt_tab[v]);
+ }
+-static int mt312_read_status(struct dvb_i2c_bus *i2c, fe_status_t * s)
++static int mt312_read_status(struct dvb_i2c_bus *i2c, fe_status_t *s, const long id)
+ {
+       int ret;
+-      u8 status[3];
++      u8 status[3], vit_mode;
+       *s = 0;
+       if ((ret = mt312_read(i2c, QPSK_STAT_H, status, sizeof(status))) < 0)
+               return ret;
++      dprintk(KERN_DEBUG "QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x, FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]);
++
+       if (status[0] & 0xc0)
+               *s |= FE_HAS_SIGNAL;    /* signal noise ratio */
+       if (status[0] & 0x04)
+@@ -390,6 +409,16 @@ static int mt312_read_status(struct dvb_
+               *s |= FE_HAS_SYNC;      /* byte align lock */
+       if (status[0] & 0x01)
+               *s |= FE_HAS_LOCK;      /* qpsk lock */
++      // VP310 doesn't have AUTO, so we "implement it here" ACCJr
++      if ((id == ID_VP310) && !(status[0] & 0x01)) {
++              if ((ret = mt312_readreg(i2c, VIT_MODE, &vit_mode)) < 0)
++                      return ret;
++              vit_mode ^= 0x40;
++              if ((ret = mt312_writereg(i2c, VIT_MODE, vit_mode)) < 0)
++                      return ret;
++              if ((ret = mt312_writereg(i2c, GO, 0x01)) < 0)
++                      return ret;
++      }
+       return 0;
+ }
+@@ -422,7 +451,7 @@ static int mt312_read_agc(struct dvb_i2c
+       *signal_strength = agc;
+-      printk(KERN_DEBUG "agc=%08x err_db=%hd\n", agc, err_db);
++      dprintk(KERN_DEBUG "agc=%08x err_db=%hd\n", agc, err_db);
+       return 0;
+ }
+@@ -458,7 +487,7 @@ static int mt312_set_frontend(struct dvb
+                             const long id)
+ {
+       int ret;
+-      u8 buf[5];
++      u8 buf[5], config_val;
+       u16 sr;
+       const u8 fec_tab[10] =
+@@ -467,6 +496,8 @@ static int mt312_set_frontend(struct dvb
+       int (*set_tv_freq)(struct dvb_i2c_bus *i2c, u32 freq, u32 sr);
++      dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency);
++
+       if ((p->frequency < mt312_info.frequency_min)
+           || (p->frequency > mt312_info.frequency_max))
+               return -EINVAL;
+@@ -489,6 +520,22 @@ static int mt312_set_frontend(struct dvb
+       switch (id) {
+       case ID_VP310:
++      // For now we will do this only for the VP310.
++      // It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03
++              if ((ret = mt312_readreg(i2c, CONFIG, &config_val) < 0))
++                      return ret;
++              if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz
++              {
++                      if ((config_val & 0x0c) == 0x08) //We are running 60MHz
++                              if ((ret = mt312_init(i2c, id, (u8) 90)) < 0)
++                                      return ret;
++              }
++              else
++              {
++                      if ((config_val & 0x0c) == 0x0C) //We are running 90MHz
++                              if ((ret = mt312_init(i2c, id, (u8) 60)) < 0)
++                                      return ret;
++              }
+               set_tv_freq = tsa5059_set_tv_freq;
+               break;
+       case ID_MT312:
+@@ -562,7 +609,7 @@ static int mt312_get_symbol_rate(struct 
+               monitor = (buf[0] << 8) | buf[1];
+-              printk(KERN_DEBUG "sr(auto) = %u\n",
++              dprintk(KERN_DEBUG "sr(auto) = %u\n",
+                      mt312_div(monitor * 15625, 4));
+       } else {
+               if ((ret = mt312_writereg(i2c, MON_CTRL, 0x05)) < 0)
+@@ -578,9 +625,9 @@ static int mt312_get_symbol_rate(struct 
+               sym_rat_op = (buf[0] << 8) | buf[1];
+-              printk(KERN_DEBUG "sym_rat_op=%d dec_ratio=%d\n",
++              dprintk(KERN_DEBUG "sym_rat_op=%d dec_ratio=%d\n",
+                      sym_rat_op, dec_ratio);
+-              printk(KERN_DEBUG "*sr(manual) = %lu\n",
++              dprintk(KERN_DEBUG "*sr(manual) = %lu\n",
+                      (((MT312_PLL_CLK * 8192) / (sym_rat_op + 8192)) *
+                       2) - dec_ratio);
+       }
+@@ -675,7 +722,7 @@ static int mt312_ioctl(struct dvb_fronte
+               return -EOPNOTSUPP;
+       case FE_READ_STATUS:
+-              return mt312_read_status(i2c, arg);
++              return mt312_read_status(i2c, arg, (long) fe->data);
+       case FE_READ_BER:
+               return mt312_read_bercnt(i2c, arg);
+@@ -702,7 +749,12 @@ static int mt312_ioctl(struct dvb_fronte
+               return mt312_sleep(i2c);
+       case FE_INIT:
+-              return mt312_init(i2c, (long) fe->data);
++      //For the VP310 we should run at 60MHz when ever possible.
++      //It should be better to run the mt312 ar lower speed when ever possible, but tunning will be slower. ACCJr 09/29/03
++              if ((long)fe->data == ID_MT312)
++                      return mt312_init(i2c, (long) fe->data, (u8) 90);
++              else
++                      return mt312_init(i2c, (long) fe->data, (u8) 60);
+       case FE_RESET:
+               return mt312_reset(i2c, 0);
+@@ -755,6 +807,11 @@ static void __exit mt312_module_exit(voi
+ module_init(mt312_module_init);
+ module_exit(mt312_module_exit);
++#if MT312_DEBUG != 0
++MODULE_PARM(debug,"i");
++MODULE_PARM_DESC(debug, "enable verbose debug messages");
++#endif
++
+ MODULE_DESCRIPTION("MT312 Satellite Channel Decoder Driver");
+ MODULE_AUTHOR("Andreas Oberritter <obi@saftware.de>");
+ MODULE_LICENSE("GPL");
+--- linux-2.6.0/drivers/media/dvb/frontends/nxt6000.c  2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/dvb/frontends/nxt6000.c   2003-12-28 23:22:38.000000000 -0800
+@@ -55,34 +55,21 @@ static struct dvb_frontend_info nxt6000_
+       .symbol_rate_max = 9360000,     /* FIXME */
+       .symbol_rate_tolerance = 4000,
+       .notifier_delay = 0,
+-      .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+-                      FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
+-                      FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
+-                      FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+-                      FE_CAN_TRANSMISSION_MODE_AUTO |
+-                      FE_CAN_GUARD_INTERVAL_AUTO |
+-                      FE_CAN_HIERARCHY_AUTO,
+-
++      .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
+ };
+-#pragma pack(1)
+-
+ struct nxt6000_config {
+-
+       u8 demod_addr;
+       u8 tuner_addr;
+       u8 tuner_type;
+       u8 clock_inversion;
+-
+ };
+-#pragma pack()
+-
+ #define TUNER_TYPE_ALP510     0
+ #define TUNER_TYPE_SP5659     1
+ #define TUNER_TYPE_SP5730     2
+-#define FE2NXT(fe) ((struct nxt6000_config *)&(fe->data))
++#define FE2NXT(fe) ((struct nxt6000_config *)((fe)->data))
+ #define FREQ2DIV(freq) ((freq + 36166667) / 166667)
+ #define dprintk if (debug) printk
+@@ -116,8 +103,10 @@ static u8 nxt6000_read(struct dvb_i2c_bu
+       int ret;
+       u8 b0[] = {reg};
+       u8 b1[] = {0};
+-      struct i2c_msg msgs[] = {{.addr = addr >> 1, .flags = 0, .buf = b0, .len = 1},
+-                                                      {.addr = addr >> 1, .flags = I2C_M_RD, .buf = b1, .len = 1}};
++      struct i2c_msg msgs[] = {
++              {.addr = addr >> 1,.flags = 0,.buf = b0,.len = 1},
++              {.addr = addr >> 1,.flags = I2C_M_RD,.buf = b1,.len = 1}
++      };
+       ret = i2c->xfer(i2c, msgs, 2);
+       
+@@ -394,7 +383,7 @@ static void nxt6000_setup(struct dvb_fro
+       nxt6000_writereg(fe, OFDM_ITB_FREQ_1, 0x06);
+       nxt6000_writereg(fe, OFDM_ITB_FREQ_2, 0x31);
+       nxt6000_writereg(fe, OFDM_CAS_CTL, (0x01 << 7) | (0x02 << 3) | 0x04);
+-      nxt6000_writereg(fe, CAS_FREQ, 0xBB);   // CHECKME
++      nxt6000_writereg(fe, CAS_FREQ, 0xBB);   /* CHECKME */
+       nxt6000_writereg(fe, OFDM_SYR_CTL, 1 << 2);
+       nxt6000_writereg(fe, OFDM_PPM_CTL_1, PPM256);
+       nxt6000_writereg(fe, OFDM_TRL_NOMINALRATE_1, 0x49);
+@@ -414,20 +403,20 @@ static void nxt6000_setup(struct dvb_fro
+ static void nxt6000_dump_status(struct dvb_frontend *fe)
+ {
+-
+       u8 val;
+-//    printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT));
+-//    printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS));
+-//    printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT));
+-//    printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT));
+-//    printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1));
+-//    printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2));
+-//    printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3));
+-//    printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4));
+-//    printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1));
+-//    printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2));
+-
++/*
++      printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT));
++      printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS));
++      printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT));
++      printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT));
++      printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1));
++      printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2));
++      printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3));
++      printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4));
++      printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1));
++      printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2));
++*/
+       printk("NXT6000 status:");
+       val = nxt6000_readreg(fe, RS_COR_STAT);
+@@ -460,13 +449,11 @@ static void nxt6000_dump_status(struct d
+                       break;
+       
+               case 0x03: 
+-              
+                       printk(" VITERBI CODERATE: 5/6,");
++              break;
+               case 0x04: 
+-              
+                       printk(" VITERBI CODERATE: 7/8,");
+-                      
+                       break;
+               default: 
+@@ -503,13 +490,11 @@ static void nxt6000_dump_status(struct d
+                       break;
+       
+               case 0x04:
+-              
+                       printk(" CoreState: WAIT_PPM,");
++              break;
+               case 0x01:
+-              
+                       printk(" CoreState: WAIT_TRL,");
+-                      
+                       break;
+               case 0x05:
+@@ -586,13 +571,11 @@ static void nxt6000_dump_status(struct d
+                       break;
+       
+               case 0x03: 
+-              
+                       printk(" TPSLP: 5/6,");
++              break;
+               case 0x04: 
+-              
+                       printk(" TPSLP: 7/8,");
+-                      
+                       break;
+               default: 
+@@ -622,13 +605,11 @@ static void nxt6000_dump_status(struct d
+                       break;
+       
+               case 0x03: 
+-              
+                       printk(" TPSHP: 5/6,");
++              break;
+               case 0x04: 
+-              
+                       printk(" TPSHP: 7/8,");
+-                      
+                       break;
+               default: 
+@@ -669,7 +650,7 @@ static void nxt6000_dump_status(struct d
+                       
+       }
+       
+-      // Strange magic required to gain access to RF_AGC_STATUS
++      /* Strange magic required to gain access to RF_AGC_STATUS */
+       nxt6000_readreg(fe, RF_AGC_VAL_1);
+       val = nxt6000_readreg(fe, RF_AGC_STATUS);
+       val = nxt6000_readreg(fe, RF_AGC_STATUS);
+@@ -735,21 +716,23 @@ static int nxt6000_ioctl(struct dvb_fron
+       
+               case FE_READ_SIGNAL_STRENGTH:
+               {
+-//                    s16 *signal = (s16 *)arg;
+-
+-//            *signal=(((signed char)readreg(client, 0x16))+128)<<8;
+-
++                      s16 *signal = (s16 *) arg;
++/*
++                      *signal=(((signed char)readreg(client, 0x16))+128)<<8;
++*/
++                      *signal = 0;
+                       return 0;
+                       
+               }
+       
+               case FE_READ_SNR:
+               {
+-//                    s16 *snr = (s16 *)arg;
+-
+-//            *snr=readreg(client, 0x24)<<8;
+-//            *snr|=readreg(client, 0x25);
+-
++                      s16 *snr = (s16 *) arg;
++/*
++                      *snr=readreg(client, 0x24)<<8;
++                      *snr|=readreg(client, 0x25);
++*/
++                      *snr = 0;
+                       break;
+               }
+       
+@@ -831,70 +814,74 @@ static u8 demod_addr_tbl[] = {0x14, 0x18
+ static int nxt6000_attach(struct dvb_i2c_bus *i2c, void **data)
+ {
+-
+       u8 addr_nr;
+       u8 fe_count = 0;
+-      struct nxt6000_config nxt;
++      struct nxt6000_config *pnxt;
+       dprintk("nxt6000: attach\n");
+       
++      pnxt = kmalloc(sizeof(demod_addr_tbl)*sizeof(struct nxt6000_config), GFP_KERNEL);
++      if (NULL == pnxt) {
++              dprintk("nxt6000: no memory for private data.\n");
++              return -ENOMEM;
++      }
++      *data = pnxt;
++
+       for (addr_nr = 0; addr_nr < sizeof(demod_addr_tbl); addr_nr++) {
++              struct nxt6000_config *nxt = &pnxt[addr_nr];
+       
+               if (nxt6000_read(i2c, demod_addr_tbl[addr_nr], OFDM_MSC_REV) != NXT6000ASICDEVICE)
+                       continue;
+               if (pll_write(i2c, demod_addr_tbl[addr_nr], 0xC0, NULL, 0) == 0) {
++                      nxt->tuner_addr = 0xC0;
++                      nxt->tuner_type = TUNER_TYPE_ALP510;
++                      nxt->clock_inversion = 1;
+       
+-                      nxt.tuner_addr = 0xC0;
+-                      nxt.tuner_type = TUNER_TYPE_ALP510;
+-                      nxt.clock_inversion = 1;
+-                      
+-                      dprintk("nxt6000: detected TI ALP510 tuner at 0x%02X\n", nxt.tuner_addr);
++                      dprintk("nxt6000: detected TI ALP510 tuner at 0x%02X\n", nxt->tuner_addr);
+               
+               } else if (pll_write(i2c, demod_addr_tbl[addr_nr], 0xC2, NULL, 0) == 0) {
++                      nxt->tuner_addr = 0xC2;
++                      nxt->tuner_type = TUNER_TYPE_SP5659;
++                      nxt->clock_inversion = 0;
+-                      nxt.tuner_addr = 0xC2;
+-                      nxt.tuner_type = TUNER_TYPE_SP5659;
+-                      nxt.clock_inversion = 0;
+-      
+-                      dprintk("nxt6000: detected MITEL SP5659 tuner at 0x%02X\n", nxt.tuner_addr);
++                      dprintk("nxt6000: detected MITEL SP5659 tuner at 0x%02X\n", nxt->tuner_addr);
+               
+               } else if (pll_write(i2c, demod_addr_tbl[addr_nr], 0xC0, NULL, 0) == 0) {
++                      nxt->tuner_addr = 0xC0;
++                      nxt->tuner_type = TUNER_TYPE_SP5730;
++                      nxt->clock_inversion = 0;
+-                      nxt.tuner_addr = 0xC0;
+-                      nxt.tuner_type = TUNER_TYPE_SP5730;
+-                      nxt.clock_inversion = 0;
+-      
+-                      dprintk("nxt6000: detected SP5730 tuner at 0x%02X\n", nxt.tuner_addr);
++                      dprintk("nxt6000: detected SP5730 tuner at 0x%02X\n", nxt->tuner_addr);
+               
+               } else {
+-
+                       printk("nxt6000: unable to detect tuner\n");
+-
+                       continue;       
+-              
+               }
+               
+-              nxt.demod_addr = demod_addr_tbl[addr_nr];
++              nxt->demod_addr = demod_addr_tbl[addr_nr];
+         
+               dprintk("nxt6000: attached at %d:%d\n", i2c->adapter->num, i2c->id);
+       
+-              dvb_register_frontend(nxt6000_ioctl, i2c, (void *)(*((u32 *)&nxt)), &nxt6000_info);
++              dvb_register_frontend(nxt6000_ioctl, i2c, (void *)nxt, &nxt6000_info);
+               
+               fe_count++;
+       }
+       
+-      return (fe_count > 0) ? 0 : -ENODEV;
++      if (fe_count == 0) {
++              kfree(pnxt);
++              return -ENODEV;
++      }
+       
++      return 0;
+ }
+ static void nxt6000_detach(struct dvb_i2c_bus *i2c, void *data)
+ {
+-
++      struct nxt6000_config *pnxt = (struct nxt6000_config *)data;
+       dprintk("nxt6000: detach\n");
+-
+       dvb_unregister_frontend(nxt6000_ioctl, i2c);
+-      
++      kfree(pnxt);
+ }
+ static __init int nxt6000_init(void)
+--- linux-2.6.0/drivers/media/dvb/frontends/nxt6000.h  2003-06-14 12:17:56.000000000 -0700
++++ 25/drivers/media/dvb/frontends/nxt6000.h   2003-12-28 23:22:38.000000000 -0800
+@@ -1,45 +1,10 @@
+-/**********************************************************************/
+- * DRV6000reg.H
++/*
+  * Public Include File for DRV6000 users
++ * (ie. NxtWave Communications - NXT6000 demodulator driver)
+  *
+  * Copyright (C) 2001 NxtWave Communications, Inc.
+  *
+- * $Log: nxt6000.h,v $
+- * Revision 1.2  2003/01/27 12:32:42  fschirmer
+- * Lots of bugfixes and new features
+- *
+- * Revision 1.1  2003/01/21 18:43:09  fschirmer
+- * Nxt6000 based frontend driver
+- *
+- * Revision 1.1  2003/01/03 02:25:45  obi
+- * alps tdme7 driver
+- *
+- * 
+- *    Rev 1.10   Jun 12 2002 11:28:02   dkoeger
+- * Updated for SA in GUi work
+- * 
+- *    Rev 1.9   Apr 01 2002 10:38:46   dkoeger
+- * Updated for 1.0.31 GUI
+- * 
+- *    Rev 1.8   Mar 11 2002 10:04:56   dkoeger
+- * Updated for 1.0.31 GUI version
+- * 
+- *    Rev 1.5   Dec 07 2001 14:40:40   dkoeger
+- * Updated for 1.0.28 GUI
+- * 
+- *    Rev 1.4   Nov 13 2001 11:09:00   dkoeger
+- * No change.
+- * 
+- *    Rev 1.3   Aug 23 2001 14:21:02   dkoeger
+- * Updated for driver version 2.1.9
+- * 
+- *    Rev 1.2   Jul 09 2001 09:20:04   dkoeger
+- * Updated for 1.0.18
+- * 
+- *    Rev 1.1   Jun 13 2001 16:14:24   dkoeger
+- * Updated to reflect NXT6000 GUI BETA 1.0.11 6/13/2001
+- **********************************************************************/
+-
++ */
+ /*  Nxt6000 Register Addresses and Bit Masks */
+--- linux-2.6.0/drivers/media/dvb/frontends/sp887x.c   2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/dvb/frontends/sp887x.c    2003-12-28 23:22:38.000000000 -0800
+@@ -1,11 +1,39 @@
++/*
++   Driver for the Microtune 7202D Frontend
++*/
++
++/*
++   This driver needs a copy of the Avermedia firmware. The version tested
++   is part of the Avermedia DVB-T 1.3.26.3 Application. If the software is
++   installed in Windows the file will be in the /Program Files/AVerTV DVB-T/
++   directory and is called sc_main.mc. Alternatively it can "extracted" from
++   the install cab files. Copy this file to /etc/dvb/sc_main.mc.
++   With this version of the file the first 10 bytes are discarded and the
++   next 0x4000 loaded. This may change in future versions.
++ */
++#define __KERNEL_SYSCALLS__
++#include <linux/kernel.h>
++#include <linux/vmalloc.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/unistd.h>
++#include <linux/fcntl.h>
++#include <linux/errno.h>
+ #include <linux/i2c.h>
++
+ #include "dvb_frontend.h"
+ #include "dvb_functions.h"
++#ifndef DVB_SP887X_FIRMWARE_FILE
++#define DVB_SP887X_FIRMWARE_FILE "/etc/dvb/sc_main.mc"
++#endif
++
++static char *sp887x_firmware = DVB_SP887X_FIRMWARE_FILE;
+ #if 0
+ #define dprintk(x...) printk(x)
+@@ -39,7 +67,7 @@ struct dvb_frontend_info sp887x_info = {
+               FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_RECOVER
+ };
+-
++static int errno;
+ static
+ int i2c_writebytes (struct dvb_frontend *fe, u8 addr, u8 *buf, u8 len)
+@@ -112,6 +140,7 @@ u16 sp887x_readreg (struct dvb_frontend 
+ static
+ void sp887x_microcontroller_stop (struct dvb_frontend *fe)
+ {
++      dprintk("%s\n", __FUNCTION__);
+       sp887x_writereg(fe, 0xf08, 0x000);
+       sp887x_writereg(fe, 0xf09, 0x000);              
+@@ -123,6 +152,7 @@ void sp887x_microcontroller_stop (struct
+ static
+ void sp887x_microcontroller_start (struct dvb_frontend *fe)
+ {
++      dprintk("%s\n", __FUNCTION__);
+       sp887x_writereg(fe, 0xf08, 0x000);
+       sp887x_writereg(fe, 0xf09, 0x000);              
+@@ -135,6 +165,7 @@ static
+ void sp887x_setup_agc (struct dvb_frontend *fe)
+ {
+       /* setup AGC parameters */
++      dprintk("%s\n", __FUNCTION__);
+       sp887x_writereg(fe, 0x33c, 0x054);
+       sp887x_writereg(fe, 0x33b, 0x04c);
+       sp887x_writereg(fe, 0x328, 0x000);
+@@ -152,8 +183,6 @@ void sp887x_setup_agc (struct dvb_fronte
+ }
+-#include "sp887x_firm.h"
+-
+ #define BLOCKSIZE 30
+ /**
+@@ -162,14 +191,63 @@ void sp887x_setup_agc (struct dvb_fronte
+ static
+ int sp887x_initial_setup (struct dvb_frontend *fe)
+ {
+-      u8 buf [BLOCKSIZE];
++      u8 buf [BLOCKSIZE+2];
++      unsigned char *firmware = NULL;
+       int i;
++      int fd;
++      int filesize;
++      int fw_size;
++      mm_segment_t fs;
++
++      dprintk("%s\n", __FUNCTION__);
+       /* soft reset */
+       sp887x_writereg(fe, 0xf1a, 0x000);
+       sp887x_microcontroller_stop (fe);
++      fs = get_fs();
++
++      // Load the firmware
++      set_fs(get_ds());
++      fd = open(sp887x_firmware, 0, 0);
++      if (fd < 0) {
++              printk(KERN_WARNING "%s: Unable to open firmware %s\n", __FUNCTION__,
++                     sp887x_firmware);
++              return -EIO;
++      }
++      filesize = lseek(fd, 0L, 2);
++      if (filesize <= 0) {
++              printk(KERN_WARNING "%s: Firmware %s is empty\n", __FUNCTION__,
++                     sp887x_firmware);
++              sys_close(fd);
++              return -EIO;
++      }
++
++      fw_size = 0x4000;
++
++      // allocate buffer for it
++      firmware = vmalloc(fw_size);
++      if (firmware == NULL) {
++              printk(KERN_WARNING "%s: Out of memory loading firmware\n",
++                     __FUNCTION__);
++              sys_close(fd);
++              return -EIO;
++      }
++
++      // read it!
++      // read the first 16384 bytes from the file
++      // ignore the first 10 bytes
++      lseek(fd, 10, 0);
++      if (read(fd, firmware, fw_size) != fw_size) {
++              printk(KERN_WARNING "%s: Failed to read firmware\n", __FUNCTION__);
++              vfree(firmware);
++              sys_close(fd);
++              return -EIO;
++      }
++      sys_close(fd);
++      set_fs(fs);
++
+       printk ("%s: firmware upload... ", __FUNCTION__);
+       /* setup write pointer to -1 (end of memory) */
+@@ -179,12 +257,12 @@ int sp887x_initial_setup (struct dvb_fro
+       /* dummy write (wrap around to start of memory) */
+       sp887x_writereg(fe, 0x8f0a, 0x0000);
+-      for (i=0; i<sizeof(sp887x_firm); i+=BLOCKSIZE) {
++      for (i=0; i<fw_size; i+=BLOCKSIZE) {
+               int c = BLOCKSIZE;
+               int err;
+-              if (i+c > sizeof(sp887x_firm))
+-                      c = sizeof(sp887x_firm) - i;
++              if (i+c > fw_size)
++                      c = fw_size - i;
+               /* bit 0x8000 in address is set to enable 13bit mode */
+               /* bit 0x4000 enables multibyte read/write transfers */
+@@ -192,15 +270,18 @@ int sp887x_initial_setup (struct dvb_fro
+               buf[0] = 0xcf;
+               buf[1] = 0x0a;
+-              memcpy(&buf[2], &sp887x_firm[i], c);
++              memcpy(&buf[2], firmware + i, c);
+               if ((err = i2c_writebytes (fe, 0x70, buf, c+2)) < 0) {
+                       printk ("failed.\n");
+                       printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
++                      vfree(firmware);
+                       return err;
+               }
+       }
++      vfree(firmware);
++
+       /* don't write RS bytes between packets */
+       sp887x_writereg(fe, 0xc13, 0x001);
+--- linux-2.6.0/drivers/media/dvb/frontends/stv0299.c  2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/dvb/frontends/stv0299.c   2003-12-28 23:22:38.000000000 -0800
+@@ -9,16 +9,23 @@
+       <holger@convergence.de>,
+       <js@convergence.de>
+     
++
+     Philips SU1278/SH
+-    Copyright (C) 2002 by Peter Schildmann
+-        <peter.schildmann@web.de>
++    Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
++
+     LG TDQF-S001F
+     Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
+                      & Andreas Oberritter <andreas@oberritter.de>
++
++    Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
++
++    Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
++
++
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+@@ -39,6 +46,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/string.h>
++#include <asm/div64.h>
+ #include "dvb_frontend.h"
+ #include "dvb_functions.h"
+@@ -49,6 +57,11 @@
+ #define dprintk(x...)
+ #endif
++static int stv0299_status = 0;
++
++#define STATUS_BER 0
++#define STATUS_UCBLOCKS 1
++
+ /* frontend types */
+ #define UNKNOWN_FRONTEND  -1
+@@ -56,6 +69,7 @@
+ #define ALPS_BSRU6         1
+ #define LG_TDQF_S001F      2
+ #define PHILIPS_SU1278     3
++#define SAMSUNG_TBMU24112IMB    4
+ /* Master Clock = 88 MHz */
+ #define M_CLK (88000000UL) 
+@@ -142,6 +156,51 @@ static u8 init_tab [] = {
+ };
++static u8 init_tab_samsung [] = {
++      0x01, 0x15,
++      0x02, 0x00,
++      0x03, 0x00,
++      0x04, 0x7D,
++      0x05, 0x35,
++      0x06, 0x02,
++      0x07, 0x00,
++      0x08, 0xC3,
++      0x0C, 0x00,
++      0x0D, 0x81,
++      0x0E, 0x23,
++      0x0F, 0x12,
++      0x10, 0x7E,
++      0x11, 0x84,
++      0x12, 0xB9,
++      0x13, 0x88,
++      0x14, 0x89,
++      0x15, 0xC9,
++      0x16, 0x00,
++      0x17, 0x5C,
++      0x18, 0x00,
++      0x19, 0x00,
++      0x1A, 0x00,
++      0x1C, 0x00,
++      0x1D, 0x00,
++      0x1E, 0x00,
++      0x1F, 0x3A,
++      0x20, 0x2E,
++      0x21, 0x80,
++      0x22, 0xFF,
++      0x23, 0xC1,
++      0x28, 0x00,
++      0x29, 0x1E,
++      0x2A, 0x14,
++      0x2B, 0x0F,
++      0x2C, 0x09,
++      0x2D, 0x05,
++      0x31, 0x1F,
++      0x32, 0x19,
++      0x33, 0xFE,
++      0x34, 0x93
++};
++
++
+ static int stv0299_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data)
+ {
+       int ret;
+@@ -169,7 +228,8 @@ static u8 stv0299_readreg (struct dvb_i2
+       ret = i2c->xfer (i2c, msg, 2);
+         
+       if (ret != 2) 
+-              dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
++              dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
++                              __FUNCTION__, reg, ret);
+       return b1[0];
+ }
+@@ -193,18 +253,19 @@ static int stv0299_readregs (struct dvb_
+ static int pll_write (struct dvb_i2c_bus *i2c, u8 addr, u8 *data, int len)
+ {
+       int ret;
+-      u8 rpt1 [] = { 0x05, 0xb5 };  /*  enable i2c repeater on stv0299  */
+-      u8 rpt2 [] = { 0x05, 0x35 };  /*  disable i2c repeater on stv0299  */
+-      struct i2c_msg msg [] = {{ .addr = 0x68, .flags = 0, .buf = rpt1, .len = 2 },
+-                               { addr: addr, .flags = 0, .buf = data, .len = len },
+-                               { .addr = 0x68, .flags = 0, .buf = rpt2, .len = 2 }};
++      struct i2c_msg msg = { addr: addr, .flags = 0, .buf = data, .len = len };
+-      ret = i2c->xfer (i2c, msg, 3);
+-      if (ret != 3)
+-              printk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret);
++      stv0299_writereg(i2c, 0x05, 0xb5);      /*  enable i2c repeater on stv0299  */
+-      return (ret != 3) ? ret : 0;
++      ret =  i2c->xfer (i2c, &msg, 1);
++
++      stv0299_writereg(i2c, 0x05, 0x35);      /*  disable i2c repeater on stv0299  */
++
++      if (ret != 1)
++              dprintk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret);
++
++      return (ret != 1) ? -1 : 0;
+ }
+@@ -213,23 +274,16 @@ static int sl1935_set_tv_freq (struct dv
+       u8 buf[4];
+       u32 div;
+-      u32 ratios[] = { 2000, 1000, 500, 250, 125 };
+-      u8 ratio;
+-
+-      for (ratio = 4; ratio > 0; ratio--)
+-              if ((freq / ratios[ratio]) <= 0x3fff)
+-                      break;
++      div = freq / 125;
+-      div = freq / ratios[ratio];
++      dprintk("%s : freq = %i, div = %i\n", __FUNCTION__, freq, div);
+-      buf[0] = (freq >> 8) & 0x7f;
+-      buf[1] = freq & 0xff;
+-      buf[2] = 0x80 | ratio;
++      buf[0] = (div >> 8) & 0x7f;
++      buf[1] = div & 0xff;
++      buf[2] = 0x84;  // 0xC4
++      buf[3] = 0x08;
+-      if (freq < 1531000)
+-              buf[3] = 0x10;
+-      else
+-              buf[3] = 0x00;
++      if (freq < 1500000) buf[3] |= 0x10;
+       return pll_write (i2c, 0x61, buf, sizeof(buf));
+ }
+@@ -238,21 +292,47 @@ static int sl1935_set_tv_freq (struct dv
+  *   set up the downconverter frequency divisor for a 
+  *   reference clock comparision frequency of 125 kHz.
+  */
+-static int tsa5059_set_tv_freq        (struct dvb_i2c_bus *i2c, u32 freq, int ftype)
++static int tsa5059_set_tv_freq        (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate)
+ {
+-      u8 addr = (ftype == PHILIPS_SU1278SH) ? 0x60 : 0x61;
+-        u32 div = freq / 125;
+-      u8 buf[4] = { (div >> 8) & 0x7f, div & 0xff, 0x84 };
++      u8 addr;
++      u32 div;
++      u8 buf[4];
+       dprintk ("%s: freq %i, ftype %i\n", __FUNCTION__, freq, ftype);
+-      if (ftype == PHILIPS_SU1278SH)
+-              /* activate f_xtal/f_comp signal output */
+-              /* charge pump current C0/C1 = 00 */
+-              buf[3] = 0x20;
+-      else
+-              buf[3] = freq > 1530000 ? 0xc0 : 0xc4;
++      if ((freq < 950000) || (freq > 2150000)) return -EINVAL;
++
++      // setup frequency divisor
++      div = freq / 1000;
++      buf[0] = (div >> 8) & 0x7f;
++      buf[1] = div & 0xff;
++      buf[2] = 0x81 | ((div & 0x18000) >> 10);
++      buf[3] = 0;
++
++      // tuner-specific settings
++      switch(ftype) {
++      case PHILIPS_SU1278SH:
++              addr = 0x60;
++              buf[3] |= 0x20;
++
++              if (srate < 4000000) buf[3] |= 1;
++         
++              if (freq <= 1250000) buf[3] |= 0;
++              else if (freq <= 1550000) buf[3] |= 0x40;
++              else if (freq <= 2050000) buf[3] |= 0x80;
++              else if (freq <= 2150000) buf[3] |= 0xC0;
++              break;
++
++      case ALPS_BSRU6:
++              addr = 0x61;
++              buf[3] |= 0xC0;
++              break;
++
++      default:
++              return -EINVAL;
++      }
++      // charge pump
+       return pll_write (i2c, addr, buf, sizeof(buf));
+ }
+@@ -385,12 +465,14 @@ static int tua6100_set_tv_freq   (struct d
+ static int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate)
+ {
+-      if (ftype == LG_TDQF_S001F)
++      if (ftype == SAMSUNG_TBMU24112IMB)
++              return sl1935_set_tv_freq(i2c, freq, ftype);
++      else if (ftype == LG_TDQF_S001F)
+               return sl1935_set_tv_freq(i2c, freq, ftype);
+       else if (ftype == PHILIPS_SU1278)
+               return tua6100_set_tv_freq(i2c, freq, ftype, srate);
+       else
+-              return tsa5059_set_tv_freq(i2c, freq, ftype);
++              return tsa5059_set_tv_freq(i2c, freq, ftype, srate);
+ }
+ #if 0
+@@ -421,6 +503,19 @@ static int stv0299_init (struct dvb_i2c_
+       dprintk("stv0299: init chip\n");
++      switch(ftype) {
++      case SAMSUNG_TBMU24112IMB:
++              dprintk("%s: init stv0299 chip for Samsung TBMU24112IMB\n", __FUNCTION__);
++
++              for (i=0; i<sizeof(init_tab_samsung); i+=2)
++              {
++                      dprintk("%s: reg == 0x%02x, val == 0x%02x\n", __FUNCTION__, init_tab_samsung[i], init_tab_samsung[i+1]);
++
++                      stv0299_writereg (i2c, init_tab_samsung[i], init_tab_samsung[i+1]);
++              }
++              break;
++
++      default:
+       stv0299_writereg (i2c, 0x01, 0x15);
+       stv0299_writereg (i2c, 0x02, ftype == PHILIPS_SU1278 ? 0x00 : 0x30);
+       stv0299_writereg (i2c, 0x03, 0x00);
+@@ -430,11 +525,23 @@ static int stv0299_init (struct dvb_i2c_
+         /* AGC1 reference register setup */
+       if (ftype == PHILIPS_SU1278SH)
+-        stv0299_writereg (i2c, 0x0f, 0xd2);  /* Iagc = Inverse, m1 = 18 */
++                stv0299_writereg (i2c, 0x0f, 0x92);  /* Iagc = Inverse, m1 = 18 */
+       else if (ftype == PHILIPS_SU1278)
+-        stv0299_writereg (i2c, 0x0f, 0x94);  /* Iagc = Inverse, m1 = 18 */
++                stv0299_writereg (i2c, 0x0f, 0x94);  /* Iagc = Inverse, m1 = 20 */
+       else
+         stv0299_writereg (i2c, 0x0f, 0x52);  /* Iagc = Normal,  m1 = 18 */
++              break;
++      }
++      
++      switch(stv0299_status) {
++      case STATUS_BER:
++              stv0299_writereg(i2c, 0x34, 0x93);
++              break;
++      
++      case STATUS_UCBLOCKS:
++              stv0299_writereg(i2c, 0x34, 0xB3);
++              break;
++      }
+       return 0;
+ }
+@@ -448,6 +555,7 @@ static int stv0299_check_inversion (stru
+               dvb_delay(30);
+               if ((stv0299_readreg (i2c, 0x1b) & 0x98) != 0x98) {
+               u8 val = stv0299_readreg (i2c, 0x0c);
++                      dprintk ("%s : changing inversion\n", __FUNCTION__);
+               return stv0299_writereg (i2c, 0x0c, val ^ 0x01);
+       }
+       }
+@@ -462,21 +570,42 @@ static int stv0299_set_FEC (struct dvb_i
+       switch (fec) {
+       case FEC_AUTO:
++      {
++              dprintk ("%s : FEC_AUTO\n", __FUNCTION__);
+               return stv0299_writereg (i2c, 0x31, 0x1f);
++      }
+       case FEC_1_2:
++      {
++              dprintk ("%s : FEC_1_2\n", __FUNCTION__);
+               return stv0299_writereg (i2c, 0x31, 0x01);
++      }
+       case FEC_2_3:
++      {
++              dprintk ("%s : FEC_2_3\n", __FUNCTION__);
+               return stv0299_writereg (i2c, 0x31, 0x02);
++      }
+       case FEC_3_4:
++      {
++              dprintk ("%s : FEC_3_4\n", __FUNCTION__);
+               return stv0299_writereg (i2c, 0x31, 0x04);
++      }
+       case FEC_5_6:
++      {
++              dprintk ("%s : FEC_5_6\n", __FUNCTION__);
+               return stv0299_writereg (i2c, 0x31, 0x08);
++      }
+       case FEC_7_8:
++      {
++              dprintk ("%s : FEC_7_8\n", __FUNCTION__);
+               return stv0299_writereg (i2c, 0x31, 0x10);
++      }
+       default:
++      {
++              dprintk ("%s : FEC invalid\n", __FUNCTION__);
+               return -EINVAL;
+       }
+ }
++}
+ static fe_code_rate_t stv0299_get_fec (struct dvb_i2c_bus *i2c)
+@@ -606,11 +735,20 @@ static int stv0299_set_tone (struct dvb_
+       switch (tone) {
+       case SEC_TONE_ON:
++      {
++              dprintk("%s: TONE_ON\n", __FUNCTION__);
+               return stv0299_writereg (i2c, 0x08, val | 0x3);
++      }       
+       case SEC_TONE_OFF:
++      {
++              dprintk("%s: TONE_OFF\n", __FUNCTION__);
+               return stv0299_writereg (i2c, 0x08, (val & ~0x3) | 0x02);
++      }
+       default:
++      {
++              dprintk("%s: TONE INVALID\n", __FUNCTION__);
+               return -EINVAL;
++      }
+       };
+ }
+@@ -651,39 +789,60 @@ static int stv0299_set_voltage (struct d
+ }
+-static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate)
++static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate, int tuner_type)
+ {
++      u64 big = srate;
+       u32 ratio;
+-      u32 tmp;
+-      u8 aclk = 0xb4, bclk = 0x51;
++      u8 aclk = 0;
++      u8 bclk = 0;
++      u8 m1;
++
++      if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;
++      switch(tuner_type) {
++      case PHILIPS_SU1278SH:
++              aclk = 0xb5;
++              if (srate < 2000000) bclk = 0x86;
++              else if (srate < 5000000) bclk = 0x89;
++              else if (srate < 15000000) bclk = 0x8f;
++              else if (srate < 45000000) bclk = 0x95;
+-      if (srate > M_CLK)
+-              srate = M_CLK;
+-        if (srate < 500000)
+-              srate = 500000;
+-
+-      if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
+-      if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
+-      if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
+-      if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
+-      if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
++              m1 = 0x14;
++              if (srate < 4000000) m1 = 0x10;
++              break;
+-#define FIN (M_CLK >> 4)
++      case ALPS_BSRU6:
++      default:
++              if (srate <= 1500000) { aclk = 0xb7; bclk = 0x87; }
++              else if (srate <= 3000000) { aclk = 0xb7; bclk = 0x8b; }
++              else if (srate <= 7000000) { aclk = 0xb7; bclk = 0x8f; }
++              else if (srate <= 14000000) { aclk = 0xb7; bclk = 0x93; }
++              else if (srate <= 30000000) { aclk = 0xb6; bclk = 0x93; }
++              else if (srate <= 45000000) { aclk = 0xb4; bclk = 0x91; }
+-      tmp = srate << 4;
+-      ratio = tmp / FIN;
++              m1 = 0x12;
++              break;   
++      }
+         
+-      tmp = (tmp % FIN) << 8;
+-      ratio = (ratio << 8) + tmp / FIN;
++      dprintk("%s : big = 0x%08x%08x\n", __FUNCTION__, (int) ((big>>32) & 0xffffffff),  (int) (big & 0xffffffff) );
+         
+-      tmp = (tmp % FIN) << 8;
+-      ratio = (ratio << 8) + tmp / FIN;
++      big = big << 20;
++
++      dprintk("%s : big = 0x%08x%08x\n", __FUNCTION__, (int) ((big>>32) & 0xffffffff),  (int) (big & 0xffffffff) );
++
++      do_div(big, M_CLK);
++
++      dprintk("%s : big = 0x%08x%08x\n", __FUNCTION__, (int) ((big>>32) & 0xffffffff),  (int) (big & 0xffffffff) );
++
++      ratio = big << 4;
++
++      dprintk("%s : ratio = %i\n", __FUNCTION__, ratio);
+   
+       stv0299_writereg (i2c, 0x13, aclk);
+       stv0299_writereg (i2c, 0x14, bclk);
+       stv0299_writereg (i2c, 0x1f, (ratio >> 16) & 0xff);
+       stv0299_writereg (i2c, 0x20, (ratio >>  8) & 0xff);
+       stv0299_writereg (i2c, 0x21, (ratio      ) & 0xf0);
++      stv0299_writereg (i2c, 0x0f, (stv0299_readreg(i2c, 0x0f) & 0xc0) | m1);
+       return 0;
+ }
+@@ -710,6 +869,9 @@ static int stv0299_get_symbolrate (struc
+       offset = (s32) rtf * (srate / 4096L);
+       offset /= 128;
++      dprintk ("%s : srate = %i\n", __FUNCTION__, srate);
++      dprintk ("%s : ofset = %i\n", __FUNCTION__, offset);
++
+       srate += offset;
+       srate += 1000;
+@@ -725,6 +887,8 @@ static int uni0299_ioctl (struct dvb_fro
+         int tuner_type = (long) fe->data;
+       struct dvb_i2c_bus *i2c = fe->i2c;
++      dprintk ("%s\n", __FUNCTION__);
++
+       switch (cmd) {
+       case FE_GET_INFO:
+               memcpy (arg, &uni0299_info, sizeof(struct dvb_frontend_info));
+@@ -736,7 +900,7 @@ static int uni0299_ioctl (struct dvb_fro
+               u8 signal = 0xff - stv0299_readreg (i2c, 0x18);
+               u8 sync = stv0299_readreg (i2c, 0x1b);
+-              dprintk ("VSTATUS: 0x%02x\n", sync);
++              dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __FUNCTION__, sync);
+               *status = 0;
+@@ -759,8 +923,12 @@ static int uni0299_ioctl (struct dvb_fro
+       }
+         case FE_READ_BER:
++              if (stv0299_status == STATUS_BER) {
+               *((u32*) arg) = (stv0299_readreg (i2c, 0x1d) << 8)
+                              | stv0299_readreg (i2c, 0x1e);
++              } else {
++                      *((u32*) arg) = 0;
++              }
+               break;
+       case FE_READ_SIGNAL_STRENGTH:
+@@ -768,7 +936,7 @@ static int uni0299_ioctl (struct dvb_fro
+               s32 signal =  0xffff - ((stv0299_readreg (i2c, 0x18) << 8)
+                                      | stv0299_readreg (i2c, 0x19));
+-              dprintk ("AGC2I: 0x%02x%02x, signal=0x%04x\n",
++              dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __FUNCTION__,
+                        stv0299_readreg (i2c, 0x18),
+                        stv0299_readreg (i2c, 0x19), (int) signal);
+@@ -787,18 +955,25 @@ static int uni0299_ioctl (struct dvb_fro
+               break;
+       }
+       case FE_READ_UNCORRECTED_BLOCKS: 
+-              *((u32*) arg) = 0;    /* the stv0299 can't measure BER and */
+-              return -EOPNOTSUPP;   /* errors at the same time.... */
++              if (stv0299_status == STATUS_UCBLOCKS) {
++                      *((u32*) arg) = (stv0299_readreg (i2c, 0x1d) << 8)
++                                     | stv0299_readreg (i2c, 0x1e);
++              } else {
++                      *((u32*) arg) = 0;
++              }
++              break;
+         case FE_SET_FRONTEND:
+         {
+               struct dvb_frontend_parameters *p = arg;
++              dprintk ("%s : FE_SET_FRONTEND\n", __FUNCTION__);
++
+               pll_set_tv_freq (i2c, p->frequency, tuner_type,
+                                p->u.qpsk.symbol_rate);
+                 stv0299_set_FEC (i2c, p->u.qpsk.fec_inner);
+-                stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate);
++                stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate, tuner_type);
+               stv0299_writereg (i2c, 0x22, 0x00);
+               stv0299_writereg (i2c, 0x23, 0x00);
+               stv0299_readreg (i2c, 0x23);
+@@ -859,6 +1034,8 @@ static int uni0299_ioctl (struct dvb_fro
+ static long probe_tuner (struct dvb_i2c_bus *i2c)
+ {
++      struct dvb_adapter * adapter = (struct dvb_adapter *) i2c->adapter;
++
+         /* read the status register of TSA5059 */
+       u8 rpt[] = { 0x05, 0xb5 };
+         u8 stat [] = { 0 };
+@@ -875,6 +1052,17 @@ static long probe_tuner (struct dvb_i2c_
+       stv0299_writereg (i2c, 0x02, 0x30);
+       stv0299_writereg (i2c, 0x03, 0x00);
++
++      printk ("%s: try to attach to %s\n", __FUNCTION__, adapter->name);
++
++      if ( strcmp(adapter->name, "Technisat SkyStar2 driver") == 0 )
++      {
++          printk ("%s: setup for tuner Samsung TBMU24112IMB\n", __FILE__);
++
++          return SAMSUNG_TBMU24112IMB;
++      }
++
++
+       if ((ret = i2c->xfer(i2c, msg1, 2)) == 2) {
+               printk ("%s: setup for tuner SU1278/SH\n", __FILE__);
+               return PHILIPS_SU1278SH;
+@@ -961,3 +1149,5 @@ MODULE_DESCRIPTION("Universal STV0299/TS
+ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, Andreas Oberritter");
+ MODULE_LICENSE("GPL");
++MODULE_PARM(stv0299_status, "i");
++MODULE_PARM_DESC(stv0299_status, "Which status value to support (0: BER, 1: UCBLOCKS)");
+--- linux-2.6.0/drivers/media/dvb/frontends/tda1004x.c 2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/media/dvb/frontends/tda1004x.c  2003-12-28 23:22:38.000000000 -0800
+@@ -108,7 +108,7 @@ static struct dvb_frontend_info tda10045
+       .frequency_min = 51000000,
+       .frequency_max = 858000000,
+       .frequency_stepsize = 166667,
+-      .caps = FE_CAN_INVERSION_AUTO |
++      .caps =
+           FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+           FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+           FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+--- linux-2.6.0/drivers/media/dvb/frontends/ves1820.c  2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/dvb/frontends/ves1820.c   2003-12-28 23:22:38.000000000 -0800
+@@ -19,6 +19,8 @@
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */    
++#include <linux/config.h>
++#include <linux/delay.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+@@ -70,7 +72,18 @@ static int verbose;
+ #define GET_TUNER(data) ((u8) (((long) data >> 16) & 0xff))
+ #define GET_DEMOD_ADDR(data) ((u8) (((long) data >> 24) & 0xff))
++#if defined(CONFIG_DBOX2)
++#define XIN 69600000UL
++#define DISABLE_INVERSION(reg0)               do { reg0 &= ~0x20; } while (0)
++#define ENABLE_INVERSION(reg0)                do { reg0 |= 0x20; } while (0)
++#define HAS_INVERSION(reg0)           (reg0 & 0x20)
++#else /* PCI cards */
+ #define XIN 57840000UL
++#define DISABLE_INVERSION(reg0)               do { reg0 |= 0x20; } while (0)
++#define ENABLE_INVERSION(reg0)                do { reg0 &= ~0x20; } while (0)
++#define HAS_INVERSION(reg0)           (!(reg0 & 0x20))
++#endif
++
+ #define FIN (XIN >> 4)
+@@ -209,9 +222,9 @@ static int ves1820_setup_reg0 (struct dv
+       reg0 |= GET_REG0(fe->data) & 0x62;
+       
+       if (INVERSION_ON == inversion)
+-              reg0 &= ~0x20;
++              ENABLE_INVERSION(reg0);
+       else if (INVERSION_OFF == inversion)
+-              reg0 |= 0x20;
++              DISABLE_INVERSION(reg0);
+       
+       ves1820_writereg (fe, 0x00, reg0 & 0xfe);
+         ves1820_writereg (fe, 0x00, reg0 | 0x01);
+@@ -220,7 +233,7 @@ static int ves1820_setup_reg0 (struct dv
+        *  check lock and toggle inversion bit if required...
+        */
+       if (INVERSION_AUTO == inversion && !(ves1820_readreg (fe, 0x11) & 0x08)) {
+-              dvb_delay(10);
++              mdelay(30);
+               if (!(ves1820_readreg (fe, 0x11) & 0x08)) {
+                       reg0 ^= 0x20;
+                       ves1820_writereg (fe, 0x00, reg0 & 0xfe);
+@@ -242,6 +255,10 @@ static int ves1820_init (struct dvb_fron
+         ves1820_writereg (fe, 0, 0);
++#if defined(CONFIG_DBOX2)
++      ves1820_inittab[2] &= ~0x08;
++#endif
++
+       for (i=0; i<53; i++)
+                 ves1820_writereg (fe, i, ves1820_inittab[i]);
+@@ -330,6 +347,10 @@ static int ves1820_set_parameters (struc
+       ves1820_setup_reg0 (fe, reg0x00[real_qam], p->inversion);
++      /* yes, this speeds things up: userspace reports lock in about 8 ms
++         instead of 500 to 1200 ms after calling FE_SET_FRONTEND. */
++      mdelay(30);
++
+       return 0;
+ }
+@@ -419,14 +440,14 @@ static int ves1820_ioctl (struct dvb_fro
+                                       fe->i2c->adapter->num, afc,
+                               -((s32)(p->u.qam.symbol_rate >> 3) * afc >> 7));
+-              p->inversion = reg0 & 0x20 ? INVERSION_OFF : INVERSION_ON;
++              p->inversion = HAS_INVERSION(reg0) ? INVERSION_ON : INVERSION_OFF;
+               p->u.qam.modulation = ((reg0 >> 2) & 7) + QAM_16;
+               p->u.qam.fec_inner = FEC_NONE;
+               p->frequency = ((p->frequency + 31250) / 62500) * 62500;
+-              // To prevent overflow, shift symbol rate first a
+-              // couple of bits.
++              /* To prevent overflow, shift symbol rate first a
++                 couple of bits. */
+               p->frequency -= (s32)(p->u.qam.symbol_rate >> 3) * afc >> 7;
+               break;
+       }
+@@ -462,8 +483,6 @@ static long probe_tuner (struct dvb_i2c_
+               printk ("DVB: VES1820(%d): setup for tuner sp5659c\n", i2c->adapter->num);
+       } else {
+               type = -1;
+-              printk ("DVB: VES1820(%d): unknown PLL, "
+-                      "please report to <linuxdvb@linuxtv.org>!!\n", i2c->adapter->num);
+       }
+       return type;
+@@ -477,13 +496,11 @@ static u8 read_pwm (struct dvb_i2c_bus *
+       struct i2c_msg msg [] = { { .addr = 0x50, .flags = 0, .buf = &b, .len = 1 },
+                        { .addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1 } };
+-      i2c->xfer (i2c, msg, 2);
++      if ((i2c->xfer(i2c, msg, 2) != 2) || (pwm == 0xff))
++              pwm = 0x48;
+       printk("DVB: VES1820(%d): pwm=0x%02x\n", i2c->adapter->num, pwm);
+-      if (pwm == 0xff)
+-              pwm = 0x48;
+-
+       return pwm;
+ }
+@@ -516,8 +533,7 @@ static int ves1820_attach (struct dvb_i2
+       if ((demod_addr = probe_demod_addr(i2c)) < 0)
+               return -ENODEV;
+-      if ((tuner_type = probe_tuner(i2c)) < 0)
+-              return -ENODEV;
++      tuner_type = probe_tuner(i2c);
+       if ((i2c->adapter->num < MAX_UNITS) && pwm[i2c->adapter->num] != -1) {
+               printk("DVB: VES1820(%d): pwm=0x%02x (user specified)\n",
+--- linux-2.6.0/drivers/media/dvb/Kconfig      2003-10-08 15:07:08.000000000 -0700
++++ 25/drivers/media/dvb/Kconfig       2003-12-28 23:22:37.000000000 -0800
+@@ -45,5 +45,9 @@ comment "Supported FlexCopII (B2C2) Adap
+       depends on DVB_CORE && PCI
+ source "drivers/media/dvb/b2c2/Kconfig"
++comment "Supported BT878 Adapters"
++      depends on DVB_CORE && PCI
++source "drivers/media/dvb/bt8xx/Kconfig"
++
+ endmenu
+--- linux-2.6.0/drivers/media/dvb/Makefile     2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/media/dvb/Makefile      2003-12-28 23:22:37.000000000 -0800
+@@ -2,5 +2,5 @@
+ # Makefile for the kernel multimedia device drivers.
+ #
+-obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/
++obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/
+--- linux-2.6.0/drivers/media/dvb/ttpci/av7110.c       2003-10-25 14:45:44.000000000 -0700
++++ 25/drivers/media/dvb/ttpci/av7110.c        2003-12-28 23:22:39.000000000 -0800
+@@ -35,7 +35,6 @@
+ #define __KERNEL_SYSCALLS__
+ #include <linux/module.h>
+-#include <linux/init.h>
+ #include <linux/kmod.h>
+ #include <linux/delay.h>
+ #include <linux/fs.h>
+@@ -43,7 +42,6 @@
+ #include <linux/poll.h>
+ #include <linux/unistd.h>
+ #include <linux/byteorder/swabb.h>
+-#include <linux/slab.h>
+ #include <linux/smp_lock.h>
+ #include <stdarg.h>
+@@ -55,15 +53,15 @@
+ #include <linux/ptrace.h>
+ #include <linux/ioport.h>
+ #include <linux/in.h>
+-#include <linux/slab.h>
+ #include <linux/string.h>
+ #include <linux/pci.h>
+-#include <linux/init.h>
+ #include <linux/vmalloc.h>
+ #include <linux/netdevice.h>
+ #include <linux/inetdevice.h>
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
++#include <linux/firmware.h>
++#include <linux/crc32.h>
+ #include <asm/system.h>
+ #include <asm/bitops.h>
+@@ -108,6 +106,7 @@ static int vidmode=CVBS_RGB_OUT;
+ static int pids_off;
+ static int adac=DVB_ADAC_TI;
+ static int hw_sections = 1;
++static int rgb_on = 0;
+ int av7110_num = 0;
+@@ -118,42 +117,12 @@ int av7110_num = 0;
+  * DEBI functions
+  ****************************************************************************/
++#define wait_for_debi_done(x) \
++       saa7146_wait_for_debi_done(x->dev) \
++
+ /* This DEBI code is based on the Stradis driver 
+    by Nathan Laredo <laredo@gnu.org> */
+-static int wait_for_debi_done(struct av7110 *av7110)
+-{
+-      struct saa7146_dev *dev = av7110->dev;
+-      int start;
+-
+-      /* wait for registers to be programmed */
+-      start = jiffies;
+-      while (1) {
+-                if (saa7146_read(dev, MC2) & 2)
+-                        break;
+-              if (jiffies-start > HZ/20) {
+-                      printk ("%s: timed out while waiting for registers "
+-                              "getting programmed\n", __FUNCTION__);
+-                      return -ETIMEDOUT;
+-              }
+-      }
+-
+-      /* wait for transfer to complete */
+-      start = jiffies;
+-      while (1) {
+-              if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
+-                      break;
+-              saa7146_read(dev, MC2);
+-              if (jiffies-start > HZ/4) {
+-                      printk ("%s: timed out while waiting for transfer "
+-                              "completion\n", __FUNCTION__);
+-                      return -ETIMEDOUT;
+-              }
+-      }
+-
+-      return 0;
+-}
+-
+ static int debiwrite(struct av7110 *av7110, u32 config, 
+                      int addr, u32 val, int count)
+ {
+@@ -375,7 +344,7 @@ static int record_cb(struct dvb_filter_p
+ {
+         struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) p2t->priv;
+-      DEB_EE(("struct dvb_filter_pes2ts:%p\n",p2t));
++//    DEB_EE(("struct dvb_filter_pes2ts:%p\n",p2t));
+         if (!(dvbdmxfeed->ts_type & TS_PACKET)) 
+                 return 0;
+@@ -385,14 +354,14 @@ static int record_cb(struct dvb_filter_p
+                 return dvbdmxfeed->cb.ts(buf, len, 0, 0, 
+                                          &dvbdmxfeed->feed.ts, DMX_OK); 
+         else
+-                return dvb_filter_pes2ts(p2t, buf, len);
++                return dvb_filter_pes2ts(p2t, buf, len, 1);
+ }
+ static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
+ {
+         struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) priv;
+-      DEB_EE(("dvb_demux_feed:%p\n",dvbdmxfeed));
++//    DEB_EE(("dvb_demux_feed:%p\n",dvbdmxfeed));
+         
+         dvbdmxfeed->cb.ts(data, 188, 0, 0,
+                           &dvbdmxfeed->feed.ts,
+@@ -886,10 +855,10 @@ static void gpioirq (unsigned long data)
+         txbuf=irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
+         len=(av7110->debilen+3)&(~3);
+-        DEB_D(("GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen));
++//        DEB_D(("GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen));
+         print_time("gpio");
+-        DEB_D(("GPIO0 irq %02x\n", av7110->debitype&0xff));        
++//       DEB_D(("GPIO0 irq %02x\n", av7110->debitype&0xff));        
+         switch (av7110->debitype&0xff) {
+         case DATA_TS_PLAY:
+@@ -2002,8 +1971,6 @@ static u8 bootcode[] = {
+         0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x04, 0x00,
+ };
+-#include "av7110_firm.h"
+-
+ static int bootarm(struct av7110 *av7110)
+ {
+       struct saa7146_dev *dev= av7110->dev;
+@@ -2056,7 +2023,7 @@ static int bootarm(struct av7110 *av7110
+         
+         DEB_D(("bootarm: load dram code\n"));
+-      if (load_dram(av7110, (u32 *)Root, sizeof(Root))<0)
++      if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root)<0)
+               return -1;
+       saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
+@@ -2064,7 +2031,7 @@ static int bootarm(struct av7110 *av7110
+         
+         DEB_D(("bootarm: load dpram code\n"));
+-      mwdebi(av7110, DEBISWAB, DPRAM_BASE, Dpram, sizeof(Dpram));
++      mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);
+       wait_for_debi_done(av7110);
+@@ -2706,9 +2673,9 @@ static int tuner_set_tv_freq (struct saa
+       buf[1] = div & 0xff;
+       buf[2] = 0x8e;
+-      if (freq < (u32) (16*168.25) ) 
++      if (freq < (u32) 16*168.25 )
+               config = 0xa0;
+-      else if (freq < (u32) (16*447.25)) 
++      else if (freq < (u32) 16*447.25)
+               config = 0x90;
+       else
+               config = 0x30;
+@@ -4294,8 +4261,10 @@ static void av7110_before_after_tune (fe
+                         av7110->pids[DMX_PES_TELETEXT], 0, 
+                         av7110->pids[DMX_PES_PCR]);
+               outcom(av7110, COMTYPE_PIDFILTER, Scan, 0);
+-      } else 
++      } else {
+               SetPIDs(av7110, 0, 0, 0, 0, 0);
++              outcom(av7110, COMTYPE_PIDFILTER, FlushTSQueue, 0);
++      }
+         up(&av7110->pid_mutex);
+ }
+@@ -4531,29 +4500,98 @@ static struct saa7146_ext_vv av7110_vv_d
+ static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
+ {
++      const struct firmware *fw;
+       struct av7110 *av7110 = NULL;
+       int ret = 0;
+-      
++      u32 crc = 0, len = 0;
++      unsigned char *ptr;
++              
++      DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
++
++      /* request the av7110 firmware, this will block until someone uploads it */
++      ret = request_firmware(&fw, "dvb-ttpci-01.fw", &dev->pci->dev);
++      if ( 0 != ret ) {
++              printk("dvb-ttpci: cannot request firmware!\n");
++              return -EINVAL;
++      }
++
++      if (fw->size <= 200000) {
++              printk("dvb-ttpci: this firmware is way too small.\n");
++              return -EINVAL;
++      }
++
++      /* prepare the av7110 device struct */
+       if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) {
+               printk ("%s: out of memory!\n", __FUNCTION__);
+               return -ENOMEM;
+       }
+-
+       memset(av7110, 0, sizeof(struct av7110));
++      
++      /* check if the firmware is available */
++      av7110->bin_fw = (unsigned char*)vmalloc(fw->size);
++      if (NULL == av7110->bin_fw) {
++              DEB_D(("out of memory\n"));
++              kfree(av7110);
++              return -ENOMEM;
++      }
++      memcpy(av7110->bin_fw, fw->data, fw->size);
++      av7110->size_fw = fw->size;
++      /* check for firmware magic */
++      ptr = av7110->bin_fw;
++      if (ptr[0] != 'A' || ptr[1] != 'V' || 
++          ptr[2] != 'F' || ptr[3] != 'W') {
++              printk("dvb-ttpci: this is not an av7110 firmware\n");
++              goto fw_error;
++      }
++      ptr += 4;
++
++      /* check dpram file */
++      crc = ntohl(*(u32*)ptr);
++      ptr += 4;
++      len = ntohl(*(u32*)ptr);
++      ptr += 4;
++      if (len >= 512) {
++              printk("dvb-ttpci: dpram file is way to big.\n");
++              goto fw_error;
++      }
++      if( crc != crc32_le(0,ptr,len)) {
++              printk("dvb-ttpci: crc32 of dpram file does not match.\n");
++              goto fw_error;
++      }
++      av7110->bin_dpram = ptr;
++      av7110->size_dpram = len;
++      ptr += len;
++      
++      /* check root file */
++      crc = ntohl(*(u32*)ptr);
++      ptr += 4;
++      len = ntohl(*(u32*)ptr);
++      ptr += 4;
++      
++      if (len <= 200000 || len >= 300000 || len > ((av7110->bin_fw+av7110->size_fw)-ptr) ) {
++              printk("dvb-ttpci: root file has strange size (%d). aborting.\n",len);
++              goto fw_error;
++      }
++      if( crc != crc32_le(0,ptr,len)) {
++              printk("dvb-ttpci: crc32 of dpram file does not match.\n");
++              goto fw_error;
++      }
++      av7110->bin_root = ptr;
++      av7110->size_root = len;
++      
++      /* go on with regular device initialization */
+       av7110->card_name = (char*)pci_ext->ext_priv;
++      av7110->dev=(struct saa7146_dev *)dev;
+       (struct av7110*)dev->ext_priv = av7110;
+-      DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
+-
+-      av7110->dev=(struct saa7146_dev *)dev;
+       dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name);
+       /* the Siemens DVB needs this if you want to have the i2c chips
+          get recognized before the main driver is fully loaded */
+       saa7146_write(dev, GPIO_CTRL, 0x500000);
+-      saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_3200);
++      saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
+       av7110->i2c_bus = dvb_register_i2c_bus (master_xfer, dev,
+                                               av7110->dvb_adapter, 0);
+@@ -4571,7 +4609,7 @@ static int av7110_attach (struct saa7146
+       /* set dd1 stream a & b */
+               saa7146_write(dev, DD1_STREAM_B, 0x00000000);
+-      saa7146_write(dev, DD1_INIT, 0x02000000);
++      saa7146_write(dev, DD1_INIT, 0x03000000);
+       saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+       /* upload all */
+@@ -4729,7 +4767,7 @@ static int av7110_attach (struct saa7146
+               memcpy(standard,dvb_standard,sizeof(struct saa7146_standard)*2);
+               /* set dd1 stream a & b */
+                       saa7146_write(dev, DD1_STREAM_B, 0x00000000);
+-              saa7146_write(dev, DD1_INIT, 0x02000700);
++              saa7146_write(dev, DD1_INIT, 0x03000700);
+               saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
+       }
+       else if (dev->pci->subsystem_vendor == 0x110a) {
+@@ -4747,7 +4785,8 @@ static int av7110_attach (struct saa7146
+               // switch DVB SCART on
+               outcom(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
+               outcom(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
+-              //saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
++              if (rgb_on)
++                      saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
+               //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
+       }
+       
+@@ -4786,6 +4825,7 @@ static int av7110_attach (struct saa7146
+       }       
+       printk(KERN_INFO "av7110: found av7110-%d.\n",av7110_num);
++      av7110->device_initialized = 1;
+       av7110_num++;
+         return 0;
+@@ -4809,12 +4849,20 @@ err:
+       dvb_unregister_adapter (av7110->dvb_adapter);
+       return ret;
++fw_error:
++      vfree(av7110->bin_fw);
++      kfree(av7110);
++      return -EINVAL;
+ }
+ static int av7110_detach (struct saa7146_dev* saa)
+ {
+       struct av7110 *av7110 = (struct av7110*)saa->ext_priv;
+       DEB_EE(("av7110: %p\n",av7110));
++      
++      if( 0 == av7110->device_initialized ) {
++              return 0;
++      }
+       saa7146_unregister_device(&av7110->v4l_dev, saa);
+       if (2 == av7110->has_analog_tuner) {
+@@ -4845,11 +4893,13 @@ static int av7110_detach (struct saa7146
+       dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id);
+       dvb_unregister_adapter (av7110->dvb_adapter);
++      av7110_num--;
++      if (NULL != av7110->bin_fw ) {
++              vfree(av7110->bin_fw);
++      }
+       kfree (av7110);
+-
+       saa->ext_priv = NULL;
+-      av7110_num--;
+-      
++
+       return 0;
+ }
+@@ -4858,7 +4908,7 @@ static void av7110_irq(struct saa7146_de
+ {
+       struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
+-      DEB_INT(("dev: %p, av7110: %p\n",dev,av7110));
++//    DEB_INT(("dev: %p, av7110: %p\n",dev,av7110));
+       if (*isr & MASK_19)
+               tasklet_schedule (&av7110->debi_tasklet);
+@@ -4887,7 +4937,7 @@ static struct saa7146_standard standard[
+ static struct saa7146_standard analog_standard[] = {
+       {
+               .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
+-              .v_offset       = 0x18, .v_field        = 288,          .v_calc = 576,
++              .v_offset       = 0x18 /* 0 */ ,        .v_field        = 288,          .v_calc = 576,
+               .h_offset       = 0x08, .h_pixels       = 708,          .h_calc = 709,
+               .v_max_out      = 576,  .h_max_out      = 768,
+       }, {
+@@ -4975,7 +5025,7 @@ static struct saa7146_ext_vv av7110_vv_d
+       .inputs         = 1,
+       .audios         = 1,
+       .capabilities   = 0,
+-      .flags          = SAA7146_EXT_SWAP_ODD_EVEN,
++      .flags          = 0, 
+       .stds           = &standard[0],
+       .num_stds       = sizeof(standard)/sizeof(struct saa7146_standard),
+@@ -5002,6 +5052,7 @@ static struct saa7146_ext_vv av7110_vv_d
+ static struct saa7146_extension av7110_extension = {
+       .name           = "dvb\0",
++      .flags          = SAA7146_I2C_SHORT_DELAY,
+       .module         = THIS_MODULE,
+       .pci_tbl        = &pci_tbl[0],
+@@ -5054,4 +5105,6 @@ MODULE_PARM(adac,"i");
+ MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
+ MODULE_PARM(hw_sections, "i");
+ MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
+-
++MODULE_PARM(rgb_on, "i");
++MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
++              " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/media/dvb/ttpci/av7110.c.orig   2003-12-28 23:22:39.000000000 -0800
+@@ -0,0 +1,5030 @@
++/*
++ * av7110.c: driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB)
++ *
++ * Copyright (C) 1999-2002 Ralph  Metzler 
++ *                       & Marcus Metzler for convergence integrated media GmbH
++ *
++ * originally based on code by:
++ * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ * 
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ * 
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
++ * 
++ *
++ * the project's page is at http://www.linuxtv.org/dvb/
++ */
++
++#define NEW_CI 1
++
++/* for debugging ARM communication: */
++//#define COM_DEBUG
++
++#define __KERNEL_SYSCALLS__
++#include <linux/module.h>
++#include <linux/kmod.h>
++#include <linux/delay.h>
++#include <linux/fs.h>
++#include <linux/timer.h>
++#include <linux/poll.h>
++#include <linux/unistd.h>
++#include <linux/byteorder/swabb.h>
++#include <linux/smp_lock.h>
++#include <stdarg.h>
++
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/interrupt.h>
++#include <linux/ptrace.h>
++#include <linux/ioport.h>
++#include <linux/in.h>
++#include <linux/string.h>
++#include <linux/pci.h>
++#include <linux/vmalloc.h>
++#include <linux/netdevice.h>
++#include <linux/inetdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++
++#include <asm/system.h>
++#include <asm/bitops.h>
++#include <asm/io.h>
++#include <asm/dma.h>
++#include <asm/semaphore.h>
++
++#include <linux/dvb/frontend.h>
++
++#include "dvb_i2c.h"
++#include "dvb_frontend.h"
++#include "dvb_functions.h"
++
++
++#if 1 
++      #define DEBUG_VARIABLE av7110_debug
++#else
++      #define DEB_S(x) 
++      #define DEB_D(x) 
++      #define DEB_EE(x)
++#endif
++
++#include "ttpci-eeprom.h"
++#include "av7110.h"
++#include "av7110_ipack.h"
++
++static int AV_StartPlay(struct av7110 *av7110, int av);
++static void restart_feeds(struct av7110 *av7110);
++static int bootarm(struct av7110 *av7110);
++static inline int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val);
++static inline u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg);
++static int  outcom(struct av7110 *av7110, int type, int com, int num, ...);
++static void SetMode(struct av7110 *av7110, int mode);
++static void dvb_video_add_event (struct av7110 *av7110, struct video_event *event);
++
++void pes_to_ts(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p);
++void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, struct dvb_demux_feed *feed);
++
++static int av7110_debug = 0;
++
++static int vidmode=CVBS_RGB_OUT;
++static int pids_off;
++static int adac=DVB_ADAC_TI;
++static int hw_sections = 1;
++static int rgb_on = 0;
++
++int av7110_num = 0;
++
++#define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000)
++#define FW_VERSION(arm_app)       ((arm_app) & 0x0000FFFF)
++
++/****************************************************************************
++ * DEBI functions
++ ****************************************************************************/
++
++#define wait_for_debi_done(x) \
++       saa7146_wait_for_debi_done(x->dev) \
++
++/* This DEBI code is based on the Stradis driver 
++   by Nathan Laredo <laredo@gnu.org> */
++
++static int debiwrite(struct av7110 *av7110, u32 config, 
++                     int addr, u32 val, int count)
++{
++        struct saa7146_dev *dev = av7110->dev;
++      u32 cmd;
++
++      if (count <= 0 || count > 32764)
++              return -1;
++      if (wait_for_debi_done(av7110) < 0)
++              return -1;
++      saa7146_write(dev, DEBI_CONFIG, config);
++      if (count <= 4)         /* immediate transfer */
++              saa7146_write(dev, DEBI_AD, val );
++      else                    /* block transfer */
++              saa7146_write(dev, DEBI_AD, av7110->debi_bus);
++      saa7146_write(dev, DEBI_COMMAND, (cmd = (count << 17) | (addr & 0xffff)));
++      saa7146_write(dev, MC2, (2 << 16) | 2);
++      return 0;
++}
++
++static u32 debiread(struct av7110 *av7110, u32 config, int addr, int count)
++{
++        struct saa7146_dev *dev = av7110->dev;
++      u32 result = 0;
++
++      if (count > 32764 || count <= 0)
++              return 0;
++      if (wait_for_debi_done(av7110) < 0)
++              return 0;
++      saa7146_write(dev, DEBI_AD, av7110->debi_bus);
++      saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff));
++
++      saa7146_write(dev, DEBI_CONFIG, config);
++      saa7146_write(dev, MC2, (2 << 16) | 2);
++      if (count > 4)  
++              return count;
++      wait_for_debi_done(av7110);
++      result = saa7146_read(dev, DEBI_AD);
++        result &= (0xffffffffUL >> ((4-count)*8));
++      return result;
++}
++
++
++/* DEBI during interrupt */
++/* single word writes */
++static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
++{
++        debiwrite(av7110, config, addr, val, count);
++}
++
++/* buffer writes */
++static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, char *val, int count)
++{
++      memcpy(av7110->debi_virt, val, count);
++        debiwrite(av7110, config, addr, 0, count);
++}
++
++
++static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
++{
++        u32 res;
++
++        res=debiread(av7110, config, addr, count);
++        if (count<=4) 
++                memcpy(av7110->debi_virt, (char *) &res, count);
++        return res;
++}
++
++/* DEBI outside interrupts, only for count<=4! */
++
++static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
++{
++        unsigned long flags;
++
++        spin_lock_irqsave(&av7110->debilock, flags);
++        debiwrite(av7110, config, addr, val, count);
++        spin_unlock_irqrestore(&av7110->debilock, flags);
++}
++
++static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count)
++{
++        unsigned long flags;
++        u32 res;
++
++        spin_lock_irqsave(&av7110->debilock, flags);
++        res=debiread(av7110, config, addr, count);
++        spin_unlock_irqrestore(&av7110->debilock, flags);
++        return res;
++}
++
++
++static inline char chtrans(char c)
++{
++        if (c<32 || c>126)
++                c=0x20;
++        return c;
++}
++
++
++/* handle mailbox registers of the dual ported RAM */
++
++static inline void ARM_ResetMailBox(struct av7110 *av7110)
++{
++        unsigned long flags;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        spin_lock_irqsave(&av7110->debilock, flags);
++        debiread(av7110, DEBINOSWAP, IRQ_RX, 2);
++        //printk("dvb: IRQ_RX=%d\n", debiread(av7110, DEBINOSWAP, IRQ_RX, 2));
++        debiwrite(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
++        spin_unlock_irqrestore(&av7110->debilock, flags);
++}
++
++static inline void ARM_ClearMailBox(struct av7110 *av7110)
++{
++        iwdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
++}
++
++static inline void ARM_ClearIrq(struct av7110 *av7110)
++{
++      irdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2);
++}
++
++static void reset_arm(struct av7110 *av7110)
++{
++        saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);
++
++        /* Disable DEBI and GPIO irq */
++      IER_DISABLE(av7110->dev, (MASK_19 | MASK_03));
++//        saa7146_write(av7110->dev, IER, 
++//                      saa7146_read(av7110->dev, IER) & ~(MASK_19 | MASK_03));
++        saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03));
++
++        mdelay(800);
++        saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI);
++        mdelay(800);
++
++        ARM_ResetMailBox(av7110); 
++
++        saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03));
++
++      IER_ENABLE(av7110->dev, MASK_03);
++//        saa7146_write(av7110->dev, IER, 
++//                      saa7146_read(av7110->dev, IER) | MASK_03 );
++
++        av7110->arm_ready=1;
++        printk("av7110: ARM RESET\n");
++}
++
++static void recover_arm(struct av7110 *av7110)
++{
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (current->files)
++                bootarm(av7110);
++        else {
++                printk("OOPS, no current->files\n");
++                reset_arm(av7110);
++        }
++
++        dvb_delay(100); 
++        restart_feeds(av7110);
++        outcom(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
++}
++
++static void arm_error(struct av7110 *av7110)
++{
++      DEB_EE(("av7110: %p\n",av7110));
++
++        av7110->arm_errors++;
++        av7110->arm_ready=0;
++        recover_arm(av7110);
++}
++
++static int arm_thread(void *data)
++{
++      struct av7110 *av7110 = data;
++        u16 newloops = 0;
++
++      DEB_EE(("av7110: %p\n",av7110));
++      
++      dvb_kernel_thread_setup ("arm_mon");
++      av7110->arm_thread = current;
++
++      while (!av7110->arm_rmmod && !signal_pending(current)) {
++                interruptible_sleep_on_timeout(&av7110->arm_wait, 5*HZ);
++
++                if (!av7110->arm_ready)
++                        continue;
++
++                if (down_interruptible(&av7110->dcomlock))
++                        break;
++
++                newloops=rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
++                up(&av7110->dcomlock);
++
++                if (newloops==av7110->arm_loops) {
++                        printk(KERN_ERR "av7110%d: ARM crashed!\n",
++                              av7110->dvb_adapter->num);
++
++                      arm_error(av7110);
++
++                        if (down_interruptible(&av7110->dcomlock))
++                                break;
++
++                        newloops=rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2)-1;
++                        up(&av7110->dcomlock);
++                }
++                av7110->arm_loops=newloops;
++      }
++
++      av7110->arm_thread = NULL;
++      return 0;
++}
++
++
++static int record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
++{
++        struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) p2t->priv;
++
++//    DEB_EE(("struct dvb_filter_pes2ts:%p\n",p2t));
++
++        if (!(dvbdmxfeed->ts_type & TS_PACKET)) 
++                return 0;
++      if (buf[3]==0xe0)        // video PES do not have a length in TS
++                buf[4]=buf[5]=0;
++        if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) 
++                return dvbdmxfeed->cb.ts(buf, len, 0, 0, 
++                                         &dvbdmxfeed->feed.ts, DMX_OK); 
++        else
++                return dvb_filter_pes2ts(p2t, buf, len, 1);
++}
++
++static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
++{
++        struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) priv;
++
++//    DEB_EE(("dvb_demux_feed:%p\n",dvbdmxfeed));
++        
++        dvbdmxfeed->cb.ts(data, 188, 0, 0,
++                          &dvbdmxfeed->feed.ts,
++                          DMX_OK); 
++        return 0;
++}
++
++static int AV_StartRecord(struct av7110 *av7110, int av,
++               struct dvb_demux_feed *dvbdmxfeed)
++{
++        struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
++  
++      DEB_EE(("av7110: %p, dvb_demux_feed:%p\n",av7110,dvbdmxfeed));
++
++        if (av7110->playing||(av7110->rec_mode&av))
++                return -EBUSY;
++        outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0);
++        dvbdmx->recording=1;
++        av7110->rec_mode|=av;
++
++        switch (av7110->rec_mode) {
++        case RP_AUDIO:
++                dvb_filter_pes2ts_init (&av7110->p2t[0],
++                                      dvbdmx->pesfilter[0]->pid,
++                                      dvb_filter_pes2ts_cb,
++                                      (void *)dvbdmx->pesfilter[0]);
++                outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
++                break;
++
++      case RP_VIDEO:
++                dvb_filter_pes2ts_init (&av7110->p2t[1],
++                                      dvbdmx->pesfilter[1]->pid,
++                                      dvb_filter_pes2ts_cb,
++                                      (void *)dvbdmx->pesfilter[1]);
++                outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
++                break;
++
++      case RP_AV:
++                dvb_filter_pes2ts_init (&av7110->p2t[0],
++                                      dvbdmx->pesfilter[0]->pid,
++                                      dvb_filter_pes2ts_cb,
++                                      (void *)dvbdmx->pesfilter[0]);
++                dvb_filter_pes2ts_init (&av7110->p2t[1],
++                                      dvbdmx->pesfilter[1]->pid,
++                                      dvb_filter_pes2ts_cb,
++                                      (void *)dvbdmx->pesfilter[1]);
++                outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
++                break;
++        }
++        return 0;
++}
++
++static int AV_StartPlay(struct av7110 *av7110, int av)
++{
++      DEB_EE(("av7110: %p\n",av7110));
++      
++        if (av7110->rec_mode)
++                return -EBUSY;
++        if (av7110->playing&av)
++                return -EBUSY;
++
++        outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0);
++
++        if (av7110->playing == RP_NONE) {
++                av7110_ipack_reset(&av7110->ipack[0]);
++                av7110_ipack_reset(&av7110->ipack[1]);
++        }
++
++        av7110->playing|=av;
++        switch (av7110->playing) {
++        case RP_AUDIO:
++                outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
++                break;
++        case RP_VIDEO:
++                outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
++                av7110->sinfo=0;
++                break;
++        case RP_AV:
++                av7110->sinfo=0;
++                outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
++                break;
++        }
++        return av7110->playing;
++}
++
++static void AV_Stop(struct av7110 *av7110, int av)
++{
++      DEB_EE(("av7110: %p\n",av7110));
++
++      if (!(av7110->playing&av) && !(av7110->rec_mode&av))
++                return;
++
++        outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0);
++        if (av7110->playing) {
++                av7110->playing&=~av;
++                switch (av7110->playing) {
++                case RP_AUDIO:
++                        outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
++                        break;
++                case RP_VIDEO:
++                        outcom(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
++                        break;
++                case RP_NONE:
++                        SetMode(av7110, av7110->vidmode);
++                        break;
++                }
++        } else {
++                av7110->rec_mode&=~av;
++                switch (av7110->rec_mode) {
++                case RP_AUDIO:
++                        outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
++                        break;
++                case RP_VIDEO:
++                        outcom(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
++                        break;
++                case RP_NONE:
++                        break;
++                }
++        }
++}
++
++/**
++ *  Hack! we save the last av7110 ptr. This should be ok, since
++ *  you rarely will use more then one IR control. 
++ *
++ *  If we want to support multiple controls we would have to do much more...
++ */
++void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config)
++{
++      static struct av7110 *last;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++      if (!av7110)
++              av7110 = last;
++      else
++              last = av7110;
++
++      if (av7110) {
++              outcom(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
++              av7110->ir_config = ir_config;
++      }
++}
++
++static void (*irc_handler)(u32);
++
++void av7110_register_irc_handler(void (*func)(u32)) 
++{
++        //DEB_EE(("registering %08x\n",func));
++        irc_handler = func;
++}
++
++void av7110_unregister_irc_handler(void (*func)(u32)) 
++{
++        //DEB_EE(("unregistering %08x\n",func));
++        irc_handler = NULL;
++}
++
++void run_handlers(unsigned long ircom) 
++{
++        if (irc_handler != NULL)
++                (*irc_handler)((u32) ircom);
++}
++
++DECLARE_TASKLET(irtask,run_handlers,0);
++
++void IR_handle(struct av7110 *av7110, u32 ircom)
++{
++      DEB_S(("av7110: ircommand = %08x\n", ircom));
++        irtask.data = (unsigned long) ircom;
++        tasklet_schedule(&irtask);
++}
++
++/****************************************************************************
++ * IRQ handling
++ ****************************************************************************/
++
++void CI_handle(struct av7110 *av7110, u8 *data, u16 len) 
++{
++        //CI_out(av7110, data, len);
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (len<3)
++                return;
++        switch (data[0]) {
++        case CI_MSG_CI_INFO:
++                if (data[2]!=1 && data[2]!=2)
++                        break;
++                switch (data[1]) {
++                case 0:
++                        av7110->ci_slot[data[2]-1].flags=0;
++                        break;
++                case 1:
++                        av7110->ci_slot[data[2]-1].flags|=CA_CI_MODULE_PRESENT;
++                        break;
++                case 2:
++                        av7110->ci_slot[data[2]-1].flags|=CA_CI_MODULE_READY;
++                        break;
++                }
++                break;
++        case CI_SWITCH_PRG_REPLY:
++                //av7110->ci_stat=data[1];
++                break;
++        default:
++                break;
++        }
++
++}
++
++static inline int DvbDmxFilterCallback(u8 * buffer1, size_t buffer1_len,
++                     u8 * buffer2, size_t buffer2_len,
++                     struct dvb_demux_filter *dvbdmxfilter,
++                     enum dmx_success success,
++                     struct av7110 *av7110)
++{
++      DEB_INT(("av7110: %p\n",av7110));
++
++        if (!dvbdmxfilter->feed->demux->dmx.frontend)
++                return 0;
++        if (dvbdmxfilter->feed->demux->dmx.frontend->source==DMX_MEMORY_FE)
++                return 0;
++        
++        switch(dvbdmxfilter->type) {
++        case DMX_TYPE_SEC:
++                if ((((buffer1[1]<<8)|buffer1[2])&0xfff)+3!=buffer1_len)
++                        return 0;
++                if (dvbdmxfilter->doneq) {
++                        struct dmx_section_filter *filter=&dvbdmxfilter->filter;
++                        int i;
++                        u8 xor, neq=0;
++                        
++                        for (i=0; i<DVB_DEMUX_MASK_MAX; i++) {
++                                xor=filter->filter_value[i]^buffer1[i];
++                                neq|=dvbdmxfilter->maskandnotmode[i]&xor;
++                        }
++                        if (!neq)
++                                return 0;
++                }
++                return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len,
++                                                buffer2, buffer2_len,
++                                                &dvbdmxfilter->filter,
++                                                DMX_OK); 
++        case DMX_TYPE_TS:
++                if (!(dvbdmxfilter->feed->ts_type & TS_PACKET)) 
++                        return 0;
++                if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY) 
++                        return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len,
++                                                         buffer2, buffer2_len,
++                                                         &dvbdmxfilter->feed->feed.ts,
++                                                         DMX_OK); 
++                else
++                        pes_to_ts(buffer1, buffer1_len, 
++                                  dvbdmxfilter->feed->pid, 
++                                  &av7110->p2t_filter[dvbdmxfilter->index]);
++      default:
++              return 0;
++        }
++}
++
++
++u8 pshead[0x26] = {
++        0x00, 0x00, 0x01, 0xba, 0x5f, 0xff, 0xfe, 0xe6, 
++        0xc4, 0x01, 0x01, 0x89, 0xc3, 0xf8, 0x00, 0x00,
++        0x01, 0xbb, 0x00, 0x12, 0x80, 0xc4, 0xe1, 0x00,
++        0xe1, 0xff, 0xb9, 0xe0, 0xe8, 0xb8, 0xc0, 0x20,
++        0xbd, 0xe0, 0x44, 0xbf, 0xe0, 0x02,
++};                                                            
++
++
++//#define DEBUG_TIMING
++static inline void print_time(char *s)
++{
++#ifdef DEBUG_TIMING
++        struct timeval tv;
++        do_gettimeofday(&tv);
++        printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec);
++#endif
++}
++
++static void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len)
++{
++        if (dvb_ringbuffer_free(cibuf) < len+2)
++                return;
++
++        DVB_RINGBUFFER_WRITE_BYTE(cibuf,len>>8);
++        DVB_RINGBUFFER_WRITE_BYTE(cibuf,len&0xff);   
++
++        dvb_ringbuffer_write(cibuf,data,len,0);
++
++        wake_up_interruptible(&cibuf->queue);
++}
++
++static void debiirq (unsigned long data)
++{
++      struct av7110 *av7110 = (struct av7110*) data;
++        int type=av7110->debitype;
++        int handle=(type>>8)&0x1f;
++      
++//    DEB_EE(("av7110: %p\n",av7110));
++
++        print_time("debi");
++        saa7146_write(av7110->dev, IER, 
++                      saa7146_read(av7110->dev, IER) & ~MASK_19 );
++        saa7146_write(av7110->dev, ISR, MASK_19 );
++
++        if (type==-1) {
++                printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",jiffies,saa7146_read(av7110->dev,PSR),saa7146_read(av7110->dev,SSR));
++              spin_lock(&av7110->debilock);
++                ARM_ClearMailBox(av7110);
++                ARM_ClearIrq(av7110);
++              spin_unlock(&av7110->debilock);
++                return;
++        }
++        av7110->debitype=-1;
++
++        switch (type&0xff) {
++
++        case DATA_TS_RECORD:
++                dvb_dmx_swfilter_packets(&av7110->demux, 
++                                      (const u8 *)av7110->debi_virt, 
++                                      av7110->debilen/188);
++                spin_lock(&av7110->debilock);
++                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
++                ARM_ClearMailBox(av7110);
++                spin_unlock(&av7110->debilock);
++                return;
++
++        case DATA_PES_RECORD:
++                if (av7110->demux.recording) 
++                        record_cb(&av7110->p2t[handle], 
++                                  (u8 *)av7110->debi_virt,
++                                  av7110->debilen);
++                spin_lock(&av7110->debilock);
++                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
++                ARM_ClearMailBox(av7110);
++                spin_unlock(&av7110->debilock);
++                return;
++
++        case DATA_IPMPE:
++        case DATA_FSECTION:
++        case DATA_PIPING:
++                if (av7110->handle2filter[handle]) 
++                        DvbDmxFilterCallback((u8 *)av7110->debi_virt, 
++                                             av7110->debilen, 0, 0, 
++                                             av7110->handle2filter[handle], 
++                                             DMX_OK, av7110); 
++                spin_lock(&av7110->debilock);
++                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
++                ARM_ClearMailBox(av7110);
++                spin_unlock(&av7110->debilock);
++                return;
++
++        case DATA_CI_GET:
++        {
++                u8 *data=av7110->debi_virt;
++
++                if ((data[0]<2) && data[2]==0xff) {
++                        int flags=0;
++                        if (data[5]>0) 
++                                flags|=CA_CI_MODULE_PRESENT;
++                        if (data[5]>5) 
++                                flags|=CA_CI_MODULE_READY;
++                        av7110->ci_slot[data[0]].flags=flags;
++                } else
++                        ci_get_data(&av7110->ci_rbuffer, 
++                                    av7110->debi_virt, 
++                                    av7110->debilen);
++                spin_lock(&av7110->debilock);
++                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
++                ARM_ClearMailBox(av7110);
++                spin_unlock(&av7110->debilock);
++                return;
++        }
++
++        case DATA_COMMON_INTERFACE:
++                CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen);
++#if 0
++        {
++                int i;
++
++                printk("av7110%d: ", av7110->num);
++                printk("%02x ", *(u8 *)av7110->debi_virt);
++                printk("%02x ", *(1+(u8 *)av7110->debi_virt));
++                for (i=2; i<av7110->debilen; i++)
++                  printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt)));
++                for (i=2; i<av7110->debilen; i++)
++                  printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt)));
++
++                printk("\n");
++        }
++#endif
++                spin_lock(&av7110->debilock);
++                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
++                ARM_ClearMailBox(av7110);
++                spin_unlock(&av7110->debilock);
++                return;
++
++        case DATA_DEBUG_MESSAGE:
++                ((s8*)av7110->debi_virt)[Reserved_SIZE-1]=0;
++                printk("%s\n", (s8 *)av7110->debi_virt);
++                spin_lock(&av7110->debilock);
++                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
++                ARM_ClearMailBox(av7110);
++                spin_unlock(&av7110->debilock);
++                return;
++
++        case DATA_CI_PUT:
++        case DATA_MPEG_PLAY:
++        case DATA_BMP_LOAD:
++                spin_lock(&av7110->debilock);
++                iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
++                ARM_ClearMailBox(av7110);
++                spin_unlock(&av7110->debilock);
++                return;
++        default:
++                break;
++        }
++        spin_lock(&av7110->debilock);
++        ARM_ClearMailBox(av7110);
++        spin_unlock(&av7110->debilock);
++}
++
++static int pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
++{
++        int len;
++        u32 sync;
++        u16 blen;
++
++      DEB_EE(("dvb_ring_buffer_t: %p\n",buf));
++
++        if (!dlen) {
++                wake_up(&buf->queue);
++                return -1;
++        }
++        while (1) {
++                if ((len=dvb_ringbuffer_avail(buf)) < 6)
++                        return -1;
++                sync= DVB_RINGBUFFER_PEEK(buf,0)<<24;
++                sync|=DVB_RINGBUFFER_PEEK(buf,1)<<16;
++                sync|=DVB_RINGBUFFER_PEEK(buf,2)<<8;
++                sync|=DVB_RINGBUFFER_PEEK(buf,3);
++                
++                if (((sync&~0x0f)==0x000001e0) ||
++                    ((sync&~0x1f)==0x000001c0) ||
++                    (sync==0x000001bd))
++                        break;
++                printk("resync\n");
++                DVB_RINGBUFFER_SKIP(buf,1);
++        }
++        blen= DVB_RINGBUFFER_PEEK(buf,4)<<8;
++        blen|=DVB_RINGBUFFER_PEEK(buf,5);
++        blen+=6;
++        if (len<blen || blen>dlen) {
++                //printk("buffer empty - avail %d blen %u dlen %d\n",len,blen,dlen);
++                wake_up(&buf->queue);
++                return -1;
++        }
++
++        (void)dvb_ringbuffer_read(buf,dest,(size_t)blen,0);
++
++        DEB_S(("pread=0x%08lx, pwrite=0x%08lx\n",(unsigned long)buf->pread, (unsigned long)buf->pwrite));
++        wake_up(&buf->queue);
++        return blen;
++}
++
++
++static void gpioirq (unsigned long data)
++{
++      struct av7110 *av7110 = (struct av7110*) data;
++        u32 rxbuf, txbuf;
++        int len;
++        
++        //printk("GPIO0 irq\n");        
++
++        if (av7110->debitype !=-1)
++                printk("GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",jiffies,saa7146_read(av7110->dev,PSR),saa7146_read(av7110->dev,SSR));
++       
++        spin_lock(&av7110->debilock);
++
++      ARM_ClearIrq(av7110);
++
++        saa7146_write(av7110->dev, IER, 
++                      saa7146_read(av7110->dev, IER) & ~MASK_19 );
++        saa7146_write(av7110->dev, ISR, MASK_19 );
++
++        av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
++        av7110->debilen  = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
++        av7110->debibuf  = 0;
++        rxbuf=irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
++        txbuf=irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
++        len=(av7110->debilen+3)&(~3);
++
++//        DEB_D(("GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen));
++        print_time("gpio");
++
++//       DEB_D(("GPIO0 irq %02x\n", av7110->debitype&0xff));        
++        switch (av7110->debitype&0xff) {
++
++        case DATA_TS_PLAY:
++        case DATA_PES_PLAY:
++                break;
++
++      case DATA_MPEG_VIDEO_EVENT:
++      {
++              u32 h_ar;
++              struct video_event event;
++
++                av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2);
++                h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2);
++
++                iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
++                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
++
++              av7110->video_size.h = h_ar & 0xfff;
++              DEB_D(("GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
++                              av7110->video_size.w,
++                              av7110->video_size.h,
++                              av7110->video_size.aspect_ratio));
++
++              event.type = VIDEO_EVENT_SIZE_CHANGED;
++              event.u.size.w = av7110->video_size.w;
++              event.u.size.h = av7110->video_size.h;
++              switch ((h_ar >> 12) & 0xf)
++              {
++              case 3:
++                      av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
++                      event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
++                      av7110->videostate.video_format = VIDEO_FORMAT_16_9;
++                      break;
++              case 4:
++                      av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1;
++                      event.u.size.aspect_ratio = VIDEO_FORMAT_221_1;
++                      av7110->videostate.video_format = VIDEO_FORMAT_221_1;
++                      break;
++              default:
++                      av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3;
++                      event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
++                      av7110->videostate.video_format = VIDEO_FORMAT_4_3;
++              }
++              dvb_video_add_event(av7110, &event);
++              break;
++      }
++
++        case DATA_CI_PUT:
++        {
++                int avail;
++                struct dvb_ringbuffer *cibuf=&av7110->ci_wbuffer;
++
++                avail=dvb_ringbuffer_avail(cibuf);
++                if (avail<=2) {
++                        iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
++                        iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
++                        iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
++                        break;
++                } 
++                len= DVB_RINGBUFFER_PEEK(cibuf,0)<<8;
++                len|=DVB_RINGBUFFER_PEEK(cibuf,1);
++                if (avail<len+2) {
++                        iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
++                        iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
++                        iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
++                        break;
++                } 
++                DVB_RINGBUFFER_SKIP(cibuf,2); 
++
++                dvb_ringbuffer_read(cibuf,av7110->debi_virt,len,0);
++
++                wake_up(&cibuf->queue);
++                iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
++                iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
++                wait_for_debi_done(av7110);
++                saa7146_write(av7110->dev, IER, 
++                              saa7146_read(av7110->dev, IER) | MASK_19 );
++                if (len<5) len=5; /* we want a real DEBI DMA */
++                iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3);
++                spin_unlock(&av7110->debilock);
++                return;
++        }
++
++        case DATA_MPEG_PLAY:
++                if (!av7110->playing) {
++                        iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
++                        iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
++                        iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
++                        break;
++                }
++                len=0;
++                if (av7110->debitype&0x100) {
++                        spin_lock(&av7110->aout.lock);
++                        len=pes_play(av7110->debi_virt, &av7110->aout, 2048);
++                        spin_unlock(&av7110->aout.lock);
++                }
++                if (len<=0 && (av7110->debitype&0x200)
++                        &&av7110->videostate.play_state!=VIDEO_FREEZED) {
++                        spin_lock(&av7110->avout.lock);
++                        len=pes_play(av7110->debi_virt, &av7110->avout, 2048);
++                        spin_unlock(&av7110->avout.lock);
++                }
++                if (len<=0) {
++                        iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
++                        iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
++                        iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
++                        break;
++                } 
++                DEB_D(("GPIO0 PES_PLAY len=%04x\n", len));        
++                iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
++                iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
++                wait_for_debi_done(av7110);
++                saa7146_write(av7110->dev, IER, 
++                              saa7146_read(av7110->dev, IER) | MASK_19 );
++
++                iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3);
++                spin_unlock(&av7110->debilock);
++                return;
++
++        case DATA_BMP_LOAD:
++                len=av7110->debilen;
++                if (!len) {
++                        av7110->bmp_state=BMP_LOADED;
++                        iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
++                        iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2);
++                        iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
++                        wake_up(&av7110->bmpq);
++                        break;
++                }
++                if (len>av7110->bmplen)
++                        len=av7110->bmplen;
++                if (len>2*1024)
++                        len=2*1024;
++                iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
++                iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
++                memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
++                av7110->bmpp+=len;
++                av7110->bmplen-=len;
++                wait_for_debi_done(av7110);
++                saa7146_write(av7110->dev, IER, 
++                              saa7146_read(av7110->dev, IER) | MASK_19 );
++                if (len<5) len=5; /* we want a real DEBI DMA */
++                iwdebi(av7110, DEBISWAB, DPRAM_BASE+txbuf, 0, (len+3)&~3);
++                spin_unlock(&av7110->debilock);
++                return;
++
++        case DATA_CI_GET:
++        case DATA_COMMON_INTERFACE:
++        case DATA_FSECTION:
++        case DATA_IPMPE:
++        case DATA_PIPING:
++                if (!len || len>4*1024) {
++                        iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
++                        break;
++                }                  /* yes, fall through */
++        case DATA_TS_RECORD:
++        case DATA_PES_RECORD:
++                wait_for_debi_done(av7110);
++                saa7146_write(av7110->dev, IER, 
++                              saa7146_read(av7110->dev, IER) | MASK_19);
++                irdebi(av7110, DEBISWAB, DPRAM_BASE+rxbuf, 0, len);
++                spin_unlock(&av7110->debilock);
++                return;
++
++        case DATA_DEBUG_MESSAGE:
++                wait_for_debi_done(av7110);
++                if (!len || len>0xff) {
++                        iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
++                        break;
++                }
++                saa7146_write(av7110->dev, IER, 
++                              saa7146_read(av7110->dev, IER) | MASK_19);
++                irdebi(av7110, DEBISWAB, Reserved, 0, len);
++                spin_unlock(&av7110->debilock);
++                return;
++
++        case DATA_IRCOMMAND: 
++                IR_handle(av7110, 
++                          swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4)));
++                iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
++                break;
++
++        default:
++                printk("gpioirq unknown type=%d len=%d\n", 
++                       av7110->debitype, av7110->debilen);
++                break;
++        }      
++        ARM_ClearMailBox(av7110);
++        av7110->debitype=-1;
++        spin_unlock(&av7110->debilock);
++}
++
++
++/****************************************************************************
++ * DEBI command polling 
++ ****************************************************************************/
++
++
++static int OutCommand(struct av7110 *av7110, u16* buf, int length)
++{
++        int i;
++        u32 start;
++#ifdef COM_DEBUG
++        u32 stat;
++#endif
++
++//    DEB_EE(("av7110: %p\n",av7110));
++
++      if (!av7110->arm_ready) {
++              DEB_D(("arm not ready.\n"));
++              return -1;
++      }
++
++        start = jiffies;
++        while ( rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 ) )
++        {
++                dvb_delay(1);
++                if ((jiffies - start) > ARM_WAIT_FREE) {
++                      printk(KERN_ERR "%s: timeout waiting for COMMAND idle\n", __FUNCTION__);
++                        return -1;
++                }
++        }
++
++#ifndef _NOHANDSHAKE
++        start = jiffies;
++        while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) )
++        {
++                dvb_delay(1);
++                if ((jiffies - start) > ARM_WAIT_SHAKE) {
++                      printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
++                        return -1;
++                }
++        }
++#endif
++
++        start = jiffies;
++        while ( rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2) & OSDQFull )
++        {
++                dvb_delay(1);
++                if ((jiffies - start) > ARM_WAIT_OSD) {
++                      printk(KERN_ERR "%s: timeout waiting for !OSDQFull\n", __FUNCTION__);
++                      return -1;
++                }
++        }
++        for (i=2; i<length; i++)
++                wdebi(av7110, DEBINOSWAP, COMMAND + 2*i, (u32) buf[i], 2);
++
++        if (length)
++                wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2);
++        else
++                wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2);
++
++        wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
++
++#ifdef COM_DEBUG
++        start = jiffies;
++        while ( rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 ) )
++        {
++                dvb_delay(1);
++                if ((jiffies - start) > ARM_WAIT_FREE) {
++                        printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
++                        return -1;
++                }
++        }
++
++      stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
++      if (stat & GPMQOver) {
++              printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__);
++              return -1;
++      }
++      else if (stat & OSDQOver) {
++              printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__);
++              return -1;
++      }
++#endif
++
++        return 0;
++}
++
++static inline int SOutCommand(struct av7110 *av7110, u16* buf, int length)
++{
++        int ret;
++        
++//    DEB_EE(("av7110: %p\n",av7110));
++
++        if (!av7110->arm_ready) {
++              DEB_D(("arm not ready.\n"));
++              return -1;
++      }
++      
++        if (down_interruptible(&av7110->dcomlock))
++              return -ERESTARTSYS;
++
++        ret=OutCommand(av7110, buf, length);
++        up(&av7110->dcomlock);
++      if (ret)
++                printk("SOutCommand error\n");
++        return ret;
++}
++
++
++static int outcom(struct av7110 *av7110, int type, int com, int num, ...)
++{
++      va_list args;
++        u16 buf[num+2];
++        int i, ret;
++
++//    DEB_EE(("av7110: %p\n",av7110));
++
++        buf[0]=(( type << 8 ) | com);
++        buf[1]=num;
++
++        if (num) {
++                va_start(args, num);
++                for (i=0; i<num; i++)
++                        buf[i+2]=va_arg(args, u32);
++                va_end(args);
++        }
++
++        ret = SOutCommand(av7110, buf, num+2);
++      if (ret)
++                printk("outcom error\n");
++      return ret;
++}
++
++int SendCICommand(struct av7110 *av7110, u8 subcom, u8 *Params, u8 ParamLen)
++{
++        int i, ret;
++        u16 CommandBuffer[18] = { ((COMTYPE_COMMON_IF << 8) + subcom),
++                                  16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++      for(i=0; (i<ParamLen)&&(i<32); i++)     
++      {
++              if(i%2 == 0)
++                      CommandBuffer[(i/2)+2] = (u16)(Params[i]) << 8;
++              else
++                      CommandBuffer[(i/2)+2] |= Params[i];
++      }
++
++        ret = SOutCommand(av7110, CommandBuffer, 18);
++      if (ret)
++                printk("SendCICommand error\n");
++      return ret;
++}
++
++
++static int CommandRequest(struct av7110 *av7110, u16 *Buff, int length, u16 *buf, int n)
++{
++      int err;
++        s16 i;
++        u32 start;
++#ifdef COM_DEBUG
++        u32 stat;
++#endif
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (!av7110->arm_ready) {
++              DEB_D(("arm not ready.\n"));
++              return -1;
++      }
++
++        if (down_interruptible(&av7110->dcomlock))
++              return -ERESTARTSYS;
++
++        if ((err = OutCommand(av7110, Buff, length)) < 0) {
++              up(&av7110->dcomlock);
++              printk("CommandRequest error\n");
++              return err;
++      }
++
++        start = jiffies;
++        while ( rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) )
++        {
++#ifdef _NOHANDSHAKE
++                dvb_delay(1);
++#endif
++                if ((jiffies - start) > ARM_WAIT_FREE) {
++                      printk("%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
++                        up(&av7110->dcomlock);
++                        return -1;
++                }
++        }
++
++#ifndef _NOHANDSHAKE
++        start = jiffies;
++        while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) ) {
++                dvb_delay(1);
++                if ((jiffies - start) > ARM_WAIT_SHAKE) {
++                      printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
++                        up(&av7110->dcomlock);
++                        return -1;
++                }
++        }
++#endif
++
++#ifdef COM_DEBUG
++      stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
++      if (stat & GPMQOver) {
++              printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__);
++                up(&av7110->dcomlock);
++              return -1;
++      }
++      else if (stat & OSDQOver) {
++              printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__);
++                up(&av7110->dcomlock);
++              return -1;
++      }
++#endif
++
++        for (i=0; i<n; i++)
++                buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2*i, 0, 2);
++
++      up(&av7110->dcomlock);
++        return 0;
++}
++
++
++static inline int  RequestParameter(struct av7110 *av7110, u16 tag, u16* Buff, s16 length)
++{
++      int ret;
++        ret = CommandRequest(av7110, &tag, 0, Buff, length);
++      if (ret)
++              printk("RequestParameter error\n");
++      return ret;
++}
++
++
++/****************************************************************************
++ * Firmware commands 
++ ****************************************************************************/
++
++/* msp3400 i2c subaddresses */
++#define MSP_WR_DEM 0x10
++#define MSP_RD_DEM 0x11
++#define MSP_WR_DSP 0x12
++#define MSP_RD_DSP 0x13
++
++static inline int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
++{
++        u8 msg[5]={ dev, reg>>8, reg&0xff, val>>8 , val&0xff }; 
++        struct dvb_i2c_bus *i2c = av7110->i2c_bus;
++        struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg};
++
++        if (i2c->xfer(i2c, &msgs, 1) != 1) {
++              printk("av7110(%d): %s(%u = %u) failed\n",
++                              av7110->dvb_adapter->num, __FUNCTION__, reg, val);
++              return -EIO;
++      }
++      return 0;
++}
++
++static inline int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
++{
++        u8 msg1[3]={ dev, reg>>8, reg&0xff };
++        u8 msg2[2];
++        struct dvb_i2c_bus *i2c = av7110->i2c_bus;
++        struct i2c_msg msgs[2] = {
++              { .flags = 0,        .addr = 0x40, .len = 3, .buf = msg1},
++              { .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2}
++      };
++
++        if (i2c->xfer(i2c, msgs, 2) != 2) {
++              printk("av7110(%d): %s(%u) failed\n",
++                              av7110->dvb_adapter->num, __FUNCTION__, reg);
++              return -EIO;
++      }
++      *val = (msg2[0] << 8) | msg2[1];
++      return 0;
++}
++
++static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data)
++{
++//    DEB_EE(("av7110: %p\n",av7110));
++
++        return outcom(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data);
++}
++
++static int SetVolume(struct av7110 *av7110, int volleft, int volright)
++{
++        int err, vol, val, balance = 0;
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++        switch (av7110->adac_type) {
++        case DVB_ADAC_TI:
++                volleft = (volleft * 256) / 1036;
++                volright = (volright * 256) / 1036;
++                if (volleft > 0x3f)
++                        volleft = 0x3f;
++                if (volright > 0x3f)
++                        volright = 0x3f;
++                if ((err = SendDAC(av7110, 3, 0x80 + volleft)))
++                        return err;
++                return SendDAC(av7110, 4, volright);
++                
++        case DVB_ADAC_CRYSTAL:
++                volleft=127-volleft/2;
++                volright=127-volright/2;
++                i2c_writereg(av7110, 0x20, 0x03, volleft);
++                i2c_writereg(av7110, 0x20, 0x04, volright);
++                return 0;
++
++        case DVB_ADAC_MSP:
++                vol  = (volleft > volright) ? volleft : volright;
++              val     = (vol * 0x73 / 255) << 8;
++              if (vol > 0) {
++                     balance = ((volright-volleft) * 127) / vol;
++              }
++              msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8);
++              msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
++              msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */
++              return 0;
++        }
++        return 0;
++}
++
++#ifdef CONFIG_DVB_AV7110_OSD
++
++static inline int ResetBlend(struct av7110 *av7110, u8 windownr)
++{
++        return outcom(av7110, COMTYPE_OSD, SetNonBlend, 1, windownr);
++}
++
++static inline int SetColorBlend(struct av7110 *av7110, u8 windownr)
++{
++        return outcom(av7110, COMTYPE_OSD, SetCBlend, 1, windownr); 
++}
++
++static inline int SetWindowBlend(struct av7110 *av7110, u8 windownr, u8 blending)
++{
++        return outcom(av7110, COMTYPE_OSD, SetWBlend, 2, windownr, blending); 
++}
++
++static inline int SetBlend_(struct av7110 *av7110, u8 windownr,
++                     enum av7110_osd_palette_type colordepth, u16 index, u8 blending)
++{
++        return outcom(av7110, COMTYPE_OSD, SetBlend, 4,
++                      windownr, colordepth, index, blending);
++} 
++
++static inline int SetColor_(struct av7110 *av7110, u8 windownr,
++                     enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo)
++{
++        return outcom(av7110, COMTYPE_OSD, SetColor, 5,
++                      windownr, colordepth, index, colorhi, colorlo);
++} 
++
++static inline int BringToTop(struct av7110 *av7110, u8 windownr)
++{
++        return outcom(av7110, COMTYPE_OSD, WTop, 1, windownr);
++} 
++
++static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
++                   u16 colorfg, u16 colorbg)
++{
++        return outcom(av7110, COMTYPE_OSD, Set_Font, 4,
++                      windownr, fontsize, colorfg, colorbg);
++} 
++
++static int FlushText(struct av7110 *av7110)
++{
++        u32 start;
++
++        if (down_interruptible(&av7110->dcomlock))
++              return -ERESTARTSYS;
++        start = jiffies;
++        while ( rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2 ) ) {
++                dvb_delay(1); 
++                if ((jiffies - start) > ARM_WAIT_OSD) {
++                        printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__);
++                        up(&av7110->dcomlock);
++                        return -1;
++                }
++        }
++        up(&av7110->dcomlock);
++        return 0;
++}
++
++static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
++{
++        int i, ret;
++        u32 start;
++        int length=strlen(buf)+1;
++        u16 cbuf[5] = { (COMTYPE_OSD<<8) + DText, 3, win, x, y };
++        
++        if (down_interruptible(&av7110->dcomlock))
++              return -ERESTARTSYS;
++
++        start = jiffies;
++        while ( rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2 ) ) {
++                dvb_delay(1);
++                if ((jiffies - start) > ARM_WAIT_OSD) {
++                        printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__);
++                        up(&av7110->dcomlock);
++                        return -1;
++                }
++        }
++#ifndef _NOHANDSHAKE
++        start = jiffies;
++        while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) ) {
++                dvb_delay(1);
++                if ((jiffies - start) > ARM_WAIT_SHAKE) {
++                        printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
++                        up(&av7110->dcomlock);
++                        return -1;
++                }
++        }
++#endif
++        for (i=0; i<length/2; i++)
++                wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i*2, 
++                      swab16(*(u16 *)(buf+2*i)), 2);
++        if (length&1)
++                wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i*2, 0, 2);
++        ret=OutCommand(av7110, cbuf, 5);
++        up(&av7110->dcomlock);
++      if (ret)
++              printk("WriteText error\n");
++        return ret;
++}
++
++static inline int DrawLine(struct av7110 *av7110, u8 windownr, 
++                    u16 x, u16 y, u16 dx, u16 dy, u16 color)
++{
++        return outcom(av7110, COMTYPE_OSD, DLine, 6,
++                      windownr, x, y, dx, dy, color);
++} 
++
++static inline int DrawBlock(struct av7110 *av7110, u8 windownr, 
++                    u16 x, u16 y, u16 dx, u16 dy, u16 color)
++{
++        return outcom(av7110, COMTYPE_OSD, DBox, 6,
++                      windownr, x, y, dx, dy, color);
++} 
++
++static inline int HideWindow(struct av7110 *av7110, u8 windownr)
++{
++        return outcom(av7110, COMTYPE_OSD, WHide, 1, windownr);
++} 
++
++static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
++{
++        return outcom(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y);
++} 
++
++static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y)
++{
++        return outcom(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y);
++} 
++
++static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr)
++{
++        return outcom(av7110, COMTYPE_OSD, WDestroy, 1, windownr);
++} 
++
++#if 0
++static void DestroyOSDWindows(struct av7110 *av7110)
++{
++        int i;
++
++        for (i=1; i<7; i++)
++                outcom(av7110, COMTYPE_OSD, WDestroy, 1, i);
++} 
++#endif
++
++static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr,
++                           enum av7110_window_display_type disptype, u16 width, u16 height)
++{
++        return outcom(av7110, COMTYPE_OSD, WCreate, 4,
++                      windownr, disptype, width, height);
++} 
++
++
++static enum av7110_osd_palette_type bpp2pal[8]={Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit}; 
++static enum av7110_window_display_type   bpp2bit[8]={BITMAP1, BITMAP2, 0, BITMAP4, 0, 0, 0, BITMAP8}; 
++
++static inline int LoadBitmap(struct av7110 *av7110, u16 format, u16 dx, u16 dy, int inc, u8* data)
++{
++        int bpp;
++        int i;
++        int d, delta; 
++        u8 c;
++        DECLARE_WAITQUEUE(wait, current);
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (av7110->bmp_state==BMP_LOADING) {
++                add_wait_queue(&av7110->bmpq, &wait);
++                while (1) {
++                        set_current_state(TASK_INTERRUPTIBLE);
++                        if (av7110->bmp_state!=BMP_LOADING
++                            || signal_pending(current))
++                                break;
++                        schedule();
++                }
++                set_current_state(TASK_RUNNING);
++                remove_wait_queue(&av7110->bmpq, &wait);
++        }
++        if (av7110->bmp_state==BMP_LOADING)
++                return -1;
++        av7110->bmp_state=BMP_LOADING;
++        if      (format==BITMAP8) { bpp=8; delta = 1; } 
++        else if (format==BITMAP4) { bpp=4; delta = 2; }
++        else if (format==BITMAP2) { bpp=2; delta = 4; }
++        else if (format==BITMAP1) { bpp=1; delta = 8; }
++        else {
++                av7110->bmp_state=BMP_NONE;
++                return -1;
++        }
++        av7110->bmplen= ((dx*dy*bpp+7)&~7)/8; 
++        av7110->bmpp=0;
++        if (av7110->bmplen>32768) {
++                av7110->bmp_state=BMP_NONE;
++                return -1;
++        }
++        for (i=0; i<dy; i++) {
++                if (copy_from_user(av7110->bmpbuf+1024+i*dx, data+i*inc, dx)) { 
++                        av7110->bmp_state=BMP_NONE;
++                        return -1;
++                }
++        }
++        if (format != BITMAP8) {
++                for (i=0; i<dx*dy/delta; i++) {
++                        c = ((u8 *)av7110->bmpbuf)[1024+i*delta+delta-1];
++                        for (d=delta-2; d>=0; d--) {
++                                c |= (((u8 *)av7110->bmpbuf)[1024+i*delta+d] 
++                                      << ((delta-d-1)*bpp));
++                                ((u8 *)av7110->bmpbuf)[1024+i] = c;
++                        }
++                }
++        }
++        av7110->bmplen+=1024;
++        return outcom(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
++} 
++
++static int BlitBitmap(struct av7110 *av7110, u16 win, u16 x, u16 y, u16 trans)
++{
++        DECLARE_WAITQUEUE(wait, current);
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++       if (av7110->bmp_state==BMP_NONE)
++                return -1;
++        if (av7110->bmp_state==BMP_LOADING) {
++                add_wait_queue(&av7110->bmpq, &wait);
++                while (1) {
++                        set_current_state(TASK_INTERRUPTIBLE);
++                        if (av7110->bmp_state!=BMP_LOADING
++                            || signal_pending(current))
++                                break;
++                        schedule();
++                }
++                set_current_state(TASK_RUNNING);
++                remove_wait_queue(&av7110->bmpq, &wait);
++        }
++        if (av7110->bmp_state==BMP_LOADED)
++                return outcom(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans);
++        return -1;
++} 
++
++static inline int  ReleaseBitmap(struct av7110 *av7110)
++{
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (av7110->bmp_state!=BMP_LOADED)
++                return -1;
++        av7110->bmp_state=BMP_NONE;
++        return outcom(av7110, COMTYPE_OSD, ReleaseBmp, 0);
++} 
++
++static u32 RGB2YUV(u16 R, u16 G, u16 B)
++{
++        u16 y, u, v;
++        u16 Y, Cr, Cb;
++
++        y = R * 77 + G * 150 + B * 29;  // Luma=0.299R+0.587G+0.114B 0..65535
++        u = 2048+B * 8 -(y>>5);    // Cr 0..4095
++        v = 2048+R * 8 -(y>>5);    // Cb 0..4095
++
++        Y=y/256;
++        Cb=u/16;
++        Cr=v/16;
++
++        return Cr|(Cb<<16)|(Y<<8);
++}
++
++static void OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
++{
++        u16 ch, cl;
++        u32 yuv;
++
++        yuv=blend ? RGB2YUV(r,g,b) : 0;
++        cl=(yuv&0xffff);
++        ch=((yuv>>16)&0xffff);
++        SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
++                  color, ch, cl);
++        SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
++                  color, ((blend>>4)&0x0f));
++}
++
++static int OSDSetPalette(struct av7110 *av7110, u32 *colors, u8 first, u8 last)
++{
++       int i;
++       int length = last - first + 1;
++
++       if (length * 4 > DATA_BUFF3_SIZE)
++               return -1;
++
++       for (i=0; i<length; i++) {
++               u32 blend = (colors[i] & 0xF0000000) >> 4;
++               u32 yuv = blend ? RGB2YUV(colors[i] & 0xFF, (colors[i] >> 8) & 0xFF, (colors[i] >> 16) & 0xFF) | blend : 0;
++               yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16); // TODO kls2003-06-15: not sure if this is endian-proof
++               wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i*4, yuv, 4);
++       }
++       return outcom(av7110, COMTYPE_OSD, Set_Palette, 4,
++               av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], first, last);
++}
++
++static int OSDSetBlock(struct av7110 *av7110, int x0, int y0, int x1, int y1, int inc, u8 *data)
++{
++        uint w, h, bpp, bpl, size, lpb, bnum, brest;
++        int i;
++
++        w=x1-x0+1; h=y1-y0+1;
++        if (inc<=0)
++                inc=w; 
++        if (w<=0 || w>720 || h<=0 || h>576) 
++                return -1;
++        bpp=av7110->osdbpp[av7110->osdwin]+1; 
++        bpl=((w*bpp+7)&~7)/8; 
++        size=h*bpl;
++        lpb=(32*1024)/bpl; 
++        bnum=size/(lpb*bpl);
++        brest=size-bnum*lpb*bpl;
++
++        for (i=0; i<bnum; i++) {
++                LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]], w, lpb, inc, data); 
++                BlitBitmap(av7110, av7110->osdwin, x0, y0+i*lpb, 0);
++                data+=lpb*inc; 
++        }
++        if (brest) {
++                LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]], w, brest/bpl, inc, data); 
++                BlitBitmap(av7110, av7110->osdwin, x0, y0+bnum*lpb, 0);
++        }
++        ReleaseBitmap(av7110);
++        return 0;
++}
++
++static int OSD_DrawCommand(struct av7110 *av7110, osd_cmd_t *dc)
++{
++        switch (dc->cmd) {
++        case OSD_Close:
++                DestroyOSDWindow(av7110, av7110->osdwin);
++                return 0;
++        case OSD_Open:
++                av7110->osdbpp[av7110->osdwin]=(dc->color-1)&7;
++                CreateOSDWindow(av7110, av7110->osdwin, bpp2bit[av7110->osdbpp[av7110->osdwin]],
++                                dc->x1-dc->x0+1, dc->y1-dc->y0+1);
++                if (!dc->data) {
++                        MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
++                        SetColorBlend(av7110, av7110->osdwin);
++                }
++                return 0;
++        case OSD_Show:
++                MoveWindowRel(av7110, av7110->osdwin, 0, 0);
++                return 0;
++        case OSD_Hide:
++                HideWindow(av7110, av7110->osdwin);
++                return 0;
++        case OSD_Clear:
++                DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
++                return 0;
++        case OSD_Fill:
++                DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
++                return 0;
++        case OSD_SetColor:
++                OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1); 
++                return 0;
++        case OSD_SetPalette:
++        {      
++                if (FW_VERSION(av7110->arm_app) >= 0x2618)
++                        OSDSetPalette(av7110, (u32 *)dc->data, dc->color, dc->x0);
++                else {
++                int i, len=dc->x0-dc->color+1;
++                u8 *colors=(u8 *)dc->data;
++
++                for (i=0; i<len; i++)
++                        OSDSetColor(av7110, dc->color+i,
++                                    colors[i*4]  , colors[i*4+1],
++                                    colors[i*4+2], colors[i*4+3]);
++                }
++                return 0;
++        }
++        case OSD_SetTrans: 
++                return 0;
++        case OSD_SetPixel:
++                DrawLine(av7110, av7110->osdwin,
++                         dc->x0, dc->y0, 0, 0,
++                         dc->color);
++                return 0;
++        case OSD_GetPixel: 
++                return 0;
++
++        case OSD_SetRow:   
++                dc->y1=dc->y0;
++        case OSD_SetBlock:
++                OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
++                return 0;
++
++        case OSD_FillRow:
++                DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
++                          dc->x1-dc->x0+1, dc->y1,
++                          dc->color);
++                return 0;
++        case OSD_FillBlock:
++                DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
++                          dc->x1-dc->x0+1, dc->y1-dc->y0+1,
++                          dc->color);
++                return 0;
++        case OSD_Line:
++                DrawLine(av7110, av7110->osdwin,
++                         dc->x0, dc->y0, dc->x1-dc->x0, dc->y1-dc->y0,
++                         dc->color);
++                return 0;
++        case OSD_Query: 
++                return 0;
++        case OSD_Test:
++                return 0;
++        case OSD_Text:
++        {
++                char textbuf[240];
++                
++                if (strncpy_from_user(textbuf, dc->data, 240)<0)
++                        return -EFAULT;
++                textbuf[239]=0;
++                if (dc->x1>3) 
++                        dc->x1=3;
++                SetFont(av7110, av7110->osdwin, dc->x1,
++                        (u16) (dc->color&0xffff), (u16) (dc->color>>16));
++                FlushText(av7110);
++                WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
++                return 0;
++        }
++        case OSD_SetWindow:
++                if (dc->x0<1 || dc->x0>7)
++                        return -EINVAL;
++                av7110->osdwin=dc->x0;
++                return 0;
++        case OSD_MoveWindow:
++                MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
++                SetColorBlend(av7110, av7110->osdwin);
++                return 0;
++        default:
++                return -EINVAL;
++        }
++}
++
++
++static int dvb_osd_ioctl(struct inode *inode, struct file *file,
++            unsigned int cmd, void *parg)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (cmd==OSD_SEND_CMD)
++                return OSD_DrawCommand(av7110, (osd_cmd_t *)parg);
++
++      return -EINVAL;
++}
++
++
++static struct file_operations dvb_osd_fops = {
++      .owner          = THIS_MODULE,
++      .ioctl          = dvb_generic_ioctl,
++      .open           = dvb_generic_open,
++      .release        = dvb_generic_release,
++};
++
++static struct dvb_device dvbdev_osd = {
++      .priv           = 0,
++      .users          = 1,
++      .writers        = 1,
++      .fops           = &dvb_osd_fops,
++      .kernel_ioctl   = dvb_osd_ioctl,
++};
++
++#endif /* CONFIG_DVB_AV7110_OSD */
++
++
++/* get version of the firmware ROM, RTSL, video ucode and ARM application  */
++
++static void firmversion(struct av7110 *av7110)
++{
++        u16 buf[20];
++
++        u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion);
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++        RequestParameter(av7110, tag, buf, 16);
++        
++        av7110->arm_fw=(buf[0] << 16) + buf[1];
++        av7110->arm_rtsl=(buf[2] << 16) + buf[3];
++        av7110->arm_vid=(buf[4] << 16) + buf[5];
++        av7110->arm_app=(buf[6] << 16) + buf[7];
++        av7110->avtype=(buf[8] << 16) + buf[9];
++
++        printk ("DVB: AV711%d(%d) - firm %08x, rtsl %08x, vid %08x, app %08x\n",
++              av7110->avtype, av7110->dvb_adapter->num, av7110->arm_fw, 
++                av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);
++
++      /* print firmware capabilities */
++      if (FW_CI_LL_SUPPORT(av7110->arm_app))
++              printk ("DVB: AV711%d(%d) - firmware supports CI link layer interface\n",
++                              av7110->avtype, av7110->dvb_adapter->num);
++      else
++              printk ("DVB: AV711%d(%d) - no firmware support for CI link layer interface\n",
++                              av7110->avtype, av7110->dvb_adapter->num);
++
++        return;
++}
++
++static int waitdebi(struct av7110 *av7110, int adr, int state)
++{
++        int k;
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++        for (k=0; k<100; k++, udelay(500)) {
++                if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state) 
++                        return 0;
++        }
++        return -1;
++}
++
++
++static int load_dram(struct av7110 *av7110, u32 *data, int len)
++{
++        int i;
++        int blocks, rest;
++        u32 base, bootblock=BOOT_BLOCK;
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++        blocks=len/BOOT_MAX_SIZE;
++        rest=len % BOOT_MAX_SIZE;
++        base=DRAM_START_CODE;
++        
++        for (i=0; i<blocks; i++) {
++                if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0)
++                        return -1;
++                DEB_D(("Writing DRAM block %d\n",i));
++                mwdebi(av7110, DEBISWAB, bootblock,
++                       ((char*)data) + i*(BOOT_MAX_SIZE),
++                       BOOT_MAX_SIZE);
++                bootblock^=0x1400;
++                iwdebi(av7110, DEBISWAB, BOOT_BASE, swab32(base), 4);
++                iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, BOOT_MAX_SIZE, 2);
++                iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
++                base+=BOOT_MAX_SIZE;
++        }
++        
++        if (rest > 0) {
++                if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0)
++                        return -1;
++                if (rest>4)
++                        mwdebi(av7110, DEBISWAB, bootblock, ((char*)data) + i*(BOOT_MAX_SIZE), rest);
++                else
++                        mwdebi(av7110, DEBISWAB, bootblock, ((char*)data) + i*(BOOT_MAX_SIZE) - 4, rest+4);
++                
++                iwdebi(av7110, DEBISWAB, BOOT_BASE, swab32(base), 4);
++                iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, rest, 2);
++                iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
++        }
++        if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0)
++                return -1;
++        iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, 0, 2);
++        iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
++        if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BOOT_COMPLETE) < 0)
++                return -1;
++        return 0;
++}
++
++
++static u8 bootcode[] = {
++        0xea, 0x00, 0x00, 0x0e, 0xe1, 0xb0, 0xf0, 0x0e, /* 0x0000 */
++        0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x04,
++        0xe2, 0x5e, 0xf0, 0x08, 0xe2, 0x5e, 0xf0, 0x04,
++        0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x04,
++        0x2c, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c,
++        0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x34,
++        0x00, 0x00, 0x00, 0x00, 0xa5, 0xa5, 0x5a, 0x5a,
++        0x00, 0x1f, 0x15, 0x55, 0x00, 0x00, 0x00, 0x09,
++        0xe5, 0x9f, 0xd0, 0x5c, 0xe5, 0x9f, 0x40, 0x54, /* 0x0040 */
++        0xe3, 0xa0, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x00,
++        0xe5, 0x84, 0x00, 0x04, 0xe1, 0xd4, 0x10, 0xb0,
++        0xe3, 0x51, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xfc,
++        0xe1, 0xa0, 0x10, 0x0d, 0xe5, 0x94, 0x30, 0x04,
++        0xe1, 0xd4, 0x20, 0xb2, 0xe2, 0x82, 0x20, 0x3f,
++        0xe1, 0xb0, 0x23, 0x22, 0x03, 0xa0, 0x00, 0x02,
++        0xe1, 0xc4, 0x00, 0xb0, 0x0a, 0xff, 0xff, 0xf4,
++        0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, /* 0x0080 */
++        0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0,
++        0xe2, 0x52, 0x20, 0x01, 0x1a, 0xff, 0xff, 0xf9,
++        0xe2, 0x2d, 0xdb, 0x05, 0xea, 0xff, 0xff, 0xec,
++        0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x04, 0x00,
++};
++
++#include "av7110_firm.h"
++
++static int bootarm(struct av7110 *av7110)
++{
++      struct saa7146_dev *dev= av7110->dev;
++        u32 ret;
++        int i;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
++
++        /* Disable DEBI and GPIO irq */
++      IER_DISABLE(av7110->dev, MASK_03|MASK_19);
++/*
++        saa7146_write(av7110->dev, IER, 
++                      saa7146_read(av7110->dev, IER) & 
++                      ~(MASK_19 | MASK_03));
++*/
++        saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03));
++
++        /* enable DEBI */
++        saa7146_write(av7110->dev, MC1, 0x08800880);
++        saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000);
++        saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
++        
++        /* test DEBI */
++        iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
++        if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4))!=0x10325476) {
++                printk(KERN_ERR "dvb: debi test in bootarm() failed: "
++                       "%08x != %08x\n", ret, 0x10325476);;
++                return -1;
++        }
++        for (i=0; i<8192; i+=4) 
++                iwdebi(av7110, DEBISWAP, DPRAM_BASE+i, 0x00, 4);
++        DEB_D(("bootarm: debi test OK\n"));
++
++        /* boot */
++        DEB_D(("bootarm: load boot code\n"));
++
++        saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO);
++        //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT);
++        //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
++
++      mwdebi(av7110, DEBISWAB, DPRAM_BASE, bootcode, sizeof(bootcode));
++        iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
++        
++        wait_for_debi_done(av7110);
++        saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
++        set_current_state(TASK_INTERRUPTIBLE);
++        schedule_timeout(HZ);
++        
++        DEB_D(("bootarm: load dram code\n"));
++
++      if (load_dram(av7110, (u32 *)Root, sizeof(Root))<0)
++              return -1;
++
++      saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
++        mdelay(1);
++        
++        DEB_D(("bootarm: load dpram code\n"));
++
++      mwdebi(av7110, DEBISWAB, DPRAM_BASE, Dpram, sizeof(Dpram));
++
++      wait_for_debi_done(av7110);
++
++        saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
++        mdelay(800);
++
++        //ARM_ClearIrq(av7110); 
++        ARM_ResetMailBox(av7110); 
++        saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03));
++      IER_ENABLE(av7110->dev, MASK_03);
++//      saa7146_write(av7110->dev, IER, 
++//                      saa7146_read(av7110->dev, IER) | MASK_03 );
++
++        av7110->arm_errors=0;
++        av7110->arm_ready=1;
++        return 0;
++}
++
++static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, 
++        u16 subpid, u16 pcrpid)
++{
++      DEB_EE(("av7110: %p\n",av7110));
++
++      if (vpid == 0x1fff || apid == 0x1fff ||
++          ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
++              vpid = apid = ttpid = subpid = pcrpid = 0;
++              av7110->pids[DMX_PES_VIDEO] = 0;
++              av7110->pids[DMX_PES_AUDIO] = 0;
++              av7110->pids[DMX_PES_TELETEXT] = 0;
++              av7110->pids[DMX_PES_PCR] = 0;
++      }
++
++        return outcom(av7110, COMTYPE_PIDFILTER, MultiPID, 5, 
++                      pcrpid, vpid, apid, ttpid, subpid);
++}
++
++static void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, 
++        u16 subpid, u16 pcrpid)
++{
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (down_interruptible(&av7110->pid_mutex))
++              return;
++
++        if (!(vpid&0x8000))  av7110->pids[DMX_PES_VIDEO]=vpid;
++        if (!(apid&0x8000))  av7110->pids[DMX_PES_AUDIO]=apid;
++        if (!(ttpid&0x8000)) av7110->pids[DMX_PES_TELETEXT]=ttpid;
++        if (!(pcrpid&0x8000)) av7110->pids[DMX_PES_PCR]=pcrpid;
++
++        av7110->pids[DMX_PES_SUBTITLE]=0;
++
++        if (av7110->fe_synced) {
++                pcrpid = av7110->pids[DMX_PES_PCR];
++                SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
++        }
++
++        up(&av7110->pid_mutex);
++}
++
++
++static void SetMode(struct av7110 *av7110, int mode)
++{
++      DEB_EE(("av7110: %p\n",av7110));
++
++        outcom(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
++        
++        if (!av7110->playing) {
++                ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO], 
++                           av7110->pids[DMX_PES_AUDIO], 
++                           av7110->pids[DMX_PES_TELETEXT],  
++                           0, av7110->pids[DMX_PES_PCR]);
++                outcom(av7110, COMTYPE_PIDFILTER, Scan, 0);
++        }
++}
++
++static inline void TestMode(struct av7110 *av7110, int mode)
++{
++//    DEB_EE(("av7110: %p\n",av7110));
++        outcom(av7110, COMTYPE_ENCODER, SetTestMode, 1, mode);
++}
++
++static inline void VidMode(struct av7110 *av7110, int mode)
++{
++//    DEB_EE(("av7110: %p\n",av7110));
++        outcom(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
++}
++           
++
++static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg)
++{
++//    DEB_EE(("av7110: %p\n",av7110));
++        return outcom(av7110, 0x80, 0x02, 4, 
++                      (com>>16), (com&0xffff), 
++                      (arg>>16), (arg&0xffff));
++}
++
++static int inline audcom(struct av7110 *av7110, u32 com)
++{
++//    DEB_EE(("av7110: %p\n",av7110));
++      return outcom(av7110, 0x80, 0x03, 4, 
++                      (com>>16), (com&0xffff));
++}
++
++static inline void Set22K(struct av7110 *av7110, int state)
++{
++      DEB_EE(("av7110: %p\n",av7110));
++      outcom(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
++}
++
++
++static int SendDiSEqCMsg(struct av7110 *av7110, int len, u8 *msg, unsigned long burst)
++{
++        int i;
++      u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC),
++                        16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++      if (len>10)
++              len=10;
++
++      buf[1] = len+2;
++      buf[2] = len;
++
++      if (burst!=-1)
++              buf[3]=burst ? 0x01 : 0x00;
++      else
++              buf[3]=0xffff;
++
++      for (i=0; i<len; i++)
++              buf[i+4]=msg[i];
++
++      if (SOutCommand(av7110, buf, 18))
++              printk("SendDiSEqCMsg error\n");
++
++        return 0;
++}
++
++/****************************************************************************
++ * I2C client commands
++ ****************************************************************************/
++
++static inline int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
++{
++        u8 msg[2]={ reg, val }; 
++        struct dvb_i2c_bus *i2c = av7110->i2c_bus;
++        struct i2c_msg msgs;
++
++        msgs.flags=0;
++        msgs.addr=id/2;
++        msgs.len=2;
++        msgs.buf=msg;
++        return i2c->xfer (i2c, &msgs, 1);
++}
++
++static inline u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
++{
++        struct dvb_i2c_bus *i2c = av7110->i2c_bus;
++        u8 mm1[] = {0x00};
++        u8 mm2[] = {0x00};
++        struct i2c_msg msgs[2];
++
++        msgs[0].flags=0;
++        msgs[1].flags=I2C_M_RD;
++        msgs[0].addr=msgs[1].addr=id/2;
++        mm1[0]=reg;
++        msgs[0].len=1; msgs[1].len=1;
++        msgs[0].buf=mm1; msgs[1].buf=mm2;
++        i2c->xfer(i2c, msgs, 2);
++
++        return mm2[0];
++}
++
++
++/****************************************************************************
++ * I/O buffer management and control
++ ****************************************************************************/
++
++static int sw2mode[16] = {
++        VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL,
++        VIDEO_MODE_NTSC, VIDEO_MODE_NTSC, VIDEO_MODE_PAL, VIDEO_MODE_NTSC,
++        VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
++        VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
++};
++
++static void get_video_format(struct av7110 *av7110, u8 *buf, int count)
++{
++        int i;
++      int hsize,vsize;
++        int sw;
++        u8 *p;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (av7110->sinfo)
++                return;
++        for (i=7; i<count-10; i++) {
++                p=buf+i;
++                if (p[0] || p[1] || p[2]!=0x01 || p[3]!=0xb3)
++                        continue;
++                p+=4;
++                hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4);
++                vsize = ((p[1] &0x0F) << 8) | (p[2]);
++                sw = (p[3]&0x0F);
++                SetMode(av7110, sw2mode[sw]);
++                DEB_S(("dvb: playback %dx%d fr=%d\n", hsize, vsize, sw));
++                av7110->sinfo=1;
++                break;
++        }
++}
++
++static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, const char *buf, unsigned long count)
++{
++        unsigned long todo = count;
++        int free;
++    
++        while (todo > 0) {
++                if (dvb_ringbuffer_free(rbuf)<2048) {
++                        if (wait_event_interruptible(rbuf->queue,
++                                                     (dvb_ringbuffer_free(rbuf)>=2048)))
++                              return count-todo;
++                }   
++                free = dvb_ringbuffer_free(rbuf);
++                if (free > todo)
++                        free = todo;
++                (void)dvb_ringbuffer_write(rbuf,buf,free,0);
++                todo -= free;
++                buf += free;
++        }
++
++      return count-todo;
++}
++
++static void play_video_cb(u8 *buf, int count, void *priv)
++{
++        struct av7110 *av7110=(struct av7110 *) priv;
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if ((buf[3]&0xe0)==0xe0) {
++                get_video_format(av7110, buf, count);
++                aux_ring_buffer_write(&av7110->avout, buf, count);
++        } else
++                aux_ring_buffer_write(&av7110->aout, buf, count);
++}
++
++static void play_audio_cb(u8 *buf, int count, void *priv)
++{
++        struct av7110 *av7110=(struct av7110 *) priv;
++      DEB_EE(("av7110: %p\n",av7110));
++        
++        aux_ring_buffer_write(&av7110->aout, buf, count);
++}
++
++#define FREE_COND (dvb_ringbuffer_free(&av7110->avout)>=20*1024 && dvb_ringbuffer_free(&av7110->aout)>=20*1024)
++
++static ssize_t dvb_play(struct av7110 *av7110, const u8 *buf,
++         unsigned long count, int nonblock, int type, int umem)
++{
++        unsigned long todo = count, n;
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (!av7110->kbuf[type])
++                return -ENOBUFS;
++
++      if (nonblock && !FREE_COND)
++                return -EWOULDBLOCK;
++                
++        while (todo>0) {
++                if (!FREE_COND) {
++                        if (nonblock)
++                                return count-todo;
++                        if (wait_event_interruptible(av7110->avout.queue,
++                                                     FREE_COND))
++                              return count-todo;
++                } 
++              n=todo;
++                if (n>IPACKS*2)
++                        n=IPACKS*2;
++                if (umem) {
++                        if (copy_from_user(av7110->kbuf[type], buf, n)) 
++                                return -EFAULT;
++                        av7110_ipack_instant_repack(av7110->kbuf[type], n,
++                                                  &av7110->ipack[type]);
++                } else {
++                        av7110_ipack_instant_repack(buf, n,
++                                                  &av7110->ipack[type]);
++              }
++                todo -= n;
++                buf += n;
++        }
++      return count-todo;
++}
++
++static ssize_t dvb_aplay(struct av7110 *av7110, const u8 *buf,
++         unsigned long count, int nonblock, int type)
++{
++        unsigned long todo = count, n;
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (!av7110->kbuf[type])
++                return -ENOBUFS;
++        if (nonblock && dvb_ringbuffer_free(&av7110->aout)<20*1024)
++                return -EWOULDBLOCK;
++                
++        while (todo>0) {
++                if (dvb_ringbuffer_free(&av7110->aout)<20*1024) {
++                        if (nonblock)
++                                return count-todo;
++                        if (wait_event_interruptible(av7110->aout.queue,
++                                                     (dvb_ringbuffer_free(&av7110->aout)>=
++                                                      20*1024)))
++                              return count-todo;
++                } 
++              n=todo;
++                if (n>IPACKS*2)
++                        n=IPACKS*2;
++                if (copy_from_user(av7110->kbuf[type], buf, n)) 
++                        return -EFAULT;
++                av7110_ipack_instant_repack(av7110->kbuf[type], n,
++                                          &av7110->ipack[type]);
++//                        memcpy(dvb->kbuf[type], buf, n); 
++                todo -= n;
++                buf += n;
++        }
++      return count-todo;
++}
++
++void init_p2t(struct av7110_p2t *p, struct dvb_demux_feed *feed)
++{
++      memset(p->pes,0,TS_SIZE);
++      p->counter = 0;
++      p->pos = 0;
++      p->frags = 0;
++      if (feed) p->feed = feed;
++}
++
++void clear_p2t(struct av7110_p2t *p)
++{
++      memset(p->pes,0,TS_SIZE);
++//    p->counter = 0;
++      p->pos = 0;
++      p->frags = 0;
++}
++
++
++long int find_pes_header(u8 const *buf, long int length, int *frags)
++{
++      int c = 0;
++      int found = 0;
++
++      *frags = 0;
++
++      while (c < length-3 && !found) {
++              if (buf[c] == 0x00 && buf[c+1] == 0x00 && 
++                  buf[c+2] == 0x01) {
++                      switch ( buf[c+3] ) {
++                              
++                      case PROG_STREAM_MAP:
++                      case PRIVATE_STREAM2:
++                      case PROG_STREAM_DIR:
++                      case ECM_STREAM     :
++                      case EMM_STREAM     :
++                      case PADDING_STREAM :
++                      case DSM_CC_STREAM  :
++                      case ISO13522_STREAM:
++                      case PRIVATE_STREAM1:
++                      case AUDIO_STREAM_S ... AUDIO_STREAM_E:
++                      case VIDEO_STREAM_S ... VIDEO_STREAM_E:
++                              found = 1;
++                              break;
++                              
++                      default:
++                              c++;
++                              break;
++                      }       
++              } else c++;
++      }
++      if (c == length-3 && !found){
++              if (buf[length-1] == 0x00) *frags = 1;
++              if (buf[length-2] == 0x00 &&
++                  buf[length-1] == 0x00) *frags = 2;
++              if (buf[length-3] == 0x00 &&
++                  buf[length-2] == 0x00 &&
++                  buf[length-1] == 0x01) *frags = 3;
++              return -1;
++      }
++
++      return c;
++}
++
++void pes_to_ts( u8 const *buf, long int length, u16 pid, struct av7110_p2t *p)
++{
++      int c,c2,l,add;
++      int check,rest;
++
++      c = 0;
++      c2 = 0;
++      if (p->frags){
++              check = 0;
++              switch(p->frags){
++              case 1:
++                      if ( buf[c] == 0x00 && buf[c+1] == 0x01 ){
++                              check = 1;
++                              c += 2;
++                      }
++                      break;
++              case 2:
++                      if ( buf[c] == 0x01 ){
++                              check = 1;
++                              c++;
++                      }
++                      break;
++              case 3:
++                      check = 1;
++              }
++              if(check){
++                      switch ( buf[c] ) {
++                              
++                      case PROG_STREAM_MAP:
++                      case PRIVATE_STREAM2:
++                      case PROG_STREAM_DIR:
++                      case ECM_STREAM     :
++                      case EMM_STREAM     :
++                      case PADDING_STREAM :
++                      case DSM_CC_STREAM  :
++                      case ISO13522_STREAM:
++                      case PRIVATE_STREAM1:
++                      case AUDIO_STREAM_S ... AUDIO_STREAM_E:
++                      case VIDEO_STREAM_S ... VIDEO_STREAM_E:
++                              p->pes[0] = 0x00;
++                              p->pes[1] = 0x00;
++                              p->pes[2] = 0x01;
++                              p->pes[3] = buf[c];
++                              p->pos=4;
++                              memcpy(p->pes+p->pos,buf+c,(TS_SIZE-4)-p->pos);
++                              c += (TS_SIZE-4)-p->pos;
++                              p_to_t(p->pes,(TS_SIZE-4),pid,&p->counter,
++                                     p->feed);
++                              clear_p2t(p);
++                              break;
++                              
++                      default:
++                              c=0;
++                              break;
++                      }
++              }
++              p->frags = 0;
++      }
++              
++      if (p->pos){
++              c2 = find_pes_header(buf+c,length-c,&p->frags);
++              if (c2 >= 0 && c2 < (TS_SIZE-4)-p->pos){
++                      l = c2+c;
++              } else l = (TS_SIZE-4)-p->pos;
++              memcpy(p->pes+p->pos,buf,l);
++              c += l;
++              p->pos += l;
++              p_to_t(p->pes,p->pos,pid,&p->counter, p->feed);
++              clear_p2t(p);
++      }
++                      
++      add = 0;
++      while (c < length){
++              c2 = find_pes_header(buf+c+add,length-c-add,&p->frags);
++              if (c2 >= 0) {
++                      c2 += c+add;
++                      if (c2 > c){
++                              p_to_t(buf+c,c2-c,pid,&p->counter,
++                                     p->feed);
++                              c = c2;
++                              clear_p2t(p);
++                              add = 0;
++                      } else add = 1;
++              } else {
++                      l = length-c;
++                      rest = l % (TS_SIZE-4);
++                      l -= rest;
++                      p_to_t(buf+c,l,pid,&p->counter,
++                             p->feed);
++                      memcpy(p->pes,buf+c+l,rest);
++                      p->pos = rest;
++                      c = length;
++              }
++      }
++}
++
++
++int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length)
++{
++      int i;
++      int c = 0;
++      int fill;
++      u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10}; 
++        
++      fill = (TS_SIZE-4)-length;
++        if (pes_start) tshead[1] = 0x40;
++      if (fill) tshead[3] = 0x30;
++        tshead[1] |= (u8)((pid & 0x1F00) >> 8);
++        tshead[2] |= (u8)(pid & 0x00FF);
++        tshead[3] |= ((*counter)++ & 0x0F) ;
++        memcpy(buf,tshead,4);
++      c+=4;
++
++
++      if (fill){
++              buf[4] = fill-1;
++              c++;
++              if (fill >1){
++                      buf[5] = 0x00;
++                      c++;
++              }
++              for ( i = 6; i < fill+4; i++){
++                      buf[i] = 0xFF;
++                      c++;
++              }
++      }
++
++        return c;
++}
++
++
++void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, 
++            struct dvb_demux_feed *feed)
++{
++  
++      int l, pes_start;
++      u8 obuf[TS_SIZE];
++      long int c = 0;
++
++      pes_start = 0;
++      if ( length > 3 && 
++             buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01 )
++              switch (buf[3]){
++                      case PROG_STREAM_MAP:
++                      case PRIVATE_STREAM2:
++                      case PROG_STREAM_DIR:
++                      case ECM_STREAM     :
++                      case EMM_STREAM     :
++                      case PADDING_STREAM :
++                      case DSM_CC_STREAM  :
++                      case ISO13522_STREAM:
++                      case PRIVATE_STREAM1:
++                      case AUDIO_STREAM_S ... AUDIO_STREAM_E:
++                      case VIDEO_STREAM_S ... VIDEO_STREAM_E:
++                              pes_start = 1;
++                              break;
++                              
++                      default:
++                              break;
++              }                       
++
++      while ( c < length ){
++              memset(obuf,0,TS_SIZE);
++              if (length - c >= (TS_SIZE-4)){
++                      l = write_ts_header2(pid, counter, pes_start
++                                           , obuf, (TS_SIZE-4));
++                      memcpy(obuf+l, buf+c, TS_SIZE-l);
++                      c += TS_SIZE-l;
++              } else { 
++                      l = write_ts_header2(pid, counter, pes_start
++                                           , obuf, length-c);
++                      memcpy(obuf+l, buf+c, TS_SIZE-l);
++                      c = length;
++              }
++                feed->cb.ts(obuf, 188, 0, 0, &feed->feed.ts, DMX_OK); 
++              pes_start = 0;
++      }
++}
++
++/****************************************************************************
++ * V4L SECTION
++ ****************************************************************************/
++
++static struct v4l2_input inputs[2] = {
++      {       
++              .index          = 0,
++              .name           = "DVB",
++              .type           = V4L2_INPUT_TYPE_CAMERA,
++              .audioset       = 1,
++              .tuner          = 0, /* ignored */
++              .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
++              .status         = 0,
++      }, { 
++              .index          = 1,
++              .name           = "Television",
++              .type           = V4L2_INPUT_TYPE_TUNER,
++              .audioset       = 2,
++              .tuner          = 0,
++              .std            = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
++              .status         = 0,
++      }
++};
++
++/* taken from ves1820.c */
++static int ves1820_writereg(struct saa7146_dev *dev, u8 reg, u8 data)
++{
++      u8 addr = 0x09;
++        u8 buf[] = { 0x00, reg, data };
++      struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
++
++      DEB_EE(("av7710: dev: %p\n",dev));
++
++      if( 1 != saa7146_i2c_transfer(dev, &msg, 1, 1)) {
++              return -1;
++      }
++      return 0;
++}
++
++static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
++{
++        struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
++
++      DEB_EE(("av7710: dev: %p\n",dev));
++
++      if( 1 != saa7146_i2c_transfer(dev, &msg, 1, 1)) {
++              return -1;
++      }
++      return 0;
++}
++
++
++/**
++ *   set up the downconverter frequency divisor for a
++ *   reference clock comparision frequency of 62.5 kHz.
++ */
++static int tuner_set_tv_freq (struct saa7146_dev *dev, u32 freq)
++{
++        u32 div;
++      u8 config;
++        u8 buf [4];
++
++      DEB_EE(("av7710: freq: 0x%08x\n",freq));
++
++      /* magic number: 614. tuning with the frequency given by v4l2
++         is always off by 614*62.5 = 38375 kHz...*/
++      div = freq + 614;
++
++      buf[0] = (div >> 8) & 0x7f;
++      buf[1] = div & 0xff;
++      buf[2] = 0x8e;
++
++      if (freq < (u32) 16*168.25 )
++              config = 0xa0;
++      else if (freq < (u32) 16*447.25)
++              config = 0x90;
++      else
++              config = 0x30;
++      config &= ~0x02;
++
++      buf[3] = config;
++
++        return tuner_write (dev, 0x61, buf);
++}
++
++static struct saa7146_standard analog_standard[];
++static struct saa7146_standard dvb_standard[];
++static struct saa7146_standard standard[];
++
++static struct v4l2_audio msp3400_v4l2_audio = {
++      .index = 0,
++      .name = "Television",
++      .capability = V4L2_AUDCAP_STEREO
++};
++
++int av7110_dvb_c_switch(struct saa7146_fh *fh)
++{
++      struct saa7146_dev *dev = fh->dev;
++      struct saa7146_vv *vv = dev->vv_data;
++      struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
++      u16 adswitch;
++      u8 band = 0;
++      int source, sync;
++      struct saa7146_fh *ov_fh = NULL;
++      int restart_overlay = 0;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++      if( vv->ov_data != NULL ) {
++              ov_fh = vv->ov_data->fh;
++              saa7146_stop_preview(ov_fh);
++              restart_overlay = 1;
++      }
++
++      if( 0 != av7110->current_input ) {
++              adswitch = 1;
++              band = 0x68; /* analog band */
++              source = SAA7146_HPS_SOURCE_PORT_B;
++              sync = SAA7146_HPS_SYNC_PORT_B;
++              memcpy(standard,analog_standard,sizeof(struct saa7146_standard)*2);
++              printk("av7110: switching to analog TV\n");
++              msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source
++              msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source
++              msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source
++              msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
++              msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
++              msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
++      } else {
++              adswitch = 0;
++              band = 0x28; /* digital band */ 
++              source = SAA7146_HPS_SOURCE_PORT_A;
++              sync = SAA7146_HPS_SYNC_PORT_A;
++              memcpy(standard,dvb_standard,sizeof(struct saa7146_standard)*2);
++              printk("av7110: switching DVB mode\n");
++              msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
++              msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
++              msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
++              msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
++              msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
++              msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
++      }
++
++      /* hmm, this does not do anything!? */
++      if (outcom(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
++              printk("ADSwitch error\n");
++
++      if( 0 != ves1820_writereg(dev, 0x0f, band )) {
++              printk("setting band in demodulator failed.\n");
++      }
++      saa7146_set_hps_source_and_sync(dev, source, sync);
++
++      /* restart overlay if it was active before */
++      if( 0 != restart_overlay ) {
++              saa7146_start_preview(ov_fh);
++      }
++
++      return 0;
++}
++
++int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 
++{
++      struct saa7146_dev *dev = fh->dev;
++      struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
++      DEB_EE(("saa7146_dev: %p\n",dev));
++
++      switch(cmd) {
++      case VIDIOC_G_TUNER:
++      {
++              struct v4l2_tuner *t = arg;
++              u16 stereo_det;
++              s8 stereo;
++
++              DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
++
++              if( 0 == av7110->has_analog_tuner || t->index != 0 ) {
++                      return -EINVAL;
++              }
++
++              memset(t,0,sizeof(*t));
++              strcpy(t->name, "Television");
++
++              t->type = V4L2_TUNER_ANALOG_TV;
++              t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
++                      V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
++              t->rangelow = 772;      /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
++              t->rangehigh = 13684;   /* 855.25 MHz / 62.5 kHz = 13684 */
++              /* FIXME: add the real signal strength here */
++              t->signal = 0xffff;
++              t->afc = 0;             
++
++msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
++printk("VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
++
++              msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
++              printk("VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
++              stereo = (s8)(stereo_det >> 8);
++              if (stereo > 0x10) {
++                      /* stereo */
++              t->rxsubchans   = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
++                      t->audmode = V4L2_TUNER_MODE_STEREO;
++              }
++              else if (stereo < -0x10) {
++                      /* bilingual*/
++                      t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
++                       t->audmode = V4L2_TUNER_MODE_LANG1;
++              }
++              else /* mono */
++                      t->rxsubchans = V4L2_TUNER_SUB_MONO;
++
++              return 0;
++      }
++      case VIDIOC_S_TUNER:
++      {
++              struct v4l2_tuner *t = arg;
++              u16 fm_matrix, src;
++              DEB_EE(("VIDIOC_S_TUNER: %d\n", t->index));
++
++              if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) {
++                      return -EINVAL;
++              }
++
++
++              switch(t->audmode) {
++              case V4L2_TUNER_MODE_STEREO:
++                              DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"));
++                      fm_matrix = 0x3001; // stereo
++                      src = 0x0020;
++                              break;
++              case V4L2_TUNER_MODE_LANG1:
++                              DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"));
++                      fm_matrix = 0x3000; // mono
++                      src = 0x0000;
++                              break;
++              case V4L2_TUNER_MODE_LANG2:
++                              DEB_D(("VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"));
++                      fm_matrix = 0x3000; // mono
++                      src = 0x0010;
++                              break;
++              default: /* case V4L2_TUNER_MODE_MONO: {*/
++                              DEB_D(("VIDIOC_S_TUNER: TDA9840_SET_MONO\n"));
++                      fm_matrix = 0x3000; // mono
++                      src = 0x0030;
++                              break;
++                      }
++              msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
++              msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
++              msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
++              msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
++
++              return 0;
++      }
++      case VIDIOC_G_FREQUENCY:
++      {
++              struct v4l2_frequency *f = arg;
++
++              DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency));
++
++              if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) {
++                      return -EINVAL;
++              }
++
++              memset(f,0,sizeof(*f));
++              f->type = V4L2_TUNER_ANALOG_TV;
++              f->frequency =  av7110->current_freq;
++
++              return 0;
++      }
++      case VIDIOC_S_FREQUENCY:
++      {
++              struct v4l2_frequency *f = arg;
++
++              DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n",f->frequency));
++
++              if( 0 == av7110->has_analog_tuner || av7110->current_input != 1 ) {
++                      return -EINVAL;
++              }
++
++              if (V4L2_TUNER_ANALOG_TV != f->type)
++                      return -EINVAL;
++
++              msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
++              msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
++
++              /* tune in desired frequency */                 
++              tuner_set_tv_freq(dev, f->frequency);
++              av7110->current_freq = f->frequency;
++
++              msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
++              msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
++              msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
++              msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
++
++              return 0;
++      }
++      case VIDIOC_ENUMINPUT:
++      {
++              struct v4l2_input *i = arg;
++              
++              DEB_EE(("VIDIOC_ENUMINPUT: %d\n", i->index));
++
++              if( 0 != av7110->has_analog_tuner ) {
++                      if( i->index < 0 || i->index >= 2) {
++                              return -EINVAL;
++                      }
++              } else {
++              if( i->index != 0 ) {
++                      return -EINVAL;
++              }
++              }               
++
++              memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
++              
++              return 0;
++      }
++      case VIDIOC_G_INPUT:
++      {
++              int *input = (int *)arg;
++              *input = av7110->current_input;
++              DEB_EE(("VIDIOC_G_INPUT: %d\n", *input));
++              return 0;               
++      }       
++      case VIDIOC_S_INPUT:
++      {
++              int input = *(int *)arg;
++
++              DEB_EE(("VIDIOC_S_INPUT: %d\n", input));
++
++              if( 0 == av7110->has_analog_tuner ) {
++              return 0;               
++      }       
++              
++              if( input < 0 || input >= 2) {
++                      return -EINVAL;
++              }
++              
++              /* fixme: switch inputs here */
++              av7110->current_input = input;
++              return av7110_dvb_c_switch(fh);
++      }       
++      case VIDIOC_G_AUDIO:
++      {
++              struct v4l2_audio *a = arg;
++
++              DEB_EE(("VIDIOC_G_AUDIO: %d\n", a->index));
++              if (a->index != 0)
++                      return -EINVAL;
++              memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
++              break;
++      }
++      case VIDIOC_S_AUDIO:
++      {
++              struct v4l2_audio *a = arg;
++              DEB_EE(("VIDIOC_S_AUDIO: %d\n", a->index));
++              break;
++      }
++      default:
++              printk("no such ioctl\n");
++              return -ENOIOCTLCMD;
++      }
++      return 0;
++}     
++
++static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
++{
++      struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
++        struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
++        unsigned int mask = 0;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++      poll_wait(file, &av7110->aout.queue, wait);
++
++      if (av7110->playing) {
++                if (dvb_ringbuffer_free(&av7110->aout)>=20*1024)
++                        mask |= (POLLOUT | POLLWRNORM);
++        } else /* if not playing: may play if asked for */
++              mask = (POLLOUT | POLLWRNORM);
++
++      return mask;
++}
++
++
++/****************************************************************************
++ * END OF V4L SECTION
++ ****************************************************************************/
++
++
++/****************************************************************************
++ * DVB API SECTION
++ ****************************************************************************/
++
++
++/******************************************************************************
++ * hardware filter functions
++ ******************************************************************************/
++
++static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
++{
++        struct dvb_demux_feed *dvbdmxfeed=dvbdmxfilter->feed;
++        struct av7110 *av7110=(struct av7110 *) dvbdmxfeed->demux->priv;
++        u16 buf[20];
++        int ret, i;
++        u16 handle;
++//        u16 mode=0x0320;
++        u16 mode=0xb96a;
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (dvbdmxfilter->type==DMX_TYPE_SEC) {
++              if (hw_sections) {
++                      buf[4]=(dvbdmxfilter->filter.filter_value[0]<<8)|
++                              dvbdmxfilter->maskandmode[0];
++                      for (i=3; i<18; i++)
++                              buf[i+4-2]=(dvbdmxfilter->filter.filter_value[i]<<8)|
++                                      dvbdmxfilter->maskandmode[i];
++                      mode=4;
++              }
++        } else
++        if ((dvbdmxfeed->ts_type & TS_PACKET) &&
++            !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) 
++                init_p2t(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed);
++
++        buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter; 
++        buf[1] = 16;  
++        buf[2] = dvbdmxfeed->pid;
++        buf[3] = mode;
++
++        ret=CommandRequest(av7110, buf, 20, &handle, 1);          
++        if (ret<0) {
++              printk("StartHWFilter error\n");
++                return ret;
++      }
++
++        av7110->handle2filter[handle]=dvbdmxfilter;
++        dvbdmxfilter->hw_handle=handle;
++
++        return ret;
++}
++
++static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
++{
++        struct av7110 *av7110=(struct av7110 *) dvbdmxfilter->feed->demux->priv;
++        u16 buf[3];
++        u16 answ[2];
++        int ret;
++        u16 handle;
++                
++      DEB_EE(("av7110: %p\n",av7110));
++
++        handle=dvbdmxfilter->hw_handle;
++        if (handle>32) {
++                DEB_S(("dvb: StopHWFilter tried to stop invalid filter %d.\n",
++                       handle));
++                DEB_S(("dvb: filter type = %d\n",  dvbdmxfilter->type));
++                return 0;
++        }
++
++        av7110->handle2filter[handle]=NULL;
++
++        buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter; 
++        buf[1] = 1;   
++        buf[2] = handle;
++        ret=CommandRequest(av7110, buf, 3, answ, 2);          
++      if (ret)
++              printk("StopHWFilter error\n");
++
++        if (answ[1] != handle) {
++                DEB_S(("dvb: filter %d shutdown error :%d\n", handle, answ[1]));
++                ret=-1;
++        }
++        return ret;
++}
++
++
++static int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len)
++{
++        struct dvb_demux *demux = feed->demux;
++        struct av7110 *av7110 = (struct av7110 *) demux->priv;
++        struct ipack *ipack = &av7110->ipack[feed->pes_type];
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        switch (feed->pes_type) {
++        case 0:
++                if (av7110->audiostate.stream_source==AUDIO_SOURCE_MEMORY)
++                        return -EINVAL;
++                break;
++        case 1:
++                if (av7110->videostate.stream_source==VIDEO_SOURCE_MEMORY)
++                        return -EINVAL;
++                break;
++        default:
++                return -1;
++        }
++
++        if (!(buf[3] & 0x10)) { // no payload?
++                return -1;
++        }
++        if (buf[1] & 0x40)
++                av7110_ipack_flush(ipack);
++
++        if (buf[3] & 0x20) {  // adaptation field?
++                len -= buf[4]+1;
++                buf += buf[4]+1;
++                if (!len)
++                        return 0;
++        }
++        
++        av7110_ipack_instant_repack(buf+4, len-4, &av7110->ipack[feed->pes_type]);
++        return 0;
++}
++
++
++static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
++{
++        struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
++        struct av7110 *av7110=(struct av7110 *) dvbdmx->priv;
++        u16 *pid=dvbdmx->pids, npids[5];
++        int i;
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++        npids[0]=npids[1]=npids[2]=npids[3]=0xffff;
++        npids[4]=0xffff;
++        i=dvbdmxfeed->pes_type;
++        npids[i]=(pid[i]&0x8000) ? 0 : pid[i];
++        if ((i==2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
++                npids[i]=0;
++                ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
++                StartHWFilter(dvbdmxfeed->filter); 
++                return;
++        }
++        if (dvbdmxfeed->pes_type<=2 || dvbdmxfeed->pes_type==4)
++                ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
++
++        if (dvbdmxfeed->pes_type<2 && npids[0])
++                if (av7110->fe_synced) 
++                        outcom(av7110, COMTYPE_PIDFILTER, Scan, 0);
++
++        if ((dvbdmxfeed->ts_type & TS_PACKET)) { 
++                if (dvbdmxfeed->pes_type == 0 && 
++                    !(dvbdmx->pids[0]&0x8000))
++                        AV_StartRecord(av7110, RP_AUDIO, 
++                                       dvbdmxfeed);
++                if (dvbdmxfeed->pes_type == 1 && 
++                    !(dvbdmx->pids[1]&0x8000))
++                        AV_StartRecord(av7110, RP_VIDEO, 
++                                       dvbdmxfeed);
++        }
++}
++
++static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
++{
++        struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
++        struct av7110 *av7110=(struct av7110 *) dvbdmx->priv;
++        u16 *pid=dvbdmx->pids, npids[5];
++        int i;
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (dvbdmxfeed->pes_type<=1) {
++                AV_Stop(av7110, dvbdmxfeed->pes_type ? 
++                        RP_VIDEO : RP_AUDIO);
++                if (!av7110->rec_mode)
++                        dvbdmx->recording=0;
++                if (!av7110->playing)
++                        dvbdmx->playing=0;
++        }
++        npids[0]=npids[1]=npids[2]=npids[3]=0xffff;
++        npids[4]=0xffff;
++        i=dvbdmxfeed->pes_type;
++        switch (i) {
++        case 2: //teletext
++                if (dvbdmxfeed->ts_type & TS_PACKET)
++                        StopHWFilter(dvbdmxfeed->filter); 
++                npids[2]=0;
++                break;
++        case 0:
++        case 1:
++        case 4:
++                if (!pids_off) 
++                        return;
++                npids[i]=(pid[i]&0x8000) ? 0 : pid[i];
++                break;
++        }
++        ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
++}
++
++static int av7110_start_feed(struct dvb_demux_feed *feed)
++{
++        struct dvb_demux *demux = feed->demux;
++        struct av7110 *av7110 = (struct av7110 *) demux->priv;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (!demux->dmx.frontend)
++                return -EINVAL;
++
++        if (feed->pid > 0x1fff) 
++                return -EINVAL;
++
++        if (feed->type == DMX_TYPE_TS) {
++              if ((feed->ts_type & TS_DECODER) &&
++                  (feed->pes_type < DMX_TS_PES_OTHER)) {
++                      switch (demux->dmx.frontend->source) {
++                      case DMX_MEMORY_FE: 
++                              if (feed->ts_type & TS_DECODER)
++                                     if (feed->pes_type < 2 && 
++                                           !(demux->pids[0] & 0x8000) &&
++                                         !(demux->pids[1] & 0x8000)) {
++                                               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
++                                               dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
++                                               AV_StartPlay(av7110,RP_AV);
++                                               demux->playing = 1;
++                                      }
++                              break;
++                      default:
++                                dvb_feed_start_pid(feed);
++                              break;
++                      }
++              } else
++                      if ((feed->ts_type & TS_PACKET) &&
++                            (demux->dmx.frontend->source!=DMX_MEMORY_FE))
++                                StartHWFilter(feed->filter); 
++        }
++        
++        if (feed->type == DMX_TYPE_SEC) {
++                int i;
++
++              for (i=0; i<demux->filternum; i++) {
++                      if (demux->filter[i].state!=DMX_STATE_READY)
++                              continue;
++                      if (demux->filter[i].type!=DMX_TYPE_SEC)
++                              continue;
++                      if (demux->filter[i].filter.parent!=&feed->feed.sec)
++                              continue;
++                      demux->filter[i].state=DMX_STATE_GO;
++                        if (demux->dmx.frontend->source!=DMX_MEMORY_FE)
++                                StartHWFilter(&demux->filter[i]); 
++                }
++      }
++
++        return 0;
++}
++
++
++static int av7110_stop_feed(struct dvb_demux_feed *feed)
++{
++        struct dvb_demux *demux = feed->demux;
++        struct av7110 *av7110 = (struct av7110 *) demux->priv;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (feed->type == DMX_TYPE_TS) {
++                if (feed->ts_type & TS_DECODER) {
++                        if (feed->pes_type >= DMX_TS_PES_OTHER ||
++                            !demux->pesfilter[feed->pes_type]) 
++                                return -EINVAL;
++                        demux->pids[feed->pes_type]|=0x8000;
++                        demux->pesfilter[feed->pes_type]=0;
++                }
++                if (feed->ts_type & TS_DECODER &&
++                  feed->pes_type < DMX_TS_PES_OTHER) {
++                        dvb_feed_stop_pid(feed);
++                } else 
++                        if ((feed->ts_type & TS_PACKET) &&
++                            (demux->dmx.frontend->source != DMX_MEMORY_FE))
++                                StopHWFilter(feed->filter); 
++        }
++        
++        if (feed->type == DMX_TYPE_SEC) {
++                int i;
++
++              for (i=0; i<demux->filternum; i++)
++                      if (demux->filter[i].state==DMX_STATE_GO && 
++                          demux->filter[i].filter.parent==&feed->feed.sec) {
++                              demux->filter[i].state=DMX_STATE_READY;
++                                if (demux->dmx.frontend->source!=DMX_MEMORY_FE)
++                                        StopHWFilter(&demux->filter[i]); 
++                }
++      }
++
++        return 0;
++}
++
++
++static void restart_feeds(struct av7110 *av7110)
++{
++        struct dvb_demux *dvbdmx=&av7110->demux;
++        struct dvb_demux_feed *feed;
++        int mode;
++        int i;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        mode=av7110->playing;
++        av7110->playing=0;
++        av7110->rec_mode=0;
++
++        for (i=0; i<dvbdmx->filternum; i++) {
++                feed=&dvbdmx->feed[i];
++                if (feed->state==DMX_STATE_GO)
++                        av7110_start_feed(feed);
++        }
++
++        if (mode)
++                AV_StartPlay(av7110, mode);
++}
++
++static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
++              uint64_t *stc, unsigned int *base)
++{
++      int ret;
++        u16 fwstc[4];
++        u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC);
++      struct dvb_demux *dvbdemux;
++      struct av7110 *av7110;
++
++      /* pointer casting paranoia... */
++      if (!demux)
++              BUG();
++      dvbdemux = (struct dvb_demux *) demux->priv;
++      if (!dvbdemux)
++              BUG();
++      av7110 = (struct av7110 *) dvbdemux->priv;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++      if (num != 0)
++              return -EINVAL;
++
++        ret = CommandRequest(av7110, &tag, 0, fwstc, 4);
++      if (ret) {
++              printk(KERN_ERR "%s: CommandRequest error\n", __FUNCTION__);
++              return -EIO;
++      }
++      DEB_EE(("av7110: fwstc = %04hx %04hx %04hx %04hx\n",
++                      fwstc[0], fwstc[1], fwstc[2], fwstc[3]));
++
++      *stc =  (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
++              (((uint64_t)fwstc[1])     << 16) | ((uint64_t)fwstc[0]);
++      *base = 1;
++
++      DEB_EE(("av7110: stc = %lu\n", (unsigned long)*stc));
++
++      return 0;
++}
++
++
++/******************************************************************************
++ * SEC device file operations
++ ******************************************************************************/
++
++static int av7110_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
++{
++      struct av7110 *av7110 = fe->before_after_data;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++      switch (cmd) {
++      case FE_SET_TONE:
++              switch ((fe_sec_tone_mode_t) arg) {
++              case SEC_TONE_ON:
++                      Set22K (av7110, 1);
++                      break;
++              case SEC_TONE_OFF:
++                      Set22K (av7110, 0);
++                      break;
++              default:
++                      return -EINVAL;
++              };
++              break;
++
++      case FE_DISEQC_SEND_MASTER_CMD:
++      {
++              struct dvb_diseqc_master_cmd *cmd = arg;
++              SendDiSEqCMsg (av7110, cmd->msg_len, cmd->msg, -1);
++              break;
++      }
++
++      case FE_DISEQC_SEND_BURST:
++              SendDiSEqCMsg (av7110, 0, NULL, (unsigned long)arg);
++              break;
++
++      default:
++              return -EOPNOTSUPP;
++      };
++
++      return 0;
++}
++
++/******************************************************************************
++ * CI link layer file ops (FIXME: move this to separate module later)
++ ******************************************************************************/
++
++int ci_ll_init(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf, int size)
++{
++        dvb_ringbuffer_init(cirbuf, vmalloc(size), size);
++        dvb_ringbuffer_init(ciwbuf, vmalloc(size), size);
++        return 0;
++}
++
++void ci_ll_flush(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
++{
++        dvb_ringbuffer_flush_spinlock_wakeup(cirbuf);
++        dvb_ringbuffer_flush_spinlock_wakeup(ciwbuf);
++}
++
++void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf)
++{
++        vfree(cirbuf->data);
++        cirbuf->data=0;
++        vfree(ciwbuf->data);
++        ciwbuf->data=0;
++}
++
++
++int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file, 
++                int slots, ca_slot_info_t *slot)
++{
++      int i;
++      int len=0;
++      u8 msg[8]={0x00,0x06,0,0x00,0xff,0x02,0x00,0x00};
++
++      for (i=0; i<2; i++) {
++              if (slots & (1<<i)) 
++                      len+=8;
++      }
++
++      if (dvb_ringbuffer_free(cibuf) < len)
++              return -EBUSY;
++
++      for (i=0; i<2; i++) {
++              if (slots & (1<<i)) {
++                      msg[2]=i;
++                      dvb_ringbuffer_write(cibuf,msg,8,0);
++                      slot[i].flags=0;
++              }
++      }
++
++      return 0;
++}
++
++static ssize_t ci_ll_write(struct dvb_ringbuffer *cibuf, struct file *file, const char *buf, size_t count, loff_t *ppos)
++{
++        int free;
++        int non_blocking=file->f_flags&O_NONBLOCK;
++
++        if (count>2048)
++                return -EINVAL;
++        free=dvb_ringbuffer_free(cibuf);
++        if (count+2>free) { 
++                if (non_blocking)
++                        return -EWOULDBLOCK;
++                if (wait_event_interruptible(cibuf->queue,
++                                             (dvb_ringbuffer_free(cibuf)>=count+2)))
++                        return 0;
++        }
++
++        DVB_RINGBUFFER_WRITE_BYTE(cibuf,count>>8);   
++        DVB_RINGBUFFER_WRITE_BYTE(cibuf,count&0xff); 
++
++        return dvb_ringbuffer_write(cibuf,buf,count,1);
++}
++
++static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file, char *buf, size_t count, loff_t *ppos)
++{
++      int avail;
++      int non_blocking=file->f_flags&O_NONBLOCK;
++      ssize_t len;
++
++      if (!cibuf->data || !count)
++              return 0;
++      if (non_blocking && (dvb_ringbuffer_empty(cibuf)))
++              return -EWOULDBLOCK;
++      if (wait_event_interruptible(cibuf->queue, 
++                                   !dvb_ringbuffer_empty(cibuf)))
++              return 0;
++      avail=dvb_ringbuffer_avail(cibuf);
++      if (avail<4) 
++              return 0;
++      len= DVB_RINGBUFFER_PEEK(cibuf,0)<<8;
++      len|=DVB_RINGBUFFER_PEEK(cibuf,1);
++      if (avail<len+2 || count<len) 
++              return -EINVAL;
++      DVB_RINGBUFFER_SKIP(cibuf,2);
++
++      return dvb_ringbuffer_read(cibuf,buf,len,1);
++}
++
++static int dvb_ca_open(struct inode *inode, struct file *file)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++        int err=dvb_generic_open(inode, file);
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (err<0)
++                return err;
++        ci_ll_flush(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
++        return 0;
++}
++
++static unsigned int dvb_ca_poll (struct file *file, poll_table *wait)
++{
++      struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
++        struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
++        struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer;
++        struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer;
++        unsigned int mask = 0;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        poll_wait (file, &rbuf->queue, wait);
++        
++        if (!dvb_ringbuffer_empty(rbuf))
++                mask |= POLLIN;
++
++      if (dvb_ringbuffer_avail(wbuf)>1024)
++                mask |= POLLOUT;
++
++        return mask;
++}
++
++static int dvb_ca_ioctl(struct inode *inode, struct file *file, 
++                 unsigned int cmd, void *parg)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++        unsigned long arg=(unsigned long) parg;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        switch (cmd) {
++        case CA_RESET:
++#ifdef NEW_CI
++                
++                return ci_ll_reset(&av7110->ci_wbuffer, file, arg, &av7110->ci_slot[0]);
++#endif                        
++                break;
++                
++        case CA_GET_CAP:
++        {
++                ca_caps_t cap;
++                
++                cap.slot_num=2;
++#ifdef NEW_CI
++                cap.slot_type=(FW_CI_LL_SUPPORT(av7110->arm_app) ? CA_CI_LINK : CA_CI) | CA_DESCR;
++#else
++                cap.slot_type=CA_CI|CA_DESCR;
++#endif
++                cap.descr_num=16;
++                cap.descr_type=CA_ECD;
++                memcpy(parg, &cap, sizeof(cap));
++        }
++        break;
++
++        case CA_GET_SLOT_INFO:
++        {
++                ca_slot_info_t *info=(ca_slot_info_t *)parg;
++
++                if (info->num>1)
++                        return -EINVAL;
++                av7110->ci_slot[info->num].num = info->num;
++#ifdef NEW_CI
++                av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? CA_CI_LINK : CA_CI;
++#else
++                av7110->ci_slot[info->num].type = CA_CI;
++#endif
++                memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t));
++        }
++        break;
++
++        case CA_GET_MSG:
++                break;
++
++        case CA_SEND_MSG:
++                break;
++                
++        case CA_GET_DESCR_INFO:
++        {
++                ca_descr_info_t info;
++
++                info.num=16;
++                info.type=CA_ECD;
++                memcpy (parg, &info, sizeof (info));
++        }
++        break;
++
++        case CA_SET_DESCR:
++        {
++                ca_descr_t *descr=(ca_descr_t*) parg;
++
++                if (descr->index>=16)
++                        return -EINVAL;
++                if (descr->parity>1)
++                        return -EINVAL;
++                outcom(av7110, COMTYPE_PIDFILTER, SetDescr, 5,
++                       (descr->index<<8)|descr->parity,
++                       (descr->cw[0]<<8)|descr->cw[1],
++                       (descr->cw[2]<<8)|descr->cw[3],
++                       (descr->cw[4]<<8)|descr->cw[5],
++                       (descr->cw[6]<<8)|descr->cw[7]);
++        }
++        break;
++
++        default:
++                return -EINVAL;
++        }
++        return 0;
++}
++
++static ssize_t dvb_ca_write(struct file *file, const char *buf, 
++             size_t count, loff_t *ppos)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++        
++      DEB_EE(("av7110: %p\n",av7110));
++        return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos);
++}
++
++static ssize_t dvb_ca_read(struct file *file, char *buf, size_t count, loff_t *ppos)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++
++      DEB_EE(("av7110: %p\n",av7110));
++        return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
++}
++
++
++
++/******************************************************************************
++ * Video MPEG decoder events
++ ******************************************************************************/
++static void dvb_video_add_event (struct av7110 *av7110, struct video_event *event)
++{
++      struct dvb_video_events *events = &av7110->video_events;
++      int wp;
++
++      DEB_D(("\n"));
++
++      spin_lock_bh(&events->lock);
++
++      wp = (events->eventw + 1) % MAX_VIDEO_EVENT;
++
++      if (wp == events->eventr) {
++              events->overflow = 1;
++              events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
++      }
++
++      //FIXME: timestamp?
++      memcpy(&events->events[events->eventw], event, sizeof(struct video_event));
++
++      events->eventw = wp;
++
++      spin_unlock_bh(&events->lock);
++
++      wake_up_interruptible (&events->wait_queue);
++}
++
++
++static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags)
++{
++      struct dvb_video_events *events = &av7110->video_events;
++
++      DEB_D(("\n"));
++
++      if (events->overflow) {
++                events->overflow = 0;
++                return -EOVERFLOW;
++        }
++
++        if (events->eventw == events->eventr) {
++              int ret;
++
++                if (flags & O_NONBLOCK)
++                        return -EWOULDBLOCK;
++
++                ret = wait_event_interruptible (events->wait_queue,
++                                                events->eventw != events->eventr);
++                if (ret < 0)
++                        return ret;
++        }
++
++      spin_lock_bh(&events->lock);
++
++      memcpy (event, &events->events[events->eventr],
++              sizeof(struct video_event));
++
++        events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT;
++
++      spin_unlock_bh(&events->lock);
++
++        return 0;
++}
++
++
++/******************************************************************************
++ * DVB device file operations
++ ******************************************************************************/
++
++static unsigned int dvb_video_poll(struct file *file, poll_table *wait)
++{
++      struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
++        struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
++        unsigned int mask = 0;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++      if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
++      poll_wait(file, &av7110->avout.queue, wait);
++      }
++      
++      poll_wait(file, &av7110->video_events.wait_queue, wait);
++
++      if (av7110->video_events.eventw != av7110->video_events.eventr)
++              mask = POLLPRI;
++
++      if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
++      if (av7110->playing) {
++                if (FREE_COND)
++                        mask |= (POLLOUT | POLLWRNORM);
++        } else /* if not playing: may play if asked for */
++                mask |= (POLLOUT | POLLWRNORM);
++      }
++
++        return mask;
++}
++
++static ssize_t dvb_video_write(struct file *file, const char *buf, 
++                size_t count, loff_t *ppos)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++      if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
++              return -EPERM;
++      }
++
++        if (av7110->videostate.stream_source!=VIDEO_SOURCE_MEMORY) 
++                return -EPERM;
++
++      return dvb_play(av7110, buf, count, file->f_flags&O_NONBLOCK, 1, 1);
++}
++
++static ssize_t dvb_audio_write(struct file *file, const char *buf, 
++                size_t count, loff_t *ppos)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (av7110->audiostate.stream_source!=AUDIO_SOURCE_MEMORY) {
++                printk(KERN_ERR "not audio source memory\n");
++                return -EPERM;
++        }
++        return dvb_aplay(av7110, buf, count, file->f_flags&O_NONBLOCK, 0);
++}
++
++u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 };
++
++#define MIN_IFRAME 400000
++
++static int play_iframe(struct av7110 *av7110, u8 *buf, unsigned int len, int nonblock)
++{
++        int i, n=1;
++       
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (!(av7110->playing&RP_VIDEO)) {
++                if (AV_StartPlay(av7110, RP_VIDEO) < 0)
++                      return -EBUSY;
++                n=MIN_IFRAME/len+1;
++        }
++
++      /* setting n always > 1, fixes problems when playing stillframes
++         consisting of I- and P-Frames */
++      n=MIN_IFRAME/len+1;
++      
++      /* FIXME: nonblock? */
++      dvb_play(av7110, iframe_header, sizeof(iframe_header), 0, 1, 0);
++
++      for (i=0; i<n; i++) 
++                dvb_play(av7110, buf, len, 0, 1, 1);
++
++      av7110_ipack_flush(&av7110->ipack[1]);
++      return 0;
++}
++
++
++static int dvb_video_ioctl(struct inode *inode, struct file *file,
++            unsigned int cmd, void *parg)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++        unsigned long arg=(unsigned long) parg;
++        int ret=0;
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if ((file->f_flags&O_ACCMODE)==O_RDONLY) {
++              if ( cmd!=VIDEO_GET_STATUS && cmd!=VIDEO_GET_EVENT && 
++                   cmd!=VIDEO_GET_SIZE ) {
++                return -EPERM;
++              }
++      }
++        
++        switch (cmd) {
++        case VIDEO_STOP:
++                av7110->videostate.play_state=VIDEO_STOPPED;
++                if (av7110->videostate.stream_source==VIDEO_SOURCE_MEMORY)
++                        AV_Stop(av7110, RP_VIDEO);
++                else
++                        vidcom(av7110, 0x000e, 
++                               av7110->videostate.video_blank ? 0 : 1);
++                av7110->trickmode=TRICK_NONE;
++                break; 
++                
++        case VIDEO_PLAY:
++                av7110->trickmode=TRICK_NONE;
++                if (av7110->videostate.play_state==VIDEO_FREEZED) {
++                        av7110->videostate.play_state=VIDEO_PLAYING;
++                        vidcom(av7110, 0x000d, 0);
++                } 
++                
++                if (av7110->videostate.stream_source==VIDEO_SOURCE_MEMORY) {
++                        if (av7110->playing==RP_AV) {
++                                outcom(av7110, COMTYPE_REC_PLAY, __Stop, 0);
++                                av7110->playing&=~RP_VIDEO;
++                        }
++                        AV_StartPlay(av7110,RP_VIDEO);
++                        vidcom(av7110, 0x000d, 0);
++                } else {
++                        //AV_Stop(av7110, RP_VIDEO);
++                        vidcom(av7110, 0x000d, 0);
++                }
++                av7110->videostate.play_state=VIDEO_PLAYING;
++                break;
++                
++        case VIDEO_FREEZE:
++                av7110->videostate.play_state=VIDEO_FREEZED;
++                if (av7110->playing&RP_VIDEO) 
++                        outcom(av7110, COMTYPE_REC_PLAY, __Pause, 0);
++                else
++                        vidcom(av7110, 0x0102, 1);
++                av7110->trickmode=TRICK_FREEZE;
++                break;
++                
++        case VIDEO_CONTINUE:
++                if (av7110->playing&RP_VIDEO) 
++                        outcom(av7110, COMTYPE_REC_PLAY, __Continue, 0);
++                vidcom(av7110, 0x000d, 0);
++                av7110->videostate.play_state=VIDEO_PLAYING;
++                av7110->trickmode=TRICK_NONE;
++                break;
++                
++        case VIDEO_SELECT_SOURCE:
++                av7110->videostate.stream_source=(video_stream_source_t) arg;
++                break;
++                
++        case VIDEO_SET_BLANK:
++                av7110->videostate.video_blank=(int) arg;
++              break;
++                
++        case VIDEO_GET_STATUS:
++                memcpy(parg, &av7110->videostate, sizeof(struct video_status));
++                break;
++                
++        case VIDEO_GET_EVENT:
++                ret=dvb_video_get_event(av7110, parg, file->f_flags);
++              break;
++
++      case VIDEO_GET_SIZE:
++                memcpy(parg, &av7110->video_size, sizeof(video_size_t));
++              break;
++                
++        case VIDEO_SET_DISPLAY_FORMAT:
++        {
++                video_displayformat_t format=(video_displayformat_t) arg;
++                u16 val=0;
++                
++                switch(format) {
++                case VIDEO_PAN_SCAN:
++                        val=VID_PAN_SCAN_PREF;
++                        break;
++                        
++                case VIDEO_LETTER_BOX:
++                        val=VID_VC_AND_PS_PREF;
++                        break;
++                        
++                case VIDEO_CENTER_CUT_OUT:
++                        val=VID_CENTRE_CUT_PREF;
++                        break;
++                        
++                default:
++                        ret=-EINVAL;
++                        break;
++                }
++                if (ret<0)
++                        break;
++                av7110->videostate.video_format=format;
++                ret=outcom(av7110, COMTYPE_ENCODER, SetPanScanType, 
++                           1, (u16) val);
++                break;
++        }
++        
++        case VIDEO_SET_FORMAT:
++                if (arg>1) {
++                        ret=-EINVAL;
++                        break;
++                }
++                av7110->display_ar=arg;
++                ret=outcom(av7110, COMTYPE_ENCODER, SetMonitorType, 
++                           1, (u16) arg);
++                break;
++                
++        case VIDEO_STILLPICTURE:
++        { 
++                struct video_still_picture *pic=
++                        (struct video_still_picture *) parg;
++                av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;
++                dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
++                ret = play_iframe(av7110, pic->iFrame, pic->size,
++                            file->f_flags&O_NONBLOCK);
++                break;
++        }
++        
++        case VIDEO_FAST_FORWARD:
++                //note: arg is ignored by firmware
++                if (av7110->playing&RP_VIDEO) 
++                        outcom(av7110, COMTYPE_REC_PLAY, 
++                               __Scan_I, 2, AV_PES, 0);
++                else 
++                        vidcom(av7110, 0x16, arg); 
++                av7110->trickmode=TRICK_FAST;
++                av7110->videostate.play_state=VIDEO_PLAYING;
++                break;
++                
++        case VIDEO_SLOWMOTION:
++                if (av7110->playing&RP_VIDEO) {
++                        outcom(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
++                        vidcom(av7110, 0x22, arg);
++                } else {
++                        vidcom(av7110, 0x0d, 0);
++                        vidcom(av7110, 0x0e, 0);
++                        vidcom(av7110, 0x22, arg);
++                }
++                av7110->trickmode=TRICK_SLOW;
++                av7110->videostate.play_state=VIDEO_PLAYING;
++                break;
++                
++        case VIDEO_GET_CAPABILITIES:
++                *(int *)parg=VIDEO_CAP_MPEG1|
++                        VIDEO_CAP_MPEG2|
++                        VIDEO_CAP_SYS|
++                        VIDEO_CAP_PROG;
++                break;
++        
++        case VIDEO_CLEAR_BUFFER:
++                dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
++                av7110_ipack_reset(&av7110->ipack[1]);
++                
++                if (av7110->playing==RP_AV) {
++                        outcom(av7110, COMTYPE_REC_PLAY, 
++                               __Play, 2, AV_PES, 0);
++                        if (av7110->trickmode==TRICK_FAST)
++                                outcom(av7110, COMTYPE_REC_PLAY, 
++                                       __Scan_I, 2, AV_PES, 0);
++                        if (av7110->trickmode==TRICK_SLOW) {
++                                outcom(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
++                                vidcom(av7110, 0x22, arg);
++                        }
++                        if (av7110->trickmode==TRICK_FREEZE)
++                                vidcom(av7110, 0x000e, 1);
++                }
++                break;
++                
++        case VIDEO_SET_STREAMTYPE:
++                
++                break;
++                
++        default:
++                ret=-ENOIOCTLCMD;
++                break;
++        }
++        return ret;
++}
++
++static int dvb_audio_ioctl(struct inode *inode, struct file *file,
++            unsigned int cmd, void *parg)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++        unsigned long arg=(unsigned long) parg;
++        int ret=0;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (((file->f_flags&O_ACCMODE)==O_RDONLY) &&
++            (cmd!=AUDIO_GET_STATUS))
++                return -EPERM;
++        
++        switch (cmd) {
++        case AUDIO_STOP:
++                if (av7110->audiostate.stream_source==AUDIO_SOURCE_MEMORY)
++                        AV_Stop(av7110, RP_AUDIO);
++                else
++                        audcom(av7110, 1);
++                av7110->audiostate.play_state=AUDIO_STOPPED;
++                break;
++                
++        case AUDIO_PLAY:
++                if (av7110->audiostate.stream_source==AUDIO_SOURCE_MEMORY)
++                        AV_StartPlay(av7110, RP_AUDIO);
++                audcom(av7110, 2);
++                av7110->audiostate.play_state=AUDIO_PLAYING;
++                break;
++                
++        case AUDIO_PAUSE:
++                audcom(av7110, 1);
++                av7110->audiostate.play_state=AUDIO_PAUSED;
++                break;
++                
++        case AUDIO_CONTINUE:
++                if (av7110->audiostate.play_state==AUDIO_PAUSED) {
++                        av7110->audiostate.play_state=AUDIO_PLAYING;
++                        audcom(av7110, 0x12);
++                } 
++                break;
++                
++        case AUDIO_SELECT_SOURCE:
++                av7110->audiostate.stream_source=(audio_stream_source_t) arg;
++                break;
++                
++        case AUDIO_SET_MUTE:
++        {
++                audcom(av7110, arg ? 1 : 2);
++                av7110->audiostate.mute_state=(int) arg;
++                break;
++        }
++        
++        case AUDIO_SET_AV_SYNC:
++                av7110->audiostate.AV_sync_state=(int) arg;
++                audcom(av7110, arg ? 0x0f : 0x0e);
++                break;
++                
++        case AUDIO_SET_BYPASS_MODE:
++                ret=-EINVAL;
++                break;
++                
++        case AUDIO_CHANNEL_SELECT:
++                av7110->audiostate.channel_select=(audio_channel_select_t) arg;
++                
++                switch(av7110->audiostate.channel_select) {
++                case AUDIO_STEREO:
++                        audcom(av7110, 0x80);
++                        break;
++                        
++                case AUDIO_MONO_LEFT:
++                        audcom(av7110, 0x100);
++                        break;
++                        
++                case AUDIO_MONO_RIGHT:
++                        audcom(av7110, 0x200);
++                        break;
++                        
++                default:
++                        ret=-EINVAL;
++                        break;
++                }
++                break;
++                
++        case AUDIO_GET_STATUS:
++                memcpy(parg, &av7110->audiostate, sizeof(struct audio_status));
++                break;
++                
++        case AUDIO_GET_CAPABILITIES:
++                *(int *)parg=AUDIO_CAP_LPCM|
++                        AUDIO_CAP_MP1|
++                        AUDIO_CAP_MP2;
++                break;
++
++        case AUDIO_CLEAR_BUFFER:
++                dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
++                av7110_ipack_reset(&av7110->ipack[0]);
++                if (av7110->playing==RP_AV)
++                        outcom(av7110, COMTYPE_REC_PLAY, 
++                               __Play, 2, AV_PES, 0);
++                break;
++        case AUDIO_SET_ID:
++                
++                break;
++        case AUDIO_SET_MIXER:
++        {
++                struct audio_mixer *amix=(struct audio_mixer *)parg;
++
++                SetVolume(av7110, amix->volume_left, amix->volume_right);
++                break;
++        }
++        case AUDIO_SET_STREAMTYPE:
++                break;
++        default:
++                ret=-ENOIOCTLCMD;
++                break;
++        }
++        return ret;
++}
++
++
++static int dvb_video_open(struct inode *inode, struct file *file)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++        int err;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if ((err=dvb_generic_open(inode, file))<0)
++                return err;
++
++      if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
++        dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
++        dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
++        av7110->video_blank=1;
++        av7110->audiostate.AV_sync_state=1;
++        av7110->videostate.stream_source=VIDEO_SOURCE_DEMUX;
++
++              /*  empty event queue */
++              av7110->video_events.eventr = av7110->video_events.eventw = 0;
++      }
++
++        return 0;
++}
++
++static int dvb_video_release(struct inode *inode, struct file *file)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++      if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
++        AV_Stop(av7110, RP_VIDEO);
++      }
++
++        return dvb_generic_release(inode, file);
++}
++
++static int dvb_audio_open(struct inode *inode, struct file *file)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++        int err=dvb_generic_open(inode, file);
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (err<0)
++                return err;
++        dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
++        av7110->audiostate.stream_source=AUDIO_SOURCE_DEMUX;
++        return 0;
++}
++
++static int dvb_audio_release(struct inode *inode, struct file *file)
++{
++      struct dvb_device *dvbdev=(struct dvb_device *) file->private_data;
++        struct av7110 *av7110=(struct av7110 *) dvbdev->priv;
++        
++      DEB_EE(("av7110: %p\n",av7110));
++
++        AV_Stop(av7110, RP_AUDIO);
++        return dvb_generic_release(inode, file);
++}
++
++
++
++/******************************************************************************
++ * driver registration 
++ ******************************************************************************/
++
++static struct file_operations dvb_video_fops = {
++      .owner          = THIS_MODULE,
++      .write          = dvb_video_write,
++      .ioctl          = dvb_generic_ioctl,
++      .open           = dvb_video_open,
++      .release        = dvb_video_release,
++      .poll           = dvb_video_poll,
++};
++
++static struct dvb_device dvbdev_video = {
++      .priv           = 0,
++      .users          = 6,
++      .readers        = 5,    /* arbitrary */
++      .writers        = 1,
++      .fops           = &dvb_video_fops,
++      .kernel_ioctl   = dvb_video_ioctl,
++};
++
++static struct file_operations dvb_audio_fops = {
++      .owner          = THIS_MODULE,
++      .write          = dvb_audio_write,
++      .ioctl          = dvb_generic_ioctl,
++      .open           = dvb_audio_open,
++      .release        = dvb_audio_release,
++      .poll           = dvb_audio_poll,
++};
++
++static struct dvb_device dvbdev_audio = {
++      .priv           = 0,
++      .users          = 1,
++      .writers        = 1,
++      .fops           = &dvb_audio_fops,
++      .kernel_ioctl   = dvb_audio_ioctl,
++};
++
++static struct file_operations dvb_ca_fops = {
++      .owner          = THIS_MODULE,
++      .read           = dvb_ca_read,
++      .write          = dvb_ca_write,
++      .ioctl          = dvb_generic_ioctl,
++      .open           = dvb_ca_open,
++      .release        = dvb_generic_release,
++      .poll           = dvb_ca_poll,
++};
++
++static struct dvb_device dvbdev_ca = {
++      .priv           = 0,
++      .users          = 1,
++      .writers        = 1,
++      .fops           = &dvb_ca_fops,
++      .kernel_ioctl   = dvb_ca_ioctl,
++};
++
++
++static void av7110_before_after_tune (fe_status_t s, void *data)
++{
++      struct av7110 *av7110 = data;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        av7110->fe_synced = (s & FE_HAS_LOCK) ? 1 : 0;
++
++        if (av7110->playing)
++                return;
++
++        if (down_interruptible(&av7110->pid_mutex))
++                return;
++
++      if (av7110->fe_synced) {
++                SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO], 
++                        av7110->pids[DMX_PES_AUDIO], 
++                        av7110->pids[DMX_PES_TELETEXT], 0, 
++                        av7110->pids[DMX_PES_PCR]);
++              outcom(av7110, COMTYPE_PIDFILTER, Scan, 0);
++      } else {
++              SetPIDs(av7110, 0, 0, 0, 0, 0);
++              outcom(av7110, COMTYPE_PIDFILTER, FlushTSQueue, 0);
++      }
++
++        up(&av7110->pid_mutex);
++}
++
++
++static int av7110_register(struct av7110 *av7110)
++{
++        int ret, i;
++        struct dvb_demux *dvbdemux=&av7110->demux;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (av7110->registered)
++                return -1;
++
++        av7110->registered=1;
++
++      dvb_add_frontend_notifier (av7110->dvb_adapter,
++                                 av7110_before_after_tune, av7110);
++
++      /**
++       *   init DiSEqC stuff
++       */
++      dvb_add_frontend_ioctls (av7110->dvb_adapter,
++                               av7110_diseqc_ioctl, NULL, av7110);
++
++      av7110->audiostate.AV_sync_state=0;
++      av7110->audiostate.mute_state=0;
++      av7110->audiostate.play_state=AUDIO_STOPPED;
++      av7110->audiostate.stream_source=AUDIO_SOURCE_DEMUX;
++      av7110->audiostate.channel_select=AUDIO_STEREO;
++      av7110->audiostate.bypass_mode=0;
++
++      av7110->videostate.video_blank=0;
++      av7110->videostate.play_state=VIDEO_STOPPED;
++      av7110->videostate.stream_source=VIDEO_SOURCE_DEMUX;
++      av7110->videostate.video_format=VIDEO_FORMAT_4_3;
++      av7110->videostate.display_format=VIDEO_CENTER_CUT_OUT;
++        av7110->display_ar=VIDEO_FORMAT_4_3;
++
++        dvbdemux->priv = (void *) av7110;
++
++      for (i=0; i<32; i++)
++              av7110->handle2filter[i]=NULL;
++
++      dvbdemux->filternum = 32;
++      dvbdemux->feednum = 32;
++      dvbdemux->start_feed = av7110_start_feed;
++      dvbdemux->stop_feed = av7110_stop_feed;
++      dvbdemux->write_to_decoder = av7110_write_to_decoder;
++      dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
++                                    DMX_MEMORY_BASED_FILTERING);
++
++      dvb_dmx_init(&av7110->demux);
++      av7110->demux.dmx.get_stc = dvb_get_stc;
++
++      av7110->dmxdev.filternum = 32;
++      av7110->dmxdev.demux = &dvbdemux->dmx;
++      av7110->dmxdev.capabilities = 0;
++        
++      dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter);
++
++        av7110->hw_frontend.source = DMX_FRONTEND_0;
++
++        ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
++
++        if (ret < 0)
++                return ret;
++        
++        av7110->mem_frontend.source = DMX_MEMORY_FE;
++
++      ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
++
++      if (ret < 0)
++                return ret;
++        
++        ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, 
++                                           &av7110->hw_frontend);
++        if (ret < 0)
++                return ret;
++
++      init_waitqueue_head(&av7110->video_events.wait_queue);
++      spin_lock_init(&av7110->video_events.lock);
++      av7110->video_events.eventw = av7110->video_events.eventr = 0;
++      av7110->video_events.overflow = 0;
++      memset(&av7110->video_size, 0, sizeof (video_size_t));
++
++      dvb_register_device(av7110->dvb_adapter, &av7110->video_dev,
++                          &dvbdev_video, av7110, DVB_DEVICE_VIDEO);
++          
++      dvb_register_device(av7110->dvb_adapter, &av7110->audio_dev,
++                          &dvbdev_audio, av7110, DVB_DEVICE_AUDIO);
++  
++      dvb_register_device(av7110->dvb_adapter, &av7110->ca_dev,  
++                                    &dvbdev_ca, av7110, DVB_DEVICE_CA);
++#ifdef CONFIG_DVB_AV7110_OSD
++      dvb_register_device(av7110->dvb_adapter, &av7110->osd_dev,
++                          &dvbdev_osd, av7110, DVB_DEVICE_OSD);
++#endif
++#ifdef USE_DVB_DSP
++                dvb->dsp_dev = dvb_register_dsp(dvb_audio_open, 
++                                                dvb_audio_release, 
++                                                dvb_audio_ioctl, 
++                                                dvb_audio_write, 
++                                                av7110->audio_dev);
++#endif
++//        }
++        
++        dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
++
++      return 0;
++}
++
++
++static void dvb_unregister(struct av7110 *av7110)
++{
++        struct dvb_demux *dvbdemux=&av7110->demux;
++
++      DEB_EE(("av7110: %p\n",av7110));
++
++        if (!av7110->registered)
++                return;
++
++      dvb_net_release(&av7110->dvb_net);
++
++      dvbdemux->dmx.close(&dvbdemux->dmx);
++        dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend);
++        dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend);
++
++        dvb_dmxdev_release(&av7110->dmxdev);
++        dvb_dmx_release(&av7110->demux);
++
++      dvb_remove_frontend_notifier (av7110->dvb_adapter,
++                                    av7110_before_after_tune);
++
++      dvb_remove_frontend_ioctls (av7110->dvb_adapter,
++                                  av7110_diseqc_ioctl, NULL);
++
++      dvb_unregister_device(av7110->audio_dev);
++      dvb_unregister_device(av7110->video_dev);
++      dvb_unregister_device(av7110->osd_dev);
++      dvb_unregister_device(av7110->ca_dev);
++#ifdef USE_DVB_DSP
++      dvb_unregister_dsp(av7110->dsp_dev);
++#endif
++//        }
++}
++
++static int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num)
++{
++      struct saa7146_dev *dev = i2c->data;
++      return saa7146_i2c_transfer(dev, msgs, num, 6);
++}
++
++/****************************************************************************
++ * INITIALIZATION
++ ****************************************************************************/
++
++struct saa7146_extension_ioctls ioctls[] = {
++      { VIDIOC_ENUMINPUT,     SAA7146_EXCLUSIVE },
++      { VIDIOC_G_INPUT,       SAA7146_EXCLUSIVE },
++      { VIDIOC_S_INPUT,       SAA7146_EXCLUSIVE },
++      { VIDIOC_G_FREQUENCY,   SAA7146_EXCLUSIVE },
++      { VIDIOC_S_FREQUENCY,   SAA7146_EXCLUSIVE },
++      { VIDIOC_G_TUNER,       SAA7146_EXCLUSIVE },
++      { VIDIOC_S_TUNER,       SAA7146_EXCLUSIVE },
++      { VIDIOC_G_AUDIO,       SAA7146_EXCLUSIVE },
++      { VIDIOC_S_AUDIO,       SAA7146_EXCLUSIVE },
++      { 0, 0 }
++};
++
++static u8 saa7113_init_regs[] = {
++      0x02, 0xd0,
++      0x03, 0x23,
++      0x04, 0x00,
++      0x05, 0x00,
++      0x06, 0xe9,
++      0x07, 0x0d,
++      0x08, 0x98,
++      0x09, 0x02,
++      0x0a, 0x80,
++      0x0b, 0x40,
++      0x0c, 0x40,
++      0x0d, 0x00,
++      0x0e, 0x01,
++      0x0f, 0x7c,
++      0x10, 0x48,
++      0x11, 0x0c,
++      0x12, 0x8b,
++      0x13, 0x1a,
++      0x14, 0x00,
++      0x15, 0x00,
++      0x16, 0x00,
++      0x17, 0x00,
++      0x18, 0x00,
++      0x19, 0x00,
++      0x1a, 0x00,
++      0x1b, 0x00,
++      0x1c, 0x00,
++      0x1d, 0x00,
++      0x1e, 0x00,
++
++      0x41, 0x77,
++      0x42, 0x77,
++      0x43, 0x77,
++      0x44, 0x77,
++      0x45, 0x77,
++      0x46, 0x77,
++      0x47, 0x77,
++      0x48, 0x77,
++      0x49, 0x77,
++      0x4a, 0x77,
++      0x4b, 0x77,
++      0x4c, 0x77,
++      0x4d, 0x77,
++      0x4e, 0x77,
++      0x4f, 0x77,
++      0x50, 0x77,
++      0x51, 0x77,
++      0x52, 0x77,
++      0x53, 0x77,
++      0x54, 0x77,
++      0x55, 0x77,
++      0x56, 0x77,
++      0x57, 0xff,
++      
++      0xff
++};
++
++
++static struct saa7146_ext_vv av7110_vv_data_st;
++static struct saa7146_ext_vv av7110_vv_data_c;
++
++static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
++{
++      struct av7110 *av7110 = NULL;
++      int ret = 0;
++      
++      if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) {
++              printk ("%s: out of memory!\n", __FUNCTION__);
++              return -ENOMEM;
++      }
++
++      memset(av7110, 0, sizeof(struct av7110));
++
++      av7110->card_name = (char*)pci_ext->ext_priv;
++      (struct av7110*)dev->ext_priv = av7110;
++
++      DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
++
++      av7110->dev=(struct saa7146_dev *)dev;
++      dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name);
++
++      /* the Siemens DVB needs this if you want to have the i2c chips
++         get recognized before the main driver is fully loaded */
++      saa7146_write(dev, GPIO_CTRL, 0x500000);
++
++      saa7146_i2c_adapter_prepare(dev, NULL, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
++
++      av7110->i2c_bus = dvb_register_i2c_bus (master_xfer, dev,
++                                              av7110->dvb_adapter, 0);
++
++      if (!av7110->i2c_bus) {
++              dvb_unregister_adapter (av7110->dvb_adapter);
++              kfree(av7110);
++              return -ENOMEM;
++      }
++
++      ttpci_eeprom_parse_mac(av7110->i2c_bus);
++
++      saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
++      saa7146_write(dev, BCS_CTRL, 0x80400040);
++
++      /* set dd1 stream a & b */
++              saa7146_write(dev, DD1_STREAM_B, 0x00000000);
++      saa7146_write(dev, DD1_INIT, 0x03000000);
++      saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
++
++      /* upload all */
++      saa7146_write(dev, MC2, 0x077c077c);
++        saa7146_write(dev, GPIO_CTRL, 0x000000);
++
++      tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110);
++      tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110);
++
++        sema_init(&av7110->pid_mutex, 1);
++
++        /* locks for data transfers from/to AV7110 */
++        spin_lock_init (&av7110->debilock);
++        sema_init(&av7110->dcomlock, 1);
++        av7110->debilock=SPIN_LOCK_UNLOCKED;
++        av7110->debitype=-1;
++
++        /* default OSD window */
++        av7110->osdwin=1;
++
++        /* ARM "watchdog" */
++      init_waitqueue_head(&av7110->arm_wait);
++        av7110->arm_thread=0;
++     
++        av7110->vidmode=VIDEO_MODE_PAL;
++
++        av7110_ipack_init(&av7110->ipack[0], IPACKS, play_audio_cb);
++        av7110->ipack[0].data=(void *) av7110;
++        av7110_ipack_init(&av7110->ipack[1], IPACKS, play_video_cb);
++        av7110->ipack[1].data=(void *) av7110;
++        
++
++        /* allocate and init buffers */
++        av7110->debi_virt = pci_alloc_consistent(dev->pci, 8192,
++                                               &av7110->debi_bus);
++      if (!av7110->debi_virt) {
++              ret = -ENOMEM;
++                goto err;
++      }
++
++        av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
++      if (!av7110->iobuf) {
++              ret = -ENOMEM;
++                goto err;
++      }
++
++        dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN);
++        dvb_ringbuffer_init(&av7110->aout, av7110->iobuf+AVOUTLEN, AOUTLEN);
++
++        /* init BMP buffer */
++        av7110->bmpbuf=av7110->iobuf+AVOUTLEN+AOUTLEN;
++        init_waitqueue_head(&av7110->bmpq);
++        
++        av7110->kbuf[0]=(u8 *)(av7110->iobuf+AVOUTLEN+AOUTLEN+BMPLEN);
++        av7110->kbuf[1]=av7110->kbuf[0]+2*IPACKS;
++
++        /* CI link layer buffers */
++        ci_ll_init(&av7110->ci_rbuffer, &av7110->ci_wbuffer, 8192);
++
++        /* handle different card types */
++
++        /* load firmware into AV7110 cards */
++
++      bootarm(av7110);
++      firmversion(av7110);
++
++      if (FW_VERSION(av7110->arm_app)<0x2501)
++              printk ("av7110: Warning, firmware version 0x%04x is too old. "
++                      "System might be unstable!\n", FW_VERSION(av7110->arm_app));
++
++      kernel_thread(arm_thread, (void *) av7110, 0);
++
++      /* set internal volume control to maximum */
++      av7110->adac_type = DVB_ADAC_TI;
++      SetVolume(av7110, 0xff, 0xff);
++
++      VidMode(av7110, vidmode);
++
++      /* remaining inits according to card and frontend type */
++      av7110->has_analog_tuner = 0;
++      av7110->current_input = 0;
++      if (i2c_writereg(av7110, 0x20, 0x00, 0x00)==1) {
++              printk ("av7110(%d): Crystal audio DAC detected\n",
++                      av7110->dvb_adapter->num);
++              av7110->adac_type = DVB_ADAC_CRYSTAL;
++              i2c_writereg(av7110, 0x20, 0x01, 0xd2);
++              i2c_writereg(av7110, 0x20, 0x02, 0x49);
++              i2c_writereg(av7110, 0x20, 0x03, 0x00);
++              i2c_writereg(av7110, 0x20, 0x04, 0x00);
++      
++      /**
++       * some special handling for the Siemens DVB-C cards...
++       */
++      } else if (i2c_writereg(av7110, 0x80, 0x0, 0x80) == 1
++                      && i2c_writereg(av7110, 0x80, 0x0, 0) == 1) {
++              u16 version1, version2;
++              printk ("av7110(%d): DVB-C analog module detected, "
++                      "initializing MSP3400\n",
++                      av7110->dvb_adapter->num);
++              av7110->adac_type = DVB_ADAC_MSP;
++              dvb_delay(100); // the probing above resets the msp...
++              msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
++              msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
++              printk("av7110(%d): MSP3400 version 0x%04x 0x%04x\n",
++                      av7110->dvb_adapter->num, version1, version2);
++              msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
++              msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
++              msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source
++              msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source
++              msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume
++              msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source
++              msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
++              msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x4800); // prescale SCART
++              
++              if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
++                      INFO(("saa7113 not accessible.\n"));
++              }
++              else {
++                      u8 *i = saa7113_init_regs;
++                      av7110->has_analog_tuner = 1;
++                      /* init the saa7113 */
++                      while (*i != 0xff) {
++                              if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
++                                      printk("av7110(%d): saa7113 initialization failed",
++                                                      av7110->dvb_adapter->num);
++                                      break;
++                              }
++                              i += 2;
++                      }
++                      /* setup msp for analog sound: B/G Dual-FM */
++                      msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0001,  3); // FIR1
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0005,  4); // FIR2
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0005,  0); // FIR2
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0005,  3); // FIR2
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz
++                      msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI
++                      msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz
++                      msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI
++                      msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2
++              }       
++
++              memcpy(standard,dvb_standard,sizeof(struct saa7146_standard)*2);
++              /* set dd1 stream a & b */
++                      saa7146_write(dev, DD1_STREAM_B, 0x00000000);
++              saa7146_write(dev, DD1_INIT, 0x03000700);
++              saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
++      }
++      else if (dev->pci->subsystem_vendor == 0x110a) {
++              printk("av7110(%d): DVB-C w/o analog module detected\n",
++                      av7110->dvb_adapter->num);
++              av7110->adac_type = DVB_ADAC_NONE;
++      }
++      else {
++              av7110->adac_type = adac;
++              printk("av7110(%d): adac type set to %d\n",
++                      av7110->dvb_adapter->num, av7110->adac_type);
++              }
++
++      if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
++              // switch DVB SCART on
++              outcom(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
++              outcom(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
++              if (rgb_on)
++                      saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
++              //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
++      }
++      
++      SetVolume(av7110, 0xff, 0xff);
++
++      av7110_setup_irc_config (av7110, 0);
++      av7110_register(av7110);
++      
++      /* special case DVB-C: these cards have an analog tuner
++         plus need some special handling, so we have separate
++         saa7146_ext_vv data for these... */
++      if (0 != av7110->has_analog_tuner) {
++              ret = saa7146_vv_init(dev, &av7110_vv_data_c);
++      } else {
++              ret = saa7146_vv_init(dev, &av7110_vv_data_st);
++      }
++      
++      if ( 0 != ret) {
++              ERR(("cannot init capture device. skipping.\n"));
++              ret = -ENODEV;
++              goto err;
++      }
++
++      if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
++              ERR(("cannot register capture device. skipping.\n"));
++              ret = -ENODEV;
++              goto video_err;
++      }
++      
++      if (0 != av7110->has_analog_tuner) {
++              if( 0 != saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
++                      ERR(("cannot register vbi v4l2 device. skipping.\n"));
++              }
++              /* we use this to remember that this dvb-c card cannot do vbi */
++              av7110->has_analog_tuner = 2;
++      }       
++
++      printk(KERN_INFO "av7110: found av7110-%d.\n",av7110_num);
++      av7110_num++;
++        return 0;
++
++video_err:
++      saa7146_vv_release(dev);
++
++err:
++      if (NULL != av7110 ) {
++              kfree(av7110);
++      }
++      if (NULL != av7110->debi_virt) {
++              pci_free_consistent(dev->pci, 8192, av7110->debi_virt, av7110->debi_bus);
++      }
++      if (NULL != av7110->iobuf) {
++              vfree(av7110->iobuf);
++      }
++
++      dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter,
++                              av7110->i2c_bus->id);
++
++      dvb_unregister_adapter (av7110->dvb_adapter);
++
++      return ret;
++}
++
++static int av7110_detach (struct saa7146_dev* saa)
++{
++      struct av7110 *av7110 = (struct av7110*)saa->ext_priv;
++      DEB_EE(("av7110: %p\n",av7110));
++
++      saa7146_unregister_device(&av7110->v4l_dev, saa);
++      if (2 == av7110->has_analog_tuner) {
++              saa7146_unregister_device(&av7110->vbi_dev, saa);
++      }       
++
++      av7110->arm_rmmod=1;
++      wake_up_interruptible(&av7110->arm_wait);
++
++      while (av7110->arm_thread)
++              dvb_delay(1);
++
++      dvb_unregister(av7110);
++      
++      IER_DISABLE(saa, (MASK_19 | MASK_03));
++//    saa7146_write (av7110->dev, IER, 
++//                 saa7146_read(av7110->dev, IER) & ~(MASK_19 | MASK_03));
++      
++      saa7146_write(av7110->dev, ISR,(MASK_19 | MASK_03));
++
++      ci_ll_release(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
++      av7110_ipack_free(&av7110->ipack[0]);
++      av7110_ipack_free(&av7110->ipack[1]);
++      vfree(av7110->iobuf);
++      pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
++                          av7110->debi_bus);
++
++      dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id);
++      dvb_unregister_adapter (av7110->dvb_adapter);
++
++      kfree (av7110);
++
++      saa->ext_priv = NULL;
++      av7110_num--;
++      
++      return 0;
++}
++
++
++static void av7110_irq(struct saa7146_dev* dev, u32 *isr) 
++{
++      struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
++
++//    DEB_INT(("dev: %p, av7110: %p\n",dev,av7110));
++
++      if (*isr & MASK_19)
++              tasklet_schedule (&av7110->debi_tasklet);
++      
++      if (*isr & MASK_03)
++              tasklet_schedule (&av7110->gpio_tasklet);
++}
++
++
++/* FIXME: these values are experimental values that look better than the
++   values from the latest "official" driver -- at least for me... (MiHu) */
++static struct saa7146_standard standard[] = {
++      {
++              .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
++              .v_offset       = 0x15, .v_field        = 288,          .v_calc = 576,
++              .h_offset       = 0x4a, .h_pixels       = 708,          .h_calc = 709,
++              .v_max_out      = 576,  .h_max_out      = 768,
++      }, {
++              .name   = "NTSC",       .id             = V4L2_STD_NTSC,
++              .v_offset       = 0x10, .v_field        = 244,          .v_calc = 480,
++              .h_offset       = 0x40, .h_pixels       = 708,          .h_calc = 709,
++              .v_max_out      = 480,  .h_max_out      = 640,
++      }
++};
++
++static struct saa7146_standard analog_standard[] = {
++      {
++              .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
++              .v_offset       = 0x18 /* 0 */ ,        .v_field        = 288,          .v_calc = 576,
++              .h_offset       = 0x08, .h_pixels       = 708,          .h_calc = 709,
++              .v_max_out      = 576,  .h_max_out      = 768,
++      }, {
++              .name   = "NTSC",       .id             = V4L2_STD_NTSC,
++              .v_offset       = 0x10, .v_field        = 244,          .v_calc = 480,
++              .h_offset       = 0x40, .h_pixels       = 708,          .h_calc = 709,
++              .v_max_out      = 480,  .h_max_out      = 640,
++      }
++};
++
++static struct saa7146_standard dvb_standard[] = {
++      {
++              .name   = "PAL",        .id             = V4L2_STD_PAL_BG,
++              .v_offset       = 0x14, .v_field        = 288,          .v_calc = 576,
++              .h_offset       = 0x4a, .h_pixels       = 708,          .h_calc = 709,
++              .v_max_out      = 576,  .h_max_out      = 768,
++      }, {
++              .name   = "NTSC",       .id             = V4L2_STD_NTSC,
++              .v_offset       = 0x10, .v_field        = 244,          .v_calc = 480,
++              .h_offset       = 0x40, .h_pixels       = 708,          .h_calc = 709,
++              .v_max_out      = 480,  .h_max_out      = 640,
++      }
++};
++
++static struct saa7146_extension av7110_extension;
++
++#define MAKE_AV7110_INFO(x_var,x_name) \
++static struct saa7146_pci_extension_data x_var = { \
++      .ext_priv = x_name, \
++      .ext = &av7110_extension }
++
++MAKE_AV7110_INFO(fs_1_5, "Siemens cable card PCI rev1.5");
++MAKE_AV7110_INFO(fs_1_3, "Siemens/Technotrend/Hauppauge PCI rev1.3");
++MAKE_AV7110_INFO(tt_1_6, "Technotrend/Hauppauge PCI rev1.3 or 1.6");
++MAKE_AV7110_INFO(tt_2_1, "Technotrend/Hauppauge PCI rev2.1");
++MAKE_AV7110_INFO(tt_t,         "Technotrend/Hauppauge PCI DVB-T");
++MAKE_AV7110_INFO(unkwn0, "Technotrend/Hauppauge PCI rev?(unknown0)?");
++MAKE_AV7110_INFO(unkwn1, "Technotrend/Hauppauge PCI rev?(unknown1)?");
++MAKE_AV7110_INFO(unkwn2, "Technotrend/Hauppauge PCI rev?(unknown2)?");
++MAKE_AV7110_INFO(nexus,  "Technotrend/Hauppauge Nexus PCI DVB-S");
++MAKE_AV7110_INFO(dvboc11,"Octal/Technotrend DVB-C for iTV");
++
++static struct pci_device_id pci_tbl[] = {
++      MAKE_EXTENSION_PCI(fs_1_5, 0x110a, 0xffff),
++      MAKE_EXTENSION_PCI(fs_1_5, 0x110a, 0x0000),
++      MAKE_EXTENSION_PCI(fs_1_3, 0x13c2, 0x0000),
++      MAKE_EXTENSION_PCI(unkwn0, 0x13c2, 0x1002),
++      MAKE_EXTENSION_PCI(tt_1_6, 0x13c2, 0x0001),
++      MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0002),
++      MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0003),
++      MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0004),
++      MAKE_EXTENSION_PCI(tt_1_6, 0x13c2, 0x0006),
++      MAKE_EXTENSION_PCI(tt_t,   0x13c2, 0x0008),
++      MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x1102),
++      MAKE_EXTENSION_PCI(unkwn1, 0xffc2, 0x0000),
++      MAKE_EXTENSION_PCI(unkwn2, 0x00a1, 0x00a1),
++      MAKE_EXTENSION_PCI(nexus,  0x00a1, 0xa1a0),
++      MAKE_EXTENSION_PCI(dvboc11,0x13c2, 0x000a),
++      {
++              .vendor    = 0,
++      }
++};
++
++MODULE_DEVICE_TABLE(pci, pci_tbl);
++
++static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
++{
++      struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
++      if (std->id == V4L2_STD_PAL) {
++                av7110->vidmode = VIDEO_MODE_PAL;
++              SetMode(av7110, av7110->vidmode);
++      }
++      else if (std->id == V4L2_STD_NTSC) {
++              av7110->vidmode = VIDEO_MODE_NTSC;
++              SetMode(av7110, av7110->vidmode);
++      }
++      else
++              return -1;
++
++      return 0;
++}
++
++
++static struct saa7146_ext_vv av7110_vv_data_st = {
++      .inputs         = 1,
++      .audios         = 1,
++      .capabilities   = 0,
++      .flags          = 0, 
++
++      .stds           = &standard[0],
++      .num_stds       = sizeof(standard)/sizeof(struct saa7146_standard),
++      .std_callback   = &std_callback, 
++
++      .ioctls         = &ioctls[0],
++      .ioctl          = av7110_ioctl,
++};
++
++static struct saa7146_ext_vv av7110_vv_data_c = {
++      .inputs         = 1,
++      .audios         = 1,
++      .capabilities   = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
++      .flags          = SAA7146_USE_PORT_B_FOR_VBI,
++
++      .stds           = &standard[0],
++      .num_stds       = sizeof(standard)/sizeof(struct saa7146_standard),
++      .std_callback   = &std_callback, 
++
++      .ioctls         = &ioctls[0],
++      .ioctl          = av7110_ioctl,
++};
++
++
++static struct saa7146_extension av7110_extension = {
++      .name           = "dvb\0",
++      .flags          = SAA7146_I2C_SHORT_DELAY,
++
++      .module         = THIS_MODULE,
++      .pci_tbl        = &pci_tbl[0],
++      .attach         = av7110_attach,
++      .detach         = av7110_detach,
++
++      .irq_mask       = MASK_19|MASK_03,
++      .irq_func       = av7110_irq,
++};    
++
++
++static int __init av7110_init(void) 
++{
++      int retval;
++      retval = saa7146_register_extension(&av7110_extension);
++      if (retval)
++              goto failed_saa7146_register;
++      
++      retval = av7110_ir_init();
++      if (retval)
++              goto failed_av7110_ir_init;
++      return 0;
++failed_av7110_ir_init:
++      saa7146_unregister_extension(&av7110_extension);
++failed_saa7146_register:
++      return retval;
++}
++
++
++static void __exit av7110_exit(void)
++{
++      av7110_ir_exit();
++      saa7146_unregister_extension(&av7110_extension);
++}
++
++module_init(av7110_init);
++module_exit(av7110_exit);
++
++MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by "
++                 "Siemens, Technotrend, Hauppauge");
++MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
++MODULE_LICENSE("GPL");
++
++MODULE_PARM(av7110_debug,"i");
++MODULE_PARM(vidmode,"i");
++MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
++MODULE_PARM(pids_off,"i");
++MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
++MODULE_PARM(adac,"i");
++MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
++MODULE_PARM(hw_sections, "i");
++MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
++MODULE_PARM(rgb_on, "i");
++MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
++              " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
+--- linux-2.6.0/drivers/media/dvb/ttpci/av7110_firm.h  2003-10-25 14:45:45.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,28315 +0,0 @@
+-
+-#include <asm/types.h>
+-
+-static u8 Dpram [] = {
+-      0xe5, 0x9f, 0xf0, 0x1c, 0xe1, 0xb0, 0xf0, 0x0e, 
+-      0xe5, 0x9f, 0xf0, 0x18, 0xe2, 0x5e, 0xf0, 0x04, 
+-      0xe2, 0x5e, 0xf0, 0x08, 0xe1, 0xa0, 0x00, 0x00, 
+-      0xea, 0x00, 0x00, 0x06, 0xe2, 0x5e, 0xf0, 0x04, 
+-      0x2c, 0x00, 0x00, 0xe8, 0x2e, 0x02, 0x5c, 0xcc, 
+-      0x2e, 0x01, 0xcb, 0x40, 0xa5, 0xa5, 0x5a, 0x5a, 
+-      0x00, 0x1f, 0x15, 0x55, 0x00, 0x00, 0x00, 0x09, 
+-      0xe9, 0x2d, 0x5f, 0xff, 0xe1, 0x4f, 0x00, 0x00, 
+-      0xe9, 0x2d, 0x00, 0x01, 0xe2, 0x8f, 0x00, 0x01, 
+-      0xe1, 0x2f, 0xff, 0x10, 0x21, 0xff, 0x48, 0x25, 
+-      0x68, 0x00, 0x40, 0x52, 0x42, 0x08, 0xd1, 0x0b, 
+-      0x32, 0x20, 0x0a, 0x00, 0x42, 0x08, 0xd1, 0x07, 
+-      0x32, 0x20, 0x0a, 0x00, 0x42, 0x08, 0xd1, 0x03, 
+-      0x0a, 0x00, 0x42, 0x08, 0xd0, 0x29, 0x32, 0x20, 
+-      0x21, 0x0f, 0x42, 0x08, 0xd1, 0x01, 0x32, 0x10, 
+-      0x09, 0x00, 0x21, 0x01, 0x42, 0x08, 0xd1, 0x08, 
+-      0x1d, 0x12, 0x21, 0x02, 0x42, 0x08, 0xd1, 0x04, 
+-      0x1d, 0x12, 0x21, 0x04, 0x42, 0x08, 0xd1, 0x00, 
+-      0x1d, 0x12, 0x48, 0x13, 0x68, 0x00, 0xb4, 0x01, 
+-      0x08, 0x90, 0x21, 0x01, 0x40, 0x81, 0x48, 0x0f, 
+-      0x60, 0x01, 0x48, 0x0d, 0x58, 0x82, 0x48, 0x01, 
+-      0x46, 0x86, 0x47, 0x10, 0x2c, 0x00, 0x00, 0xb1, 
+-      0xbc, 0x02, 0x48, 0x0b, 0x68, 0x02, 0x23, 0x20, 
+-      0x05, 0x1b, 0x40, 0x1a, 0x43, 0x99, 0x43, 0x11, 
+-      0x60, 0x01, 0x00, 0x00, 0x47, 0x78, 0x00, 0x00, 
+-      0xe8, 0xbd, 0x00, 0x01, 0xe1, 0x69, 0xf0, 0x00, 
+-      0xe8, 0xbd, 0x5f, 0xff, 0xe2, 0x5e, 0xf0, 0x04, 
+-      0x2e, 0x08, 0x3a, 0xf4, 0x66, 0x00, 0x00, 0x14, 
+-      0x66, 0x00, 0x00, 0x18, 0x66, 0x00, 0x00, 0x1c, 
+-      0x00, 0x00, 0x00, 0x0c, 0x2e, 0x02, 0x5d, 0xd4, 
+-      0x2c, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-};
+-
+-
+-static u8 Root [] = {
+-      0xb4, 0x90, 0x49, 0x18, 0x1c, 0x0b, 0x4a, 0x18, 
+-      0x1a, 0x50, 0x4f, 0x18, 0x1a, 0x79, 0x10, 0x8f, 
+-      0x21, 0x00, 0x2f, 0x00, 0xdd, 0x04, 0xcb, 0x10, 
+-      0xc2, 0x10, 0x31, 0x01, 0x42, 0xb9, 0xdb, 0xfa, 
+-      0x49, 0x13, 0x18, 0x09, 0x4a, 0x13, 0x60, 0x11, 
+-      0x49, 0x13, 0x18, 0x09, 0x4a, 0x13, 0x60, 0x11, 
+-      0x49, 0x13, 0x18, 0x09, 0x4a, 0x13, 0x60, 0x11, 
+-      0x49, 0x13, 0x18, 0x09, 0x4a, 0x13, 0x60, 0x11, 
+-      0x49, 0x13, 0x18, 0x09, 0x4a, 0x13, 0x60, 0x11, 
+-      0x49, 0x13, 0x18, 0x09, 0x4a, 0x13, 0x60, 0x11, 
+-      0x49, 0x13, 0x18, 0x09, 0x4a, 0x13, 0x60, 0x11, 
+-      0x49, 0x13, 0x18, 0x08, 0x49, 0x13, 0x60, 0x08, 
+-      0xbc, 0x90, 0x47, 0x70, 0x2e, 0x01, 0xc8, 0x08, 
+-      0x9e, 0x00, 0x0a, 0x00, 0x2e, 0x01, 0xc9, 0x08, 
+-      0x2e, 0x01, 0xc8, 0x58, 0x2e, 0x01, 0xca, 0x28, 
+-      0x2e, 0x01, 0xc8, 0x90, 0x2e, 0x01, 0xca, 0x2c, 
+-      0x2e, 0x01, 0xc8, 0xac, 0x2e, 0x01, 0xca, 0x30, 
+-      0x2e, 0x01, 0xc8, 0x58, 0x2e, 0x01, 0xca, 0x34, 
+-      0x2e, 0x01, 0xc8, 0x74, 0x2e, 0x01, 0xca, 0x38, 
+-      0x2e, 0x01, 0xc8, 0xac, 0x2e, 0x01, 0xca, 0x3c, 
+-      0x2e, 0x01, 0xc8, 0x90, 0x2e, 0x01, 0xca, 0x40, 
+-      0x2e, 0x01, 0xc8, 0x08, 0x2e, 0x01, 0xca, 0x44, 
+-      0xb5, 0xf0, 0x1c, 0x0c, 0x1c, 0x15, 0x1c, 0x07, 
+-      0xb0, 0x82, 0x2a, 0x00, 0xd1, 0x03, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x0e, 0x38, 
+-      0x06, 0x00, 0x21, 0x0b, 0x06, 0x89, 0x4b, 0x43, 
+-      0x93, 0x01, 0x42, 0x88, 0xd1, 0x32, 0x08, 0x78, 
+-      0xd3, 0x05, 0x1e, 0x78, 0x88, 0x00, 0x70, 0x20, 
+-      0x34, 0x01, 0x3d, 0x01, 0x37, 0x01, 0x08, 0xb8, 
+-      0xd3, 0x0f, 0x2d, 0x02, 0xdb, 0x0d, 0x08, 0x60, 
+-      0xd3, 0x06, 0x88, 0x39, 0x0a, 0x09, 0x70, 0x21, 
+-      0x88, 0x38, 0x70, 0x60, 0x34, 0x02, 0xe0, 0x02, 
+-      0x88, 0x38, 0x80, 0x20, 0x34, 0x02, 0x3d, 0x02, 
+-      0x37, 0x02, 0x07, 0xae, 0x0f, 0xb6, 0x1b, 0xad, 
+-      0xd0, 0x08, 0x9b, 0x01, 0x68, 0x1b, 0x1c, 0x38, 
+-      0x1c, 0x21, 0x1c, 0x2a, 0xf0, 0x18, 0xfb, 0x6a, 
+-      0x19, 0x7f, 0x19, 0x64, 0x2e, 0x00, 0xd0, 0x54, 
+-      0x68, 0x38, 0x90, 0x00, 0x46, 0x6f, 0x78, 0x38, 
+-      0x70, 0x20, 0x34, 0x01, 0x37, 0x01, 0x3e, 0x01, 
+-      0xd1, 0xf9, 0xe0, 0x4a, 0x0e, 0x20, 0x06, 0x00, 
+-      0x42, 0x88, 0xd1, 0x3f, 0xe0, 0x14, 0x08, 0x60, 
+-      0xd3, 0x08, 0x1e, 0x60, 0x88, 0x01, 0x23, 0xff, 
+-      0x02, 0x1b, 0x40, 0x19, 0x78, 0x3a, 0x43, 0x11, 
+-      0x80, 0x01, 0xe0, 0x06, 0x88, 0x21, 0x06, 0x09, 
+-      0x0e, 0x09, 0x78, 0x3a, 0x02, 0x12, 0x43, 0x11, 
+-      0x80, 0x21, 0x34, 0x01, 0x3d, 0x01, 0x37, 0x01, 
+-      0x07, 0xb8, 0xd0, 0x01, 0x2d, 0x00, 0xdc, 0xe6, 
+-      0x07, 0xae, 0x0f, 0xb6, 0x1b, 0xad, 0xd0, 0x06, 
+-      0x9b, 0x01, 0x68, 0x1b, 0x1c, 0x38, 0x1c, 0x21, 
+-      0x1c, 0x2a, 0xf0, 0x18, 0xfb, 0x33, 0x19, 0x7f, 
+-      0x19, 0x64, 0x2e, 0x00, 0xd0, 0x1d, 0x08, 0x60, 
+-      0xd3, 0x08, 0x1e, 0x60, 0x88, 0x01, 0x23, 0xff, 
+-      0x02, 0x1b, 0x40, 0x19, 0x78, 0x3a, 0x43, 0x11, 
+-      0x80, 0x01, 0xe0, 0x06, 0x88, 0x21, 0x06, 0x09, 
+-      0x0e, 0x09, 0x78, 0x3a, 0x02, 0x12, 0x43, 0x11, 
+-      0x80, 0x21, 0x34, 0x01, 0x37, 0x01, 0x3e, 0x01, 
+-      0xd1, 0xe9, 0xe0, 0x06, 0x9b, 0x01, 0x68, 0x1b, 
+-      0x1c, 0x38, 0x1c, 0x21, 0x1c, 0x2a, 0xf0, 0x18, 
+-      0xfb, 0x11, 0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x00, 0x48, 
+-      0xb5, 0x00, 0x20, 0x03, 0xf0, 0x03, 0xfc, 0x50, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xf0, 0x4f, 0x10, 
+-      0x89, 0x3c, 0x89, 0xbe, 0x8a, 0x3d, 0x23, 0x04, 
+-      0x43, 0xdb, 0x68, 0x78, 0x40, 0x18, 0x0c, 0x1a, 
+-      0x60, 0x78, 0xb4, 0x04, 0x1c, 0x13, 0x22, 0x00, 
+-      0x21, 0x00, 0x20, 0x00, 0xf0, 0x00, 0xf8, 0x54, 
+-      0x20, 0x01, 0x60, 0x78, 0xb0, 0x01, 0x4a, 0x07, 
+-      0xb4, 0x04, 0x1c, 0x20, 0x1c, 0x31, 0x1c, 0x2a, 
+-      0x4b, 0x04, 0xf0, 0x00, 0xf8, 0x49, 0xb0, 0x01, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 
+-      0xb5, 0xb0, 0x06, 0x00, 0x0e, 0x00, 0x4f, 0x1d, 
+-      0x24, 0x10, 0x68, 0x3b, 0x2b, 0x00, 0xd1, 0x1a, 
+-      0x28, 0x00, 0xd0, 0x18, 0x20, 0xa5, 0x01, 0xc0, 
+-      0xf0, 0x05, 0xfb, 0x64, 0x60, 0x38, 0x8a, 0xbf, 
+-      0x1c, 0x03, 0x2f, 0x00, 0xd0, 0x0c, 0x2b, 0x00, 
+-      0xd0, 0x0a, 0x22, 0x01, 0x21, 0x00, 0x20, 0x1c, 
+-      0xb4, 0x07, 0x1c, 0x18, 0x22, 0x1d, 0x1c, 0x39, 
+-      0x1c, 0x23, 0xf0, 0x0a, 0xfb, 0xc7, 0xb0, 0x03, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x2b, 0x00, 
+-      0xd0, 0xfa, 0x28, 0x00, 0xd1, 0xf8, 0x8a, 0xbd, 
+-      0x2d, 0x00, 0xd0, 0x0a, 0x22, 0x00, 0x21, 0x00, 
+-      0x20, 0x1c, 0xb4, 0x07, 0x1c, 0x18, 0x22, 0x1d, 
+-      0x1c, 0x29, 0x1c, 0x23, 0xf0, 0x0a, 0xfb, 0xb2, 
+-      0xb0, 0x03, 0x68, 0x38, 0xf0, 0x05, 0xfb, 0x44, 
+-      0x20, 0x00, 0x60, 0x38, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x00, 0x00, 
+-      0xb5, 0xf0, 0x9f, 0x05, 0x04, 0x04, 0x0c, 0x24, 
+-      0x04, 0x0d, 0x0c, 0x2d, 0x04, 0x16, 0x0c, 0x36, 
+-      0x04, 0x19, 0x0c, 0x09, 0xb0, 0x82, 0x91, 0x00, 
+-      0x04, 0x38, 0x0c, 0x00, 0xb0, 0x81, 0x49, 0x89, 
+-      0x4f, 0x89, 0x42, 0x8d, 0xd1, 0x00, 0x89, 0xbd, 
+-      0x42, 0x8e, 0xd1, 0x00, 0x8a, 0x3e, 0x4a, 0x87, 
+-      0x42, 0x95, 0xd1, 0x02, 0x89, 0xbd, 0x08, 0xd3, 
+-      0x81, 0xbb, 0x4b, 0x84, 0x42, 0x9e, 0xd1, 0x02, 
+-      0x8a, 0x3e, 0x08, 0xdb, 0x82, 0x3b, 0x9a, 0x01, 
+-      0x42, 0x8a, 0xd1, 0x01, 0x8a, 0xba, 0x92, 0x01, 
+-      0x8a, 0xbb, 0x99, 0x01, 0x42, 0x99, 0xd0, 0x20, 
+-      0x68, 0x38, 0x90, 0x02, 0x28, 0x00, 0xd0, 0x1a, 
+-      0x2b, 0x00, 0xd0, 0x0a, 0x22, 0x00, 0x21, 0x00, 
+-      0x20, 0x1c, 0xb4, 0x07, 0x1c, 0x19, 0x23, 0x10, 
+-      0x22, 0x1d, 0x98, 0x05, 0xf0, 0x0a, 0xfb, 0x6a, 
+-      0xb0, 0x03, 0x99, 0x01, 0x29, 0x00, 0xd0, 0x0a, 
+-      0x22, 0x01, 0x21, 0x00, 0x20, 0x1c, 0xb4, 0x07, 
+-      0x99, 0x04, 0x23, 0x10, 0x22, 0x1d, 0x68, 0x38, 
+-      0xf0, 0x0a, 0xfb, 0x5c, 0xb0, 0x03, 0x99, 0x01, 
+-      0x82, 0xb9, 0x4b, 0x6d, 0x42, 0x9c, 0xd0, 0x37, 
+-      0xdc, 0x28, 0x2c, 0x00, 0xd0, 0x2e, 0x3b, 0x02, 
+-      0x42, 0x9c, 0xd0, 0x29, 0x4b, 0x69, 0x42, 0x9c, 
+-      0xd1, 0x00, 0x1c, 0x34, 0x22, 0x00, 0xb4, 0x04, 
+-      0x23, 0x00, 0x49, 0x62, 0x20, 0x1c, 0xf0, 0x0a, 
+-      0xfc, 0xe3, 0x89, 0xb8, 0xb0, 0x01, 0x42, 0x85, 
+-      0xd1, 0x02, 0x89, 0x38, 0x42, 0x84, 0xd0, 0x44, 
+-      0x81, 0xbd, 0x20, 0x1f, 0xf0, 0x0b, 0xf8, 0x1c, 
+-      0x23, 0x03, 0x02, 0x5b, 0x22, 0x01, 0x02, 0xd2, 
+-      0x21, 0x02, 0x20, 0x1f, 0xf0, 0x0a, 0xfe, 0x94, 
+-      0x2d, 0x00, 0xd0, 0x33, 0x2d, 0x01, 0xd1, 0x11, 
+-      0x25, 0x00, 0xe0, 0x32, 0x4b, 0x55, 0x42, 0x9c, 
+-      0xd0, 0x04, 0x33, 0x01, 0x42, 0x9c, 0xd1, 0xd9, 
+-      0x89, 0x3c, 0xe7, 0xd7, 0x2d, 0x00, 0xd0, 0x01, 
+-      0x1c, 0x2c, 0xe7, 0xd3, 0x1c, 0x34, 0xe7, 0xd1, 
+-      0x1c, 0x2c, 0xe7, 0xcf, 0x42, 0xac, 0xd1, 0x01, 
+-      0x20, 0x80, 0xe0, 0x00, 0x20, 0x00, 0x22, 0x00, 
+-      0xb4, 0x04, 0x06, 0x00, 0x0e, 0x00, 0x22, 0x02, 
+-      0x43, 0x02, 0x23, 0x01, 0x20, 0x1f, 0x1c, 0x29, 
+-      0xf0, 0x0a, 0xfc, 0xaa, 0x23, 0x01, 0x02, 0x9b, 
+-      0x00, 0x5a, 0x21, 0x01, 0x20, 0x1f, 0xb0, 0x01, 
+-      0xf0, 0x0a, 0xfe, 0x66, 0x21, 0x00, 0x20, 0x1f, 
+-      0xf0, 0x0b, 0xfb, 0x58, 0x20, 0x01, 0xf0, 0x0d, 
+-      0xff, 0x47, 0xe0, 0x02, 0x20, 0x00, 0xf0, 0x0d, 
+-      0xff, 0x43, 0x8a, 0x38, 0x42, 0x86, 0xd1, 0x02, 
+-      0x89, 0x39, 0x42, 0x8c, 0xd0, 0x52, 0x28, 0x00, 
+-      0xd0, 0x0d, 0x20, 0x03, 0xf0, 0x0e, 0xf8, 0x9a, 
+-      0x20, 0x1e, 0xf0, 0x0b, 0xf8, 0x97, 0x23, 0x03, 
+-      0x02, 0x5b, 0x22, 0x01, 0x02, 0xd2, 0x21, 0x02, 
+-      0x20, 0x1e, 0xf0, 0x0a, 0xfe, 0x45, 0x82, 0x3e, 
+-      0x2e, 0x00, 0xd0, 0x3f, 0x42, 0xb4, 0xd1, 0x02, 
+-      0x20, 0x80, 0x90, 0x00, 0xe0, 0x01, 0x20, 0x00, 
+-      0x90, 0x00, 0xf0, 0x1c, 0xf9, 0x57, 0x23, 0x01, 
+-      0x04, 0x1b, 0x43, 0x18, 0xf0, 0x1c, 0xf9, 0x56, 
+-      0x21, 0x00, 0x20, 0x00, 0xf0, 0x0e, 0xfd, 0x78, 
+-      0x20, 0xff, 0x49, 0x29, 0x68, 0x09, 0x70, 0x08, 
+-      0x49, 0x28, 0x48, 0x29, 0x23, 0x1e, 0x22, 0x10, 
+-      0xf0, 0x0e, 0xfe, 0xac, 0x48, 0x27, 0x68, 0x00, 
+-      0x78, 0x01, 0x23, 0x06, 0x43, 0x19, 0x70, 0x01, 
+-      0xf0, 0x1c, 0xf9, 0x3c, 0x4b, 0x24, 0x40, 0x18, 
+-      0xf0, 0x1c, 0xf9, 0x3c, 0x22, 0x00, 0xb4, 0x04, 
+-      0x98, 0x01, 0x06, 0x00, 0x0e, 0x00, 0x22, 0x02, 
+-      0x43, 0x02, 0x23, 0x02, 0x20, 0x1e, 0x1c, 0x31, 
+-      0xf0, 0x0a, 0xfc, 0x4a, 0x23, 0x01, 0x02, 0x9b, 
+-      0x00, 0x5a, 0x21, 0x01, 0x20, 0x1e, 0xb0, 0x01, 
+-      0xf0, 0x0a, 0xfe, 0x06, 0x21, 0x00, 0x20, 0x1e, 
+-      0xf0, 0x0b, 0xfa, 0xf8, 0x42, 0xac, 0xd0, 0x13, 
+-      0x42, 0xb4, 0xd0, 0x11, 0x2c, 0x00, 0xd0, 0x0f, 
+-      0x23, 0x01, 0x02, 0x9b, 0x00, 0x5a, 0x21, 0x01, 
+-      0x20, 0x1c, 0xf0, 0x0a, 0xfd, 0xf5, 0x22, 0x00, 
+-      0xb4, 0x04, 0x23, 0x00, 0x22, 0x82, 0x20, 0x1c, 
+-      0x1c, 0x21, 0xf0, 0x0a, 0xfc, 0x29, 0xb0, 0x01, 
+-      0x81, 0x3c, 0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 
+-      0x00, 0x00, 0xff, 0xfd, 0x00, 0x00, 0xff, 0xfc, 
+-      0x2e, 0x08, 0x5e, 0x2c, 0x2e, 0x08, 0x47, 0x60, 
+-      0x2e, 0x08, 0x05, 0xa8, 0x2e, 0x08, 0x5e, 0x58, 
+-      0xff, 0xfe, 0xff, 0xff, 0xb5, 0x00, 0x22, 0x00, 
+-      0xb4, 0x04, 0x04, 0x01, 0x0c, 0x09, 0x23, 0x00, 
+-      0x4a, 0x03, 0x1e, 0x50, 0xf7, 0xff, 0xfe, 0xc0, 
+-      0xb0, 0x01, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x00, 0x00, 0xff, 0xff, 0xb5, 0x00, 0x22, 0x00, 
+-      0xb4, 0x04, 0x04, 0x02, 0x0c, 0x12, 0x23, 0x00, 
+-      0x49, 0x03, 0x1e, 0x48, 0xf7, 0xff, 0xfe, 0xb0, 
+-      0xb0, 0x01, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x00, 0x00, 0xff, 0xff, 0xb5, 0x00, 0x04, 0x00, 
+-      0x0c, 0x00, 0xd0, 0x08, 0x28, 0x01, 0xd0, 0x0b, 
+-      0x28, 0x02, 0xd1, 0x02, 0x02, 0x00, 0xf0, 0x0d, 
+-      0xff, 0xf1, 0xbc, 0x08, 0x47, 0x18, 0x20, 0x80, 
+-      0xf0, 0x0d, 0xff, 0xec, 0xbc, 0x08, 0x47, 0x18, 
+-      0x20, 0xff, 0x30, 0x01, 0xf0, 0x0d, 0xff, 0xe6, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xb0, 0x27, 0x00, 
+-      0x4c, 0x1b, 0x20, 0x01, 0x04, 0x80, 0x21, 0x00, 
+-      0x22, 0x00, 0xc4, 0x86, 0xc4, 0x84, 0x3c, 0x14, 
+-      0xf0, 0x05, 0xf9, 0x70, 0x61, 0x60, 0x28, 0x00, 
+-      0xd0, 0x06, 0x21, 0x01, 0x04, 0x89, 0x61, 0xe1, 
+-      0x18, 0x41, 0x62, 0x20, 0x61, 0xa1, 0xe0, 0x02, 
+-      0x61, 0xe7, 0x61, 0xa7, 0x62, 0x27, 0x68, 0x21, 
+-      0x00, 0xc9, 0x4a, 0x10, 0x18, 0x89, 0x60, 0x48, 
+-      0x20, 0x00, 0x49, 0x0f, 0x4d, 0x0f, 0x00, 0x42, 
+-      0x52, 0x8d, 0x30, 0x01, 0x06, 0x00, 0x0e, 0x00, 
+-      0x28, 0x1d, 0xdb, 0xf8, 0x20, 0x00, 0x1c, 0x39, 
+-      0x4c, 0x0b, 0x4f, 0x0c, 0x4b, 0x0c, 0x00, 0x42, 
+-      0x52, 0xa5, 0x00, 0x82, 0x50, 0xb9, 0x50, 0x99, 
+-      0x30, 0x01, 0x06, 0x00, 0x0e, 0x00, 0x28, 0x20, 
+-      0xdb, 0xf5, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x00, 0x1c, 0x2e, 0x08, 0x3b, 0x70, 
+-      0x2e, 0x08, 0x48, 0xf8, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x49, 0x30, 0x2e, 0x08, 0x49, 0xe8, 
+-      0x2e, 0x08, 0x4a, 0x68, 0xb4, 0xf0, 0xb0, 0x81, 
+-      0x49, 0x25, 0xc9, 0x0c, 0x39, 0x08, 0x1a, 0xd2, 
+-      0x60, 0x8a, 0xd5, 0x02, 0x32, 0xff, 0x32, 0x01, 
+-      0x60, 0x8a, 0x6a, 0x0a, 0x62, 0x8a, 0x68, 0x8f, 
+-      0x2f, 0xfe, 0xdb, 0x03, 0x20, 0x00, 0xb0, 0x01, 
+-      0xbc, 0xf0, 0x47, 0x70, 0x30, 0x03, 0x08, 0x80, 
+-      0x00, 0x80, 0x4c, 0x1b, 0x69, 0xa6, 0x69, 0x64, 
+-      0x2f, 0x3e, 0xdb, 0x24, 0x00, 0xdb, 0x4f, 0x19, 
+-      0x19, 0xdb, 0x68, 0x5b, 0x62, 0x4b, 0x93, 0x00, 
+-      0x1a, 0x9f, 0x4b, 0x15, 0x69, 0xdd, 0x2f, 0x00, 
+-      0xdc, 0x00, 0x19, 0x7f, 0x23, 0x01, 0x03, 0x1b, 
+-      0x18, 0xc3, 0x42, 0xbb, 0xdd, 0x0f, 0x18, 0x17, 
+-      0x42, 0xb7, 0xdb, 0x09, 0x9a, 0x00, 0x1b, 0x12, 
+-      0x2a, 0x00, 0xdc, 0x00, 0x19, 0x52, 0x42, 0x93, 
+-      0xdd, 0x11, 0x18, 0x20, 0x62, 0x08, 0xe0, 0x0e, 
+-      0x62, 0x0f, 0x1c, 0x14, 0xe0, 0x0b, 0x18, 0x10, 
+-      0x62, 0x08, 0x1c, 0x14, 0xe0, 0x07, 0x18, 0x12, 
+-      0x42, 0xb2, 0xdb, 0x00, 0x62, 0x0c, 0x6a, 0x0a, 
+-      0x18, 0x10, 0x62, 0x08, 0x1c, 0x14, 0x1c, 0x20, 
+-      0xb0, 0x01, 0xbc, 0xf0, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x00, 0x1c, 0x2e, 0x08, 0x3b, 0x70, 
+-      0x48, 0x03, 0x6a, 0x81, 0x62, 0x01, 0x69, 0x01, 
+-      0x31, 0x01, 0x61, 0x01, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x00, 0x1c, 0xb5, 0xf7, 0x04, 0x05, 
+-      0x0c, 0x2d, 0x04, 0x0e, 0x0c, 0x36, 0xb0, 0x81, 
+-      0x23, 0x01, 0x03, 0x1b, 0x98, 0x03, 0x42, 0x9e, 
+-      0xdd, 0x05, 0x20, 0xff, 0xb0, 0x01, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x4f, 0x24, 
+-      0x68, 0xb9, 0x29, 0xff, 0xdb, 0x02, 0x20, 0xff, 
+-      0xb0, 0x01, 0xe7, 0xf4, 0x00, 0x69, 0x19, 0x49, 
+-      0x00, 0x89, 0x4a, 0x20, 0x18, 0x8c, 0x89, 0x21, 
+-      0x29, 0x01, 0xd0, 0x02, 0x20, 0xff, 0xb0, 0x01, 
+-      0xe7, 0xe9, 0x79, 0x81, 0x91, 0x00, 0x88, 0xa0, 
+-      0x08, 0x40, 0x07, 0x80, 0xd1, 0x02, 0x1c, 0x28, 
+-      0xf0, 0x05, 0xfb, 0xca, 0x88, 0xa0, 0x23, 0x06, 
+-      0x40, 0x18, 0x28, 0x02, 0xd1, 0x09, 0x88, 0xe0, 
+-      0x99, 0x00, 0x42, 0x88, 0xd1, 0x05, 0x1c, 0x28, 
+-      0xf0, 0x05, 0xfb, 0xbe, 0x20, 0xff, 0xb0, 0x01, 
+-      0xe7, 0xd1, 0x88, 0xe0, 0x4b, 0x10, 0x42, 0x98, 
+-      0xd1, 0x01, 0x99, 0x00, 0x80, 0xe1, 0x68, 0x39, 
+-      0x00, 0xc8, 0x4a, 0x0e, 0x52, 0x15, 0x18, 0x80, 
+-      0x80, 0x46, 0x9a, 0x03, 0x31, 0x01, 0x60, 0x42, 
+-      0x20, 0x00, 0x23, 0xff, 0x60, 0x39, 0x33, 0x01, 
+-      0x42, 0x99, 0xd1, 0x00, 0x60, 0x38, 0x68, 0xb9, 
+-      0x31, 0x01, 0x60, 0xb9, 0x68, 0xfb, 0x42, 0x99, 
+-      0xdd, 0x00, 0x60, 0xf9, 0xb0, 0x01, 0xe7, 0xb2, 
+-      0x2e, 0x08, 0x00, 0x1c, 0x2e, 0x08, 0x47, 0x78, 
+-      0x00, 0x00, 0xff, 0xff, 0x2e, 0x08, 0x3b, 0x70, 
+-      0xb5, 0xf0, 0x20, 0xff, 0xb0, 0x82, 0x49, 0x33, 
+-      0x91, 0x01, 0x49, 0x33, 0x8e, 0x89, 0x29, 0x00, 
+-      0xd0, 0x03, 0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x4f, 0x30, 0xcf, 0x0a, 0x3f, 0x08, 
+-      0x1a, 0xc9, 0x60, 0xb9, 0x1c, 0x0a, 0xd5, 0x02, 
+-      0x1d, 0xd1, 0x31, 0xf9, 0x60, 0xb9, 0x68, 0xb9, 
+-      0x29, 0x00, 0xd1, 0x03, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0xda, 0x49, 0x28, 
+-      0x5a, 0x8d, 0x18, 0x51, 0x88, 0x4c, 0x68, 0x49, 
+-      0x91, 0x00, 0x00, 0xa9, 0x4a, 0x25, 0x58, 0x56, 
+-      0x2e, 0x00, 0xd0, 0x07, 0x48, 0x24, 0x58, 0x43, 
+-      0x99, 0x00, 0x1c, 0x28, 0x1c, 0x22, 0xf0, 0x17, 
+-      0xff, 0xff, 0x20, 0x00, 0x28, 0x00, 0xd0, 0x29, 
+-      0x06, 0xed, 0x0e, 0xed, 0x1c, 0xe0, 0x08, 0x82, 
+-      0x00, 0x92, 0x98, 0x00, 0x99, 0x01, 0x6a, 0xfb, 
+-      0xf0, 0x17, 0xff, 0xec, 0x00, 0x68, 0x19, 0x40, 
+-      0x00, 0x80, 0x49, 0x1a, 0x18, 0x40, 0x88, 0x80, 
+-      0x21, 0x0c, 0x40, 0x01, 0x29, 0x0c, 0xd1, 0x04, 
+-      0x02, 0x29, 0x31, 0x02, 0x04, 0x09, 0x0c, 0x09, 
+-      0xe0, 0x03, 0x02, 0x29, 0x31, 0x01, 0x04, 0x09, 
+-      0x0c, 0x09, 0x08, 0x40, 0xd3, 0x04, 0x04, 0x08, 
+-      0x0c, 0x00, 0x21, 0x01, 0x03, 0xc9, 0x43, 0x01, 
+-      0x48, 0x09, 0x85, 0x01, 0x85, 0x44, 0x21, 0x01, 
+-      0x02, 0x49, 0x86, 0x81, 0x68, 0x78, 0x28, 0xff, 
+-      0xd1, 0x02, 0x20, 0x00, 0x60, 0x78, 0xe0, 0x01, 
+-      0x30, 0x01, 0x60, 0x78, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2c, 0x00, 0x02, 0x00, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x2e, 0x08, 0x00, 0x1c, 
+-      0x2e, 0x08, 0x3b, 0x70, 0x2e, 0x08, 0x49, 0xe8, 
+-      0x2e, 0x08, 0x4a, 0x68, 0x2e, 0x08, 0x47, 0x78, 
+-      0xb4, 0xf0, 0x06, 0x09, 0x0e, 0x09, 0x4f, 0x14, 
+-      0x8e, 0xba, 0x2a, 0x00, 0xd0, 0x03, 0x20, 0x00, 
+-      0x43, 0xc0, 0xbc, 0xf0, 0x47, 0x70, 0x1c, 0x05, 
+-      0x4c, 0x10, 0x1d, 0x48, 0xd5, 0x00, 0x30, 0x01, 
+-      0x10, 0x40, 0x04, 0x01, 0x0c, 0x09, 0x20, 0x00, 
+-      0x29, 0x02, 0xdb, 0xf2, 0x29, 0xe0, 0xdc, 0xf0, 
+-      0x22, 0x00, 0x29, 0x00, 0xdd, 0x07, 0x00, 0x53, 
+-      0x5a, 0xee, 0x52, 0xe6, 0x32, 0x01, 0x04, 0x12, 
+-      0x0c, 0x12, 0x42, 0x8a, 0xdb, 0xf7, 0x22, 0x04, 
+-      0x85, 0x3a, 0x00, 0x49, 0x85, 0x79, 0x21, 0x0f, 
+-      0x02, 0x49, 0x86, 0xb9, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x2c, 0x00, 0x1e, 0x00, 
+-      0xb5, 0xb0, 0x27, 0x00, 0x4d, 0x13, 0x8e, 0xa9, 
+-      0x29, 0x00, 0xd0, 0x03, 0x43, 0xf8, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x1c, 0x79, 0x04, 0x09, 
+-      0x0c, 0x09, 0x1c, 0x3a, 0x1c, 0x0f, 0x56, 0x81, 
+-      0x29, 0x00, 0xd1, 0xf7, 0x24, 0x00, 0x2f, 0xfe, 
+-      0xdd, 0x03, 0x27, 0xfe, 0x1d, 0xc1, 0x31, 0xd9, 
+-      0x77, 0xcc, 0x1c, 0x7a, 0x49, 0x08, 0xf7, 0xff, 
+-      0xfb, 0xc3, 0x20, 0x04, 0x85, 0x28, 0x1c, 0xf8, 
+-      0x08, 0x80, 0x00, 0x80, 0x85, 0x68, 0x20, 0x0f, 
+-      0x02, 0x40, 0x86, 0xa8, 0x1c, 0x20, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2c, 0x00, 0x1f, 0xc0, 
+-      0x2c, 0x00, 0x1e, 0x00, 0xb4, 0xf0, 0x4b, 0x1b, 
+-      0x8e, 0x9b, 0x2b, 0x00, 0xd0, 0x03, 0x20, 0x00, 
+-      0x43, 0xc0, 0xbc, 0xf0, 0x47, 0x70, 0x1c, 0xd4, 
+-      0xd5, 0x00, 0x34, 0x01, 0x10, 0x64, 0x1c, 0x0d, 
+-      0x4f, 0x15, 0x02, 0x00, 0x04, 0x00, 0x0c, 0x00, 
+-      0x78, 0x4e, 0x0a, 0x33, 0xd3, 0x07, 0x06, 0x73, 
+-      0x0e, 0x5b, 0x18, 0x59, 0x78, 0x89, 0x43, 0x08, 
+-      0x04, 0x00, 0x0c, 0x00, 0xe0, 0x03, 0x78, 0x89, 
+-      0x43, 0x08, 0x04, 0x00, 0x0c, 0x00, 0x80, 0x38, 
+-      0x20, 0x00, 0x2c, 0x00, 0xdd, 0x06, 0x00, 0x41, 
+-      0x5a, 0x6b, 0x19, 0xc9, 0x80, 0x4b, 0x30, 0x01, 
+-      0x42, 0xa0, 0xdb, 0xf8, 0x20, 0x0b, 0x49, 0x05, 
+-      0x85, 0x08, 0x1c, 0x90, 0x85, 0x48, 0x20, 0x01, 
+-      0x02, 0x40, 0x86, 0x88, 0x20, 0x00, 0xbc, 0xf0, 
+-      0x47, 0x70, 0x00, 0x00, 0x2c, 0x00, 0x1f, 0xc0, 
+-      0x2c, 0x00, 0x02, 0x00, 0x04, 0x02, 0x0c, 0x12, 
+-      0x48, 0x0c, 0x6f, 0xc1, 0x20, 0x00, 0x43, 0xc0, 
+-      0x29, 0x00, 0xd1, 0x12, 0x49, 0x0a, 0x8e, 0xcb, 
+-      0x2b, 0x00, 0xd1, 0x0e, 0x8d, 0x8b, 0x2b, 0x00, 
+-      0xd1, 0x0b, 0x48, 0x08, 0x86, 0xc2, 0x23, 0x07, 
+-      0x86, 0x83, 0x85, 0x8b, 0x85, 0xca, 0x20, 0x09, 
+-      0x02, 0x40, 0x86, 0xc8, 0x20, 0x01, 0x87, 0x88, 
+-      0x20, 0x00, 0x47, 0x70, 0x2c, 0x00, 0x1f, 0x80, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x2c, 0x00, 0x00, 0xc0, 
+-      0xb5, 0x80, 0x1c, 0x01, 0x4a, 0x0d, 0x8e, 0xd3, 
+-      0x20, 0x00, 0x43, 0xc0, 0x2b, 0x00, 0xd1, 0x12, 
+-      0x8d, 0x93, 0x2b, 0x07, 0xd1, 0x0f, 0x8d, 0xd7, 
+-      0x20, 0x00, 0x85, 0x90, 0x2f, 0x00, 0xd0, 0x0a, 
+-      0x23, 0x01, 0x02, 0xdb, 0x42, 0x9f, 0xdc, 0x06, 
+-      0x1c, 0x3a, 0x48, 0x05, 0x4b, 0x05, 0x6a, 0xdb, 
+-      0xf0, 0x17, 0xfe, 0xdc, 0x1c, 0x38, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2c, 0x00, 0x1f, 0xc0, 
+-      0x2c, 0x00, 0x12, 0x00, 0x2e, 0x08, 0x00, 0x1c, 
+-      0xb5, 0xf0, 0xb0, 0x83, 0x49, 0x62, 0x8e, 0x88, 
+-      0x28, 0x00, 0xd0, 0x03, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x4e, 0x5f, 0x78, 0x30, 
+-      0x49, 0x5f, 0x91, 0x02, 0x78, 0x09, 0x42, 0x88, 
+-      0xd1, 0x03, 0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x20, 0x00, 0x4d, 0x5b, 0x4b, 0x5c, 
+-      0x93, 0x01, 0x1d, 0xd9, 0x31, 0x19, 0x7d, 0x0a, 
+-      0x00, 0x53, 0x18, 0x9b, 0x01, 0x1b, 0x19, 0x5b, 
+-      0x78, 0xdc, 0x1c, 0x1f, 0x79, 0x1b, 0x42, 0x9c, 
+-      0xd1, 0x04, 0x79, 0x7b, 0x07, 0xdb, 0x0f, 0xdb, 
+-      0x2b, 0x01, 0xd1, 0x06, 0x7d, 0x0b, 0x93, 0x00, 
+-      0x32, 0x01, 0x07, 0x52, 0x0f, 0x52, 0x75, 0x0a, 
+-      0xe0, 0x08, 0x32, 0x01, 0x07, 0x52, 0x0f, 0x52, 
+-      0x75, 0x0a, 0x30, 0x01, 0x06, 0x00, 0x0e, 0x00, 
+-      0x28, 0x08, 0xdb, 0xe0, 0x28, 0x08, 0xd1, 0x03, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x98, 0x00, 0x00, 0x43, 0x18, 0x18, 0x01, 0x00, 
+-      0x19, 0x47, 0x78, 0xf8, 0x00, 0xc0, 0x19, 0xc0, 
+-      0x89, 0x84, 0x23, 0x01, 0x03, 0x1b, 0x42, 0x9c, 
+-      0xdd, 0x00, 0x1c, 0x1c, 0x68, 0x81, 0x89, 0xc0, 
+-      0x18, 0x08, 0x1c, 0xe1, 0x08, 0x8a, 0x00, 0x92, 
+-      0x49, 0x3e, 0x9b, 0x01, 0x6a, 0xdb, 0xf0, 0x17, 
+-      0xfe, 0x79, 0x88, 0x38, 0x02, 0x00, 0x30, 0x09, 
+-      0x49, 0x35, 0x85, 0x08, 0x85, 0x4c, 0x20, 0x01, 
+-      0x02, 0x40, 0x86, 0x88, 0x78, 0xf8, 0x00, 0xc0, 
+-      0x19, 0xc0, 0x89, 0xc1, 0x19, 0x09, 0x81, 0xc1, 
+-      0x78, 0xf8, 0x00, 0xc0, 0x19, 0xc0, 0x89, 0x81, 
+-      0x1b, 0x09, 0x81, 0x81, 0x78, 0xf8, 0x00, 0xc0, 
+-      0x19, 0xc0, 0x89, 0x81, 0x29, 0x00, 0xd1, 0x4f, 
+-      0x24, 0x00, 0x81, 0xc4, 0x78, 0xf9, 0x6a, 0xb8, 
+-      0x18, 0x40, 0x73, 0x04, 0x78, 0xf8, 0x30, 0x01, 
+-      0x07, 0x80, 0x0f, 0x80, 0x70, 0xf8, 0x78, 0x30, 
+-      0x30, 0x01, 0x70, 0x30, 0x78, 0xf8, 0x79, 0x39, 
+-      0x42, 0x88, 0xd1, 0x3d, 0x79, 0x78, 0x21, 0x02, 
+-      0x40, 0x01, 0x29, 0x02, 0xd1, 0x1e, 0x70, 0xfc, 
+-      0x71, 0x3c, 0x71, 0x7c, 0x49, 0x22, 0x80, 0x39, 
+-      0x6a, 0xb8, 0x68, 0x00, 0xf0, 0x04, 0xfe, 0xac, 
+-      0x6a, 0xb8, 0xf0, 0x04, 0xfe, 0xa9, 0x20, 0x00, 
+-      0x49, 0x1d, 0x00, 0x42, 0x18, 0x12, 0x01, 0x12, 
+-      0x5a, 0xaa, 0x42, 0x8a, 0xd1, 0x04, 0x30, 0x01, 
+-      0x06, 0x00, 0x0e, 0x00, 0x28, 0x08, 0xdb, 0xf4, 
+-      0x28, 0x08, 0xd1, 0x1d, 0x70, 0x34, 0x99, 0x02, 
+-      0x70, 0x0c, 0xe0, 0x19, 0x07, 0xc0, 0x0f, 0xc0, 
+-      0x28, 0x01, 0xd1, 0x15, 0x70, 0xfc, 0x71, 0x3c, 
+-      0x21, 0x06, 0x1d, 0xf8, 0x30, 0x19, 0x73, 0x41, 
+-      0x6a, 0xb9, 0x72, 0x0c, 0x79, 0x79, 0x08, 0x49, 
+-      0x00, 0x49, 0x71, 0x79, 0x22, 0x04, 0x7b, 0x01, 
+-      0xb4, 0x06, 0x78, 0xb9, 0x22, 0x0a, 0x20, 0x85, 
+-      0x6a, 0xbb, 0xf0, 0x0a, 0xfb, 0x07, 0xb0, 0x02, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x2e, 0x08, 0x03, 0xbc, 
+-      0x2e, 0x08, 0x03, 0xb8, 0x2e, 0x08, 0x44, 0x68, 
+-      0x2e, 0x08, 0x00, 0x1c, 0x2c, 0x00, 0x02, 0x00, 
+-      0x00, 0x00, 0xff, 0xff, 0xb5, 0x80, 0x4f, 0x0b, 
+-      0x68, 0x38, 0x28, 0x00, 0xd1, 0x0f, 0x20, 0x2f, 
+-      0x02, 0x80, 0xf0, 0x04, 0xfe, 0x87, 0x60, 0x38, 
+-      0x20, 0x00, 0x49, 0x07, 0x60, 0x08, 0x49, 0x07, 
+-      0x60, 0x08, 0x49, 0x07, 0x60, 0x08, 0x20, 0x2f, 
+-      0x02, 0x80, 0x49, 0x06, 0x60, 0x08, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x02, 0x5c, 0x90, 
+-      0x2e, 0x02, 0x5c, 0x98, 0x2e, 0x02, 0x5c, 0x94, 
+-      0x2e, 0x02, 0x5c, 0x9c, 0x2e, 0x02, 0x5c, 0xa0, 
+-      0xb5, 0x80, 0x4f, 0x04, 0x68, 0x38, 0xf0, 0x04, 
+-      0xfe, 0x73, 0x20, 0x00, 0x60, 0x38, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x02, 0x5c, 0x90, 
+-      0xb5, 0xf0, 0xb0, 0x82, 0x4a, 0x36, 0x8e, 0x90, 
+-      0x28, 0x00, 0xd0, 0x03, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x48, 0x33, 0x68, 0x01, 
+-      0x4e, 0x33, 0x68, 0x30, 0x1a, 0x0f, 0xd1, 0x03, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2f, 0x00, 0xda, 0x02, 0x23, 0x2f, 0x02, 0x9b, 
+-      0x18, 0xff, 0x4c, 0x2e, 0x6b, 0xa1, 0x1c, 0x4a, 
+-      0x49, 0x2d, 0x68, 0x09, 0x42, 0x8a, 0xd9, 0x13, 
+-      0x23, 0x2f, 0x01, 0x1b, 0x42, 0x9f, 0xda, 0x03, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x4a, 0x23, 0x8e, 0xd2, 0x2a, 0x00, 0xd0, 0x07, 
+-      0x23, 0xeb, 0x01, 0x1b, 0x42, 0x9f, 0xda, 0x03, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x63, 0xa1, 0x4b, 0x22, 0x42, 0x9f, 0xdd, 0x00, 
+-      0x1c, 0x1f, 0x21, 0x2f, 0x02, 0x89, 0x1a, 0x0d, 
+-      0x49, 0x1f, 0x91, 0x01, 0x42, 0xaf, 0xdd, 0x14, 
+-      0x1b, 0x7a, 0x92, 0x00, 0x99, 0x01, 0x68, 0x09, 
+-      0x18, 0x08, 0x1c, 0x2a, 0x49, 0x1b, 0x6b, 0x23, 
+-      0xf0, 0x17, 0xfd, 0x84, 0x4b, 0x19, 0x18, 0xe9, 
+-      0x98, 0x01, 0x9a, 0x00, 0x68, 0x00, 0x6b, 0x23, 
+-      0xf0, 0x17, 0xfd, 0x7c, 0x9a, 0x00, 0x60, 0x32, 
+-      0xe0, 0x0e, 0x99, 0x01, 0x68, 0x09, 0x18, 0x08, 
+-      0x1c, 0x3a, 0x49, 0x12, 0x6b, 0x23, 0xf0, 0x17, 
+-      0xfd, 0x71, 0x68, 0x30, 0x19, 0xc1, 0x20, 0x2f, 
+-      0x02, 0x80, 0xf0, 0x17, 0xfd, 0x75, 0x60, 0x31, 
+-      0x20, 0x12, 0x4a, 0x05, 0x85, 0x10, 0x85, 0x57, 
+-      0x20, 0x01, 0x02, 0x40, 0x86, 0x90, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x2e, 0x02, 0x5c, 0x98, 
+-      0x2e, 0x02, 0x5c, 0x94, 0x2e, 0x08, 0x00, 0x1c, 
+-      0x2e, 0x08, 0x05, 0xb0, 0x00, 0x00, 0x0f, 0x6c, 
+-      0x2e, 0x02, 0x5c, 0x90, 0x2c, 0x00, 0x02, 0x00, 
+-      0x20, 0x00, 0x49, 0x03, 0x60, 0x08, 0x49, 0x03, 
+-      0x60, 0x08, 0x49, 0x03, 0x60, 0x08, 0x47, 0x70, 
+-      0x2e, 0x02, 0x5c, 0x98, 0x2e, 0x02, 0x5c, 0x94, 
+-      0x2e, 0x02, 0x5c, 0x9c, 0x2a, 0x00, 0xd0, 0x05, 
+-      0x78, 0x03, 0x70, 0x0b, 0x30, 0x01, 0x31, 0x01, 
+-      0x3a, 0x01, 0xd1, 0xf9, 0x47, 0x70, 0xb5, 0xf3, 
+-      0xb0, 0x83, 0x98, 0x03, 0x78, 0x40, 0x00, 0x80, 
+-      0x1c, 0x0f, 0x49, 0x3d, 0x58, 0x08, 0x28, 0x00, 
+-      0xd1, 0x05, 0x20, 0xb0, 0xb0, 0x03, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x98, 0x03, 
+-      0x88, 0x45, 0x30, 0x04, 0xc8, 0x41, 0x1d, 0xf2, 
+-      0x32, 0xb9, 0x1a, 0x14, 0x23, 0x01, 0x03, 0x1b, 
+-      0x42, 0x9d, 0xdd, 0x03, 0x20, 0x00, 0x43, 0xc0, 
+-      0xb0, 0x03, 0xe7, 0xec, 0x19, 0x79, 0x91, 0x00, 
+-      0x4b, 0x30, 0x93, 0x02, 0x2c, 0xbc, 0xdc, 0x01, 
+-      0x2c, 0x00, 0xda, 0x07, 0x9b, 0x02, 0x68, 0x18, 
+-      0x30, 0x01, 0x60, 0x18, 0x20, 0x00, 0x43, 0xc0, 
+-      0xb0, 0x03, 0xe7, 0xdc, 0x42, 0xac, 0xdb, 0x06, 
+-      0x9b, 0x02, 0x68, 0x5b, 0x1c, 0x39, 0x1c, 0x2a, 
+-      0xf0, 0x17, 0xfd, 0x00, 0xe0, 0x44, 0x2d, 0x00, 
+-      0xdd, 0x42, 0x4b, 0x25, 0x93, 0x01, 0x99, 0x00, 
+-      0x42, 0x8f, 0xd9, 0x07, 0x9b, 0x02, 0x68, 0x18, 
+-      0x30, 0x01, 0x60, 0x18, 0x20, 0x00, 0x43, 0xc0, 
+-      0xb0, 0x03, 0xe7, 0xc4, 0x42, 0xa5, 0xdd, 0x07, 
+-      0x9b, 0x02, 0x68, 0x5b, 0x1c, 0x39, 0x1c, 0x22, 
+-      0xf0, 0x17, 0xfc, 0xe8, 0x68, 0x36, 0xe0, 0x05, 
+-      0x9b, 0x02, 0x68, 0x5b, 0x1c, 0x39, 0x1c, 0x2a, 
+-      0xf0, 0x17, 0xfc, 0xe0, 0x19, 0x3f, 0x1b, 0x2d, 
+-      0x79, 0xb0, 0x19, 0x80, 0x9a, 0x03, 0x78, 0x52, 
+-      0x00, 0xd3, 0x1a, 0x9a, 0x00, 0x92, 0x9b, 0x01, 
+-      0x68, 0x1b, 0x18, 0xd2, 0x78, 0x92, 0x06, 0xd2, 
+-      0x0e, 0xd2, 0x1d, 0x31, 0x2a, 0x12, 0xd1, 0x06, 
+-      0x78, 0xca, 0x0a, 0x12, 0xd2, 0x03, 0x78, 0x89, 
+-      0x29, 0x09, 0xd1, 0x00, 0x38, 0x01, 0x1d, 0xf1, 
+-      0x31, 0xb9, 0x1a, 0x0c, 0x2c, 0xbc, 0xdc, 0x01, 
+-      0x2c, 0x00, 0xda, 0x03, 0x20, 0x00, 0x43, 0xc0, 
+-      0xb0, 0x03, 0xe7, 0x90, 0x2d, 0x00, 0xdc, 0xbe, 
+-      0x20, 0x00, 0xb0, 0x03, 0xe7, 0x8b, 0x00, 0x00, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x00, 0x58, 
+-      0x2e, 0x08, 0x5d, 0xc4, 0xb4, 0xf0, 0x68, 0x42, 
+-      0x68, 0x84, 0x1d, 0xe1, 0x31, 0xb7, 0x1c, 0x16, 
+-      0xb0, 0x81, 0x42, 0x91, 0xd9, 0x09, 0x78, 0x51, 
+-      0x07, 0x09, 0x0f, 0x09, 0x02, 0x09, 0x78, 0x92, 
+-      0x43, 0x11, 0x31, 0x03, 0x04, 0x09, 0x0c, 0x09, 
+-      0xe0, 0x5b, 0x68, 0x21, 0x79, 0x8b, 0x93, 0x00, 
+-      0x1d, 0x0f, 0x18, 0x59, 0x78, 0x45, 0x00, 0xeb, 
+-      0x1b, 0x5b, 0x00, 0x9b, 0x4d, 0x2b, 0x68, 0x2d, 
+-      0x19, 0x5b, 0x78, 0x9b, 0x06, 0xdb, 0x0e, 0xdb, 
+-      0x2b, 0x12, 0xd1, 0x31, 0x1d, 0xe3, 0x33, 0xb9, 
+-      0x1b, 0x9b, 0x06, 0x1d, 0x0e, 0x2d, 0x78, 0xfe, 
+-      0x0a, 0x33, 0xd2, 0x29, 0x2d, 0x0e, 0xda, 0x27, 
+-      0x9b, 0x00, 0x2b, 0x09, 0xdd, 0x06, 0x79, 0x3b, 
+-      0x18, 0xfb, 0x33, 0x05, 0x42, 0x8b, 0xd0, 0x1f, 
+-      0x39, 0x01, 0xe0, 0x1d, 0x9b, 0x00, 0x2b, 0x09, 
+-      0xd1, 0x1a, 0x79, 0x3b, 0x2b, 0x00, 0xd0, 0x01, 
+-      0x39, 0x01, 0xe0, 0x15, 0x39, 0x01, 0x1d, 0xe3, 
+-      0x33, 0xb8, 0x42, 0x93, 0xd9, 0x09, 0x78, 0x53, 
+-      0x07, 0x1b, 0x0f, 0x1b, 0x02, 0x1b, 0x04, 0x1b, 
+-      0x0c, 0x1b, 0x33, 0x03, 0x04, 0x1b, 0x0c, 0x1b, 
+-      0xe0, 0x03, 0x78, 0x4b, 0x33, 0x03, 0x04, 0x1b, 
+-      0x0c, 0x1b, 0x42, 0x9d, 0xda, 0x00, 0x31, 0x01, 
+-      0x1d, 0xe3, 0x33, 0xb8, 0x42, 0x93, 0xd9, 0x0b, 
+-      0x78, 0x52, 0x07, 0x12, 0x0f, 0x12, 0x02, 0x12, 
+-      0x04, 0x12, 0x0c, 0x12, 0x78, 0x09, 0x18, 0x51, 
+-      0x31, 0x03, 0x04, 0x09, 0x0c, 0x09, 0xe0, 0x08, 
+-      0x78, 0x0a, 0x07, 0x12, 0x0f, 0x12, 0x02, 0x12, 
+-      0x78, 0x49, 0x43, 0x11, 0x31, 0x03, 0x04, 0x09, 
+-      0x0c, 0x09, 0x80, 0x41, 0xb0, 0x01, 0xbc, 0xf0, 
+-      0x47, 0x70, 0x00, 0x00, 0x2e, 0x08, 0x5d, 0xc4, 
+-      0x4a, 0x02, 0xc2, 0x03, 0x3a, 0x08, 0x20, 0x00, 
+-      0x60, 0x90, 0x47, 0x70, 0x2e, 0x08, 0x43, 0x70, 
+-      0x48, 0x01, 0x68, 0x80, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x43, 0x70, 0x48, 0x01, 0x68, 0x80, 
+-      0x08, 0xc0, 0x47, 0x70, 0x2e, 0x08, 0x43, 0x70, 
+-      0x48, 0x02, 0x68, 0x81, 0x08, 0xc9, 0x68, 0x00, 
+-      0x18, 0x08, 0x47, 0x70, 0x2e, 0x08, 0x43, 0x70, 
+-      0xb4, 0xf0, 0x1c, 0x03, 0x20, 0x00, 0xb0, 0x82, 
+-      0x49, 0x53, 0x91, 0x01, 0x68, 0x89, 0x18, 0xcf, 
+-      0x97, 0x00, 0x08, 0xca, 0x07, 0x4c, 0x0f, 0x64, 
+-      0x49, 0x4f, 0x68, 0x09, 0xd1, 0x32, 0x1c, 0x1f, 
+-      0xd5, 0x04, 0x42, 0x7f, 0x07, 0x7f, 0x0f, 0x7f, 
+-      0x42, 0x7f, 0xe0, 0x01, 0x07, 0x7f, 0x0f, 0x7f, 
+-      0x2f, 0x00, 0xd1, 0x27, 0x2b, 0x10, 0xd0, 0x16, 
+-      0xdc, 0x05, 0x2b, 0x00, 0xd0, 0x5a, 0x2b, 0x08, 
+-      0xd1, 0x59, 0x5c, 0x88, 0xe0, 0x81, 0x2b, 0x18, 
+-      0xd0, 0x13, 0x2b, 0x20, 0xd1, 0x53, 0x5c, 0x88, 
+-      0x06, 0x00, 0x18, 0x89, 0x78, 0x4a, 0x04, 0x12, 
+-      0x18, 0x80, 0x78, 0x8a, 0x02, 0x12, 0x18, 0x80, 
+-      0x78, 0xc9, 0x18, 0x40, 0xe0, 0x71, 0x5c, 0x88, 
+-      0x02, 0x00, 0x18, 0x89, 0x78, 0x49, 0x18, 0x40, 
+-      0xe0, 0x6b, 0x5c, 0x88, 0x04, 0x00, 0x18, 0x89, 
+-      0x78, 0x4a, 0x02, 0x12, 0x18, 0x80, 0x78, 0x89, 
+-      0x18, 0x40, 0xe0, 0x62, 0x2b, 0x00, 0xd1, 0x03, 
+-      0x20, 0x00, 0xb0, 0x02, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x9f, 0x00, 0x08, 0xfd, 0x07, 0x7f, 0x0f, 0x7f, 
+-      0x2b, 0x20, 0xdc, 0x56, 0x1a, 0xae, 0x4d, 0x2f, 
+-      0x2e, 0x05, 0xd2, 0x52, 0xa3, 0x01, 0x5d, 0x9b, 
+-      0x00, 0x5b, 0x44, 0x9f, 0x02, 0x09, 0x14, 0x25, 
+-      0x38, 0x00, 0x5c, 0x88, 0x5d, 0x29, 0x40, 0x08, 
+-      0x21, 0x08, 0x1b, 0xc9, 0x40, 0xc8, 0xe0, 0x44, 
+-      0x1c, 0x50, 0x5c, 0x8a, 0x5d, 0x2b, 0x40, 0x1a, 
+-      0x02, 0x12, 0x5c, 0x08, 0x18, 0x80, 0x21, 0x08, 
+-      0x1b, 0xc9, 0x40, 0xc8, 0xe0, 0x39, 0x1c, 0x50, 
+-      0x5c, 0x8a, 0x5d, 0x2b, 0x40, 0x1a, 0x02, 0x12, 
+-      0x1c, 0x43, 0x5c, 0x08, 0x18, 0x80, 0x02, 0x00, 
+-      0x5c, 0xc9, 0x18, 0x08, 0x21, 0x08, 0x1b, 0xc9, 
+-      0x40, 0xc8, 0xe0, 0x2a, 0xe0, 0x29, 0xe0, 0x28, 
+-      0x1c, 0x50, 0x5c, 0x8a, 0x5d, 0x2b, 0x40, 0x1a, 
+-      0x02, 0x12, 0x1c, 0x43, 0x5c, 0x08, 0x18, 0x80, 
+-      0x02, 0x00, 0x1c, 0x5a, 0x5c, 0xcb, 0x18, 0x18, 
+-      0x02, 0x00, 0x5c, 0x89, 0x18, 0x08, 0x21, 0x08, 
+-      0x1b, 0xc9, 0x40, 0xc8, 0xe0, 0x15, 0x1c, 0x50, 
+-      0x5c, 0x8a, 0x5d, 0x2b, 0x40, 0x1a, 0x02, 0x12, 
+-      0x1c, 0x43, 0x5c, 0x08, 0x18, 0x80, 0x02, 0x00, 
+-      0x1c, 0x5a, 0x5c, 0xcb, 0x18, 0x18, 0x02, 0x03, 
+-      0x1c, 0x50, 0x5c, 0x8a, 0x18, 0xd2, 0x40, 0xba, 
+-      0x5c, 0x08, 0x21, 0x08, 0x1b, 0xc9, 0x40, 0xc8, 
+-      0x18, 0x80, 0x99, 0x01, 0x9f, 0x00, 0x60, 0x8f, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x43, 0x70, 0x2e, 0x08, 0x00, 0x60, 
+-      0xb5, 0xb0, 0x1c, 0x07, 0x20, 0x00, 0x24, 0x00, 
+-      0x2f, 0x00, 0xdd, 0x09, 0x00, 0x85, 0x18, 0x2d, 
+-      0x00, 0x6d, 0x20, 0x04, 0xf7, 0xff, 0xff, 0x44, 
+-      0x19, 0x40, 0x34, 0x01, 0x42, 0xbc, 0xdb, 0xf5, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x47, 0x70, 0xb5, 0xb0, 0x1c, 0x0c, 0x1c, 0x05, 
+-      0x1c, 0x17, 0xb0, 0x90, 0xf0, 0x1b, 0xfb, 0x16, 
+-      0x49, 0x25, 0x20, 0x0c, 0xf0, 0x1b, 0xfa, 0xde, 
+-      0xf0, 0x1b, 0xfa, 0xd4, 0x4b, 0x23, 0x40, 0x18, 
+-      0xf0, 0x1b, 0xfa, 0xd4, 0xf0, 0x1b, 0xfb, 0x40, 
+-      0x20, 0x10, 0x90, 0x0a, 0x20, 0xff, 0x90, 0x0b, 
+-      0xa8, 0x0f, 0x90, 0x0c, 0x20, 0x0c, 0x90, 0x0d, 
+-      0x48, 0x1d, 0x90, 0x0e, 0xa8, 0x0a, 0xf0, 0x0f, 
+-      0xf8, 0xd5, 0xab, 0x07, 0x70, 0x1d, 0x94, 0x08, 
+-      0x72, 0x1f, 0x24, 0x00, 0xab, 0x09, 0x70, 0x5c, 
+-      0x27, 0x00, 0x4d, 0x18, 0xf0, 0x0f, 0xf9, 0x36, 
+-      0x28, 0x00, 0xd0, 0x02, 0x37, 0x01, 0x42, 0xaf, 
+-      0xdb, 0xf8, 0x20, 0x01, 0xa9, 0x07, 0xf0, 0x0f, 
+-      0xf9, 0x37, 0xf0, 0x0f, 0xf9, 0x2b, 0x28, 0x00, 
+-      0xd1, 0xfb, 0x94, 0x0b, 0xa8, 0x0a, 0xf0, 0x0f, 
+-      0xf8, 0xb9, 0xf0, 0x1b, 0xfa, 0xdf, 0x21, 0x00, 
+-      0x20, 0x0c, 0xf0, 0x1b, 0xfa, 0xa7, 0xf0, 0x1b, 
+-      0xfa, 0x9d, 0x23, 0x01, 0x02, 0xdb, 0x43, 0x18, 
+-      0xf0, 0x1b, 0xfa, 0x9c, 0xf0, 0x1b, 0xfb, 0x08, 
+-      0x46, 0x68, 0xf0, 0x0f, 0xf8, 0xf3, 0x98, 0x04, 
+-      0xb0, 0x10, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x00, 0x15, 0x45, 0xff, 0xff, 0xf7, 0xff, 
+-      0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x27, 0x10, 
+-      0xb5, 0xff, 0x9e, 0x09, 0x1c, 0x04, 0x1c, 0x0d, 
+-      0x1c, 0x17, 0xb0, 0x93, 0xf0, 0x1b, 0xfa, 0xba, 
+-      0x49, 0x31, 0x20, 0x0c, 0xf0, 0x1b, 0xfa, 0x82, 
+-      0xf0, 0x1b, 0xfa, 0x78, 0x4b, 0x2f, 0x40, 0x18, 
+-      0xf0, 0x1b, 0xfa, 0x78, 0xf0, 0x1b, 0xfa, 0xe4, 
+-      0x20, 0x10, 0x90, 0x0d, 0x20, 0xff, 0x90, 0x0e, 
+-      0xa8, 0x12, 0x90, 0x0f, 0x20, 0x0c, 0x90, 0x10, 
+-      0x48, 0x29, 0x90, 0x11, 0xa8, 0x0d, 0xf0, 0x0f, 
+-      0xf8, 0x79, 0xab, 0x07, 0x70, 0x1c, 0x95, 0x08, 
+-      0x72, 0x1f, 0x20, 0xff, 0xab, 0x09, 0x70, 0x58, 
+-      0x1c, 0x60, 0x71, 0x18, 0x9b, 0x16, 0x93, 0x0b, 
+-      0xab, 0x0c, 0x70, 0x1e, 0x20, 0xff, 0x70, 0x58, 
+-      0x24, 0x00, 0x4d, 0x20, 0xf0, 0x0f, 0xf8, 0xd2, 
+-      0x28, 0x00, 0xd0, 0x02, 0x34, 0x01, 0x42, 0xac, 
+-      0xdb, 0xf8, 0x2f, 0x00, 0xd1, 0x04, 0x20, 0x01, 
+-      0xa9, 0x0a, 0xf0, 0x0f, 0xf8, 0xd1, 0xe0, 0x03, 
+-      0x20, 0x02, 0xa9, 0x07, 0xf0, 0x0f, 0xf8, 0xcc, 
+-      0xf0, 0x0f, 0xf8, 0xc0, 0x28, 0x00, 0xd1, 0xfb, 
+-      0x27, 0x00, 0x97, 0x0e, 0xa8, 0x0d, 0xf0, 0x0f, 
+-      0xf8, 0x4d, 0xf0, 0x1b, 0xfa, 0x73, 0x21, 0x00, 
+-      0x20, 0x0c, 0xf0, 0x1b, 0xfa, 0x3b, 0xf0, 0x1b, 
+-      0xfa, 0x31, 0x23, 0x01, 0x02, 0xdb, 0x43, 0x18, 
+-      0xf0, 0x1b, 0xfa, 0x30, 0xf0, 0x1b, 0xfa, 0x9c, 
+-      0x46, 0x68, 0xf0, 0x0f, 0xf8, 0x87, 0x98, 0x01, 
+-      0x0a, 0x80, 0xd2, 0x05, 0x20, 0x01, 0xb0, 0x13, 
+-      0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x1c, 0x38, 0xb0, 0x13, 0xe7, 0xf8, 0x00, 0x00, 
+-      0x2e, 0x00, 0x15, 0x45, 0xff, 0xff, 0xf7, 0xff, 
+-      0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x27, 0x10, 
+-      0x1c, 0x01, 0x48, 0x04, 0x61, 0xc1, 0x68, 0x00, 
+-      0x28, 0x00, 0xd1, 0x01, 0x48, 0x02, 0x60, 0x01, 
+-      0x47, 0x70, 0x00, 0x00, 0x2e, 0x08, 0x01, 0x68, 
+-      0x6e, 0x00, 0x17, 0x00, 0xb5, 0xb0, 0x4f, 0x41, 
+-      0x69, 0x38, 0x4c, 0x41, 0x28, 0x00, 0xd0, 0x07, 
+-      0x20, 0x03, 0x60, 0x20, 0x69, 0x38, 0x38, 0x01, 
+-      0x61, 0x38, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x21, 0x02, 0x69, 0x78, 0x28, 0x00, 0xd0, 0x04, 
+-      0x60, 0x21, 0x69, 0x78, 0x38, 0x01, 0x61, 0x78, 
+-      0xd1, 0xf3, 0x68, 0xf8, 0x28, 0x00, 0xd0, 0x20, 
+-      0x38, 0x01, 0x60, 0xf8, 0x4a, 0x35, 0xd0, 0x08, 
+-      0x68, 0xbb, 0x18, 0xd2, 0x3a, 0x20, 0x7f, 0xd2, 
+-      0x1e, 0x45, 0x40, 0xea, 0x07, 0xd2, 0x0f, 0xd2, 
+-      0xe0, 0x09, 0x68, 0xbb, 0x18, 0xd2, 0x3a, 0x20, 
+-      0x7f, 0xd2, 0x4b, 0x2f, 0x5c, 0x9a, 0x23, 0x01, 
+-      0x40, 0x5a, 0x06, 0x12, 0x0e, 0x12, 0x23, 0x01, 
+-      0x2a, 0x00, 0xd0, 0x02, 0x61, 0x79, 0x61, 0x3b, 
+-      0xe0, 0x01, 0x61, 0x39, 0x61, 0x7b, 0x28, 0x00, 
+-      0xd1, 0xcf, 0x68, 0xb8, 0x30, 0x01, 0x60, 0xb8, 
+-      0x23, 0x09, 0x68, 0x7a, 0x1c, 0x01, 0x42, 0x90, 
+-      0xdc, 0x03, 0x60, 0xfb, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x20, 0x20, 0x1c, 0x55, 0x42, 0x8d, 
+-      0xd1, 0x03, 0x61, 0x78, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x1c, 0x95, 0x42, 0x8d, 0xd1, 0x0d, 
+-      0x7e, 0x3d, 0x2d, 0xff, 0xd0, 0x0a, 0x2d, 0x00, 
+-      0xd0, 0x03, 0x60, 0xfb, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x20, 0x19, 0x61, 0x38, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x32, 0x03, 0x42, 0x8a, 
+-      0xd1, 0x04, 0x20, 0x22, 0x61, 0x78, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x69, 0xf9, 0x60, 0x21, 
+-      0x68, 0x79, 0x68, 0xba, 0x31, 0x04, 0x42, 0x91, 
+-      0xd1, 0x0a, 0x69, 0xf9, 0x29, 0x00, 0xd0, 0x03, 
+-      0x61, 0x38, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x61, 0x78, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xf0, 0x04, 0xf8, 0xac, 0x20, 0x00, 0x60, 0x38, 
+-      0x69, 0xf8, 0x60, 0x20, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x01, 0x68, 
+-      0x6e, 0x00, 0x17, 0x00, 0x2e, 0x08, 0x43, 0x7c, 
+-      0x2e, 0x08, 0x00, 0x68, 0xb5, 0xb0, 0x04, 0x0b, 
+-      0x0c, 0x1b, 0x04, 0x14, 0x0c, 0x24, 0x49, 0x14, 
+-      0x68, 0x0a, 0x2a, 0x00, 0xd0, 0x02, 0x68, 0x0a, 
+-      0x2a, 0x00, 0xd1, 0xfc, 0x22, 0x01, 0x60, 0x0a, 
+-      0x2b, 0x0a, 0xdd, 0x00, 0x23, 0x0a, 0x22, 0x00, 
+-      0x4f, 0x0e, 0x2b, 0x00, 0xdd, 0x05, 0x00, 0x55, 
+-      0x5b, 0x45, 0x54, 0xbd, 0x32, 0x01, 0x42, 0x9a, 
+-      0xdb, 0xf9, 0x76, 0x0c, 0x20, 0xff, 0x18, 0xfa, 
+-      0x70, 0x50, 0x20, 0x00, 0x60, 0x4b, 0x22, 0x20, 
+-      0x61, 0x08, 0x61, 0x4a, 0x60, 0x88, 0x60, 0xc8, 
+-      0x49, 0x05, 0x20, 0x32, 0xf0, 0x04, 0xf8, 0x48, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x01, 0x68, 0x2e, 0x08, 0x43, 0x7c, 
+-      0x2e, 0x00, 0x17, 0x01, 0xb5, 0x80, 0x04, 0x01, 
+-      0x0c, 0x09, 0x20, 0x00, 0x22, 0x00, 0xb0, 0x88, 
+-      0x00, 0x47, 0x46, 0x6b, 0x53, 0xda, 0x30, 0x01, 
+-      0x04, 0x00, 0x14, 0x00, 0x28, 0x10, 0xdb, 0xf7, 
+-      0x22, 0x80, 0x00, 0x43, 0x46, 0x68, 0x52, 0xc2, 
+-      0x46, 0x6a, 0x1c, 0x08, 0x21, 0x05, 0xf0, 0x04, 
+-      0xfb, 0x17, 0x49, 0x06, 0x80, 0x88, 0x00, 0x42, 
+-      0x18, 0x12, 0x00, 0x92, 0x4b, 0x04, 0x5a, 0x9a, 
+-      0x81, 0x0a, 0xb0, 0x08, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x01, 0x88, 
+-      0x2e, 0x08, 0x47, 0x78, 0xb5, 0xf0, 0xb0, 0xb3, 
+-      0xa8, 0x01, 0xf0, 0x0f, 0xfd, 0xc9, 0x49, 0x61, 
+-      0x68, 0x0f, 0x68, 0x4d, 0x68, 0x8c, 0x03, 0x20, 
+-      0x05, 0x2a, 0x0d, 0x12, 0x43, 0x10, 0x04, 0x00, 
+-      0x0c, 0x00, 0x4b, 0x5d, 0x8e, 0x9a, 0x2a, 0x00, 
+-      0xd1, 0x16, 0x89, 0xda, 0x42, 0x90, 0xd0, 0x01, 
+-      0x22, 0x01, 0xe0, 0x00, 0x22, 0x00, 0x89, 0x9e, 
+-      0x42, 0xb7, 0xd0, 0x01, 0x26, 0x01, 0xe0, 0x00, 
+-      0x26, 0x00, 0x43, 0x32, 0xd0, 0x08, 0x81, 0x9f, 
+-      0x81, 0xd8, 0x20, 0x00, 0x85, 0x58, 0x20, 0x0d, 
+-      0x85, 0x18, 0x20, 0x01, 0x02, 0x40, 0x86, 0x98, 
+-      0x68, 0xce, 0x69, 0x08, 0x90, 0x00, 0x1c, 0x38, 
+-      0x1c, 0x29, 0x1c, 0x32, 0xf0, 0x00, 0xfa, 0x72, 
+-      0x1c, 0x20, 0xf0, 0x00, 0xfb, 0x8d, 0xa0, 0x4b, 
+-      0x22, 0x00, 0x21, 0x11, 0xf0, 0x04, 0xff, 0xc2, 
+-      0x22, 0x0a, 0x21, 0x11, 0x98, 0x1b, 0xf0, 0x05, 
+-      0xf8, 0x1f, 0x22, 0x14, 0x21, 0x11, 0x1c, 0x38, 
+-      0xf0, 0x05, 0xf8, 0x1a, 0x22, 0x1e, 0x21, 0x11, 
+-      0x1c, 0x28, 0xf0, 0x05, 0xf8, 0x15, 0x22, 0x28, 
+-      0x21, 0x11, 0x1c, 0x20, 0xf0, 0x05, 0xf8, 0x10, 
+-      0x22, 0x32, 0x21, 0x11, 0x1c, 0x30, 0xf0, 0x05, 
+-      0xf8, 0x0b, 0x22, 0x3c, 0x21, 0x11, 0x98, 0x00, 
+-      0xf0, 0x05, 0xf8, 0x06, 0xa0, 0x3b, 0x22, 0x00, 
+-      0x21, 0x13, 0xf0, 0x04, 0xff, 0x9f, 0x22, 0x0a, 
+-      0x21, 0x13, 0x4f, 0x35, 0x8d, 0x78, 0xf0, 0x04, 
+-      0xff, 0xfb, 0xa0, 0x38, 0x22, 0x14, 0x21, 0x13, 
+-      0xf0, 0x04, 0xff, 0x94, 0x22, 0x1e, 0x21, 0x13, 
+-      0x8d, 0xf8, 0xf0, 0x04, 0xff, 0xf1, 0xa0, 0x35, 
+-      0x22, 0x00, 0x21, 0x14, 0xf0, 0x04, 0xff, 0x8a, 
+-      0x22, 0x0a, 0x21, 0x14, 0x8e, 0xb8, 0xf0, 0x04, 
+-      0xff, 0xe7, 0xa0, 0x32, 0x22, 0x14, 0x21, 0x14, 
+-      0xf0, 0x04, 0xff, 0x80, 0x22, 0x1e, 0x21, 0x14, 
+-      0x8e, 0xf8, 0xf0, 0x04, 0xff, 0xdd, 0xa0, 0x2f, 
+-      0x22, 0x28, 0x21, 0x14, 0xf0, 0x04, 0xff, 0x76, 
+-      0x22, 0x32, 0x21, 0x14, 0x48, 0x2e, 0x6f, 0xc0, 
+-      0xf0, 0x04, 0xff, 0xd2, 0xa0, 0x2d, 0x22, 0x00, 
+-      0x21, 0x15, 0xf0, 0x04, 0xff, 0x6b, 0x22, 0x0a, 
+-      0x21, 0x15, 0x8d, 0x38, 0xf0, 0x04, 0xff, 0xc8, 
+-      0xa0, 0x2b, 0x22, 0x14, 0x21, 0x15, 0xf0, 0x04, 
+-      0xff, 0x61, 0x22, 0x1e, 0x21, 0x15, 0x8d, 0xb8, 
+-      0xf0, 0x04, 0xff, 0xbe, 0xa0, 0x29, 0x22, 0x00, 
+-      0x21, 0x10, 0xf0, 0x04, 0xff, 0x57, 0xf0, 0x0f, 
+-      0xfe, 0xf1, 0x22, 0x0a, 0x21, 0x10, 0xf0, 0x04, 
+-      0xff, 0xb3, 0xa0, 0x26, 0x22, 0x14, 0x21, 0x10, 
+-      0xf0, 0x04, 0xff, 0x4c, 0x22, 0x1e, 0x21, 0x10, 
+-      0x27, 0x33, 0x06, 0x7f, 0x6d, 0x78, 0xf0, 0x04, 
+-      0xff, 0xa7, 0xa0, 0x22, 0x22, 0x28, 0x21, 0x10, 
+-      0xf0, 0x04, 0xff, 0x40, 0xf0, 0x0f, 0xfe, 0xda, 
+-      0x6d, 0x79, 0x1a, 0x08, 0x22, 0x32, 0x21, 0x10, 
+-      0xf0, 0x04, 0xff, 0x9a, 0xb0, 0x33, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xcc, 0x00, 0x0c, 0x00, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x73, 0x74, 0x61, 0x74, 
+-      0x73, 0x3a, 0x00, 0x00, 0x72, 0x78, 0x6c, 0x65, 
+-      0x6e, 0x3a, 0x00, 0x00, 0x74, 0x78, 0x6c, 0x65, 
+-      0x6e, 0x3a, 0x00, 0x00, 0x72, 0x78, 0x62, 0x75, 
+-      0x66, 0x66, 0x3a, 0x00, 0x74, 0x78, 0x62, 0x75, 
+-      0x66, 0x66, 0x3a, 0x00, 0x69, 0x66, 0x5f, 0x75, 
+-      0x73, 0x65, 0x64, 0x3a, 0x00, 0x00, 0x00, 0x00, 
+-      0x2c, 0x00, 0x1f, 0x80, 0x72, 0x78, 0x73, 0x74, 
+-      0x61, 0x74, 0x65, 0x3a, 0x00, 0x00, 0x00, 0x00, 
+-      0x74, 0x78, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3a, 
+-      0x00, 0x00, 0x00, 0x00, 0x65, 0x6e, 0x64, 0x63, 
+-      0x75, 0x72, 0x3a, 0x00, 0x76, 0x69, 0x64, 0x62, 
+-      0x75, 0x66, 0x3a, 0x00, 0x6f, 0x73, 0x64, 0x3a, 
+-      0x00, 0x00, 0x00, 0x00, 0xb5, 0xf0, 0x25, 0x00, 
+-      0x20, 0x00, 0x49, 0x19, 0x81, 0xc8, 0x81, 0x88, 
+-      0x4e, 0x18, 0x4c, 0x19, 0x4f, 0x19, 0x68, 0x30, 
+-      0x68, 0x00, 0x00, 0x40, 0x0a, 0x40, 0x02, 0x40, 
+-      0x21, 0x19, 0x06, 0x89, 0x6a, 0x89, 0x4b, 0x16, 
+-      0x40, 0x19, 0x0a, 0x49, 0x43, 0x08, 0x49, 0x15, 
+-      0x64, 0x08, 0xf0, 0x01, 0xfc, 0x57, 0xf0, 0x02, 
+-      0xf9, 0x6b, 0x68, 0x38, 0x30, 0x01, 0x60, 0x38, 
+-      0x48, 0x11, 0x88, 0x01, 0x31, 0x01, 0x80, 0x01, 
+-      0x20, 0x0c, 0x68, 0x21, 0xf0, 0x17, 0xf8, 0x9a, 
+-      0x29, 0x00, 0xd1, 0x01, 0xf7, 0xff, 0xfe, 0xd6, 
+-      0x20, 0x32, 0x68, 0x21, 0xf0, 0x17, 0xf8, 0x92, 
+-      0x42, 0x85, 0xd0, 0xd8, 0x1c, 0x05, 0xf0, 0x00, 
+-      0xfe, 0x39, 0x20, 0x00, 0x60, 0x38, 0xe7, 0xd2, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x2e, 0x08, 0x5e, 0x38, 
+-      0x2e, 0x08, 0x05, 0xb0, 0x2e, 0x08, 0x01, 0x88, 
+-      0x00, 0x03, 0xfe, 0x00, 0x2c, 0x00, 0x1f, 0x80, 
+-      0x2c, 0x00, 0x1f, 0xc8, 0xb5, 0xf0, 0x27, 0x00, 
+-      0xb0, 0x94, 0x46, 0x68, 0x4c, 0x2f, 0xcc, 0x6e, 
+-      0xc0, 0x6e, 0xcc, 0x6e, 0xc0, 0x6e, 0x23, 0x28, 
+-      0x22, 0x41, 0x00, 0xd2, 0x21, 0x00, 0x20, 0x01, 
+-      0xf0, 0x08, 0xfa, 0x30, 0x22, 0xff, 0x21, 0x64, 
+-      0x20, 0x01, 0x32, 0xf5, 0xf0, 0x08, 0xfa, 0xf2, 
+-      0x20, 0x00, 0x46, 0x69, 0x5c, 0x09, 0x40, 0x41, 
+-      0x23, 0x35, 0x40, 0x59, 0xaa, 0x0a, 0x54, 0x11, 
+-      0x30, 0x01, 0x28, 0x25, 0xdb, 0xf5, 0x24, 0x00, 
+-      0xa9, 0x0a, 0x54, 0x0c, 0x22, 0x00, 0x20, 0x01, 
+-      0x1c, 0x23, 0xf0, 0x08, 0xfd, 0x50, 0x4e, 0x1e, 
+-      0x4d, 0x1e, 0x4c, 0x1f, 0xf0, 0x03, 0xff, 0x80, 
+-      0xf0, 0x03, 0xff, 0x7e, 0x28, 0x28, 0xd9, 0x10, 
+-      0x42, 0xb0, 0xd3, 0x0e, 0x69, 0xe9, 0x08, 0xc9, 
+-      0xd3, 0x0b, 0x4b, 0x1a, 0x18, 0xc1, 0x20, 0x1e, 
+-      0xf0, 0x17, 0xf8, 0x40, 0x21, 0x64, 0x1d, 0xc2, 
+-      0x32, 0xff, 0x32, 0xee, 0x20, 0x01, 0xf0, 0x08, 
+-      0xfa, 0xc5, 0xf0, 0x01, 0xfb, 0xe7, 0xf0, 0x02, 
+-      0xf8, 0xfb, 0xf0, 0x03, 0xff, 0x65, 0x1c, 0x01, 
+-      0x20, 0x7d, 0x00, 0xc0, 0xf0, 0x17, 0xf8, 0x2e, 
+-      0x1c, 0x01, 0x48, 0x0f, 0x88, 0x02, 0x32, 0x01, 
+-      0x80, 0x02, 0x42, 0xb9, 0xd0, 0xd6, 0x2f, 0x04, 
+-      0xd3, 0x06, 0x20, 0x01, 0xf0, 0x08, 0xf9, 0xce, 
+-      0xb0, 0x14, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x1c, 0x0f, 0xf0, 0x00, 0xfd, 0xc7, 0x20, 0x00, 
+-      0x60, 0x20, 0xe7, 0xc7, 0x2e, 0x02, 0x5e, 0x00, 
+-      0x00, 0x00, 0x0b, 0xb8, 0x72, 0x00, 0x01, 0x00, 
+-      0x2e, 0x08, 0x01, 0x88, 0xff, 0xff, 0xf4, 0x48, 
+-      0x2c, 0x00, 0x1f, 0xc8, 0xb5, 0x80, 0x27, 0x00, 
+-      0x48, 0x07, 0x81, 0x07, 0xf0, 0x03, 0xfd, 0x5e, 
+-      0xf7, 0xff, 0xff, 0x88, 0xf0, 0x00, 0xf8, 0xce, 
+-      0xf0, 0x05, 0xfe, 0xfe, 0xf7, 0xff, 0xff, 0x3e, 
+-      0x1c, 0x38, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0xb5, 0xf0, 0x4d, 0x29, 
+-      0x68, 0x01, 0x31, 0x03, 0x10, 0x89, 0x1e, 0xcb, 
+-      0x68, 0x41, 0x10, 0x89, 0x68, 0x82, 0x10, 0x92, 
+-      0x00, 0x89, 0x30, 0x0c, 0x18, 0x0c, 0x21, 0x03, 
+-      0x05, 0x89, 0x27, 0x35, 0x06, 0x7f, 0x60, 0x39, 
+-      0x49, 0x21, 0x68, 0x0e, 0x08, 0xb6, 0x00, 0xb6, 
+-      0x60, 0x0e, 0x21, 0x00, 0x2b, 0x00, 0xd9, 0x04, 
+-      0xc8, 0x40, 0xc5, 0x40, 0x31, 0x01, 0x42, 0x99, 
+-      0xd3, 0xfa, 0x23, 0x00, 0x49, 0x1b, 0x65, 0x8b, 
+-      0x20, 0x00, 0x2a, 0x00, 0xd9, 0x04, 0xcc, 0x20, 
+-      0x64, 0x8d, 0x30, 0x01, 0x42, 0x90, 0xd3, 0xfa, 
+-      0x48, 0x17, 0x60, 0x03, 0x60, 0x3b, 0x66, 0x8b, 
+-      0x60, 0x3b, 0x22, 0x01, 0x64, 0xca, 0x21, 0x00, 
+-      0x4a, 0x14, 0x68, 0x03, 0x2b, 0x00, 0xd1, 0x05, 
+-      0x33, 0x01, 0x2b, 0x64, 0xdb, 0xfc, 0x31, 0x01, 
+-      0x42, 0x91, 0xdb, 0xf6, 0x48, 0x10, 0x68, 0x01, 
+-      0x23, 0x01, 0x43, 0x19, 0x60, 0x01, 0x49, 0x0f, 
+-      0x20, 0x33, 0x06, 0x40, 0x65, 0x41, 0x49, 0x0e, 
+-      0x65, 0x81, 0x49, 0x0e, 0x66, 0x81, 0x39, 0x04, 
+-      0x66, 0x41, 0x21, 0x03, 0x67, 0x01, 0x21, 0x00, 
+-      0x20, 0x0d, 0xf0, 0x0f, 0xf9, 0xc9, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xcc, 0x00, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x70, 0x6a, 0x00, 0x00, 0x80, 
+-      0xcc, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x27, 0x10, 
+-      0x6a, 0x00, 0x00, 0x10, 0xcc, 0x00, 0x0f, 0x84, 
+-      0xcc, 0x00, 0x0f, 0x88, 0x98, 0x00, 0x0f, 0x88, 
+-      0xb5, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0x08, 
+-      0xf0, 0x0f, 0xfe, 0x04, 0x48, 0x08, 0x21, 0x40, 
+-      0xf0, 0x0f, 0xfa, 0xd4, 0x20, 0x01, 0x21, 0x35, 
+-      0x06, 0x49, 0x61, 0x08, 0x20, 0x02, 0x43, 0xc0, 
+-      0x49, 0x04, 0x63, 0x08, 0x20, 0x00, 0x21, 0x39, 
+-      0x06, 0x49, 0x62, 0xc8, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x01, 0xcc, 0x90, 0x72, 0x00, 0x01, 0x00, 
+-      0xb5, 0x00, 0x1c, 0x01, 0x48, 0x0f, 0xd0, 0x10, 
+-      0x29, 0x01, 0xd0, 0x12, 0x29, 0x02, 0xd0, 0x14, 
+-      0x29, 0x03, 0xd1, 0x01, 0x49, 0x0c, 0x60, 0x01, 
+-      0x68, 0x01, 0x68, 0x40, 0x43, 0x08, 0x22, 0x00, 
+-      0x21, 0x1e, 0xf0, 0x0f, 0xfe, 0x43, 0xbc, 0x08, 
+-      0x47, 0x18, 0x21, 0x01, 0x04, 0x49, 0x60, 0x01, 
+-      0xe7, 0xf2, 0x21, 0x21, 0x03, 0x09, 0x60, 0x01, 
+-      0xe7, 0xee, 0x21, 0x41, 0x03, 0x09, 0x60, 0x01, 
+-      0xe7, 0xea, 0x00, 0x00, 0x2e, 0x08, 0x01, 0x94, 
+-      0x00, 0x08, 0x10, 0x08, 0xb5, 0x00, 0x1c, 0x01, 
+-      0x48, 0x0b, 0xd0, 0x0e, 0x29, 0x01, 0xd0, 0x0f, 
+-      0x29, 0x02, 0xd1, 0x01, 0x21, 0x04, 0x60, 0x41, 
+-      0x68, 0x01, 0x68, 0x40, 0x43, 0x08, 0x22, 0x00, 
+-      0x21, 0x1e, 0xf0, 0x0f, 0xfe, 0x1f, 0xbc, 0x08, 
+-      0x47, 0x18, 0x21, 0x01, 0x60, 0x41, 0xe7, 0xf3, 
+-      0x21, 0x02, 0x60, 0x41, 0xe7, 0xf0, 0x00, 0x00, 
+-      0x2e, 0x08, 0x01, 0x94, 0xb5, 0x80, 0x4b, 0x09, 
+-      0x22, 0x0a, 0x21, 0x0a, 0x20, 0x0b, 0xf0, 0x10, 
+-      0xf8, 0x53, 0x20, 0x0b, 0xf0, 0x10, 0xf9, 0x75, 
+-      0x4f, 0x05, 0x60, 0x38, 0x00, 0x80, 0xf0, 0x03, 
+-      0xff, 0x45, 0x60, 0x78, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x01, 0xc0, 
+-      0x2e, 0x08, 0x01, 0xd0, 0xb5, 0xb0, 0x25, 0x00, 
+-      0x1c, 0x0c, 0x1c, 0x07, 0x2a, 0x08, 0xd2, 0x30, 
+-      0xa3, 0x01, 0x5c, 0x9b, 0x00, 0x5b, 0x44, 0x9f, 
+-      0x2c, 0x29, 0x29, 0x03, 0x29, 0x29, 0x03, 0x29, 
+-      0x20, 0x00, 0xf0, 0x00, 0xf8, 0x4d, 0x23, 0x2d, 
+-      0x01, 0x1b, 0x42, 0x9f, 0xd0, 0x13, 0x23, 0x0b, 
+-      0x01, 0x9b, 0x42, 0x9f, 0xd0, 0x0f, 0x23, 0xff, 
+-      0x33, 0xe1, 0x42, 0x9f, 0xd0, 0x0b, 0x23, 0xff, 
+-      0x33, 0x61, 0x42, 0x9f, 0xd0, 0x07, 0x23, 0x21, 
+-      0x01, 0x1b, 0x42, 0x9f, 0xd0, 0x03, 0x23, 0x11, 
+-      0x01, 0x5b, 0x42, 0x9f, 0xd1, 0x08, 0x23, 0x09, 
+-      0x01, 0x9b, 0x42, 0x9c, 0xd0, 0x09, 0x08, 0x5b, 
+-      0x42, 0x9c, 0xd0, 0x06, 0x2c, 0xf0, 0xd0, 0x04, 
+-      0x25, 0x01, 0xe0, 0x02, 0x20, 0x01, 0xf0, 0x00, 
+-      0xf8, 0x27, 0x4f, 0x12, 0x6c, 0x78, 0x42, 0x85, 
+-      0xd0, 0x1c, 0x1d, 0xfb, 0x33, 0x35, 0x2d, 0x00, 
+-      0xd0, 0x12, 0x1f, 0xda, 0x3a, 0x0d, 0x21, 0x03, 
+-      0x1d, 0x10, 0xb4, 0x07, 0x22, 0x0b, 0xb4, 0x04, 
+-      0x1c, 0x19, 0x23, 0x00, 0x22, 0x00, 0x20, 0x00, 
+-      0xf0, 0x0a, 0xfc, 0x4c, 0x6a, 0xb8, 0x1c, 0x29, 
+-      0xb0, 0x04, 0xf0, 0x0b, 0xfd, 0x9b, 0xe0, 0x04, 
+-      0x21, 0x00, 0x6a, 0xb8, 0x1c, 0x1a, 0xf0, 0x0a, 
+-      0xff, 0x51, 0x64, 0x7d, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x01, 0x94, 
+-      0xb5, 0xf0, 0x1c, 0x07, 0xb0, 0x81, 0x4d, 0x56, 
+-      0x1d, 0xee, 0x36, 0x19, 0x79, 0x30, 0x42, 0x87, 
+-      0xd1, 0x03, 0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x24, 0x00, 0x6c, 0x68, 0x28, 0x00, 
+-      0xd0, 0x05, 0x64, 0x6c, 0x4a, 0x4f, 0x21, 0x00, 
+-      0x6a, 0xa8, 0xf0, 0x0a, 0xff, 0x33, 0x71, 0x37, 
+-      0x21, 0x00, 0x20, 0x0e, 0xf0, 0x0f, 0xf8, 0xc4, 
+-      0x20, 0x00, 0xf0, 0x0c, 0xfb, 0xc5, 0x20, 0x1f, 
+-      0xf0, 0x09, 0xfc, 0x5a, 0x26, 0x03, 0x02, 0x76, 
+-      0x22, 0x01, 0x02, 0xd2, 0x21, 0x02, 0x20, 0x1f, 
+-      0x1c, 0x33, 0xf0, 0x09, 0xfa, 0xd1, 0x20, 0x1e, 
+-      0xf0, 0x09, 0xfd, 0x18, 0x22, 0x01, 0x02, 0xd2, 
+-      0x21, 0x02, 0x20, 0x1e, 0x1c, 0x33, 0xf0, 0x09, 
+-      0xfa, 0xc7, 0x1c, 0x39, 0x27, 0x1c, 0x48, 0x3e, 
+-      0x26, 0x0c, 0x29, 0x06, 0xd2, 0x07, 0xa3, 0x02, 
+-      0x5c, 0x5b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x03, 0x12, 0x03, 0x21, 0x12, 0x30, 0x48, 0x39, 
+-      0x21, 0x40, 0xf0, 0x0f, 0xf9, 0xc3, 0xab, 0x00, 
+-      0x70, 0x1c, 0x20, 0x08, 0x70, 0x58, 0x70, 0x9f, 
+-      0x70, 0xdc, 0x22, 0x00, 0x21, 0x00, 0xf0, 0x0f, 
+-      0xfc, 0xe5, 0xe0, 0x2b, 0x21, 0x1f, 0x43, 0xc9, 
+-      0xf0, 0x0f, 0xf9, 0xb4, 0xab, 0x00, 0x70, 0x1c, 
+-      0x70, 0x5c, 0x70, 0x9e, 0x70, 0xdc, 0x22, 0x00, 
+-      0x21, 0x00, 0x20, 0x00, 0xf0, 0x0f, 0xfc, 0xd6, 
+-      0xe0, 0x1c, 0x21, 0x40, 0xf0, 0x0f, 0xf9, 0xa6, 
+-      0xab, 0x00, 0x70, 0x1c, 0x20, 0x10, 0x70, 0x58, 
+-      0x70, 0x9f, 0x70, 0xdc, 0x22, 0x00, 0x21, 0x00, 
+-      0x20, 0x08, 0xf0, 0x0f, 0xfc, 0xc7, 0xe0, 0x0d, 
+-      0x21, 0x1f, 0x43, 0xc9, 0xf0, 0x0f, 0xf9, 0x96, 
+-      0xab, 0x00, 0x70, 0x1c, 0x70, 0x5c, 0x70, 0x9e, 
+-      0x70, 0xdc, 0x22, 0x00, 0x21, 0x00, 0x20, 0x08, 
+-      0xf0, 0x0f, 0xfc, 0xb8, 0x20, 0x01, 0x21, 0x35, 
+-      0x06, 0x49, 0x61, 0x08, 0x20, 0x02, 0x43, 0xc0, 
+-      0x49, 0x19, 0x63, 0x08, 0x20, 0x39, 0x06, 0x40, 
+-      0x62, 0xc4, 0xcd, 0x03, 0x43, 0x08, 0x22, 0x00, 
+-      0x21, 0x1e, 0xf0, 0x0f, 0xfd, 0x0f, 0x48, 0x15, 
+-      0xf0, 0x0c, 0xfa, 0xd0, 0x20, 0x00, 0xf0, 0x0c, 
+-      0xfb, 0x41, 0x20, 0x00, 0xf0, 0x00, 0xf8, 0x68, 
+-      0x20, 0x00, 0xf0, 0x03, 0xfb, 0x3f, 0x20, 0x01, 
+-      0xf0, 0x0c, 0xfb, 0x46, 0x4a, 0x0e, 0xb4, 0x04, 
+-      0x1c, 0x13, 0x3a, 0x01, 0x49, 0x0d, 0x1e, 0xc8, 
+-      0xf7, 0xfe, 0xfb, 0x4e, 0x21, 0x00, 0x20, 0x0d, 
+-      0xb0, 0x01, 0xf0, 0x0f, 0xf8, 0x35, 0xb0, 0x01, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x01, 0x94, 0x2e, 0x08, 0x01, 0xd0, 
+-      0x2e, 0x02, 0x12, 0xfc, 0x2e, 0x01, 0xcc, 0x90, 
+-      0x72, 0x00, 0x01, 0x00, 0x00, 0x80, 0x10, 0x80, 
+-      0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xfe, 
+-      0xb5, 0xb0, 0x1c, 0x07, 0x4c, 0x10, 0x6a, 0x20, 
+-      0x42, 0x87, 0xd0, 0x19, 0x20, 0x00, 0x2f, 0x03, 
+-      0xd1, 0x02, 0x21, 0x01, 0x61, 0x61, 0xe0, 0x00, 
+-      0x61, 0x60, 0x21, 0x02, 0x4d, 0x0b, 0x60, 0x29, 
+-      0x71, 0x28, 0x71, 0x68, 0x22, 0x01, 0xb4, 0x04, 
+-      0x7a, 0x23, 0x7c, 0x22, 0x7b, 0x21, 0x20, 0x00, 
+-      0xf0, 0x0f, 0xfb, 0x02, 0x69, 0x61, 0x1c, 0x28, 
+-      0xb0, 0x01, 0xf0, 0x10, 0xfb, 0xa9, 0x62, 0x27, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x01, 0x94, 0x2e, 0x08, 0x01, 0xac, 
+-      0xb5, 0x00, 0x22, 0x02, 0x49, 0x09, 0x60, 0x0a, 
+-      0x22, 0x00, 0x71, 0x0a, 0x71, 0x4a, 0x39, 0x48, 
+-      0x28, 0x00, 0xd0, 0x08, 0x28, 0x01, 0xd1, 0x00, 
+-      0x72, 0x08, 0x6a, 0x08, 0x62, 0x0a, 0xf7, 0xff, 
+-      0xff, 0xc7, 0xbc, 0x08, 0x47, 0x18, 0x72, 0x0a, 
+-      0xe7, 0xf7, 0x00, 0x00, 0x2e, 0x08, 0x01, 0xdc, 
+-      0xb5, 0x80, 0x06, 0x00, 0x0e, 0x00, 0x4f, 0x0b, 
+-      0xd0, 0x02, 0x20, 0x00, 0x73, 0x38, 0xe0, 0x01, 
+-      0x20, 0x01, 0x73, 0x38, 0x22, 0x01, 0xb4, 0x04, 
+-      0x7a, 0x3b, 0x7c, 0x3a, 0x7b, 0x39, 0x20, 0x00, 
+-      0xf0, 0x0f, 0xfa, 0xca, 0x69, 0x79, 0xb0, 0x01, 
+-      0x48, 0x03, 0xf0, 0x10, 0xfb, 0x71, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x01, 0x94, 
+-      0x2e, 0x08, 0x01, 0xac, 0xb5, 0x80, 0x06, 0x00, 
+-      0x0e, 0x00, 0x1c, 0x01, 0x4f, 0x08, 0x74, 0x39, 
+-      0x22, 0x01, 0xb4, 0x04, 0x7a, 0x3b, 0x7b, 0x39, 
+-      0x1c, 0x02, 0x20, 0x00, 0xf0, 0x0f, 0xfa, 0xb0, 
+-      0x69, 0x79, 0xb0, 0x01, 0x48, 0x03, 0xf0, 0x10, 
+-      0xfb, 0x57, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x01, 0x94, 0x2e, 0x08, 0x01, 0xac, 
+-      0xb4, 0xb0, 0x21, 0x00, 0x48, 0x08, 0x60, 0x01, 
+-      0x20, 0x00, 0x4c, 0x08, 0x4f, 0x08, 0x4b, 0x09, 
+-      0x4a, 0x09, 0x00, 0x85, 0x51, 0x61, 0x54, 0x39, 
+-      0x54, 0x19, 0x54, 0x11, 0x30, 0x01, 0x28, 0x20, 
+-      0xdb, 0xf7, 0xbc, 0xb0, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x01, 0xe4, 0x2e, 0x08, 0x43, 0x88, 
+-      0x2e, 0x08, 0x44, 0x08, 0x2e, 0x08, 0x44, 0x48, 
+-      0x2e, 0x08, 0x44, 0x28, 0x06, 0x00, 0x0e, 0x00, 
+-      0x21, 0x01, 0x40, 0x81, 0x43, 0xca, 0x49, 0x05, 
+-      0x68, 0x0b, 0x40, 0x1a, 0x60, 0x0a, 0x21, 0x00, 
+-      0x00, 0x82, 0x4b, 0x03, 0x50, 0x99, 0x4a, 0x03, 
+-      0x54, 0x11, 0x47, 0x70, 0x2e, 0x08, 0x01, 0xe4, 
+-      0x2e, 0x08, 0x43, 0x88, 0x2e, 0x08, 0x44, 0x08, 
+-      0xb5, 0xf0, 0xb0, 0x84, 0x4f, 0x36, 0x68, 0x38, 
+-      0x1d, 0xc1, 0x31, 0x0d, 0x20, 0x00, 0xf0, 0x23, 
+-      0xfb, 0xc1, 0x1c, 0x04, 0x68, 0x38, 0x1d, 0xc1, 
+-      0x31, 0x05, 0x20, 0x00, 0xf0, 0x23, 0xfb, 0xba, 
+-      0x1c, 0x05, 0x68, 0x38, 0x1d, 0xc1, 0x31, 0x09, 
+-      0x20, 0x00, 0xf0, 0x23, 0xfb, 0xb3, 0x43, 0x2c, 
+-      0x1c, 0x20, 0x4c, 0x2c, 0x68, 0x21, 0x43, 0x08, 
+-      0x27, 0x00, 0x60, 0x20, 0x1c, 0x05, 0xd0, 0x4a, 
+-      0x48, 0x29, 0x90, 0x03, 0x48, 0x29, 0x90, 0x02, 
+-      0x4a, 0x29, 0x92, 0x01, 0x4e, 0x29, 0x08, 0x68, 
+-      0xd3, 0x3c, 0x98, 0x03, 0x5d, 0xc0, 0x28, 0x00, 
+-      0xd0, 0x32, 0x98, 0x02, 0x5d, 0xc0, 0x28, 0x00, 
+-      0xd0, 0x2a, 0x46, 0x68, 0x1c, 0x39, 0xf0, 0x10, 
+-      0xff, 0x69, 0xa8, 0x00, 0x78, 0x00, 0x28, 0x01, 
+-      0xd1, 0x1b, 0x68, 0x60, 0x30, 0x01, 0x60, 0x60, 
+-      0x5d, 0xf0, 0x28, 0x00, 0xd1, 0x06, 0x20, 0xff, 
+-      0x55, 0xf0, 0x21, 0x00, 0x00, 0xb8, 0x9a, 0x01, 
+-      0x50, 0x11, 0xe0, 0x1f, 0x20, 0x02, 0x1c, 0x39, 
+-      0xf0, 0x00, 0xf8, 0x8e, 0x28, 0x00, 0xd1, 0x19, 
+-      0x21, 0x00, 0x55, 0xf1, 0x20, 0x01, 0x40, 0xb8, 
+-      0x43, 0xc0, 0x68, 0x21, 0x40, 0x08, 0x60, 0x20, 
+-      0xe0, 0x10, 0x20, 0x01, 0x40, 0xb8, 0x43, 0xc0, 
+-      0x68, 0x21, 0x40, 0x08, 0x60, 0x20, 0xe0, 0x09, 
+-      0x68, 0x60, 0x30, 0x01, 0x60, 0x60, 0xe0, 0x05, 
+-      0x20, 0x01, 0x40, 0xb8, 0x43, 0xc0, 0x68, 0x21, 
+-      0x40, 0x08, 0x60, 0x20, 0x1c, 0x78, 0x06, 0x07, 
+-      0x0e, 0x3f, 0x08, 0x6d, 0xd1, 0xbb, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x5e, 0x0c, 0x2e, 0x08, 0x01, 0xe4, 
+-      0x2e, 0x08, 0x44, 0x28, 0x2e, 0x08, 0x44, 0x48, 
+-      0x2e, 0x08, 0x43, 0x88, 0x2e, 0x08, 0x44, 0x08, 
+-      0xb5, 0xf0, 0x27, 0x00, 0xb0, 0x85, 0x4c, 0x26, 
+-      0x68, 0x25, 0x2d, 0x00, 0xd0, 0x44, 0x4e, 0x25, 
+-      0x48, 0x25, 0x90, 0x04, 0x49, 0x25, 0x91, 0x03, 
+-      0x4a, 0x25, 0x92, 0x02, 0x48, 0x25, 0x90, 0x01, 
+-      0x08, 0x68, 0xd3, 0x34, 0x5d, 0xf0, 0x28, 0x00, 
+-      0xd0, 0x2b, 0x98, 0x04, 0x5d, 0xc0, 0x28, 0x00, 
+-      0xd0, 0x2d, 0x46, 0x68, 0x1c, 0x39, 0xf0, 0x10, 
+-      0xff, 0x05, 0xa8, 0x00, 0x78, 0x00, 0x28, 0x01, 
+-      0xd1, 0x18, 0x68, 0x60, 0x30, 0x01, 0x60, 0x60, 
+-      0x00, 0xb8, 0x99, 0x03, 0x58, 0x09, 0x69, 0x09, 
+-      0x9a, 0x02, 0x50, 0x11, 0x20, 0x02, 0x1c, 0x39, 
+-      0xf0, 0x00, 0xf8, 0x2e, 0x28, 0x00, 0xd1, 0x16, 
+-      0x21, 0x00, 0x98, 0x01, 0x55, 0xc1, 0x20, 0x01, 
+-      0x40, 0xb8, 0x43, 0xc0, 0x68, 0x21, 0x40, 0x08, 
+-      0x60, 0x20, 0xe0, 0x0c, 0x20, 0x01, 0x40, 0xb8, 
+-      0x43, 0xc0, 0x68, 0x21, 0x40, 0x08, 0x60, 0x20, 
+-      0xe0, 0x05, 0x20, 0x01, 0x40, 0xb8, 0x43, 0xc0, 
+-      0x68, 0x21, 0x40, 0x08, 0x60, 0x20, 0x1c, 0x78, 
+-      0x06, 0x07, 0x0e, 0x3f, 0x08, 0x6d, 0xd1, 0xc3, 
+-      0xb0, 0x05, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x01, 0xe4, 0x2e, 0x08, 0x44, 0x28, 
+-      0x2e, 0x08, 0x44, 0x48, 0x2e, 0x08, 0x5e, 0x5c, 
+-      0x2e, 0x08, 0x43, 0x88, 0x2e, 0x08, 0x44, 0x08, 
+-      0xb4, 0xf0, 0x06, 0x03, 0x0e, 0x1b, 0xb0, 0x82, 
+-      0x93, 0x00, 0x06, 0x0c, 0x0e, 0x24, 0x00, 0xa2, 
+-      0xb0, 0x81, 0x48, 0x33, 0x58, 0x80, 0x90, 0x00, 
+-      0x28, 0x00, 0xd1, 0x03, 0x20, 0xb0, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0x47, 0x70, 0x48, 0x2f, 0x68, 0x00, 
+-      0x18, 0x17, 0x00, 0xe0, 0x1b, 0x00, 0x00, 0x80, 
+-      0x49, 0x2d, 0x68, 0x09, 0x18, 0x41, 0x9b, 0x01, 
+-      0x48, 0x2c, 0x4d, 0x2d, 0x95, 0x02, 0x2b, 0x01, 
+-      0xd0, 0x2a, 0x2b, 0x02, 0xd1, 0x47, 0x4d, 0x2b, 
+-      0x58, 0xab, 0x2b, 0x00, 0xd1, 0x03, 0x20, 0xff, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0x47, 0x70, 0x60, 0x4b, 
+-      0x23, 0x00, 0x50, 0xab, 0x22, 0x00, 0x5c, 0x83, 
+-      0x42, 0xa3, 0xd1, 0x07, 0x00, 0x93, 0x9d, 0x02, 
+-      0x58, 0xeb, 0x78, 0x5e, 0x1c, 0x5d, 0x23, 0x80, 
+-      0x43, 0x9e, 0x70, 0x2e, 0x32, 0x01, 0x06, 0x12, 
+-      0x0e, 0x12, 0x2a, 0x20, 0xdb, 0xef, 0x88, 0x08, 
+-      0x4b, 0x1d, 0x40, 0x18, 0x80, 0x08, 0x98, 0x00, 
+-      0x9b, 0x01, 0x70, 0xc3, 0x68, 0x38, 0x23, 0x01, 
+-      0x03, 0x5b, 0x43, 0x18, 0x60, 0x38, 0xe0, 0x1a, 
+-      0x68, 0x3a, 0x4b, 0x18, 0x40, 0x1a, 0x60, 0x3a, 
+-      0x9a, 0x00, 0x9b, 0x01, 0x70, 0xd3, 0x23, 0x00, 
+-      0x60, 0x8b, 0x70, 0xcb, 0x60, 0xcb, 0x21, 0x00, 
+-      0x5c, 0x42, 0x42, 0xa2, 0xd1, 0x06, 0x00, 0x8a, 
+-      0x9d, 0x02, 0x58, 0xaa, 0x78, 0x57, 0x23, 0x80, 
+-      0x43, 0x3b, 0x70, 0x53, 0x31, 0x01, 0x06, 0x09, 
+-      0x0e, 0x09, 0x29, 0x20, 0xdb, 0xf0, 0x20, 0x00, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0x47, 0x70, 0x20, 0xbc, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x5d, 0xcc, 
+-      0x2e, 0x08, 0x5d, 0xc4, 0x2e, 0x08, 0x5f, 0xa4, 
+-      0x2e, 0x08, 0x5e, 0xe4, 0x2e, 0x08, 0x43, 0x88, 
+-      0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xdf, 0xff, 
+-      0xb4, 0xf0, 0x78, 0x43, 0x00, 0x9e, 0x49, 0x32, 
+-      0x59, 0x8c, 0x88, 0x42, 0x68, 0x87, 0x68, 0x40, 
+-      0x1d, 0xf9, 0x31, 0xb9, 0x1a, 0x09, 0x42, 0x91, 
+-      0xda, 0x3d, 0x25, 0x00, 0x1c, 0x18, 0x00, 0xdb, 
+-      0x1a, 0x18, 0x00, 0x80, 0x4b, 0x2b, 0x68, 0x1b, 
+-      0x18, 0xc0, 0x78, 0x80, 0x06, 0xc0, 0x0e, 0xc0, 
+-      0x28, 0x12, 0xd1, 0x02, 0x29, 0x0e, 0xda, 0x00, 
+-      0x25, 0x01, 0x2a, 0x00, 0xdd, 0x2b, 0x42, 0x8a, 
+-      0xdd, 0x05, 0x68, 0x3f, 0x2f, 0x00, 0xd1, 0x02, 
+-      0x20, 0xba, 0xbc, 0xf0, 0x47, 0x70, 0x1a, 0x52, 
+-      0x79, 0xb9, 0x23, 0xc0, 0x1a, 0x59, 0x79, 0xfb, 
+-      0x1d, 0x38, 0x08, 0x5b, 0xd3, 0x01, 0x22, 0x00, 
+-      0xe0, 0x16, 0x2d, 0x00, 0xd0, 0x14, 0x42, 0x91, 
+-      0xdb, 0x01, 0x31, 0x01, 0xe0, 0x10, 0x1c, 0x4b, 
+-      0x42, 0x93, 0xd1, 0x0d, 0x78, 0x85, 0x2d, 0x09, 
+-      0xdd, 0x06, 0x79, 0x05, 0x78, 0x80, 0x35, 0x09, 
+-      0x42, 0x85, 0xd0, 0x05, 0x1c, 0x19, 0xe0, 0x03, 
+-      0x78, 0x80, 0x28, 0x09, 0xd1, 0x00, 0x1c, 0x19, 
+-      0x25, 0x00, 0x2a, 0x00, 0xdc, 0xd3, 0x69, 0x21, 
+-      0x20, 0x00, 0x1c, 0x0a, 0x42, 0xb9, 0xd0, 0xd4, 
+-      0x68, 0x0b, 0x42, 0xbb, 0xd0, 0x08, 0x68, 0x09, 
+-      0x29, 0x00, 0xd1, 0x02, 0x20, 0xba, 0xbc, 0xf0, 
+-      0x47, 0x70, 0x68, 0x0b, 0x42, 0xbb, 0xd1, 0xf6, 
+-      0x4b, 0x07, 0x51, 0x9a, 0x60, 0x08, 0x69, 0xa2, 
+-      0x69, 0x23, 0x60, 0x13, 0x61, 0xa1, 0x61, 0x27, 
+-      0x61, 0x67, 0xbc, 0xf0, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x5d, 0xc4, 
+-      0x2e, 0x08, 0x43, 0x88, 0xb5, 0xf0, 0x06, 0x07, 
+-      0x0e, 0x3f, 0x04, 0x0c, 0x0c, 0x24, 0x06, 0x15, 
+-      0x0e, 0x2d, 0x00, 0xf8, 0x49, 0x2c, 0x68, 0x09, 
+-      0x18, 0x40, 0x00, 0xb9, 0x4a, 0x2b, 0x68, 0x12, 
+-      0x18, 0x8a, 0x00, 0xf9, 0x1b, 0xc9, 0x00, 0x89, 
+-      0x4b, 0x29, 0x68, 0x1b, 0x18, 0xc9, 0x68, 0x16, 
+-      0x23, 0x01, 0x03, 0x5b, 0x43, 0x9e, 0x60, 0x16, 
+-      0x68, 0x06, 0x23, 0x03, 0x03, 0x9b, 0x43, 0x9e, 
+-      0x60, 0x06, 0x4b, 0x24, 0x42, 0x9c, 0xd0, 0x36, 
+-      0x68, 0x06, 0x23, 0x21, 0x43, 0x9e, 0x60, 0x06, 
+-      0x68, 0x16, 0x23, 0x07, 0x03, 0x5b, 0x40, 0x33, 
+-      0x60, 0x13, 0x23, 0x07, 0x03, 0x5b, 0x43, 0x9c, 
+-      0x1c, 0x23, 0x68, 0x14, 0x43, 0x23, 0x60, 0x13, 
+-      0x22, 0x00, 0x75, 0x0a, 0x88, 0x0c, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x9c, 0x80, 0x0c, 0x07, 0xab, 
+-      0x0f, 0x9b, 0x2b, 0x01, 0xd1, 0x04, 0x88, 0x0c, 
+-      0x23, 0x10, 0x43, 0x23, 0x80, 0x0b, 0xe0, 0x03, 
+-      0x88, 0x0c, 0x23, 0x10, 0x43, 0x9c, 0x80, 0x0c, 
+-      0x68, 0x01, 0x23, 0x40, 0x43, 0xdb, 0x40, 0x19, 
+-      0x60, 0x01, 0x00, 0xf9, 0x4b, 0x0e, 0x68, 0x1b, 
+-      0x18, 0xc9, 0x60, 0x4a, 0x68, 0x01, 0x4b, 0x0d, 
+-      0x43, 0x19, 0x60, 0x01, 0x68, 0x01, 0x60, 0x01, 
+-      0x21, 0x0f, 0x60, 0x41, 0xe0, 0x04, 0x1c, 0x38, 
+-      0xf0, 0x0d, 0xff, 0x1a, 0x28, 0x00, 0xd1, 0x00, 
+-      0x20, 0x00, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x5d, 0xd0, 0x2e, 0x08, 0x5d, 0xcc, 
+-      0x2e, 0x08, 0x5d, 0xc4, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x5d, 0xd4, 0x00, 0x00, 0x20, 0xa0, 
+-      0xb5, 0xf0, 0x06, 0x09, 0x0e, 0x09, 0x1c, 0x07, 
+-      0xb0, 0x8a, 0x48, 0x58, 0x29, 0x00, 0xd1, 0x0a, 
+-      0x4d, 0x57, 0x69, 0x01, 0x91, 0x04, 0x49, 0x57, 
+-      0x91, 0x03, 0x69, 0x41, 0x91, 0x02, 0x6a, 0x00, 
+-      0x1e, 0x43, 0x93, 0x01, 0xe0, 0x0b, 0x29, 0x20, 
+-      0xd1, 0x15, 0x4d, 0x53, 0x69, 0x81, 0x91, 0x04, 
+-      0x49, 0x52, 0x91, 0x03, 0x69, 0xc1, 0x91, 0x02, 
+-      0x6a, 0x40, 0x1e, 0x43, 0x93, 0x01, 0x24, 0x00, 
+-      0x4b, 0x4f, 0x93, 0x09, 0x4a, 0x4f, 0x92, 0x08, 
+-      0x4b, 0x4f, 0x93, 0x07, 0x4e, 0x4f, 0x96, 0x06, 
+-      0x4a, 0x4f, 0x92, 0x05, 0xe0, 0x7a, 0x20, 0xb3, 
+-      0xb0, 0x0a, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x98, 0x04, 0x00, 0x80, 0x19, 0x40, 0x23, 0x01, 
+-      0x02, 0x9b, 0x18, 0xc0, 0x68, 0x01, 0x98, 0x04, 
+-      0x00, 0x80, 0x58, 0x28, 0x9a, 0x04, 0x18, 0xaa, 
+-      0x00, 0x5b, 0x18, 0xd2, 0x78, 0x12, 0x92, 0x00, 
+-      0x22, 0x00, 0x9b, 0x04, 0x18, 0xee, 0x23, 0x01, 
+-      0x02, 0xdb, 0x18, 0xf3, 0x70, 0x1a, 0x9a, 0x04, 
+-      0x32, 0x01, 0x92, 0x04, 0x9b, 0x01, 0x40, 0x1a, 
+-      0x92, 0x04, 0x29, 0x00, 0xd0, 0x56, 0xb0, 0x82, 
+-      0x91, 0x01, 0x21, 0x01, 0x9a, 0x02, 0x2a, 0x80, 
+-      0xd1, 0x19, 0x22, 0x00, 0x9b, 0x01, 0x40, 0x0b, 
+-      0xd0, 0x10, 0x9b, 0x0b, 0x5c, 0x9b, 0x2b, 0xff, 
+-      0xd0, 0x0c, 0x9b, 0x0b, 0x5c, 0x9b, 0x93, 0x00, 
+-      0x00, 0x91, 0x9a, 0x0a, 0x58, 0x52, 0x00, 0xa1, 
+-      0x19, 0xc9, 0x61, 0x0a, 0x1c, 0x61, 0x06, 0x0c, 
+-      0x0e, 0x24, 0xe0, 0x1c, 0x00, 0x49, 0x32, 0x01, 
+-      0x2a, 0x10, 0xd3, 0xe7, 0xe0, 0x17, 0x22, 0x00, 
+-      0x9b, 0x01, 0x40, 0x0b, 0xd0, 0x0f, 0x9b, 0x09, 
+-      0x5c, 0x9b, 0x2b, 0xff, 0xd0, 0x0b, 0x93, 0x00, 
+-      0x00, 0x93, 0x9e, 0x08, 0x58, 0xf6, 0x00, 0xa3, 
+-      0x19, 0xdb, 0x61, 0x1e, 0x28, 0x00, 0xd0, 0x02, 
+-      0x1c, 0x63, 0x06, 0x1c, 0x0e, 0x24, 0x00, 0x49, 
+-      0x32, 0x01, 0x2a, 0x20, 0xd3, 0xe8, 0x2c, 0x00, 
+-      0xd0, 0x1b, 0x9b, 0x00, 0x70, 0x7b, 0x60, 0x78, 
+-      0x9b, 0x00, 0x00, 0x99, 0x9a, 0x07, 0x58, 0x52, 
+-      0x69, 0x51, 0xe0, 0x07, 0x68, 0x09, 0x29, 0x00, 
+-      0xd1, 0x04, 0x20, 0xba, 0xb0, 0x0c, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x42, 0x88, 0xd3, 0xf5, 
+-      0x1d, 0xcb, 0x33, 0xb9, 0x42, 0x83, 0xd3, 0xf1, 
+-      0x60, 0xb9, 0x61, 0x51, 0x1c, 0x38, 0xf0, 0x0d, 
+-      0xff, 0x24, 0xb0, 0x02, 0x98, 0x04, 0x99, 0x02, 
+-      0x42, 0x88, 0xd0, 0x01, 0x2c, 0x00, 0xd0, 0x83, 
+-      0x70, 0x3c, 0x98, 0x04, 0x99, 0x03, 0x60, 0x08, 
+-      0x20, 0x00, 0xb0, 0x0a, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x9e, 0x00, 0x04, 0x80, 
+-      0x2e, 0x08, 0x60, 0x90, 0x9e, 0x00, 0x04, 0x90, 
+-      0x2e, 0x08, 0x69, 0x90, 0x9e, 0x00, 0x04, 0x98, 
+-      0x2e, 0x08, 0x5f, 0xc4, 0x2e, 0x08, 0x5f, 0x64, 
+-      0x2e, 0x08, 0x5f, 0xa4, 0x2e, 0x08, 0x5e, 0xe4, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0xb5, 0x00, 0x20, 0xff, 
+-      0x49, 0x03, 0x60, 0x08, 0x20, 0x01, 0x05, 0x00, 
+-      0xf0, 0x1a, 0xf9, 0x9e, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x01, 0xe4, 0xb5, 0xf0, 0x06, 0x07, 
+-      0x0e, 0x3f, 0x06, 0x0c, 0x0e, 0x24, 0x20, 0x10, 
+-      0x2f, 0x1f, 0xdc, 0x2c, 0x2c, 0x1f, 0xdc, 0x2a, 
+-      0x1c, 0x39, 0x43, 0x21, 0x08, 0x49, 0xd2, 0x26, 
+-      0x49, 0x14, 0x1c, 0x38, 0xf0, 0x1a, 0xf9, 0x9a, 
+-      0x26, 0x01, 0x1c, 0x35, 0x40, 0xbd, 0x1c, 0x30, 
+-      0x40, 0xa0, 0x1c, 0x04, 0x43, 0x28, 0xf0, 0x1a, 
+-      0xf9, 0x84, 0xf0, 0x1a, 0xf9, 0x87, 0x43, 0xa8, 
+-      0xf0, 0x1a, 0xf9, 0x88, 0xf0, 0x1a, 0xf9, 0x82, 
+-      0x43, 0xa0, 0xf0, 0x1a, 0xf9, 0x83, 0x1c, 0x38, 
+-      0xf0, 0x10, 0xf8, 0x66, 0x1c, 0x04, 0xd1, 0x07, 
+-      0x21, 0x03, 0x05, 0x09, 0x20, 0x00, 0x1c, 0x3a, 
+-      0x1c, 0x33, 0xf0, 0x10, 0xff, 0x17, 0x1c, 0x04, 
+-      0xf7, 0xff, 0xfc, 0x8e, 0x1c, 0x20, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x00, 0x2d, 0x43, 
+-      0xb5, 0xf0, 0x06, 0x04, 0x0e, 0x24, 0x04, 0x0d, 
+-      0x0c, 0x2d, 0x06, 0x16, 0x0e, 0x36, 0x9f, 0x05, 
+-      0x06, 0x38, 0x0e, 0x00, 0x22, 0x00, 0x21, 0x00, 
+-      0xb4, 0x07, 0x21, 0x10, 0x1c, 0x1a, 0xb4, 0x06, 
+-      0x23, 0x10, 0x1c, 0x20, 0x1c, 0x29, 0x1c, 0x32, 
+-      0xf0, 0x00, 0xf8, 0x54, 0xb0, 0x05, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xf0, 0x06, 0x04, 
+-      0x0e, 0x24, 0x04, 0x0d, 0x0c, 0x2d, 0x06, 0x16, 
+-      0x0e, 0x36, 0x9f, 0x05, 0x06, 0x38, 0x0e, 0x00, 
+-      0x22, 0x00, 0x21, 0x00, 0xb4, 0x07, 0x21, 0x18, 
+-      0x1c, 0x1a, 0xb4, 0x06, 0x23, 0x11, 0x1c, 0x20, 
+-      0x1c, 0x29, 0x1c, 0x32, 0xf0, 0x00, 0xf8, 0x3a, 
+-      0xb0, 0x05, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0xf0, 0x06, 0x04, 0x0e, 0x24, 0x04, 0x0d, 
+-      0x0c, 0x2d, 0x06, 0x16, 0x0e, 0x36, 0x9f, 0x05, 
+-      0x06, 0x38, 0x0e, 0x00, 0x22, 0x00, 0x21, 0x00, 
+-      0xb4, 0x07, 0x21, 0x20, 0x1c, 0x1a, 0xb4, 0x06, 
+-      0x23, 0x51, 0x1c, 0x20, 0x1c, 0x29, 0x1c, 0x32, 
+-      0xf0, 0x00, 0xf8, 0x20, 0xb0, 0x05, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xff, 0x06, 0x03, 
+-      0x0e, 0x1b, 0x04, 0x0d, 0x0c, 0x2d, 0x06, 0x16, 
+-      0x0e, 0x36, 0x9c, 0x09, 0x9f, 0x0a, 0x06, 0x20, 
+-      0x0e, 0x00, 0x22, 0x00, 0x1c, 0x39, 0xb4, 0x07, 
+-      0x21, 0x10, 0x9a, 0x06, 0xb4, 0x06, 0x1c, 0x18, 
+-      0x23, 0x62, 0x1c, 0x29, 0x1c, 0x32, 0xf0, 0x00, 
+-      0xf8, 0x05, 0xb0, 0x05, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xff, 0x9e, 0x09, 
+-      0x9f, 0x0b, 0x06, 0x04, 0x0e, 0x24, 0x04, 0x09, 
+-      0x0c, 0x09, 0xb0, 0x88, 0x91, 0x00, 0x06, 0x15, 
+-      0x0e, 0x2d, 0x06, 0x18, 0x0e, 0x00, 0x90, 0x01, 
+-      0x06, 0x32, 0x0e, 0x12, 0x92, 0x02, 0x06, 0x38, 
+-      0x0e, 0x00, 0x90, 0x03, 0xb0, 0x82, 0xf0, 0x1a, 
+-      0xf8, 0xe9, 0x0d, 0x40, 0xd2, 0x09, 0x20, 0xff, 
+-      0x90, 0x00, 0xf0, 0x1a, 0xf8, 0xe3, 0x23, 0x01, 
+-      0x05, 0x1b, 0x43, 0x18, 0xf0, 0x1a, 0xf8, 0xe2, 
+-      0xe0, 0x01, 0x20, 0x00, 0x90, 0x00, 0x98, 0x03, 
+-      0x08, 0x40, 0xd3, 0x02, 0x22, 0x12, 0x92, 0x01, 
+-      0xe0, 0x01, 0x22, 0x11, 0x92, 0x01, 0x22, 0x01, 
+-      0x1c, 0x11, 0x40, 0xa9, 0x4b, 0x5f, 0x1c, 0x0f, 
+-      0x68, 0x18, 0x40, 0x07, 0xd0, 0x01, 0x27, 0x11, 
+-      0xe0, 0xa2, 0x27, 0x00, 0x43, 0x08, 0x60, 0x18, 
+-      0x23, 0x1c, 0x98, 0x05, 0x40, 0x18, 0x28, 0x1c, 
+-      0xd1, 0x06, 0x21, 0x01, 0x20, 0x7d, 0x01, 0x00, 
+-      0xf0, 0x10, 0xfb, 0xc4, 0x1c, 0x06, 0xe0, 0x0d, 
+-      0x98, 0x05, 0x08, 0x40, 0xd3, 0x05, 0x21, 0x01, 
+-      0x20, 0xc8, 0xf0, 0x10, 0xfb, 0xbb, 0x1c, 0x06, 
+-      0xe0, 0x04, 0x21, 0x01, 0x20, 0x3c, 0xf0, 0x10, 
+-      0xfb, 0xb5, 0x1c, 0x06, 0x20, 0x34, 0xf0, 0x03, 
+-      0xf9, 0x6d, 0x00, 0xaa, 0x92, 0x09, 0x49, 0x4c, 
+-      0x91, 0x08, 0x50, 0x88, 0x00, 0xa1, 0x91, 0x07, 
+-      0x48, 0x4a, 0x90, 0x06, 0x58, 0x40, 0x28, 0x00, 
+-      0xd1, 0x05, 0x00, 0xb0, 0xf0, 0x03, 0xf9, 0x5e, 
+-      0x99, 0x07, 0x9a, 0x06, 0x50, 0x50, 0x98, 0x09, 
+-      0x99, 0x08, 0x58, 0x08, 0x28, 0x00, 0xd0, 0x04, 
+-      0x98, 0x06, 0x99, 0x07, 0x58, 0x40, 0x28, 0x00, 
+-      0xd1, 0x01, 0x27, 0x13, 0xe0, 0x64, 0x99, 0x07, 
+-      0x4a, 0x3f, 0x58, 0x51, 0x29, 0x00, 0xd1, 0x3a, 
+-      0x9a, 0x01, 0xb4, 0x04, 0x23, 0x40, 0x1c, 0x31, 
+-      0x1c, 0x22, 0xf0, 0x10, 0xfc, 0x13, 0xb0, 0x01, 
+-      0x1c, 0x07, 0xd1, 0x17, 0x23, 0x03, 0x02, 0x5b, 
+-      0x22, 0x01, 0x02, 0xd2, 0x21, 0x01, 0x1c, 0x20, 
+-      0xf0, 0x08, 0xfd, 0x56, 0x22, 0x00, 0xb4, 0x04, 
+-      0x22, 0x02, 0x99, 0x03, 0x9b, 0x02, 0x1c, 0x20, 
+-      0xf0, 0x08, 0xfb, 0x8a, 0xb0, 0x01, 0x1c, 0x07, 
+-      0xd1, 0x04, 0x22, 0x01, 0x48, 0x2f, 0x55, 0x02, 
+-      0x48, 0x2f, 0x55, 0x02, 0x2f, 0x00, 0xd1, 0x16, 
+-      0x98, 0x16, 0x28, 0x00, 0xd0, 0x13, 0x21, 0x02, 
+-      0x98, 0x16, 0xf0, 0x10, 0xfb, 0x63, 0x1c, 0x07, 
+-      0x00, 0x80, 0xf0, 0x03, 0xf9, 0x1b, 0x99, 0x07, 
+-      0x4a, 0x28, 0x50, 0x50, 0x28, 0x00, 0xd0, 0x05, 
+-      0x1c, 0x39, 0x1c, 0x22, 0xf0, 0x10, 0xfb, 0x77, 
+-      0x1c, 0x07, 0xe0, 0x00, 0x27, 0x13, 0x2f, 0x00, 
+-      0xd1, 0x22, 0x98, 0x03, 0x09, 0x80, 0xd3, 0x06, 
+-      0x20, 0x5c, 0xf0, 0x03, 0xf9, 0x07, 0x28, 0x00, 
+-      0xd1, 0x02, 0x27, 0x13, 0xe0, 0x00, 0x20, 0x00, 
+-      0x1c, 0x02, 0x98, 0x05, 0x99, 0x17, 0xb4, 0x07, 
+-      0x1c, 0x2a, 0xb4, 0x04, 0x98, 0x0d, 0x99, 0x0c, 
+-      0x58, 0x08, 0x99, 0x18, 0x9a, 0x08, 0x9b, 0x07, 
+-      0xf0, 0x00, 0xf9, 0x1c, 0xb0, 0x04, 0x2f, 0x00, 
+-      0xd1, 0x06, 0x98, 0x09, 0x99, 0x08, 0x58, 0x08, 
+-      0x1c, 0x21, 0xf0, 0x0c, 0xfd, 0xf7, 0x1c, 0x07, 
+-      0x2f, 0x00, 0xd0, 0x03, 0x1c, 0x20, 0x1c, 0x29, 
+-      0xf0, 0x00, 0xf8, 0x20, 0x98, 0x00, 0x28, 0x00, 
+-      0xd0, 0x05, 0xf0, 0x1a, 0xf8, 0x1b, 0x4b, 0x0c, 
+-      0x40, 0x18, 0xf0, 0x1a, 0xf8, 0x1b, 0x1c, 0x38, 
+-      0xb0, 0x0a, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x01, 0xec, 
+-      0x2e, 0x08, 0x01, 0xf0, 0x2e, 0x08, 0x02, 0x70, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x44, 0x48, 
+-      0x2e, 0x08, 0x44, 0x28, 0x2e, 0x08, 0x02, 0xf0, 
+-      0xff, 0xef, 0xff, 0xff, 0xb5, 0xf0, 0x06, 0x07, 
+-      0x0e, 0x3f, 0x06, 0x0d, 0x0e, 0x2d, 0xb0, 0x83, 
+-      0xf0, 0x19, 0xff, 0xf8, 0x0d, 0x40, 0xd2, 0x09, 
+-      0x20, 0xff, 0x90, 0x00, 0xf0, 0x19, 0xff, 0xf2, 
+-      0x23, 0x01, 0x05, 0x1b, 0x43, 0x18, 0xf0, 0x19, 
+-      0xff, 0xf1, 0xe0, 0x01, 0x20, 0x00, 0x90, 0x00, 
+-      0x24, 0x00, 0x20, 0x01, 0x40, 0xa8, 0x1c, 0x02, 
+-      0x49, 0x3f, 0x1c, 0x13, 0x68, 0x08, 0x40, 0x03, 
+-      0xd0, 0x69, 0x43, 0xd2, 0x40, 0x10, 0x00, 0xae, 
+-      0x60, 0x08, 0x4d, 0x3c, 0x59, 0xa8, 0x28, 0x00, 
+-      0xd0, 0x62, 0x78, 0x81, 0x91, 0x02, 0x08, 0x49, 
+-      0xd3, 0x02, 0x23, 0x12, 0x93, 0x01, 0xe0, 0x01, 
+-      0x23, 0x11, 0x93, 0x01, 0x1c, 0x39, 0xf0, 0x0c, 
+-      0xfe, 0x11, 0x1c, 0x04, 0x59, 0xa8, 0x6b, 0x00, 
+-      0x28, 0x00, 0xd0, 0x01, 0xf0, 0x03, 0xf8, 0xac, 
+-      0x59, 0xa8, 0x6a, 0xc0, 0x28, 0x00, 0xd0, 0x01, 
+-      0xf0, 0x03, 0xf8, 0xa6, 0x59, 0xa8, 0xf0, 0x03, 
+-      0xf8, 0xa3, 0x20, 0x00, 0x51, 0xa8, 0x00, 0xbd, 
+-      0x48, 0x2b, 0x59, 0x40, 0x78, 0x80, 0x28, 0x00, 
+-      0xd1, 0x40, 0x1c, 0x39, 0xf0, 0x10, 0xf9, 0x36, 
+-      0x2c, 0x00, 0xd1, 0x2a, 0x98, 0x02, 0x09, 0x80, 
+-      0xd3, 0x0a, 0x21, 0x00, 0x1c, 0x3a, 0x48, 0x25, 
+-      0xf0, 0x10, 0xfa, 0xd1, 0x28, 0x00, 0xd0, 0x03, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x22, 0x00, 0xb4, 0x04, 0x22, 0x02, 0x9b, 0x02, 
+-      0x1c, 0x38, 0x49, 0x1e, 0xf0, 0x08, 0xfa, 0xb8, 
+-      0xb0, 0x01, 0x1c, 0x04, 0xd1, 0x11, 0x9a, 0x01, 
+-      0xb4, 0x04, 0x26, 0x00, 0x21, 0x00, 0x1c, 0x3a, 
+-      0x1c, 0x33, 0x48, 0x18, 0xf0, 0x10, 0xfb, 0x22, 
+-      0x1c, 0x04, 0xb0, 0x01, 0x48, 0x16, 0x55, 0xc6, 
+-      0x48, 0x16, 0x55, 0xc6, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfa, 0xc1, 0x4f, 0x15, 0x59, 0x78, 0xf0, 0x03, 
+-      0xf8, 0x67, 0x26, 0x00, 0x51, 0x7e, 0x37, 0x80, 
+-      0x59, 0x78, 0x28, 0x00, 0xd0, 0x04, 0xf0, 0x03, 
+-      0xf8, 0x5f, 0x51, 0x7e, 0xe0, 0x02, 0xe0, 0x00, 
+-      0xe0, 0x00, 0x24, 0x12, 0x98, 0x00, 0x28, 0x00, 
+-      0xd0, 0x05, 0xf0, 0x19, 0xff, 0x6f, 0x4b, 0x0b, 
+-      0x40, 0x18, 0xf0, 0x19, 0xff, 0x6f, 0x1c, 0x20, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x01, 0xec, 0x2e, 0x08, 0x01, 0xf0, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x44, 0x48, 0x2e, 0x08, 0x44, 0x28, 
+-      0x2e, 0x08, 0x02, 0x70, 0xff, 0xef, 0xff, 0xff, 
+-      0xb5, 0xb0, 0x06, 0x00, 0x0e, 0x00, 0x00, 0x80, 
+-      0x1c, 0x0c, 0x1c, 0x17, 0xb0, 0xad, 0x49, 0x1c, 
+-      0x58, 0x08, 0x90, 0x04, 0x78, 0x81, 0x23, 0x04, 
+-      0x40, 0x19, 0x25, 0x00, 0x29, 0x00, 0xd0, 0x0b, 
+-      0xa9, 0x25, 0xf0, 0x0d, 0xf9, 0xd3, 0xab, 0x00, 
+-      0x80, 0x5d, 0xa8, 0x25, 0x90, 0x24, 0x46, 0x68, 
+-      0x21, 0x00, 0xf0, 0x0d, 0xf9, 0xf2, 0xe0, 0x0c, 
+-      0x78, 0x00, 0x0a, 0x00, 0xd3, 0x04, 0x20, 0x01, 
+-      0x03, 0x00, 0xab, 0x00, 0x80, 0x58, 0xe0, 0x03, 
+-      0x20, 0x01, 0x02, 0x80, 0xab, 0x00, 0x80, 0x58, 
+-      0x20, 0x00, 0x28, 0x00, 0xd1, 0x0e, 0xa8, 0x00, 
+-      0x88, 0x40, 0x60, 0x38, 0xf0, 0x02, 0xff, 0xea, 
+-      0x60, 0x20, 0x28, 0x00, 0xd1, 0x01, 0x20, 0x13, 
+-      0xe0, 0x06, 0x1c, 0x01, 0x46, 0x68, 0xf0, 0x0d, 
+-      0xf9, 0xd4, 0xe0, 0x01, 0x60, 0x25, 0x60, 0x3d, 
+-      0xb0, 0x2d, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x01, 0xf0, 0xb4, 0xf0, 0x06, 0x12, 
+-      0x0e, 0x12, 0x06, 0x1b, 0x0e, 0x1b, 0x9c, 0x06, 
+-      0x9f, 0x07, 0x9d, 0x05, 0x9e, 0x04, 0x06, 0x36, 
+-      0x0e, 0x36, 0x06, 0x2d, 0xd0, 0x02, 0x25, 0x80, 
+-      0x70, 0x05, 0xe0, 0x01, 0x25, 0x00, 0x70, 0x05, 
+-      0x25, 0x00, 0x70, 0x45, 0x80, 0x85, 0x72, 0x05, 
+-      0x70, 0xc6, 0x70, 0x83, 0x62, 0xc4, 0x63, 0x07, 
+-      0x27, 0x00, 0x23, 0x00, 0x2a, 0x00, 0xdd, 0x10, 
+-      0x5c, 0xcc, 0x19, 0xc5, 0x73, 0x2c, 0x18, 0xcc, 
+-      0x78, 0x66, 0x1c, 0x7c, 0x06, 0x25, 0x0e, 0x2d, 
+-      0x1c, 0x3c, 0x18, 0x24, 0x77, 0x26, 0x33, 0x02, 
+-      0x06, 0x1b, 0x0e, 0x1b, 0x1c, 0x2f, 0x42, 0x93, 
+-      0xdb, 0xee, 0xbc, 0xf0, 0x47, 0x70, 0xb5, 0xf0, 
+-      0xb0, 0xac, 0x21, 0x00, 0xa8, 0x07, 0xf0, 0x0d, 
+-      0xf8, 0x59, 0xa8, 0x07, 0x78, 0x00, 0x90, 0x06, 
+-      0x28, 0x00, 0xd0, 0x4b, 0x24, 0x00, 0x98, 0x06, 
+-      0x28, 0x00, 0xdd, 0x43, 0xa8, 0x07, 0xf0, 0x0d, 
+-      0xfc, 0x20, 0x00, 0xa1, 0xa8, 0x07, 0x18, 0x08, 
+-      0x69, 0x07, 0x78, 0xfe, 0xad, 0x07, 0x88, 0x6d, 
+-      0x78, 0xb8, 0x09, 0xc0, 0xd3, 0x12, 0xa8, 0x07, 
+-      0xa9, 0x01, 0xf0, 0x10, 0xfe, 0x6f, 0x78, 0xb8, 
+-      0x08, 0x40, 0xd3, 0x05, 0x46, 0x6a, 0x1c, 0x38, 
+-      0xa9, 0x01, 0xf0, 0x10, 0xfe, 0x9c, 0xe0, 0x08, 
+-      0x46, 0x6a, 0x1c, 0x38, 0xa9, 0x01, 0xf0, 0x10, 
+-      0xfe, 0xd9, 0xe0, 0x02, 0x20, 0x40, 0xab, 0x00, 
+-      0x70, 0x18, 0xa8, 0x00, 0x78, 0x00, 0x09, 0xc0, 
+-      0xd3, 0x16, 0x1c, 0x28, 0xf7, 0xfd, 0xfe, 0x3a, 
+-      0x1c, 0x07, 0xd0, 0x11, 0xa8, 0x07, 0x1c, 0x39, 
+-      0xf0, 0x0d, 0xfa, 0x92, 0x28, 0x00, 0xd1, 0x09, 
+-      0x1c, 0x30, 0x1c, 0x29, 0x1c, 0x3a, 0xf7, 0xfd, 
+-      0xfe, 0x89, 0x28, 0x00, 0xd0, 0x04, 0xf7, 0xfd, 
+-      0xfe, 0x7b, 0xe0, 0x01, 0xf7, 0xfd, 0xfe, 0x78, 
+-      0x1c, 0x60, 0x06, 0x04, 0x0e, 0x24, 0x98, 0x06, 
+-      0x42, 0x84, 0xdb, 0xbb, 0xa8, 0x07, 0xf0, 0x0d, 
+-      0xf8, 0xfb, 0xe7, 0xaa, 0xf7, 0xff, 0xfa, 0x58, 
+-      0xb0, 0x2c, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0xf0, 0xb0, 0xad, 0x21, 0x00, 0xa8, 0x08, 
+-      0xf0, 0x0c, 0xff, 0xfc, 0x22, 0x05, 0x21, 0x16, 
+-      0x1c, 0x04, 0xf0, 0x03, 0xfd, 0x76, 0x2c, 0xb2, 
+-      0xd1, 0x03, 0x21, 0x00, 0xa8, 0x08, 0xf0, 0x0c, 
+-      0xff, 0xab, 0xa8, 0x08, 0x78, 0x00, 0x90, 0x06, 
+-      0x28, 0x00, 0xd0, 0x73, 0x25, 0x00, 0x98, 0x06, 
+-      0x28, 0x00, 0xdd, 0x57, 0xa8, 0x08, 0xf0, 0x0d, 
+-      0xfb, 0xb8, 0x00, 0xa9, 0xa8, 0x08, 0x18, 0x08, 
+-      0x69, 0x07, 0x78, 0xf8, 0x90, 0x07, 0xae, 0x08, 
+-      0x88, 0x76, 0x78, 0xb8, 0x09, 0xc0, 0xd3, 0x12, 
+-      0xa8, 0x08, 0xa9, 0x01, 0xf0, 0x10, 0xfe, 0x06, 
+-      0x78, 0xb8, 0x08, 0x40, 0xd3, 0x05, 0x46, 0x6a, 
+-      0x1c, 0x38, 0xa9, 0x01, 0xf0, 0x10, 0xfe, 0x33, 
+-      0xe0, 0x08, 0x46, 0x6a, 0x1c, 0x38, 0xa9, 0x01, 
+-      0xf0, 0x10, 0xfe, 0x70, 0xe0, 0x02, 0x20, 0x40, 
+-      0xab, 0x00, 0x70, 0x18, 0xa8, 0x00, 0x78, 0x00, 
+-      0x09, 0xc0, 0xd3, 0x29, 0x78, 0xb8, 0x09, 0x80, 
+-      0xd3, 0x0f, 0xa8, 0x08, 0xa9, 0x01, 0xf0, 0x10, 
+-      0xff, 0xcd, 0x1c, 0x04, 0xa8, 0x00, 0x78, 0x00, 
+-      0x08, 0x80, 0xd2, 0x02, 0x78, 0xb8, 0x08, 0x80, 
+-      0xd3, 0x1a, 0x1c, 0x38, 0xf0, 0x11, 0xf8, 0xd4, 
+-      0xe0, 0x16, 0x1c, 0x30, 0xf7, 0xfd, 0xfd, 0xbe, 
+-      0x1c, 0x07, 0xd0, 0x11, 0xa8, 0x08, 0x1c, 0x39, 
+-      0xf0, 0x0d, 0xfa, 0x16, 0x28, 0x00, 0xd1, 0x09, 
+-      0x98, 0x07, 0x1c, 0x31, 0x1c, 0x3a, 0xf7, 0xfd, 
+-      0xfe, 0x0d, 0x28, 0x00, 0xd0, 0x04, 0xf7, 0xfd, 
+-      0xfd, 0xff, 0xe0, 0x01, 0xf7, 0xfd, 0xfd, 0xfc, 
+-      0x1c, 0x68, 0x06, 0x05, 0x0e, 0x2d, 0x98, 0x06, 
+-      0x42, 0x85, 0xdb, 0xa7, 0x98, 0x06, 0x28, 0x00, 
+-      0xd0, 0x08, 0xa8, 0x08, 0xf0, 0x0d, 0xf8, 0x7c, 
+-      0x2c, 0xb2, 0xd1, 0x03, 0x21, 0x00, 0xa8, 0x08, 
+-      0xf0, 0x0c, 0xff, 0x3e, 0xf7, 0xff, 0xf9, 0x58, 
+-      0x21, 0x00, 0xa8, 0x08, 0xf7, 0xff, 0xfb, 0x88, 
+-      0x1c, 0x04, 0xa8, 0x08, 0x78, 0x00, 0x90, 0x06, 
+-      0x28, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xd1, 0x89, 
+-      0xf7, 0xff, 0xf9, 0xc6, 0xb0, 0x2d, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xf0, 0x26, 0x00, 
+-      0x48, 0x28, 0x71, 0x06, 0x70, 0x06, 0x20, 0x00, 
+-      0x4f, 0x27, 0x4a, 0x28, 0x49, 0x28, 0x00, 0x43, 
+-      0x52, 0xd6, 0x52, 0xfe, 0x00, 0x83, 0x50, 0xce, 
+-      0x30, 0x01, 0x06, 0x00, 0x0e, 0x00, 0x28, 0x1d, 
+-      0xdb, 0xf5, 0x28, 0x20, 0xda, 0x08, 0x00, 0x43, 
+-      0x52, 0xd6, 0x00, 0x83, 0x50, 0xce, 0x30, 0x01, 
+-      0x06, 0x00, 0x0e, 0x00, 0x28, 0x20, 0xdb, 0xf6, 
+-      0x20, 0x01, 0x02, 0x80, 0xf0, 0x19, 0xfd, 0xcd, 
+-      0xf0, 0x19, 0xfd, 0xd0, 0x4b, 0x1b, 0x40, 0x18, 
+-      0xf0, 0x19, 0xfd, 0xd0, 0x49, 0x1a, 0x20, 0x0a, 
+-      0xf0, 0x19, 0xfd, 0xd0, 0x21, 0x00, 0x4f, 0x19, 
+-      0x20, 0xff, 0x4a, 0x19, 0x00, 0x4b, 0x18, 0x5b, 
+-      0x01, 0x1b, 0x52, 0xd7, 0x18, 0x9b, 0x70, 0x98, 
+-      0x70, 0xde, 0x71, 0x1e, 0x1d, 0xdc, 0x34, 0x19, 
+-      0x73, 0x26, 0x71, 0x5e, 0x1c, 0x1d, 0x23, 0x06, 
+-      0x73, 0x63, 0x23, 0x00, 0x00, 0xdc, 0x19, 0x2c, 
+-      0x81, 0xa6, 0x81, 0xe6, 0x33, 0x01, 0x06, 0x1b, 
+-      0x0e, 0x1b, 0x60, 0xa6, 0x2b, 0x04, 0xdb, 0xf5, 
+-      0x31, 0x01, 0x06, 0x09, 0x0e, 0x09, 0x29, 0x08, 
+-      0xdb, 0xe0, 0x1c, 0x30, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x03, 0xb8, 
+-      0x2e, 0x08, 0x49, 0xb0, 0x2e, 0x08, 0x49, 0x70, 
+-      0x2e, 0x08, 0x45, 0xe8, 0xff, 0xff, 0xfb, 0xff, 
+-      0x2e, 0x00, 0x31, 0x7d, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x44, 0x68, 0xb5, 0xf0, 0x06, 0x00, 
+-      0x0e, 0x00, 0xb0, 0x83, 0x90, 0x00, 0x04, 0x09, 
+-      0x0c, 0x09, 0x91, 0x01, 0x06, 0x10, 0x0e, 0x00, 
+-      0x04, 0x1c, 0x0c, 0x24, 0x27, 0x00, 0x49, 0x5a, 
+-      0x00, 0x7b, 0x19, 0xdb, 0x01, 0x1b, 0x5a, 0xcd, 
+-      0x4b, 0x58, 0x42, 0x9d, 0xd1, 0x01, 0x1c, 0x3a, 
+-      0xe0, 0x04, 0x1c, 0x7b, 0x06, 0x1f, 0x0e, 0x3f, 
+-      0x2f, 0x08, 0xdb, 0xf1, 0x2f, 0x08, 0xd1, 0x05, 
+-      0x20, 0x00, 0x43, 0xc0, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0x46, 0x4f, 0x50, 
+-      0x97, 0x02, 0x5b, 0xbb, 0x2b, 0x00, 0xd0, 0x05, 
+-      0x20, 0x00, 0x43, 0xc0, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x23, 0x01, 0x9f, 0x02, 
+-      0x53, 0xbb, 0x00, 0x53, 0x18, 0x9a, 0x01, 0x12, 
+-      0x18, 0x57, 0x80, 0x38, 0x20, 0x14, 0xf0, 0x02, 
+-      0xfe, 0x19, 0x1c, 0x01, 0x62, 0xb8, 0x20, 0x00, 
+-      0x29, 0x00, 0xd1, 0x08, 0x49, 0x41, 0x80, 0x39, 
+-      0x9f, 0x02, 0x53, 0xb8, 0x43, 0xc0, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x1c, 0x0d, 
+-      0x21, 0xff, 0x02, 0x09, 0x40, 0x21, 0x12, 0x08, 
+-      0x28, 0x09, 0xd2, 0x1f, 0xa3, 0x01, 0x5c, 0x1b, 
+-      0x00, 0x5b, 0x44, 0x9f, 0x1b, 0x04, 0x06, 0x09, 
+-      0x0c, 0x0f, 0x12, 0x15, 0x18, 0x00, 0x24, 0xb8, 
+-      0xe0, 0x16, 0x24, 0xff, 0x34, 0x71, 0xe0, 0x13, 
+-      0x24, 0x01, 0x02, 0xa4, 0xe0, 0x10, 0x24, 0x01, 
+-      0x02, 0xe4, 0xe0, 0x0d, 0x24, 0x01, 0x03, 0x24, 
+-      0xe0, 0x0a, 0x24, 0x01, 0x03, 0x64, 0xe0, 0x07, 
+-      0x24, 0x01, 0x03, 0xa4, 0xe0, 0x04, 0x24, 0x01, 
+-      0x03, 0xe4, 0xe0, 0x01, 0x24, 0x01, 0x02, 0xa4, 
+-      0x80, 0xac, 0x88, 0xa8, 0x00, 0x80, 0xf0, 0x02, 
+-      0xfd, 0xdd, 0x60, 0x28, 0x28, 0x00, 0xd1, 0x0d, 
+-      0x48, 0x24, 0x80, 0x38, 0x20, 0x00, 0x9f, 0x02, 
+-      0x53, 0xb8, 0x1c, 0x28, 0xf0, 0x02, 0xfd, 0xf4, 
+-      0x20, 0x00, 0x43, 0xc0, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x98, 0x00, 0x70, 0xb8, 
+-      0x26, 0x00, 0x88, 0x38, 0x00, 0x80, 0x49, 0x1d, 
+-      0x50, 0x0e, 0x20, 0x00, 0x1c, 0x01, 0x43, 0x61, 
+-      0x68, 0x2a, 0x18, 0x8a, 0x00, 0xc1, 0x19, 0xc9, 
+-      0x30, 0x01, 0x06, 0x00, 0x0e, 0x00, 0x60, 0x8a, 
+-      0x28, 0x04, 0xdb, 0xf3, 0x20, 0xb8, 0x1c, 0x21, 
+-      0xf0, 0x15, 0xfd, 0x94, 0x1d, 0xfc, 0x34, 0x19, 
+-      0x73, 0x20, 0x72, 0x2e, 0x78, 0xb8, 0x23, 0x01, 
+-      0x02, 0x9b, 0x00, 0x5a, 0x21, 0x01, 0xf0, 0x08, 
+-      0xf9, 0xc7, 0x22, 0x00, 0xb4, 0x04, 0x78, 0xb8, 
+-      0x23, 0x05, 0x22, 0x02, 0x99, 0x02, 0xf0, 0x07, 
+-      0xff, 0xfb, 0x22, 0x04, 0x7b, 0x21, 0xb0, 0x01, 
+-      0xb4, 0x06, 0x78, 0xb9, 0x22, 0x0a, 0x20, 0x85, 
+-      0x6a, 0xbb, 0xf0, 0x08, 0xfa, 0x43, 0x1c, 0x30, 
+-      0xb0, 0x05, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x44, 0x68, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x49, 0x70, 0x2e, 0x08, 0x45, 0xe8, 
+-      0xb5, 0xf0, 0xb0, 0x82, 0x46, 0x68, 0xf0, 0x08, 
+-      0xff, 0xd7, 0x21, 0x00, 0x4f, 0x24, 0x4b, 0x25, 
+-      0x93, 0x01, 0x4a, 0x25, 0x00, 0x48, 0x18, 0x40, 
+-      0x01, 0x00, 0x19, 0xc0, 0x78, 0x84, 0x9d, 0x00, 
+-      0x40, 0xe5, 0x07, 0xeb, 0x0f, 0xdb, 0x2b, 0x01, 
+-      0xd1, 0x31, 0x6a, 0x83, 0x7a, 0x1c, 0x2c, 0xa4, 
+-      0xd0, 0x01, 0x2c, 0xa5, 0xd1, 0x2b, 0x1d, 0xc4, 
+-      0x34, 0x19, 0xe0, 0x0e, 0x79, 0x05, 0x73, 0x65, 
+-      0x88, 0xde, 0x79, 0x05, 0x00, 0xed, 0x18, 0x2d, 
+-      0x81, 0xae, 0x79, 0x05, 0x35, 0x01, 0x07, 0xad, 
+-      0x0f, 0xad, 0x71, 0x05, 0x78, 0x15, 0x35, 0x01, 
+-      0x70, 0x15, 0x7a, 0x9d, 0x7b, 0x66, 0x42, 0xb5, 
+-      0xd0, 0x02, 0x79, 0x45, 0x2d, 0x00, 0xd0, 0xe9, 
+-      0x7a, 0x1b, 0x2b, 0xa5, 0xd1, 0x0f, 0x79, 0x43, 
+-      0x07, 0xdc, 0x0f, 0xe4, 0x2c, 0x01, 0xd0, 0x0a, 
+-      0x1c, 0x1c, 0x23, 0x01, 0x43, 0x23, 0x71, 0x43, 
+-      0x88, 0x00, 0x00, 0x80, 0x9b, 0x01, 0x18, 0xc0, 
+-      0x68, 0x03, 0x33, 0x01, 0x60, 0x03, 0x1c, 0x48, 
+-      0x06, 0x01, 0x0e, 0x09, 0x29, 0x08, 0xdb, 0xbd, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x44, 0x68, 0x2e, 0x08, 0x45, 0xe8, 
+-      0x2e, 0x08, 0x03, 0xb8, 0xb5, 0xf0, 0x04, 0x05, 
+-      0x0c, 0x2d, 0x20, 0x00, 0x4c, 0x31, 0x00, 0x42, 
+-      0x18, 0x12, 0x01, 0x12, 0x5a, 0xa2, 0x42, 0xaa, 
+-      0xd1, 0x01, 0x1c, 0x01, 0xe0, 0x04, 0x30, 0x01, 
+-      0x06, 0x00, 0x0e, 0x00, 0x28, 0x08, 0xdb, 0xf2, 
+-      0x28, 0x08, 0xd1, 0x04, 0x20, 0x00, 0x43, 0xc0, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x48, 
+-      0x18, 0x40, 0x01, 0x00, 0x19, 0x07, 0x78, 0xb8, 
+-      0x49, 0x25, 0xf0, 0x08, 0xfa, 0x0f, 0x79, 0x78, 
+-      0x23, 0x02, 0x43, 0x18, 0x71, 0x78, 0x78, 0xbe, 
+-      0x20, 0xff, 0x70, 0xb8, 0x21, 0x00, 0x1d, 0xf8, 
+-      0x30, 0x19, 0x73, 0x01, 0x21, 0x06, 0x73, 0x41, 
+-      0x78, 0xf8, 0x79, 0x39, 0x42, 0x88, 0xd1, 0x11, 
+-      0x79, 0x78, 0x07, 0xc0, 0x0f, 0xc0, 0x28, 0x01, 
+-      0xd0, 0x0c, 0x20, 0x00, 0x70, 0xf8, 0x71, 0x38, 
+-      0x71, 0x78, 0x48, 0x17, 0x80, 0x38, 0x6a, 0xb8, 
+-      0x68, 0x00, 0xf0, 0x02, 0xfd, 0x15, 0x6a, 0xb8, 
+-      0xf0, 0x02, 0xfd, 0x12, 0x4f, 0x12, 0x00, 0x68, 
+-      0x49, 0x12, 0x52, 0x0f, 0x00, 0x71, 0x4a, 0x12, 
+-      0x52, 0x57, 0x21, 0x00, 0x4a, 0x11, 0x52, 0x11, 
+-      0x1c, 0x30, 0x1c, 0x29, 0xf0, 0x03, 0xf8, 0x12, 
+-      0x20, 0x00, 0x00, 0x41, 0x18, 0x09, 0x01, 0x09, 
+-      0x5a, 0x61, 0x42, 0xb9, 0xd1, 0x04, 0x30, 0x01, 
+-      0x06, 0x00, 0x0e, 0x00, 0x28, 0x08, 0xdb, 0xf4, 
+-      0x28, 0x08, 0xd1, 0x03, 0x21, 0x00, 0x48, 0x08, 
+-      0x71, 0x01, 0x70, 0x01, 0x20, 0x00, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x44, 0x68, 
+-      0x00, 0x00, 0xff, 0xff, 0x2e, 0x08, 0x49, 0x30, 
+-      0x2e, 0x08, 0x48, 0xf8, 0x2e, 0x08, 0x49, 0x70, 
+-      0x2e, 0x08, 0x03, 0xb8, 0xb5, 0x80, 0x1c, 0x07, 
+-      0x30, 0x28, 0xf0, 0x02, 0xfc, 0xbb, 0x49, 0x07, 
+-      0x64, 0x88, 0x65, 0x08, 0x65, 0x48, 0x19, 0xc0, 
+-      0x64, 0xc8, 0x20, 0x00, 0x64, 0x08, 0x64, 0x4f, 
+-      0x49, 0x03, 0x84, 0x08, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x03, 0xc0, 
+-      0x2c, 0x00, 0x01, 0x00, 0xb5, 0x80, 0x1c, 0x07, 
+-      0x30, 0x28, 0xf0, 0x02, 0xfc, 0xa3, 0x49, 0x06, 
+-      0x66, 0x08, 0x66, 0x88, 0x66, 0xc8, 0x19, 0xc0, 
+-      0x66, 0x48, 0x20, 0x00, 0x65, 0x88, 0x65, 0xcf, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x03, 0xc0, 0xb4, 0x80, 0x04, 0x09, 
+-      0x0c, 0x09, 0x88, 0x02, 0x42, 0x8a, 0xd0, 0x18, 
+-      0x4a, 0x0d, 0x8f, 0x13, 0x2b, 0x01, 0xd0, 0x04, 
+-      0x23, 0x01, 0x87, 0x13, 0x8f, 0x17, 0x2f, 0x01, 
+-      0xd1, 0xfb, 0x88, 0x03, 0x42, 0x8b, 0xd0, 0x03, 
+-      0x80, 0x01, 0x88, 0x03, 0x42, 0x8b, 0xd1, 0xfb, 
+-      0x8f, 0x11, 0x1c, 0x10, 0x29, 0x00, 0xd0, 0x04, 
+-      0x21, 0x00, 0x87, 0x01, 0x8f, 0x02, 0x2a, 0x00, 
+-      0xd1, 0xfb, 0xbc, 0x80, 0x47, 0x70, 0x00, 0x00, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0xb5, 0x80, 0x48, 0x1f, 
+-      0x8f, 0x40, 0x28, 0x00, 0xd1, 0x37, 0x4f, 0x1e, 
+-      0x88, 0x38, 0x12, 0x00, 0x4a, 0x1d, 0x28, 0x06, 
+-      0xd0, 0x1e, 0xdc, 0x08, 0x28, 0x06, 0xd2, 0x26, 
+-      0xa3, 0x01, 0x5c, 0x1b, 0x00, 0x5b, 0x44, 0x9f, 
+-      0x2a, 0x12, 0x12, 0x0d, 0x22, 0x12, 0x28, 0x07, 
+-      0xd0, 0x15, 0x28, 0x09, 0xd0, 0x0b, 0x28, 0x0b, 
+-      0xd0, 0x14, 0x28, 0x80, 0xd1, 0x17, 0xf0, 0x00, 
+-      0xf9, 0x1f, 0xe0, 0x18, 0x88, 0x79, 0x88, 0x38, 
+-      0xf0, 0x00, 0xf8, 0x24, 0xe0, 0x13, 0x88, 0x79, 
+-      0x88, 0x38, 0xf0, 0x00, 0xf8, 0xbd, 0xe0, 0x0e, 
+-      0xf0, 0x00, 0xf9, 0x6a, 0xe0, 0x0b, 0xf0, 0x00, 
+-      0xf9, 0xd5, 0xe0, 0x08, 0x88, 0x79, 0x88, 0x38, 
+-      0xf0, 0x00, 0xfc, 0x9c, 0xe0, 0x03, 0x48, 0x08, 
+-      0x8e, 0x81, 0x31, 0x01, 0x86, 0x81, 0x21, 0x00, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xff, 0x9f, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2c, 0x00, 0x1f, 0xc0, 
+-      0x2c, 0x00, 0x00, 0xfc, 0x2c, 0x00, 0x01, 0x00, 
+-      0x2e, 0x08, 0x04, 0x00, 0xb5, 0xf0, 0x04, 0x04, 
+-      0x0c, 0x24, 0x04, 0x0d, 0x0c, 0x2d, 0x1c, 0x17, 
+-      0x2d, 0x10, 0xdd, 0x03, 0x20, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xf0, 0x19, 0xfb, 0x92, 
+-      0x1c, 0x68, 0x10, 0x40, 0x00, 0x40, 0x04, 0x01, 
+-      0x0c, 0x09, 0x1c, 0x88, 0x00, 0x40, 0x1d, 0x02, 
+-      0x48, 0x1c, 0x6c, 0x03, 0x18, 0x9d, 0x6c, 0x46, 
+-      0x4b, 0x1b, 0x42, 0xb5, 0xdd, 0x0a, 0x88, 0x19, 
+-      0x1c, 0x18, 0x23, 0x20, 0x43, 0x19, 0x80, 0x01, 
+-      0xf0, 0x19, 0xfb, 0xb2, 0x20, 0x01, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x64, 0x05, 0x35, 0x28, 
+-      0x42, 0xb5, 0xdd, 0x04, 0x88, 0x1e, 0x1c, 0x1d, 
+-      0x23, 0x10, 0x43, 0x33, 0x80, 0x2b, 0x6d, 0x03, 
+-      0x80, 0x9c, 0x6d, 0x04, 0x80, 0xe2, 0x23, 0x00, 
+-      0x29, 0x00, 0xdd, 0x08, 0x88, 0x3d, 0x00, 0x5c, 
+-      0x6d, 0x06, 0x19, 0xa4, 0x81, 0x25, 0x33, 0x01, 
+-      0x37, 0x02, 0x42, 0x8b, 0xdb, 0xf6, 0x6d, 0x01, 
+-      0x18, 0x8a, 0x6c, 0xc3, 0x42, 0x9a, 0xd9, 0x00, 
+-      0x6c, 0x82, 0x60, 0x0a, 0x65, 0x02, 0xf0, 0x19, 
+-      0xfb, 0x8b, 0x20, 0x00, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x03, 0xc0, 
+-      0x2c, 0x00, 0x00, 0xf8, 0xb4, 0xf0, 0x04, 0x04, 
+-      0x0c, 0x24, 0x04, 0x08, 0x0c, 0x00, 0x28, 0x10, 
+-      0xdd, 0x02, 0x20, 0x02, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x30, 0x01, 0x4f, 0x1c, 0x40, 0x07, 0x1c, 0xb8, 
+-      0x00, 0x40, 0x1d, 0x01, 0x48, 0x1a, 0x6d, 0x83, 
+-      0x18, 0x5d, 0x6d, 0xc6, 0x4b, 0x19, 0x42, 0xb5, 
+-      0xdd, 0x07, 0x88, 0x19, 0x1c, 0x18, 0x23, 0x02, 
+-      0x43, 0x19, 0x80, 0x01, 0x20, 0x01, 0xbc, 0xf0, 
+-      0x47, 0x70, 0x65, 0x85, 0x35, 0x28, 0x42, 0xb5, 
+-      0xdd, 0x04, 0x88, 0x1e, 0x1c, 0x1d, 0x23, 0x01, 
+-      0x43, 0x33, 0x80, 0x2b, 0x6e, 0x83, 0x80, 0x9c, 
+-      0x6e, 0x84, 0x80, 0xe1, 0x23, 0x00, 0x2f, 0x00, 
+-      0xdd, 0x08, 0x88, 0x15, 0x00, 0x5c, 0x6e, 0x86, 
+-      0x19, 0xa4, 0x81, 0x25, 0x32, 0x02, 0x33, 0x01, 
+-      0x42, 0xbb, 0xdb, 0xf6, 0x6e, 0x82, 0x18, 0x51, 
+-      0x6e, 0x43, 0x42, 0x99, 0xd3, 0x00, 0x6e, 0x01, 
+-      0x60, 0x11, 0x66, 0x81, 0x20, 0x00, 0xbc, 0xf0, 
+-      0x47, 0x70, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 
+-      0x2e, 0x08, 0x03, 0xc0, 0x2c, 0x00, 0x00, 0xf8, 
+-      0xb5, 0xb0, 0x04, 0x04, 0x0c, 0x24, 0x04, 0x0d, 
+-      0x0c, 0x2d, 0x1c, 0x17, 0xf0, 0x19, 0xfa, 0xfa, 
+-      0x1c, 0x20, 0x1c, 0x29, 0x1c, 0x3a, 0xf7, 0xff, 
+-      0xff, 0xa9, 0x1c, 0x07, 0xf0, 0x19, 0xfb, 0x28, 
+-      0x1c, 0x38, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb4, 0xf0, 0x04, 0x04, 0x0c, 0x24, 0x04, 0x09, 
+-      0x0c, 0x09, 0x29, 0x08, 0xdd, 0x02, 0x20, 0x02, 
+-      0xbc, 0xf0, 0x47, 0x70, 0x00, 0x88, 0x1d, 0xc7, 
+-      0x37, 0x01, 0x48, 0x19, 0x6d, 0x83, 0x19, 0xdd, 
+-      0x6d, 0xc6, 0x4b, 0x18, 0x42, 0xb5, 0xdd, 0x07, 
+-      0x88, 0x19, 0x1c, 0x18, 0x23, 0x02, 0x43, 0x19, 
+-      0x80, 0x01, 0x20, 0x01, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x65, 0x85, 0x35, 0x28, 0x42, 0xb5, 0xdd, 0x04, 
+-      0x88, 0x1e, 0x1c, 0x1d, 0x23, 0x01, 0x43, 0x33, 
+-      0x80, 0x2b, 0x6e, 0x83, 0x80, 0x9c, 0x6e, 0x84, 
+-      0x80, 0xe7, 0x23, 0x00, 0x6e, 0x84, 0x29, 0x00, 
+-      0xdd, 0x06, 0xca, 0x40, 0x00, 0x9d, 0x19, 0x2d, 
+-      0x60, 0xae, 0x33, 0x01, 0x42, 0x8b, 0xdb, 0xf8, 
+-      0x6e, 0x81, 0x19, 0xca, 0x6e, 0x43, 0x42, 0x9a, 
+-      0xd3, 0x00, 0x6e, 0x02, 0x60, 0x0a, 0x66, 0x82, 
+-      0x20, 0x00, 0xbc, 0xf0, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x03, 0xc0, 0x2c, 0x00, 0x00, 0xf8, 
+-      0xb5, 0x80, 0x48, 0x28, 0x88, 0x00, 0x06, 0x00, 
+-      0x0e, 0x00, 0x4f, 0x27, 0x28, 0x01, 0xd0, 0x13, 
+-      0x28, 0x02, 0xd0, 0x1a, 0x28, 0x03, 0xd1, 0x0c, 
+-      0x68, 0x38, 0x88, 0x41, 0x29, 0x0e, 0xdb, 0x02, 
+-      0x88, 0x41, 0x29, 0x0f, 0xdd, 0x2f, 0x88, 0x01, 
+-      0x04, 0x09, 0x88, 0x40, 0x43, 0x08, 0xf0, 0x0b, 
+-      0xf9, 0x81, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x68, 0x38, 0x88, 0x82, 0x88, 0x41, 0x88, 0x00, 
+-      0xf0, 0x0e, 0xf8, 0x60, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x68, 0x38, 0x88, 0x81, 0x04, 0x09, 
+-      0x88, 0xc2, 0x43, 0x11, 0x88, 0x02, 0x04, 0x12, 
+-      0x88, 0x40, 0x43, 0x10, 0xf0, 0x0d, 0xfd, 0x04, 
+-      0x68, 0x38, 0x88, 0x41, 0x29, 0x0e, 0xd1, 0x08, 
+-      0x88, 0x81, 0x04, 0x09, 0x88, 0xc0, 0x43, 0x08, 
+-      0xf0, 0x0a, 0xff, 0xfe, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x20, 0x01, 0xf0, 0x0a, 0xff, 0xf8, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x88, 0x41, 
+-      0x48, 0x08, 0x29, 0x0e, 0xd1, 0x02, 0x21, 0x00, 
+-      0x60, 0x01, 0xe0, 0x01, 0x21, 0x01, 0x60, 0x01, 
+-      0x68, 0x00, 0xf0, 0x00, 0xfb, 0xe1, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2c, 0x00, 0x00, 0xfc, 
+-      0x2e, 0x08, 0x03, 0xc0, 0x2e, 0x08, 0x04, 0xf4, 
+-      0xb5, 0x90, 0x48, 0x31, 0x88, 0x00, 0x06, 0x04, 
+-      0x0e, 0x24, 0x48, 0x30, 0x22, 0x03, 0x21, 0x02, 
+-      0x4f, 0x2f, 0x2c, 0x08, 0xd2, 0x4f, 0xa3, 0x02, 
+-      0x5d, 0x1b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x04, 0x4b, 0x10, 0x16, 0x1c, 0x28, 0x34, 0x3f, 
+-      0x68, 0x39, 0x88, 0x49, 0x06, 0x09, 0x0e, 0x09, 
+-      0x88, 0x00, 0x06, 0x00, 0x0e, 0x00, 0xf0, 0x03, 
+-      0xfa, 0xa7, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x20, 0x03, 0xf7, 0xfd, 0xff, 0xe1, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x20, 0x02, 0xf7, 0xfd, 
+-      0xff, 0xdb, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x88, 0x00, 0x4b, 0x1e, 0x28, 0x00, 0xd0, 0x03, 
+-      0x60, 0x1a, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x60, 0x19, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x88, 0x00, 0x4b, 0x19, 0x28, 0x00, 0xd0, 0x03, 
+-      0x60, 0x1a, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x60, 0x19, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0xf0, 0x02, 0xfe, 0x72, 0x68, 0x39, 0x88, 0x4a, 
+-      0x1d, 0x08, 0x88, 0x09, 0xf7, 0xfe, 0xf8, 0x52, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x68, 0x38, 
+-      0x88, 0x81, 0x04, 0x09, 0x88, 0xc2, 0x18, 0x8a, 
+-      0x88, 0x01, 0x04, 0x09, 0x88, 0x40, 0x50, 0x0a, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x1d, 0xf8, 
+-      0x30, 0x39, 0x8e, 0x81, 0x31, 0x01, 0x86, 0x81, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2c, 0x00, 0x00, 0xfc, 0x2c, 0x00, 0x01, 0x00, 
+-      0x2e, 0x08, 0x03, 0xc0, 0x6e, 0x00, 0x13, 0x00, 
+-      0x6e, 0x00, 0x12, 0x00, 0xb5, 0x90, 0xb0, 0x86, 
+-      0x48, 0x80, 0x88, 0x00, 0x06, 0x00, 0x0e, 0x00, 
+-      0x4c, 0x7f, 0x4f, 0x80, 0x28, 0x0b, 0xd2, 0x61, 
+-      0xa3, 0x01, 0x5c, 0x1b, 0x00, 0x5b, 0x44, 0x9f, 
+-      0x05, 0x0f, 0x17, 0x3a, 0x5e, 0x86, 0x90, 0xbd, 
+-      0xc5, 0xd3, 0xd8, 0x00, 0xf0, 0x0b, 0xfb, 0x38, 
+-      0x90, 0x05, 0x14, 0x00, 0x68, 0x39, 0x80, 0x08, 
+-      0x98, 0x05, 0x68, 0x39, 0x80, 0x48, 0xe0, 0xe0, 
+-      0x20, 0x1e, 0xa9, 0x05, 0xf0, 0x0b, 0xfa, 0x3a, 
+-      0x98, 0x05, 0x68, 0x39, 0x80, 0x08, 0xe0, 0xd8, 
+-      0x1c, 0x20, 0xf0, 0x0d, 0xfe, 0x31, 0x20, 0x00, 
+-      0x00, 0x81, 0x58, 0x61, 0x00, 0x42, 0x68, 0x3b, 
+-      0x52, 0x99, 0x30, 0x01, 0x28, 0x04, 0xdd, 0xf7, 
+-      0x20, 0x07, 0x00, 0x81, 0x58, 0x61, 0x00, 0x42, 
+-      0x68, 0x3b, 0x18, 0xd2, 0x3a, 0x40, 0x87, 0x91, 
+-      0x30, 0x01, 0x28, 0x0b, 0xdd, 0xf5, 0x20, 0x0d, 
+-      0x00, 0x81, 0x58, 0x61, 0x00, 0x42, 0x68, 0x3b, 
+-      0x18, 0xd2, 0x3a, 0x40, 0x87, 0x51, 0x30, 0x01, 
+-      0x28, 0x12, 0xdd, 0xf5, 0xe0, 0xb5, 0x20, 0x13, 
+-      0x00, 0x81, 0x58, 0x61, 0x00, 0x42, 0x68, 0x3b, 
+-      0x18, 0xd2, 0x3a, 0x40, 0x83, 0x51, 0x30, 0x01, 
+-      0x28, 0x15, 0xdd, 0xf5, 0x20, 0x00, 0x00, 0x81, 
+-      0x19, 0x09, 0x6d, 0x89, 0x00, 0x42, 0x68, 0x3b, 
+-      0x18, 0xd2, 0x80, 0xd1, 0x30, 0x01, 0x28, 0x0a, 
+-      0xdd, 0xf5, 0x20, 0x00, 0x00, 0x81, 0x19, 0x09, 
+-      0x31, 0x80, 0x68, 0x49, 0x00, 0x42, 0x68, 0x3b, 
+-      0x18, 0xd2, 0x83, 0x91, 0x30, 0x01, 0x28, 0x01, 
+-      0xdd, 0xf4, 0xe0, 0x92, 0xe0, 0x8c, 0x20, 0x02, 
+-      0x00, 0x81, 0x19, 0x09, 0x31, 0x80, 0x68, 0x49, 
+-      0x00, 0x42, 0x68, 0x3b, 0x18, 0xd2, 0x3a, 0x40, 
+-      0x87, 0x91, 0x30, 0x01, 0x28, 0x05, 0xdd, 0xf3, 
+-      0x20, 0x09, 0x00, 0x81, 0x19, 0x09, 0x31, 0x80, 
+-      0x68, 0x49, 0x00, 0x42, 0x68, 0x3b, 0x18, 0xd2, 
+-      0x3a, 0x40, 0x86, 0xd1, 0x30, 0x01, 0x28, 0x0f, 
+-      0xdd, 0xf3, 0x20, 0x11, 0x00, 0x81, 0x19, 0x09, 
+-      0x31, 0x80, 0x68, 0x49, 0x00, 0x42, 0x68, 0x3b, 
+-      0x18, 0xd2, 0x3a, 0x40, 0x86, 0x91, 0x30, 0x01, 
+-      0x28, 0x13, 0xdd, 0xf3, 0xe0, 0x69, 0x22, 0x00, 
+-      0x21, 0x00, 0x20, 0x01, 0x02, 0xc0, 0xf7, 0xff, 
+-      0xfe, 0x47, 0x6f, 0xb8, 0x49, 0x36, 0x80, 0x08, 
+-      0xe0, 0x5f, 0xa8, 0x02, 0xf0, 0x10, 0xfc, 0x18, 
+-      0x98, 0x02, 0x0c, 0x00, 0x68, 0x39, 0x80, 0x08, 
+-      0x98, 0x02, 0x68, 0x39, 0x80, 0x48, 0x98, 0x03, 
+-      0x0c, 0x00, 0x68, 0x39, 0x80, 0x88, 0x98, 0x03, 
+-      0x68, 0x39, 0x80, 0xc8, 0x98, 0x04, 0x0c, 0x00, 
+-      0x68, 0x39, 0x81, 0x08, 0x98, 0x04, 0x68, 0x39, 
+-      0x81, 0x48, 0x20, 0x00, 0x68, 0x39, 0x81, 0x88, 
+-      0x68, 0x38, 0x89, 0x81, 0x23, 0x01, 0x03, 0xdb, 
+-      0x43, 0x19, 0x81, 0x81, 0x48, 0x25, 0x68, 0x39, 
+-      0x81, 0xc8, 0x48, 0x25, 0x68, 0x01, 0x14, 0x09, 
+-      0x68, 0x3a, 0x82, 0x11, 0x68, 0x00, 0x68, 0x39, 
+-      0x82, 0x48, 0xe0, 0x32, 0x20, 0x19, 0x06, 0x80, 
+-      0x6b, 0x80, 0x06, 0x00, 0x0e, 0x00, 0x68, 0x39, 
+-      0x80, 0x08, 0xe0, 0x2a, 0x68, 0x38, 0x88, 0x01, 
+-      0x04, 0x09, 0x88, 0x40, 0x18, 0x08, 0x68, 0x00, 
+-      0x90, 0x05, 0x14, 0x00, 0x68, 0x39, 0x80, 0x08, 
+-      0x98, 0x05, 0x68, 0x39, 0x80, 0x48, 0xe0, 0x1c, 
+-      0x48, 0x16, 0x68, 0x00, 0x68, 0x39, 0x80, 0x08, 
+-      0xe0, 0x17, 0x46, 0x69, 0xa8, 0x01, 0xf0, 0x08, 
+-      0xfb, 0xb9, 0x98, 0x01, 0x68, 0x39, 0x80, 0x08, 
+-      0x98, 0x01, 0x0c, 0x00, 0x68, 0x39, 0x80, 0x48, 
+-      0x98, 0x00, 0x68, 0x39, 0x80, 0x88, 0x98, 0x00, 
+-      0x0c, 0x00, 0x68, 0x39, 0x80, 0xc8, 0xe0, 0x04, 
+-      0x1d, 0xf8, 0x30, 0x39, 0x8e, 0x81, 0x31, 0x01, 
+-      0x86, 0x81, 0xb0, 0x06, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2c, 0x00, 0x00, 0xfc, 
+-      0x2e, 0x08, 0x46, 0x68, 0x2e, 0x08, 0x03, 0xc0, 
+-      0x2c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, 0x1a, 
+-      0x2e, 0x08, 0x05, 0x68, 0x2e, 0x08, 0x00, 0x58, 
+-      0xb5, 0xf0, 0x4f, 0x6e, 0x25, 0x00, 0x6f, 0xf8, 
+-      0x28, 0x00, 0xd0, 0x08, 0xf0, 0x06, 0xff, 0x4a, 
+-      0x28, 0x00, 0xd0, 0x00, 0x67, 0xfd, 0x20, 0x01, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x6c, 0x38, 
+-      0x28, 0x00, 0xd1, 0x03, 0x1c, 0x28, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x6d, 0x38, 0x6d, 0x7c, 
+-      0x42, 0xa0, 0xd1, 0x03, 0x1c, 0x28, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x88, 0xa0, 0x06, 0x00, 
+-      0x0e, 0x00, 0x28, 0x15, 0xd2, 0x56, 0xa3, 0x02, 
+-      0x5c, 0x1b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x0b, 0x12, 0x1c, 0x16, 0x22, 0x53, 0x26, 0x31, 
+-      0x3c, 0x47, 0x57, 0x61, 0x68, 0x6d, 0x71, 0x75, 
+-      0x7d, 0x84, 0x83, 0x83, 0x87, 0x00, 0x89, 0xe3, 
+-      0x89, 0xa2, 0x89, 0x61, 0x89, 0x20, 0xf0, 0x06, 
+-      0xfa, 0xc5, 0xe0, 0x70, 0x89, 0x20, 0xf0, 0x06, 
+-      0xfa, 0xa9, 0xe0, 0x6c, 0x89, 0xa2, 0x89, 0x61, 
+-      0x89, 0x20, 0xf0, 0x06, 0xfb, 0x83, 0xe0, 0x66, 
+-      0x89, 0xa2, 0x89, 0x61, 0x89, 0x20, 0xf0, 0x06, 
+-      0xfb, 0x2b, 0xe0, 0x60, 0x89, 0x20, 0xf0, 0x06, 
+-      0xfb, 0xc1, 0xe0, 0x5c, 0x8a, 0x62, 0x8a, 0x21, 
+-      0xb4, 0x06, 0x89, 0xe3, 0x89, 0xa2, 0x89, 0x61, 
+-      0x89, 0x20, 0xf0, 0x06, 0xfc, 0x45, 0xb0, 0x02, 
+-      0xe0, 0x51, 0x8a, 0x62, 0x8a, 0x21, 0xb4, 0x06, 
+-      0x89, 0xe3, 0x89, 0xa2, 0x89, 0x61, 0x89, 0x20, 
+-      0xf0, 0x06, 0xfc, 0x8c, 0xb0, 0x02, 0xe0, 0x46, 
+-      0x89, 0xa3, 0x89, 0x62, 0x89, 0x20, 0x49, 0x3c, 
+-      0xf0, 0x06, 0xfd, 0xcd, 0x21, 0x00, 0x48, 0x3a, 
+-      0xf7, 0xff, 0xfc, 0x58, 0xe0, 0x3b, 0x89, 0xe0, 
+-      0x04, 0x03, 0x14, 0x1b, 0x89, 0xa0, 0x04, 0x02, 
+-      0x14, 0x12, 0x89, 0x61, 0x89, 0x20, 0xf0, 0x06, 
+-      0xfd, 0xed, 0xe0, 0x30, 0xe0, 0x4c, 0x89, 0x20, 
+-      0xf0, 0x06, 0xfb, 0xa0, 0xe0, 0x2b, 0x89, 0xe0, 
+-      0x04, 0x00, 0x8a, 0x21, 0x18, 0x43, 0x89, 0xa2, 
+-      0x89, 0x61, 0x89, 0x20, 0xf0, 0x06, 0xfe, 0x40, 
+-      0xe0, 0x21, 0x89, 0xe3, 0x89, 0xa2, 0x89, 0x61, 
+-      0x89, 0x20, 0xf0, 0x06, 0xfe, 0x71, 0xe0, 0x1a, 
+-      0x89, 0x61, 0x89, 0x20, 0xf0, 0x06, 0xfb, 0xc2, 
+-      0xe0, 0x15, 0x89, 0x20, 0xf0, 0x06, 0xfb, 0xdc, 
+-      0xe0, 0x11, 0x89, 0x20, 0xf0, 0x06, 0xfb, 0xec, 
+-      0xe0, 0x0d, 0x20, 0x01, 0x67, 0xf8, 0x89, 0xa2, 
+-      0x89, 0x61, 0x89, 0x20, 0xf0, 0x06, 0xff, 0x04, 
+-      0xe0, 0x05, 0x89, 0xe3, 0x89, 0xa2, 0x89, 0x61, 
+-      0x89, 0x20, 0xf0, 0x06, 0xff, 0x67, 0xe0, 0x1b, 
+-      0xf0, 0x06, 0xff, 0xfe, 0xe0, 0x18, 0x89, 0x20, 
+-      0xb0, 0x82, 0x90, 0x01, 0x89, 0x61, 0x91, 0x00, 
+-      0x89, 0xa5, 0x89, 0xe0, 0x1b, 0x40, 0x24, 0x00, 
+-      0x1c, 0x46, 0x2e, 0x00, 0xdd, 0x0b, 0x00, 0xa0, 
+-      0x4b, 0x12, 0x18, 0xc0, 0x19, 0x2a, 0x68, 0x03, 
+-      0x98, 0x01, 0x99, 0x00, 0xf0, 0x06, 0xfe, 0x04, 
+-      0x34, 0x01, 0x42, 0xb4, 0xdb, 0xf3, 0xb0, 0x02, 
+-      0x6d, 0x78, 0x88, 0xc0, 0x6c, 0x39, 0x1a, 0x08, 
+-      0x64, 0x38, 0x6c, 0x79, 0x1a, 0x08, 0x28, 0x28, 
+-      0xdb, 0x05, 0x48, 0x09, 0x88, 0x01, 0x23, 0x10, 
+-      0x43, 0xdb, 0x40, 0x19, 0x80, 0x01, 0x6d, 0x78, 
+-      0x68, 0x00, 0x65, 0x78, 0x20, 0x01, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x03, 0xc0, 
+-      0x2c, 0x00, 0x01, 0x20, 0x2c, 0x00, 0x1a, 0x00, 
+-      0x2c, 0x00, 0x00, 0xf8, 0xb5, 0x90, 0x4f, 0x66, 
+-      0x6e, 0xf8, 0x6e, 0xb9, 0x42, 0x81, 0xd0, 0x57, 
+-      0x88, 0x81, 0x0a, 0x0a, 0x2a, 0x0a, 0xd2, 0x5a, 
+-      0xa3, 0x01, 0x5c, 0x9b, 0x00, 0x5b, 0x44, 0x9f, 
+-      0x93, 0x04, 0x50, 0x93, 0x93, 0x57, 0x93, 0x93, 
+-      0x7c, 0x82, 0x06, 0x09, 0x0e, 0x09, 0x24, 0x00, 
+-      0x29, 0x0c, 0xd2, 0x4c, 0xa3, 0x01, 0x5c, 0x5b, 
+-      0x00, 0x5b, 0x44, 0x9f, 0x1d, 0x09, 0x13, 0x3c, 
+-      0x85, 0x85, 0x85, 0x85, 0x85, 0x39, 0x85, 0x05, 
+-      0x89, 0x00, 0xf0, 0x03, 0xf8, 0xc1, 0xe0, 0x7b, 
+-      0x22, 0x00, 0xb4, 0x04, 0x89, 0x01, 0x1c, 0x23, 
+-      0x4a, 0x52, 0x1e, 0x50, 0xf7, 0xfc, 0xfd, 0x5c, 
+-      0xb0, 0x01, 0xe0, 0x71, 0x22, 0x00, 0xb4, 0x04, 
+-      0x89, 0x02, 0x1c, 0x23, 0x49, 0x4d, 0x1e, 0x48, 
+-      0xf7, 0xfc, 0xfd, 0x52, 0xb0, 0x01, 0xe0, 0x67, 
+-      0x8a, 0x02, 0xb4, 0x04, 0x89, 0xc3, 0x89, 0x82, 
+-      0x89, 0x41, 0x89, 0x00, 0xf7, 0xfc, 0xfd, 0x48, 
+-      0x6e, 0xf8, 0x89, 0x01, 0xb0, 0x01, 0x29, 0x00, 
+-      0xd1, 0x5a, 0x89, 0x41, 0x29, 0x00, 0xd1, 0x57, 
+-      0x89, 0x81, 0x29, 0x00, 0xd1, 0x54, 0x89, 0xc1, 
+-      0x29, 0x00, 0xd1, 0x51, 0x8a, 0x00, 0x28, 0x00, 
+-      0xd1, 0x4e, 0xf7, 0xfd, 0xfa, 0x85, 0xe0, 0x62, 
+-      0xf7, 0xfc, 0xfc, 0xc6, 0xe0, 0x5f, 0x21, 0x18, 
+-      0x20, 0x14, 0xf7, 0xfe, 0xfd, 0xaf, 0xe0, 0x5a, 
+-      0xe0, 0x6a, 0x06, 0x09, 0xd1, 0x40, 0x89, 0x00, 
+-      0xf7, 0xfc, 0xfe, 0x7c, 0xe0, 0x53, 0xe0, 0x52, 
+-      0x06, 0x09, 0x0e, 0x09, 0x29, 0x06, 0xd2, 0x4e, 
+-      0xa3, 0x01, 0x5c, 0x5b, 0x00, 0x5b, 0x44, 0x9f, 
+-      0x02, 0x06, 0x0a, 0x0e, 0x12, 0x16, 0x89, 0x00, 
+-      0xf7, 0xfe, 0xf8, 0x6a, 0xe0, 0x43, 0x89, 0x00, 
+-      0xf7, 0xfe, 0xf8, 0x8c, 0xe0, 0x3f, 0x89, 0x00, 
+-      0xf7, 0xfe, 0xf9, 0x1a, 0xe0, 0x3b, 0x89, 0x00, 
+-      0xf7, 0xfe, 0xf9, 0xfe, 0xe0, 0x37, 0x89, 0x00, 
+-      0xf7, 0xfe, 0xfa, 0x30, 0xe0, 0x33, 0x89, 0x00, 
+-      0x06, 0x00, 0x0e, 0x00, 0xf7, 0xfe, 0xfa, 0x0c, 
+-      0xe0, 0x2d, 0x06, 0x08, 0xd1, 0x14, 0x6f, 0xb8, 
+-      0x30, 0x01, 0x67, 0xb8, 0xe0, 0x27, 0x06, 0x09, 
+-      0x0e, 0x09, 0x29, 0x08, 0xd2, 0x23, 0xa3, 0x02, 
+-      0x5c, 0x5b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x04, 0x0d, 0x09, 0x10, 0x13, 0x17, 0x1a, 0x1d, 
+-      0x89, 0x00, 0xf0, 0x01, 0xf9, 0x7f, 0xe0, 0x16, 
+-      0xe0, 0x15, 0x89, 0x00, 0xf0, 0x01, 0xf9, 0xa6, 
+-      0xe0, 0x11, 0xf0, 0x01, 0xf9, 0xf1, 0xe0, 0x0e, 
+-      0xf0, 0x01, 0xfa, 0x48, 0xe0, 0x0b, 0x89, 0x00, 
+-      0xf0, 0x01, 0xfa, 0xcc, 0xe0, 0x07, 0xf0, 0x01, 
+-      0xfb, 0x05, 0xe0, 0x04, 0xf0, 0x01, 0xfb, 0x1e, 
+-      0xe0, 0x01, 0xf0, 0x01, 0xfa, 0x7b, 0x6e, 0xf8, 
+-      0x88, 0xc0, 0x6d, 0xb9, 0x1a, 0x08, 0x65, 0xb8, 
+-      0x6d, 0xf9, 0x1a, 0x08, 0x28, 0x28, 0xdb, 0x04, 
+-      0x48, 0x07, 0x88, 0x01, 0x08, 0x49, 0x00, 0x49, 
+-      0x80, 0x01, 0x6e, 0xf8, 0x68, 0x00, 0x66, 0xf8, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x03, 0xc0, 0x00, 0x00, 0xff, 0xff, 
+-      0x2c, 0x00, 0x00, 0xf8, 0xb5, 0x80, 0x06, 0x00, 
+-      0x0e, 0x00, 0x1c, 0x17, 0x28, 0x03, 0xd0, 0x0b, 
+-      0x28, 0x07, 0xd0, 0x0e, 0x28, 0x08, 0xd1, 0x03, 
+-      0x88, 0x38, 0xf0, 0x02, 0xfa, 0x39, 0x80, 0x78, 
+-      0x20, 0x00, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x21, 0x18, 0x20, 0x14, 0xf7, 0xfe, 0xfd, 0x22, 
+-      0xe7, 0xf6, 0x88, 0x79, 0x88, 0x38, 0x1d, 0x3a, 
+-      0xf0, 0x02, 0xf8, 0xaa, 0x49, 0x01, 0x68, 0x09, 
+-      0x80, 0x08, 0xe7, 0xed, 0x2e, 0x08, 0x03, 0xc0, 
+-      0x48, 0x0d, 0x6f, 0xc0, 0x28, 0x00, 0xd1, 0x0c, 
+-      0x49, 0x0c, 0x60, 0x08, 0x48, 0x0c, 0x8e, 0x83, 
+-      0x49, 0x0c, 0x22, 0x01, 0x2b, 0x00, 0xd0, 0x05, 
+-      0x8d, 0x03, 0x86, 0x8b, 0x8d, 0x43, 0x86, 0xcb, 
+-      0x87, 0x82, 0x47, 0x70, 0x8e, 0xc3, 0x2b, 0x00, 
+-      0xd0, 0xfb, 0x8d, 0x83, 0x86, 0x8b, 0x8d, 0xc3, 
+-      0x86, 0xcb, 0x87, 0x82, 0x47, 0x70, 0x00, 0x00, 
+-      0x2c, 0x00, 0x1f, 0x80, 0x2e, 0x08, 0x04, 0x40, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x2c, 0x00, 0x00, 0xc0, 
+-      0xb5, 0x00, 0xf0, 0x00, 0xfa, 0x71, 0xf7, 0xfd, 
+-      0xf8, 0x37, 0xf7, 0xfc, 0xfe, 0xdd, 0xf7, 0xfd, 
+-      0xf9, 0x37, 0xf0, 0x03, 0xf8, 0x71, 0xf7, 0xff, 
+-      0xff, 0xcf, 0x48, 0x09, 0x8e, 0x80, 0x28, 0x00, 
+-      0xd1, 0x0b, 0x48, 0x08, 0x6f, 0xc0, 0x28, 0x00, 
+-      0xd1, 0x01, 0xf0, 0x03, 0xfd, 0xe3, 0xf7, 0xff, 
+-      0xfd, 0xe7, 0x28, 0x00, 0xd1, 0x01, 0xf7, 0xff, 
+-      0xfe, 0xc9, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x2c, 0x00, 0x1f, 0x80, 
+-      0xb4, 0x80, 0x02, 0x4f, 0x4b, 0x07, 0x40, 0x3b, 
+-      0x43, 0x1a, 0x23, 0x19, 0x06, 0x9b, 0x62, 0x9a, 
+-      0x0a, 0x49, 0x02, 0x49, 0x08, 0x49, 0x07, 0xc0, 
+-      0x43, 0x08, 0x49, 0x03, 0x68, 0x09, 0x60, 0x08, 
+-      0xbc, 0x80, 0x47, 0x70, 0x00, 0x03, 0xfe, 0x00, 
+-      0x2e, 0x08, 0x5e, 0x38, 0xb4, 0x90, 0x4b, 0x0c, 
+-      0x68, 0x1f, 0x68, 0x3f, 0x0f, 0xff, 0x60, 0x07, 
+-      0x68, 0x18, 0x68, 0x00, 0x00, 0x40, 0x0a, 0x47, 
+-      0x02, 0x7f, 0x20, 0x19, 0x06, 0x80, 0x6a, 0x84, 
+-      0x4b, 0x06, 0x40, 0x23, 0x0a, 0x5b, 0x43, 0x3b, 
+-      0x60, 0x0b, 0x6a, 0x80, 0x05, 0xc0, 0x0d, 0xc0, 
+-      0x60, 0x10, 0xbc, 0x90, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x5e, 0x38, 0x00, 0x03, 0xfe, 0x00, 
+-      0xb5, 0x00, 0x49, 0x1d, 0x62, 0xc8, 0x28, 0x00, 
+-      0xd0, 0x11, 0x28, 0x01, 0xd0, 0x1b, 0x28, 0x02, 
+-      0xd0, 0x25, 0x28, 0x03, 0xd1, 0x09, 0x48, 0x19, 
+-      0x68, 0x01, 0x08, 0x49, 0x00, 0x49, 0x60, 0x01, 
+-      0x22, 0x01, 0x21, 0x01, 0x20, 0x00, 0xf0, 0x0b, 
+-      0xf9, 0x8f, 0xbc, 0x08, 0x47, 0x18, 0x48, 0x13, 
+-      0x68, 0x01, 0x08, 0x49, 0x00, 0x49, 0x60, 0x01, 
+-      0x48, 0x11, 0x68, 0x01, 0x04, 0x03, 0x43, 0x19, 
+-      0x60, 0x01, 0xbc, 0x08, 0x47, 0x18, 0x48, 0x0d, 
+-      0x68, 0x01, 0x23, 0x01, 0x43, 0x19, 0x60, 0x01, 
+-      0x48, 0x0b, 0x68, 0x01, 0x4b, 0x0b, 0x40, 0x19, 
+-      0x60, 0x01, 0xbc, 0x08, 0x47, 0x18, 0x48, 0x07, 
+-      0x68, 0x01, 0x08, 0x49, 0x00, 0x49, 0x60, 0x01, 
+-      0x22, 0x00, 0x21, 0x00, 0x20, 0x00, 0xf0, 0x0b, 
+-      0xf9, 0x6b, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x04, 0xc4, 0x6a, 0x00, 0x00, 0x18, 
+-      0x6c, 0x00, 0x00, 0x20, 0xff, 0xdf, 0xff, 0xff, 
+-      0xb5, 0x90, 0x48, 0x11, 0x6c, 0xc1, 0x6c, 0x80, 
+-      0x1a, 0x0f, 0x48, 0x10, 0xd5, 0x01, 0x69, 0x01, 
+-      0x18, 0x7f, 0x69, 0x00, 0x10, 0x80, 0x4c, 0x0e, 
+-      0x42, 0xb8, 0xda, 0x0b, 0x68, 0xe0, 0x28, 0x00, 
+-      0xd1, 0x08, 0x48, 0x0c, 0x68, 0x01, 0x23, 0x02, 
+-      0x43, 0xdb, 0x40, 0x19, 0x60, 0x01, 0x20, 0x02, 
+-      0xf0, 0x0a, 0xfd, 0x0c, 0x2f, 0x00, 0xd1, 0x04, 
+-      0x20, 0x01, 0x61, 0xe0, 0x6b, 0xa0, 0x30, 0x01, 
+-      0x63, 0xa0, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x66, 0x00, 0x00, 0x80, 0x2e, 0x08, 0x04, 0x44, 
+-      0x2e, 0x08, 0x04, 0xc4, 0x6c, 0x00, 0x00, 0x20, 
+-      0xb5, 0x00, 0x20, 0x03, 0xf0, 0x0a, 0xfc, 0xf6, 
+-      0x20, 0x1e, 0xf0, 0x07, 0xfc, 0xf3, 0x23, 0x03, 
+-      0x02, 0x5b, 0x22, 0x01, 0x02, 0xd2, 0x21, 0x02, 
+-      0x20, 0x1e, 0xf0, 0x07, 0xfa, 0xa1, 0x22, 0x00, 
+-      0xb4, 0x04, 0x23, 0x02, 0x22, 0x02, 0x49, 0x07, 
+-      0x20, 0x1e, 0xf0, 0x07, 0xf8, 0xd5, 0x23, 0x01, 
+-      0x02, 0x9b, 0x00, 0x5a, 0x21, 0x01, 0x20, 0x1e, 
+-      0xb0, 0x01, 0xf0, 0x07, 0xfa, 0x91, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 
+-      0xb5, 0x00, 0x21, 0x00, 0x20, 0x0e, 0xf0, 0x0d, 
+-      0xf8, 0x6b, 0x20, 0x1f, 0xf0, 0x07, 0xfc, 0x04, 
+-      0x23, 0x03, 0x02, 0x5b, 0x22, 0x01, 0x02, 0xd2, 
+-      0x21, 0x02, 0x20, 0x1f, 0xf0, 0x07, 0xfa, 0x7c, 
+-      0x20, 0x00, 0xf0, 0x0a, 0xfb, 0x61, 0x22, 0x00, 
+-      0xb4, 0x04, 0x23, 0x01, 0x22, 0x02, 0x49, 0x07, 
+-      0x20, 0x1f, 0xf0, 0x07, 0xf8, 0xad, 0x23, 0x01, 
+-      0x02, 0x9b, 0x00, 0x5a, 0x21, 0x01, 0x20, 0x1f, 
+-      0xb0, 0x01, 0xf0, 0x07, 0xfa, 0x69, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 
+-      0xb5, 0x80, 0x20, 0x0f, 0x02, 0x40, 0x4f, 0x0a, 
+-      0x61, 0x38, 0x49, 0x0a, 0x6c, 0x89, 0x61, 0x79, 
+-      0xf0, 0x01, 0xfe, 0x3c, 0x1d, 0xf9, 0x31, 0x79, 
+-      0x61, 0x08, 0x28, 0x00, 0xd0, 0x05, 0x20, 0x00, 
+-      0x61, 0xf8, 0x62, 0x38, 0x64, 0xf8, 0x20, 0xff, 
+-      0x72, 0x08, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x04, 0x44, 0x66, 0x00, 0x00, 0x80, 
+-      0xb5, 0x80, 0x4f, 0x05, 0x69, 0x38, 0x28, 0x00, 
+-      0xd0, 0x03, 0xf0, 0x01, 0xfe, 0x45, 0x20, 0x00, 
+-      0x61, 0x38, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x04, 0xc4, 0xb5, 0x00, 0x4a, 0x0d, 
+-      0xb4, 0x04, 0x1f, 0x10, 0x1e, 0x51, 0x1c, 0x13, 
+-      0xf7, 0xfc, 0xfb, 0x2a, 0x21, 0x33, 0x06, 0x49, 
+-      0x6d, 0x88, 0x6d, 0x4a, 0x1a, 0x82, 0xb0, 0x01, 
+-      0x48, 0x07, 0x62, 0x42, 0x6d, 0x49, 0x62, 0xc1, 
+-      0x21, 0x00, 0x65, 0x81, 0x21, 0x01, 0x02, 0xc9, 
+-      0x64, 0x41, 0x21, 0x01, 0x30, 0x60, 0x76, 0x01, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x04, 0x44, 0xb5, 0x00, 0x4a, 0x10, 
+-      0xb4, 0x04, 0x1c, 0x13, 0x3a, 0x01, 0x49, 0x0f, 
+-      0x1e, 0xc8, 0xf7, 0xfc, 0xfb, 0x09, 0x21, 0x33, 
+-      0x06, 0x49, 0x6d, 0x88, 0x6d, 0x4a, 0x1a, 0x82, 
+-      0xb0, 0x01, 0x48, 0x0b, 0x62, 0x42, 0x6d, 0x49, 
+-      0x62, 0xc1, 0x21, 0x00, 0x65, 0x81, 0x21, 0x01, 
+-      0x02, 0xc9, 0x64, 0x41, 0x21, 0x01, 0x30, 0x60, 
+-      0x76, 0x01, 0x48, 0x06, 0x23, 0x02, 0x68, 0x01, 
+-      0x43, 0x19, 0x60, 0x01, 0xbc, 0x08, 0x47, 0x18, 
+-      0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xfe, 
+-      0x2e, 0x08, 0x04, 0x44, 0x2e, 0x08, 0x00, 0x04, 
+-      0x48, 0x03, 0x23, 0x02, 0x43, 0xdb, 0x68, 0x01, 
+-      0x40, 0x19, 0x60, 0x01, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x00, 0x04, 0xb5, 0xf0, 0x20, 0x0f, 
+-      0x02, 0x40, 0x4c, 0x11, 0x61, 0x20, 0x20, 0x00, 
+-      0xf7, 0xfc, 0xfc, 0x1c, 0x48, 0x0f, 0xf7, 0xfc, 
+-      0xfc, 0x19, 0x26, 0x00, 0x1d, 0xe0, 0x30, 0x59, 
+-      0x77, 0x06, 0x25, 0xff, 0x1d, 0xe7, 0x37, 0x79, 
+-      0x70, 0x3d, 0x20, 0x01, 0x63, 0x78, 0x60, 0xe6, 
+-      0x69, 0x78, 0x28, 0x00, 0xd1, 0x04, 0x20, 0x41, 
+-      0x01, 0x40, 0xf0, 0x01, 0xfd, 0xab, 0x61, 0x78, 
+-      0x69, 0x78, 0x28, 0x00, 0xd0, 0x01, 0x76, 0x3e, 
+-      0x70, 0x3d, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x04, 0x44, 0x00, 0x00, 0x1f, 0xff, 
+-      0xb5, 0x00, 0x20, 0x00, 0xf7, 0xfd, 0xff, 0xbc, 
+-      0x22, 0x00, 0xb4, 0x04, 0x23, 0x00, 0x4a, 0x06, 
+-      0x21, 0x00, 0x20, 0x00, 0xf7, 0xfc, 0xfa, 0xa8, 
+-      0x21, 0x00, 0x20, 0x0d, 0xb0, 0x01, 0xf0, 0x0c, 
+-      0xff, 0x8f, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x00, 0x00, 0xff, 0xff, 0xb5, 0x80, 0x22, 0x00, 
+-      0xb4, 0x04, 0x27, 0x00, 0x1c, 0x3b, 0x4a, 0x17, 
+-      0x21, 0x00, 0x20, 0x00, 0xf7, 0xfc, 0xfa, 0x94, 
+-      0x22, 0x00, 0xb0, 0x01, 0xb4, 0x04, 0x1c, 0x3b, 
+-      0x4a, 0x12, 0x49, 0x13, 0x20, 0x00, 0xf7, 0xfc, 
+-      0xfa, 0x8b, 0x21, 0x33, 0x06, 0x49, 0x6d, 0x88, 
+-      0x6d, 0x4a, 0x1a, 0x82, 0xb0, 0x01, 0x48, 0x0f, 
+-      0x62, 0x42, 0x6d, 0x49, 0x63, 0x01, 0x21, 0x01, 
+-      0x02, 0xc9, 0x64, 0x81, 0x21, 0x01, 0x65, 0x87, 
+-      0x30, 0x60, 0x76, 0x01, 0x77, 0x07, 0x22, 0x00, 
+-      0x21, 0x00, 0x20, 0x00, 0xf7, 0xff, 0xfe, 0x28, 
+-      0x20, 0x00, 0xf7, 0xff, 0xfe, 0x59, 0x21, 0x00, 
+-      0x20, 0x0d, 0xf0, 0x0c, 0xff, 0x59, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 0xff, 0xff, 
+-      0x00, 0x00, 0x1f, 0xfe, 0x2e, 0x08, 0x04, 0x44, 
+-      0xb5, 0xf0, 0x06, 0x05, 0x0e, 0x2d, 0x20, 0x0f, 
+-      0x02, 0x40, 0x4f, 0x2f, 0x26, 0x33, 0x06, 0x76, 
+-      0x61, 0x38, 0x6d, 0xb0, 0x6d, 0x71, 0x1a, 0x40, 
+-      0x62, 0x78, 0x62, 0xb8, 0x20, 0x00, 0x1d, 0xfc, 
+-      0x34, 0x79, 0x60, 0xe0, 0x2d, 0x00, 0xd0, 0x02, 
+-      0x20, 0xff, 0xf7, 0xfd, 0xff, 0x59, 0x22, 0x00, 
+-      0xb4, 0x04, 0x23, 0x00, 0x21, 0x00, 0x20, 0x00, 
+-      0xf7, 0xfc, 0xfa, 0x46, 0x22, 0x01, 0x21, 0x01, 
+-      0x20, 0x00, 0xb0, 0x01, 0xf0, 0x0a, 0xff, 0xcc, 
+-      0x21, 0x00, 0x20, 0x00, 0xf0, 0x0b, 0xf8, 0x8c, 
+-      0x22, 0x00, 0xb4, 0x04, 0x23, 0x00, 0x4a, 0x1d, 
+-      0x20, 0x00, 0x1e, 0x51, 0xf7, 0xfc, 0xfa, 0x34, 
+-      0x20, 0x01, 0x63, 0x60, 0x69, 0x60, 0xb0, 0x01, 
+-      0x28, 0x00, 0xd1, 0x04, 0x20, 0x41, 0x01, 0x40, 
+-      0xf0, 0x01, 0xfd, 0x14, 0x61, 0x60, 0x69, 0x60, 
+-      0x28, 0x00, 0xd0, 0x03, 0x20, 0x00, 0x76, 0x20, 
+-      0x20, 0xff, 0x70, 0x20, 0x6d, 0x70, 0x63, 0x38, 
+-      0x20, 0x01, 0x02, 0xc0, 0x64, 0xb8, 0x20, 0x00, 
+-      0x26, 0x01, 0x65, 0xb8, 0x1d, 0xf9, 0x31, 0x59, 
+-      0x76, 0x0e, 0x22, 0x00, 0x21, 0x00, 0x20, 0x00, 
+-      0xf7, 0xff, 0xfd, 0xc6, 0x21, 0x00, 0x20, 0x0d, 
+-      0xf0, 0x0c, 0xfe, 0xfa, 0x20, 0x00, 0x60, 0xf8, 
+-      0x2d, 0x00, 0xd1, 0x02, 0xf7, 0xff, 0xfd, 0xf0, 
+-      0x61, 0xe6, 0x20, 0x00, 0x60, 0xb8, 0x66, 0x38, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x04, 0x44, 0x00, 0x00, 0x1f, 0xff, 
+-      0xb5, 0xb0, 0x4f, 0x45, 0x25, 0x00, 0x6d, 0x38, 
+-      0x4c, 0x44, 0x28, 0x05, 0xd2, 0x14, 0xa3, 0x02, 
+-      0x5c, 0x1b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x10, 0x03, 0x2e, 0x65, 0x73, 0x00, 0x4d, 0x40, 
+-      0x68, 0x28, 0x08, 0x41, 0xd2, 0x08, 0x08, 0xc0, 
+-      0xd3, 0x09, 0xf7, 0xff, 0xfe, 0xb3, 0x23, 0x04, 
+-      0x43, 0xdb, 0x68, 0x28, 0x40, 0x18, 0x60, 0x28, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x6d, 0x78, 
+-      0x28, 0x00, 0xd0, 0xf9, 0x28, 0x01, 0xd0, 0x01, 
+-      0x28, 0x05, 0xd1, 0x06, 0xf0, 0x00, 0xf8, 0x6c, 
+-      0x8e, 0xa0, 0x28, 0x00, 0xd1, 0xf0, 0xf0, 0x00, 
+-      0xf9, 0x29, 0x6d, 0x78, 0x28, 0x04, 0xd0, 0x01, 
+-      0x28, 0x05, 0xd1, 0xe9, 0x8e, 0xa0, 0x28, 0x00, 
+-      0xd1, 0xe6, 0xf0, 0x00, 0xfa, 0x4b, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x8e, 0xe0, 0x28, 0x00, 
+-      0xd1, 0xde, 0x8d, 0xa0, 0x06, 0x00, 0x0e, 0x00, 
+-      0x28, 0x06, 0xd1, 0x15, 0x48, 0x27, 0x78, 0x00, 
+-      0x28, 0x00, 0xd0, 0x06, 0x6d, 0x78, 0x28, 0x01, 
+-      0xd0, 0x01, 0x28, 0x05, 0xd1, 0x01, 0xf0, 0x00, 
+-      0xfc, 0xcd, 0x6d, 0x78, 0x28, 0x04, 0xd0, 0x01, 
+-      0x28, 0x05, 0xd1, 0x01, 0xf0, 0x00, 0xfc, 0x2e, 
+-      0x85, 0xa5, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x8d, 0xa0, 0x28, 0x00, 0xd1, 0xc0, 0x6d, 0x78, 
+-      0x28, 0x01, 0xd0, 0x08, 0x28, 0x04, 0xd0, 0x0b, 
+-      0x28, 0x05, 0xd1, 0xb9, 0xf0, 0x00, 0xfd, 0xe4, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0xf0, 0x00, 
+-      0xfd, 0xb9, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xf0, 0x00, 0xfd, 0x88, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x8e, 0xe0, 0x28, 0x00, 0xd1, 0xa7, 
+-      0x20, 0x06, 0x85, 0xa0, 0x85, 0xe5, 0x20, 0x09, 
+-      0x02, 0x40, 0x86, 0xe0, 0x20, 0x04, 0x65, 0x38, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x8e, 0xe0, 
+-      0x28, 0x00, 0xd1, 0x99, 0x8d, 0xa0, 0x06, 0x00, 
+-      0x0e, 0x00, 0x28, 0x06, 0xd1, 0x94, 0x85, 0xa5, 
+-      0x65, 0x3d, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x04, 0x44, 0x2c, 0x00, 0x1f, 0xc0, 
+-      0x2e, 0x08, 0x00, 0x04, 0x2e, 0x08, 0x04, 0xc4, 
+-      0xb5, 0xb0, 0x48, 0x46, 0x6c, 0xc1, 0x4c, 0x46, 
+-      0x64, 0x21, 0x69, 0x60, 0x1a, 0x09, 0x1d, 0xe7, 
+-      0x37, 0x79, 0x63, 0xf9, 0x29, 0x00, 0xda, 0x02, 
+-      0x69, 0x22, 0x18, 0x89, 0x63, 0xf9, 0x23, 0xff, 
+-      0x6b, 0xf9, 0x33, 0x01, 0x42, 0x99, 0xdb, 0x73, 
+-      0x22, 0x01, 0x03, 0x12, 0x42, 0x91, 0xdd, 0x00, 
+-      0x63, 0xfa, 0x6b, 0xf9, 0x08, 0x89, 0x00, 0x89, 
+-      0x63, 0xf9, 0x7a, 0x3a, 0x2a, 0x00, 0xd0, 0x05, 
+-      0x23, 0xff, 0x03, 0x5b, 0x1a, 0xc2, 0x61, 0xe2, 
+-      0x22, 0x00, 0x72, 0x3a, 0x18, 0x42, 0x49, 0x35, 
+-      0x25, 0x12, 0x42, 0x8a, 0xdd, 0x2c, 0x1a, 0x08, 
+-      0x64, 0x38, 0xf0, 0x18, 0xfb, 0x5f, 0x4b, 0x32, 
+-      0x40, 0x18, 0xf0, 0x18, 0xfb, 0x5f, 0x22, 0x00, 
+-      0x49, 0x30, 0xb4, 0x06, 0x69, 0x60, 0x69, 0x39, 
+-      0x18, 0x41, 0x23, 0xff, 0x03, 0x5b, 0x1a, 0xc9, 
+-      0x23, 0x0d, 0x06, 0x9b, 0x1a, 0xc0, 0x6c, 0x3a, 
+-      0x1c, 0x2b, 0xf0, 0x0f, 0xf8, 0x67, 0x22, 0x00, 
+-      0xb0, 0x02, 0x49, 0x28, 0xb4, 0x06, 0x6b, 0xf8, 
+-      0x6c, 0x39, 0x1a, 0x42, 0x69, 0x39, 0x1c, 0x2b, 
+-      0x48, 0x25, 0xf0, 0x0f, 0xf8, 0x5b, 0xb0, 0x02, 
+-      0xf0, 0x18, 0xfb, 0x3c, 0x23, 0x01, 0x04, 0x9b, 
+-      0x43, 0x18, 0xf0, 0x18, 0xfb, 0x3b, 0xe0, 0x1d, 
+-      0xf0, 0x18, 0xfb, 0x34, 0x4b, 0x1c, 0x40, 0x18, 
+-      0xf0, 0x18, 0xfb, 0x34, 0x22, 0x00, 0x49, 0x1b, 
+-      0xb4, 0x06, 0x69, 0x60, 0x69, 0x39, 0x18, 0x41, 
+-      0x23, 0xff, 0x03, 0x5b, 0x1a, 0xc9, 0x23, 0x0d, 
+-      0x06, 0x9b, 0x1a, 0xc0, 0x6b, 0xfa, 0x1c, 0x2b, 
+-      0xf0, 0x0f, 0xf8, 0x3c, 0xb0, 0x02, 0xf0, 0x18, 
+-      0xfb, 0x1d, 0x23, 0x01, 0x04, 0x9b, 0x43, 0x18, 
+-      0xf0, 0x18, 0xfb, 0x1c, 0x69, 0x60, 0x6b, 0xf9, 
+-      0x18, 0x40, 0x23, 0x0d, 0x06, 0x9b, 0x1a, 0xc1, 
+-      0x61, 0x60, 0x4b, 0x0e, 0x42, 0x99, 0xd3, 0x02, 
+-      0x69, 0x21, 0x1a, 0x40, 0x61, 0x60, 0x23, 0xff, 
+-      0x03, 0x5b, 0x69, 0x60, 0x1a, 0xc0, 0xe0, 0x00, 
+-      0xe0, 0x00, 0x62, 0x20, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x66, 0x00, 0x00, 0x80, 
+-      0x2e, 0x08, 0x04, 0x44, 0x00, 0x1f, 0xfe, 0x00, 
+-      0xff, 0xfb, 0xff, 0xff, 0x9e, 0x00, 0x08, 0x00, 
+-      0xcc, 0x1f, 0xe0, 0x00, 0xcc, 0x1f, 0xfe, 0x00, 
+-      0x21, 0x00, 0x23, 0xff, 0x68, 0x02, 0x33, 0xc1, 
+-      0x42, 0x9a, 0xd0, 0x01, 0x1c, 0x08, 0x47, 0x70, 
+-      0x79, 0xc2, 0x0a, 0x12, 0xd2, 0x01, 0x1c, 0x08, 
+-      0x47, 0x70, 0x7a, 0x41, 0x23, 0x0e, 0x40, 0x19, 
+-      0x07, 0x49, 0x7a, 0x82, 0x05, 0x92, 0x43, 0x11, 
+-      0x7a, 0xc2, 0x23, 0xfe, 0x40, 0x1a, 0x03, 0x92, 
+-      0x43, 0x11, 0x7b, 0x02, 0x01, 0xd2, 0x43, 0x11, 
+-      0x7b, 0x40, 0x40, 0x18, 0x08, 0x40, 0x43, 0x08, 
+-      0x49, 0x01, 0x67, 0x08, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x04, 0x44, 0xb5, 0xf0, 0xb0, 0x86, 
+-      0x4c, 0x8c, 0x6c, 0xe0, 0x1d, 0xe7, 0x37, 0x79, 
+-      0x1d, 0xfd, 0x35, 0x39, 0x28, 0x00, 0xd0, 0x04, 
+-      0x28, 0x01, 0xd0, 0x3a, 0x28, 0x02, 0xd1, 0x73, 
+-      0xe0, 0x74, 0x69, 0xe0, 0x6a, 0x21, 0x1a, 0x09, 
+-      0x63, 0xf9, 0x1c, 0x0a, 0xd5, 0x02, 0x69, 0x21, 
+-      0x18, 0x51, 0x63, 0xf9, 0x6b, 0xf9, 0x29, 0x04, 
+-      0xdb, 0x67, 0x69, 0x3e, 0x5c, 0x31, 0x06, 0x0a, 
+-      0x65, 0x7a, 0x92, 0x05, 0x1c, 0x41, 0x69, 0x20, 
+-      0x90, 0x04, 0xf0, 0x14, 0xfb, 0x29, 0x61, 0xe1, 
+-      0x5c, 0x70, 0x04, 0x00, 0x9a, 0x05, 0x18, 0x82, 
+-      0x65, 0x7a, 0x92, 0x03, 0x98, 0x04, 0x31, 0x01, 
+-      0xf0, 0x14, 0xfb, 0x1e, 0x61, 0xe1, 0x5c, 0x70, 
+-      0x02, 0x00, 0x9a, 0x03, 0x18, 0x80, 0x65, 0x78, 
+-      0x90, 0x02, 0x98, 0x04, 0x31, 0x01, 0xf0, 0x14, 
+-      0xfb, 0x13, 0x61, 0xe1, 0x5c, 0x70, 0x9a, 0x02, 
+-      0x18, 0x80, 0x65, 0x78, 0x98, 0x04, 0x31, 0x01, 
+-      0xf0, 0x14, 0xfb, 0x0a, 0x20, 0x01, 0x64, 0xe0, 
+-      0x61, 0xe1, 0x6a, 0x20, 0x69, 0xe1, 0x1a, 0x40, 
+-      0x63, 0xf8, 0x1c, 0x01, 0xd4, 0x05, 0x48, 0x67, 
+-      0x69, 0x06, 0x30, 0x80, 0x69, 0x02, 0x92, 0x01, 
+-      0xe0, 0x03, 0x69, 0x20, 0x18, 0x08, 0x63, 0xf8, 
+-      0xe7, 0xf5, 0x6b, 0xf8, 0x90, 0x00, 0x28, 0x02, 
+-      0xdb, 0x22, 0x6d, 0x78, 0x09, 0x01, 0x01, 0x09, 
+-      0x23, 0xff, 0x33, 0xc1, 0x42, 0x99, 0xd1, 0x31, 
+-      0x9a, 0x01, 0x69, 0xe0, 0x5c, 0x11, 0x02, 0x09, 
+-      0x83, 0x29, 0x1c, 0x41, 0x1c, 0x30, 0xf0, 0x14, 
+-      0xfa, 0xe3, 0x61, 0xe1, 0x69, 0x38, 0x5c, 0x40, 
+-      0x8b, 0x2a, 0x18, 0x80, 0x83, 0x28, 0x8b, 0x28, 
+-      0x30, 0x06, 0x83, 0x28, 0x19, 0x88, 0x1f, 0x41, 
+-      0x1c, 0x30, 0xf0, 0x14, 0xfa, 0xd5, 0x61, 0xe1, 
+-      0x21, 0xff, 0x71, 0x39, 0x20, 0x02, 0x64, 0xe0, 
+-      0x6c, 0xe0, 0x28, 0x02, 0xd1, 0x00, 0xe0, 0x01, 
+-      0xe0, 0x94, 0xe0, 0x93, 0x6a, 0x20, 0x69, 0xe1, 
+-      0x1a, 0x40, 0x63, 0xf8, 0x1c, 0x01, 0xd5, 0x02, 
+-      0x69, 0x20, 0x18, 0x08, 0x63, 0xf8, 0x79, 0x38, 
+-      0x28, 0x00, 0xd0, 0x13, 0x20, 0x01, 0x02, 0xc0, 
+-      0x83, 0xa8, 0xe0, 0x11, 0x02, 0x01, 0x65, 0x79, 
+-      0x9a, 0x01, 0x69, 0xe0, 0x5c, 0x12, 0x18, 0x51, 
+-      0x65, 0x79, 0x1c, 0x41, 0x1c, 0x30, 0xf0, 0x14, 
+-      0xfa, 0xaf, 0x61, 0xe1, 0x98, 0x00, 0x38, 0x01, 
+-      0x63, 0xf8, 0xe7, 0xb2, 0x48, 0x3c, 0x83, 0xa8, 
+-      0x8b, 0x28, 0x6b, 0xf9, 0x42, 0x88, 0xda, 0x01, 
+-      0x63, 0xf8, 0xe0, 0x02, 0x8b, 0xa8, 0x42, 0x81, 
+-      0xdb, 0x68, 0x8b, 0xa8, 0x6b, 0xf9, 0x42, 0x81, 
+-      0xdd, 0x00, 0x63, 0xf8, 0x48, 0x35, 0x21, 0x00, 
+-      0x66, 0x78, 0x80, 0x01, 0x30, 0x02, 0x21, 0xff, 
+-      0x31, 0xc1, 0x66, 0x78, 0x80, 0x01, 0x48, 0x32, 
+-      0x66, 0x78, 0x79, 0x39, 0x29, 0x00, 0xd0, 0x21, 
+-      0x21, 0x00, 0x71, 0x39, 0x69, 0x3b, 0x69, 0x20, 
+-      0x18, 0x1a, 0xb4, 0x04, 0x69, 0xe0, 0x18, 0x18, 
+-      0x6b, 0xfa, 0x49, 0x2a, 0xf0, 0x00, 0xfe, 0xf4, 
+-      0x6b, 0xf8, 0x38, 0x06, 0x6e, 0x79, 0x80, 0x08, 
+-      0x31, 0x02, 0x66, 0x79, 0xb0, 0x01, 0x48, 0x25, 
+-      0xf7, 0xff, 0xff, 0x02, 0x8b, 0x28, 0x6b, 0xf9, 
+-      0x1a, 0x40, 0x83, 0x28, 0x69, 0xe0, 0x6b, 0xf9, 
+-      0x18, 0x41, 0x69, 0x20, 0xf0, 0x14, 0xfa, 0x6c, 
+-      0x61, 0xe1, 0xe0, 0x26, 0x6b, 0xf9, 0x31, 0x03, 
+-      0x80, 0x01, 0x48, 0x1e, 0x21, 0x01, 0x03, 0xc9, 
+-      0x66, 0x78, 0x80, 0x01, 0x30, 0x02, 0x21, 0xff, 
+-      0x66, 0x78, 0x80, 0x01, 0x48, 0x1a, 0x66, 0x78, 
+-      0x69, 0x3b, 0x69, 0x20, 0x18, 0x1a, 0xb4, 0x04, 
+-      0x69, 0xe0, 0x18, 0x18, 0x6b, 0xfa, 0x49, 0x17, 
+-      0xf0, 0x00, 0xfe, 0xc6, 0x8b, 0x28, 0x6b, 0xf9, 
+-      0x1a, 0x40, 0x83, 0x28, 0x69, 0xe0, 0x6b, 0xfe, 
+-      0x19, 0x81, 0x69, 0x20, 0xb0, 0x01, 0xf0, 0x14, 
+-      0xfa, 0x47, 0x1d, 0xf0, 0x30, 0x02, 0x61, 0xe1, 
+-      0x63, 0xf8, 0x8b, 0x28, 0x28, 0x00, 0xd1, 0x01, 
+-      0x21, 0x00, 0x64, 0xe0, 0x21, 0x10, 0x48, 0x0c, 
+-      0x85, 0x01, 0x6b, 0xf9, 0x85, 0x41, 0x21, 0x01, 
+-      0x02, 0x49, 0x86, 0x81, 0xb0, 0x06, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x04, 0x44, 
+-      0x00, 0x00, 0x07, 0xf7, 0x2c, 0x00, 0x02, 0x00, 
+-      0x2c, 0x00, 0x02, 0x04, 0x2c, 0x00, 0x02, 0x06, 
+-      0x2c, 0x00, 0x02, 0x0a, 0x2c, 0x00, 0x02, 0x09, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0xb5, 0xf0, 0x20, 0x33, 
+-      0x06, 0x40, 0x6e, 0x40, 0xb0, 0x81, 0x4f, 0x77, 
+-      0x63, 0xb8, 0x6a, 0xf9, 0x1a, 0x40, 0x1d, 0xfc, 
+-      0x34, 0x79, 0x63, 0xe0, 0x28, 0x00, 0xda, 0x02, 
+-      0x6a, 0x79, 0x18, 0x40, 0x63, 0xe0, 0x6b, 0xe0, 
+-      0x4b, 0x71, 0x42, 0x98, 0xdc, 0x03, 0xb0, 0x01, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x6d, 0xb9, 
+-      0x48, 0x6e, 0x1d, 0xc5, 0x35, 0x59, 0x29, 0x00, 
+-      0xd1, 0x16, 0x7e, 0x01, 0x29, 0x00, 0xd1, 0x13, 
+-      0x21, 0x01, 0x75, 0x01, 0x21, 0x05, 0x84, 0x29, 
+-      0x23, 0x0d, 0x06, 0x9b, 0x6c, 0x79, 0x1a, 0xca, 
+-      0x68, 0x52, 0x31, 0x08, 0x23, 0x05, 0x02, 0x5b, 
+-      0x64, 0x79, 0x66, 0xba, 0x42, 0x99, 0xdb, 0x06, 
+-      0x21, 0x01, 0x02, 0xc9, 0x64, 0x79, 0xe0, 0x02, 
+-      0x21, 0x00, 0x75, 0x01, 0x84, 0x29, 0x8c, 0x29, 
+-      0x1c, 0x4a, 0x6a, 0xfb, 0x1a, 0x9a, 0x07, 0x92, 
+-      0x0f, 0x92, 0x18, 0x51, 0x84, 0x29, 0x7e, 0x01, 
+-      0x29, 0x00, 0xd0, 0x03, 0x21, 0x00, 0x66, 0x39, 
+-      0x66, 0x79, 0x76, 0x01, 0x6c, 0x79, 0x4a, 0x58, 
+-      0x69, 0x52, 0x42, 0x91, 0xd0, 0x26, 0x6e, 0x7a, 
+-      0x2a, 0x00, 0xd1, 0x10, 0x23, 0x0d, 0x06, 0x9b, 
+-      0x1a, 0xc9, 0x68, 0x09, 0x66, 0x79, 0x1c, 0x0a, 
+-      0x6e, 0x3b, 0x18, 0x59, 0x66, 0x39, 0x4b, 0x51, 
+-      0x42, 0x99, 0xdb, 0x04, 0x32, 0x01, 0x31, 0x01, 
+-      0x40, 0x19, 0x66, 0x39, 0x66, 0x7a, 0x6e, 0x79, 
+-      0x6d, 0xba, 0x1a, 0x89, 0x65, 0x21, 0x91, 0x00, 
+-      0x8c, 0x2b, 0x4e, 0x4b, 0x1a, 0xf3, 0x42, 0x8b, 
+-      0xd3, 0x04, 0x63, 0xe1, 0x21, 0x00, 0x65, 0xb9, 
+-      0x66, 0x79, 0xe0, 0x0a, 0x18, 0xd1, 0x63, 0xe3, 
+-      0x65, 0xb9, 0xe0, 0x06, 0x8c, 0x29, 0x4a, 0x44, 
+-      0x1a, 0x51, 0x63, 0xe1, 0x6d, 0xba, 0x18, 0x51, 
+-      0x65, 0xb9, 0x49, 0x42, 0x66, 0x61, 0x8c, 0x2a, 
+-      0x6b, 0xe1, 0x18, 0x89, 0x31, 0x03, 0x83, 0xa9, 
+-      0x22, 0x00, 0x6e, 0x61, 0x80, 0x0a, 0x31, 0x02, 
+-      0x22, 0xff, 0x32, 0xe1, 0x66, 0x61, 0x80, 0x0a, 
+-      0x31, 0x02, 0x66, 0x61, 0x8b, 0xaa, 0x80, 0x0a, 
+-      0x31, 0x02, 0x66, 0x61, 0x7d, 0x00, 0x28, 0x00, 
+-      0xd0, 0x1d, 0x4a, 0x37, 0x80, 0x0a, 0x1c, 0x88, 
+-      0x66, 0x60, 0x8c, 0x29, 0x02, 0x09, 0x6e, 0xba, 
+-      0x0f, 0x52, 0x23, 0x06, 0x40, 0x1a, 0x43, 0x11, 
+-      0x23, 0x21, 0x43, 0x19, 0x80, 0x01, 0x30, 0x02, 
+-      0x66, 0x60, 0x6e, 0xb9, 0x0b, 0x89, 0x23, 0x01, 
+-      0x43, 0x19, 0x80, 0x01, 0x30, 0x02, 0x66, 0x60, 
+-      0x6e, 0xb9, 0x00, 0x49, 0x43, 0x19, 0x80, 0x01, 
+-      0x30, 0x02, 0x66, 0x60, 0xe0, 0x0b, 0x20, 0x01, 
+-      0x03, 0xc0, 0x80, 0x08, 0x31, 0x02, 0x66, 0x61, 
+-      0x8c, 0x28, 0x02, 0x00, 0x23, 0xff, 0x43, 0x18, 
+-      0x80, 0x08, 0x31, 0x02, 0x66, 0x61, 0x48, 0x23, 
+-      0x6e, 0x61, 0x80, 0x08, 0x31, 0x02, 0x66, 0x61, 
+-      0x80, 0x08, 0x31, 0x02, 0x22, 0x33, 0x06, 0x52, 
+-      0x66, 0x61, 0x00, 0x53, 0x6d, 0x90, 0x18, 0xc2, 
+-      0xb4, 0x04, 0x08, 0x5a, 0x6d, 0x50, 0x18, 0xc6, 
+-      0x8c, 0x28, 0x4b, 0x1b, 0x18, 0xc1, 0x00, 0x53, 
+-      0x6a, 0xf8, 0x18, 0xc0, 0x6b, 0xe2, 0x1c, 0x33, 
+-      0xf0, 0x00, 0xfd, 0xbe, 0x6a, 0xf8, 0x6b, 0xe1, 
+-      0x18, 0x40, 0x22, 0x33, 0x06, 0x52, 0x62, 0xf8, 
+-      0x6d, 0x92, 0xb0, 0x01, 0x42, 0x90, 0xdb, 0x02, 
+-      0x6a, 0x79, 0x1a, 0x40, 0x62, 0xf8, 0x21, 0xff, 
+-      0x31, 0x11, 0x48, 0x10, 0x85, 0x01, 0x8b, 0xa9, 
+-      0x31, 0x06, 0x85, 0x41, 0x21, 0x01, 0x02, 0x49, 
+-      0x86, 0x81, 0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x04, 0x44, 
+-      0x00, 0x00, 0x0f, 0xee, 0x2e, 0x08, 0x04, 0xa4, 
+-      0xcc, 0x00, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 
+-      0x00, 0x00, 0x07, 0xf7, 0x2c, 0x00, 0x02, 0x00, 
+-      0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 
+-      0x2c, 0x00, 0x02, 0x09, 0x2c, 0x00, 0x1f, 0xc0, 
+-      0xb5, 0xb0, 0x1c, 0x07, 0xb0, 0x83, 0x4d, 0x20, 
+-      0x6b, 0x28, 0xf7, 0xff, 0xfa, 0x51, 0x48, 0x1f, 
+-      0x6c, 0xc1, 0x6c, 0x80, 0x1a, 0x08, 0xd5, 0x03, 
+-      0x1f, 0xe9, 0x39, 0x79, 0x69, 0x09, 0x18, 0x40, 
+-      0x6e, 0xa9, 0x29, 0x00, 0xd0, 0x22, 0x29, 0x10, 
+-      0xd0, 0x20, 0x29, 0x20, 0xd0, 0x24, 0x29, 0x30, 
+-      0xd1, 0x04, 0x24, 0x2d, 0x43, 0x44, 0xd5, 0x00, 
+-      0x34, 0x3f, 0x11, 0xa4, 0x46, 0x6a, 0xa8, 0x01, 
+-      0xa9, 0x02, 0xf7, 0xff, 0xfa, 0x17, 0x1b, 0x38, 
+-      0x99, 0x02, 0x1a, 0x08, 0x22, 0x7d, 0x01, 0x52, 
+-      0x42, 0x90, 0xdc, 0x01, 0x42, 0x90, 0xda, 0x05, 
+-      0x1a, 0x09, 0x91, 0x02, 0x22, 0x00, 0x20, 0x00, 
+-      0xf7, 0xff, 0xf9, 0xf2, 0xb0, 0x03, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x01, 0x04, 0x1a, 0x24, 
+-      0xd5, 0x00, 0x34, 0x1f, 0x11, 0x64, 0xe7, 0xe1, 
+-      0x21, 0x4b, 0x43, 0x41, 0x20, 0x93, 0xf0, 0x14, 
+-      0xf8, 0xd7, 0x1c, 0x04, 0xe7, 0xda, 0x00, 0x00, 
+-      0x2e, 0x08, 0x04, 0xc4, 0x66, 0x00, 0x00, 0x80, 
+-      0xb5, 0x90, 0x1c, 0x07, 0xb0, 0x83, 0x4c, 0x18, 
+-      0x6f, 0x60, 0x30, 0x01, 0x46, 0x6a, 0x67, 0x60, 
+-      0xa8, 0x01, 0xa9, 0x02, 0xf7, 0xff, 0xf9, 0xe6, 
+-      0x4b, 0x14, 0x18, 0xf9, 0x98, 0x02, 0x1a, 0x40, 
+-      0x4b, 0x13, 0x42, 0x98, 0xdc, 0x04, 0x42, 0xd8, 
+-      0xdb, 0x02, 0x69, 0xe0, 0x28, 0x01, 0xd1, 0x07, 
+-      0x91, 0x02, 0x20, 0x00, 0x90, 0x01, 0x22, 0x00, 
+-      0xf7, 0xff, 0xf9, 0xbe, 0x20, 0x01, 0x61, 0xe0, 
+-      0x69, 0xe0, 0x28, 0x00, 0xd0, 0x0b, 0x6b, 0x20, 
+-      0xf7, 0xff, 0xf9, 0xea, 0x6f, 0x60, 0x67, 0xa0, 
+-      0x48, 0x08, 0x60, 0x07, 0x6f, 0xe0, 0x30, 0x01, 
+-      0x67, 0xe0, 0x20, 0x00, 0x61, 0xe0, 0xb0, 0x03, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x04, 0xc4, 0xff, 0xff, 0xec, 0x78, 
+-      0x00, 0x02, 0xbf, 0x20, 0x2e, 0x08, 0x05, 0x44, 
+-      0xb4, 0xf0, 0x1c, 0x1c, 0x23, 0x00, 0x9f, 0x04, 
+-      0x60, 0x3b, 0x79, 0x85, 0x23, 0xc0, 0x40, 0x1d, 
+-      0x4b, 0x33, 0x2d, 0x80, 0xd1, 0x16, 0x25, 0x02, 
+-      0x60, 0x9d, 0x79, 0xc5, 0x0a, 0x2b, 0xd3, 0x06, 
+-      0x7a, 0x45, 0x23, 0xe0, 0x40, 0x2b, 0x2b, 0x20, 
+-      0xd1, 0x01, 0x23, 0x09, 0x60, 0x3b, 0x7a, 0x03, 
+-      0x33, 0x09, 0x60, 0x13, 0x79, 0x02, 0x02, 0x12, 
+-      0x79, 0x45, 0x43, 0x2a, 0x32, 0x06, 0x1a, 0xd2, 
+-      0x60, 0x22, 0xe0, 0x25, 0x25, 0x06, 0x26, 0x01, 
+-      0x60, 0x9e, 0x79, 0x83, 0x2b, 0xff, 0xd1, 0x03, 
+-      0x35, 0x01, 0x5d, 0x43, 0x2b, 0xff, 0xd0, 0xfb, 
+-      0x5d, 0x46, 0x23, 0xc0, 0x40, 0x33, 0x2b, 0x40, 
+-      0xd1, 0x00, 0x35, 0x02, 0x5d, 0x46, 0x09, 0x33, 
+-      0x07, 0x9b, 0xd0, 0x08, 0x60, 0x3d, 0x5d, 0x46, 
+-      0x09, 0x73, 0xd3, 0x02, 0x1d, 0xeb, 0x33, 0x03, 
+-      0xe0, 0x02, 0x1d, 0x6b, 0xe0, 0x00, 0x1c, 0x6b, 
+-      0x60, 0x13, 0x79, 0x02, 0x02, 0x12, 0x79, 0x45, 
+-      0x43, 0x2a, 0x32, 0x06, 0x1a, 0xd2, 0x60, 0x22, 
+-      0x68, 0x3a, 0x2a, 0x00, 0xd0, 0x20, 0x5c, 0x82, 
+-      0x23, 0x0e, 0x40, 0x1a, 0x07, 0x52, 0x60, 0x0a, 
+-      0x68, 0x3b, 0x18, 0xc3, 0x78, 0x5b, 0x05, 0x9b, 
+-      0x43, 0x1a, 0x60, 0x0a, 0x68, 0x3b, 0x18, 0xc3, 
+-      0x78, 0x9c, 0x23, 0xfe, 0x40, 0x23, 0x03, 0x9b, 
+-      0x43, 0x1a, 0x60, 0x0a, 0x68, 0x3b, 0x18, 0xc3, 
+-      0x78, 0xdb, 0x01, 0xdb, 0x43, 0x1a, 0x60, 0x0a, 
+-      0x68, 0x3b, 0x18, 0xc0, 0x79, 0x00, 0x23, 0xfe, 
+-      0x40, 0x18, 0x08, 0x40, 0x43, 0x10, 0x60, 0x08, 
+-      0x20, 0x00, 0xbc, 0xf0, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x04, 0x44, 0xb5, 0xb0, 0xb0, 0x83, 
+-      0x48, 0x43, 0x49, 0x44, 0x8d, 0xc9, 0x4c, 0x44, 
+-      0x63, 0xe1, 0x29, 0x06, 0xda, 0x03, 0xb0, 0x03, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x68, 0x01, 
+-      0x09, 0x09, 0x01, 0x09, 0x23, 0xff, 0x33, 0xe1, 
+-      0x42, 0x99, 0xd0, 0x03, 0xb0, 0x03, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x46, 0x6a, 0xb4, 0x04, 
+-      0xaa, 0x03, 0xab, 0x02, 0x49, 0x39, 0xf7, 0xff, 
+-      0xff, 0x6f, 0xb0, 0x01, 0x28, 0x00, 0xd0, 0x03, 
+-      0xb0, 0x03, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x98, 0x02, 0x99, 0x01, 0x18, 0x40, 0x6b, 0xe1, 
+-      0x42, 0x88, 0xd0, 0x03, 0xb0, 0x03, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x98, 0x00, 0x4f, 0x30, 
+-      0x28, 0x00, 0xd0, 0x2e, 0x6e, 0x38, 0x6d, 0xb9, 
+-      0x18, 0x40, 0x23, 0x01, 0x06, 0x1b, 0x66, 0x38, 
+-      0x42, 0x98, 0xdb, 0x04, 0x43, 0xdb, 0x18, 0xc0, 
+-      0x66, 0x38, 0x1e, 0x48, 0x65, 0xb8, 0x23, 0x0d, 
+-      0x06, 0x9b, 0x6d, 0xb8, 0x6c, 0xb9, 0x1a, 0xc9, 
+-      0x60, 0x08, 0x6e, 0xe0, 0x6c, 0xb9, 0x1a, 0xc9, 
+-      0x60, 0x48, 0x20, 0x00, 0x65, 0xb8, 0x6c, 0xb8, 
+-      0x30, 0x08, 0x23, 0x05, 0x02, 0x5b, 0x64, 0xb8, 
+-      0x42, 0x98, 0xd1, 0x02, 0x20, 0x01, 0x02, 0xc0, 
+-      0x64, 0xb8, 0x6c, 0xb8, 0x49, 0x1d, 0x61, 0x48, 
+-      0x6d, 0x78, 0x28, 0x04, 0xd1, 0x05, 0x68, 0xe0, 
+-      0x28, 0x00, 0xd1, 0x02, 0x6e, 0xe0, 0xf7, 0xff, 
+-      0xfe, 0xef, 0x24, 0x33, 0x06, 0x64, 0x00, 0x63, 
+-      0x6d, 0xa0, 0x18, 0xc2, 0xb4, 0x04, 0x6d, 0x60, 
+-      0x18, 0xc5, 0x6e, 0x60, 0x18, 0xc1, 0x98, 0x03, 
+-      0x4b, 0x0d, 0x18, 0xc0, 0x9a, 0x02, 0x1c, 0x2b, 
+-      0xf0, 0x00, 0xfc, 0x52, 0xb0, 0x01, 0x6d, 0xb8, 
+-      0x99, 0x01, 0x18, 0x40, 0x65, 0xb8, 0x48, 0x0e, 
+-      0x68, 0x02, 0x18, 0x51, 0x60, 0x01, 0x6e, 0x60, 
+-      0x6d, 0xa1, 0x42, 0x88, 0xdb, 0x04, 0x48, 0x0a, 
+-      0x68, 0x01, 0x6a, 0x7a, 0x1a, 0x89, 0x60, 0x01, 
+-      0xb0, 0x03, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2c, 0x00, 0x12, 0x00, 0x2c, 0x00, 0x1f, 0xc0, 
+-      0x2e, 0x08, 0x04, 0xc4, 0x2e, 0x08, 0x05, 0x30, 
+-      0x2e, 0x08, 0x04, 0x44, 0xcc, 0x00, 0x0f, 0x00, 
+-      0x66, 0x00, 0x00, 0x64, 0xb5, 0xf0, 0xb0, 0x83, 
+-      0x4e, 0x65, 0x25, 0x00, 0x4f, 0x65, 0x6a, 0xf8, 
+-      0xf7, 0xff, 0xf8, 0xc2, 0x48, 0x64, 0x8d, 0xc0, 
+-      0x63, 0xf8, 0x28, 0x0a, 0xda, 0x03, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x68, 0x34, 
+-      0x09, 0x60, 0x01, 0x40, 0x23, 0xff, 0x33, 0xc1, 
+-      0x42, 0x98, 0xd0, 0x07, 0x23, 0xff, 0x33, 0xbe, 
+-      0x42, 0x9c, 0xd0, 0x03, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x46, 0x6a, 0xb4, 0x04, 
+-      0xaa, 0x03, 0xab, 0x02, 0x49, 0x57, 0x1c, 0x30, 
+-      0xf7, 0xff, 0xfe, 0xce, 0xb0, 0x01, 0x28, 0x00, 
+-      0xd0, 0x03, 0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x98, 0x02, 0x99, 0x01, 0x18, 0x41, 
+-      0x6b, 0xfa, 0x42, 0x91, 0xd0, 0x03, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x21, 0x01, 
+-      0x1c, 0x22, 0x4c, 0x4d, 0x23, 0xff, 0x33, 0xbe, 
+-      0x42, 0x9a, 0xd1, 0x3c, 0x5c, 0x30, 0x28, 0xa0, 
+-      0xd0, 0x03, 0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x68, 0xe0, 0x28, 0x00, 0xd1, 0x1b, 
+-      0x20, 0x02, 0x63, 0x78, 0x60, 0xe1, 0x21, 0x00, 
+-      0x20, 0x00, 0xf0, 0x09, 0xfd, 0x8d, 0x20, 0x00, 
+-      0xf7, 0xfb, 0xfd, 0xd4, 0x98, 0x02, 0x4b, 0x3c, 
+-      0x18, 0xc0, 0x79, 0x40, 0x23, 0x30, 0x40, 0x18, 
+-      0x66, 0xb8, 0xd0, 0x16, 0x28, 0x10, 0xd0, 0x14, 
+-      0x28, 0x20, 0xd0, 0x17, 0x28, 0x30, 0xd1, 0x03, 
+-      0x21, 0x20, 0x20, 0x1e, 0xf0, 0x0a, 0xf8, 0xa7, 
+-      0x98, 0x00, 0x28, 0x00, 0xd0, 0x2b, 0x6d, 0x60, 
+-      0x28, 0x05, 0xd1, 0x28, 0x68, 0xf8, 0x28, 0x00, 
+-      0xd1, 0x25, 0x6f, 0x38, 0xf7, 0xff, 0xfe, 0x00, 
+-      0xe0, 0x21, 0x21, 0x02, 0x20, 0x1e, 0xf0, 0x0a, 
+-      0xf8, 0x96, 0xe7, 0xed, 0x21, 0x08, 0x20, 0x1e, 
+-      0xf0, 0x0a, 0xf8, 0x91, 0xe7, 0xe8, 0x68, 0xe0, 
+-      0x28, 0x00, 0xd0, 0x08, 0x20, 0x00, 0x63, 0x79, 
+-      0x21, 0x00, 0x60, 0xe0, 0xf0, 0x09, 0xfd, 0x58, 
+-      0x20, 0x02, 0xf0, 0x09, 0xfd, 0xab, 0x98, 0x00, 
+-      0x28, 0x00, 0xd0, 0x08, 0x6d, 0x60, 0x28, 0x05, 
+-      0xd1, 0x05, 0x68, 0xf8, 0x28, 0x00, 0xd1, 0x02, 
+-      0x6f, 0x38, 0xf7, 0xff, 0xfe, 0x25, 0x68, 0xe0, 
+-      0x28, 0x00, 0xd0, 0x01, 0x98, 0x02, 0x1d, 0xc5, 
+-      0x6b, 0xf8, 0x1b, 0x42, 0x63, 0xfa, 0x7e, 0x39, 
+-      0x69, 0x78, 0x18, 0x41, 0x4b, 0x16, 0x18, 0xe8, 
+-      0xf7, 0xfb, 0xfb, 0x3a, 0x7e, 0x38, 0x6b, 0xf9, 
+-      0x18, 0x40, 0x07, 0x81, 0x0f, 0x89, 0x76, 0x39, 
+-      0x1a, 0x44, 0x20, 0x01, 0x06, 0x00, 0x49, 0x15, 
+-      0x60, 0x08, 0xf0, 0x17, 0xfe, 0x57, 0x4b, 0x14, 
+-      0x40, 0x18, 0xf0, 0x17, 0xfe, 0x57, 0x22, 0x04, 
+-      0x49, 0x10, 0xb4, 0x06, 0x23, 0x12, 0x21, 0x1e, 
+-      0x69, 0x78, 0x1c, 0x22, 0xf0, 0x0e, 0xfb, 0x66, 
+-      0xb0, 0x02, 0xf0, 0x17, 0xfe, 0x47, 0x23, 0x01, 
+-      0x04, 0x9b, 0x43, 0x18, 0xf0, 0x17, 0xfe, 0x46, 
+-      0x69, 0x78, 0x59, 0x01, 0x60, 0x01, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2c, 0x00, 0x12, 0x00, 0x2e, 0x08, 0x04, 0xc4, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x2e, 0x08, 0x05, 0x34, 
+-      0x2e, 0x08, 0x04, 0x44, 0x9e, 0x00, 0x08, 0x00, 
+-      0xff, 0xfb, 0xff, 0xff, 0x20, 0x33, 0x06, 0x40, 
+-      0x6e, 0x81, 0x6e, 0x40, 0x1a, 0x09, 0x48, 0x0f, 
+-      0x63, 0xc1, 0x29, 0x00, 0xdc, 0x04, 0x1f, 0xc2, 
+-      0x3a, 0x79, 0x6a, 0x52, 0x18, 0x89, 0x63, 0xc1, 
+-      0x6b, 0xc1, 0x08, 0x89, 0x00, 0x89, 0x23, 0x01, 
+-      0x02, 0xdb, 0x63, 0xc1, 0x42, 0x99, 0xdd, 0x0b, 
+-      0x4a, 0x07, 0x42, 0x91, 0xdd, 0x00, 0x63, 0xc2, 
+-      0x4a, 0x06, 0x49, 0x07, 0x85, 0x8a, 0x6b, 0xc0, 
+-      0x85, 0xc8, 0x20, 0x09, 0x02, 0x40, 0x86, 0xc8, 
+-      0x47, 0x70, 0x00, 0x00, 0x2e, 0x08, 0x04, 0xc4, 
+-      0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x02, 0x06, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x48, 0x0f, 0x78, 0x01, 
+-      0x29, 0x00, 0xd0, 0x1a, 0x49, 0x0e, 0x6c, 0x8a, 
+-      0x6c, 0xc9, 0x1a, 0x51, 0x63, 0xc1, 0x1c, 0x0a, 
+-      0x29, 0x00, 0xdc, 0x04, 0x1f, 0xc1, 0x39, 0x79, 
+-      0x69, 0x09, 0x18, 0x51, 0x63, 0xc1, 0x23, 0x01, 
+-      0x03, 0x1b, 0x6b, 0xc1, 0x42, 0x99, 0xdb, 0x08, 
+-      0x22, 0xff, 0x32, 0x07, 0x49, 0x05, 0x85, 0x8a, 
+-      0x6b, 0xc0, 0x85, 0xc8, 0x20, 0x09, 0x02, 0x40, 
+-      0x86, 0xc8, 0x47, 0x70, 0x2e, 0x08, 0x04, 0xc4, 
+-      0x66, 0x00, 0x00, 0x80, 0x2c, 0x00, 0x1f, 0xc0, 
+-      0xb4, 0x80, 0x20, 0x00, 0x49, 0x1e, 0x6c, 0x8a, 
+-      0x6c, 0xc9, 0x1a, 0x52, 0x49, 0x1d, 0x2a, 0x00, 
+-      0xdc, 0x01, 0x69, 0x0b, 0x18, 0xd2, 0x23, 0x01, 
+-      0x02, 0xdb, 0x42, 0x9a, 0xdd, 0x00, 0x08, 0xd8, 
+-      0x22, 0x33, 0x06, 0x52, 0x6e, 0x93, 0x6e, 0x52, 
+-      0x1a, 0x9a, 0x2a, 0x00, 0xdc, 0x01, 0x6a, 0x4b, 
+-      0x18, 0xd2, 0x08, 0x92, 0x00, 0x92, 0x4b, 0x14, 
+-      0x68, 0xdb, 0x2b, 0x00, 0xd0, 0x06, 0x23, 0x01, 
+-      0x03, 0x1b, 0x6a, 0x4f, 0x18, 0xfb, 0x6a, 0x89, 
+-      0x1a, 0x59, 0xe0, 0x01, 0x21, 0x01, 0x03, 0x09, 
+-      0x42, 0x8a, 0xdd, 0x04, 0x04, 0x00, 0x0c, 0x00, 
+-      0x23, 0x01, 0x02, 0x5b, 0x43, 0x18, 0x28, 0x00, 
+-      0xd0, 0x0b, 0x4b, 0x0a, 0x42, 0x9a, 0xdd, 0x00, 
+-      0x1c, 0x1a, 0x21, 0x06, 0x43, 0x01, 0x48, 0x08, 
+-      0x85, 0x81, 0x85, 0xc2, 0x21, 0x09, 0x02, 0x49, 
+-      0x86, 0xc1, 0xbc, 0x80, 0x47, 0x70, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x80, 0x2e, 0x08, 0x04, 0x44, 
+-      0x2e, 0x08, 0x04, 0xc4, 0x00, 0x00, 0xff, 0xff, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0xb5, 0x90, 0x04, 0x00, 
+-      0x0c, 0x00, 0x4f, 0x13, 0x6d, 0x39, 0x29, 0x00, 
+-      0xd1, 0x10, 0x24, 0x01, 0x28, 0x01, 0xd0, 0x10, 
+-      0x28, 0x04, 0xd0, 0x15, 0x28, 0x05, 0xd1, 0x09, 
+-      0xf7, 0xff, 0xf8, 0x48, 0xf7, 0xfe, 0xff, 0xfc, 
+-      0x20, 0x00, 0x66, 0xf8, 0x67, 0x38, 0x20, 0x05, 
+-      0x65, 0x78, 0x65, 0x3c, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0xf7, 0xfe, 0xff, 0xf1, 0x65, 0x3c, 
+-      0x65, 0x7c, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0xf7, 0xff, 0xf8, 0x34, 0x20, 0x04, 0x65, 0x78, 
+-      0x65, 0x3c, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x04, 0x44, 0xb5, 0x90, 0x04, 0x00, 
+-      0x0c, 0x00, 0x4f, 0x23, 0x6d, 0x39, 0x29, 0x00, 
+-      0xd0, 0x0e, 0x29, 0x02, 0xd1, 0x09, 0x6d, 0x78, 
+-      0x28, 0x01, 0xd0, 0x34, 0x28, 0x04, 0xd0, 0x27, 
+-      0x28, 0x05, 0xd1, 0x02, 0x20, 0xff, 0xf7, 0xff, 
+-      0xf8, 0xc7, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x24, 0x02, 0x28, 0x01, 0xd0, 0x0c, 0x28, 0x04, 
+-      0xd0, 0x12, 0x28, 0x05, 0xd1, 0xf5, 0x20, 0x00, 
+-      0xf7, 0xff, 0xf8, 0xba, 0x20, 0x05, 0x65, 0x78, 
+-      0x65, 0x3c, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0xf7, 0xff, 0xf8, 0x38, 0x20, 0x01, 0x65, 0x78, 
+-      0x65, 0x3c, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0xf7, 0xff, 0xf8, 0x70, 0x20, 0x04, 0x65, 0x78, 
+-      0x65, 0x3c, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x21, 0x00, 0x20, 0x0e, 0xf0, 0x0b, 0xff, 0xf0, 
+-      0x21, 0x00, 0x20, 0x0d, 0xf0, 0x0b, 0xff, 0xec, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x20, 0x02, 
+-      0xf0, 0x09, 0xfc, 0x4c, 0x20, 0xff, 0x49, 0x03, 
+-      0x70, 0x08, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x04, 0x44, 0x2e, 0x08, 0x04, 0xc4, 
+-      0xb5, 0xf0, 0x4f, 0x2b, 0x24, 0x00, 0x6d, 0x38, 
+-      0x28, 0x01, 0xd0, 0x1e, 0x28, 0x02, 0xd1, 0x19, 
+-      0x26, 0x03, 0x6d, 0x78, 0x1d, 0xfd, 0x35, 0x79, 
+-      0x28, 0x01, 0xd0, 0x34, 0x28, 0x04, 0xd0, 0x3f, 
+-      0x28, 0x05, 0xd1, 0x0f, 0x20, 0x02, 0x63, 0x6c, 
+-      0xf0, 0x09, 0xfc, 0x2c, 0x20, 0x00, 0xf7, 0xfb, 
+-      0xfc, 0x1d, 0xf7, 0xff, 0xf8, 0x21, 0x65, 0x3e, 
+-      0x20, 0x00, 0x65, 0x78, 0xf7, 0xfe, 0xfe, 0xb8, 
+-      0x20, 0x01, 0x61, 0xe8, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x6d, 0x78, 0x28, 0x01, 0xd0, 0x0c, 
+-      0x28, 0x04, 0xd0, 0x11, 0x28, 0x05, 0xd1, 0xf5, 
+-      0xf7, 0xfe, 0xff, 0x82, 0xf7, 0xfe, 0xff, 0xd8, 
+-      0x65, 0x3c, 0x65, 0x7c, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0xf7, 0xfe, 0xff, 0x79, 0x65, 0x3c, 
+-      0x65, 0x7c, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xf7, 0xfe, 0xff, 0xca, 0x65, 0x3c, 0x65, 0x7c, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x63, 0x6c, 
+-      0x20, 0x02, 0x60, 0xfc, 0xf0, 0x09, 0xfb, 0xfa, 
+-      0x20, 0x00, 0xf7, 0xfb, 0xfb, 0xeb, 0x65, 0x7c, 
+-      0x65, 0x3e, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xf7, 0xfe, 0xff, 0xea, 0x65, 0x7c, 0x65, 0x3e, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x04, 0x44, 0xb5, 0x90, 0x4c, 0x1b, 
+-      0x68, 0xe0, 0x28, 0x03, 0xd0, 0x1f, 0x1f, 0xe7, 
+-      0x3f, 0x79, 0x6d, 0x38, 0x28, 0x02, 0xd1, 0x1a, 
+-      0x6d, 0x78, 0x28, 0x01, 0xd0, 0x1a, 0x28, 0x04, 
+-      0xd0, 0x20, 0x28, 0x05, 0xd1, 0x13, 0x4a, 0x14, 
+-      0x49, 0x14, 0x48, 0x15, 0xf7, 0xfe, 0xfe, 0x4a, 
+-      0x21, 0x00, 0x20, 0x0e, 0xf0, 0x0b, 0xff, 0x68, 
+-      0x20, 0x01, 0xf0, 0x09, 0xfb, 0xcb, 0x20, 0x03, 
+-      0x60, 0xe0, 0x68, 0xf8, 0x28, 0x00, 0xd0, 0x02, 
+-      0x20, 0x01, 0xf0, 0x09, 0xfb, 0xc3, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x20, 0x01, 0xf0, 0x09, 
+-      0xfb, 0xbd, 0x20, 0x00, 0x70, 0x20, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x21, 0x00, 0x20, 0x0b, 
+-      0xf0, 0x0b, 0xff, 0x4e, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x04, 0xc4, 
+-      0x2e, 0x08, 0x05, 0x50, 0x2e, 0x08, 0x05, 0x48, 
+-      0x2e, 0x08, 0x05, 0x4c, 0xb5, 0xf0, 0x4c, 0x21, 
+-      0x6d, 0x20, 0x28, 0x02, 0xd1, 0x24, 0x26, 0xff, 
+-      0x6d, 0x60, 0x1d, 0xe7, 0x37, 0x79, 0x28, 0x01, 
+-      0xd0, 0x1d, 0x28, 0x04, 0xd0, 0x1f, 0x28, 0x05, 
+-      0xd1, 0x1a, 0x20, 0x01, 0xf0, 0x09, 0xfb, 0x96, 
+-      0x25, 0x00, 0x68, 0xe0, 0x28, 0x00, 0xd0, 0x04, 
+-      0x21, 0x00, 0x20, 0x00, 0xf0, 0x09, 0xfb, 0x38, 
+-      0x60, 0xe5, 0x70, 0x3e, 0x68, 0xf8, 0x28, 0x03, 
+-      0xd1, 0x14, 0x48, 0x13, 0x22, 0x00, 0x68, 0x41, 
+-      0x20, 0x00, 0xf7, 0xfe, 0xfd, 0xe5, 0x6b, 0x38, 
+-      0xf7, 0xfe, 0xfe, 0x16, 0xe0, 0x0f, 0x70, 0x3e, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x21, 0x00, 
+-      0x20, 0x0d, 0xf0, 0x0b, 0xff, 0x11, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x20, 0x01, 0x61, 0xf8, 
+-      0x6b, 0x38, 0xf7, 0xfe, 0xfe, 0x05, 0x20, 0x02, 
+-      0x60, 0xfd, 0xf0, 0x09, 0xfb, 0x6b, 0x21, 0x00, 
+-      0x20, 0x0d, 0xf0, 0x0b, 0xff, 0x01, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x04, 0x44, 
+-      0x2e, 0x08, 0x05, 0x44, 0xb5, 0xb0, 0x04, 0x07, 
+-      0x0c, 0x3f, 0x2f, 0x01, 0xda, 0x00, 0x27, 0x01, 
+-      0x2f, 0x3f, 0xdd, 0x00, 0x27, 0x3f, 0x48, 0x17, 
+-      0x6d, 0x01, 0x29, 0x02, 0xd1, 0x13, 0x6d, 0x40, 
+-      0x25, 0x02, 0x4c, 0x15, 0x28, 0x04, 0xd0, 0x11, 
+-      0x28, 0x05, 0xd1, 0x0c, 0x21, 0x00, 0x20, 0x0e, 
+-      0xf0, 0x0b, 0xfe, 0xe2, 0x21, 0x00, 0x20, 0x0d, 
+-      0xf0, 0x0b, 0xfe, 0xde, 0x20, 0x22, 0x1c, 0x39, 
+-      0xf0, 0x0b, 0xfe, 0xda, 0x60, 0xe5, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x21, 0x00, 0x20, 0x0e, 
+-      0xf0, 0x0b, 0xfe, 0xd2, 0x21, 0x00, 0x20, 0x0d, 
+-      0xf0, 0x0b, 0xfe, 0xce, 0x20, 0x22, 0x1c, 0x39, 
+-      0xf0, 0x0b, 0xfe, 0xca, 0x20, 0x00, 0xf7, 0xfe, 
+-      0xfd, 0xc3, 0x60, 0xe5, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x04, 0x44, 
+-      0x2e, 0x08, 0x04, 0xc4, 0xb5, 0x00, 0x48, 0x0b, 
+-      0x6d, 0x01, 0x29, 0x02, 0xd1, 0x10, 0x6d, 0x40, 
+-      0x28, 0x04, 0xd0, 0x01, 0x28, 0x05, 0xd1, 0x0b, 
+-      0x21, 0x00, 0x20, 0x16, 0xf0, 0x0b, 0xfe, 0xb0, 
+-      0x20, 0x00, 0xf7, 0xfe, 0xfd, 0xa9, 0x21, 0x00, 
+-      0x48, 0x03, 0x70, 0x01, 0x21, 0x01, 0x60, 0xc1, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x04, 0x44, 
+-      0x2e, 0x08, 0x04, 0xc4, 0xb5, 0x00, 0x48, 0x0b, 
+-      0x6d, 0x01, 0x29, 0x02, 0xd1, 0x10, 0x6d, 0x40, 
+-      0x28, 0x04, 0xd0, 0x01, 0x28, 0x05, 0xd1, 0x0b, 
+-      0x21, 0x00, 0x20, 0x1a, 0xf0, 0x0b, 0xfe, 0x94, 
+-      0x20, 0x00, 0xf7, 0xfe, 0xfd, 0x8d, 0x21, 0x00, 
+-      0x48, 0x03, 0x70, 0x01, 0x21, 0x01, 0x60, 0xc1, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x04, 0x44, 
+-      0x2e, 0x08, 0x04, 0xc4, 0x48, 0x03, 0x6d, 0x00, 
+-      0x28, 0x00, 0xd1, 0x00, 0x47, 0x70, 0x20, 0xff, 
+-      0x47, 0x70, 0x00, 0x00, 0x2e, 0x08, 0x04, 0x44, 
+-      0xb5, 0xf0, 0x1c, 0x04, 0x1c, 0x0f, 0x4d, 0x52, 
+-      0x6d, 0x29, 0x48, 0x52, 0x26, 0x00, 0x29, 0x01, 
+-      0xd0, 0x4c, 0x29, 0x02, 0xd1, 0x6e, 0x6d, 0x69, 
+-      0x29, 0x01, 0xd0, 0x20, 0x29, 0x04, 0xd0, 0x2e, 
+-      0x29, 0x05, 0xd1, 0x3e, 0x6c, 0xc1, 0x6c, 0x80, 
+-      0x1a, 0x08, 0xd5, 0x01, 0x69, 0x29, 0x18, 0x40, 
+-      0x21, 0x64, 0x43, 0x41, 0x69, 0x28, 0xf0, 0x13, 
+-      0xfc, 0x1b, 0x70, 0x20, 0x20, 0x33, 0x06, 0x40, 
+-      0x6e, 0x41, 0x6e, 0x80, 0x1a, 0x08, 0xd5, 0x01, 
+-      0x6a, 0x69, 0x18, 0x40, 0x21, 0x64, 0x43, 0x41, 
+-      0x6a, 0x68, 0xf0, 0x13, 0xfc, 0x0d, 0x70, 0x38, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x6c, 0xc1, 
+-      0x6c, 0x80, 0x1a, 0x08, 0xd5, 0x01, 0x69, 0x29, 
+-      0x18, 0x40, 0x21, 0x64, 0x43, 0x41, 0x69, 0x28, 
+-      0xf0, 0x13, 0xfb, 0xfe, 0x70, 0x20, 0x70, 0x3e, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x20, 0x33, 
+-      0x06, 0x40, 0x6e, 0x41, 0x6e, 0x80, 0x1a, 0x08, 
+-      0xd5, 0x01, 0x6a, 0x69, 0x18, 0x40, 0x21, 0x64, 
+-      0x43, 0x41, 0x6a, 0x68, 0xf0, 0x13, 0xfb, 0xec, 
+-      0x70, 0x38, 0x70, 0x26, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x70, 0x26, 0x70, 0x3e, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x6d, 0x69, 0x29, 0x01, 
+-      0xd0, 0x21, 0x29, 0x04, 0xd0, 0x2f, 0x29, 0x05, 
+-      0xd1, 0x3f, 0x69, 0x69, 0x6c, 0xc0, 0x1a, 0x40, 
+-      0xd5, 0x01, 0x69, 0x29, 0x18, 0x40, 0x21, 0x64, 
+-      0x43, 0x41, 0x69, 0x28, 0xf0, 0x13, 0xfb, 0xd0, 
+-      0x70, 0x20, 0x21, 0x33, 0x06, 0x49, 0x6a, 0xe8, 
+-      0x6e, 0x49, 0x1a, 0x08, 0xd5, 0x01, 0x6a, 0x69, 
+-      0x18, 0x40, 0x21, 0x64, 0x43, 0x41, 0x6a, 0x68, 
+-      0xf0, 0x13, 0xfb, 0xc2, 0x70, 0x38, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xe0, 0x26, 0x69, 0x69, 
+-      0x6c, 0xc0, 0x1a, 0x40, 0xd5, 0x01, 0x69, 0x29, 
+-      0x18, 0x40, 0x21, 0x64, 0x43, 0x41, 0x69, 0x28, 
+-      0xf0, 0x13, 0xfb, 0xb2, 0x70, 0x20, 0x70, 0x3e, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x21, 0x33, 
+-      0x06, 0x49, 0x6a, 0xe8, 0x6e, 0x49, 0x1a, 0x08, 
+-      0xd5, 0x01, 0x6a, 0x69, 0x18, 0x40, 0x21, 0x64, 
+-      0x43, 0x41, 0x6a, 0x68, 0xf0, 0x13, 0xfb, 0xa0, 
+-      0x70, 0x38, 0x70, 0x26, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x70, 0x26, 0x70, 0x3e, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x70, 0x26, 0x70, 0x3e, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x04, 0x44, 0x66, 0x00, 0x00, 0x80, 
+-      0xb5, 0xf0, 0x1c, 0x17, 0x9e, 0x05, 0x1a, 0xf2, 
+-      0x1c, 0x0d, 0x21, 0x00, 0x1c, 0x1c, 0x42, 0xba, 
+-      0xda, 0x03, 0x1c, 0x08, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x42, 0xa0, 0xd3, 0x01, 0x42, 0xb0, 
+-      0xd9, 0x03, 0x1c, 0x08, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x19, 0xc1, 0x42, 0xb1, 0xd9, 0x0c, 
+-      0x1a, 0x32, 0x4e, 0x0a, 0x64, 0x32, 0x1c, 0x29, 
+-      0xf7, 0xfa, 0xff, 0xc2, 0x6c, 0x30, 0x1a, 0x3a, 
+-      0x18, 0x29, 0x1c, 0x20, 0xf7, 0xfa, 0xff, 0xbc, 
+-      0xe0, 0x03, 0x1c, 0x29, 0x1c, 0x3a, 0xf7, 0xfa, 
+-      0xff, 0xb7, 0x1c, 0x38, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x04, 0xc4, 
+-      0xb5, 0xf0, 0x1c, 0x17, 0x9e, 0x05, 0x1a, 0xf2, 
+-      0x1c, 0x05, 0x20, 0x00, 0x1c, 0x1c, 0x42, 0xba, 
+-      0xdb, 0x18, 0x42, 0xa1, 0xd3, 0x16, 0x42, 0xb1, 
+-      0xd2, 0x14, 0x19, 0xc8, 0x42, 0xb0, 0xd9, 0x0c, 
+-      0x1a, 0x72, 0x4e, 0x0a, 0x64, 0x32, 0x1c, 0x28, 
+-      0xf7, 0xfa, 0xff, 0x9a, 0x6c, 0x30, 0x1a, 0x3a, 
+-      0x18, 0x28, 0x1c, 0x21, 0xf7, 0xfa, 0xff, 0x94, 
+-      0xe0, 0x03, 0x1c, 0x28, 0x1c, 0x3a, 0xf7, 0xfa, 
+-      0xff, 0x8f, 0x1c, 0x38, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x04, 0xc4, 
+-      0x47, 0x70, 0xb5, 0x00, 0xb0, 0x82, 0x46, 0x6a, 
+-      0x49, 0x06, 0xa8, 0x01, 0xf7, 0xfe, 0xfc, 0x4e, 
+-      0x21, 0x00, 0x20, 0x0b, 0xf0, 0x0b, 0xfd, 0x6c, 
+-      0x20, 0x03, 0x49, 0x03, 0x61, 0x08, 0xb0, 0x02, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x05, 0x58, 
+-      0x2e, 0x08, 0x05, 0x44, 0xb5, 0x80, 0x4f, 0x0b, 
+-      0x22, 0x00, 0x20, 0x00, 0x69, 0x79, 0xf7, 0xfe, 
+-      0xfc, 0x23, 0x21, 0x00, 0x20, 0x0d, 0xf0, 0x0b, 
+-      0xfd, 0x57, 0x21, 0x01, 0x1f, 0xf8, 0x38, 0x79, 
+-      0x61, 0xc1, 0x6b, 0x00, 0xf7, 0xfe, 0xfc, 0x4c, 
+-      0x20, 0x00, 0x61, 0x38, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x05, 0x44, 
+-      0xb5, 0x80, 0x4f, 0x06, 0x68, 0x38, 0x1d, 0xc1, 
+-      0x31, 0xb5, 0x20, 0x2f, 0x02, 0x80, 0xf0, 0x13, 
+-      0xfa, 0xfb, 0x60, 0x39, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x02, 0x5c, 0x9c, 
+-      0x48, 0x05, 0x8f, 0xc1, 0x29, 0x00, 0xd0, 0x05, 
+-      0x21, 0x00, 0x87, 0xc1, 0x48, 0x03, 0x69, 0x01, 
+-      0x31, 0x01, 0x61, 0x01, 0x47, 0x70, 0x00, 0x00, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x2e, 0x08, 0x05, 0x5c, 
+-      0x20, 0x00, 0x49, 0x03, 0x60, 0x08, 0x48, 0x03, 
+-      0x69, 0x41, 0x31, 0x01, 0x61, 0x41, 0x47, 0x70, 
+-      0x2e, 0x08, 0x47, 0x50, 0x2e, 0x08, 0x05, 0x5c, 
+-      0xb5, 0x00, 0xb0, 0x88, 0x46, 0x68, 0xf0, 0x0e, 
+-      0xf8, 0xfd, 0x48, 0x07, 0x69, 0x81, 0x31, 0x01, 
+-      0x23, 0x01, 0x22, 0x06, 0x61, 0x81, 0x21, 0x47, 
+-      0x02, 0x49, 0x05, 0x48, 0xf0, 0x0d, 0xff, 0xea, 
+-      0xb0, 0x08, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x05, 0x5c, 0xb5, 0x80, 0x1c, 0x07, 
+-      0x20, 0xff, 0x30, 0xcd, 0xb0, 0x85, 0x90, 0x00, 
+-      0x20, 0x01, 0x02, 0x40, 0x90, 0x02, 0x48, 0x0e, 
+-      0x90, 0x04, 0x20, 0x0e, 0xab, 0x03, 0x80, 0x18, 
+-      0x46, 0x68, 0xf0, 0x0e, 0xf9, 0x0f, 0x2f, 0x00, 
+-      0xd0, 0x0d, 0x20, 0x33, 0x06, 0x40, 0x6d, 0x40, 
+-      0x23, 0x0d, 0x06, 0x9b, 0x1a, 0xc7, 0x98, 0x02, 
+-      0x1e, 0x79, 0xf0, 0x00, 0xfb, 0x21, 0x98, 0x02, 
+-      0x1a, 0x38, 0x49, 0x04, 0x60, 0x88, 0xb0, 0x05, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x1c, 0x00, 0x00, 0x2e, 0x08, 0x05, 0x5c, 
+-      0xb5, 0x00, 0x22, 0x01, 0x21, 0x01, 0x20, 0x00, 
+-      0xf0, 0x09, 0xfd, 0x76, 0x48, 0x04, 0x68, 0x00, 
+-      0x78, 0x01, 0x23, 0x06, 0x43, 0x19, 0x70, 0x01, 
+-      0xf0, 0x00, 0xf9, 0xe4, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x5e, 0x58, 0xb5, 0xf0, 0x48, 0x53, 
+-      0x4e, 0x53, 0x80, 0x30, 0x27, 0x00, 0x4c, 0x53, 
+-      0x86, 0xe7, 0x86, 0xa7, 0x48, 0x52, 0x60, 0x07, 
+-      0xf0, 0x05, 0xfc, 0x76, 0x48, 0x51, 0xf0, 0x0e, 
+-      0xfd, 0x23, 0xf7, 0xfa, 0xfe, 0x71, 0x21, 0xff, 
+-      0x48, 0x4f, 0x60, 0x01, 0x68, 0x01, 0x29, 0x00, 
+-      0xd0, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0x01, 
+-      0x4a, 0x4c, 0x60, 0xd1, 0x60, 0x07, 0xf7, 0xfc, 
+-      0xfa, 0xf7, 0x20, 0x01, 0xf7, 0xff, 0xff, 0xa2, 
+-      0x21, 0x00, 0x20, 0x00, 0xf0, 0x09, 0xf8, 0xb4, 
+-      0xf0, 0x01, 0xfa, 0xac, 0x48, 0x46, 0x60, 0x07, 
+-      0x25, 0x02, 0x48, 0x46, 0x60, 0x05, 0x20, 0x03, 
+-      0x49, 0x45, 0x60, 0x08, 0x49, 0x45, 0x60, 0x08, 
+-      0x49, 0x45, 0x60, 0x0d, 0x49, 0x45, 0x60, 0x08, 
+-      0x48, 0x45, 0x60, 0x07, 0x48, 0x45, 0x65, 0x87, 
+-      0xf0, 0x00, 0xf9, 0x84, 0xf0, 0x0e, 0xfd, 0x90, 
+-      0x20, 0x00, 0xf0, 0x0c, 0xfa, 0xcd, 0x28, 0x00, 
+-      0xd1, 0x60, 0x48, 0x41, 0xf0, 0x08, 0xff, 0x06, 
+-      0x20, 0x00, 0xf0, 0x08, 0xff, 0x77, 0x87, 0xe7, 
+-      0x87, 0xa7, 0x22, 0x01, 0xb4, 0x04, 0x22, 0x03, 
+-      0x21, 0x01, 0x20, 0x00, 0x1c, 0x2b, 0xf0, 0x0b, 
+-      0xff, 0x73, 0x20, 0x02, 0xb0, 0x01, 0xf7, 0xfc, 
+-      0xfc, 0x53, 0xf7, 0xff, 0xff, 0x95, 0x20, 0x7d, 
+-      0x00, 0xc0, 0xf7, 0xfd, 0xfd, 0xab, 0x20, 0x7d, 
+-      0x00, 0xc0, 0xf7, 0xfd, 0xfd, 0xbf, 0xf0, 0x04, 
+-      0xfb, 0x8d, 0xf0, 0x04, 0xfb, 0xcb, 0xf7, 0xfb, 
+-      0xf8, 0xe5, 0x21, 0x18, 0x20, 0x14, 0xf7, 0xfc, 
+-      0xff, 0xf5, 0xf7, 0xfd, 0xfb, 0xa3, 0xf7, 0xfb, 
+-      0xfc, 0x11, 0x20, 0xff, 0xf7, 0xfa, 0xff, 0x2c, 
+-      0x05, 0xa8, 0xf0, 0x17, 0xf9, 0x8a, 0x49, 0x29, 
+-      0x20, 0x17, 0xf0, 0x17, 0xf9, 0x93, 0x49, 0x28, 
+-      0x20, 0x08, 0xf0, 0x17, 0xf9, 0x8f, 0xf0, 0x17, 
+-      0xf9, 0x85, 0x4b, 0x26, 0x40, 0x18, 0xf0, 0x17, 
+-      0xf9, 0x85, 0x01, 0xe8, 0xf0, 0x17, 0xf9, 0x79, 
+-      0x48, 0x23, 0x23, 0x01, 0x22, 0x08, 0x21, 0x81, 
+-      0x01, 0x09, 0x60, 0x07, 0xf0, 0x0b, 0xfe, 0x84, 
+-      0xf0, 0x01, 0xfa, 0xd2, 0x49, 0x1f, 0x20, 0x04, 
+-      0xf0, 0x17, 0xf9, 0x78, 0xf0, 0x17, 0xf9, 0x6e, 
+-      0x23, 0x10, 0x43, 0xdb, 0x40, 0x18, 0xf0, 0x17, 
+-      0xf9, 0x6d, 0x20, 0x10, 0xf0, 0x17, 0xf9, 0x61, 
+-      0x87, 0x67, 0x21, 0x00, 0x1c, 0x30, 0xf7, 0xfd, 
+-      0xfd, 0x91, 0x1c, 0x38, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 
+-      0x2c, 0x00, 0x00, 0xfc, 0x2c, 0x00, 0x1f, 0xc0, 
+-      0x2e, 0x08, 0x04, 0x94, 0x07, 0x77, 0x77, 0x20, 
+-      0x72, 0x00, 0x02, 0x00, 0x2e, 0x08, 0x05, 0x5c, 
+-      0x6e, 0x00, 0x10, 0x00, 0x6e, 0x00, 0x11, 0x00, 
+-      0x6e, 0x00, 0x14, 0x00, 0x6e, 0x00, 0x15, 0x00, 
+-      0x6e, 0x00, 0x16, 0x00, 0x6e, 0x00, 0x17, 0x00, 
+-      0x6e, 0x00, 0x18, 0x00, 0xcc, 0x00, 0x0f, 0x80, 
+-      0x00, 0x80, 0x10, 0x80, 0x2e, 0x00, 0x56, 0x25, 
+-      0x2e, 0x00, 0x56, 0x45, 0xff, 0xff, 0xfe, 0xff, 
+-      0x2e, 0x08, 0x47, 0x50, 0x2e, 0x00, 0x56, 0x05, 
+-      0xb5, 0x90, 0x1c, 0x0c, 0x1c, 0x07, 0xf0, 0x17, 
+-      0xf9, 0x69, 0x2f, 0x01, 0xda, 0x00, 0x27, 0x01, 
+-      0x4b, 0x0e, 0x42, 0x9f, 0xdd, 0x00, 0x1c, 0x1f, 
+-      0x3f, 0x01, 0x04, 0x3f, 0x4b, 0x0c, 0x18, 0xff, 
+-      0x21, 0x03, 0x48, 0x0c, 0x60, 0x01, 0x60, 0x47, 
+-      0x21, 0x01, 0x60, 0x01, 0x20, 0x01, 0x1c, 0x21, 
+-      0xf0, 0x17, 0xf9, 0x20, 0xf0, 0x17, 0xf9, 0x16, 
+-      0x23, 0x02, 0x43, 0xdb, 0x40, 0x18, 0xf0, 0x17, 
+-      0xf9, 0x15, 0xf0, 0x17, 0xf9, 0x81, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 0xfd, 0xe8, 
+-      0x00, 0x00, 0x9e, 0x34, 0x6e, 0x00, 0x03, 0x00, 
+-      0xb5, 0x90, 0x1c, 0x0c, 0x1c, 0x07, 0xf0, 0x17, 
+-      0xf9, 0x3d, 0x2f, 0x01, 0xda, 0x00, 0x27, 0x01, 
+-      0x4b, 0x0e, 0x42, 0x9f, 0xdd, 0x00, 0x1c, 0x1f, 
+-      0x3f, 0x01, 0x04, 0x3f, 0x21, 0x03, 0x37, 0xff, 
+-      0x37, 0x96, 0x48, 0x0b, 0x60, 0x01, 0x60, 0x47, 
+-      0x21, 0x01, 0x60, 0x01, 0x20, 0x01, 0x1c, 0x21, 
+-      0xf0, 0x17, 0xf8, 0xf4, 0xf0, 0x17, 0xf8, 0xea, 
+-      0x23, 0x02, 0x43, 0xdb, 0x40, 0x18, 0xf0, 0x17, 
+-      0xf8, 0xe9, 0xf0, 0x17, 0xf9, 0x55, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 0xfd, 0xe8, 
+-      0x6e, 0x00, 0x03, 0x00, 0xb5, 0x00, 0xf0, 0x17, 
+-      0xf9, 0x15, 0x20, 0x03, 0x49, 0x05, 0x60, 0x08, 
+-      0xf0, 0x17, 0xf8, 0xd4, 0x23, 0x02, 0x43, 0x18, 
+-      0xf0, 0x17, 0xf8, 0xd4, 0xf0, 0x17, 0xf9, 0x40, 
+-      0xbc, 0x08, 0x47, 0x18, 0x6e, 0x00, 0x03, 0x00, 
+-      0xb5, 0x90, 0x1c, 0x0c, 0x1c, 0x07, 0xf0, 0x17, 
+-      0xf9, 0x01, 0x2f, 0x01, 0xda, 0x00, 0x27, 0x01, 
+-      0x4b, 0x0e, 0x42, 0x9f, 0xdd, 0x00, 0x1c, 0x1f, 
+-      0x3f, 0x01, 0x04, 0x3f, 0x4b, 0x0c, 0x18, 0xff, 
+-      0x21, 0x03, 0x48, 0x0c, 0x60, 0x01, 0x60, 0x47, 
+-      0x21, 0x01, 0x60, 0x01, 0x20, 0x05, 0x1c, 0x21, 
+-      0xf0, 0x17, 0xf8, 0xb8, 0xf0, 0x17, 0xf8, 0xae, 
+-      0x23, 0x20, 0x43, 0xdb, 0x40, 0x18, 0xf0, 0x17, 
+-      0xf8, 0xad, 0xf0, 0x17, 0xf9, 0x19, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 0xfd, 0xe8, 
+-      0x00, 0x00, 0x9e, 0x34, 0x6e, 0x00, 0x04, 0x00, 
+-      0xb5, 0x90, 0x1c, 0x0c, 0x1c, 0x07, 0xf0, 0x17, 
+-      0xf8, 0xd5, 0x2f, 0x01, 0xda, 0x00, 0x27, 0x01, 
+-      0x4b, 0x0e, 0x42, 0x9f, 0xdd, 0x00, 0x1c, 0x1f, 
+-      0x3f, 0x01, 0x04, 0x3f, 0x21, 0x03, 0x37, 0xff, 
+-      0x37, 0x96, 0x48, 0x0b, 0x60, 0x01, 0x60, 0x47, 
+-      0x21, 0x01, 0x60, 0x01, 0x20, 0x05, 0x1c, 0x21, 
+-      0xf0, 0x17, 0xf8, 0x8c, 0xf0, 0x17, 0xf8, 0x82, 
+-      0x23, 0x20, 0x43, 0xdb, 0x40, 0x18, 0xf0, 0x17, 
+-      0xf8, 0x81, 0xf0, 0x17, 0xf8, 0xed, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 0xfd, 0xe8, 
+-      0x6e, 0x00, 0x04, 0x00, 0xb5, 0x00, 0xf0, 0x17, 
+-      0xf8, 0xad, 0x20, 0x03, 0x49, 0x05, 0x60, 0x08, 
+-      0xf0, 0x17, 0xf8, 0x6c, 0x23, 0x20, 0x43, 0x18, 
+-      0xf0, 0x17, 0xf8, 0x6c, 0xf0, 0x17, 0xf8, 0xd8, 
+-      0xbc, 0x08, 0x47, 0x18, 0x6e, 0x00, 0x04, 0x00, 
+-      0xb5, 0x00, 0x48, 0x0b, 0x68, 0x41, 0x31, 0x14, 
+-      0x60, 0x41, 0x68, 0x81, 0x31, 0x01, 0x60, 0x81, 
+-      0x48, 0x08, 0x68, 0x00, 0x28, 0x00, 0xd0, 0x05, 
+-      0x28, 0x01, 0xd1, 0x01, 0xf7, 0xfe, 0xfa, 0x58, 
+-      0xbc, 0x08, 0x47, 0x18, 0x48, 0x04, 0x21, 0x10, 
+-      0xf0, 0x09, 0xfc, 0x82, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x05, 0xa8, 0x2e, 0x08, 0x04, 0xf8, 
+-      0x2e, 0x08, 0x05, 0xa8, 0xb5, 0x00, 0xf0, 0x17, 
+-      0xf8, 0x7d, 0x21, 0x00, 0x48, 0x08, 0x60, 0x41, 
+-      0x60, 0x81, 0x49, 0x08, 0x20, 0x07, 0xf0, 0x17, 
+-      0xf8, 0x41, 0xf0, 0x17, 0xf8, 0x37, 0x23, 0x80, 
+-      0x43, 0xdb, 0x40, 0x18, 0xf0, 0x17, 0xf8, 0x36, 
+-      0xf0, 0x17, 0xf8, 0xa2, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x05, 0xa8, 0x2e, 0x00, 0x5a, 0x45, 
+-      0x48, 0x01, 0x68, 0x40, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x05, 0xa8, 0xb5, 0x90, 0x49, 0x0d, 
+-      0x1c, 0x0f, 0x48, 0x0d, 0x24, 0x1e, 0x22, 0x10, 
+-      0x1c, 0x23, 0xf0, 0x09, 0xfd, 0x83, 0x22, 0x02, 
+-      0x21, 0x10, 0x1c, 0x38, 0x1c, 0x23, 0xf0, 0x05, 
+-      0xff, 0xeb, 0x49, 0x08, 0x20, 0x10, 0xf0, 0x17, 
+-      0xf8, 0x19, 0xf0, 0x17, 0xf8, 0x0f, 0x4b, 0x06, 
+-      0x40, 0x18, 0xf0, 0x17, 0xf8, 0x0f, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x47, 0x60, 
+-      0x2e, 0x08, 0x05, 0xa8, 0x2e, 0x00, 0x5b, 0x09, 
+-      0xff, 0xfe, 0xff, 0xff, 0xb5, 0x00, 0xb0, 0x86, 
+-      0x46, 0x68, 0x49, 0x0c, 0xc9, 0x0c, 0xc0, 0x0c, 
+-      0xc9, 0x0c, 0xc0, 0x0c, 0xc9, 0x0c, 0xc0, 0x0c, 
+-      0x48, 0x09, 0xab, 0x00, 0xcb, 0x0e, 0xb0, 0x03, 
+-      0xf0, 0x09, 0xfd, 0x88, 0xb0, 0x03, 0x48, 0x07, 
+-      0x68, 0x01, 0x08, 0x4a, 0xd3, 0x04, 0x08, 0x49, 
+-      0x00, 0x49, 0x23, 0x04, 0x43, 0x19, 0x60, 0x01, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x47, 0x60, 
+-      0x2e, 0x08, 0x05, 0xa8, 0x2e, 0x08, 0x00, 0x04, 
+-      0xb5, 0x80, 0x29, 0x0c, 0xd2, 0x00, 0x21, 0x0c, 
+-      0x31, 0x07, 0x08, 0xc9, 0x00, 0xc9, 0x27, 0x00, 
+-      0x68, 0x02, 0x42, 0x82, 0xd0, 0x03, 0x68, 0x93, 
+-      0x42, 0x8b, 0xd3, 0x0d, 0x1c, 0x17, 0x2f, 0x00, 
+-      0xd0, 0x1e, 0x68, 0xb8, 0x1a, 0x42, 0x2a, 0x0c, 
+-      0xd2, 0x00, 0x1c, 0x01, 0x1a, 0x42, 0xd1, 0x05, 
+-      0x1c, 0x38, 0xf0, 0x00, 0xf8, 0x76, 0xe0, 0x0c, 
+-      0x68, 0x12, 0xe7, 0xea, 0x1d, 0xca, 0x32, 0x01, 
+-      0x1a, 0x80, 0x60, 0xb8, 0x19, 0xc0, 0x1d, 0xc7, 
+-      0x37, 0x01, 0x20, 0x00, 0x60, 0x38, 0x60, 0x78, 
+-      0x60, 0xb9, 0x68, 0xb8, 0x60, 0x38, 0x1d, 0xf8, 
+-      0x30, 0x01, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x20, 0x00, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0xb0, 0x1f, 0xcc, 0x3c, 0x01, 0x68, 0x21, 
+-      0x19, 0x0a, 0x60, 0xa1, 0x68, 0x07, 0x32, 0x08, 
+-      0x42, 0x87, 0xd1, 0x06, 0x68, 0x41, 0x1c, 0x20, 
+-      0xf0, 0x00, 0xf8, 0x48, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x42, 0x97, 0xd1, 0x0f, 0x68, 0x7d, 
+-      0x1c, 0x38, 0xf0, 0x00, 0xf8, 0x46, 0x68, 0xa0, 
+-      0x68, 0xb9, 0x18, 0x40, 0x30, 0x08, 0x60, 0xa0, 
+-      0x1c, 0x20, 0x1c, 0x29, 0xf0, 0x00, 0xf8, 0x36, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x68, 0xbb, 
+-      0x19, 0xdb, 0x33, 0x08, 0x42, 0xa3, 0xd1, 0x13, 
+-      0x68, 0xb8, 0x18, 0x40, 0x30, 0x08, 0x60, 0xb8, 
+-      0x19, 0xc0, 0x68, 0x3c, 0x30, 0x08, 0x42, 0xa0, 
+-      0xd1, 0xdc, 0x1c, 0x20, 0xf0, 0x00, 0xf8, 0x29, 
+-      0x68, 0xb8, 0x68, 0xa1, 0x18, 0x40, 0x30, 0x08, 
+-      0x60, 0xb8, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x42, 0xbc, 0xd2, 0x06, 0x68, 0x79, 0x1c, 0x20, 
+-      0xf0, 0x00, 0xf8, 0x14, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x68, 0x3f, 0xe7, 0xc0, 0xb5, 0x00, 
+-      0x31, 0x10, 0x32, 0x01, 0x1c, 0x0b, 0x1a, 0x51, 
+-      0x39, 0x08, 0x60, 0x99, 0x60, 0x00, 0x1c, 0x01, 
+-      0x60, 0x40, 0x1c, 0x18, 0xf0, 0x00, 0xf8, 0x02, 
+-      0xbc, 0x08, 0x47, 0x18, 0x68, 0x0a, 0x60, 0x02, 
+-      0x60, 0x08, 0x68, 0x02, 0x60, 0x50, 0x60, 0x41, 
+-      0x47, 0x70, 0xc8, 0x06, 0x38, 0x08, 0x60, 0x11, 
+-      0xc8, 0x03, 0x60, 0x41, 0x47, 0x70, 0xb5, 0x00, 
+-      0x1c, 0x0a, 0x1c, 0x01, 0x48, 0x02, 0xf7, 0xff, 
+-      0xff, 0xde, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x05, 0xcc, 0xb5, 0x90, 0x1c, 0x07, 
+-      0xf0, 0x16, 0xff, 0x38, 0x23, 0x11, 0x05, 0x1b, 
+-      0x1c, 0x04, 0x43, 0x18, 0xf0, 0x16, 0xff, 0x36, 
+-      0x1c, 0x39, 0x48, 0x05, 0xf7, 0xff, 0xff, 0x50, 
+-      0x1c, 0x07, 0x1c, 0x20, 0xf0, 0x16, 0xff, 0x2e, 
+-      0x1c, 0x38, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x05, 0xcc, 0xb5, 0x00, 0x1c, 0x01, 
+-      0x48, 0x02, 0xf7, 0xff, 0xff, 0x41, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x05, 0xcc, 
+-      0xb5, 0x90, 0x1c, 0x07, 0xd0, 0x0e, 0xf0, 0x16, 
+-      0xff, 0x15, 0x23, 0x11, 0x05, 0x1b, 0x1c, 0x04, 
+-      0x43, 0x18, 0xf0, 0x16, 0xff, 0x13, 0x1c, 0x39, 
+-      0x48, 0x04, 0xf7, 0xff, 0xff, 0x61, 0x1c, 0x20, 
+-      0xf0, 0x16, 0xff, 0x0c, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x05, 0xcc, 
+-      0xb5, 0x00, 0x4a, 0x04, 0xc2, 0x03, 0x1c, 0x0a, 
+-      0x1c, 0x01, 0x48, 0x03, 0xf7, 0xff, 0xff, 0x97, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x05, 0xb4, 
+-      0x2e, 0x08, 0x05, 0xc4, 0xb5, 0x00, 0x1c, 0x01, 
+-      0x48, 0x02, 0xf7, 0xff, 0xff, 0x11, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x05, 0xc4, 
+-      0xb5, 0x00, 0x49, 0x08, 0x68, 0x0a, 0x42, 0x90, 
+-      0xd3, 0x02, 0x68, 0x49, 0x42, 0x88, 0xd9, 0x03, 
+-      0xf7, 0xff, 0xff, 0xc6, 0xbc, 0x08, 0x47, 0x18, 
+-      0x1c, 0x01, 0x48, 0x03, 0xf7, 0xff, 0xff, 0x30, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x05, 0xb4, 
+-      0x2e, 0x08, 0x05, 0xc4, 0xb5, 0x00, 0x4a, 0x05, 
+-      0x60, 0x90, 0x60, 0xd1, 0x1c, 0x0a, 0x1c, 0x01, 
+-      0x48, 0x03, 0xf7, 0xff, 0xff, 0x68, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x05, 0xb4, 
+-      0x2e, 0x08, 0x05, 0xd4, 0xb5, 0x00, 0x1c, 0x01, 
+-      0x48, 0x02, 0xf7, 0xff, 0xfe, 0xe1, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x05, 0xd4, 
+-      0xb5, 0x00, 0x49, 0x08, 0x68, 0x8a, 0x42, 0x90, 
+-      0xd3, 0x02, 0x68, 0xc9, 0x42, 0x88, 0xd9, 0x03, 
+-      0xf7, 0xff, 0xff, 0x96, 0xbc, 0x08, 0x47, 0x18, 
+-      0x1c, 0x01, 0x48, 0x03, 0xf7, 0xff, 0xff, 0x00, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x05, 0xb4, 
+-      0x2e, 0x08, 0x05, 0xd4, 0xb5, 0xf0, 0x06, 0x07, 
+-      0x0e, 0x3f, 0x04, 0x09, 0x0c, 0x09, 0xb0, 0x81, 
+-      0x91, 0x00, 0x06, 0x16, 0x0e, 0x36, 0x00, 0xbd, 
+-      0x4c, 0x15, 0x59, 0x60, 0x28, 0x00, 0xd1, 0x15, 
+-      0xf7, 0xfb, 0xf9, 0x10, 0x22, 0x00, 0xb4, 0x04, 
+-      0x23, 0x00, 0x22, 0x02, 0x99, 0x01, 0x1c, 0x38, 
+-      0xf0, 0x05, 0xf9, 0xaa, 0x23, 0x01, 0x02, 0x9b, 
+-      0x00, 0x5a, 0x21, 0x01, 0x1c, 0x38, 0xb0, 0x01, 
+-      0xf0, 0x05, 0xfb, 0x66, 0x20, 0x03, 0x00, 0x71, 
+-      0x4a, 0x0a, 0x52, 0x50, 0x59, 0x60, 0x30, 0x01, 
+-      0x51, 0x60, 0x48, 0x09, 0x23, 0x14, 0x5e, 0xc1, 
+-      0x29, 0x00, 0xd1, 0x02, 0x49, 0x07, 0x4a, 0x08, 
+-      0x65, 0xd1, 0x8a, 0x81, 0x31, 0x01, 0x82, 0x81, 
+-      0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x02, 0x5c, 0x10, 0x2e, 0x08, 0x49, 0x70, 
+-      0x2e, 0x08, 0x07, 0x5c, 0x2e, 0x02, 0x5a, 0x20, 
+-      0xa0, 0x00, 0x0d, 0x00, 0xb5, 0xb0, 0x06, 0x07, 
+-      0x0e, 0x3f, 0x06, 0x0d, 0x0e, 0x2d, 0x00, 0xb9, 
+-      0x48, 0x1b, 0x58, 0x42, 0x3a, 0x01, 0x50, 0x42, 
+-      0x24, 0x00, 0x2a, 0x00, 0xd1, 0x1f, 0x23, 0x01, 
+-      0x02, 0x9b, 0x00, 0x5a, 0x21, 0x02, 0x1c, 0x38, 
+-      0xf0, 0x05, 0xfb, 0x32, 0x22, 0x00, 0xb4, 0x04, 
+-      0x1c, 0x38, 0x1c, 0x23, 0x49, 0x13, 0xf0, 0x05, 
+-      0xf9, 0x67, 0x00, 0x69, 0xb0, 0x01, 0x48, 0x12, 
+-      0x52, 0x44, 0x48, 0x10, 0x4a, 0x11, 0x52, 0x50, 
+-      0x00, 0x79, 0x4a, 0x11, 0x52, 0x50, 0x00, 0x6a, 
+-      0x19, 0x52, 0x00, 0x92, 0x4b, 0x0f, 0x18, 0xd1, 
+-      0x81, 0x0c, 0x52, 0x98, 0x80, 0x48, 0x48, 0x0e, 
+-      0x8a, 0x81, 0x39, 0x01, 0x82, 0x81, 0x23, 0x14, 
+-      0x5e, 0xc0, 0x28, 0x00, 0xd1, 0x03, 0x20, 0xd7, 
+-      0x00, 0xc0, 0x49, 0x0a, 0x65, 0xc8, 0x1c, 0x20, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x02, 0x5c, 0x10, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x49, 0x70, 0x2e, 0x08, 0x49, 0x30, 
+-      0x2e, 0x08, 0x48, 0xf8, 0x2e, 0x08, 0x47, 0x78, 
+-      0x2e, 0x08, 0x07, 0x5c, 0xa0, 0x00, 0x0d, 0x00, 
+-      0xb5, 0xf0, 0x04, 0x06, 0x0c, 0x36, 0x04, 0x0c, 
+-      0x0c, 0x24, 0x1c, 0x17, 0xb0, 0x8a, 0x46, 0x69, 
+-      0x1c, 0x30, 0x1c, 0x22, 0xf0, 0x00, 0xf8, 0xb0, 
+-      0x23, 0x01, 0x1c, 0x05, 0x42, 0xd8, 0xd1, 0x03, 
+-      0xb0, 0x0a, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x4b, 0x4e, 0x42, 0x9c, 0xd1, 0x06, 0xa8, 0x00, 
+-      0x88, 0x00, 0x1c, 0x31, 0x1c, 0x2a, 0xf7, 0xff, 
+-      0xff, 0x55, 0xe0, 0x7f, 0x20, 0x20, 0x40, 0x20, 
+-      0x28, 0x20, 0xd1, 0x1f, 0x06, 0x2a, 0x0e, 0x12, 
+-      0xa8, 0x00, 0x88, 0x00, 0x06, 0x00, 0x0e, 0x00, 
+-      0x1c, 0x31, 0x1c, 0x23, 0xf7, 0xfd, 0xf8, 0x5a, 
+-      0x28, 0x00, 0xd0, 0x6f, 0x48, 0x42, 0x00, 0x69, 
+-      0x4a, 0x42, 0x52, 0x50, 0xa9, 0x00, 0x88, 0x09, 
+-      0x00, 0x49, 0x4a, 0x41, 0x52, 0x50, 0xa8, 0x00, 
+-      0x88, 0x00, 0x1c, 0x29, 0xf0, 0x00, 0xf9, 0xce, 
+-      0x20, 0x00, 0x43, 0xc0, 0xb0, 0x0a, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x20, 0x00, 0x21, 0x00, 
+-      0xaa, 0x01, 0x88, 0x3b, 0x0a, 0x1b, 0x70, 0x13, 
+-      0x88, 0x3b, 0x93, 0x09, 0x32, 0x01, 0x06, 0x1b, 
+-      0xd0, 0x02, 0x1c, 0x48, 0x06, 0x00, 0x0e, 0x00, 
+-      0x9b, 0x09, 0x70, 0x13, 0x31, 0x01, 0x32, 0x01, 
+-      0x37, 0x02, 0x29, 0x0e, 0xdb, 0xed, 0x21, 0x00, 
+-      0x23, 0x00, 0x70, 0x13, 0x31, 0x01, 0x32, 0x01, 
+-      0x29, 0x04, 0xdb, 0xfa, 0x21, 0x0c, 0x40, 0x21, 
+-      0x29, 0x0c, 0xd1, 0x03, 0x04, 0x21, 0x0c, 0x09, 
+-      0x24, 0x01, 0x43, 0x0c, 0x28, 0x06, 0xdc, 0x0e, 
+-      0x06, 0x22, 0x0e, 0x12, 0xb4, 0x04, 0x06, 0x2a, 
+-      0x0e, 0x12, 0xa8, 0x01, 0x88, 0x00, 0x06, 0x00, 
+-      0x0e, 0x00, 0x1c, 0x31, 0xab, 0x02, 0xf7, 0xfc, 
+-      0xfc, 0x37, 0xb0, 0x01, 0xe0, 0x1e, 0x28, 0x0a, 
+-      0xdc, 0x0e, 0x06, 0x22, 0x0e, 0x12, 0xb4, 0x04, 
+-      0x06, 0x2a, 0x0e, 0x12, 0xa8, 0x01, 0x88, 0x00, 
+-      0x06, 0x00, 0x0e, 0x00, 0x1c, 0x31, 0xab, 0x02, 
+-      0xf7, 0xfc, 0xfc, 0x40, 0xb0, 0x01, 0xe0, 0x0d, 
+-      0x06, 0x22, 0x0e, 0x12, 0xb4, 0x04, 0x06, 0x2a, 
+-      0x0e, 0x12, 0xa8, 0x01, 0x88, 0x00, 0x06, 0x00, 
+-      0x0e, 0x00, 0x1c, 0x31, 0xab, 0x02, 0xf7, 0xfc, 
+-      0xfc, 0x4b, 0xb0, 0x01, 0x28, 0x00, 0xd0, 0x05, 
+-      0x20, 0x00, 0x43, 0xc0, 0xb0, 0x0a, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xe7, 0xff, 0xa8, 0x00, 
+-      0x88, 0x00, 0x00, 0x6a, 0x19, 0x52, 0x00, 0x92, 
+-      0x49, 0x0a, 0x52, 0x88, 0x18, 0x50, 0x80, 0x46, 
+-      0x80, 0x84, 0x49, 0x05, 0x80, 0xc1, 0x21, 0x01, 
+-      0x81, 0x01, 0x1c, 0x28, 0xb0, 0x0a, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 0xb9, 0x6a, 
+-      0x00, 0x00, 0xff, 0xff, 0x2e, 0x08, 0x49, 0x30, 
+-      0x2e, 0x08, 0x48, 0xf8, 0x2e, 0x08, 0x47, 0x78, 
+-      0xb4, 0xf0, 0x04, 0x04, 0x0c, 0x24, 0x04, 0x17, 
+-      0x0c, 0x3f, 0xb0, 0x82, 0x48, 0x58, 0x22, 0x00, 
+-      0x4d, 0x58, 0x95, 0x01, 0x1c, 0x06, 0x00, 0x53, 
+-      0x9d, 0x01, 0x5a, 0xed, 0x42, 0xb5, 0xd1, 0x02, 
+-      0x04, 0x10, 0x0c, 0x00, 0xe0, 0x02, 0x32, 0x01, 
+-      0x2a, 0x20, 0xdb, 0xf4, 0x42, 0xb0, 0xd1, 0x04, 
+-      0x20, 0x00, 0x43, 0xc0, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0x47, 0x70, 0x80, 0x0e, 0x4a, 0x4e, 0x92, 0x00, 
+-      0x4d, 0x4e, 0x4a, 0x4f, 0x4b, 0x4f, 0x42, 0x9f, 
+-      0xd1, 0x32, 0x23, 0x00, 0x00, 0x5f, 0x5b, 0xd7, 
+-      0x42, 0xa7, 0xd1, 0x0a, 0x00, 0x5f, 0x5b, 0xef, 
+-      0x2f, 0x03, 0xd1, 0x01, 0x80, 0x0b, 0xe0, 0x07, 
+-      0x20, 0x00, 0x43, 0xc0, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0x47, 0x70, 0x33, 0x01, 0x2b, 0x1c, 0xdb, 0xed, 
+-      0x88, 0x0f, 0x4b, 0x3f, 0x42, 0x9f, 0xd1, 0x0a, 
+-      0x27, 0x00, 0x00, 0x7b, 0x5a, 0xd6, 0x4b, 0x3c, 
+-      0x42, 0x9e, 0xd1, 0x01, 0x80, 0x0f, 0xe0, 0x02, 
+-      0x37, 0x01, 0x2f, 0x1c, 0xdb, 0xf5, 0x88, 0x0f, 
+-      0x4b, 0x37, 0x42, 0x9f, 0xd1, 0x04, 0x20, 0x00, 
+-      0x43, 0xc0, 0xb0, 0x02, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x23, 0x03, 0x00, 0x47, 0x9e, 0x00, 0x53, 0xf3, 
+-      0x88, 0x0f, 0x00, 0x7f, 0x53, 0xeb, 0xe0, 0x54, 
+-      0x23, 0x20, 0x40, 0x3b, 0x2b, 0x20, 0xd1, 0x1e, 
+-      0x23, 0x00, 0x00, 0x5f, 0x5b, 0xd7, 0x42, 0xa7, 
+-      0xd1, 0x04, 0x20, 0x00, 0x43, 0xc0, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0x47, 0x70, 0x33, 0x01, 0x2b, 0x1c, 
+-      0xdb, 0xf3, 0x27, 0x00, 0x00, 0x7b, 0x5a, 0xd5, 
+-      0x42, 0xb5, 0xd1, 0x01, 0x80, 0x0f, 0xe0, 0x02, 
+-      0x37, 0x01, 0x2f, 0x1c, 0xdb, 0xf6, 0x88, 0x0f, 
+-      0x42, 0xb7, 0xd1, 0x36, 0x20, 0x00, 0x43, 0xc0, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0x47, 0x70, 0x23, 0x00, 
+-      0x00, 0x5f, 0x5b, 0xd7, 0x42, 0xa7, 0xd1, 0x0a, 
+-      0x00, 0x5f, 0x5b, 0xef, 0x2f, 0x02, 0xd1, 0x01, 
+-      0x80, 0x0b, 0xe0, 0x07, 0x20, 0x00, 0x43, 0xc0, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0x47, 0x70, 0x33, 0x01, 
+-      0x2b, 0x1c, 0xdb, 0xed, 0x88, 0x0f, 0x4b, 0x14, 
+-      0x42, 0x9f, 0xd1, 0x0a, 0x27, 0x00, 0x00, 0x7b, 
+-      0x5a, 0xd6, 0x4b, 0x11, 0x42, 0x9e, 0xd1, 0x01, 
+-      0x80, 0x0f, 0xe0, 0x02, 0x37, 0x01, 0x2f, 0x1c, 
+-      0xdb, 0xf5, 0x88, 0x0f, 0x4b, 0x0c, 0x42, 0x9f, 
+-      0xd1, 0x04, 0x20, 0x00, 0x43, 0xc0, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0x47, 0x70, 0x23, 0x02, 0x00, 0x47, 
+-      0x9e, 0x00, 0x53, 0xf3, 0x88, 0x0f, 0x00, 0x7f, 
+-      0x53, 0xeb, 0x00, 0x43, 0x9d, 0x01, 0x52, 0xec, 
+-      0x88, 0x09, 0x00, 0x49, 0x52, 0x54, 0x04, 0x00, 
+-      0x14, 0x00, 0xb0, 0x02, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x00, 0x00, 0xff, 0xff, 0x2e, 0x08, 0x49, 0x30, 
+-      0x2e, 0x08, 0x49, 0x70, 0x2e, 0x08, 0x49, 0xb0, 
+-      0x2e, 0x08, 0x48, 0xf8, 0x00, 0x00, 0xb9, 0x6a, 
+-      0xb5, 0xf0, 0x04, 0x07, 0x0c, 0x3f, 0xb0, 0x81, 
+-      0x4a, 0x34, 0x92, 0x00, 0x1c, 0x11, 0x42, 0x97, 
+-      0xd0, 0x01, 0x2f, 0x20, 0xdb, 0x05, 0x20, 0x00, 
+-      0x43, 0xc0, 0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x7c, 0x4a, 0x2e, 0x5b, 0x10, 
+-      0x42, 0x88, 0xd1, 0x05, 0x20, 0x00, 0x43, 0xc0, 
+-      0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x49, 0x28, 0x53, 0x11, 0x23, 0x00, 0x49, 0x29, 
+-      0x00, 0x5e, 0x5b, 0x8e, 0x42, 0x86, 0xd1, 0x02, 
+-      0x04, 0x1d, 0x0c, 0x2d, 0xe0, 0x02, 0x33, 0x01, 
+-      0x2b, 0x1c, 0xdb, 0xf5, 0x23, 0x00, 0x00, 0x5e, 
+-      0x5b, 0x96, 0x42, 0x86, 0xd1, 0x03, 0x04, 0x1a, 
+-      0x0c, 0x12, 0x92, 0x00, 0xe0, 0x02, 0x33, 0x01, 
+-      0x2b, 0x20, 0xdb, 0xf4, 0x9a, 0x00, 0x4e, 0x1b, 
+-      0x42, 0xb2, 0xd1, 0x0d, 0x22, 0x00, 0x00, 0x53, 
+-      0x5a, 0xcb, 0x42, 0x83, 0xd1, 0x05, 0x23, 0x00, 
+-      0x00, 0x50, 0x4a, 0x19, 0x52, 0x13, 0x52, 0x0e, 
+-      0xe0, 0x02, 0x32, 0x01, 0x2a, 0x1c, 0xdb, 0xf2, 
+-      0x4e, 0x16, 0x5b, 0x30, 0x28, 0x02, 0xd1, 0x05, 
+-      0x23, 0x00, 0x53, 0x33, 0x1c, 0x28, 0x1c, 0x39, 
+-      0xf0, 0x00, 0xf8, 0x38, 0x5b, 0x30, 0x28, 0x01, 
+-      0xd1, 0x0a, 0x1c, 0x38, 0xf7, 0xfc, 0xff, 0xce, 
+-      0x28, 0x00, 0xd0, 0x05, 0x20, 0x00, 0x43, 0xc0, 
+-      0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x5b, 0x30, 0x28, 0x03, 0xd1, 0x03, 0x1c, 0x28, 
+-      0x1c, 0x39, 0xf7, 0xff, 0xfd, 0xcb, 0x04, 0x38, 
+-      0x14, 0x00, 0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x49, 0x30, 0x2e, 0x08, 0x48, 0xf8, 
+-      0x2e, 0x08, 0x49, 0xb0, 0x2e, 0x08, 0x49, 0x70, 
+-      0x04, 0x01, 0x0c, 0x09, 0x20, 0x02, 0x00, 0x4b, 
+-      0x18, 0x5b, 0x00, 0x9b, 0x4a, 0x03, 0x18, 0x99, 
+-      0x81, 0x08, 0x48, 0x03, 0x52, 0xd0, 0x80, 0x48, 
+-      0x47, 0x70, 0x00, 0x00, 0x2e, 0x08, 0x47, 0x78, 
+-      0x00, 0x00, 0xff, 0xff, 0xb5, 0x80, 0x04, 0x0f, 
+-      0x0c, 0x3f, 0x06, 0x39, 0x0e, 0x09, 0x06, 0x00, 
+-      0x0e, 0x00, 0xf7, 0xfc, 0xfc, 0x03, 0x20, 0x00, 
+-      0x00, 0x7b, 0x19, 0xdb, 0x00, 0x9b, 0x4a, 0x04, 
+-      0x18, 0x99, 0x81, 0x08, 0x48, 0x03, 0x52, 0xd0, 
+-      0x80, 0x48, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x47, 0x78, 0x00, 0x00, 0xff, 0xff, 
+-      0xb5, 0x80, 0x04, 0x09, 0x0c, 0x09, 0x78, 0x42, 
+-      0x02, 0x12, 0x78, 0x83, 0x43, 0x1a, 0x05, 0x12, 
+-      0x0d, 0x12, 0x27, 0x00, 0x43, 0xff, 0x32, 0x03, 
+-      0x42, 0x8a, 0xd0, 0x03, 0x1c, 0x38, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0xf0, 0x05, 0xfd, 0xec, 
+-      0x28, 0x00, 0xd0, 0x03, 0x1c, 0x38, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x20, 0x00, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xff, 0x9c, 0x09, 
+-      0x04, 0x00, 0x0c, 0x00, 0xb0, 0x81, 0x90, 0x00, 
+-      0x06, 0x09, 0x0e, 0x09, 0x06, 0x12, 0x0e, 0x12, 
+-      0xb0, 0x88, 0x4f, 0x16, 0x68, 0xb8, 0x28, 0x0c, 
+-      0xdb, 0x06, 0x20, 0x00, 0x43, 0xc0, 0xb0, 0x09, 
+-      0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x20, 0x00, 0x23, 0x00, 0x00, 0x45, 0x46, 0x6e, 
+-      0x53, 0x73, 0x30, 0x01, 0x04, 0x00, 0x14, 0x00, 
+-      0x28, 0x10, 0xdb, 0xf7, 0x02, 0x08, 0x43, 0x10, 
+-      0xab, 0x00, 0x80, 0x18, 0x46, 0x6a, 0x21, 0x04, 
+-      0x98, 0x08, 0xf7, 0xff, 0xfd, 0x95, 0x28, 0x00, 
+-      0xda, 0x01, 0xb0, 0x09, 0xe7, 0xe4, 0x00, 0x81, 
+-      0x4a, 0x05, 0x50, 0x54, 0x9b, 0x0c, 0x4a, 0x05, 
+-      0x50, 0x53, 0x68, 0xb9, 0x31, 0x01, 0x60, 0xb9, 
+-      0xb0, 0x09, 0xe7, 0xd9, 0x2e, 0x08, 0x07, 0x74, 
+-      0x2e, 0x08, 0x4a, 0x68, 0x2e, 0x08, 0x49, 0xe8, 
+-      0xb5, 0x80, 0x04, 0x07, 0x14, 0x3f, 0xd5, 0x04, 
+-      0x20, 0x00, 0x43, 0xc0, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x1c, 0x38, 0xf7, 0xff, 0xfe, 0xf4, 
+-      0x20, 0x00, 0x00, 0xb9, 0x4a, 0x05, 0x50, 0x50, 
+-      0x4a, 0x05, 0x50, 0x50, 0x49, 0x05, 0x68, 0x8a, 
+-      0x3a, 0x01, 0x60, 0x8a, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x49, 0xe8, 
+-      0x2e, 0x08, 0x4a, 0x68, 0x2e, 0x08, 0x07, 0x74, 
+-      0xb5, 0x90, 0x27, 0x00, 0x4c, 0x08, 0x00, 0xb8, 
+-      0x58, 0x20, 0x28, 0x00, 0xd0, 0x02, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xff, 0xd6, 0x37, 0x01, 0x2f, 0x20, 
+-      0xdb, 0xf5, 0x20, 0x00, 0x49, 0x03, 0x60, 0xc8, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x49, 0xe8, 0x2e, 0x08, 0x07, 0x74, 
+-      0xb5, 0x00, 0xf7, 0xff, 0xff, 0xe5, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0xf0, 0x04, 0x00, 0x14, 0x00, 
+-      0xb0, 0x83, 0x90, 0x00, 0x1c, 0x0f, 0x04, 0x11, 
+-      0x0c, 0x09, 0x24, 0x00, 0x1c, 0x38, 0x1c, 0x1d, 
+-      0x1c, 0x0e, 0xb0, 0x81, 0xf7, 0xff, 0xff, 0x58, 
+-      0x1c, 0x01, 0x20, 0x00, 0x29, 0x00, 0xd0, 0x03, 
+-      0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x78, 0xf9, 0x02, 0x09, 0x79, 0x3a, 0x43, 0x11, 
+-      0x04, 0x09, 0x0c, 0x09, 0x88, 0x2a, 0x42, 0x91, 
+-      0xd0, 0x03, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x7a, 0x39, 0x02, 0x09, 0x7a, 0x7a, 
+-      0x43, 0x11, 0x04, 0xc9, 0x0c, 0xc9, 0x91, 0x00, 
+-      0x7a, 0xb9, 0x02, 0x09, 0x7a, 0xfa, 0x43, 0x11, 
+-      0x05, 0x0b, 0x0d, 0x1b, 0x1d, 0xf9, 0x31, 0x05, 
+-      0x27, 0x00, 0x1d, 0xd8, 0x30, 0x09, 0x1a, 0x32, 
+-      0x2b, 0x00, 0xdd, 0x0a, 0x78, 0x08, 0x28, 0x09, 
+-      0xd1, 0x00, 0x37, 0x01, 0x78, 0x48, 0x1c, 0x85, 
+-      0x1b, 0x5b, 0x18, 0x40, 0x1c, 0x81, 0x2b, 0x00, 
+-      0xdc, 0xf4, 0x2a, 0x00, 0xdd, 0x36, 0x48, 0x26, 
+-      0x88, 0x06, 0x96, 0x03, 0x88, 0x85, 0x95, 0x02, 
+-      0x78, 0xc8, 0x02, 0x00, 0x79, 0x0b, 0x43, 0x18, 
+-      0x05, 0x00, 0x0d, 0x00, 0x78, 0x0b, 0x2b, 0x01, 
+-      0xd0, 0x01, 0x2b, 0x02, 0xd1, 0x06, 0x78, 0x4d, 
+-      0x02, 0x2d, 0x78, 0x8e, 0x43, 0x35, 0x04, 0xed, 
+-      0x0c, 0xed, 0x9e, 0x03, 0x2b, 0x04, 0xd0, 0x01, 
+-      0x2b, 0x03, 0xd1, 0x09, 0x78, 0x4b, 0x02, 0x1b, 
+-      0x78, 0x8d, 0x43, 0x2b, 0x04, 0xdb, 0x0c, 0xdb, 
+-      0x9d, 0x02, 0x42, 0xab, 0xd1, 0x00, 0x24, 0x01, 
+-      0x1d, 0x43, 0x1a, 0xd2, 0x31, 0x05, 0x28, 0x00, 
+-      0xdd, 0x0a, 0x78, 0x0b, 0x2b, 0x09, 0xd1, 0x00, 
+-      0x37, 0x01, 0x78, 0x4b, 0x1c, 0x9d, 0x1b, 0x40, 
+-      0x18, 0x59, 0x31, 0x02, 0x28, 0x00, 0xdc, 0xf4, 
+-      0x2a, 0x00, 0xdc, 0xcd, 0x2c, 0x00, 0xd0, 0x09, 
+-      0xf7, 0xff, 0xff, 0x62, 0x99, 0x00, 0x48, 0x09, 
+-      0x80, 0x01, 0x2f, 0x00, 0xd1, 0x07, 0xf7, 0xfa, 
+-      0xf8, 0x45, 0xe0, 0x04, 0x98, 0x01, 0xf7, 0xff, 
+-      0xff, 0x37, 0xf0, 0x00, 0xf8, 0x23, 0x20, 0x00, 
+-      0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x07, 0x74, 0x2e, 0x08, 0x00, 0x08, 
+-      0xb4, 0x90, 0x04, 0x02, 0x0c, 0x12, 0x04, 0x0f, 
+-      0x0c, 0x3f, 0x4b, 0x07, 0x68, 0xd8, 0x28, 0x80, 
+-      0xda, 0x08, 0x2a, 0x00, 0xd0, 0x06, 0x00, 0x41, 
+-      0x4c, 0x04, 0x52, 0x67, 0x4f, 0x04, 0x52, 0x7a, 
+-      0x30, 0x01, 0x60, 0xd8, 0xbc, 0x90, 0x47, 0x70, 
+-      0x2e, 0x08, 0x07, 0x74, 0x2e, 0x08, 0x4a, 0xe8, 
+-      0x2e, 0x08, 0x4b, 0xe8, 0xb5, 0x90, 0x4f, 0x13, 
+-      0x24, 0x00, 0x43, 0xe4, 0x68, 0xf8, 0x28, 0x00, 
+-      0xd1, 0x03, 0x1c, 0x20, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x40, 0x49, 0x0e, 0x18, 0x41, 
+-      0x1e, 0x8a, 0xb4, 0x04, 0x49, 0x0d, 0x18, 0x40, 
+-      0x38, 0x40, 0x8f, 0xc0, 0x4b, 0x0c, 0x22, 0xff, 
+-      0x21, 0x02, 0xf7, 0xff, 0xfe, 0xbb, 0xb0, 0x01, 
+-      0x28, 0x00, 0xda, 0x03, 0x1c, 0x20, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x68, 0xf8, 0x38, 0x01, 
+-      0x60, 0xf8, 0x20, 0x00, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x07, 0x74, 
+-      0x2e, 0x08, 0x4b, 0xe8, 0x2e, 0x08, 0x4a, 0xe8, 
+-      0x2e, 0x00, 0x64, 0x57, 0xb5, 0xf0, 0x04, 0x05, 
+-      0x14, 0x2d, 0x1c, 0x0f, 0x04, 0x11, 0x0c, 0x09, 
+-      0x1c, 0x0e, 0x4c, 0x28, 0x23, 0x02, 0x69, 0x20, 
+-      0x42, 0xd8, 0xd0, 0x04, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfe, 0x77, 0x28, 0x00, 0xd0, 0x06, 0x1c, 0x28, 
+-      0xf7, 0xff, 0xfe, 0xce, 0x20, 0x00, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x79, 0xb8, 0x69, 0x21, 
+-      0x42, 0x88, 0xd1, 0x09, 0x20, 0x01, 0x43, 0xc0, 
+-      0x61, 0x20, 0x1c, 0x28, 0xf7, 0xff, 0xfe, 0xc0, 
+-      0x20, 0x00, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x23, 0x01, 0x42, 0xd9, 0xd1, 0x02, 0x61, 0x20, 
+-      0x20, 0x00, 0x60, 0xe0, 0x37, 0x08, 0x1f, 0xf4, 
+-      0x3c, 0x05, 0x2c, 0x00, 0xdd, 0x11, 0x78, 0x38, 
+-      0x02, 0x00, 0x78, 0x79, 0x43, 0x08, 0x04, 0x00, 
+-      0x0c, 0x00, 0x78, 0xb9, 0x02, 0x09, 0x78, 0xfa, 
+-      0x43, 0x11, 0x04, 0xc9, 0x0c, 0xc9, 0xf7, 0xff, 
+-      0xff, 0x77, 0x37, 0x04, 0x3c, 0x04, 0x2c, 0x00, 
+-      0xdc, 0xed, 0xf7, 0xff, 0xff, 0x8b, 0xf7, 0xff, 
+-      0xff, 0x89, 0xf7, 0xff, 0xff, 0x87, 0xf7, 0xff, 
+-      0xff, 0x85, 0xf7, 0xff, 0xff, 0x83, 0xf7, 0xff, 
+-      0xff, 0x81, 0xf7, 0xff, 0xff, 0x7f, 0xf7, 0xff, 
+-      0xff, 0x7d, 0x20, 0x00, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x07, 0x74, 
+-      0xb5, 0xf0, 0x04, 0x04, 0x0c, 0x24, 0x04, 0x0d, 
+-      0x0c, 0x2d, 0x26, 0x00, 0x43, 0xf6, 0x4f, 0x0f, 
+-      0x62, 0x3e, 0x61, 0xfe, 0x61, 0xbe, 0xf7, 0xff, 
+-      0xfe, 0x9b, 0x2d, 0x00, 0xd0, 0x13, 0x2c, 0x00, 
+-      0xd0, 0x11, 0x0c, 0xf0, 0x42, 0x85, 0xd0, 0x0e, 
+-      0x42, 0x84, 0xd0, 0x0c, 0x80, 0x3c, 0x80, 0xbd, 
+-      0x20, 0x00, 0x61, 0x3e, 0x22, 0x00, 0x61, 0x78, 
+-      0xb4, 0x04, 0x4b, 0x05, 0x22, 0xff, 0x21, 0x00, 
+-      0xf7, 0xff, 0xfe, 0x28, 0xb0, 0x01, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x07, 0x74, 
+-      0x2e, 0x00, 0x66, 0x19, 0x56, 0x47, 0x41, 0x38, 
+-      0x78, 0x31, 0x36, 0x00, 0xb5, 0x00, 0xb0, 0x81, 
+-      0x48, 0x05, 0x69, 0xc0, 0x68, 0x80, 0x46, 0x6b, 
+-      0x22, 0x00, 0x21, 0x00, 0xf0, 0x0d, 0xfe, 0x7a, 
+-      0xb0, 0x01, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x55, 0x10, 0xb5, 0xf0, 0x27, 0x00, 
+-      0xb0, 0x85, 0x97, 0x00, 0x26, 0x10, 0x96, 0x01, 
+-      0x25, 0x05, 0x01, 0xed, 0x95, 0x02, 0x20, 0xff, 
+-      0x30, 0xd1, 0x90, 0x03, 0x97, 0x04, 0x22, 0x00, 
+-      0x21, 0x00, 0xb4, 0x06, 0x4c, 0x0d, 0x69, 0xe0, 
+-      0x68, 0x81, 0x1c, 0x08, 0xaa, 0x02, 0x1c, 0x3b, 
+-      0xf0, 0x0e, 0xf8, 0xe2, 0xb0, 0x02, 0x97, 0x00, 
+-      0x20, 0xff, 0x30, 0xd1, 0x90, 0x01, 0x95, 0x02, 
+-      0x96, 0x03, 0x97, 0x04, 0x69, 0xe0, 0x68, 0x80, 
+-      0x46, 0x69, 0xf0, 0x0e, 0xf8, 0x13, 0xf7, 0xff, 
+-      0xff, 0xc9, 0xb0, 0x05, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x55, 0x10, 
+-      0xb5, 0x90, 0x20, 0x07, 0xb0, 0x85, 0xf0, 0x03, 
+-      0xfb, 0xfd, 0x24, 0xff, 0x34, 0xe1, 0x22, 0x05, 
+-      0x01, 0xd2, 0x21, 0x00, 0x20, 0x07, 0x1c, 0x23, 
+-      0xf0, 0x03, 0xfc, 0x0c, 0x27, 0x00, 0x22, 0x00, 
+-      0x21, 0x02, 0x20, 0x07, 0x1c, 0x3b, 0xf0, 0x03, 
+-      0xff, 0xcf, 0x22, 0x01, 0x21, 0x01, 0x20, 0x07, 
+-      0x1c, 0x3b, 0xf0, 0x03, 0xff, 0x67, 0x22, 0x32, 
+-      0x21, 0x32, 0x20, 0x07, 0xf0, 0x03, 0xfc, 0xc2, 
+-      0x97, 0x00, 0x97, 0x01, 0x20, 0x05, 0x01, 0xc0, 
+-      0x90, 0x02, 0x94, 0x03, 0x97, 0x04, 0x48, 0x06, 
+-      0x69, 0xc0, 0x68, 0x80, 0x46, 0x69, 0xf0, 0x0d, 
+-      0xff, 0xdd, 0xf7, 0xff, 0xff, 0x93, 0xb0, 0x05, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x55, 0x10, 0xb4, 0x80, 0x01, 0x00, 
+-      0x4b, 0x2a, 0x18, 0xc0, 0x4b, 0x2a, 0x69, 0xdb, 
+-      0x69, 0x9f, 0x00, 0x8b, 0x18, 0x59, 0x02, 0x09, 
+-      0x18, 0x89, 0x18, 0x79, 0x78, 0x02, 0x70, 0x0a, 
+-      0x78, 0x42, 0x1d, 0xcb, 0x33, 0x39, 0x74, 0x1a, 
+-      0x78, 0x82, 0x1d, 0xcb, 0x33, 0x99, 0x70, 0x1a, 
+-      0x78, 0xc2, 0x1d, 0xcb, 0x33, 0xd9, 0x74, 0x1a, 
+-      0x79, 0x02, 0x1d, 0xcb, 0x33, 0xff, 0x33, 0x3a, 
+-      0x70, 0x1a, 0x79, 0x42, 0x1d, 0xcb, 0x33, 0xff, 
+-      0x33, 0x7a, 0x74, 0x1a, 0x79, 0x82, 0x1d, 0xcb, 
+-      0x33, 0xff, 0x33, 0xda, 0x70, 0x1a, 0x79, 0xc2, 
+-      0x23, 0x11, 0x01, 0x5b, 0x18, 0xcb, 0x74, 0x1a, 
+-      0x7a, 0x02, 0x23, 0x05, 0x01, 0xdb, 0x18, 0xcb, 
+-      0x70, 0x1a, 0x7a, 0x42, 0x23, 0x0b, 0x01, 0x9b, 
+-      0x18, 0xcb, 0x74, 0x1a, 0x7a, 0x82, 0x23, 0x19, 
+-      0x01, 0x5b, 0x18, 0xcb, 0x70, 0x1a, 0x7a, 0xc2, 
+-      0x23, 0x1b, 0x01, 0x5b, 0x18, 0xcb, 0x74, 0x1a, 
+-      0x7b, 0x02, 0x23, 0x0f, 0x01, 0x9b, 0x18, 0xcb, 
+-      0x70, 0x1a, 0x7b, 0x42, 0x23, 0x01, 0x02, 0x9b, 
+-      0x18, 0xcb, 0x74, 0x1a, 0x7b, 0x82, 0x23, 0x23, 
+-      0x01, 0x5b, 0x18, 0xcb, 0x70, 0x1a, 0x7b, 0xc0, 
+-      0x23, 0x25, 0x01, 0x5b, 0x18, 0xc9, 0x74, 0x08, 
+-      0xbc, 0x80, 0x47, 0x70, 0x2e, 0x08, 0x07, 0x98, 
+-      0x2e, 0x08, 0x55, 0x10, 0xb5, 0xb0, 0x23, 0x00, 
+-      0x1c, 0x07, 0x56, 0xc0, 0x1c, 0x14, 0x1c, 0x0d, 
+-      0x28, 0x00, 0xd0, 0x0f, 0x20, 0x50, 0x1c, 0x21, 
+-      0xf0, 0x12, 0xf9, 0x96, 0x19, 0x41, 0x23, 0x00, 
+-      0x56, 0xf8, 0x1c, 0x22, 0xf7, 0xff, 0xff, 0x92, 
+-      0x23, 0x00, 0x37, 0x01, 0x56, 0xf8, 0x34, 0x01, 
+-      0x28, 0x00, 0xd1, 0xef, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0x90, 0x06, 0x00, 0x0e, 0x00, 
+-      0x04, 0x09, 0x14, 0x09, 0x04, 0x17, 0x14, 0x3f, 
+-      0x09, 0x03, 0xb0, 0x81, 0x4a, 0x08, 0x5c, 0xd4, 
+-      0xab, 0x00, 0x70, 0x1c, 0x07, 0x00, 0x0f, 0x00, 
+-      0x5c, 0x10, 0x70, 0x58, 0x20, 0x00, 0x70, 0x98, 
+-      0x46, 0x68, 0x1c, 0x3a, 0xf7, 0xff, 0xff, 0xce, 
+-      0xb0, 0x01, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x17, 0xb0, 0xb5, 0x90, 0x04, 0x00, 
+-      0x0c, 0x00, 0x04, 0x09, 0x14, 0x09, 0x04, 0x17, 
+-      0x14, 0x3f, 0x0b, 0x03, 0xb0, 0x82, 0x4a, 0x0f, 
+-      0x5c, 0xd4, 0xab, 0x00, 0x70, 0x1c, 0x0a, 0x03, 
+-      0x07, 0x1b, 0x0f, 0x1b, 0x5c, 0xd4, 0xab, 0x00, 
+-      0x70, 0x5c, 0x09, 0x03, 0x07, 0x1b, 0x0f, 0x1b, 
+-      0x5c, 0xd4, 0xab, 0x00, 0x70, 0x9c, 0x07, 0x00, 
+-      0x0f, 0x00, 0x5c, 0x10, 0x70, 0xd8, 0x20, 0x00, 
+-      0x71, 0x18, 0x46, 0x68, 0x1c, 0x3a, 0xf7, 0xff, 
+-      0xff, 0xa5, 0xb0, 0x02, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x17, 0xb0, 
+-      0xb5, 0x90, 0x04, 0x0f, 0x14, 0x3f, 0x04, 0x12, 
+-      0x14, 0x12, 0x0f, 0x03, 0xb0, 0x83, 0x49, 0x1b, 
+-      0x5c, 0xcc, 0xab, 0x00, 0x70, 0x1c, 0x0e, 0x03, 
+-      0x07, 0x1b, 0x0f, 0x1b, 0x5c, 0xcc, 0xab, 0x00, 
+-      0x70, 0x5c, 0x0d, 0x03, 0x07, 0x1b, 0x0f, 0x1b, 
+-      0x5c, 0xcc, 0xab, 0x00, 0x70, 0x9c, 0x0c, 0x03, 
+-      0x07, 0x1b, 0x0f, 0x1b, 0x5c, 0xcc, 0xab, 0x00, 
+-      0x70, 0xdc, 0x0b, 0x03, 0x07, 0x1b, 0x0f, 0x1b, 
+-      0x5c, 0xcc, 0xab, 0x01, 0x70, 0x1c, 0x0a, 0x03, 
+-      0x07, 0x1b, 0x0f, 0x1b, 0x5c, 0xcc, 0xab, 0x01, 
+-      0x70, 0x5c, 0x09, 0x03, 0x07, 0x1b, 0x0f, 0x1b, 
+-      0x5c, 0xcc, 0xab, 0x01, 0x70, 0x9c, 0x07, 0x00, 
+-      0x0f, 0x00, 0x5c, 0x08, 0x70, 0xd8, 0x20, 0x00, 
+-      0x71, 0x18, 0x46, 0x68, 0x1c, 0x39, 0xf7, 0xff, 
+-      0xff, 0x65, 0xb0, 0x03, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x17, 0xb0, 
+-      0xb5, 0xf0, 0x1c, 0x04, 0x04, 0x10, 0x14, 0x00, 
+-      0xb0, 0x81, 0x90, 0x00, 0x04, 0x1e, 0x14, 0x36, 
+-      0x22, 0x3c, 0x1c, 0x20, 0x1c, 0x0f, 0xb0, 0x85, 
+-      0xf0, 0x12, 0xf9, 0x2a, 0xa3, 0x72, 0xcb, 0x0c, 
+-      0xf0, 0x12, 0xf9, 0x36, 0xf0, 0x12, 0xf9, 0x38, 
+-      0x4d, 0x71, 0x5c, 0x28, 0xab, 0x02, 0x70, 0x18, 
+-      0x22, 0x38, 0x1c, 0x20, 0x1c, 0x39, 0xf0, 0x12, 
+-      0xf9, 0x1b, 0xa3, 0x6b, 0xcb, 0x0c, 0xf0, 0x12, 
+-      0xf9, 0x27, 0xf0, 0x12, 0xf9, 0x29, 0x5c, 0x28, 
+-      0xab, 0x02, 0x70, 0x58, 0x22, 0x34, 0x1c, 0x20, 
+-      0x1c, 0x39, 0xf0, 0x12, 0xf9, 0x0d, 0xa3, 0x64, 
+-      0xcb, 0x0c, 0xf0, 0x12, 0xf9, 0x19, 0xf0, 0x12, 
+-      0xf9, 0x1b, 0x5c, 0x28, 0xab, 0x02, 0x70, 0x98, 
+-      0x22, 0x30, 0x1c, 0x20, 0x1c, 0x39, 0xf0, 0x12, 
+-      0xf8, 0xff, 0xa3, 0x5d, 0xcb, 0x0c, 0xf0, 0x12, 
+-      0xf9, 0x0b, 0xf0, 0x12, 0xf9, 0x0d, 0x5c, 0x28, 
+-      0xab, 0x02, 0x70, 0xd8, 0x22, 0x2c, 0x1c, 0x20, 
+-      0x1c, 0x39, 0xf0, 0x12, 0xf8, 0xf1, 0xa3, 0x56, 
+-      0xcb, 0x0c, 0xf0, 0x12, 0xf8, 0xfd, 0xf0, 0x12, 
+-      0xf8, 0xff, 0x5c, 0x28, 0xab, 0x03, 0x70, 0x18, 
+-      0x22, 0x28, 0x1c, 0x20, 0x1c, 0x39, 0xf0, 0x12, 
+-      0xf8, 0xe3, 0xa3, 0x4f, 0xcb, 0x0c, 0xf0, 0x12, 
+-      0xf8, 0xef, 0xf0, 0x12, 0xf8, 0xf1, 0x5c, 0x28, 
+-      0xab, 0x03, 0x70, 0x58, 0x22, 0x24, 0x1c, 0x20, 
+-      0x1c, 0x39, 0xf0, 0x12, 0xf8, 0xd5, 0xa3, 0x48, 
+-      0xcb, 0x0c, 0xf0, 0x12, 0xf8, 0xe1, 0xf0, 0x12, 
+-      0xf8, 0xe3, 0x5c, 0x28, 0xab, 0x03, 0x70, 0x98, 
+-      0x22, 0x20, 0x1c, 0x20, 0x1c, 0x39, 0xf0, 0x12, 
+-      0xf8, 0xc7, 0xa3, 0x41, 0xcb, 0x0c, 0xf0, 0x12, 
+-      0xf8, 0xd3, 0xf0, 0x12, 0xf8, 0xd5, 0x5c, 0x28, 
+-      0xab, 0x03, 0x70, 0xd8, 0x22, 0x1c, 0x1c, 0x20, 
+-      0x1c, 0x39, 0xf0, 0x12, 0xf8, 0xb9, 0xa3, 0x3a, 
+-      0xcb, 0x0c, 0xf0, 0x12, 0xf8, 0xc5, 0xf0, 0x12, 
+-      0xf8, 0xc7, 0x5c, 0x28, 0xab, 0x00, 0x70, 0x18, 
+-      0x22, 0x18, 0x1c, 0x20, 0x1c, 0x39, 0xf0, 0x12, 
+-      0xf8, 0xab, 0xa3, 0x33, 0xcb, 0x0c, 0xf0, 0x12, 
+-      0xf8, 0xb7, 0xf0, 0x12, 0xf8, 0xb9, 0x5c, 0x28, 
+-      0xab, 0x00, 0x70, 0x58, 0x22, 0x14, 0x1c, 0x20, 
+-      0x1c, 0x39, 0xf0, 0x12, 0xf8, 0x9d, 0xa3, 0x2c, 
+-      0xcb, 0x0c, 0xf0, 0x12, 0xf8, 0xa9, 0xf0, 0x12, 
+-      0xf8, 0xab, 0x5c, 0x28, 0xab, 0x00, 0x70, 0x98, 
+-      0x22, 0x10, 0x1c, 0x20, 0x1c, 0x39, 0xf0, 0x12, 
+-      0xf8, 0x8f, 0xa3, 0x25, 0xcb, 0x0c, 0xf0, 0x12, 
+-      0xf8, 0x9b, 0xf0, 0x12, 0xf8, 0x9d, 0x5c, 0x28, 
+-      0xab, 0x00, 0x70, 0xd8, 0x22, 0x0c, 0x1c, 0x20, 
+-      0x1c, 0x39, 0xf0, 0x12, 0xf8, 0x81, 0xa3, 0x1e, 
+-      0xcb, 0x0c, 0xf0, 0x12, 0xf8, 0x8d, 0xf0, 0x12, 
+-      0xf8, 0x8f, 0x5c, 0x28, 0xab, 0x01, 0x70, 0x18, 
+-      0x22, 0x08, 0x1c, 0x20, 0x1c, 0x39, 0xf0, 0x12, 
+-      0xf8, 0x73, 0xa3, 0x17, 0xcb, 0x0c, 0xf0, 0x12, 
+-      0xf8, 0x7f, 0xf0, 0x12, 0xf8, 0x81, 0x5c, 0x28, 
+-      0xab, 0x01, 0x70, 0x58, 0x22, 0x04, 0x1c, 0x20, 
+-      0x1c, 0x39, 0xf0, 0x12, 0xf8, 0x65, 0xa3, 0x10, 
+-      0xcb, 0x0c, 0xf0, 0x12, 0xf8, 0x71, 0xf0, 0x12, 
+-      0xf8, 0x73, 0x5c, 0x28, 0xab, 0x01, 0x70, 0x98, 
+-      0xa3, 0x0b, 0xcb, 0x0c, 0x1c, 0x20, 0x1c, 0x39, 
+-      0xf0, 0x12, 0xf8, 0x66, 0xf0, 0x12, 0xf8, 0x68, 
+-      0x5c, 0x28, 0xab, 0x01, 0x70, 0xd8, 0x20, 0x00, 
+-      0x73, 0x18, 0x46, 0x68, 0x99, 0x05, 0x1c, 0x32, 
+-      0x33, 0x0c, 0xf7, 0xff, 0xfe, 0x6f, 0xb0, 0x06, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 
+-      0x2e, 0x08, 0x17, 0xb0, 0x21, 0x00, 0xb0, 0x81, 
+-      0x91, 0x00, 0xe0, 0x02, 0x99, 0x00, 0x31, 0x01, 
+-      0x91, 0x00, 0x99, 0x00, 0x42, 0x81, 0xdb, 0xf9, 
+-      0xb0, 0x01, 0x47, 0x70, 0xb5, 0xf0, 0x06, 0x06, 
+-      0x0e, 0x36, 0x25, 0x02, 0x48, 0x0d, 0x60, 0x05, 
+-      0x27, 0x07, 0x4c, 0x0d, 0x60, 0x25, 0x20, 0x01, 
+-      0x40, 0xb8, 0x40, 0x30, 0xd0, 0x01, 0x20, 0x03, 
+-      0xe0, 0x00, 0x20, 0x02, 0x49, 0x09, 0x60, 0x08, 
+-      0x20, 0x0a, 0xf7, 0xff, 0xff, 0xdf, 0x20, 0x03, 
+-      0x60, 0x20, 0x20, 0x0c, 0xf7, 0xff, 0xff, 0xda, 
+-      0x3f, 0x01, 0xd5, 0xeb, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x6e, 0x00, 0x14, 0x00, 
+-      0x6e, 0x00, 0x13, 0x00, 0x6e, 0x00, 0x12, 0x00, 
+-      0xb5, 0x80, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x0f, 
+-      0x0e, 0x3f, 0x06, 0x00, 0x0e, 0x00, 0x23, 0x80, 
+-      0x43, 0x18, 0xf7, 0xff, 0xff, 0xcf, 0x20, 0x14, 
+-      0xf7, 0xff, 0xff, 0xc0, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xff, 0xc9, 0x20, 0x03, 0x49, 0x04, 0x60, 0x08, 
+-      0x20, 0x00, 0x49, 0x04, 0x60, 0x08, 0x49, 0x04, 
+-      0x60, 0x08, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x6e, 0x00, 0x14, 0x00, 0x6e, 0x00, 0x12, 0x00, 
+-      0x6e, 0x00, 0x13, 0x00, 0xb5, 0x00, 0x21, 0x01, 
+-      0x20, 0x02, 0xf7, 0xff, 0xff, 0xd9, 0x48, 0x10, 
+-      0xf7, 0xff, 0xff, 0xa4, 0x21, 0x00, 0x20, 0x02, 
+-      0xf7, 0xff, 0xff, 0xd2, 0x48, 0x0d, 0xf7, 0xff, 
+-      0xff, 0x9d, 0x21, 0x44, 0x20, 0x00, 0xf7, 0xff, 
+-      0xff, 0xcb, 0x21, 0x81, 0x20, 0x01, 0xf7, 0xff, 
+-      0xff, 0xc7, 0x21, 0xf0, 0x20, 0x02, 0xf7, 0xff, 
+-      0xff, 0xc3, 0x21, 0x45, 0x20, 0x03, 0xf7, 0xff, 
+-      0xff, 0xbf, 0x21, 0x45, 0x20, 0x04, 0xf7, 0xff, 
+-      0xff, 0xbb, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x00, 0x00, 0x4e, 0x20, 0x00, 0x00, 0xc3, 0x50, 
+-      0xb5, 0x80, 0x06, 0x07, 0x0e, 0x3f, 0x06, 0x08, 
+-      0x0e, 0x00, 0x28, 0x45, 0xdd, 0x00, 0x20, 0x45, 
+-      0x1d, 0xc1, 0x31, 0x79, 0x20, 0x03, 0xf7, 0xff, 
+-      0xff, 0xa7, 0x2f, 0x45, 0xdd, 0x00, 0x27, 0x45, 
+-      0x20, 0x04, 0x1d, 0xf9, 0x31, 0x79, 0xf7, 0xff, 
+-      0xff, 0x9f, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0x00, 0xf0, 0x15, 0xfe, 0xeb, 0x23, 0x01, 
+-      0x03, 0x5b, 0x43, 0x18, 0xf0, 0x15, 0xfe, 0xea, 
+-      0xf0, 0x15, 0xfe, 0xe4, 0x23, 0x01, 0x03, 0x9b, 
+-      0x43, 0x18, 0xf0, 0x15, 0xfe, 0xe3, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0x00, 0xf0, 0x15, 0xfe, 0xda, 
+-      0x4b, 0x05, 0x40, 0x18, 0xf0, 0x15, 0xfe, 0xda, 
+-      0xf0, 0x15, 0xfe, 0xd4, 0x4b, 0x03, 0x40, 0x18, 
+-      0xf0, 0x15, 0xfe, 0xd4, 0xbc, 0x08, 0x47, 0x18, 
+-      0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xdf, 0xff, 
+-      0xb5, 0x80, 0x07, 0x01, 0x0f, 0x09, 0x29, 0x02, 
+-      0xd2, 0x19, 0x00, 0x89, 0x4a, 0x0d, 0x58, 0x51, 
+-      0x4f, 0x0d, 0x0c, 0x00, 0x60, 0x39, 0xd3, 0x05, 
+-      0x23, 0x01, 0x02, 0x5b, 0x68, 0x08, 0x43, 0x18, 
+-      0x60, 0x08, 0xe0, 0x03, 0x68, 0x08, 0x4b, 0x09, 
+-      0x40, 0x18, 0x60, 0x08, 0xf7, 0xff, 0xff, 0xc4, 
+-      0x68, 0x38, 0xf0, 0x0e, 0xfb, 0xb1, 0x20, 0x00, 
+-      0x61, 0xb8, 0xf7, 0xff, 0xff, 0xce, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x1a, 0x3c, 
+-      0x2e, 0x08, 0x17, 0xc0, 0xff, 0xff, 0xfd, 0xff, 
+-      0xb5, 0x00, 0x4a, 0x09, 0x1f, 0x11, 0x20, 0x0e, 
+-      0xf0, 0x0e, 0xfb, 0x58, 0x28, 0x00, 0xd1, 0x09, 
+-      0x48, 0x06, 0xf0, 0x0e, 0xfb, 0x99, 0x49, 0x06, 
+-      0x20, 0x0e, 0xf0, 0x15, 0xfe, 0x9b, 0xf7, 0xff, 
+-      0xff, 0xb4, 0x20, 0x00, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x17, 0xd8, 0x2e, 0x08, 0x19, 0x00, 
+-      0x2e, 0x00, 0x6e, 0x0b, 0xb5, 0x00, 0xf7, 0xff, 
+-      0xff, 0x97, 0x21, 0x00, 0x20, 0x0e, 0xf0, 0x15, 
+-      0xfe, 0x89, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0x00, 
+-      0x48, 0x04, 0x7d, 0x01, 0x29, 0x01, 0xd1, 0x02, 
+-      0x69, 0x80, 0xf0, 0x00, 0xf8, 0x05, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x17, 0xc0, 
+-      0xb5, 0x90, 0x1c, 0x07, 0x4c, 0x12, 0x68, 0x20, 
+-      0x49, 0x12, 0x42, 0x88, 0xd1, 0x01, 0x0b, 0x38, 
+-      0xd1, 0x1a, 0xf7, 0xff, 0xff, 0x79, 0x60, 0x67, 
+-      0x69, 0x21, 0x1c, 0x38, 0x29, 0x00, 0xd1, 0x11, 
+-      0x68, 0xe1, 0x1c, 0x4a, 0x68, 0xe1, 0x60, 0xe2, 
+-      0x00, 0x89, 0x4a, 0x0b, 0x50, 0x50, 0x68, 0xe0, 
+-      0x28, 0x64, 0xd1, 0x01, 0x20, 0x00, 0x60, 0xe0, 
+-      0x68, 0xe0, 0x68, 0xa1, 0x42, 0x88, 0xd1, 0x01, 
+-      0x20, 0x01, 0x61, 0x20, 0xf7, 0xff, 0xff, 0x71, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x17, 0xc0, 0x2e, 0x08, 0x19, 0x00, 
+-      0x2e, 0x08, 0x4c, 0xe8, 0xb5, 0x90, 0x1c, 0x07, 
+-      0xf7, 0xff, 0xff, 0x52, 0x48, 0x10, 0x69, 0x01, 
+-      0x24, 0x00, 0x29, 0x00, 0xd1, 0x03, 0x68, 0x81, 
+-      0x68, 0xc2, 0x42, 0x91, 0xd0, 0x12, 0x68, 0x81, 
+-      0x1c, 0x4a, 0x68, 0x81, 0x60, 0x82, 0x00, 0x89, 
+-      0x4a, 0x0a, 0x58, 0x51, 0x60, 0x39, 0x68, 0x81, 
+-      0x29, 0x64, 0xd1, 0x00, 0x60, 0x84, 0x61, 0x04, 
+-      0xf7, 0xff, 0xff, 0x4b, 0x20, 0x01, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0xf7, 0xff, 0xff, 0x45, 
+-      0x1c, 0x20, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x17, 0xc0, 0x2e, 0x08, 0x4c, 0xe8, 
+-      0xb5, 0x80, 0xb0, 0x81, 0x4f, 0x0e, 0x8e, 0xb8, 
+-      0x28, 0x00, 0xd1, 0x04, 0x46, 0x68, 0xf7, 0xff, 
+-      0xff, 0xcd, 0x28, 0x00, 0xd1, 0x05, 0x20, 0x00, 
+-      0x43, 0xc0, 0xb0, 0x01, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x98, 0x00, 0x49, 0x07, 0x60, 0x08, 
+-      0x20, 0x08, 0x85, 0x38, 0x20, 0x04, 0x85, 0x78, 
+-      0x20, 0x0f, 0x02, 0x40, 0x86, 0xb8, 0x20, 0x01, 
+-      0xb0, 0x01, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0x2c, 0x00, 0x1e, 0x00, 
+-      0x06, 0x00, 0x16, 0x00, 0x28, 0x30, 0xdb, 0x03, 
+-      0x28, 0x39, 0xdc, 0x01, 0x20, 0x01, 0x47, 0x70, 
+-      0x20, 0x00, 0x47, 0x70, 0xb5, 0xff, 0x26, 0x00, 
+-      0x1c, 0x07, 0x20, 0x00, 0x1c, 0x14, 0x22, 0x30, 
+-      0x9d, 0x09, 0x54, 0x3a, 0x30, 0x01, 0x28, 0x1f, 
+-      0xdb, 0xfb, 0x20, 0x00, 0x77, 0xf8, 0x29, 0x00, 
+-      0xda, 0x02, 0x2d, 0x00, 0xd1, 0x00, 0x42, 0x49, 
+-      0x25, 0x1e, 0x29, 0x00, 0xd0, 0x14, 0x1c, 0x20, 
+-      0xf0, 0x11, 0xfe, 0x78, 0x31, 0x30, 0x55, 0x79, 
+-      0x57, 0x79, 0x29, 0x39, 0xdd, 0x07, 0x31, 0x07, 
+-      0x55, 0x79, 0x9b, 0x03, 0x2b, 0x00, 0xd0, 0x02, 
+-      0x5d, 0x79, 0x31, 0x20, 0x55, 0x79, 0x1c, 0x01, 
+-      0x3d, 0x01, 0x36, 0x01, 0x28, 0x00, 0xd1, 0xea, 
+-      0x2e, 0x00, 0xd1, 0x00, 0x26, 0x01, 0x1c, 0x30, 
+-      0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0xff, 0x9e, 0x09, 0x20, 0x01, 0x1c, 0x0f, 
+-      0x21, 0x00, 0xb0, 0x94, 0x91, 0x12, 0x91, 0x11, 
+-      0x91, 0x10, 0x91, 0x0f, 0x91, 0x0e, 0x25, 0x00, 
+-      0x42, 0x41, 0x91, 0x0d, 0x21, 0x00, 0x91, 0x0c, 
+-      0x1c, 0x14, 0x92, 0x00, 0x23, 0x00, 0x56, 0xe1, 
+-      0x29, 0x2b, 0xd0, 0x10, 0xdc, 0x07, 0x29, 0x20, 
+-      0xd0, 0x15, 0x29, 0x23, 0xd1, 0x17, 0x21, 0x01, 
+-      0x91, 0x0f, 0x18, 0x64, 0xe0, 0x14, 0x29, 0x2d, 
+-      0xd0, 0x09, 0x29, 0x30, 0xd1, 0x0f, 0x21, 0x01, 
+-      0x91, 0x0e, 0x18, 0x64, 0xe0, 0x0c, 0x21, 0x01, 
+-      0x91, 0x12, 0x18, 0x64, 0xe0, 0x08, 0x21, 0x01, 
+-      0x91, 0x11, 0x18, 0x64, 0xe0, 0x04, 0x21, 0x01, 
+-      0x91, 0x10, 0x18, 0x64, 0xe0, 0x00, 0x20, 0x00, 
+-      0x28, 0x00, 0xd1, 0xdb, 0x23, 0x00, 0x56, 0xe0, 
+-      0xf7, 0xff, 0xff, 0x8a, 0x28, 0x00, 0xd0, 0x15, 
+-      0x25, 0x00, 0x23, 0x00, 0x56, 0xe0, 0xf7, 0xff, 
+-      0xff, 0x83, 0x28, 0x00, 0xd0, 0x19, 0x00, 0xa8, 
+-      0x19, 0x40, 0x00, 0x40, 0x23, 0x00, 0x56, 0xe1, 
+-      0x18, 0x08, 0x34, 0x01, 0x1f, 0xc5, 0x3d, 0x29, 
+-      0x56, 0xe0, 0xf7, 0xff, 0xff, 0x75, 0x28, 0x00, 
+-      0xd1, 0xf1, 0xe0, 0x0a, 0x23, 0x00, 0x56, 0xe0, 
+-      0x28, 0x2a, 0xd1, 0x06, 0x9b, 0x17, 0xcb, 0x20, 
+-      0x93, 0x17, 0x68, 0x30, 0x30, 0x01, 0x60, 0x30, 
+-      0x34, 0x01, 0x23, 0x00, 0x56, 0xe0, 0x28, 0x2e, 
+-      0xd1, 0x16, 0x20, 0x00, 0x90, 0x0d, 0x34, 0x01, 
+-      0x56, 0xe0, 0xf7, 0xff, 0xff, 0x5d, 0x28, 0x00, 
+-      0xd0, 0x0e, 0x98, 0x0d, 0x00, 0x83, 0x18, 0x18, 
+-      0x00, 0x40, 0x23, 0x00, 0x56, 0xe1, 0x18, 0x08, 
+-      0x38, 0x30, 0x90, 0x0d, 0x34, 0x01, 0x56, 0xe0, 
+-      0xf7, 0xff, 0xff, 0x4e, 0x28, 0x00, 0xd1, 0xf0, 
+-      0x23, 0x00, 0x56, 0xe0, 0x28, 0x68, 0xd0, 0x01, 
+-      0x28, 0x6c, 0xd1, 0x02, 0x90, 0x0c, 0x34, 0x01, 
+-      0xe0, 0x04, 0x28, 0x46, 0xd0, 0x01, 0x28, 0x4e, 
+-      0xd1, 0x00, 0x34, 0x01, 0x23, 0x00, 0x56, 0xe0, 
+-      0x21, 0x25, 0x34, 0x01, 0x28, 0x67, 0xd0, 0x12, 
+-      0xdc, 0x1d, 0x28, 0x63, 0xd0, 0x54, 0xdc, 0x08, 
+-      0x28, 0x25, 0xd0, 0x73, 0x28, 0x45, 0xd0, 0x0a, 
+-      0x28, 0x47, 0xd0, 0x08, 0x28, 0x58, 0xd1, 0x6e, 
+-      0xe0, 0x53, 0x28, 0x64, 0xd0, 0x6c, 0x28, 0x65, 
+-      0xd0, 0x01, 0x28, 0x66, 0xd1, 0x67, 0x98, 0x0c, 
+-      0x28, 0x6c, 0xd1, 0x66, 0x68, 0x30, 0x30, 0x03, 
+-      0x60, 0x30, 0x22, 0x08, 0x99, 0x17, 0xa8, 0x09, 
+-      0xf0, 0x11, 0xfd, 0xe0, 0xe0, 0xe5, 0x28, 0x70, 
+-      0xd0, 0x3d, 0xdc, 0x36, 0x28, 0x69, 0xd0, 0x57, 
+-      0x28, 0x6e, 0xd0, 0x57, 0x28, 0x6f, 0xd1, 0x52, 
+-      0x68, 0x30, 0x30, 0x01, 0x60, 0x30, 0x9b, 0x17, 
+-      0x68, 0x19, 0x91, 0x13, 0x98, 0x0c, 0x28, 0x68, 
+-      0xd1, 0x09, 0x99, 0x13, 0x04, 0x09, 0x0c, 0x09, 
+-      0x91, 0x13, 0x0c, 0x08, 0xd3, 0x03, 0x99, 0x13, 
+-      0x4b, 0xeb, 0x43, 0x19, 0x91, 0x13, 0x22, 0x01, 
+-      0xb4, 0x04, 0x23, 0x00, 0x22, 0x08, 0x99, 0x14, 
+-      0xa8, 0x02, 0xf7, 0xff, 0xfe, 0xff, 0xb0, 0x01, 
+-      0x99, 0x0f, 0x1c, 0x06, 0x29, 0x00, 0xd0, 0x03, 
+-      0x99, 0x13, 0x29, 0x00, 0xd0, 0x00, 0x3e, 0x01, 
+-      0x99, 0x12, 0x29, 0x00, 0xd0, 0x55, 0x20, 0x2b, 
+-      0x68, 0x39, 0x70, 0x08, 0x31, 0x01, 0x60, 0x39, 
+-      0x2d, 0x00, 0xd0, 0x73, 0x3d, 0x01, 0xe0, 0xe7, 
+-      0xe0, 0x3f, 0x28, 0x73, 0xd0, 0x6f, 0x28, 0x75, 
+-      0xd0, 0x6e, 0x28, 0x78, 0xd1, 0x1b, 0x23, 0x01, 
+-      0x93, 0x0b, 0x68, 0x30, 0x30, 0x01, 0x60, 0x30, 
+-      0x23, 0x1f, 0x1f, 0xe0, 0x38, 0x19, 0x56, 0xc0, 
+-      0x28, 0x58, 0xd1, 0x01, 0x23, 0x00, 0x93, 0x0b, 
+-      0x9b, 0x17, 0x68, 0x19, 0x98, 0x0c, 0x28, 0x68, 
+-      0xd1, 0x05, 0x04, 0x09, 0x0c, 0x09, 0x0c, 0x08, 
+-      0xd3, 0x01, 0x4b, 0xcd, 0x43, 0x19, 0x22, 0x01, 
+-      0xb4, 0x04, 0xe0, 0x04, 0xe0, 0x16, 0xe1, 0x88, 
+-      0xe0, 0x28, 0xe0, 0x7e, 0xe0, 0x91, 0x22, 0x10, 
+-      0x9b, 0x0c, 0xa8, 0x02, 0xf7, 0xff, 0xfe, 0xbe, 
+-      0xb0, 0x01, 0x99, 0x12, 0x1c, 0x06, 0x29, 0x00, 
+-      0xd0, 0x52, 0x20, 0x2b, 0x68, 0x39, 0x70, 0x08, 
+-      0x31, 0x01, 0x60, 0x39, 0x2d, 0x00, 0xd0, 0x57, 
+-      0x3d, 0x01, 0xe1, 0x0a, 0x68, 0x38, 0x70, 0x01, 
+-      0x30, 0x01, 0x23, 0x00, 0x60, 0x38, 0x70, 0x03, 
+-      0xe1, 0x70, 0x68, 0x30, 0x30, 0x01, 0x60, 0x30, 
+-      0x98, 0x17, 0x68, 0x01, 0x68, 0x38, 0x70, 0x01, 
+-      0x30, 0x01, 0x23, 0x00, 0x60, 0x38, 0x70, 0x03, 
+-      0xe1, 0x64, 0xe0, 0x74, 0x68, 0x30, 0x30, 0x01, 
+-      0x60, 0x30, 0x98, 0x17, 0x68, 0x01, 0x91, 0x13, 
+-      0x98, 0x0c, 0x28, 0x68, 0xd1, 0x09, 0x99, 0x13, 
+-      0x04, 0x09, 0x0c, 0x09, 0x91, 0x13, 0x0c, 0x08, 
+-      0xd3, 0x03, 0x99, 0x13, 0x4b, 0xac, 0x43, 0x19, 
+-      0x91, 0x13, 0x22, 0x00, 0xb4, 0x04, 0x23, 0x00, 
+-      0x22, 0x0a, 0x99, 0x14, 0xa8, 0x02, 0xf7, 0xff, 
+-      0xfe, 0x81, 0xb0, 0x01, 0x1c, 0x06, 0x20, 0x2d, 
+-      0x99, 0x12, 0x29, 0x00, 0xd0, 0x15, 0x99, 0x13, 
+-      0x29, 0x00, 0xe0, 0x02, 0xe0, 0x87, 0xe0, 0x5a, 
+-      0xe0, 0x97, 0xda, 0x04, 0x68, 0x39, 0x70, 0x08, 
+-      0x31, 0x01, 0x60, 0x39, 0xe0, 0x04, 0x20, 0x2b, 
+-      0x68, 0x39, 0x70, 0x08, 0x31, 0x01, 0x60, 0x39, 
+-      0x2d, 0x00, 0xd0, 0x65, 0x3d, 0x01, 0xe0, 0x76, 
+-      0xe0, 0xb4, 0x99, 0x10, 0x29, 0x00, 0xd0, 0x11, 
+-      0x99, 0x13, 0x29, 0x00, 0xda, 0x05, 0x68, 0x39, 
+-      0x70, 0x08, 0x31, 0x01, 0x60, 0x39, 0xe0, 0x05, 
+-      0xe0, 0xb3, 0x21, 0x20, 0x68, 0x38, 0x70, 0x01, 
+-      0x30, 0x01, 0x60, 0x38, 0x2d, 0x00, 0xd0, 0x4f, 
+-      0x3d, 0x01, 0xe0, 0x60, 0x99, 0x13, 0x29, 0x00, 
+-      0xda, 0x5d, 0x68, 0x39, 0x70, 0x08, 0x31, 0x01, 
+-      0x60, 0x39, 0x2d, 0x00, 0xd0, 0x44, 0x3d, 0x01, 
+-      0xe0, 0xab, 0x68, 0x30, 0x30, 0x02, 0x60, 0x30, 
+-      0x22, 0x08, 0x99, 0x17, 0xa8, 0x09, 0xf0, 0x11, 
+-      0xfc, 0xf9, 0x68, 0x38, 0xa1, 0x85, 0x22, 0x10, 
+-      0xf0, 0x11, 0xfc, 0xf4, 0x68, 0x38, 0xf0, 0x11, 
+-      0xfd, 0x35, 0x68, 0x39, 0x18, 0x40, 0x60, 0x38, 
+-      0xe0, 0xf8, 0x68, 0x30, 0x30, 0x01, 0x60, 0x30, 
+-      0x98, 0x17, 0x68, 0x00, 0x68, 0x39, 0x9a, 0x14, 
+-      0x1a, 0x89, 0x60, 0x01, 0xe0, 0xee, 0x99, 0x10, 
+-      0x29, 0x00, 0xd0, 0x21, 0x21, 0x20, 0x68, 0x38, 
+-      0x70, 0x01, 0x30, 0x01, 0x60, 0x38, 0x2d, 0x00, 
+-      0xd0, 0x1a, 0x3d, 0x01, 0xe0, 0x81, 0x68, 0x30, 
+-      0x30, 0x01, 0x60, 0x30, 0x98, 0x17, 0xf0, 0x11, 
+-      0xfd, 0x15, 0x1c, 0x06, 0x98, 0x0d, 0x28, 0x00, 
+-      0xdd, 0x03, 0x98, 0x0d, 0x42, 0xb0, 0xda, 0x00, 
+-      0x9e, 0x0d, 0x2d, 0x00, 0xd0, 0x09, 0x21, 0x20, 
+-      0x68, 0x38, 0x1c, 0x2a, 0xf0, 0x11, 0xfd, 0x28, 
+-      0x23, 0x00, 0x68, 0x38, 0x55, 0x43, 0xe0, 0x03, 
+-      0xe0, 0x67, 0x23, 0x00, 0x68, 0x38, 0x55, 0x83, 
+-      0x2d, 0x00, 0xd0, 0x0d, 0x42, 0xae, 0xda, 0x0b, 
+-      0x99, 0x11, 0x29, 0x00, 0xd1, 0x08, 0x68, 0x38, 
+-      0x19, 0x40, 0x1b, 0x80, 0x99, 0x17, 0x1c, 0x32, 
+-      0xf0, 0x11, 0xfd, 0x2c, 0xe0, 0x0a, 0xe0, 0x54, 
+-      0x2d, 0x00, 0xd0, 0x02, 0x42, 0xae, 0xdb, 0x00, 
+-      0x36, 0x01, 0x99, 0x17, 0x68, 0x38, 0x1c, 0x32, 
+-      0xf0, 0x11, 0xfd, 0x20, 0x68, 0x38, 0xf0, 0x11, 
+-      0xfc, 0xe1, 0x68, 0x39, 0x18, 0x40, 0x60, 0x38, 
+-      0xe0, 0xa4, 0x68, 0x30, 0x30, 0x01, 0x60, 0x30, 
+-      0x98, 0x17, 0x99, 0x0c, 0x29, 0x68, 0xd1, 0x02, 
+-      0x23, 0x01, 0x03, 0xdb, 0x40, 0x18, 0x22, 0x01, 
+-      0xb4, 0x04, 0x98, 0x18, 0x68, 0x01, 0x23, 0x00, 
+-      0x22, 0x0a, 0xa8, 0x02, 0xf7, 0xff, 0xfd, 0xca, 
+-      0xb0, 0x01, 0x99, 0x12, 0x1c, 0x06, 0x29, 0x00, 
+-      0xd0, 0x08, 0x20, 0x2b, 0x68, 0x39, 0x70, 0x08, 
+-      0x31, 0x01, 0x60, 0x39, 0x2d, 0x00, 0xd0, 0x24, 
+-      0x3d, 0x01, 0xe0, 0x22, 0x99, 0x10, 0x29, 0x00, 
+-      0xd0, 0x1f, 0x21, 0x20, 0x68, 0x38, 0x70, 0x01, 
+-      0x30, 0x01, 0x60, 0x38, 0x2d, 0x00, 0xd0, 0x18, 
+-      0x3d, 0x01, 0xe0, 0x16, 0x99, 0x10, 0x29, 0x00, 
+-      0xd0, 0x07, 0x21, 0x20, 0x68, 0x38, 0x70, 0x01, 
+-      0x30, 0x01, 0x60, 0x38, 0x2d, 0x00, 0xd0, 0x00, 
+-      0x3d, 0x01, 0x99, 0x0f, 0x29, 0x00, 0xd0, 0x08, 
+-      0x21, 0x30, 0x68, 0x38, 0x70, 0x01, 0x30, 0x01, 
+-      0x21, 0x78, 0x60, 0x38, 0x70, 0x01, 0x30, 0x01, 
+-      0x60, 0x38, 0x2d, 0x00, 0xd0, 0x48, 0x42, 0xb5, 
+-      0xdd, 0x46, 0x99, 0x11, 0x29, 0x00, 0xd0, 0x02, 
+-      0x99, 0x0e, 0x29, 0x00, 0xd0, 0x2a, 0x99, 0x0e, 
+-      0x29, 0x00, 0xd0, 0x0c, 0x20, 0x00, 0x1b, 0xa9, 
+-      0x29, 0x00, 0xdd, 0x14, 0x22, 0x30, 0x68, 0x3b, 
+-      0x70, 0x1a, 0x33, 0x01, 0x60, 0x3b, 0x30, 0x01, 
+-      0x42, 0x81, 0xdc, 0xf8, 0xe0, 0x0b, 0x20, 0x00, 
+-      0x1b, 0xa9, 0x29, 0x00, 0xdd, 0x07, 0x23, 0x20, 
+-      0x68, 0x3a, 0x70, 0x13, 0x32, 0x01, 0x60, 0x3a, 
+-      0x30, 0x01, 0x42, 0x81, 0xdc, 0xf8, 0x21, 0x20, 
+-      0x1b, 0x89, 0xa8, 0x01, 0x18, 0x08, 0x1e, 0x41, 
+-      0x68, 0x38, 0xf0, 0x11, 0xfc, 0xd3, 0x68, 0x38, 
+-      0xf0, 0x11, 0xfc, 0x68, 0x68, 0x39, 0x18, 0x40, 
+-      0x60, 0x38, 0xe0, 0x2b, 0x68, 0x38, 0xf0, 0x11, 
+-      0xfc, 0x61, 0x68, 0x39, 0x18, 0x40, 0x60, 0x38, 
+-      0x20, 0x00, 0x1b, 0xa9, 0x29, 0x00, 0xdd, 0x07, 
+-      0x23, 0x20, 0x68, 0x3a, 0x70, 0x13, 0x32, 0x01, 
+-      0x60, 0x3a, 0x30, 0x01, 0x42, 0x81, 0xdc, 0xf8, 
+-      0x23, 0x00, 0x68, 0x38, 0x70, 0x03, 0xe0, 0x15, 
+-      0x21, 0x20, 0x1b, 0x89, 0xa8, 0x01, 0x18, 0x08, 
+-      0x1e, 0x41, 0x68, 0x38, 0xf0, 0x11, 0xfc, 0xae, 
+-      0x68, 0x38, 0xf0, 0x11, 0xfc, 0x43, 0x68, 0x39, 
+-      0x18, 0x40, 0x23, 0x00, 0x60, 0x38, 0x70, 0x03, 
+-      0xe0, 0x04, 0x68, 0x38, 0x70, 0x01, 0x30, 0x01, 
+-      0x60, 0x38, 0x9c, 0x00, 0x1c, 0x20, 0xb0, 0x14, 
+-      0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xff, 0xff, 0x00, 0x00, 0x28, 0x46, 0x50, 0x20, 
+-      0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 
+-      0x65, 0x64, 0x29, 0x00, 0xb5, 0x87, 0x23, 0x00, 
+-      0x98, 0x01, 0x9f, 0x00, 0x56, 0xc0, 0x28, 0x00, 
+-      0xd0, 0x2f, 0xe0, 0x05, 0x30, 0x01, 0x90, 0x01, 
+-      0x98, 0x00, 0x70, 0x01, 0x30, 0x01, 0x90, 0x00, 
+-      0x23, 0x00, 0x98, 0x01, 0x56, 0xc1, 0x29, 0x25, 
+-      0xd0, 0x01, 0x29, 0x00, 0xd1, 0xf2, 0x23, 0x00, 
+-      0x99, 0x01, 0x56, 0xc9, 0x29, 0x00, 0xd0, 0x17, 
+-      0x23, 0x01, 0x56, 0xc0, 0x28, 0x00, 0xd0, 0x13, 
+-      0x20, 0x00, 0xb0, 0x81, 0x90, 0x00, 0x46, 0x6a, 
+-      0xb4, 0x04, 0x98, 0x03, 0x1c, 0x42, 0x9b, 0x04, 
+-      0x1c, 0x38, 0xa9, 0x02, 0xf7, 0xff, 0xfd, 0x30, 
+-      0xb0, 0x01, 0x90, 0x02, 0x98, 0x00, 0x00, 0x80, 
+-      0x99, 0x03, 0x18, 0x40, 0x90, 0x03, 0xb0, 0x01, 
+-      0x23, 0x00, 0x98, 0x01, 0x56, 0xc0, 0x28, 0x00, 
+-      0xd1, 0xd6, 0x20, 0x00, 0x99, 0x00, 0x70, 0x08, 
+-      0x31, 0x01, 0x91, 0x00, 0x1c, 0x38, 0xf0, 0x11, 
+-      0xfb, 0xe9, 0xb0, 0x03, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb4, 0x0f, 0xb5, 0x00, 0x98, 0x01, 
+-      0x99, 0x02, 0xaa, 0x03, 0xf7, 0xff, 0xff, 0xb6, 
+-      0xbc, 0x08, 0xb0, 0x04, 0x47, 0x18, 0xb4, 0x0f, 
+-      0xb5, 0x00, 0xb0, 0xb8, 0x46, 0x68, 0x99, 0x39, 
+-      0xaa, 0x3a, 0xf7, 0xff, 0xff, 0xab, 0x46, 0x68, 
+-      0xf0, 0x11, 0xfb, 0xd0, 0x1c, 0x01, 0x46, 0x68, 
+-      0xf7, 0xf9, 0xfb, 0x7e, 0xb0, 0x38, 0xbc, 0x08, 
+-      0xb0, 0x04, 0x47, 0x18, 0x21, 0x00, 0xb0, 0x81, 
+-      0x91, 0x00, 0xe0, 0x02, 0x99, 0x00, 0x31, 0x01, 
+-      0x91, 0x00, 0x99, 0x00, 0x42, 0x81, 0xd3, 0xf9, 
+-      0xb0, 0x01, 0x47, 0x70, 0xb5, 0xf0, 0x06, 0x0d, 
+-      0x0e, 0x2d, 0xb0, 0x83, 0x49, 0x23, 0x68, 0x09, 
+-      0x91, 0x01, 0x26, 0x09, 0x1d, 0xc4, 0x34, 0x19, 
+-      0xab, 0x02, 0x70, 0x1d, 0x20, 0xff, 0x3b, 0x04, 
+-      0x70, 0x18, 0x22, 0x01, 0xb4, 0x04, 0x7b, 0x20, 
+-      0xa9, 0x03, 0xab, 0x02, 0xf7, 0xfa, 0xf8, 0x0c, 
+-      0xb0, 0x01, 0xaf, 0x01, 0x78, 0x3f, 0xab, 0x02, 
+-      0x70, 0x1d, 0x20, 0xff, 0x3b, 0x04, 0x70, 0x18, 
+-      0x22, 0x01, 0xb4, 0x04, 0x7b, 0x20, 0xa9, 0x03, 
+-      0xab, 0x02, 0xf7, 0xf9, 0xff, 0xfd, 0xb0, 0x01, 
+-      0xa9, 0x01, 0x78, 0x09, 0x91, 0x00, 0xab, 0x02, 
+-      0x70, 0x1d, 0x20, 0xff, 0x3b, 0x04, 0x70, 0x18, 
+-      0x22, 0x01, 0xb4, 0x04, 0x7b, 0x20, 0xa9, 0x03, 
+-      0xab, 0x02, 0xf7, 0xf9, 0xff, 0xed, 0xb0, 0x01, 
+-      0xa8, 0x01, 0x78, 0x00, 0x99, 0x00, 0x42, 0x8f, 
+-      0xd1, 0x06, 0x42, 0x87, 0xd1, 0x04, 0x1c, 0x38, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x1e, 0x70, 0x06, 0x06, 0x0e, 0x36, 0xd1, 0xc3, 
+-      0x20, 0xff, 0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x02, 0x5e, 0x28, 
+-      0xb5, 0xf0, 0x06, 0x0c, 0x0e, 0x24, 0x06, 0x16, 
+-      0x0e, 0x36, 0x25, 0x0a, 0xb0, 0x82, 0xab, 0x00, 
+-      0x70, 0x1c, 0x70, 0x5e, 0x1c, 0x07, 0x30, 0x20, 
+-      0x90, 0x01, 0x98, 0x01, 0x7b, 0x00, 0x46, 0x69, 
+-      0x22, 0x02, 0xf7, 0xf9, 0xff, 0x66, 0x1c, 0x38, 
+-      0x1c, 0x21, 0xf7, 0xff, 0xff, 0x9b, 0x1c, 0x01, 
+-      0x2c, 0x00, 0xd0, 0x05, 0x2c, 0x09, 0xd0, 0x03, 
+-      0x2c, 0x1f, 0xd1, 0x03, 0x20, 0x7f, 0xe0, 0x02, 
+-      0x20, 0x5e, 0xe0, 0x00, 0x20, 0xff, 0x40, 0x71, 
+-      0x40, 0x08, 0xd1, 0x03, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x1e, 0x68, 0x06, 0x05, 
+-      0x0e, 0x2d, 0xd1, 0xde, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0x90, 0x1c, 0x07, 
+-      0x2a, 0x00, 0xd0, 0x01, 0x24, 0x09, 0xe0, 0x00, 
+-      0x24, 0x00, 0x00, 0x90, 0x19, 0xc0, 0x6c, 0x02, 
+-      0x42, 0x8a, 0xd0, 0x15, 0x64, 0x01, 0x20, 0x03, 
+-      0x4a, 0x19, 0x29, 0x01, 0xd0, 0x13, 0x29, 0x02, 
+-      0xd0, 0x1f, 0x29, 0x03, 0xd1, 0x0c, 0x60, 0x10, 
+-      0x1c, 0x38, 0x1c, 0x21, 0xf7, 0xff, 0xff, 0x66, 
+-      0x23, 0xf3, 0x40, 0x18, 0x22, 0x08, 0x43, 0x02, 
+-      0x1c, 0x38, 0x1c, 0x21, 0xf7, 0xff, 0xff, 0xac, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x60, 0x10, 
+-      0x1c, 0x38, 0x1c, 0x21, 0xf7, 0xff, 0xff, 0x56, 
+-      0x22, 0xf3, 0x40, 0x02, 0x1c, 0x38, 0x1c, 0x21, 
+-      0xf7, 0xff, 0xff, 0x9e, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x1c, 0x38, 0x1c, 0x21, 0xf7, 0xff, 
+-      0xff, 0x49, 0x23, 0xf3, 0x40, 0x18, 0x22, 0x04, 
+-      0x43, 0x02, 0x1c, 0x38, 0x1c, 0x21, 0xf7, 0xff, 
+-      0xff, 0x8f, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x6e, 0x00, 0x11, 0x00, 0xb5, 0xf0, 0x1c, 0x0c, 
+-      0x68, 0x41, 0x68, 0x09, 0x68, 0x80, 0x1c, 0x1f, 
+-      0x28, 0x00, 0xd0, 0x01, 0x6b, 0x8b, 0xe0, 0x00, 
+-      0x23, 0x00, 0x6b, 0x0e, 0x43, 0x32, 0x6b, 0xcd, 
+-      0x43, 0x2a, 0x43, 0x1a, 0x43, 0x1e, 0x1c, 0x15, 
+-      0x1c, 0x02, 0x1c, 0x08, 0x21, 0x01, 0xf7, 0xff, 
+-      0xff, 0xa5, 0x20, 0x00, 0x2f, 0x00, 0xdd, 0x07, 
+-      0x88, 0x29, 0x54, 0x21, 0x88, 0x31, 0x54, 0x21, 
+-      0x30, 0x01, 0x35, 0x02, 0x42, 0xb8, 0xdb, 0xf7, 
+-      0x1c, 0x38, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0xff, 0x68, 0x41, 0x68, 0x0c, 0x68, 0x80, 
+-      0x1c, 0x1f, 0x28, 0x00, 0xd0, 0x01, 0x6b, 0xa6, 
+-      0xe0, 0x00, 0x26, 0x00, 0x6b, 0x21, 0x43, 0x11, 
+-      0x6b, 0xe2, 0x43, 0x11, 0x43, 0x31, 0x1c, 0x02, 
+-      0x1c, 0x0d, 0x21, 0x01, 0x1c, 0x20, 0xf7, 0xff, 
+-      0xff, 0x81, 0x20, 0x00, 0x2f, 0x00, 0xdd, 0x09, 
+-      0x99, 0x01, 0x5c, 0x09, 0x80, 0x29, 0x6b, 0x21, 
+-      0x19, 0x89, 0x88, 0x09, 0x30, 0x01, 0x35, 0x02, 
+-      0x42, 0xb8, 0xdb, 0xf5, 0x1c, 0x38, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0xb0, 
+-      0x68, 0x42, 0x68, 0x17, 0x68, 0x82, 0x2a, 0x00, 
+-      0xd0, 0x01, 0x6b, 0xbc, 0xe0, 0x00, 0x24, 0x00, 
+-      0x08, 0x48, 0xd3, 0x0a, 0x23, 0xfe, 0x40, 0x19, 
+-      0x6b, 0x38, 0x43, 0x08, 0x6b, 0x79, 0x43, 0x08, 
+-      0x6b, 0xf9, 0x43, 0x08, 0x43, 0x20, 0x1c, 0x05, 
+-      0xe0, 0x05, 0x6b, 0x38, 0x43, 0x08, 0x6b, 0xf9, 
+-      0x43, 0x08, 0x43, 0x20, 0x1c, 0x05, 0x21, 0x02, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xff, 0x4f, 0x6b, 0x38, 
+-      0x43, 0x20, 0x88, 0x29, 0x88, 0x01, 0x88, 0x00, 
+-      0x06, 0x00, 0x0e, 0x00, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0xb0, 0x06, 0x15, 0x0e, 0x2d, 
+-      0x68, 0x42, 0x68, 0x13, 0x68, 0x82, 0x2a, 0x00, 
+-      0xd0, 0x01, 0x6b, 0x98, 0xe0, 0x00, 0x20, 0x00, 
+-      0x07, 0xcc, 0x0f, 0xe4, 0xd0, 0x08, 0x6b, 0x1f, 
+-      0x43, 0x39, 0x6b, 0x5f, 0x43, 0x39, 0x6b, 0xdf, 
+-      0x43, 0x39, 0x43, 0x01, 0x1c, 0x0f, 0xe0, 0x05, 
+-      0x6b, 0x1f, 0x43, 0x39, 0x6b, 0xdf, 0x43, 0x39, 
+-      0x43, 0x01, 0x1c, 0x0f, 0x21, 0x02, 0x1c, 0x18, 
+-      0xf7, 0xff, 0xff, 0x24, 0x80, 0x3d, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x47, 0x70, 0xb5, 0x80, 
+-      0x68, 0x41, 0x68, 0x0a, 0x68, 0x81, 0x29, 0x00, 
+-      0xd0, 0x01, 0x21, 0x09, 0xe0, 0x00, 0x21, 0x00, 
+-      0x27, 0x00, 0x69, 0x80, 0x28, 0x06, 0xd1, 0x03, 
+-      0x20, 0x01, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x1c, 0x10, 0x6c, 0xd2, 0xf0, 0x11, 0xf9, 0xa8, 
+-      0x08, 0x40, 0xd3, 0x00, 0x27, 0x01, 0x1c, 0x38, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0xf0, 
+-      0x68, 0x42, 0x68, 0x17, 0x68, 0x80, 0x28, 0x00, 
+-      0xd0, 0x01, 0x24, 0x09, 0xe0, 0x00, 0x24, 0x00, 
+-      0x29, 0x00, 0xd0, 0x16, 0x29, 0x01, 0xd0, 0x21, 
+-      0x29, 0x02, 0xd1, 0x0e, 0x22, 0x80, 0x6c, 0xbb, 
+-      0x1c, 0x38, 0x1c, 0x21, 0xf0, 0x11, 0xf9, 0x8e, 
+-      0x48, 0x1e, 0xf7, 0xff, 0xfe, 0x5f, 0x22, 0x00, 
+-      0x6c, 0xbb, 0x1c, 0x38, 0x1c, 0x21, 0xf0, 0x11, 
+-      0xf9, 0x85, 0x20, 0x00, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x6c, 0xfa, 0x1c, 0x38, 0x1c, 0x21, 
+-      0xf0, 0x11, 0xf9, 0x7a, 0x22, 0x9f, 0x40, 0x02, 
+-      0x6c, 0xbb, 0x1c, 0x38, 0x1c, 0x21, 0xf0, 0x11, 
+-      0xf9, 0x75, 0xe7, 0xee, 0x6c, 0xfa, 0x1c, 0x38, 
+-      0x1c, 0x21, 0xf0, 0x11, 0xf9, 0x6d, 0x22, 0x20, 
+-      0x43, 0x02, 0x6c, 0xbb, 0x1c, 0x38, 0x1c, 0x21, 
+-      0xf0, 0x11, 0xf9, 0x68, 0x25, 0x00, 0x6c, 0xfa, 
+-      0x1c, 0x38, 0x1c, 0x21, 0xf0, 0x11, 0xf9, 0x60, 
+-      0x1c, 0x06, 0x09, 0x80, 0xd2, 0x05, 0x20, 0x14, 
+-      0xf7, 0xff, 0xfe, 0x30, 0x35, 0x01, 0x2d, 0x0a, 
+-      0xdb, 0xf1, 0x22, 0x40, 0x43, 0x32, 0x6c, 0xbb, 
+-      0x1c, 0x38, 0x1c, 0x21, 0xf0, 0x11, 0xf9, 0x52, 
+-      0xe7, 0xcb, 0x00, 0x00, 0x00, 0x01, 0x86, 0xa0, 
+-      0xb5, 0x80, 0x49, 0x0f, 0x4f, 0x0f, 0x8e, 0xfa, 
+-      0x20, 0x00, 0x43, 0xc0, 0x2a, 0x00, 0xd1, 0x13, 
+-      0x8d, 0xba, 0x06, 0x12, 0x0e, 0x12, 0x2a, 0x0c, 
+-      0xd1, 0x0e, 0x8d, 0xf8, 0x28, 0x00, 0xd0, 0x09, 
+-      0x8d, 0xf8, 0x1e, 0x82, 0xb4, 0x04, 0x78, 0x4a, 
+-      0x1c, 0x8b, 0x78, 0x09, 0x48, 0x06, 0xf0, 0x00, 
+-      0xfd, 0x5f, 0xb0, 0x01, 0x20, 0x00, 0x85, 0xb8, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2c, 0x00, 0x12, 0x00, 0x2c, 0x00, 0x1f, 0xc0, 
+-      0x2e, 0x08, 0x4e, 0x78, 0x48, 0x08, 0x8d, 0x81, 
+-      0x29, 0x00, 0xd0, 0x02, 0x20, 0x00, 0x43, 0xc0, 
+-      0x47, 0x70, 0x21, 0x0c, 0x85, 0x81, 0x21, 0x01, 
+-      0x02, 0xc9, 0x85, 0xc1, 0x21, 0x09, 0x02, 0x49, 
+-      0x86, 0xc1, 0x20, 0x00, 0x47, 0x70, 0x00, 0x00, 
+-      0x2c, 0x00, 0x1f, 0xc0, 0xb5, 0x90, 0x4f, 0x15, 
+-      0x68, 0x38, 0x28, 0x00, 0xd0, 0x23, 0xf7, 0xff, 
+-      0xff, 0xbf, 0x48, 0x13, 0x68, 0x00, 0x68, 0x79, 
+-      0x1a, 0x41, 0x29, 0x02, 0xd3, 0x1b, 0x60, 0x78, 
+-      0x4c, 0x10, 0x8e, 0xa0, 0x4f, 0x10, 0x28, 0x00, 
+-      0xd1, 0x02, 0x1c, 0x38, 0xf0, 0x00, 0xfc, 0xd0, 
+-      0x8e, 0xa0, 0x28, 0x00, 0xd1, 0x04, 0x23, 0xc9, 
+-      0x00, 0x9b, 0x18, 0xf8, 0xf0, 0x00, 0xfc, 0xc8, 
+-      0x69, 0xb8, 0x28, 0x06, 0xd0, 0x05, 0x23, 0x03, 
+-      0x02, 0x1b, 0x18, 0xf8, 0x6b, 0xc0, 0x28, 0x06, 
+-      0xd1, 0x01, 0xf7, 0xff, 0xff, 0xc3, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x1a, 0x44, 
+-      0x2e, 0x08, 0x05, 0xb0, 0x2c, 0x00, 0x1f, 0xc0, 
+-      0x2e, 0x08, 0x4e, 0xc8, 0xb5, 0x00, 0x1c, 0x10, 
+-      0x1c, 0x1a, 0x1c, 0x03, 0x1c, 0x08, 0x1c, 0x19, 
+-      0xf7, 0xf9, 0xf9, 0x84, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0x90, 0x4f, 0x23, 0x24, 0x02, 0x48, 0x23, 
+-      0x60, 0x04, 0x22, 0x50, 0x21, 0x00, 0x1c, 0x38, 
+-      0xf0, 0x11, 0xf9, 0x8a, 0x20, 0x80, 0x1d, 0xf9, 
+-      0x31, 0x19, 0x73, 0x08, 0x20, 0x03, 0x07, 0x00, 
+-      0x63, 0x38, 0x02, 0xe0, 0x63, 0x78, 0x03, 0x20, 
+-      0x63, 0xb8, 0x03, 0x60, 0x63, 0xf8, 0x48, 0x1a, 
+-      0x64, 0xb8, 0x48, 0x1a, 0x64, 0xf8, 0x60, 0x3f, 
+-      0x48, 0x19, 0x60, 0xf8, 0x60, 0x7c, 0x24, 0x00, 
+-      0x60, 0xbc, 0x48, 0x18, 0x61, 0x78, 0x48, 0x18, 
+-      0x61, 0xb8, 0x48, 0x18, 0x61, 0xf8, 0x48, 0x18, 
+-      0x62, 0x38, 0x48, 0x18, 0x61, 0x38, 0x48, 0x18, 
+-      0x62, 0x78, 0x48, 0x18, 0x62, 0xb8, 0x1c, 0x38, 
+-      0xf0, 0x00, 0xf8, 0xbc, 0x4f, 0x16, 0x28, 0x00, 
+-      0xd0, 0x03, 0x60, 0x3c, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x20, 0x01, 0x06, 0x40, 0xf0, 0x15, 
+-      0xf8, 0x1c, 0x48, 0x12, 0xf7, 0xff, 0xfd, 0x6a, 
+-      0x20, 0x01, 0x60, 0x38, 0x48, 0x10, 0x68, 0x00, 
+-      0x60, 0x78, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x4e, 0x78, 0x6e, 0x00, 0x11, 0x00, 
+-      0x2e, 0x00, 0x76, 0x55, 0x2e, 0x00, 0x75, 0xb9, 
+-      0x2e, 0x08, 0x4e, 0xc8, 0x2e, 0x00, 0x77, 0x41, 
+-      0x2e, 0x00, 0x77, 0x8d, 0x2e, 0x00, 0x77, 0xdb, 
+-      0x2e, 0x00, 0x78, 0x2f, 0x2e, 0x00, 0x7a, 0x39, 
+-      0x2e, 0x00, 0x78, 0x7b, 0x2e, 0x00, 0x78, 0xb3, 
+-      0x2e, 0x08, 0x1a, 0x44, 0x00, 0x06, 0x1a, 0x80, 
+-      0x2e, 0x08, 0x05, 0xb0, 0xb5, 0x80, 0x22, 0x80, 
+-      0x21, 0x1f, 0x6c, 0x83, 0x1c, 0x07, 0xf0, 0x11, 
+-      0xf8, 0x69, 0x48, 0x3f, 0xf7, 0xff, 0xfd, 0x3a, 
+-      0x22, 0x55, 0x21, 0x02, 0x6c, 0xbb, 0x1c, 0x38, 
+-      0xf0, 0x11, 0xf8, 0x60, 0x21, 0x02, 0x6c, 0xfa, 
+-      0x1c, 0x38, 0xf0, 0x11, 0xf8, 0x59, 0x28, 0x55, 
+-      0xd0, 0x04, 0x20, 0x00, 0x43, 0xc0, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x22, 0x33, 0x21, 0x05, 
+-      0x6c, 0xbb, 0x1c, 0x38, 0xf0, 0x11, 0xf8, 0x4e, 
+-      0x22, 0x33, 0x21, 0x0e, 0x6c, 0xbb, 0x1c, 0x38, 
+-      0xf0, 0x11, 0xf8, 0x48, 0x22, 0x21, 0x21, 0x17, 
+-      0x6c, 0xbb, 0x1c, 0x38, 0xf0, 0x11, 0xf8, 0x42, 
+-      0x22, 0x00, 0x21, 0x01, 0x6c, 0xbb, 0x1c, 0x38, 
+-      0xf0, 0x11, 0xf8, 0x3c, 0x22, 0x00, 0x21, 0x0a, 
+-      0x6c, 0xbb, 0x1c, 0x38, 0xf0, 0x11, 0xf8, 0x36, 
+-      0x22, 0x01, 0x21, 0x02, 0x6c, 0xbb, 0x1c, 0x38, 
+-      0xf0, 0x11, 0xf8, 0x30, 0x22, 0x01, 0x21, 0x0b, 
+-      0x6c, 0xbb, 0x1c, 0x38, 0xf0, 0x11, 0xf8, 0x2a, 
+-      0x22, 0x00, 0x21, 0x03, 0x6c, 0xbb, 0x1c, 0x38, 
+-      0xf0, 0x11, 0xf8, 0x24, 0x22, 0x00, 0x21, 0x0c, 
+-      0x6c, 0xbb, 0x1c, 0x38, 0xf0, 0x11, 0xf8, 0x1e, 
+-      0x22, 0x00, 0x21, 0x04, 0x6c, 0xbb, 0x1c, 0x38, 
+-      0xf0, 0x11, 0xf8, 0x18, 0x22, 0x01, 0x21, 0x0d, 
+-      0x6c, 0xbb, 0x1c, 0x38, 0xf0, 0x11, 0xf8, 0x12, 
+-      0x22, 0x02, 0x21, 0x1e, 0x6c, 0xbb, 0x1c, 0x38, 
+-      0xf0, 0x11, 0xf8, 0x0c, 0x22, 0x04, 0x21, 0x1c, 
+-      0x6c, 0xbb, 0x1c, 0x38, 0xf0, 0x11, 0xf8, 0x06, 
+-      0x22, 0x03, 0x21, 0x1b, 0x6c, 0xbb, 0x1c, 0x38, 
+-      0xf0, 0x11, 0xf8, 0x00, 0x22, 0x01, 0x21, 0x1f, 
+-      0x6c, 0xbb, 0x1c, 0x38, 0xf0, 0x10, 0xff, 0xfa, 
+-      0x22, 0x01, 0x21, 0x18, 0x6c, 0xbb, 0x1c, 0x38, 
+-      0xf0, 0x10, 0xff, 0xf4, 0x21, 0x1a, 0x6c, 0xfa, 
+-      0x1c, 0x38, 0xf0, 0x10, 0xff, 0xed, 0x20, 0x00, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x00, 0x00, 0xc3, 0x50, 0xb5, 0x90, 0x1c, 0x07, 
+-      0xf7, 0xff, 0xff, 0x74, 0x28, 0x00, 0xda, 0x04, 
+-      0x20, 0x00, 0x43, 0xc0, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x24, 0x00, 0x64, 0x3c, 0x64, 0x7c, 
+-      0x1c, 0x38, 0xf0, 0x00, 0xfc, 0x2f, 0x1c, 0x20, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0xb5, 0x00, 0x1c, 0x13, 0x1c, 0x0a, 0x1c, 0x01, 
+-      0x1c, 0x18, 0xf0, 0x00, 0xf8, 0xeb, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0x90, 0x1c, 0x0b, 0x68, 0x54, 
+-      0x69, 0x27, 0x1c, 0x11, 0x2f, 0x00, 0xd0, 0x07, 
+-      0x68, 0x89, 0x1c, 0x02, 0x1c, 0x20, 0xf0, 0x10, 
+-      0xff, 0xc5, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x20, 0x00, 0x43, 0xc0, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0x90, 0x69, 0x82, 0x68, 0x44, 
+-      0xb0, 0x81, 0x42, 0x8a, 0xd1, 0x03, 0xb0, 0x01, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x22, 0xff, 
+-      0xab, 0x00, 0x61, 0x81, 0x70, 0x1a, 0x22, 0x02, 
+-      0x70, 0x5a, 0x22, 0x00, 0x70, 0x9a, 0x70, 0xd9, 
+-      0x69, 0x27, 0x2f, 0x00, 0xd0, 0x05, 0x46, 0x6a, 
+-      0x68, 0x81, 0x23, 0x04, 0x1c, 0x20, 0xf0, 0x10, 
+-      0xff, 0xa1, 0xb0, 0x01, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0x00, 0x49, 0x04, 0x68, 0x09, 
+-      0x31, 0x19, 0x61, 0x01, 0x21, 0x00, 0xf7, 0xff, 
+-      0xff, 0xd8, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x05, 0xb0, 0xb5, 0xf0, 0x1c, 0x07, 
+-      0x68, 0x40, 0x69, 0x40, 0x25, 0x00, 0xb0, 0x9e, 
+-      0x28, 0x00, 0xd1, 0x08, 0x21, 0x02, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xff, 0xc7, 0x1c, 0x28, 0xb0, 0x1e, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x23, 0x11, 
+-      0x01, 0x5b, 0x18, 0xfc, 0x70, 0x25, 0x23, 0xff, 
+-      0x22, 0x00, 0x68, 0x7e, 0x69, 0x76, 0x1c, 0x38, 
+-      0x1c, 0x21, 0x33, 0x01, 0xf0, 0x10, 0xff, 0x70, 
+-      0x46, 0x68, 0x22, 0xff, 0x1c, 0x21, 0x32, 0x01, 
+-      0xf0, 0x01, 0xfa, 0xea, 0x28, 0x00, 0xda, 0x11, 
+-      0x23, 0x03, 0x02, 0x1b, 0x18, 0xf8, 0x6a, 0x01, 
+-      0x31, 0x01, 0x62, 0x01, 0x29, 0x64, 0xdd, 0x03, 
+-      0x21, 0x00, 0x1c, 0x38, 0xf7, 0xff, 0xff, 0xa1, 
+-      0x20, 0x00, 0x43, 0xc0, 0xb0, 0x1e, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x46, 0x68, 0x1d, 0xc1, 
+-      0x31, 0x6b, 0x23, 0x01, 0x9a, 0x16, 0x68, 0x7c, 
+-      0x69, 0xa4, 0x1c, 0x38, 0xf0, 0x10, 0xff, 0x48, 
+-      0x21, 0x02, 0x1c, 0x38, 0xf7, 0xff, 0xff, 0x8d, 
+-      0x21, 0x01, 0x68, 0x7a, 0x6a, 0x92, 0x1c, 0x38, 
+-      0xf0, 0x10, 0xff, 0x3a, 0x1c, 0x28, 0xb0, 0x1e, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0x00, 
+-      0x21, 0x01, 0x68, 0x42, 0x69, 0xd2, 0xf0, 0x10, 
+-      0xff, 0x2f, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0xf0, 
+-      0x1d, 0xc6, 0x36, 0x19, 0x1c, 0x07, 0xf7, 0xff, 
+-      0xff, 0xf2, 0x0a, 0x00, 0xd2, 0x03, 0x20, 0x00, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x21, 0x02, 
+-      0x68, 0x7a, 0x69, 0xd2, 0x1c, 0x38, 0xf0, 0x10, 
+-      0xff, 0x1b, 0x1c, 0x04, 0x21, 0x03, 0x68, 0x7a, 
+-      0x69, 0xd2, 0x1c, 0x38, 0xf0, 0x10, 0xff, 0x14, 
+-      0x02, 0x00, 0x43, 0x20, 0x04, 0x04, 0x0c, 0x24, 
+-      0x69, 0xf8, 0x42, 0xa0, 0xda, 0x01, 0x04, 0x04, 
+-      0x0c, 0x24, 0x25, 0x00, 0x2c, 0x00, 0xdd, 0x09, 
+-      0x21, 0x00, 0x68, 0x7a, 0x69, 0xd2, 0x1c, 0x38, 
+-      0xf0, 0x10, 0xff, 0x02, 0x55, 0x70, 0x35, 0x01, 
+-      0x42, 0xa5, 0xdb, 0xf5, 0x1c, 0x21, 0xa0, 0x07, 
+-      0xf0, 0x11, 0xf8, 0x22, 0x69, 0xb8, 0x28, 0x06, 
+-      0xd1, 0x04, 0x68, 0xf8, 0x1c, 0x31, 0x1c, 0x22, 
+-      0xf0, 0x00, 0xff, 0x40, 0x1c, 0x20, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x63, 0x69, 0x5f, 0x73, 
+-      0x6c, 0x6f, 0x74, 0x3a, 0x20, 0x72, 0x65, 0x63, 
+-      0x65, 0x69, 0x76, 0x65, 0x64, 0x20, 0x64, 0x61, 
+-      0x74, 0x61, 0x20, 0x6c, 0x65, 0x6e, 0x3d, 0x25, 
+-      0x64, 0x0a, 0x00, 0x00, 0xb5, 0xf0, 0x1c, 0x14, 
+-      0x1c, 0x0d, 0x1c, 0x07, 0xf7, 0xff, 0xff, 0xab, 
+-      0x22, 0x01, 0x21, 0x01, 0x68, 0x7b, 0x6a, 0x1b, 
+-      0x1c, 0x38, 0xf0, 0x10, 0xfe, 0xd3, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xff, 0x99, 0x09, 0xc0, 0xd3, 0x23, 
+-      0x06, 0x22, 0x0e, 0x12, 0x21, 0x02, 0x68, 0x7b, 
+-      0x6a, 0x1b, 0x1c, 0x38, 0xf0, 0x10, 0xfe, 0xc6, 
+-      0x12, 0x22, 0x21, 0x03, 0x68, 0x7b, 0x6a, 0x1b, 
+-      0x1c, 0x38, 0xf0, 0x10, 0xfe, 0xbf, 0x26, 0x00, 
+-      0x2c, 0x00, 0xdd, 0x09, 0x5d, 0xaa, 0x21, 0x00, 
+-      0x68, 0x7b, 0x6a, 0x1b, 0x1c, 0x38, 0xf0, 0x10, 
+-      0xfe, 0xb5, 0x36, 0x01, 0x42, 0xa6, 0xdb, 0xf5, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xff, 0x78, 0x08, 0x80, 
+-      0xd3, 0x02, 0xa0, 0x0b, 0xf0, 0x10, 0xff, 0xd0, 
+-      0x22, 0x00, 0x21, 0x01, 0x68, 0x7b, 0x6a, 0x1b, 
+-      0x1c, 0x38, 0xf0, 0x10, 0xfe, 0xa3, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xff, 0x69, 0x08, 0x80, 0xd3, 0x02, 
+-      0xa0, 0x0b, 0xf0, 0x10, 0xff, 0xc1, 0x20, 0x00, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x63, 0x69, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 
+-      0x77, 0x72, 0x69, 0x74, 0x65, 0x3a, 0x20, 0x77, 
+-      0x72, 0x69, 0x74, 0x65, 0x20, 0x65, 0x72, 0x72, 
+-      0x6f, 0x72, 0x20, 0x31, 0x0a, 0x00, 0x00, 0x00, 
+-      0x63, 0x69, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 
+-      0x77, 0x72, 0x69, 0x74, 0x65, 0x3a, 0x20, 0x77, 
+-      0x72, 0x69, 0x74, 0x65, 0x20, 0x65, 0x72, 0x72, 
+-      0x6f, 0x72, 0x20, 0x32, 0x0a, 0x00, 0x00, 0x00, 
+-      0xb5, 0x00, 0x1c, 0x0a, 0x1d, 0xc1, 0x31, 0xff, 
+-      0x31, 0x1a, 0xf7, 0xff, 0xff, 0x8f, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0x80, 0x1c, 0x07, 0xa0, 0x0d, 
+-      0xf0, 0x10, 0xff, 0x8e, 0x22, 0x08, 0x21, 0x01, 
+-      0x68, 0x7b, 0x6a, 0x1b, 0x1c, 0x38, 0xf0, 0x10, 
+-      0xfe, 0x61, 0x21, 0x03, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfe, 0xa8, 0x48, 0x0a, 0x68, 0x00, 0x30, 0x05, 
+-      0x61, 0x38, 0x20, 0x00, 0x23, 0x03, 0x02, 0x1b, 
+-      0x18, 0xf9, 0x62, 0x08, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x63, 0x69, 0x5f, 0x73, 
+-      0x6c, 0x6f, 0x74, 0x3a, 0x20, 0x72, 0x65, 0x73, 
+-      0x65, 0x74, 0x0a, 0x00, 0x2e, 0x08, 0x05, 0xb0, 
+-      0xb5, 0x90, 0x22, 0x00, 0x21, 0x01, 0x68, 0x43, 
+-      0x6a, 0x1b, 0x1c, 0x07, 0xf0, 0x10, 0xfe, 0x3e, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xff, 0x04, 0x23, 0x40, 
+-      0x40, 0x18, 0x4c, 0x14, 0xd1, 0x13, 0x68, 0x20, 
+-      0x30, 0x05, 0x23, 0x03, 0x02, 0x1b, 0x61, 0x38, 
+-      0x18, 0xf8, 0x6a, 0x01, 0x31, 0x01, 0x62, 0x01, 
+-      0x29, 0x0a, 0xdd, 0x03, 0x21, 0x00, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfe, 0x73, 0x20, 0x00, 0x43, 0xc0, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x22, 0x04, 
+-      0x21, 0x01, 0x68, 0x7b, 0x6a, 0x1b, 0x1c, 0x38, 
+-      0xf0, 0x10, 0xfe, 0x1c, 0x21, 0x04, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfe, 0x63, 0x68, 0x20, 0x30, 0x05, 
+-      0x61, 0x38, 0x20, 0x00, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x05, 0xb0, 
+-      0xb5, 0xf0, 0x26, 0xff, 0x36, 0x01, 0x61, 0xc6, 
+-      0x1d, 0xc5, 0x35, 0x19, 0x1c, 0x07, 0xf7, 0xff, 
+-      0xfe, 0xd6, 0x4c, 0x17, 0x28, 0x00, 0xd1, 0x0d, 
+-      0xa0, 0x16, 0xf0, 0x10, 0xff, 0x25, 0x21, 0xfe, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xfe, 0x46, 0x68, 0x20, 
+-      0x61, 0x78, 0x20, 0x00, 0x43, 0xc0, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x78, 0x28, 0x02, 0x00, 
+-      0x78, 0x69, 0x43, 0x01, 0x61, 0xf9, 0xa0, 0x19, 
+-      0xf0, 0x10, 0xff, 0x12, 0x69, 0xf8, 0x42, 0xb0, 
+-      0xdd, 0x00, 0x61, 0xfe, 0x22, 0x02, 0x21, 0x01, 
+-      0x68, 0x7b, 0x6a, 0x1b, 0x1c, 0x38, 0xf0, 0x10, 
+-      0xfd, 0xe1, 0x68, 0x20, 0x30, 0x05, 0x61, 0x38, 
+-      0x21, 0x05, 0x1c, 0x38, 0xf7, 0xff, 0xfe, 0x25, 
+-      0x20, 0x00, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x05, 0xb0, 0x63, 0x69, 0x5f, 0x73, 
+-      0x6c, 0x6f, 0x74, 0x3a, 0x20, 0x6d, 0x6f, 0x64, 
+-      0x75, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 
+-      0x72, 0x65, 0x61, 0x64, 0x79, 0x20, 0x74, 0x6f, 
+-      0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x62, 0x75, 
+-      0x66, 0x66, 0x65, 0x72, 0x20, 0x73, 0x69, 0x7a, 
+-      0x65, 0x0a, 0x00, 0x00, 0x63, 0x69, 0x5f, 0x73, 
+-      0x6c, 0x6f, 0x74, 0x3a, 0x20, 0x6d, 0x6f, 0x64, 
+-      0x75, 0x6c, 0x65, 0x20, 0x62, 0x75, 0x66, 0x66, 
+-      0x65, 0x72, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 
+-      0x3d, 0x20, 0x25, 0x30, 0x34, 0x78, 0x0a, 0x00, 
+-      0xb5, 0xb0, 0x1c, 0x07, 0xf7, 0xff, 0xfe, 0x6f, 
+-      0x23, 0x40, 0x40, 0x18, 0x25, 0x00, 0x43, 0xed, 
+-      0x4c, 0x3d, 0x28, 0x00, 0xd1, 0x0c, 0xa0, 0x3d, 
+-      0xf0, 0x10, 0xfe, 0xc2, 0x21, 0xff, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfd, 0xe3, 0x68, 0x20, 0x61, 0x78, 
+-      0x1c, 0x28, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x22, 0x03, 0x21, 0x01, 0x68, 0x7b, 0x6a, 0x1b, 
+-      0x1c, 0x38, 0xf0, 0x10, 0xfd, 0x8b, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfe, 0x51, 0x09, 0xc0, 0xd2, 0x0c, 
+-      0xa0, 0x3d, 0xf0, 0x10, 0xfe, 0xa9, 0x21, 0xff, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xfd, 0xca, 0x68, 0x20, 
+-      0x61, 0x78, 0x1c, 0x28, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x22, 0x02, 0x21, 0x02, 0x68, 0x7b, 
+-      0x6a, 0x1b, 0x1c, 0x38, 0xf0, 0x10, 0xfd, 0x72, 
+-      0x22, 0x00, 0x21, 0x03, 0x68, 0x7b, 0x6a, 0x1b, 
+-      0x1c, 0x38, 0xf0, 0x10, 0xfd, 0x6b, 0x69, 0xf8, 
+-      0x12, 0x02, 0x21, 0x00, 0x68, 0x7b, 0x6a, 0x1b, 
+-      0x1c, 0x38, 0xf0, 0x10, 0xfd, 0x63, 0x69, 0xf8, 
+-      0x06, 0x02, 0x0e, 0x12, 0x21, 0x00, 0x68, 0x7b, 
+-      0x6a, 0x1b, 0x1c, 0x38, 0xf0, 0x10, 0xfd, 0x5a, 
+-      0xa0, 0x34, 0xf0, 0x10, 0xfe, 0x7d, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfe, 0x1d, 0x08, 0x80, 0xd3, 0x02, 
+-      0xa0, 0x3e, 0xf0, 0x10, 0xfe, 0x75, 0x22, 0x00, 
+-      0x21, 0x01, 0x68, 0x7b, 0x6a, 0x1b, 0x1c, 0x38, 
+-      0xf0, 0x10, 0xfd, 0x48, 0x68, 0xf8, 0x69, 0xf9, 
+-      0xf0, 0x00, 0xfa, 0x3e, 0x48, 0x42, 0x68, 0xf9, 
+-      0x4b, 0x42, 0x18, 0xc9, 0x61, 0x48, 0x68, 0xf8, 
+-      0x18, 0xc0, 0x61, 0x07, 0x48, 0x40, 0x68, 0xf9, 
+-      0x18, 0xc9, 0x61, 0x88, 0x68, 0xf8, 0x18, 0xc0, 
+-      0x60, 0xc7, 0x69, 0xf9, 0xa0, 0x3d, 0xf0, 0x10, 
+-      0xfe, 0x57, 0x68, 0x20, 0x61, 0x38, 0x21, 0x06, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xfd, 0x76, 0x20, 0x00, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x05, 0xb0, 0x63, 0x69, 0x5f, 0x73, 
+-      0x6c, 0x6f, 0x74, 0x3a, 0x20, 0x6d, 0x6f, 0x64, 
+-      0x75, 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 
+-      0x72, 0x65, 0x61, 0x64, 0x79, 0x20, 0x74, 0x6f, 
+-      0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 
+-      0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 
+-      0x73, 0x69, 0x7a, 0x65, 0x0a, 0x00, 0x00, 0x00, 
+-      0x63, 0x69, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x3a, 
+-      0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 
+-      0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x61, 0x64, 
+-      0x79, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x63, 
+-      0x65, 0x69, 0x76, 0x65, 0x20, 0x62, 0x75, 0x66, 
+-      0x66, 0x65, 0x72, 0x20, 0x73, 0x69, 0x7a, 0x65, 
+-      0x20, 0x32, 0x0a, 0x00, 0x63, 0x69, 0x5f, 0x73, 
+-      0x6c, 0x6f, 0x74, 0x3a, 0x20, 0x73, 0x65, 0x6e, 
+-      0x64, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x65, 0x67, 
+-      0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 
+-      0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x73, 
+-      0x69, 0x7a, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, 
+-      0x20, 0x74, 0x6f, 0x20, 0x6d, 0x6f, 0x64, 0x75, 
+-      0x6c, 0x65, 0x0a, 0x00, 0x63, 0x69, 0x5f, 0x73, 
+-      0x6c, 0x6f, 0x74, 0x5f, 0x6e, 0x65, 0x67, 0x6f, 
+-      0x74, 0x69, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x62, 
+-      0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x73, 0x69, 
+-      0x7a, 0x65, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 
+-      0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x00, 
+-      0x2e, 0x00, 0x7c, 0x55, 0x00, 0x01, 0x3b, 0x80, 
+-      0x2e, 0x00, 0x7c, 0x67, 0x63, 0x69, 0x5f, 0x73, 
+-      0x6c, 0x6f, 0x74, 0x3a, 0x20, 0x62, 0x75, 0x66, 
+-      0x66, 0x65, 0x72, 0x20, 0x73, 0x69, 0x7a, 0x65, 
+-      0x20, 0x3d, 0x20, 0x25, 0x30, 0x34, 0x78, 0x0a, 
+-      0x00, 0x00, 0x00, 0x00, 0xb5, 0x80, 0x1c, 0x07, 
+-      0x20, 0xff, 0x30, 0x01, 0x61, 0xf8, 0x21, 0x00, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xfc, 0xea, 0x48, 0x05, 
+-      0x68, 0x00, 0x61, 0x38, 0x48, 0x04, 0xf7, 0xfd, 
+-      0xfc, 0xe5, 0x60, 0xf8, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x05, 0xb0, 
+-      0x00, 0x01, 0x3b, 0x9c, 0xb5, 0x00, 0x68, 0xc0, 
+-      0xf7, 0xfd, 0xfc, 0xfa, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0x80, 0x1c, 0x1f, 0x06, 0x0b, 0x0e, 0x1b, 
+-      0x69, 0x81, 0x29, 0x06, 0xd0, 0x04, 0x20, 0x00, 
+-      0x43, 0xc0, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x78, 0x11, 0x29, 0xff, 0xd1, 0x05, 0xf7, 0xff, 
+-      0xfc, 0xe4, 0x1c, 0x38, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x68, 0xc0, 0x1c, 0x11, 0x1c, 0x3a, 
+-      0xf0, 0x00, 0xfb, 0x9a, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x69, 0x00, 0x49, 0x04, 0x68, 0x09, 
+-      0x1a, 0x40, 0x4b, 0x04, 0x42, 0x98, 0xd2, 0x01, 
+-      0x20, 0x00, 0x47, 0x70, 0x20, 0x01, 0x47, 0x70, 
+-      0x2e, 0x08, 0x05, 0xb0, 0x80, 0x00, 0x00, 0x00, 
+-      0xb5, 0x90, 0x68, 0x44, 0x6a, 0x61, 0x1c, 0x07, 
+-      0x29, 0x00, 0xd0, 0x03, 0x1c, 0x38, 0xf0, 0x10, 
+-      0xfc, 0x51, 0xe0, 0x00, 0x20, 0x01, 0x08, 0x40, 
+-      0xd2, 0x06, 0x21, 0x00, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfc, 0x98, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x69, 0xb8, 0x28, 0x00, 0xd1, 0xf9, 0x6a, 0xa2, 
+-      0x2a, 0x00, 0xd0, 0x03, 0x21, 0x02, 0x1c, 0x38, 
+-      0xf0, 0x10, 0xfc, 0x3e, 0x21, 0x01, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfc, 0x87, 0x20, 0x00, 0x23, 0x03, 
+-      0x02, 0x1b, 0x18, 0xf9, 0x62, 0x08, 0x48, 0x03, 
+-      0x68, 0x00, 0x30, 0x19, 0x61, 0x38, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x05, 0xb0, 
+-      0xb5, 0x90, 0x1c, 0x07, 0xf7, 0xff, 0xff, 0xcc, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xff, 0xba, 0x28, 0x00, 
+-      0xd1, 0x03, 0x43, 0xc0, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x69, 0xb8, 0x4c, 0x23, 0x28, 0x05, 
+-      0xd0, 0x30, 0xdc, 0x0b, 0x28, 0x01, 0xd0, 0x1e, 
+-      0x28, 0x02, 0xd0, 0x23, 0x28, 0x03, 0xd0, 0x25, 
+-      0x28, 0x04, 0xd1, 0x14, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfe, 0x03, 0xe0, 0x10, 0x28, 0x06, 0xd0, 0x25, 
+-      0x28, 0xfe, 0xd0, 0x01, 0x28, 0xff, 0xd1, 0x0a, 
+-      0x69, 0x78, 0x68, 0x21, 0x1a, 0x08, 0x23, 0xff, 
+-      0x33, 0xf5, 0x42, 0x98, 0xd9, 0x03, 0x21, 0x00, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xfc, 0x4a, 0x20, 0x00, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x68, 0x20, 
+-      0x30, 0x05, 0x61, 0x38, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfc, 0x6d, 0xe7, 0xf4, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfd, 0x84, 0xe7, 0xf0, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfd, 0xa7, 0xe7, 0xec, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfe, 0x3f, 0xe7, 0xe8, 0x68, 0xf8, 0xf0, 0x00, 
+-      0xfc, 0x53, 0x28, 0x00, 0xd1, 0x02, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfc, 0xb1, 0x68, 0xf8, 0xf0, 0x00, 
+-      0xfb, 0xd9, 0x68, 0x20, 0x30, 0x02, 0x61, 0x38, 
+-      0xe7, 0xd9, 0x00, 0x00, 0x2e, 0x08, 0x05, 0xb0, 
+-      0xb5, 0xb0, 0x06, 0x15, 0x0e, 0x2d, 0x9f, 0x04, 
+-      0x68, 0x42, 0x1c, 0x1c, 0x42, 0x8a, 0xdc, 0x04, 
+-      0x20, 0x00, 0x43, 0xc0, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x68, 0xc0, 0x23, 0xc9, 0x00, 0x9b, 
+-      0x43, 0x59, 0x18, 0x40, 0x1c, 0x29, 0x1c, 0x22, 
+-      0x1c, 0x3b, 0xf7, 0xff, 0xff, 0x35, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0x90, 0x24, 0x00, 
+-      0x1c, 0x07, 0x68, 0x40, 0x28, 0x00, 0xdd, 0x0a, 
+-      0x21, 0xc9, 0x00, 0x89, 0x43, 0x61, 0x68, 0xf8, 
+-      0x18, 0x40, 0xf7, 0xff, 0xff, 0x81, 0x68, 0x78, 
+-      0x34, 0x01, 0x42, 0xa0, 0xdc, 0xf4, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0x90, 0x24, 0x00, 
+-      0x1c, 0x07, 0x68, 0x40, 0x28, 0x00, 0xdd, 0x0f, 
+-      0x21, 0xc9, 0x00, 0x89, 0x43, 0x61, 0x68, 0xf8, 
+-      0x18, 0x40, 0x60, 0x84, 0x68, 0x3a, 0xc0, 0x84, 
+-      0x68, 0xf8, 0x18, 0x40, 0xf7, 0xff, 0xfe, 0xee, 
+-      0x68, 0x78, 0x34, 0x01, 0x42, 0xa0, 0xdc, 0xef, 
+-      0x20, 0x00, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0xf0, 0x25, 0x00, 0x1c, 0x07, 0x68, 0x40, 
+-      0x1c, 0x0c, 0x28, 0x00, 0xdd, 0x0f, 0x26, 0x01, 
+-      0x1c, 0x30, 0x40, 0xa8, 0x40, 0x20, 0xd0, 0x06, 
+-      0x21, 0xc9, 0x00, 0x89, 0x43, 0x69, 0x68, 0xf8, 
+-      0x18, 0x40, 0xf7, 0xff, 0xfb, 0xe6, 0x68, 0x78, 
+-      0x35, 0x01, 0x42, 0xa8, 0xdc, 0xf0, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb4, 0xf0, 0x21, 0x00, 
+-      0x78, 0x07, 0x22, 0x80, 0x43, 0xd2, 0x40, 0x3a, 
+-      0x1c, 0x04, 0x0a, 0x3b, 0xd3, 0x0f, 0x27, 0x00, 
+-      0x30, 0x01, 0x2a, 0x00, 0xdd, 0x0d, 0x1b, 0xd3, 
+-      0x00, 0xdb, 0x78, 0x06, 0x1f, 0xdd, 0x3d, 0x01, 
+-      0x40, 0xae, 0x43, 0x31, 0x30, 0x01, 0x37, 0x01, 
+-      0x42, 0x97, 0xdb, 0xf4, 0xe0, 0x01, 0x30, 0x01, 
+-      0x1c, 0x11, 0x1b, 0x00, 0x18, 0x40, 0xbc, 0xf0, 
+-      0x47, 0x70, 0xb4, 0xb0, 0x22, 0x01, 0x28, 0x80, 
+-      0xda, 0x02, 0x70, 0x08, 0xbc, 0xb0, 0x47, 0x70, 
+-      0x27, 0x03, 0x25, 0xff, 0x00, 0xfc, 0x1c, 0x2b, 
+-      0x40, 0xa3, 0x40, 0x03, 0xd0, 0x03, 0x1c, 0x03, 
+-      0x41, 0x23, 0x54, 0x8b, 0x32, 0x01, 0x37, 0x01, 
+-      0xd5, 0xf4, 0x20, 0x80, 0x43, 0x10, 0x70, 0x08, 
+-      0xbc, 0xb0, 0x47, 0x70, 0xb5, 0xb0, 0x22, 0x00, 
+-      0x78, 0x41, 0x1c, 0x47, 0x20, 0x80, 0x43, 0xc0, 
+-      0x40, 0x08, 0x0a, 0x09, 0xd3, 0x0f, 0x21, 0x00, 
+-      0x37, 0x01, 0x28, 0x00, 0xdd, 0x0d, 0x1a, 0x43, 
+-      0x00, 0xdb, 0x78, 0x3d, 0x1f, 0xdc, 0x3c, 0x01, 
+-      0x40, 0xa5, 0x43, 0x2a, 0x31, 0x01, 0x37, 0x01, 
+-      0x42, 0x81, 0xdb, 0xf4, 0xe0, 0x01, 0x1c, 0x02, 
+-      0x37, 0x01, 0x78, 0x3b, 0xa1, 0x03, 0xa0, 0x04, 
+-      0xf0, 0x10, 0xfc, 0x42, 0x78, 0x38, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x63, 0x69, 0x3a, 0x00, 
+-      0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 
+-      0x3a, 0x20, 0x25, 0x73, 0x2c, 0x20, 0x6c, 0x65, 
+-      0x6e, 0x3d, 0x25, 0x64, 0x2c, 0x20, 0x69, 0x64, 
+-      0x3d, 0x25, 0x30, 0x32, 0x78, 0x0a, 0x00, 0x00, 
+-      0xb5, 0xb0, 0x25, 0x00, 0x60, 0x01, 0x1c, 0x07, 
+-      0x4b, 0x2f, 0x18, 0xc4, 0x72, 0x25, 0x72, 0x65, 
+-      0x72, 0xa5, 0x72, 0xe5, 0x1c, 0x08, 0x21, 0x01, 
+-      0x04, 0x09, 0xf0, 0x10, 0xfb, 0x01, 0x21, 0x01, 
+-      0x02, 0x49, 0x42, 0x88, 0xdd, 0x01, 0x60, 0x79, 
+-      0xe0, 0x00, 0x60, 0x78, 0x22, 0x01, 0x04, 0x12, 
+-      0x21, 0x00, 0x1d, 0xf8, 0x30, 0x01, 0xf0, 0x10, 
+-      0xfb, 0xa7, 0x20, 0x00, 0x43, 0xc1, 0x00, 0x82, 
+-      0x19, 0xd2, 0x4b, 0x22, 0x18, 0xd3, 0x60, 0x9d, 
+-      0x4b, 0x21, 0x18, 0xd3, 0x60, 0x9d, 0x23, 0x9d, 
+-      0x02, 0x5b, 0x18, 0xd3, 0x60, 0x9d, 0x4b, 0x1f, 
+-      0x18, 0xd2, 0x60, 0x95, 0x00, 0x42, 0x19, 0xd2, 
+-      0x4b, 0x1d, 0x18, 0xd3, 0x81, 0x19, 0x4b, 0x1d, 
+-      0x18, 0xd2, 0x81, 0x11, 0x30, 0x01, 0x28, 0x20, 
+-      0xdb, 0xe5, 0x20, 0x00, 0x68, 0x79, 0x29, 0x00, 
+-      0xdd, 0x11, 0x00, 0x41, 0x18, 0x09, 0x00, 0xc9, 
+-      0x19, 0xc9, 0x23, 0x01, 0x04, 0x1b, 0x18, 0xc9, 
+-      0x72, 0x0d, 0x60, 0xcd, 0x61, 0x0d, 0x61, 0x4d, 
+-      0x76, 0x0d, 0x76, 0x4d, 0x61, 0xc8, 0x68, 0x79, 
+-      0x30, 0x01, 0x42, 0x81, 0xdc, 0xed, 0x4b, 0x10, 
+-      0x18, 0xf8, 0x22, 0x01, 0x02, 0xd2, 0x21, 0x00, 
+-      0xf0, 0x10, 0xfb, 0x6e, 0x4b, 0x0d, 0x18, 0xf8, 
+-      0x22, 0xff, 0x21, 0x00, 0x32, 0x01, 0xf0, 0x10, 
+-      0xfb, 0x67, 0x60, 0xe5, 0x61, 0x25, 0x61, 0x65, 
+-      0x61, 0xa5, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x00, 0x01, 0x3b, 0x80, 0x00, 0x01, 0x39, 0x00, 
+-      0x00, 0x01, 0x39, 0x80, 0x00, 0x01, 0x3a, 0x80, 
+-      0x00, 0x01, 0x3b, 0x00, 0x00, 0x01, 0x3b, 0x40, 
+-      0x00, 0x01, 0x30, 0x08, 0x00, 0x01, 0x38, 0x08, 
+-      0x21, 0x00, 0x70, 0x01, 0x60, 0x41, 0x60, 0x81, 
+-      0x60, 0xc1, 0x74, 0x01, 0x74, 0x41, 0x47, 0x70, 
+-      0xb4, 0x80, 0x21, 0x00, 0x68, 0x42, 0x2a, 0x00, 
+-      0xdd, 0x18, 0x00, 0x4b, 0x18, 0x5b, 0x00, 0xdb, 
+-      0x18, 0x1f, 0x23, 0x01, 0x04, 0x1b, 0x18, 0xfb, 
+-      0x7a, 0x1b, 0x2b, 0x00, 0xd1, 0x0b, 0x22, 0x01, 
+-      0x00, 0x4b, 0x18, 0x59, 0x00, 0xc9, 0x18, 0x08, 
+-      0x04, 0x13, 0x18, 0xc1, 0x72, 0x0a, 0x4b, 0x05, 
+-      0x18, 0xc0, 0xbc, 0x80, 0x47, 0x70, 0x31, 0x01, 
+-      0x42, 0x8a, 0xdc, 0xe6, 0x20, 0x00, 0xbc, 0x80, 
+-      0x47, 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 
+-      0xb5, 0xb0, 0x06, 0x1d, 0x0e, 0x2d, 0x1c, 0x14, 
+-      0x68, 0x0a, 0x21, 0x00, 0x1c, 0x07, 0xf0, 0x10, 
+-      0xfb, 0x1b, 0x70, 0x3d, 0x2c, 0x00, 0xd0, 0x04, 
+-      0x20, 0x80, 0x70, 0x78, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x20, 0x00, 0x70, 0x78, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xff, 0x99, 0x01, 
+-      0x1c, 0x1c, 0x1c, 0x15, 0x1c, 0x07, 0x29, 0x00, 
+-      0xd1, 0x04, 0x20, 0x00, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x1c, 0x28, 0xf7, 0xff, 
+-      0xff, 0xb7, 0x1c, 0x06, 0xd1, 0x01, 0x20, 0x00, 
+-      0xe7, 0xf4, 0x69, 0x70, 0x68, 0x29, 0x43, 0x48, 
+-      0x19, 0x01, 0x23, 0x01, 0x04, 0x1b, 0x42, 0x99, 
+-      0xdd, 0x01, 0x20, 0x00, 0xe7, 0xea, 0x18, 0x2d, 
+-      0x99, 0x01, 0x1d, 0xe8, 0x30, 0x01, 0x1c, 0x22, 
+-      0xf0, 0x10, 0xfa, 0x84, 0x74, 0x34, 0x7a, 0x68, 
+-      0x74, 0x70, 0x2f, 0x00, 0xd0, 0x04, 0x68, 0xb8, 
+-      0x60, 0xb0, 0x60, 0xf7, 0x60, 0xbe, 0xe0, 0x02, 
+-      0x20, 0x00, 0x60, 0xb0, 0x60, 0xf0, 0x1c, 0x30, 
+-      0xe7, 0xd4, 0xb5, 0xff, 0x9c, 0x09, 0x06, 0x25, 
+-      0x0e, 0x2d, 0x24, 0x00, 0x43, 0xe4, 0x1c, 0x07, 
+-      0x98, 0x02, 0x1c, 0x21, 0x4b, 0x4c, 0x18, 0xfa, 
+-      0x28, 0x00, 0xd0, 0x03, 0x28, 0x01, 0xd1, 0x6a, 
+-      0x20, 0x00, 0xe0, 0x2d, 0x20, 0x00, 0x00, 0x43, 
+-      0x19, 0xde, 0x4b, 0x48, 0x18, 0xf6, 0x23, 0x08, 
+-      0x5e, 0xf3, 0x42, 0xab, 0xd1, 0x00, 0x1c, 0x04, 
+-      0x29, 0x00, 0xda, 0x04, 0x1c, 0x1e, 0x23, 0x01, 
+-      0x42, 0xde, 0xd1, 0x00, 0x1c, 0x01, 0x30, 0x01, 
+-      0x28, 0x20, 0xdb, 0xec, 0x20, 0x00, 0x43, 0xc0, 
+-      0x42, 0x84, 0xd1, 0x05, 0x42, 0x81, 0xd0, 0x03, 
+-      0x7a, 0x13, 0x33, 0x01, 0x72, 0x13, 0x1c, 0x0c, 
+-      0x2c, 0x00, 0xdb, 0x44, 0x00, 0x60, 0x19, 0xc0, 
+-      0x4b, 0x38, 0x18, 0xc0, 0x81, 0x05, 0x00, 0xa0, 
+-      0x19, 0xc1, 0x4b, 0x37, 0x18, 0xc8, 0x68, 0x80, 
+-      0x4b, 0x36, 0x18, 0xc9, 0x68, 0x8d, 0xe0, 0x2c, 
+-      0x00, 0x43, 0x19, 0xde, 0x4b, 0x34, 0x18, 0xf6, 
+-      0x23, 0x08, 0x5e, 0xf3, 0x42, 0xab, 0xd1, 0x00, 
+-      0x1c, 0x04, 0x29, 0x00, 0xda, 0x04, 0x1c, 0x1e, 
+-      0x23, 0x01, 0x42, 0xde, 0xd1, 0x00, 0x1c, 0x01, 
+-      0x30, 0x01, 0x28, 0x20, 0xdb, 0xec, 0x20, 0x00, 
+-      0x43, 0xc0, 0x42, 0x84, 0xd1, 0x05, 0x42, 0x81, 
+-      0xd0, 0x03, 0x7a, 0x93, 0x33, 0x01, 0x72, 0x93, 
+-      0x1c, 0x0c, 0x2c, 0x00, 0xdb, 0x17, 0x00, 0x60, 
+-      0x19, 0xc0, 0x4b, 0x25, 0x18, 0xc0, 0x81, 0x05, 
+-      0x00, 0xa0, 0x19, 0xc1, 0x23, 0x9d, 0x02, 0x5b, 
+-      0x18, 0xc8, 0x68, 0x80, 0x4b, 0x21, 0x18, 0xc9, 
+-      0x68, 0x8d, 0x28, 0x00, 0xd0, 0x0f, 0x99, 0x01, 
+-      0x9b, 0x03, 0x1c, 0x3a, 0xf7, 0xff, 0xff, 0x5a, 
+-      0x28, 0x00, 0xd1, 0x12, 0x43, 0xc0, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0xe7, 0xff, 
+-      0x20, 0x00, 0x43, 0xc0, 0xe7, 0xf7, 0x99, 0x01, 
+-      0x9b, 0x03, 0x1c, 0x3a, 0xf7, 0xff, 0xff, 0x4a, 
+-      0x1c, 0x05, 0xd1, 0x01, 0x43, 0xe8, 0xe7, 0xee, 
+-      0x1c, 0x28, 0x60, 0x44, 0x9a, 0x02, 0x2a, 0x00, 
+-      0xd0, 0x0c, 0x2a, 0x01, 0xd1, 0x08, 0x00, 0xa1, 
+-      0x19, 0xc9, 0x23, 0x9d, 0x02, 0x5b, 0x18, 0xca, 
+-      0x60, 0x90, 0x4b, 0x0c, 0x18, 0xc8, 0x60, 0x85, 
+-      0x1c, 0x20, 0xe7, 0xdc, 0x00, 0xa1, 0x19, 0xc9, 
+-      0x4b, 0x05, 0x18, 0xca, 0x60, 0x90, 0x4b, 0x05, 
+-      0x18, 0xc8, 0x60, 0x85, 0xe7, 0xf4, 0x00, 0x00, 
+-      0x00, 0x01, 0x3b, 0x80, 0x00, 0x01, 0x3b, 0x00, 
+-      0x00, 0x01, 0x39, 0x00, 0x00, 0x01, 0x39, 0x80, 
+-      0x00, 0x01, 0x3b, 0x40, 0x00, 0x01, 0x3a, 0x80, 
+-      0xb5, 0x80, 0x27, 0x00, 0x28, 0x00, 0xd1, 0x03, 
+-      0x1c, 0x38, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x22, 0x00, 0x68, 0x81, 0x29, 0x00, 0xd0, 0x0b, 
+-      0x68, 0xc3, 0x2b, 0x00, 0xd0, 0x05, 0x60, 0x99, 
+-      0x68, 0xc1, 0x68, 0x82, 0x60, 0xd1, 0x68, 0xc7, 
+-      0xe0, 0x07, 0x60, 0xca, 0x68, 0x87, 0xe0, 0x04, 
+-      0x68, 0xc1, 0x29, 0x00, 0xd0, 0x01, 0x60, 0x8a, 
+-      0x68, 0xc7, 0xf7, 0xff, 0xfe, 0xbd, 0x1c, 0x38, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0xf7, 
+-      0x1c, 0x07, 0x98, 0x01, 0x68, 0x46, 0x99, 0x02, 
+-      0x29, 0x00, 0xd0, 0x0b, 0x29, 0x01, 0xd1, 0x12, 
+-      0x00, 0xb0, 0x19, 0xc0, 0x23, 0x9d, 0x02, 0x5b, 
+-      0x18, 0xc1, 0x68, 0x8d, 0x4b, 0x2c, 0x18, 0xc0, 
+-      0x68, 0x84, 0xe0, 0x0a, 0x00, 0xb0, 0x19, 0xc0, 
+-      0x4b, 0x2a, 0x18, 0xc1, 0x68, 0x8d, 0x4b, 0x2a, 
+-      0x18, 0xc0, 0x68, 0x84, 0xe0, 0x01, 0x25, 0x00, 
+-      0x24, 0x00, 0x99, 0x01, 0x42, 0xa9, 0xd1, 0x08, 
+-      0x98, 0x01, 0xf7, 0xff, 0xff, 0xb9, 0x99, 0x01, 
+-      0x1c, 0x05, 0x42, 0xa1, 0xd1, 0x08, 0x24, 0x00, 
+-      0xe0, 0x06, 0x99, 0x01, 0x42, 0xa1, 0xd1, 0x03, 
+-      0x98, 0x01, 0xf7, 0xff, 0xff, 0xad, 0x1c, 0x04, 
+-      0x22, 0x00, 0x43, 0xd2, 0x99, 0x02, 0x4b, 0x1d, 
+-      0x18, 0xf8, 0x29, 0x00, 0xd0, 0x1a, 0x29, 0x01, 
+-      0xd1, 0x14, 0x00, 0xb1, 0x19, 0xc9, 0x23, 0x9d, 
+-      0x02, 0x5b, 0x18, 0xcb, 0x60, 0x9d, 0x4b, 0x14, 
+-      0x18, 0xc9, 0x60, 0x8c, 0x2d, 0x00, 0xd1, 0x09, 
+-      0x2c, 0x00, 0xd1, 0x07, 0x7a, 0x81, 0x39, 0x01, 
+-      0x72, 0x81, 0x00, 0x70, 0x19, 0xc0, 0x4b, 0x12, 
+-      0x18, 0xc0, 0x81, 0x02, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0xb1, 0x19, 0xc9, 
+-      0x4b, 0x0a, 0x18, 0xcb, 0x60, 0x9d, 0x4b, 0x0a, 
+-      0x18, 0xc9, 0x60, 0x8c, 0x2d, 0x00, 0xd1, 0xf1, 
+-      0x2c, 0x00, 0xd1, 0xef, 0x7a, 0x01, 0x39, 0x01, 
+-      0x72, 0x01, 0x00, 0x70, 0x19, 0xc0, 0x4b, 0x07, 
+-      0x18, 0xc0, 0x81, 0x02, 0xe7, 0xe6, 0x00, 0x00, 
+-      0x00, 0x01, 0x3a, 0x80, 0x00, 0x01, 0x39, 0x00, 
+-      0x00, 0x01, 0x39, 0x80, 0x00, 0x01, 0x3b, 0x80, 
+-      0x00, 0x01, 0x3b, 0x40, 0x00, 0x01, 0x3b, 0x00, 
+-      0xb5, 0xf0, 0x1c, 0x17, 0x06, 0x1a, 0x0e, 0x12, 
+-      0xb0, 0x82, 0x92, 0x00, 0x1c, 0x04, 0x1c, 0x08, 
+-      0x1c, 0x0d, 0xb0, 0x81, 0xf7, 0xff, 0xfd, 0x8e, 
+-      0x90, 0x00, 0x1c, 0x3a, 0x1c, 0x03, 0xa1, 0x27, 
+-      0x48, 0x27, 0xf0, 0x10, 0xf9, 0xe9, 0x2f, 0x00, 
+-      0xdd, 0x42, 0x4b, 0x26, 0x18, 0xe0, 0x90, 0x02, 
+-      0x68, 0x20, 0x38, 0x02, 0x42, 0xb8, 0xda, 0x01, 
+-      0x1c, 0x06, 0xe0, 0x00, 0x1c, 0x3e, 0x42, 0xbe, 
+-      0xda, 0x01, 0x22, 0x01, 0xe0, 0x00, 0x22, 0x00, 
+-      0x98, 0x02, 0x9b, 0x00, 0x1c, 0x21, 0xf7, 0xff, 
+-      0xfe, 0x47, 0x9a, 0x01, 0xb4, 0x04, 0x22, 0x00, 
+-      0x99, 0x03, 0x1c, 0x20, 0x1c, 0xb3, 0xf7, 0xff, 
+-      0xfe, 0x88, 0xb0, 0x01, 0x28, 0x00, 0xda, 0x05, 
+-      0x20, 0x00, 0x43, 0xc0, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0x80, 0x19, 0x00, 
+-      0x4b, 0x13, 0x18, 0xc0, 0x68, 0x80, 0x69, 0x40, 
+-      0x68, 0x21, 0x43, 0x48, 0x30, 0x02, 0x19, 0x81, 
+-      0x23, 0x01, 0x04, 0x1b, 0x42, 0x99, 0xdd, 0x05, 
+-      0x20, 0x00, 0x43, 0xc0, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x18, 0x20, 0x30, 0x08, 
+-      0x1c, 0x29, 0x1c, 0x32, 0xf0, 0x10, 0xf8, 0xda, 
+-      0x1b, 0xbf, 0x19, 0xad, 0x2f, 0x00, 0xdc, 0xbf, 
+-      0x20, 0x00, 0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x63, 0x69, 0x3a, 0x00, 
+-      0x2e, 0x00, 0x85, 0xcc, 0x00, 0x01, 0x38, 0x08, 
+-      0x00, 0x01, 0x39, 0x00, 0xb5, 0xf3, 0xb0, 0x83, 
+-      0x1c, 0x07, 0x99, 0x04, 0x00, 0x88, 0x19, 0xc0, 
+-      0x4b, 0x2f, 0x18, 0xc0, 0x90, 0x02, 0x68, 0x84, 
+-      0x4b, 0x2e, 0x18, 0xfb, 0x93, 0x01, 0x2c, 0x00, 
+-      0xd0, 0x46, 0x25, 0x00, 0x7c, 0x26, 0x69, 0x60, 
+-      0x68, 0x39, 0x43, 0x48, 0x7c, 0x61, 0x23, 0x80, 
+-      0x40, 0x19, 0x91, 0x00, 0x30, 0x02, 0x19, 0x81, 
+-      0x02, 0x5b, 0x39, 0x02, 0x42, 0x99, 0xdd, 0x04, 
+-      0xb0, 0x03, 0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x18, 0x38, 0x1d, 0xc1, 0x31, 0x01, 
+-      0x19, 0x78, 0x1e, 0xb2, 0x4b, 0x20, 0x18, 0xc0, 
+-      0xf0, 0x10, 0xf8, 0x9c, 0x19, 0xa8, 0x1e, 0x85, 
+-      0x68, 0xa0, 0x42, 0xa0, 0xd0, 0x04, 0x1c, 0x04, 
+-      0xd0, 0x02, 0x99, 0x00, 0x29, 0x00, 0xd1, 0xd9, 
+-      0x23, 0x01, 0x02, 0xdb, 0x42, 0x9d, 0xda, 0x1b, 
+-      0x9b, 0x01, 0x68, 0xda, 0x4b, 0x16, 0x18, 0xf8, 
+-      0x9b, 0x01, 0x69, 0x9b, 0x1c, 0x29, 0xf0, 0x10, 
+-      0xf8, 0x2d, 0x28, 0x00, 0xd1, 0x18, 0x98, 0x02, 
+-      0x68, 0x81, 0x29, 0x00, 0xd0, 0x0c, 0x7c, 0x48, 
+-      0x24, 0x80, 0x40, 0x04, 0x22, 0x01, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfe, 0xd5, 0x98, 0x02, 0x68, 0x81, 
+-      0x29, 0x00, 0xd0, 0x01, 0x2c, 0x00, 0xd1, 0xf2, 
+-      0x99, 0x04, 0x1c, 0x48, 0xd5, 0x06, 0x42, 0x40, 
+-      0x06, 0xc0, 0x0e, 0xc0, 0x42, 0x40, 0xe0, 0x03, 
+-      0xb0, 0x03, 0xe7, 0xbe, 0x06, 0xc0, 0x0e, 0xc0, 
+-      0x9b, 0x01, 0x72, 0x58, 0xb0, 0x03, 0xe7, 0xb8, 
+-      0x00, 0x01, 0x3a, 0x80, 0x00, 0x01, 0x3b, 0x80, 
+-      0x00, 0x01, 0x30, 0x08, 0xb5, 0xf0, 0x21, 0x00, 
+-      0x4b, 0x24, 0x18, 0xc4, 0x7a, 0xe7, 0x7a, 0xa2, 
+-      0x25, 0x00, 0x2a, 0x00, 0xd1, 0x03, 0x1c, 0x28, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x22, 0x00, 
+-      0xe0, 0x1e, 0x00, 0x7b, 0x18, 0x1e, 0x4b, 0x1e, 
+-      0x18, 0xf6, 0x23, 0x08, 0x5e, 0xf3, 0x2b, 0x00, 
+-      0xdb, 0x0c, 0x00, 0xbb, 0x18, 0x1e, 0x23, 0x9d, 
+-      0x02, 0x5b, 0x18, 0xf3, 0x68, 0x9b, 0x2b, 0x00, 
+-      0xd0, 0x04, 0x7c, 0x5e, 0x0a, 0x33, 0xd2, 0x01, 
+-      0x21, 0x01, 0xe0, 0x09, 0x37, 0x01, 0xd5, 0x04, 
+-      0x42, 0x7f, 0x06, 0xff, 0x0e, 0xff, 0x42, 0x7f, 
+-      0xe0, 0x01, 0x06, 0xff, 0x0e, 0xff, 0x32, 0x01, 
+-      0x2a, 0x20, 0xda, 0x01, 0x29, 0x00, 0xd0, 0xdc, 
+-      0x29, 0x00, 0xd1, 0x04, 0x72, 0xe5, 0x1c, 0x28, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x72, 0xe7, 
+-      0x1c, 0x39, 0xf7, 0xff, 0xff, 0x57, 0x1c, 0x78, 
+-      0xd5, 0x04, 0x42, 0x40, 0x06, 0xc0, 0x0e, 0xc0, 
+-      0x42, 0x40, 0xe0, 0x01, 0x06, 0xc0, 0x0e, 0xc0, 
+-      0x72, 0xe0, 0x20, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x00, 0x01, 0x3b, 0x80, 
+-      0x00, 0x01, 0x3b, 0x40, 0xb5, 0xb0, 0x78, 0x0b, 
+-      0x1c, 0x14, 0x1c, 0x05, 0x1c, 0x0f, 0xa1, 0x0c, 
+-      0x48, 0x0c, 0xf0, 0x10, 0xf8, 0xd1, 0x78, 0x3a, 
+-      0xb4, 0x04, 0x22, 0x01, 0x1c, 0x28, 0x1c, 0x39, 
+-      0x1c, 0x23, 0xf7, 0xff, 0xfd, 0x86, 0xb0, 0x01, 
+-      0x28, 0x00, 0xda, 0x04, 0x20, 0x00, 0x43, 0xc0, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x20, 0x00, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x63, 0x69, 0x3a, 0x00, 0x2e, 0x00, 0x85, 0xcc, 
+-      0xb5, 0xf0, 0x1c, 0x07, 0x4b, 0x2a, 0x18, 0xc4, 
+-      0x7a, 0x65, 0x7a, 0x20, 0x28, 0x00, 0xd1, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x20, 0x00, 
+-      0x43, 0xc1, 0xe0, 0x09, 0x35, 0x01, 0xd5, 0x04, 
+-      0x42, 0x6d, 0x06, 0xed, 0x0e, 0xed, 0x42, 0x6d, 
+-      0xe0, 0x01, 0x06, 0xed, 0x0e, 0xed, 0x30, 0x01, 
+-      0x28, 0x20, 0xda, 0x07, 0x00, 0x6a, 0x19, 0xd2, 
+-      0x4b, 0x1e, 0x18, 0xd2, 0x23, 0x08, 0x5e, 0xd2, 
+-      0x42, 0x8a, 0xd0, 0xeb, 0x00, 0xa8, 0x19, 0xc0, 
+-      0x4b, 0x1b, 0x18, 0xc1, 0x68, 0x89, 0x29, 0x00, 
+-      0xd0, 0x10, 0x72, 0x65, 0x4b, 0x19, 0x18, 0xc6, 
+-      0x68, 0xb1, 0x69, 0x48, 0x68, 0x3a, 0x43, 0x50, 
+-      0x7c, 0x09, 0x18, 0x0a, 0x23, 0x01, 0x04, 0x1b, 
+-      0x42, 0x9a, 0xdd, 0x08, 0x20, 0x00, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x20, 0x00, 0x72, 0x60, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x18, 0x38, 
+-      0x69, 0x22, 0x69, 0x63, 0x30, 0x08, 0xf0, 0x0f, 
+-      0xff, 0x4d, 0x22, 0x00, 0x68, 0xb1, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfd, 0xfd, 0x1c, 0x68, 0xd5, 0x04, 
+-      0x42, 0x40, 0x06, 0xc0, 0x0e, 0xc0, 0x42, 0x40, 
+-      0xe0, 0x01, 0x06, 0xc0, 0x0e, 0xc0, 0x72, 0x60, 
+-      0x20, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x00, 0x01, 0x3b, 0x80, 0x00, 0x01, 0x3b, 0x00, 
+-      0x00, 0x01, 0x39, 0x00, 0x00, 0x01, 0x39, 0x80, 
+-      0xb5, 0xff, 0xb0, 0x8b, 0x9a, 0x0d, 0x1c, 0x1c, 
+-      0x1c, 0x0f, 0x2a, 0x02, 0xda, 0x06, 0x20, 0x00, 
+-      0x43, 0xc0, 0xb0, 0x0b, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x78, 0x79, 0x91, 0x04, 
+-      0x31, 0x02, 0x78, 0x3b, 0x1c, 0x0d, 0x42, 0x83, 
+-      0xd0, 0x07, 0x1c, 0x19, 0x1c, 0x02, 0xa0, 0xf9, 
+-      0xf0, 0x10, 0xf8, 0x3e, 0x42, 0x68, 0xb0, 0x0b, 
+-      0xe7, 0xec, 0x9a, 0x0d, 0x42, 0x91, 0xdd, 0x02, 
+-      0x42, 0x68, 0xb0, 0x0b, 0xe7, 0xe6, 0x1d, 0x39, 
+-      0x91, 0x0a, 0x1d, 0xe2, 0x32, 0x59, 0x92, 0x09, 
+-      0x1d, 0xe6, 0x36, 0x39, 0x28, 0x1d, 0xd0, 0x63, 
+-      0xdc, 0x08, 0x28, 0x15, 0xd0, 0x13, 0x28, 0x1a, 
+-      0xd0, 0x5f, 0x28, 0x1b, 0xd0, 0x5e, 0x28, 0x1c, 
+-      0xd0, 0x5a, 0xe0, 0x7a, 0x28, 0x20, 0xd0, 0x41, 
+-      0x1c, 0xbe, 0x28, 0xc0, 0xd0, 0x74, 0x28, 0xc1, 
+-      0xd1, 0x73, 0x98, 0x14, 0x28, 0x1b, 0xd0, 0x71, 
+-      0x42, 0x68, 0xb0, 0x0b, 0xe7, 0xc6, 0x78, 0xb8, 
+-      0x28, 0x05, 0xd0, 0x02, 0x42, 0x68, 0xb0, 0x0b, 
+-      0xe7, 0xc0, 0x78, 0xf8, 0x28, 0x00, 0xd0, 0x02, 
+-      0x42, 0x68, 0xb0, 0x0b, 0xe7, 0xba, 0x98, 0x04, 
+-      0x1e, 0x82, 0x2a, 0x4f, 0xda, 0x04, 0x99, 0x0a, 
+-      0x1c, 0x20, 0xf0, 0x0f, 0xff, 0x33, 0xe0, 0x04, 
+-      0x22, 0x4f, 0x99, 0x0a, 0x1c, 0x20, 0xf0, 0x0f, 
+-      0xff, 0x2d, 0x78, 0xfa, 0x78, 0xb9, 0x9c, 0x0a, 
+-      0xa0, 0xe0, 0x1c, 0x23, 0xf0, 0x0f, 0xff, 0xf4, 
+-      0x98, 0x04, 0x18, 0x38, 0x1c, 0x47, 0x42, 0xa7, 
+-      0xd9, 0x0c, 0x1c, 0x20, 0xf0, 0x0f, 0xff, 0x62, 
+-      0x19, 0x00, 0x1c, 0x44, 0x42, 0xa7, 0xd9, 0x03, 
+-      0x1c, 0x21, 0xa0, 0xdd, 0xf0, 0x0f, 0xff, 0xe4, 
+-      0x42, 0xa7, 0xd8, 0xf2, 0xa0, 0xd4, 0xf0, 0x0f, 
+-      0xff, 0xdf, 0xe0, 0xe3, 0x98, 0x04, 0x28, 0x04, 
+-      0xd0, 0x02, 0x42, 0x68, 0xb0, 0x0b, 0xe7, 0x89, 
+-      0x78, 0xf8, 0x02, 0x00, 0x78, 0xb9, 0x43, 0x08, 
+-      0x82, 0x30, 0x79, 0x78, 0x02, 0x00, 0x79, 0x39, 
+-      0x43, 0x08, 0x82, 0x70, 0x8a, 0x72, 0x8a, 0x31, 
+-      0xa0, 0xd1, 0xf0, 0x0f, 0xff, 0xc9, 0xe0, 0xcd, 
+-      0xe2, 0x17, 0xe0, 0x00, 0xe0, 0x62, 0x78, 0xb8, 
+-      0x07, 0x80, 0x0f, 0x80, 0x30, 0x01, 0x75, 0x30, 
+-      0x78, 0xb8, 0x08, 0x80, 0x07, 0x00, 0x0f, 0x00, 
+-      0x30, 0x01, 0x75, 0x70, 0x78, 0xf8, 0x9a, 0x09, 
+-      0x73, 0x10, 0x20, 0x00, 0x65, 0xa0, 0x7d, 0x31, 
+-      0x29, 0x00, 0xdd, 0x0e, 0x18, 0x39, 0x79, 0x09, 
+-      0x00, 0xc2, 0x40, 0x91, 0x6d, 0xa2, 0x43, 0x11, 
+-      0x65, 0xa1, 0x7d, 0x31, 0x30, 0x01, 0xe0, 0x02, 
+-      0xe1, 0x02, 0xe1, 0xf9, 0xe1, 0x4b, 0x42, 0x81, 
+-      0xdc, 0xf0, 0x7d, 0x30, 0x30, 0x04, 0x90, 0x03, 
+-      0x7d, 0x72, 0x18, 0x39, 0x1d, 0xe0, 0x30, 0x55, 
+-      0xf0, 0x0f, 0xfe, 0xcc, 0x7d, 0x70, 0x99, 0x03, 
+-      0x18, 0x40, 0x90, 0x03, 0x6d, 0xa1, 0xa0, 0xbc, 
+-      0xf0, 0x0f, 0xff, 0x92, 0x7d, 0x70, 0x28, 0x00, 
+-      0xd0, 0x17, 0xa0, 0xbf, 0xf0, 0x0f, 0xff, 0x8c, 
+-      0x21, 0x00, 0x91, 0x02, 0x7d, 0x70, 0x28, 0x00, 
+-      0xdd, 0x0c, 0x99, 0x02, 0x18, 0x60, 0x30, 0x40, 
+-      0x7f, 0x01, 0xa0, 0xbc, 0xf0, 0x0f, 0xff, 0x80, 
+-      0x99, 0x02, 0x31, 0x01, 0x91, 0x02, 0x7d, 0x70, 
+-      0x42, 0x88, 0xdc, 0xf2, 0xa0, 0xb9, 0xf0, 0x0f, 
+-      0xff, 0x77, 0x9a, 0x09, 0x7b, 0x11, 0xa0, 0xb8, 
+-      0xf0, 0x0f, 0xff, 0x72, 0x22, 0x1a, 0xb4, 0x04, 
+-      0x98, 0x04, 0x9a, 0x0e, 0x1a, 0x12, 0x18, 0x39, 
+-      0x20, 0xc0, 0x1c, 0x23, 0xf7, 0xff, 0xff, 0x10, 
+-      0xb0, 0x01, 0x28, 0x00, 0xda, 0x6a, 0x42, 0x68, 
+-      0xb0, 0x0b, 0xe7, 0x13, 0x78, 0xb8, 0x06, 0x86, 
+-      0x0e, 0xb6, 0x1c, 0x31, 0xa0, 0xb1, 0xf0, 0x0f, 
+-      0xff, 0x5b, 0x9a, 0x09, 0x7b, 0x10, 0x42, 0xb0, 
+-      0xd1, 0x01, 0x22, 0x01, 0x67, 0x62, 0x78, 0xb8, 
+-      0x23, 0xc0, 0x40, 0x18, 0x28, 0xc0, 0xd0, 0x02, 
+-      0x1c, 0x28, 0xb0, 0x0b, 0xe6, 0xfe, 0x2e, 0x00, 
+-      0xd1, 0x02, 0x1c, 0x28, 0xb0, 0x0b, 0xe6, 0xf9, 
+-      0x78, 0xf8, 0x28, 0x04, 0xd0, 0x02, 0x1c, 0x28, 
+-      0xb0, 0x0b, 0xe6, 0xf3, 0x79, 0x38, 0x90, 0x08, 
+-      0x23, 0x0b, 0x40, 0x18, 0x28, 0x09, 0xda, 0x02, 
+-      0x1c, 0x28, 0xb0, 0x0b, 0xe6, 0xea, 0x20, 0x00, 
+-      0x21, 0x00, 0x79, 0x7a, 0x92, 0x07, 0x9a, 0x07, 
+-      0x40, 0xca, 0x08, 0x52, 0xd3, 0x05, 0x30, 0x01, 
+-      0x18, 0x3a, 0x79, 0x52, 0x0a, 0x12, 0xd3, 0x00, 
+-      0x30, 0x01, 0x31, 0x01, 0x29, 0x08, 0xdb, 0xf2, 
+-      0x1c, 0x41, 0x98, 0x08, 0x08, 0xc0, 0xd3, 0x22, 
+-      0x20, 0x00, 0x18, 0x7a, 0x79, 0x52, 0x92, 0x06, 
+-      0x07, 0x92, 0xd0, 0x0a, 0x19, 0xca, 0x79, 0x92, 
+-      0x0a, 0x12, 0xd3, 0x05, 0x30, 0x01, 0x18, 0x0a, 
+-      0x19, 0xd2, 0x79, 0x92, 0x0a, 0x12, 0xd2, 0xf9, 
+-      0x30, 0x01, 0x9a, 0x06, 0x08, 0x92, 0x07, 0x52, 
+-      0xd0, 0x0b, 0x18, 0x0a, 0x19, 0xd2, 0x79, 0x92, 
+-      0x0a, 0x12, 0xd3, 0x05, 0x30, 0x01, 0x18, 0x0a, 
+-      0x19, 0xd2, 0x79, 0x92, 0x0a, 0x12, 0xd2, 0xf9, 
+-      0x30, 0x01, 0x18, 0x08, 0x1c, 0x41, 0x18, 0x78, 
+-      0x79, 0x40, 0x28, 0x22, 0xd0, 0x03, 0x1c, 0x28, 
+-      0xb0, 0x0b, 0xe6, 0xab, 0xe1, 0x49, 0x1c, 0x48, 
+-      0x99, 0x08, 0x09, 0x49, 0xd3, 0x05, 0x18, 0x39, 
+-      0x79, 0x49, 0x09, 0x49, 0xd3, 0x00, 0x30, 0x02, 
+-      0x30, 0x01, 0x99, 0x08, 0x09, 0x49, 0x07, 0x49, 
+-      0xd0, 0x1b, 0x22, 0x00, 0x92, 0x01, 0x92, 0x00, 
+-      0x18, 0x39, 0x79, 0x49, 0x91, 0x05, 0x08, 0xc9, 
+-      0x07, 0x89, 0x0f, 0x89, 0xd0, 0x03, 0x22, 0x01, 
+-      0x39, 0x01, 0x40, 0x8a, 0x92, 0x01, 0x99, 0x05, 
+-      0x09, 0x49, 0x07, 0x89, 0x0f, 0x89, 0xd0, 0x03, 
+-      0x22, 0x01, 0x39, 0x01, 0x40, 0x8a, 0x92, 0x00, 
+-      0x99, 0x00, 0x9a, 0x01, 0x18, 0x51, 0x18, 0x08, 
+-      0x30, 0x01, 0x1d, 0x41, 0x91, 0x03, 0x22, 0x1b, 
+-      0xb4, 0x04, 0x99, 0x04, 0x9a, 0x0e, 0x1a, 0x52, 
+-      0x18, 0x79, 0x20, 0xc0, 0x1c, 0x23, 0xf7, 0xff, 
+-      0xfe, 0x6b, 0xb0, 0x01, 0x28, 0x00, 0xda, 0x02, 
+-      0x42, 0x68, 0xb0, 0x0b, 0xe6, 0x6e, 0x99, 0x03, 
+-      0x18, 0x08, 0x22, 0x1b, 0xb4, 0x04, 0x9a, 0x0e, 
+-      0x1a, 0x12, 0x18, 0x39, 0x20, 0xc1, 0x1c, 0x23, 
+-      0xf7, 0xff, 0xfe, 0x5a, 0xb0, 0x01, 0x28, 0x00, 
+-      0xda, 0x02, 0x42, 0x68, 0xb0, 0x0b, 0xe6, 0x5d, 
+-      0x9a, 0x09, 0x74, 0x96, 0x9a, 0x09, 0x7c, 0x91, 
+-      0xa0, 0x5d, 0xf0, 0x0f, 0xfe, 0xa5, 0xe0, 0xf4, 
+-      0x98, 0x14, 0x28, 0x1a, 0xd1, 0x2f, 0x98, 0x04, 
+-      0x28, 0x0e, 0xd0, 0x02, 0x42, 0x68, 0xb0, 0x0b, 
+-      0xe6, 0x4c, 0x78, 0xb8, 0x28, 0x41, 0xd1, 0x02, 
+-      0x78, 0xf8, 0x28, 0x02, 0xd0, 0x02, 0x42, 0x68, 
+-      0xb0, 0x0b, 0xe6, 0x43, 0xa0, 0x5a, 0xf0, 0x0f, 
+-      0xfe, 0x05, 0x99, 0x0a, 0x1c, 0x02, 0xa0, 0x58, 
+-      0xf0, 0x0f, 0xfe, 0xba, 0x28, 0x00, 0xd0, 0x02, 
+-      0x42, 0x68, 0xb0, 0x0b, 0xe6, 0x36, 0xa0, 0x54, 
+-      0xf0, 0x0f, 0xfd, 0xf8, 0x19, 0xc0, 0x1d, 0x01, 
+-      0x1d, 0xe0, 0x30, 0x66, 0x22, 0x04, 0x1c, 0x07, 
+-      0xf0, 0x0f, 0xfe, 0x2c, 0x20, 0x00, 0x9a, 0x09, 
+-      0x74, 0x50, 0x1c, 0x3a, 0xa1, 0x4c, 0xa0, 0x4f, 
+-      0xf0, 0x0f, 0xfe, 0x72, 0xe0, 0xc1, 0x98, 0x14, 
+-      0x28, 0x1b, 0xd1, 0x11, 0xa0, 0x4f, 0xf0, 0x0f, 
+-      0xfd, 0xe1, 0x1c, 0x31, 0x1c, 0x02, 0xa0, 0x4d, 
+-      0xf0, 0x0f, 0xfe, 0x96, 0x28, 0x00, 0xd0, 0x02, 
+-      0x42, 0x68, 0xb0, 0x0b, 0xe6, 0x12, 0xa1, 0x49, 
+-      0xa0, 0x4b, 0xf0, 0x0f, 0xfe, 0x5d, 0xe0, 0xac, 
+-      0x42, 0x68, 0xb0, 0x0b, 0xe6, 0x0a, 0xa0, 0x4c, 
+-      0xf0, 0x0f, 0xfd, 0xcc, 0x1c, 0x31, 0x1c, 0x02, 
+-      0xa0, 0x49, 0xf0, 0x0f, 0xfe, 0x81, 0x28, 0x00, 
+-      0xe0, 0x96, 0x00, 0x00, 0x74, 0x75, 0x70, 0x6c, 
+-      0x65, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 
+-      0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, 0x74, 
+-      0x75, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x30, 
+-      0x78, 0x25, 0x30, 0x32, 0x78, 0x20, 0x6e, 0x6f, 
+-      0x74, 0x20, 0x30, 0x78, 0x25, 0x30, 0x32, 0x78, 
+-      0x0a, 0x00, 0x00, 0x00, 0x76, 0x65, 0x72, 0x73, 
+-      0x5f, 0x31, 0x3a, 0x20, 0x25, 0x64, 0x2e, 0x25, 
+-      0x64, 0x2c, 0x20, 0x25, 0x73, 0x00, 0x00, 0x00, 
+-      0x2c, 0x20, 0x25, 0x73, 0x00, 0x00, 0x00, 0x00, 
+-      0x6d, 0x61, 0x6e, 0x66, 0x69, 0x64, 0x3a, 0x20, 
+-      0x30, 0x78, 0x25, 0x30, 0x34, 0x78, 0x20, 0x20, 
+-      0x30, 0x78, 0x25, 0x30, 0x34, 0x78, 0x0a, 0x00, 
+-      0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x20, 0x62, 
+-      0x61, 0x73, 0x65, 0x3a, 0x20, 0x30, 0x78, 0x25, 
+-      0x30, 0x34, 0x78, 0x20, 0x00, 0x00, 0x00, 0x00, 
+-      0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x30, 0x78, 
+-      0x00, 0x00, 0x00, 0x00, 0x25, 0x30, 0x32, 0x78, 
+-      0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 
+-      0x6c, 0x61, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x64, 
+-      0x65, 0x78, 0x3a, 0x20, 0x30, 0x78, 0x25, 0x30, 
+-      0x32, 0x78, 0x0a, 0x00, 0x63, 0x6f, 0x6e, 0x66, 
+-      0x69, 0x67, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 
+-      0x20, 0x6e, 0x62, 0x3a, 0x20, 0x30, 0x78, 0x25, 
+-      0x30, 0x32, 0x78, 0x0a, 0x00, 0x00, 0x00, 0x00, 
+-      0x63, 0x66, 0x67, 0x20, 0x74, 0x61, 0x62, 0x6c, 
+-      0x65, 0x20, 0x63, 0x6f, 0x72, 0x20, 0x76, 0x61, 
+-      0x6c, 0x75, 0x65, 0x3a, 0x20, 0x30, 0x78, 0x25, 
+-      0x30, 0x32, 0x78, 0x20, 0x0a, 0x00, 0x00, 0x00, 
+-      0x44, 0x56, 0x42, 0x5f, 0x43, 0x49, 0x5f, 0x56, 
+-      0x00, 0x00, 0x00, 0x00, 0x76, 0x65, 0x72, 0x73, 
+-      0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x25, 0x73, 0x25, 
+-      0x73, 0x0a, 0x00, 0x00, 0x44, 0x56, 0x42, 0x5f, 
+-      0x48, 0x4f, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 
+-      0x73, 0x74, 0x63, 0x65, 0x5f, 0x65, 0x76, 0x3a, 
+-      0x20, 0x25, 0x73, 0x0a, 0x00, 0x00, 0x00, 0x00, 
+-      0x44, 0x56, 0x42, 0x5f, 0x43, 0x49, 0x5f, 0x4d, 
+-      0x4f, 0x44, 0x55, 0x4c, 0x45, 0x00, 0x00, 0x00, 
+-      0xd0, 0x02, 0x42, 0x68, 0xb0, 0x0b, 0xe5, 0x65, 
+-      0x46, 0x79, 0x39, 0x1c, 0xa0, 0x04, 0xf0, 0x0f, 
+-      0xfd, 0xaf, 0x1c, 0x28, 0xb0, 0x0b, 0xe5, 0x5d, 
+-      0x1c, 0x28, 0xb0, 0x0b, 0xe5, 0x5a, 0x00, 0x00, 
+-      0x73, 0x74, 0x63, 0x65, 0x5f, 0x70, 0x64, 0x3a, 
+-      0x20, 0x25, 0x73, 0x0a, 0x00, 0x00, 0x00, 0x00, 
+-      0xb5, 0xf0, 0x26, 0x00, 0x1c, 0x04, 0x20, 0x00, 
+-      0x67, 0x60, 0x1c, 0x0d, 0x1c, 0x17, 0xe0, 0x00, 
+-      0x36, 0x01, 0x42, 0xbe, 0xda, 0x02, 0x5d, 0xa8, 
+-      0x28, 0x1d, 0xd1, 0xf9, 0x22, 0x00, 0xb4, 0x04, 
+-      0x1b, 0xba, 0x19, 0xa9, 0x20, 0x1d, 0x1c, 0x23, 
+-      0xf7, 0xff, 0xfd, 0x32, 0xb0, 0x01, 0x28, 0x00, 
+-      0xda, 0x04, 0x20, 0x00, 0x43, 0xc0, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x18, 0x36, 0x22, 0x00, 
+-      0xb4, 0x04, 0x1b, 0xba, 0x19, 0xa9, 0x20, 0x1c, 
+-      0x1c, 0x23, 0xf7, 0xff, 0xfd, 0x21, 0xb0, 0x01, 
+-      0x28, 0x00, 0xda, 0x04, 0x20, 0x00, 0x43, 0xc0, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x18, 0x36, 
+-      0x22, 0x00, 0xb4, 0x04, 0x1b, 0xba, 0x19, 0xa9, 
+-      0x20, 0x15, 0x1c, 0x23, 0xf7, 0xff, 0xfd, 0x10, 
+-      0xb0, 0x01, 0x28, 0x00, 0xda, 0x04, 0x20, 0x00, 
+-      0x43, 0xc0, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x18, 0x36, 0x22, 0x00, 0xb4, 0x04, 0x1b, 0xba, 
+-      0x19, 0xa9, 0x20, 0x20, 0x1c, 0x23, 0xf7, 0xff, 
+-      0xfc, 0xff, 0xb0, 0x01, 0x28, 0x00, 0xda, 0x04, 
+-      0x20, 0x00, 0x43, 0xc0, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x18, 0x36, 0x22, 0x00, 0xb4, 0x04, 
+-      0x1b, 0xba, 0x19, 0xa9, 0x20, 0x1a, 0x1c, 0x23, 
+-      0xf7, 0xff, 0xfc, 0xee, 0xb0, 0x01, 0x28, 0x00, 
+-      0xda, 0x04, 0x20, 0x00, 0x43, 0xc0, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x18, 0x36, 0xe0, 0x10, 
+-      0x22, 0x00, 0xb4, 0x04, 0x1b, 0xba, 0x19, 0xa9, 
+-      0x20, 0x1b, 0x1c, 0x23, 0xf7, 0xff, 0xfc, 0xdc, 
+-      0xb0, 0x01, 0x28, 0x00, 0xda, 0x04, 0x20, 0x00, 
+-      0x43, 0xc0, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x18, 0x36, 0x42, 0xbe, 0xda, 0x02, 0x6f, 0x60, 
+-      0x28, 0x00, 0xd0, 0xe9, 0x22, 0x00, 0xb4, 0x04, 
+-      0x1b, 0xba, 0x19, 0xa9, 0x20, 0x14, 0x1c, 0x23, 
+-      0xf7, 0xff, 0xfc, 0xc6, 0xb0, 0x01, 0x28, 0x00, 
+-      0xda, 0x04, 0x20, 0x00, 0x43, 0xc0, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x20, 0x00, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xf7, 0x06, 0x0e, 
+-      0x0e, 0x36, 0xb0, 0x83, 0xf0, 0x0c, 0xfc, 0x40, 
+-      0x1c, 0x05, 0xd0, 0x05, 0x00, 0xa8, 0x30, 0x0c, 
+-      0xf7, 0xfc, 0xfc, 0x2c, 0x1c, 0x04, 0xd1, 0x01, 
+-      0x20, 0x00, 0xe0, 0x22, 0x95, 0x01, 0x1d, 0xe0, 
+-      0x30, 0x05, 0x90, 0x02, 0x46, 0x6a, 0xb4, 0x04, 
+-      0x25, 0x00, 0x98, 0x04, 0x1c, 0x31, 0xaa, 0x02, 
+-      0x1c, 0x2b, 0x1c, 0x27, 0xf0, 0x0c, 0xf9, 0xe6, 
+-      0xb0, 0x01, 0x98, 0x00, 0x60, 0x38, 0x28, 0x00, 
+-      0xd0, 0x0b, 0x99, 0x05, 0xf0, 0x0c, 0xfb, 0xbc, 
+-      0x28, 0x00, 0xd1, 0x02, 0x60, 0x7d, 0x1c, 0x38, 
+-      0xe0, 0x07, 0x68, 0x38, 0xa9, 0x01, 0xf0, 0x0c, 
+-      0xfa, 0x05, 0x1c, 0x20, 0xf7, 0xfc, 0xfc, 0x28, 
+-      0x1c, 0x28, 0xb0, 0x03, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xff, 0x9c, 0x0b, 
+-      0x9e, 0x09, 0xb0, 0x8b, 0x4a, 0x7c, 0x92, 0x0a, 
+-      0x4d, 0x7c, 0x2c, 0x00, 0xd1, 0x0b, 0x20, 0x00, 
+-      0x00, 0x81, 0x9a, 0x0a, 0x58, 0x51, 0x29, 0x00, 
+-      0xd1, 0x01, 0x1c, 0x04, 0xe0, 0x16, 0x30, 0x01, 
+-      0x28, 0x08, 0xdb, 0xf5, 0xe0, 0x12, 0x2c, 0x08, 
+-      0xd8, 0x07, 0x3c, 0x01, 0x00, 0xa0, 0x9a, 0x0a, 
+-      0x58, 0x10, 0x28, 0x00, 0xd0, 0x0a, 0x20, 0x00, 
+-      0xe0, 0xd8, 0x23, 0x20, 0x5e, 0xec, 0x1c, 0x60, 
+-      0x84, 0x28, 0x5e, 0xe8, 0x28, 0x00, 0xd1, 0x01, 
+-      0x20, 0x64, 0x84, 0x28, 0x98, 0x15, 0x28, 0x00, 
+-      0xd0, 0x03, 0x28, 0x01, 0xd1, 0x03, 0x22, 0x01, 
+-      0xe0, 0x02, 0x22, 0x00, 0xe0, 0x00, 0x22, 0x03, 
+-      0x92, 0x01, 0x1c, 0x30, 0xf0, 0x08, 0xfd, 0xf5, 
+-      0x90, 0x00, 0x00, 0x80, 0x30, 0x80, 0xf7, 0xfc, 
+-      0xfb, 0xc5, 0x1c, 0x07, 0xd0, 0xdf, 0x98, 0x00, 
+-      0x1d, 0xc2, 0x32, 0x79, 0x21, 0x00, 0x1c, 0x38, 
+-      0xf0, 0x0f, 0xfc, 0x2e, 0x98, 0x00, 0x60, 0xf8, 
+-      0x1d, 0xf8, 0x30, 0x79, 0x61, 0x38, 0x98, 0x0d, 
+-      0x86, 0x78, 0x98, 0x0e, 0x86, 0xb8, 0x98, 0x0b, 
+-      0x90, 0x02, 0x99, 0x0c, 0x91, 0x03, 0x9a, 0x0d, 
+-      0x18, 0x80, 0x38, 0x01, 0x90, 0x04, 0x98, 0x0e, 
+-      0x18, 0x08, 0x38, 0x01, 0x90, 0x05, 0xa8, 0x02, 
+-      0x1c, 0x31, 0xf0, 0x08, 0xfd, 0xd5, 0x61, 0x78, 
+-      0x9a, 0x01, 0x2a, 0x00, 0xd0, 0x0e, 0x2a, 0x01, 
+-      0xd1, 0x27, 0x00, 0x80, 0xf7, 0xfc, 0xfb, 0x9a, 
+-      0x61, 0xb8, 0x28, 0x00, 0xd0, 0x04, 0x69, 0x79, 
+-      0x00, 0x8a, 0x21, 0x00, 0xf0, 0x0f, 0xfc, 0x04, 
+-      0x20, 0x01, 0xe0, 0x14, 0x23, 0x28, 0x5e, 0xe8, 
+-      0x1c, 0x41, 0x85, 0x29, 0x28, 0x00, 0xd1, 0x01, 
+-      0xf7, 0xf7, 0xf8, 0x5e, 0x69, 0x78, 0x00, 0x80, 
+-      0xf7, 0xfc, 0xfb, 0xcc, 0x61, 0xb8, 0x28, 0x00, 
+-      0xd0, 0x04, 0x69, 0x79, 0x00, 0x8a, 0x21, 0x00, 
+-      0xf0, 0x0f, 0xfb, 0xee, 0x20, 0x00, 0x86, 0x38, 
+-      0x23, 0x01, 0x03, 0xdb, 0x69, 0xf8, 0x43, 0x18, 
+-      0xe0, 0x10, 0x98, 0x15, 0x61, 0xb8, 0x98, 0x15, 
+-      0x0e, 0x00, 0x06, 0x00, 0x90, 0x15, 0x23, 0x0d, 
+-      0x06, 0x9b, 0x42, 0xd8, 0xd1, 0x01, 0x20, 0x00, 
+-      0xe0, 0x00, 0x20, 0x01, 0x86, 0x38, 0x69, 0xf8, 
+-      0x4b, 0x33, 0x40, 0x18, 0x61, 0xf8, 0x69, 0xb8, 
+-      0x28, 0x00, 0xd1, 0x06, 0x69, 0x78, 0x28, 0x00, 
+-      0xd0, 0x03, 0x1c, 0x38, 0xf7, 0xfc, 0xfb, 0x7c, 
+-      0xe7, 0x75, 0x68, 0xf8, 0x90, 0x06, 0x69, 0x38, 
+-      0x90, 0x07, 0x69, 0x78, 0x90, 0x08, 0x69, 0xb8, 
+-      0x90, 0x09, 0xa8, 0x02, 0x1c, 0x21, 0x1d, 0xfa, 
+-      0x32, 0x01, 0xb4, 0x07, 0x1c, 0x32, 0xb4, 0x04, 
+-      0x20, 0x00, 0x9a, 0x05, 0xa9, 0x0a, 0xab, 0x0c, 
+-      0xf0, 0x03, 0xf8, 0xa0, 0xb0, 0x04, 0x28, 0x00, 
+-      0xd0, 0x03, 0x1c, 0x38, 0xf0, 0x00, 0xf8, 0x5f, 
+-      0xe7, 0x59, 0x2e, 0x00, 0xd0, 0x09, 0x2e, 0x01, 
+-      0xd0, 0x07, 0x2e, 0x02, 0xd0, 0x05, 0x2e, 0x03, 
+-      0xd0, 0x03, 0x23, 0x02, 0x69, 0xf8, 0x43, 0x18, 
+-      0x61, 0xf8, 0x85, 0xfc, 0x2c, 0x08, 0xd2, 0x02, 
+-      0x00, 0xa0, 0x9a, 0x0a, 0x50, 0x17, 0x20, 0x01, 
+-      0x24, 0x00, 0x63, 0xf8, 0x63, 0xbc, 0x85, 0xbe, 
+-      0x21, 0x01, 0x1c, 0x38, 0xf0, 0x00, 0xf9, 0x18, 
+-      0x8c, 0xa8, 0x06, 0x01, 0x0e, 0x09, 0x1c, 0x38, 
+-      0xf0, 0x00, 0xf8, 0xcb, 0x22, 0x00, 0x21, 0x00, 
+-      0x1c, 0x38, 0xf0, 0x00, 0xf8, 0xa0, 0x98, 0x17, 
+-      0x60, 0x38, 0x98, 0x17, 0x28, 0x00, 0xd0, 0x06, 
+-      0x22, 0x00, 0x21, 0x03, 0x1c, 0x23, 0x9c, 0x17, 
+-      0x1c, 0x38, 0xf0, 0x0f, 0xfa, 0xc1, 0x68, 0xb8, 
+-      0x60, 0x78, 0x1c, 0x38, 0xb0, 0x0b, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x1a, 0x4c, 0x2e, 0x08, 0x1a, 0x4c, 
+-      0xff, 0xff, 0x7f, 0xff, 0xb5, 0x80, 0x1c, 0x07, 
+-      0xb0, 0x82, 0x28, 0x00, 0xd0, 0x13, 0x68, 0x78, 
+-      0x28, 0x00, 0xd1, 0x10, 0x68, 0xb8, 0x90, 0x00, 
+-      0x1d, 0xf8, 0x30, 0x05, 0x90, 0x01, 0x46, 0x69, 
+-      0x68, 0x38, 0xf0, 0x0c, 0xf8, 0xe7, 0x22, 0x0c, 
+-      0x21, 0x00, 0x1c, 0x38, 0xf0, 0x0f, 0xfb, 0x58, 
+-      0x1c, 0x38, 0xf7, 0xfc, 0xfb, 0x05, 0xb0, 0x02, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0x90, 
+-      0x1c, 0x07, 0xb0, 0x84, 0x28, 0x00, 0xd1, 0x03, 
+-      0xb0, 0x04, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x20, 0x00, 0x23, 0x00, 0x49, 0x22, 0x00, 0x82, 
+-      0x58, 0x8c, 0x42, 0xbc, 0xd1, 0x00, 0x50, 0x8b, 
+-      0x30, 0x01, 0x28, 0x08, 0xdb, 0xf7, 0x21, 0x00, 
+-      0x1c, 0x38, 0xf0, 0x00, 0xf8, 0xc8, 0x68, 0xf8, 
+-      0x90, 0x00, 0x69, 0x38, 0x90, 0x01, 0x69, 0x78, 
+-      0x90, 0x02, 0x69, 0xb8, 0x90, 0x03, 0x46, 0x68, 
+-      0x1d, 0xc2, 0x32, 0x01, 0x46, 0x69, 0x68, 0xb8, 
+-      0xf0, 0x03, 0xfb, 0x24, 0x6a, 0x38, 0x28, 0x00, 
+-      0xd0, 0x03, 0x68, 0x41, 0x39, 0x01, 0x60, 0x41, 
+-      0x30, 0x04, 0x69, 0xf8, 0x0c, 0x00, 0xd3, 0x16, 
+-      0x23, 0x30, 0x5e, 0xf8, 0x28, 0x00, 0xd1, 0x0d, 
+-      0x69, 0xb8, 0xf7, 0xfc, 0xfa, 0xf9, 0x48, 0x0d, 
+-      0x8d, 0x01, 0x39, 0x01, 0x04, 0x09, 0x14, 0x09, 
+-      0x85, 0x01, 0xd1, 0x08, 0x20, 0xff, 0xf7, 0xf6, 
+-      0xff, 0x73, 0xe0, 0x04, 0x28, 0x01, 0xd1, 0x02, 
+-      0x69, 0xb8, 0xf7, 0xfc, 0xfa, 0xb9, 0x22, 0x80, 
+-      0x21, 0x00, 0x1c, 0x38, 0xf0, 0x0f, 0xfb, 0x04, 
+-      0x1c, 0x38, 0xf7, 0xfc, 0xfa, 0xb1, 0xe7, 0xb3, 
+-      0x2e, 0x08, 0x1a, 0x4c, 0x2e, 0x08, 0x1a, 0x4c, 
+-      0x28, 0x00, 0xd0, 0x08, 0x28, 0x01, 0xd0, 0x08, 
+-      0x28, 0x02, 0xd0, 0x08, 0x28, 0x03, 0xd1, 0x08, 
+-      0x20, 0xff, 0x30, 0x01, 0x47, 0x70, 0x20, 0x02, 
+-      0x47, 0x70, 0x20, 0x04, 0x47, 0x70, 0x20, 0x10, 
+-      0x47, 0x70, 0x20, 0x00, 0x47, 0x70, 0xb5, 0x90, 
+-      0x1c, 0x07, 0x06, 0x08, 0x0e, 0x00, 0x06, 0x14, 
+-      0x0e, 0x24, 0x28, 0x00, 0xd0, 0x0a, 0x21, 0x03, 
+-      0x68, 0xb8, 0xf0, 0x04, 0xfc, 0x1f, 0x68, 0xb8, 
+-      0x1c, 0x21, 0xf0, 0x04, 0xfc, 0xc7, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x21, 0x00, 0x68, 0xb8, 
+-      0xf0, 0x04, 0xfc, 0x14, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0x00, 0x06, 0x09, 0xd0, 0x02, 
+-      0x68, 0x80, 0x21, 0x02, 0xe0, 0x01, 0x68, 0x80, 
+-      0x21, 0x00, 0xf0, 0x04, 0xfc, 0x07, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0x00, 0x06, 0x09, 0x0e, 0x09, 
+-      0x28, 0x00, 0xd0, 0x02, 0x68, 0x80, 0xf0, 0x04, 
+-      0xfe, 0x0d, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0xb0, 
+-      0x23, 0x05, 0x43, 0x18, 0x4d, 0x08, 0x84, 0xa8, 
+-      0x27, 0x00, 0x4c, 0x08, 0x00, 0xb8, 0x58, 0x20, 
+-      0x8c, 0xa9, 0x06, 0x09, 0x0e, 0x09, 0xf7, 0xff, 
+-      0xff, 0xe8, 0x37, 0x01, 0x2f, 0x08, 0xdb, 0xf5, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x1a, 0x4c, 0x2e, 0x08, 0x1a, 0x4c, 
+-      0x48, 0x01, 0x23, 0x24, 0x5e, 0xc0, 0x47, 0x70, 
+-      0x2e, 0x08, 0x1a, 0x4c, 0xb5, 0x90, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0x28, 0x00, 0xd0, 0x15, 0x6a, 0x20, 
+-      0x28, 0x00, 0xd0, 0x06, 0x42, 0xb8, 0xd0, 0x10, 
+-      0x68, 0x41, 0x39, 0x01, 0x60, 0x41, 0x20, 0x00, 
+-      0x62, 0x20, 0x2f, 0x00, 0xd0, 0x09, 0x68, 0xa0, 
+-      0x68, 0x39, 0xf0, 0x0c, 0xf8, 0x19, 0x28, 0x00, 
+-      0xd1, 0x03, 0x62, 0x27, 0x68, 0x78, 0x30, 0x01, 
+-      0x60, 0x78, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0x00, 0x06, 0x09, 0xd0, 0x01, 0x21, 0x01, 
+-      0xe0, 0x00, 0x21, 0x00, 0x68, 0x80, 0xf0, 0x04, 
+-      0xfd, 0x0d, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0x90, 
+-      0x1c, 0x07, 0x1c, 0x0c, 0xd0, 0x01, 0x21, 0x01, 
+-      0xe0, 0x00, 0x21, 0x00, 0x68, 0xb8, 0xf0, 0x04, 
+-      0xf8, 0xa5, 0x2c, 0x00, 0xd0, 0x03, 0x23, 0x01, 
+-      0x69, 0xf8, 0x43, 0x18, 0xe0, 0x02, 0x69, 0xf8, 
+-      0x08, 0x40, 0x00, 0x40, 0x61, 0xf8, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x20, 0x01, 0x21, 0x07, 
+-      0x07, 0x09, 0x63, 0x88, 0x47, 0x70, 0x00, 0x00, 
+-      0xb5, 0x90, 0x9c, 0x03, 0x9f, 0x04, 0xb0, 0x85, 
+-      0x91, 0x00, 0x92, 0x01, 0x93, 0x02, 0x94, 0x03, 
+-      0x97, 0x04, 0x68, 0x80, 0x46, 0x69, 0xf0, 0x0a, 
+-      0xff, 0x69, 0xb0, 0x05, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0xff, 0xb0, 0x86, 0x98, 0x06, 
+-      0x6a, 0x40, 0x68, 0xc3, 0x93, 0x05, 0x98, 0x06, 
+-      0x6b, 0xc0, 0x01, 0x80, 0x06, 0x05, 0x0e, 0x2d, 
+-      0x95, 0x00, 0x68, 0x18, 0x01, 0x00, 0x30, 0x1f, 
+-      0x09, 0x40, 0x01, 0x40, 0x08, 0xc0, 0x90, 0x04, 
+-      0x99, 0x07, 0x68, 0x48, 0x99, 0x04, 0x43, 0x48, 
+-      0x99, 0x07, 0x68, 0x09, 0x08, 0xc9, 0x18, 0x0f, 
+-      0x97, 0x03, 0x21, 0x00, 0x91, 0x02, 0x9b, 0x05, 
+-      0x68, 0x58, 0x28, 0x00, 0xdd, 0x5e, 0x23, 0x32, 
+-      0x98, 0x06, 0x5e, 0xc0, 0x9b, 0x09, 0x43, 0x58, 
+-      0x9a, 0x08, 0x18, 0x81, 0x1c, 0x08, 0xd5, 0x00, 
+-      0x30, 0x03, 0x10, 0x80, 0x29, 0x00, 0xda, 0x04, 
+-      0x42, 0x49, 0x07, 0x89, 0x0f, 0x89, 0x42, 0x49, 
+-      0xe0, 0x01, 0x07, 0x89, 0x0f, 0x89, 0x00, 0x4a, 
+-      0x9d, 0x00, 0x41, 0x15, 0x1c, 0x2b, 0x06, 0x2d, 
+-      0x0e, 0x2d, 0x27, 0xc0, 0x40, 0xd7, 0x06, 0x3a, 
+-      0x0e, 0x12, 0x9b, 0x06, 0x69, 0x9b, 0x18, 0x18, 
+-      0x9b, 0x05, 0x9f, 0x03, 0x19, 0xdb, 0x33, 0x88, 
+-      0x78, 0x1f, 0x33, 0x01, 0x93, 0x01, 0x24, 0x00, 
+-      0x9b, 0x07, 0x68, 0x9b, 0x2b, 0x00, 0xd9, 0x23, 
+-      0x0a, 0x3b, 0xd3, 0x05, 0x78, 0x03, 0x43, 0x93, 
+-      0x70, 0x03, 0x78, 0x03, 0x43, 0x2b, 0x70, 0x03, 
+-      0x31, 0x01, 0x29, 0x03, 0xdd, 0x04, 0x22, 0xc0, 
+-      0x21, 0x00, 0x9d, 0x00, 0x30, 0x01, 0xe0, 0x05, 
+-      0x10, 0x92, 0x06, 0x12, 0x0e, 0x12, 0x10, 0xab, 
+-      0x06, 0x1d, 0x0e, 0x2d, 0x00, 0x7b, 0x06, 0x1f, 
+-      0x0e, 0x3f, 0x34, 0x01, 0x07, 0x63, 0xd1, 0x03, 
+-      0x9b, 0x01, 0x78, 0x1f, 0x33, 0x01, 0x93, 0x01, 
+-      0x9b, 0x07, 0x68, 0x9b, 0x42, 0xa3, 0xd8, 0xdb, 
+-      0x98, 0x04, 0x9f, 0x03, 0x18, 0x3f, 0x97, 0x03, 
+-      0x9b, 0x09, 0x33, 0x01, 0x93, 0x09, 0x99, 0x02, 
+-      0x31, 0x01, 0x91, 0x02, 0x9b, 0x05, 0x68, 0x58, 
+-      0x42, 0x88, 0xdc, 0xa0, 0xb0, 0x06, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0xff, 
+-      0xb0, 0x86, 0x98, 0x06, 0x6a, 0x40, 0x68, 0xc3, 
+-      0x93, 0x05, 0x98, 0x06, 0x6b, 0xc0, 0x07, 0x06, 
+-      0x0f, 0x36, 0x96, 0x00, 0x01, 0x30, 0x06, 0x06, 
+-      0x0e, 0x36, 0x96, 0x01, 0x68, 0x18, 0x01, 0x00, 
+-      0x30, 0x1f, 0x09, 0x40, 0x01, 0x40, 0x08, 0xc0, 
+-      0x90, 0x04, 0x68, 0x48, 0x9a, 0x04, 0x43, 0x50, 
+-      0x68, 0x0a, 0x08, 0xd2, 0x18, 0x17, 0x97, 0x03, 
+-      0x22, 0x00, 0x92, 0x02, 0x9b, 0x05, 0x68, 0x58, 
+-      0x28, 0x00, 0xdd, 0x48, 0x23, 0x32, 0x98, 0x06, 
+-      0x5e, 0xc0, 0x9b, 0x09, 0x43, 0x58, 0x9a, 0x08, 
+-      0x18, 0x82, 0x1c, 0x10, 0xd5, 0x00, 0x30, 0x01, 
+-      0x10, 0x40, 0x9b, 0x06, 0x69, 0x9b, 0x18, 0x18, 
+-      0x9b, 0x05, 0x9f, 0x03, 0x19, 0xdb, 0x1d, 0xdd, 
+-      0x35, 0x81, 0x78, 0x2f, 0x24, 0x00, 0x68, 0x8b, 
+-      0x35, 0x01, 0x2b, 0x00, 0xd9, 0x21, 0x0a, 0x3b, 
+-      0xd3, 0x10, 0x08, 0x53, 0xd3, 0x06, 0x78, 0x06, 
+-      0x23, 0xf0, 0x40, 0x33, 0x70, 0x03, 0x78, 0x03, 
+-      0x9e, 0x00, 0xe0, 0x05, 0x78, 0x03, 0x07, 0x1b, 
+-      0x0f, 0x1b, 0x70, 0x03, 0x78, 0x03, 0x9e, 0x01, 
+-      0x43, 0x33, 0x70, 0x03, 0x32, 0x01, 0x08, 0x53, 
+-      0xd2, 0x00, 0x30, 0x01, 0x00, 0x7b, 0x06, 0x1f, 
+-      0x0e, 0x3f, 0x34, 0x01, 0x07, 0x63, 0xd1, 0x01, 
+-      0x78, 0x2f, 0x35, 0x01, 0x68, 0x8b, 0x42, 0xa3, 
+-      0xd8, 0xdd, 0x98, 0x04, 0x9f, 0x03, 0x18, 0x3f, 
+-      0x97, 0x03, 0x9b, 0x09, 0x33, 0x01, 0x93, 0x09, 
+-      0x9a, 0x02, 0x32, 0x01, 0x92, 0x02, 0x9b, 0x05, 
+-      0x68, 0x58, 0x42, 0x90, 0xdc, 0xb6, 0xb0, 0x06, 
+-      0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0xff, 0xb0, 0x83, 0x98, 0x03, 0x6a, 0x40, 
+-      0x68, 0xc4, 0x98, 0x03, 0x6b, 0xc0, 0x06, 0x03, 
+-      0x0e, 0x1b, 0x93, 0x00, 0x68, 0x20, 0x01, 0x00, 
+-      0x30, 0x1f, 0x09, 0x40, 0x01, 0x40, 0x08, 0xc2, 
+-      0x92, 0x02, 0x68, 0x48, 0x43, 0x50, 0x68, 0x0a, 
+-      0x08, 0xd2, 0x18, 0x10, 0x90, 0x01, 0x25, 0x00, 
+-      0x68, 0x60, 0x28, 0x00, 0xdd, 0x35, 0x23, 0x32, 
+-      0x98, 0x03, 0x5e, 0xc0, 0x9b, 0x06, 0x43, 0x58, 
+-      0x9a, 0x05, 0x18, 0x80, 0x9a, 0x03, 0x69, 0x92, 
+-      0x18, 0x17, 0x98, 0x01, 0x18, 0x20, 0x1d, 0xc6, 
+-      0x36, 0x81, 0x78, 0x32, 0x20, 0x00, 0x68, 0x8b, 
+-      0x36, 0x01, 0x2b, 0x00, 0xd9, 0x16, 0x0a, 0x13, 
+-      0xd3, 0x01, 0x9b, 0x00, 0x70, 0x3b, 0x00, 0x52, 
+-      0x06, 0x12, 0x0e, 0x12, 0xd1, 0x09, 0x1d, 0xc2, 
+-      0x32, 0x01, 0x08, 0xd2, 0x00, 0xd2, 0x1a, 0x10, 
+-      0x19, 0xc7, 0x1c, 0x10, 0x78, 0x32, 0x36, 0x01, 
+-      0xe0, 0x01, 0x30, 0x01, 0x37, 0x01, 0x68, 0x8b, 
+-      0x42, 0x83, 0xd8, 0xe8, 0x98, 0x01, 0x9a, 0x02, 
+-      0x18, 0x80, 0x90, 0x01, 0x9b, 0x06, 0x33, 0x01, 
+-      0x93, 0x06, 0x68, 0x60, 0x35, 0x01, 0x42, 0xa8, 
+-      0xdc, 0xc9, 0xb0, 0x03, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xff, 0x23, 0x2c, 
+-      0x1c, 0x07, 0x5e, 0xc0, 0xb0, 0x85, 0x28, 0x01, 
+-      0xd0, 0x0f, 0x28, 0x02, 0xd0, 0x07, 0x28, 0x03, 
+-      0xd1, 0x11, 0xab, 0x06, 0xcb, 0x0e, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xff, 0x9a, 0xe0, 0x5d, 0xab, 0x06, 
+-      0xcb, 0x0e, 0x1c, 0x38, 0xf7, 0xff, 0xff, 0x23, 
+-      0xe0, 0x57, 0xab, 0x06, 0xcb, 0x0e, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfe, 0x97, 0xe0, 0x51, 0x6a, 0x78, 
+-      0x68, 0xc0, 0x90, 0x04, 0x68, 0x00, 0x01, 0x00, 
+-      0x30, 0x1f, 0x09, 0x40, 0x01, 0x40, 0x08, 0xc0, 
+-      0x90, 0x03, 0x99, 0x06, 0x68, 0x48, 0x99, 0x03, 
+-      0x43, 0x48, 0x99, 0x06, 0x68, 0x09, 0x08, 0xc9, 
+-      0x18, 0x09, 0x91, 0x02, 0x21, 0x00, 0x91, 0x01, 
+-      0x98, 0x04, 0x68, 0x40, 0x28, 0x00, 0xdd, 0x38, 
+-      0x98, 0x04, 0x99, 0x02, 0x9e, 0x07, 0x18, 0x40, 
+-      0x30, 0x88, 0x78, 0x05, 0x30, 0x01, 0x90, 0x00, 
+-      0x24, 0x00, 0x99, 0x06, 0x68, 0x88, 0x28, 0x00, 
+-      0xd9, 0x1d, 0x0a, 0x28, 0xd3, 0x05, 0x68, 0xb8, 
+-      0x6b, 0xfb, 0x9a, 0x08, 0x1c, 0x31, 0xf0, 0x0a, 
+-      0xfb, 0x87, 0x00, 0x68, 0x06, 0x05, 0x0e, 0x2d, 
+-      0xd1, 0x0b, 0x1d, 0xe0, 0x30, 0x01, 0x08, 0xc0, 
+-      0x00, 0xc0, 0x1b, 0x01, 0x19, 0x8e, 0x1c, 0x04, 
+-      0x98, 0x00, 0x78, 0x05, 0x30, 0x01, 0x90, 0x00, 
+-      0xe0, 0x01, 0x34, 0x01, 0x36, 0x01, 0x99, 0x06, 
+-      0x68, 0x88, 0x42, 0xa0, 0xd8, 0xe1, 0x98, 0x03, 
+-      0x99, 0x02, 0x18, 0x09, 0x91, 0x02, 0x9a, 0x08, 
+-      0x32, 0x01, 0x92, 0x08, 0x99, 0x01, 0x31, 0x01, 
+-      0x91, 0x01, 0x98, 0x04, 0x68, 0x40, 0x42, 0x88, 
+-      0xdc, 0xc6, 0xb0, 0x05, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0x90, 0x1c, 0x07, 
+-      0x20, 0x00, 0xb0, 0x88, 0xf0, 0x08, 0xfa, 0x35, 
+-      0x90, 0x06, 0x00, 0x80, 0x30, 0x10, 0x00, 0x80, 
+-      0xf7, 0xfc, 0xf8, 0x04, 0x1c, 0x04, 0x20, 0x00, 
+-      0x2c, 0x00, 0xd1, 0x03, 0xb0, 0x08, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x1d, 0xe1, 0x31, 0x09, 
+-      0x91, 0x07, 0x49, 0x19, 0x68, 0x4b, 0x1c, 0x5a, 
+-      0x60, 0x4a, 0x60, 0x63, 0x60, 0xe7, 0x68, 0x39, 
+-      0x01, 0x09, 0x31, 0x1f, 0x09, 0x49, 0x01, 0x49, 
+-      0x90, 0x00, 0x90, 0x01, 0x1e, 0x48, 0x90, 0x02, 
+-      0x68, 0xe0, 0x68, 0x40, 0x00, 0xc0, 0x38, 0x01, 
+-      0x90, 0x03, 0x46, 0x68, 0x21, 0x00, 0xf0, 0x08, 
+-      0xfa, 0x13, 0x60, 0xa0, 0x68, 0xe0, 0x30, 0x88, 
+-      0x90, 0x05, 0x68, 0xa0, 0x90, 0x04, 0x46, 0x68, 
+-      0x1c, 0x22, 0x68, 0x61, 0xb4, 0x07, 0x22, 0x00, 
+-      0xb4, 0x04, 0x22, 0x01, 0x20, 0x00, 0xa9, 0x0a, 
+-      0xab, 0x08, 0xf0, 0x02, 0xfd, 0x2b, 0xb0, 0x04, 
+-      0x28, 0x00, 0xd0, 0x03, 0x1c, 0x20, 0xf7, 0xfb, 
+-      0xff, 0xeb, 0x24, 0x00, 0x1c, 0x20, 0xe7, 0xc5, 
+-      0x2e, 0x08, 0x1a, 0x78, 0xb5, 0x80, 0x1c, 0x07, 
+-      0xb0, 0x84, 0x28, 0x00, 0xd0, 0x1a, 0x20, 0x00, 
+-      0xf0, 0x08, 0xf9, 0xe7, 0x90, 0x00, 0x1d, 0xf8, 
+-      0x30, 0x09, 0x90, 0x01, 0x68, 0xb8, 0x90, 0x02, 
+-      0x68, 0xf8, 0x30, 0x88, 0x90, 0x03, 0x46, 0x68, 
+-      0x46, 0x69, 0x1d, 0xc2, 0x32, 0x01, 0x68, 0x38, 
+-      0xf0, 0x03, 0xf8, 0x18, 0x22, 0x10, 0x21, 0x00, 
+-      0x1c, 0x38, 0xf0, 0x0f, 0xf8, 0x19, 0x1c, 0x38, 
+-      0xf7, 0xfb, 0xff, 0xc6, 0xb0, 0x04, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xff, 0x23, 0x32, 
+-      0x1c, 0x07, 0x5e, 0xc0, 0x1c, 0x0c, 0x1c, 0x15, 
+-      0xb0, 0x8a, 0x42, 0x90, 0xdd, 0x63, 0x6a, 0x78, 
+-      0x28, 0x00, 0xd1, 0x0b, 0x4e, 0x38, 0x68, 0x30, 
+-      0x28, 0x00, 0xd1, 0x05, 0x48, 0x37, 0xf7, 0xff, 
+-      0xff, 0x7d, 0x60, 0x30, 0x28, 0x00, 0xd0, 0x61, 
+-      0x68, 0x30, 0x62, 0x78, 0x23, 0x01, 0x6b, 0xb8, 
+-      0x6a, 0x79, 0x42, 0xd8, 0xd1, 0x01, 0x22, 0x01, 
+-      0xe0, 0x00, 0x22, 0x00, 0x92, 0x01, 0x68, 0xc8, 
+-      0x90, 0x00, 0x68, 0x00, 0x90, 0x04, 0x98, 0x00, 
+-      0x68, 0x40, 0x90, 0x03, 0x6b, 0xf8, 0x28, 0x01, 
+-      0xd1, 0x01, 0x90, 0x02, 0xe0, 0x11, 0x20, 0x00, 
+-      0x90, 0x02, 0x9a, 0x01, 0x2a, 0x00, 0xd1, 0x0c, 
+-      0x1c, 0x20, 0xf0, 0x00, 0xf8, 0x57, 0x6b, 0xba, 
+-      0x99, 0x03, 0xb4, 0x06, 0x1c, 0x03, 0x9a, 0x0f, 
+-      0x1c, 0x38, 0x1c, 0x29, 0xf7, 0xff, 0xfd, 0x80, 
+-      0xb0, 0x02, 0x99, 0x03, 0x91, 0x08, 0x20, 0x01, 
+-      0x90, 0x09, 0x78, 0x20, 0x28, 0x00, 0xd0, 0x31, 
+-      0x23, 0x32, 0x5e, 0xf8, 0x42, 0xa8, 0xdd, 0x22, 
+-      0x78, 0x20, 0x99, 0x00, 0xf0, 0x00, 0xf8, 0x34, 
+-      0x90, 0x07, 0x1c, 0x06, 0x78, 0x20, 0x07, 0x00, 
+-      0x0f, 0x00, 0x99, 0x04, 0x43, 0x48, 0x90, 0x05, 
+-      0x78, 0x20, 0x09, 0x00, 0x07, 0x40, 0x0f, 0x40, 
+-      0x99, 0x03, 0x43, 0x48, 0x90, 0x06, 0x98, 0x02, 
+-      0x34, 0x01, 0x28, 0x00, 0xd0, 0x0c, 0x99, 0x0d, 
+-      0x9a, 0x01, 0xb4, 0x06, 0x6a, 0x78, 0x68, 0xb9, 
+-      0x68, 0x00, 0xaa, 0x07, 0x1c, 0x2b, 0xf0, 0x0a, 
+-      0xfd, 0x8b, 0xb0, 0x02, 0xe0, 0x06, 0xe0, 0x09, 
+-      0x9b, 0x0d, 0x1c, 0x38, 0xa9, 0x05, 0x1c, 0x2a, 
+-      0xf7, 0xff, 0xfe, 0xa8, 0x19, 0xad, 0x78, 0x20, 
+-      0x28, 0x00, 0xd1, 0xcd, 0xb0, 0x0a, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x1a, 0x78, 0x2e, 0x02, 0xd7, 0x44, 
+-      0x29, 0x00, 0xd1, 0x00, 0x49, 0x02, 0x06, 0x40, 
+-      0x0e, 0x40, 0x18, 0x40, 0x7a, 0x00, 0x47, 0x70, 
+-      0x2e, 0x02, 0xd7, 0x44, 0xb5, 0xb0, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0xd1, 0x08, 0x4f, 0x0c, 0x68, 0x38, 
+-      0x28, 0x00, 0xd1, 0x03, 0x48, 0x0b, 0xf7, 0xff, 
+-      0xfe, 0xf9, 0x60, 0x38, 0x68, 0x3f, 0x25, 0x00, 
+-      0x78, 0x20, 0x28, 0x00, 0xd0, 0x08, 0x78, 0x20, 
+-      0x68, 0xf9, 0x34, 0x01, 0xf7, 0xff, 0xff, 0xe0, 
+-      0x19, 0x45, 0x78, 0x20, 0x28, 0x00, 0xd1, 0xf6, 
+-      0x1c, 0x28, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x1a, 0x78, 0x2e, 0x02, 0xd7, 0x44, 
+-      0xb5, 0x80, 0x28, 0x00, 0xd1, 0x08, 0x4f, 0x09, 
+-      0x68, 0x38, 0x28, 0x00, 0xd1, 0x03, 0x48, 0x08, 
+-      0xf7, 0xff, 0xfe, 0xd8, 0x60, 0x38, 0x68, 0x38, 
+-      0x28, 0x00, 0xd1, 0x02, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x68, 0xc0, 0x68, 0x40, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x1a, 0x78, 
+-      0x2e, 0x02, 0xd7, 0x44, 0xb5, 0xf0, 0xb0, 0x83, 
+-      0x4a, 0x18, 0x21, 0x00, 0x20, 0xff, 0x30, 0x01, 
+-      0xf7, 0xff, 0xfa, 0x98, 0x49, 0x16, 0x27, 0x00, 
+-      0x64, 0x08, 0x49, 0x16, 0x91, 0x02, 0x49, 0x16, 
+-      0x91, 0x01, 0x49, 0x16, 0x91, 0x00, 0x4c, 0x16, 
+-      0x01, 0x38, 0x06, 0x01, 0x0e, 0x09, 0x20, 0x10, 
+-      0x1c, 0x22, 0x1c, 0x0d, 0xf7, 0xff, 0xfa, 0x86, 
+-      0x00, 0xbe, 0x99, 0x02, 0x51, 0x88, 0x20, 0x04, 
+-      0x1c, 0x29, 0x1c, 0x22, 0xf7, 0xff, 0xfa, 0x7e, 
+-      0x99, 0x01, 0x51, 0x88, 0x20, 0x02, 0x1c, 0x29, 
+-      0x1c, 0x22, 0xf7, 0xff, 0xfa, 0x77, 0x99, 0x00, 
+-      0x51, 0x88, 0x37, 0x01, 0x2f, 0x08, 0xdb, 0xe3, 
+-      0x20, 0x00, 0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x1a, 0xc0, 
+-      0x2e, 0x08, 0x1c, 0x80, 0x2e, 0x08, 0x55, 0x50, 
+-      0x2e, 0x08, 0x55, 0x70, 0x2e, 0x08, 0x55, 0x90, 
+-      0x2e, 0x08, 0x1a, 0x80, 0xb5, 0x80, 0x48, 0x0c, 
+-      0xf7, 0xff, 0xfe, 0x84, 0x4f, 0x0b, 0x64, 0x78, 
+-      0x48, 0x0b, 0xf7, 0xff, 0xfe, 0x7f, 0x64, 0xb8, 
+-      0x48, 0x0a, 0xf7, 0xff, 0xfe, 0x7b, 0x64, 0xf8, 
+-      0x20, 0x00, 0x22, 0x00, 0x49, 0x08, 0x00, 0x83, 
+-      0x50, 0xca, 0x30, 0x01, 0x28, 0x10, 0xdb, 0xfa, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x02, 0x5e, 0x2c, 0x2e, 0x08, 0x1c, 0x80, 
+-      0x2e, 0x02, 0x94, 0xb8, 0x2e, 0x02, 0xd7, 0x44, 
+-      0x2e, 0x08, 0x55, 0x10, 0xb5, 0x90, 0x04, 0x01, 
+-      0x0c, 0x09, 0x20, 0xff, 0x29, 0x00, 0xd0, 0x0b, 
+-      0x29, 0x0f, 0xdc, 0x09, 0x00, 0x8c, 0x4f, 0x06, 
+-      0x59, 0x39, 0x29, 0x00, 0xd0, 0x04, 0x1c, 0x08, 
+-      0xf7, 0xff, 0xfb, 0x85, 0x20, 0x00, 0x51, 0x38, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x55, 0x10, 0xb5, 0xff, 0x04, 0x05, 
+-      0x0c, 0x2d, 0x04, 0x10, 0x0c, 0x00, 0xb0, 0x82, 
+-      0x90, 0x00, 0x04, 0x18, 0x0c, 0x00, 0x90, 0x01, 
+-      0x2d, 0x00, 0xd0, 0x01, 0x2d, 0x0f, 0xdd, 0x01, 
+-      0x20, 0xff, 0xe0, 0x53, 0x00, 0xaf, 0x4c, 0x2c, 
+-      0x59, 0xe0, 0x28, 0x00, 0xd0, 0x02, 0x1c, 0x28, 
+-      0xf7, 0xff, 0xff, 0xd0, 0x98, 0x00, 0x4a, 0x29, 
+-      0x40, 0x02, 0x92, 0x00, 0x23, 0x2d, 0x01, 0x1b, 
+-      0x42, 0x9a, 0xdd, 0x01, 0x1c, 0x1a, 0x93, 0x00, 
+-      0x23, 0x09, 0x01, 0x9b, 0x98, 0x01, 0x42, 0x98, 
+-      0xdd, 0x01, 0x1c, 0x1a, 0x93, 0x00, 0x2d, 0x08, 
+-      0xda, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x01, 
+-      0x22, 0x00, 0x21, 0x00, 0xb4, 0x07, 0x9a, 0x06, 
+-      0xb4, 0x04, 0x20, 0x00, 0x9a, 0x04, 0x9b, 0x05, 
+-      0xf7, 0xff, 0xfa, 0x24, 0x51, 0xe0, 0xb0, 0x04, 
+-      0x1c, 0x01, 0xd0, 0xd1, 0x48, 0x18, 0x6c, 0x82, 
+-      0x62, 0x4a, 0x21, 0x01, 0x59, 0xe2, 0x63, 0xd1, 
+-      0x21, 0x00, 0x43, 0xc9, 0x59, 0xe2, 0x63, 0x91, 
+-      0x99, 0x03, 0x29, 0x08, 0xd2, 0x10, 0xa3, 0x02, 
+-      0x5c, 0x5b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x04, 0x06, 0x08, 0x0b, 0x04, 0x06, 0x08, 0x0b, 
+-      0x48, 0x0e, 0xe0, 0x02, 0x48, 0x0e, 0xe0, 0x00, 
+-      0x48, 0x0e, 0x59, 0xc6, 0xe0, 0x00, 0x6c, 0x06, 
+-      0x59, 0xe0, 0x1c, 0x31, 0xf7, 0xff, 0xfb, 0xd6, 
+-      0x59, 0xe0, 0x68, 0x80, 0x21, 0x07, 0xf0, 0x04, 
+-      0xf9, 0xbd, 0x20, 0x00, 0xb0, 0x02, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x55, 0x10, 0x00, 0x00, 0xff, 0xfe, 
+-      0x2e, 0x08, 0x1c, 0x80, 0x2e, 0x08, 0x55, 0x90, 
+-      0x2e, 0x08, 0x55, 0x70, 0x2e, 0x08, 0x55, 0x50, 
+-      0xb5, 0xf0, 0x04, 0x00, 0x0c, 0x00, 0x04, 0x09, 
+-      0x14, 0x09, 0x04, 0x16, 0x14, 0x36, 0xb0, 0x85, 
+-      0x28, 0x07, 0xdc, 0x29, 0x00, 0x84, 0x4f, 0x21, 
+-      0x59, 0x38, 0x28, 0x00, 0xd0, 0x24, 0x08, 0x49, 
+-      0x00, 0x49, 0x04, 0x0d, 0x14, 0x2d, 0x68, 0x80, 
+-      0xa9, 0x01, 0xf0, 0x04, 0xfa, 0x6b, 0x98, 0x01, 
+-      0x19, 0x40, 0x90, 0x01, 0x98, 0x03, 0x19, 0x40, 
+-      0x90, 0x03, 0x98, 0x02, 0x19, 0x80, 0x90, 0x02, 
+-      0x98, 0x04, 0x19, 0x80, 0x90, 0x04, 0x98, 0x01, 
+-      0x49, 0x15, 0x42, 0x88, 0xd8, 0x0c, 0x98, 0x02, 
+-      0x42, 0x88, 0xd8, 0x09, 0x23, 0x2d, 0x01, 0x1b, 
+-      0x98, 0x01, 0x42, 0x98, 0xda, 0x04, 0x23, 0x09, 
+-      0x01, 0x9b, 0x98, 0x02, 0x42, 0x98, 0xdb, 0x01, 
+-      0x20, 0xff, 0xe0, 0x12, 0x59, 0x38, 0x68, 0x80, 
+-      0xa9, 0x01, 0xf0, 0x02, 0xf8, 0x3b, 0x59, 0x38, 
+-      0x68, 0x80, 0x46, 0x69, 0xf0, 0x03, 0xff, 0x0a, 
+-      0x98, 0x00, 0x28, 0x00, 0xd1, 0x04, 0x59, 0x38, 
+-      0x68, 0x80, 0x21, 0x01, 0xf0, 0x03, 0xfc, 0x4e, 
+-      0x20, 0x00, 0xb0, 0x05, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x55, 0x10, 
+-      0x80, 0x00, 0x00, 0x00, 0xb5, 0xf0, 0x04, 0x07, 
+-      0x0c, 0x3f, 0x04, 0x0b, 0x0c, 0x1b, 0x04, 0x16, 
+-      0x0c, 0x36, 0x20, 0xff, 0xb0, 0x85, 0x2f, 0x07, 
+-      0xdc, 0x10, 0x00, 0xbc, 0x4f, 0x1c, 0x59, 0x39, 
+-      0x29, 0x00, 0xd0, 0x0b, 0x08, 0x5a, 0x00, 0x52, 
+-      0x04, 0x15, 0x0c, 0x2d, 0x23, 0x2d, 0x01, 0x1b, 
+-      0x42, 0x9d, 0xda, 0x03, 0x23, 0x09, 0x01, 0x9b, 
+-      0x42, 0x9e, 0xdb, 0x03, 0xb0, 0x05, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x68, 0x88, 0xa9, 0x01, 
+-      0xf0, 0x04, 0xfa, 0x0c, 0x98, 0x03, 0x99, 0x01, 
+-      0x1a, 0x40, 0x90, 0x03, 0x19, 0x40, 0x90, 0x03, 
+-      0x98, 0x04, 0x99, 0x02, 0x1a, 0x40, 0x90, 0x04, 
+-      0x19, 0x80, 0x90, 0x04, 0x95, 0x01, 0x96, 0x02, 
+-      0x59, 0x38, 0x68, 0x80, 0xa9, 0x01, 0xf0, 0x01, 
+-      0xff, 0xed, 0x59, 0x38, 0x68, 0x80, 0x46, 0x69, 
+-      0xf0, 0x03, 0xfe, 0xbc, 0x98, 0x00, 0x28, 0x00, 
+-      0xd1, 0x04, 0x59, 0x38, 0x68, 0x80, 0x21, 0x01, 
+-      0xf0, 0x03, 0xfc, 0x00, 0x20, 0x00, 0xe7, 0xd5, 
+-      0x2e, 0x08, 0x55, 0x10, 0xb5, 0x00, 0x04, 0x00, 
+-      0x0c, 0x00, 0x00, 0x80, 0x49, 0x04, 0x58, 0x08, 
+-      0x28, 0x00, 0xd0, 0x03, 0x68, 0x80, 0x21, 0x00, 
+-      0xf0, 0x03, 0xfb, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x55, 0x10, 0xb5, 0x80, 0x04, 0x01, 
+-      0x0c, 0x09, 0x20, 0xff, 0x29, 0x07, 0xdc, 0x0c, 
+-      0x29, 0x01, 0xdb, 0x0a, 0x00, 0x88, 0x49, 0x06, 
+-      0x58, 0x08, 0x27, 0x00, 0x28, 0x00, 0xd0, 0x03, 
+-      0x68, 0x80, 0x21, 0x01, 0xf0, 0x03, 0xfa, 0x36, 
+-      0x1c, 0x38, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x55, 0x10, 0x04, 0x01, 0x0c, 0x09, 
+-      0x20, 0x00, 0x29, 0x0f, 0xdc, 0x06, 0x00, 0x89, 
+-      0x4a, 0x03, 0x58, 0x51, 0x29, 0x00, 0xd0, 0x01, 
+-      0x23, 0x32, 0x5e, 0xc8, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x55, 0x10, 0x04, 0x01, 0x0c, 0x09, 
+-      0x20, 0x00, 0x29, 0x0f, 0xdc, 0x06, 0x00, 0x89, 
+-      0x4a, 0x03, 0x58, 0x51, 0x29, 0x00, 0xd0, 0x01, 
+-      0x23, 0x34, 0x5e, 0xc8, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x55, 0x10, 0xb5, 0xb0, 0x04, 0x03, 
+-      0x0c, 0x1b, 0x04, 0x0a, 0x0c, 0x12, 0x20, 0xff, 
+-      0x2b, 0x07, 0xdc, 0x10, 0x00, 0x9d, 0x4f, 0x09, 
+-      0x59, 0x79, 0x29, 0x00, 0xd0, 0x0b, 0x07, 0x14, 
+-      0x0f, 0x24, 0x68, 0x88, 0x21, 0x03, 0xf0, 0x03, 
+-      0xfe, 0xa5, 0x59, 0x78, 0x68, 0x80, 0x1c, 0x21, 
+-      0xf0, 0x03, 0xff, 0x4c, 0x20, 0x00, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x55, 0x10, 
+-      0xb5, 0x00, 0x04, 0x01, 0x0c, 0x09, 0x20, 0xff, 
+-      0x29, 0x07, 0xdc, 0x09, 0x00, 0x89, 0x4a, 0x05, 
+-      0x58, 0x51, 0x29, 0x00, 0xd0, 0x04, 0x68, 0x88, 
+-      0x21, 0x02, 0xf0, 0x03, 0xfe, 0x8b, 0x20, 0x00, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x55, 0x10, 
+-      0xb5, 0x00, 0x04, 0x01, 0x0c, 0x09, 0x20, 0xff, 
+-      0x29, 0x07, 0xdc, 0x09, 0x00, 0x89, 0x4a, 0x05, 
+-      0x58, 0x51, 0x29, 0x00, 0xd0, 0x04, 0x68, 0x88, 
+-      0x21, 0x00, 0xf0, 0x03, 0xfe, 0x77, 0x20, 0x00, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x55, 0x10, 
+-      0xb5, 0xf0, 0x04, 0x05, 0x0c, 0x2d, 0x04, 0x09, 
+-      0x0c, 0x09, 0x04, 0x12, 0x0c, 0x12, 0x04, 0x1e, 
+-      0x0c, 0x36, 0x9c, 0x05, 0x9f, 0x06, 0x04, 0x24, 
+-      0x0c, 0x24, 0x04, 0x3f, 0x0c, 0x3f, 0x20, 0xff, 
+-      0xb0, 0x85, 0x2d, 0x0f, 0xdc, 0x04, 0x00, 0xab, 
+-      0x4d, 0x10, 0x58, 0xed, 0x2d, 0x00, 0xd1, 0x03, 
+-      0xb0, 0x05, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x19, 0x88, 0x23, 0x32, 0x5e, 0xeb, 0x42, 0x98, 
+-      0xdd, 0x02, 0x1a, 0x58, 0x04, 0x06, 0x0c, 0x36, 
+-      0x19, 0x10, 0x23, 0x34, 0x5e, 0xeb, 0x42, 0x98, 
+-      0xdd, 0x02, 0x1a, 0x98, 0x04, 0x04, 0x0c, 0x24, 
+-      0x91, 0x00, 0x92, 0x01, 0x96, 0x02, 0x94, 0x03, 
+-      0x97, 0x04, 0x46, 0x69, 0x68, 0xa8, 0xf0, 0x0a, 
+-      0xfa, 0x1d, 0xe7, 0xe1, 0x2e, 0x08, 0x55, 0x10, 
+-      0xb4, 0x80, 0x04, 0x03, 0x0c, 0x1b, 0x20, 0x00, 
+-      0x29, 0x00, 0xdb, 0x0f, 0x2a, 0x00, 0xdb, 0x0d, 
+-      0x00, 0x9b, 0x4f, 0x07, 0x58, 0xff, 0x2f, 0x00, 
+-      0xd0, 0x08, 0x23, 0x32, 0x5e, 0xfb, 0x42, 0x8b, 
+-      0xdd, 0x04, 0x23, 0x34, 0x5e, 0xf9, 0x42, 0x91, 
+-      0xdd, 0x00, 0x20, 0x01, 0xbc, 0x80, 0x47, 0x70, 
+-      0x2e, 0x08, 0x55, 0x10, 0xb5, 0xf0, 0x9c, 0x06, 
+-      0x9e, 0x05, 0x04, 0x00, 0x0c, 0x00, 0xb0, 0x85, 
+-      0x90, 0x00, 0x04, 0x08, 0x14, 0x00, 0x04, 0x17, 
+-      0x14, 0x3f, 0x04, 0x1d, 0x14, 0x2d, 0x04, 0x31, 
+-      0x14, 0x09, 0x91, 0x01, 0x04, 0x23, 0x0c, 0x1b, 
+-      0x93, 0x02, 0xb0, 0x82, 0x99, 0x02, 0x00, 0x89, 
+-      0x91, 0x06, 0x4a, 0x71, 0x92, 0x05, 0x58, 0x51, 
+-      0x29, 0x00, 0xd1, 0x01, 0x20, 0xff, 0xe0, 0xd6, 
+-      0x2d, 0x00, 0xda, 0x0e, 0x19, 0x40, 0x04, 0x00, 
+-      0x14, 0x00, 0x42, 0x69, 0x04, 0x0d, 0x14, 0x2d, 
+-      0x99, 0x03, 0x18, 0x79, 0x04, 0x0f, 0x14, 0x3f, 
+-      0x99, 0x03, 0x42, 0x49, 0x04, 0x09, 0x14, 0x09, 
+-      0x91, 0x03, 0x1c, 0x01, 0x1c, 0x04, 0x98, 0x02, 
+-      0x1c, 0x3a, 0xf7, 0xff, 0xff, 0xb1, 0x28, 0x00, 
+-      0xd0, 0x08, 0x98, 0x06, 0x99, 0x05, 0x58, 0x08, 
+-      0x68, 0x80, 0x9b, 0x04, 0x1c, 0x21, 0x1c, 0x3a, 
+-      0xf0, 0x09, 0xff, 0x7a, 0x98, 0x03, 0x10, 0x40, 
+-      0x90, 0x00, 0x10, 0x6e, 0x1c, 0x28, 0xb0, 0x82, 
+-      0xf0, 0x0e, 0xfd, 0x58, 0xf0, 0x0e, 0xfd, 0x94, 
+-      0x90, 0x00, 0x91, 0x01, 0x98, 0x05, 0xf0, 0x0e, 
+-      0xfd, 0x51, 0xf0, 0x0e, 0xfd, 0x8d, 0x9a, 0x00, 
+-      0x9b, 0x01, 0xb0, 0x02, 0xf0, 0x0e, 0xfd, 0x8c, 
+-      0x28, 0x00, 0xd0, 0x4c, 0x98, 0x03, 0x28, 0x00, 
+-      0xdd, 0x21, 0x26, 0x00, 0x2d, 0x00, 0xdd, 0x6d, 
+-      0x98, 0x00, 0x99, 0x03, 0x18, 0x40, 0x90, 0x00, 
+-      0x34, 0x01, 0x42, 0xa8, 0xdb, 0x03, 0x98, 0x00, 
+-      0x1b, 0x40, 0x90, 0x00, 0x37, 0x01, 0x98, 0x02, 
+-      0x1c, 0x21, 0x1c, 0x3a, 0xf7, 0xff, 0xff, 0x78, 
+-      0x28, 0x00, 0xd0, 0x08, 0x98, 0x06, 0x99, 0x05, 
+-      0x58, 0x08, 0x68, 0x80, 0x9b, 0x04, 0x1c, 0x21, 
+-      0x1c, 0x3a, 0xf0, 0x09, 0xff, 0x41, 0x36, 0x01, 
+-      0x42, 0xae, 0xdb, 0xe1, 0xe0, 0x76, 0x98, 0x03, 
+-      0x42, 0x40, 0x04, 0x00, 0x14, 0x00, 0x90, 0x03, 
+-      0x98, 0x00, 0x42, 0x46, 0x20, 0x00, 0x90, 0x01, 
+-      0x2d, 0x00, 0xdd, 0x43, 0x98, 0x03, 0x18, 0x36, 
+-      0x34, 0x01, 0x42, 0xae, 0xdb, 0x01, 0x1b, 0x76, 
+-      0x3f, 0x01, 0x98, 0x02, 0x1c, 0x21, 0x1c, 0x3a, 
+-      0xf7, 0xff, 0xff, 0x52, 0x28, 0x00, 0xd0, 0x08, 
+-      0x98, 0x06, 0x99, 0x05, 0x58, 0x08, 0x68, 0x80, 
+-      0x9b, 0x04, 0x1c, 0x21, 0x1c, 0x3a, 0xf0, 0x09, 
+-      0xff, 0x1b, 0x98, 0x01, 0x30, 0x01, 0x90, 0x01, 
+-      0x42, 0xa8, 0xdb, 0xe3, 0xe0, 0x4e, 0x98, 0x03, 
+-      0x28, 0x00, 0xdd, 0x24, 0x20, 0x00, 0x90, 0x01, 
+-      0x98, 0x03, 0x28, 0x00, 0xdd, 0x1e, 0x19, 0x76, 
+-      0x99, 0x03, 0x37, 0x01, 0x42, 0x8e, 0xdb, 0x02, 
+-      0x98, 0x03, 0x1a, 0x36, 0x34, 0x01, 0x98, 0x02, 
+-      0x1c, 0x21, 0x1c, 0x3a, 0xf7, 0xff, 0xff, 0x2c, 
+-      0x28, 0x00, 0xd0, 0x08, 0x98, 0x06, 0x99, 0x05, 
+-      0x58, 0x08, 0x68, 0x80, 0x9b, 0x04, 0x1c, 0x21, 
+-      0x1c, 0x3a, 0xf0, 0x09, 0xfe, 0xf5, 0x98, 0x01, 
+-      0x30, 0x01, 0x90, 0x01, 0x99, 0x03, 0x42, 0x88, 
+-      0xdb, 0xe1, 0xe0, 0x27, 0xe0, 0x26, 0x98, 0x03, 
+-      0x42, 0x40, 0x04, 0x01, 0x14, 0x09, 0x91, 0x03, 
+-      0x20, 0x00, 0x90, 0x01, 0x29, 0x00, 0xdd, 0x1d, 
+-      0x19, 0x76, 0x99, 0x03, 0x3f, 0x01, 0x42, 0x8e, 
+-      0xdb, 0x02, 0x99, 0x03, 0x1a, 0x76, 0x34, 0x01, 
+-      0x98, 0x02, 0x1c, 0x21, 0x1c, 0x3a, 0xf7, 0xff, 
+-      0xff, 0x03, 0x28, 0x00, 0xd0, 0x08, 0x98, 0x06, 
+-      0x99, 0x05, 0x58, 0x08, 0x68, 0x80, 0x9b, 0x04, 
+-      0x1c, 0x21, 0x1c, 0x3a, 0xf0, 0x09, 0xfe, 0xcc, 
+-      0x98, 0x01, 0x30, 0x01, 0x90, 0x01, 0x99, 0x03, 
+-      0x42, 0x88, 0xdb, 0xe1, 0x20, 0x00, 0xb0, 0x07, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x55, 0x10, 0xb4, 0x80, 0x23, 0x00, 
+-      0x88, 0x01, 0x0a, 0x0a, 0x06, 0x12, 0x0e, 0x12, 
+-      0x06, 0x09, 0x0e, 0x09, 0x2a, 0xdf, 0xd0, 0x1a, 
+-      0xdc, 0x07, 0x2a, 0xc4, 0xd0, 0x19, 0x2a, 0xd6, 
+-      0xd0, 0x1b, 0x2a, 0xdc, 0xd1, 0x08, 0x22, 0x1e, 
+-      0xe0, 0x06, 0x2a, 0xe4, 0xd0, 0x13, 0x2a, 0xf6, 
+-      0xd0, 0x15, 0x2a, 0xfc, 0xd1, 0x00, 0x22, 0x1f, 
+-      0x29, 0xdf, 0xd0, 0x26, 0xdc, 0x11, 0x29, 0xc4, 
+-      0xd0, 0x25, 0x29, 0xd6, 0xd0, 0x27, 0x29, 0xdc, 
+-      0xd1, 0x12, 0x21, 0x1e, 0xe0, 0x10, 0x22, 0x19, 
+-      0xe7, 0xf2, 0x22, 0x1a, 0xe7, 0xf0, 0x22, 0x1b, 
+-      0xe7, 0xee, 0x22, 0x1c, 0xe7, 0xec, 0x22, 0x1d, 
+-      0xe7, 0xea, 0x29, 0xe4, 0xd0, 0x15, 0x29, 0xf6, 
+-      0xd0, 0x17, 0x29, 0xfc, 0xd1, 0x00, 0x21, 0x1f, 
+-      0x02, 0x17, 0x18, 0x7f, 0x80, 0x07, 0x30, 0x02, 
+-      0x2a, 0x00, 0xd0, 0x04, 0x29, 0x00, 0xd0, 0x02, 
+-      0x33, 0x01, 0x2b, 0x70, 0xdb, 0xc0, 0xbc, 0x80, 
+-      0x47, 0x70, 0x21, 0x19, 0xe7, 0xf0, 0x21, 0x1a, 
+-      0xe7, 0xee, 0x21, 0x1b, 0xe7, 0xec, 0x21, 0x1c, 
+-      0xe7, 0xea, 0x21, 0x1d, 0xe7, 0xe8, 0xb5, 0xf0, 
+-      0x1c, 0x0f, 0x1c, 0x11, 0x04, 0x02, 0x0c, 0x12, 
+-      0x04, 0x0c, 0x0c, 0x24, 0x04, 0x1d, 0x0c, 0x2d, 
+-      0x00, 0x96, 0xb0, 0x81, 0x48, 0x10, 0x90, 0x00, 
+-      0x59, 0x81, 0x20, 0xff, 0x29, 0x00, 0xd0, 0x16, 
+-      0x2a, 0x00, 0xd0, 0x14, 0x2a, 0x0f, 0xdc, 0x12, 
+-      0x23, 0x32, 0x5e, 0xca, 0x42, 0xa2, 0xdb, 0x0e, 
+-      0x23, 0x34, 0x5e, 0xc9, 0x42, 0xa9, 0xdb, 0x0a, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xff, 0x93, 0x98, 0x00, 
+-      0x59, 0x80, 0x1c, 0x39, 0x1c, 0x22, 0x1c, 0x2b, 
+-      0xf7, 0xff, 0xfb, 0x5c, 0x20, 0x00, 0xb0, 0x01, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x55, 0x10, 0xb4, 0xb0, 0x04, 0x07, 
+-      0x0c, 0x3f, 0x04, 0x09, 0x0c, 0x09, 0x04, 0x14, 
+-      0x14, 0x24, 0x04, 0x1a, 0x14, 0x12, 0x20, 0xff, 
+-      0x2f, 0x0f, 0xdc, 0x1d, 0x00, 0xbd, 0x4f, 0x0f, 
+-      0x59, 0x7b, 0x2b, 0x00, 0xd0, 0x18, 0x48, 0x0e, 
+-      0x29, 0x01, 0xd0, 0x05, 0x29, 0x02, 0xd0, 0x01, 
+-      0x29, 0x03, 0xd0, 0x03, 0x6c, 0x80, 0xe0, 0x02, 
+-      0x6c, 0x40, 0xe0, 0x00, 0x6c, 0xc0, 0x62, 0x58, 
+-      0x59, 0x78, 0x63, 0xc4, 0x20, 0x00, 0x43, 0xc0, 
+-      0x42, 0x82, 0xd1, 0x02, 0x59, 0x79, 0x63, 0x88, 
+-      0xe0, 0x01, 0x59, 0x78, 0x63, 0x82, 0x20, 0x00, 
+-      0xbc, 0xb0, 0x47, 0x70, 0x2e, 0x08, 0x55, 0x10, 
+-      0x2e, 0x08, 0x1c, 0x80, 0xb5, 0x00, 0x04, 0x00, 
+-      0x0c, 0x00, 0x04, 0x09, 0x0c, 0x09, 0x00, 0x80, 
+-      0x4a, 0x07, 0x58, 0x10, 0x28, 0x00, 0xd1, 0x02, 
+-      0x20, 0xff, 0xbc, 0x08, 0x47, 0x18, 0x07, 0x89, 
+-      0x0f, 0x89, 0x68, 0x80, 0xf0, 0x03, 0xfe, 0x76, 
+-      0x20, 0x00, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x55, 0x10, 0x04, 0x09, 0x0c, 0x09, 
+-      0x4b, 0x0a, 0x40, 0x18, 0x08, 0x4a, 0xd3, 0x01, 
+-      0x23, 0x02, 0x43, 0x18, 0x08, 0x8a, 0xd3, 0x02, 
+-      0x23, 0x01, 0x04, 0x5b, 0x43, 0x18, 0x08, 0xca, 
+-      0xd3, 0x01, 0x23, 0x01, 0x43, 0x18, 0x09, 0x09, 
+-      0xd3, 0x02, 0x23, 0x01, 0x04, 0x1b, 0x43, 0x18, 
+-      0x47, 0x70, 0x00, 0x00, 0xff, 0xfc, 0xff, 0xfc, 
+-      0xb5, 0xf0, 0x04, 0x00, 0x0c, 0x00, 0x04, 0x14, 
+-      0x0c, 0x24, 0x1c, 0x1e, 0x1c, 0x0f, 0x28, 0x07, 
+-      0xdc, 0x25, 0x28, 0x01, 0xdb, 0x23, 0x00, 0x85, 
+-      0x48, 0x12, 0x59, 0x40, 0x28, 0x00, 0xd0, 0x1e, 
+-      0x0e, 0x31, 0x02, 0x30, 0x0a, 0x00, 0xf7, 0xff, 
+-      0xff, 0xd1, 0x1c, 0x06, 0x2f, 0x02, 0xd0, 0x0e, 
+-      0x2f, 0x04, 0xd0, 0x0c, 0x2f, 0x10, 0xd0, 0x0a, 
+-      0x23, 0xff, 0x33, 0x01, 0x42, 0x9f, 0xd1, 0x0e, 
+-      0x06, 0x22, 0x0e, 0x12, 0x1c, 0x31, 0x48, 0x08, 
+-      0x6c, 0x00, 0x68, 0x00, 0xe0, 0x05, 0x07, 0x22, 
+-      0x0f, 0x12, 0x48, 0x06, 0x59, 0x40, 0x68, 0x00, 
+-      0x1c, 0x31, 0xf0, 0x0b, 0xfa, 0xdb, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x55, 0x10, 
+-      0x2e, 0x08, 0x1c, 0x80, 0x2e, 0x08, 0x55, 0x50, 
+-      0xb5, 0xf0, 0x04, 0x04, 0x0c, 0x24, 0x04, 0x10, 
+-      0x0c, 0x00, 0x04, 0x1f, 0x0c, 0x3f, 0x22, 0x00, 
+-      0xb0, 0x81, 0x92, 0x00, 0x2c, 0x07, 0xdc, 0x3a, 
+-      0x2c, 0x01, 0xdb, 0x38, 0x00, 0xa4, 0x4a, 0x1e, 
+-      0x59, 0x12, 0x2a, 0x00, 0xd0, 0x33, 0x29, 0x02, 
+-      0xd0, 0x1b, 0x29, 0x04, 0xd0, 0x19, 0x29, 0x10, 
+-      0xd0, 0x17, 0x23, 0xff, 0x33, 0x01, 0x42, 0x99, 
+-      0xd1, 0x29, 0x06, 0x02, 0x0e, 0x12, 0x46, 0x69, 
+-      0x1c, 0x15, 0x4c, 0x16, 0x6c, 0x20, 0x68, 0x00, 
+-      0xf0, 0x0b, 0xfa, 0xdc, 0x98, 0x00, 0x02, 0x00, 
+-      0x0a, 0x00, 0x1c, 0x39, 0xf7, 0xff, 0xff, 0x82, 
+-      0x90, 0x00, 0x1c, 0x01, 0x6c, 0x20, 0x1c, 0x2a, 
+-      0xe0, 0x12, 0x07, 0x02, 0x0f, 0x12, 0x1c, 0x15, 
+-      0x4e, 0x0d, 0x59, 0x30, 0x68, 0x00, 0x46, 0x69, 
+-      0xf0, 0x0b, 0xfa, 0xc8, 0x98, 0x00, 0x02, 0x00, 
+-      0x0a, 0x00, 0x1c, 0x39, 0xf7, 0xff, 0xff, 0x6e, 
+-      0x90, 0x00, 0x1c, 0x01, 0x59, 0x30, 0x1c, 0x2a, 
+-      0x68, 0x00, 0xf0, 0x0b, 0xfa, 0x8b, 0xb0, 0x01, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x55, 0x10, 0x2e, 0x08, 0x1c, 0x80, 
+-      0x2e, 0x08, 0x55, 0x50, 0xb5, 0xf0, 0x4f, 0x28, 
+-      0x25, 0x00, 0x24, 0xff, 0x69, 0x38, 0x28, 0x00, 
+-      0xd1, 0x01, 0x60, 0xbd, 0xe0, 0x0c, 0x26, 0x05, 
+-      0x68, 0xb9, 0x29, 0x07, 0xd2, 0xf9, 0xa3, 0x02, 
+-      0x5c, 0x5b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x04, 0x08, 0x10, 0x1a, 0x21, 0x30, 0x38, 0x00, 
+-      0x1c, 0x20, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x20, 0x01, 0x02, 0x80, 0xf7, 0xf6, 0xfa, 0x86, 
+-      0x28, 0x00, 0xdb, 0x2d, 0x20, 0x02, 0xe0, 0x25, 
+-      0x48, 0x18, 0xf7, 0xf6, 0xfa, 0xa1, 0x28, 0x00, 
+-      0xdb, 0x26, 0x89, 0xb8, 0x28, 0x00, 0xdd, 0x15, 
+-      0x20, 0x03, 0xe0, 0x1b, 0x89, 0xb8, 0xf7, 0xf6, 
+-      0xfa, 0x75, 0x28, 0x00, 0xdb, 0x1c, 0x20, 0x04, 
+-      0xe0, 0x14, 0xf7, 0xf6, 0xfa, 0x91, 0x28, 0x00, 
+-      0xdb, 0x16, 0x69, 0x39, 0x18, 0x09, 0x61, 0x39, 
+-      0x89, 0xb9, 0x1a, 0x08, 0x81, 0xb8, 0x89, 0xb8, 
+-      0x28, 0x00, 0xdc, 0xe9, 0x60, 0xbe, 0xe0, 0x0b, 
+-      0x20, 0x00, 0xf7, 0xf6, 0xfa, 0x5f, 0x28, 0x00, 
+-      0xd1, 0x06, 0x20, 0x06, 0x60, 0xb8, 0xe0, 0x03, 
+-      0xf7, 0xf6, 0xfa, 0x7a, 0x28, 0x00, 0xda, 0xb8, 
+-      0x1c, 0x28, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x1d, 0x00, 0x2e, 0x08, 0x55, 0xb0, 
+-      0xb5, 0xf0, 0x04, 0x04, 0x0c, 0x24, 0x04, 0x0d, 
+-      0x0c, 0x2d, 0x04, 0x16, 0x0c, 0x36, 0xb0, 0x85, 
+-      0xa8, 0x01, 0x49, 0x2e, 0xc9, 0x8e, 0xc0, 0x8e, 
+-      0x2c, 0x00, 0xd0, 0x07, 0x2c, 0x01, 0xd0, 0x07, 
+-      0x2c, 0x02, 0xd0, 0x07, 0x2c, 0x03, 0xd1, 0x3f, 
+-      0x21, 0x08, 0xe0, 0x04, 0x21, 0x01, 0xe0, 0x02, 
+-      0x21, 0x02, 0xe0, 0x00, 0x21, 0x04, 0x91, 0x00, 
+-      0x23, 0x2d, 0x01, 0x1b, 0x42, 0x9d, 0xdc, 0x33, 
+-      0x23, 0x09, 0x01, 0x9b, 0x42, 0x9e, 0xdc, 0x2f, 
+-      0x1e, 0x68, 0x90, 0x03, 0x1e, 0x70, 0x90, 0x04, 
+-      0xa8, 0x01, 0x1c, 0x21, 0xf0, 0x07, 0xfb, 0xb8, 
+-      0x4f, 0x1d, 0x60, 0x78, 0x00, 0x80, 0x23, 0x01, 
+-      0x04, 0x1b, 0x42, 0x98, 0xdc, 0x20, 0x1f, 0xf8, 
+-      0x38, 0x79, 0x67, 0xc4, 0x68, 0x38, 0x28, 0x00, 
+-      0xd0, 0x0a, 0x68, 0x80, 0xb0, 0x81, 0x46, 0x6b, 
+-      0x22, 0x00, 0x21, 0x00, 0xf0, 0x09, 0xfd, 0x42, 
+-      0x68, 0x38, 0xf7, 0xfe, 0xfe, 0x90, 0xb0, 0x01, 
+-      0x22, 0x00, 0x21, 0x0a, 0x20, 0x01, 0xb4, 0x07, 
+-      0x1c, 0x22, 0xb4, 0x04, 0x21, 0x00, 0x20, 0x00, 
+-      0x1c, 0x2a, 0x1c, 0x33, 0xf7, 0xfe, 0xfd, 0x62, 
+-      0xb0, 0x04, 0x60, 0x38, 0x1c, 0x01, 0xd1, 0x03, 
+-      0xb0, 0x05, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x69, 0x88, 0x99, 0x00, 0x43, 0x4d, 0x1d, 0xe9, 
+-      0xd5, 0x00, 0x31, 0x07, 0x10, 0xc9, 0x43, 0x71, 
+-      0x61, 0x38, 0x60, 0x79, 0x81, 0xb9, 0x20, 0x01, 
+-      0x60, 0xb8, 0xe7, 0xed, 0x2e, 0x03, 0x39, 0x50, 
+-      0x2e, 0x08, 0x1d, 0x00, 0xb5, 0xf0, 0x04, 0x00, 
+-      0x0c, 0x00, 0x04, 0x09, 0x0c, 0x09, 0xb0, 0x87, 
+-      0x91, 0x00, 0x04, 0x11, 0x0c, 0x09, 0x91, 0x01, 
+-      0x04, 0x19, 0x0c, 0x09, 0x91, 0x02, 0xb0, 0x85, 
+-      0x28, 0x07, 0xdc, 0x43, 0x28, 0x01, 0xdb, 0x41, 
+-      0x00, 0x85, 0x48, 0x3e, 0x90, 0x0b, 0x59, 0x41, 
+-      0x29, 0x00, 0xd0, 0x3b, 0x48, 0x3c, 0x90, 0x0a, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x36, 0x23, 0x2c, 
+-      0x5e, 0xca, 0x2a, 0x0b, 0xd2, 0x32, 0xa3, 0x02, 
+-      0x5c, 0x9b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 
+-      0x06, 0x06, 0x06, 0x00, 0x22, 0x00, 0x92, 0x00, 
+-      0x92, 0x01, 0x23, 0x32, 0x5e, 0xc3, 0x93, 0x02, 
+-      0x23, 0x34, 0x5e, 0xc0, 0x90, 0x03, 0x92, 0x04, 
+-      0x98, 0x07, 0x08, 0x80, 0xd3, 0x40, 0x23, 0x2c, 
+-      0x5e, 0xc8, 0x28, 0x00, 0xd0, 0x08, 0x28, 0x01, 
+-      0xd0, 0x08, 0x28, 0x02, 0xd0, 0x08, 0x28, 0x03, 
+-      0xd1, 0x10, 0x27, 0xff, 0x37, 0x01, 0xe0, 0x04, 
+-      0x27, 0x02, 0xe0, 0x02, 0x27, 0x04, 0xe0, 0x00, 
+-      0x27, 0x10, 0x4e, 0x24, 0x23, 0xff, 0x33, 0x01, 
+-      0x42, 0x9f, 0xd1, 0x16, 0x24, 0x00, 0x48, 0x22, 
+-      0x90, 0x09, 0xe0, 0x03, 0xb0, 0x0c, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0xa0, 0x58, 0x31, 
+-      0x29, 0x00, 0xd0, 0x06, 0x06, 0x22, 0x0e, 0x12, 
+-      0x98, 0x09, 0x6c, 0x00, 0x68, 0x00, 0xf0, 0x0b, 
+-      0xf9, 0x5d, 0x34, 0x01, 0x42, 0xbc, 0xdb, 0xf1, 
+-      0xe0, 0x12, 0x24, 0x00, 0x2f, 0x00, 0xdd, 0x0f, 
+-      0x48, 0x16, 0x90, 0x08, 0x00, 0xa0, 0x58, 0x31, 
+-      0x29, 0x00, 0xd0, 0x06, 0x07, 0x22, 0x0f, 0x12, 
+-      0x98, 0x08, 0x59, 0x40, 0x68, 0x00, 0xf0, 0x0b, 
+-      0xf9, 0x49, 0x34, 0x01, 0x42, 0xbc, 0xdb, 0xf1, 
+-      0x98, 0x07, 0x08, 0x40, 0xd3, 0x01, 0x22, 0xff, 
+-      0xe0, 0x00, 0x22, 0x00, 0x99, 0x06, 0xb4, 0x06, 
+-      0x98, 0x0d, 0x59, 0x40, 0x68, 0x81, 0x98, 0x0c, 
+-      0x68, 0x00, 0x68, 0x80, 0x9b, 0x07, 0xaa, 0x02, 
+-      0xf0, 0x09, 0xff, 0x12, 0xb0, 0x0e, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x55, 0x10, 
+-      0x2e, 0x08, 0x1d, 0x00, 0x2e, 0x08, 0x55, 0xb0, 
+-      0x2e, 0x08, 0x1c, 0x80, 0x2e, 0x08, 0x55, 0x50, 
+-      0xb5, 0x80, 0x4f, 0x0a, 0x68, 0x38, 0x28, 0x00, 
+-      0xd0, 0x0c, 0x68, 0x80, 0xb0, 0x81, 0x46, 0x6b, 
+-      0x22, 0x00, 0x21, 0x00, 0xf0, 0x09, 0xfc, 0x72, 
+-      0x68, 0x38, 0xf7, 0xfe, 0xfd, 0xc0, 0x20, 0x00, 
+-      0x60, 0x38, 0xb0, 0x01, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x1d, 0x00, 
+-      0xb5, 0x00, 0x04, 0x01, 0x0c, 0x09, 0x20, 0xff, 
+-      0x29, 0x07, 0xdc, 0x09, 0x00, 0x89, 0x4a, 0x05, 
+-      0x58, 0x51, 0x29, 0x00, 0xd0, 0x04, 0x68, 0x88, 
+-      0x21, 0x01, 0xf0, 0x03, 0xfb, 0x93, 0x20, 0x00, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x55, 0x10, 
+-      0xb5, 0x00, 0x04, 0x01, 0x0c, 0x09, 0x20, 0xff, 
+-      0x29, 0x07, 0xdc, 0x09, 0x00, 0x89, 0x4a, 0x05, 
+-      0x58, 0x51, 0x29, 0x00, 0xd0, 0x04, 0x68, 0x88, 
+-      0x21, 0x00, 0xf0, 0x03, 0xfb, 0x7f, 0x20, 0x00, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x55, 0x10, 
+-      0xb5, 0xf7, 0xb0, 0x86, 0x9c, 0x07, 0x20, 0x00, 
+-      0x6e, 0x40, 0x90, 0x05, 0x98, 0x05, 0x30, 0x0c, 
+-      0x90, 0x05, 0x48, 0x7f, 0x90, 0x04, 0x98, 0x04, 
+-      0x30, 0x0c, 0x90, 0x04, 0xf0, 0x11, 0xff, 0xf0, 
+-      0x90, 0x01, 0xf0, 0x11, 0xff, 0xd3, 0x90, 0x00, 
+-      0x20, 0x00, 0x43, 0xc0, 0x49, 0x79, 0x60, 0x08, 
+-      0x20, 0x00, 0x43, 0xc0, 0x49, 0x77, 0x60, 0x88, 
+-      0x20, 0x00, 0x43, 0xc0, 0x49, 0x75, 0x61, 0x08, 
+-      0x98, 0x06, 0x28, 0x00, 0xd0, 0x73, 0x20, 0x00, 
+-      0x6a, 0x40, 0x90, 0x03, 0x68, 0x20, 0x30, 0x05, 
+-      0x99, 0x06, 0x1a, 0x08, 0x90, 0x06, 0x68, 0xe0, 
+-      0x28, 0x00, 0xd0, 0x08, 0x68, 0x60, 0x99, 0x03, 
+-      0x68, 0x09, 0x42, 0x88, 0xd1, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0xe0, 0x06, 0x68, 0x60, 
+-      0x9a, 0x08, 0x42, 0x90, 0xd1, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0x28, 0x00, 0xd0, 0x73, 
+-      0x68, 0x27, 0x68, 0xe0, 0x28, 0x00, 0xd0, 0x01, 
+-      0x98, 0x05, 0xe0, 0x00, 0x98, 0x04, 0x1c, 0x06, 
+-      0x68, 0xe0, 0x28, 0x00, 0xd0, 0x02, 0x20, 0x00, 
+-      0x6e, 0x40, 0xe0, 0x00, 0x48, 0x5c, 0x90, 0x02, 
+-      0x1d, 0xe5, 0x35, 0x0d, 0x68, 0xa0, 0x28, 0x08, 
+-      0xd2, 0x5f, 0xa3, 0x02, 0x5c, 0x1b, 0x00, 0x5b, 
+-      0x44, 0x9f, 0x1c, 0x00, 0x04, 0x16, 0x28, 0x3a, 
+-      0x49, 0x55, 0x65, 0x71, 0x69, 0x20, 0x49, 0x55, 
+-      0x60, 0x08, 0xcd, 0x02, 0x48, 0x53, 0x60, 0x41, 
+-      0xcd, 0x02, 0x98, 0x02, 0x60, 0x01, 0x3f, 0x01, 
+-      0x1c, 0x38, 0x3f, 0x01, 0x28, 0x00, 0xd0, 0x02, 
+-      0xcd, 0x02, 0xc6, 0x02, 0xe7, 0xf8, 0xe0, 0x67, 
+-      0x69, 0x20, 0x49, 0x4c, 0x60, 0x88, 0xcd, 0x02, 
+-      0x48, 0x4a, 0x60, 0xc1, 0xcd, 0x02, 0x98, 0x02, 
+-      0x60, 0x41, 0x3f, 0x01, 0x1c, 0x38, 0x3f, 0x01, 
+-      0x28, 0x00, 0xd0, 0x02, 0xcd, 0x02, 0xc6, 0x02, 
+-      0xe7, 0xf8, 0xe0, 0x55, 0x69, 0x20, 0x49, 0x43, 
+-      0x61, 0x08, 0xcd, 0x02, 0x48, 0x41, 0x61, 0x41, 
+-      0xcd, 0x02, 0x98, 0x02, 0x60, 0x81, 0x3f, 0x01, 
+-      0x1c, 0x38, 0x3f, 0x01, 0x28, 0x00, 0xd0, 0x02, 
+-      0xcd, 0x02, 0xc6, 0x02, 0xe7, 0xf8, 0xe0, 0x43, 
+-      0x69, 0x20, 0x00, 0x80, 0xe0, 0x00, 0xe0, 0x4b, 
+-      0x21, 0x00, 0x6a, 0x89, 0x50, 0x0e, 0x1c, 0x38, 
+-      0x3f, 0x01, 0x28, 0x00, 0xd0, 0x02, 0xcd, 0x02, 
+-      0xc6, 0x02, 0xe7, 0xf8, 0xe0, 0x34, 0x69, 0x20, 
+-      0x00, 0x80, 0x49, 0x33, 0x50, 0x0e, 0x1c, 0x38, 
+-      0x3f, 0x01, 0x28, 0x00, 0xd0, 0x02, 0xcd, 0x02, 
+-      0xc6, 0x02, 0xe7, 0xf8, 0xe0, 0x28, 0x69, 0x20, 
+-      0x00, 0x80, 0x21, 0x00, 0x6e, 0x09, 0xe0, 0x01, 
+-      0xe0, 0x28, 0xe0, 0x20, 0x50, 0x0e, 0x1c, 0x38, 
+-      0x3f, 0x01, 0x28, 0x00, 0xd0, 0x02, 0xcd, 0x02, 
+-      0xc6, 0x02, 0xe7, 0xf8, 0xe0, 0x18, 0x69, 0x20, 
+-      0x00, 0x80, 0x49, 0x26, 0x50, 0x0e, 0x1c, 0x38, 
+-      0x3f, 0x01, 0x28, 0x00, 0xd0, 0x02, 0xcd, 0x02, 
+-      0xc6, 0x02, 0xe7, 0xf8, 0xe0, 0x0c, 0x69, 0x20, 
+-      0x90, 0x03, 0x1c, 0x38, 0x3f, 0x01, 0x28, 0x00, 
+-      0xd0, 0x04, 0xcd, 0x02, 0x98, 0x03, 0xc0, 0x02, 
+-      0x90, 0x03, 0xe7, 0xf6, 0xe0, 0x00, 0xe7, 0xff, 
+-      0x68, 0xe0, 0x28, 0xff, 0xd1, 0x01, 0x96, 0x05, 
+-      0xe0, 0x00, 0x96, 0x04, 0x68, 0x20, 0x00, 0x80, 
+-      0x19, 0x00, 0x1d, 0xc4, 0x34, 0x0d, 0xe7, 0x3b, 
+-      0x98, 0x01, 0x28, 0x00, 0xd1, 0x01, 0xf0, 0x11, 
+-      0xff, 0x4f, 0x98, 0x00, 0x28, 0x00, 0xd1, 0x01, 
+-      0xf0, 0x11, 0xff, 0x2e, 0x20, 0x00, 0x6e, 0x80, 
+-      0x68, 0x00, 0x4b, 0x0f, 0x42, 0x98, 0xd0, 0x06, 
+-      0x48, 0x0d, 0x21, 0x00, 0x6e, 0x89, 0x60, 0x08, 
+-      0x20, 0x01, 0x49, 0x08, 0x62, 0x08, 0x20, 0x00, 
+-      0x21, 0x00, 0x6e, 0x89, 0x60, 0x08, 0x20, 0x00, 
+-      0xb0, 0x06, 0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb0, 0x06, 0xe7, 0xf9, 0x00, 0x00, 
+-      0x2e, 0x08, 0x59, 0xb0, 0x66, 0x00, 0x00, 0x80, 
+-      0x2e, 0x08, 0x3a, 0xf4, 0x2e, 0x08, 0x1d, 0x14, 
+-      0xda, 0xa5, 0xaa, 0x57, 0xb5, 0x80, 0xb0, 0xa7, 
+-      0x46, 0x68, 0x4f, 0x08, 0x23, 0x13, 0xcf, 0x06, 
+-      0xc0, 0x06, 0x3b, 0x01, 0xd1, 0xfb, 0xcf, 0x04, 
+-      0xc0, 0x04, 0x46, 0x69, 0x4a, 0x04, 0x20, 0x27, 
+-      0xf7, 0xff, 0xfe, 0xde, 0xb0, 0x27, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x03, 0x39, 0x60, 
+-      0xf0, 0x24, 0x00, 0x09, 0xb5, 0xff, 0xb0, 0x83, 
+-      0x99, 0x04, 0x04, 0x09, 0x0c, 0x09, 0x91, 0x00, 
+-      0x9a, 0x05, 0x06, 0x16, 0x0e, 0x36, 0x9b, 0x06, 
+-      0x06, 0x18, 0x0e, 0x00, 0x90, 0x01, 0x98, 0x0c, 
+-      0x06, 0x00, 0x0e, 0x00, 0x90, 0x02, 0xb0, 0x84, 
+-      0x25, 0x00, 0x98, 0x07, 0x1d, 0xc2, 0x32, 0x21, 
+-      0x92, 0x00, 0x20, 0xff, 0x30, 0x01, 0x68, 0x00, 
+-      0x49, 0x6b, 0x60, 0x08, 0x98, 0x12, 0x28, 0x01, 
+-      0xd1, 0x73, 0x98, 0x07, 0x28, 0x00, 0xd1, 0x05, 
+-      0x20, 0x63, 0xb0, 0x07, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x21, 0x00, 0x91, 0x01, 
+-      0x99, 0x01, 0x23, 0xff, 0x33, 0xe1, 0x42, 0x99, 
+-      0xd3, 0x04, 0xe0, 0x0a, 0x99, 0x01, 0x31, 0x01, 
+-      0x91, 0x01, 0xe7, 0xf5, 0x20, 0x00, 0x99, 0x01, 
+-      0x23, 0x2c, 0x43, 0x59, 0x9a, 0x00, 0x50, 0x50, 
+-      0xe7, 0xf4, 0x98, 0x07, 0x49, 0x5b, 0x68, 0x09, 
+-      0x60, 0x08, 0x98, 0x05, 0x28, 0x10, 0xdb, 0x01, 
+-      0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 0x99, 0x05, 
+-      0x29, 0x1f, 0xdc, 0x01, 0x21, 0x01, 0xe0, 0x00, 
+-      0x21, 0x00, 0x40, 0x08, 0xd0, 0x04, 0x98, 0x05, 
+-      0x49, 0x53, 0x68, 0x09, 0x60, 0x08, 0xe0, 0x02, 
+-      0x20, 0x62, 0xb0, 0x07, 0xe7, 0xce, 0x20, 0x00, 
+-      0x49, 0x4d, 0x68, 0x09, 0x70, 0x08, 0x1c, 0x30, 
+-      0x23, 0x03, 0x02, 0x5b, 0x22, 0x01, 0x02, 0xd2, 
+-      0x21, 0x01, 0xf0, 0x00, 0xfb, 0x01, 0x1c, 0x07, 
+-      0x2f, 0x00, 0xd0, 0x02, 0x20, 0xa2, 0xb0, 0x07, 
+-      0xe7, 0xbc, 0x22, 0x00, 0xb4, 0x04, 0x99, 0x05, 
+-      0x1c, 0x30, 0x23, 0x04, 0x22, 0x00, 0xf0, 0x00, 
+-      0xf9, 0x2f, 0xb0, 0x01, 0x1c, 0x07, 0x2f, 0x00, 
+-      0xd0, 0x02, 0x20, 0xa2, 0xb0, 0x07, 0xe7, 0xad, 
+-      0x98, 0x06, 0x28, 0x00, 0xdb, 0x04, 0x98, 0x06, 
+-      0x28, 0x3f, 0xdc, 0x01, 0x9d, 0x06, 0xe0, 0x00, 
+-      0x25, 0x1b, 0x98, 0x11, 0x01, 0x80, 0x43, 0x05, 
+-      0x23, 0x80, 0x43, 0x1d, 0x48, 0x39, 0x68, 0x01, 
+-      0x0a, 0x09, 0x02, 0x09, 0x60, 0x01, 0x48, 0x37, 
+-      0x68, 0x01, 0x43, 0x29, 0x60, 0x01, 0xf0, 0x11, 
+-      0xfe, 0x2d, 0x90, 0x03, 0xf0, 0x11, 0xfe, 0x44, 
+-      0xe0, 0x00, 0xe0, 0x13, 0x90, 0x02, 0xf0, 0x11, 
+-      0xfe, 0xa3, 0x1c, 0x04, 0x4b, 0x30, 0x40, 0x1c, 
+-      0x1c, 0x20, 0xf0, 0x11, 0xfe, 0xa1, 0x98, 0x02, 
+-      0x28, 0x40, 0xd0, 0x01, 0xf0, 0x11, 0xfe, 0x6c, 
+-      0x98, 0x03, 0x28, 0x80, 0xd0, 0x01, 0xf0, 0x11, 
+-      0xfe, 0x4b, 0xe0, 0x43, 0x22, 0x00, 0xb4, 0x04, 
+-      0x1c, 0x30, 0x23, 0x04, 0x22, 0x00, 0x49, 0x27, 
+-      0xf0, 0x00, 0xf8, 0xee, 0xb0, 0x01, 0x1c, 0x07, 
+-      0x2f, 0x00, 0xd0, 0x02, 0x20, 0xa2, 0xb0, 0x07, 
+-      0xe7, 0x6c, 0x1c, 0x30, 0x23, 0x03, 0x02, 0x5b, 
+-      0x22, 0x01, 0x02, 0xd2, 0x21, 0x02, 0xf0, 0x00, 
+-      0xfa, 0xa3, 0x1c, 0x07, 0x2f, 0x00, 0xd0, 0x02, 
+-      0x20, 0xa2, 0xb0, 0x07, 0xe7, 0x5e, 0x48, 0x19, 
+-      0x68, 0x01, 0x0a, 0x09, 0x02, 0x09, 0x60, 0x01, 
+-      0x48, 0x16, 0x68, 0x01, 0x23, 0x1b, 0x43, 0x19, 
+-      0x60, 0x01, 0x48, 0x12, 0x68, 0x00, 0x68, 0x00, 
+-      0x90, 0x07, 0xf0, 0x11, 0xfd, 0xe7, 0x90, 0x03, 
+-      0xf0, 0x11, 0xfd, 0xfe, 0x90, 0x02, 0xf0, 0x11, 
+-      0xfe, 0x5f, 0x1c, 0x04, 0x23, 0x01, 0x04, 0x5b, 
+-      0x43, 0x1c, 0x1c, 0x20, 0xf0, 0x11, 0xfe, 0x5c, 
+-      0x98, 0x02, 0x28, 0x40, 0xd0, 0x01, 0xf0, 0x11, 
+-      0xfe, 0x27, 0x98, 0x03, 0x28, 0x80, 0xd0, 0x01, 
+-      0xf0, 0x11, 0xfe, 0x06, 0x1c, 0x38, 0xb0, 0x07, 
+-      0xe7, 0x34, 0xb0, 0x04, 0xb0, 0x03, 0xe7, 0x31, 
+-      0x2e, 0x08, 0x5d, 0xb8, 0x2e, 0x08, 0x5d, 0xb0, 
+-      0x2e, 0x08, 0x5d, 0xb4, 0x68, 0x00, 0x00, 0x38, 
+-      0xff, 0xfd, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 
+-      0xb5, 0x00, 0xf7, 0xff, 0xfe, 0xe7, 0xf0, 0x00, 
+-      0xf8, 0x02, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0xf0, 
+-      0xf0, 0x0b, 0xf9, 0x48, 0x26, 0x00, 0x2e, 0x04, 
+-      0xd3, 0x02, 0xe0, 0x12, 0x36, 0x01, 0xe7, 0xfa, 
+-      0x01, 0x30, 0x4b, 0x3c, 0x18, 0xc7, 0x25, 0x00, 
+-      0x2d, 0x04, 0xd3, 0x02, 0xe0, 0x08, 0x35, 0x01, 
+-      0xe7, 0xfa, 0x20, 0x00, 0x60, 0xb8, 0x20, 0x00, 
+-      0x60, 0xf8, 0x37, 0xff, 0x37, 0x01, 0xe7, 0xf6, 
+-      0xe7, 0xec, 0x4f, 0x35, 0x25, 0x00, 0x2d, 0x04, 
+-      0xd3, 0x02, 0xe0, 0x07, 0x35, 0x01, 0xe7, 0xfa, 
+-      0x20, 0x00, 0x60, 0xb8, 0x20, 0x00, 0x60, 0xf8, 
+-      0x37, 0x10, 0xe7, 0xf7, 0x20, 0x00, 0x49, 0x2f, 
+-      0x68, 0x09, 0x70, 0x08, 0x24, 0x00, 0x2c, 0x20, 
+-      0xd3, 0x02, 0xe0, 0x1f, 0x34, 0x01, 0xe7, 0xfa, 
+-      0x21, 0x00, 0x00, 0xe0, 0x4a, 0x2a, 0x68, 0x12, 
+-      0x50, 0x11, 0x20, 0x00, 0x00, 0xe1, 0x4a, 0x28, 
+-      0x68, 0x12, 0x18, 0x89, 0x60, 0x48, 0x21, 0x00, 
+-      0x00, 0xe0, 0x4a, 0x26, 0x68, 0x12, 0x18, 0x80, 
+-      0x60, 0x41, 0x20, 0x00, 0x00, 0xa1, 0x4a, 0x24, 
+-      0x68, 0x12, 0x50, 0x50, 0x20, 0x00, 0x00, 0xe1, 
+-      0x1b, 0x09, 0x00, 0x89, 0x4a, 0x21, 0x68, 0x12, 
+-      0x52, 0x50, 0xe7, 0xdf, 0x20, 0x00, 0x21, 0x19, 
+-      0x06, 0x89, 0x62, 0x48, 0x48, 0x1e, 0x21, 0x19, 
+-      0x06, 0x89, 0x62, 0x48, 0x20, 0x00, 0x49, 0x1d, 
+-      0x68, 0x09, 0x60, 0x08, 0x20, 0x00, 0x49, 0x1b, 
+-      0x68, 0x09, 0x60, 0x48, 0x20, 0x00, 0x49, 0x19, 
+-      0x68, 0x09, 0x60, 0xc8, 0x20, 0x00, 0x49, 0x17, 
+-      0x68, 0x09, 0x61, 0x08, 0x20, 0x00, 0x49, 0x15, 
+-      0x68, 0x09, 0x61, 0x48, 0x20, 0x00, 0x49, 0x13, 
+-      0x68, 0x09, 0x61, 0x88, 0x20, 0x00, 0x49, 0x12, 
+-      0x68, 0x09, 0x60, 0x08, 0x20, 0x00, 0x49, 0x10, 
+-      0x68, 0x09, 0x60, 0x48, 0x20, 0x00, 0x49, 0x0e, 
+-      0x68, 0x09, 0x60, 0x88, 0x48, 0x0d, 0x68, 0x01, 
+-      0x23, 0x01, 0x43, 0x19, 0x60, 0x01, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x9e, 0x00, 0x00, 0xc0, 
+-      0x9e, 0x00, 0x09, 0x80, 0x2e, 0x08, 0x5d, 0xbc, 
+-      0x2e, 0x08, 0x5d, 0xd0, 0x2e, 0x08, 0x5d, 0xd4, 
+-      0x2e, 0x08, 0x5d, 0xcc, 0x2e, 0x08, 0x5d, 0xc4, 
+-      0x00, 0x40, 0x00, 0x03, 0x2e, 0x08, 0x5e, 0x0c, 
+-      0x2e, 0x08, 0x5e, 0x10, 0x6a, 0x00, 0x00, 0x10, 
+-      0xb5, 0xff, 0xb0, 0x83, 0x98, 0x03, 0x06, 0x04, 
+-      0x0e, 0x24, 0x99, 0x04, 0x04, 0x08, 0x0c, 0x00, 
+-      0x90, 0x00, 0x9a, 0x05, 0x06, 0x10, 0x0e, 0x00, 
+-      0x90, 0x01, 0x9b, 0x06, 0x06, 0x18, 0x0e, 0x00, 
+-      0x90, 0x02, 0xb0, 0x81, 0x00, 0xe0, 0x49, 0xc1, 
+-      0x68, 0x09, 0x18, 0x47, 0x00, 0xa0, 0x49, 0xc0, 
+-      0x68, 0x09, 0x18, 0x45, 0x00, 0xe0, 0x1b, 0x00, 
+-      0x00, 0x80, 0x49, 0xbe, 0x68, 0x09, 0x18, 0x46, 
+-      0x2c, 0x20, 0xdb, 0x05, 0x20, 0xa2, 0xb0, 0x04, 
+-      0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x68, 0x28, 0x4b, 0xb9, 0x40, 0x18, 0x60, 0x28, 
+-      0x68, 0x38, 0x4b, 0xb8, 0x40, 0x18, 0x60, 0x38, 
+-      0x68, 0x38, 0x23, 0x40, 0x40, 0x18, 0xd0, 0x17, 
+-      0x68, 0x38, 0x23, 0x40, 0x43, 0xdb, 0x40, 0x18, 
+-      0x60, 0x38, 0x48, 0xb3, 0x68, 0x01, 0x08, 0x49, 
+-      0x00, 0x49, 0x60, 0x01, 0x48, 0xb1, 0x68, 0x01, 
+-      0x23, 0x01, 0x05, 0x5b, 0x43, 0x19, 0x60, 0x01, 
+-      0x98, 0x01, 0x4b, 0xaf, 0x42, 0x98, 0xd1, 0x03, 
+-      0x20, 0x00, 0x49, 0xae, 0x68, 0x09, 0x60, 0x08, 
+-      0x98, 0x01, 0x4b, 0xab, 0x42, 0x98, 0xd0, 0x73, 
+-      0x68, 0x38, 0x23, 0x21, 0x43, 0xdb, 0x40, 0x18, 
+-      0x60, 0x38, 0x68, 0x28, 0x23, 0x07, 0x03, 0x5b, 
+-      0x40, 0x18, 0x60, 0x28, 0x98, 0x01, 0x4b, 0xa6, 
+-      0x40, 0x18, 0x68, 0x29, 0x43, 0x08, 0x60, 0x28, 
+-      0x20, 0x00, 0x75, 0x30, 0x98, 0x02, 0x07, 0x80, 
+-      0x0f, 0x80, 0x28, 0x01, 0xd1, 0x04, 0x88, 0x30, 
+-      0x23, 0x10, 0x43, 0x18, 0x80, 0x30, 0xe0, 0x04, 
+-      0x88, 0x30, 0x23, 0x10, 0x43, 0xdb, 0x40, 0x18, 
+-      0x80, 0x30, 0x98, 0x02, 0x23, 0x80, 0x40, 0x18, 
+-      0x28, 0x80, 0xd1, 0x08, 0x68, 0x38, 0x23, 0x40, 
+-      0x43, 0x18, 0x60, 0x38, 0x20, 0xff, 0x49, 0x97, 
+-      0x68, 0x09, 0x70, 0x08, 0xe0, 0x04, 0x68, 0x38, 
+-      0x23, 0x40, 0x43, 0xdb, 0x40, 0x18, 0x60, 0x38, 
+-      0x98, 0x03, 0x28, 0x01, 0xd1, 0x36, 0x88, 0x30, 
+-      0x23, 0x10, 0x43, 0xdb, 0x40, 0x18, 0x80, 0x30, 
+-      0x20, 0x33, 0x06, 0x40, 0x6d, 0x40, 0x23, 0x0d, 
+-      0x06, 0x9b, 0x1a, 0xc1, 0x00, 0xe0, 0x4a, 0x8c, 
+-      0x68, 0x12, 0x18, 0x80, 0x60, 0x41, 0x20, 0x01, 
+-      0x70, 0xb0, 0x68, 0x38, 0x23, 0x01, 0x03, 0x9b, 
+-      0x43, 0x18, 0x60, 0x38, 0x68, 0x38, 0x4b, 0x87, 
+-      0x43, 0x18, 0x60, 0x38, 0x48, 0x86, 0x70, 0x44, 
+-      0x20, 0x00, 0x49, 0x86, 0x68, 0x09, 0x60, 0x08, 
+-      0x20, 0x01, 0x02, 0xc0, 0x49, 0x84, 0x61, 0x48, 
+-      0x49, 0x83, 0x61, 0x08, 0x20, 0x01, 0x49, 0x83, 
+-      0x64, 0x48, 0x20, 0x00, 0x49, 0x81, 0x64, 0x48, 
+-      0x68, 0x28, 0x23, 0x01, 0x03, 0x5b, 0x43, 0x18, 
+-      0x60, 0x28, 0x20, 0x00, 0x49, 0x7e, 0x68, 0x09, 
+-      0x60, 0x08, 0xe0, 0x9a, 0x98, 0x03, 0x28, 0x02, 
+-      0xd1, 0x30, 0x20, 0x33, 0x06, 0x40, 0xe0, 0x00, 
+-      0xe0, 0x94, 0x6d, 0xc0, 0x23, 0x0d, 0x06, 0x9b, 
+-      0x1a, 0xc0, 0x00, 0xe1, 0x4a, 0x70, 0x68, 0x12, 
+-      0x18, 0x89, 0x60, 0x48, 0x20, 0x02, 0x70, 0xb0, 
+-      0x68, 0x38, 0x23, 0x01, 0x03, 0xdb, 0x43, 0x18, 
+-      0x60, 0x38, 0x68, 0x38, 0x4b, 0x6b, 0x43, 0x18, 
+-      0x60, 0x38, 0x48, 0x6b, 0x70, 0x84, 0x20, 0x00, 
+-      0x49, 0x6e, 0x60, 0x08, 0x00, 0xe0, 0x49, 0x5b, 
+-      0x68, 0x09, 0x58, 0x08, 0x23, 0xff, 0x33, 0x01, 
+-      0x43, 0x18, 0x00, 0xe1, 0x4a, 0x57, 0x68, 0x12, 
+-      0x50, 0x50, 0x20, 0x4b, 0x49, 0x67, 0x60, 0x08, 
+-      0x68, 0x28, 0x23, 0x01, 0x03, 0x5b, 0x43, 0x18, 
+-      0x60, 0x28, 0xe0, 0x66, 0x98, 0x03, 0x28, 0x04, 
+-      0xd1, 0x15, 0x20, 0x00, 0x00, 0xe1, 0x4a, 0x5a, 
+-      0x68, 0x12, 0x18, 0x89, 0x60, 0x48, 0x98, 0x03, 
+-      0x70, 0xb0, 0x68, 0x38, 0x23, 0x20, 0x43, 0x18, 
+-      0x60, 0x38, 0x68, 0x38, 0x60, 0x38, 0x48, 0x56, 
+-      0x70, 0x04, 0x68, 0x28, 0x23, 0x01, 0x03, 0x5b, 
+-      0x43, 0x18, 0x60, 0x28, 0xe0, 0x4d, 0x98, 0x03, 
+-      0x23, 0x10, 0x40, 0x18, 0xd0, 0x0f, 0x21, 0x00, 
+-      0x00, 0xe0, 0x4a, 0x4d, 0x68, 0x12, 0x18, 0x80, 
+-      0x60, 0x41, 0x68, 0x38, 0x4b, 0x52, 0x43, 0x18, 
+-      0x60, 0x38, 0x68, 0x38, 0x60, 0x38, 0x37, 0x04, 
+-      0x20, 0x0e, 0x60, 0x38, 0xe0, 0x39, 0x98, 0x03, 
+-      0x28, 0x08, 0xd1, 0x23, 0x48, 0x4d, 0x68, 0x00, 
+-      0x30, 0x60, 0x7e, 0x80, 0x28, 0x00, 0xd0, 0x03, 
+-      0x20, 0x4f, 0xb0, 0x04, 0xe6, 0xf8, 0xe0, 0x67, 
+-      0x20, 0x01, 0x49, 0x48, 0x68, 0x09, 0x31, 0x60, 
+-      0x76, 0x88, 0x48, 0x46, 0x68, 0x00, 0x30, 0x60, 
+-      0x76, 0x04, 0x20, 0x01, 0x49, 0x43, 0x68, 0x09, 
+-      0x31, 0x80, 0x70, 0xc8, 0x49, 0x42, 0x00, 0xe0, 
+-      0x4a, 0x37, 0x68, 0x12, 0x18, 0x80, 0x60, 0x41, 
+-      0x68, 0x28, 0x23, 0x01, 0x03, 0x5b, 0x43, 0x18, 
+-      0x60, 0x28, 0xe0, 0x12, 0x21, 0x00, 0x00, 0xe0, 
+-      0x4a, 0x31, 0x68, 0x12, 0x18, 0x80, 0x60, 0x41, 
+-      0x98, 0x03, 0x70, 0xb0, 0x68, 0x38, 0x23, 0x20, 
+-      0x43, 0x18, 0x60, 0x38, 0x68, 0x38, 0x60, 0x38, 
+-      0x68, 0x28, 0x23, 0x01, 0x03, 0x5b, 0x43, 0x18, 
+-      0x60, 0x28, 0xe0, 0x33, 0x98, 0x03, 0x23, 0x10, 
+-      0x40, 0x18, 0xd0, 0x09, 0x1c, 0x20, 0xf0, 0x05, 
+-      0xf8, 0x0f, 0x90, 0x00, 0x28, 0x00, 0xd0, 0x02, 
+-      0x98, 0x00, 0xb0, 0x04, 0xe6, 0xbc, 0xe0, 0x1a, 
+-      0x98, 0x03, 0x28, 0x01, 0xd1, 0x03, 0x20, 0xff, 
+-      0x49, 0x21, 0x70, 0x48, 0xe0, 0x13, 0x98, 0x03, 
+-      0x28, 0x02, 0xd1, 0x03, 0x20, 0xff, 0x49, 0x1e, 
+-      0x70, 0x88, 0xe0, 0x0c, 0x98, 0x03, 0x28, 0x08, 
+-      0xd1, 0x09, 0x20, 0x00, 0x49, 0x21, 0x68, 0x09, 
+-      0x31, 0x80, 0x70, 0xc8, 0x20, 0x00, 0x49, 0x1f, 
+-      0x68, 0x09, 0x31, 0x60, 0x76, 0x88, 0x7d, 0x30, 
+-      0x07, 0xc0, 0x0f, 0xc0, 0x28, 0x01, 0xd1, 0x03, 
+-      0x1c, 0x20, 0x49, 0x1c, 0xf0, 0x00, 0xf9, 0x16, 
+-      0x20, 0x00, 0x70, 0xb0, 0x20, 0x00, 0xb0, 0x04, 
+-      0xe6, 0x92, 0xb0, 0x01, 0xb0, 0x03, 0xe6, 0x8f, 
+-      0xe6, 0x8e, 0x00, 0x00, 0x2e, 0x08, 0x5d, 0xd0, 
+-      0x2e, 0x08, 0x5d, 0xcc, 0x2e, 0x08, 0x5d, 0xc4, 
+-      0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0x3f, 0xff, 
+-      0x6a, 0x00, 0x00, 0x18, 0x6c, 0x00, 0x00, 0x20, 
+-      0x00, 0x00, 0xff, 0xff, 0x2e, 0x08, 0x5d, 0xd8, 
+-      0xff, 0xff, 0x1f, 0xff, 0x2e, 0x08, 0x5e, 0x2c, 
+-      0x2e, 0x08, 0x5d, 0xd4, 0x00, 0x00, 0x20, 0x01, 
+-      0x2e, 0x08, 0x5e, 0x30, 0x2e, 0x08, 0x5d, 0xfc, 
+-      0xcc, 0x00, 0x0f, 0x00, 0x66, 0x00, 0x00, 0x80, 
+-      0x2e, 0x08, 0x5e, 0x40, 0x2e, 0x08, 0x5e, 0x44, 
+-      0x00, 0x00, 0x20, 0xa0, 0x2e, 0x08, 0x7c, 0x44, 
+-      0x66, 0x00, 0x01, 0xf0, 0xff, 0xff, 0x00, 0x00, 
+-      0xb5, 0xff, 0x98, 0x00, 0x06, 0x01, 0x0e, 0x09, 
+-      0x98, 0x01, 0x06, 0x02, 0x0e, 0x12, 0x98, 0x02, 
+-      0x04, 0x07, 0x0c, 0x3f, 0x9b, 0x03, 0x04, 0x1c, 
+-      0x0c, 0x24, 0x29, 0x20, 0xdb, 0x04, 0x20, 0xa2, 
+-      0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2a, 0x02, 0xd1, 0x0a, 0x00, 0xc8, 0x4b, 0x1f, 
+-      0x68, 0x1b, 0x58, 0x18, 0x4b, 0x1e, 0x40, 0x18, 
+-      0x00, 0xcb, 0x4d, 0x1c, 0x68, 0x2d, 0x50, 0xe8, 
+-      0xe0, 0x30, 0x2a, 0x01, 0xd1, 0x0b, 0x00, 0xc8, 
+-      0x4b, 0x18, 0x68, 0x1b, 0x58, 0x18, 0x43, 0x27, 
+-      0x1c, 0x3b, 0x43, 0x18, 0x00, 0xcb, 0x4d, 0x15, 
+-      0x68, 0x2d, 0x50, 0xe8, 0xe0, 0x22, 0x20, 0x00, 
+-      0x28, 0x20, 0xdb, 0x04, 0xe0, 0x1e, 0x1c, 0x43, 
+-      0x06, 0x1b, 0x16, 0x18, 0xe7, 0xf8, 0x2a, 0x03, 
+-      0xd1, 0x0b, 0x00, 0xc3, 0x4d, 0x0d, 0x68, 0x2d, 
+-      0x58, 0xeb, 0x1c, 0x3d, 0x43, 0x25, 0x43, 0x1d, 
+-      0x00, 0xc3, 0x4e, 0x0a, 0x68, 0x36, 0x50, 0xf5, 
+-      0xe0, 0x0b, 0x2a, 0x04, 0xd1, 0x09, 0x00, 0xc3, 
+-      0x4d, 0x06, 0x68, 0x2d, 0x58, 0xed, 0x4b, 0x06, 
+-      0x40, 0x2b, 0x00, 0xc5, 0x4e, 0x03, 0x68, 0x36, 
+-      0x51, 0x73, 0xe7, 0xe0, 0x20, 0x00, 0xe7, 0xbb, 
+-      0xe7, 0xba, 0x00, 0x00, 0x2e, 0x08, 0x5d, 0xd0, 
+-      0xff, 0xff, 0xe1, 0xff, 0xb4, 0xb0, 0x1c, 0x07, 
+-      0x1c, 0x0a, 0x06, 0x38, 0x0e, 0x00, 0x06, 0x11, 
+-      0x0e, 0x09, 0x4c, 0x14, 0x68, 0x25, 0x4b, 0x14, 
+-      0x40, 0x2b, 0x60, 0x23, 0x28, 0x01, 0xd1, 0x06, 
+-      0x4c, 0x10, 0x68, 0x25, 0x23, 0x01, 0x04, 0x1b, 
+-      0x43, 0x2b, 0x60, 0x23, 0xe0, 0x07, 0x28, 0x00, 
+-      0xd1, 0x05, 0x4c, 0x0c, 0x68, 0x25, 0x23, 0x01, 
+-      0x05, 0x9b, 0x43, 0x2b, 0x60, 0x23, 0x29, 0x01, 
+-      0xd1, 0x06, 0x4c, 0x08, 0x68, 0x25, 0x23, 0x01, 
+-      0x03, 0x9b, 0x43, 0x2b, 0x60, 0x23, 0xe0, 0x07, 
+-      0x29, 0x02, 0xd1, 0x05, 0x4c, 0x03, 0x68, 0x25, 
+-      0x23, 0x01, 0x03, 0xdb, 0x43, 0x2b, 0x60, 0x23, 
+-      0xbc, 0xb0, 0x47, 0x70, 0x64, 0x00, 0x00, 0x24, 
+-      0xff, 0xbe, 0x3f, 0xff, 0xb5, 0xff, 0x1c, 0x1f, 
+-      0x9c, 0x09, 0xb0, 0x82, 0x98, 0x02, 0x04, 0x00, 
+-      0x0c, 0x00, 0x90, 0x00, 0x99, 0x03, 0x06, 0x0a, 
+-      0x0e, 0x12, 0x98, 0x04, 0x06, 0x05, 0x0e, 0x2d, 
+-      0x98, 0x0c, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x01, 
+-      0x00, 0xd0, 0x1a, 0x80, 0x00, 0x80, 0x4b, 0x1b, 
+-      0x68, 0x1b, 0x18, 0xc1, 0x2a, 0x20, 0xdb, 0x05, 
+-      0x20, 0xa2, 0xb0, 0x02, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2d, 0x1f, 0xdb, 0x02, 
+-      0x20, 0xaf, 0xb0, 0x02, 0xe7, 0xf6, 0x71, 0x8d, 
+-      0x68, 0x3b, 0x00, 0xd0, 0x4e, 0x12, 0x68, 0x36, 
+-      0x19, 0x80, 0x60, 0x43, 0x1c, 0x20, 0x71, 0xc8, 
+-      0x20, 0x00, 0x80, 0x88, 0x20, 0x00, 0x60, 0xc8, 
+-      0x98, 0x00, 0x23, 0x01, 0x43, 0x18, 0x75, 0x08, 
+-      0x98, 0x01, 0x74, 0x88, 0x60, 0x8f, 0x88, 0xb8, 
+-      0x82, 0x08, 0x20, 0x00, 0x74, 0xc8, 0x88, 0xb8, 
+-      0x61, 0x38, 0x20, 0x00, 0x73, 0x38, 0x20, 0x00, 
+-      0x73, 0x78, 0x20, 0x00, 0x73, 0xb8, 0x20, 0x00, 
+-      0x73, 0xf8, 0x20, 0x00, 0xb0, 0x02, 0xe7, 0xd1, 
+-      0xb0, 0x02, 0xe7, 0xcf, 0x2e, 0x08, 0x5d, 0xc4, 
+-      0x2e, 0x08, 0x5d, 0xd4, 0xb5, 0xf3, 0x98, 0x00, 
+-      0x06, 0x04, 0x0e, 0x24, 0x99, 0x01, 0x04, 0x0d, 
+-      0x0c, 0x2d, 0x00, 0xe0, 0x1b, 0x00, 0x00, 0x80, 
+-      0x49, 0x25, 0x68, 0x09, 0x18, 0x47, 0x2c, 0x20, 
+-      0xdb, 0x04, 0x20, 0xa2, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x4b, 0x21, 0x42, 0x9d, 
+-      0xd1, 0x27, 0x00, 0xe1, 0x4b, 0x20, 0x68, 0x1b, 
+-      0x18, 0xc8, 0x00, 0xa1, 0x4b, 0x1f, 0x68, 0x1b, 
+-      0x18, 0xca, 0x68, 0x11, 0x4b, 0x1e, 0x40, 0x19, 
+-      0x60, 0x11, 0x68, 0x01, 0x23, 0x40, 0x40, 0x19, 
+-      0xd0, 0x13, 0x68, 0x01, 0x23, 0x40, 0x43, 0xdb, 
+-      0x40, 0x19, 0x60, 0x01, 0x21, 0x00, 0x4b, 0x19, 
+-      0x68, 0x1b, 0x70, 0x19, 0x49, 0x18, 0x68, 0x0b, 
+-      0x08, 0x5b, 0x00, 0x5b, 0x60, 0x0b, 0x49, 0x17, 
+-      0x68, 0x0e, 0x23, 0x01, 0x05, 0x5b, 0x43, 0x33, 
+-      0x60, 0x0b, 0x68, 0x01, 0x4b, 0x14, 0x40, 0x19, 
+-      0x60, 0x01, 0x20, 0x00, 0x75, 0x38, 0x20, 0x00, 
+-      0x80, 0x38, 0x20, 0x00, 0x80, 0xb8, 0x68, 0xb8, 
+-      0x72, 0x44, 0x20, 0xa0, 0x68, 0xb9, 0x72, 0x08, 
+-      0x20, 0x00, 0x60, 0xb8, 0x79, 0xb9, 0x20, 0x01, 
+-      0x40, 0x88, 0xf0, 0x11, 0xf9, 0xe5, 0x20, 0x00, 
+-      0x71, 0xb8, 0x20, 0x00, 0xe7, 0xba, 0xe7, 0xb9, 
+-      0x2e, 0x08, 0x5d, 0xc4, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x5d, 0xd0, 0x2e, 0x08, 0x5d, 0xcc, 
+-      0xff, 0xff, 0xdf, 0xff, 0x2e, 0x08, 0x5d, 0xc0, 
+-      0x6a, 0x00, 0x00, 0x18, 0x6c, 0x00, 0x00, 0x20, 
+-      0xff, 0xff, 0x3f, 0xde, 0xb5, 0xff, 0x1c, 0x05, 
+-      0x1c, 0x0c, 0x1c, 0x17, 0x06, 0x28, 0x0e, 0x00, 
+-      0x06, 0x23, 0x0e, 0x1b, 0x06, 0x39, 0x0e, 0x09, 
+-      0x9e, 0x03, 0x06, 0x36, 0x16, 0x32, 0x28, 0x20, 
+-      0xda, 0x02, 0x4e, 0x08, 0x68, 0x36, 0x60, 0x30, 
+-      0x4e, 0x07, 0x68, 0x36, 0x60, 0x33, 0x4e, 0x07, 
+-      0x68, 0x36, 0x60, 0x31, 0x4e, 0x06, 0x68, 0x36, 
+-      0x60, 0x32, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x5d, 0xec, 
+-      0x2e, 0x08, 0x5d, 0xf0, 0x2e, 0x08, 0x5d, 0xf4, 
+-      0x2e, 0x08, 0x5d, 0xf8, 0x1c, 0x01, 0x06, 0x08, 
+-      0x0e, 0x00, 0x28, 0x01, 0xd1, 0x04, 0x22, 0x01, 
+-      0x4b, 0x04, 0x68, 0x1b, 0x60, 0x1a, 0xe0, 0x03, 
+-      0x22, 0x02, 0x4b, 0x02, 0x68, 0x1b, 0x60, 0x1a, 
+-      0x47, 0x70, 0x00, 0x00, 0x2e, 0x08, 0x5e, 0x34, 
+-      0xb5, 0xf1, 0x98, 0x00, 0x06, 0x04, 0x0e, 0x24, 
+-      0xb0, 0x81, 0x27, 0x00, 0x26, 0x00, 0x4a, 0x55, 
+-      0x92, 0x00, 0x00, 0xe0, 0x49, 0x54, 0x68, 0x09, 
+-      0x58, 0x08, 0x23, 0x03, 0x03, 0x9b, 0x40, 0x18, 
+-      0x23, 0x01, 0x03, 0x9b, 0x42, 0x98, 0xd0, 0x05, 
+-      0x20, 0xa0, 0xb0, 0x01, 0xb0, 0x01, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0xe0, 0x49, 0x4c, 
+-      0x68, 0x09, 0x58, 0x08, 0x21, 0x20, 0x43, 0x01, 
+-      0x00, 0xe0, 0x4a, 0x49, 0x68, 0x12, 0x50, 0x11, 
+-      0x21, 0x00, 0x48, 0x48, 0xf0, 0x05, 0xfc, 0x3c, 
+-      0x48, 0x47, 0x68, 0x00, 0x28, 0x00, 0xd1, 0x01, 
+-      0xe0, 0x08, 0xe0, 0x82, 0x20, 0x02, 0xf0, 0x0c, 
+-      0xf8, 0x75, 0x1c, 0x38, 0x37, 0x01, 0x4b, 0x43, 
+-      0x42, 0x98, 0xd3, 0xf1, 0x4b, 0x41, 0x42, 0x9f, 
+-      0xd3, 0x00, 0x26, 0xa1, 0x48, 0x40, 0x68, 0x01, 
+-      0x4b, 0x40, 0x40, 0x19, 0x60, 0x01, 0x20, 0x00, 
+-      0x00, 0xe1, 0x1b, 0x09, 0x00, 0x89, 0x4a, 0x3e, 
+-      0x68, 0x12, 0x18, 0x89, 0x70, 0x88, 0x20, 0x00, 
+-      0x43, 0xc0, 0x49, 0x3c, 0x67, 0x48, 0x22, 0x00, 
+-      0xb4, 0x04, 0x1c, 0x20, 0x23, 0x00, 0x22, 0x00, 
+-      0x49, 0x39, 0xf7, 0xff, 0xfc, 0x69, 0xb0, 0x01, 
+-      0x27, 0x00, 0x25, 0x00, 0x2d, 0x04, 0xdb, 0x02, 
+-      0xe0, 0x1e, 0x35, 0x01, 0xe7, 0xfa, 0x00, 0xa9, 
+-      0x22, 0x0f, 0x1c, 0x10, 0x40, 0x88, 0x01, 0x29, 
+-      0x9a, 0x00, 0x18, 0x89, 0x68, 0x49, 0x42, 0xa1, 
+-      0xd1, 0x11, 0x21, 0x33, 0x06, 0x49, 0x6b, 0xc9, 
+-      0x40, 0x01, 0xd0, 0x01, 0x37, 0x01, 0xe0, 0x00, 
+-      0xe0, 0x02, 0x4b, 0x26, 0x42, 0x9f, 0xd3, 0xf4, 
+-      0x4b, 0x24, 0x42, 0x9f, 0xd3, 0x02, 0x26, 0xa1, 
+-      0xe0, 0x02, 0xe0, 0x3a, 0x27, 0x00, 0xe7, 0xe0, 
+-      0x48, 0x26, 0x68, 0x01, 0x23, 0xff, 0x33, 0x01, 
+-      0x43, 0x19, 0x60, 0x01, 0x48, 0x21, 0x6d, 0x80, 
+-      0x49, 0x20, 0x65, 0x88, 0x48, 0x1f, 0x6b, 0xc0, 
+-      0x23, 0x01, 0x07, 0x9b, 0x40, 0x18, 0xd0, 0x00, 
+-      0xe7, 0xf8, 0x20, 0x33, 0x06, 0x40, 0x6d, 0x40, 
+-      0x21, 0x33, 0x06, 0x49, 0x66, 0x48, 0x20, 0x33, 
+-      0x06, 0x40, 0x6d, 0x80, 0x21, 0x33, 0x06, 0x49, 
+-      0x66, 0x88, 0x20, 0x03, 0x02, 0x00, 0x49, 0x15, 
+-      0x67, 0x48, 0x48, 0x11, 0x68, 0x01, 0x23, 0x01, 
+-      0x02, 0x5b, 0x43, 0x19, 0x60, 0x01, 0x20, 0x00, 
+-      0x49, 0x13, 0x65, 0x88, 0x20, 0x00, 0x49, 0x12, 
+-      0x65, 0xc8, 0x20, 0x00, 0x49, 0x10, 0x66, 0x08, 
+-      0x21, 0x00, 0x20, 0xff, 0xf0, 0x05, 0xfb, 0xb8, 
+-      0x1c, 0x30, 0xb0, 0x01, 0xe7, 0x66, 0xb0, 0x01, 
+-      0xe7, 0x64, 0xe7, 0x63, 0x9e, 0x00, 0x00, 0xc0, 
+-      0x2e, 0x08, 0x5d, 0xd0, 0x00, 0x00, 0x80, 0x0f, 
+-      0xcc, 0x00, 0x05, 0x00, 0x00, 0x1e, 0x84, 0x80, 
+-      0x66, 0x00, 0x00, 0x4c, 0xff, 0xff, 0xfd, 0xff, 
+-      0x2e, 0x08, 0x5d, 0xc4, 0x66, 0x00, 0x00, 0x80, 
+-      0x00, 0x00, 0xff, 0xff, 0x66, 0x00, 0x00, 0xe0, 
+-      0xcc, 0x00, 0x00, 0x00, 0xb5, 0xf1, 0x98, 0x00, 
+-      0x06, 0x07, 0x0e, 0x3f, 0xb0, 0x81, 0x25, 0x00, 
+-      0x26, 0x00, 0x4a, 0x2e, 0x92, 0x00, 0x00, 0xf8, 
+-      0x49, 0x2d, 0x68, 0x09, 0x58, 0x08, 0x23, 0x03, 
+-      0x03, 0x9b, 0x40, 0x18, 0x23, 0x01, 0x03, 0xdb, 
+-      0x42, 0x98, 0xd0, 0x05, 0x20, 0xa0, 0xb0, 0x01, 
+-      0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x22, 0x00, 0xb4, 0x04, 0x1c, 0x38, 0x23, 0x00, 
+-      0x22, 0x00, 0x49, 0x24, 0xf7, 0xff, 0xfb, 0xd0, 
+-      0xb0, 0x01, 0x24, 0x00, 0x2c, 0x04, 0xdb, 0x02, 
+-      0xe0, 0x1e, 0x34, 0x01, 0xe7, 0xfa, 0x00, 0xa1, 
+-      0x22, 0x0f, 0x1c, 0x10, 0x40, 0x88, 0x01, 0x21, 
+-      0x9a, 0x00, 0x18, 0x89, 0x68, 0x49, 0x42, 0xb9, 
+-      0xd1, 0x11, 0x21, 0x33, 0x06, 0x49, 0x6b, 0xc9, 
+-      0x40, 0x01, 0xd0, 0x01, 0x35, 0x01, 0xe0, 0x00, 
+-      0xe0, 0x02, 0x4b, 0x17, 0x42, 0x9d, 0xd3, 0xf4, 
+-      0x4b, 0x15, 0x42, 0x9d, 0xd9, 0x02, 0x26, 0xa1, 
+-      0xe0, 0x02, 0xe0, 0x1d, 0x25, 0x00, 0xe7, 0xe0, 
+-      0x20, 0x04, 0xf0, 0x02, 0xff, 0xb7, 0x20, 0x01, 
+-      0x21, 0x33, 0x06, 0x49, 0x66, 0xc8, 0x21, 0x00, 
+-      0x00, 0xf8, 0x4a, 0x0b, 0x68, 0x12, 0x50, 0x11, 
+-      0x21, 0x00, 0x00, 0xf8, 0x4a, 0x08, 0x68, 0x12, 
+-      0x18, 0x80, 0x60, 0x41, 0x21, 0x00, 0x00, 0xb8, 
+-      0x4a, 0x08, 0x68, 0x12, 0x50, 0x11, 0x1c, 0x30, 
+-      0xb0, 0x01, 0xe7, 0xb5, 0xb0, 0x01, 0xe7, 0xb3, 
+-      0xe7, 0xb2, 0x00, 0x00, 0x9e, 0x00, 0x00, 0xc0, 
+-      0x2e, 0x08, 0x5d, 0xd0, 0x00, 0x00, 0xff, 0xff, 
+-      0x00, 0x01, 0xd4, 0xc0, 0x2e, 0x08, 0x5d, 0xcc, 
+-      0xb5, 0xff, 0x99, 0x01, 0x06, 0x0f, 0x0e, 0x3f, 
+-      0x9a, 0x02, 0x06, 0x15, 0x0e, 0x2d, 0x9b, 0x03, 
+-      0x06, 0x1e, 0x0e, 0x36, 0x2d, 0x1f, 0xdb, 0x04, 
+-      0x20, 0xaf, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x2f, 0x20, 0xdb, 0x01, 0x20, 0xa2, 
+-      0xe7, 0xf7, 0x2e, 0x80, 0xd0, 0x13, 0xf0, 0x11, 
+-      0xf8, 0x89, 0x1c, 0x04, 0x1c, 0x39, 0x22, 0x80, 
+-      0x20, 0x01, 0xf0, 0x00, 0xfb, 0x6d, 0x2c, 0x80, 
+-      0xd0, 0x01, 0xf0, 0x11, 0xf8, 0xb5, 0x98, 0x00, 
+-      0x21, 0x80, 0x68, 0x49, 0x60, 0x08, 0x48, 0x09, 
+-      0x68, 0x00, 0x70, 0x05, 0xe0, 0x0b, 0xf0, 0x11, 
+-      0xf8, 0x75, 0x1c, 0x04, 0x1c, 0x39, 0x22, 0x80, 
+-      0x20, 0x02, 0xf0, 0x00, 0xfb, 0x59, 0x2c, 0x80, 
+-      0xd0, 0x01, 0xf0, 0x11, 0xf8, 0xa1, 0x20, 0x00, 
+-      0xe7, 0xd3, 0xe7, 0xd2, 0x2e, 0x08, 0x5e, 0x1c, 
+-      0xb5, 0xff, 0x99, 0x01, 0x06, 0x0e, 0x0e, 0x36, 
+-      0x9a, 0x02, 0x06, 0x17, 0x0e, 0x3f, 0x9b, 0x03, 
+-      0x06, 0x1c, 0x0e, 0x24, 0xb0, 0x82, 0x20, 0x80, 
+-      0x40, 0x38, 0x90, 0x00, 0x06, 0x7f, 0x0e, 0x7f, 
+-      0x2e, 0x1f, 0xdb, 0x05, 0x20, 0xaf, 0xb0, 0x02, 
+-      0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2c, 0x20, 0xdb, 0x02, 0x20, 0xa2, 0xb0, 0x02, 
+-      0xe7, 0xf6, 0x2f, 0x04, 0xd1, 0x00, 0x27, 0x00, 
+-      0x00, 0xe0, 0x1b, 0x00, 0x00, 0x80, 0x49, 0x17, 
+-      0x68, 0x09, 0x18, 0x40, 0x90, 0x01, 0x98, 0x00, 
+-      0x28, 0x00, 0xd0, 0x0d, 0xf0, 0x11, 0xf8, 0x3a, 
+-      0x1c, 0x05, 0x1c, 0x21, 0x22, 0x01, 0x02, 0x92, 
+-      0x20, 0x02, 0xf0, 0x00, 0xfb, 0x1d, 0x2d, 0x80, 
+-      0xd0, 0x01, 0xf0, 0x11, 0xf8, 0x65, 0xe0, 0x13, 
+-      0xf0, 0x11, 0xf8, 0x2c, 0x1c, 0x05, 0x1c, 0x21, 
+-      0x22, 0x01, 0x02, 0x92, 0x20, 0x01, 0xf0, 0x00, 
+-      0xfb, 0x0f, 0x2d, 0x80, 0xd0, 0x01, 0xf0, 0x11, 
+-      0xf8, 0x57, 0x98, 0x02, 0x21, 0x80, 0x68, 0x89, 
+-      0x60, 0x08, 0x20, 0x80, 0x6a, 0x00, 0x55, 0xc6, 
+-      0x20, 0x00, 0xb0, 0x02, 0xe7, 0xc4, 0xb0, 0x02, 
+-      0xe7, 0xc2, 0x00, 0x00, 0x2e, 0x08, 0x5d, 0xc4, 
+-      0xb5, 0xff, 0xb0, 0x82, 0x99, 0x03, 0x04, 0x0d, 
+-      0x0c, 0x2d, 0x9a, 0x04, 0x06, 0x10, 0x0e, 0x00, 
+-      0x90, 0x00, 0x9b, 0x05, 0x06, 0x18, 0x0e, 0x00, 
+-      0x90, 0x01, 0x98, 0x00, 0x28, 0x1f, 0xdb, 0x05, 
+-      0x20, 0xaf, 0xb0, 0x02, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x98, 0x01, 0x23, 0x80, 
+-      0x40, 0x18, 0xd1, 0x2f, 0x98, 0x00, 0x49, 0x2c, 
+-      0x68, 0x09, 0x73, 0x08, 0x27, 0x00, 0x2f, 0x20, 
+-      0xdb, 0x04, 0xe0, 0x26, 0x1c, 0x78, 0x06, 0x07, 
+-      0x0e, 0x3f, 0xe7, 0xf8, 0x20, 0x01, 0x40, 0xb8, 
+-      0x99, 0x02, 0x40, 0x08, 0xd0, 0x1c, 0x24, 0x00, 
+-      0x20, 0x40, 0x40, 0x28, 0xd0, 0x04, 0x04, 0x20, 
+-      0x0c, 0x00, 0x24, 0x01, 0x03, 0xa4, 0x43, 0x04, 
+-      0x20, 0x80, 0x40, 0x28, 0xd0, 0x04, 0x04, 0x20, 
+-      0x0c, 0x00, 0x24, 0x01, 0x03, 0xe4, 0x43, 0x04, 
+-      0xf0, 0x10, 0xff, 0xd4, 0x1c, 0x06, 0x1c, 0x22, 
+-      0x1c, 0x39, 0x20, 0x01, 0xf0, 0x00, 0xfa, 0xb8, 
+-      0x2e, 0x80, 0xd0, 0x01, 0xf0, 0x11, 0xf8, 0x00, 
+-      0xe7, 0xd8, 0xe0, 0x24, 0x27, 0x00, 0x2f, 0x20, 
+-      0xdb, 0x04, 0xe0, 0x20, 0x1c, 0x78, 0x06, 0x07, 
+-      0x0e, 0x3f, 0xe7, 0xf8, 0x20, 0x01, 0x40, 0xb8, 
+-      0x99, 0x02, 0x40, 0x08, 0xd0, 0x16, 0x24, 0x00, 
+-      0x20, 0x40, 0x40, 0x28, 0xd0, 0x01, 0x4b, 0x0d, 
+-      0x40, 0x1c, 0x20, 0x80, 0x40, 0x28, 0xd0, 0x01, 
+-      0x04, 0x64, 0x0c, 0x64, 0xf0, 0x10, 0xff, 0xae, 
+-      0x1c, 0x06, 0x1c, 0x22, 0x1c, 0x39, 0x20, 0x02, 
+-      0xf0, 0x00, 0xfa, 0x92, 0x2e, 0x80, 0xd0, 0x01, 
+-      0xf0, 0x10, 0xff, 0xda, 0xe7, 0xde, 0x20, 0x00, 
+-      0xb0, 0x02, 0xe7, 0x9f, 0xb0, 0x02, 0xe7, 0x9d, 
+-      0x2e, 0x08, 0x5e, 0x10, 0x00, 0x00, 0xbf, 0xff, 
+-      0xb5, 0x80, 0x1c, 0x07, 0x48, 0x07, 0x68, 0x01, 
+-      0x20, 0x00, 0xf0, 0x19, 0xfe, 0x73, 0x60, 0x38, 
+-      0x48, 0x04, 0x68, 0x00, 0x1d, 0x01, 0x20, 0x00, 
+-      0xf0, 0x19, 0xfe, 0x6c, 0x60, 0x78, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x5e, 0x10, 
+-      0xb5, 0xf7, 0x1c, 0x07, 0x99, 0x01, 0x06, 0x0e, 
+-      0x0e, 0x36, 0x9a, 0x02, 0x06, 0x14, 0x0e, 0x24, 
+-      0x2e, 0x1f, 0xdb, 0x04, 0x20, 0xaf, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x2c, 0x20, 
+-      0xdb, 0x01, 0x20, 0xa2, 0xe7, 0xf7, 0x20, 0x80, 
+-      0x40, 0x20, 0xd0, 0x0d, 0xf0, 0x10, 0xff, 0x6e, 
+-      0x1c, 0x05, 0x1c, 0x21, 0x22, 0x01, 0x02, 0xd2, 
+-      0x20, 0x02, 0xf0, 0x00, 0xfa, 0x51, 0x2d, 0x80, 
+-      0xd0, 0x01, 0xf0, 0x10, 0xff, 0x99, 0xe0, 0x16, 
+-      0x48, 0x0c, 0x68, 0x00, 0x60, 0x07, 0x48, 0x0b, 
+-      0x68, 0x00, 0x71, 0x46, 0x20, 0xff, 0x49, 0x09, 
+-      0x68, 0x09, 0x71, 0x08, 0xf0, 0x10, 0xff, 0x56, 
+-      0x1c, 0x05, 0x1c, 0x21, 0x22, 0x01, 0x02, 0xd2, 
+-      0x20, 0x01, 0xf0, 0x00, 0xfa, 0x39, 0x2d, 0x80, 
+-      0xd0, 0x01, 0xf0, 0x10, 0xff, 0x81, 0x20, 0x00, 
+-      0xe7, 0xcd, 0xe7, 0xcc, 0x2e, 0x08, 0x5e, 0x14, 
+-      0xb5, 0xf7, 0x1c, 0x07, 0x99, 0x01, 0x06, 0x0e, 
+-      0x0e, 0x36, 0x9a, 0x02, 0x06, 0x14, 0x0e, 0x24, 
+-      0x2e, 0x1f, 0xdb, 0x04, 0x20, 0xaf, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x2c, 0x20, 
+-      0xdb, 0x01, 0x20, 0xa2, 0xe7, 0xf7, 0x20, 0x80, 
+-      0x40, 0x20, 0xd0, 0x0d, 0xf0, 0x10, 0xff, 0x2e, 
+-      0x1c, 0x05, 0x1c, 0x21, 0x22, 0x01, 0x03, 0x12, 
+-      0x20, 0x02, 0xf0, 0x00, 0xfa, 0x11, 0x2d, 0x80, 
+-      0xd0, 0x01, 0xf0, 0x10, 0xff, 0x59, 0xe0, 0x16, 
+-      0x48, 0x0c, 0x68, 0x00, 0x60, 0x07, 0x48, 0x0b, 
+-      0x68, 0x00, 0x71, 0x46, 0x20, 0xff, 0x49, 0x09, 
+-      0x68, 0x09, 0x71, 0x08, 0xf0, 0x10, 0xff, 0x16, 
+-      0x1c, 0x05, 0x1c, 0x21, 0x22, 0x01, 0x03, 0x12, 
+-      0x20, 0x01, 0xf0, 0x00, 0xf9, 0xf9, 0x2d, 0x80, 
+-      0xd0, 0x01, 0xf0, 0x10, 0xff, 0x41, 0x20, 0x00, 
+-      0xe7, 0xcd, 0xe7, 0xcc, 0x2e, 0x08, 0x5e, 0x18, 
+-      0xb5, 0xff, 0xb0, 0x81, 0x98, 0x01, 0x06, 0x00, 
+-      0x0e, 0x00, 0x90, 0x00, 0x99, 0x02, 0x06, 0x0d, 
+-      0x0e, 0x2d, 0x9a, 0x03, 0x06, 0x16, 0x0e, 0x36, 
+-      0x9f, 0x04, 0x1c, 0x29, 0x98, 0x00, 0xf0, 0x00, 
+-      0xf8, 0x91, 0x28, 0x00, 0xd0, 0x05, 0x20, 0xa2, 
+-      0xb0, 0x01, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x79, 0x38, 0x79, 0x79, 0x18, 0x40, 
+-      0x79, 0xb9, 0x18, 0x40, 0x06, 0x04, 0x0e, 0x24, 
+-      0x79, 0xb8, 0x02, 0x00, 0x43, 0x04, 0x00, 0x68, 
+-      0x19, 0x80, 0x01, 0x00, 0x49, 0x15, 0x68, 0x09, 
+-      0x50, 0x0c, 0x9b, 0x04, 0x88, 0x99, 0x00, 0x68, 
+-      0x19, 0x80, 0x01, 0x00, 0x4a, 0x11, 0x68, 0x12, 
+-      0x18, 0x80, 0x60, 0x41, 0x78, 0x78, 0x78, 0x39, 
+-      0x18, 0x40, 0x78, 0xb9, 0x18, 0x40, 0x06, 0x04, 
+-      0x0e, 0x24, 0x78, 0xb8, 0x02, 0x00, 0x43, 0x04, 
+-      0x00, 0x68, 0x19, 0x80, 0x01, 0x00, 0x49, 0x09, 
+-      0x68, 0x09, 0x18, 0x40, 0x60, 0x84, 0x9b, 0x04, 
+-      0x88, 0x19, 0x00, 0x68, 0x19, 0x80, 0x01, 0x00, 
+-      0x4a, 0x04, 0x68, 0x12, 0x18, 0x80, 0x60, 0xc1, 
+-      0x20, 0x00, 0xb0, 0x01, 0xe7, 0xc5, 0xb0, 0x01, 
+-      0xe7, 0xc3, 0x00, 0x00, 0x2e, 0x08, 0x5d, 0xc8, 
+-      0xb5, 0xff, 0x1c, 0x07, 0x06, 0x3d, 0x0e, 0x2d, 
+-      0x99, 0x01, 0x06, 0x0c, 0x0e, 0x24, 0x9a, 0x02, 
+-      0x06, 0x16, 0x0e, 0x36, 0x1c, 0x21, 0x1c, 0x28, 
+-      0xf0, 0x00, 0xf8, 0x40, 0x28, 0x00, 0xd0, 0x04, 
+-      0x20, 0xa2, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x9a, 0x03, 0x1c, 0x31, 0x1c, 0x20, 
+-      0xf0, 0x00, 0xf8, 0x02, 0xe7, 0xf5, 0xe7, 0xf4, 
+-      0xb4, 0xf0, 0x1c, 0x04, 0x1c, 0x0f, 0x1c, 0x13, 
+-      0x06, 0x21, 0x0e, 0x09, 0x06, 0x3a, 0x0e, 0x12, 
+-      0x29, 0x10, 0xdb, 0x02, 0x20, 0xa2, 0xbc, 0xf0, 
+-      0x47, 0x70, 0x88, 0xdd, 0x00, 0x48, 0x18, 0x80, 
+-      0x01, 0x00, 0x4e, 0x0f, 0x68, 0x36, 0x50, 0x35, 
+-      0x88, 0x98, 0x00, 0x4d, 0x18, 0xad, 0x01, 0x2d, 
+-      0x4e, 0x0b, 0x68, 0x36, 0x19, 0xad, 0x60, 0x68, 
+-      0x88, 0x58, 0x00, 0x4d, 0x18, 0xad, 0x01, 0x2d, 
+-      0x4e, 0x07, 0x68, 0x36, 0x19, 0xad, 0x60, 0xa8, 
+-      0x88, 0x18, 0x00, 0x4d, 0x18, 0xad, 0x01, 0x2d, 
+-      0x4e, 0x03, 0x68, 0x36, 0x19, 0xad, 0x60, 0xe8, 
+-      0x20, 0x00, 0xe7, 0xdc, 0xe7, 0xdb, 0x00, 0x00, 
+-      0x2e, 0x08, 0x5d, 0xc8, 0xb4, 0xb0, 0x1c, 0x07, 
+-      0x1c, 0x0a, 0x06, 0x39, 0x0e, 0x09, 0x06, 0x15, 
+-      0x0e, 0x2d, 0xb0, 0x81, 0x29, 0x20, 0xdb, 0x03, 
+-      0x20, 0xa2, 0xb0, 0x01, 0xbc, 0xb0, 0x47, 0x70, 
+-      0x2d, 0x10, 0xdb, 0x02, 0x20, 0xa2, 0xb0, 0x01, 
+-      0xe7, 0xf8, 0x00, 0xc8, 0x4b, 0x0a, 0x68, 0x1b, 
+-      0x18, 0xc4, 0x68, 0x20, 0x90, 0x00, 0x98, 0x00, 
+-      0x4b, 0x08, 0x40, 0x18, 0x90, 0x00, 0x00, 0x68, 
+-      0x23, 0x1e, 0x40, 0x18, 0x9b, 0x00, 0x43, 0x18, 
+-      0x90, 0x00, 0x98, 0x00, 0x60, 0x20, 0x20, 0x00, 
+-      0xb0, 0x01, 0xe7, 0xe3, 0xb0, 0x01, 0xe7, 0xe1, 
+-      0x2e, 0x08, 0x5d, 0xd0, 0xff, 0xff, 0xdf, 0xe1, 
+-      0x20, 0xff, 0x49, 0x02, 0x68, 0x09, 0x70, 0x08, 
+-      0x47, 0x70, 0x00, 0x00, 0x2e, 0x08, 0x5e, 0x2c, 
+-      0xb4, 0xb0, 0x1c, 0x07, 0x1c, 0x0a, 0xb0, 0x83, 
+-      0x20, 0x00, 0x43, 0xc0, 0x23, 0x19, 0x06, 0x9b, 
+-      0x67, 0x58, 0x08, 0xb9, 0x00, 0x89, 0x1a, 0x78, 
+-      0x90, 0x02, 0x98, 0x02, 0x18, 0x10, 0x07, 0x80, 
+-      0x0f, 0x80, 0x90, 0x01, 0x98, 0x02, 0x18, 0x10, 
+-      0x08, 0x80, 0x90, 0x00, 0x9b, 0x02, 0x20, 0x03, 
+-      0x1a, 0xc0, 0x23, 0x19, 0x06, 0x9b, 0x67, 0xd8, 
+-      0x24, 0x00, 0x98, 0x00, 0x42, 0x84, 0xd3, 0x02, 
+-      0xe0, 0x06, 0x34, 0x01, 0xe7, 0xf9, 0xc9, 0x08, 
+-      0x20, 0x19, 0x06, 0x80, 0x67, 0x03, 0xe7, 0xf8, 
+-      0x98, 0x01, 0x28, 0x00, 0xd0, 0x0b, 0x9b, 0x01, 
+-      0x00, 0xd8, 0x25, 0x00, 0x43, 0xed, 0x40, 0xc5, 
+-      0x1c, 0x2b, 0x43, 0xdb, 0x68, 0x0d, 0x40, 0x2b, 
+-      0x25, 0x19, 0x06, 0xad, 0x67, 0x2b, 0x20, 0x19, 
+-      0x06, 0x80, 0x6f, 0x40, 0xb0, 0x03, 0xbc, 0xb0, 
+-      0x47, 0x70, 0xb0, 0x03, 0xe7, 0xfb, 0x1c, 0x01, 
+-      0x06, 0x08, 0x0e, 0x00, 0x22, 0x19, 0x06, 0x92, 
+-      0x63, 0x90, 0x47, 0x70, 0xb4, 0xf0, 0x48, 0x4d, 
+-      0x6a, 0x80, 0x07, 0xc0, 0x0f, 0xc0, 0xd0, 0x74, 
+-      0x22, 0x00, 0x27, 0x00, 0x49, 0x4a, 0x20, 0x00, 
+-      0x28, 0x20, 0xdb, 0x04, 0xe0, 0x16, 0x1c, 0x43, 
+-      0x06, 0x18, 0x0e, 0x00, 0xe7, 0xf8, 0x00, 0x83, 
+-      0x58, 0xcc, 0x23, 0x01, 0x03, 0x5b, 0x40, 0x23, 
+-      0xd0, 0x0b, 0x24, 0x01, 0x40, 0x84, 0x1c, 0x23, 
+-      0x43, 0x1f, 0x00, 0x83, 0x58, 0xcc, 0x23, 0x01, 
+-      0x03, 0x5b, 0x43, 0x9c, 0x1c, 0x23, 0x00, 0x84, 
+-      0x51, 0x0b, 0xe7, 0xe8, 0x20, 0x00, 0x28, 0x04, 
+-      0xdb, 0x04, 0xe0, 0x1a, 0x1c, 0x43, 0x06, 0x18, 
+-      0x0e, 0x00, 0xe7, 0xf8, 0x01, 0x05, 0x4b, 0x39, 
+-      0x18, 0xec, 0x22, 0x00, 0x2a, 0x04, 0xdb, 0x04, 
+-      0xe0, 0x0e, 0x1c, 0x53, 0x06, 0x1a, 0x0e, 0x12, 
+-      0xe7, 0xf8, 0x4b, 0x35, 0x60, 0x23, 0x4b, 0x35, 
+-      0x60, 0x63, 0x23, 0x00, 0x60, 0xa3, 0x23, 0x00, 
+-      0x60, 0xe3, 0x34, 0xff, 0x34, 0x01, 0xe7, 0xf0, 
+-      0xe7, 0xe4, 0xb0, 0x82, 0x4b, 0x2b, 0x69, 0xdc, 
+-      0x23, 0x0c, 0x40, 0x23, 0x08, 0x9c, 0xab, 0x01, 
+-      0x70, 0x1c, 0x4b, 0x28, 0x69, 0xdc, 0x23, 0x30, 
+-      0x40, 0x23, 0x09, 0x1c, 0xab, 0x00, 0x70, 0x1c, 
+-      0xab, 0x01, 0x78, 0x1b, 0xac, 0x00, 0x78, 0x24, 
+-      0x42, 0xa3, 0xd1, 0x09, 0x23, 0x33, 0x06, 0x5b, 
+-      0x6b, 0xdb, 0x2b, 0x00, 0xd1, 0x04, 0x4b, 0x1f, 
+-      0x6a, 0x9b, 0x07, 0xdb, 0x0f, 0xdb, 0xd0, 0x21, 
+-      0x4b, 0x1c, 0x69, 0xdd, 0x23, 0x0c, 0x40, 0x2b, 
+-      0x08, 0x9c, 0x00, 0xa5, 0x26, 0x01, 0x40, 0xae, 
+-      0x1c, 0x33, 0x25, 0x33, 0x06, 0x6d, 0x64, 0x2b, 
+-      0x25, 0x01, 0x40, 0xa5, 0x1c, 0x2b, 0x4d, 0x1a, 
+-      0x63, 0xab, 0x4b, 0x14, 0x69, 0xdd, 0x23, 0x0c, 
+-      0x40, 0x2b, 0x08, 0x9d, 0xab, 0x01, 0x70, 0x1d, 
+-      0xe0, 0x00, 0xe0, 0x1d, 0x4b, 0x0f, 0x69, 0xdd, 
+-      0x23, 0x30, 0x40, 0x2b, 0x09, 0x1d, 0xab, 0x00, 
+-      0x70, 0x1d, 0xe7, 0xcd, 0xb0, 0x02, 0x20, 0x00, 
+-      0x28, 0x20, 0xdb, 0x04, 0xe0, 0x10, 0x1c, 0x43, 
+-      0x06, 0x18, 0x0e, 0x00, 0xe7, 0xf8, 0x24, 0x01, 
+-      0x40, 0x84, 0x1c, 0x23, 0x40, 0x3b, 0xd0, 0x06, 
+-      0x00, 0x83, 0x58, 0xcc, 0x23, 0x01, 0x03, 0x5b, 
+-      0x43, 0x23, 0x00, 0x84, 0x51, 0x0b, 0xe7, 0xee, 
+-      0xbc, 0xf0, 0x47, 0x70, 0x66, 0x00, 0x01, 0x00, 
+-      0x64, 0x00, 0x00, 0x80, 0x9e, 0x00, 0x00, 0xc0, 
+-      0x9e, 0x00, 0x00, 0x00, 0x2e, 0x0f, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x80, 0xb4, 0x80, 0x1c, 0x03, 
+-      0x1c, 0x0a, 0x48, 0x0a, 0x68, 0x00, 0x68, 0x01, 
+-      0x20, 0x19, 0x06, 0x80, 0x6a, 0x80, 0x0a, 0x40, 
+-      0x00, 0x4f, 0x43, 0x38, 0x60, 0x18, 0x0f, 0xc8, 
+-      0x07, 0xc0, 0x60, 0x10, 0x68, 0x10, 0x0f, 0xc0, 
+-      0x60, 0x10, 0x20, 0x00, 0xbc, 0x80, 0x47, 0x70, 
+-      0xe7, 0xfc, 0x00, 0x00, 0x2e, 0x08, 0x5e, 0x38, 
+-      0xb5, 0x80, 0x1c, 0x07, 0x48, 0x05, 0x68, 0x00, 
+-      0x1d, 0xc1, 0x31, 0x01, 0x20, 0x00, 0xf0, 0x19, 
+-      0xfb, 0xfd, 0x60, 0x38, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x5e, 0x10, 
+-      0xb4, 0xf0, 0x1c, 0x04, 0x1c, 0x0f, 0x1c, 0x13, 
+-      0x06, 0x20, 0x0e, 0x00, 0x06, 0x39, 0x0e, 0x09, 
+-      0x04, 0x1a, 0x0c, 0x12, 0x4d, 0x07, 0x68, 0x2d, 
+-      0x70, 0xe8, 0x4d, 0x06, 0x68, 0x2d, 0x70, 0xa9, 
+-      0x4d, 0x04, 0x68, 0x2d, 0x80, 0x2a, 0x25, 0x01, 
+-      0x04, 0x2d, 0x26, 0x33, 0x06, 0x76, 0x60, 0x35, 
+-      0xbc, 0xf0, 0x47, 0x70, 0x2e, 0x08, 0x5e, 0x3c, 
+-      0x20, 0x0d, 0x06, 0xc0, 0x69, 0xc0, 0x47, 0x70, 
+-      0xe7, 0xfd, 0x1c, 0x01, 0x31, 0x01, 0x23, 0x2d, 
+-      0x01, 0x1b, 0x42, 0x99, 0xd9, 0x03, 0x20, 0x2d, 
+-      0x01, 0x00, 0x47, 0x70, 0xe0, 0x01, 0x1c, 0x08, 
+-      0xe7, 0xfb, 0xe7, 0xfa, 0xb5, 0xf3, 0xb0, 0x85, 
+-      0x20, 0x00, 0x90, 0x03, 0x20, 0x00, 0x90, 0x02, 
+-      0x9f, 0x05, 0x69, 0x3d, 0x69, 0x38, 0x28, 0x13, 
+-      0xd1, 0x05, 0x20, 0x75, 0xb0, 0x05, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x99, 0x06, 
+-      0x68, 0x88, 0x68, 0x09, 0x1a, 0x40, 0x1c, 0x41, 
+-      0x91, 0x04, 0x69, 0x78, 0x23, 0x04, 0x40, 0x18, 
+-      0xd0, 0x02, 0x99, 0x04, 0x08, 0x49, 0x91, 0x04, 
+-      0x00, 0xa8, 0x49, 0xf8, 0x58, 0x08, 0x99, 0x04, 
+-      0x43, 0x48, 0x61, 0xf8, 0x99, 0x06, 0x68, 0x88, 
+-      0x68, 0x09, 0x1a, 0x40, 0x30, 0x01, 0x63, 0xb8, 
+-      0x68, 0xf8, 0x90, 0x01, 0x48, 0xf2, 0x68, 0x00, 
+-      0x28, 0x00, 0xd0, 0x06, 0x98, 0x01, 0x28, 0x19, 
+-      0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0xe0, 0x05, 0x98, 0x01, 0x28, 0x08, 0xd3, 0x01, 
+-      0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 0x28, 0x00, 
+-      0xd0, 0x07, 0x1d, 0xf8, 0x30, 0x21, 0x99, 0x06, 
+-      0xf0, 0x02, 0xf9, 0xea, 0x20, 0x00, 0xb0, 0x05, 
+-      0xe7, 0xc5, 0x49, 0xe6, 0x20, 0x91, 0xf0, 0x19, 
+-      0xfb, 0x7d, 0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 
+-      0xf0, 0x0b, 0xfb, 0x64, 0xe7, 0xf5, 0x98, 0x01, 
+-      0x00, 0x80, 0x49, 0xe1, 0x58, 0x08, 0x99, 0x05, 
+-      0x42, 0x88, 0xd0, 0x05, 0x20, 0x92, 0x49, 0xdd, 
+-      0x60, 0x08, 0x20, 0xff, 0xb0, 0x05, 0xe7, 0xae, 
+-      0x48, 0xd9, 0x68, 0x00, 0x28, 0x00, 0xd0, 0x03, 
+-      0x2d, 0x0b, 0xdb, 0x26, 0x2d, 0x12, 0xdc, 0x24, 
+-      0x2d, 0x0b, 0xdb, 0x0b, 0x2d, 0x12, 0xdc, 0x09, 
+-      0x48, 0xd6, 0x68, 0x00, 0x28, 0x00, 0xd0, 0x05, 
+-      0x1d, 0xf8, 0x30, 0x21, 0x99, 0x06, 0xf0, 0x02, 
+-      0xf9, 0xbb, 0xe0, 0x16, 0x6b, 0x38, 0xf7, 0xff, 
+-      0xff, 0x7c, 0x90, 0x00, 0x6a, 0xb9, 0x9a, 0x00, 
+-      0x48, 0xcf, 0xf0, 0x0c, 0xfb, 0x4b, 0x1d, 0xf8, 
+-      0x30, 0x21, 0x99, 0x06, 0xf0, 0x02, 0xf9, 0xac, 
+-      0x6b, 0x38, 0xf7, 0xff, 0xff, 0x6e, 0x90, 0x00, 
+-      0x6a, 0xb9, 0x9a, 0x00, 0x48, 0xc8, 0xf0, 0x0c, 
+-      0xfb, 0x6b, 0x48, 0xc8, 0x68, 0x00, 0x99, 0x05, 
+-      0x42, 0x88, 0xd1, 0x30, 0x48, 0xc0, 0x68, 0x00, 
+-      0x28, 0x00, 0xd1, 0x2c, 0x48, 0xc1, 0x68, 0x00, 
+-      0x28, 0x00, 0xd1, 0x0a, 0x20, 0x0d, 0x06, 0xc0, 
+-      0x68, 0xc0, 0x90, 0x02, 0x98, 0x02, 0x28, 0x01, 
+-      0xd1, 0x03, 0x20, 0x00, 0x21, 0x0d, 0x06, 0xc9, 
+-      0x60, 0xc8, 0x48, 0xba, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x0d, 0x6a, 0xb8, 0x30, 0x01, 0x05, 0x00, 
+-      0x6a, 0xf9, 0x31, 0x01, 0x02, 0x89, 0x43, 0x08, 
+-      0x6b, 0x79, 0x31, 0x02, 0x43, 0x08, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x61, 0x88, 0xe0, 0x0b, 0x6a, 0xb8, 
+-      0x30, 0x01, 0x05, 0x00, 0x6a, 0xf9, 0x31, 0x01, 
+-      0x02, 0x89, 0x43, 0x08, 0x6b, 0x79, 0x31, 0x02, 
+-      0x43, 0x08, 0x49, 0xaf, 0x60, 0x08, 0x2d, 0x0b, 
+-      0xdb, 0x15, 0x2d, 0x12, 0xdc, 0x13, 0x48, 0xa9, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x0f, 0x48, 0xa4, 
+-      0x68, 0x00, 0x28, 0x00, 0xd1, 0x0b, 0x20, 0x00, 
+-      0x62, 0xb8, 0x20, 0x00, 0x62, 0xf8, 0x48, 0xa7, 
+-      0x63, 0x38, 0x48, 0xa7, 0x63, 0x78, 0x6b, 0x38, 
+-      0xf7, 0xff, 0xff, 0x1b, 0x90, 0x00, 0x48, 0x9c, 
+-      0x68, 0x00, 0x28, 0x00, 0xd1, 0x16, 0x20, 0x0d, 
+-      0x06, 0xc0, 0x68, 0x80, 0x90, 0x03, 0x20, 0x00, 
+-      0x21, 0x0d, 0x06, 0xc9, 0x60, 0x88, 0xf0, 0x01, 
+-      0xfb, 0x07, 0x6b, 0x38, 0xf7, 0xff, 0xff, 0x09, 
+-      0x90, 0x00, 0x9a, 0x00, 0x99, 0x01, 0x1c, 0x38, 
+-      0xf0, 0x01, 0xfa, 0x8c, 0x98, 0x03, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0x88, 0x48, 0x93, 0x68, 0x00, 
+-      0x99, 0x05, 0x42, 0x88, 0xd1, 0x0b, 0x48, 0x8c, 
+-      0x68, 0x00, 0x28, 0x00, 0xd1, 0x07, 0x48, 0x8d, 
+-      0x68, 0x00, 0x28, 0x00, 0xd1, 0x03, 0x98, 0x02, 
+-      0x21, 0x0d, 0x06, 0xc9, 0x60, 0xc8, 0x48, 0x86, 
+-      0x68, 0x00, 0x28, 0x01, 0xd1, 0x73, 0x48, 0x87, 
+-      0x68, 0x00, 0x28, 0x01, 0xd1, 0x6f, 0xb0, 0x84, 
+-      0x98, 0x05, 0xf0, 0x0c, 0xf9, 0xe1, 0x28, 0x00, 
+-      0xd1, 0x0e, 0x2d, 0x0b, 0xdb, 0x01, 0x2d, 0x12, 
+-      0xdd, 0x0a, 0x1d, 0xf8, 0x30, 0x21, 0x99, 0x0a, 
+-      0xf0, 0x02, 0xf9, 0x12, 0x20, 0x92, 0x49, 0x7b, 
+-      0x60, 0x08, 0x20, 0x00, 0xb0, 0x09, 0xe6, 0xea, 
+-      0x49, 0x80, 0x20, 0x91, 0xf0, 0x19, 0xfa, 0xa2, 
+-      0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 0xf0, 0x0c, 
+-      0xfa, 0x22, 0x20, 0x92, 0x49, 0x7b, 0x60, 0x08, 
+-      0x20, 0x01, 0x49, 0x7b, 0x68, 0x09, 0x60, 0x08, 
+-      0x2d, 0x0b, 0xdb, 0x39, 0x2d, 0x12, 0xdc, 0x37, 
+-      0xb0, 0x81, 0x24, 0x00, 0x20, 0x00, 0x90, 0x03, 
+-      0x20, 0x01, 0x49, 0x75, 0x68, 0x09, 0x23, 0x07, 
+-      0x02, 0x1b, 0x18, 0xc9, 0x66, 0x88, 0x6a, 0xb8, 
+-      0x30, 0x01, 0x05, 0x00, 0x6a, 0xf9, 0x31, 0x01, 
+-      0x02, 0x89, 0x43, 0x08, 0x6b, 0x79, 0x31, 0x02, 
+-      0x43, 0x08, 0x90, 0x00, 0x20, 0x00, 0x62, 0xb8, 
+-      0x20, 0x00, 0x62, 0xf8, 0x48, 0x67, 0x63, 0x38, 
+-      0x48, 0x67, 0x63, 0x78, 0x6b, 0x38, 0xf7, 0xff, 
+-      0xfe, 0x9c, 0x90, 0x02, 0x48, 0x66, 0x68, 0x00, 
+-      0x23, 0x77, 0x01, 0x1b, 0x18, 0xc0, 0x9a, 0x02, 
+-      0x1c, 0x39, 0xf0, 0x0b, 0xfe, 0x05, 0x98, 0x00, 
+-      0x49, 0x61, 0x68, 0x09, 0x23, 0x07, 0x02, 0x1b, 
+-      0x18, 0xc9, 0x66, 0xc8, 0x48, 0x5e, 0x68, 0x00, 
+-      0xf0, 0x0c, 0xf9, 0xf8, 0xb0, 0x01, 0xe1, 0x2b, 
+-      0x24, 0x00, 0x26, 0x00, 0x2e, 0x00, 0xd1, 0x16, 
+-      0x2c, 0x07, 0xd2, 0x14, 0x6a, 0xf8, 0x05, 0x81, 
+-      0x0d, 0x89, 0x1c, 0x20, 0x34, 0x01, 0x00, 0x83, 
+-      0x18, 0x18, 0x00, 0xc0, 0xe0, 0x00, 0xe1, 0x3c, 
+-      0x4a, 0x53, 0x68, 0x12, 0x18, 0x80, 0x23, 0x05, 
+-      0x02, 0x1b, 0x18, 0xc0, 0x6f, 0xc0, 0x42, 0x81, 
+-      0xd1, 0x00, 0x26, 0x01, 0xe7, 0xe6, 0x2e, 0x00, 
+-      0xd1, 0x13, 0x2c, 0x18, 0xd2, 0x11, 0x6a, 0xf8, 
+-      0x05, 0x81, 0x0d, 0x89, 0x1c, 0x20, 0x34, 0x01, 
+-      0x23, 0x4c, 0x43, 0x58, 0x4a, 0x48, 0x68, 0x12, 
+-      0x18, 0x80, 0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 
+-      0x69, 0x40, 0x42, 0x81, 0xd1, 0x00, 0x26, 0x01, 
+-      0xe7, 0xe9, 0x3c, 0x01, 0x6b, 0x38, 0xf7, 0xff, 
+-      0xfe, 0x50, 0x90, 0x01, 0x2c, 0x07, 0xd2, 0x05, 
+-      0x48, 0x3f, 0x68, 0x01, 0x1c, 0x20, 0xf0, 0x0b, 
+-      0xfc, 0xcb, 0xe0, 0x06, 0x2c, 0x18, 0xd2, 0x04, 
+-      0x1f, 0xe0, 0x49, 0x3b, 0x68, 0x09, 0xf0, 0x0b, 
+-      0xfd, 0x01, 0x48, 0x3a, 0x49, 0x38, 0x68, 0x09, 
+-      0x23, 0x09, 0x01, 0xdb, 0x18, 0xc9, 0x66, 0xc8, 
+-      0x48, 0x36, 0x49, 0x35, 0x68, 0x09, 0x23, 0x09, 
+-      0x01, 0xdb, 0x18, 0xc9, 0x67, 0x08, 0x48, 0x33, 
+-      0x49, 0x31, 0x68, 0x09, 0x23, 0x09, 0x01, 0xdb, 
+-      0x18, 0xc9, 0x66, 0x88, 0x48, 0x2f, 0x49, 0x2e, 
+-      0x68, 0x09, 0x23, 0x09, 0x01, 0xdb, 0x18, 0xc9, 
+-      0x66, 0x48, 0x20, 0x00, 0x49, 0x2a, 0x68, 0x09, 
+-      0x23, 0x09, 0x01, 0xdb, 0x18, 0xc9, 0x64, 0x88, 
+-      0x6b, 0x79, 0x48, 0x27, 0x68, 0x00, 0xf0, 0x0b, 
+-      0xfd, 0x4b, 0x94, 0x02, 0x1d, 0xf8, 0x30, 0x21, 
+-      0x99, 0x0a, 0xf0, 0x02, 0xf8, 0x4d, 0x24, 0x00, 
+-      0x26, 0x00, 0x2e, 0x00, 0xd1, 0x14, 0x2c, 0x07, 
+-      0xd2, 0x12, 0x6a, 0xf8, 0x05, 0x81, 0x0d, 0x89, 
+-      0x1c, 0x20, 0x34, 0x01, 0x00, 0x83, 0x18, 0x18, 
+-      0x00, 0xc0, 0x4a, 0x1b, 0x68, 0x12, 0x18, 0x80, 
+-      0x23, 0x05, 0x02, 0x1b, 0x18, 0xc0, 0x6f, 0xc0, 
+-      0x42, 0x81, 0xda, 0x00, 0x26, 0x01, 0xe7, 0xe8, 
+-      0x2e, 0x00, 0xd1, 0x2f, 0x2c, 0x18, 0xd2, 0x2d, 
+-      0x6a, 0xf8, 0x05, 0x81, 0x0d, 0x89, 0x1c, 0x20, 
+-      0x34, 0x01, 0x23, 0x4c, 0x43, 0x58, 0x4a, 0x10, 
+-      0x68, 0x12, 0x18, 0x80, 0x38, 0xff, 0x38, 0xff, 
+-      0x38, 0x02, 0x69, 0x40, 0x42, 0x81, 0xda, 0x1c, 
+-      0xe0, 0x1a, 0x00, 0x00, 0x2e, 0x03, 0x3a, 0x54, 
+-      0x2e, 0x08, 0x94, 0x84, 0x2e, 0x08, 0x7c, 0xc0, 
+-      0x2e, 0x08, 0x7c, 0x58, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x7d, 0x94, 0x2e, 0x08, 0x7c, 0xbc, 
+-      0x2e, 0x08, 0x5e, 0x4c, 0x00, 0x00, 0x02, 0xcf, 
+-      0x00, 0x00, 0x02, 0x3f, 0x2e, 0x08, 0x94, 0x88, 
+-      0x2e, 0x08, 0x7d, 0xb4, 0x00, 0x00, 0xff, 0xff, 
+-      0x26, 0x01, 0xe7, 0xcd, 0x3c, 0x01, 0x6b, 0x38, 
+-      0xf7, 0xff, 0xfd, 0xc3, 0x90, 0x01, 0x2c, 0x07, 
+-      0xd2, 0x12, 0x48, 0x48, 0x68, 0x01, 0x1c, 0x20, 
+-      0xf0, 0x0b, 0xfb, 0xcc, 0x00, 0xa0, 0x19, 0x00, 
+-      0x00, 0xc0, 0x49, 0x44, 0x68, 0x09, 0x18, 0x40, 
+-      0x23, 0x2b, 0x01, 0x5b, 0x18, 0xc0, 0x9a, 0x01, 
+-      0x1c, 0x39, 0xf0, 0x0b, 0xfd, 0x21, 0xe0, 0x4a, 
+-      0x2c, 0x18, 0xd2, 0x48, 0x1f, 0xe0, 0x49, 0x3d, 
+-      0x68, 0x09, 0xf0, 0x0b, 0xfc, 0x0b, 0x20, 0x4c, 
+-      0x43, 0x60, 0x49, 0x3a, 0x68, 0x09, 0x18, 0x40, 
+-      0x38, 0xff, 0x38, 0xff, 0x38, 0x0a, 0x9a, 0x01, 
+-      0x1c, 0x39, 0xf0, 0x0b, 0xfd, 0x0d, 0x20, 0x4c, 
+-      0x43, 0x60, 0x49, 0x34, 0x68, 0x09, 0x18, 0x40, 
+-      0x38, 0xff, 0x38, 0xff, 0x38, 0x82, 0x6f, 0xc0, 
+-      0x28, 0x00, 0xd0, 0x17, 0x20, 0x4c, 0x43, 0x60, 
+-      0x49, 0x2e, 0x68, 0x09, 0x18, 0x40, 0x38, 0xff, 
+-      0x38, 0xff, 0x38, 0x02, 0x68, 0x00, 0x04, 0x00, 
+-      0x0c, 0x00, 0xd0, 0x0b, 0x20, 0x4c, 0x43, 0x60, 
+-      0x49, 0x28, 0x68, 0x09, 0x18, 0x40, 0x38, 0xff, 
+-      0x38, 0xff, 0x38, 0x02, 0x68, 0x00, 0x0c, 0x00, 
+-      0x04, 0x00, 0xd1, 0x0a, 0x20, 0x02, 0x21, 0x4c, 
+-      0x43, 0x61, 0x4a, 0x22, 0x68, 0x12, 0x18, 0x89, 
+-      0x39, 0xff, 0x39, 0xff, 0x39, 0x82, 0x67, 0x48, 
+-      0xe0, 0x09, 0x20, 0x03, 0x21, 0x4c, 0x43, 0x61, 
+-      0x4a, 0x1c, 0x68, 0x12, 0x18, 0x89, 0x39, 0xff, 
+-      0x39, 0xff, 0x39, 0x82, 0x67, 0x48, 0x48, 0x19, 
+-      0x68, 0x00, 0xf0, 0x0c, 0xf8, 0xcf, 0x6b, 0x79, 
+-      0x48, 0x16, 0x68, 0x00, 0xf0, 0x0b, 0xfc, 0x36, 
+-      0x98, 0x02, 0x42, 0x84, 0xda, 0x01, 0x1c, 0x21, 
+-      0xe0, 0x00, 0x99, 0x02, 0x91, 0x00, 0x99, 0x00, 
+-      0x48, 0x10, 0x68, 0x00, 0xf0, 0x0b, 0xfd, 0x46, 
+-      0x49, 0x0f, 0x20, 0x91, 0xf0, 0x19, 0xf9, 0x1e, 
+-      0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 0x48, 0x0b, 
+-      0x68, 0x00, 0x90, 0x03, 0x48, 0x0b, 0x68, 0x00, 
+-      0x49, 0x08, 0x60, 0x08, 0x98, 0x03, 0x49, 0x09, 
+-      0x60, 0x08, 0x20, 0x92, 0x49, 0x06, 0x60, 0x08, 
+-      0xb0, 0x04, 0x20, 0x92, 0x49, 0x06, 0x60, 0x08, 
+-      0x20, 0x00, 0xb0, 0x05, 0xe5, 0x4b, 0xb0, 0x05, 
+-      0xe5, 0x49, 0x00, 0x00, 0x2e, 0x08, 0x7d, 0xb4, 
+-      0x2e, 0x08, 0x94, 0x88, 0x2e, 0x08, 0x7d, 0xb8, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0xb5, 0xff, 0x1c, 0x07, 
+-      0x9d, 0x09, 0xb0, 0x89, 0x26, 0x00, 0x20, 0x00, 
+-      0x90, 0x03, 0x99, 0x0a, 0x68, 0x4c, 0x2d, 0x13, 
+-      0xd1, 0x05, 0x20, 0x75, 0xb0, 0x09, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x98, 0x15, 
+-      0x60, 0x04, 0x20, 0x00, 0x60, 0xe0, 0x20, 0x00, 
+-      0x61, 0x20, 0x69, 0x60, 0x4b, 0xf9, 0x40, 0x18, 
+-      0x61, 0x60, 0x02, 0x00, 0x69, 0x60, 0x4b, 0xf8, 
+-      0x40, 0x18, 0x61, 0x60, 0x04, 0x80, 0x69, 0x60, 
+-      0x4b, 0xf6, 0x40, 0x18, 0x61, 0x60, 0x05, 0x80, 
+-      0x69, 0x60, 0x23, 0xc0, 0x43, 0xdb, 0x40, 0x18, 
+-      0x61, 0x60, 0x06, 0x00, 0x69, 0x60, 0x4b, 0xf2, 
+-      0x40, 0x18, 0x61, 0x60, 0x04, 0x40, 0x69, 0x60, 
+-      0x23, 0x20, 0x43, 0xdb, 0x40, 0x18, 0x61, 0x60, 
+-      0x06, 0x80, 0x69, 0x60, 0x09, 0x40, 0x01, 0x40, 
+-      0x61, 0x60, 0x06, 0xc0, 0x20, 0x00, 0x61, 0xa0, 
+-      0x20, 0x00, 0x61, 0xe0, 0x20, 0x00, 0x62, 0x20, 
+-      0x20, 0x00, 0x62, 0x60, 0x20, 0x00, 0x63, 0xa0, 
+-      0x20, 0x00, 0x63, 0xe0, 0x20, 0x00, 0x64, 0x60, 
+-      0x20, 0x00, 0x64, 0x20, 0x20, 0x00, 0x60, 0x20, 
+-      0x20, 0x00, 0x71, 0x20, 0x99, 0x0a, 0x68, 0x48, 
+-      0x64, 0xe0, 0x99, 0x0a, 0x68, 0x08, 0x64, 0xa0, 
+-      0x1d, 0xe0, 0x30, 0x21, 0x99, 0x13, 0xf0, 0x01, 
+-      0xff, 0x07, 0x2d, 0x0b, 0xdb, 0x06, 0x2d, 0x12, 
+-      0xdc, 0x04, 0x1d, 0xe0, 0x30, 0x49, 0x99, 0x13, 
+-      0xf0, 0x01, 0xfe, 0xfe, 0x6b, 0x20, 0x6a, 0xa1, 
+-      0x1a, 0x40, 0x30, 0x01, 0x63, 0xa0, 0x00, 0xa8, 
+-      0x49, 0xd4, 0x58, 0x08, 0x69, 0x61, 0x09, 0x49, 
+-      0x01, 0x49, 0x06, 0xc0, 0x0e, 0xc0, 0x43, 0x08, 
+-      0x61, 0x60, 0x06, 0xc0, 0x0e, 0xc0, 0x6b, 0x20, 
+-      0x6a, 0xa1, 0x1a, 0x40, 0x1c, 0x41, 0x91, 0x04, 
+-      0x69, 0x60, 0x23, 0x04, 0x40, 0x18, 0xd0, 0x02, 
+-      0x99, 0x04, 0x08, 0x49, 0x91, 0x04, 0x00, 0xa8, 
+-      0x49, 0xc9, 0x58, 0x08, 0x99, 0x04, 0x43, 0x48, 
+-      0x61, 0xe0, 0x2d, 0x13, 0xd1, 0x04, 0x20, 0x00, 
+-      0x90, 0x14, 0x20, 0x00, 0x61, 0xa0, 0xe0, 0x13, 
+-      0x9b, 0x0c, 0x68, 0x58, 0x90, 0x01, 0x98, 0x01, 
+-      0x08, 0x80, 0x61, 0xa0, 0x98, 0x01, 0x64, 0x60, 
+-      0x9b, 0x0c, 0x68, 0x18, 0x64, 0x20, 0x20, 0x00, 
+-      0x62, 0x60, 0x9a, 0x0b, 0x63, 0xe2, 0x69, 0x60, 
+-      0x4b, 0xb6, 0x40, 0x18, 0x61, 0x60, 0x02, 0x00, 
+-      0x69, 0x60, 0x4b, 0xb6, 0x40, 0x18, 0x61, 0x60, 
+-      0x05, 0x80, 0x69, 0x60, 0x23, 0x0f, 0x02, 0x9b, 
+-      0x43, 0x18, 0x61, 0x60, 0x04, 0x80, 0x69, 0x60, 
+-      0x23, 0x20, 0x43, 0xdb, 0x40, 0x18, 0x61, 0x60, 
+-      0x06, 0x80, 0x69, 0x60, 0x23, 0xc0, 0x43, 0x18, 
+-      0x61, 0x60, 0x06, 0x00, 0x69, 0x60, 0x23, 0x01, 
+-      0x03, 0x9b, 0x43, 0x18, 0x61, 0x60, 0x04, 0x40, 
+-      0x98, 0x14, 0x60, 0xe0, 0x61, 0x25, 0x48, 0xab, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x06, 0x98, 0x14, 
+-      0x28, 0x19, 0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 
+-      0x20, 0x00, 0xe0, 0x05, 0x98, 0x14, 0x28, 0x08, 
+-      0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0x28, 0x00, 0xd0, 0x02, 0x20, 0x00, 0xb0, 0x09, 
+-      0xe7, 0x35, 0x49, 0xa1, 0x20, 0x91, 0xf0, 0x19, 
+-      0xf8, 0x21, 0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 
+-      0xf0, 0x0b, 0xf8, 0x08, 0xe7, 0xf5, 0x48, 0x9d, 
+-      0x68, 0x00, 0x28, 0x01, 0xd1, 0x53, 0x68, 0x38, 
+-      0x01, 0x80, 0x0f, 0xc0, 0x68, 0xa1, 0x4b, 0x9a, 
+-      0x40, 0x19, 0x07, 0xc0, 0x09, 0x80, 0x43, 0x08, 
+-      0x60, 0xa0, 0x01, 0x80, 0x0f, 0xc0, 0x68, 0x38, 
+-      0x01, 0xc0, 0x0f, 0xc0, 0x68, 0xa1, 0x4b, 0x95, 
+-      0x40, 0x19, 0x07, 0xc0, 0x09, 0xc0, 0x43, 0x08, 
+-      0x60, 0xa0, 0x01, 0xc0, 0x0f, 0xc0, 0x68, 0x38, 
+-      0x02, 0x00, 0x0e, 0x00, 0x68, 0xa1, 0x4b, 0x85, 
+-      0x40, 0x19, 0x06, 0x00, 0x0e, 0x00, 0x04, 0x00, 
+-      0x43, 0x08, 0x60, 0xa0, 0x02, 0x00, 0x0e, 0x00, 
+-      0x48, 0x86, 0x68, 0x00, 0x28, 0x00, 0xd1, 0x2a, 
+-      0x2f, 0x00, 0xd0, 0x28, 0x20, 0x0d, 0x06, 0xc0, 
+-      0x6a, 0x00, 0x1c, 0x06, 0x68, 0x38, 0x4b, 0x85, 
+-      0x43, 0x98, 0xd0, 0x06, 0x68, 0x38, 0x02, 0x00, 
+-      0x0e, 0x01, 0x20, 0x01, 0x40, 0x88, 0x43, 0x06, 
+-      0xe0, 0x05, 0x68, 0x38, 0x02, 0x00, 0x0e, 0x00, 
+-      0x21, 0x01, 0x40, 0x81, 0x43, 0x8e, 0x68, 0x38, 
+-      0x4b, 0x7b, 0x43, 0x98, 0xd0, 0x08, 0x68, 0x38, 
+-      0x02, 0x00, 0x0e, 0x00, 0x1d, 0xc1, 0x31, 0x01, 
+-      0x20, 0x01, 0x40, 0x88, 0x43, 0x06, 0xe0, 0x06, 
+-      0x68, 0x38, 0x02, 0x00, 0x0e, 0x00, 0x30, 0x08, 
+-      0x21, 0x01, 0x40, 0x81, 0x43, 0x8e, 0x2d, 0x0b, 
+-      0xdb, 0x0a, 0x2d, 0x12, 0xdc, 0x08, 0x48, 0x6f, 
+-      0x68, 0x00, 0x28, 0x01, 0xd1, 0x04, 0x20, 0x51, 
+-      0x01, 0x00, 0x21, 0x0d, 0x06, 0xc9, 0x60, 0x08, 
+-      0x98, 0x14, 0x00, 0x80, 0x49, 0x6c, 0x58, 0x08, 
+-      0x28, 0x00, 0xd0, 0x01, 0x20, 0x83, 0x90, 0x03, 
+-      0x2d, 0x0b, 0xdb, 0x08, 0x2d, 0x12, 0xdc, 0x06, 
+-      0x48, 0x68, 0x68, 0x00, 0x28, 0x00, 0xd0, 0x01, 
+-      0x20, 0x84, 0x90, 0x03, 0xe0, 0x06, 0x9a, 0x0b, 
+-      0x2a, 0x01, 0xd1, 0x03, 0x2d, 0x13, 0xd0, 0x01, 
+-      0x20, 0x82, 0x90, 0x03, 0x98, 0x03, 0x28, 0x00, 
+-      0xd0, 0x07, 0x20, 0x92, 0x49, 0x5a, 0x60, 0x08, 
+-      0x20, 0x08, 0x60, 0xe0, 0x98, 0x03, 0xb0, 0x09, 
+-      0xe6, 0xa1, 0x98, 0x15, 0x68, 0x01, 0x98, 0x14, 
+-      0x00, 0x80, 0x4a, 0x59, 0x50, 0x11, 0x6a, 0xa0, 
+-      0x28, 0x00, 0xda, 0x01, 0x20, 0x00, 0x62, 0xa0, 
+-      0x6b, 0x20, 0x28, 0x00, 0xdc, 0x01, 0x20, 0x01, 
+-      0x63, 0x20, 0x6a, 0xe0, 0x28, 0x00, 0xda, 0x01, 
+-      0x20, 0x00, 0x62, 0xe0, 0x6b, 0x60, 0x4b, 0x52, 
+-      0x42, 0x98, 0xdd, 0x01, 0x48, 0x50, 0x63, 0x60, 
+-      0x6b, 0x20, 0xf7, 0xff, 0xfb, 0x9e, 0x90, 0x00, 
+-      0x2d, 0x13, 0xd1, 0x05, 0x6a, 0xa1, 0x9a, 0x00, 
+-      0x48, 0x4c, 0xf0, 0x0b, 0xff, 0x99, 0xe0, 0x15, 
+-      0x2d, 0x0b, 0xdb, 0x01, 0x2d, 0x12, 0xdd, 0x03, 
+-      0x48, 0x40, 0x68, 0x00, 0x28, 0x00, 0xd1, 0x0d, 
+-      0x2d, 0x0b, 0xdb, 0x06, 0x2d, 0x12, 0xdc, 0x04, 
+-      0x48, 0x3e, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x00, 
+-      0xe0, 0x04, 0x6a, 0xa1, 0x9a, 0x00, 0x48, 0x41, 
+-      0xf0, 0x0b, 0xff, 0x82, 0x2d, 0x0b, 0xdb, 0x5f, 
+-      0x2d, 0x12, 0xdc, 0x5e, 0x98, 0x15, 0x68, 0x00, 
+-      0x49, 0x3a, 0x60, 0x08, 0x99, 0x13, 0xa8, 0x05, 
+-      0xf0, 0x01, 0xfd, 0xae, 0xa9, 0x05, 0x98, 0x15, 
+-      0x68, 0x00, 0xf0, 0x05, 0xfc, 0x5f, 0x1d, 0xe0, 
+-      0x30, 0x21, 0xa9, 0x05, 0xf0, 0x01, 0xfd, 0xa4, 
+-      0x20, 0x01, 0x49, 0x35, 0x65, 0x08, 0x20, 0x02, 
+-      0x21, 0x0d, 0x06, 0xc9, 0x60, 0xc8, 0x21, 0x00, 
+-      0x20, 0x02, 0xf0, 0x04, 0xfa, 0xdd, 0x2d, 0x0b, 
+-      0xd0, 0x05, 0x2d, 0x0f, 0xd0, 0x03, 0x2d, 0x10, 
+-      0xd0, 0x01, 0x2d, 0x11, 0xd1, 0x03, 0x21, 0x00, 
+-      0x20, 0x12, 0xf0, 0x04, 0xfa, 0xd1, 0x2d, 0x0c, 
+-      0xd0, 0x01, 0x2d, 0x0f, 0xd1, 0x03, 0x21, 0x00, 
+-      0x20, 0x04, 0xf0, 0x04, 0xfa, 0xc9, 0x2d, 0x0d, 
+-      0xd0, 0x01, 0x2d, 0x10, 0xd1, 0x03, 0x21, 0x00, 
+-      0x20, 0x08, 0xf0, 0x04, 0xfa, 0xc1, 0x2d, 0x0e, 
+-      0xd0, 0x01, 0x2d, 0x11, 0xd1, 0x03, 0x21, 0x00, 
+-      0x20, 0x01, 0xf0, 0x04, 0xfa, 0xb9, 0x48, 0x15, 
+-      0x68, 0x00, 0x28, 0x01, 0xd1, 0x73, 0xb0, 0x82, 
+-      0x49, 0x1c, 0x20, 0x91, 0xf0, 0x18, 0xff, 0x06, 
+-      0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 0xf0, 0x0b, 
+-      0xfe, 0x86, 0x20, 0x92, 0x49, 0x17, 0x60, 0x08, 
+-      0x20, 0x01, 0x49, 0x17, 0x68, 0x09, 0x60, 0x08, 
+-      0x20, 0x01, 0x49, 0x15, 0x68, 0x09, 0x23, 0x07, 
+-      0x02, 0x1b, 0x18, 0xc9, 0x66, 0x88, 0xe0, 0x25, 
+-      0xe0, 0xae, 0xe0, 0xad, 0xff, 0x00, 0xff, 0xff, 
+-      0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xfc, 0xff, 
+-      0xff, 0xff, 0xbf, 0xff, 0x2e, 0x03, 0x3a, 0x04, 
+-      0x2e, 0x03, 0x3a, 0x54, 0x2e, 0x08, 0x94, 0x84, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0x2e, 0x08, 0x60, 0x84, 
+-      0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 
+-      0x2e, 0x08, 0x7c, 0x58, 0x2e, 0x08, 0x7c, 0xbc, 
+-      0x00, 0x00, 0x02, 0x3f, 0x2e, 0x08, 0x7d, 0x94, 
+-      0xcc, 0x00, 0x00, 0x00, 0x2e, 0x08, 0x94, 0x88, 
+-      0x2e, 0x08, 0x7d, 0xb4, 0x6a, 0xa0, 0x30, 0x01, 
+-      0x05, 0x00, 0x6a, 0xe1, 0x31, 0x01, 0x02, 0x89, 
+-      0x43, 0x08, 0x6b, 0x61, 0x31, 0x02, 0x43, 0x08, 
+-      0x90, 0x00, 0x20, 0x00, 0x62, 0xa0, 0x20, 0x00, 
+-      0x62, 0xe0, 0x48, 0x5f, 0x63, 0x20, 0x48, 0x5f, 
+-      0x63, 0x60, 0x6b, 0x20, 0xf7, 0xff, 0xfa, 0xe1, 
+-      0x90, 0x02, 0x48, 0x5d, 0x68, 0x00, 0x23, 0x77, 
+-      0x01, 0x1b, 0x18, 0xc0, 0x9a, 0x02, 0x1c, 0x21, 
+-      0xf0, 0x0b, 0xfa, 0x4a, 0x98, 0x00, 0x49, 0x58, 
+-      0x68, 0x09, 0x23, 0x07, 0x02, 0x1b, 0x18, 0xc9, 
+-      0x66, 0xc8, 0x48, 0x55, 0x68, 0x00, 0x21, 0x00, 
+-      0xf0, 0x0b, 0xfa, 0xc4, 0x48, 0x52, 0x68, 0x00, 
+-      0xf0, 0x0b, 0xfe, 0x38, 0x49, 0x51, 0x20, 0x91, 
+-      0xf0, 0x18, 0xfe, 0x98, 0xe0, 0x00, 0xe0, 0x11, 
+-      0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf6, 0x48, 0x4c, 
+-      0x68, 0x00, 0x90, 0x01, 0x48, 0x4c, 0x68, 0x00, 
+-      0x49, 0x49, 0x60, 0x08, 0x98, 0x01, 0x49, 0x4a, 
+-      0x60, 0x08, 0x20, 0x92, 0x49, 0x47, 0x60, 0x08, 
+-      0xb0, 0x02, 0xe0, 0x40, 0x48, 0x47, 0x68, 0x00, 
+-      0x28, 0x00, 0xd0, 0x0c, 0x6a, 0xa0, 0x30, 0x01, 
+-      0x05, 0x00, 0x6a, 0xe1, 0x31, 0x01, 0x02, 0x89, 
+-      0x43, 0x08, 0x6b, 0x61, 0x31, 0x02, 0x43, 0x08, 
+-      0x49, 0x41, 0x60, 0x08, 0xe0, 0x0c, 0x6a, 0xa0, 
+-      0x30, 0x01, 0x05, 0x00, 0x6a, 0xe1, 0x31, 0x01, 
+-      0x02, 0x89, 0x43, 0x08, 0x6b, 0x61, 0x31, 0x02, 
+-      0x43, 0x08, 0x21, 0x0d, 0x06, 0xc9, 0x61, 0x88, 
+-      0x20, 0x0d, 0x06, 0xc0, 0x68, 0x80, 0x90, 0x02, 
+-      0x20, 0x00, 0x21, 0x0d, 0x06, 0xc9, 0x60, 0x88, 
+-      0xf0, 0x00, 0xfe, 0x82, 0x48, 0x33, 0x68, 0x00, 
+-      0x28, 0x00, 0xd0, 0x07, 0x20, 0x00, 0x62, 0xa0, 
+-      0x20, 0x00, 0x62, 0xe0, 0x48, 0x2a, 0x63, 0x20, 
+-      0x48, 0x2a, 0x63, 0x60, 0x6b, 0x20, 0xf7, 0xff, 
+-      0xfa, 0x78, 0x90, 0x00, 0x9a, 0x00, 0x99, 0x14, 
+-      0x1c, 0x20, 0xf0, 0x00, 0xfd, 0xfb, 0x98, 0x02, 
+-      0x21, 0x0d, 0x06, 0xc9, 0x60, 0x88, 0xe0, 0x05, 
+-      0x2d, 0x13, 0xd1, 0x03, 0x20, 0x1f, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0x08, 0x2d, 0x0b, 0xdb, 0x01, 
+-      0x2d, 0x12, 0xdd, 0x1a, 0x48, 0x23, 0x68, 0x00, 
+-      0x28, 0x00, 0xd1, 0x16, 0x20, 0x0d, 0x06, 0xc0, 
+-      0x68, 0x80, 0x90, 0x02, 0x20, 0x00, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0x88, 0xf0, 0x00, 0xfe, 0x50, 
+-      0x6b, 0x20, 0xf7, 0xff, 0xfa, 0x52, 0x90, 0x00, 
+-      0x9a, 0x00, 0x99, 0x14, 0x1c, 0x20, 0xf0, 0x00, 
+-      0xfd, 0xd5, 0x98, 0x02, 0x21, 0x0d, 0x06, 0xc9, 
+-      0x60, 0x88, 0x48, 0x14, 0x68, 0x00, 0x28, 0x01, 
+-      0xd1, 0x06, 0x48, 0x14, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x02, 0x20, 0x0d, 0x06, 0xc0, 0x62, 0x06, 
+-      0x48, 0x0e, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x07, 
+-      0x48, 0x0e, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x03, 
+-      0x98, 0x14, 0x21, 0x00, 0xf0, 0x0b, 0xfd, 0x0a, 
+-      0x20, 0x92, 0x49, 0x0b, 0x60, 0x08, 0x20, 0x00, 
+-      0xb0, 0x09, 0xe5, 0x10, 0xb0, 0x09, 0xe5, 0x0e, 
+-      0x00, 0x00, 0x02, 0xcf, 0x00, 0x00, 0x02, 0x3f, 
+-      0x2e, 0x08, 0x7d, 0xb4, 0x2e, 0x08, 0x94, 0x88, 
+-      0x2e, 0x08, 0x7d, 0xb8, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x5e, 0x4c, 0x2e, 0x08, 0x94, 0x84, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0xb5, 0xf7, 0xb0, 0x83, 
+-      0x9f, 0x03, 0x69, 0x38, 0x90, 0x00, 0x98, 0x00, 
+-      0x28, 0x13, 0xd1, 0x05, 0x20, 0x75, 0xb0, 0x03, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x6c, 0x78, 0x99, 0x04, 0x60, 0x48, 0x6c, 0x38, 
+-      0x99, 0x04, 0x60, 0x08, 0x6c, 0xf8, 0x9a, 0x05, 
+-      0x60, 0x50, 0x6c, 0xb8, 0x9a, 0x05, 0x60, 0x10, 
+-      0x68, 0xfd, 0x48, 0xf9, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x05, 0x2d, 0x19, 0xd3, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0xe0, 0x04, 0x2d, 0x08, 
+-      0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0x28, 0x00, 0xd0, 0x02, 0x20, 0x00, 0xb0, 0x03, 
+-      0xe7, 0xda, 0x49, 0xf0, 0x20, 0x91, 0xf0, 0x18, 
+-      0xfd, 0xb9, 0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 
+-      0xf0, 0x0a, 0xfd, 0xa0, 0xe7, 0xf5, 0x00, 0xa8, 
+-      0x49, 0xeb, 0x58, 0x08, 0x99, 0x03, 0x42, 0x88, 
+-      0xd0, 0x05, 0x20, 0x92, 0x49, 0xe7, 0x60, 0x08, 
+-      0x20, 0xff, 0xb0, 0x03, 0xe7, 0xc4, 0x21, 0x00, 
+-      0x00, 0xa8, 0x4a, 0xe5, 0x50, 0x11, 0x48, 0xe2, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x05, 0x69, 0x38, 
+-      0x28, 0x0b, 0xdb, 0x16, 0x69, 0x38, 0x28, 0x12, 
+-      0xdc, 0x13, 0x48, 0xe0, 0x68, 0x00, 0x28, 0x01, 
+-      0xd1, 0x06, 0x69, 0x38, 0x28, 0x0b, 0xdb, 0x03, 
+-      0x69, 0x38, 0x28, 0x12, 0xdc, 0x00, 0xe0, 0x08, 
+-      0x6b, 0x38, 0xf7, 0xff, 0xf9, 0xb6, 0x90, 0x01, 
+-      0x6a, 0xb9, 0x9a, 0x01, 0x48, 0xd8, 0xf0, 0x0b, 
+-      0xfd, 0x85, 0x69, 0x38, 0x28, 0x0b, 0xdb, 0x2e, 
+-      0x69, 0x38, 0x28, 0x12, 0xdc, 0x2b, 0x48, 0xd0, 
+-      0x68, 0x00, 0x28, 0x00, 0xd1, 0x27, 0x20, 0x00, 
+-      0x49, 0xd2, 0x65, 0x08, 0x20, 0x01, 0x03, 0x00, 
+-      0x49, 0xd0, 0x65, 0x48, 0x20, 0x00, 0x49, 0xcf, 
+-      0x65, 0x88, 0x20, 0x00, 0x49, 0xcd, 0x65, 0xc8, 
+-      0x20, 0x00, 0x49, 0xcc, 0x66, 0x08, 0x20, 0x00, 
+-      0x49, 0xcb, 0x60, 0x08, 0x20, 0x02, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0xc8, 0x21, 0x00, 0x20, 0x02, 
+-      0xf0, 0x04, 0xf9, 0x0a, 0x48, 0xc3, 0x68, 0x00, 
+-      0x28, 0x00, 0xd1, 0x04, 0x48, 0xc5, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x61, 0x88, 0xe0, 0x02, 0x48, 0xc3, 
+-      0x49, 0xc3, 0x60, 0x08, 0xe0, 0x06, 0x69, 0x38, 
+-      0x28, 0x13, 0xd1, 0x03, 0x20, 0x00, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0x08, 0x48, 0xb6, 0x68, 0x00, 
+-      0x28, 0x00, 0xd1, 0x2c, 0x20, 0x0d, 0x06, 0xc0, 
+-      0x68, 0x80, 0x90, 0x02, 0x20, 0x00, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0x88, 0xf0, 0x00, 0xfd, 0x64, 
+-      0x20, 0x00, 0x43, 0xc0, 0x00, 0xe9, 0x4b, 0xb7, 
+-      0x18, 0xc9, 0x60, 0x08, 0x20, 0x00, 0x43, 0xc0, 
+-      0x00, 0xe9, 0x4b, 0xb4, 0x18, 0xc9, 0x60, 0x48, 
+-      0x20, 0x00, 0x43, 0xc0, 0x00, 0xe9, 0x4b, 0xb1, 
+-      0x18, 0xc9, 0x64, 0x08, 0x20, 0x00, 0x43, 0xc0, 
+-      0x00, 0xe9, 0x4b, 0xae, 0x18, 0xc9, 0x64, 0x48, 
+-      0x20, 0x01, 0x40, 0xa8, 0x43, 0xc0, 0x99, 0x02, 
+-      0x40, 0x08, 0x90, 0x02, 0x98, 0x02, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0x88, 0xe0, 0x9c, 0x69, 0x38, 
+-      0x28, 0x0b, 0xdb, 0x74, 0x69, 0x38, 0x28, 0x12, 
+-      0xdc, 0x72, 0x48, 0x9b, 0x68, 0x00, 0x28, 0x01, 
+-      0xd1, 0x6f, 0x20, 0x00, 0x49, 0x9d, 0x65, 0x08, 
+-      0x20, 0x01, 0x03, 0x00, 0x49, 0x9b, 0x65, 0x48, 
+-      0x20, 0x00, 0x49, 0x9a, 0x65, 0x88, 0x20, 0x00, 
+-      0x49, 0x98, 0x65, 0xc8, 0x20, 0x00, 0x49, 0x97, 
+-      0x66, 0x08, 0x20, 0x00, 0x49, 0x96, 0x60, 0x08, 
+-      0x20, 0x02, 0x21, 0x0d, 0x06, 0xc9, 0x60, 0xc8, 
+-      0x21, 0x00, 0x20, 0x02, 0xf0, 0x04, 0xf8, 0xa0, 
+-      0x49, 0x95, 0x20, 0x91, 0xf0, 0x18, 0xfc, 0xf2, 
+-      0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 0xf0, 0x0b, 
+-      0xfc, 0x72, 0x20, 0x92, 0x49, 0x90, 0x60, 0x08, 
+-      0x48, 0x90, 0x68, 0x00, 0x23, 0x0d, 0x01, 0xdb, 
+-      0x18, 0xc0, 0x69, 0x80, 0x08, 0x40, 0x00, 0x40, 
+-      0x49, 0x8c, 0x68, 0x09, 0x23, 0x0d, 0x01, 0xdb, 
+-      0x18, 0xc9, 0x61, 0x88, 0x20, 0x01, 0x49, 0x89, 
+-      0x68, 0x09, 0x60, 0x08, 0x20, 0x01, 0x49, 0x87, 
+-      0x68, 0x09, 0x23, 0x07, 0x02, 0x1b, 0x18, 0xc9, 
+-      0x66, 0x88, 0x20, 0x00, 0x43, 0xc0, 0x49, 0x83, 
+-      0x68, 0x09, 0x23, 0x0f, 0x01, 0xdb, 0x18, 0xc9, 
+-      0x61, 0x08, 0x20, 0x00, 0x43, 0xc0, 0x49, 0x7f, 
+-      0x68, 0x09, 0x23, 0x0f, 0x01, 0xdb, 0x18, 0xc9, 
+-      0x61, 0x48, 0x20, 0x00, 0x43, 0xc0, 0x49, 0x7b, 
+-      0x68, 0x09, 0x23, 0x0f, 0x01, 0xdb, 0x18, 0xc9, 
+-      0x60, 0xc8, 0x20, 0x00, 0x43, 0xc0, 0x49, 0x77, 
+-      0x68, 0x09, 0x23, 0x0f, 0x01, 0xdb, 0x18, 0xc9, 
+-      0x60, 0x88, 0x6b, 0x38, 0xf7, 0xff, 0xf8, 0xd9, 
+-      0x90, 0x01, 0x48, 0x72, 0x68, 0x00, 0x23, 0x77, 
+-      0x01, 0x1b, 0x18, 0xc0, 0x9a, 0x01, 0x1c, 0x39, 
+-      0xf0, 0x0b, 0xf8, 0x42, 0xe0, 0x02, 0xe0, 0x23, 
+-      0xe0, 0x22, 0xe0, 0x21, 0x48, 0x67, 0x49, 0x6b, 
+-      0x68, 0x09, 0x23, 0x07, 0x02, 0x1b, 0x18, 0xc9, 
+-      0x66, 0xc8, 0x48, 0x68, 0x68, 0x00, 0x21, 0x00, 
+-      0xf0, 0x0b, 0xf8, 0xb8, 0x48, 0x65, 0x68, 0x00, 
+-      0xf0, 0x0b, 0xfc, 0x2c, 0x49, 0x62, 0x20, 0x91, 
+-      0xf0, 0x18, 0xfc, 0x8c, 0x28, 0x92, 0xd0, 0x00, 
+-      0xe7, 0xf8, 0x48, 0x60, 0x68, 0x04, 0x48, 0x60, 
+-      0x68, 0x00, 0x49, 0x5e, 0x60, 0x08, 0x48, 0x5e, 
+-      0x60, 0x04, 0x20, 0x92, 0x49, 0x5a, 0x60, 0x08, 
+-      0x48, 0x52, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x73, 
+-      0x48, 0x4d, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x6f, 
+-      0x1c, 0x28, 0xf0, 0x0b, 0xfb, 0x9d, 0x28, 0x01, 
+-      0xd1, 0x6a, 0x98, 0x00, 0x28, 0x0b, 0xdb, 0x02, 
+-      0x98, 0x00, 0x28, 0x12, 0xdd, 0x65, 0xb0, 0x84, 
+-      0x49, 0x4f, 0x20, 0x91, 0xf0, 0x18, 0xfc, 0x66, 
+-      0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 0xf0, 0x0b, 
+-      0xfb, 0xe6, 0x48, 0x4c, 0x68, 0x00, 0x68, 0x40, 
+-      0x28, 0x00, 0xd0, 0x06, 0x48, 0x49, 0x68, 0x00, 
+-      0x68, 0x40, 0x38, 0x01, 0x49, 0x47, 0x68, 0x09, 
+-      0x60, 0x48, 0x20, 0x92, 0x49, 0x44, 0x60, 0x08, 
+-      0x20, 0x01, 0x49, 0x44, 0x68, 0x09, 0x60, 0x08, 
+-      0x24, 0x00, 0x20, 0x00, 0x90, 0x02, 0x98, 0x02, 
+-      0x28, 0x00, 0xd1, 0x15, 0x2c, 0x07, 0xd2, 0x13, 
+-      0x6a, 0xf8, 0x05, 0x81, 0x0d, 0x89, 0x1c, 0x20, 
+-      0x34, 0x01, 0x00, 0x83, 0x18, 0x18, 0x00, 0xc0, 
+-      0x4a, 0x3a, 0x68, 0x12, 0x18, 0x80, 0x23, 0x05, 
+-      0x02, 0x1b, 0x18, 0xc0, 0x6f, 0xc0, 0x42, 0x81, 
+-      0xd1, 0x01, 0x20, 0x01, 0x90, 0x02, 0xe7, 0xe6, 
+-      0x98, 0x02, 0x28, 0x00, 0xd1, 0x14, 0x2c, 0x18, 
+-      0xd2, 0x12, 0x6a, 0xf8, 0x05, 0x81, 0x0d, 0x89, 
+-      0x1c, 0x20, 0x34, 0x01, 0x23, 0x4c, 0x43, 0x58, 
+-      0x4a, 0x2e, 0x68, 0x12, 0x18, 0x80, 0x38, 0xff, 
+-      0x38, 0xff, 0x38, 0x02, 0x69, 0x40, 0x42, 0x81, 
+-      0xd1, 0x01, 0x20, 0x01, 0x90, 0x02, 0xe7, 0xe7, 
+-      0x3c, 0x01, 0x6b, 0x38, 0xf7, 0xff, 0xf8, 0x41, 
+-      0x90, 0x01, 0x2c, 0x07, 0xd2, 0x09, 0x48, 0x25, 
+-      0x68, 0x01, 0x1c, 0x20, 0xf0, 0x0a, 0xfe, 0xbc, 
+-      0x48, 0x22, 0x68, 0x00, 0xf0, 0x0b, 0xfb, 0xa6, 
+-      0xe0, 0x09, 0x2c, 0x18, 0xd2, 0x07, 0xe0, 0x01, 
+-      0xe0, 0x95, 0xe0, 0x94, 0x1f, 0xe0, 0x49, 0x1d, 
+-      0x68, 0x09, 0xf0, 0x0a, 0xfe, 0xeb, 0x48, 0x1b, 
+-      0x68, 0x00, 0x4b, 0x1c, 0x18, 0xc0, 0xf0, 0x0b, 
+-      0xf8, 0x0b, 0x20, 0x00, 0x49, 0x17, 0x68, 0x09, 
+-      0x23, 0x09, 0x01, 0xdb, 0x18, 0xc9, 0x64, 0x88, 
+-      0x48, 0x14, 0x68, 0x00, 0x68, 0x40, 0x28, 0x07, 
+-      0xd3, 0x2c, 0x48, 0x12, 0x68, 0x00, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc0, 0x69, 0x80, 0x23, 0xfe, 
+-      0x43, 0x18, 0x49, 0x0e, 0x68, 0x09, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc9, 0xe0, 0x1c, 0x00, 0x00, 
+-      0x2e, 0x08, 0x94, 0x84, 0x2e, 0x08, 0x7c, 0xc0, 
+-      0x2e, 0x08, 0x7c, 0x58, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x7d, 0x94, 0xcc, 0x00, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7c, 0xbc, 0x3f, 0xff, 0xff, 0xff, 
+-      0x2e, 0x08, 0x5e, 0x4c, 0x68, 0x00, 0x04, 0x00, 
+-      0x2e, 0x08, 0x94, 0x88, 0x2e, 0x08, 0x7d, 0xb4, 
+-      0x2e, 0x08, 0x7d, 0xb8, 0x00, 0x00, 0x04, 0xcc, 
+-      0x61, 0x88, 0xe0, 0x2d, 0x26, 0x01, 0x21, 0x00, 
+-      0x91, 0x00, 0x48, 0x2b, 0x68, 0x00, 0x68, 0x40, 
+-      0x99, 0x00, 0x42, 0x88, 0xd8, 0x04, 0xe0, 0x06, 
+-      0x99, 0x00, 0x31, 0x01, 0x91, 0x00, 0xe7, 0xf4, 
+-      0x00, 0x70, 0x1c, 0x46, 0xe7, 0xf8, 0x08, 0x76, 
+-      0x00, 0x76, 0x48, 0x23, 0x68, 0x00, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc0, 0x69, 0x80, 0x07, 0xc0, 
+-      0x0f, 0xc0, 0x49, 0x1f, 0x68, 0x09, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc9, 0x61, 0x88, 0x48, 0x1c, 
+-      0x68, 0x00, 0x23, 0x0d, 0x01, 0xdb, 0x18, 0xc0, 
+-      0x69, 0x80, 0x43, 0x30, 0x49, 0x18, 0x68, 0x09, 
+-      0x23, 0x0d, 0x01, 0xdb, 0x18, 0xc9, 0x61, 0x88, 
+-      0x1c, 0x21, 0x48, 0x15, 0x68, 0x00, 0xf0, 0x0a, 
+-      0xff, 0xb1, 0x6b, 0x79, 0x48, 0x12, 0x68, 0x00, 
+-      0xf0, 0x0a, 0xfe, 0xe6, 0x1c, 0x28, 0x21, 0x00, 
+-      0xf0, 0x0b, 0xfa, 0x88, 0x49, 0x0f, 0x20, 0x91, 
+-      0xf0, 0x18, 0xfb, 0x80, 0x28, 0x92, 0xd0, 0x00, 
+-      0xe7, 0xf8, 0x48, 0x0b, 0x68, 0x00, 0x90, 0x03, 
+-      0x48, 0x0b, 0x68, 0x00, 0x49, 0x08, 0x60, 0x08, 
+-      0x98, 0x03, 0x49, 0x09, 0x60, 0x08, 0x20, 0x92, 
+-      0x49, 0x06, 0x60, 0x08, 0xb0, 0x04, 0x20, 0x92, 
+-      0x49, 0x06, 0x60, 0x08, 0x20, 0x00, 0xb0, 0x03, 
+-      0xe5, 0x86, 0xb0, 0x03, 0xe5, 0x84, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7d, 0xb4, 0x2e, 0x08, 0x94, 0x88, 
+-      0x2e, 0x08, 0x7d, 0xb8, 0x2e, 0x08, 0x7c, 0xc0, 
+-      0xb5, 0xf3, 0xb0, 0x85, 0x20, 0x00, 0x90, 0x01, 
+-      0x9d, 0x05, 0x9f, 0x06, 0x69, 0x28, 0x90, 0x04, 
+-      0x69, 0x3c, 0x98, 0x04, 0x28, 0x13, 0xd0, 0x01, 
+-      0x2c, 0x13, 0xd1, 0x05, 0x20, 0xff, 0xb0, 0x05, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x68, 0xee, 0x68, 0xf9, 0x91, 0x03, 0x48, 0xdf, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x05, 0x2e, 0x19, 
+-      0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0xe0, 0x04, 0x2e, 0x08, 0xd3, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0x28, 0x00, 0xd0, 0x20, 
+-      0x48, 0xd6, 0x68, 0x00, 0x28, 0x00, 0xd0, 0x06, 
+-      0x99, 0x03, 0x29, 0x19, 0xd3, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0xe0, 0x05, 0x99, 0x03, 
+-      0x29, 0x08, 0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 
+-      0x20, 0x00, 0x28, 0x00, 0xd0, 0x06, 0x99, 0x03, 
+-      0x60, 0xe9, 0x60, 0xfe, 0x20, 0x00, 0xb0, 0x05, 
+-      0xe7, 0xce, 0xe1, 0x92, 0x1c, 0x3d, 0x9f, 0x05, 
+-      0x9e, 0x03, 0x68, 0xf9, 0x91, 0x03, 0x9c, 0x04, 
+-      0xe0, 0xaa, 0x48, 0xc6, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x06, 0x99, 0x03, 0x29, 0x19, 0xd3, 0x01, 
+-      0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 0xe0, 0x05, 
+-      0x99, 0x03, 0x29, 0x08, 0xd3, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0x28, 0x00, 0xd1, 0x73, 
+-      0x49, 0xbd, 0x20, 0x91, 0xf0, 0x18, 0xfa, 0xfe, 
+-      0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 0xf0, 0x0a, 
+-      0xfa, 0xe5, 0xe7, 0xf5, 0x00, 0xb0, 0x49, 0xb9, 
+-      0x58, 0x08, 0x42, 0xa8, 0xd1, 0x05, 0x99, 0x03, 
+-      0x00, 0x88, 0x49, 0xb6, 0x58, 0x08, 0x42, 0xb8, 
+-      0xd0, 0x05, 0x20, 0x92, 0x49, 0xb2, 0x60, 0x08, 
+-      0x20, 0xff, 0xb0, 0x05, 0xe7, 0x98, 0x48, 0xb2, 
+-      0x68, 0x00, 0x42, 0xa8, 0xd0, 0x03, 0x48, 0xb0, 
+-      0x68, 0x00, 0x42, 0xb8, 0xd1, 0x0a, 0x20, 0x0d, 
+-      0x06, 0xc0, 0x68, 0xc0, 0x90, 0x01, 0x98, 0x01, 
+-      0x28, 0x01, 0xd1, 0x03, 0x20, 0x00, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0xc8, 0x99, 0x03, 0x60, 0xe9, 
+-      0x60, 0xfe, 0x00, 0xb0, 0x49, 0xa5, 0x50, 0x0f, 
+-      0x99, 0x03, 0x00, 0x88, 0x49, 0xa3, 0x50, 0x0d, 
+-      0x48, 0xa0, 0x68, 0x00, 0x28, 0x00, 0xd1, 0x55, 
+-      0x20, 0x0d, 0x06, 0xc0, 0x68, 0x80, 0x90, 0x02, 
+-      0x20, 0x00, 0x21, 0x0d, 0x06, 0xc9, 0x60, 0x88, 
+-      0x20, 0x01, 0x40, 0xb0, 0x99, 0x02, 0x40, 0x08, 
+-      0xd1, 0x12, 0x99, 0x03, 0x20, 0x01, 0x40, 0x88, 
+-      0x99, 0x02, 0x40, 0x08, 0xd0, 0x0b, 0x99, 0x03, 
+-      0x20, 0x01, 0x40, 0x88, 0x43, 0xc0, 0x99, 0x02, 
+-      0x40, 0x08, 0x90, 0x02, 0x20, 0x01, 0x40, 0xb0, 
+-      0x99, 0x02, 0x43, 0x08, 0x90, 0x02, 0xe0, 0x11, 
+-      0x99, 0x03, 0x20, 0x01, 0x40, 0x88, 0x99, 0x02, 
+-      0x40, 0x08, 0xd1, 0x0b, 0x20, 0x01, 0x40, 0xb0, 
+-      0x43, 0xc0, 0x99, 0x02, 0x40, 0x08, 0x90, 0x02, 
+-      0x99, 0x03, 0x20, 0x01, 0x40, 0x88, 0x99, 0x02, 
+-      0x43, 0x08, 0x90, 0x02, 0x6b, 0x28, 0xf7, 0xfe, 
+-      0xfe, 0xbc, 0x90, 0x00, 0x9a, 0x00, 0xe0, 0x00, 
+-      0xe0, 0x22, 0x99, 0x03, 0x1c, 0x28, 0xf0, 0x00, 
+-      0xfa, 0x3d, 0x6b, 0x38, 0xf7, 0xfe, 0xfe, 0xb1, 
+-      0x90, 0x00, 0x9a, 0x00, 0x1c, 0x31, 0x1c, 0x38, 
+-      0xf0, 0x00, 0xfa, 0x34, 0x98, 0x02, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0x88, 0x48, 0x7c, 0x68, 0x00, 
+-      0x42, 0xa8, 0xd0, 0x03, 0x48, 0x7a, 0x68, 0x00, 
+-      0x42, 0xb8, 0xd1, 0x03, 0x98, 0x01, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0xc8, 0x20, 0x92, 0x49, 0x74, 
+-      0x60, 0x08, 0x20, 0x00, 0xb0, 0x05, 0xe7, 0x1b, 
+-      0x49, 0x71, 0x20, 0x91, 0xf0, 0x18, 0xfa, 0x66, 
+-      0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 0xf0, 0x0a, 
+-      0xfa, 0x4d, 0xe7, 0xf5, 0x00, 0xb0, 0x49, 0x6d, 
+-      0x58, 0x08, 0x42, 0xa8, 0xd0, 0x05, 0x20, 0x92, 
+-      0x49, 0x69, 0x60, 0x08, 0x20, 0xff, 0xb0, 0x05, 
+-      0xe7, 0x06, 0x2c, 0x0b, 0xdb, 0x12, 0x2c, 0x12, 
+-      0xdc, 0x10, 0x48, 0x67, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x09, 0x48, 0x65, 0x68, 0x00, 0x42, 0xa8, 
+-      0xd0, 0x05, 0x20, 0x92, 0x49, 0x60, 0x60, 0x08, 
+-      0x20, 0xff, 0xb0, 0x05, 0xe6, 0xf4, 0x48, 0x60, 
+-      0x60, 0x07, 0xe0, 0x08, 0x6b, 0xf8, 0x28, 0x01, 
+-      0xd1, 0x05, 0x20, 0x92, 0x49, 0x5a, 0x60, 0x08, 
+-      0x20, 0xff, 0xb0, 0x05, 0xe6, 0xe8, 0x48, 0x5a, 
+-      0x68, 0x00, 0x42, 0xa8, 0xd1, 0x02, 0x20, 0x00, 
+-      0x49, 0x57, 0x60, 0x08, 0x00, 0xb0, 0x49, 0x55, 
+-      0x50, 0x0f, 0x99, 0x03, 0x60, 0xe9, 0x60, 0xfe, 
+-      0x48, 0x50, 0x68, 0x00, 0x28, 0x00, 0xd1, 0x73, 
+-      0x6b, 0x28, 0xf7, 0xfe, 0xfe, 0x4e, 0x90, 0x00, 
+-      0x6a, 0xa9, 0x9a, 0x00, 0x48, 0x4f, 0xf0, 0x0b, 
+-      0xfa, 0x1d, 0x6b, 0x38, 0xf7, 0xfe, 0xfe, 0x45, 
+-      0x90, 0x00, 0x6a, 0xb9, 0x9a, 0x00, 0x48, 0x4b, 
+-      0xf0, 0x0b, 0xfa, 0x42, 0x48, 0x48, 0x68, 0x00, 
+-      0x42, 0xa8, 0xd1, 0x0f, 0x20, 0x02, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0xc8, 0x2c, 0x0b, 0xdb, 0x01, 
+-      0x2c, 0x12, 0xdd, 0x07, 0x21, 0x00, 0x20, 0x02, 
+-      0xf0, 0x03, 0xfd, 0xae, 0x48, 0x42, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x61, 0x88, 0x2c, 0x0b, 0xdb, 0x42, 
+-      0x2c, 0x12, 0xdc, 0x40, 0x98, 0x04, 0x42, 0xa0, 
+-      0xd0, 0x2c, 0x20, 0x02, 0x21, 0x0d, 0x06, 0xc9, 
+-      0x60, 0xc8, 0x21, 0x00, 0x20, 0x02, 0xf0, 0x03, 
+-      0xfd, 0x9b, 0x2c, 0x0f, 0xd0, 0x05, 0x2c, 0x10, 
+-      0xd0, 0x03, 0x2c, 0x11, 0xd0, 0x01, 0x2c, 0x0b, 
+-      0xd1, 0x03, 0x21, 0x00, 0x20, 0x12, 0xf0, 0x03, 
+-      0xfd, 0x8f, 0x2c, 0x0c, 0xd0, 0x01, 0x2c, 0x0f, 
+-      0xd1, 0x03, 0x21, 0x00, 0x20, 0x04, 0xf0, 0x03, 
+-      0xfd, 0x87, 0x2c, 0x0d, 0xd0, 0x01, 0x2c, 0x10, 
+-      0xd1, 0x03, 0x21, 0x00, 0x20, 0x08, 0xf0, 0x03, 
+-      0xfd, 0x7f, 0x2c, 0x0e, 0xd0, 0x01, 0x2c, 0x11, 
+-      0xd1, 0x03, 0x21, 0x00, 0x20, 0x01, 0xf0, 0x03, 
+-      0xfd, 0x77, 0xe0, 0x03, 0x20, 0x00, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0xc8, 0x6a, 0xb8, 0x30, 0x01, 
+-      0x05, 0x00, 0x6a, 0xf9, 0x31, 0x01, 0x02, 0x89, 
+-      0x43, 0x08, 0x6b, 0x79, 0x31, 0x02, 0x43, 0x08, 
+-      0x21, 0x0d, 0x06, 0xc9, 0x61, 0x88, 0x20, 0x0d, 
+-      0x06, 0xc0, 0x68, 0x80, 0x90, 0x02, 0x20, 0x00, 
+-      0x21, 0x0d, 0x06, 0xc9, 0x60, 0x88, 0xe0, 0x00, 
+-      0xe0, 0x1f, 0x20, 0x01, 0x40, 0xb0, 0x43, 0xc0, 
+-      0x99, 0x02, 0x40, 0x08, 0x90, 0x02, 0xf0, 0x00, 
+-      0xf9, 0xcf, 0x6b, 0x38, 0xf7, 0xfe, 0xfd, 0xd1, 
+-      0x90, 0x00, 0x9a, 0x00, 0x1c, 0x31, 0x1c, 0x38, 
+-      0xf0, 0x00, 0xf9, 0x54, 0x98, 0x02, 0x21, 0x0d, 
+-      0x06, 0xc9, 0x60, 0x88, 0x2c, 0x0b, 0xdb, 0x08, 
+-      0x2c, 0x12, 0xdc, 0x06, 0x98, 0x04, 0x42, 0xa0, 
+-      0xd1, 0x03, 0x20, 0x01, 0x21, 0x0d, 0x06, 0xc9, 
+-      0x60, 0xc8, 0x20, 0x92, 0x49, 0x04, 0x60, 0x08, 
+-      0x20, 0x00, 0xb0, 0x05, 0xe6, 0x3c, 0xb0, 0x05, 
+-      0xe6, 0x3a, 0xe6, 0x39, 0x2e, 0x08, 0x94, 0x84, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0x2e, 0x08, 0x7c, 0x58, 
+-      0x2e, 0x08, 0x7c, 0xbc, 0x2e, 0x08, 0x7d, 0x94, 
+-      0x3f, 0xff, 0xff, 0xff, 0xb5, 0xf0, 0x1c, 0x07, 
+-      0x00, 0xb8, 0x49, 0x09, 0x58, 0x0c, 0x1c, 0x7d, 
+-      0x60, 0xe5, 0x00, 0xa8, 0x49, 0x06, 0x50, 0x0c, 
+-      0x6b, 0x20, 0xf7, 0xfe, 0xfd, 0x9a, 0x1c, 0x06, 
+-      0x1c, 0x32, 0x1c, 0x29, 0x1c, 0x20, 0xf0, 0x00, 
+-      0xf9, 0x1d, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x7c, 0x58, 0xb5, 0xf0, 0x1c, 0x07, 
+-      0x00, 0xb8, 0x49, 0x09, 0x58, 0x0c, 0x1e, 0x7d, 
+-      0x60, 0xe5, 0x00, 0xa8, 0x49, 0x06, 0x50, 0x0c, 
+-      0x6b, 0x20, 0xf7, 0xfe, 0xfd, 0x82, 0x1c, 0x06, 
+-      0x1c, 0x32, 0x1c, 0x29, 0x1c, 0x20, 0xf0, 0x00, 
+-      0xf9, 0x05, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x7c, 0x58, 0xb5, 0xf3, 0x1c, 0x0f, 
+-      0xb0, 0x86, 0x98, 0x06, 0x90, 0x05, 0x98, 0x05, 
+-      0x68, 0xc5, 0x48, 0x77, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x05, 0x2d, 0x19, 0xd3, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0xe0, 0x04, 0x2d, 0x08, 
+-      0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0x28, 0x00, 0xd0, 0x05, 0x20, 0xff, 0xb0, 0x06, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x98, 0x05, 0x69, 0x00, 0x28, 0x13, 0xd1, 0x02, 
+-      0x20, 0xff, 0xb0, 0x06, 0xe7, 0xf4, 0x49, 0x69, 
+-      0x20, 0x91, 0xf0, 0x18, 0xf9, 0x23, 0x28, 0x92, 
+-      0xd0, 0x03, 0x20, 0x01, 0xf0, 0x0a, 0xf9, 0x0a, 
+-      0xe7, 0xf5, 0x00, 0xa8, 0x49, 0x64, 0x58, 0x08, 
+-      0x99, 0x05, 0x42, 0x88, 0xd0, 0x05, 0x20, 0x92, 
+-      0x49, 0x60, 0x60, 0x08, 0x20, 0xff, 0xb0, 0x06, 
+-      0xe7, 0xde, 0x42, 0xbd, 0xd1, 0x05, 0x20, 0x92, 
+-      0x49, 0x5c, 0x60, 0x08, 0x20, 0x00, 0xb0, 0x06, 
+-      0xe7, 0xd6, 0x20, 0x00, 0x00, 0xa9, 0x4a, 0x5a, 
+-      0x50, 0x50, 0x98, 0x05, 0x60, 0xc7, 0x48, 0x59, 
+-      0x68, 0x00, 0x28, 0x01, 0xd1, 0x0d, 0x48, 0x54, 
+-      0x68, 0x00, 0x28, 0x01, 0xd1, 0x09, 0x99, 0x05, 
+-      0x00, 0xb8, 0x4a, 0x53, 0x50, 0x11, 0x20, 0x92, 
+-      0x49, 0x50, 0x60, 0x08, 0x20, 0x00, 0xb0, 0x06, 
+-      0xe7, 0xbe, 0x20, 0x0d, 0x06, 0xc0, 0x68, 0x80, 
+-      0x1c, 0x04, 0x20, 0x00, 0x21, 0x0d, 0x06, 0xc9, 
+-      0x60, 0x88, 0x20, 0x00, 0x43, 0xc0, 0x00, 0xe9, 
+-      0x4b, 0x4b, 0x18, 0xc9, 0x60, 0x08, 0x20, 0x00, 
+-      0x43, 0xc0, 0x00, 0xe9, 0x4b, 0x48, 0x18, 0xc9, 
+-      0x60, 0x48, 0x20, 0x00, 0x43, 0xc0, 0x00, 0xe9, 
+-      0x4b, 0x45, 0x18, 0xc9, 0x64, 0x08, 0x20, 0x00, 
+-      0x43, 0xc0, 0x00, 0xe9, 0x4b, 0x42, 0x18, 0xc9, 
+-      0x64, 0x48, 0x20, 0x01, 0x90, 0x01, 0x20, 0x01, 
+-      0x40, 0xa8, 0x40, 0x20, 0xd1, 0x01, 0x20, 0x00, 
+-      0x90, 0x01, 0x20, 0x01, 0x40, 0xa8, 0x43, 0xc0, 
+-      0x40, 0x04, 0x1c, 0x3e, 0x42, 0xbd, 0xd9, 0x23, 
+-      0x00, 0xb0, 0x49, 0x37, 0x58, 0x08, 0x28, 0x00, 
+-      0xd0, 0x01, 0x36, 0x01, 0xe7, 0xf8, 0x1e, 0x70, 
+-      0x90, 0x04, 0x98, 0x04, 0x42, 0xb8, 0xda, 0x04, 
+-      0xe0, 0x07, 0x98, 0x04, 0x38, 0x01, 0x90, 0x04, 
+-      0xe7, 0xf7, 0x98, 0x04, 0xf7, 0xff, 0xff, 0x32, 
+-      0xe7, 0xf7, 0x20, 0xff, 0x40, 0xb8, 0x90, 0x03, 
+-      0x20, 0xff, 0x40, 0xb0, 0x43, 0xc0, 0x99, 0x03, 
+-      0x40, 0x08, 0x90, 0x03, 0x98, 0x03, 0x00, 0x40, 
+-      0x90, 0x03, 0x00, 0x60, 0x90, 0x00, 0xe0, 0x1f, 
+-      0x00, 0xb0, 0x49, 0x25, 0x58, 0x08, 0x28, 0x00, 
+-      0xd0, 0x01, 0x3e, 0x01, 0xe7, 0xf8, 0x1c, 0x70, 
+-      0x90, 0x04, 0x98, 0x04, 0x42, 0xb8, 0xd9, 0x04, 
+-      0xe0, 0x07, 0x98, 0x04, 0x30, 0x01, 0x90, 0x04, 
+-      0xe7, 0xf7, 0x98, 0x04, 0xf7, 0xff, 0xff, 0x26, 
+-      0xe7, 0xf7, 0x20, 0xff, 0x40, 0xb0, 0x90, 0x03, 
+-      0x20, 0xff, 0x40, 0xb8, 0x43, 0xc0, 0x99, 0x03, 
+-      0x40, 0x08, 0x90, 0x03, 0x08, 0x60, 0x90, 0x00, 
+-      0x98, 0x00, 0x99, 0x03, 0x40, 0x08, 0x90, 0x00, 
+-      0x98, 0x03, 0x43, 0x84, 0x98, 0x00, 0x43, 0x04, 
+-      0x20, 0x01, 0x40, 0xb8, 0x43, 0xc0, 0x40, 0x04, 
+-      0x98, 0x01, 0x40, 0xb8, 0x43, 0x04, 0x99, 0x05, 
+-      0x00, 0xb8, 0x4a, 0x0d, 0x50, 0x11, 0x98, 0x05, 
+-      0x6b, 0x00, 0xf7, 0xfe, 0xfc, 0x92, 0x90, 0x02, 
+-      0x9a, 0x02, 0x1c, 0x39, 0x98, 0x05, 0xf0, 0x00, 
+-      0xf8, 0x15, 0x20, 0x0d, 0x06, 0xc0, 0x60, 0x84, 
+-      0x20, 0x92, 0x49, 0x04, 0x60, 0x08, 0x20, 0x00, 
+-      0xb0, 0x06, 0xe7, 0x25, 0xb0, 0x06, 0xe7, 0x23, 
+-      0x2e, 0x08, 0x94, 0x84, 0x2e, 0x08, 0x7c, 0xc0, 
+-      0x2e, 0x08, 0x7c, 0x58, 0x2e, 0x08, 0x60, 0x84, 
+-      0x68, 0x00, 0x04, 0x00, 0xb5, 0xf7, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0x01, 0x3d, 0x4b, 0x2f, 0x18, 0xe9, 
+-      0x1d, 0xe2, 0x32, 0x0d, 0x20, 0x00, 0x28, 0x03, 
+-      0xd3, 0x02, 0xe0, 0x04, 0x30, 0x01, 0xe7, 0xfa, 
+-      0xca, 0x20, 0xc1, 0x20, 0xe7, 0xfa, 0x6a, 0xe3, 
+-      0x05, 0x9d, 0x0d, 0xad, 0x00, 0xfe, 0x4b, 0x28, 
+-      0x18, 0xf3, 0x60, 0x1d, 0x6b, 0x63, 0x33, 0x01, 
+-      0x05, 0x9d, 0x0d, 0xad, 0x00, 0xfe, 0x4b, 0x24, 
+-      0x18, 0xf3, 0x60, 0x5d, 0x6a, 0xa5, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x1d, 0x00, 0xfe, 0x4b, 0x20, 
+-      0x18, 0xf3, 0x64, 0x1d, 0x9d, 0x02, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x1d, 0x00, 0xfe, 0x4b, 0x1c, 
+-      0x18, 0xf3, 0x64, 0x5d, 0x4b, 0x1b, 0x68, 0x1b, 
+-      0x2b, 0x01, 0xd1, 0x2a, 0x2f, 0x00, 0xd1, 0x28, 
+-      0x4b, 0x17, 0x68, 0x5d, 0x23, 0x8f, 0x00, 0x9b, 
+-      0x42, 0x9d, 0xd3, 0x03, 0x23, 0x8f, 0x00, 0x9b, 
+-      0x4d, 0x13, 0x60, 0x6b, 0x4b, 0x12, 0x68, 0x1d, 
+-      0x4b, 0x13, 0x42, 0x9d, 0xd3, 0x02, 0x4b, 0x12, 
+-      0x4d, 0x0f, 0x60, 0x2b, 0x4b, 0x0e, 0x6c, 0x5d, 
+-      0x23, 0x01, 0x02, 0x9b, 0x1a, 0xed, 0x23, 0xb3, 
+-      0x00, 0x9b, 0x42, 0x9d, 0xd3, 0x02, 0x4b, 0x0d, 
+-      0x4d, 0x09, 0x64, 0x6b, 0x4b, 0x08, 0x6c, 0x1d, 
+-      0x23, 0x01, 0x02, 0x9b, 0x1a, 0xed, 0x4b, 0x0a, 
+-      0x42, 0x9d, 0xd3, 0x02, 0x4b, 0x09, 0x4d, 0x04, 
+-      0x64, 0x2b, 0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x68, 0x00, 0x0c, 0x00, 
+-      0x68, 0x00, 0x04, 0x00, 0x2e, 0x08, 0x60, 0x84, 
+-      0x00, 0x00, 0x02, 0x3a, 0x00, 0x00, 0x06, 0xcc, 
+-      0x00, 0x00, 0x02, 0xca, 0x00, 0x00, 0x06, 0xca, 
+-      0xb4, 0xf0, 0x4f, 0x15, 0x4c, 0x15, 0x20, 0x00, 
+-      0x21, 0x00, 0x22, 0x00, 0x43, 0xd2, 0x4d, 0x14, 
+-      0x68, 0x6d, 0x42, 0x85, 0xdd, 0x1b, 0x1c, 0x05, 
+-      0x30, 0x01, 0x00, 0xad, 0x59, 0x7b, 0x42, 0x93, 
+-      0xd0, 0xf9, 0x4d, 0x0f, 0x68, 0x6d, 0x42, 0x85, 
+-      0xda, 0x00, 0xe0, 0x10, 0x31, 0x01, 0x1c, 0x05, 
+-      0x30, 0x01, 0x00, 0xad, 0x59, 0x7a, 0x42, 0x93, 
+-      0xd0, 0xf9, 0x02, 0x95, 0x43, 0x1d, 0x1c, 0x2e, 
+-      0xc4, 0x40, 0x4d, 0x07, 0x68, 0x6d, 0x42, 0x85, 
+-      0xdb, 0x00, 0x31, 0x01, 0xe7, 0xdf, 0x25, 0x0d, 
+-      0x06, 0xed, 0x61, 0x29, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x2e, 0x08, 0x7c, 0xcc, 0x68, 0x00, 0x0d, 0x40, 
+-      0x2e, 0x08, 0x7d, 0x94, 0xb5, 0xf3, 0xb0, 0x82, 
+-      0x9d, 0x02, 0x69, 0x2c, 0x2c, 0x13, 0xd1, 0x05, 
+-      0x20, 0x75, 0xb0, 0x02, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x68, 0xee, 0x48, 0xf8, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x05, 0x2e, 0x19, 
+-      0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0xe0, 0x04, 0x2e, 0x08, 0xd3, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0x28, 0x00, 0xd0, 0x02, 
+-      0x20, 0xff, 0xb0, 0x02, 0xe7, 0xe6, 0x49, 0xef, 
+-      0x20, 0x91, 0xf0, 0x17, 0xff, 0x83, 0x28, 0x92, 
+-      0xd0, 0x03, 0x20, 0x01, 0xf0, 0x09, 0xff, 0x6a, 
+-      0xe7, 0xf5, 0x00, 0xb0, 0x49, 0xea, 0x58, 0x08, 
+-      0x99, 0x02, 0x42, 0x88, 0xd0, 0x05, 0x20, 0x92, 
+-      0x49, 0xe6, 0x60, 0x08, 0x20, 0xff, 0xb0, 0x02, 
+-      0xe7, 0xd0, 0x48, 0xe3, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x16, 0x20, 0x0d, 0x06, 0xc0, 0x68, 0x80, 
+-      0x90, 0x01, 0x99, 0x03, 0x29, 0x01, 0xd1, 0x05, 
+-      0x20, 0x01, 0x40, 0xb0, 0x99, 0x01, 0x43, 0x08, 
+-      0x90, 0x01, 0xe0, 0x05, 0x20, 0x01, 0x40, 0xb0, 
+-      0x43, 0xc0, 0x99, 0x01, 0x40, 0x08, 0x90, 0x01, 
+-      0x98, 0x01, 0x21, 0x0d, 0x06, 0xc9, 0x60, 0x88, 
+-      0x48, 0xd8, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x73, 
+-      0x48, 0xd3, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x6f, 
+-      0x99, 0x03, 0x29, 0x01, 0xd1, 0x6c, 0xb0, 0x83, 
+-      0x1c, 0x30, 0xf0, 0x0a, 0xfe, 0x71, 0x28, 0x01, 
+-      0xd1, 0x05, 0x20, 0x92, 0x49, 0xcd, 0x60, 0x08, 
+-      0x20, 0x00, 0xb0, 0x05, 0xe7, 0x9e, 0x49, 0xce, 
+-      0x20, 0x91, 0xf0, 0x17, 0xff, 0x3b, 0x28, 0x92, 
+-      0xd0, 0x00, 0xe7, 0xf8, 0xf0, 0x0a, 0xfe, 0xbb, 
+-      0x2c, 0x0b, 0xdb, 0x01, 0x2c, 0x12, 0xdd, 0x06, 
+-      0x48, 0xc8, 0x68, 0x00, 0x68, 0x40, 0x30, 0x01, 
+-      0x49, 0xc6, 0x68, 0x09, 0x60, 0x48, 0x20, 0x92, 
+-      0x49, 0xc3, 0x60, 0x08, 0x20, 0x01, 0x49, 0xc3, 
+-      0x68, 0x09, 0x60, 0x08, 0x2c, 0x0b, 0xdb, 0x11, 
+-      0x2c, 0x12, 0xdc, 0x0f, 0x48, 0xbf, 0x68, 0x00, 
+-      0x23, 0x0d, 0x01, 0xdb, 0x18, 0xc0, 0x69, 0x80, 
+-      0x23, 0x01, 0x43, 0x18, 0x49, 0xbb, 0x68, 0x09, 
+-      0x23, 0x0d, 0x01, 0xdb, 0x18, 0xc9, 0x61, 0x88, 
+-      0x27, 0x00, 0xe0, 0xbc, 0x27, 0x00, 0x20, 0x00, 
+-      0x90, 0x01, 0x98, 0x01, 0x28, 0x00, 0xd1, 0x15, 
+-      0x2f, 0x07, 0xd2, 0x13, 0x6a, 0xe8, 0x05, 0x81, 
+-      0x0d, 0x89, 0x1c, 0x38, 0x37, 0x01, 0x00, 0x83, 
+-      0x18, 0x18, 0x00, 0xc0, 0x4a, 0xaf, 0x68, 0x12, 
+-      0x18, 0x80, 0x23, 0x05, 0x02, 0x1b, 0x18, 0xc0, 
+-      0x6f, 0xc0, 0x42, 0x81, 0xda, 0x01, 0x20, 0x01, 
+-      0x90, 0x01, 0xe7, 0xe6, 0x98, 0x01, 0x28, 0x00, 
+-      0xd1, 0x16, 0x2f, 0x18, 0xd2, 0x14, 0x6a, 0xe8, 
+-      0x05, 0x81, 0x0d, 0x89, 0x1c, 0x38, 0x37, 0x01, 
+-      0x23, 0x4c, 0x43, 0x58, 0x4a, 0xa3, 0x68, 0x12, 
+-      0x18, 0x80, 0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 
+-      0x69, 0x40, 0x42, 0x81, 0xda, 0x03, 0xe0, 0x00, 
+-      0xe0, 0xb0, 0x20, 0x01, 0x90, 0x01, 0xe7, 0xe5, 
+-      0x3f, 0x01, 0x6b, 0x28, 0xf7, 0xfe, 0xfb, 0x01, 
+-      0x90, 0x00, 0x2f, 0x07, 0xd2, 0x16, 0x48, 0x99, 
+-      0x68, 0x01, 0x1c, 0x38, 0xf0, 0x0a, 0xf9, 0x0a, 
+-      0x00, 0xb8, 0x19, 0xc0, 0x00, 0xc0, 0x49, 0x95, 
+-      0x68, 0x09, 0x18, 0x40, 0x23, 0x2b, 0x01, 0x5b, 
+-      0x18, 0xc0, 0x9a, 0x00, 0x1c, 0x29, 0xf0, 0x0a, 
+-      0xfa, 0x5f, 0x48, 0x90, 0x68, 0x00, 0xf0, 0x0a, 
+-      0xfe, 0x59, 0xe0, 0x4a, 0x2f, 0x18, 0xd2, 0x48, 
+-      0x1f, 0xf8, 0x49, 0x8c, 0x68, 0x09, 0xf0, 0x0a, 
+-      0xf9, 0x45, 0x20, 0x4c, 0x43, 0x78, 0x49, 0x89, 
+-      0x68, 0x09, 0x18, 0x40, 0x38, 0xff, 0x38, 0xff, 
+-      0x38, 0x0a, 0x9a, 0x00, 0x1c, 0x29, 0xf0, 0x0a, 
+-      0xfa, 0x47, 0x20, 0x4c, 0x43, 0x78, 0x49, 0x83, 
+-      0x68, 0x09, 0x18, 0x40, 0x38, 0xff, 0x38, 0xff, 
+-      0x38, 0x82, 0x6f, 0xc0, 0x28, 0x00, 0xd0, 0x17, 
+-      0x20, 0x4c, 0x43, 0x78, 0x49, 0x7d, 0x68, 0x09, 
+-      0x18, 0x40, 0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 
+-      0x68, 0x00, 0x04, 0x00, 0x0c, 0x00, 0xd0, 0x0b, 
+-      0x20, 0x4c, 0x43, 0x78, 0x49, 0x77, 0x68, 0x09, 
+-      0x18, 0x40, 0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 
+-      0x68, 0x00, 0x0c, 0x00, 0x04, 0x00, 0xd1, 0x0a, 
+-      0x20, 0x02, 0x21, 0x4c, 0x43, 0x79, 0x4a, 0x71, 
+-      0x68, 0x12, 0x18, 0x89, 0x39, 0xff, 0x39, 0xff, 
+-      0x39, 0x82, 0x67, 0x48, 0xe0, 0x09, 0x20, 0x03, 
+-      0x21, 0x4c, 0x43, 0x79, 0x4a, 0x6b, 0x68, 0x12, 
+-      0x18, 0x89, 0x39, 0xff, 0x39, 0xff, 0x39, 0x82, 
+-      0x67, 0x48, 0x48, 0x68, 0x68, 0x00, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc0, 0x69, 0x80, 0x00, 0x40, 
+-      0x90, 0x03, 0x98, 0x03, 0x23, 0x02, 0x43, 0x18, 
+-      0x90, 0x03, 0x48, 0x62, 0x68, 0x00, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc0, 0x69, 0x80, 0x07, 0xc0, 
+-      0x0f, 0xc0, 0x99, 0x03, 0x18, 0x40, 0x90, 0x03, 
+-      0x98, 0x03, 0x49, 0x5c, 0x68, 0x09, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc9, 0x61, 0x88, 0x1c, 0x39, 
+-      0x48, 0x58, 0x68, 0x00, 0xf0, 0x0a, 0xfa, 0x72, 
+-      0x2c, 0x0b, 0xdb, 0x01, 0x2c, 0x12, 0xdd, 0x04, 
+-      0x6b, 0x69, 0x48, 0x54, 0x68, 0x00, 0xf0, 0x0a, 
+-      0xf9, 0x4d, 0x1c, 0x30, 0x21, 0x01, 0xf0, 0x0a, 
+-      0xfd, 0x45, 0x49, 0x4f, 0x20, 0x91, 0xf0, 0x17, 
+-      0xfe, 0x3d, 0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 
+-      0x48, 0x4c, 0x68, 0x00, 0x90, 0x02, 0x48, 0x4c, 
+-      0x68, 0x00, 0x49, 0x4a, 0x60, 0x08, 0x98, 0x02, 
+-      0x49, 0x49, 0x60, 0x08, 0x20, 0x92, 0x49, 0x46, 
+-      0x60, 0x08, 0xb0, 0x03, 0x48, 0x43, 0x68, 0x00, 
+-      0x28, 0x01, 0xd1, 0x75, 0x48, 0x3e, 0x68, 0x00, 
+-      0x28, 0x01, 0xd1, 0x71, 0x99, 0x03, 0x29, 0x00, 
+-      0xd1, 0x6e, 0xb0, 0x85, 0x1c, 0x30, 0xf0, 0x0a, 
+-      0xfd, 0x47, 0x28, 0x00, 0xd1, 0x05, 0x20, 0x92, 
+-      0x49, 0x38, 0x60, 0x08, 0x20, 0x00, 0xb0, 0x07, 
+-      0xe6, 0x74, 0x49, 0x39, 0x20, 0x91, 0xf0, 0x17, 
+-      0xfe, 0x11, 0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 
+-      0xf0, 0x0a, 0xfd, 0x91, 0x2c, 0x0b, 0xdb, 0x01, 
+-      0x2c, 0x12, 0xdd, 0x0b, 0x48, 0x33, 0x68, 0x00, 
+-      0x68, 0x40, 0x28, 0x00, 0xd0, 0x06, 0x48, 0x31, 
+-      0x68, 0x00, 0x68, 0x40, 0x38, 0x01, 0x49, 0x2f, 
+-      0x68, 0x09, 0x60, 0x48, 0x20, 0x92, 0x49, 0x2c, 
+-      0x60, 0x08, 0x20, 0x01, 0x49, 0x2b, 0x68, 0x09, 
+-      0x60, 0x08, 0x2c, 0x0b, 0xdb, 0x11, 0x2c, 0x12, 
+-      0xdc, 0x0f, 0x48, 0x28, 0x68, 0x00, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc0, 0x69, 0x80, 0x08, 0x40, 
+-      0x00, 0x40, 0x49, 0x24, 0x68, 0x09, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc9, 0x61, 0x88, 0x27, 0x00, 
+-      0xe0, 0xb2, 0x27, 0x00, 0x20, 0x00, 0x90, 0x03, 
+-      0x98, 0x03, 0x28, 0x00, 0xd1, 0x15, 0x2f, 0x07, 
+-      0xd2, 0x13, 0x6a, 0xe8, 0x05, 0x81, 0x0d, 0x89, 
+-      0x1c, 0x38, 0x37, 0x01, 0x00, 0x83, 0x18, 0x18, 
+-      0x00, 0xc0, 0x4a, 0x18, 0x68, 0x12, 0x18, 0x80, 
+-      0x23, 0x05, 0x02, 0x1b, 0x18, 0xc0, 0x6f, 0xc0, 
+-      0x42, 0x81, 0xd1, 0x01, 0x20, 0x01, 0x90, 0x03, 
+-      0xe7, 0xe6, 0x98, 0x03, 0x28, 0x00, 0xd1, 0x26, 
+-      0x2f, 0x18, 0xd2, 0x24, 0x6a, 0xe8, 0x05, 0x81, 
+-      0x0d, 0x89, 0x1c, 0x38, 0x37, 0x01, 0x23, 0x4c, 
+-      0x43, 0x58, 0x4a, 0x0c, 0x68, 0x12, 0x18, 0x80, 
+-      0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 0xe0, 0x00, 
+-      0xe0, 0xa9, 0x69, 0x40, 0x42, 0x81, 0xd1, 0x11, 
+-      0x20, 0x01, 0x90, 0x03, 0xe0, 0x0e, 0x00, 0x00, 
+-      0x2e, 0x08, 0x94, 0x84, 0x2e, 0x08, 0x7c, 0xc0, 
+-      0x2e, 0x08, 0x7c, 0x58, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x94, 0x88, 0x2e, 0x08, 0x7d, 0xb4, 
+-      0x2e, 0x08, 0x7d, 0xb8, 0xe7, 0xd5, 0x3f, 0x01, 
+-      0x6b, 0x28, 0xf7, 0xfe, 0xf9, 0xc2, 0x90, 0x01, 
+-      0x2f, 0x07, 0xd2, 0x09, 0x48, 0x4a, 0x68, 0x01, 
+-      0x1c, 0x38, 0xf0, 0x0a, 0xf8, 0x3d, 0x48, 0x48, 
+-      0x68, 0x00, 0xf0, 0x0a, 0xfd, 0x27, 0xe0, 0x06, 
+-      0x2f, 0x18, 0xd2, 0x04, 0x1f, 0xf8, 0x49, 0x44, 
+-      0x68, 0x09, 0xf0, 0x0a, 0xf8, 0x6f, 0x48, 0x42, 
+-      0x68, 0x00, 0x4b, 0x42, 0x18, 0xc0, 0xf0, 0x0a, 
+-      0xf9, 0x8f, 0x20, 0x00, 0x49, 0x3e, 0x68, 0x09, 
+-      0x23, 0x09, 0x01, 0xdb, 0x18, 0xc9, 0x64, 0x88, 
+-      0x48, 0x3b, 0x68, 0x00, 0x68, 0x40, 0x28, 0x07, 
+-      0xd3, 0x0e, 0x48, 0x39, 0x68, 0x00, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc0, 0x69, 0x80, 0x23, 0xfe, 
+-      0x43, 0x18, 0x49, 0x35, 0x68, 0x09, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc9, 0x61, 0x88, 0xe0, 0x33, 
+-      0x20, 0x01, 0x90, 0x00, 0x21, 0x00, 0x91, 0x02, 
+-      0x48, 0x2f, 0x68, 0x00, 0x68, 0x40, 0x99, 0x02, 
+-      0x42, 0x88, 0xd8, 0x04, 0xe0, 0x08, 0x99, 0x02, 
+-      0x31, 0x01, 0x91, 0x02, 0xe7, 0xf4, 0x98, 0x00, 
+-      0x00, 0x40, 0x30, 0x01, 0x90, 0x00, 0xe7, 0xf6, 
+-      0x98, 0x00, 0x08, 0x40, 0x00, 0x40, 0x90, 0x00, 
+-      0x48, 0x25, 0x68, 0x00, 0x23, 0x0d, 0x01, 0xdb, 
+-      0x18, 0xc0, 0x69, 0x80, 0x07, 0xc0, 0x0f, 0xc0, 
+-      0x49, 0x21, 0x68, 0x09, 0x23, 0x0d, 0x01, 0xdb, 
+-      0x18, 0xc9, 0x61, 0x88, 0x48, 0x1e, 0x68, 0x00, 
+-      0x23, 0x0d, 0x01, 0xdb, 0x18, 0xc0, 0x69, 0x80, 
+-      0x99, 0x00, 0x43, 0x08, 0x49, 0x1a, 0x68, 0x09, 
+-      0x23, 0x0d, 0x01, 0xdb, 0x18, 0xc9, 0x61, 0x88, 
+-      0x1c, 0x39, 0x48, 0x17, 0x68, 0x00, 0xf0, 0x0a, 
+-      0xf9, 0x4d, 0x2c, 0x0b, 0xdb, 0x01, 0x2c, 0x12, 
+-      0xdd, 0x04, 0x6b, 0x69, 0x48, 0x12, 0x68, 0x00, 
+-      0xf0, 0x0a, 0xf8, 0x7e, 0x1c, 0x30, 0x21, 0x00, 
+-      0xf0, 0x0a, 0xfc, 0x20, 0x49, 0x10, 0x20, 0x91, 
+-      0xf0, 0x17, 0xfd, 0x18, 0x28, 0x92, 0xd0, 0x00, 
+-      0xe7, 0xf8, 0x48, 0x0b, 0x68, 0x00, 0x90, 0x04, 
+-      0x48, 0x0c, 0x68, 0x00, 0x49, 0x08, 0x60, 0x08, 
+-      0x98, 0x04, 0x49, 0x0a, 0x60, 0x08, 0x20, 0x92, 
+-      0x49, 0x07, 0x60, 0x08, 0xb0, 0x05, 0x20, 0x92, 
+-      0x49, 0x07, 0x60, 0x08, 0x20, 0x00, 0xb0, 0x02, 
+-      0xe5, 0x60, 0xb0, 0x02, 0xe5, 0x5e, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7d, 0xb4, 0x00, 0x00, 0x04, 0xcc, 
+-      0x2e, 0x08, 0x94, 0x88, 0x2e, 0x08, 0x7d, 0xb8, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0xb5, 0xf3, 0x1c, 0x07, 
+-      0x1c, 0x3e, 0x69, 0x30, 0x28, 0x13, 0xd1, 0x04, 
+-      0x20, 0x75, 0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x68, 0xf4, 0x48, 0x1e, 0x68, 0x00, 
+-      0x28, 0x00, 0xd0, 0x05, 0x2c, 0x19, 0xd3, 0x01, 
+-      0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 0xe0, 0x04, 
+-      0x2c, 0x08, 0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 
+-      0x20, 0x00, 0x28, 0x00, 0xd0, 0x01, 0x20, 0xff, 
+-      0xe7, 0xe7, 0x49, 0x16, 0x20, 0x91, 0xf0, 0x17, 
+-      0xfc, 0xd1, 0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 
+-      0xf0, 0x09, 0xfc, 0xb8, 0xe7, 0xf5, 0x00, 0xa0, 
+-      0x49, 0x11, 0x58, 0x08, 0x42, 0xb8, 0xd0, 0x04, 
+-      0x20, 0x92, 0x49, 0x0e, 0x60, 0x08, 0x20, 0xff, 
+-      0xe7, 0xd3, 0x20, 0x0d, 0x06, 0xc0, 0x68, 0x80, 
+-      0x1c, 0x05, 0x20, 0x01, 0x40, 0xa0, 0x40, 0x05, 
+-      0x2d, 0x00, 0xd1, 0x03, 0x20, 0x00, 0x99, 0x01, 
+-      0x60, 0x08, 0xe0, 0x02, 0x20, 0x01, 0x99, 0x01, 
+-      0x60, 0x08, 0x20, 0x92, 0x49, 0x03, 0x60, 0x08, 
+-      0x20, 0x00, 0xe7, 0xbe, 0xe7, 0xbd, 0x00, 0x00, 
+-      0x2e, 0x08, 0x94, 0x84, 0x2e, 0x08, 0x7c, 0xc0, 
+-      0x2e, 0x08, 0x7c, 0x58, 0xb5, 0xf3, 0x1c, 0x07, 
+-      0xb0, 0x81, 0x1c, 0x3c, 0x68, 0xe5, 0x69, 0x60, 
+-      0x4b, 0x49, 0x40, 0x18, 0x99, 0x02, 0x07, 0x89, 
+-      0x0f, 0x89, 0x02, 0x09, 0x43, 0x08, 0x61, 0x60, 
+-      0x05, 0x80, 0x48, 0x46, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x05, 0x2d, 0x19, 0xd3, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0xe0, 0x04, 0x2d, 0x08, 
+-      0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0x28, 0x00, 0xd0, 0x05, 0x20, 0x00, 0xb0, 0x01, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x49, 0x3b, 0x20, 0x91, 0xf0, 0x17, 0xfc, 0x7a, 
+-      0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 0xf0, 0x09, 
+-      0xfc, 0x61, 0xe7, 0xf5, 0x00, 0xa8, 0x49, 0x37, 
+-      0x58, 0x08, 0x42, 0xb8, 0xd0, 0x05, 0x20, 0x92, 
+-      0x49, 0x33, 0x60, 0x08, 0x20, 0xff, 0xb0, 0x01, 
+-      0xe7, 0xe6, 0x48, 0x30, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x05, 0x69, 0x20, 0x28, 0x0b, 0xdb, 0x0c, 
+-      0x69, 0x20, 0x28, 0x12, 0xdc, 0x09, 0x01, 0x28, 
+-      0x4b, 0x2d, 0x18, 0xc1, 0x91, 0x00, 0x1d, 0xe6, 
+-      0x36, 0x0d, 0x68, 0x30, 0x99, 0x00, 0x60, 0x08, 
+-      0xe0, 0x41, 0x48, 0x26, 0x68, 0x00, 0x28, 0x01, 
+-      0xd1, 0x3d, 0x48, 0x28, 0x68, 0x00, 0x28, 0x01, 
+-      0xd1, 0x39, 0xb0, 0x82, 0x1c, 0x28, 0xf0, 0x0a, 
+-      0xfb, 0x73, 0x28, 0x00, 0xd1, 0x05, 0x20, 0x92, 
+-      0x49, 0x1f, 0x60, 0x08, 0x20, 0x00, 0xb0, 0x03, 
+-      0xe7, 0xbe, 0x49, 0x21, 0x20, 0x91, 0xf0, 0x17, 
+-      0xfc, 0x3d, 0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 
+-      0xf0, 0x0a, 0xfb, 0xbd, 0x20, 0x92, 0x49, 0x1c, 
+-      0x60, 0x08, 0x20, 0x01, 0x49, 0x1b, 0x68, 0x09, 
+-      0x60, 0x08, 0x48, 0x1a, 0x68, 0x01, 0x1c, 0x20, 
+-      0xf0, 0x0a, 0xfb, 0x6e, 0x90, 0x00, 0x69, 0x60, 
+-      0x99, 0x00, 0x60, 0xc8, 0x49, 0x14, 0x20, 0x91, 
+-      0xf0, 0x17, 0xfc, 0x24, 0x28, 0x92, 0xd0, 0x00, 
+-      0xe7, 0xf8, 0x48, 0x12, 0x68, 0x00, 0x90, 0x01, 
+-      0x48, 0x11, 0x68, 0x00, 0x49, 0x0f, 0x60, 0x08, 
+-      0x98, 0x01, 0x49, 0x0f, 0x60, 0x08, 0x20, 0x92, 
+-      0x49, 0x0b, 0x60, 0x08, 0xb0, 0x02, 0x20, 0x92, 
+-      0x49, 0x05, 0x60, 0x08, 0x20, 0x00, 0xb0, 0x01, 
+-      0xe7, 0x8a, 0xb0, 0x01, 0xe7, 0x88, 0x00, 0x00, 
+-      0xff, 0xff, 0xfc, 0xff, 0x2e, 0x08, 0x94, 0x84, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0x2e, 0x08, 0x7c, 0x58, 
+-      0x68, 0x00, 0x0c, 0x00, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x94, 0x88, 0x2e, 0x08, 0x7d, 0xb4, 
+-      0x2e, 0x08, 0x7d, 0xb8, 0xb5, 0xf3, 0x1c, 0x07, 
+-      0xb0, 0x81, 0x1c, 0x3c, 0x68, 0xe5, 0x69, 0x60, 
+-      0x4b, 0x49, 0x40, 0x18, 0x99, 0x02, 0x07, 0x09, 
+-      0x0f, 0x09, 0x02, 0x89, 0x43, 0x08, 0x61, 0x60, 
+-      0x04, 0x80, 0x48, 0x46, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x05, 0x2d, 0x19, 0xd3, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0xe0, 0x04, 0x2d, 0x08, 
+-      0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0x28, 0x00, 0xd0, 0x05, 0x20, 0x00, 0xb0, 0x01, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x49, 0x3b, 0x20, 0x91, 0xf0, 0x17, 0xfb, 0xce, 
+-      0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 0xf0, 0x09, 
+-      0xfb, 0xb5, 0xe7, 0xf5, 0x00, 0xa8, 0x49, 0x37, 
+-      0x58, 0x08, 0x42, 0xb8, 0xd0, 0x05, 0x20, 0x92, 
+-      0x49, 0x33, 0x60, 0x08, 0x20, 0xff, 0xb0, 0x01, 
+-      0xe7, 0xe6, 0x48, 0x30, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x05, 0x69, 0x20, 0x28, 0x0b, 0xdb, 0x0c, 
+-      0x69, 0x20, 0x28, 0x12, 0xdc, 0x09, 0x01, 0x28, 
+-      0x4b, 0x2d, 0x18, 0xc6, 0x1d, 0xe0, 0x30, 0x0d, 
+-      0x90, 0x00, 0x98, 0x00, 0x68, 0x00, 0x60, 0x30, 
+-      0xe0, 0x41, 0x48, 0x26, 0x68, 0x00, 0x28, 0x01, 
+-      0xd1, 0x3d, 0x48, 0x28, 0x68, 0x00, 0x28, 0x01, 
+-      0xd1, 0x39, 0xb0, 0x82, 0x1c, 0x28, 0xf0, 0x0a, 
+-      0xfa, 0xc7, 0x28, 0x00, 0xd1, 0x05, 0x20, 0x92, 
+-      0x49, 0x1f, 0x60, 0x08, 0x20, 0x00, 0xb0, 0x03, 
+-      0xe7, 0xbe, 0x49, 0x21, 0x20, 0x91, 0xf0, 0x17, 
+-      0xfb, 0x91, 0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 
+-      0xf0, 0x0a, 0xfb, 0x11, 0x20, 0x92, 0x49, 0x1c, 
+-      0x60, 0x08, 0x20, 0x01, 0x49, 0x1b, 0x68, 0x09, 
+-      0x60, 0x08, 0x48, 0x1a, 0x68, 0x01, 0x1c, 0x20, 
+-      0xf0, 0x0a, 0xfa, 0xc2, 0x90, 0x00, 0x69, 0x60, 
+-      0x99, 0x00, 0x60, 0xc8, 0x49, 0x14, 0x20, 0x91, 
+-      0xf0, 0x17, 0xfb, 0x78, 0x28, 0x92, 0xd0, 0x00, 
+-      0xe7, 0xf8, 0x48, 0x12, 0x68, 0x00, 0x90, 0x01, 
+-      0x48, 0x11, 0x68, 0x00, 0x49, 0x0f, 0x60, 0x08, 
+-      0x98, 0x01, 0x49, 0x0f, 0x60, 0x08, 0x20, 0x92, 
+-      0x49, 0x0b, 0x60, 0x08, 0xb0, 0x02, 0x20, 0x92, 
+-      0x49, 0x05, 0x60, 0x08, 0x20, 0x00, 0xb0, 0x01, 
+-      0xe7, 0x8a, 0xb0, 0x01, 0xe7, 0x88, 0x00, 0x00, 
+-      0xff, 0xff, 0xc3, 0xff, 0x2e, 0x08, 0x94, 0x84, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0x2e, 0x08, 0x7c, 0x58, 
+-      0x68, 0x00, 0x0c, 0x00, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x94, 0x88, 0x2e, 0x08, 0x7d, 0xb4, 
+-      0x2e, 0x08, 0x7d, 0xb8, 0xb5, 0xf3, 0x1c, 0x07, 
+-      0xb0, 0x82, 0x1c, 0x3c, 0x68, 0xe5, 0x26, 0x00, 
+-      0x99, 0x03, 0x29, 0x01, 0xd1, 0x00, 0x26, 0x01, 
+-      0x69, 0x60, 0x06, 0x80, 0x0f, 0xc0, 0x42, 0xb0, 
+-      0xd1, 0x05, 0x20, 0x00, 0xb0, 0x02, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x69, 0x60, 
+-      0x23, 0x20, 0x43, 0xdb, 0x40, 0x18, 0x07, 0xf1, 
+-      0x0e, 0x89, 0x43, 0x08, 0x61, 0x60, 0x06, 0x80, 
+-      0x48, 0x44, 0x68, 0x00, 0x28, 0x00, 0xd0, 0x05, 
+-      0x2d, 0x19, 0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 
+-      0x20, 0x00, 0xe0, 0x04, 0x2d, 0x08, 0xd3, 0x01, 
+-      0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 0x28, 0x00, 
+-      0xd0, 0x02, 0x20, 0x00, 0xb0, 0x02, 0xe7, 0xde, 
+-      0x49, 0x3b, 0x20, 0x91, 0xf0, 0x17, 0xfb, 0x16, 
+-      0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 0xf0, 0x09, 
+-      0xfa, 0xfd, 0xe7, 0xf5, 0x00, 0xa8, 0x49, 0x37, 
+-      0x58, 0x08, 0x42, 0xb8, 0xd0, 0x05, 0x20, 0x92, 
+-      0x49, 0x33, 0x60, 0x08, 0x20, 0xff, 0xb0, 0x02, 
+-      0xe7, 0xc9, 0x48, 0x30, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x05, 0x69, 0x20, 0x28, 0x0b, 0xdb, 0x0e, 
+-      0x69, 0x20, 0x28, 0x12, 0xdc, 0x0b, 0x01, 0x28, 
+-      0x4b, 0x2d, 0x18, 0xc1, 0x91, 0x01, 0x1d, 0xe0, 
+-      0x30, 0x0d, 0x90, 0x00, 0x98, 0x00, 0x68, 0x00, 
+-      0x99, 0x01, 0x60, 0x08, 0xe0, 0x41, 0x48, 0x25, 
+-      0x68, 0x00, 0x28, 0x01, 0xd1, 0x3d, 0x48, 0x27, 
+-      0x68, 0x00, 0x28, 0x01, 0xd1, 0x39, 0xb0, 0x82, 
+-      0x1c, 0x28, 0xf0, 0x0a, 0xfa, 0x0d, 0x28, 0x00, 
+-      0xd1, 0x05, 0x20, 0x92, 0x49, 0x1e, 0x60, 0x08, 
+-      0x20, 0x00, 0xb0, 0x04, 0xe7, 0x9f, 0x49, 0x20, 
+-      0x20, 0x91, 0xf0, 0x17, 0xfa, 0xd7, 0x28, 0x92, 
+-      0xd0, 0x00, 0xe7, 0xf8, 0xf0, 0x0a, 0xfa, 0x57, 
+-      0x20, 0x92, 0x49, 0x1b, 0x60, 0x08, 0x20, 0x01, 
+-      0x49, 0x1a, 0x68, 0x09, 0x60, 0x08, 0x48, 0x19, 
+-      0x68, 0x01, 0x1c, 0x20, 0xf0, 0x0a, 0xfa, 0x08, 
+-      0x90, 0x00, 0x69, 0x60, 0x99, 0x00, 0x60, 0xc8, 
+-      0x49, 0x13, 0x20, 0x91, 0xf0, 0x17, 0xfa, 0xbe, 
+-      0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 0x48, 0x11, 
+-      0x68, 0x00, 0x90, 0x01, 0x48, 0x10, 0x68, 0x00, 
+-      0x49, 0x0e, 0x60, 0x08, 0x98, 0x01, 0x49, 0x0e, 
+-      0x60, 0x08, 0x20, 0x92, 0x49, 0x0a, 0x60, 0x08, 
+-      0xb0, 0x02, 0x20, 0x92, 0x49, 0x04, 0x60, 0x08, 
+-      0x20, 0x00, 0xb0, 0x02, 0xe7, 0x6b, 0xb0, 0x02, 
+-      0xe7, 0x69, 0x00, 0x00, 0x2e, 0x08, 0x94, 0x84, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0x2e, 0x08, 0x7c, 0x58, 
+-      0x68, 0x00, 0x0c, 0x00, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x94, 0x88, 0x2e, 0x08, 0x7d, 0xb4, 
+-      0x2e, 0x08, 0x7d, 0xb8, 0xb5, 0xf0, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0xb0, 0x83, 0x1c, 0x25, 0x69, 0x28, 
+-      0x28, 0x13, 0xd1, 0x04, 0x20, 0x75, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x68, 0xee, 
+-      0x20, 0x04, 0x40, 0x38, 0x08, 0x81, 0x91, 0x02, 
+-      0x69, 0x68, 0x23, 0xc0, 0x43, 0xdb, 0x40, 0x18, 
+-      0x07, 0xb9, 0x0f, 0x89, 0x01, 0x89, 0x43, 0x08, 
+-      0x61, 0x68, 0x06, 0x00, 0x69, 0x68, 0x4b, 0x48, 
+-      0x40, 0x18, 0x99, 0x02, 0x07, 0xc9, 0x0c, 0x49, 
+-      0x43, 0x08, 0x61, 0x68, 0x04, 0x40, 0x48, 0x45, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x05, 0x2e, 0x19, 
+-      0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0xe0, 0x04, 0x2e, 0x08, 0xd3, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0x28, 0x00, 0xd0, 0x02, 
+-      0x20, 0x00, 0xb0, 0x03, 0xe7, 0xd0, 0x49, 0x3c, 
+-      0x20, 0x91, 0xf0, 0x17, 0xfa, 0x57, 0x28, 0x92, 
+-      0xd0, 0x03, 0x20, 0x01, 0xf0, 0x09, 0xfa, 0x3e, 
+-      0xe7, 0xf5, 0x00, 0xb0, 0x49, 0x37, 0x58, 0x08, 
+-      0x42, 0xa0, 0xd0, 0x05, 0x20, 0x92, 0x49, 0x34, 
+-      0x60, 0x08, 0x20, 0xff, 0xb0, 0x03, 0xe7, 0xbb, 
+-      0x48, 0x30, 0x68, 0x00, 0x28, 0x00, 0xd0, 0x05, 
+-      0x69, 0x28, 0x28, 0x0b, 0xdb, 0x0e, 0x69, 0x28, 
+-      0x28, 0x12, 0xdc, 0x0b, 0x01, 0x30, 0x4b, 0x2e, 
+-      0x18, 0xc0, 0x90, 0x01, 0x1d, 0xe8, 0x30, 0x0d, 
+-      0x90, 0x00, 0x98, 0x00, 0x68, 0x00, 0x99, 0x01, 
+-      0x60, 0x08, 0xe0, 0x41, 0x48, 0x25, 0x68, 0x00, 
+-      0x28, 0x01, 0xd1, 0x3d, 0x48, 0x27, 0x68, 0x00, 
+-      0x28, 0x01, 0xd1, 0x39, 0xb0, 0x82, 0x1c, 0x30, 
+-      0xf0, 0x0a, 0xf9, 0x4e, 0x28, 0x00, 0xd1, 0x05, 
+-      0x20, 0x92, 0x49, 0x1f, 0x60, 0x08, 0x20, 0x00, 
+-      0xb0, 0x05, 0xe7, 0x91, 0x49, 0x20, 0x20, 0x91, 
+-      0xf0, 0x17, 0xfa, 0x18, 0x28, 0x92, 0xd0, 0x00, 
+-      0xe7, 0xf8, 0xf0, 0x0a, 0xf9, 0x98, 0x20, 0x92, 
+-      0x49, 0x1b, 0x60, 0x08, 0x20, 0x01, 0x49, 0x1b, 
+-      0x68, 0x09, 0x60, 0x08, 0x48, 0x19, 0x68, 0x01, 
+-      0x1c, 0x28, 0xf0, 0x0a, 0xf9, 0x49, 0x90, 0x00, 
+-      0x69, 0x68, 0x99, 0x00, 0x60, 0xc8, 0x49, 0x14, 
+-      0x20, 0x91, 0xf0, 0x17, 0xf9, 0xff, 0x28, 0x92, 
+-      0xd0, 0x00, 0xe7, 0xf8, 0x48, 0x11, 0x68, 0x00, 
+-      0x90, 0x01, 0x48, 0x11, 0x68, 0x00, 0x49, 0x0f, 
+-      0x60, 0x08, 0x98, 0x01, 0x49, 0x0e, 0x60, 0x08, 
+-      0x20, 0x92, 0x49, 0x0b, 0x60, 0x08, 0xb0, 0x02, 
+-      0x20, 0x92, 0x49, 0x05, 0x60, 0x08, 0x20, 0x00, 
+-      0xb0, 0x03, 0xe7, 0x5d, 0xb0, 0x03, 0xe7, 0x5b, 
+-      0xff, 0xff, 0xbf, 0xff, 0x2e, 0x08, 0x94, 0x84, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0x2e, 0x08, 0x7c, 0x58, 
+-      0x68, 0x00, 0x0c, 0x00, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x94, 0x88, 0x2e, 0x08, 0x7d, 0xb4, 
+-      0x2e, 0x08, 0x7d, 0xb8, 0x1c, 0x01, 0x20, 0x0d, 
+-      0x06, 0xc0, 0x60, 0x41, 0x48, 0x02, 0x63, 0x81, 
+-      0x20, 0x00, 0x47, 0x70, 0xe7, 0xfd, 0x00, 0x00, 
+-      0x68, 0x00, 0x0d, 0x00, 0x20, 0x0d, 0x06, 0xc0, 
+-      0x68, 0x40, 0x02, 0x00, 0x0a, 0x00, 0x47, 0x70, 
+-      0xe7, 0xfd, 0x1c, 0x01, 0x1c, 0x0a, 0x68, 0xd0, 
+-      0x47, 0x70, 0xe7, 0xfd, 0x1c, 0x03, 0x1c, 0x0a, 
+-      0x1c, 0x19, 0x69, 0x08, 0x28, 0x13, 0xd1, 0x01, 
+-      0x20, 0x75, 0x47, 0x70, 0x69, 0x08, 0x28, 0x0b, 
+-      0xdb, 0x0b, 0x69, 0x08, 0x28, 0x12, 0xdc, 0x08, 
+-      0x6d, 0x08, 0x60, 0x10, 0x6d, 0x88, 0x60, 0x90, 
+-      0x6d, 0x48, 0x60, 0x50, 0x6d, 0xc8, 0x60, 0xd0, 
+-      0xe0, 0x07, 0x6a, 0x88, 0x60, 0x10, 0x6b, 0x08, 
+-      0x60, 0x90, 0x6a, 0xc8, 0x60, 0x50, 0x6b, 0x48, 
+-      0x60, 0xd0, 0x20, 0x00, 0xe7, 0xe5, 0xe7, 0xe4, 
+-      0x1c, 0x03, 0x1c, 0x0a, 0x68, 0x10, 0x60, 0x18, 
+-      0x68, 0x90, 0x60, 0x98, 0x68, 0x50, 0x60, 0x58, 
+-      0x68, 0xd0, 0x60, 0xd8, 0x47, 0x70, 0xe7, 0xfd, 
+-      0x1c, 0x01, 0x1c, 0x0a, 0x69, 0x50, 0x05, 0x80, 
+-      0x0f, 0x80, 0x47, 0x70, 0xe7, 0xfd, 0x1c, 0x01, 
+-      0x1c, 0x0a, 0x69, 0x50, 0x12, 0x80, 0x07, 0x00, 
+-      0x0f, 0x00, 0x47, 0x70, 0xe7, 0xfd, 0xb4, 0x80, 
+-      0x1c, 0x01, 0x1c, 0x0f, 0x22, 0x01, 0x69, 0x78, 
+-      0x23, 0x20, 0x40, 0x18, 0xd1, 0x00, 0x22, 0x00, 
+-      0x1c, 0x10, 0xbc, 0x80, 0x47, 0x70, 0xe7, 0xfc, 
+-      0x1c, 0x01, 0x1c, 0x0b, 0x69, 0x18, 0x28, 0x13, 
+-      0xd1, 0x01, 0x20, 0x75, 0x47, 0x70, 0x69, 0x58, 
+-      0x06, 0x00, 0x0f, 0x82, 0x69, 0x58, 0x04, 0x40, 
+-      0x0f, 0xc0, 0x00, 0x80, 0x43, 0x02, 0x1c, 0x10, 
+-      0xe7, 0xf4, 0xe7, 0xf3, 0x1c, 0x01, 0x20, 0x0d, 
+-      0x06, 0xc0, 0x61, 0x41, 0x20, 0x00, 0x47, 0x70, 
+-      0xe7, 0xfd, 0x20, 0x0d, 0x06, 0xc0, 0x69, 0x40, 
+-      0x1c, 0x01, 0x1c, 0x08, 0x47, 0x70, 0xe7, 0xfd, 
+-      0x1c, 0x01, 0x22, 0x00, 0x29, 0x01, 0xd1, 0x00, 
+-      0x22, 0x01, 0x20, 0x0d, 0x06, 0xc0, 0x68, 0xc0, 
+-      0x1c, 0x03, 0x2b, 0x02, 0xd1, 0x01, 0x29, 0x00, 
+-      0xd1, 0x02, 0x20, 0x0d, 0x06, 0xc0, 0x60, 0xc2, 
+-      0x20, 0x00, 0x47, 0x70, 0xe7, 0xfd, 0x21, 0x01, 
+-      0x20, 0x0d, 0x06, 0xc0, 0x68, 0xc0, 0x1c, 0x02, 
+-      0x2a, 0x00, 0xd1, 0x00, 0x21, 0x00, 0x1c, 0x08, 
+-      0x47, 0x70, 0xe7, 0xfd, 0x1c, 0x01, 0x1c, 0x0a, 
+-      0x69, 0x10, 0x47, 0x70, 0xe7, 0xfd, 0xb4, 0x90, 
+-      0x1c, 0x07, 0x1c, 0x0a, 0x1c, 0x39, 0x69, 0x08, 
+-      0x28, 0x13, 0xd0, 0x05, 0x69, 0x08, 0x28, 0x0b, 
+-      0xdb, 0x05, 0x69, 0x08, 0x28, 0x12, 0xdc, 0x02, 
+-      0x20, 0x86, 0xbc, 0x90, 0x47, 0x70, 0x6b, 0x8c, 
+-      0x69, 0x48, 0x23, 0x04, 0x40, 0x18, 0xd0, 0x00, 
+-      0x08, 0x64, 0x69, 0x08, 0x00, 0x80, 0x4b, 0x03, 
+-      0x58, 0x18, 0x43, 0x60, 0x60, 0x10, 0x20, 0x00, 
+-      0xe7, 0xef, 0xe7, 0xee, 0x2e, 0x03, 0x3a, 0x54, 
+-      0xb5, 0xf3, 0x1c, 0x07, 0xb0, 0x81, 0x9c, 0x02, 
+-      0x69, 0x20, 0x28, 0x13, 0xd0, 0x05, 0x69, 0x20, 
+-      0x28, 0x0b, 0xdb, 0x08, 0x69, 0x20, 0x28, 0x12, 
+-      0xdc, 0x05, 0x20, 0x86, 0xb0, 0x01, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x68, 0xe5, 
+-      0x68, 0x38, 0x64, 0x20, 0x68, 0x7e, 0x64, 0x66, 
+-      0x08, 0xb6, 0x61, 0xa6, 0x48, 0x3f, 0x68, 0x00, 
+-      0x28, 0x00, 0xd0, 0x05, 0x2d, 0x19, 0xd3, 0x01, 
+-      0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 0xe0, 0x04, 
+-      0x2d, 0x08, 0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 
+-      0x20, 0x00, 0x28, 0x00, 0xd0, 0x02, 0x20, 0x00, 
+-      0xb0, 0x01, 0xe7, 0xe0, 0x49, 0x36, 0x20, 0x91, 
+-      0xf0, 0x17, 0xf8, 0xdc, 0x28, 0x92, 0xd0, 0x03, 
+-      0x20, 0x01, 0xf0, 0x09, 0xf8, 0xc3, 0xe7, 0xf5, 
+-      0x00, 0xa8, 0x49, 0x32, 0x58, 0x08, 0x99, 0x02, 
+-      0x42, 0x88, 0xd0, 0x05, 0x20, 0x92, 0x49, 0x2e, 
+-      0x60, 0x08, 0x20, 0x86, 0xb0, 0x01, 0xe7, 0xca, 
+-      0x48, 0x2a, 0x68, 0x00, 0x28, 0x00, 0xd1, 0x06, 
+-      0x01, 0x28, 0x4b, 0x2b, 0x18, 0xc0, 0x90, 0x00, 
+-      0x98, 0x00, 0x60, 0x06, 0xe0, 0x41, 0x48, 0x25, 
+-      0x68, 0x00, 0x28, 0x01, 0xd1, 0x3d, 0x48, 0x27, 
+-      0x68, 0x00, 0x28, 0x01, 0xd1, 0x39, 0xb0, 0x82, 
+-      0x1c, 0x28, 0xf0, 0x09, 0xff, 0xdd, 0x28, 0x00, 
+-      0xd1, 0x05, 0x20, 0x92, 0x49, 0x1e, 0x60, 0x08, 
+-      0x20, 0x00, 0xb0, 0x03, 0xe7, 0xab, 0x49, 0x20, 
+-      0x20, 0x91, 0xf0, 0x17, 0xf8, 0xa7, 0x28, 0x92, 
+-      0xd0, 0x00, 0xe7, 0xf8, 0xf0, 0x0a, 0xf8, 0x27, 
+-      0x20, 0x92, 0x49, 0x1b, 0x60, 0x08, 0x20, 0x01, 
+-      0x49, 0x1a, 0x68, 0x09, 0x60, 0x08, 0x48, 0x19, 
+-      0x68, 0x01, 0x1c, 0x20, 0xf0, 0x09, 0xff, 0xd8, 
+-      0x90, 0x00, 0x69, 0xa0, 0x99, 0x00, 0x61, 0x08, 
+-      0x49, 0x13, 0x20, 0x91, 0xf0, 0x17, 0xf8, 0x8e, 
+-      0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 0x48, 0x11, 
+-      0x68, 0x00, 0x90, 0x01, 0x48, 0x10, 0x68, 0x00, 
+-      0x49, 0x0e, 0x60, 0x08, 0x98, 0x01, 0x49, 0x0e, 
+-      0x60, 0x08, 0x20, 0x92, 0x49, 0x0a, 0x60, 0x08, 
+-      0xb0, 0x02, 0x20, 0x92, 0x49, 0x04, 0x60, 0x08, 
+-      0x20, 0x00, 0xb0, 0x01, 0xe7, 0x77, 0xb0, 0x01, 
+-      0xe7, 0x75, 0x00, 0x00, 0x2e, 0x08, 0x94, 0x84, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0x2e, 0x08, 0x7c, 0x58, 
+-      0x68, 0x00, 0x0c, 0x04, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x94, 0x88, 0x2e, 0x08, 0x7d, 0xb4, 
+-      0x2e, 0x08, 0x7d, 0xb8, 0xb4, 0x80, 0x1c, 0x01, 
+-      0x06, 0x0b, 0x0e, 0x1b, 0x22, 0x01, 0x2a, 0x19, 
+-      0xd3, 0x02, 0xe0, 0x0f, 0x32, 0x01, 0xe7, 0xfa, 
+-      0x00, 0x90, 0x4f, 0x08, 0x58, 0x38, 0x68, 0x80, 
+-      0x02, 0x00, 0x0e, 0x00, 0x42, 0x98, 0xd1, 0x04, 
+-      0x00, 0x90, 0x4f, 0x04, 0x58, 0x38, 0xbc, 0x80, 
+-      0x47, 0x70, 0xe7, 0xef, 0x20, 0x00, 0xe7, 0xfa, 
+-      0xe7, 0xf9, 0x00, 0x00, 0x2e, 0x08, 0x7c, 0x58, 
+-      0xb4, 0x90, 0x1c, 0x07, 0x1c, 0x0a, 0x06, 0x38, 
+-      0x16, 0x01, 0x48, 0x20, 0x60, 0x02, 0x48, 0x20, 
+-      0x68, 0x80, 0x23, 0x33, 0x06, 0x5b, 0x65, 0xd8, 
+-      0x48, 0x1d, 0x68, 0xc0, 0x23, 0x33, 0x06, 0x5b, 
+-      0x66, 0x18, 0x48, 0x1c, 0x4b, 0x1a, 0x60, 0x98, 
+-      0x48, 0x1b, 0x4b, 0x19, 0x60, 0xd8, 0x20, 0x01, 
+-      0x23, 0x33, 0x06, 0x5b, 0x66, 0xd8, 0x48, 0x19, 
+-      0x68, 0x04, 0x23, 0x01, 0x04, 0xdb, 0x43, 0x23, 
+-      0x60, 0x03, 0x48, 0x16, 0x68, 0x04, 0x23, 0x01, 
+-      0x04, 0xdb, 0x43, 0x9c, 0x1c, 0x23, 0x60, 0x03, 
+-      0x29, 0x00, 0xd1, 0x10, 0x20, 0xff, 0x30, 0x14, 
+-      0x23, 0x1b, 0x06, 0x9b, 0x62, 0x18, 0x48, 0x10, 
+-      0x68, 0x04, 0x23, 0xff, 0x33, 0x01, 0x43, 0x9c, 
+-      0x1c, 0x23, 0x60, 0x03, 0x48, 0x0d, 0x23, 0x1b, 
+-      0x06, 0x9b, 0x64, 0x18, 0xe0, 0x08, 0x20, 0xff, 
+-      0x30, 0x14, 0x23, 0x1b, 0x06, 0x9b, 0x62, 0x18, 
+-      0x48, 0x02, 0x68, 0x00, 0x4b, 0x08, 0x60, 0x18, 
+-      0xbc, 0x90, 0x47, 0x70, 0x2e, 0x08, 0x5e, 0x50, 
+-      0x2e, 0x08, 0x7c, 0x1c, 0xcc, 0x1f, 0xe0, 0x00, 
+-      0xcc, 0x1f, 0xfe, 0x00, 0x6c, 0x00, 0x00, 0x40, 
+-      0x6c, 0x00, 0x00, 0x20, 0x00, 0x00, 0x82, 0x18, 
+-      0x6c, 0x00, 0x00, 0x80, 0xb4, 0xf0, 0x1c, 0x01, 
+-      0xb0, 0x82, 0x23, 0x1b, 0x06, 0x9b, 0x6a, 0x1b, 
+-      0x1c, 0x18, 0x27, 0x00, 0x22, 0x00, 0x08, 0x40, 
+-      0x00, 0x40, 0x4b, 0xaf, 0x68, 0x1c, 0x08, 0x64, 
+-      0x00, 0x64, 0x60, 0x1c, 0x4b, 0xad, 0x68, 0x1b, 
+-      0x1c, 0x1d, 0x23, 0x1b, 0x06, 0x9b, 0x6c, 0x1b, 
+-      0x93, 0x01, 0x23, 0xff, 0x33, 0x01, 0x40, 0x03, 
+-      0xd0, 0x00, 0x22, 0xff, 0x23, 0x01, 0x04, 0x9b, 
+-      0x40, 0x03, 0xd0, 0x1b, 0x4c, 0xa4, 0x68, 0x26, 
+-      0x23, 0x01, 0x04, 0x9b, 0x43, 0x9e, 0x1c, 0x33, 
+-      0x60, 0x23, 0x4c, 0xa1, 0x68, 0x26, 0x23, 0x01, 
+-      0x43, 0x33, 0x60, 0x23, 0x23, 0x00, 0x93, 0x00, 
+-      0x9b, 0x00, 0x2b, 0x0a, 0xdb, 0x04, 0xe0, 0x04, 
+-      0x9b, 0x00, 0x33, 0x01, 0x93, 0x00, 0xe7, 0xf7, 
+-      0xe7, 0xfa, 0x4b, 0x99, 0x68, 0x1c, 0x08, 0x64, 
+-      0x00, 0x64, 0x60, 0x1c, 0x23, 0x01, 0x02, 0x9b, 
+-      0x40, 0x0b, 0xd0, 0x29, 0x23, 0x01, 0x02, 0xdb, 
+-      0x40, 0x0b, 0xd0, 0x01, 0x4b, 0x94, 0x40, 0x18, 
+-      0x23, 0x01, 0x03, 0x1b, 0x40, 0x0b, 0xd0, 0x02, 
+-      0x23, 0x01, 0x05, 0x9b, 0x43, 0x18, 0x4b, 0x91, 
+-      0x40, 0x18, 0x02, 0x4c, 0x23, 0x7f, 0x02, 0x5b, 
+-      0x40, 0x23, 0x43, 0x18, 0x23, 0x40, 0x40, 0x0b, 
+-      0xd0, 0x03, 0x23, 0x01, 0x04, 0x5b, 0x43, 0x18, 
+-      0xe0, 0x0a, 0x4b, 0x8b, 0x40, 0x18, 0x23, 0x20, 
+-      0x40, 0x0b, 0xd0, 0x03, 0x23, 0x01, 0x04, 0x1b, 
+-      0x43, 0x18, 0xe0, 0x01, 0x4b, 0x87, 0x40, 0x18, 
+-      0x23, 0x1b, 0x06, 0x9b, 0x62, 0x18, 0xe0, 0xfc, 
+-      0x23, 0x04, 0x40, 0x0b, 0xd0, 0x0f, 0x4c, 0x7e, 
+-      0x68, 0x26, 0x23, 0x01, 0x43, 0x33, 0x60, 0x23, 
+-      0x4b, 0x81, 0x68, 0x9b, 0x24, 0x33, 0x06, 0x64, 
+-      0x65, 0xe3, 0x4b, 0x7f, 0x68, 0xdb, 0x24, 0x33, 
+-      0x06, 0x64, 0x66, 0x23, 0xe0, 0xe9, 0x23, 0x01, 
+-      0x03, 0x5b, 0x40, 0x0b, 0xd0, 0x13, 0x4b, 0x7a, 
+-      0x68, 0x9b, 0x24, 0x33, 0x06, 0x64, 0x65, 0xe3, 
+-      0x4b, 0x77, 0x68, 0xdb, 0x24, 0x33, 0x06, 0x64, 
+-      0x66, 0x23, 0x23, 0x01, 0x24, 0x33, 0x06, 0x64, 
+-      0x66, 0xe3, 0x4c, 0x6d, 0x68, 0x26, 0x23, 0x01, 
+-      0x43, 0x33, 0x60, 0x23, 0xe0, 0xd1, 0x07, 0xcb, 
+-      0x0f, 0xdb, 0xd0, 0x02, 0x23, 0x02, 0x43, 0x18, 
+-      0xe0, 0x05, 0x23, 0x02, 0x40, 0x0b, 0xd0, 0x02, 
+-      0x23, 0x02, 0x43, 0xdb, 0x40, 0x18, 0x23, 0x07, 
+-      0x01, 0xdb, 0x40, 0x0b, 0xd0, 0x0f, 0x23, 0x0c, 
+-      0x43, 0xdb, 0x40, 0x18, 0x23, 0xff, 0x33, 0x01, 
+-      0x40, 0x0b, 0xd0, 0x02, 0x23, 0x04, 0x43, 0x18, 
+-      0xe0, 0x05, 0x23, 0x01, 0x02, 0x5b, 0x40, 0x0b, 
+-      0xd0, 0x01, 0x23, 0x08, 0x43, 0x18, 0x23, 0x01, 
+-      0x04, 0x1b, 0x40, 0x0b, 0xd0, 0x08, 0x23, 0x01, 
+-      0x04, 0x9b, 0x43, 0x98, 0x1c, 0x04, 0x20, 0x01, 
+-      0x04, 0xc0, 0x43, 0x20, 0x23, 0x01, 0x43, 0x18, 
+-      0x23, 0x78, 0x40, 0x0b, 0xd0, 0x73, 0x23, 0x30, 
+-      0x40, 0x03, 0xd0, 0x06, 0x2b, 0x10, 0xd0, 0x04, 
+-      0x2b, 0x20, 0xd0, 0x42, 0x2b, 0x30, 0xd0, 0x40, 
+-      0xe0, 0x81, 0x23, 0x10, 0x40, 0x0b, 0xd1, 0x02, 
+-      0x23, 0x08, 0x40, 0x0b, 0xd0, 0x08, 0x23, 0x30, 
+-      0x43, 0xdb, 0x40, 0x18, 0x23, 0x10, 0x40, 0x0b, 
+-      0xd0, 0x01, 0x23, 0x10, 0x43, 0x18, 0xe0, 0x2f, 
+-      0x23, 0x30, 0x43, 0xdb, 0x40, 0x18, 0x23, 0x20, 
+-      0x40, 0x0b, 0xd0, 0x02, 0x23, 0x20, 0x43, 0x18, 
+-      0xe0, 0x01, 0x23, 0x30, 0x43, 0x18, 0x23, 0x01, 
+-      0x43, 0x18, 0x23, 0x1b, 0x06, 0x9b, 0x62, 0x18, 
+-      0x27, 0xff, 0x2a, 0x00, 0xd0, 0x04, 0x4b, 0x43, 
+-      0x68, 0x1b, 0x4c, 0x43, 0x60, 0x23, 0xe0, 0x17, 
+-      0x07, 0xab, 0x0f, 0x9b, 0xd0, 0x09, 0x2b, 0x01, 
+-      0xd0, 0x02, 0x2b, 0x02, 0xd0, 0x0a, 0xe0, 0x0e, 
+-      0x4b, 0x3e, 0x24, 0x1b, 0x06, 0xa4, 0x64, 0x23, 
+-      0xe0, 0x0a, 0x4b, 0x3d, 0x24, 0x1b, 0x06, 0xa4, 
+-      0x64, 0x23, 0xe0, 0x05, 0x4b, 0x3b, 0x24, 0x1b, 
+-      0x06, 0xa4, 0x64, 0x23, 0xe0, 0x00, 0xe7, 0xff, 
+-      0xe0, 0x42, 0x23, 0x40, 0x40, 0x0b, 0xd1, 0x02, 
+-      0x23, 0x20, 0x40, 0x0b, 0xd0, 0x0b, 0x23, 0x30, 
+-      0x43, 0xdb, 0x40, 0x18, 0x23, 0x20, 0x40, 0x0b, 
+-      0xd0, 0x02, 0x23, 0x20, 0x43, 0x18, 0xe0, 0x01, 
+-      0x23, 0x30, 0x43, 0x18, 0xe0, 0x2e, 0x23, 0x30, 
+-      0x43, 0xdb, 0x40, 0x18, 0x23, 0x10, 0x40, 0x0b, 
+-      0xd0, 0x01, 0x23, 0x10, 0x43, 0x18, 0x23, 0x01, 
+-      0x43, 0x18, 0x23, 0x1b, 0x06, 0x9b, 0x62, 0x18, 
+-      0x27, 0xff, 0x2a, 0x00, 0xd0, 0x04, 0x4b, 0x23, 
+-      0x68, 0x1b, 0x4c, 0x23, 0x60, 0x23, 0xe0, 0x19, 
+-      0x07, 0xab, 0x0f, 0x9b, 0xe0, 0x00, 0xe0, 0x17, 
+-      0xd0, 0x09, 0x2b, 0x01, 0xd0, 0x02, 0x2b, 0x02, 
+-      0xd0, 0x0a, 0xe0, 0x0e, 0x4b, 0x20, 0x24, 0x1b, 
+-      0x06, 0xa4, 0x64, 0x23, 0xe0, 0x0a, 0x4b, 0x1f, 
+-      0x24, 0x1b, 0x06, 0xa4, 0x64, 0x23, 0xe0, 0x05, 
+-      0x4b, 0x1d, 0x24, 0x1b, 0x06, 0xa4, 0x64, 0x23, 
+-      0xe0, 0x00, 0xe7, 0xff, 0xe0, 0x00, 0xe7, 0xff, 
+-      0x2f, 0x00, 0xd1, 0x12, 0x23, 0x1b, 0x06, 0x9b, 
+-      0x62, 0x18, 0x23, 0x00, 0x93, 0x00, 0x9b, 0x00, 
+-      0x2b, 0x0a, 0xdb, 0x04, 0xe0, 0x04, 0x9b, 0x00, 
+-      0x33, 0x01, 0x93, 0x00, 0xe7, 0xf7, 0xe7, 0xfa, 
+-      0x4b, 0x03, 0x68, 0x1c, 0x08, 0x64, 0x00, 0x64, 
+-      0x60, 0x1c, 0xb0, 0x02, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x6c, 0x00, 0x00, 0x20, 0x6c, 0x00, 0x68, 0x00, 
+-      0xff, 0xbf, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 
+-      0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 
+-      0x2e, 0x08, 0x7c, 0x1c, 0x2e, 0x08, 0x5e, 0x50, 
+-      0x6c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x98, 0x60, 
+-      0x00, 0x01, 0x58, 0x60, 0x00, 0x02, 0x54, 0x28, 
+-      0x00, 0x00, 0x82, 0x18, 0x00, 0x01, 0x42, 0x18, 
+-      0x00, 0x02, 0x42, 0x18, 0xb5, 0xf3, 0x1c, 0x0f, 
+-      0xb0, 0x81, 0x98, 0x01, 0x06, 0x00, 0x0e, 0x00, 
+-      0x90, 0x00, 0x98, 0x00, 0x28, 0x20, 0xdb, 0x05, 
+-      0x20, 0xa2, 0xb0, 0x01, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x20, 0x33, 0x06, 0x40, 
+-      0x6e, 0x00, 0x21, 0x33, 0x06, 0x49, 0x6d, 0xc9, 
+-      0x1a, 0x46, 0x48, 0x12, 0x6c, 0x80, 0x1c, 0x04, 
+-      0x48, 0x10, 0x6c, 0xc0, 0x1c, 0x05, 0x42, 0xac, 
+-      0xd9, 0x09, 0x1b, 0x60, 0x21, 0x64, 0x43, 0x41, 
+-      0x1c, 0x30, 0xf0, 0x09, 0xff, 0xcb, 0x21, 0x64, 
+-      0x1a, 0x08, 0x60, 0x38, 0xe0, 0x06, 0x1b, 0x28, 
+-      0x21, 0x64, 0x43, 0x41, 0x1c, 0x30, 0xf0, 0x09, 
+-      0xff, 0xc1, 0x60, 0x38, 0x42, 0xac, 0xd1, 0x03, 
+-      0x20, 0x31, 0xb0, 0x01, 0xe7, 0xd6, 0xe0, 0x02, 
+-      0x20, 0x00, 0xb0, 0x01, 0xe7, 0xd2, 0xb0, 0x01, 
+-      0xe7, 0xd0, 0x00, 0x00, 0x66, 0x00, 0x00, 0x80, 
+-      0xb5, 0xff, 0x1c, 0x14, 0x1c, 0x1f, 0xb0, 0x82, 
+-      0x98, 0x02, 0x06, 0x01, 0x0e, 0x09, 0x91, 0x00, 
+-      0x98, 0x0b, 0x06, 0x03, 0x16, 0x1b, 0x93, 0x01, 
+-      0xb0, 0x84, 0x99, 0x04, 0x29, 0x20, 0xdb, 0x05, 
+-      0x20, 0xa2, 0xb0, 0x06, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x9b, 0x05, 0x2b, 0x1f, 
+-      0xdd, 0x02, 0x20, 0xaf, 0xb0, 0x06, 0xe7, 0xf5, 
+-      0x98, 0x07, 0x90, 0x01, 0x2f, 0x00, 0xd0, 0x47, 
+-      0xb0, 0x81, 0x98, 0x08, 0x22, 0x00, 0x92, 0x00, 
+-      0x22, 0x1b, 0x06, 0x92, 0x6a, 0x12, 0x23, 0x01, 
+-      0x05, 0x1b, 0x40, 0x1a, 0xd0, 0x01, 0x22, 0xff, 
+-      0x92, 0x00, 0x25, 0x00, 0x08, 0x62, 0x42, 0xaa, 
+-      0xd8, 0x02, 0xe0, 0x34, 0x35, 0x01, 0xe7, 0xf9, 
+-      0x9a, 0x00, 0x2a, 0x00, 0xd0, 0x1e, 0x88, 0x02, 
+-      0x23, 0xff, 0x02, 0x1b, 0x40, 0x1a, 0x12, 0x12, 
+-      0x88, 0x03, 0x02, 0x1b, 0x43, 0x1a, 0x04, 0x11, 
+-      0x0c, 0x09, 0x2f, 0x00, 0xda, 0x05, 0x42, 0x7a, 
+-      0x41, 0x11, 0x1c, 0x0b, 0x04, 0x19, 0x0c, 0x09, 
+-      0xe0, 0x03, 0x40, 0xb9, 0x1c, 0x0a, 0x04, 0x11, 
+-      0x0c, 0x09, 0x22, 0xff, 0x02, 0x12, 0x40, 0x0a, 
+-      0x12, 0x12, 0x02, 0x0b, 0x43, 0x13, 0x80, 0x03, 
+-      0x30, 0x02, 0xe0, 0x0f, 0x2f, 0x00, 0xda, 0x07, 
+-      0x88, 0x02, 0x42, 0x7e, 0x41, 0x32, 0x04, 0x12, 
+-      0x0c, 0x12, 0x80, 0x02, 0x30, 0x02, 0xe0, 0x05, 
+-      0x88, 0x02, 0x40, 0xba, 0x04, 0x12, 0x0c, 0x12, 
+-      0x80, 0x02, 0x30, 0x02, 0xe7, 0xca, 0xb0, 0x01, 
+-      0x49, 0x23, 0x91, 0x03, 0x20, 0x01, 0x06, 0x00, 
+-      0x99, 0x03, 0x60, 0x08, 0x48, 0x21, 0x6c, 0x80, 
+-      0x49, 0x20, 0x6c, 0xc9, 0x1a, 0x40, 0x90, 0x00, 
+-      0x98, 0x00, 0x28, 0x00, 0xdc, 0x09, 0x20, 0x33, 
+-      0x06, 0x40, 0x6e, 0x00, 0x21, 0x33, 0x06, 0x49, 
+-      0x6d, 0xc9, 0x1a, 0x40, 0x99, 0x00, 0x18, 0x40, 
+-      0x90, 0x00, 0x98, 0x00, 0x23, 0x3b, 0x01, 0xdb, 
+-      0x42, 0x98, 0xda, 0x02, 0x20, 0x06, 0xf0, 0x08, 
+-      0xfd, 0x8d, 0x98, 0x00, 0x23, 0x3b, 0x01, 0xdb, 
+-      0x42, 0x98, 0xdb, 0xdf, 0x98, 0x00, 0x42, 0x84, 
+-      0xd9, 0x02, 0x98, 0x00, 0x90, 0x02, 0xe0, 0x00, 
+-      0x94, 0x02, 0x22, 0x04, 0x99, 0x03, 0xb4, 0x06, 
+-      0x9b, 0x07, 0x9a, 0x04, 0x99, 0x06, 0x98, 0x03, 
+-      0xf0, 0x04, 0xfb, 0x8c, 0xb0, 0x02, 0x98, 0x02, 
+-      0x1a, 0x24, 0x98, 0x01, 0x99, 0x02, 0x18, 0x40, 
+-      0x90, 0x01, 0x20, 0x00, 0x90, 0x00, 0x2c, 0x00, 
+-      0xd1, 0xc4, 0x20, 0x00, 0xb0, 0x06, 0xe7, 0x65, 
+-      0xb0, 0x04, 0xb0, 0x02, 0xe7, 0x62, 0x00, 0x00, 
+-      0x9e, 0x00, 0x08, 0x00, 0x66, 0x00, 0x00, 0x80, 
+-      0x20, 0x1b, 0x06, 0x80, 0x6a, 0x00, 0x07, 0xc0, 
+-      0x0f, 0xc0, 0x4a, 0x03, 0x68, 0x12, 0x1c, 0x01, 
+-      0x43, 0x11, 0x1c, 0x08, 0x47, 0x70, 0xe7, 0xfd, 
+-      0x6c, 0x00, 0x08, 0x00, 0xb4, 0x90, 0x1c, 0x01, 
+-      0x20, 0x1b, 0x06, 0x80, 0x6a, 0x00, 0x1c, 0x04, 
+-      0x48, 0x1b, 0x68, 0x00, 0x1c, 0x07, 0x20, 0x30, 
+-      0x40, 0x20, 0xd0, 0x06, 0x28, 0x10, 0xd0, 0x06, 
+-      0x28, 0x20, 0xd0, 0x06, 0x28, 0x30, 0xd0, 0x06, 
+-      0xe0, 0x07, 0x22, 0x01, 0xe0, 0x08, 0x22, 0x02, 
+-      0xe0, 0x06, 0x22, 0x04, 0xe0, 0x04, 0x22, 0x08, 
+-      0xe0, 0x02, 0x20, 0x30, 0xbc, 0x90, 0x47, 0x70, 
+-      0x20, 0x03, 0x07, 0x40, 0x40, 0x38, 0x0f, 0x40, 
+-      0xd0, 0x04, 0x28, 0x01, 0xd0, 0x05, 0x28, 0x02, 
+-      0xd0, 0x06, 0xe0, 0x08, 0x23, 0x10, 0x43, 0x1a, 
+-      0xe0, 0x07, 0x23, 0x20, 0x43, 0x1a, 0xe0, 0x04, 
+-      0x23, 0x40, 0x43, 0x1a, 0xe0, 0x01, 0x20, 0x30, 
+-      0xe7, 0xe8, 0x20, 0x01, 0x05, 0xc0, 0x40, 0x38, 
+-      0xd1, 0x01, 0x23, 0x80, 0x43, 0x1a, 0x60, 0x0a, 
+-      0x20, 0x00, 0xe7, 0xdf, 0xe7, 0xde, 0x00, 0x00, 
+-      0x6c, 0x00, 0x08, 0x00, 0x1c, 0x01, 0x48, 0x01, 
+-      0x60, 0x01, 0x47, 0x70, 0x6c, 0x00, 0x00, 0x80, 
+-      0x1c, 0x01, 0x29, 0x1f, 0xdd, 0x01, 0x20, 0xaf, 
+-      0x47, 0x70, 0x20, 0x80, 0x6c, 0x00, 0x60, 0x01, 
+-      0x20, 0x00, 0xe7, 0xf9, 0xe7, 0xf8, 0xb5, 0xf3, 
+-      0x1c, 0x0a, 0xb0, 0x81, 0x98, 0x01, 0x06, 0x03, 
+-      0x0e, 0x1b, 0x93, 0x00, 0xb0, 0x81, 0x20, 0x1b, 
+-      0x06, 0x80, 0x6a, 0x00, 0x1c, 0x01, 0x25, 0x00, 
+-      0x20, 0x00, 0x90, 0x00, 0x20, 0x1b, 0x06, 0x80, 
+-      0x6c, 0x00, 0x1c, 0x04, 0x27, 0x00, 0x9b, 0x01, 
+-      0x2b, 0x20, 0xdb, 0x05, 0x20, 0xa2, 0xb0, 0x02, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x20, 0x33, 0x06, 0x40, 0x6d, 0xc0, 0x23, 0x0d, 
+-      0x06, 0x9b, 0x1a, 0xc0, 0x9b, 0x01, 0x00, 0xdb, 
+-      0x4e, 0x5f, 0x68, 0x36, 0x19, 0x9b, 0x60, 0x58, 
+-      0x20, 0xff, 0x30, 0x01, 0x40, 0x08, 0xd0, 0x01, 
+-      0x20, 0xff, 0x90, 0x00, 0x23, 0x01, 0x04, 0xdb, 
+-      0x43, 0x99, 0x1c, 0x08, 0x21, 0x01, 0x04, 0x89, 
+-      0x43, 0x01, 0x20, 0x01, 0x03, 0x00, 0x40, 0x10, 
+-      0xd0, 0x05, 0x06, 0x90, 0x0e, 0x80, 0xd0, 0x02, 
+-      0x23, 0x01, 0x05, 0x1b, 0x43, 0x19, 0x23, 0x30, 
+-      0x43, 0xdb, 0x40, 0x19, 0x05, 0x10, 0x0d, 0x00, 
+-      0x28, 0x40, 0xd0, 0x48, 0xdc, 0x0e, 0x28, 0x08, 
+-      0xd0, 0x32, 0xdc, 0x06, 0x28, 0x01, 0xd0, 0x1e, 
+-      0x28, 0x02, 0xd0, 0x21, 0x28, 0x04, 0xd0, 0x26, 
+-      0xe0, 0x67, 0x28, 0x10, 0xd0, 0x2f, 0x28, 0x20, 
+-      0xd0, 0x32, 0xe0, 0x62, 0x23, 0x01, 0x02, 0x5b, 
+-      0x42, 0x98, 0xd0, 0x49, 0xdc, 0x06, 0x28, 0x80, 
+-      0xd0, 0x38, 0x23, 0xff, 0x33, 0x01, 0x42, 0x98, 
+-      0xd0, 0x3b, 0xe0, 0x56, 0x23, 0x01, 0x02, 0x9b, 
+-      0x42, 0x98, 0xd0, 0x44, 0x23, 0x01, 0x02, 0xdb, 
+-      0x42, 0x98, 0xd0, 0x47, 0xe0, 0x4d, 0x4b, 0x3d, 
+-      0x42, 0x9c, 0xd0, 0x00, 0x4f, 0x3b, 0xe0, 0x49, 
+-      0x23, 0x10, 0x43, 0x19, 0x4b, 0x39, 0x42, 0x9c, 
+-      0xd0, 0x00, 0x4f, 0x38, 0xe0, 0x42, 0x4b, 0x38, 
+-      0x42, 0x9c, 0xd0, 0x00, 0x4f, 0x36, 0xe0, 0x3d, 
+-      0x23, 0x10, 0x43, 0x19, 0x4b, 0x34, 0x42, 0x9c, 
+-      0xd0, 0x00, 0x4f, 0x33, 0xe0, 0x36, 0x4b, 0x33, 
+-      0x42, 0x9c, 0xd0, 0x00, 0x4f, 0x31, 0xe0, 0x31, 
+-      0x23, 0x10, 0x43, 0x19, 0x4b, 0x2f, 0x42, 0x9c, 
+-      0xd0, 0x00, 0x4f, 0x2e, 0xe0, 0x2a, 0x23, 0x20, 
+-      0x43, 0x19, 0x4b, 0x2d, 0x42, 0x9c, 0xd0, 0x00, 
+-      0x4f, 0x2b, 0xe0, 0x23, 0x23, 0x30, 0x43, 0x19, 
+-      0x4b, 0x29, 0x42, 0x9c, 0xd0, 0x00, 0x4f, 0x28, 
+-      0xe0, 0x1c, 0x23, 0x20, 0x43, 0x19, 0x4b, 0x27, 
+-      0x42, 0x9c, 0xd0, 0x00, 0x4f, 0x25, 0xe0, 0x15, 
+-      0x23, 0x30, 0x43, 0x19, 0x4b, 0x23, 0x42, 0x9c, 
+-      0xd0, 0x00, 0x4f, 0x22, 0xe0, 0x0e, 0x23, 0x20, 
+-      0x43, 0x19, 0x4b, 0x21, 0x42, 0x9c, 0xd0, 0x00, 
+-      0x4f, 0x1f, 0xe0, 0x07, 0x23, 0x30, 0x43, 0x19, 
+-      0x4b, 0x1d, 0x42, 0x9c, 0xd0, 0x00, 0x4f, 0x1c, 
+-      0xe0, 0x00, 0xe7, 0xff, 0x98, 0x00, 0x28, 0x00, 
+-      0xd0, 0x0a, 0x23, 0x01, 0x43, 0x19, 0x20, 0x1b, 
+-      0x06, 0x80, 0x62, 0x01, 0x48, 0x17, 0x68, 0x00, 
+-      0x4b, 0x17, 0x60, 0x18, 0x25, 0xff, 0xe0, 0x0e, 
+-      0x23, 0x01, 0x43, 0x19, 0x2f, 0x00, 0xd0, 0x07, 
+-      0x20, 0x1b, 0x06, 0x80, 0x62, 0x01, 0x20, 0x1b, 
+-      0x06, 0x80, 0x64, 0x07, 0x25, 0xff, 0xe0, 0x02, 
+-      0x20, 0x1b, 0x06, 0x80, 0x62, 0x01, 0x2d, 0x00, 
+-      0xd1, 0x04, 0x48, 0x0e, 0x68, 0x03, 0x08, 0x5b, 
+-      0x00, 0x5b, 0x60, 0x03, 0x20, 0x00, 0xb0, 0x02, 
+-      0xe7, 0x36, 0xb0, 0x01, 0xb0, 0x01, 0xe7, 0x33, 
+-      0x2e, 0x08, 0x5d, 0xd4, 0x00, 0x00, 0x82, 0x18, 
+-      0x00, 0x01, 0x42, 0x18, 0x00, 0x02, 0x42, 0x18, 
+-      0x00, 0x00, 0x98, 0x60, 0x00, 0x01, 0x58, 0x60, 
+-      0x00, 0x02, 0x54, 0x28, 0x2e, 0x08, 0x5e, 0x50, 
+-      0x6c, 0x00, 0x00, 0x80, 0x6c, 0x00, 0x00, 0x20, 
+-      0xb5, 0xf3, 0x1c, 0x0f, 0xb0, 0x82, 0x49, 0x2c, 
+-      0x46, 0x68, 0x22, 0x08, 0xf0, 0x09, 0xfd, 0xca, 
+-      0x20, 0x04, 0xf7, 0xff, 0xfc, 0x23, 0x48, 0x29, 
+-      0x68, 0x80, 0x21, 0x33, 0x06, 0x49, 0x65, 0xc8, 
+-      0x48, 0x26, 0x68, 0xc0, 0x21, 0x33, 0x06, 0x49, 
+-      0x66, 0x08, 0x48, 0x25, 0x68, 0x01, 0x23, 0x02, 
+-      0x43, 0x19, 0x60, 0x01, 0x20, 0x01, 0x21, 0x33, 
+-      0x06, 0x49, 0x67, 0xc8, 0x48, 0x21, 0x68, 0x01, 
+-      0x31, 0xff, 0x31, 0xff, 0x31, 0x02, 0x60, 0x01, 
+-      0x1c, 0x78, 0x12, 0x00, 0xab, 0x01, 0x70, 0x18, 
+-      0x1c, 0x78, 0xab, 0x01, 0x70, 0x58, 0x20, 0x33, 
+-      0x06, 0x40, 0x6d, 0xc5, 0x4b, 0x1a, 0x43, 0x1d, 
+-      0x26, 0x00, 0x2e, 0x10, 0xdb, 0x02, 0xe0, 0x18, 
+-      0x36, 0x01, 0xe7, 0xfa, 0x24, 0x00, 0x2c, 0x07, 
+-      0xd3, 0x02, 0xe0, 0x06, 0x34, 0x01, 0xe7, 0xfa, 
+-      0x46, 0x68, 0x5d, 0x01, 0x70, 0x29, 0x35, 0x01, 
+-      0xe7, 0xf8, 0x24, 0x00, 0x42, 0xbc, 0xdb, 0x02, 
+-      0xe0, 0x06, 0x34, 0x01, 0xe7, 0xfa, 0x98, 0x02, 
+-      0x5d, 0x01, 0x70, 0x29, 0x35, 0x01, 0xe7, 0xf8, 
+-      0xe7, 0xe6, 0x20, 0x33, 0x06, 0x40, 0x66, 0x05, 
+-      0x48, 0x0a, 0x68, 0x01, 0x23, 0x01, 0x05, 0x5b, 
+-      0x43, 0x19, 0x60, 0x01, 0xb0, 0x02, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x03, 0x39, 0xfc, 0x2e, 0x08, 0x7c, 0x1c, 
+-      0x66, 0x00, 0x00, 0x70, 0x66, 0x00, 0x00, 0x5c, 
+-      0xcc, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x20, 
+-      0xb5, 0xf7, 0x1c, 0x04, 0x1c, 0x0f, 0x06, 0x20, 
+-      0x0e, 0x00, 0x06, 0x3d, 0x0e, 0x2d, 0x99, 0x02, 
+-      0x06, 0x0a, 0x0e, 0x12, 0x21, 0x02, 0x40, 0x01, 
+-      0xd0, 0x04, 0x21, 0xff, 0x4b, 0x2f, 0x68, 0x1b, 
+-      0x72, 0x19, 0xe0, 0x0c, 0x49, 0x2d, 0x68, 0x09, 
+-      0x7a, 0x09, 0x29, 0xff, 0xd1, 0x03, 0x21, 0x00, 
+-      0x4b, 0x2a, 0x68, 0x1b, 0x60, 0x19, 0x21, 0x00, 
+-      0x4b, 0x28, 0x68, 0x1b, 0x72, 0x19, 0x07, 0xc1, 
+-      0x0f, 0xc9, 0xd0, 0x04, 0x21, 0xff, 0x4b, 0x25, 
+-      0x68, 0x1b, 0x72, 0x59, 0xe0, 0x0c, 0x49, 0x23, 
+-      0x68, 0x09, 0x7a, 0x49, 0x29, 0xff, 0xd1, 0x03, 
+-      0x21, 0x00, 0x4b, 0x20, 0x68, 0x1b, 0x60, 0x59, 
+-      0x21, 0x00, 0x4b, 0x1e, 0x68, 0x1b, 0x72, 0x59, 
+-      0x2d, 0x01, 0xd1, 0x0f, 0x49, 0x1c, 0x68, 0x0e, 
+-      0x23, 0x01, 0x05, 0x5b, 0x43, 0x9e, 0x1c, 0x33, 
+-      0x60, 0x0b, 0x49, 0x1a, 0x68, 0x09, 0x78, 0x09, 
+-      0x23, 0x02, 0x43, 0x19, 0x4b, 0x17, 0x68, 0x1b, 
+-      0x70, 0x19, 0xe0, 0x0e, 0x49, 0x14, 0x68, 0x0e, 
+-      0x23, 0x01, 0x05, 0x5b, 0x43, 0x33, 0x60, 0x0b, 
+-      0x49, 0x12, 0x68, 0x09, 0x78, 0x09, 0x23, 0x02, 
+-      0x43, 0xdb, 0x40, 0x19, 0x4b, 0x0f, 0x68, 0x1b, 
+-      0x70, 0x19, 0x49, 0x0f, 0x62, 0x4a, 0x2a, 0x01, 
+-      0xd1, 0x08, 0x49, 0x0c, 0x68, 0x09, 0x78, 0x09, 
+-      0x23, 0x01, 0x43, 0x19, 0x4b, 0x09, 0x68, 0x1b, 
+-      0x70, 0x19, 0xe0, 0x07, 0x49, 0x07, 0x68, 0x09, 
+-      0x78, 0x09, 0x08, 0x49, 0x00, 0x49, 0x4b, 0x05, 
+-      0x68, 0x1b, 0x70, 0x19, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x5e, 0x54, 
+-      0x6c, 0x00, 0x00, 0x20, 0x2e, 0x08, 0x5e, 0x58, 
+-      0xcc, 0x00, 0x0f, 0x80, 0xb4, 0x80, 0x1c, 0x07, 
+-      0x1c, 0x0a, 0x68, 0x38, 0x49, 0x23, 0x68, 0x09, 
+-      0x60, 0xc8, 0x68, 0x78, 0x49, 0x21, 0x68, 0x09, 
+-      0x61, 0x08, 0x68, 0xb8, 0x49, 0x1f, 0x68, 0x09, 
+-      0x61, 0x48, 0x68, 0xf8, 0x49, 0x1d, 0x68, 0x09, 
+-      0x61, 0x88, 0x7d, 0x38, 0x49, 0x1b, 0x68, 0x09, 
+-      0x31, 0x20, 0x70, 0x08, 0x7d, 0x78, 0x49, 0x19, 
+-      0x68, 0x09, 0x31, 0x20, 0x70, 0x48, 0x69, 0x38, 
+-      0x49, 0x16, 0x68, 0x09, 0x61, 0xc8, 0x7d, 0xb8, 
+-      0x49, 0x14, 0x68, 0x09, 0x31, 0x20, 0x70, 0x88, 
+-      0x68, 0x10, 0x49, 0x12, 0x68, 0x09, 0x62, 0x48, 
+-      0x68, 0x50, 0x49, 0x10, 0x68, 0x09, 0x62, 0x88, 
+-      0x68, 0x90, 0x49, 0x0e, 0x68, 0x09, 0x62, 0xc8, 
+-      0x68, 0xd0, 0x49, 0x0c, 0x68, 0x09, 0x63, 0x08, 
+-      0x7d, 0x10, 0x49, 0x0a, 0x68, 0x09, 0x31, 0x20, 
+-      0x76, 0x08, 0x7d, 0x50, 0x49, 0x07, 0x68, 0x09, 
+-      0x31, 0x20, 0x76, 0x48, 0x69, 0x10, 0x49, 0x05, 
+-      0x68, 0x09, 0x63, 0x48, 0x7d, 0x90, 0x49, 0x03, 
+-      0x68, 0x09, 0x31, 0x20, 0x76, 0x88, 0xbc, 0x80, 
+-      0x47, 0x70, 0x00, 0x00, 0x2e, 0x08, 0x5e, 0x54, 
+-      0x1c, 0x02, 0x1c, 0x0b, 0x48, 0x03, 0x68, 0x00, 
+-      0x60, 0x02, 0x48, 0x02, 0x68, 0x00, 0x60, 0x43, 
+-      0x47, 0x70, 0x00, 0x00, 0x2e, 0x08, 0x5e, 0x54, 
+-      0xb5, 0xf3, 0xb0, 0x88, 0x98, 0x08, 0x68, 0x04, 
+-      0x20, 0x01, 0x90, 0x06, 0x20, 0x01, 0x90, 0x05, 
+-      0x48, 0x8c, 0x68, 0x00, 0x28, 0x00, 0xd0, 0x19, 
+-      0x48, 0x8a, 0x68, 0x00, 0x38, 0x01, 0x49, 0x89, 
+-      0x60, 0x08, 0x48, 0x88, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x10, 0x48, 0x87, 0x78, 0x80, 0x90, 0x00, 
+-      0x98, 0x00, 0x00, 0xc0, 0x49, 0x85, 0x68, 0x09, 
+-      0x58, 0x08, 0x23, 0xff, 0x33, 0x01, 0x43, 0x98, 
+-      0x1c, 0x01, 0x98, 0x00, 0x00, 0xc0, 0x4a, 0x81, 
+-      0x68, 0x12, 0x50, 0x11, 0x20, 0x33, 0x06, 0x40, 
+-      0x6e, 0x00, 0x23, 0x0d, 0x06, 0x9b, 0x1a, 0xc1, 
+-      0x91, 0x02, 0x20, 0x33, 0x06, 0x40, 0x6d, 0xc0, 
+-      0x23, 0x0d, 0x06, 0x9b, 0x1a, 0xc0, 0x90, 0x01, 
+-      0x48, 0x79, 0x68, 0x00, 0x42, 0x84, 0xd1, 0x73, 
+-      0x98, 0x01, 0x1d, 0xc7, 0x37, 0x01, 0x78, 0x38, 
+-      0x18, 0x38, 0x1c, 0x47, 0x48, 0x75, 0x6c, 0xc0, 
+-      0x23, 0x0d, 0x06, 0x9b, 0x1a, 0xc0, 0x42, 0xb8, 
+-      0xd9, 0x19, 0x78, 0x38, 0x28, 0xff, 0xd1, 0x12, 
+-      0x78, 0x78, 0x23, 0xf0, 0x40, 0x18, 0x28, 0xf0, 
+-      0xd1, 0x0d, 0x78, 0xb8, 0x10, 0x80, 0x07, 0x80, 
+-      0x0f, 0x80, 0x06, 0x00, 0x16, 0x00, 0x90, 0x06, 
+-      0x78, 0x78, 0x10, 0xc0, 0x07, 0xc0, 0x09, 0xc0, 
+-      0x16, 0x00, 0x90, 0x05, 0xe0, 0x03, 0x21, 0x01, 
+-      0x70, 0x39, 0x18, 0x7f, 0xe7, 0xde, 0x21, 0x40, 
+-      0x91, 0x03, 0x25, 0x20, 0x21, 0x14, 0x91, 0x07, 
+-      0x98, 0x06, 0x28, 0x00, 0xd1, 0x02, 0x25, 0x23, 
+-      0x21, 0x12, 0x91, 0x07, 0x98, 0x06, 0x28, 0x02, 
+-      0xd1, 0x02, 0x25, 0x30, 0x21, 0x18, 0x91, 0x07, 
+-      0x98, 0x05, 0x28, 0x00, 0xd1, 0x02, 0x00, 0x6d, 
+-      0x21, 0x70, 0x91, 0x03, 0x99, 0x03, 0x00, 0x48, 
+-      0x99, 0x02, 0x1a, 0x08, 0x90, 0x04, 0x98, 0x04, 
+-      0x99, 0x02, 0x42, 0x88, 0xd3, 0x05, 0xe0, 0x4e, 
+-      0x98, 0x04, 0x99, 0x03, 0x18, 0x40, 0x90, 0x04, 
+-      0xe7, 0xf5, 0x9f, 0x04, 0x21, 0x00, 0x70, 0x39, 
+-      0x37, 0x01, 0x21, 0x00, 0x70, 0x39, 0x37, 0x01, 
+-      0x21, 0x01, 0x70, 0x39, 0x18, 0x7f, 0x21, 0xc0, 
+-      0x70, 0x39, 0x37, 0x01, 0x21, 0x00, 0x70, 0x39, 
+-      0x37, 0x01, 0x21, 0x3a, 0x70, 0x39, 0x37, 0x01, 
+-      0x21, 0x80, 0x70, 0x39, 0x37, 0x01, 0x21, 0x00, 
+-      0x70, 0x39, 0x37, 0x01, 0x99, 0x03, 0x1f, 0xc8, 
+-      0x38, 0x02, 0x1b, 0x41, 0x70, 0x39, 0x37, 0x01, 
+-      0x26, 0x00, 0x99, 0x03, 0x1f, 0xc8, 0x38, 0x02, 
+-      0x1b, 0x40, 0x42, 0xb0, 0xdc, 0x04, 0xe0, 0x00, 
+-      0xe0, 0x34, 0xe0, 0x05, 0x36, 0x01, 0xe7, 0xf4, 
+-      0x21, 0xff, 0x70, 0x39, 0x37, 0x01, 0xe7, 0xf9, 
+-      0x21, 0xff, 0x70, 0x39, 0x37, 0x01, 0x98, 0x05, 
+-      0x00, 0xc0, 0x21, 0xf7, 0x43, 0x01, 0x70, 0x39, 
+-      0x37, 0x01, 0x99, 0x07, 0x70, 0x39, 0x37, 0x01, 
+-      0x21, 0xc0, 0x70, 0x39, 0x37, 0x01, 0x26, 0x00, 
+-      0x1f, 0x28, 0x42, 0xb0, 0xdc, 0x02, 0xe0, 0x05, 
+-      0x36, 0x01, 0xe7, 0xf9, 0x21, 0x00, 0x70, 0x39, 
+-      0x37, 0x01, 0xe7, 0xf9, 0xe7, 0xb0, 0x99, 0x03, 
+-      0x00, 0x48, 0x99, 0x02, 0x1a, 0x08, 0x23, 0x0d, 
+-      0x06, 0x9b, 0x18, 0xc0, 0x49, 0x29, 0x64, 0x88, 
+-      0x99, 0x09, 0x20, 0x78, 0x40, 0x08, 0x23, 0x02, 
+-      0x43, 0x18, 0xf7, 0xff, 0xfa, 0x17, 0x20, 0x01, 
+-      0xf7, 0xff, 0xfa, 0x14, 0x48, 0x22, 0x68, 0x00, 
+-      0x38, 0x02, 0x42, 0xa0, 0xd1, 0x09, 0x48, 0x22, 
+-      0x68, 0x01, 0x23, 0x01, 0x05, 0x5b, 0x43, 0x19, 
+-      0x60, 0x01, 0x20, 0xff, 0x49, 0x1f, 0x68, 0x09, 
+-      0x70, 0x08, 0x48, 0x1b, 0x68, 0x00, 0x38, 0x02, 
+-      0x42, 0xa0, 0xd3, 0x0f, 0x48, 0x1c, 0x68, 0x00, 
+-      0x28, 0x00, 0xd0, 0x05, 0x48, 0x1a, 0x68, 0x00, 
+-      0x23, 0x01, 0x06, 0x9b, 0x40, 0x18, 0xd0, 0x05, 
+-      0x20, 0x32, 0x49, 0x13, 0x60, 0x08, 0x48, 0x12, 
+-      0x68, 0x00, 0x1e, 0x84, 0x2c, 0x01, 0xd1, 0x02, 
+-      0x20, 0x02, 0xf7, 0xff, 0xf9, 0xeb, 0x2c, 0xff, 
+-      0xd1, 0x08, 0x20, 0x33, 0x06, 0x40, 0x6d, 0xc0, 
+-      0x30, 0xbc, 0x49, 0x0c, 0x6c, 0xc9, 0x42, 0x88, 
+-      0xd2, 0x00, 0x24, 0x18, 0x2c, 0x00, 0xd0, 0x02, 
+-      0x2c, 0xff, 0xd0, 0x00, 0x3c, 0x01, 0x98, 0x08, 
+-      0x60, 0x04, 0xb0, 0x08, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x5e, 0x44, 
+-      0x2e, 0x08, 0x5e, 0x30, 0x2e, 0x08, 0x5d, 0xd0, 
+-      0x2e, 0x08, 0x1f, 0x18, 0x66, 0x00, 0x00, 0x80, 
+-      0x6c, 0x00, 0x00, 0x20, 0x2e, 0x08, 0x5e, 0x2c, 
+-      0x6c, 0x00, 0x08, 0x00, 0xb5, 0xff, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0x9a, 0x02, 0x06, 0x15, 0x0e, 0x2d, 
+-      0x9b, 0x03, 0x06, 0x1e, 0x0e, 0x36, 0x2e, 0x20, 
+-      0xdb, 0x04, 0x20, 0xa2, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2d, 0x1f, 0xdb, 0x01, 
+-      0x20, 0xaf, 0xe7, 0xf7, 0x20, 0x01, 0x03, 0x40, 
+-      0xf7, 0xff, 0xf9, 0xac, 0x20, 0x14, 0x49, 0x09, 
+-      0x60, 0x08, 0x20, 0xff, 0x60, 0x20, 0x1c, 0x33, 
+-      0x1c, 0x29, 0x1c, 0x38, 0x22, 0x02, 0xf7, 0xfc, 
+-      0xfa, 0x4b, 0x48, 0x05, 0x68, 0x01, 0x23, 0x01, 
+-      0x05, 0x5b, 0x43, 0x19, 0x60, 0x01, 0x20, 0x00, 
+-      0xe7, 0xe0, 0xe7, 0xdf, 0x2e, 0x08, 0x1f, 0x18, 
+-      0x6c, 0x00, 0x00, 0x20, 0xb4, 0x0f, 0xb5, 0xf0, 
+-      0x1c, 0x07, 0xb0, 0x82, 0x20, 0x00, 0x49, 0x16, 
+-      0x60, 0x08, 0x48, 0x16, 0x6f, 0x80, 0x23, 0x09, 
+-      0x01, 0x9b, 0x42, 0x98, 0xd1, 0x02, 0x20, 0xe1, 
+-      0x00, 0xc0, 0xe0, 0x00, 0x48, 0x12, 0x1c, 0x05, 
+-      0x68, 0x38, 0x28, 0xff, 0xd1, 0x17, 0x98, 0x0d, 
+-      0x90, 0x00, 0x98, 0x0c, 0x90, 0x01, 0x98, 0x01, 
+-      0x99, 0x00, 0x1a, 0x46, 0x08, 0x68, 0x19, 0x81, 
+-      0x1c, 0x28, 0xf0, 0x09, 0xfa, 0xeb, 0x1c, 0x04, 
+-      0x34, 0x01, 0x0f, 0xf0, 0x07, 0xc0, 0xd0, 0x00, 
+-      0x24, 0x04, 0x2c, 0x32, 0xd9, 0x00, 0x24, 0x04, 
+-      0x1d, 0xe0, 0x30, 0x0d, 0x60, 0x38, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0xb0, 0x04, 0x47, 0x18, 
+-      0x2e, 0x08, 0x5e, 0x44, 0xcc, 0x00, 0x0f, 0x80, 
+-      0x00, 0x00, 0x05, 0xdd, 0xb5, 0xf3, 0x1c, 0x07, 
+-      0xb0, 0x81, 0x99, 0x02, 0x06, 0x09, 0x0e, 0x09, 
+-      0x91, 0x00, 0xb0, 0x82, 0x99, 0x02, 0x29, 0x20, 
+-      0xdb, 0x05, 0x20, 0xa2, 0xb0, 0x03, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x99, 0x02, 
+-      0x00, 0x88, 0x49, 0x2f, 0x58, 0x08, 0x90, 0x01, 
+-      0x28, 0x00, 0xd1, 0x02, 0x20, 0xb0, 0xb0, 0x03, 
+-      0xe7, 0xf1, 0x20, 0x00, 0x70, 0x78, 0x78, 0xb8, 
+-      0x07, 0x00, 0x0f, 0x00, 0x90, 0x00, 0x98, 0x00, 
+-      0x28, 0x04, 0xd1, 0x1f, 0x6a, 0xfe, 0x24, 0x00, 
+-      0x2c, 0x08, 0xdb, 0x04, 0xe0, 0x18, 0x1c, 0x60, 
+-      0x06, 0x04, 0x0e, 0x24, 0xe7, 0xf8, 0x00, 0xa0, 
+-      0x19, 0x80, 0x68, 0x40, 0x00, 0xa1, 0x19, 0x89, 
+-      0x64, 0x48, 0x21, 0x00, 0x00, 0xa0, 0x19, 0x80, 
+-      0x62, 0x41, 0x00, 0xa0, 0x19, 0x80, 0x6c, 0x40, 
+-      0x28, 0x00, 0xd0, 0x04, 0x20, 0x80, 0x41, 0x20, 
+-      0x88, 0x31, 0x43, 0x08, 0x80, 0x30, 0xe7, 0xe6, 
+-      0x88, 0x30, 0x80, 0x70, 0x78, 0xb8, 0x23, 0x20, 
+-      0x40, 0x18, 0xd0, 0x1f, 0x6b, 0x3d, 0x20, 0x00, 
+-      0x60, 0x28, 0x20, 0x00, 0x60, 0x68, 0x20, 0x00, 
+-      0x60, 0xa8, 0x24, 0x00, 0x2c, 0x08, 0xdb, 0x04, 
+-      0xe0, 0x0c, 0x1c, 0x60, 0x06, 0x04, 0x0e, 0x24, 
+-      0xe7, 0xf8, 0x20, 0x00, 0x00, 0xa1, 0x19, 0x49, 
+-      0x60, 0xc8, 0x20, 0x00, 0x00, 0xa1, 0x19, 0x49, 
+-      0x63, 0x88, 0xe7, 0xf2, 0x20, 0x00, 0x62, 0xe8, 
+-      0x20, 0x00, 0x63, 0x28, 0x20, 0x00, 0x63, 0x68, 
+-      0x20, 0x00, 0x65, 0xa8, 0x99, 0x02, 0x1c, 0x38, 
+-      0xf0, 0x00, 0xf8, 0x3e, 0xb0, 0x03, 0xe7, 0x9e, 
+-      0xb0, 0x02, 0xb0, 0x01, 0xe7, 0x9b, 0x00, 0x00, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0xb5, 0xf3, 0x1c, 0x07, 
+-      0x99, 0x01, 0x06, 0x0c, 0x0e, 0x24, 0xb0, 0x82, 
+-      0x2c, 0x20, 0xdb, 0x05, 0x20, 0xa2, 0xb0, 0x02, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x00, 0xa0, 0x49, 0x12, 0x58, 0x08, 0x1c, 0x05, 
+-      0xd1, 0x02, 0x20, 0xb0, 0xb0, 0x02, 0xe7, 0xf3, 
+-      0x1c, 0x21, 0x1c, 0x38, 0xf0, 0x00, 0xf9, 0x84, 
+-      0x1c, 0x06, 0xd0, 0x02, 0x1c, 0x30, 0xb0, 0x02, 
+-      0xe7, 0xea, 0x78, 0x68, 0x21, 0x20, 0x40, 0x01, 
+-      0x91, 0x00, 0x99, 0x00, 0x1c, 0x38, 0xf0, 0x00, 
+-      0xff, 0x3f, 0x68, 0xe9, 0x91, 0x01, 0x29, 0x00, 
+-      0xd0, 0x03, 0x99, 0x01, 0x1c, 0x38, 0xf0, 0x03, 
+-      0xfe, 0x7a, 0x20, 0x00, 0xb0, 0x02, 0xe7, 0xd7, 
+-      0xb0, 0x02, 0xe7, 0xd5, 0x2e, 0x08, 0x5e, 0x5c, 
+-      0xb5, 0xf3, 0x1c, 0x02, 0x99, 0x01, 0x06, 0x0f, 
+-      0x0e, 0x3f, 0xb0, 0x86, 0x00, 0xb8, 0x4b, 0xa1, 
+-      0x68, 0x1b, 0x18, 0xc0, 0x90, 0x00, 0x2f, 0x20, 
+-      0xdb, 0x05, 0x20, 0xa2, 0xb0, 0x06, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0xb8, 
+-      0x4b, 0x9b, 0x58, 0x18, 0x90, 0x05, 0x28, 0x00, 
+-      0xd1, 0x02, 0x20, 0xb0, 0xb0, 0x06, 0xe7, 0xf2, 
+-      0x78, 0x90, 0x90, 0x01, 0x71, 0xd7, 0x78, 0xd1, 
+-      0x98, 0x01, 0x23, 0x80, 0x40, 0x18, 0xd1, 0x73, 
+-      0x29, 0x20, 0xdd, 0x02, 0x20, 0xb1, 0xb0, 0x06, 
+-      0xe7, 0xe5, 0x48, 0x92, 0x68, 0x00, 0x23, 0x01, 
+-      0x42, 0xd8, 0xd1, 0x02, 0x20, 0xb2, 0xb0, 0x06, 
+-      0xe7, 0xdd, 0x20, 0x01, 0x40, 0x88, 0x4b, 0x8d, 
+-      0x68, 0x1b, 0x40, 0x18, 0xd0, 0x02, 0x20, 0xb1, 
+-      0xb0, 0x06, 0xe7, 0xd4, 0x00, 0x88, 0x4b, 0x8a, 
+-      0x50, 0x1a, 0x48, 0x8a, 0x54, 0x47, 0x01, 0x08, 
+-      0x4b, 0x89, 0x18, 0xc5, 0x7f, 0x10, 0x06, 0x00, 
+-      0x7f, 0x53, 0x04, 0x1b, 0x43, 0x18, 0x7f, 0x93, 
+-      0x02, 0x1b, 0x43, 0x18, 0x7f, 0xd3, 0x43, 0x03, 
+-      0xc5, 0x08, 0x1d, 0xd0, 0x30, 0x19, 0x78, 0x00, 
+-      0x06, 0x00, 0x1d, 0xd3, 0x33, 0x19, 0x78, 0x5b, 
+-      0x04, 0x1b, 0x43, 0x18, 0x1d, 0xd3, 0x33, 0x19, 
+-      0x78, 0x9b, 0x02, 0x1b, 0x43, 0x18, 0x1d, 0xd3, 
+-      0x33, 0x19, 0x78, 0xdb, 0x43, 0x03, 0xc5, 0x08, 
+-      0x01, 0x08, 0x4b, 0x7a, 0x18, 0xc4, 0x7b, 0x10, 
+-      0x06, 0x00, 0x7b, 0x53, 0x04, 0x1b, 0x43, 0x18, 
+-      0x7b, 0x93, 0x02, 0x1b, 0x43, 0x18, 0x7b, 0xd3, 
+-      0x43, 0x03, 0xc4, 0x08, 0x7c, 0x10, 0x06, 0x00, 
+-      0x7c, 0x53, 0x04, 0x1b, 0x43, 0x18, 0x7c, 0x93, 
+-      0x02, 0x1b, 0x43, 0x18, 0x7c, 0xd3, 0x43, 0x03, 
+-      0xc4, 0x08, 0x98, 0x01, 0x07, 0xc0, 0x0f, 0xc0, 
+-      0xd0, 0x20, 0x1d, 0xd0, 0x30, 0x19, 0x79, 0x00, 
+-      0x06, 0x00, 0x1d, 0xd3, 0x33, 0x19, 0x79, 0x5b, 
+-      0x04, 0x1b, 0x43, 0x18, 0x1d, 0xd3, 0x33, 0x19, 
+-      0x79, 0x9b, 0x02, 0x1b, 0x43, 0x18, 0x1d, 0xd3, 
+-      0x33, 0x19, 0x79, 0xdb, 0x43, 0x03, 0xc5, 0x08, 
+-      0x7d, 0x10, 0x06, 0x00, 0x7d, 0x53, 0x04, 0x1b, 
+-      0x43, 0x18, 0x7d, 0x93, 0x02, 0x1b, 0xe0, 0x00, 
+-      0xe0, 0x42, 0x43, 0x18, 0x7d, 0xd3, 0x43, 0x03, 
+-      0xc4, 0x08, 0xe0, 0x03, 0x23, 0x00, 0xc5, 0x08, 
+-      0x23, 0x00, 0xc4, 0x08, 0x23, 0xff, 0xc5, 0x08, 
+-      0x20, 0x19, 0x06, 0x80, 0x6b, 0x00, 0x23, 0x08, 
+-      0x40, 0x18, 0xd0, 0x06, 0x88, 0x90, 0x04, 0x00, 
+-      0x19, 0xc3, 0x93, 0x02, 0x9b, 0x02, 0xc4, 0x08, 
+-      0xe0, 0x00, 0xc4, 0x80, 0x98, 0x01, 0x23, 0x08, 
+-      0x40, 0x18, 0xd0, 0x17, 0x48, 0x50, 0x5d, 0xc0, 
+-      0x30, 0x01, 0x4b, 0x4f, 0x55, 0xd8, 0x7a, 0x10, 
+-      0x07, 0xc0, 0x0f, 0xc0, 0xd0, 0x04, 0x20, 0x01, 
+-      0x40, 0x88, 0x23, 0x19, 0x06, 0x9b, 0x61, 0x18, 
+-      0x7a, 0x10, 0x23, 0x02, 0x40, 0x18, 0xd0, 0x04, 
+-      0x20, 0x01, 0x40, 0x88, 0x23, 0x19, 0x06, 0x9b, 
+-      0x61, 0x58, 0xe0, 0x05, 0x4e, 0x45, 0x20, 0x01, 
+-      0x40, 0x88, 0x68, 0x33, 0x43, 0x18, 0x60, 0x30, 
+-      0x20, 0x01, 0x40, 0x88, 0x4b, 0x3b, 0x68, 0x1b, 
+-      0x43, 0x18, 0x4b, 0x3a, 0x60, 0x18, 0xe0, 0x4f, 
+-      0x98, 0x01, 0x23, 0x80, 0x40, 0x18, 0xd0, 0x48, 
+-      0x48, 0x3d, 0x88, 0x00, 0x4b, 0x3d, 0x42, 0x98, 
+-      0xd1, 0x02, 0x20, 0xb2, 0xb0, 0x06, 0xe7, 0x26, 
+-      0x00, 0x88, 0x4b, 0x3b, 0x58, 0x18, 0x28, 0x00, 
+-      0xd0, 0x02, 0x20, 0xb1, 0xb0, 0x06, 0xe7, 0x1e, 
+-      0x29, 0x10, 0xdb, 0x02, 0x20, 0xb1, 0xb0, 0x06, 
+-      0xe7, 0x19, 0x20, 0x01, 0x40, 0x88, 0x4b, 0x32, 
+-      0x88, 0x1b, 0x40, 0x18, 0xd0, 0x02, 0x20, 0xb1, 
+-      0xb0, 0x06, 0xe7, 0x10, 0x98, 0x05, 0x78, 0x80, 
+-      0x28, 0x02, 0xdb, 0x02, 0x20, 0xb1, 0xb0, 0x06, 
+-      0xe7, 0x09, 0x00, 0x88, 0x4b, 0x2c, 0x50, 0x1a, 
+-      0x48, 0x2c, 0x54, 0x47, 0x00, 0xf8, 0x1b, 0xc0, 
+-      0x00, 0x80, 0x4b, 0x2b, 0x68, 0x1b, 0x18, 0xc0, 
+-      0x90, 0x04, 0x98, 0x04, 0x7e, 0x00, 0x28, 0xff, 
+-      0xd1, 0x02, 0x98, 0x04, 0x76, 0x01, 0xe0, 0x01, 
+-      0x98, 0x04, 0x76, 0x41, 0x4e, 0x25, 0x96, 0x03, 
+-      0x1d, 0xd3, 0x33, 0x05, 0x00, 0x88, 0x9e, 0x03, 
+-      0x50, 0x33, 0x20, 0x01, 0x40, 0x88, 0x4b, 0x1c, 
+-      0x88, 0x1b, 0x43, 0x18, 0x4b, 0x1a, 0x80, 0x18, 
+-      0xe0, 0x02, 0x20, 0xb1, 0xb0, 0x06, 0xe6, 0xe2, 
+-      0x78, 0x50, 0x23, 0x80, 0x43, 0xdb, 0x40, 0x18, 
+-      0x70, 0x50, 0x98, 0x05, 0x78, 0x80, 0x28, 0x00, 
+-      0xd1, 0x09, 0x98, 0x00, 0x68, 0x00, 0x23, 0x01, 
+-      0x03, 0x5b, 0x43, 0x18, 0x9b, 0x00, 0x60, 0x18, 
+-      0x20, 0x02, 0x9b, 0x05, 0x70, 0xd8, 0x98, 0x05, 
+-      0x78, 0x80, 0x30, 0x01, 0x9b, 0x05, 0x70, 0x98, 
+-      0x20, 0x00, 0xb0, 0x06, 0xe6, 0xc7, 0xb0, 0x06, 
+-      0xe6, 0xc5, 0x00, 0x00, 0x2e, 0x08, 0x5d, 0xcc, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x5e, 0xdc, 
+-      0x2e, 0x08, 0x5e, 0xe4, 0x2e, 0x08, 0x5f, 0xa4, 
+-      0x64, 0x00, 0x10, 0x00, 0x64, 0x00, 0x08, 0x00, 
+-      0x2e, 0x08, 0x7b, 0xf4, 0x64, 0x00, 0x00, 0x18, 
+-      0x2e, 0x08, 0x5e, 0xe0, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x5f, 0x64, 0x2e, 0x08, 0x5f, 0xc4, 
+-      0x2e, 0x08, 0x5d, 0xc4, 0x9e, 0x00, 0x04, 0xb8, 
+-      0xb5, 0xf3, 0x1c, 0x02, 0x99, 0x01, 0x06, 0x0f, 
+-      0x0e, 0x3f, 0xb0, 0x86, 0x00, 0xb8, 0x4b, 0x65, 
+-      0x68, 0x1b, 0x18, 0xc0, 0x90, 0x01, 0x2f, 0x20, 
+-      0xdb, 0x05, 0x20, 0xa2, 0xb0, 0x06, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0xb8, 
+-      0x4b, 0x5f, 0x58, 0x18, 0x1c, 0x05, 0xd1, 0x02, 
+-      0x20, 0xb0, 0xb0, 0x06, 0xe7, 0xf3, 0x78, 0x90, 
+-      0x90, 0x03, 0x78, 0xd1, 0x00, 0x88, 0x4b, 0x5b, 
+-      0x58, 0x18, 0x42, 0x90, 0xd0, 0x02, 0x20, 0xb1, 
+-      0xb0, 0x06, 0xe7, 0xe8, 0x98, 0x03, 0x23, 0x80, 
+-      0x40, 0x18, 0xd1, 0x49, 0x01, 0x08, 0x4b, 0x56, 
+-      0x18, 0xc3, 0x93, 0x00, 0x20, 0x00, 0x9b, 0x00, 
+-      0x60, 0x18, 0x23, 0x00, 0x00, 0x88, 0x4e, 0x51, 
+-      0x50, 0x33, 0x23, 0xff, 0x48, 0x51, 0x54, 0x43, 
+-      0x20, 0x01, 0x40, 0x88, 0x43, 0xc0, 0x4b, 0x50, 
+-      0x68, 0x1b, 0x40, 0x18, 0x4b, 0x4e, 0x60, 0x18, 
+-      0x98, 0x03, 0x23, 0x08, 0x40, 0x18, 0xd0, 0x27, 
+-      0x20, 0x01, 0x40, 0x88, 0x90, 0x04, 0x7a, 0x10, 
+-      0x07, 0xc0, 0x0f, 0xc0, 0xd0, 0x0b, 0x98, 0x04, 
+-      0x23, 0x19, 0x06, 0x9b, 0x69, 0x1b, 0x40, 0x18, 
+-      0xd0, 0x04, 0x98, 0x04, 0x23, 0x19, 0x06, 0x9b, 
+-      0x61, 0x18, 0xe7, 0xf4, 0xe0, 0x0e, 0x7a, 0x10, 
+-      0x23, 0x02, 0x40, 0x18, 0xd0, 0x0a, 0x98, 0x04, 
+-      0x23, 0x19, 0x06, 0x9b, 0x69, 0x5b, 0x40, 0x18, 
+-      0xd0, 0x04, 0x98, 0x04, 0x23, 0x19, 0x06, 0x9b, 
+-      0x61, 0x58, 0xe7, 0xf4, 0x48, 0x3b, 0x5d, 0xc0, 
+-      0x38, 0x01, 0x4b, 0x3a, 0x55, 0xd8, 0xe0, 0x06, 
+-      0x4e, 0x39, 0x20, 0x01, 0x40, 0x88, 0x43, 0xc0, 
+-      0x68, 0x33, 0x40, 0x18, 0x60, 0x30, 0xe0, 0x36, 
+-      0x98, 0x03, 0x23, 0x80, 0x40, 0x18, 0xd0, 0x2f, 
+-      0x00, 0xf8, 0x1b, 0xc0, 0x00, 0x80, 0x4b, 0x33, 
+-      0x68, 0x1b, 0x18, 0xc3, 0x93, 0x02, 0x9b, 0x02, 
+-      0x7e, 0x18, 0x42, 0x88, 0xd1, 0x03, 0x20, 0xff, 
+-      0x9b, 0x02, 0x76, 0x18, 0xe0, 0x0a, 0x9b, 0x02, 
+-      0x7e, 0x58, 0x42, 0x88, 0xd1, 0x03, 0x20, 0xff, 
+-      0x9b, 0x02, 0x76, 0x58, 0xe0, 0x02, 0x20, 0xb1, 
+-      0xb0, 0x06, 0xe7, 0x7c, 0x23, 0x00, 0x00, 0x88, 
+-      0x4e, 0x27, 0x50, 0x33, 0x20, 0xff, 0x4b, 0x27, 
+-      0x54, 0x58, 0x20, 0x01, 0x40, 0x88, 0x43, 0xc0, 
+-      0x4b, 0x25, 0x88, 0x1b, 0x40, 0x18, 0x4b, 0x24, 
+-      0x80, 0x18, 0x4e, 0x24, 0x96, 0x05, 0x23, 0x00, 
+-      0x00, 0x88, 0x9e, 0x05, 0x50, 0x33, 0xe0, 0x02, 
+-      0x20, 0xb1, 0xb0, 0x06, 0xe7, 0x63, 0x78, 0xa8, 
+-      0x38, 0x01, 0x70, 0xa8, 0x78, 0x50, 0x23, 0x80, 
+-      0x43, 0x18, 0x70, 0x50, 0x78, 0xa8, 0x28, 0x00, 
+-      0xd1, 0x07, 0x98, 0x01, 0x68, 0x00, 0x4b, 0x1a, 
+-      0x40, 0x18, 0x9b, 0x01, 0x60, 0x18, 0x20, 0x01, 
+-      0x70, 0xe8, 0x24, 0x1f, 0x2c, 0x00, 0xd1, 0x02, 
+-      0xe0, 0x0a, 0x3c, 0x01, 0xe7, 0xfa, 0x48, 0x0d, 
+-      0x5d, 0x00, 0x28, 0x00, 0xd1, 0x03, 0x20, 0x19, 
+-      0x06, 0x80, 0x64, 0xc4, 0xe0, 0x00, 0xe7, 0xf4, 
+-      0x20, 0x00, 0xb0, 0x06, 0xe7, 0x3f, 0xb0, 0x06, 
+-      0xe7, 0x3d, 0x00, 0x00, 0x2e, 0x08, 0x5d, 0xcc, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x5e, 0xe4, 
+-      0x64, 0x00, 0x08, 0x08, 0x2e, 0x08, 0x5f, 0xa4, 
+-      0x2e, 0x08, 0x5e, 0xdc, 0x2e, 0x08, 0x7b, 0xf4, 
+-      0x64, 0x00, 0x00, 0x18, 0x2e, 0x08, 0x5d, 0xc4, 
+-      0x2e, 0x08, 0x5f, 0x64, 0x2e, 0x08, 0x5f, 0xc4, 
+-      0x2e, 0x08, 0x5e, 0xe0, 0x9e, 0x00, 0x04, 0xb8, 
+-      0xff, 0xff, 0xdf, 0xff, 0x1c, 0x03, 0x1c, 0x0a, 
+-      0x78, 0x58, 0x70, 0x10, 0x20, 0x00, 0x47, 0x70, 
+-      0xe7, 0xfd, 0xb5, 0xf7, 0x1c, 0x07, 0xb0, 0x81, 
+-      0x9a, 0x03, 0x06, 0x10, 0x0e, 0x00, 0x90, 0x00, 
+-      0xb0, 0x87, 0x78, 0x78, 0x23, 0x80, 0x40, 0x18, 
+-      0xd0, 0x4c, 0x78, 0x78, 0x23, 0x80, 0x40, 0x18, 
+-      0xd0, 0x48, 0x78, 0xb8, 0x90, 0x06, 0x99, 0x09, 
+-      0x78, 0x88, 0x90, 0x05, 0x98, 0x06, 0x23, 0x20, 
+-      0x40, 0x18, 0xd0, 0x3f, 0x98, 0x05, 0x23, 0x20, 
+-      0x40, 0x18, 0xd0, 0x3b, 0x6b, 0x38, 0x90, 0x01, 
+-      0x99, 0x09, 0x6b, 0x08, 0x90, 0x00, 0x98, 0x01, 
+-      0x28, 0x00, 0xd1, 0x02, 0x98, 0x00, 0x28, 0x00, 
+-      0xd0, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0x28, 0x00, 0xd1, 0x05, 0x20, 0xb6, 0xb0, 0x08, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x98, 0x01, 0x68, 0x05, 0x98, 0x00, 0x68, 0x04, 
+-      0x7a, 0x2e, 0x7a, 0x21, 0x91, 0x04, 0x7d, 0x6a, 
+-      0x92, 0x03, 0x7d, 0x62, 0x92, 0x02, 0x98, 0x07, 
+-      0x28, 0x00, 0xd0, 0x0a, 0x9a, 0x02, 0x99, 0x04, 
+-      0x1c, 0x28, 0xf0, 0x00, 0xfc, 0xe5, 0x9a, 0x03, 
+-      0x1c, 0x31, 0x1c, 0x20, 0xf0, 0x00, 0xfc, 0xe0, 
+-      0xe0, 0x09, 0x99, 0x04, 0x1c, 0x28, 0x22, 0x00, 
+-      0xf0, 0x00, 0xfc, 0xda, 0x1c, 0x31, 0x1c, 0x20, 
+-      0x22, 0x00, 0xf0, 0x00, 0xfc, 0xd5, 0x20, 0x00, 
+-      0xb0, 0x08, 0xe7, 0xd5, 0x20, 0xb1, 0xb0, 0x08, 
+-      0xe7, 0xd2, 0xb0, 0x07, 0xb0, 0x01, 0xe7, 0xcf, 
+-      0xb4, 0xf0, 0x1c, 0x02, 0x1c, 0x0b, 0x06, 0x1d, 
+-      0x0e, 0x2d, 0xb0, 0x82, 0x2d, 0x00, 0xd1, 0x0a, 
+-      0x48, 0x1a, 0x69, 0x00, 0x90, 0x01, 0x49, 0x1a, 
+-      0x48, 0x18, 0x69, 0x40, 0x90, 0x00, 0x48, 0x17, 
+-      0x6a, 0x00, 0x1e, 0x44, 0xe0, 0x10, 0x2d, 0x20, 
+-      0xd1, 0x0a, 0x48, 0x14, 0x69, 0x80, 0x90, 0x01, 
+-      0x49, 0x14, 0x48, 0x12, 0x69, 0xc0, 0x90, 0x00, 
+-      0x48, 0x10, 0x6a, 0x40, 0x1e, 0x44, 0xe0, 0x03, 
+-      0x20, 0xb3, 0xb0, 0x02, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x20, 0x00, 0x70, 0x10, 0x78, 0x50, 0x00, 0x80, 
+-      0x4e, 0x0d, 0x58, 0x37, 0x69, 0x38, 0x61, 0x78, 
+-      0x98, 0x01, 0x9e, 0x00, 0x42, 0xb0, 0xd0, 0x07, 
+-      0x98, 0x01, 0x30, 0x01, 0x90, 0x01, 0x98, 0x01, 
+-      0x40, 0x20, 0x90, 0x01, 0x98, 0x01, 0x60, 0x08, 
+-      0x20, 0x00, 0xb0, 0x02, 0xe7, 0xe6, 0xb0, 0x02, 
+-      0xe7, 0xe4, 0x00, 0x00, 0x9e, 0x00, 0x04, 0x80, 
+-      0x9e, 0x00, 0x04, 0x90, 0x9e, 0x00, 0x04, 0x98, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0xb5, 0xf3, 0x1c, 0x07, 
+-      0xb0, 0x81, 0x99, 0x02, 0x06, 0x08, 0x0e, 0x00, 
+-      0x90, 0x00, 0xb0, 0x88, 0x98, 0x08, 0x28, 0x00, 
+-      0xd1, 0x0e, 0x49, 0x69, 0x91, 0x02, 0x48, 0x69, 
+-      0x69, 0x00, 0x90, 0x07, 0x48, 0x68, 0x90, 0x06, 
+-      0x48, 0x66, 0x69, 0x40, 0x90, 0x05, 0x48, 0x65, 
+-      0x6a, 0x00, 0x1e, 0x41, 0x91, 0x04, 0xe0, 0x17, 
+-      0x98, 0x08, 0x28, 0x20, 0xd1, 0x0e, 0x49, 0x63, 
+-      0x91, 0x02, 0x48, 0x60, 0x69, 0x80, 0x90, 0x07, 
+-      0x48, 0x61, 0x90, 0x06, 0x48, 0x5d, 0x69, 0xc0, 
+-      0x90, 0x05, 0x48, 0x5c, 0x6a, 0x40, 0x1e, 0x41, 
+-      0x91, 0x04, 0xe0, 0x05, 0x20, 0xb3, 0xb0, 0x09, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x25, 0x00, 0x98, 0x07, 0x99, 0x05, 0x42, 0x88, 
+-      0xd0, 0x73, 0x2d, 0x00, 0xd1, 0x72, 0x98, 0x07, 
+-      0x00, 0x80, 0x99, 0x02, 0x18, 0x40, 0x23, 0x01, 
+-      0x02, 0x9b, 0x18, 0xc0, 0x68, 0x01, 0x91, 0x03, 
+-      0x98, 0x07, 0x00, 0x80, 0x99, 0x02, 0x58, 0x08, 
+-      0x90, 0x01, 0x99, 0x02, 0x98, 0x07, 0x18, 0x08, 
+-      0x23, 0x01, 0x02, 0xdb, 0x18, 0xc0, 0x78, 0x00, 
+-      0x90, 0x00, 0x20, 0x00, 0x99, 0x02, 0x9a, 0x07, 
+-      0x18, 0x89, 0x23, 0x01, 0x02, 0xdb, 0x18, 0xc9, 
+-      0x70, 0x08, 0x98, 0x07, 0x30, 0x01, 0x90, 0x07, 
+-      0x98, 0x07, 0x99, 0x04, 0x40, 0x08, 0x90, 0x07, 
+-      0x99, 0x03, 0x29, 0x00, 0xd0, 0x71, 0xb0, 0x83, 
+-      0x20, 0x00, 0x90, 0x00, 0x99, 0x06, 0x91, 0x02, 
+-      0x20, 0x01, 0x90, 0x01, 0x98, 0x03, 0x28, 0x80, 
+-      0xd1, 0x1f, 0x24, 0x00, 0x2c, 0x10, 0xd3, 0x02, 
+-      0xe0, 0x1a, 0x34, 0x01, 0xe7, 0xfa, 0x98, 0x01, 
+-      0x99, 0x02, 0x40, 0x08, 0xd0, 0x10, 0x48, 0x39, 
+-      0x5d, 0x00, 0x28, 0xff, 0xd0, 0x0c, 0x48, 0x37, 
+-      0x5d, 0x00, 0x90, 0x00, 0x00, 0xa0, 0x49, 0x36, 
+-      0x58, 0x09, 0x00, 0xa8, 0x19, 0xc0, 0x61, 0x01, 
+-      0x1c, 0x68, 0x06, 0x05, 0x0e, 0x2d, 0xe0, 0x03, 
+-      0x98, 0x01, 0x00, 0x40, 0x90, 0x01, 0xe7, 0xe4, 
+-      0xe0, 0x1d, 0x24, 0x00, 0x2c, 0x20, 0xd3, 0x02, 
+-      0xe0, 0x19, 0x34, 0x01, 0xe7, 0xfa, 0x98, 0x01, 
+-      0x99, 0x02, 0x40, 0x08, 0xd0, 0x0f, 0x48, 0x2b, 
+-      0x5d, 0x00, 0x28, 0xff, 0xd0, 0x0b, 0x48, 0x29, 
+-      0x5d, 0x00, 0x90, 0x00, 0x00, 0xa0, 0x49, 0x28, 
+-      0x58, 0x09, 0x00, 0xa8, 0x19, 0xc0, 0x61, 0x01, 
+-      0x1c, 0x68, 0x06, 0x05, 0x0e, 0x2d, 0x98, 0x01, 
+-      0x00, 0x40, 0x90, 0x01, 0xe7, 0xe5, 0x2d, 0x00, 
+-      0xe0, 0x01, 0xe0, 0x27, 0xe0, 0x26, 0xd0, 0x23, 
+-      0xb0, 0x81, 0x98, 0x01, 0x70, 0x78, 0x98, 0x05, 
+-      0x60, 0x78, 0x98, 0x01, 0x00, 0x80, 0x49, 0x1d, 
+-      0x58, 0x08, 0x90, 0x00, 0x98, 0x00, 0x69, 0x46, 
+-      0x98, 0x05, 0x42, 0xb0, 0xd3, 0x04, 0x1d, 0xf0, 
+-      0x30, 0xb9, 0x99, 0x05, 0x42, 0x88, 0xd2, 0x08, 
+-      0x68, 0x30, 0x28, 0x00, 0xd0, 0x01, 0x68, 0x36, 
+-      0xe0, 0x02, 0x20, 0xba, 0xb0, 0x0d, 0xe7, 0x63, 
+-      0xe7, 0xee, 0x60, 0xbe, 0x98, 0x00, 0x61, 0x46, 
+-      0x1c, 0x38, 0xf0, 0x00, 0xfb, 0x02, 0xb0, 0x01, 
+-      0xb0, 0x03, 0xe7, 0x5e, 0x70, 0x3d, 0x98, 0x07, 
+-      0x99, 0x06, 0x60, 0x08, 0x20, 0x00, 0xb0, 0x09, 
+-      0xe7, 0x52, 0xb0, 0x08, 0xb0, 0x01, 0xe7, 0x4f, 
+-      0x2e, 0x08, 0x60, 0x90, 0x9e, 0x00, 0x04, 0x80, 
+-      0x9e, 0x00, 0x04, 0x90, 0x2e, 0x08, 0x69, 0x90, 
+-      0x9e, 0x00, 0x04, 0x98, 0x2e, 0x08, 0x5f, 0xc4, 
+-      0x2e, 0x08, 0x5f, 0x64, 0x2e, 0x08, 0x5f, 0xa4, 
+-      0x2e, 0x08, 0x5e, 0xe4, 0x2e, 0x08, 0x5e, 0x5c, 
+-      0xb4, 0x90, 0x1c, 0x01, 0x78, 0x48, 0x00, 0x80, 
+-      0x4c, 0x0d, 0x58, 0x23, 0x69, 0x1a, 0x68, 0x8f, 
+-      0x42, 0xba, 0xd0, 0x12, 0x68, 0x10, 0x42, 0xb8, 
+-      0xd0, 0x08, 0x68, 0x10, 0x28, 0x00, 0xd0, 0x01, 
+-      0x68, 0x12, 0xe0, 0x02, 0x20, 0xba, 0xbc, 0x90, 
+-      0x47, 0x70, 0xe7, 0xf3, 0x20, 0x00, 0x60, 0x10, 
+-      0x69, 0x9c, 0x69, 0x18, 0x60, 0x20, 0x61, 0x1f, 
+-      0x61, 0x9a, 0x20, 0x00, 0xe7, 0xf3, 0xe7, 0xf2, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0xb4, 0xb0, 0x1c, 0x02, 
+-      0x1c, 0x0f, 0x78, 0x90, 0x23, 0x04, 0x40, 0x18, 
+-      0xd0, 0x1c, 0x78, 0x90, 0x23, 0x20, 0x40, 0x18, 
+-      0xd0, 0x18, 0x6b, 0x14, 0x68, 0x20, 0x28, 0x00, 
+-      0xd0, 0x02, 0x1d, 0xe5, 0x35, 0x05, 0xe0, 0x01, 
+-      0x1d, 0xe5, 0x35, 0x31, 0x21, 0x00, 0x29, 0x08, 
+-      0xdb, 0x04, 0xe0, 0x08, 0x1c, 0x48, 0x06, 0x01, 
+-      0x0e, 0x09, 0xe7, 0xf8, 0x00, 0x88, 0x58, 0x2b, 
+-      0x00, 0x88, 0x50, 0x3b, 0xe7, 0xf6, 0x20, 0x00, 
+-      0xbc, 0xb0, 0x47, 0x70, 0x20, 0xb1, 0xe7, 0xfb, 
+-      0xe7, 0xfa, 0xb5, 0xf3, 0x1c, 0x0a, 0xb0, 0x93, 
+-      0x20, 0x00, 0x90, 0x06, 0x98, 0x13, 0x69, 0x00, 
+-      0x90, 0x00, 0x98, 0x00, 0x6b, 0x00, 0x90, 0x12, 
+-      0x98, 0x00, 0x78, 0x80, 0x90, 0x05, 0x98, 0x12, 
+-      0x68, 0x00, 0x90, 0x01, 0x28, 0x00, 0xd0, 0x03, 
+-      0x98, 0x12, 0x30, 0x0c, 0x90, 0x09, 0xe0, 0x0e, 
+-      0x98, 0x12, 0x6a, 0xc0, 0x90, 0x01, 0x28, 0x00, 
+-      0xd0, 0x03, 0x98, 0x12, 0x30, 0x38, 0x90, 0x09, 
+-      0xe0, 0x05, 0x20, 0xb1, 0xb0, 0x13, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x20, 0x00, 
+-      0x90, 0x06, 0x98, 0x05, 0x23, 0x04, 0x40, 0x18, 
+-      0xd0, 0x73, 0x21, 0x00, 0x29, 0x08, 0xdb, 0x04, 
+-      0xe0, 0x0c, 0x1c, 0x48, 0x06, 0x01, 0x0e, 0x09, 
+-      0xe7, 0xf8, 0x98, 0x13, 0x30, 0x80, 0x69, 0x00, 
+-      0x00, 0x8b, 0x58, 0xc0, 0x00, 0x8e, 0xab, 0x0a, 
+-      0x51, 0x98, 0xe7, 0xf2, 0x9d, 0x01, 0x21, 0x00, 
+-      0x29, 0x08, 0xdb, 0x04, 0xe0, 0xa7, 0x1c, 0x48, 
+-      0x06, 0x01, 0x0e, 0x09, 0xe7, 0xf8, 0x00, 0x88, 
+-      0xab, 0x0a, 0x58, 0x18, 0x28, 0x00, 0xd0, 0x55, 
+-      0x20, 0x00, 0x90, 0x08, 0x48, 0x73, 0x90, 0x07, 
+-      0x20, 0x00, 0x90, 0x02, 0x98, 0x02, 0x28, 0x20, 
+-      0xdb, 0x06, 0xe0, 0x8d, 0x98, 0x02, 0x30, 0x01, 
+-      0x06, 0x00, 0x0e, 0x00, 0x90, 0x02, 0xe7, 0xf5, 
+-      0x00, 0x8b, 0xa8, 0x0a, 0x58, 0xc0, 0x9b, 0x07, 
+-      0x40, 0x18, 0x90, 0x08, 0x28, 0x00, 0xd0, 0x73, 
+-      0x00, 0x88, 0x9b, 0x09, 0x58, 0x18, 0x9b, 0x08, 
+-      0x40, 0x18, 0xd0, 0x6e, 0x1d, 0xec, 0x34, 0x01, 
+-      0x27, 0x00, 0x79, 0xa0, 0x9b, 0x06, 0x42, 0x98, 
+-      0xd0, 0x08, 0x68, 0x68, 0x1c, 0x05, 0xd1, 0x02, 
+-      0x20, 0xba, 0xb0, 0x13, 0xe7, 0xab, 0x1d, 0xec, 
+-      0x34, 0x01, 0xe7, 0xf2, 0x78, 0x60, 0x07, 0x00, 
+-      0x0f, 0x00, 0x02, 0x00, 0x04, 0x07, 0x0c, 0x3f, 
+-      0x78, 0xa0, 0x19, 0xc0, 0x30, 0x03, 0x04, 0x07, 
+-      0x0c, 0x3f, 0x2a, 0x00, 0xd0, 0x42, 0x98, 0x13, 
+-      0x88, 0x40, 0x42, 0xb8, 0xdb, 0x3a, 0x98, 0x13, 
+-      0x88, 0x40, 0x1b, 0xc0, 0x9b, 0x13, 0x80, 0x58, 
+-      0x20, 0xbc, 0x90, 0x04, 0x2f, 0x00, 0xdd, 0x30, 
+-      0x2f, 0xbc, 0xdd, 0x1b, 0x20, 0x00, 0x90, 0x03, 
+-      0x98, 0x03, 0x28, 0xbc, 0xdb, 0x09, 0xe0, 0x0d, 
+-      0x98, 0x03, 0x30, 0x01, 0x06, 0x00, 0x0e, 0x00, 
+-      0xe0, 0x01, 0xe0, 0x4c, 0xe0, 0x41, 0x90, 0x03, 
+-      0xe7, 0xf2, 0x78, 0x23, 0x34, 0x01, 0x70, 0x13, 
+-      0x32, 0x01, 0xe7, 0xf1, 0x1f, 0xf8, 0x38, 0xb5, 
+-      0x04, 0x07, 0x0c, 0x3f, 0x68, 0x2d, 0x1d, 0xec, 
+-      0x34, 0x01, 0xe0, 0x11, 0x20, 0x00, 0x90, 0x03, 
+-      0x98, 0x03, 0x42, 0xb8, 0xdb, 0x06, 0xe0, 0x0a, 
+-      0x98, 0x03, 0x30, 0x01, 0x06, 0x00, 0x0e, 0x00, 
+-      0x90, 0x03, 0xe7, 0xf5, 0x78, 0x23, 0x34, 0x01, 
+-      0x70, 0x13, 0x32, 0x01, 0xe7, 0xf4, 0x27, 0x00, 
+-      0xe7, 0xcc, 0xe0, 0x02, 0x20, 0xb7, 0xb0, 0x13, 
+-      0xe7, 0x59, 0xe0, 0x04, 0x98, 0x13, 0x88, 0x40, 
+-      0x19, 0xc0, 0x9b, 0x13, 0x80, 0x58, 0x00, 0x88, 
+-      0xab, 0x0a, 0x58, 0x18, 0x9b, 0x07, 0x43, 0x98, 
+-      0x00, 0x8e, 0xab, 0x0a, 0x51, 0x98, 0xe0, 0x01, 
+-      0xe0, 0x01, 0xe0, 0x00, 0x9d, 0x01, 0x98, 0x06, 
+-      0x30, 0x01, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x06, 
+-      0x98, 0x07, 0x08, 0x40, 0x90, 0x07, 0xe7, 0x71, 
+-      0xe0, 0x04, 0x98, 0x06, 0x30, 0x20, 0x06, 0x00, 
+-      0x0e, 0x00, 0x90, 0x06, 0xe7, 0x57, 0x20, 0x00, 
+-      0xb0, 0x13, 0xe7, 0x34, 0xe0, 0x44, 0x98, 0x05, 
+-      0x23, 0x02, 0x40, 0x18, 0xd0, 0x3b, 0x98, 0x01, 
+-      0x1d, 0xc4, 0x34, 0x01, 0x78, 0x60, 0x07, 0x00, 
+-      0x0f, 0x00, 0x02, 0x00, 0x04, 0x07, 0x0c, 0x3f, 
+-      0x78, 0xa0, 0x19, 0xc0, 0x30, 0x03, 0x04, 0x07, 
+-      0x0c, 0x3f, 0x2f, 0x00, 0xdd, 0x28, 0x2f, 0xbc, 
+-      0xdd, 0x17, 0x21, 0x00, 0x29, 0xbc, 0xdb, 0x04, 
+-      0xe0, 0x08, 0x1c, 0x48, 0x06, 0x01, 0x0e, 0x09, 
+-      0xe7, 0xf8, 0x78, 0x23, 0x34, 0x01, 0x70, 0x13, 
+-      0x32, 0x01, 0xe7, 0xf6, 0x1f, 0xf8, 0x38, 0xb5, 
+-      0x04, 0x07, 0x0c, 0x3f, 0x98, 0x01, 0x68, 0x00, 
+-      0x90, 0x01, 0x98, 0x01, 0x1d, 0xc4, 0x34, 0x01, 
+-      0xe0, 0x0d, 0x21, 0x00, 0x42, 0xb9, 0xdb, 0x04, 
+-      0xe0, 0x08, 0x1c, 0x48, 0x06, 0x01, 0x0e, 0x09, 
+-      0xe7, 0xf8, 0x78, 0x23, 0x34, 0x01, 0x70, 0x13, 
+-      0x32, 0x01, 0xe7, 0xf6, 0x27, 0x00, 0xe7, 0xd4, 
+-      0x20, 0x00, 0xb0, 0x13, 0xe6, 0xf3, 0x20, 0xb1, 
+-      0xb0, 0x13, 0xe6, 0xf0, 0xb0, 0x13, 0xe6, 0xee, 
+-      0xe6, 0xed, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 
+-      0xb5, 0xf3, 0xb0, 0x84, 0x98, 0x04, 0x78, 0x40, 
+-      0x00, 0x80, 0x49, 0x4b, 0x58, 0x08, 0x90, 0x03, 
+-      0x28, 0x00, 0xd1, 0x05, 0x20, 0xb0, 0xb0, 0x04, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x98, 0x04, 0x68, 0x86, 0x98, 0x04, 0x88, 0x47, 
+-      0x98, 0x04, 0x68, 0x44, 0x1d, 0xf0, 0x30, 0xb9, 
+-      0x99, 0x04, 0x68, 0x49, 0x1a, 0x45, 0x42, 0xbd, 
+-      0xdb, 0x0c, 0x2f, 0x00, 0xdb, 0x01, 0x2f, 0xbc, 
+-      0xdd, 0x02, 0x20, 0xba, 0xb0, 0x04, 0xe7, 0xe7, 
+-      0x1c, 0x3a, 0x99, 0x05, 0x1c, 0x20, 0xf0, 0x00, 
+-      0xf9, 0x29, 0xe0, 0x6b, 0x20, 0x00, 0x90, 0x00, 
+-      0x98, 0x04, 0x78, 0x40, 0x00, 0xc3, 0x1a, 0x18, 
+-      0x00, 0x80, 0x49, 0x36, 0x68, 0x09, 0x18, 0x40, 
+-      0x90, 0x01, 0x98, 0x01, 0x78, 0x80, 0x90, 0x02, 
+-      0x98, 0x02, 0x06, 0xc0, 0x0e, 0xc0, 0x90, 0x02, 
+-      0x98, 0x02, 0x28, 0x12, 0xd1, 0x03, 0x2d, 0x0e, 
+-      0xda, 0x01, 0x20, 0x01, 0x90, 0x00, 0x2f, 0x00, 
+-      0xdd, 0x50, 0xb0, 0x81, 0x42, 0xaf, 0xdd, 0x0d, 
+-      0x2d, 0x00, 0xdb, 0x01, 0x2d, 0xbc, 0xdd, 0x02, 
+-      0x20, 0xba, 0xb0, 0x05, 0xe7, 0xbc, 0x1c, 0x2a, 
+-      0x99, 0x06, 0x1c, 0x20, 0xf0, 0x00, 0xf8, 0xfe, 
+-      0x68, 0x36, 0xe0, 0x0b, 0x2f, 0x00, 0xdb, 0x01, 
+-      0x2f, 0xbc, 0xdd, 0x02, 0x20, 0xba, 0xb0, 0x05, 
+-      0xe7, 0xae, 0x1c, 0x3a, 0x99, 0x06, 0x1c, 0x20, 
+-      0xf0, 0x00, 0xf8, 0xf0, 0x99, 0x06, 0x19, 0x49, 
+-      0x91, 0x06, 0x1b, 0x7f, 0x1d, 0x31, 0x91, 0x00, 
+-      0x99, 0x00, 0x78, 0x88, 0x19, 0x84, 0x98, 0x01, 
+-      0x28, 0x00, 0xd0, 0x20, 0x99, 0x00, 0x78, 0xc8, 
+-      0x23, 0x80, 0x40, 0x18, 0xd1, 0x1b, 0x1d, 0xf0, 
+-      0x30, 0xb9, 0x1b, 0x05, 0x42, 0xbd, 0xdb, 0x01, 
+-      0x3c, 0x01, 0xe0, 0x14, 0x1c, 0x68, 0x42, 0xb8, 
+-      0xd1, 0x11, 0x99, 0x00, 0x78, 0x88, 0x28, 0x09, 
+-      0xdd, 0x08, 0x99, 0x00, 0x79, 0x08, 0x30, 0x09, 
+-      0x99, 0x00, 0x78, 0x89, 0x42, 0x88, 0xd0, 0x00, 
+-      0x3c, 0x01, 0xe0, 0x04, 0x99, 0x00, 0x78, 0x88, 
+-      0x28, 0x09, 0xd1, 0x00, 0x3c, 0x01, 0x20, 0x00, 
+-      0x90, 0x01, 0x1d, 0xf0, 0x30, 0xb9, 0x1b, 0x05, 
+-      0xb0, 0x01, 0xe7, 0xac, 0x20, 0x00, 0xb0, 0x04, 
+-      0xe7, 0x72, 0xb0, 0x04, 0xe7, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x5d, 0xc4, 
+-      0xb5, 0xf1, 0x98, 0x00, 0x06, 0x04, 0x0e, 0x24, 
+-      0xb0, 0x83, 0x00, 0xa0, 0x4b, 0x4c, 0x58, 0x1d, 
+-      0x78, 0x28, 0x90, 0x02, 0x2c, 0x20, 0xdb, 0x05, 
+-      0x20, 0xa2, 0xb0, 0x03, 0xb0, 0x01, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0xa0, 0x4b, 0x46, 
+-      0x58, 0x18, 0x1c, 0x05, 0xd1, 0x02, 0x20, 0xb0, 
+-      0xb0, 0x03, 0xe7, 0xf3, 0x00, 0xe0, 0x1b, 0x00, 
+-      0x00, 0x80, 0x4b, 0x42, 0x68, 0x1b, 0x18, 0xc7, 
+-      0x78, 0xa8, 0x28, 0x00, 0xd0, 0x63, 0x20, 0x00, 
+-      0x42, 0x80, 0xd0, 0x20, 0x21, 0x00, 0x29, 0x20, 
+-      0xdb, 0x04, 0xe0, 0x1b, 0x1c, 0x48, 0x06, 0x01, 
+-      0x0e, 0x09, 0xe7, 0xf8, 0x00, 0x88, 0x4b, 0x3a, 
+-      0x58, 0x18, 0x90, 0x01, 0x98, 0x01, 0x79, 0xc0, 
+-      0x42, 0xa0, 0xd1, 0x0e, 0x20, 0x01, 0x40, 0x88, 
+-      0x43, 0xc0, 0x4b, 0x36, 0x68, 0x1b, 0x40, 0x18, 
+-      0x4b, 0x34, 0x60, 0x18, 0x23, 0x00, 0x00, 0x88, 
+-      0x4e, 0x31, 0x50, 0x33, 0x23, 0xff, 0x48, 0x32, 
+-      0x54, 0x43, 0xe7, 0xe3, 0xe0, 0x3f, 0x7e, 0x38, 
+-      0x1c, 0x02, 0x28, 0xff, 0xd0, 0x10, 0x20, 0xff, 
+-      0x4b, 0x2e, 0x54, 0x98, 0x23, 0x00, 0x00, 0x90, 
+-      0x4e, 0x2d, 0x50, 0x33, 0x20, 0x01, 0x40, 0x90, 
+-      0x43, 0xc0, 0x4b, 0x2c, 0x88, 0x1b, 0x40, 0x18, 
+-      0x4b, 0x2a, 0x80, 0x18, 0x20, 0xff, 0x76, 0x38, 
+-      0x7e, 0x78, 0x1c, 0x02, 0x28, 0xff, 0xd0, 0x11, 
+-      0x20, 0xff, 0x4b, 0x24, 0x54, 0x98, 0x23, 0x00, 
+-      0x00, 0x90, 0x4e, 0x23, 0x50, 0x33, 0x20, 0x01, 
+-      0x40, 0x90, 0x43, 0xc0, 0x4b, 0x21, 0x88, 0x1b, 
+-      0x40, 0x18, 0x4b, 0x20, 0x80, 0x18, 0x20, 0xff, 
+-      0x76, 0x78, 0xe0, 0x02, 0x20, 0xb1, 0xb0, 0x03, 
+-      0xe7, 0x98, 0x23, 0x00, 0x00, 0x90, 0x4e, 0x1a, 
+-      0x50, 0x33, 0x20, 0x01, 0x40, 0x90, 0x43, 0xc0, 
+-      0x4b, 0x18, 0x88, 0x1b, 0x40, 0x18, 0x4b, 0x17, 
+-      0x80, 0x18, 0x4e, 0x17, 0x96, 0x00, 0x20, 0x00, 
+-      0x00, 0x93, 0x9e, 0x00, 0x50, 0xf0, 0x98, 0x02, 
+-      0x23, 0x20, 0x40, 0x18, 0xd0, 0xff, 0x21, 0x00, 
+-      0x29, 0x0c, 0xdb, 0x04, 0xe0, 0x07, 0x1c, 0x48, 
+-      0x06, 0x01, 0x0e, 0x09, 0xe7, 0xf8, 0x20, 0x00, 
+-      0x18, 0x7b, 0x73, 0x18, 0xe7, 0xf7, 0x20, 0x00, 
+-      0x83, 0x38, 0x20, 0x00, 0x70, 0xf8, 0x20, 0x00, 
+-      0xb0, 0x03, 0xe7, 0x6f, 0xb0, 0x03, 0xe7, 0x6d, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x5d, 0xc4, 
+-      0x2e, 0x08, 0x5e, 0xe4, 0x2e, 0x08, 0x5e, 0xdc, 
+-      0x2e, 0x08, 0x5f, 0xa4, 0x2e, 0x08, 0x5f, 0xc4, 
+-      0x2e, 0x08, 0x5f, 0x64, 0x2e, 0x08, 0x5e, 0xe0, 
+-      0x9e, 0x00, 0x04, 0xb8, 0xb5, 0xf0, 0x1c, 0x05, 
+-      0x1c, 0x0c, 0x1c, 0x17, 0x20, 0x1d, 0x02, 0x80, 
+-      0x69, 0x86, 0x1c, 0x3a, 0x1c, 0x29, 0x1c, 0x20, 
+-      0xf0, 0x08, 0xfb, 0x32, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb4, 0xf0, 0x1c, 0x01, 0xb0, 0x82, 
+-      0x68, 0x48, 0x68, 0x8c, 0x1d, 0xe2, 0x32, 0xb7, 
+-      0x42, 0x82, 0xd9, 0x09, 0x78, 0x42, 0x07, 0x12, 
+-      0x0f, 0x12, 0x02, 0x12, 0x78, 0x83, 0x43, 0x1a, 
+-      0x32, 0x03, 0x04, 0x17, 0x0c, 0x3f, 0xe0, 0x41, 
+-      0xb0, 0x82, 0x68, 0x23, 0x93, 0x01, 0x9b, 0x01, 
+-      0x33, 0x04, 0x93, 0x00, 0x9b, 0x00, 0x78, 0x9b, 
+-      0x9e, 0x01, 0x19, 0x9a, 0x78, 0x4e, 0x00, 0xf3, 
+-      0x1b, 0x9b, 0x00, 0x9b, 0x4e, 0x1b, 0x68, 0x36, 
+-      0x19, 0x9b, 0x93, 0x02, 0x9b, 0x02, 0x78, 0x9d, 
+-      0x06, 0xed, 0x0e, 0xed, 0x2d, 0x12, 0xd1, 0x0f, 
+-      0x1d, 0xe3, 0x33, 0xb9, 0x68, 0x4e, 0x1b, 0x9b, 
+-      0x06, 0x1b, 0x0e, 0x1b, 0x93, 0x03, 0x9b, 0x00, 
+-      0x78, 0xde, 0x23, 0x80, 0x40, 0x33, 0xd1, 0x03, 
+-      0x9b, 0x03, 0x2b, 0x0e, 0xda, 0x00, 0x3a, 0x01, 
+-      0x1d, 0xe3, 0x33, 0xb8, 0x42, 0x83, 0xd9, 0x0b, 
+-      0x78, 0x43, 0x07, 0x1b, 0x0f, 0x1b, 0x02, 0x1b, 
+-      0x04, 0x1f, 0x0c, 0x3f, 0x78, 0x13, 0x18, 0xfb, 
+-      0x33, 0x03, 0x04, 0x1f, 0x0c, 0x3f, 0xe0, 0x08, 
+-      0x78, 0x13, 0x07, 0x1b, 0x0f, 0x1b, 0x02, 0x1b, 
+-      0x78, 0x56, 0x43, 0x33, 0x33, 0x03, 0x04, 0x1f, 
+-      0x0c, 0x3f, 0xb0, 0x02, 0x80, 0x4f, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0x47, 0x70, 0x2e, 0x08, 0x5d, 0xc4, 
+-      0xb5, 0xf3, 0xb0, 0x81, 0x99, 0x02, 0x06, 0x0b, 
+-      0x0e, 0x1b, 0x93, 0x00, 0x9b, 0x00, 0x2b, 0x00, 
+-      0xd1, 0x0a, 0x49, 0x24, 0x4b, 0x24, 0x69, 0x1b, 
+-      0x1c, 0x18, 0x4b, 0x23, 0x69, 0x5b, 0x1c, 0x1c, 
+-      0x4b, 0x21, 0x6a, 0x1b, 0x1e, 0x5a, 0xe0, 0x09, 
+-      0x49, 0x20, 0x4b, 0x1f, 0x69, 0x9b, 0x1c, 0x18, 
+-      0x4b, 0x1d, 0x69, 0xdb, 0x1c, 0x1c, 0x4b, 0x1c, 
+-      0x6a, 0x5b, 0x1e, 0x5a, 0x9b, 0x01, 0x78, 0xdd, 
+-      0x26, 0x01, 0x40, 0xae, 0x1c, 0x37, 0x42, 0xa0, 
+-      0xd0, 0x26, 0x00, 0x83, 0x18, 0x5d, 0x23, 0x01, 
+-      0x02, 0x9b, 0x18, 0xeb, 0x68, 0x1b, 0x40, 0x3b, 
+-      0xd0, 0x1b, 0x00, 0x83, 0x18, 0x5d, 0x23, 0x01, 
+-      0x02, 0x9b, 0x18, 0xeb, 0x68, 0x1b, 0x43, 0xbb, 
+-      0x1c, 0x1d, 0x00, 0x83, 0x18, 0x5e, 0x23, 0x01, 
+-      0x02, 0x9b, 0x18, 0xf3, 0x60, 0x1d, 0x00, 0x83, 
+-      0x18, 0x5d, 0x23, 0x01, 0x02, 0x9b, 0x18, 0xeb, 
+-      0x68, 0x1b, 0x2b, 0x00, 0xd1, 0x05, 0x25, 0x00, 
+-      0x18, 0x0e, 0x23, 0x01, 0x02, 0xdb, 0x18, 0xf3, 
+-      0x70, 0x1d, 0x30, 0x01, 0x40, 0x10, 0xe7, 0xd6, 
+-      0xb0, 0x01, 0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x60, 0x90, 
+-      0x9e, 0x00, 0x04, 0x80, 0x2e, 0x08, 0x69, 0x90, 
+-      0xb4, 0x90, 0x1c, 0x03, 0x1c, 0x0c, 0x1c, 0x17, 
+-      0x06, 0x21, 0x0e, 0x09, 0x06, 0x38, 0x0e, 0x00, 
+-      0x72, 0x19, 0x28, 0x00, 0xd0, 0x00, 0x75, 0x58, 
+-      0x68, 0x5b, 0x2b, 0x00, 0xd1, 0xf8, 0xbc, 0x90, 
+-      0x47, 0x70, 0x00, 0x00, 0xb5, 0x80, 0x1c, 0x07, 
+-      0x68, 0xf8, 0x28, 0x1f, 0xd9, 0x03, 0x20, 0xe1, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x48, 0x1e, 
+-      0x6d, 0x00, 0x68, 0x00, 0x4b, 0x1d, 0x40, 0x18, 
+-      0x49, 0x1b, 0x6d, 0x09, 0x60, 0x08, 0x05, 0x80, 
+-      0x48, 0x19, 0x6d, 0x00, 0x68, 0x00, 0x49, 0x18, 
+-      0x6e, 0xc9, 0x60, 0x08, 0x48, 0x16, 0x6d, 0x00, 
+-      0x68, 0x00, 0x23, 0x01, 0x02, 0x5b, 0x43, 0x18, 
+-      0x49, 0x13, 0x6d, 0x09, 0x60, 0x08, 0x05, 0x80, 
+-      0x48, 0x11, 0x6d, 0x00, 0x68, 0x00, 0x49, 0x10, 
+-      0x6e, 0xc9, 0x60, 0x08, 0x48, 0x0e, 0x6f, 0xc1, 
+-      0xcf, 0x09, 0xc1, 0x09, 0xcf, 0x09, 0xc1, 0x09, 
+-      0xcf, 0x08, 0xc1, 0x08, 0xf0, 0x00, 0xfc, 0x1e, 
+-      0x20, 0x00, 0x49, 0x09, 0x60, 0x08, 0x20, 0x00, 
+-      0x49, 0x07, 0x60, 0x48, 0x20, 0x00, 0x49, 0x06, 
+-      0x60, 0x88, 0x49, 0x07, 0x20, 0x0b, 0xf0, 0x0c, 
+-      0xf9, 0xb5, 0x20, 0xff, 0x30, 0x01, 0x49, 0x02, 
+-      0x61, 0xc8, 0x20, 0x00, 0xe7, 0xc0, 0xe7, 0xbf, 
+-      0x2e, 0x08, 0x1f, 0x1c, 0xff, 0xff, 0xfd, 0xff, 
+-      0x2e, 0x01, 0x09, 0x15, 0x1c, 0x01, 0x48, 0x0e, 
+-      0x6f, 0x00, 0x68, 0x00, 0x60, 0x08, 0x48, 0x0c, 
+-      0x6e, 0x80, 0x68, 0x00, 0x60, 0x48, 0x48, 0x0a, 
+-      0x6e, 0xc0, 0x68, 0x00, 0x60, 0x88, 0x48, 0x08, 
+-      0x6f, 0x40, 0x68, 0x00, 0x60, 0xc8, 0x48, 0x06, 
+-      0x68, 0x00, 0x61, 0x08, 0x48, 0x04, 0x68, 0x40, 
+-      0x61, 0x48, 0x48, 0x03, 0x68, 0x80, 0x61, 0x88, 
+-      0x20, 0x00, 0x47, 0x70, 0xe7, 0xfd, 0x00, 0x00, 
+-      0x2e, 0x08, 0x1f, 0x1c, 0x48, 0x03, 0x6e, 0x80, 
+-      0x68, 0x00, 0x07, 0x40, 0x0f, 0xc0, 0x47, 0x70, 
+-      0xe7, 0xfd, 0x00, 0x00, 0x2e, 0x08, 0x1f, 0x1c, 
+-      0xb4, 0x80, 0x1c, 0x07, 0x1c, 0x0a, 0x48, 0x37, 
+-      0x69, 0xc0, 0x23, 0xff, 0x33, 0x01, 0x42, 0x98, 
+-      0xd0, 0x02, 0x20, 0xe0, 0xbc, 0x80, 0x47, 0x70, 
+-      0x48, 0x32, 0x62, 0x07, 0x20, 0x00, 0x49, 0x31, 
+-      0x62, 0x48, 0x48, 0x31, 0x60, 0x02, 0x48, 0x30, 
+-      0x68, 0x00, 0x78, 0x00, 0x49, 0x2d, 0x61, 0x88, 
+-      0x48, 0x2d, 0x68, 0x00, 0x7a, 0x00, 0x49, 0x2b, 
+-      0x61, 0x08, 0x48, 0x2b, 0x68, 0x00, 0x68, 0x40, 
+-      0x49, 0x28, 0x60, 0xc8, 0x48, 0x27, 0x69, 0x80, 
+-      0x07, 0xc0, 0x0f, 0xc0, 0xd0, 0x01, 0x48, 0x27, 
+-      0xe0, 0x01, 0x20, 0x01, 0x02, 0x40, 0x49, 0x23, 
+-      0x61, 0xc8, 0x48, 0x22, 0x68, 0x40, 0x30, 0x01, 
+-      0x49, 0x20, 0x60, 0x48, 0x48, 0x1f, 0x6d, 0x40, 
+-      0x68, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x49, 0x1d, 
+-      0x69, 0x89, 0x08, 0x49, 0x06, 0x09, 0x0e, 0x09, 
+-      0x43, 0x08, 0x49, 0x1a, 0x6d, 0x49, 0x60, 0x08, 
+-      0x06, 0x00, 0x48, 0x18, 0x6d, 0x00, 0x68, 0x00, 
+-      0x4b, 0x19, 0x40, 0x18, 0x49, 0x15, 0x69, 0x89, 
+-      0x07, 0xc9, 0x0c, 0x49, 0x43, 0x08, 0x49, 0x13, 
+-      0x6d, 0x09, 0x60, 0x08, 0x04, 0x40, 0x48, 0x11, 
+-      0x6d, 0x00, 0x68, 0x00, 0x4b, 0x13, 0x40, 0x18, 
+-      0x49, 0x0e, 0x6d, 0x09, 0x60, 0x08, 0x05, 0x40, 
+-      0x48, 0x0c, 0x6d, 0x00, 0x68, 0x00, 0x23, 0x01, 
+-      0x03, 0x1b, 0x43, 0x18, 0x49, 0x09, 0x6d, 0x09, 
+-      0x60, 0x08, 0x04, 0xc0, 0x48, 0x07, 0x6d, 0x40, 
+-      0x68, 0x00, 0x49, 0x06, 0x6f, 0x09, 0x60, 0x08, 
+-      0x48, 0x04, 0x6d, 0x00, 0x68, 0x00, 0x49, 0x03, 
+-      0x6e, 0xc9, 0x60, 0x08, 0x20, 0x00, 0xe7, 0x99, 
+-      0xe7, 0x98, 0x00, 0x00, 0x2e, 0x08, 0x1f, 0x1c, 
+-      0x2e, 0x08, 0x60, 0x54, 0x00, 0x00, 0x02, 0x01, 
+-      0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xfb, 0xff, 
+-      0xb5, 0x00, 0x48, 0xf6, 0x6e, 0x80, 0x68, 0x00, 
+-      0x23, 0x08, 0x40, 0x18, 0xd0, 0x74, 0x48, 0xf3, 
+-      0x6d, 0x00, 0x68, 0x00, 0x4b, 0xf2, 0x40, 0x18, 
+-      0x49, 0xf0, 0x6d, 0x09, 0x60, 0x08, 0x04, 0x80, 
+-      0x48, 0xee, 0x6e, 0x40, 0x68, 0x00, 0x0a, 0x00, 
+-      0x02, 0x00, 0x49, 0xec, 0x6e, 0x49, 0x60, 0x08, 
+-      0x06, 0x00, 0x48, 0xea, 0x6e, 0xc0, 0x68, 0x00, 
+-      0x23, 0x01, 0x02, 0xdb, 0x40, 0x18, 0xd0, 0x3e, 
+-      0x20, 0xff, 0x30, 0x01, 0x49, 0xe5, 0x61, 0xc8, 
+-      0x48, 0xe4, 0x6d, 0x00, 0x68, 0x00, 0x4b, 0xe5, 
+-      0x40, 0x18, 0x49, 0xe2, 0x6d, 0x09, 0x60, 0x08, 
+-      0x04, 0xc0, 0x48, 0xe0, 0x6f, 0xc0, 0x68, 0x80, 
+-      0x68, 0x01, 0x02, 0x09, 0x0a, 0x09, 0x4a, 0xdd, 
+-      0x6a, 0x52, 0x06, 0x12, 0x43, 0x11, 0x60, 0x01, 
+-      0x48, 0xdd, 0x68, 0x00, 0x7a, 0x00, 0x49, 0xd9, 
+-      0x69, 0x09, 0x1a, 0x41, 0x48, 0xd7, 0x6f, 0xc0, 
+-      0x68, 0x80, 0x68, 0x02, 0x4b, 0xd9, 0x40, 0x1a, 
+-      0x04, 0x09, 0x0c, 0x09, 0x02, 0x09, 0x43, 0x11, 
+-      0x60, 0x01, 0x02, 0x08, 0x0c, 0x00, 0x48, 0xd1, 
+-      0x6f, 0xc0, 0x68, 0x80, 0x68, 0x01, 0x23, 0x04, 
+-      0x43, 0x19, 0x60, 0x01, 0x07, 0x48, 0x48, 0xcd, 
+-      0x6f, 0xc0, 0x68, 0xc1, 0x20, 0x01, 0x40, 0x88, 
+-      0xf0, 0x0c, 0xf8, 0x96, 0x48, 0xc9, 0x68, 0x00, 
+-      0x30, 0x01, 0x49, 0xc8, 0x60, 0x08, 0x48, 0xc7, 
+-      0x69, 0xc0, 0x4b, 0xcb, 0x42, 0x98, 0xd0, 0x73, 
+-      0xdc, 0x08, 0x23, 0xff, 0x33, 0x01, 0x42, 0x98, 
+-      0xd0, 0x6f, 0x23, 0x01, 0x02, 0x5b, 0x42, 0x98, 
+-      0xd0, 0x07, 0xe2, 0xba, 0x4b, 0xc5, 0x42, 0x98, 
+-      0xd0, 0x68, 0x4b, 0xc5, 0x42, 0x98, 0xd0, 0x66, 
+-      0xe2, 0xb3, 0x48, 0xbc, 0x6e, 0x80, 0x68, 0x00, 
+-      0x23, 0x01, 0x02, 0x5b, 0x40, 0x18, 0xe0, 0x00, 
+-      0xe2, 0xcd, 0xd0, 0x3f, 0x48, 0xb7, 0x68, 0x00, 
+-      0x30, 0x01, 0x49, 0xb6, 0x60, 0x08, 0x48, 0xb5, 
+-      0x6d, 0x00, 0x68, 0x00, 0x4b, 0xb5, 0x40, 0x18, 
+-      0x49, 0xb2, 0x6d, 0x09, 0x60, 0x08, 0x04, 0xc0, 
+-      0x20, 0xff, 0x30, 0x01, 0x49, 0xaf, 0x61, 0xc8, 
+-      0x48, 0xae, 0x6f, 0xc0, 0x68, 0x80, 0x68, 0x01, 
+-      0x02, 0x09, 0x0a, 0x09, 0x4a, 0xab, 0x6a, 0x52, 
+-      0x06, 0x12, 0x43, 0x11, 0x60, 0x01, 0x48, 0xac, 
+-      0x68, 0x00, 0x7a, 0x00, 0x49, 0xa7, 0x69, 0x09, 
+-      0x1a, 0x41, 0x48, 0xa6, 0x6f, 0xc0, 0x68, 0x80, 
+-      0x68, 0x02, 0x4b, 0xa8, 0x40, 0x1a, 0x04, 0x09, 
+-      0x0c, 0x09, 0x02, 0x09, 0x43, 0x11, 0x60, 0x01, 
+-      0x02, 0x08, 0x0c, 0x00, 0x48, 0x9f, 0x6f, 0xc0, 
+-      0x68, 0x80, 0x68, 0x01, 0x23, 0x02, 0x43, 0x19, 
+-      0x60, 0x01, 0x07, 0x88, 0x48, 0x9b, 0x6f, 0xc0, 
+-      0x68, 0xc1, 0x20, 0x01, 0x40, 0x88, 0xf0, 0x0c, 
+-      0xf8, 0x33, 0xe0, 0x5e, 0x48, 0x97, 0x69, 0x00, 
+-      0x28, 0x00, 0xd0, 0x20, 0x48, 0x95, 0x69, 0x00, 
+-      0x38, 0x01, 0x49, 0x94, 0x61, 0x08, 0x48, 0x93, 
+-      0x68, 0xc0, 0x78, 0x00, 0x49, 0x91, 0x6c, 0x89, 
+-      0x68, 0x09, 0x0a, 0x09, 0x02, 0x09, 0x43, 0x08, 
+-      0x49, 0x8e, 0x6c, 0x89, 0x60, 0x08, 0x06, 0x00, 
+-      0x0e, 0x00, 0x48, 0x8c, 0x68, 0xc0, 0xe0, 0x03, 
+-      0xe1, 0x4b, 0xe2, 0x4d, 0xe0, 0x42, 0xe1, 0x93, 
+-      0x30, 0x01, 0x49, 0x88, 0x60, 0xc8, 0x48, 0x8d, 
+-      0x49, 0x86, 0x61, 0xc8, 0xe0, 0x39, 0x20, 0xff, 
+-      0x30, 0x01, 0x49, 0x84, 0x61, 0xc8, 0x48, 0x83, 
+-      0x6f, 0xc0, 0x68, 0x80, 0x68, 0x01, 0x02, 0x09, 
+-      0x0a, 0x09, 0x4a, 0x80, 0x6a, 0x52, 0x06, 0x12, 
+-      0x43, 0x11, 0x60, 0x01, 0x48, 0x80, 0x68, 0x00, 
+-      0x7a, 0x00, 0x49, 0x7c, 0x69, 0x09, 0x1a, 0x41, 
+-      0x48, 0x7a, 0x6f, 0xc0, 0x68, 0x80, 0x68, 0x02, 
+-      0x4b, 0x7c, 0x40, 0x1a, 0x04, 0x09, 0x0c, 0x09, 
+-      0x02, 0x09, 0x43, 0x11, 0x60, 0x01, 0x02, 0x08, 
+-      0x0c, 0x00, 0x48, 0x74, 0x6f, 0xc0, 0x68, 0x80, 
+-      0x68, 0x01, 0x23, 0x01, 0x43, 0x19, 0x60, 0x01, 
+-      0x07, 0xc8, 0x48, 0x70, 0x6f, 0xc0, 0x68, 0xc1, 
+-      0x20, 0x01, 0x40, 0x88, 0xf0, 0x0b, 0xff, 0xdc, 
+-      0x48, 0x6c, 0x6d, 0x00, 0x68, 0x00, 0x4b, 0x6d, 
+-      0x40, 0x18, 0x49, 0x6a, 0x6d, 0x09, 0x60, 0x08, 
+-      0x04, 0xc0, 0xe2, 0x08, 0x48, 0x67, 0x69, 0x00, 
+-      0x28, 0x00, 0xd0, 0x5f, 0x48, 0x65, 0x6e, 0x80, 
+-      0x68, 0x00, 0x23, 0xff, 0x33, 0x01, 0x40, 0x18, 
+-      0xd0, 0x3f, 0x48, 0x62, 0x68, 0x00, 0x30, 0x01, 
+-      0x49, 0x60, 0x60, 0x08, 0x48, 0x5f, 0x6d, 0x00, 
+-      0x68, 0x00, 0x4b, 0x60, 0x40, 0x18, 0x49, 0x5d, 
+-      0x6d, 0x09, 0x60, 0x08, 0x04, 0xc0, 0x20, 0xff, 
+-      0x30, 0x01, 0x49, 0x5a, 0x61, 0xc8, 0x48, 0x59, 
+-      0x6f, 0xc0, 0x68, 0x80, 0x68, 0x01, 0x02, 0x09, 
+-      0x0a, 0x09, 0x4a, 0x56, 0x6a, 0x52, 0x06, 0x12, 
+-      0x43, 0x11, 0x60, 0x01, 0x48, 0x56, 0x68, 0x00, 
+-      0x7a, 0x00, 0x49, 0x52, 0x69, 0x09, 0x1a, 0x41, 
+-      0x48, 0x50, 0x6f, 0xc0, 0x68, 0x80, 0x68, 0x02, 
+-      0x4b, 0x52, 0x40, 0x1a, 0x04, 0x09, 0x0c, 0x09, 
+-      0x02, 0x09, 0x43, 0x11, 0x60, 0x01, 0x02, 0x08, 
+-      0x0c, 0x00, 0x48, 0x4a, 0x6f, 0xc0, 0x68, 0x80, 
+-      0x68, 0x01, 0x23, 0x02, 0x43, 0x19, 0x60, 0x01, 
+-      0x07, 0x88, 0x48, 0x46, 0x6f, 0xc0, 0x68, 0xc1, 
+-      0x20, 0x01, 0x40, 0x88, 0xf0, 0x0b, 0xff, 0x88, 
+-      0xe0, 0x17, 0x48, 0x42, 0x68, 0xc0, 0x78, 0x00, 
+-      0x49, 0x40, 0x6c, 0x89, 0x68, 0x09, 0x0a, 0x09, 
+-      0x02, 0x09, 0x43, 0x08, 0x49, 0x3d, 0x6c, 0x89, 
+-      0x60, 0x08, 0x06, 0x00, 0x0e, 0x00, 0x48, 0x3b, 
+-      0x68, 0xc0, 0x30, 0x01, 0x49, 0x39, 0x60, 0xc8, 
+-      0x48, 0x38, 0x69, 0x00, 0x38, 0x01, 0x49, 0x37, 
+-      0x61, 0x08, 0xe0, 0xa1, 0x48, 0x35, 0x6a, 0x00, 
+-      0x38, 0x01, 0x49, 0x34, 0x62, 0x08, 0x48, 0x33, 
+-      0x6a, 0x00, 0x28, 0x00, 0xd0, 0x4b, 0x48, 0x31, 
+-      0x6a, 0x40, 0x30, 0x01, 0x49, 0x2f, 0x62, 0x48, 
+-      0x48, 0x31, 0x68, 0x00, 0x30, 0x0c, 0x49, 0x30, 
+-      0x60, 0x08, 0x48, 0x2f, 0x68, 0x00, 0x78, 0x00, 
+-      0x49, 0x2a, 0x61, 0x88, 0x48, 0x2c, 0x68, 0x00, 
+-      0x7a, 0x00, 0x49, 0x28, 0x61, 0x08, 0x48, 0x2a, 
+-      0x68, 0x00, 0x68, 0x40, 0x49, 0x25, 0x60, 0xc8, 
+-      0x48, 0x24, 0x69, 0x80, 0x07, 0xc0, 0x0f, 0xc0, 
+-      0xd0, 0x01, 0x48, 0x27, 0xe0, 0x01, 0x20, 0x01, 
+-      0x02, 0x40, 0x49, 0x20, 0x61, 0xc8, 0x48, 0x1f, 
+-      0x6d, 0x00, 0x68, 0x00, 0x23, 0x01, 0x03, 0x5b, 
+-      0x43, 0x18, 0x49, 0x1c, 0x6d, 0x09, 0x60, 0x08, 
+-      0x04, 0x80, 0x48, 0x1a, 0x6d, 0x40, 0x68, 0x00, 
+-      0x0a, 0x00, 0x02, 0x00, 0x49, 0x17, 0x69, 0x89, 
+-      0x08, 0x49, 0x06, 0x09, 0x0e, 0x09, 0x43, 0x08, 
+-      0x49, 0x14, 0x6d, 0x49, 0x60, 0x08, 0x06, 0x00, 
+-      0x48, 0x12, 0x6d, 0x00, 0x68, 0x00, 0x4b, 0x19, 
+-      0x40, 0x18, 0x49, 0x10, 0x69, 0x89, 0x07, 0xc9, 
+-      0x0c, 0x49, 0x43, 0x08, 0x49, 0x0d, 0x6d, 0x09, 
+-      0x60, 0x08, 0x04, 0x40, 0xe0, 0x4c, 0x20, 0xff, 
+-      0x30, 0x01, 0x49, 0x0a, 0x61, 0xc8, 0x48, 0x09, 
+-      0x6f, 0xc0, 0x68, 0x80, 0x68, 0x01, 0x02, 0x09, 
+-      0x0a, 0x09, 0x4a, 0x06, 0x6a, 0x52, 0x06, 0x12, 
+-      0x43, 0x11, 0x60, 0x01, 0x48, 0x06, 0x68, 0x00, 
+-      0x7a, 0x00, 0x49, 0x02, 0x69, 0x09, 0x1a, 0x41, 
+-      0x48, 0x00, 0xe0, 0x11, 0x2e, 0x08, 0x1f, 0x1c, 
+-      0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xef, 0xff, 
+-      0x2e, 0x08, 0x60, 0x54, 0xff, 0x00, 0x00, 0xff, 
+-      0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 0x02, 
+-      0x00, 0x00, 0x02, 0x03, 0xff, 0xff, 0xbf, 0xff, 
+-      0x6f, 0xc0, 0x68, 0x80, 0x68, 0x02, 0x4b, 0xa5, 
+-      0x40, 0x1a, 0x04, 0x09, 0x0c, 0x09, 0x02, 0x09, 
+-      0x43, 0x11, 0x60, 0x01, 0x02, 0x08, 0x0c, 0x00, 
+-      0x48, 0xa1, 0x6f, 0xc0, 0x68, 0x80, 0x68, 0x01, 
+-      0x23, 0x01, 0x43, 0x19, 0x60, 0x01, 0x07, 0xc8, 
+-      0x48, 0x9d, 0x6f, 0xc0, 0x68, 0xc1, 0x20, 0x01, 
+-      0x40, 0x88, 0xf0, 0x0b, 0xfe, 0xd5, 0x48, 0x9a, 
+-      0x6d, 0x00, 0x68, 0x00, 0x4b, 0x99, 0x40, 0x18, 
+-      0x49, 0x97, 0x6d, 0x09, 0x60, 0x08, 0x04, 0xc0, 
+-      0xe1, 0x01, 0x48, 0x95, 0x6e, 0x80, 0x68, 0x00, 
+-      0x23, 0x01, 0x02, 0x5b, 0x40, 0x18, 0xd0, 0x3f, 
+-      0x48, 0x91, 0x68, 0x00, 0x30, 0x01, 0x49, 0x90, 
+-      0x60, 0x08, 0x48, 0x8f, 0x6d, 0x00, 0x68, 0x00, 
+-      0x4b, 0x8e, 0x40, 0x18, 0x49, 0x8c, 0x6d, 0x09, 
+-      0x60, 0x08, 0x04, 0xc0, 0x20, 0xff, 0x30, 0x01, 
+-      0x49, 0x89, 0x61, 0xc8, 0x48, 0x88, 0x6f, 0xc0, 
+-      0x68, 0x80, 0x68, 0x01, 0x02, 0x09, 0x0a, 0x09, 
+-      0x4a, 0x85, 0x6a, 0x52, 0x06, 0x12, 0x43, 0x11, 
+-      0x60, 0x01, 0x48, 0x85, 0x68, 0x00, 0x7a, 0x00, 
+-      0x49, 0x81, 0x69, 0x09, 0x1a, 0x41, 0x48, 0x80, 
+-      0x6f, 0xc0, 0x68, 0x80, 0x68, 0x02, 0x4b, 0x7d, 
+-      0x40, 0x1a, 0x04, 0x09, 0x0c, 0x09, 0x02, 0x09, 
+-      0x43, 0x11, 0x60, 0x01, 0x02, 0x08, 0x0c, 0x00, 
+-      0x48, 0x79, 0x6f, 0xc0, 0x68, 0x80, 0x68, 0x01, 
+-      0x23, 0x02, 0x43, 0x19, 0x60, 0x01, 0x07, 0x88, 
+-      0x48, 0x75, 0x6f, 0xc0, 0x68, 0xc1, 0x20, 0x01, 
+-      0x40, 0x88, 0xf0, 0x0b, 0xfe, 0x85, 0xe0, 0x02, 
+-      0x48, 0x74, 0x49, 0x71, 0x61, 0xc8, 0xe0, 0xb6, 
+-      0x48, 0x6f, 0x69, 0x00, 0x28, 0x00, 0xd0, 0x62, 
+-      0x48, 0x6d, 0x6e, 0x00, 0x68, 0x00, 0x49, 0x6c, 
+-      0x68, 0xc9, 0x70, 0x08, 0x48, 0x6a, 0x68, 0xc0, 
+-      0x30, 0x01, 0x49, 0x69, 0x60, 0xc8, 0x48, 0x68, 
+-      0x69, 0x00, 0x38, 0x01, 0x49, 0x66, 0x61, 0x08, 
+-      0x48, 0x65, 0x69, 0x00, 0x28, 0x00, 0xd1, 0x4d, 
+-      0x48, 0x63, 0x6a, 0x00, 0x28, 0x01, 0xd1, 0x49, 
+-      0x48, 0x63, 0x68, 0x00, 0x7a, 0x40, 0x49, 0x60, 
+-      0x6d, 0x09, 0x68, 0x09, 0x4b, 0x62, 0x40, 0x19, 
+-      0x07, 0xc0, 0x0d, 0x40, 0x43, 0x08, 0x49, 0x5c, 
+-      0x6d, 0x09, 0x60, 0x08, 0x05, 0x40, 0x0f, 0xc0, 
+-      0x20, 0xff, 0x30, 0x01, 0x49, 0x58, 0x61, 0xc8, 
+-      0x48, 0x57, 0x6d, 0x00, 0x68, 0x00, 0x4b, 0x57, 
+-      0x40, 0x18, 0x49, 0x55, 0x6d, 0x09, 0x60, 0x08, 
+-      0x04, 0xc0, 0x48, 0x53, 0x6f, 0xc0, 0x68, 0x80, 
+-      0x68, 0x01, 0x02, 0x09, 0x0a, 0x09, 0x4a, 0x50, 
+-      0x6a, 0x52, 0x06, 0x12, 0x43, 0x11, 0x60, 0x01, 
+-      0x48, 0x4f, 0x68, 0x00, 0x7a, 0x00, 0x49, 0x4c, 
+-      0x69, 0x09, 0x1a, 0x41, 0x48, 0x4a, 0x6f, 0xc0, 
+-      0x68, 0x80, 0x68, 0x02, 0x4b, 0x47, 0x40, 0x1a, 
+-      0x04, 0x09, 0x0c, 0x09, 0x02, 0x09, 0x43, 0x11, 
+-      0x60, 0x01, 0x02, 0x08, 0x0c, 0x00, 0x48, 0x44, 
+-      0x6f, 0xc0, 0x68, 0x80, 0x68, 0x01, 0x23, 0x01, 
+-      0x43, 0x19, 0x60, 0x01, 0x07, 0xc8, 0x48, 0x40, 
+-      0x6f, 0xc0, 0x68, 0xc1, 0x20, 0x01, 0x40, 0x88, 
+-      0xf0, 0x0b, 0xfe, 0x1a, 0xe0, 0x4f, 0x48, 0x3c, 
+-      0x6a, 0x00, 0x38, 0x01, 0x49, 0x3a, 0x62, 0x08, 
+-      0x48, 0x39, 0x6a, 0x40, 0x30, 0x01, 0x49, 0x38, 
+-      0x62, 0x48, 0x48, 0x39, 0x68, 0x00, 0x30, 0x0c, 
+-      0x49, 0x37, 0x60, 0x08, 0x48, 0x36, 0x68, 0x00, 
+-      0x78, 0x00, 0x49, 0x33, 0x61, 0x88, 0x48, 0x34, 
+-      0x68, 0x00, 0x7a, 0x00, 0x49, 0x30, 0x61, 0x08, 
+-      0x48, 0x31, 0x68, 0x00, 0x68, 0x40, 0x49, 0x2e, 
+-      0x60, 0xc8, 0x48, 0x2d, 0x69, 0x80, 0x07, 0xc0, 
+-      0x0f, 0xc0, 0xd0, 0x01, 0x48, 0x2f, 0xe0, 0x01, 
+-      0x20, 0x01, 0x02, 0x40, 0x49, 0x28, 0x61, 0xc8, 
+-      0x48, 0x27, 0x6d, 0x00, 0x68, 0x00, 0x23, 0x01, 
+-      0x03, 0x5b, 0x43, 0x18, 0x49, 0x24, 0x6d, 0x09, 
+-      0x60, 0x08, 0x04, 0x80, 0x48, 0x22, 0x6d, 0x40, 
+-      0x68, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x49, 0x20, 
+-      0x69, 0x89, 0x08, 0x49, 0x06, 0x09, 0x0e, 0x09, 
+-      0x43, 0x08, 0x49, 0x1d, 0x6d, 0x49, 0x60, 0x08, 
+-      0x06, 0x00, 0x48, 0x1b, 0x6d, 0x00, 0x68, 0x00, 
+-      0x4b, 0x1f, 0x40, 0x18, 0x49, 0x18, 0x69, 0x89, 
+-      0x07, 0xc9, 0x0c, 0x49, 0x43, 0x08, 0x49, 0x16, 
+-      0x6d, 0x09, 0x60, 0x08, 0x04, 0x40, 0xe0, 0x01, 
+-      0xe0, 0x00, 0xe7, 0xff, 0x48, 0x12, 0x6c, 0x80, 
+-      0x68, 0x00, 0x49, 0x11, 0x6e, 0x49, 0x60, 0x08, 
+-      0x48, 0x0f, 0x6d, 0x40, 0x68, 0x00, 0x49, 0x0e, 
+-      0x6f, 0x09, 0x60, 0x08, 0x48, 0x0c, 0x6d, 0x00, 
+-      0x68, 0x00, 0x49, 0x0b, 0x6e, 0xc9, 0x60, 0x08, 
+-      0x48, 0x09, 0x6c, 0xc0, 0x68, 0x00, 0x23, 0x08, 
+-      0x43, 0x18, 0x49, 0x07, 0x6c, 0xc9, 0x60, 0x08, 
+-      0x07, 0x00, 0x48, 0x05, 0x6c, 0xc0, 0x68, 0x00, 
+-      0x49, 0x03, 0x6e, 0x89, 0x60, 0x08, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 
+-      0x2e, 0x08, 0x1f, 0x1c, 0xff, 0xff, 0xef, 0xff, 
+-      0x2e, 0x08, 0x60, 0x54, 0x00, 0x00, 0x02, 0x03, 
+-      0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x02, 0x01, 
+-      0xff, 0xff, 0xbf, 0xff, 0xb4, 0x80, 0x49, 0x2e, 
+-      0x20, 0x00, 0x28, 0x08, 0xd3, 0x04, 0xe0, 0x06, 
+-      0x1c, 0x42, 0x06, 0x10, 0x0e, 0x00, 0xe7, 0xf8, 
+-      0x23, 0x00, 0xc1, 0x08, 0xe7, 0xf8, 0x4a, 0x29, 
+-      0x6f, 0xd2, 0x68, 0x12, 0x4b, 0x27, 0x6d, 0x9b, 
+-      0x68, 0x1b, 0x0a, 0x1b, 0x02, 0x1b, 0x06, 0x12, 
+-      0x0e, 0x12, 0x43, 0x1a, 0x4b, 0x23, 0x6d, 0x9b, 
+-      0x60, 0x1a, 0x06, 0x12, 0x0e, 0x12, 0x4a, 0x21, 
+-      0x6f, 0xd2, 0x68, 0x52, 0x4b, 0x1f, 0x6d, 0x1b, 
+-      0x68, 0x1f, 0x23, 0x01, 0x03, 0xdb, 0x43, 0x9f, 
+-      0x1c, 0x3b, 0x07, 0xd2, 0x0c, 0x12, 0x43, 0x1a, 
+-      0x4b, 0x1a, 0x6d, 0x1b, 0x60, 0x1a, 0x04, 0x12, 
+-      0x0f, 0xd2, 0x4a, 0x18, 0x6f, 0xd2, 0x69, 0x12, 
+-      0x4b, 0x16, 0x6d, 0xdb, 0x68, 0x1b, 0x0c, 0x1b, 
+-      0x04, 0x1b, 0x04, 0x12, 0x0c, 0x12, 0x43, 0x1a, 
+-      0x4b, 0x12, 0x6d, 0xdb, 0x60, 0x1a, 0x04, 0x12, 
+-      0x0c, 0x12, 0x4a, 0x10, 0x6d, 0x12, 0x68, 0x12, 
+-      0x23, 0x01, 0x02, 0x5b, 0x43, 0x1a, 0x4b, 0x0d, 
+-      0x6d, 0x1b, 0x60, 0x1a, 0x05, 0x92, 0x4a, 0x0b, 
+-      0x6d, 0x12, 0x68, 0x12, 0x4b, 0x09, 0x6e, 0xdb, 
+-      0x60, 0x1a, 0x4a, 0x08, 0x6d, 0x92, 0x68, 0x12, 
+-      0x4b, 0x06, 0x6f, 0x5b, 0x60, 0x1a, 0x4a, 0x05, 
+-      0x6d, 0xd2, 0x68, 0x12, 0x4b, 0x03, 0x6f, 0x9b, 
+-      0x60, 0x1a, 0xbc, 0x80, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x1f, 0x44, 0x2e, 0x08, 0x1f, 0x1c, 
+-      0xb5, 0x90, 0x1c, 0x07, 0x1c, 0x0c, 0x2f, 0x22, 
+-      0xd1, 0x07, 0x2c, 0x3f, 0xd8, 0x01, 0x2c, 0x01, 
+-      0xd2, 0x03, 0x20, 0x38, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x20, 0x01, 0x49, 0x13, 0x70, 0x08, 
+-      0x23, 0x01, 0x03, 0xdb, 0x42, 0x9f, 0xd0, 0x02, 
+-      0x4b, 0x11, 0x42, 0x9f, 0xd1, 0x04, 0x48, 0x11, 
+-      0x60, 0x07, 0x20, 0x00, 0xe7, 0xee, 0xe0, 0x18, 
+-      0x2f, 0xff, 0xd1, 0x0b, 0x21, 0x00, 0x43, 0xc9, 
+-      0x20, 0x0d, 0xf0, 0x00, 0xf8, 0x1d, 0x48, 0x0c, 
+-      0x68, 0x01, 0x48, 0x0c, 0x68, 0x00, 0xf0, 0x00, 
+-      0xf8, 0x43, 0xe0, 0x07, 0x1c, 0x21, 0x1c, 0x38, 
+-      0xf0, 0x00, 0xf8, 0x3e, 0x48, 0x07, 0x60, 0x07, 
+-      0x48, 0x05, 0x60, 0x04, 0x20, 0x00, 0xe7, 0xd5, 
+-      0xe7, 0xd4, 0xe7, 0xd3, 0x2e, 0x08, 0x60, 0x7c, 
+-      0x00, 0x00, 0x80, 0x0f, 0xcc, 0x00, 0x05, 0x00, 
+-      0x2e, 0x08, 0x60, 0x78, 0x2e, 0x08, 0x1f, 0x9c, 
+-      0xb4, 0xb0, 0x1c, 0x07, 0x1c, 0x0a, 0x4b, 0x13, 
+-      0x68, 0x5b, 0x1c, 0x18, 0x21, 0x00, 0x29, 0x02, 
+-      0xdb, 0x04, 0xe0, 0x1a, 0x1c, 0x4b, 0x06, 0x19, 
+-      0x0e, 0x09, 0xe7, 0xf8, 0x23, 0x0d, 0x06, 0x9b, 
+-      0x1a, 0xc4, 0x29, 0x00, 0xd1, 0x01, 0x60, 0x27, 
+-      0xe0, 0x05, 0x23, 0x01, 0x42, 0xda, 0xd0, 0x01, 
+-      0x60, 0x22, 0xe0, 0x00, 0xe0, 0x09, 0x1d, 0x05, 
+-      0x23, 0x05, 0x02, 0x1b, 0x42, 0x9d, 0xdb, 0x02, 
+-      0x20, 0x01, 0x02, 0x80, 0xe0, 0x00, 0x30, 0x04, 
+-      0xe7, 0xe4, 0x4b, 0x02, 0x60, 0x58, 0xbc, 0xb0, 
+-      0x47, 0x70, 0x00, 0x00, 0xcc, 0x00, 0x0f, 0x00, 
+-      0xb5, 0x90, 0x1c, 0x04, 0x1c, 0x0f, 0x05, 0x20, 
+-      0x0d, 0x00, 0x23, 0xff, 0x33, 0x04, 0x42, 0x98, 
+-      0xd0, 0x50, 0xdc, 0x18, 0x28, 0x10, 0xd0, 0x2d, 
+-      0xdc, 0x08, 0x28, 0x01, 0xd0, 0x23, 0x28, 0x02, 
+-      0xd0, 0x1e, 0x28, 0x04, 0xd0, 0x1f, 0x28, 0x08, 
+-      0xd0, 0x1d, 0xe0, 0x76, 0x28, 0x12, 0xd0, 0x1d, 
+-      0x28, 0x22, 0xd0, 0x3a, 0x23, 0xff, 0x33, 0x02, 
+-      0x42, 0x98, 0xd0, 0x24, 0x23, 0xff, 0x33, 0x03, 
+-      0x42, 0x98, 0xd0, 0x29, 0xe0, 0x69, 0x38, 0xff, 
+-      0x38, 0x05, 0x28, 0x08, 0xd2, 0x65, 0xa3, 0x02, 
+-      0x5c, 0x1b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x35, 0x3c, 0x41, 0x4f, 0x56, 0x4b, 0x5d, 0x46, 
+-      0x20, 0x00, 0x49, 0x32, 0x63, 0x48, 0x48, 0x31, 
+-      0x62, 0x04, 0xe0, 0x5c, 0x20, 0x01, 0x49, 0x2f, 
+-      0x63, 0x48, 0xe0, 0x58, 0x20, 0x00, 0x49, 0x2e, 
+-      0x67, 0x08, 0x21, 0x00, 0x43, 0xc9, 0x20, 0x10, 
+-      0xf7, 0xff, 0xff, 0x92, 0xe0, 0x4f, 0x20, 0x01, 
+-      0x49, 0x29, 0x67, 0x08, 0x21, 0x00, 0x43, 0xc9, 
+-      0x20, 0x10, 0xf7, 0xff, 0xff, 0x89, 0xe0, 0x46, 
+-      0x20, 0x02, 0x49, 0x25, 0x67, 0x08, 0x21, 0x00, 
+-      0x43, 0xc9, 0x20, 0x10, 0xf7, 0xff, 0xff, 0x80, 
+-      0xe0, 0x3d, 0x1c, 0x39, 0x20, 0x22, 0xf7, 0xff, 
+-      0xff, 0x7b, 0xe0, 0x38, 0x48, 0x1e, 0x65, 0xc7, 
+-      0x21, 0x01, 0x20, 0x35, 0xf7, 0xff, 0xff, 0x74, 
+-      0xe0, 0x31, 0x48, 0x1b, 0x65, 0xc7, 0x21, 0x02, 
+-      0x20, 0x35, 0xf7, 0xff, 0xff, 0x6d, 0xe0, 0x2a, 
+-      0x21, 0x00, 0x20, 0x35, 0xf7, 0xff, 0xff, 0x68, 
+-      0xe0, 0x25, 0x21, 0x03, 0x20, 0x35, 0xf7, 0xff, 
+-      0xff, 0x63, 0xe0, 0x20, 0x21, 0x04, 0x20, 0x35, 
+-      0xf7, 0xff, 0xff, 0x5e, 0xe0, 0x1b, 0x20, 0x00, 
+-      0x49, 0x0f, 0x65, 0xc8, 0xe0, 0x17, 0x48, 0x0e, 
+-      0x66, 0x07, 0x21, 0x01, 0x20, 0x36, 0xf7, 0xff, 
+-      0xff, 0x53, 0xe0, 0x10, 0x48, 0x0a, 0x66, 0x07, 
+-      0x21, 0x02, 0x20, 0x36, 0xf7, 0xff, 0xff, 0x4c, 
+-      0xe0, 0x09, 0x20, 0x00, 0x49, 0x06, 0x66, 0x08, 
+-      0xe0, 0x05, 0x1c, 0x20, 0x21, 0x00, 0x43, 0xc9, 
+-      0xf7, 0xff, 0xff, 0x42, 0xe7, 0xff, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0xcc, 0x00, 0x0f, 0x80, 
+-      0xcc, 0x00, 0x05, 0x00, 0xb4, 0xb0, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0x1c, 0x13, 0x06, 0x38, 0x0e, 0x00, 
+-      0x06, 0x19, 0x0e, 0x09, 0x29, 0x01, 0xd0, 0x08, 
+-      0x22, 0x00, 0x4d, 0x09, 0x60, 0x2a, 0x22, 0x00, 
+-      0x43, 0xd2, 0x4d, 0x08, 0x68, 0x2d, 0x60, 0x2a, 
+-      0xe0, 0x08, 0x4a, 0x07, 0x68, 0x12, 0x60, 0x14, 
+-      0x4a, 0x04, 0x68, 0x12, 0x60, 0x10, 0x22, 0x01, 
+-      0x4d, 0x01, 0x60, 0x2a, 0xbc, 0xb0, 0x47, 0x70, 
+-      0xcc, 0x00, 0x0d, 0x00, 0x2e, 0x08, 0x60, 0x70, 
+-      0x2e, 0x08, 0x60, 0x6c, 0xb5, 0xf3, 0xb0, 0x81, 
+-      0x99, 0x02, 0x06, 0x08, 0x16, 0x00, 0x90, 0x00, 
+-      0xb0, 0x85, 0x20, 0x00, 0x90, 0x01, 0x9c, 0x06, 
+-      0x1d, 0xe6, 0x36, 0x05, 0xcc, 0x20, 0x07, 0xa8, 
+-      0x0f, 0x80, 0x06, 0x00, 0x16, 0x00, 0x90, 0x00, 
+-      0x08, 0xad, 0x3d, 0x03, 0xcc, 0x80, 0x08, 0xb8, 
+-      0x00, 0x80, 0x19, 0x86, 0xcc, 0x02, 0x91, 0x04, 
+-      0x99, 0x04, 0x08, 0x89, 0x91, 0x04, 0x20, 0x03, 
+-      0x05, 0x80, 0x21, 0x35, 0x06, 0x49, 0x60, 0x08, 
+-      0x48, 0x46, 0x68, 0x01, 0x08, 0x89, 0x00, 0x89, 
+-      0x60, 0x01, 0x48, 0x45, 0x90, 0x03, 0x20, 0x00, 
+-      0x90, 0x02, 0x98, 0x02, 0x42, 0xa8, 0xd3, 0x04, 
+-      0xe0, 0x08, 0x98, 0x02, 0x30, 0x01, 0x90, 0x02, 
+-      0xe7, 0xf7, 0xcc, 0x02, 0x98, 0x03, 0xc0, 0x02, 
+-      0x90, 0x03, 0xe7, 0xf6, 0x98, 0x00, 0x28, 0x00, 
+-      0xd0, 0x03, 0xcc, 0x02, 0x98, 0x03, 0xc0, 0x02, 
+-      0x90, 0x03, 0x20, 0x00, 0x49, 0x39, 0x65, 0x88, 
+-      0x9f, 0x04, 0x2f, 0x00, 0xd8, 0x02, 0xe0, 0x05, 
+-      0x3f, 0x01, 0xe7, 0xfa, 0xce, 0x02, 0x48, 0x35, 
+-      0x64, 0x81, 0xe7, 0xf9, 0x20, 0x00, 0x49, 0x34, 
+-      0x60, 0x48, 0x20, 0x00, 0x21, 0x35, 0x06, 0x49, 
+-      0x60, 0x08, 0x20, 0x00, 0x49, 0x2f, 0x66, 0x88, 
+-      0x20, 0x00, 0x21, 0x35, 0x06, 0x49, 0x61, 0x88, 
+-      0x20, 0x01, 0x49, 0x2c, 0x64, 0xc8, 0x48, 0x2c, 
+-      0x68, 0x40, 0x28, 0x00, 0xd1, 0x0e, 0x27, 0x00, 
+-      0x2f, 0x64, 0xd3, 0x02, 0xe0, 0x02, 0x37, 0x01, 
+-      0xe7, 0xfa, 0xe7, 0xfc, 0x98, 0x01, 0x1c, 0x41, 
+-      0x91, 0x01, 0x4b, 0x26, 0x42, 0x98, 0xdb, 0x00, 
+-      0xe0, 0x00, 0xe7, 0xec, 0x48, 0x24, 0x68, 0x01, 
+-      0x23, 0x01, 0x43, 0x19, 0x60, 0x01, 0x48, 0x23, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x03, 0x48, 0x21, 
+-      0x68, 0x40, 0x28, 0x00, 0xd1, 0x0b, 0x48, 0x20, 
+-      0x68, 0x40, 0x4b, 0x19, 0x18, 0xc0, 0x49, 0x1d, 
+-      0x60, 0x08, 0x48, 0x1d, 0x68, 0x80, 0x4b, 0x16, 
+-      0x18, 0xc0, 0x49, 0x1a, 0x60, 0x48, 0x48, 0x19, 
+-      0x68, 0x00, 0x21, 0x33, 0x06, 0x49, 0x65, 0x48, 
+-      0x48, 0x16, 0x68, 0x40, 0x21, 0x33, 0x06, 0x49, 
+-      0x65, 0x88, 0x48, 0x14, 0x68, 0x40, 0x21, 0x33, 
+-      0x06, 0x49, 0x66, 0x88, 0x48, 0x11, 0x68, 0x00, 
+-      0x21, 0x33, 0x06, 0x49, 0x66, 0x48, 0x20, 0x03, 
+-      0x21, 0x33, 0x06, 0x49, 0x67, 0x08, 0x20, 0x00, 
+-      0x49, 0x0e, 0x68, 0x09, 0x70, 0x08, 0x21, 0x00, 
+-      0x20, 0x0d, 0xf7, 0xff, 0xfe, 0x2d, 0xb0, 0x05, 
+-      0xb0, 0x01, 0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x66, 0x00, 0x00, 0x70, 
+-      0xcc, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x80, 
+-      0xcc, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x27, 0x10, 
+-      0x6a, 0x00, 0x00, 0x10, 0x2e, 0x08, 0x7c, 0x1c, 
+-      0xcc, 0x00, 0x0f, 0x80, 0x2e, 0x08, 0x94, 0xa4, 
+-      0x1c, 0x01, 0xb0, 0x81, 0x48, 0x27, 0x22, 0x00, 
+-      0x92, 0x00, 0x9a, 0x00, 0x2a, 0x16, 0xdb, 0x04, 
+-      0xe0, 0x09, 0x9a, 0x00, 0x32, 0x01, 0x92, 0x00, 
+-      0xe7, 0xf7, 0x68, 0x02, 0x9b, 0x00, 0x00, 0x9b, 
+-      0x50, 0xca, 0x30, 0x04, 0xe7, 0xf5, 0x48, 0x20, 
+-      0x22, 0x00, 0x92, 0x00, 0x9a, 0x00, 0x2a, 0x0b, 
+-      0xdb, 0x04, 0xe0, 0x0a, 0x9a, 0x00, 0x32, 0x01, 
+-      0x92, 0x00, 0xe7, 0xf7, 0x68, 0x03, 0x9a, 0x00, 
+-      0x00, 0x92, 0x18, 0x52, 0x65, 0x93, 0x30, 0x04, 
+-      0xe7, 0xf4, 0x48, 0x18, 0x22, 0x00, 0x92, 0x00, 
+-      0x9a, 0x00, 0x2a, 0x11, 0xdb, 0x04, 0xe0, 0x0b, 
+-      0x9a, 0x00, 0x32, 0x01, 0x92, 0x00, 0xe7, 0xf7, 
+-      0x68, 0x03, 0x9a, 0x00, 0x00, 0x92, 0x18, 0x52, 
+-      0x32, 0x80, 0x60, 0x53, 0x30, 0x04, 0xe7, 0xf3, 
+-      0x48, 0x0f, 0x22, 0x02, 0x92, 0x00, 0x9a, 0x00, 
+-      0x2a, 0x05, 0xdb, 0x04, 0xe0, 0x0b, 0x9a, 0x00, 
+-      0x32, 0x01, 0x92, 0x00, 0xe7, 0xf7, 0x68, 0x02, 
+-      0x9b, 0x00, 0x00, 0x9b, 0x18, 0x5b, 0x33, 0x80, 
+-      0x60, 0x5a, 0x30, 0x04, 0xe7, 0xf3, 0x4a, 0x07, 
+-      0x6c, 0x12, 0x1d, 0xcb, 0x33, 0x79, 0x61, 0xda, 
+-      0xb0, 0x01, 0x47, 0x70, 0xcc, 0x00, 0x05, 0x20, 
+-      0xcc, 0x00, 0x0c, 0x00, 0xcc, 0x00, 0x0c, 0x5c, 
+-      0xcc, 0x00, 0x0c, 0xa0, 0xcc, 0x00, 0x0c, 0x80, 
+-      0xb4, 0xf0, 0x1c, 0x06, 0x1c, 0x0f, 0x1c, 0x14, 
+-      0x1c, 0x1d, 0x06, 0x29, 0x0e, 0x09, 0x2c, 0x1f, 
+-      0xdb, 0x02, 0x20, 0xaf, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x4b, 0x0b, 0x40, 0x1f, 0x48, 0x0b, 0x68, 0x00, 
+-      0x60, 0x06, 0x29, 0x01, 0xd1, 0x07, 0x48, 0x0a, 
+-      0x68, 0x02, 0x43, 0x3a, 0x60, 0x02, 0x20, 0x80, 
+-      0x6e, 0x00, 0x60, 0x04, 0xe0, 0x05, 0x29, 0x02, 
+-      0xd1, 0x03, 0x48, 0x05, 0x68, 0x02, 0x43, 0xba, 
+-      0x60, 0x02, 0x20, 0x00, 0xe7, 0xe6, 0xe7, 0xe5, 
+-      0xff, 0xff, 0xf8, 0xff, 0x2e, 0x08, 0x60, 0x74, 
+-      0xcc, 0x00, 0x02, 0x20, 0xb5, 0xf3, 0xb0, 0x81, 
+-      0x98, 0x01, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x00, 
+-      0x99, 0x02, 0x06, 0x0e, 0x0e, 0x36, 0x48, 0x1a, 
+-      0x6f, 0x00, 0x23, 0x02, 0x40, 0x18, 0xd0, 0x0d, 
+-      0x20, 0x33, 0x06, 0x40, 0x6d, 0x80, 0x21, 0x33, 
+-      0x06, 0x49, 0x6d, 0x49, 0x1a, 0x41, 0x48, 0x14, 
+-      0x6d, 0xc0, 0x4a, 0x13, 0x6d, 0x92, 0x1a, 0x80, 
+-      0x18, 0x0d, 0xe0, 0x06, 0x20, 0x33, 0x06, 0x40, 
+-      0x6d, 0x80, 0x21, 0x33, 0x06, 0x49, 0x6d, 0x49, 
+-      0x1a, 0x45, 0x98, 0x00, 0x43, 0x68, 0x1c, 0x01, 
+-      0x20, 0x64, 0xf0, 0x07, 0xfb, 0x43, 0x1c, 0x04, 
+-      0x43, 0x6e, 0x1c, 0x31, 0x20, 0x64, 0xf0, 0x07, 
+-      0xfb, 0x3d, 0x1c, 0x07, 0x08, 0xa4, 0x00, 0xa4, 
+-      0x08, 0xbf, 0x00, 0xbf, 0x48, 0x05, 0x64, 0x84, 
+-      0x48, 0x04, 0x64, 0xc7, 0xb0, 0x01, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x80, 0xcc, 0x00, 0x0c, 0x80, 
+-      0xb5, 0xf7, 0x9a, 0x02, 0x06, 0x15, 0x0e, 0x2d, 
+-      0xb0, 0x82, 0x27, 0x00, 0x2d, 0x1f, 0xdb, 0x05, 
+-      0x20, 0xaf, 0xb0, 0x02, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2f, 0x00, 0xd1, 0x0d, 
+-      0x48, 0x19, 0x69, 0x80, 0x28, 0x00, 0xd0, 0x00, 
+-      0xe7, 0xfa, 0x20, 0x02, 0x49, 0x16, 0x61, 0x88, 
+-      0x48, 0x15, 0x69, 0x80, 0x28, 0x02, 0xd1, 0x00, 
+-      0x27, 0xff, 0xe7, 0xef, 0x4c, 0x13, 0x94, 0x00, 
+-      0x20, 0x01, 0x02, 0x40, 0x90, 0x01, 0x22, 0x00, 
+-      0x99, 0x03, 0xb4, 0x06, 0x06, 0x2b, 0x16, 0x1b, 
+-      0x9a, 0x03, 0x99, 0x04, 0x1c, 0x20, 0xf0, 0x01, 
+-      0xff, 0x75, 0xb0, 0x02, 0x1c, 0x06, 0x2e, 0xd2, 
+-      0xd1, 0x06, 0x20, 0x00, 0x49, 0x08, 0x61, 0x88, 
+-      0x20, 0xd2, 0xb0, 0x02, 0xe7, 0xd2, 0xe0, 0x08, 
+-      0x20, 0x00, 0x99, 0x00, 0x60, 0x08, 0x20, 0x00, 
+-      0x49, 0x03, 0x61, 0x88, 0x20, 0x00, 0xb0, 0x02, 
+-      0xe7, 0xc8, 0xb0, 0x02, 0xe7, 0xc6, 0x00, 0x00, 
+-      0xcc, 0x00, 0x0f, 0x80, 0xcc, 0x00, 0x06, 0x00, 
+-      0xb5, 0xff, 0x9f, 0x09, 0xb0, 0x81, 0x9b, 0x01, 
+-      0x06, 0x18, 0x0e, 0x00, 0x9b, 0x02, 0x06, 0x19, 
+-      0x0e, 0x09, 0x9b, 0x03, 0x06, 0x1b, 0x0e, 0x1b, 
+-      0x93, 0x00, 0x9b, 0x04, 0x06, 0x1a, 0x0e, 0x12, 
+-      0x06, 0x3d, 0x0e, 0x2d, 0x2d, 0x01, 0xd1, 0x07, 
+-      0x4c, 0x1c, 0x68, 0x26, 0x23, 0x01, 0x02, 0x9b, 
+-      0x43, 0x9e, 0x1c, 0x33, 0x60, 0x23, 0xe0, 0x07, 
+-      0x2d, 0x02, 0xd1, 0x05, 0x4c, 0x17, 0x68, 0x26, 
+-      0x23, 0x01, 0x02, 0x9b, 0x43, 0x33, 0x60, 0x23, 
+-      0x28, 0x00, 0xd1, 0x03, 0x23, 0x00, 0x4c, 0x14, 
+-      0x61, 0xe3, 0xe0, 0x04, 0x28, 0x01, 0xd1, 0x02, 
+-      0x23, 0x01, 0x4c, 0x11, 0x61, 0xe3, 0x29, 0x00, 
+-      0xd1, 0x03, 0x23, 0x00, 0x4c, 0x0e, 0x65, 0xa3, 
+-      0xe0, 0x04, 0x29, 0x01, 0xd1, 0x02, 0x23, 0x01, 
+-      0x4c, 0x0b, 0x65, 0xa3, 0x2a, 0x00, 0xd1, 0x03, 
+-      0x23, 0x02, 0x4c, 0x09, 0x66, 0xe3, 0xe0, 0x04, 
+-      0x2a, 0x01, 0xd1, 0x02, 0x23, 0x03, 0x4c, 0x06, 
+-      0x66, 0xe3, 0x9b, 0x00, 0x4c, 0x04, 0x67, 0x23, 
+-      0xb0, 0x01, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0xcc, 0x00, 0x02, 0x20, 
+-      0xcc, 0x00, 0x0f, 0x80, 0xb5, 0xf0, 0x1c, 0x05, 
+-      0x1c, 0x0c, 0x1c, 0x17, 0x06, 0x2e, 0x0e, 0x36, 
+-      0xb0, 0x84, 0x48, 0x15, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x04, 0x20, 0x39, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x01, 0xd1, 0x0a, 
+-      0x94, 0x00, 0x97, 0x01, 0x48, 0x0f, 0x90, 0x02, 
+-      0x48, 0x0f, 0x90, 0x03, 0x46, 0x68, 0x21, 0x01, 
+-      0xf0, 0x00, 0xfd, 0x1a, 0xe0, 0x0f, 0x20, 0x00, 
+-      0x90, 0x00, 0x20, 0x00, 0x90, 0x01, 0x48, 0x09, 
+-      0x90, 0x02, 0x48, 0x09, 0x90, 0x03, 0x46, 0x68, 
+-      0x21, 0x01, 0xf0, 0x00, 0xfd, 0x0d, 0x21, 0x00, 
+-      0x20, 0x02, 0xf7, 0xff, 0xfc, 0x85, 0x20, 0x00, 
+-      0xb0, 0x04, 0xe7, 0xdc, 0xb0, 0x04, 0xe7, 0xda, 
+-      0x2e, 0x08, 0x7c, 0xbc, 0x00, 0x00, 0x02, 0xcf, 
+-      0x00, 0x00, 0x02, 0x3f, 0xb4, 0xb0, 0x1c, 0x05, 
+-      0x1c, 0x0c, 0x1c, 0x17, 0x48, 0x14, 0x6c, 0x00, 
+-      0x1c, 0x01, 0x48, 0x13, 0x6f, 0x80, 0x23, 0x09, 
+-      0x01, 0x9b, 0x42, 0x98, 0xd1, 0x12, 0x20, 0x02, 
+-      0x40, 0x20, 0xd0, 0x0c, 0x2d, 0x02, 0xd1, 0x0a, 
+-      0x2f, 0x03, 0xd1, 0x00, 0x31, 0x04, 0x2f, 0x03, 
+-      0xd2, 0x05, 0x07, 0xe0, 0x0f, 0xc0, 0xd0, 0x01, 
+-      0x31, 0x05, 0xe0, 0x00, 0x31, 0x08, 0x2d, 0x02, 
+-      0xd9, 0x00, 0x21, 0x12, 0x00, 0x48, 0x18, 0x40, 
+-      0x30, 0x01, 0x10, 0x40, 0x21, 0x2d, 0x02, 0x09, 
+-      0x43, 0x41, 0x48, 0x03, 0x69, 0x40, 0x18, 0x09, 
+-      0x1c, 0x08, 0xbc, 0xb0, 0x47, 0x70, 0xe7, 0xfc, 
+-      0xcc, 0x00, 0x0f, 0x80, 0x48, 0x07, 0x6a, 0xc0, 
+-      0x1c, 0x01, 0x00, 0x48, 0x18, 0x40, 0x30, 0x01, 
+-      0x10, 0x40, 0x21, 0x2d, 0x02, 0x09, 0x43, 0x41, 
+-      0x48, 0x03, 0x69, 0x40, 0x18, 0x09, 0x1c, 0x08, 
+-      0x47, 0x70, 0xe7, 0xfd, 0xcc, 0x00, 0x00, 0x00, 
+-      0xcc, 0x00, 0x0f, 0x80, 0x48, 0x07, 0x68, 0x80, 
+-      0x28, 0x00, 0xd1, 0x03, 0x48, 0x06, 0x69, 0x00, 
+-      0x1c, 0x01, 0xe0, 0x02, 0x48, 0x04, 0x68, 0xc0, 
+-      0x1c, 0x01, 0x4b, 0x02, 0x18, 0xc9, 0x1c, 0x08, 
+-      0x47, 0x70, 0xe7, 0xfd, 0xcc, 0x00, 0x00, 0x00, 
+-      0xcc, 0x00, 0x0f, 0x80, 0xb5, 0x90, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0x48, 0x06, 0x6c, 0x40, 0x60, 0x20, 
+-      0x48, 0x04, 0x6c, 0x80, 0x60, 0x38, 0xf7, 0xff, 
+-      0xff, 0xe1, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0xe7, 0xfb, 0x00, 0x00, 0xcc, 0x00, 0x02, 0x00, 
+-      0xb5, 0xf0, 0x1c, 0x05, 0x1c, 0x0c, 0x1c, 0x17, 
+-      0xf7, 0xff, 0xff, 0xd4, 0x1c, 0x06, 0x2d, 0x00, 
+-      0xd0, 0x01, 0x2c, 0x00, 0xd1, 0x03, 0x20, 0x3a, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x08, 0x78, 
+-      0x00, 0x40, 0xd0, 0x01, 0x20, 0x3a, 0xe7, 0xf7, 
+-      0x20, 0x00, 0x49, 0x0d, 0x66, 0x88, 0x48, 0x0d, 
+-      0x68, 0x01, 0x23, 0x12, 0x43, 0x19, 0x60, 0x01, 
+-      0x48, 0x0b, 0x63, 0x45, 0x48, 0x0a, 0x63, 0x84, 
+-      0x20, 0x01, 0x49, 0x09, 0x62, 0x48, 0x48, 0x09, 
+-      0x68, 0x01, 0x23, 0x01, 0x40, 0x59, 0x60, 0x01, 
+-      0x48, 0x05, 0x63, 0xc7, 0x48, 0x02, 0x60, 0x46, 
+-      0x20, 0x00, 0xe7, 0xdd, 0xe7, 0xdc, 0x00, 0x00, 
+-      0xcc, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x0f, 0x48, 
+-      0xcc, 0x00, 0x00, 0x80, 0xcc, 0x00, 0x00, 0x08, 
+-      0xb4, 0xf0, 0x1c, 0x07, 0x1c, 0x0c, 0x1c, 0x16, 
+-      0x1c, 0x1d, 0x48, 0x10, 0x6a, 0x00, 0x28, 0x10, 
+-      0xd0, 0x02, 0x20, 0x3b, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x48, 0x0d, 0x68, 0x00, 0x60, 0x38, 0x68, 0x38, 
+-      0x4b, 0x0b, 0x18, 0xc0, 0x60, 0x38, 0x48, 0x0b, 
+-      0x6b, 0x40, 0x60, 0x30, 0x48, 0x09, 0x6b, 0x80, 
+-      0x60, 0x28, 0x48, 0x09, 0x6c, 0x80, 0x23, 0x10, 
+-      0x40, 0x18, 0xd0, 0x02, 0x20, 0x02, 0x60, 0x20, 
+-      0xe0, 0x01, 0x20, 0x01, 0x60, 0x20, 0x20, 0x00, 
+-      0xe7, 0xe4, 0xe7, 0xe3, 0xcc, 0x00, 0x05, 0x00, 
+-      0xcc, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x80, 
+-      0xcc, 0x00, 0x0f, 0x00, 0xb4, 0xf0, 0x1c, 0x05, 
+-      0x1c, 0x0c, 0x1c, 0x17, 0x06, 0x2a, 0x0e, 0x12, 
+-      0x06, 0x21, 0x0e, 0x09, 0x2f, 0x00, 0xd1, 0x30, 
+-      0xb0, 0x81, 0x46, 0x6f, 0x2a, 0x00, 0xd0, 0x06, 
+-      0x2a, 0x08, 0xd0, 0x0d, 0x2a, 0x10, 0xd0, 0x14, 
+-      0x2a, 0x18, 0xd0, 0x1b, 0xe0, 0x23, 0x20, 0x00, 
+-      0x70, 0x38, 0x20, 0x00, 0x70, 0x78, 0x20, 0x0c, 
+-      0x70, 0xb8, 0x20, 0x00, 0x70, 0xf8, 0xe0, 0x1b, 
+-      0x20, 0x00, 0x70, 0x38, 0x20, 0x08, 0x70, 0x78, 
+-      0x20, 0x1c, 0x70, 0xb8, 0x20, 0x00, 0x70, 0xf8, 
+-      0xe0, 0x12, 0x20, 0x00, 0x70, 0x38, 0x20, 0x10, 
+-      0x70, 0x78, 0x20, 0x0c, 0x70, 0xb8, 0x20, 0x00, 
+-      0x70, 0xf8, 0xe0, 0x09, 0x20, 0x00, 0x70, 0x38, 
+-      0x20, 0x18, 0x70, 0x78, 0x20, 0x1c, 0x70, 0xb8, 
+-      0x20, 0x00, 0x70, 0xf8, 0xe0, 0x00, 0xe7, 0xff, 
+-      0xb0, 0x01, 0x23, 0x00, 0x56, 0xf8, 0x23, 0x39, 
+-      0x06, 0x5b, 0x60, 0x18, 0x23, 0x01, 0x56, 0xf8, 
+-      0x23, 0x39, 0x06, 0x5b, 0x61, 0xd8, 0x29, 0x00, 
+-      0xd1, 0x06, 0x48, 0x0e, 0x68, 0x06, 0x23, 0x20, 
+-      0x43, 0x9e, 0x1c, 0x33, 0x60, 0x03, 0xe0, 0x06, 
+-      0x29, 0x20, 0xd1, 0x04, 0x48, 0x09, 0x68, 0x06, 
+-      0x23, 0x20, 0x43, 0x33, 0x60, 0x03, 0x23, 0x02, 
+-      0x56, 0xf8, 0x23, 0x39, 0x06, 0x5b, 0x60, 0x58, 
+-      0x23, 0x03, 0x56, 0xf8, 0x4b, 0x04, 0x63, 0x18, 
+-      0x20, 0x00, 0x23, 0x39, 0x06, 0x5b, 0x64, 0x98, 
+-      0xbc, 0xf0, 0x47, 0x70, 0x72, 0x00, 0x00, 0x1c, 
+-      0x72, 0x00, 0x01, 0x00, 0xb4, 0xb0, 0x1c, 0x07, 
+-      0x1c, 0x0d, 0x1c, 0x14, 0x06, 0x29, 0x0e, 0x09, 
+-      0x06, 0x22, 0x0e, 0x12, 0xb0, 0x84, 0x29, 0x33, 
+-      0xdc, 0x01, 0x2a, 0x0f, 0xdd, 0x03, 0x20, 0xff, 
+-      0xb0, 0x04, 0xbc, 0xb0, 0x47, 0x70, 0x20, 0x39, 
+-      0x06, 0x40, 0x63, 0x41, 0x20, 0x10, 0x43, 0x10, 
+-      0x23, 0x39, 0x06, 0x5b, 0x63, 0x98, 0x20, 0x39, 
+-      0x06, 0x40, 0x68, 0x00, 0x90, 0x03, 0x98, 0x03, 
+-      0x23, 0x9c, 0x43, 0xdb, 0x40, 0x18, 0x90, 0x03, 
+-      0x20, 0x39, 0x06, 0x40, 0x68, 0x40, 0x90, 0x01, 
+-      0x98, 0x01, 0x23, 0x20, 0x43, 0xdb, 0x40, 0x18, 
+-      0x90, 0x01, 0x06, 0x38, 0x0e, 0x00, 0xd0, 0x29, 
+-      0x20, 0x10, 0x40, 0x38, 0xd0, 0x03, 0x98, 0x03, 
+-      0x23, 0x80, 0x43, 0x18, 0x90, 0x03, 0x20, 0x08, 
+-      0x40, 0x38, 0xd0, 0x03, 0x98, 0x03, 0x23, 0x10, 
+-      0x43, 0x18, 0x90, 0x03, 0x20, 0x04, 0x40, 0x38, 
+-      0xd0, 0x04, 0x98, 0x03, 0x23, 0x08, 0x43, 0x18, 
+-      0x90, 0x03, 0xe0, 0x0c, 0x20, 0x02, 0x40, 0x38, 
+-      0xd0, 0x04, 0x98, 0x03, 0x23, 0x0c, 0x43, 0x18, 
+-      0x90, 0x03, 0xe0, 0x04, 0x98, 0x03, 0x23, 0x0c, 
+-      0x43, 0xdb, 0x40, 0x18, 0x90, 0x03, 0x20, 0x20, 
+-      0x40, 0x38, 0xd0, 0x03, 0x98, 0x01, 0x23, 0x20, 
+-      0x43, 0x18, 0x90, 0x01, 0x98, 0x03, 0x23, 0x39, 
+-      0x06, 0x5b, 0x60, 0x18, 0x98, 0x01, 0x23, 0x39, 
+-      0x06, 0x5b, 0x60, 0x58, 0x20, 0x39, 0x06, 0x40, 
+-      0x6a, 0x00, 0x90, 0x00, 0x98, 0x00, 0x23, 0xf0, 
+-      0x43, 0xdb, 0x43, 0x18, 0x90, 0x00, 0x20, 0xff, 
+-      0x02, 0x00, 0x40, 0x38, 0xd0, 0x27, 0x20, 0xff, 
+-      0x30, 0x01, 0x40, 0x38, 0xd0, 0x03, 0x98, 0x00, 
+-      0x23, 0xfe, 0x40, 0x18, 0x90, 0x00, 0x20, 0x01, 
+-      0x02, 0x40, 0x40, 0x38, 0xd0, 0x03, 0x98, 0x00, 
+-      0x23, 0xfd, 0x40, 0x18, 0x90, 0x00, 0x20, 0x01, 
+-      0x02, 0x80, 0x40, 0x38, 0xd0, 0x03, 0x98, 0x00, 
+-      0x23, 0xfb, 0x40, 0x18, 0x90, 0x00, 0x20, 0x01, 
+-      0x02, 0xc0, 0x40, 0x38, 0xd0, 0x03, 0x98, 0x00, 
+-      0x23, 0xf7, 0x40, 0x18, 0x90, 0x00, 0x20, 0x01, 
+-      0x03, 0x00, 0x40, 0x38, 0xd0, 0x03, 0x98, 0x00, 
+-      0x23, 0xf0, 0x40, 0x18, 0x90, 0x00, 0x98, 0x00, 
+-      0x23, 0x39, 0x06, 0x5b, 0x62, 0x18, 0x20, 0x39, 
+-      0x06, 0x40, 0x69, 0xc0, 0x90, 0x02, 0x98, 0x02, 
+-      0x08, 0x40, 0x00, 0x40, 0x90, 0x02, 0x20, 0x39, 
+-      0x06, 0x40, 0x6a, 0xc0, 0x90, 0x00, 0x98, 0x00, 
+-      0x23, 0x1c, 0x43, 0xdb, 0x40, 0x18, 0x90, 0x00, 
+-      0x20, 0x39, 0x06, 0x40, 0x6b, 0x80, 0x90, 0x03, 
+-      0x98, 0x03, 0x23, 0x10, 0x43, 0xdb, 0x40, 0x18, 
+-      0x90, 0x03, 0x20, 0x39, 0x06, 0x40, 0x6b, 0xc0, 
+-      0x90, 0x01, 0x98, 0x01, 0x09, 0x00, 0x01, 0x00, 
+-      0x90, 0x01, 0x48, 0x4a, 0x40, 0x38, 0xd0, 0x45, 
+-      0x20, 0x01, 0x04, 0x00, 0x40, 0x38, 0xd0, 0x03, 
+-      0x98, 0x02, 0x23, 0x01, 0x43, 0x18, 0x90, 0x02, 
+-      0x20, 0x01, 0x05, 0xc0, 0x40, 0x38, 0xd0, 0x03, 
+-      0x98, 0x00, 0x23, 0x10, 0x43, 0x18, 0x90, 0x00, 
+-      0x20, 0x07, 0x04, 0x40, 0x40, 0x38, 0x23, 0x01, 
+-      0x04, 0x5b, 0x42, 0x98, 0xd0, 0x08, 0x23, 0x01, 
+-      0x04, 0x9b, 0x42, 0x98, 0xd0, 0x07, 0x23, 0x01, 
+-      0x04, 0xdb, 0x42, 0x98, 0xd0, 0x08, 0xe0, 0x0c, 
+-      0x98, 0x00, 0x90, 0x00, 0xe0, 0x0a, 0x98, 0x00, 
+-      0x23, 0x04, 0x43, 0x18, 0x90, 0x00, 0xe0, 0x05, 
+-      0x98, 0x00, 0x23, 0x0c, 0x43, 0x18, 0x90, 0x00, 
+-      0xe0, 0x00, 0xe7, 0xff, 0x20, 0x01, 0x05, 0x80, 
+-      0x40, 0x38, 0xd0, 0x03, 0x98, 0x03, 0x23, 0x10, 
+-      0x43, 0x18, 0x90, 0x03, 0x20, 0x01, 0x05, 0x00, 
+-      0x40, 0x38, 0xd0, 0x03, 0x98, 0x01, 0x23, 0x08, 
+-      0x43, 0x18, 0x90, 0x01, 0x20, 0x01, 0x05, 0x40, 
+-      0x40, 0x38, 0xd0, 0x03, 0x98, 0x01, 0x23, 0x07, 
+-      0x43, 0x18, 0x90, 0x01, 0x98, 0x03, 0x23, 0x39, 
+-      0x06, 0x5b, 0x63, 0x98, 0x98, 0x02, 0x23, 0x39, 
+-      0x06, 0x5b, 0x61, 0xd8, 0x98, 0x01, 0x23, 0x39, 
+-      0x06, 0x5b, 0x63, 0xd8, 0x98, 0x00, 0x23, 0x39, 
+-      0x06, 0x5b, 0x62, 0xd8, 0x20, 0x39, 0x06, 0x40, 
+-      0x68, 0x80, 0x90, 0x03, 0x98, 0x03, 0x08, 0x80, 
+-      0x00, 0x80, 0x90, 0x03, 0x0f, 0x38, 0x07, 0x00, 
+-      0xd0, 0x26, 0x20, 0x01, 0x07, 0x00, 0x40, 0x38, 
+-      0x23, 0x01, 0x07, 0x1b, 0x42, 0x98, 0xd1, 0x04, 
+-      0x98, 0x03, 0x23, 0x02, 0x43, 0x18, 0x90, 0x03, 
+-      0xe0, 0x07, 0x20, 0x00, 0x42, 0x80, 0xd1, 0x04, 
+-      0x98, 0x03, 0x23, 0x02, 0x43, 0xdb, 0x40, 0x18, 
+-      0x90, 0x03, 0x20, 0x01, 0x07, 0x40, 0x40, 0x38, 
+-      0x23, 0x01, 0x07, 0x5b, 0x42, 0x98, 0xd1, 0x04, 
+-      0x98, 0x03, 0x23, 0x01, 0x43, 0x18, 0x90, 0x03, 
+-      0xe0, 0x06, 0x20, 0x00, 0x42, 0x80, 0xd1, 0x03, 
+-      0x98, 0x03, 0x08, 0x40, 0x00, 0x40, 0x90, 0x03, 
+-      0x98, 0x03, 0x23, 0x39, 0x06, 0x5b, 0x60, 0x98, 
+-      0x20, 0x00, 0xb0, 0x04, 0xe6, 0xc1, 0xb0, 0x04, 
+-      0xe6, 0xbf, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 
+-      0x48, 0x02, 0x69, 0xc0, 0x06, 0x00, 0x16, 0x00, 
+-      0x47, 0x70, 0xe7, 0xfd, 0x72, 0x00, 0x01, 0x00, 
+-      0xb5, 0xf7, 0x1c, 0x04, 0x1c, 0x0f, 0x06, 0x23, 
+-      0x16, 0x18, 0x06, 0x3b, 0x16, 0x19, 0x9b, 0x02, 
+-      0x06, 0x1a, 0x0e, 0x12, 0x2a, 0x00, 0xd1, 0x0b, 
+-      0x23, 0x39, 0x06, 0x5b, 0x60, 0xd8, 0x23, 0x39, 
+-      0x06, 0x5b, 0x61, 0x19, 0x4d, 0x0b, 0x68, 0x2e, 
+-      0x23, 0x01, 0x43, 0x33, 0x60, 0x2b, 0xe0, 0x0c, 
+-      0x2a, 0x01, 0xd1, 0x0a, 0x23, 0x39, 0x06, 0x5b, 
+-      0x61, 0x58, 0x23, 0x39, 0x06, 0x5b, 0x61, 0x99, 
+-      0x4d, 0x04, 0x68, 0x2e, 0x23, 0x02, 0x43, 0x33, 
+-      0x60, 0x2b, 0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x72, 0x00, 0x00, 0x08, 
+-      0xb4, 0x90, 0x1c, 0x01, 0x20, 0x92, 0x4b, 0x4b, 
+-      0x60, 0x18, 0x20, 0x92, 0x4b, 0x4a, 0x60, 0x18, 
+-      0x20, 0x10, 0x4b, 0x4a, 0x60, 0x18, 0x20, 0x00, 
+-      0x4b, 0x48, 0x60, 0x58, 0x48, 0x48, 0x4b, 0x47, 
+-      0x60, 0x98, 0x22, 0x00, 0x2a, 0x10, 0xdb, 0x02, 
+-      0xe0, 0x07, 0x32, 0x01, 0xe7, 0xfa, 0x20, 0x00, 
+-      0x43, 0xc0, 0x00, 0x93, 0x4c, 0x42, 0x50, 0xe0, 
+-      0xe7, 0xf7, 0x20, 0x00, 0x43, 0xc0, 0x00, 0x93, 
+-      0x4c, 0x3f, 0x50, 0xe0, 0x22, 0x00, 0x2a, 0x08, 
+-      0xdb, 0x02, 0xe0, 0x08, 0x32, 0x01, 0xe7, 0xfa, 
+-      0x20, 0x00, 0x43, 0xc0, 0x00, 0x94, 0x4b, 0x3b, 
+-      0x18, 0xe3, 0x64, 0x18, 0xe7, 0xf6, 0x22, 0x00, 
+-      0x2a, 0x20, 0xdb, 0x02, 0xe0, 0x08, 0x32, 0x01, 
+-      0xe7, 0xfa, 0x20, 0x00, 0x43, 0xc0, 0x00, 0x94, 
+-      0x4b, 0x35, 0x18, 0xe3, 0x60, 0x18, 0xe7, 0xf6, 
+-      0x22, 0x00, 0x2a, 0x19, 0xdb, 0x02, 0xe0, 0x06, 
+-      0x32, 0x01, 0xe7, 0xfa, 0x20, 0x00, 0x00, 0x93, 
+-      0x4c, 0x30, 0x50, 0xe0, 0xe7, 0xf8, 0x20, 0x00, 
+-      0x4b, 0x2f, 0x60, 0x18, 0x20, 0x39, 0x06, 0x40, 
+-      0x69, 0xc0, 0x27, 0x18, 0x40, 0x07, 0x2f, 0x00, 
+-      0xd0, 0x03, 0x48, 0x2c, 0x4b, 0x2c, 0x60, 0x18, 
+-      0xe0, 0x03, 0x20, 0xff, 0x30, 0xe0, 0x4b, 0x2a, 
+-      0x60, 0x18, 0x20, 0x00, 0x4b, 0x29, 0x60, 0x18, 
+-      0x20, 0x00, 0x4b, 0x28, 0x60, 0x58, 0x48, 0x28, 
+-      0x4b, 0x26, 0x60, 0x98, 0x48, 0x24, 0x68, 0x00, 
+-      0x4b, 0x24, 0x60, 0xd8, 0x48, 0x25, 0x60, 0x01, 
+-      0x20, 0x0d, 0x06, 0xc0, 0x61, 0xc1, 0x20, 0x05, 
+-      0x02, 0x00, 0x23, 0x0d, 0x06, 0xdb, 0x60, 0x18, 
+-      0x48, 0x21, 0x23, 0x0d, 0x06, 0xdb, 0x60, 0x58, 
+-      0x48, 0x1f, 0x4b, 0x16, 0x63, 0x98, 0x20, 0x00, 
+-      0x23, 0x0d, 0x06, 0xdb, 0x60, 0x98, 0x20, 0x00, 
+-      0x23, 0x0d, 0x06, 0xdb, 0x61, 0x18, 0x48, 0x1b, 
+-      0x23, 0x0d, 0x06, 0xdb, 0x61, 0x98, 0x20, 0x01, 
+-      0x23, 0x0d, 0x06, 0xdb, 0x60, 0xd8, 0x48, 0x18, 
+-      0x23, 0x0d, 0x06, 0xdb, 0x63, 0x18, 0x48, 0x17, 
+-      0x23, 0x0d, 0x06, 0xdb, 0x63, 0x58, 0x20, 0x00, 
+-      0x4b, 0x15, 0x60, 0x18, 0x48, 0x11, 0x4b, 0x15, 
+-      0x60, 0x18, 0x20, 0x00, 0xbc, 0x90, 0x47, 0x70, 
+-      0xe7, 0xfc, 0x00, 0x00, 0x2e, 0x08, 0x7c, 0xc4, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0x2e, 0x08, 0x7d, 0x94, 
+-      0x2e, 0x08, 0x7c, 0xcc, 0x68, 0x00, 0x0d, 0x00, 
+-      0x68, 0x00, 0x04, 0x00, 0x2e, 0x08, 0x7c, 0x58, 
+-      0x2e, 0x08, 0x7c, 0xbc, 0x00, 0x00, 0x02, 0x3f, 
+-      0x2e, 0x08, 0x60, 0x80, 0x2e, 0x08, 0x7d, 0xa0, 
+-      0x00, 0x00, 0x02, 0xcf, 0x2e, 0x08, 0x60, 0x84, 
+-      0x00, 0xf0, 0x29, 0x6d, 0x3f, 0xff, 0xff, 0xff, 
+-      0x00, 0x80, 0x10, 0x80, 0x00, 0x80, 0xeb, 0x80, 
+-      0x2e, 0x08, 0x94, 0x84, 0x2e, 0x08, 0x5e, 0x4c, 
+-      0xb5, 0xff, 0xb0, 0x85, 0x20, 0x39, 0x06, 0x40, 
+-      0x69, 0xc0, 0x23, 0x18, 0x40, 0x18, 0x90, 0x00, 
+-      0x98, 0x00, 0x28, 0x00, 0xd0, 0x03, 0x48, 0x5a, 
+-      0x4b, 0x5a, 0x60, 0x18, 0xe0, 0x03, 0x20, 0xff, 
+-      0x30, 0xe0, 0x4b, 0x58, 0x60, 0x18, 0x9c, 0x06, 
+-      0x9f, 0x07, 0x22, 0x00, 0x21, 0x00, 0x98, 0x05, 
+-      0x38, 0x0c, 0x28, 0x06, 0xd2, 0x0c, 0xa3, 0x02, 
+-      0x5c, 0x1b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x04, 0x03, 0x06, 0x04, 0x03, 0x06, 0x32, 0x01, 
+-      0x32, 0x01, 0xe0, 0x02, 0x3a, 0x01, 0xe0, 0x00, 
+-      0xe7, 0xff, 0x98, 0x05, 0x38, 0x0b, 0x28, 0x08, 
+-      0xd2, 0x15, 0xa3, 0x02, 0x5c, 0x1b, 0x00, 0x5b, 
+-      0x44, 0x9f, 0x1c, 0x00, 0x0a, 0x04, 0x04, 0x04, 
+-      0x0a, 0x0a, 0x0a, 0x04, 0x25, 0x2d, 0x01, 0x2d, 
+-      0x48, 0x44, 0x68, 0x00, 0x1c, 0x46, 0xe0, 0x0e, 
+-      0x48, 0x43, 0x6c, 0x40, 0x1c, 0x05, 0x48, 0x43, 
+-      0x68, 0x40, 0x1c, 0x06, 0xe0, 0x07, 0x21, 0xff, 
+-      0x1c, 0x08, 0xb0, 0x05, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xe7, 0xff, 0x2d, 0x00, 
+-      0xd0, 0x01, 0x2e, 0x00, 0xd1, 0x04, 0x25, 0x2d, 
+-      0x01, 0x2d, 0x48, 0x38, 0x68, 0x00, 0x1c, 0x46, 
+-      0x29, 0xff, 0xd1, 0x02, 0x1c, 0x08, 0xb0, 0x05, 
+-      0xe7, 0xec, 0x1e, 0x68, 0x90, 0x02, 0x1e, 0x70, 
+-      0x90, 0x01, 0x23, 0x01, 0x42, 0xda, 0xd1, 0x08, 
+-      0x42, 0x50, 0x40, 0x85, 0x1c, 0x2b, 0x1e, 0x5d, 
+-      0x42, 0x50, 0x40, 0x86, 0x1c, 0x33, 0x1e, 0x5e, 
+-      0xe0, 0x05, 0x41, 0x15, 0x1c, 0x28, 0x1e, 0x45, 
+-      0x41, 0x16, 0x1c, 0x30, 0x1e, 0x46, 0x07, 0xe0, 
+-      0x0f, 0xc0, 0xd0, 0x02, 0x21, 0x80, 0x08, 0x64, 
+-      0x00, 0x64, 0x07, 0xf8, 0x0f, 0xc0, 0xd0, 0x02, 
+-      0x21, 0x80, 0x08, 0x7f, 0x00, 0x7f, 0x19, 0x60, 
+-      0x90, 0x04, 0x19, 0xb8, 0x90, 0x03, 0x2c, 0x00, 
+-      0xda, 0x01, 0x21, 0x80, 0x24, 0x00, 0x98, 0x04, 
+-      0x28, 0x01, 0xda, 0x02, 0x21, 0x80, 0x20, 0x01, 
+-      0x90, 0x04, 0x4b, 0x1f, 0x42, 0x9c, 0xdb, 0x01, 
+-      0x21, 0x80, 0x4c, 0x1e, 0x98, 0x04, 0x4b, 0x1c, 
+-      0x42, 0x98, 0xdd, 0x02, 0x21, 0x80, 0x48, 0x1a, 
+-      0x90, 0x04, 0x2f, 0x00, 0xda, 0x01, 0x21, 0x80, 
+-      0x27, 0x00, 0x98, 0x03, 0x28, 0x01, 0xda, 0x02, 
+-      0x21, 0x80, 0x20, 0x01, 0x90, 0x03, 0x48, 0x11, 
+-      0x68, 0x00, 0x42, 0x87, 0xd3, 0x03, 0x21, 0x80, 
+-      0x48, 0x0e, 0x68, 0x00, 0x1e, 0x47, 0x98, 0x03, 
+-      0x4b, 0x0c, 0x68, 0x1b, 0x42, 0x98, 0xd9, 0x03, 
+-      0x21, 0x80, 0x48, 0x0a, 0x68, 0x00, 0x90, 0x03, 
+-      0x9b, 0x08, 0x60, 0x1c, 0x9b, 0x08, 0x60, 0x5f, 
+-      0x98, 0x04, 0x9b, 0x08, 0x60, 0x98, 0x98, 0x03, 
+-      0x9b, 0x08, 0x60, 0xd8, 0x1c, 0x08, 0xb0, 0x05, 
+-      0xe7, 0x88, 0xb0, 0x05, 0xe7, 0x86, 0x00, 0x00, 
+-      0x00, 0x00, 0x02, 0x3f, 0x2e, 0x08, 0x60, 0x80, 
+-      0xcc, 0x00, 0x02, 0x00, 0xcc, 0x00, 0x0c, 0x00, 
+-      0x00, 0x00, 0x02, 0xcf, 0x00, 0x00, 0x02, 0xce, 
+-      0xb5, 0xf0, 0x1c, 0x07, 0x1c, 0x0c, 0xb0, 0x81, 
+-      0x2c, 0x0b, 0xdb, 0x19, 0x2c, 0x12, 0xdc, 0x17, 
+-      0x68, 0xbe, 0x68, 0xf9, 0x91, 0x00, 0x68, 0x7a, 
+-      0x1c, 0x3b, 0x68, 0x39, 0x1c, 0x20, 0xf7, 0xff, 
+-      0xff, 0x23, 0x1c, 0x05, 0x68, 0xb8, 0x42, 0xb0, 
+-      0xd0, 0x00, 0x25, 0x80, 0x68, 0xf8, 0x99, 0x00, 
+-      0x42, 0x88, 0xd0, 0x00, 0x25, 0x80, 0x1c, 0x28, 
+-      0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x25, 0x00, 0x68, 0x38, 0x28, 0x00, 0xda, 0x02, 
+-      0x25, 0x80, 0x20, 0x00, 0x60, 0x38, 0x68, 0x78, 
+-      0x28, 0x00, 0xda, 0x02, 0x25, 0x80, 0x20, 0x00, 
+-      0x60, 0x78, 0x68, 0x38, 0x07, 0xc0, 0x0f, 0xc0, 
+-      0xd0, 0x04, 0x25, 0x80, 0x68, 0x38, 0x08, 0x40, 
+-      0x00, 0x40, 0x60, 0x38, 0x68, 0xb8, 0x07, 0xc0, 
+-      0x0f, 0xc0, 0xd1, 0x09, 0x25, 0x80, 0x68, 0xb8, 
+-      0x07, 0xc0, 0x0f, 0xc0, 0xd0, 0x01, 0x68, 0xb8, 
+-      0xe0, 0x01, 0x68, 0xb8, 0x38, 0x01, 0x60, 0xb8, 
+-      0x68, 0xb8, 0x68, 0x39, 0x42, 0x88, 0xdc, 0x03, 
+-      0x25, 0x80, 0x68, 0x38, 0x30, 0x01, 0x60, 0xb8, 
+-      0x68, 0x78, 0x68, 0xf9, 0x42, 0x88, 0xdb, 0x03, 
+-      0x25, 0x80, 0x68, 0x78, 0x30, 0x01, 0x60, 0xf8, 
+-      0x1c, 0x28, 0xb0, 0x01, 0xe7, 0xc5, 0xb0, 0x01, 
+-      0xe7, 0xc3, 0x1c, 0x02, 0x21, 0x18, 0xe0, 0x00, 
+-      0x31, 0x01, 0x1c, 0x08, 0x47, 0x70, 0xe7, 0xfd, 
+-      0xb4, 0xf0, 0x1c, 0x07, 0x1c, 0x0a, 0xb0, 0x81, 
+-      0x68, 0xb8, 0x68, 0x3b, 0x1a, 0xc0, 0x1c, 0x46, 
+-      0x68, 0xf8, 0x68, 0x7b, 0x1a, 0xc0, 0x30, 0x01, 
+-      0x90, 0x00, 0x00, 0x90, 0x4b, 0x15, 0x58, 0x1c, 
+-      0x98, 0x00, 0x43, 0x46, 0x1c, 0x35, 0x07, 0xa0, 
+-      0x0f, 0x80, 0x1c, 0x29, 0x40, 0x81, 0x2a, 0x0b, 
+-      0xdb, 0x01, 0x2a, 0x12, 0xdd, 0x01, 0x2a, 0x13, 
+-      0xd1, 0x01, 0x21, 0x00, 0xe0, 0x0a, 0x2a, 0x09, 
+-      0xd0, 0x01, 0x2a, 0x0a, 0xd1, 0x03, 0x00, 0x69, 
+-      0x19, 0x49, 0x00, 0xc9, 0xe0, 0x02, 0x2a, 0x08, 
+-      0xd1, 0x00, 0x01, 0x29, 0x20, 0x04, 0x40, 0x20, 
+-      0xd0, 0x00, 0x08, 0x49, 0x09, 0x4c, 0x06, 0xc8, 
+-      0x0e, 0xc0, 0xd0, 0x00, 0x34, 0x01, 0x1c, 0x20, 
+-      0xb0, 0x01, 0xbc, 0xf0, 0x47, 0x70, 0xb0, 0x01, 
+-      0xe7, 0xfb, 0x00, 0x00, 0x2e, 0x03, 0x3a, 0x04, 
+-      0xb4, 0x80, 0x23, 0x00, 0x22, 0x01, 0x21, 0x00, 
+-      0x29, 0x08, 0xdb, 0x02, 0xe0, 0x09, 0x31, 0x01, 
+-      0xe7, 0xfa, 0x00, 0x88, 0x4f, 0x05, 0x58, 0x38, 
+-      0x28, 0x00, 0xd0, 0x00, 0x43, 0x13, 0x00, 0x52, 
+-      0xe7, 0xf5, 0x1c, 0x18, 0xbc, 0x80, 0x47, 0x70, 
+-      0xe7, 0xfc, 0x00, 0x00, 0x2e, 0x08, 0x7c, 0x58, 
+-      0xb5, 0xf3, 0x1c, 0x0f, 0xb0, 0x81, 0x20, 0x39, 
+-      0x06, 0x40, 0x69, 0xc0, 0x23, 0x18, 0x40, 0x18, 
+-      0x90, 0x00, 0x98, 0x00, 0x28, 0x00, 0xd0, 0x03, 
+-      0x48, 0x32, 0x49, 0x33, 0x60, 0x08, 0xe0, 0x03, 
+-      0x20, 0xff, 0x30, 0xe0, 0x49, 0x30, 0x60, 0x08, 
+-      0x24, 0x00, 0x99, 0x01, 0x48, 0x2f, 0xf7, 0xfc, 
+-      0xfa, 0x1f, 0x48, 0x2e, 0x68, 0x00, 0x28, 0x00, 
+-      0xda, 0x03, 0x20, 0x00, 0x49, 0x2b, 0x60, 0x08, 
+-      0x24, 0x80, 0x48, 0x2a, 0x68, 0x40, 0x28, 0x00, 
+-      0xda, 0x03, 0x20, 0x00, 0x49, 0x27, 0x60, 0x48, 
+-      0x24, 0x80, 0x48, 0x26, 0x68, 0x80, 0x4b, 0x26, 
+-      0x42, 0x98, 0xdd, 0x03, 0x48, 0x24, 0x49, 0x23, 
+-      0x60, 0x88, 0x24, 0x80, 0x48, 0x21, 0x68, 0xc0, 
+-      0x49, 0x1f, 0x68, 0x09, 0x42, 0x88, 0xd9, 0x04, 
+-      0x48, 0x1d, 0x68, 0x00, 0x49, 0x1d, 0x60, 0xc8, 
+-      0x24, 0x80, 0x48, 0x1e, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x27, 0x2f, 0x01, 0xd1, 0x25, 0x48, 0x19, 
+-      0x68, 0x06, 0x48, 0x18, 0x68, 0x45, 0x23, 0xff, 
+-      0x33, 0x68, 0x42, 0x9e, 0xdd, 0x01, 0x26, 0xff, 
+-      0x36, 0x68, 0x48, 0x13, 0x68, 0x00, 0x08, 0x40, 
+-      0x42, 0xa8, 0xd2, 0x02, 0x48, 0x10, 0x68, 0x00, 
+-      0x08, 0x45, 0x48, 0x13, 0x49, 0x13, 0x65, 0x48, 
+-      0x48, 0x13, 0x43, 0x70, 0x23, 0x01, 0x04, 0x1b, 
+-      0x18, 0xc0, 0x14, 0x40, 0x49, 0x0f, 0x65, 0x88, 
+-      0x20, 0x00, 0x49, 0x0e, 0x65, 0xc8, 0x48, 0x0d, 
+-      0x66, 0x05, 0x1c, 0x38, 0x21, 0x00, 0xf7, 0xfe, 
+-      0xff, 0x13, 0x1c, 0x20, 0xb0, 0x01, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0xb0, 0x01, 
+-      0xe7, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3f, 
+-      0x2e, 0x08, 0x60, 0x80, 0x2e, 0x08, 0x7d, 0xa0, 
+-      0x00, 0x00, 0x02, 0xcf, 0x2e, 0x08, 0x7c, 0xbc, 
+-      0x00, 0x00, 0x07, 0xfa, 0xcc, 0x00, 0x00, 0x00, 
+-      0x00, 0x0b, 0x60, 0xb6, 0xb5, 0xf0, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0xb0, 0x81, 0x1c, 0x26, 0x69, 0x30, 
+-      0x90, 0x00, 0x98, 0x00, 0x28, 0x13, 0xd1, 0x04, 
+-      0x20, 0x75, 0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x68, 0xf5, 0x68, 0x38, 0x08, 0x40, 
+-      0x00, 0x40, 0x60, 0x38, 0x68, 0x78, 0x08, 0x40, 
+-      0x00, 0x40, 0x60, 0x78, 0x68, 0xb8, 0x07, 0xc0, 
+-      0x0f, 0xc0, 0xd1, 0x02, 0x68, 0xb8, 0x38, 0x01, 
+-      0x60, 0xb8, 0x68, 0xf8, 0x07, 0xc0, 0x0f, 0xc0, 
+-      0xd1, 0x02, 0x68, 0xf8, 0x38, 0x01, 0x60, 0xf8, 
+-      0x1d, 0xf0, 0x30, 0x49, 0x1c, 0x39, 0xf7, 0xfc, 
+-      0xf9, 0x8b, 0x48, 0x1c, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x05, 0x2d, 0x19, 0xd3, 0x01, 0x20, 0x01, 
+-      0xe0, 0x00, 0x20, 0x00, 0xe0, 0x04, 0x2d, 0x08, 
+-      0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0x28, 0x00, 0xd0, 0x02, 0x20, 0x00, 0xb0, 0x01, 
+-      0xe7, 0xcc, 0x49, 0x13, 0x20, 0x91, 0xf0, 0x13, 
+-      0xfb, 0x0d, 0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 
+-      0xf0, 0x05, 0xfa, 0xf4, 0xe7, 0xf5, 0x00, 0xa8, 
+-      0x49, 0x0e, 0x58, 0x08, 0x42, 0xa0, 0xd0, 0x05, 
+-      0x20, 0x92, 0x49, 0x0b, 0x60, 0x08, 0x20, 0xff, 
+-      0xb0, 0x01, 0xe7, 0xb7, 0x48, 0x0a, 0x68, 0x00, 
+-      0x42, 0xa0, 0xd1, 0x03, 0x1c, 0x39, 0x1c, 0x20, 
+-      0xf0, 0x00, 0xf8, 0x10, 0x20, 0x92, 0x49, 0x04, 
+-      0x60, 0x08, 0x20, 0x00, 0xb0, 0x01, 0xe7, 0xa9, 
+-      0xb0, 0x01, 0xe7, 0xa7, 0x2e, 0x08, 0x94, 0x84, 
+-      0x2e, 0x08, 0x7c, 0xc0, 0x2e, 0x08, 0x7c, 0x58, 
+-      0x2e, 0x08, 0x7c, 0xbc, 0xb5, 0xf3, 0x1c, 0x0f, 
+-      0xb0, 0x9b, 0x20, 0x39, 0x06, 0x40, 0x69, 0xc0, 
+-      0x23, 0x18, 0x40, 0x18, 0x90, 0x01, 0x98, 0x01, 
+-      0x28, 0x00, 0xd0, 0x03, 0x48, 0xf8, 0x49, 0xf9, 
+-      0x60, 0x08, 0xe0, 0x03, 0x20, 0xff, 0x30, 0xe0, 
+-      0x49, 0xf6, 0x60, 0x08, 0x20, 0xff, 0x30, 0x01, 
+-      0x90, 0x06, 0x98, 0x1b, 0x90, 0x1a, 0x98, 0x1a, 
+-      0x69, 0x05, 0x98, 0x1a, 0x68, 0xc0, 0x90, 0x19, 
+-      0x48, 0xf1, 0x68, 0x00, 0x99, 0x1b, 0x42, 0x88, 
+-      0xd1, 0x73, 0x20, 0x02, 0x90, 0x08, 0x2d, 0x0c, 
+-      0xd0, 0x01, 0x2d, 0x0f, 0xd1, 0x02, 0x20, 0x04, 
+-      0x90, 0x08, 0xe0, 0x0c, 0x2d, 0x0d, 0xd0, 0x01, 
+-      0x2d, 0x10, 0xd1, 0x02, 0x20, 0x08, 0x90, 0x08, 
+-      0xe0, 0x05, 0x2d, 0x0e, 0xd0, 0x01, 0x2d, 0x11, 
+-      0xd1, 0x01, 0x20, 0x01, 0x90, 0x08, 0x68, 0xf8, 
+-      0x68, 0x79, 0x1a, 0x40, 0x1c, 0x44, 0x2d, 0x0b, 
+-      0xd0, 0x05, 0x2d, 0x0f, 0xd0, 0x03, 0x2d, 0x10, 
+-      0xd0, 0x01, 0x2d, 0x11, 0xd1, 0x11, 0x48, 0xdf, 
+-      0x6c, 0x40, 0x1c, 0x06, 0x48, 0xdd, 0x6c, 0x81, 
+-      0x91, 0x07, 0x2e, 0x00, 0xd0, 0x02, 0x99, 0x07, 
+-      0x29, 0x00, 0xd1, 0x05, 0x26, 0x2d, 0x01, 0x36, 
+-      0x48, 0xd6, 0x68, 0x00, 0x1c, 0x41, 0x91, 0x07, 
+-      0xe0, 0x05, 0x26, 0x2d, 0x01, 0x36, 0x48, 0xd3, 
+-      0x68, 0x00, 0x1c, 0x41, 0x91, 0x07, 0x49, 0xd4, 
+-      0xa8, 0x15, 0xf7, 0xfc, 0xf8, 0xe9, 0x98, 0x17, 
+-      0x1e, 0x71, 0x42, 0x88, 0xdd, 0x01, 0x1e, 0x70, 
+-      0x90, 0x17, 0x98, 0x18, 0x99, 0x07, 0x39, 0x01, 
+-      0x42, 0x88, 0xdd, 0x02, 0x99, 0x07, 0x1e, 0x48, 
+-      0x90, 0x18, 0x98, 0x18, 0x99, 0x16, 0x1a, 0x40, 
+-      0x00, 0x40, 0x1c, 0x81, 0x98, 0x08, 0xf0, 0x06, 
+-      0xfb, 0xd3, 0x90, 0x0a, 0x98, 0x0a, 0x42, 0x84, 
+-      0xdd, 0x00, 0x9c, 0x0a, 0x48, 0xc5, 0x6f, 0x00, 
+-      0x90, 0x02, 0x20, 0x00, 0x90, 0x05, 0x98, 0x02, 
+-      0x28, 0x02, 0xd0, 0x02, 0x98, 0x02, 0x28, 0x03, 
+-      0xd1, 0x3a, 0x48, 0xc1, 0x6b, 0x00, 0x90, 0x04, 
+-      0x48, 0xbe, 0x6e, 0xc1, 0x91, 0x03, 0x98, 0x04, 
+-      0x99, 0x03, 0x42, 0x88, 0xdd, 0x21, 0x20, 0xc0, 
+-      0x90, 0x06, 0x1d, 0x20, 0x28, 0x00, 0xda, 0x02, 
+-      0xe0, 0x00, 0xe1, 0x8e, 0x30, 0x07, 0x10, 0xc0, 
+-      0x90, 0x05, 0x98, 0x04, 0x28, 0x03, 0xd0, 0x14, 
+-      0x99, 0x03, 0x29, 0x03, 0xd1, 0x07, 0x20, 0xcd, 
+-      0x90, 0x06, 0x1d, 0x61, 0x20, 0x0a, 0xf0, 0x06, 
+-      0xfb, 0xa3, 0x90, 0x05, 0xe0, 0x09, 0x98, 0x02, 
+-      0x28, 0x02, 0xd1, 0x06, 0x20, 0x9a, 0x90, 0x06, 
+-      0x1c, 0xa1, 0x20, 0x05, 0xf0, 0x06, 0xfb, 0x98, 
+-      0x90, 0x05, 0x98, 0x06, 0x28, 0x9a, 0xd0, 0x02, 
+-      0x98, 0x06, 0x28, 0xcd, 0xd1, 0x08, 0x2d, 0x0e, 
+-      0xd0, 0x01, 0x2d, 0x11, 0xd1, 0x04, 0x20, 0x00, 
+-      0x90, 0x05, 0x20, 0xff, 0x30, 0x01, 0x90, 0x06, 
+-      0x2d, 0x12, 0xd1, 0x0b, 0x48, 0x9d, 0x68, 0x00, 
+-      0x30, 0x01, 0x42, 0xa0, 0xd1, 0x06, 0x68, 0x78, 
+-      0x28, 0x00, 0xd1, 0x03, 0x20, 0x01, 0x49, 0x9f, 
+-      0x63, 0x48, 0xe0, 0x02, 0x20, 0x00, 0x49, 0x9d, 
+-      0x63, 0x48, 0x98, 0x0a, 0x99, 0x06, 0x43, 0x48, 
+-      0x28, 0x00, 0xda, 0x00, 0x30, 0xff, 0x12, 0x00, 
+-      0x42, 0xa0, 0xdd, 0x04, 0x20, 0x00, 0x90, 0x05, 
+-      0x20, 0xff, 0x30, 0x01, 0x90, 0x06, 0x68, 0x78, 
+-      0x99, 0x05, 0x18, 0x40, 0x60, 0x78, 0x1c, 0x39, 
+-      0xa8, 0x11, 0xf7, 0xfc, 0xf8, 0x61, 0x1c, 0x29, 
+-      0xa8, 0x11, 0xf7, 0xff, 0xfd, 0x71, 0x98, 0x12, 
+-      0x49, 0x88, 0x68, 0x09, 0x39, 0x01, 0x42, 0x88, 
+-      0xd1, 0x00, 0x24, 0x00, 0x99, 0x15, 0x91, 0x0d, 
+-      0x98, 0x16, 0x90, 0x0f, 0x21, 0x00, 0x91, 0x10, 
+-      0x68, 0x38, 0x28, 0x00, 0xda, 0x08, 0x68, 0x38, 
+-      0x99, 0x08, 0x43, 0x48, 0x42, 0x41, 0x29, 0x00, 
+-      0xda, 0x00, 0x31, 0x01, 0x10, 0x49, 0x91, 0x10, 
+-      0x68, 0x78, 0x28, 0x00, 0xda, 0x0d, 0x68, 0x78, 
+-      0x99, 0x08, 0x43, 0x48, 0x28, 0x00, 0xda, 0x00, 
+-      0x30, 0x01, 0x10, 0x40, 0x02, 0x01, 0x98, 0x06, 
+-      0xf0, 0x06, 0xfb, 0x36, 0x99, 0x0f, 0x1a, 0x08, 
+-      0x90, 0x0f, 0x98, 0x18, 0x99, 0x0f, 0x42, 0x88, 
+-      0xdc, 0x02, 0x98, 0x18, 0x30, 0x01, 0x90, 0x0f, 
+-      0x98, 0x17, 0x99, 0x0d, 0x1a, 0x40, 0x30, 0x01, 
+-      0x90, 0x0e, 0x98, 0x18, 0x99, 0x0f, 0x1a, 0x40, 
+-      0x30, 0x01, 0x90, 0x09, 0x98, 0x09, 0x00, 0x41, 
+-      0x98, 0x08, 0xf0, 0x06, 0xfb, 0x1d, 0x99, 0x06, 
+-      0x43, 0x48, 0x28, 0x00, 0xda, 0x00, 0x30, 0xff, 
+-      0x12, 0x00, 0x90, 0x09, 0x68, 0xb8, 0x68, 0x39, 
+-      0x1a, 0x40, 0x1c, 0x41, 0x91, 0x0c, 0x98, 0x17, 
+-      0x99, 0x15, 0x1a, 0x40, 0x00, 0x40, 0x1c, 0x81, 
+-      0x98, 0x08, 0xf0, 0x06, 0xfb, 0x09, 0x90, 0x0b, 
+-      0x98, 0x0b, 0x4b, 0x65, 0x40, 0x18, 0x90, 0x0b, 
+-      0x98, 0x0b, 0x99, 0x08, 0x43, 0x48, 0x28, 0x00, 
+-      0xda, 0x00, 0x30, 0x01, 0x10, 0x40, 0x90, 0x0e, 
+-      0x99, 0x0c, 0x98, 0x0b, 0x42, 0x81, 0xdd, 0x01, 
+-      0x98, 0x0b, 0x90, 0x0c, 0x99, 0x0c, 0x4b, 0x5c, 
+-      0x40, 0x19, 0x91, 0x0c, 0x98, 0x0c, 0x28, 0x00, 
+-      0xdd, 0x05, 0x68, 0x38, 0x99, 0x0c, 0x18, 0x40, 
+-      0x38, 0x01, 0x90, 0x13, 0xe0, 0x02, 0x68, 0x38, 
+-      0x30, 0x01, 0x90, 0x13, 0x98, 0x13, 0x28, 0x01, 
+-      0xda, 0x01, 0x20, 0x01, 0x90, 0x13, 0x98, 0x13, 
+-      0x4b, 0x52, 0x42, 0x98, 0xdd, 0x01, 0x48, 0x51, 
+-      0x90, 0x13, 0x99, 0x06, 0x43, 0x4c, 0x1c, 0x20, 
+-      0x28, 0x00, 0xda, 0x00, 0x30, 0xff, 0x12, 0x04, 
+-      0x98, 0x0a, 0x42, 0x84, 0xdd, 0x00, 0x9c, 0x0a, 
+-      0x2c, 0x02, 0xda, 0x00, 0x24, 0x02, 0x68, 0x78, 
+-      0x19, 0x00, 0x38, 0x01, 0x90, 0x14, 0x98, 0x14, 
+-      0x28, 0x01, 0xda, 0x01, 0x20, 0x01, 0x90, 0x14, 
+-      0x98, 0x14, 0x49, 0x3c, 0x68, 0x09, 0x42, 0x88, 
+-      0xd9, 0x02, 0x48, 0x3a, 0x68, 0x00, 0x90, 0x14, 
+-      0x98, 0x12, 0x49, 0x38, 0x68, 0x09, 0x39, 0x01, 
+-      0x42, 0x88, 0xd9, 0x03, 0x48, 0x35, 0x68, 0x00, 
+-      0x38, 0x01, 0x90, 0x12, 0x98, 0x09, 0x28, 0x04, 
+-      0xdb, 0x01, 0x2c, 0x04, 0xda, 0x01, 0x20, 0x00, 
+-      0x90, 0x0e, 0x98, 0x0e, 0x28, 0x03, 0xdb, 0x02, 
+-      0x98, 0x0c, 0x28, 0x04, 0xda, 0x09, 0x20, 0x00, 
+-      0x90, 0x0e, 0x48, 0x35, 0x90, 0x11, 0x48, 0x33, 
+-      0x90, 0x13, 0x20, 0x00, 0x90, 0x12, 0x20, 0x01, 
+-      0x90, 0x14, 0x21, 0x00, 0x91, 0x00, 0x98, 0x08, 
+-      0x28, 0x01, 0xd1, 0x16, 0x98, 0x0e, 0x99, 0x10, 
+-      0x1a, 0x40, 0x00, 0x40, 0x4b, 0x2b, 0x42, 0x98, 
+-      0xdd, 0x0b, 0x98, 0x0e, 0x99, 0x10, 0x1a, 0x40, 
+-      0x00, 0x40, 0x23, 0x2d, 0x01, 0x1b, 0x1a, 0xc1, 
+-      0x29, 0x00, 0xda, 0x00, 0x31, 0x01, 0x10, 0x49, 
+-      0x91, 0x00, 0x98, 0x0e, 0x42, 0xb0, 0xdd, 0x00, 
+-      0x96, 0x0e, 0x99, 0x10, 0x42, 0xb1, 0xdd, 0x00, 
+-      0x96, 0x10, 0x1c, 0x30, 0x21, 0x01, 0x07, 0x49, 
+-      0xf0, 0x06, 0xfa, 0x76, 0x99, 0x0d, 0x43, 0x48, 
+-      0x23, 0x01, 0x04, 0x1b, 0x18, 0xc0, 0x14, 0x40, 
+-      0x49, 0x1c, 0x65, 0x88, 0x1c, 0x30, 0x21, 0x01, 
+-      0x07, 0x49, 0xf0, 0x06, 0xfa, 0x69, 0x99, 0x10, 
+-      0x43, 0x48, 0x23, 0x01, 0x04, 0x1b, 0x18, 0xc0, 
+-      0x14, 0x40, 0x49, 0x16, 0x65, 0xc8, 0x1c, 0x30, 
+-      0x21, 0x01, 0x07, 0x49, 0xf0, 0x06, 0xfa, 0x5c, 
+-      0x99, 0x0e, 0x43, 0x48, 0x23, 0x01, 0x04, 0x1b, 
+-      0x18, 0xc0, 0x14, 0x40, 0x49, 0x0f, 0x65, 0x48, 
+-      0x99, 0x07, 0x1f, 0x08, 0x99, 0x0f, 0x42, 0x88, 
+-      0xdc, 0x1b, 0x99, 0x07, 0x1f, 0x08, 0xe0, 0x17, 
+-      0x00, 0x00, 0x02, 0x3f, 0x2e, 0x08, 0x60, 0x80, 
+-      0x2e, 0x08, 0x7c, 0xbc, 0xcc, 0x00, 0x02, 0x00, 
+-      0x2e, 0x08, 0x7d, 0xa0, 0xcc, 0x00, 0x0f, 0x80, 
+-      0xcc, 0x00, 0x00, 0x80, 0xcc, 0x00, 0x01, 0x00, 
+-      0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x02, 0xcf, 
+-      0x00, 0x00, 0x02, 0xce, 0xcc, 0x00, 0x00, 0x00, 
+-      0x90, 0x0f, 0x98, 0x0f, 0x49, 0x0d, 0x66, 0x08, 
+-      0x1c, 0x30, 0x21, 0x01, 0x07, 0x49, 0xf0, 0x06, 
+-      0xfa, 0x2b, 0x99, 0x00, 0x43, 0x48, 0x23, 0x01, 
+-      0x04, 0x1b, 0x18, 0xc0, 0x14, 0x40, 0x49, 0x07, 
+-      0x66, 0x48, 0xa9, 0x11, 0x1c, 0x38, 0xf7, 0xfb, 
+-      0xff, 0x1f, 0x20, 0x00, 0xb0, 0x1b, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0xb0, 0x1b, 
+-      0xe7, 0xf9, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 
+-      0xb4, 0xb0, 0x1c, 0x02, 0x1c, 0x0f, 0x2a, 0x00, 
+-      0xd1, 0x02, 0x20, 0x01, 0xbc, 0xb0, 0x47, 0x70, 
+-      0x2f, 0x01, 0xd1, 0x20, 0x20, 0x00, 0x23, 0x00, 
+-      0x4d, 0x13, 0x62, 0x2b, 0x23, 0x00, 0x4d, 0x12, 
+-      0x62, 0xab, 0x4b, 0x12, 0x68, 0x9b, 0x1c, 0x1c, 
+-      0x4b, 0x11, 0x6e, 0xdb, 0x1c, 0x19, 0x2c, 0x02, 
+-      0xd0, 0x01, 0x29, 0x02, 0xd1, 0x01, 0x20, 0x08, 
+-      0xe0, 0x00, 0x20, 0x07, 0x79, 0x13, 0x2b, 0x00, 
+-      0xd0, 0x01, 0x23, 0x10, 0x43, 0x18, 0x4b, 0x08, 
+-      0x62, 0x58, 0x79, 0x55, 0x23, 0x80, 0x43, 0x2b, 
+-      0x4d, 0x05, 0x62, 0xab, 0xe0, 0x05, 0x48, 0x07, 
+-      0x68, 0x05, 0x23, 0x80, 0x43, 0x9d, 0x1c, 0x2b, 
+-      0x60, 0x03, 0x20, 0x00, 0xe7, 0xd2, 0xe7, 0xd1, 
+-      0x72, 0x00, 0x01, 0x00, 0xcc, 0x00, 0x0c, 0x00, 
+-      0xcc, 0x00, 0x0f, 0x80, 0x72, 0x00, 0x01, 0x28, 
+-      0xb5, 0xff, 0x9f, 0x09, 0xb0, 0x81, 0x98, 0x01, 
+-      0x06, 0x00, 0x0e, 0x00, 0x90, 0x00, 0x99, 0x02, 
+-      0x06, 0x0c, 0x0e, 0x24, 0x98, 0x03, 0x06, 0x02, 
+-      0x0e, 0x12, 0x9b, 0x04, 0x06, 0x1d, 0x0e, 0x2d, 
+-      0x2f, 0x01, 0xd1, 0x1b, 0x20, 0x00, 0x4b, 0x14, 
+-      0x62, 0x18, 0x20, 0x00, 0x4b, 0x12, 0x62, 0x98, 
+-      0x98, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x01, 0x23, 
+-      0x43, 0x18, 0x06, 0x01, 0x0e, 0x09, 0x48, 0x0e, 
+-      0x62, 0x41, 0x07, 0x50, 0x0f, 0x40, 0x07, 0x6b, 
+-      0x0f, 0x5b, 0x00, 0xdb, 0x43, 0x18, 0x06, 0x01, 
+-      0x0e, 0x09, 0x20, 0x80, 0x43, 0x08, 0x4b, 0x08, 
+-      0x62, 0x98, 0xe0, 0x05, 0x48, 0x07, 0x68, 0x06, 
+-      0x23, 0x80, 0x43, 0x9e, 0x1c, 0x33, 0x60, 0x03, 
+-      0x20, 0x00, 0xb0, 0x01, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb0, 0x01, 0xe7, 0xf9, 
+-      0x72, 0x00, 0x01, 0x00, 0x72, 0x00, 0x01, 0x28, 
+-      0xb5, 0xf1, 0x98, 0x00, 0x06, 0x07, 0x0e, 0x3f, 
+-      0xb0, 0x81, 0x2f, 0x1f, 0xdb, 0x05, 0x20, 0xb3, 
+-      0xb0, 0x01, 0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x48, 0x62, 0x23, 0x80, 0x68, 0x1b, 
+-      0x60, 0x18, 0x48, 0x61, 0x23, 0x80, 0x6b, 0x1b, 
+-      0x60, 0x18, 0x48, 0x60, 0x23, 0x80, 0x6b, 0x5b, 
+-      0x60, 0x18, 0x48, 0x5f, 0x23, 0x80, 0x6b, 0x9b, 
+-      0x60, 0x18, 0x20, 0x01, 0x40, 0xb8, 0x4b, 0x59, 
+-      0x60, 0x18, 0x20, 0x00, 0x4b, 0x57, 0x71, 0x18, 
+-      0x20, 0x00, 0x4b, 0x56, 0x71, 0x58, 0x48, 0x55, 
+-      0x68, 0x00, 0x4b, 0x58, 0x60, 0x58, 0x48, 0x58, 
+-      0x4b, 0x56, 0x60, 0x98, 0x48, 0x57, 0x4b, 0x55, 
+-      0x60, 0xd8, 0x20, 0xff, 0x30, 0x01, 0x4b, 0x53, 
+-      0x62, 0x18, 0x20, 0xff, 0x30, 0x01, 0x4b, 0x51, 
+-      0x62, 0x58, 0x20, 0x03, 0x4b, 0x52, 0x75, 0x18, 
+-      0x20, 0x0e, 0x4b, 0x51, 0x75, 0x58, 0x20, 0x04, 
+-      0x4b, 0x4f, 0x75, 0x98, 0x20, 0x03, 0x4b, 0x4e, 
+-      0x75, 0xd8, 0x20, 0x00, 0x4b, 0x4d, 0x60, 0x18, 
+-      0x20, 0x00, 0x4b, 0x4d, 0x60, 0x18, 0x20, 0x0d, 
+-      0x23, 0x19, 0x06, 0x9b, 0x63, 0x18, 0x22, 0x00, 
+-      0x2a, 0x20, 0xdb, 0x04, 0xe0, 0x21, 0x1c, 0x50, 
+-      0x06, 0x02, 0x0e, 0x12, 0xe7, 0xf8, 0x25, 0x00, 
+-      0x00, 0x93, 0x4e, 0x46, 0x50, 0xf5, 0x25, 0xff, 
+-      0x4b, 0x45, 0x54, 0x9d, 0x01, 0x15, 0x4b, 0x45, 
+-      0x18, 0xec, 0x01, 0x15, 0x4b, 0x44, 0x18, 0xe8, 
+-      0x25, 0x00, 0xc4, 0x20, 0x25, 0x00, 0xc4, 0x20, 
+-      0x25, 0x00, 0xc4, 0x20, 0x25, 0x00, 0xc4, 0x20, 
+-      0x25, 0x00, 0xc0, 0x20, 0x25, 0x00, 0xc0, 0x20, 
+-      0x25, 0x00, 0xc0, 0x20, 0x25, 0x00, 0xc0, 0x20, 
+-      0xe7, 0xdd, 0x21, 0x00, 0x29, 0x20, 0xdb, 0x04, 
+-      0xe0, 0x0b, 0x1c, 0x48, 0x04, 0x01, 0x0c, 0x09, 
+-      0xe7, 0xf8, 0x23, 0x00, 0x00, 0x88, 0x4c, 0x2a, 
+-      0x50, 0x23, 0x23, 0x00, 0x48, 0x35, 0x54, 0x43, 
+-      0xe7, 0xf3, 0x4c, 0x35, 0x94, 0x00, 0x22, 0x00, 
+-      0x2a, 0x10, 0xdb, 0x04, 0xe0, 0x0f, 0x1c, 0x50, 
+-      0x06, 0x02, 0x0e, 0x12, 0xe7, 0xf8, 0x20, 0x00, 
+-      0x00, 0x93, 0x4c, 0x30, 0x50, 0xe0, 0x23, 0xff, 
+-      0x48, 0x2f, 0x54, 0x83, 0x20, 0x00, 0x00, 0x93, 
+-      0x9c, 0x00, 0x50, 0xe0, 0xe7, 0xef, 0x21, 0x00, 
+-      0x23, 0xff, 0x33, 0x01, 0x42, 0x99, 0xdb, 0x04, 
+-      0xe0, 0x2a, 0x1c, 0x48, 0x04, 0x01, 0x0c, 0x09, 
+-      0xe7, 0xf6, 0x23, 0x00, 0x00, 0x88, 0x4c, 0x1a, 
+-      0x50, 0x23, 0x20, 0x00, 0x00, 0x8b, 0x4c, 0x18, 
+-      0x19, 0x1c, 0x23, 0x01, 0x02, 0x9b, 0x18, 0xe3, 
+-      0x60, 0x18, 0x20, 0x00, 0x4b, 0x14, 0x18, 0x5c, 
+-      0x23, 0x01, 0x02, 0xdb, 0x18, 0xe3, 0x70, 0x18, 
+-      0x20, 0x00, 0x00, 0x8b, 0x4c, 0x11, 0x50, 0xe0, 
+-      0x20, 0x00, 0x00, 0x8b, 0x4c, 0x0f, 0x19, 0x1c, 
+-      0x23, 0x01, 0x02, 0x9b, 0x18, 0xe3, 0x60, 0x18, 
+-      0x20, 0x00, 0x4b, 0x0c, 0x18, 0x5c, 0x23, 0x01, 
+-      0x02, 0xdb, 0x18, 0xe3, 0x70, 0x18, 0xe7, 0xd4, 
+-      0x20, 0x00, 0xb0, 0x01, 0xe7, 0x39, 0xb0, 0x01, 
+-      0xe7, 0x37, 0x00, 0x00, 0x2e, 0x08, 0x72, 0xec, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x72, 0x90, 
+-      0x2e, 0x08, 0x72, 0x9c, 0x9e, 0x00, 0x04, 0x80, 
+-      0x2e, 0x08, 0x60, 0x90, 0x2e, 0x08, 0x69, 0x90, 
+-      0x9e, 0x00, 0x04, 0xa0, 0x2e, 0x08, 0x5e, 0xdc, 
+-      0x2e, 0x08, 0x5e, 0xe0, 0x2e, 0x08, 0x5e, 0xe4, 
+-      0x2e, 0x08, 0x5f, 0xa4, 0x64, 0x00, 0x08, 0x00, 
+-      0x64, 0x00, 0x10, 0x00, 0x2e, 0x08, 0x7b, 0xf4, 
+-      0x9e, 0x00, 0x04, 0xb8, 0x2e, 0x08, 0x5f, 0x64, 
+-      0x2e, 0x08, 0x5f, 0xc4, 0xb4, 0xb0, 0x1c, 0x07, 
+-      0x1c, 0x0a, 0x06, 0x11, 0x0e, 0x09, 0x29, 0x20, 
+-      0xdb, 0x02, 0x20, 0xa2, 0xbc, 0xb0, 0x47, 0x70, 
+-      0x00, 0x88, 0x4b, 0x0a, 0x58, 0x18, 0x1c, 0x05, 
+-      0xd1, 0x01, 0x20, 0xb0, 0xe7, 0xf6, 0x68, 0xe8, 
+-      0x1c, 0x04, 0xd1, 0x01, 0x20, 0xb6, 0xe7, 0xf1, 
+-      0x68, 0x60, 0x00, 0x43, 0x18, 0x18, 0x01, 0x80, 
+-      0x08, 0x80, 0x60, 0x38, 0x20, 0x00, 0xe7, 0xe9, 
+-      0xe7, 0xe8, 0x00, 0x00, 0x2e, 0x08, 0x5e, 0x5c, 
+-      0xb5, 0xff, 0xb0, 0x82, 0x9a, 0x04, 0x06, 0x11, 
+-      0x0e, 0x09, 0x91, 0x00, 0x9b, 0x05, 0x06, 0x18, 
+-      0x0e, 0x00, 0x90, 0x01, 0xb0, 0x83, 0x99, 0x03, 
+-      0x29, 0x20, 0xdb, 0x05, 0x20, 0xa2, 0xb0, 0x05, 
+-      0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x98, 0x05, 0x28, 0x00, 0xd0, 0x64, 0x98, 0x05, 
+-      0x23, 0x0d, 0x06, 0x9b, 0x42, 0xd8, 0xd3, 0x02, 
+-      0x20, 0xb4, 0xb0, 0x05, 0xe7, 0xf0, 0x99, 0x06, 
+-      0x23, 0xff, 0x33, 0x81, 0x42, 0x99, 0xd2, 0x02, 
+-      0x20, 0xb5, 0xb0, 0x05, 0xe7, 0xe8, 0x99, 0x03, 
+-      0x00, 0x88, 0x49, 0x2c, 0x58, 0x08, 0x90, 0x02, 
+-      0x28, 0x00, 0xd1, 0x02, 0x20, 0xb0, 0xb0, 0x05, 
+-      0xe7, 0xde, 0x99, 0x06, 0x00, 0x88, 0x1f, 0xc1, 
+-      0x39, 0x05, 0x91, 0x00, 0x9e, 0x05, 0x98, 0x05, 
+-      0x1d, 0xc5, 0x35, 0x05, 0x60, 0x35, 0x99, 0x06, 
+-      0x60, 0x71, 0x20, 0x00, 0x60, 0xb0, 0x98, 0x04, 
+-      0x28, 0x10, 0xd1, 0x0a, 0x98, 0x02, 0x68, 0x84, 
+-      0x98, 0x02, 0x30, 0x18, 0x90, 0x01, 0x1c, 0x2a, 
+-      0x99, 0x00, 0x98, 0x01, 0xf0, 0x00, 0xfc, 0x86, 
+-      0xe0, 0x25, 0x98, 0x04, 0x28, 0x20, 0xd1, 0x1f, 
+-      0x98, 0x02, 0x68, 0xc0, 0x1c, 0x07, 0xd1, 0x02, 
+-      0x20, 0xb6, 0xb0, 0x05, 0xe7, 0xb8, 0x78, 0xb8, 
+-      0x08, 0x40, 0x00, 0x40, 0x70, 0xb8, 0x69, 0x3c, 
+-      0x1d, 0xf8, 0x30, 0x05, 0x90, 0x01, 0x68, 0xb8, 
+-      0x28, 0x00, 0xd1, 0x00, 0x60, 0xbd, 0x1c, 0x2a, 
+-      0x99, 0x00, 0x98, 0x01, 0xf0, 0x00, 0xfc, 0x6a, 
+-      0x68, 0x79, 0x18, 0x40, 0x60, 0x78, 0x78, 0x78, 
+-      0x99, 0x03, 0xf0, 0x00, 0xf8, 0xb9, 0xe0, 0x02, 
+-      0x20, 0xbc, 0xb0, 0x05, 0xe7, 0x9c, 0x68, 0xa0, 
+-      0x28, 0x00, 0xd0, 0x01, 0x68, 0xa4, 0xe7, 0xfa, 
+-      0x60, 0xa6, 0x20, 0x00, 0xb0, 0x05, 0xe7, 0x93, 
+-      0x20, 0xb4, 0xb0, 0x05, 0xe7, 0x90, 0xb0, 0x03, 
+-      0xb0, 0x02, 0xe7, 0x8d, 0x2e, 0x08, 0x5e, 0x5c, 
+-      0xb5, 0xff, 0xb0, 0x81, 0x9a, 0x03, 0x06, 0x16, 
+-      0x0e, 0x36, 0x9b, 0x04, 0x06, 0x18, 0x0e, 0x00, 
+-      0x90, 0x00, 0xb0, 0x83, 0x27, 0x00, 0x2e, 0x20, 
+-      0xdb, 0x05, 0x20, 0xa2, 0xb0, 0x04, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0xb0, 
+-      0x49, 0x45, 0x58, 0x08, 0x1c, 0x04, 0xd1, 0x02, 
+-      0x20, 0xb0, 0xb0, 0x04, 0xe7, 0xf3, 0x78, 0xe0, 
+-      0x28, 0x00, 0xd1, 0x73, 0x98, 0x03, 0x28, 0x20, 
+-      0xd1, 0x19, 0x68, 0xe0, 0x1c, 0x07, 0xd1, 0x02, 
+-      0x20, 0xb6, 0xb0, 0x04, 0xe7, 0xe7, 0x69, 0x38, 
+-      0x49, 0x3c, 0x60, 0x48, 0x48, 0x3b, 0x68, 0x40, 
+-      0x68, 0x00, 0x60, 0xb8, 0x1d, 0xf8, 0x30, 0x05, 
+-      0x90, 0x02, 0x20, 0x01, 0x90, 0x00, 0x48, 0x37, 
+-      0x68, 0x40, 0x68, 0x40, 0x00, 0x80, 0x1f, 0xc1, 
+-      0x39, 0x19, 0x91, 0x01, 0xe0, 0x1d, 0x98, 0x03, 
+-      0x28, 0x10, 0xd1, 0x17, 0x68, 0xa0, 0x49, 0x31, 
+-      0x60, 0x48, 0x48, 0x30, 0x68, 0x40, 0x68, 0x00, 
+-      0x61, 0x20, 0x48, 0x2e, 0x68, 0x40, 0x68, 0x00, 
+-      0x61, 0x60, 0x1d, 0xe0, 0x30, 0x11, 0x90, 0x02, 
+-      0x48, 0x2a, 0x68, 0x40, 0x68, 0x40, 0x00, 0x80, 
+-      0x1f, 0xc1, 0x39, 0x21, 0x91, 0x01, 0x20, 0x00, 
+-      0x90, 0x00, 0xe0, 0x02, 0x20, 0xbc, 0xb0, 0x04, 
+-      0xe7, 0xb5, 0x48, 0x24, 0x68, 0x40, 0x68, 0x80, 
+-      0x28, 0x00, 0xd0, 0x37, 0x25, 0x00, 0x48, 0x21, 
+-      0x68, 0x40, 0x68, 0x02, 0x99, 0x01, 0x98, 0x02, 
+-      0xf0, 0x00, 0xfb, 0xe8, 0x19, 0x45, 0x48, 0x1d, 
+-      0x68, 0x40, 0x49, 0x1c, 0x60, 0x08, 0x48, 0x1b, 
+-      0x68, 0x00, 0x68, 0x80, 0x49, 0x19, 0x60, 0x48, 
+-      0x48, 0x18, 0x68, 0x40, 0x68, 0x40, 0x00, 0x80, 
+-      0x1f, 0xc1, 0x39, 0x05, 0x91, 0x01, 0x48, 0x15, 
+-      0x68, 0x40, 0x68, 0x80, 0x28, 0x00, 0xd1, 0xe2, 
+-      0x20, 0x00, 0x49, 0x12, 0x68, 0x09, 0x60, 0x88, 
+-      0x48, 0x10, 0x68, 0x40, 0x99, 0x04, 0x60, 0x08, 
+-      0x48, 0x0e, 0x68, 0x40, 0x68, 0x40, 0x99, 0x05, 
+-      0x60, 0x08, 0x98, 0x00, 0x28, 0x00, 0xd0, 0x06, 
+-      0x60, 0x7d, 0x78, 0x78, 0x1c, 0x31, 0xf0, 0x00, 
+-      0xf8, 0x13, 0xe0, 0x00, 0xe0, 0x05, 0x20, 0x00, 
+-      0xb0, 0x04, 0xe7, 0x78, 0x20, 0xb4, 0xb0, 0x04, 
+-      0xe7, 0x75, 0x20, 0xbc, 0xb0, 0x04, 0xe7, 0x72, 
+-      0xb0, 0x03, 0xb0, 0x01, 0xe7, 0x6f, 0x00, 0x00, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x60, 0x88, 
+-      0xb5, 0xf3, 0x98, 0x00, 0x06, 0x02, 0x0e, 0x12, 
+-      0x99, 0x01, 0x06, 0x0c, 0x0e, 0x24, 0xb0, 0x81, 
+-      0x2c, 0x20, 0xdb, 0x05, 0x20, 0xa2, 0xb0, 0x01, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x00, 0xa0, 0x4b, 0x14, 0x58, 0x18, 0x1c, 0x05, 
+-      0xd1, 0x02, 0x20, 0xb0, 0xb0, 0x01, 0xe7, 0xf3, 
+-      0x68, 0xe8, 0x1c, 0x01, 0xd1, 0x02, 0x20, 0xb6, 
+-      0xb0, 0x01, 0xe7, 0xed, 0x11, 0x10, 0x06, 0x00, 
+-      0x0e, 0x00, 0x90, 0x00, 0x28, 0x00, 0xd1, 0x04, 
+-      0x68, 0x48, 0x40, 0xd0, 0x06, 0x07, 0x0e, 0x3f, 
+-      0xe0, 0x09, 0x68, 0x48, 0x07, 0x16, 0x0f, 0x36, 
+-      0x40, 0xf0, 0x68, 0x4e, 0x40, 0xd6, 0x1c, 0x33, 
+-      0x18, 0xc0, 0x06, 0x07, 0x0e, 0x3f, 0x70, 0x0f, 
+-      0x70, 0x4a, 0x20, 0x00, 0xb0, 0x01, 0xe7, 0xd3, 
+-      0xb0, 0x01, 0xe7, 0xd1, 0x2e, 0x08, 0x5e, 0x5c, 
+-      0xb4, 0xb0, 0x1c, 0x03, 0x1c, 0x0a, 0x06, 0x11, 
+-      0x0e, 0x09, 0x29, 0x20, 0xdb, 0x02, 0x20, 0xa2, 
+-      0xbc, 0xb0, 0x47, 0x70, 0x00, 0x88, 0x4d, 0x08, 
+-      0x58, 0x28, 0x1c, 0x04, 0xd1, 0x01, 0x20, 0xb0, 
+-      0xe7, 0xf6, 0x68, 0xe0, 0x1c, 0x07, 0xd1, 0x01, 
+-      0x20, 0xb6, 0xe7, 0xf1, 0x78, 0x78, 0x70, 0x18, 
+-      0x20, 0x00, 0xe7, 0xed, 0xe7, 0xec, 0x00, 0x00, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0xb5, 0xf3, 0xb0, 0x81, 
+-      0x98, 0x01, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x00, 
+-      0x99, 0x02, 0x06, 0x0d, 0x0e, 0x2d, 0xb0, 0x86, 
+-      0x20, 0x00, 0x90, 0x00, 0x2d, 0x20, 0xdd, 0x05, 
+-      0x20, 0xa2, 0xb0, 0x07, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0xa8, 0x49, 0xa2, 
+-      0x58, 0x08, 0x90, 0x04, 0x28, 0x00, 0xd1, 0x02, 
+-      0x20, 0xb0, 0xb0, 0x07, 0xe7, 0xf2, 0x00, 0xa8, 
+-      0x49, 0x9e, 0x68, 0x09, 0x18, 0x40, 0x90, 0x05, 
+-      0x00, 0xe8, 0x1b, 0x40, 0x00, 0x80, 0x49, 0x9c, 
+-      0x68, 0x09, 0x18, 0x46, 0x98, 0x06, 0x28, 0x00, 
+-      0xd0, 0x73, 0x28, 0x01, 0xd0, 0x4f, 0x28, 0x02, 
+-      0xd0, 0x00, 0xe1, 0x1d, 0x98, 0x04, 0x69, 0x00, 
+-      0x60, 0x70, 0x98, 0x04, 0x78, 0x40, 0x06, 0xc0, 
+-      0x0e, 0xc0, 0x90, 0x02, 0x98, 0x02, 0x28, 0x13, 
+-      0xd0, 0x16, 0x27, 0x00, 0x2f, 0x20, 0xdb, 0x04, 
+-      0xe0, 0x11, 0x1c, 0x78, 0x06, 0x07, 0x0e, 0x3f, 
+-      0xe7, 0xf8, 0x48, 0x8e, 0x5d, 0xc0, 0x42, 0xa8, 
+-      0xd1, 0x08, 0x00, 0xb8, 0x49, 0x8c, 0x58, 0x08, 
+-      0x30, 0x01, 0x78, 0x01, 0x23, 0x80, 0x43, 0xdb, 
+-      0x40, 0x19, 0x70, 0x01, 0xe7, 0xed, 0xe0, 0x1e, 
+-      0x27, 0x00, 0x2f, 0x10, 0xdb, 0x04, 0xe0, 0x1a, 
+-      0x1c, 0x78, 0x06, 0x07, 0x0e, 0x3f, 0xe7, 0xf8, 
+-      0x48, 0x84, 0x5d, 0xc0, 0x42, 0xa8, 0xd1, 0x11, 
+-      0x00, 0xb8, 0x49, 0x83, 0x58, 0x08, 0x30, 0x01, 
+-      0x78, 0x01, 0x23, 0x80, 0x43, 0xdb, 0x40, 0x19, 
+-      0x70, 0x01, 0x98, 0x00, 0x30, 0x01, 0x06, 0x00, 
+-      0x0e, 0x00, 0x90, 0x00, 0x98, 0x00, 0x28, 0x02, 
+-      0xd1, 0x00, 0xe0, 0x00, 0xe7, 0xe4, 0x88, 0x30, 
+-      0x4b, 0x7a, 0x40, 0x18, 0x80, 0x30, 0x98, 0x05, 
+-      0x68, 0x00, 0x23, 0x01, 0x03, 0x5b, 0x43, 0x18, 
+-      0x99, 0x05, 0x60, 0x08, 0xe0, 0xd3, 0x98, 0x05, 
+-      0x68, 0x00, 0x4b, 0x75, 0x40, 0x18, 0x99, 0x05, 
+-      0x60, 0x08, 0x20, 0x00, 0x60, 0xb0, 0x20, 0x00, 
+-      0x70, 0xf0, 0x20, 0x00, 0x60, 0xf0, 0x98, 0x04, 
+-      0x78, 0x40, 0x06, 0xc0, 0x0e, 0xc0, 0x90, 0x02, 
+-      0x98, 0x02, 0x28, 0x13, 0xd0, 0x16, 0x27, 0x00, 
+-      0x2f, 0x20, 0xdb, 0x04, 0xe0, 0x11, 0x1c, 0x78, 
+-      0x06, 0x07, 0x0e, 0x3f, 0xe7, 0xf8, 0x48, 0x63, 
+-      0x5d, 0xc0, 0x42, 0xa8, 0xd1, 0x08, 0x00, 0xb8, 
+-      0xe0, 0x00, 0xe0, 0x27, 0x49, 0x60, 0x58, 0x0c, 
+-      0x78, 0x60, 0x23, 0x80, 0x43, 0x18, 0x70, 0x60, 
+-      0xe7, 0xed, 0xe0, 0x1e, 0x27, 0x00, 0x2f, 0x10, 
+-      0xdb, 0x04, 0xe0, 0x1a, 0x1c, 0x78, 0x06, 0x07, 
+-      0x0e, 0x3f, 0xe7, 0xf8, 0x48, 0x59, 0x5d, 0xc0, 
+-      0x42, 0xa8, 0xd1, 0x11, 0x00, 0xb8, 0x49, 0x58, 
+-      0x58, 0x08, 0x30, 0x01, 0x78, 0x01, 0x23, 0x80, 
+-      0x43, 0xdb, 0x40, 0x19, 0x70, 0x01, 0x98, 0x00, 
+-      0x30, 0x01, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x00, 
+-      0x98, 0x00, 0x28, 0x02, 0xd1, 0x00, 0xe0, 0x00, 
+-      0xe7, 0xe4, 0xe0, 0x88, 0x98, 0x05, 0x68, 0x00, 
+-      0x4b, 0x4f, 0x40, 0x18, 0x99, 0x05, 0x60, 0x08, 
+-      0x20, 0x00, 0x60, 0xb0, 0x20, 0x00, 0x70, 0xf0, 
+-      0x20, 0x00, 0x60, 0xf0, 0x98, 0x04, 0x78, 0x40, 
+-      0x06, 0xc0, 0x0e, 0xc0, 0x90, 0x02, 0x98, 0x04, 
+-      0x78, 0x40, 0x21, 0x20, 0x40, 0x01, 0x91, 0x03, 
+-      0x98, 0x02, 0x28, 0x13, 0xd0, 0x4c, 0x27, 0x00, 
+-      0x2f, 0x20, 0xdb, 0x04, 0xe0, 0x47, 0x1c, 0x78, 
+-      0x06, 0x07, 0x0e, 0x3f, 0xe7, 0xf8, 0x48, 0x3b, 
+-      0x5d, 0xc0, 0x42, 0xa8, 0xd1, 0x3e, 0x00, 0xb8, 
+-      0x49, 0x39, 0x58, 0x0c, 0x20, 0x80, 0x70, 0x60, 
+-      0x99, 0x03, 0x1c, 0x20, 0xf7, 0xfd, 0xfb, 0x30, 
+-      0x78, 0xa0, 0x23, 0x04, 0x40, 0x18, 0xd0, 0x28, 
+-      0x6a, 0xe0, 0x22, 0x00, 0x92, 0x01, 0x99, 0x01, 
+-      0x29, 0x08, 0xdb, 0x06, 0xe0, 0x1f, 0x99, 0x01, 
+-      0x31, 0x01, 0x06, 0x09, 0x0e, 0x09, 0x91, 0x01, 
+-      0xe7, 0xf5, 0x99, 0x01, 0x00, 0x89, 0x18, 0x09, 
+-      0x68, 0x49, 0x9a, 0x01, 0x00, 0x92, 0x18, 0x12, 
+-      0x64, 0x51, 0x22, 0x00, 0x99, 0x01, 0x00, 0x89, 
+-      0x18, 0x09, 0x62, 0x4a, 0x99, 0x01, 0x00, 0x89, 
+-      0x18, 0x09, 0x6c, 0x49, 0x29, 0x00, 0xd0, 0x05, 
+-      0x9a, 0x01, 0x21, 0x80, 0x41, 0x11, 0x88, 0x02, 
+-      0x43, 0x11, 0x80, 0x01, 0xe7, 0xdf, 0x88, 0x01, 
+-      0x80, 0x41, 0x78, 0xa0, 0x23, 0x20, 0x40, 0x18, 
+-      0xd0, 0x04, 0x98, 0x04, 0x68, 0xc1, 0x1c, 0x20, 
+-      0xf0, 0x00, 0xfa, 0x3d, 0xe7, 0xb7, 0xe0, 0x1e, 
+-      0x27, 0x00, 0x2f, 0x10, 0xdb, 0x04, 0xe0, 0x1a, 
+-      0x1c, 0x78, 0x06, 0x07, 0x0e, 0x3f, 0xe7, 0xf8, 
+-      0x48, 0x16, 0x5d, 0xc0, 0x42, 0xa8, 0xd1, 0x11, 
+-      0x00, 0xb8, 0x49, 0x15, 0x58, 0x0c, 0x20, 0x80, 
+-      0x70, 0x60, 0x99, 0x03, 0x1c, 0x20, 0xf7, 0xfd, 
+-      0xfa, 0xe3, 0x98, 0x00, 0x30, 0x01, 0x06, 0x00, 
+-      0x0e, 0x00, 0x90, 0x00, 0x98, 0x00, 0x28, 0x02, 
+-      0xd1, 0x00, 0xe0, 0x00, 0xe7, 0xe4, 0xe0, 0x02, 
+-      0x20, 0xbc, 0xb0, 0x07, 0xe6, 0xbe, 0x98, 0x06, 
+-      0x99, 0x04, 0x70, 0xc8, 0x20, 0x00, 0xb0, 0x07, 
+-      0xe6, 0xb8, 0xb0, 0x06, 0xb0, 0x01, 0xe6, 0xb5, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x5d, 0xcc, 
+-      0x2e, 0x08, 0x5d, 0xc4, 0x2e, 0x08, 0x5f, 0xa4, 
+-      0x2e, 0x08, 0x5e, 0xe4, 0x2e, 0x08, 0x5f, 0xc4, 
+-      0x2e, 0x08, 0x5f, 0x64, 0xff, 0xff, 0xfb, 0xff, 
+-      0xff, 0xff, 0xdf, 0xff, 0xb4, 0x90, 0x1c, 0x03, 
+-      0x1c, 0x0a, 0x06, 0x11, 0x0e, 0x09, 0x29, 0x20, 
+-      0xdd, 0x02, 0x20, 0xa2, 0xbc, 0x90, 0x47, 0x70, 
+-      0x00, 0x88, 0x4c, 0x05, 0x58, 0x20, 0x1c, 0x07, 
+-      0xd1, 0x01, 0x20, 0xb0, 0xe7, 0xf6, 0x78, 0xf8, 
+-      0x70, 0x18, 0x20, 0x00, 0xe7, 0xf2, 0xe7, 0xf1, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0xb4, 0x90, 0x1c, 0x02, 
+-      0x1c, 0x0f, 0x06, 0x38, 0x16, 0x04, 0x2a, 0x02, 
+-      0xda, 0x02, 0x20, 0x00, 0xbc, 0x90, 0x47, 0x70, 
+-      0x2c, 0x01, 0xd1, 0x01, 0x21, 0x28, 0xe0, 0x09, 
+-      0x2c, 0x02, 0xd1, 0x01, 0x21, 0x20, 0xe0, 0x05, 
+-      0x2c, 0x00, 0xd1, 0x01, 0x21, 0x0c, 0xe0, 0x01, 
+-      0x20, 0x00, 0xe7, 0xef, 0x00, 0x50, 0x18, 0x80, 
+-      0x01, 0x80, 0x18, 0x41, 0x1c, 0xc8, 0x08, 0x81, 
+-      0x1c, 0x08, 0xe7, 0xe7, 0xe7, 0xe6, 0xb5, 0xf7, 
+-      0x1c, 0x07, 0xb0, 0x81, 0x9a, 0x03, 0x06, 0x11, 
+-      0x0e, 0x09, 0x91, 0x00, 0xb0, 0x84, 0x99, 0x04, 
+-      0x29, 0x20, 0xdb, 0x05, 0x20, 0xa2, 0xb0, 0x05, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x99, 0x04, 0x00, 0x88, 0x49, 0x29, 0x58, 0x08, 
+-      0x1c, 0x06, 0xd1, 0x02, 0x20, 0xb0, 0xb0, 0x05, 
+-      0xe7, 0xf2, 0x2f, 0x00, 0xd1, 0x02, 0x20, 0xb4, 
+-      0xb0, 0x05, 0xe7, 0xed, 0x4b, 0x24, 0x42, 0x9f, 
+-      0xd1, 0x0a, 0x78, 0xf0, 0x28, 0x00, 0xd0, 0x02, 
+-      0x20, 0xbc, 0xb0, 0x05, 0xe7, 0xe4, 0x20, 0x00, 
+-      0x60, 0xf0, 0x20, 0x00, 0xb0, 0x05, 0xe7, 0xdf, 
+-      0x68, 0xf0, 0x28, 0x00, 0xd0, 0x02, 0x20, 0xb4, 
+-      0xb0, 0x05, 0xe7, 0xd9, 0x99, 0x06, 0x00, 0x88, 
+-      0x1f, 0xc1, 0x39, 0x19, 0x91, 0x02, 0x20, 0xff, 
+-      0x30, 0x81, 0x90, 0x01, 0x99, 0x02, 0x98, 0x01, 
+-      0x42, 0x81, 0xda, 0x02, 0x20, 0xb5, 0xb0, 0x05, 
+-      0xe7, 0xca, 0x1c, 0x3c, 0x60, 0xf4, 0x37, 0x14, 
+-      0x1c, 0x3d, 0x37, 0x0c, 0x60, 0x2f, 0x99, 0x06, 
+-      0x60, 0x69, 0x20, 0x00, 0x60, 0xa8, 0x97, 0x03, 
+-      0x20, 0x00, 0x60, 0xe0, 0x1d, 0xe0, 0x30, 0x05, 
+-      0x9a, 0x03, 0x99, 0x02, 0xf0, 0x00, 0xf9, 0x56, 
+-      0x90, 0x00, 0x20, 0x00, 0x70, 0xa0, 0x98, 0x00, 
+-      0x60, 0x60, 0x9a, 0x03, 0x60, 0xa2, 0x61, 0x25, 
+-      0x99, 0x04, 0x20, 0x54, 0xf7, 0xff, 0xfd, 0xa0, 
+-      0xb0, 0x05, 0xe7, 0xa9, 0xb0, 0x04, 0xb0, 0x01, 
+-      0xe7, 0xa6, 0x00, 0x00, 0x2e, 0x08, 0x5e, 0x5c, 
+-      0x00, 0x00, 0xff, 0xff, 0xb5, 0xff, 0xb0, 0x83, 
+-      0x9a, 0x05, 0x06, 0x11, 0x0e, 0x09, 0x91, 0x00, 
+-      0x9b, 0x06, 0x06, 0x18, 0x0e, 0x00, 0x90, 0x01, 
+-      0x98, 0x0c, 0x06, 0x01, 0x0e, 0x09, 0x91, 0x02, 
+-      0xb0, 0x85, 0x99, 0x05, 0x29, 0x20, 0xdb, 0x05, 
+-      0x20, 0xa2, 0xb0, 0x08, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x98, 0x08, 0x28, 0x00, 
+-      0xd1, 0x02, 0x20, 0xb4, 0xb0, 0x08, 0xe7, 0xf5, 
+-      0x99, 0x05, 0x00, 0xc8, 0x1a, 0x40, 0x00, 0x80, 
+-      0x49, 0x83, 0x68, 0x09, 0x18, 0x47, 0x98, 0x08, 
+-      0x4b, 0x82, 0x42, 0x98, 0xd1, 0x73, 0x99, 0x05, 
+-      0x00, 0x88, 0x49, 0x81, 0x58, 0x08, 0x1c, 0x05, 
+-      0xd1, 0x02, 0x20, 0xb0, 0xb0, 0x08, 0xe7, 0xe1, 
+-      0x68, 0xe8, 0x28, 0x00, 0xd1, 0x02, 0x78, 0xe8, 
+-      0x28, 0x00, 0xd0, 0x02, 0x20, 0xbc, 0xb0, 0x08, 
+-      0xe7, 0xd8, 0x78, 0xa8, 0x28, 0x00, 0xd0, 0x54, 
+-      0x20, 0x00, 0x42, 0x80, 0xd0, 0x1d, 0x24, 0x00, 
+-      0x2c, 0x20, 0xdb, 0x04, 0xe0, 0x18, 0x1c, 0x60, 
+-      0x06, 0x04, 0x0e, 0x24, 0xe7, 0xf8, 0x48, 0x73, 
+-      0x5d, 0x00, 0x99, 0x05, 0x42, 0x88, 0xd1, 0x0e, 
+-      0x20, 0x01, 0x40, 0xa0, 0x43, 0xc0, 0x49, 0x70, 
+-      0x68, 0x09, 0x40, 0x08, 0x49, 0x6e, 0x60, 0x08, 
+-      0x20, 0x00, 0x00, 0xa1, 0x4a, 0x6d, 0x50, 0x50, 
+-      0x20, 0xff, 0x49, 0x6a, 0x55, 0x08, 0xe7, 0xe6, 
+-      0xe0, 0x33, 0x4a, 0x6b, 0x92, 0x03, 0x7e, 0x38, 
+-      0x1c, 0x06, 0x28, 0xff, 0xd0, 0x14, 0x20, 0x00, 
+-      0x00, 0xb1, 0x4a, 0x68, 0x50, 0x50, 0x20, 0x01, 
+-      0x40, 0xb0, 0x43, 0xc0, 0x49, 0x66, 0x68, 0x09, 
+-      0x40, 0x08, 0x49, 0x65, 0x60, 0x08, 0x20, 0xff, 
+-      0x76, 0x38, 0x21, 0xff, 0x48, 0x63, 0x55, 0x81, 
+-      0x21, 0x00, 0x00, 0xb0, 0x9a, 0x03, 0x50, 0x11, 
+-      0x7e, 0x78, 0x1c, 0x06, 0x28, 0xff, 0xd0, 0x14, 
+-      0x21, 0x00, 0x00, 0xb0, 0x4a, 0x5b, 0x50, 0x11, 
+-      0x20, 0x01, 0x40, 0xb0, 0x43, 0xc0, 0x49, 0x5a, 
+-      0x68, 0x09, 0x40, 0x08, 0x49, 0x58, 0x60, 0x08, 
+-      0x20, 0xff, 0x76, 0x78, 0x20, 0xff, 0x49, 0x51, 
+-      0x55, 0x88, 0x21, 0x00, 0x00, 0xb0, 0x9a, 0x03, 
+-      0x50, 0x11, 0x20, 0x00, 0x99, 0x05, 0x00, 0x89, 
+-      0x4a, 0x4b, 0x50, 0x50, 0x24, 0x00, 0x2c, 0x0c, 
+-      0xdb, 0x06, 0xe0, 0x09, 0xe0, 0x00, 0xe0, 0x0e, 
+-      0x1c, 0x60, 0x06, 0x04, 0x0e, 0x24, 0xe7, 0xf6, 
+-      0x20, 0x00, 0x19, 0x39, 0x73, 0x08, 0xe7, 0xf7, 
+-      0x20, 0x00, 0x83, 0x38, 0x20, 0x00, 0x70, 0xf8, 
+-      0x20, 0x00, 0xb0, 0x08, 0xe7, 0x66, 0x99, 0x05, 
+-      0x00, 0x88, 0x49, 0x3f, 0x58, 0x08, 0x28, 0x00, 
+-      0xd0, 0x02, 0x20, 0xb0, 0xb0, 0x08, 0xe7, 0x5d, 
+-      0x99, 0x07, 0x29, 0x11, 0xdb, 0x02, 0x99, 0x07, 
+-      0x29, 0x13, 0xdd, 0x02, 0x20, 0xb1, 0xb0, 0x08, 
+-      0xe7, 0x54, 0x99, 0x09, 0x00, 0x88, 0x1f, 0xc1, 
+-      0x39, 0x21, 0x91, 0x01, 0x20, 0xff, 0x30, 0x81, 
+-      0x90, 0x00, 0x99, 0x01, 0x98, 0x00, 0x42, 0x81, 
+-      0xda, 0x02, 0x20, 0xb5, 0xb0, 0x08, 0xe7, 0x45, 
+-      0x9d, 0x08, 0x98, 0x08, 0x30, 0x1c, 0x90, 0x08, 
+-      0x98, 0x08, 0x90, 0x04, 0x98, 0x08, 0x30, 0x0c, 
+-      0x90, 0x08, 0x98, 0x08, 0x90, 0x02, 0x9a, 0x02, 
+-      0x98, 0x04, 0x60, 0x02, 0x99, 0x09, 0x98, 0x04, 
+-      0x60, 0x41, 0x20, 0x00, 0x99, 0x04, 0x60, 0x88, 
+-      0x20, 0x00, 0x61, 0xa8, 0x1d, 0xe8, 0x30, 0x11, 
+-      0x9a, 0x02, 0x99, 0x01, 0xf0, 0x00, 0xf8, 0x56, 
+-      0x20, 0x00, 0x70, 0x28, 0x98, 0x06, 0x99, 0x07, 
+-      0x43, 0x08, 0x70, 0x68, 0x20, 0x00, 0x70, 0xa8, 
+-      0x20, 0x02, 0x70, 0xe8, 0x20, 0x00, 0x71, 0x28, 
+-      0x98, 0x04, 0x60, 0xa8, 0x20, 0x00, 0x60, 0xe8, 
+-      0x9a, 0x02, 0x61, 0x2a, 0x9a, 0x02, 0x61, 0x6a, 
+-      0x99, 0x05, 0x00, 0x88, 0x49, 0x16, 0x50, 0x0d, 
+-      0x20, 0x00, 0x60, 0xf8, 0x88, 0x38, 0x4b, 0x1c, 
+-      0x40, 0x18, 0x80, 0x38, 0x20, 0x00, 0x60, 0xb8, 
+-      0x9a, 0x02, 0x60, 0x7a, 0x98, 0x06, 0x99, 0x07, 
+-      0x43, 0x08, 0x70, 0xb8, 0x24, 0x00, 0x2c, 0x0c, 
+-      0xdb, 0x04, 0xe0, 0x07, 0x1c, 0x60, 0x06, 0x04, 
+-      0x0e, 0x24, 0xe7, 0xf8, 0x20, 0x00, 0x19, 0x39, 
+-      0x74, 0x08, 0xe7, 0xf7, 0x20, 0x00, 0x83, 0x38, 
+-      0x20, 0x00, 0x70, 0xf8, 0x20, 0xff, 0x76, 0x38, 
+-      0x20, 0xff, 0x76, 0x78, 0x20, 0x00, 0xb0, 0x08, 
+-      0xe6, 0xec, 0xb0, 0x05, 0xb0, 0x03, 0xe6, 0xe9, 
+-      0x2e, 0x08, 0x5d, 0xc4, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x2e, 0x08, 0x5f, 0xa4, 
+-      0x2e, 0x08, 0x5e, 0xdc, 0x2e, 0x08, 0x5e, 0xe4, 
+-      0x9e, 0x00, 0x04, 0xb8, 0x2e, 0x08, 0x5f, 0x64, 
+-      0x2e, 0x08, 0x5e, 0xe0, 0x2e, 0x08, 0x5f, 0xc4, 
+-      0xff, 0xff, 0xfb, 0xff, 0xb4, 0x90, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0x1c, 0x13, 0x21, 0x00, 0x68, 0x22, 
+-      0x2a, 0x00, 0xd0, 0x00, 0x60, 0x13, 0x1d, 0xd8, 
+-      0x30, 0xb9, 0x60, 0x18, 0x33, 0xc0, 0x31, 0x01, 
+-      0x3f, 0xc0, 0x2f, 0xc0, 0xd8, 0xf7, 0x20, 0x00, 
+-      0x60, 0x18, 0x60, 0x23, 0x31, 0x01, 0x1c, 0x08, 
+-      0xbc, 0x90, 0x47, 0x70, 0xe7, 0xfc, 0xb4, 0x90, 
+-      0x1c, 0x03, 0x1c, 0x0a, 0x6b, 0x18, 0x68, 0xd1, 
+-      0x68, 0x07, 0x2f, 0x00, 0xd0, 0x0c, 0x68, 0x07, 
+-      0x60, 0x0f, 0x68, 0x41, 0x68, 0x57, 0x68, 0x84, 
+-      0x19, 0x3f, 0x60, 0x57, 0x27, 0x00, 0x60, 0x07, 
+-      0x27, 0x00, 0x60, 0x47, 0x27, 0x00, 0x60, 0x87, 
+-      0x6a, 0xc7, 0x2f, 0x00, 0xd0, 0x0c, 0x6a, 0xc7, 
+-      0x60, 0x0f, 0x6b, 0x01, 0x68, 0x57, 0x6b, 0x44, 
+-      0x19, 0x3f, 0x60, 0x57, 0x27, 0x00, 0x62, 0xc7, 
+-      0x27, 0x00, 0x63, 0x07, 0x27, 0x00, 0x63, 0x47, 
+-      0x60, 0xd1, 0xbc, 0x90, 0x47, 0x70, 0xe7, 0xfc, 
+-      0x20, 0x00, 0x49, 0x01, 0x70, 0x08, 0x47, 0x70, 
+-      0x2e, 0x08, 0x7c, 0x14, 0xb5, 0xff, 0xb0, 0x82, 
+-      0x9b, 0x05, 0x06, 0x18, 0x16, 0x00, 0x90, 0x00, 
+-      0x98, 0x0c, 0x06, 0x01, 0x16, 0x09, 0x91, 0x01, 
+-      0x98, 0x00, 0x28, 0x1f, 0xdd, 0x05, 0x20, 0xaf, 
+-      0xb0, 0x02, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x48, 0x37, 0x78, 0x00, 0x28, 0x00, 
+-      0xd0, 0x03, 0x20, 0xd2, 0xb0, 0x02, 0xe7, 0xf4, 
+-      0xe0, 0x64, 0x20, 0xff, 0x49, 0x32, 0x70, 0x08, 
+-      0x49, 0x32, 0x98, 0x00, 0xf0, 0x09, 0xfa, 0xca, 
+-      0x9a, 0x04, 0x2a, 0x00, 0xd9, 0x52, 0x20, 0xff, 
+-      0x49, 0x2f, 0x70, 0x08, 0x9d, 0x02, 0x98, 0x0b, 
+-      0x99, 0x01, 0x18, 0x44, 0x99, 0x01, 0x20, 0xc0, 
+-      0x1a, 0x40, 0x9a, 0x04, 0x42, 0x90, 0xd9, 0x01, 
+-      0x9f, 0x04, 0xe0, 0x02, 0x99, 0x01, 0x20, 0xc0, 
+-      0x1a, 0x47, 0x1c, 0x3a, 0x1c, 0x21, 0x1c, 0x28, 
+-      0x23, 0xfe, 0xf0, 0x05, 0xfa, 0xa5, 0x1c, 0x06, 
+-      0x2e, 0xd0, 0xd1, 0x0a, 0x20, 0x03, 0xf0, 0x04, 
+-      0xf9, 0xa9, 0x1c, 0x3a, 0x1c, 0x21, 0x1c, 0x28, 
+-      0x23, 0xfe, 0xf0, 0x05, 0xfa, 0x99, 0x1c, 0x06, 
+-      0xe7, 0xf2, 0x98, 0x02, 0x19, 0xc0, 0x90, 0x02, 
+-      0x9a, 0x04, 0x1b, 0xd2, 0x92, 0x04, 0x9d, 0x0b, 
+-      0x9c, 0x03, 0x9b, 0x00, 0x1c, 0x3a, 0x1c, 0x21, 
+-      0x1c, 0x28, 0xf0, 0x05, 0xfa, 0x89, 0x1c, 0x06, 
+-      0x2e, 0xd0, 0xd1, 0x0a, 0x20, 0x03, 0xf0, 0x04, 
+-      0xf9, 0x8d, 0x9b, 0x00, 0x1c, 0x3a, 0x1c, 0x21, 
+-      0x1c, 0x28, 0xf0, 0x05, 0xfa, 0x7d, 0x1c, 0x06, 
+-      0xe7, 0xf2, 0x99, 0x03, 0x29, 0x20, 0xd3, 0x04, 
+-      0x99, 0x01, 0x18, 0x78, 0x99, 0x03, 0x18, 0x41, 
+-      0x91, 0x03, 0x48, 0x0b, 0x78, 0x00, 0x28, 0x00, 
+-      0xd0, 0x03, 0x20, 0x03, 0xf0, 0x04, 0xf9, 0x76, 
+-      0xe7, 0xf7, 0xe7, 0xa9, 0x20, 0x00, 0x49, 0x04, 
+-      0x70, 0x08, 0x20, 0x00, 0xb0, 0x02, 0xe7, 0x90, 
+-      0xb0, 0x02, 0xe7, 0x8e, 0xe7, 0x8d, 0x00, 0x00, 
+-      0x2e, 0x08, 0x1f, 0xa0, 0x2e, 0x01, 0x35, 0x35, 
+-      0x2e, 0x08, 0x7c, 0x14, 0xb5, 0xff, 0x1c, 0x0f, 
+-      0x9a, 0x02, 0x06, 0x14, 0x0e, 0x24, 0x9b, 0x03, 
+-      0x06, 0x1d, 0x0e, 0x2d, 0x2c, 0x1f, 0xdb, 0x04, 
+-      0x20, 0xb3, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x04, 0x3a, 0x0c, 0x12, 0x2d, 0x01, 
+-      0xd1, 0x73, 0x20, 0x01, 0x03, 0x40, 0x40, 0x10, 
+-      0xd0, 0x0a, 0x4b, 0x6f, 0x40, 0x1a, 0x48, 0x6f, 
+-      0x68, 0x00, 0x68, 0x00, 0x23, 0x02, 0x43, 0xdb, 
+-      0x40, 0x18, 0x4b, 0x6c, 0x68, 0x1b, 0x60, 0x18, 
+-      0x20, 0x01, 0x02, 0x40, 0x40, 0x10, 0xd0, 0x0a, 
+-      0x4b, 0x69, 0x40, 0x1a, 0x48, 0x67, 0x68, 0x00, 
+-      0x68, 0x00, 0x23, 0x20, 0x43, 0xdb, 0x40, 0x18, 
+-      0x4b, 0x64, 0x68, 0x1b, 0x60, 0x18, 0x20, 0x01, 
+-      0x05, 0x00, 0x40, 0x38, 0xd0, 0x08, 0x48, 0x63, 
+-      0x68, 0x00, 0x69, 0x80, 0x23, 0x01, 0x05, 0x1b, 
+-      0x43, 0x18, 0x4b, 0x60, 0x68, 0x1b, 0x61, 0x98, 
+-      0x20, 0x01, 0x05, 0x40, 0x40, 0x38, 0xd0, 0x08, 
+-      0x48, 0x5c, 0x68, 0x00, 0x69, 0x80, 0x23, 0x01, 
+-      0x05, 0x5b, 0x43, 0x18, 0x4b, 0x59, 0x68, 0x1b, 
+-      0x61, 0x98, 0x0a, 0x12, 0x48, 0x55, 0x68, 0x00, 
+-      0x68, 0x00, 0x43, 0x90, 0x4b, 0x53, 0x68, 0x1b, 
+-      0x60, 0x18, 0x48, 0x52, 0x68, 0x00, 0x68, 0x00, 
+-      0x4b, 0x53, 0x65, 0x18, 0x48, 0x51, 0x68, 0x00, 
+-      0x77, 0x04, 0x20, 0x09, 0x04, 0x80, 0x40, 0x38, 
+-      0xd0, 0x35, 0x21, 0x00, 0x29, 0x20, 0xdb, 0x04, 
+-      0xe0, 0x31, 0x1c, 0x48, 0x06, 0x01, 0x0e, 0x09, 
+-      0xe7, 0xf8, 0x20, 0x01, 0x40, 0x88, 0x9b, 0x00, 
+-      0x40, 0x18, 0xd0, 0x27, 0x20, 0x01, 0x05, 0x40, 
+-      0x40, 0x38, 0xd0, 0x0e, 0x00, 0xc8, 0x1a, 0x40, 
+-      0x00, 0x80, 0x4b, 0x46, 0x68, 0x1b, 0x5a, 0x18, 
+-      0x23, 0xff, 0x33, 0x01, 0x43, 0x18, 0x00, 0xcb, 
+-      0x1a, 0x5b, 0x00, 0x9b, 0x4e, 0x41, 0x68, 0x36, 
+-      0x52, 0xf0, 0x20, 0x01, 0x04, 0x80, 0x40, 0x38, 
+-      0xd0, 0x10, 0x00, 0xc8, 0x1a, 0x40, 0x00, 0x80, 
+-      0xe0, 0x00, 0xe0, 0x0d, 0x4b, 0x3b, 0x68, 0x1b, 
+-      0x5a, 0x18, 0x23, 0x01, 0x02, 0x5b, 0x43, 0x18, 
+-      0x00, 0xcb, 0x1a, 0x5b, 0x00, 0x9b, 0x4e, 0x37, 
+-      0x68, 0x36, 0x52, 0xf0, 0xe7, 0xcd, 0xe0, 0x5c, 
+-      0x2d, 0x02, 0xd1, 0x5a, 0x0a, 0x12, 0x48, 0x2f, 
+-      0x68, 0x00, 0x68, 0x00, 0x43, 0x10, 0x4b, 0x2d, 
+-      0x68, 0x1b, 0x60, 0x18, 0x48, 0x2b, 0x68, 0x00, 
+-      0x68, 0x00, 0x4b, 0x2d, 0x65, 0x18, 0x20, 0x01, 
+-      0x05, 0x00, 0x40, 0x38, 0xd0, 0x07, 0x48, 0x29, 
+-      0x68, 0x00, 0x69, 0x80, 0x4b, 0x2a, 0x40, 0x18, 
+-      0x4b, 0x26, 0x68, 0x1b, 0x61, 0x98, 0x20, 0x01, 
+-      0x05, 0x40, 0x40, 0x38, 0xd0, 0x07, 0x48, 0x23, 
+-      0x68, 0x00, 0x69, 0x80, 0x4b, 0x25, 0x40, 0x18, 
+-      0x4b, 0x20, 0x68, 0x1b, 0x61, 0x98, 0x21, 0x00, 
+-      0x29, 0x20, 0xdb, 0x04, 0xe0, 0x31, 0x1c, 0x48, 
+-      0x06, 0x01, 0x0e, 0x09, 0xe7, 0xf8, 0x20, 0x09, 
+-      0x04, 0x80, 0x40, 0x38, 0xd0, 0x28, 0x20, 0x01, 
+-      0x40, 0x88, 0x9b, 0x00, 0x40, 0x18, 0xd0, 0x23, 
+-      0x20, 0x01, 0x05, 0x40, 0x40, 0x38, 0xd0, 0x0d, 
+-      0x00, 0xc8, 0x1a, 0x40, 0x00, 0x80, 0x4b, 0x15, 
+-      0x68, 0x1b, 0x5a, 0x18, 0x4b, 0x16, 0x40, 0x18, 
+-      0x00, 0xcb, 0x1a, 0x5b, 0x00, 0x9b, 0x4e, 0x11, 
+-      0x68, 0x36, 0x52, 0xf0, 0x20, 0x01, 0x04, 0x80, 
+-      0x40, 0x38, 0xd0, 0x0d, 0x00, 0xc8, 0x1a, 0x40, 
+-      0x00, 0x80, 0x4b, 0x0c, 0x68, 0x1b, 0x5a, 0x18, 
+-      0x4b, 0x05, 0x40, 0x18, 0x00, 0xcb, 0x1a, 0x5b, 
+-      0x00, 0x9b, 0x4e, 0x08, 0x68, 0x36, 0x52, 0xf0, 
+-      0xe7, 0xcd, 0x20, 0x00, 0xe7, 0x15, 0xe7, 0x14, 
+-      0xff, 0xff, 0xfd, 0xff, 0x2e, 0x08, 0x7c, 0x18, 
+-      0xff, 0xff, 0xdf, 0xff, 0x2e, 0x08, 0x5e, 0x0c, 
+-      0x66, 0x00, 0x00, 0x80, 0x2e, 0x08, 0x5d, 0xc4, 
+-      0xff, 0xef, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 
+-      0xff, 0xff, 0xfe, 0xff, 0xb5, 0x80, 0x1c, 0x07, 
+-      0x48, 0x17, 0x68, 0x01, 0x20, 0x00, 0xf0, 0x12, 
+-      0xf8, 0x69, 0x60, 0x38, 0x48, 0x14, 0x68, 0x00, 
+-      0x1d, 0x01, 0x20, 0x00, 0xf0, 0x12, 0xf8, 0x62, 
+-      0x60, 0x78, 0x48, 0x11, 0x68, 0x00, 0x1d, 0xc1, 
+-      0x31, 0x05, 0x20, 0x00, 0xf0, 0x12, 0xf8, 0x5a, 
+-      0x60, 0xf8, 0x48, 0x0d, 0x68, 0x00, 0x1d, 0xc1, 
+-      0x31, 0x09, 0x20, 0x00, 0xf0, 0x12, 0xf8, 0x52, 
+-      0x61, 0x38, 0x48, 0x09, 0x68, 0x00, 0x1d, 0xc1, 
+-      0x31, 0x0d, 0x20, 0x00, 0xf0, 0x12, 0xf8, 0x4a, 
+-      0x61, 0x78, 0x48, 0x05, 0x68, 0x00, 0x1d, 0xc1, 
+-      0x31, 0x01, 0x20, 0x00, 0xf0, 0x12, 0xf8, 0x42, 
+-      0x60, 0xb8, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x5e, 0x0c, 0xb5, 0xf0, 0x1c, 0x07, 
+-      0xb0, 0x82, 0x26, 0x00, 0x89, 0xb8, 0x23, 0x08, 
+-      0x40, 0x18, 0xd0, 0x08, 0x48, 0x59, 0x6e, 0xc2, 
+-      0x48, 0x58, 0x6f, 0x01, 0x48, 0x57, 0x6a, 0x00, 
+-      0xf7, 0xfd, 0xff, 0x5c, 0x1c, 0x06, 0x89, 0xb8, 
+-      0x23, 0x10, 0x40, 0x18, 0xd0, 0x02, 0x48, 0x53, 
+-      0x69, 0x40, 0x1c, 0x06, 0x89, 0xb8, 0x07, 0xc0, 
+-      0x0f, 0xc0, 0xd0, 0x21, 0x48, 0x50, 0x68, 0xc0, 
+-      0x90, 0x00, 0x68, 0x78, 0x02, 0x40, 0x99, 0x00, 
+-      0x1a, 0x08, 0x90, 0x01, 0x98, 0x01, 0x21, 0x33, 
+-      0x06, 0x49, 0x65, 0xc8, 0x98, 0x00, 0x21, 0x33, 
+-      0x06, 0x49, 0x66, 0x08, 0x98, 0x01, 0x49, 0x48, 
+-      0x60, 0x88, 0x98, 0x00, 0x49, 0x46, 0x60, 0xc8, 
+-      0x20, 0x01, 0x21, 0x33, 0x06, 0x49, 0x66, 0xc8, 
+-      0x20, 0x00, 0x21, 0x33, 0x06, 0x49, 0x66, 0xc8, 
+-      0x89, 0xb8, 0x23, 0x02, 0x43, 0x18, 0x81, 0xb8, 
+-      0x89, 0xb8, 0x23, 0x02, 0x40, 0x18, 0xd0, 0x3e, 
+-      0x48, 0x3d, 0x68, 0x80, 0x1f, 0xc4, 0x3c, 0xff, 
+-      0x3c, 0xfa, 0x68, 0x38, 0x02, 0x40, 0x1a, 0x25, 
+-      0x48, 0x38, 0x60, 0x45, 0x48, 0x37, 0x60, 0x84, 
+-      0x20, 0x33, 0x06, 0x40, 0x65, 0x45, 0x20, 0x33, 
+-      0x06, 0x40, 0x65, 0x84, 0x1b, 0x60, 0x38, 0xc0, 
+-      0x21, 0x33, 0x06, 0x49, 0x66, 0x88, 0x21, 0x00, 
+-      0x48, 0x32, 0xf7, 0xfd, 0xfb, 0x89, 0x48, 0x32, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x00, 0xe7, 0xfa, 
+-      0x48, 0x30, 0x68, 0x01, 0x23, 0xff, 0x33, 0x01, 
+-      0x43, 0x19, 0x60, 0x01, 0x48, 0x2e, 0x6d, 0x80, 
+-      0x49, 0x2d, 0x65, 0x88, 0x48, 0x2c, 0x6b, 0xc0, 
+-      0x23, 0x01, 0x07, 0x9b, 0x40, 0x18, 0xd0, 0x00, 
+-      0xe7, 0xf8, 0x20, 0x33, 0x06, 0x40, 0x66, 0x45, 
+-      0x20, 0x33, 0x06, 0x40, 0x66, 0x84, 0x21, 0x00, 
+-      0x20, 0xff, 0xf7, 0xfd, 0xfb, 0x69, 0x48, 0x20, 
+-      0x60, 0x05, 0x48, 0x1f, 0x60, 0x44, 0x89, 0xb8, 
+-      0x23, 0x04, 0x40, 0x18, 0xd0, 0x21, 0x68, 0xb8, 
+-      0x28, 0x00, 0xd1, 0x06, 0x48, 0x1f, 0x68, 0x01, 
+-      0x23, 0x02, 0x43, 0xdb, 0x40, 0x19, 0x60, 0x01, 
+-      0xe0, 0x17, 0x69, 0x38, 0x49, 0x1a, 0x65, 0x88, 
+-      0x69, 0x38, 0x68, 0xb9, 0x02, 0x49, 0x18, 0x40, 
+-      0x49, 0x17, 0x65, 0xc8, 0x20, 0x03, 0x02, 0x00, 
+-      0x49, 0x15, 0x67, 0x48, 0x20, 0x02, 0x49, 0x14, 
+-      0x67, 0x88, 0x20, 0x40, 0x49, 0x12, 0x66, 0x08, 
+-      0x48, 0x12, 0x68, 0x01, 0x23, 0x02, 0x43, 0x19, 
+-      0x60, 0x01, 0x20, 0x33, 0x06, 0x40, 0x6d, 0x40, 
+-      0x23, 0x0d, 0x06, 0x9b, 0x1a, 0xc0, 0x60, 0x38, 
+-      0x20, 0x33, 0x06, 0x40, 0x6d, 0xc0, 0x23, 0x0d, 
+-      0x06, 0x9b, 0x1a, 0xc0, 0x60, 0x78, 0x48, 0x0a, 
+-      0x43, 0x30, 0x60, 0xb8, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xcc, 0x00, 0x0f, 0x80, 
+-      0x2e, 0x08, 0x7c, 0x1c, 0x00, 0x00, 0x80, 0x0f, 
+-      0xcc, 0x00, 0x05, 0x00, 0x66, 0x00, 0x00, 0xe0, 
+-      0x66, 0x00, 0x00, 0x80, 0x66, 0x00, 0x00, 0xf0, 
+-      0xcc, 0x00, 0x00, 0x00, 0xb5, 0xf3, 0x1c, 0x02, 
+-      0xb0, 0x81, 0x68, 0x93, 0x68, 0x54, 0x21, 0x00, 
+-      0x1d, 0xd8, 0x30, 0xb9, 0x1b, 0x00, 0x06, 0x05, 
+-      0x0e, 0x2d, 0x2d, 0x12, 0xda, 0x12, 0x21, 0x00, 
+-      0x42, 0xa9, 0xdb, 0x04, 0xe0, 0x08, 0x1c, 0x48, 
+-      0x06, 0x01, 0x0e, 0x09, 0xe7, 0xf8, 0x78, 0x26, 
+-      0x34, 0x01, 0x98, 0x02, 0x54, 0x46, 0xe7, 0xf6, 
+-      0x68, 0x1b, 0x1d, 0x18, 0x90, 0x00, 0x98, 0x00, 
+-      0x78, 0x80, 0x18, 0xc4, 0x1c, 0x0f, 0x2f, 0x12, 
+-      0xdb, 0x04, 0xe0, 0x08, 0x1c, 0x78, 0x06, 0x07, 
+-      0x0e, 0x3f, 0xe7, 0xf8, 0x78, 0x26, 0x34, 0x01, 
+-      0x98, 0x02, 0x55, 0xc6, 0xe7, 0xf6, 0x20, 0x00, 
+-      0xb0, 0x01, 0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb0, 0x01, 0xe7, 0xf9, 0xb4, 0xf0, 
+-      0x1c, 0x07, 0x1c, 0x0d, 0x1c, 0x14, 0xb0, 0x82, 
+-      0x20, 0x00, 0x70, 0x20, 0x78, 0x78, 0x23, 0x80, 
+-      0x40, 0x18, 0xd0, 0x03, 0x20, 0xb1, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0x47, 0x70, 0x78, 0xba, 0x20, 0x40, 
+-      0x40, 0x10, 0xd0, 0x2a, 0x07, 0x12, 0x0f, 0x12, 
+-      0x07, 0xd0, 0x0f, 0xc0, 0xd0, 0x25, 0x20, 0x40, 
+-      0x70, 0x20, 0x35, 0x0a, 0x21, 0x00, 0x1d, 0xf8, 
+-      0x30, 0x0d, 0x90, 0x01, 0x1d, 0xf8, 0x30, 0x1d, 
+-      0x90, 0x00, 0x21, 0x00, 0x29, 0x08, 0xdb, 0x04, 
+-      0xe0, 0x14, 0x1c, 0x48, 0x06, 0x01, 0x0e, 0x09, 
+-      0xe7, 0xf8, 0x78, 0x2e, 0x35, 0x01, 0x98, 0x00, 
+-      0x78, 0x03, 0x30, 0x01, 0x90, 0x00, 0x40, 0x33, 
+-      0x98, 0x01, 0x78, 0x06, 0x30, 0x01, 0x90, 0x01, 
+-      0x42, 0xb3, 0xd0, 0x02, 0x20, 0x00, 0x70, 0x20, 
+-      0xe0, 0x00, 0xe7, 0xea, 0x20, 0x00, 0xb0, 0x02, 
+-      0xe7, 0xce, 0x20, 0xb1, 0xb0, 0x02, 0xe7, 0xcb, 
+-      0xb0, 0x02, 0xe7, 0xc9, 0xb5, 0xf7, 0x1c, 0x07, 
+-      0xb0, 0x8d, 0x20, 0x00, 0x9a, 0x0f, 0x70, 0x10, 
+-      0x78, 0x78, 0x23, 0x80, 0x40, 0x18, 0xd0, 0x05, 
+-      0x20, 0xb1, 0xb0, 0x0d, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x78, 0xb8, 0x90, 0x05, 
+-      0x98, 0x05, 0x23, 0x40, 0x40, 0x18, 0xd0, 0x73, 
+-      0x98, 0x05, 0x07, 0x00, 0x0f, 0x00, 0x90, 0x05, 
+-      0x98, 0x05, 0x23, 0x02, 0x40, 0x18, 0xd1, 0x03, 
+-      0x98, 0x05, 0x23, 0x04, 0x40, 0x18, 0xd0, 0x68, 
+-      0x99, 0x0e, 0x79, 0x48, 0x23, 0x3e, 0x40, 0x18, 
+-      0x90, 0x0c, 0x78, 0xf8, 0x90, 0x04, 0x98, 0x04, 
+-      0x01, 0x00, 0x4b, 0x81, 0x18, 0xc0, 0x90, 0x02, 
+-      0x98, 0x02, 0x68, 0x00, 0x90, 0x01, 0x78, 0x7c, 
+-      0x23, 0xbf, 0x40, 0x1c, 0x23, 0xfe, 0x40, 0x1c, 
+-      0x20, 0x00, 0x90, 0x03, 0x98, 0x01, 0x06, 0x00, 
+-      0x0e, 0x00, 0x99, 0x0c, 0x42, 0x88, 0xd0, 0x08, 
+-      0x06, 0x20, 0x0e, 0x00, 0x24, 0x01, 0x43, 0x04, 
+-      0x20, 0x01, 0x90, 0x03, 0x23, 0xdf, 0x40, 0x1c, 
+-      0xe0, 0x06, 0x20, 0x02, 0x40, 0x20, 0xd0, 0x03, 
+-      0x70, 0x7c, 0x20, 0x00, 0xb0, 0x0d, 0xe7, 0xbd, 
+-      0x23, 0xfd, 0x40, 0x1c, 0x98, 0x05, 0x23, 0x04, 
+-      0x40, 0x18, 0xd0, 0x73, 0x6a, 0xfd, 0x98, 0x03, 
+-      0x28, 0x00, 0xd0, 0x14, 0x26, 0x00, 0x2e, 0x08, 
+-      0xdb, 0x04, 0xe0, 0x0e, 0x1c, 0x70, 0x06, 0x06, 
+-      0x0e, 0x36, 0xe7, 0xf8, 0x00, 0xb0, 0x19, 0x40, 
+-      0x68, 0x40, 0x00, 0xb1, 0x19, 0x49, 0x64, 0x48, 
+-      0x20, 0x00, 0x00, 0xb1, 0x19, 0x49, 0x62, 0x48, 
+-      0xe7, 0xf0, 0x88, 0x28, 0x80, 0x68, 0x20, 0x20, 
+-      0x40, 0x20, 0xd1, 0x3e, 0x99, 0x0e, 0x79, 0xc8, 
+-      0x09, 0x40, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x0a, 
+-      0x99, 0x0e, 0x79, 0xc8, 0x06, 0xc0, 0x0e, 0xc0, 
+-      0x90, 0x09, 0x98, 0x0a, 0x30, 0x01, 0x06, 0x06, 
+-      0x0e, 0x36, 0x2e, 0x08, 0xdb, 0x04, 0xe0, 0x10, 
+-      0x1c, 0x70, 0x06, 0x06, 0x0e, 0x36, 0xe7, 0xf8, 
+-      0x20, 0x00, 0x00, 0xb1, 0x19, 0x49, 0xe0, 0x01, 
+-      0xe0, 0x9d, 0xe0, 0x9c, 0x64, 0x48, 0x88, 0x68, 
+-      0x21, 0x80, 0x41, 0x31, 0x43, 0x88, 0x80, 0x68, 
+-      0xe7, 0xee, 0x98, 0x0a, 0x00, 0x80, 0x19, 0x40, 
+-      0x6c, 0x41, 0x98, 0x09, 0x00, 0x80, 0x4a, 0x4b, 
+-      0x58, 0x10, 0x40, 0x08, 0x99, 0x0a, 0x00, 0x89, 
+-      0x19, 0x49, 0x64, 0x48, 0x06, 0x20, 0x0e, 0x00, 
+-      0x24, 0x20, 0x43, 0x04, 0x98, 0x01, 0x0a, 0x00, 
+-      0x02, 0x00, 0x90, 0x01, 0x98, 0x01, 0x99, 0x0c, 
+-      0x43, 0x08, 0x90, 0x01, 0x98, 0x01, 0x99, 0x02, 
+-      0x60, 0x08, 0x78, 0x38, 0x23, 0x80, 0x40, 0x18, 
+-      0xd0, 0x19, 0x99, 0x0e, 0x7b, 0x08, 0x07, 0x42, 
+-      0x0f, 0x52, 0x92, 0x07, 0x99, 0x0e, 0x7b, 0x08, 
+-      0x08, 0xc0, 0x06, 0x02, 0x0e, 0x12, 0x92, 0x08, 
+-      0x1d, 0xe9, 0x31, 0x3d, 0x91, 0x06, 0x99, 0x06, 
+-      0x9a, 0x08, 0x5c, 0x88, 0x49, 0x36, 0x9a, 0x07, 
+-      0x5c, 0x89, 0xe0, 0x00, 0xe0, 0x4e, 0x40, 0x08, 
+-      0x99, 0x06, 0x9a, 0x08, 0x54, 0x88, 0x99, 0x0e, 
+-      0x79, 0x88, 0x06, 0xc0, 0x0e, 0xc0, 0x90, 0x00, 
+-      0x98, 0x00, 0x49, 0x30, 0x40, 0xc1, 0x91, 0x00, 
+-      0x99, 0x0e, 0x79, 0x88, 0x09, 0x40, 0x06, 0x02, 
+-      0x0e, 0x12, 0x92, 0x0b, 0x9a, 0x0b, 0x00, 0x90, 
+-      0x19, 0x40, 0x6c, 0x40, 0x99, 0x00, 0x40, 0x08, 
+-      0xd0, 0x33, 0x06, 0x20, 0x0e, 0x00, 0x24, 0x40, 
+-      0x43, 0x04, 0x9a, 0x0b, 0x00, 0x90, 0x19, 0x40, 
+-      0x6c, 0x40, 0x99, 0x00, 0x40, 0x41, 0x00, 0x90, 
+-      0x19, 0x40, 0x64, 0x41, 0x9a, 0x0b, 0x00, 0x90, 
+-      0x19, 0x40, 0x6a, 0x40, 0x99, 0x00, 0x43, 0x01, 
+-      0x00, 0x90, 0x19, 0x40, 0x62, 0x41, 0x9a, 0x0b, 
+-      0x00, 0x90, 0x19, 0x40, 0x6c, 0x40, 0x28, 0x00, 
+-      0xd1, 0x17, 0x88, 0x68, 0x9a, 0x0b, 0x21, 0x80, 
+-      0x41, 0x11, 0x43, 0x88, 0x80, 0x68, 0x88, 0x68, 
+-      0x28, 0x00, 0xd1, 0x0e, 0x06, 0x20, 0x0e, 0x00, 
+-      0x24, 0x02, 0x43, 0x04, 0x23, 0xfe, 0x40, 0x1c, 
+-      0x98, 0x0c, 0x30, 0x02, 0x06, 0x00, 0x0e, 0x00, 
+-      0x90, 0x0c, 0x98, 0x0c, 0x23, 0x3e, 0x40, 0x18, 
+-      0x90, 0x0c, 0xe0, 0x0a, 0x06, 0x20, 0x0e, 0x00, 
+-      0x24, 0x40, 0x43, 0x04, 0x23, 0xfe, 0x40, 0x1c, 
+-      0x98, 0x0c, 0x1c, 0x41, 0x98, 0x04, 0xf0, 0x00, 
+-      0xf8, 0x13, 0x9a, 0x0f, 0x70, 0x14, 0x70, 0x7c, 
+-      0x20, 0x00, 0xb0, 0x0d, 0xe6, 0xe2, 0x20, 0xb1, 
+-      0xb0, 0x0d, 0xe6, 0xdf, 0xb0, 0x0d, 0xe6, 0xdd, 
+-      0x64, 0x00, 0x08, 0x00, 0x2e, 0x08, 0x20, 0x10, 
+-      0x2e, 0x08, 0x20, 0x90, 0x80, 0x00, 0x00, 0x00, 
+-      0xb5, 0xf3, 0x98, 0x00, 0x06, 0x07, 0x0e, 0x3f, 
+-      0x99, 0x01, 0x06, 0x0e, 0x0e, 0x36, 0x00, 0xf8, 
+-      0x4b, 0x13, 0x18, 0xc5, 0x01, 0x38, 0x4b, 0x13, 
+-      0x18, 0xc4, 0x01, 0x38, 0x4b, 0x12, 0x18, 0xc2, 
+-      0x68, 0x10, 0x23, 0x40, 0x43, 0xdb, 0x40, 0x18, 
+-      0x60, 0x10, 0x2e, 0x3e, 0xdc, 0x15, 0x68, 0x20, 
+-      0x1c, 0x01, 0x0a, 0x09, 0x02, 0x09, 0x43, 0x31, 
+-      0x60, 0x21, 0x68, 0x28, 0x1c, 0x01, 0x0a, 0x09, 
+-      0x02, 0x09, 0x23, 0x3e, 0x43, 0x19, 0x60, 0x29, 
+-      0x68, 0x10, 0x23, 0x40, 0x43, 0x18, 0x60, 0x10, 
+-      0x20, 0x00, 0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x20, 0xbd, 0xe7, 0xf9, 0xe7, 0xf8, 
+-      0x64, 0x00, 0x10, 0x00, 0x64, 0x00, 0x08, 0x00, 
+-      0x64, 0x00, 0x08, 0x08, 0xb5, 0xf3, 0xb0, 0x93, 
+-      0x98, 0x13, 0x69, 0x00, 0x90, 0x01, 0x98, 0x01, 
+-      0x78, 0x40, 0x23, 0x80, 0x40, 0x18, 0xd0, 0x05, 
+-      0x20, 0xbe, 0xb0, 0x13, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x98, 0x01, 0x78, 0x80, 
+-      0x90, 0x08, 0x98, 0x08, 0x23, 0x40, 0x40, 0x18, 
+-      0xd0, 0x73, 0x98, 0x08, 0x23, 0x20, 0x40, 0x18, 
+-      0xd0, 0x6f, 0x98, 0x01, 0x6b, 0x07, 0x98, 0x01, 
+-      0x79, 0xc0, 0x00, 0x80, 0x49, 0x76, 0x58, 0x08, 
+-      0x90, 0x00, 0x98, 0x00, 0x68, 0xc0, 0x1c, 0x06, 
+-      0xd1, 0x02, 0x20, 0xb6, 0xb0, 0x13, 0xe7, 0xe1, 
+-      0x78, 0xb0, 0x07, 0xc0, 0x0f, 0xc0, 0xd0, 0x02, 
+-      0x20, 0xb6, 0xb0, 0x13, 0xe7, 0xda, 0xa9, 0x11, 
+-      0x1c, 0x30, 0xf0, 0x00, 0xf9, 0x2b, 0x90, 0x02, 
+-      0x98, 0x11, 0x28, 0x00, 0xd1, 0x02, 0x98, 0x02, 
+-      0xb0, 0x13, 0xe7, 0xcf, 0x98, 0x11, 0x90, 0x0e, 
+-      0x20, 0x01, 0x90, 0x0b, 0x98, 0x13, 0x88, 0x40, 
+-      0x90, 0x0d, 0x98, 0x13, 0x68, 0x40, 0x90, 0x06, 
+-      0x98, 0x13, 0x68, 0x81, 0x91, 0x10, 0x99, 0x10, 
+-      0x1d, 0xc8, 0x30, 0xb9, 0x90, 0x05, 0x98, 0x05, 
+-      0x99, 0x06, 0x1a, 0x40, 0x04, 0x04, 0x0c, 0x24, 
+-      0x99, 0x14, 0x79, 0x88, 0x90, 0x03, 0x98, 0x03, 
+-      0x06, 0xc0, 0x0e, 0xc0, 0x90, 0x0a, 0x98, 0x0a, 
+-      0x49, 0x5a, 0x40, 0xc1, 0x91, 0x0a, 0x98, 0x03, 
+-      0x09, 0x40, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x09, 
+-      0x98, 0x09, 0x00, 0x80, 0x19, 0xc0, 0x6b, 0x80, 
+-      0x99, 0x0a, 0x40, 0x08, 0xd0, 0x02, 0x20, 0xb1, 
+-      0xb0, 0x13, 0xe7, 0x9f, 0x20, 0xb8, 0x90, 0x0c, 
+-      0x98, 0x11, 0x30, 0x08, 0x90, 0x04, 0x20, 0x00, 
+-      0x90, 0x07, 0x98, 0x07, 0x28, 0x00, 0xd0, 0x10, 
+-      0x99, 0x10, 0x68, 0x09, 0x91, 0x10, 0x99, 0x10, 
+-      0x1d, 0x08, 0x90, 0x12, 0x98, 0x12, 0x78, 0x80, 
+-      0x99, 0x10, 0x18, 0x40, 0x90, 0x06, 0x98, 0x12, 
+-      0x78, 0x81, 0x20, 0xc0, 0x1a, 0x40, 0x04, 0x04, 
+-      0x0c, 0x24, 0x98, 0x0d, 0x42, 0x84, 0xdb, 0x05, 
+-      0xe0, 0x00, 0xe0, 0x7c, 0x9c, 0x0d, 0x20, 0x00, 
+-      0x90, 0x0d, 0xe0, 0x06, 0x98, 0x0d, 0x1b, 0x00, 
+-      0x04, 0x00, 0x0c, 0x00, 0x90, 0x0d, 0x20, 0x01, 
+-      0x90, 0x07, 0x98, 0x0c, 0x42, 0xa0, 0xda, 0x2e, 
+-      0x25, 0x00, 0x98, 0x0c, 0x42, 0x85, 0xdb, 0x04, 
+-      0xe0, 0x0c, 0x1c, 0x68, 0x06, 0x05, 0x0e, 0x2d, 
+-      0xe7, 0xf7, 0x98, 0x06, 0x78, 0x01, 0x30, 0x01, 
+-      0x90, 0x06, 0x98, 0x04, 0x70, 0x01, 0x30, 0x01, 
+-      0x90, 0x04, 0xe7, 0xf2, 0x98, 0x0c, 0x1a, 0x20, 
+-      0x04, 0x04, 0x0c, 0x24, 0xa9, 0x11, 0x1c, 0x30, 
+-      0xf0, 0x00, 0xf8, 0xac, 0x90, 0x02, 0x98, 0x11, 
+-      0x28, 0x00, 0xd1, 0x08, 0x98, 0x0e, 0x60, 0xb0, 
+-      0x68, 0x70, 0x99, 0x0b, 0x18, 0x40, 0x60, 0x70, 
+-      0x98, 0x02, 0xb0, 0x13, 0xe7, 0x4a, 0x98, 0x0b, 
+-      0x30, 0x01, 0x90, 0x0b, 0x20, 0xb8, 0x90, 0x0c, 
+-      0x98, 0x11, 0x30, 0x08, 0x90, 0x04, 0x25, 0x00, 
+-      0x42, 0xa5, 0xdb, 0x04, 0xe0, 0x0c, 0x1c, 0x68, 
+-      0x06, 0x05, 0x0e, 0x2d, 0xe7, 0xf8, 0x98, 0x06, 
+-      0x78, 0x01, 0x30, 0x01, 0x90, 0x06, 0x98, 0x04, 
+-      0x70, 0x01, 0x30, 0x01, 0x90, 0x04, 0xe7, 0xf2, 
+-      0x98, 0x0c, 0x1b, 0x00, 0x04, 0x00, 0x0c, 0x00, 
+-      0x90, 0x0c, 0x98, 0x0d, 0x28, 0x00, 0xd1, 0x90, 
+-      0x6b, 0x39, 0x91, 0x0f, 0x6a, 0xf8, 0x28, 0x00, 
+-      0xd1, 0x02, 0x98, 0x0e, 0x62, 0xf8, 0xe0, 0x05, 
+-      0x98, 0x0e, 0x99, 0x0f, 0x60, 0x08, 0x98, 0x0e, 
+-      0x6d, 0xb9, 0x60, 0x08, 0x98, 0x09, 0x00, 0x80, 
+-      0x19, 0xc0, 0x6b, 0x80, 0x99, 0x0a, 0x43, 0x01, 
+-      0x98, 0x09, 0x00, 0x80, 0x19, 0xc0, 0x63, 0x81, 
+-      0x6b, 0x78, 0x99, 0x0b, 0x18, 0x40, 0x63, 0x78, 
+-      0x20, 0x00, 0x99, 0x11, 0x60, 0x08, 0x98, 0x11, 
+-      0x63, 0x38, 0x98, 0x0e, 0x30, 0x04, 0x65, 0xb8, 
+-      0x98, 0x02, 0xb0, 0x13, 0xe7, 0x02, 0x20, 0xb1, 
+-      0xb0, 0x13, 0xe6, 0xff, 0xb0, 0x13, 0xe6, 0xfd, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0x80, 0x00, 0x00, 0x00, 
+-      0xb4, 0xf0, 0x1c, 0x01, 0x78, 0x88, 0x23, 0x20, 
+-      0x40, 0x18, 0xd0, 0x42, 0x79, 0xc8, 0x00, 0x80, 
+-      0x4b, 0x21, 0x58, 0x1d, 0x6b, 0x0a, 0x68, 0xef, 
+-      0x68, 0x10, 0x28, 0x00, 0xd0, 0x17, 0x68, 0xfe, 
+-      0x68, 0x10, 0x60, 0x30, 0x68, 0x50, 0x60, 0xf8, 
+-      0x68, 0x78, 0x68, 0x93, 0x18, 0xc0, 0x60, 0x78, 
+-      0x20, 0x00, 0x60, 0x10, 0x20, 0x00, 0x60, 0x50, 
+-      0x20, 0x00, 0x60, 0x90, 0x68, 0x78, 0x78, 0x3b, 
+-      0x42, 0x98, 0xd9, 0x04, 0x78, 0xb8, 0x23, 0x02, 
+-      0x43, 0xdb, 0x40, 0x18, 0x70, 0xb8, 0x6a, 0xd0, 
+-      0x60, 0x10, 0x6b, 0x10, 0x60, 0x50, 0x6b, 0x50, 
+-      0x60, 0x90, 0x24, 0x00, 0x2c, 0x08, 0xdb, 0x04, 
+-      0xe0, 0x0e, 0x1c, 0x60, 0x06, 0x04, 0x0e, 0x24, 
+-      0xe7, 0xf8, 0x00, 0xa0, 0x18, 0x80, 0x6b, 0x80, 
+-      0x00, 0xa3, 0x18, 0x9b, 0x60, 0xd8, 0x23, 0x00, 
+-      0x00, 0xa0, 0x18, 0x80, 0x63, 0x83, 0xe7, 0xf0, 
+-      0x20, 0x00, 0x62, 0xd0, 0x20, 0x00, 0x63, 0x10, 
+-      0x20, 0x00, 0x63, 0x50, 0x20, 0x00, 0xbc, 0xf0, 
+-      0x47, 0x70, 0x20, 0xb1, 0xe7, 0xfb, 0xe7, 0xfa, 
+-      0x2e, 0x08, 0x5e, 0x5c, 0xb4, 0x90, 0x1c, 0x02, 
+-      0x1c, 0x0f, 0x78, 0x14, 0x68, 0x90, 0x1c, 0x01, 
+-      0xd1, 0x08, 0x20, 0x00, 0x60, 0x38, 0x78, 0x90, 
+-      0x23, 0x01, 0x43, 0x18, 0x70, 0x90, 0x20, 0xb7, 
+-      0xbc, 0x90, 0x47, 0x70, 0x68, 0x08, 0x60, 0x90, 
+-      0x20, 0x00, 0x60, 0x48, 0x60, 0x39, 0x68, 0x50, 
+-      0x38, 0x01, 0x60, 0x50, 0x68, 0x50, 0x42, 0xa0, 
+-      0xd1, 0x02, 0x20, 0xbf, 0xe7, 0xf0, 0xe0, 0x01, 
+-      0x20, 0x00, 0xe7, 0xed, 0xe7, 0xec, 0x00, 0x00, 
+-      0x1c, 0x01, 0x22, 0x00, 0x6a, 0x50, 0x68, 0x02, 
+-      0x60, 0x0a, 0x4a, 0x05, 0x6f, 0xd2, 0x60, 0x8a, 
+-      0x4a, 0x04, 0x68, 0x12, 0x60, 0x4a, 0x22, 0x1d, 
+-      0x02, 0x92, 0x68, 0x12, 0x60, 0xca, 0x47, 0x70, 
+-      0xcc, 0x00, 0x0f, 0x80, 0x2e, 0x08, 0x1f, 0xa4, 
+-      0x1c, 0x01, 0x48, 0x02, 0x60, 0x01, 0x20, 0x00, 
+-      0x47, 0x70, 0xe7, 0xfd, 0x66, 0x00, 0x01, 0x00, 
+-      0x1c, 0x01, 0x20, 0x33, 0x06, 0x40, 0x62, 0x01, 
+-      0x20, 0x00, 0x47, 0x70, 0xe7, 0xfd, 0x1c, 0x01, 
+-      0x20, 0x33, 0x06, 0x40, 0x6a, 0xc0, 0x23, 0x7f, 
+-      0x03, 0x9b, 0x40, 0x18, 0x03, 0x8a, 0x43, 0x10, 
+-      0x22, 0x33, 0x06, 0x52, 0x62, 0xd0, 0x20, 0x00, 
+-      0x47, 0x70, 0xe7, 0xfd, 0x1c, 0x01, 0x20, 0x33, 
+-      0x06, 0x40, 0x6a, 0xc0, 0x23, 0x03, 0x03, 0x1b, 
+-      0x40, 0x18, 0x43, 0x08, 0x22, 0x33, 0x06, 0x52, 
+-      0x62, 0xd0, 0x20, 0x00, 0x47, 0x70, 0xe7, 0xfd, 
+-      0x1c, 0x01, 0x06, 0x0a, 0x0e, 0x12, 0x2a, 0x00, 
+-      0xd0, 0x06, 0x20, 0x33, 0x06, 0x40, 0x6a, 0xc0, 
+-      0x23, 0x01, 0x05, 0x5b, 0x43, 0x18, 0xe0, 0x04, 
+-      0x20, 0x33, 0x06, 0x40, 0x6a, 0xc0, 0x4b, 0x04, 
+-      0x40, 0x18, 0x23, 0x33, 0x06, 0x5b, 0x62, 0xd8, 
+-      0x20, 0x00, 0x47, 0x70, 0xe7, 0xfd, 0x00, 0x00, 
+-      0xff, 0xdf, 0xff, 0xff, 0x48, 0x04, 0x69, 0x80, 
+-      0x07, 0xc0, 0x0f, 0xc0, 0xd0, 0x01, 0x20, 0xff, 
+-      0x47, 0x70, 0x20, 0x00, 0xe7, 0xfc, 0xe7, 0xfb, 
+-      0x66, 0x00, 0x00, 0x80, 0xb4, 0x80, 0x1c, 0x01, 
+-      0x06, 0x0f, 0x0e, 0x3f, 0x4a, 0x08, 0x2f, 0x00, 
+-      0xd0, 0x03, 0x68, 0x10, 0x23, 0x01, 0x43, 0x18, 
+-      0xe0, 0x02, 0x68, 0x10, 0x08, 0x40, 0x00, 0x40, 
+-      0x68, 0x13, 0x43, 0x18, 0x60, 0x10, 0x20, 0x00, 
+-      0xbc, 0x80, 0x47, 0x70, 0xe7, 0xfc, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x98, 0xb4, 0x80, 0x1c, 0x07, 
+-      0x1c, 0x0a, 0x4b, 0x06, 0x40, 0x1a, 0x4b, 0x06, 
+-      0x40, 0x1f, 0x0b, 0x10, 0x02, 0x39, 0x43, 0x08, 
+-      0x49, 0x04, 0x61, 0xc8, 0x20, 0x00, 0xbc, 0x80, 
+-      0x47, 0x70, 0xe7, 0xfc, 0x01, 0xff, 0xf0, 0x00, 
+-      0x00, 0xff, 0xf0, 0x00, 0x66, 0x00, 0x00, 0x80, 
+-      0x48, 0x01, 0x69, 0xc0, 0x47, 0x70, 0xe7, 0xfd, 
+-      0x66, 0x00, 0x00, 0x80, 0x1c, 0x01, 0x48, 0x07, 
+-      0x68, 0x02, 0x4b, 0x07, 0x40, 0x1a, 0x60, 0x02, 
+-      0x23, 0x01, 0x05, 0x9b, 0x42, 0x99, 0xd1, 0x03, 
+-      0x48, 0x02, 0x68, 0x02, 0x43, 0x0a, 0x60, 0x02, 
+-      0x47, 0x70, 0x00, 0x00, 0x66, 0x00, 0x00, 0x2c, 
+-      0xff, 0xbf, 0xff, 0xff, 0x1c, 0x01, 0x20, 0x33, 
+-      0x06, 0x40, 0x67, 0x41, 0x47, 0x70, 0x1c, 0x01, 
+-      0x20, 0x33, 0x06, 0x40, 0x67, 0x81, 0x47, 0x70, 
+-      0xb5, 0x90, 0x4c, 0x21, 0x20, 0x01, 0x60, 0x20, 
+-      0xf0, 0x11, 0xfb, 0x6a, 0x48, 0x1f, 0x69, 0x84, 
+-      0x27, 0x00, 0x2f, 0x04, 0xd3, 0x04, 0xe0, 0x06, 
+-      0x1c, 0x78, 0x06, 0x07, 0x0e, 0x3f, 0xe7, 0xf8, 
+-      0x21, 0x00, 0xc4, 0x02, 0xe7, 0xf8, 0x20, 0x00, 
+-      0x49, 0x18, 0x69, 0x49, 0x60, 0x08, 0x20, 0x00, 
+-      0x49, 0x16, 0x69, 0x49, 0x60, 0x48, 0x20, 0x00, 
+-      0x49, 0x14, 0x69, 0x49, 0x60, 0x88, 0x20, 0x00, 
+-      0x49, 0x12, 0x69, 0x49, 0x60, 0xc8, 0x20, 0x00, 
+-      0x49, 0x10, 0x69, 0x49, 0x61, 0x08, 0x20, 0x00, 
+-      0x49, 0x0e, 0x69, 0x49, 0x61, 0x48, 0x20, 0x00, 
+-      0x49, 0x0c, 0x69, 0x49, 0x61, 0x88, 0x20, 0x00, 
+-      0x49, 0x0a, 0x69, 0x49, 0x61, 0xc8, 0x20, 0x00, 
+-      0x49, 0x08, 0x69, 0x49, 0x62, 0x08, 0x20, 0x00, 
+-      0x49, 0x06, 0x69, 0x49, 0x62, 0x48, 0x20, 0x18, 
+-      0x49, 0x04, 0x69, 0x49, 0x62, 0x88, 0x20, 0x00, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0xe7, 0xfb, 
+-      0x70, 0x00, 0x00, 0x38, 0x2e, 0x08, 0x1f, 0xa8, 
+-      0xb5, 0xff, 0x1c, 0x0f, 0xb0, 0x81, 0x9c, 0x01, 
+-      0x69, 0x20, 0x28, 0x08, 0xd1, 0x01, 0x08, 0x7f, 
+-      0x00, 0x7f, 0x6b, 0xa0, 0x9a, 0x03, 0x43, 0x50, 
+-      0x19, 0xc6, 0x69, 0x20, 0x00, 0x80, 0x49, 0x34, 
+-      0x58, 0x08, 0x23, 0x04, 0x40, 0x18, 0xd0, 0x00, 
+-      0x08, 0x76, 0x69, 0x20, 0x00, 0x80, 0x49, 0x31, 
+-      0x58, 0x08, 0x43, 0x70, 0x90, 0x00, 0x69, 0xa0, 
+-      0x99, 0x00, 0x09, 0x49, 0x18, 0x45, 0x6b, 0xe0, 
+-      0x28, 0x00, 0xd1, 0x02, 0x03, 0x28, 0x0b, 0x00, 
+-      0xe0, 0x01, 0x02, 0x28, 0x0a, 0x00, 0x1c, 0x05, 
+-      0xf0, 0x11, 0xfb, 0x08, 0xf0, 0x11, 0xfa, 0xe4, 
+-      0x48, 0x27, 0x69, 0x80, 0x68, 0x00, 0x08, 0xc0, 
+-      0x00, 0xc0, 0x49, 0x25, 0x69, 0x89, 0x60, 0x08, 
+-      0x07, 0x40, 0x48, 0x23, 0x69, 0x80, 0x68, 0x00, 
+-      0x01, 0x40, 0x09, 0x40, 0x49, 0x20, 0x69, 0x89, 
+-      0x60, 0x08, 0x6b, 0xe0, 0x49, 0x1e, 0x69, 0x89, 
+-      0x68, 0x09, 0x4b, 0x1e, 0x40, 0x19, 0x07, 0xc0, 
+-      0x0c, 0x80, 0x43, 0x08, 0x49, 0x1a, 0x69, 0x89, 
+-      0x60, 0x08, 0x04, 0x80, 0x0f, 0xc0, 0x1c, 0x21, 
+-      0x1c, 0x20, 0xf0, 0x00, 0xfe, 0x51, 0x48, 0x16, 
+-      0x69, 0xc0, 0x68, 0x00, 0x4b, 0x16, 0x40, 0x18, 
+-      0x02, 0x29, 0x0a, 0x09, 0x00, 0x89, 0x43, 0x08, 
+-      0x49, 0x11, 0x69, 0xc9, 0x60, 0x08, 0x01, 0x80, 
+-      0x48, 0x0f, 0x69, 0xc0, 0x68, 0x00, 0x01, 0x40, 
+-      0x09, 0x40, 0x99, 0x00, 0x06, 0xc9, 0x43, 0x08, 
+-      0x49, 0x0b, 0x69, 0xc9, 0x60, 0x08, 0x99, 0x04, 
+-      0x1c, 0x20, 0x22, 0x00, 0xf0, 0x00, 0xfe, 0xbc, 
+-      0xf0, 0x00, 0xff, 0x9d, 0xf0, 0x11, 0xfa, 0xda, 
+-      0x20, 0x00, 0xb0, 0x01, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb0, 0x01, 0xe7, 0xf9, 
+-      0x2e, 0x03, 0x3a, 0x04, 0x2e, 0x03, 0x3a, 0x54, 
+-      0x2e, 0x08, 0x1f, 0xa8, 0xff, 0xff, 0xdf, 0xff, 
+-      0xfc, 0x00, 0x00, 0x03, 0xb5, 0xff, 0x1c, 0x0f, 
+-      0xb0, 0x81, 0x9c, 0x01, 0x69, 0x20, 0x28, 0x08, 
+-      0xd1, 0x01, 0x08, 0x7f, 0x00, 0x7f, 0x6b, 0xa0, 
+-      0x9a, 0x03, 0x43, 0x50, 0x19, 0xc6, 0x69, 0x20, 
+-      0x00, 0x80, 0x49, 0x37, 0x58, 0x08, 0x23, 0x04, 
+-      0x40, 0x18, 0xd0, 0x00, 0x08, 0x76, 0x69, 0x20, 
+-      0x00, 0x80, 0x49, 0x34, 0x58, 0x08, 0x43, 0x70, 
+-      0x90, 0x00, 0x69, 0xa0, 0x99, 0x00, 0x09, 0x49, 
+-      0x18, 0x45, 0x6b, 0xe0, 0x28, 0x00, 0xd1, 0x02, 
+-      0x03, 0x28, 0x0b, 0x00, 0xe0, 0x01, 0x02, 0x28, 
+-      0x0a, 0x00, 0x1c, 0x05, 0xf0, 0x11, 0xfa, 0x86, 
+-      0xf0, 0x11, 0xfa, 0x62, 0x48, 0x2a, 0x69, 0x80, 
+-      0x68, 0x00, 0x08, 0xc0, 0x00, 0xc0, 0x23, 0x01, 
+-      0x43, 0x18, 0x49, 0x27, 0x69, 0x89, 0x60, 0x08, 
+-      0x07, 0x40, 0x6b, 0xe0, 0x49, 0x24, 0x69, 0x89, 
+-      0x68, 0x09, 0x4b, 0x24, 0x40, 0x19, 0x07, 0xc0, 
+-      0x0c, 0x80, 0x43, 0x08, 0x49, 0x20, 0x69, 0x89, 
+-      0x60, 0x08, 0x04, 0x80, 0x0f, 0xc0, 0x48, 0x1e, 
+-      0x69, 0x80, 0x68, 0x00, 0x01, 0x40, 0x09, 0x40, 
+-      0x99, 0x00, 0x06, 0xc9, 0x43, 0x01, 0x48, 0x1a, 
+-      0x69, 0x80, 0x60, 0x01, 0x1c, 0x21, 0x1c, 0x20, 
+-      0xf0, 0x00, 0xfd, 0xca, 0x48, 0x16, 0x69, 0xc0, 
+-      0x68, 0x00, 0x4b, 0x17, 0x40, 0x18, 0x02, 0x29, 
+-      0x0a, 0x09, 0x00, 0x89, 0x43, 0x08, 0x49, 0x12, 
+-      0x69, 0xc9, 0x60, 0x08, 0x01, 0x80, 0x48, 0x10, 
+-      0x69, 0xc0, 0x68, 0x00, 0x01, 0x40, 0x09, 0x40, 
+-      0x49, 0x0d, 0x69, 0xc9, 0x60, 0x08, 0xf0, 0x00, 
+-      0xff, 0x1e, 0xf0, 0x11, 0xfa, 0x39, 0x48, 0x0a, 
+-      0x6b, 0x81, 0x1c, 0x20, 0xf0, 0x00, 0xfe, 0xf0, 
+-      0x9b, 0x04, 0x60, 0x18, 0xf0, 0x11, 0xfa, 0x52, 
+-      0x20, 0x00, 0xb0, 0x01, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb0, 0x01, 0xe7, 0xf9, 
+-      0x2e, 0x03, 0x3a, 0x04, 0x2e, 0x03, 0x3a, 0x54, 
+-      0x2e, 0x08, 0x1f, 0xa8, 0xff, 0xff, 0xdf, 0xff, 
+-      0xfc, 0x00, 0x00, 0x03, 0xb5, 0xff, 0x1c, 0x0c, 
+-      0x1c, 0x1f, 0xb0, 0x83, 0x9d, 0x03, 0x6b, 0x28, 
+-      0x6a, 0xa9, 0x1a, 0x40, 0x30, 0x01, 0x90, 0x00, 
+-      0x19, 0xe0, 0x99, 0x00, 0x42, 0x88, 0xd9, 0x01, 
+-      0x98, 0x00, 0x1b, 0x07, 0x69, 0x28, 0x28, 0x08, 
+-      0xd1, 0x02, 0x08, 0x7f, 0x08, 0x64, 0x00, 0x64, 
+-      0x6b, 0xa8, 0x9a, 0x05, 0x43, 0x50, 0x19, 0x01, 
+-      0x91, 0x01, 0x69, 0x28, 0x00, 0x80, 0x49, 0x38, 
+-      0x58, 0x08, 0x23, 0x04, 0x40, 0x18, 0xd0, 0x02, 
+-      0x99, 0x01, 0x08, 0x49, 0x91, 0x01, 0x69, 0x28, 
+-      0x00, 0x80, 0x49, 0x34, 0x58, 0x08, 0x99, 0x01, 
+-      0x43, 0x48, 0x90, 0x02, 0x69, 0xa8, 0x99, 0x02, 
+-      0x09, 0x49, 0x18, 0x46, 0x6b, 0xe8, 0x28, 0x00, 
+-      0xd1, 0x02, 0x03, 0x30, 0x0b, 0x00, 0xe0, 0x01, 
+-      0x02, 0x30, 0x0a, 0x00, 0x1c, 0x06, 0xf0, 0x11, 
+-      0xf9, 0xed, 0xf0, 0x11, 0xf9, 0xc9, 0x48, 0x2a, 
+-      0x69, 0x80, 0x68, 0x00, 0x01, 0x40, 0x09, 0x40, 
+-      0x49, 0x27, 0x69, 0x89, 0x60, 0x08, 0x48, 0x26, 
+-      0x69, 0x80, 0x68, 0x00, 0x08, 0xc0, 0x00, 0xc0, 
+-      0x23, 0x02, 0x43, 0x18, 0x49, 0x22, 0x69, 0x89, 
+-      0x60, 0x08, 0x07, 0x40, 0x6b, 0xe8, 0x49, 0x20, 
+-      0x69, 0x89, 0x68, 0x09, 0x4b, 0x1f, 0x40, 0x19, 
+-      0x07, 0xc0, 0x0c, 0x80, 0x43, 0x08, 0x49, 0x1c, 
+-      0x69, 0x89, 0x60, 0x08, 0x04, 0x80, 0x0f, 0xc0, 
+-      0x1c, 0x29, 0x1c, 0x28, 0xf0, 0x00, 0xfd, 0x34, 
+-      0x48, 0x17, 0x69, 0xc0, 0x68, 0x00, 0x4b, 0x18, 
+-      0x40, 0x18, 0x02, 0x31, 0x0a, 0x09, 0x00, 0x89, 
+-      0x43, 0x08, 0x49, 0x13, 0x69, 0xc9, 0x60, 0x08, 
+-      0x01, 0x80, 0x48, 0x11, 0x69, 0xc0, 0x68, 0x00, 
+-      0x01, 0x40, 0x09, 0x40, 0x99, 0x02, 0x06, 0xc9, 
+-      0x43, 0x08, 0x49, 0x0d, 0x69, 0xc9, 0x60, 0x08, 
+-      0x99, 0x0c, 0x1c, 0x28, 0x22, 0x02, 0xf0, 0x00, 
+-      0xfd, 0x9f, 0x48, 0x09, 0x69, 0x40, 0x62, 0x07, 
+-      0xf0, 0x00, 0xfe, 0x7d, 0xf0, 0x11, 0xf9, 0xba, 
+-      0x20, 0x00, 0xb0, 0x03, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb0, 0x03, 0xe7, 0xf9, 
+-      0x2e, 0x03, 0x3a, 0x04, 0x2e, 0x03, 0x3a, 0x54, 
+-      0x2e, 0x08, 0x1f, 0xa8, 0xff, 0xff, 0xdf, 0xff, 
+-      0xfc, 0x00, 0x00, 0x03, 0xb5, 0xff, 0xb0, 0x81, 
+-      0x9f, 0x01, 0x6b, 0x78, 0x6a, 0xf9, 0x1a, 0x40, 
+-      0x30, 0x01, 0x90, 0x00, 0x9a, 0x03, 0x9b, 0x04, 
+-      0x18, 0xd0, 0x99, 0x00, 0x42, 0x88, 0xd9, 0x03, 
+-      0x98, 0x00, 0x9a, 0x03, 0x1a, 0x83, 0x93, 0x04, 
+-      0x69, 0x38, 0x28, 0x08, 0xd1, 0x03, 0x99, 0x02, 
+-      0x08, 0x49, 0x00, 0x49, 0x91, 0x02, 0x6b, 0xb8, 
+-      0x9a, 0x03, 0x43, 0x50, 0x99, 0x02, 0x18, 0x45, 
+-      0x69, 0x38, 0x00, 0x80, 0x49, 0x3c, 0x58, 0x08, 
+-      0x23, 0x04, 0x40, 0x18, 0xd0, 0x00, 0x08, 0x6d, 
+-      0x69, 0x38, 0x00, 0x80, 0x49, 0x39, 0x58, 0x08, 
+-      0x1c, 0x06, 0x43, 0x6e, 0x69, 0xb8, 0x09, 0x71, 
+-      0x18, 0x44, 0x6b, 0xf8, 0x28, 0x00, 0xd1, 0x02, 
+-      0x03, 0x20, 0x0b, 0x00, 0xe0, 0x01, 0x02, 0x20, 
+-      0x0a, 0x00, 0x1c, 0x04, 0xf0, 0x11, 0xf9, 0x56, 
+-      0xf0, 0x11, 0xf9, 0x32, 0x48, 0x30, 0x69, 0x80, 
+-      0x68, 0x00, 0x01, 0x40, 0x09, 0x40, 0x49, 0x2e, 
+-      0x69, 0x89, 0x60, 0x08, 0x48, 0x2c, 0x69, 0x80, 
+-      0x68, 0x00, 0x08, 0xc0, 0x00, 0xc0, 0x23, 0x03, 
+-      0x43, 0x18, 0x49, 0x29, 0x69, 0x89, 0x60, 0x08, 
+-      0x07, 0x40, 0x6b, 0xf8, 0x49, 0x26, 0x69, 0x89, 
+-      0x68, 0x09, 0x4b, 0x26, 0x40, 0x19, 0x07, 0xc0, 
+-      0x0c, 0x80, 0x43, 0x08, 0x49, 0x22, 0x69, 0x89, 
+-      0x60, 0x08, 0x04, 0x80, 0x0f, 0xc0, 0x1c, 0x39, 
+-      0x1c, 0x38, 0xf0, 0x00, 0xfc, 0x9d, 0x99, 0x0a, 
+-      0x1c, 0x38, 0x22, 0x03, 0xf0, 0x00, 0xfd, 0x20, 
+-      0x69, 0xf8, 0x49, 0x1b, 0x69, 0x49, 0x61, 0x08, 
+-      0x48, 0x19, 0x69, 0xc0, 0x68, 0x00, 0x4b, 0x1a, 
+-      0x40, 0x18, 0x02, 0x21, 0x0a, 0x09, 0x00, 0x89, 
+-      0x43, 0x08, 0x49, 0x15, 0x69, 0xc9, 0x60, 0x08, 
+-      0x01, 0x80, 0x48, 0x13, 0x69, 0xc0, 0x68, 0x00, 
+-      0x01, 0x40, 0x09, 0x40, 0x06, 0xf1, 0x43, 0x08, 
+-      0x49, 0x0f, 0x69, 0xc9, 0x60, 0x08, 0x48, 0x0e, 
+-      0x69, 0x40, 0x61, 0x84, 0x06, 0xf0, 0x0e, 0xc0, 
+-      0x49, 0x0b, 0x69, 0x49, 0x61, 0x48, 0x9b, 0x04, 
+-      0x48, 0x09, 0x69, 0x40, 0x62, 0x43, 0xf0, 0x00, 
+-      0xfd, 0xda, 0xf0, 0x11, 0xf9, 0x17, 0x20, 0x00, 
+-      0xb0, 0x01, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb0, 0x01, 0xe7, 0xf9, 0x00, 0x00, 
+-      0x2e, 0x03, 0x3a, 0x04, 0x2e, 0x03, 0x3a, 0x54, 
+-      0x2e, 0x08, 0x1f, 0xa8, 0xff, 0xff, 0xdf, 0xff, 
+-      0xfc, 0x00, 0x00, 0x03, 0xb5, 0xf3, 0xb0, 0x86, 
+-      0x9f, 0x06, 0x99, 0x07, 0x68, 0x8c, 0x99, 0x07, 
+-      0x68, 0xc8, 0x90, 0x03, 0x99, 0x07, 0x68, 0x0d, 
+-      0x99, 0x07, 0x68, 0x49, 0x91, 0x02, 0x6b, 0x78, 
+-      0x6a, 0xf9, 0x1a, 0x40, 0x30, 0x01, 0x90, 0x01, 
+-      0x6b, 0x38, 0x6a, 0xb9, 0x1a, 0x40, 0x30, 0x01, 
+-      0x90, 0x00, 0x99, 0x02, 0x98, 0x03, 0x18, 0x08, 
+-      0x99, 0x01, 0x42, 0x88, 0xd9, 0x03, 0x98, 0x01, 
+-      0x99, 0x02, 0x1a, 0x40, 0x90, 0x03, 0x19, 0x28, 
+-      0x99, 0x00, 0x42, 0x88, 0xd9, 0x01, 0x98, 0x00, 
+-      0x1b, 0x44, 0x69, 0x38, 0x28, 0x08, 0xd1, 0x02, 
+-      0x08, 0x64, 0x08, 0x6d, 0x00, 0x6d, 0x6b, 0xb8, 
+-      0x99, 0x02, 0x43, 0x48, 0x19, 0x41, 0x91, 0x04, 
+-      0x69, 0x38, 0x00, 0x80, 0x49, 0x41, 0x58, 0x08, 
+-      0x23, 0x04, 0x40, 0x18, 0xd0, 0x02, 0x99, 0x04, 
+-      0x08, 0x49, 0x91, 0x04, 0x69, 0x38, 0x00, 0x80, 
+-      0x49, 0x3d, 0x58, 0x08, 0x99, 0x04, 0x43, 0x48, 
+-      0x90, 0x05, 0x69, 0xb8, 0x99, 0x05, 0x09, 0x49, 
+-      0x18, 0x46, 0x6b, 0xf8, 0x28, 0x00, 0xd1, 0x02, 
+-      0x03, 0x30, 0x0b, 0x00, 0xe0, 0x01, 0x02, 0x30, 
+-      0x0a, 0x00, 0x1c, 0x06, 0xf0, 0x11, 0xf8, 0x9a, 
+-      0xf0, 0x11, 0xf8, 0x76, 0x48, 0x33, 0x69, 0x80, 
+-      0x68, 0x00, 0x01, 0x40, 0x09, 0x40, 0x49, 0x31, 
+-      0x69, 0x89, 0x60, 0x08, 0x48, 0x2f, 0x69, 0x80, 
+-      0x68, 0x00, 0x08, 0xc0, 0x00, 0xc0, 0x23, 0x04, 
+-      0x43, 0x18, 0x49, 0x2c, 0x69, 0x89, 0x60, 0x08, 
+-      0x07, 0x40, 0x48, 0x2a, 0x69, 0xc0, 0x68, 0x00, 
+-      0x01, 0x40, 0x09, 0x40, 0x99, 0x05, 0x06, 0xc9, 
+-      0x43, 0x08, 0x49, 0x26, 0x69, 0xc9, 0x60, 0x08, 
+-      0x48, 0x24, 0x69, 0xc0, 0x68, 0x00, 0x4b, 0x24, 
+-      0x40, 0x18, 0x02, 0x31, 0x0a, 0x09, 0x00, 0x89, 
+-      0x43, 0x08, 0x49, 0x20, 0x69, 0xc9, 0x60, 0x08, 
+-      0x01, 0x80, 0x1c, 0x39, 0x1c, 0x38, 0xf0, 0x00, 
+-      0xfb, 0xd7, 0x6b, 0xf8, 0x49, 0x1b, 0x69, 0x89, 
+-      0x68, 0x09, 0x4b, 0x1c, 0x40, 0x19, 0x07, 0xc0, 
+-      0x0c, 0x80, 0x43, 0x08, 0x49, 0x17, 0x69, 0x89, 
+-      0x60, 0x08, 0x04, 0x80, 0x0f, 0xc0, 0x99, 0x07, 
+-      0x69, 0x09, 0x1c, 0x38, 0x22, 0x04, 0xf0, 0x00, 
+-      0xfc, 0x4b, 0x69, 0xf8, 0x49, 0x11, 0x69, 0x49, 
+-      0x61, 0x08, 0x98, 0x05, 0x06, 0xc0, 0x0e, 0xc0, 
+-      0x49, 0x0e, 0x69, 0x49, 0x61, 0x48, 0x48, 0x0d, 
+-      0x69, 0x40, 0x61, 0x86, 0x48, 0x0b, 0x69, 0x40, 
+-      0x62, 0x04, 0x98, 0x03, 0x49, 0x09, 0x69, 0x49, 
+-      0x62, 0x48, 0xf0, 0x00, 0xfd, 0x18, 0xf0, 0x11, 
+-      0xf8, 0x55, 0x20, 0x00, 0xb0, 0x06, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0xb0, 0x06, 
+-      0xe7, 0xf9, 0x00, 0x00, 0x2e, 0x03, 0x3a, 0x04, 
+-      0x2e, 0x03, 0x3a, 0x54, 0x2e, 0x08, 0x1f, 0xa8, 
+-      0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xdf, 0xff, 
+-      0xb5, 0xff, 0x9d, 0x09, 0xb0, 0x81, 0x98, 0x0b, 
+-      0x06, 0x02, 0x0e, 0x12, 0x92, 0x00, 0xb0, 0x93, 
+-      0x98, 0x14, 0x90, 0x12, 0x99, 0x15, 0x91, 0x11, 
+-      0xaf, 0x0c, 0x1c, 0x38, 0x9a, 0x16, 0xca, 0x5e, 
+-      0xc0, 0x5e, 0x68, 0x39, 0x91, 0x04, 0x68, 0x79, 
+-      0x91, 0x03, 0x98, 0x12, 0x99, 0x11, 0x42, 0x88, 
+-      0xd1, 0x73, 0x99, 0x03, 0x42, 0x8d, 0xd9, 0x71, 
+-      0x68, 0xb8, 0x90, 0x01, 0x68, 0xf8, 0x90, 0x02, 
+-      0x99, 0x11, 0x6b, 0x48, 0x6a, 0xc9, 0x1a, 0x40, 
+-      0x1c, 0x44, 0x99, 0x11, 0x6b, 0x08, 0x6a, 0x89, 
+-      0x1a, 0x40, 0x30, 0x01, 0x90, 0x00, 0x98, 0x02, 
+-      0x18, 0x28, 0x42, 0xa0, 0xd9, 0x01, 0x1b, 0x61, 
+-      0x91, 0x02, 0x9b, 0x17, 0x98, 0x01, 0x18, 0x18, 
+-      0x99, 0x00, 0x42, 0x88, 0xd9, 0x03, 0x98, 0x00, 
+-      0x9b, 0x17, 0x1a, 0xc0, 0x90, 0x01, 0x98, 0x01, 
+-      0x60, 0xb8, 0x98, 0x02, 0x60, 0xf8, 0x98, 0x12, 
+-      0x69, 0xc0, 0x90, 0x0a, 0x98, 0x12, 0x6b, 0x80, 
+-      0x99, 0x03, 0x43, 0x48, 0x99, 0x04, 0x18, 0x41, 
+-      0x91, 0x05, 0x98, 0x12, 0x69, 0x00, 0x00, 0x80, 
+-      0x49, 0x48, 0x58, 0x08, 0x99, 0x05, 0x43, 0x48, 
+-      0x90, 0x0b, 0x98, 0x12, 0x69, 0x80, 0x99, 0x0b, 
+-      0x09, 0x49, 0x18, 0x41, 0x91, 0x07, 0x98, 0x0a, 
+-      0x99, 0x02, 0x43, 0x48, 0x90, 0x0b, 0x98, 0x0b, 
+-      0x09, 0x40, 0x99, 0x07, 0x18, 0x40, 0x90, 0x06, 
+-      0x98, 0x06, 0x0b, 0xc0, 0x99, 0x07, 0x0b, 0xc9, 
+-      0x1a, 0x40, 0x90, 0x09, 0x98, 0x09, 0x28, 0x00, 
+-      0xd0, 0x56, 0x9e, 0x02, 0x98, 0x06, 0x04, 0x40, 
+-      0x0c, 0x40, 0x01, 0x41, 0x91, 0x08, 0x99, 0x08, 
+-      0x98, 0x0a, 0xf0, 0x04, 0xf9, 0x17, 0x1c, 0x04, 
+-      0x2c, 0x00, 0xd1, 0x00, 0x34, 0x01, 0x99, 0x03, 
+-      0x98, 0x02, 0x18, 0x08, 0x1b, 0x00, 0x60, 0x78, 
+-      0x60, 0xfc, 0x98, 0x02, 0x18, 0x28, 0x1b, 0x05, 
+-      0x9a, 0x13, 0x1c, 0x29, 0xb4, 0x06, 0x9b, 0x19, 
+-      0x1c, 0x3a, 0x99, 0x17, 0x98, 0x16, 0xf0, 0x00, 
+-      0xf8, 0x57, 0xb0, 0x02, 0x1b, 0x36, 0x98, 0x09, 
+-      0xe0, 0x01, 0xe0, 0x3c, 0xe0, 0x3b, 0x38, 0x01, 
+-      0x90, 0x09, 0x98, 0x09, 0x28, 0x00, 0xd0, 0x1a, 
+-      0x98, 0x0a, 0x21, 0x01, 0x03, 0x09, 0xf0, 0x04, 
+-      0xf8, 0xf1, 0x1c, 0x04, 0x68, 0x78, 0x1b, 0x80, 
+-      0x60, 0x78, 0x60, 0xfc, 0x68, 0xf8, 0x1a, 0x2d, 
+-      0x9a, 0x13, 0x1c, 0x29, 0xb4, 0x06, 0x9b, 0x19, 
+-      0x1c, 0x3a, 0x99, 0x17, 0x98, 0x16, 0xf0, 0x00, 
+-      0xf8, 0x37, 0xb0, 0x02, 0x1b, 0x36, 0x98, 0x09, 
+-      0x38, 0x01, 0x90, 0x09, 0xe7, 0xe1, 0x68, 0x78, 
+-      0x1b, 0x80, 0x60, 0x78, 0x60, 0xfe, 0x68, 0xf8, 
+-      0x1a, 0x2d, 0x9a, 0x13, 0x1c, 0x29, 0xb4, 0x06, 
+-      0x9b, 0x19, 0x1c, 0x3a, 0x99, 0x17, 0x98, 0x16, 
+-      0xf0, 0x00, 0xf8, 0x22, 0xb0, 0x02, 0xe0, 0x09, 
+-      0x9a, 0x13, 0x1c, 0x29, 0xb4, 0x06, 0x9b, 0x19, 
+-      0x1c, 0x3a, 0x99, 0x17, 0x98, 0x16, 0xf0, 0x00, 
+-      0xf8, 0x17, 0xb0, 0x02, 0xe0, 0x09, 0x9a, 0x13, 
+-      0x1c, 0x29, 0xb4, 0x06, 0x9b, 0x19, 0x1c, 0x3a, 
+-      0x99, 0x17, 0x98, 0x16, 0xf0, 0x00, 0xf8, 0xb8, 
+-      0xb0, 0x02, 0x20, 0x00, 0xb0, 0x14, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0xb0, 0x13, 
+-      0xb0, 0x01, 0xe7, 0xf8, 0x2e, 0x03, 0x3a, 0x54, 
+-      0xb5, 0xff, 0x9d, 0x09, 0xb0, 0x81, 0x98, 0x0b, 
+-      0x06, 0x02, 0x0e, 0x12, 0x92, 0x00, 0xb0, 0x92, 
+-      0x98, 0x13, 0x90, 0x11, 0x99, 0x14, 0x91, 0x10, 
+-      0xaf, 0x0b, 0x1c, 0x38, 0x9a, 0x15, 0xca, 0x5e, 
+-      0xc0, 0x5e, 0x68, 0x38, 0x90, 0x03, 0x68, 0x78, 
+-      0x90, 0x02, 0x68, 0xb8, 0x90, 0x00, 0x68, 0xf9, 
+-      0x91, 0x01, 0x98, 0x11, 0x69, 0xc0, 0x90, 0x09, 
+-      0x99, 0x10, 0x6b, 0x88, 0x43, 0x68, 0x9b, 0x16, 
+-      0x18, 0xc1, 0x91, 0x04, 0x99, 0x10, 0x69, 0x08, 
+-      0x00, 0x80, 0x49, 0x42, 0x58, 0x08, 0x99, 0x04, 
+-      0x43, 0x48, 0x90, 0x0a, 0x99, 0x10, 0x69, 0x88, 
+-      0x99, 0x0a, 0x09, 0x49, 0x18, 0x40, 0x90, 0x06, 
+-      0x98, 0x09, 0x99, 0x01, 0x43, 0x48, 0x90, 0x0a, 
+-      0x98, 0x0a, 0x09, 0x40, 0x99, 0x06, 0x18, 0x40, 
+-      0x90, 0x05, 0x98, 0x05, 0x0b, 0xc0, 0x99, 0x06, 
+-      0x0b, 0xc9, 0x1a, 0x40, 0x90, 0x08, 0x98, 0x08, 
+-      0x28, 0x00, 0xd0, 0x53, 0x9e, 0x01, 0x98, 0x05, 
+-      0x04, 0x40, 0x0c, 0x40, 0x01, 0x41, 0x91, 0x07, 
+-      0x99, 0x07, 0x98, 0x09, 0xf0, 0x04, 0xf8, 0x5e, 
+-      0x1c, 0x04, 0x2c, 0x00, 0xd1, 0x00, 0x34, 0x01, 
+-      0x98, 0x02, 0x99, 0x01, 0x18, 0x40, 0x1b, 0x00, 
+-      0x60, 0x78, 0x60, 0xfc, 0x99, 0x01, 0x18, 0x68, 
+-      0x1b, 0x05, 0x9a, 0x12, 0x1c, 0x29, 0xb4, 0x06, 
+-      0x9b, 0x18, 0x1c, 0x3a, 0x99, 0x16, 0x98, 0x15, 
+-      0xf0, 0x00, 0xf8, 0x4a, 0xb0, 0x02, 0x1b, 0x36, 
+-      0x98, 0x08, 0x38, 0x01, 0x90, 0x08, 0x98, 0x08, 
+-      0x28, 0x00, 0xd0, 0x1a, 0x98, 0x09, 0x21, 0x01, 
+-      0x03, 0x09, 0xf0, 0x04, 0xf8, 0x3b, 0x1c, 0x04, 
+-      0x68, 0x78, 0x1b, 0x80, 0x60, 0x78, 0x60, 0xfc, 
+-      0x68, 0xf8, 0x1a, 0x2d, 0x9a, 0x12, 0x1c, 0x29, 
+-      0xb4, 0x06, 0x9b, 0x18, 0x1c, 0x3a, 0x99, 0x16, 
+-      0x98, 0x15, 0xf0, 0x00, 0xf8, 0x2d, 0xb0, 0x02, 
+-      0x1b, 0x36, 0x98, 0x08, 0x38, 0x01, 0x90, 0x08, 
+-      0xe7, 0xe1, 0x68, 0x78, 0x1b, 0x80, 0x60, 0x78, 
+-      0x60, 0xfe, 0x68, 0xf8, 0x1a, 0x2d, 0x9a, 0x12, 
+-      0x1c, 0x29, 0xb4, 0x06, 0x9b, 0x18, 0x1c, 0x3a, 
+-      0x99, 0x16, 0x98, 0x15, 0xf0, 0x00, 0xf8, 0x18, 
+-      0xb0, 0x02, 0xe0, 0x09, 0x9a, 0x12, 0x1c, 0x29, 
+-      0xb4, 0x06, 0x9b, 0x18, 0x1c, 0x3a, 0x99, 0x16, 
+-      0x98, 0x15, 0xf0, 0x00, 0xf8, 0x0d, 0xb0, 0x02, 
+-      0x20, 0x00, 0xb0, 0x13, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb0, 0x12, 0xb0, 0x01, 
+-      0xe7, 0xf8, 0x00, 0x00, 0x2e, 0x03, 0x3a, 0x54, 
+-      0xb5, 0xff, 0xb0, 0x81, 0x98, 0x0b, 0x06, 0x02, 
+-      0x0e, 0x12, 0x92, 0x00, 0xb0, 0x8e, 0x9f, 0x0f, 
+-      0x9c, 0x10, 0x9a, 0x11, 0x68, 0x10, 0x90, 0x07, 
+-      0x9a, 0x11, 0x68, 0x50, 0x90, 0x06, 0x9a, 0x11, 
+-      0x68, 0x91, 0x91, 0x08, 0x9a, 0x11, 0x68, 0xd0, 
+-      0x90, 0x09, 0x6b, 0x60, 0x6a, 0xe1, 0x1a, 0x40, 
+-      0x30, 0x01, 0x90, 0x01, 0x6b, 0x20, 0x6a, 0xa1, 
+-      0x1a, 0x40, 0x30, 0x01, 0x90, 0x00, 0x99, 0x18, 
+-      0x98, 0x09, 0x18, 0x08, 0x99, 0x01, 0x42, 0x88, 
+-      0xd9, 0x03, 0x98, 0x01, 0x99, 0x18, 0x1a, 0x41, 
+-      0x91, 0x09, 0x9b, 0x12, 0x99, 0x08, 0x18, 0x58, 
+-      0x99, 0x00, 0x42, 0x88, 0xd9, 0x03, 0x98, 0x00, 
+-      0x9b, 0x12, 0x1a, 0xc1, 0x91, 0x08, 0x22, 0x00, 
+-      0x92, 0x05, 0x42, 0xa7, 0xd1, 0x20, 0x99, 0x18, 
+-      0x98, 0x06, 0x42, 0x81, 0xd9, 0x0c, 0x22, 0x02, 
+-      0x92, 0x05, 0x99, 0x06, 0x98, 0x09, 0x18, 0x08, 
+-      0x1e, 0x41, 0x91, 0x06, 0x99, 0x18, 0x98, 0x09, 
+-      0x18, 0x08, 0x1e, 0x41, 0x91, 0x18, 0xe0, 0x0f, 
+-      0x9b, 0x12, 0x98, 0x07, 0x42, 0x83, 0xd9, 0x0b, 
+-      0x22, 0x01, 0x92, 0x05, 0x98, 0x07, 0x99, 0x08, 
+-      0x18, 0x40, 0x38, 0x01, 0x90, 0x07, 0x9b, 0x12, 
+-      0x99, 0x08, 0x18, 0x58, 0x1e, 0x43, 0x93, 0x12, 
+-      0x69, 0x38, 0x28, 0x08, 0xd1, 0x0a, 0x99, 0x08, 
+-      0x08, 0x49, 0x91, 0x08, 0x98, 0x07, 0x08, 0x40, 
+-      0x00, 0x40, 0x90, 0x07, 0x9b, 0x12, 0x08, 0x5b, 
+-      0x00, 0x5b, 0x93, 0x12, 0x69, 0x38, 0x00, 0x80, 
+-      0x49, 0xc6, 0x58, 0x08, 0x23, 0x04, 0x40, 0x18, 
+-      0x08, 0x80, 0x90, 0x03, 0x69, 0x20, 0x00, 0x80, 
+-      0x49, 0xc2, 0x58, 0x08, 0x23, 0x04, 0x40, 0x18, 
+-      0x08, 0x80, 0x90, 0x02, 0x6b, 0xb8, 0x99, 0x06, 
+-      0x43, 0x48, 0x99, 0x07, 0x18, 0x41, 0x91, 0x04, 
+-      0x98, 0x03, 0x28, 0x00, 0xd0, 0x02, 0x99, 0x04, 
+-      0x08, 0x49, 0x91, 0x04, 0x69, 0x38, 0x00, 0x80, 
+-      0x49, 0xb9, 0x58, 0x08, 0x99, 0x04, 0x1c, 0x06, 
+-      0x43, 0x4e, 0x6b, 0xa0, 0x99, 0x18, 0x43, 0x48, 
+-      0x9b, 0x12, 0x18, 0xc1, 0x91, 0x04, 0x98, 0x02, 
+-      0x28, 0x00, 0xd0, 0x02, 0x99, 0x04, 0x08, 0x49, 
+-      0x91, 0x04, 0x69, 0x20, 0x00, 0x80, 0x49, 0xb0, 
+-      0x58, 0x08, 0x99, 0x04, 0x1c, 0x05, 0x43, 0x4d, 
+-      0x9a, 0x05, 0x2a, 0x01, 0xd1, 0x3d, 0x69, 0x38, 
+-      0x28, 0x08, 0xd0, 0x3a, 0x69, 0x38, 0x28, 0x09, 
+-      0xd0, 0x02, 0x69, 0x38, 0x28, 0x0a, 0xd1, 0x0a, 
+-      0x36, 0x10, 0x69, 0xb8, 0x09, 0x71, 0x18, 0x41, 
+-      0x91, 0x0b, 0x06, 0xf0, 0x0e, 0xc0, 0x1d, 0xc1, 
+-      0x31, 0x01, 0x91, 0x0a, 0xe0, 0x0b, 0x69, 0xb8, 
+-      0x09, 0x71, 0x18, 0x41, 0x91, 0x0b, 0x69, 0x38, 
+-      0x00, 0x80, 0x49, 0x9f, 0x58, 0x08, 0x19, 0x86, 
+-      0x06, 0xf1, 0x0e, 0xc9, 0x91, 0x0a, 0x69, 0x20, 
+-      0x28, 0x09, 0xd0, 0x02, 0x69, 0x20, 0x28, 0x0a, 
+-      0xd1, 0x0a, 0x35, 0x10, 0x69, 0xa0, 0x09, 0x69, 
+-      0x18, 0x41, 0x91, 0x0d, 0x06, 0xe8, 0x0e, 0xc0, 
+-      0x1d, 0xc1, 0x31, 0x01, 0x91, 0x0c, 0xe0, 0x0b, 
+-      0x69, 0xa0, 0x09, 0x69, 0x18, 0x41, 0x91, 0x0d, 
+-      0x69, 0x20, 0x00, 0x80, 0x49, 0x90, 0x58, 0x08, 
+-      0x19, 0x45, 0x06, 0xe9, 0x0e, 0xc9, 0x91, 0x0c, 
+-      0xe0, 0x0d, 0x69, 0xb8, 0x09, 0x71, 0x18, 0x41, 
+-      0x91, 0x0b, 0x69, 0xa0, 0x09, 0x69, 0x18, 0x41, 
+-      0x91, 0x0d, 0x06, 0xf1, 0x0e, 0xc9, 0x91, 0x0a, 
+-      0x06, 0xe9, 0x0e, 0xc9, 0x91, 0x0c, 0x6b, 0xf8, 
+-      0x28, 0x00, 0xd1, 0x03, 0x99, 0x0b, 0x03, 0x09, 
+-      0x0b, 0x09, 0xe0, 0x02, 0x99, 0x0b, 0x02, 0x09, 
+-      0x0a, 0x09, 0x91, 0x0b, 0x6b, 0xe0, 0x28, 0x00, 
+-      0xd1, 0x03, 0x99, 0x0d, 0x03, 0x09, 0x0b, 0x09, 
+-      0xe0, 0x02, 0x99, 0x0d, 0x02, 0x09, 0x0a, 0x09, 
+-      0x91, 0x0d, 0xf0, 0x10, 0xfd, 0x9b, 0xf0, 0x10, 
+-      0xfd, 0x77, 0x48, 0x7a, 0x69, 0x80, 0x68, 0x00, 
+-      0x08, 0xc0, 0x00, 0xc0, 0x23, 0x05, 0x43, 0x18, 
+-      0x49, 0x76, 0x69, 0x89, 0x60, 0x08, 0x07, 0x40, 
+-      0x1c, 0x21, 0x1c, 0x38, 0xf0, 0x00, 0xf8, 0xf8, 
+-      0x98, 0x03, 0x28, 0x00, 0xd0, 0x18, 0x98, 0x02, 
+-      0x28, 0x00, 0xd0, 0x15, 0x48, 0x6f, 0x69, 0x80, 
+-      0x68, 0x00, 0x23, 0x08, 0x43, 0xdb, 0x40, 0x18, 
+-      0x49, 0x6c, 0x69, 0x89, 0x60, 0x08, 0x07, 0x00, 
+-      0x48, 0x6a, 0x69, 0x80, 0x68, 0x00, 0x4b, 0x6a, 
+-      0x40, 0x18, 0x49, 0x68, 0x69, 0x89, 0x60, 0x08, 
+-      0x05, 0xc0, 0x99, 0x08, 0x08, 0x49, 0x91, 0x08, 
+-      0x6b, 0xf8, 0x49, 0x64, 0x69, 0x89, 0x68, 0x09, 
+-      0x4b, 0x64, 0x40, 0x19, 0x07, 0xc0, 0x0c, 0x40, 
+-      0x43, 0x08, 0x49, 0x60, 0x69, 0x89, 0x60, 0x08, 
+-      0x04, 0x40, 0x0f, 0xc0, 0x6b, 0xe0, 0x49, 0x5d, 
+-      0x69, 0x89, 0x68, 0x09, 0x4b, 0x5e, 0x40, 0x19, 
+-      0x07, 0xc0, 0x0c, 0x80, 0x43, 0x08, 0x49, 0x59, 
+-      0x69, 0x89, 0x60, 0x08, 0x04, 0x80, 0x0f, 0xc0, 
+-      0x68, 0x38, 0x28, 0x00, 0xd0, 0x0d, 0x79, 0x38, 
+-      0x49, 0x54, 0x69, 0x89, 0x68, 0x09, 0x4b, 0x57, 
+-      0x40, 0x19, 0x03, 0xc0, 0x43, 0x08, 0x49, 0x51, 
+-      0x69, 0x89, 0x60, 0x08, 0x02, 0x40, 0x0e, 0x00, 
+-      0xe0, 0x0d, 0x6a, 0x78, 0x78, 0x00, 0x49, 0x4d, 
+-      0x69, 0x89, 0x68, 0x09, 0x4b, 0x4f, 0x40, 0x19, 
+-      0x03, 0xc0, 0x43, 0x08, 0x49, 0x49, 0x69, 0x89, 
+-      0x60, 0x08, 0x02, 0x40, 0x0e, 0x00, 0x69, 0x20, 
+-      0x00, 0x80, 0x49, 0x45, 0x58, 0x08, 0x99, 0x08, 
+-      0x43, 0x48, 0x28, 0x40, 0xd9, 0x01, 0x21, 0x00, 
+-      0xe0, 0x00, 0x21, 0x01, 0x1c, 0x08, 0x49, 0x41, 
+-      0x69, 0x89, 0x68, 0x09, 0x4b, 0x44, 0x40, 0x19, 
+-      0x07, 0xc2, 0x09, 0x52, 0x43, 0x11, 0x4a, 0x3d, 
+-      0x69, 0x92, 0x60, 0x11, 0x01, 0x49, 0x0f, 0xc9, 
+-      0x49, 0x3a, 0x69, 0x89, 0x68, 0x09, 0x4b, 0x3f, 
+-      0x40, 0x19, 0x9a, 0x05, 0x07, 0x92, 0x0f, 0x92, 
+-      0x05, 0xd2, 0x43, 0x11, 0x4a, 0x35, 0x69, 0x92, 
+-      0x60, 0x11, 0x01, 0xc9, 0x49, 0x33, 0x69, 0x89, 
+-      0x68, 0x09, 0x4b, 0x39, 0x40, 0x19, 0x9a, 0x0e, 
+-      0x07, 0xd2, 0x09, 0x92, 0x43, 0x11, 0x4a, 0x2f, 
+-      0x69, 0x92, 0x60, 0x11, 0x01, 0x89, 0x69, 0xf9, 
+-      0x4a, 0x2c, 0x69, 0x52, 0x60, 0x11, 0x49, 0x2b, 
+-      0x69, 0x89, 0x68, 0x09, 0x01, 0x49, 0x09, 0x49, 
+-      0x9a, 0x0a, 0x06, 0xd2, 0x43, 0x11, 0x4a, 0x27, 
+-      0x69, 0x92, 0x60, 0x11, 0x99, 0x0a, 0x4a, 0x25, 
+-      0x69, 0x52, 0x60, 0x51, 0x99, 0x0b, 0x4a, 0x23, 
+-      0x69, 0x52, 0x60, 0x91, 0x99, 0x0b, 0x4a, 0x21, 
+-      0x69, 0x52, 0x60, 0xd1, 0x69, 0xe1, 0x4a, 0x1f, 
+-      0x69, 0x52, 0x61, 0x11, 0x49, 0x1d, 0x69, 0xc9, 
+-      0x68, 0x09, 0x01, 0x49, 0x09, 0x49, 0x9a, 0x0c, 
+-      0x06, 0xd2, 0x43, 0x11, 0x4a, 0x19, 0x69, 0xd2, 
+-      0x60, 0x11, 0x99, 0x0c, 0x4a, 0x17, 0x69, 0x52, 
+-      0x61, 0x51, 0x99, 0x0d, 0x4a, 0x15, 0x69, 0x52, 
+-      0x61, 0x91, 0x99, 0x0d, 0x4a, 0x13, 0x69, 0x52, 
+-      0x61, 0xd1, 0x99, 0x09, 0x4a, 0x11, 0x69, 0x52, 
+-      0x62, 0x51, 0x99, 0x08, 0x4a, 0x0f, 0x69, 0x52, 
+-      0x62, 0x11, 0x68, 0x38, 0x28, 0x00, 0xd0, 0x05, 
+-      0x48, 0x14, 0x68, 0x01, 0x23, 0x01, 0x43, 0x19, 
+-      0x60, 0x01, 0xe0, 0x02, 0x48, 0x11, 0x21, 0x00, 
+-      0x60, 0x01, 0xf0, 0x00, 0xf9, 0x8c, 0xf0, 0x10, 
+-      0xfc, 0xc9, 0x20, 0x00, 0xb0, 0x0f, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0xb0, 0x0e, 
+-      0xb0, 0x01, 0xe7, 0xf8, 0x2e, 0x03, 0x3a, 0x04, 
+-      0x2e, 0x03, 0x3a, 0x54, 0x2e, 0x08, 0x1f, 0xa8, 
+-      0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xbf, 0xff, 
+-      0xff, 0xff, 0xdf, 0xff, 0xff, 0x80, 0x7f, 0xff, 
+-      0xfb, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 
+-      0xfd, 0xff, 0xff, 0xff, 0x68, 0x00, 0x00, 0x40, 
+-      0xb4, 0x80, 0x1c, 0x07, 0x1c, 0x0a, 0x69, 0x38, 
+-      0x00, 0x80, 0x49, 0x3c, 0x58, 0x08, 0x23, 0x18, 
+-      0x40, 0x18, 0x08, 0xc0, 0x49, 0x3a, 0x69, 0x89, 
+-      0x68, 0x09, 0x23, 0xc0, 0x43, 0xdb, 0x40, 0x19, 
+-      0x07, 0x80, 0x0f, 0x80, 0x01, 0x80, 0x43, 0x08, 
+-      0x49, 0x35, 0x69, 0x89, 0x60, 0x08, 0x06, 0x00, 
+-      0x0f, 0x80, 0x69, 0x38, 0x00, 0x80, 0x49, 0x31, 
+-      0x58, 0x08, 0x23, 0x04, 0x40, 0x18, 0x08, 0x80, 
+-      0x49, 0x2f, 0x69, 0x89, 0x68, 0x09, 0x23, 0x08, 
+-      0x43, 0xdb, 0x40, 0x19, 0x07, 0xc0, 0x0f, 0x00, 
+-      0x43, 0x08, 0x49, 0x2b, 0x69, 0x89, 0x60, 0x08, 
+-      0x07, 0x00, 0x0f, 0xc0, 0x69, 0x38, 0x00, 0x80, 
+-      0x49, 0x26, 0x58, 0x08, 0x49, 0x26, 0x69, 0x89, 
+-      0x68, 0x09, 0x23, 0x30, 0x43, 0xdb, 0x40, 0x19, 
+-      0x07, 0x80, 0x0f, 0x80, 0x01, 0x00, 0x43, 0x08, 
+-      0x49, 0x21, 0x69, 0x89, 0x60, 0x08, 0x06, 0x80, 
+-      0x0f, 0x80, 0x69, 0x10, 0x00, 0x80, 0x49, 0x1d, 
+-      0x58, 0x08, 0x23, 0x18, 0x40, 0x18, 0x08, 0xc0, 
+-      0x49, 0x1b, 0x69, 0x89, 0x68, 0x09, 0x4b, 0x1b, 
+-      0x40, 0x19, 0x07, 0x80, 0x0f, 0x80, 0x02, 0xc0, 
+-      0x43, 0x08, 0x49, 0x17, 0x69, 0x89, 0x60, 0x08, 
+-      0x04, 0xc0, 0x0f, 0x80, 0x69, 0x10, 0x00, 0x80, 
+-      0x49, 0x12, 0x58, 0x08, 0x23, 0x04, 0x40, 0x18, 
+-      0x08, 0x80, 0x49, 0x11, 0x69, 0x89, 0x68, 0x09, 
+-      0x4b, 0x11, 0x40, 0x19, 0x07, 0xc0, 0x0d, 0xc0, 
+-      0x43, 0x08, 0x49, 0x0d, 0x69, 0x89, 0x60, 0x08, 
+-      0x05, 0xc0, 0x0f, 0xc0, 0x69, 0x10, 0x00, 0x80, 
+-      0x49, 0x08, 0x58, 0x08, 0x49, 0x08, 0x69, 0x89, 
+-      0x68, 0x09, 0x4b, 0x0a, 0x40, 0x19, 0x07, 0x80, 
+-      0x0f, 0x80, 0x02, 0x40, 0x43, 0x08, 0x49, 0x04, 
+-      0x69, 0x89, 0x60, 0x08, 0x05, 0x40, 0x0f, 0x80, 
+-      0xbc, 0x80, 0x47, 0x70, 0x2e, 0x03, 0x3a, 0x04, 
+-      0x2e, 0x08, 0x1f, 0xa8, 0xff, 0xff, 0xe7, 0xff, 
+-      0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xf9, 0xff, 
+-      0xb4, 0xb0, 0x1c, 0x04, 0x1c, 0x0f, 0x1c, 0x15, 
+-      0x2d, 0x00, 0xd0, 0x06, 0x2d, 0x02, 0xd0, 0x21, 
+-      0x2d, 0x03, 0xd0, 0x02, 0x2d, 0x04, 0xd0, 0x1d, 
+-      0xe0, 0xa3, 0x69, 0x20, 0x28, 0x0b, 0xd2, 0x14, 
+-      0xa3, 0x01, 0x5c, 0x1b, 0x00, 0x5b, 0x44, 0x9f, 
+-      0x05, 0x07, 0x09, 0x0b, 0x05, 0x07, 0x09, 0x0b, 
+-      0x0d, 0x0e, 0x0e, 0x00, 0x07, 0xff, 0xe0, 0x09, 
+-      0x07, 0xbf, 0xe0, 0x07, 0x07, 0x3f, 0xe0, 0x05, 
+-      0x06, 0x3f, 0xe0, 0x03, 0xe0, 0x02, 0x02, 0x3f, 
+-      0xe0, 0x00, 0xe7, 0xff, 0x48, 0x46, 0x6a, 0x00, 
+-      0x60, 0x07, 0xe0, 0x86, 0x69, 0x20, 0x28, 0x0b, 
+-      0xd2, 0x73, 0xa3, 0x02, 0x5c, 0x1b, 0x00, 0x5b, 
+-      0x44, 0x9f, 0x1c, 0x00, 0x06, 0x15, 0x24, 0x33, 
+-      0x06, 0x15, 0x24, 0x33, 0x41, 0x45, 0x45, 0x00, 
+-      0x01, 0xff, 0x48, 0x3d, 0x6a, 0x40, 0x68, 0x00, 
+-      0x4b, 0x3c, 0x40, 0x18, 0x06, 0x39, 0x0e, 0x09, 
+-      0x00, 0x89, 0x43, 0x08, 0x49, 0x38, 0x6a, 0x49, 
+-      0x60, 0x08, 0x05, 0x80, 0xe0, 0x69, 0x01, 0xbf, 
+-      0x48, 0x35, 0x6a, 0x40, 0x68, 0x00, 0x4b, 0x35, 
+-      0x40, 0x18, 0x06, 0x39, 0x0e, 0x09, 0x00, 0x89, 
+-      0x43, 0x08, 0x49, 0x31, 0x6a, 0x49, 0x60, 0x08, 
+-      0x05, 0x80, 0xe0, 0x5a, 0x01, 0x3f, 0x48, 0x2e, 
+-      0x6a, 0x40, 0x68, 0x00, 0x4b, 0x2d, 0x40, 0x18, 
+-      0x06, 0x39, 0x0e, 0x09, 0x00, 0x89, 0x43, 0x08, 
+-      0x49, 0x29, 0x6a, 0x49, 0x60, 0x08, 0x05, 0x80, 
+-      0xe0, 0x4b, 0x48, 0x27, 0x6a, 0x40, 0x68, 0x00, 
+-      0x4b, 0x26, 0x40, 0x18, 0x06, 0x39, 0x0e, 0x09, 
+-      0x00, 0x89, 0x43, 0x08, 0x49, 0x22, 0x6a, 0x49, 
+-      0x60, 0x08, 0x05, 0x80, 0xe0, 0x3d, 0x48, 0x20, 
+-      0x6a, 0x00, 0x60, 0x07, 0xe0, 0x39, 0x48, 0x1e, 
+-      0x6a, 0x40, 0x68, 0x00, 0x4b, 0x1d, 0x40, 0x18, 
+-      0x06, 0x39, 0x0e, 0x09, 0x00, 0x89, 0x43, 0x08, 
+-      0x49, 0x19, 0x6a, 0x49, 0x60, 0x08, 0x05, 0x80, 
+-      0x48, 0x17, 0x6a, 0x40, 0x68, 0x00, 0x4b, 0x18, 
+-      0x40, 0x18, 0x21, 0xff, 0x02, 0x09, 0x40, 0x39, 
+-      0x00, 0x89, 0x43, 0x08, 0x49, 0x12, 0x6a, 0x49, 
+-      0x60, 0x08, 0x03, 0x80, 0x48, 0x10, 0x6a, 0x40, 
+-      0x68, 0x00, 0x4b, 0x12, 0x40, 0x18, 0x21, 0xff, 
+-      0x04, 0x09, 0x40, 0x39, 0x00, 0x89, 0x43, 0x01, 
+-      0x48, 0x0b, 0x6a, 0x40, 0x60, 0x01, 0x01, 0x88, 
+-      0xe0, 0x00, 0xe0, 0x0d, 0x48, 0x08, 0x6a, 0x40, 
+-      0x68, 0x00, 0x01, 0x80, 0x09, 0x80, 0x21, 0x3f, 
+-      0x06, 0x09, 0x40, 0x39, 0x00, 0x89, 0x43, 0x08, 
+-      0x49, 0x03, 0x6a, 0x49, 0x60, 0x08, 0xe0, 0x00, 
+-      0xe7, 0xff, 0xbc, 0xb0, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x1f, 0xa8, 0xff, 0xff, 0xfc, 0x03, 
+-      0xff, 0xfc, 0x03, 0xff, 0xfc, 0x03, 0xff, 0xff, 
+-      0xb4, 0x80, 0x1c, 0x07, 0x1c, 0x0a, 0x69, 0x38, 
+-      0x28, 0x0b, 0xd2, 0x1a, 0xa3, 0x01, 0x5c, 0x1b, 
+-      0x00, 0x5b, 0x44, 0x9f, 0x05, 0x08, 0x0b, 0x0e, 
+-      0x05, 0x08, 0x0b, 0x0e, 0x11, 0x13, 0x13, 0x00, 
+-      0x68, 0x10, 0x0f, 0xc1, 0xe0, 0x0f, 0x68, 0x10, 
+-      0x0f, 0x81, 0xe0, 0x0c, 0x68, 0x10, 0x0f, 0x01, 
+-      0xe0, 0x09, 0x68, 0x10, 0x0e, 0x01, 0xe0, 0x06, 
+-      0x68, 0x11, 0xe0, 0x04, 0x68, 0x10, 0x0a, 0x01, 
+-      0xe0, 0x01, 0x68, 0x11, 0xe7, 0xff, 0x1c, 0x08, 
+-      0xbc, 0x80, 0x47, 0x70, 0xe7, 0xfc, 0x48, 0x14, 
+-      0x69, 0x80, 0x68, 0x00, 0x49, 0x12, 0x6a, 0x89, 
+-      0x60, 0x08, 0x48, 0x11, 0x69, 0xc0, 0x68, 0x00, 
+-      0x49, 0x0f, 0x6a, 0xc9, 0x60, 0x08, 0x48, 0x0e, 
+-      0x6a, 0x00, 0x68, 0x00, 0x49, 0x0c, 0x6b, 0x09, 
+-      0x60, 0x08, 0x48, 0x0b, 0x6a, 0x40, 0x68, 0x00, 
+-      0x49, 0x09, 0x6b, 0x49, 0x60, 0x08, 0x20, 0x01, 
+-      0x49, 0x07, 0x6b, 0xc9, 0x60, 0x08, 0x20, 0x00, 
+-      0x49, 0x06, 0x60, 0x08, 0x20, 0x00, 0x49, 0x05, 
+-      0x60, 0x48, 0x20, 0x00, 0x49, 0x03, 0x60, 0x88, 
+-      0x20, 0x00, 0x49, 0x02, 0x60, 0xc8, 0x47, 0x70, 
+-      0x2e, 0x08, 0x1f, 0xa8, 0x2e, 0x08, 0x1f, 0xac, 
+-      0xb4, 0x90, 0x1c, 0x01, 0x29, 0x00, 0xd1, 0x02, 
+-      0x20, 0x8d, 0xbc, 0x90, 0x47, 0x70, 0x4c, 0x08, 
+-      0x1c, 0x0f, 0x22, 0x00, 0x23, 0xff, 0x33, 0x01, 
+-      0x42, 0x9a, 0xd3, 0x02, 0xe0, 0x04, 0x32, 0x01, 
+-      0xe7, 0xf8, 0xcf, 0x08, 0xc4, 0x08, 0xe7, 0xfa, 
+-      0x20, 0x00, 0xe7, 0xee, 0xe7, 0xed, 0x00, 0x00, 
+-      0x68, 0x00, 0x18, 0x00, 0xb4, 0x90, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0x1c, 0x13, 0x06, 0x1a, 0x0e, 0x12, 
+-      0x1c, 0x21, 0x60, 0x0f, 0x71, 0x0a, 0x20, 0x00, 
+-      0xbc, 0x90, 0x47, 0x70, 0xe7, 0xfc, 0x00, 0x00, 
+-      0xb5, 0x00, 0x48, 0x1d, 0x69, 0x00, 0x23, 0x04, 
+-      0x40, 0x18, 0xd0, 0x19, 0x48, 0x1a, 0x69, 0x00, 
+-      0x23, 0x02, 0x40, 0x18, 0xd0, 0x09, 0x48, 0x18, 
+-      0x69, 0x40, 0x49, 0x18, 0x68, 0x09, 0x60, 0x08, 
+-      0x20, 0x01, 0x49, 0x17, 0x68, 0x09, 0x70, 0x08, 
+-      0xe0, 0x03, 0x20, 0x00, 0x49, 0x14, 0x68, 0x09, 
+-      0x70, 0x08, 0x48, 0x14, 0x78, 0x01, 0x20, 0x01, 
+-      0x40, 0x88, 0xf0, 0x07, 0xfb, 0x65, 0xe0, 0x18, 
+-      0x48, 0x11, 0x6a, 0x80, 0x23, 0x02, 0x40, 0x18, 
+-      0xd0, 0x13, 0x48, 0x0f, 0x6a, 0x80, 0x07, 0xc0, 
+-      0x0f, 0xc0, 0xd0, 0x04, 0x20, 0xfe, 0x49, 0x0d, 
+-      0x68, 0x09, 0x70, 0x08, 0xe0, 0x03, 0x20, 0x0e, 
+-      0x49, 0x0a, 0x68, 0x09, 0x70, 0x08, 0x48, 0x0a, 
+-      0x78, 0x01, 0x20, 0x01, 0x40, 0x88, 0xf0, 0x07, 
+-      0xfb, 0x4b, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x6e, 0x00, 0x0c, 0x00, 0x2e, 0x08, 0x7c, 0x2c, 
+-      0x2e, 0x08, 0x7c, 0x30, 0x2e, 0x08, 0x7c, 0x34, 
+-      0x6e, 0x00, 0x0e, 0x00, 0x2e, 0x08, 0x7c, 0x38, 
+-      0x2e, 0x08, 0x7c, 0x3c, 0xb5, 0xf0, 0x1c, 0x05, 
+-      0x1c, 0x0c, 0x1c, 0x17, 0x06, 0x2e, 0x0e, 0x36, 
+-      0x2e, 0x1f, 0xdd, 0x03, 0x20, 0xaf, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x49, 0x08, 0x20, 0x0d, 
+-      0xf0, 0x07, 0xfb, 0x3c, 0x48, 0x07, 0x60, 0x04, 
+-      0x20, 0x00, 0x49, 0x06, 0x68, 0x09, 0x70, 0x08, 
+-      0x48, 0x05, 0x60, 0x07, 0x48, 0x05, 0x70, 0x06, 
+-      0x20, 0x00, 0xe7, 0xec, 0xe7, 0xeb, 0x00, 0x00, 
+-      0x2e, 0x01, 0x53, 0xed, 0x2e, 0x08, 0x7c, 0x30, 
+-      0x2e, 0x08, 0x7c, 0x2c, 0x2e, 0x08, 0x7c, 0x34, 
+-      0xb5, 0xb0, 0x1c, 0x04, 0x1c, 0x0f, 0x06, 0x25, 
+-      0x0e, 0x2d, 0x2d, 0x1f, 0xdd, 0x03, 0x20, 0xaf, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x49, 0x07, 
+-      0x20, 0x0d, 0xf0, 0x07, 0xfb, 0x17, 0x48, 0x06, 
+-      0x60, 0x07, 0x20, 0x00, 0x49, 0x04, 0x68, 0x09, 
+-      0x70, 0x08, 0x48, 0x04, 0x70, 0x05, 0x20, 0x00, 
+-      0xe7, 0xee, 0xe7, 0xed, 0x2e, 0x01, 0x53, 0xed, 
+-      0x2e, 0x08, 0x7c, 0x38, 0x2e, 0x08, 0x7c, 0x3c, 
+-      0xb4, 0xb0, 0x1c, 0x01, 0x4a, 0x35, 0x23, 0x01, 
+-      0x60, 0x13, 0x4a, 0x35, 0x1c, 0x0f, 0x68, 0x3d, 
+-      0xc2, 0x20, 0x88, 0x8d, 0xc2, 0x20, 0x88, 0xcb, 
+-      0x60, 0x13, 0x68, 0x8c, 0x2c, 0x00, 0xd0, 0x57, 
+-      0x4a, 0x30, 0x1c, 0x27, 0x20, 0x00, 0x28, 0x13, 
+-      0xdb, 0x02, 0xe0, 0x04, 0x30, 0x01, 0xe7, 0xfa, 
+-      0xcf, 0x20, 0xc2, 0x20, 0xe7, 0xfa, 0x4a, 0x2c, 
+-      0x1d, 0xe7, 0x37, 0x45, 0x20, 0x00, 0x28, 0x0b, 
+-      0xdb, 0x02, 0xe0, 0x04, 0x30, 0x01, 0xe7, 0xfa, 
+-      0xcf, 0x20, 0xc2, 0x20, 0xe7, 0xfa, 0x4a, 0x27, 
+-      0x1d, 0xe7, 0x37, 0x71, 0x20, 0x00, 0x28, 0x07, 
+-      0xdb, 0x02, 0xe0, 0x04, 0x30, 0x01, 0xe7, 0xfa, 
+-      0xcf, 0x20, 0xc2, 0x20, 0xe7, 0xfa, 0x4a, 0x22, 
+-      0x1d, 0xe7, 0x37, 0x8d, 0x20, 0x00, 0x28, 0x09, 
+-      0xdb, 0x02, 0xe0, 0x04, 0x30, 0x01, 0xe7, 0xfa, 
+-      0xcf, 0x20, 0xc2, 0x20, 0xe7, 0xfa, 0x4a, 0x1d, 
+-      0x1d, 0xe7, 0x37, 0xb1, 0x20, 0x00, 0x28, 0x09, 
+-      0xdb, 0x02, 0xe0, 0x04, 0x30, 0x01, 0xe7, 0xfa, 
+-      0xcf, 0x20, 0xc2, 0x20, 0xe7, 0xfa, 0x68, 0x0d, 
+-      0x23, 0x01, 0x02, 0x9b, 0x40, 0x2b, 0xd0, 0x17, 
+-      0x4a, 0x15, 0x1d, 0xe7, 0x37, 0xd5, 0x20, 0x00, 
+-      0x28, 0x09, 0xdb, 0x02, 0xe0, 0x04, 0x30, 0x01, 
+-      0xe7, 0xfa, 0xcf, 0x20, 0xc2, 0x20, 0xe7, 0xfa, 
+-      0x4a, 0x10, 0x1d, 0xe7, 0x37, 0xf9, 0x20, 0x00, 
+-      0x28, 0x09, 0xdb, 0x02, 0xe0, 0x04, 0x30, 0x01, 
+-      0xe7, 0xfa, 0xcf, 0x20, 0xc2, 0x20, 0xe7, 0xfa, 
+-      0x4a, 0x02, 0x23, 0x00, 0x60, 0x13, 0xbc, 0xb0, 
+-      0x47, 0x70, 0x00, 0x00, 0x6e, 0x00, 0x0c, 0x0c, 
+-      0x6e, 0x00, 0x0c, 0x00, 0x6e, 0x00, 0x08, 0x00, 
+-      0x6e, 0x00, 0x08, 0x50, 0x6e, 0x00, 0x08, 0x80, 
+-      0x6e, 0x00, 0x08, 0xa0, 0x6e, 0x00, 0x08, 0xd0, 
+-      0x6e, 0x00, 0x09, 0x00, 0x6e, 0x00, 0x09, 0x30, 
+-      0xb4, 0xf0, 0x1c, 0x01, 0x69, 0x08, 0x06, 0xc0, 
+-      0x0e, 0xc0, 0x28, 0x01, 0xdb, 0x04, 0x69, 0x08, 
+-      0x06, 0xc0, 0x0e, 0xc0, 0x28, 0x0a, 0xdd, 0x02, 
+-      0x20, 0xc3, 0xbc, 0xf0, 0x47, 0x70, 0x69, 0x08, 
+-      0x05, 0x80, 0x0e, 0xc0, 0x28, 0x01, 0xdb, 0x04, 
+-      0x69, 0x08, 0x05, 0x80, 0x0e, 0xc0, 0x28, 0x0a, 
+-      0xdd, 0x01, 0x20, 0xc4, 0xe7, 0xf1, 0x48, 0x4f, 
+-      0x6a, 0x80, 0x07, 0xc0, 0x0f, 0xc0, 0xd1, 0x01, 
+-      0x20, 0xc0, 0xe7, 0xea, 0x68, 0x08, 0x07, 0x00, 
+-      0x0f, 0xc0, 0x4b, 0x4b, 0x70, 0x18, 0x4f, 0x49, 
+-      0x1c, 0x0c, 0x22, 0x00, 0x2a, 0x04, 0xd3, 0x02, 
+-      0xe0, 0x04, 0x32, 0x01, 0xe7, 0xfa, 0xcc, 0x08, 
+-      0xc7, 0x08, 0xe7, 0xfa, 0x4f, 0x45, 0x69, 0x08, 
+-      0x06, 0xc0, 0x0e, 0xc0, 0x00, 0x43, 0x18, 0x18, 
+-      0x38, 0x03, 0x69, 0x0b, 0x05, 0x9b, 0x0e, 0xde, 
+-      0x00, 0x73, 0x19, 0x9b, 0x3b, 0x03, 0x01, 0x5b, 
+-      0x43, 0x18, 0x60, 0x38, 0x4f, 0x3e, 0x69, 0x48, 
+-      0x60, 0x38, 0x4f, 0x3e, 0x69, 0x88, 0x05, 0x40, 
+-      0x0d, 0x40, 0x69, 0x8b, 0x02, 0x9b, 0x0d, 0x5b, 
+-      0x02, 0xdb, 0x43, 0x18, 0x60, 0x38, 0x69, 0xcd, 
+-      0x2d, 0x00, 0xd0, 0x63, 0x4f, 0x38, 0x1c, 0x2c, 
+-      0x22, 0x00, 0x2a, 0x09, 0xd3, 0x02, 0xe0, 0x04, 
+-      0x32, 0x01, 0xe7, 0xfa, 0xcc, 0x08, 0xc7, 0x08, 
+-      0xe7, 0xfa, 0x4f, 0x34, 0x1d, 0xec, 0x34, 0x1d, 
+-      0x22, 0x00, 0x2a, 0x09, 0xd3, 0x02, 0xe0, 0x04, 
+-      0x32, 0x01, 0xe7, 0xfa, 0xcc, 0x08, 0xc7, 0x08, 
+-      0xe7, 0xfa, 0x4f, 0x2f, 0x1d, 0xec, 0x34, 0x41, 
+-      0x22, 0x00, 0x2a, 0x09, 0xd3, 0x02, 0xe0, 0x04, 
+-      0x32, 0x01, 0xe7, 0xfa, 0xcc, 0x08, 0xc7, 0x08, 
+-      0xe7, 0xfa, 0x4f, 0x2a, 0x1d, 0xec, 0x34, 0x65, 
+-      0x22, 0x00, 0x2a, 0x09, 0xd3, 0x02, 0xe0, 0x04, 
+-      0x32, 0x01, 0xe7, 0xfa, 0xcc, 0x08, 0xc7, 0x08, 
+-      0xe7, 0xfa, 0x4f, 0x25, 0x1d, 0xec, 0x34, 0x89, 
+-      0x22, 0x00, 0x2a, 0x05, 0xd3, 0x02, 0xe0, 0x04, 
+-      0x32, 0x01, 0xe7, 0xfa, 0xcc, 0x08, 0xc7, 0x08, 
+-      0xe7, 0xfa, 0x4f, 0x20, 0x1d, 0xec, 0x34, 0x9d, 
+-      0x22, 0x00, 0x2a, 0x05, 0xd3, 0x02, 0xe0, 0x04, 
+-      0x32, 0x01, 0xe7, 0xfa, 0xcc, 0x08, 0xc7, 0x08, 
+-      0xe7, 0xfa, 0x68, 0x08, 0x23, 0x01, 0x02, 0x9b, 
+-      0x40, 0x18, 0xd0, 0x17, 0x4f, 0x18, 0x1d, 0xec, 
+-      0x34, 0xb1, 0x22, 0x00, 0x2a, 0x05, 0xd3, 0x02, 
+-      0xe0, 0x04, 0x32, 0x01, 0xe7, 0xfa, 0xcc, 0x08, 
+-      0xc7, 0x08, 0xe7, 0xfa, 0x4f, 0x13, 0x1d, 0xec, 
+-      0x34, 0xc5, 0x22, 0x00, 0x2a, 0x05, 0xd3, 0x02, 
+-      0xe0, 0x04, 0x32, 0x01, 0xe7, 0xfa, 0xcc, 0x08, 
+-      0xc7, 0x08, 0xe7, 0xfa, 0x20, 0x00, 0xe7, 0x54, 
+-      0xe7, 0x53, 0x00, 0x00, 0x6e, 0x00, 0x0e, 0x00, 
+-      0x2e, 0x08, 0x7c, 0x3d, 0x6e, 0x00, 0x0e, 0x10, 
+-      0x6e, 0x00, 0x0e, 0x14, 0x6e, 0x00, 0x0e, 0x18, 
+-      0x6e, 0x00, 0x0a, 0x00, 0x6e, 0x00, 0x0a, 0x24, 
+-      0x6e, 0x00, 0x0a, 0x48, 0x6e, 0x00, 0x0a, 0x90, 
+-      0x6e, 0x00, 0x0a, 0xc0, 0x6e, 0x00, 0x0a, 0xe4, 
+-      0x6e, 0x00, 0x09, 0xc0, 0x6e, 0x00, 0x09, 0xe4, 
+-      0x1c, 0x01, 0x48, 0x0c, 0x78, 0x00, 0x28, 0x00, 
+-      0xd0, 0x01, 0x20, 0xc1, 0x47, 0x70, 0x48, 0x0a, 
+-      0x6a, 0x80, 0x07, 0xc0, 0x0f, 0xc0, 0xd1, 0x01, 
+-      0x20, 0xc0, 0xe7, 0xf7, 0x20, 0x00, 0x4b, 0x06, 
+-      0x61, 0x58, 0x4a, 0x06, 0x68, 0x08, 0x60, 0x10, 
+-      0x4a, 0x05, 0x68, 0x48, 0x60, 0x10, 0x20, 0x00, 
+-      0xe7, 0xec, 0xe7, 0xeb, 0x2e, 0x08, 0x7c, 0x3d, 
+-      0x6e, 0x00, 0x0e, 0x00, 0x6e, 0x00, 0x0e, 0x20, 
+-      0x6e, 0x00, 0x0e, 0x24, 0x48, 0x09, 0x78, 0x00, 
+-      0x28, 0x00, 0xd0, 0x01, 0x20, 0xc1, 0x47, 0x70, 
+-      0x48, 0x07, 0x6a, 0x80, 0x07, 0xc0, 0x0f, 0xc0, 
+-      0xd0, 0x01, 0x20, 0xc2, 0xe7, 0xf7, 0x20, 0x01, 
+-      0x49, 0x03, 0x61, 0x48, 0x20, 0x00, 0xe7, 0xf2, 
+-      0xe7, 0xf1, 0x00, 0x00, 0x2e, 0x08, 0x7c, 0x3d, 
+-      0x6e, 0x00, 0x0e, 0x00, 0xb5, 0xff, 0x1c, 0x04, 
+-      0x1c, 0x0d, 0x1c, 0x17, 0x9e, 0x09, 0x20, 0x00, 
+-      0x60, 0x30, 0x48, 0x13, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x07, 0x9b, 0x03, 0x2b, 0x00, 0xd1, 0x04, 
+-      0x20, 0x8a, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x23, 0xff, 0x33, 0x01, 0x42, 0x9c, 
+-      0xdd, 0x01, 0x20, 0x87, 0xe7, 0xf5, 0x19, 0x28, 
+-      0x23, 0xff, 0x33, 0x01, 0x42, 0x98, 0xd9, 0x01, 
+-      0x20, 0x88, 0xe7, 0xee, 0x68, 0x79, 0x1c, 0x20, 
+-      0x80, 0x48, 0x70, 0x0d, 0x9b, 0x03, 0x60, 0x4b, 
+-      0x68, 0x78, 0x60, 0xc8, 0x68, 0x38, 0x60, 0x88, 
+-      0x60, 0x31, 0x20, 0x00, 0xe7, 0xe1, 0xe7, 0xe0, 
+-      0x2e, 0x08, 0x60, 0x84, 0x1c, 0x03, 0x1c, 0x0a, 
+-      0x1c, 0x19, 0x68, 0xc8, 0x60, 0x50, 0x68, 0x88, 
+-      0x60, 0x10, 0x20, 0x00, 0x47, 0x70, 0xe7, 0xfd, 
+-      0xb5, 0xf3, 0xb0, 0x87, 0x21, 0x00, 0x91, 0x06, 
+-      0x26, 0x00, 0x98, 0x07, 0xf0, 0x00, 0xfa, 0xcb, 
+-      0x90, 0x03, 0x9c, 0x07, 0x9d, 0x08, 0x88, 0x69, 
+-      0x91, 0x04, 0x98, 0x03, 0x99, 0x04, 0x42, 0x88, 
+-      0xd0, 0x09, 0x48, 0xbb, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x05, 0x20, 0xff, 0xb0, 0x07, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x78, 0x28, 
+-      0x90, 0x05, 0x99, 0x04, 0x23, 0xff, 0x33, 0x01, 
+-      0x42, 0x99, 0xdd, 0x02, 0x20, 0xff, 0xb0, 0x07, 
+-      0xe7, 0xf1, 0x98, 0x05, 0x99, 0x04, 0x18, 0x40, 
+-      0x23, 0xff, 0x33, 0x01, 0x42, 0x98, 0xdd, 0x02, 
+-      0x20, 0xff, 0xb0, 0x07, 0xe7, 0xe7, 0x48, 0xad, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x0a, 0x68, 0xa0, 
+-      0x23, 0x01, 0x06, 0x1b, 0x40, 0x18, 0xd0, 0x05, 
+-      0x68, 0x68, 0x28, 0x00, 0xd1, 0x02, 0x20, 0x8a, 
+-      0xb0, 0x07, 0xe7, 0xd8, 0x62, 0x65, 0x69, 0x60, 
+-      0x4b, 0xa5, 0x40, 0x18, 0x99, 0x05, 0x06, 0x09, 
+-      0x0e, 0x09, 0x04, 0x09, 0x43, 0x08, 0x61, 0x60, 
+-      0x02, 0x00, 0x68, 0xe0, 0x90, 0x00, 0x48, 0x9e, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x06, 0x98, 0x00, 
+-      0x28, 0x19, 0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 
+-      0x20, 0x00, 0xe0, 0x05, 0x98, 0x00, 0x28, 0x08, 
+-      0xd3, 0x01, 0x20, 0x01, 0xe0, 0x00, 0x20, 0x00, 
+-      0x28, 0x00, 0xd0, 0x02, 0x20, 0x00, 0xb0, 0x07, 
+-      0xe7, 0xb5, 0x48, 0x94, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x1e, 0x48, 0x91, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x1a, 0x68, 0xa0, 0x02, 0x00, 0x0e, 0x00, 
+-      0x06, 0x01, 0x0e, 0x09, 0x91, 0x06, 0x99, 0x04, 
+-      0x29, 0x04, 0xd0, 0x06, 0x29, 0x10, 0xd0, 0x07, 
+-      0x23, 0xff, 0x33, 0x01, 0x42, 0x99, 0xd0, 0x06, 
+-      0xe0, 0x08, 0x26, 0xff, 0x36, 0x01, 0xe0, 0x07, 
+-      0x26, 0x01, 0x02, 0x76, 0xe0, 0x04, 0x26, 0x03, 
+-      0x02, 0x36, 0xe0, 0x01, 0x26, 0x00, 0xe7, 0xff, 
+-      0x49, 0x84, 0x20, 0x91, 0xf0, 0x0f, 0xff, 0xca, 
+-      0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 0xf0, 0x01, 
+-      0xff, 0xb1, 0xe7, 0xf5, 0x98, 0x00, 0x00, 0x80, 
+-      0x49, 0x7f, 0x58, 0x08, 0x99, 0x07, 0x42, 0x88, 
+-      0xd0, 0x05, 0x20, 0x92, 0x49, 0x7b, 0x60, 0x08, 
+-      0x20, 0xff, 0xb0, 0x07, 0xe7, 0x7b, 0x48, 0x77, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x73, 0x48, 0x74, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x6f, 0x98, 0x00, 
+-      0xf0, 0x02, 0xfe, 0xd6, 0x28, 0x00, 0xd0, 0x6a, 
+-      0xb0, 0x82, 0x49, 0x74, 0x20, 0x91, 0xf0, 0x0f, 
+-      0xff, 0xa5, 0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 
+-      0xf0, 0x02, 0xff, 0x25, 0x20, 0x92, 0x49, 0x6f, 
+-      0x60, 0x08, 0x20, 0x01, 0x49, 0x6e, 0x68, 0x09, 
+-      0x60, 0x08, 0x27, 0x00, 0x20, 0x00, 0x90, 0x00, 
+-      0x98, 0x00, 0x28, 0x00, 0xd1, 0x15, 0x2f, 0x07, 
+-      0xd2, 0x13, 0x6a, 0xe0, 0x05, 0x81, 0x0d, 0x89, 
+-      0x1c, 0x38, 0x37, 0x01, 0x00, 0x83, 0x18, 0x18, 
+-      0x00, 0xc0, 0x4a, 0x65, 0x68, 0x12, 0x18, 0x80, 
+-      0x23, 0x05, 0x02, 0x1b, 0x18, 0xc0, 0x6f, 0xc0, 
+-      0x42, 0x81, 0xd1, 0x01, 0x20, 0x01, 0x90, 0x00, 
+-      0xe7, 0xe6, 0x98, 0x00, 0x28, 0x00, 0xd1, 0x14, 
+-      0x2f, 0x18, 0xd2, 0x12, 0x6a, 0xe0, 0x05, 0x81, 
+-      0x0d, 0x89, 0x1c, 0x38, 0x37, 0x01, 0x23, 0x4c, 
+-      0x43, 0x58, 0x4a, 0x59, 0x68, 0x12, 0x18, 0x80, 
+-      0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 0x69, 0x40, 
+-      0x42, 0x81, 0xd1, 0x01, 0x20, 0x01, 0x90, 0x00, 
+-      0xe7, 0xe7, 0x3f, 0x01, 0x2f, 0x07, 0xd2, 0x10, 
+-      0x00, 0xb8, 0x19, 0xc0, 0x00, 0xc0, 0x49, 0x50, 
+-      0x68, 0x09, 0x18, 0x40, 0x23, 0x2b, 0x01, 0x5b, 
+-      0x18, 0xc0, 0x1c, 0x21, 0xf0, 0x02, 0xfb, 0x38, 
+-      0x48, 0x4b, 0x68, 0x00, 0xf0, 0x02, 0xfe, 0xee, 
+-      0xe0, 0x46, 0x2f, 0x18, 0xd2, 0x44, 0x20, 0x4c, 
+-      0x43, 0x78, 0x49, 0x47, 0x68, 0x09, 0x18, 0x40, 
+-      0x38, 0xff, 0x38, 0xff, 0x38, 0x0a, 0x1c, 0x21, 
+-      0xf0, 0x02, 0xfb, 0x26, 0x20, 0x4c, 0x43, 0x78, 
+-      0x49, 0x41, 0x68, 0x09, 0xe0, 0x00, 0xe0, 0x48, 
+-      0x18, 0x40, 0x38, 0xff, 0x38, 0xff, 0x38, 0x82, 
+-      0x6f, 0xc0, 0x28, 0x00, 0xd0, 0x17, 0x20, 0x4c, 
+-      0x43, 0x78, 0x49, 0x3b, 0x68, 0x09, 0x18, 0x40, 
+-      0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 0x68, 0x00, 
+-      0x04, 0x00, 0x0c, 0x00, 0xd0, 0x0b, 0x20, 0x4c, 
+-      0x43, 0x78, 0x49, 0x35, 0x68, 0x09, 0x18, 0x40, 
+-      0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 0x68, 0x00, 
+-      0x0c, 0x00, 0x04, 0x00, 0xd1, 0x0a, 0x20, 0x02, 
+-      0x21, 0x4c, 0x43, 0x79, 0x4a, 0x2e, 0x68, 0x12, 
+-      0x18, 0x89, 0x39, 0xff, 0x39, 0xff, 0x39, 0x82, 
+-      0x67, 0x48, 0xe0, 0x09, 0x20, 0x03, 0x21, 0x4c, 
+-      0x43, 0x79, 0x4a, 0x29, 0x68, 0x12, 0x18, 0x89, 
+-      0x39, 0xff, 0x39, 0xff, 0x39, 0x82, 0x67, 0x48, 
+-      0x49, 0x24, 0x20, 0x91, 0xf0, 0x0f, 0xff, 0x06, 
+-      0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 0x48, 0x22, 
+-      0x68, 0x00, 0x90, 0x01, 0x48, 0x21, 0x68, 0x00, 
+-      0x49, 0x1f, 0x60, 0x08, 0x98, 0x01, 0x49, 0x1f, 
+-      0x60, 0x08, 0x20, 0x92, 0x49, 0x1b, 0x60, 0x08, 
+-      0xb0, 0x02, 0x48, 0x15, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x1d, 0x98, 0x00, 0x01, 0x00, 0x4b, 0x1a, 
+-      0x18, 0xc1, 0x91, 0x01, 0x1d, 0xe0, 0x30, 0x0d, 
+-      0x90, 0x02, 0x98, 0x02, 0x68, 0x00, 0x99, 0x01, 
+-      0x60, 0x08, 0x48, 0x0e, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x0d, 0x68, 0x68, 0x08, 0x80, 0x99, 0x06, 
+-      0x00, 0x89, 0x4b, 0x12, 0x18, 0xc9, 0x67, 0x08, 
+-      0x98, 0x05, 0x43, 0x30, 0x99, 0x06, 0x00, 0x89, 
+-      0x4b, 0x0f, 0x18, 0xc9, 0x61, 0x08, 0x20, 0x92, 
+-      0x49, 0x06, 0x60, 0x08, 0x20, 0x00, 0xb0, 0x07, 
+-      0xe6, 0x91, 0xb0, 0x07, 0xe6, 0x8f, 0x00, 0x00, 
+-      0x2e, 0x08, 0x94, 0x84, 0x2e, 0x08, 0x60, 0x84, 
+-      0xff, 0x00, 0xff, 0xff, 0x2e, 0x08, 0x7c, 0xc0, 
+-      0x2e, 0x08, 0x7c, 0x58, 0x2e, 0x08, 0x94, 0x88, 
+-      0x2e, 0x08, 0x7d, 0xb4, 0x2e, 0x08, 0x7d, 0xb8, 
+-      0x68, 0x00, 0x0c, 0x00, 0x68, 0x00, 0x0e, 0x00, 
+-      0x68, 0x00, 0x0e, 0x80, 0x1c, 0x01, 0x1c, 0x0a, 
+-      0x6a, 0x53, 0x1c, 0x18, 0x47, 0x70, 0xe7, 0xfd, 
+-      0xb5, 0xf3, 0x1c, 0x0f, 0xb0, 0x82, 0x48, 0x2b, 
+-      0x68, 0x00, 0x28, 0x00, 0xd0, 0x05, 0x20, 0x8a, 
+-      0xb0, 0x02, 0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x98, 0x02, 0x90, 0x01, 0x98, 0x01, 
+-      0x88, 0x44, 0x98, 0x01, 0x78, 0x06, 0x23, 0xff, 
+-      0x33, 0x01, 0x42, 0x9c, 0xdd, 0x02, 0x20, 0xff, 
+-      0xb0, 0x02, 0xe7, 0xee, 0x19, 0x30, 0x23, 0xff, 
+-      0x33, 0x01, 0x42, 0x98, 0xdd, 0x02, 0x20, 0xff, 
+-      0xb0, 0x02, 0xe7, 0xe6, 0x49, 0x1c, 0x20, 0x91, 
+-      0xf0, 0x0f, 0xfe, 0x88, 0x28, 0x92, 0xd0, 0x03, 
+-      0x20, 0x01, 0xf0, 0x01, 0xfe, 0x6f, 0xe7, 0xf5, 
+-      0x2c, 0x10, 0xda, 0x0d, 0x25, 0x00, 0x42, 0xa5, 
+-      0xdb, 0x02, 0xe0, 0x08, 0x35, 0x01, 0xe7, 0xfa, 
+-      0xcf, 0x01, 0x19, 0x71, 0x00, 0x89, 0x4b, 0x13, 
+-      0x18, 0xc9, 0x60, 0x08, 0xe7, 0xf6, 0xe0, 0x15, 
+-      0x4a, 0x11, 0x43, 0x22, 0x92, 0x00, 0x20, 0x91, 
+-      0x49, 0x10, 0x60, 0x08, 0x00, 0xb0, 0x4b, 0x0d, 
+-      0x18, 0xc1, 0x9a, 0x00, 0x1c, 0x38, 0x23, 0x02, 
+-      0xf0, 0x00, 0xfa, 0xfe, 0x28, 0x00, 0xd0, 0x00, 
+-      0xe7, 0xf4, 0x48, 0x0a, 0x68, 0x00, 0x28, 0x92, 
+-      0xd0, 0x00, 0xe7, 0xfa, 0x20, 0x92, 0x49, 0x04, 
+-      0x60, 0x08, 0x20, 0x00, 0xb0, 0x02, 0xe7, 0xb0, 
+-      0xb0, 0x02, 0xe7, 0xae, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x7c, 0xc4, 0x68, 0x00, 0x08, 0x00, 
+-      0xf0, 0x00, 0x00, 0x00, 0x2e, 0x08, 0x7c, 0xc8, 
+-      0x21, 0x04, 0xe0, 0x00, 0x31, 0x01, 0x1c, 0x08, 
+-      0x47, 0x70, 0xe7, 0xfd, 0xb5, 0xf3, 0x1c, 0x0f, 
+-      0xb0, 0x82, 0x48, 0x2b, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x05, 0x20, 0x8a, 0xb0, 0x02, 0xb0, 0x02, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x98, 0x02, 
+-      0x90, 0x01, 0x98, 0x01, 0x88, 0x44, 0x98, 0x01, 
+-      0x78, 0x06, 0x23, 0xff, 0x33, 0x01, 0x42, 0x9c, 
+-      0xdd, 0x02, 0x20, 0xff, 0xb0, 0x02, 0xe7, 0xee, 
+-      0x19, 0x30, 0x23, 0xff, 0x33, 0x01, 0x42, 0x98, 
+-      0xdd, 0x02, 0x20, 0xff, 0xb0, 0x02, 0xe7, 0xe6, 
+-      0x49, 0x1c, 0x20, 0x91, 0xf0, 0x0f, 0xfe, 0x1e, 
+-      0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 0xf0, 0x01, 
+-      0xfe, 0x05, 0xe7, 0xf5, 0x2c, 0x10, 0xda, 0x0d, 
+-      0x25, 0x00, 0x42, 0xa5, 0xdb, 0x02, 0xe0, 0x08, 
+-      0x35, 0x01, 0xe7, 0xfa, 0x19, 0x70, 0x00, 0x80, 
+-      0x4b, 0x13, 0x18, 0xc0, 0x68, 0x01, 0xc7, 0x02, 
+-      0xe7, 0xf6, 0xe0, 0x15, 0x4a, 0x11, 0x43, 0x22, 
+-      0x92, 0x00, 0x20, 0x91, 0x49, 0x10, 0x60, 0x08, 
+-      0x00, 0xb0, 0x4b, 0x0d, 0x18, 0xc0, 0x9a, 0x00, 
+-      0x1c, 0x39, 0x23, 0x02, 0xf0, 0x00, 0xfa, 0x94, 
+-      0x28, 0x00, 0xd0, 0x00, 0xe7, 0xf4, 0x48, 0x0a, 
+-      0x68, 0x00, 0x28, 0x92, 0xd0, 0x00, 0xe7, 0xfa, 
+-      0x20, 0x92, 0x49, 0x04, 0x60, 0x08, 0x20, 0x00, 
+-      0xb0, 0x02, 0xe7, 0xb0, 0xb0, 0x02, 0xe7, 0xae, 
+-      0x2e, 0x08, 0x60, 0x84, 0x2e, 0x08, 0x7c, 0xc4, 
+-      0x68, 0x00, 0x08, 0x00, 0xf0, 0x00, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7c, 0xc8, 0xb5, 0xf7, 0x9a, 0x02, 
+-      0x06, 0x15, 0x0e, 0x2d, 0x9c, 0x00, 0x88, 0x66, 
+-      0x42, 0xb5, 0xdd, 0x04, 0x20, 0xff, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x78, 0x20, 
+-      0x19, 0x40, 0x06, 0x07, 0x0e, 0x3f, 0x23, 0xff, 
+-      0x33, 0x01, 0x42, 0x9f, 0xdd, 0x01, 0x20, 0xff, 
+-      0xe7, 0xf1, 0x49, 0x0a, 0x20, 0x91, 0xf0, 0x0f, 
+-      0xfd, 0xc5, 0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 
+-      0xf0, 0x01, 0xfd, 0xac, 0xe7, 0xf5, 0x99, 0x01, 
+-      0x00, 0xb8, 0x4b, 0x05, 0x18, 0xc0, 0x60, 0x01, 
+-      0x20, 0x92, 0x49, 0x02, 0x60, 0x08, 0x20, 0x00, 
+-      0xe7, 0xdd, 0xe7, 0xdc, 0x2e, 0x08, 0x7c, 0xc4, 
+-      0x68, 0x00, 0x08, 0x00, 0xb5, 0xf7, 0x9a, 0x02, 
+-      0x06, 0x14, 0x0e, 0x24, 0x9f, 0x00, 0x88, 0x7d, 
+-      0x78, 0x38, 0x19, 0x00, 0x06, 0x06, 0x0e, 0x36, 
+-      0x42, 0xac, 0xdd, 0x04, 0x20, 0xff, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x49, 0x0b, 
+-      0x20, 0x91, 0xf0, 0x0f, 0xfd, 0x9b, 0x28, 0x92, 
+-      0xd0, 0x03, 0x20, 0x01, 0xf0, 0x01, 0xfd, 0x82, 
+-      0xe7, 0xf5, 0x00, 0xb0, 0x4b, 0x06, 0x18, 0xc0, 
+-      0x68, 0x00, 0x99, 0x01, 0x60, 0x08, 0x20, 0x92, 
+-      0x49, 0x02, 0x60, 0x08, 0x20, 0x00, 0xe7, 0xe6, 
+-      0xe7, 0xe5, 0x00, 0x00, 0x2e, 0x08, 0x7c, 0xc4, 
+-      0x68, 0x00, 0x08, 0x00, 0x1c, 0x01, 0x1c, 0x0a, 
+-      0x88, 0x50, 0x47, 0x70, 0xe7, 0xfd, 0xb4, 0x80, 
+-      0x1c, 0x01, 0x1c, 0x0f, 0x69, 0x3a, 0x2a, 0x08, 
+-      0xd2, 0x12, 0xa3, 0x02, 0x5c, 0x9b, 0x00, 0x5b, 
+-      0x44, 0x9f, 0x1c, 0x00, 0x04, 0x07, 0x09, 0x0b, 
+-      0x04, 0x07, 0x09, 0x0b, 0x20, 0x02, 0xbc, 0x80, 
+-      0x47, 0x70, 0x20, 0x04, 0xe7, 0xfb, 0x20, 0x10, 
+-      0xe7, 0xf9, 0x20, 0xff, 0x30, 0x01, 0xe7, 0xf6, 
+-      0x20, 0x00, 0xe7, 0xf4, 0xe7, 0xf3, 0xb5, 0xf3, 
+-      0x98, 0x00, 0x06, 0x05, 0x0e, 0x2d, 0x48, 0x89, 
+-      0x68, 0x00, 0x28, 0x00, 0xd1, 0x04, 0x20, 0x8b, 
+-      0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x48, 0x85, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x04, 
+-      0x2d, 0x17, 0xdd, 0x02, 0x20, 0x8c, 0xe7, 0xf3, 
+-      0xe0, 0xfe, 0x2d, 0x07, 0xdd, 0x01, 0x20, 0x8c, 
+-      0xe7, 0xee, 0x49, 0x80, 0x20, 0x91, 0xf0, 0x0f, 
+-      0xfd, 0x45, 0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 
+-      0xf0, 0x01, 0xfd, 0x2c, 0xe7, 0xf5, 0x1c, 0x28, 
+-      0xf7, 0xf8, 0xfc, 0xd8, 0x1c, 0x04, 0x2c, 0x00, 
+-      0xd0, 0x09, 0x68, 0xa0, 0x4b, 0x78, 0x40, 0x18, 
+-      0x99, 0x01, 0x07, 0xc9, 0x09, 0xc9, 0x43, 0x08, 
+-      0x60, 0xa0, 0x01, 0xc0, 0xe0, 0x04, 0x20, 0x92, 
+-      0x49, 0x72, 0x60, 0x08, 0x20, 0xff, 0xe7, 0xcf, 
+-      0x48, 0x6f, 0x68, 0x00, 0x28, 0x00, 0xd1, 0x11, 
+-      0x99, 0x01, 0x29, 0x00, 0xd0, 0x06, 0x48, 0x6f, 
+-      0x21, 0x01, 0x40, 0xa9, 0x68, 0x02, 0x43, 0x11, 
+-      0x60, 0x01, 0xe0, 0x06, 0x48, 0x6b, 0x21, 0x01, 
+-      0x40, 0xa9, 0x43, 0xc9, 0x68, 0x02, 0x40, 0x11, 
+-      0x60, 0x01, 0xe0, 0xbf, 0x68, 0xe0, 0xf0, 0x02, 
+-      0xfc, 0x3b, 0x28, 0x00, 0xd0, 0x73, 0xb0, 0x81, 
+-      0x49, 0x65, 0x20, 0x91, 0xf0, 0x0f, 0xfd, 0x0a, 
+-      0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 0xf0, 0x02, 
+-      0xfc, 0x8a, 0x20, 0x92, 0x49, 0x60, 0x60, 0x08, 
+-      0x20, 0x01, 0x49, 0x60, 0x68, 0x09, 0x60, 0x08, 
+-      0x27, 0x00, 0x26, 0x00, 0x2e, 0x00, 0xd1, 0x14, 
+-      0x2f, 0x07, 0xd2, 0x12, 0x6a, 0xe0, 0x05, 0x81, 
+-      0x0d, 0x89, 0x1c, 0x38, 0x37, 0x01, 0x00, 0x83, 
+-      0x18, 0x18, 0x00, 0xc0, 0x4a, 0x57, 0x68, 0x12, 
+-      0x18, 0x80, 0x23, 0x05, 0x02, 0x1b, 0x18, 0xc0, 
+-      0x6f, 0xc0, 0x42, 0x81, 0xd1, 0x00, 0x26, 0x01, 
+-      0xe7, 0xe8, 0x2e, 0x00, 0xd1, 0x13, 0x2f, 0x18, 
+-      0xd2, 0x11, 0x6a, 0xe0, 0x05, 0x81, 0x0d, 0x89, 
+-      0x1c, 0x38, 0x37, 0x01, 0x23, 0x4c, 0x43, 0x58, 
+-      0x4a, 0x4c, 0x68, 0x12, 0x18, 0x80, 0x38, 0xff, 
+-      0x38, 0xff, 0x38, 0x02, 0x69, 0x40, 0x42, 0x81, 
+-      0xd1, 0x00, 0x26, 0x01, 0xe7, 0xe9, 0x3f, 0x01, 
+-      0x2f, 0x07, 0xd2, 0x32, 0x99, 0x02, 0x29, 0x00, 
+-      0xd0, 0x16, 0x00, 0xb8, 0x19, 0xc0, 0x00, 0xc0, 
+-      0x49, 0x42, 0x68, 0x09, 0x18, 0x40, 0x23, 0x05, 
+-      0x02, 0x1b, 0x18, 0xc0, 0x6e, 0x80, 0x4b, 0x40, 
+-      0x43, 0x18, 0x00, 0xb9, 0x19, 0xc9, 0x00, 0xc9, 
+-      0x4a, 0x3c, 0x68, 0x12, 0x18, 0x89, 0x23, 0x05, 
+-      0x02, 0x1b, 0x18, 0xc9, 0x66, 0x88, 0xe0, 0x17, 
+-      0x00, 0xb8, 0x19, 0xc0, 0x00, 0xc0, 0x49, 0x37, 
+-      0x68, 0x09, 0x18, 0x40, 0x23, 0x05, 0x02, 0x1b, 
+-      0x18, 0xc0, 0x6e, 0x80, 0x04, 0x00, 0x0c, 0x00, 
+-      0x00, 0xb9, 0x19, 0xc9, 0x00, 0xc9, 0x4a, 0x31, 
+-      0x68, 0x12, 0x18, 0x89, 0x23, 0x05, 0x02, 0x1b, 
+-      0x18, 0xc9, 0x66, 0x88, 0xe0, 0x00, 0xe0, 0x45, 
+-      0xe0, 0x2b, 0x99, 0x02, 0x29, 0x00, 0xd0, 0x14, 
+-      0x20, 0x4c, 0x43, 0x78, 0x49, 0x29, 0x68, 0x09, 
+-      0x18, 0x40, 0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 
+-      0x68, 0x00, 0x4b, 0x27, 0x43, 0x18, 0x21, 0x4c, 
+-      0x43, 0x79, 0x4a, 0x24, 0x68, 0x12, 0x18, 0x89, 
+-      0x39, 0xff, 0x39, 0xff, 0x39, 0x02, 0x60, 0x08, 
+-      0xe0, 0x13, 0x20, 0x4c, 0x43, 0x78, 0x49, 0x1f, 
+-      0x68, 0x09, 0x18, 0x40, 0x38, 0xff, 0x38, 0xff, 
+-      0x38, 0x02, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x00, 
+-      0x21, 0x4c, 0x43, 0x79, 0x4a, 0x19, 0x68, 0x12, 
+-      0x18, 0x89, 0x39, 0xff, 0x39, 0xff, 0x39, 0x02, 
+-      0x60, 0x08, 0x48, 0x16, 0x68, 0x00, 0xf0, 0x02, 
+-      0xfc, 0x05, 0x49, 0x13, 0x20, 0x91, 0xf0, 0x0f, 
+-      0xfc, 0x65, 0x28, 0x92, 0xd0, 0x00, 0xe7, 0xf8, 
+-      0x48, 0x10, 0x68, 0x00, 0x90, 0x00, 0x48, 0x11, 
+-      0x68, 0x00, 0x49, 0x0e, 0x60, 0x08, 0x98, 0x00, 
+-      0x49, 0x0e, 0x60, 0x08, 0x20, 0x92, 0x49, 0x0a, 
+-      0x60, 0x08, 0xb0, 0x01, 0x20, 0x92, 0x49, 0x05, 
+-      0x60, 0x08, 0x20, 0x00, 0xe6, 0xf4, 0xe6, 0xf3, 
+-      0xe6, 0xf2, 0x00, 0x00, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x94, 0x84, 0x2e, 0x08, 0x7c, 0xc4, 
+-      0xfe, 0xff, 0xff, 0xff, 0x68, 0x00, 0x00, 0x20, 
+-      0x2e, 0x08, 0x94, 0x88, 0x2e, 0x08, 0x7d, 0xb4, 
+-      0xff, 0xff, 0x00, 0x00, 0x2e, 0x08, 0x7d, 0xb8, 
+-      0xb5, 0xf0, 0x1c, 0x04, 0x1c, 0x0f, 0x06, 0x26, 
+-      0x0e, 0x36, 0x48, 0x0f, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x03, 0x20, 0x8b, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x2e, 0x07, 0xdd, 0x01, 0x20, 0x8c, 
+-      0xe7, 0xf8, 0x1c, 0x30, 0xf7, 0xf8, 0xfb, 0xc2, 
+-      0x1c, 0x05, 0x2d, 0x00, 0xd0, 0x04, 0x68, 0xa8, 
+-      0x01, 0xc0, 0x0f, 0xc0, 0x60, 0x38, 0xe0, 0x04, 
+-      0x20, 0x92, 0x49, 0x04, 0x60, 0x08, 0x20, 0xff, 
+-      0xe7, 0xe8, 0x20, 0x00, 0xe7, 0xe6, 0xe7, 0xe5, 
+-      0x2e, 0x08, 0x60, 0x84, 0x2e, 0x08, 0x7c, 0xc4, 
+-      0xb5, 0xb0, 0x1c, 0x04, 0x1c, 0x0f, 0x06, 0x25, 
+-      0x0e, 0x2d, 0x48, 0x20, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x03, 0x20, 0x8b, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x48, 0x1d, 0x68, 0x00, 0x28, 0x01, 
+-      0xd1, 0x04, 0x2d, 0x17, 0xdd, 0x02, 0x20, 0x8c, 
+-      0xe7, 0xf4, 0xe0, 0x2d, 0x2d, 0x07, 0xdd, 0x01, 
+-      0x20, 0x8c, 0xe7, 0xef, 0x48, 0x16, 0x68, 0x00, 
+-      0x28, 0x00, 0xd0, 0x01, 0x20, 0xff, 0xe7, 0xe9, 
+-      0x49, 0x14, 0x20, 0x91, 0xf0, 0x0f, 0xfb, 0xee, 
+-      0x28, 0x92, 0xd0, 0x03, 0x20, 0x01, 0xf0, 0x01, 
+-      0xfb, 0xd5, 0xe7, 0xf5, 0x2f, 0x00, 0xd0, 0x08, 
+-      0x48, 0x0f, 0x1d, 0xe9, 0x31, 0x01, 0x22, 0x01, 
+-      0x40, 0x8a, 0x68, 0x01, 0x43, 0x11, 0x60, 0x01, 
+-      0xe0, 0x08, 0x48, 0x0b, 0x1d, 0xea, 0x32, 0x01, 
+-      0x21, 0x01, 0x40, 0x91, 0x43, 0xc9, 0x68, 0x02, 
+-      0x40, 0x11, 0x60, 0x01, 0x20, 0x92, 0x49, 0x05, 
+-      0x60, 0x08, 0x20, 0x00, 0xe7, 0xc6, 0xe7, 0xc5, 
+-      0xe7, 0xc4, 0x00, 0x00, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x94, 0x84, 0x2e, 0x08, 0x7c, 0xc4, 
+-      0x68, 0x00, 0x00, 0x20, 0xb4, 0x90, 0x1c, 0x07, 
+-      0x1c, 0x0a, 0x06, 0x39, 0x0e, 0x09, 0x48, 0x10, 
+-      0x68, 0x00, 0x28, 0x00, 0xd1, 0x02, 0x20, 0x8b, 
+-      0xbc, 0x90, 0x47, 0x70, 0x29, 0x07, 0xdd, 0x01, 
+-      0x20, 0x8c, 0xe7, 0xf9, 0x48, 0x0b, 0x68, 0x00, 
+-      0x28, 0x00, 0xd0, 0x01, 0x20, 0xff, 0xe7, 0xf3, 
+-      0x1d, 0xc8, 0x30, 0x01, 0x24, 0x01, 0x40, 0x84, 
+-      0x1c, 0x23, 0x20, 0x0d, 0x06, 0xc0, 0x6a, 0x00, 
+-      0x40, 0x18, 0x1d, 0xcc, 0x34, 0x01, 0x40, 0xe0, 
+-      0x60, 0x10, 0x20, 0x00, 0xe7, 0xe4, 0xe7, 0xe3, 
+-      0x2e, 0x08, 0x60, 0x84, 0x2e, 0x08, 0x94, 0x84, 
+-      0xb5, 0xb0, 0x1c, 0x04, 0x1c, 0x0f, 0x06, 0x25, 
+-      0x0e, 0x2d, 0x48, 0x13, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x03, 0x20, 0x8b, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x2d, 0x07, 0xdd, 0x01, 0x20, 0x8c, 
+-      0xe7, 0xf8, 0x48, 0x0e, 0x68, 0x00, 0x28, 0x00, 
+-      0xd0, 0x01, 0x20, 0xff, 0xe7, 0xf2, 0x49, 0x0c, 
+-      0x20, 0x91, 0xf0, 0x0f, 0xfb, 0x7f, 0x28, 0x92, 
+-      0xd0, 0x03, 0x20, 0x01, 0xf0, 0x01, 0xfb, 0x66, 
+-      0xe7, 0xf5, 0x08, 0xb8, 0x00, 0xa9, 0x4b, 0x07, 
+-      0x18, 0xc9, 0x67, 0x08, 0x20, 0x92, 0x49, 0x04, 
+-      0x60, 0x08, 0x20, 0x00, 0xe7, 0xde, 0xe7, 0xdd, 
+-      0x2e, 0x08, 0x60, 0x84, 0x2e, 0x08, 0x94, 0x84, 
+-      0x2e, 0x08, 0x7c, 0xc4, 0x68, 0x00, 0x0e, 0x00, 
+-      0xb4, 0xf0, 0x1c, 0x05, 0x1c, 0x0c, 0x1c, 0x17, 
+-      0x1c, 0x1e, 0x04, 0x3f, 0x0c, 0x3f, 0x1c, 0x39, 
+-      0x29, 0x00, 0xd8, 0x02, 0xe0, 0x04, 0x39, 0x01, 
+-      0xe7, 0xfa, 0xcd, 0x04, 0xc4, 0x04, 0xe7, 0xfa, 
+-      0x20, 0x92, 0x4a, 0x03, 0x60, 0x10, 0x20, 0x00, 
+-      0xbc, 0xf0, 0x47, 0x70, 0xe7, 0xfc, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7c, 0xc8, 0x20, 0x00, 0x6b, 0x00, 
+-      0x49, 0x63, 0x60, 0x08, 0x20, 0x00, 0x6b, 0x40, 
+-      0x49, 0x62, 0x60, 0x08, 0x48, 0x62, 0x49, 0x63, 
+-      0x60, 0x08, 0x48, 0x63, 0x49, 0x63, 0x60, 0x08, 
+-      0x20, 0x00, 0x6a, 0xc0, 0x49, 0x62, 0x60, 0x08, 
+-      0x48, 0x62, 0x49, 0x63, 0x60, 0x08, 0x48, 0x63, 
+-      0x49, 0x63, 0x60, 0x08, 0x48, 0x63, 0x49, 0x64, 
+-      0x60, 0x08, 0x20, 0x00, 0x6b, 0x80, 0x49, 0x63, 
+-      0x60, 0x08, 0x20, 0x00, 0x6b, 0xc0, 0x49, 0x62, 
+-      0x60, 0x08, 0x20, 0x00, 0x6c, 0x00, 0x49, 0x61, 
+-      0x60, 0x08, 0x20, 0x00, 0x6c, 0x40, 0x49, 0x60, 
+-      0x60, 0x08, 0x20, 0x00, 0x6c, 0x80, 0x49, 0x5f, 
+-      0x60, 0x08, 0x20, 0x00, 0x6c, 0xc0, 0x49, 0x5e, 
+-      0x60, 0x08, 0x20, 0x00, 0x6e, 0xc0, 0x49, 0x5d, 
+-      0x60, 0x08, 0x20, 0x80, 0x6d, 0x00, 0x49, 0x5c, 
+-      0x60, 0x08, 0x20, 0x80, 0x6d, 0x40, 0x49, 0x5b, 
+-      0x60, 0x08, 0x20, 0x80, 0x6d, 0x80, 0x49, 0x5a, 
+-      0x60, 0x08, 0x20, 0x00, 0x6d, 0x00, 0x49, 0x59, 
+-      0x60, 0x08, 0x20, 0x00, 0x6d, 0x40, 0x49, 0x58, 
+-      0x60, 0x08, 0x20, 0x00, 0x6d, 0x80, 0x49, 0x57, 
+-      0x60, 0x08, 0x20, 0x00, 0x6d, 0xc0, 0x49, 0x56, 
+-      0x60, 0x08, 0x20, 0x80, 0x6a, 0xc0, 0x49, 0x55, 
+-      0x60, 0x08, 0x20, 0x80, 0x6d, 0xc0, 0x49, 0x54, 
+-      0x60, 0x08, 0x20, 0x80, 0x6c, 0xc0, 0x49, 0x53, 
+-      0x60, 0x08, 0x20, 0x80, 0x68, 0x40, 0x49, 0x52, 
+-      0x60, 0x08, 0x20, 0x80, 0x68, 0x80, 0x49, 0x51, 
+-      0x60, 0x08, 0x20, 0x80, 0x68, 0xc0, 0x49, 0x50, 
+-      0x60, 0x08, 0x20, 0x80, 0x69, 0x00, 0x49, 0x4f, 
+-      0x60, 0x08, 0x20, 0x80, 0x69, 0x40, 0x49, 0x4e, 
+-      0x60, 0x08, 0x20, 0x80, 0x69, 0x80, 0x49, 0x4d, 
+-      0x60, 0x08, 0x20, 0x80, 0x69, 0xc0, 0x49, 0x4c, 
+-      0x60, 0x08, 0x20, 0x80, 0x6a, 0x00, 0x49, 0x4b, 
+-      0x60, 0x08, 0x20, 0x80, 0x6a, 0x40, 0x49, 0x4a, 
+-      0x60, 0x08, 0x20, 0x80, 0x6a, 0x80, 0x49, 0x49, 
+-      0x60, 0x08, 0x20, 0x00, 0x6f, 0x00, 0x49, 0x48, 
+-      0x60, 0x08, 0x20, 0x00, 0x6f, 0x40, 0x49, 0x47, 
+-      0x60, 0x08, 0x20, 0x80, 0x6c, 0x40, 0x49, 0x46, 
+-      0x60, 0x08, 0x20, 0x80, 0x6c, 0x80, 0x49, 0x45, 
+-      0x60, 0x08, 0x20, 0x80, 0x6e, 0x40, 0x49, 0x44, 
+-      0x60, 0x08, 0x20, 0x80, 0x6e, 0x80, 0x49, 0x43, 
+-      0x60, 0x08, 0x20, 0x00, 0x49, 0x42, 0x60, 0x08, 
+-      0x20, 0x00, 0x49, 0x41, 0x60, 0x48, 0x48, 0x41, 
+-      0x49, 0x3f, 0x60, 0x88, 0x48, 0x40, 0x49, 0x3e, 
+-      0x60, 0xc8, 0x20, 0xff, 0x30, 0x01, 0x68, 0x40, 
+-      0x49, 0x3e, 0x60, 0x08, 0x20, 0x80, 0x6e, 0xc0, 
+-      0x49, 0x3d, 0x60, 0x08, 0x20, 0x80, 0x6f, 0x00, 
+-      0x49, 0x3c, 0x60, 0x08, 0x20, 0x80, 0x6f, 0x40, 
+-      0x49, 0x3b, 0x60, 0x08, 0x20, 0x80, 0x6f, 0x80, 
+-      0x49, 0x3a, 0x60, 0x08, 0x20, 0x80, 0x6f, 0xc0, 
+-      0x49, 0x39, 0x60, 0x08, 0x20, 0xff, 0x30, 0x01, 
+-      0x68, 0x80, 0x49, 0x38, 0x60, 0x08, 0x47, 0x70, 
+-      0x2e, 0x08, 0x5d, 0xbc, 0x2e, 0x08, 0x5d, 0xc0, 
+-      0x64, 0x00, 0x05, 0x00, 0x2e, 0x08, 0x5d, 0xc8, 
+-      0x64, 0x00, 0x00, 0x80, 0x2e, 0x08, 0x5d, 0xcc, 
+-      0x2e, 0x08, 0x5d, 0xc4, 0x64, 0x00, 0x04, 0x00, 
+-      0x2e, 0x08, 0x5d, 0xd0, 0x9e, 0x00, 0x00, 0x00, 
+-      0x2e, 0x08, 0x5d, 0xe8, 0x9e, 0x00, 0x05, 0x00, 
+-      0x2e, 0x08, 0x5d, 0xd4, 0x2e, 0x08, 0x94, 0x9c, 
+-      0x2e, 0x08, 0x94, 0xa0, 0x2e, 0x08, 0x94, 0xa4, 
+-      0x2e, 0x08, 0x94, 0xa8, 0x2e, 0x08, 0x5d, 0xd8, 
+-      0x2e, 0x08, 0x5d, 0xdc, 0x2e, 0x08, 0x5d, 0xec, 
+-      0x2e, 0x08, 0x5d, 0xf0, 0x2e, 0x08, 0x5d, 0xf4, 
+-      0x2e, 0x08, 0x5d, 0xf8, 0x2e, 0x08, 0x5d, 0xe0, 
+-      0x2e, 0x08, 0x5d, 0xe4, 0x2e, 0x08, 0x60, 0x6c, 
+-      0x2e, 0x08, 0x60, 0x70, 0x2e, 0x08, 0x5d, 0xfc, 
+-      0x2e, 0x08, 0x5e, 0x00, 0x2e, 0x08, 0x5e, 0x2c, 
+-      0x2e, 0x08, 0x5e, 0x04, 0x2e, 0x08, 0x5e, 0x08, 
+-      0x2e, 0x08, 0x5e, 0x0c, 0x2e, 0x08, 0x5e, 0x10, 
+-      0x2e, 0x08, 0x5e, 0x14, 0x2e, 0x08, 0x5e, 0x18, 
+-      0x2e, 0x08, 0x5e, 0x1c, 0x2e, 0x08, 0x5e, 0x20, 
+-      0x2e, 0x08, 0x5e, 0x24, 0x2e, 0x08, 0x5e, 0x28, 
+-      0x2e, 0x08, 0x5d, 0xb0, 0x2e, 0x08, 0x5d, 0xb4, 
+-      0x2e, 0x08, 0x7c, 0x44, 0x2e, 0x08, 0x5e, 0x54, 
+-      0x2e, 0x08, 0x5e, 0x34, 0x2e, 0x08, 0x60, 0x74, 
+-      0x2e, 0x08, 0x7c, 0x1c, 0xcc, 0x1f, 0xe0, 0x00, 
+-      0xcc, 0x1f, 0xfe, 0x00, 0x2e, 0x08, 0x5e, 0x40, 
+-      0x2e, 0x08, 0x5e, 0x58, 0x2e, 0x08, 0x5e, 0x38, 
+-      0x2e, 0x08, 0x5e, 0x3c, 0x2e, 0x08, 0x7c, 0x40, 
+-      0x2e, 0x08, 0x7c, 0x18, 0x2e, 0x08, 0x5e, 0x48, 
+-      0x49, 0x4f, 0x68, 0x0a, 0x23, 0x04, 0x43, 0x1a, 
+-      0x60, 0x0a, 0x21, 0xff, 0x4a, 0x4d, 0x68, 0x12, 
+-      0x32, 0x40, 0x72, 0x11, 0x21, 0xff, 0x4a, 0x4b, 
+-      0x68, 0x12, 0x32, 0x40, 0x76, 0x11, 0x21, 0xff, 
+-      0x4a, 0x48, 0x68, 0x12, 0x32, 0x60, 0x72, 0x11, 
+-      0x21, 0xff, 0x4a, 0x46, 0x68, 0x12, 0x32, 0x20, 
+-      0x72, 0x11, 0x21, 0xff, 0x4a, 0x43, 0x68, 0x12, 
+-      0x32, 0x20, 0x76, 0x11, 0x21, 0xff, 0x4a, 0x41, 
+-      0x68, 0x12, 0x32, 0x60, 0x76, 0x11, 0x21, 0x00, 
+-      0x4a, 0x3e, 0x68, 0x12, 0x32, 0x40, 0x72, 0x91, 
+-      0x21, 0x00, 0x4a, 0x3c, 0x68, 0x12, 0x32, 0x40, 
+-      0x76, 0x91, 0x21, 0x00, 0x4a, 0x39, 0x68, 0x12, 
+-      0x32, 0x60, 0x72, 0x91, 0x21, 0x00, 0x4a, 0x37, 
+-      0x68, 0x12, 0x32, 0x20, 0x72, 0x91, 0x21, 0x00, 
+-      0x4a, 0x34, 0x68, 0x12, 0x32, 0x20, 0x76, 0x91, 
+-      0x21, 0x00, 0x4a, 0x32, 0x68, 0x12, 0x32, 0x60, 
+-      0x76, 0x91, 0x21, 0x00, 0x4a, 0x2f, 0x68, 0x12, 
+-      0x32, 0x80, 0x70, 0xd1, 0x21, 0x00, 0x4a, 0x2d, 
+-      0x68, 0x12, 0x32, 0x80, 0x70, 0x51, 0x21, 0x00, 
+-      0x4a, 0x2a, 0x68, 0x12, 0x32, 0x80, 0x70, 0x91, 
+-      0x21, 0x00, 0x4a, 0x29, 0x60, 0x11, 0x21, 0x00, 
+-      0x4a, 0x28, 0x64, 0x11, 0x21, 0x03, 0x4a, 0x28, 
+-      0x61, 0x11, 0x49, 0x28, 0x68, 0x0a, 0x4b, 0x28, 
+-      0x43, 0x1a, 0x60, 0x0a, 0x49, 0x26, 0x22, 0x33, 
+-      0x06, 0x52, 0x60, 0x51, 0x21, 0x00, 0x4a, 0x25, 
+-      0x70, 0x11, 0x21, 0x00, 0x4a, 0x23, 0x70, 0x51, 
+-      0x21, 0x00, 0x4a, 0x22, 0x70, 0x91, 0x21, 0x00, 
+-      0x4a, 0x20, 0x70, 0xd1, 0x21, 0x00, 0x4a, 0x1f, 
+-      0x71, 0x11, 0x21, 0x00, 0x4a, 0x1d, 0x71, 0x51, 
+-      0x21, 0x00, 0x4a, 0x1c, 0x71, 0x91, 0x21, 0x00, 
+-      0x4a, 0x1a, 0x71, 0xd1, 0x21, 0x00, 0x4a, 0x19, 
+-      0x72, 0x11, 0x21, 0x00, 0x4a, 0x17, 0x72, 0x51, 
+-      0x21, 0x00, 0x4a, 0x16, 0x72, 0x91, 0x21, 0x00, 
+-      0x4a, 0x14, 0x72, 0xd1, 0x21, 0x00, 0x4a, 0x13, 
+-      0x73, 0x11, 0x21, 0xff, 0x4a, 0x11, 0x70, 0x11, 
+-      0x21, 0x00, 0x4a, 0x10, 0x70, 0x11, 0x21, 0x00, 
+-      0x4a, 0x0e, 0x70, 0x51, 0x20, 0x00, 0x28, 0x20, 
+-      0xdb, 0x04, 0xe0, 0x08, 0x1c, 0x41, 0x06, 0x08, 
+-      0x0e, 0x00, 0xe7, 0xf8, 0x21, 0xff, 0x4a, 0x03, 
+-      0x68, 0x12, 0x54, 0x11, 0xe7, 0xf6, 0x47, 0x70, 
+-      0x66, 0x00, 0x01, 0x18, 0x2e, 0x08, 0x7c, 0x44, 
+-      0x9e, 0x00, 0x0a, 0x00, 0x9e, 0x00, 0x0a, 0x80, 
+-      0x66, 0x00, 0x01, 0x00, 0x66, 0x00, 0x00, 0x08, 
+-      0x23, 0x48, 0x00, 0x00, 0x2e, 0x08, 0x7c, 0x48, 
+-      0xb4, 0x80, 0x1c, 0x07, 0x1c, 0x0a, 0x06, 0x39, 
+-      0x0e, 0x09, 0x29, 0x05, 0xd2, 0x40, 0xa3, 0x02, 
+-      0x5c, 0x5b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x03, 0x14, 0x07, 0x0d, 0x13, 0x00, 0x78, 0x10, 
+-      0x4b, 0x1f, 0x70, 0x18, 0xe0, 0x38, 0x78, 0x50, 
+-      0x4b, 0x1e, 0x68, 0x1b, 0x33, 0x80, 0x71, 0x58, 
+-      0xe0, 0x32, 0x78, 0x10, 0x4b, 0x1b, 0x68, 0x1b, 
+-      0x33, 0x80, 0x71, 0x18, 0xe0, 0x2c, 0xe0, 0x2b, 
+-      0x78, 0x10, 0x4b, 0x17, 0x70, 0x18, 0x78, 0x50, 
+-      0x4b, 0x15, 0x70, 0x58, 0x78, 0x90, 0x4b, 0x14, 
+-      0x70, 0x98, 0x78, 0xd0, 0x4b, 0x12, 0x70, 0xd8, 
+-      0x79, 0x10, 0x4b, 0x11, 0x71, 0x18, 0x79, 0x50, 
+-      0x4b, 0x0f, 0x71, 0x58, 0x79, 0x90, 0x4b, 0x0e, 
+-      0x71, 0x98, 0x79, 0xd0, 0x4b, 0x0c, 0x71, 0xd8, 
+-      0x7a, 0x10, 0x4b, 0x0b, 0x72, 0x18, 0x7a, 0x50, 
+-      0x4b, 0x09, 0x72, 0x58, 0x7a, 0x90, 0x4b, 0x08, 
+-      0x72, 0x98, 0x7a, 0xd0, 0x4b, 0x06, 0x72, 0xd8, 
+-      0x7b, 0x10, 0x4b, 0x05, 0x73, 0x18, 0xe0, 0x03, 
+-      0x20, 0x4a, 0xbc, 0x80, 0x47, 0x70, 0xe7, 0xff, 
+-      0x20, 0x00, 0xe7, 0xfa, 0xe7, 0xf9, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7c, 0x48, 0x2e, 0x08, 0x7c, 0x44, 
+-      0xb5, 0xf3, 0x1c, 0x07, 0x06, 0x3e, 0x0e, 0x36, 
+-      0x99, 0x01, 0x06, 0x0c, 0x0e, 0x24, 0x2e, 0x20, 
+-      0xdb, 0x04, 0x20, 0xa2, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2c, 0x02, 0xd0, 0x03, 
+-      0x2c, 0x03, 0xd0, 0x01, 0x2c, 0x04, 0xd1, 0x0b, 
+-      0x48, 0xb8, 0x68, 0x00, 0x30, 0x20, 0x7a, 0x80, 
+-      0x28, 0x00, 0xd1, 0x39, 0x48, 0xb5, 0x68, 0x00, 
+-      0x30, 0x20, 0x7e, 0x80, 0x28, 0x00, 0xd1, 0x33, 
+-      0x2c, 0x00, 0xd1, 0x17, 0x48, 0xb1, 0x68, 0x00, 
+-      0x30, 0x40, 0x7a, 0x80, 0x28, 0x00, 0xd1, 0x2b, 
+-      0x48, 0xae, 0x68, 0x00, 0x30, 0x40, 0x7e, 0x80, 
+-      0x28, 0x00, 0xd1, 0x25, 0x48, 0xab, 0x68, 0x00, 
+-      0x30, 0x60, 0x7a, 0x80, 0x28, 0x00, 0xd1, 0x1f, 
+-      0x48, 0xa8, 0x68, 0x00, 0x30, 0x20, 0x7e, 0x80, 
+-      0x28, 0x00, 0xd1, 0x19, 0x2c, 0x01, 0xd1, 0x19, 
+-      0x48, 0xa4, 0x68, 0x00, 0x30, 0x40, 0x7a, 0x80, 
+-      0x28, 0x00, 0xd1, 0x11, 0x48, 0xa1, 0x68, 0x00, 
+-      0x30, 0x40, 0x7e, 0x80, 0x28, 0x00, 0xd1, 0x0b, 
+-      0x48, 0x9e, 0x68, 0x00, 0x30, 0x60, 0x7a, 0x80, 
+-      0x28, 0x00, 0xd1, 0x05, 0x48, 0x9b, 0x68, 0x00, 
+-      0x30, 0x20, 0x7a, 0x80, 0x28, 0x00, 0xd0, 0x01, 
+-      0x20, 0x49, 0xe7, 0xb3, 0x48, 0x97, 0x68, 0x00, 
+-      0x55, 0x84, 0x2c, 0xff, 0xd0, 0x73, 0x20, 0x01, 
+-      0x49, 0x95, 0x60, 0x48, 0x2c, 0x05, 0xd2, 0x6f, 
+-      0xa3, 0x01, 0x5d, 0x1b, 0x00, 0x5b, 0x44, 0x9f, 
+-      0x02, 0x34, 0x30, 0x30, 0x30, 0x00, 0x20, 0x02, 
+-      0x49, 0x90, 0x61, 0x88, 0x48, 0x90, 0x6a, 0xc0, 
+-      0x49, 0x90, 0x60, 0x08, 0x48, 0x90, 0x68, 0x01, 
+-      0x23, 0x01, 0x07, 0x5b, 0x43, 0x19, 0x60, 0x01, 
+-      0x48, 0x8e, 0x49, 0x8b, 0x62, 0xc8, 0x48, 0x8c, 
+-      0x68, 0x01, 0x4b, 0x8d, 0x40, 0x19, 0x60, 0x01, 
+-      0x20, 0x01, 0x21, 0x31, 0x06, 0x49, 0x61, 0x88, 
+-      0x20, 0x15, 0x21, 0x31, 0x06, 0x49, 0x61, 0x08, 
+-      0x20, 0x0f, 0x21, 0x31, 0x06, 0x49, 0x61, 0xc8, 
+-      0x20, 0x0c, 0x21, 0x31, 0x06, 0x49, 0x61, 0xc8, 
+-      0x20, 0x54, 0x21, 0x31, 0x06, 0x49, 0x62, 0xc8, 
+-      0x20, 0x37, 0x21, 0x31, 0x06, 0x49, 0x60, 0x88, 
+-      0xe0, 0x56, 0x20, 0x00, 0x49, 0x79, 0x61, 0x88, 
+-      0xe0, 0x52, 0x20, 0x01, 0x49, 0x77, 0x61, 0x88, 
+-      0x20, 0x01, 0x49, 0x7c, 0x62, 0x88, 0x48, 0x7c, 
+-      0x78, 0x00, 0x06, 0x80, 0x0e, 0x80, 0x02, 0x80, 
+-      0x49, 0x79, 0x78, 0x49, 0x07, 0xc9, 0x0d, 0x89, 
+-      0x43, 0x08, 0x49, 0x77, 0x78, 0x89, 0x07, 0xc9, 
+-      0x0d, 0xc9, 0x43, 0x08, 0x49, 0x74, 0x78, 0xc9, 
+-      0x07, 0x89, 0x0f, 0x89, 0x01, 0x89, 0x43, 0x08, 
+-      0x49, 0x71, 0x79, 0x09, 0x07, 0x89, 0x0f, 0x89, 
+-      0x01, 0x09, 0x43, 0x08, 0x49, 0x6e, 0x79, 0x49, 
+-      0x07, 0x89, 0x0f, 0x89, 0x00, 0x89, 0x43, 0x08, 
+-      0x49, 0x6b, 0x79, 0x89, 0x07, 0x89, 0x0f, 0x89, 
+-      0x43, 0x08, 0x49, 0x68, 0x62, 0x08, 0x48, 0x68, 
+-      0x79, 0xc0, 0x07, 0xc0, 0x0e, 0x40, 0x49, 0x66, 
+-      0x7a, 0x09, 0x07, 0xc9, 0xe0, 0x01, 0xe0, 0x21, 
+-      0xe0, 0x18, 0x0e, 0xc9, 0x43, 0x08, 0x49, 0x62, 
+-      0x7a, 0x49, 0x07, 0xc9, 0x0f, 0x09, 0x43, 0x08, 
+-      0x49, 0x5f, 0x7a, 0x89, 0x07, 0xc9, 0x0f, 0x49, 
+-      0x43, 0x08, 0x49, 0x5d, 0x7a, 0xc9, 0x07, 0xc9, 
+-      0x0f, 0x89, 0x43, 0x08, 0x49, 0x5a, 0x7b, 0x09, 
+-      0x07, 0xc9, 0x0f, 0xc9, 0x43, 0x08, 0x49, 0x57, 
+-      0x62, 0x48, 0xe0, 0x01, 0x20, 0x4a, 0xe7, 0x1d, 
+-      0x48, 0x51, 0x68, 0x01, 0x4b, 0x55, 0x40, 0x19, 
+-      0x60, 0x01, 0xe0, 0x8f, 0x48, 0x49, 0x68, 0x00, 
+-      0x30, 0x80, 0x78, 0xc0, 0x28, 0x00, 0xd0, 0x08, 
+-      0x22, 0x00, 0xb4, 0x04, 0x1c, 0x30, 0x23, 0x00, 
+-      0x22, 0x00, 0x49, 0x4f, 0xf7, 0xf4, 0xfc, 0x10, 
+-      0xb0, 0x01, 0x20, 0x00, 0x49, 0x42, 0x60, 0x48, 
+-      0x48, 0x45, 0x68, 0x01, 0x4b, 0x4b, 0x43, 0x19, 
+-      0x60, 0x01, 0x48, 0x4a, 0x21, 0x33, 0x06, 0x49, 
+-      0x60, 0x48, 0x48, 0x49, 0x68, 0x01, 0x23, 0x04, 
+-      0x43, 0x19, 0x60, 0x01, 0x2c, 0x00, 0xd1, 0x0e, 
+-      0x48, 0x3c, 0x68, 0x00, 0x28, 0x00, 0xd0, 0x0a, 
+-      0x48, 0x3a, 0x68, 0x00, 0x49, 0x38, 0x62, 0xc8, 
+-      0x20, 0x00, 0x49, 0x38, 0x60, 0x08, 0x20, 0x00, 
+-      0x21, 0x31, 0x06, 0x49, 0x61, 0x88, 0x20, 0x00, 
+-      0x49, 0x30, 0x68, 0x09, 0x31, 0x80, 0x70, 0x48, 
+-      0x20, 0x00, 0x49, 0x2e, 0x68, 0x09, 0x31, 0x80, 
+-      0x70, 0x88, 0x20, 0x00, 0x49, 0x39, 0x60, 0x08, 
+-      0x20, 0x00, 0x49, 0x39, 0x64, 0x08, 0x20, 0x03, 
+-      0x49, 0x2a, 0x61, 0x08, 0x25, 0x00, 0x2d, 0x20, 
+-      0xd3, 0x02, 0xe0, 0x06, 0x35, 0x01, 0xe7, 0xfa, 
+-      0x20, 0xff, 0x49, 0x24, 0x68, 0x09, 0x55, 0x48, 
+-      0xe7, 0xf8, 0x20, 0xff, 0x49, 0x21, 0x68, 0x09, 
+-      0x31, 0x40, 0x72, 0x08, 0x20, 0xff, 0x49, 0x1f, 
+-      0x68, 0x09, 0x31, 0x40, 0x76, 0x08, 0x20, 0xff, 
+-      0x49, 0x1c, 0x68, 0x09, 0x31, 0x60, 0x72, 0x08, 
+-      0x20, 0xff, 0x49, 0x1a, 0x68, 0x09, 0x31, 0x20, 
+-      0x72, 0x08, 0x20, 0xff, 0x49, 0x17, 0x68, 0x09, 
+-      0x31, 0x20, 0x76, 0x08, 0x20, 0xff, 0x49, 0x15, 
+-      0x68, 0x09, 0x31, 0x60, 0x76, 0x08, 0x20, 0x00, 
+-      0x49, 0x12, 0x68, 0x09, 0x31, 0x40, 0x72, 0x88, 
+-      0x20, 0x00, 0x49, 0x10, 0x68, 0x09, 0x31, 0x40, 
+-      0x76, 0x88, 0x20, 0x00, 0x49, 0x0d, 0x68, 0x09, 
+-      0x31, 0x60, 0x72, 0x88, 0x20, 0x00, 0x49, 0x0b, 
+-      0x68, 0x09, 0x31, 0x20, 0x72, 0x88, 0x20, 0x00, 
+-      0x49, 0x08, 0x68, 0x09, 0x31, 0x20, 0x76, 0x88, 
+-      0x20, 0x00, 0x49, 0x06, 0x68, 0x09, 0x31, 0x60, 
+-      0x76, 0x88, 0x20, 0x00, 0x49, 0x03, 0x68, 0x09, 
+-      0x31, 0x80, 0x70, 0xc8, 0x20, 0x00, 0xe6, 0x85, 
+-      0xe6, 0x84, 0x00, 0x00, 0x2e, 0x08, 0x7c, 0x44, 
+-      0x62, 0x00, 0x03, 0x00, 0x66, 0x00, 0x01, 0x00, 
+-      0xa0, 0x00, 0x0d, 0x80, 0x2e, 0x08, 0x20, 0x08, 
+-      0x66, 0x00, 0x00, 0x08, 0x2e, 0x01, 0x8b, 0xa8, 
+-      0xdf, 0xff, 0xff, 0xff, 0x62, 0x01, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7c, 0x48, 0xfc, 0xb7, 0xff, 0xff, 
+-      0x00, 0x00, 0xff, 0xff, 0x23, 0x48, 0x00, 0x00, 
+-      0x66, 0x00, 0x01, 0x18, 0x9e, 0x00, 0x0a, 0x00, 
+-      0x9e, 0x00, 0x0a, 0x80, 0xb5, 0xf7, 0x1c, 0x17, 
+-      0x98, 0x00, 0x06, 0x02, 0x0e, 0x12, 0x99, 0x01, 
+-      0x06, 0x0d, 0x0e, 0x2d, 0x48, 0x6a, 0x68, 0x00, 
+-      0x5c, 0x81, 0x2a, 0x20, 0xdb, 0x04, 0x20, 0xa2, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x29, 0xff, 0xd1, 0x01, 0x20, 0x4b, 0xe7, 0xf7, 
+-      0x48, 0x64, 0x69, 0x80, 0x28, 0x00, 0xd1, 0x03, 
+-      0x29, 0x04, 0xd1, 0x01, 0x20, 0x58, 0xe7, 0xef, 
+-      0x48, 0x60, 0x69, 0x80, 0x28, 0x00, 0xd1, 0x03, 
+-      0x29, 0x02, 0xd0, 0x01, 0x29, 0x03, 0xd1, 0x0b, 
+-      0x48, 0x5c, 0x69, 0x80, 0x28, 0x02, 0xd1, 0x01, 
+-      0x29, 0x00, 0xd1, 0x05, 0x48, 0x59, 0x69, 0x80, 
+-      0x28, 0x01, 0xd1, 0x03, 0x29, 0x01, 0xd0, 0x01, 
+-      0x20, 0x4d, 0xe7, 0xd9, 0x29, 0x02, 0xd1, 0x05, 
+-      0x48, 0x53, 0x68, 0x00, 0x30, 0x40, 0x7a, 0x80, 
+-      0x28, 0x00, 0xd1, 0x17, 0x29, 0x03, 0xd1, 0x05, 
+-      0x48, 0x4f, 0x68, 0x00, 0x30, 0x40, 0x7e, 0x80, 
+-      0x28, 0x00, 0xd1, 0x0f, 0x29, 0x00, 0xd1, 0x05, 
+-      0x48, 0x4b, 0x68, 0x00, 0x30, 0x20, 0x7a, 0x80, 
+-      0x28, 0x00, 0xd1, 0x07, 0x29, 0x01, 0xd1, 0x07, 
+-      0x48, 0x47, 0x68, 0x00, 0x30, 0x20, 0x7e, 0x80, 
+-      0x28, 0x00, 0xd0, 0x01, 0x20, 0x4e, 0xe7, 0xb7, 
+-      0x68, 0x78, 0x28, 0x00, 0xd1, 0x01, 0x20, 0x4c, 
+-      0xe7, 0xb2, 0x23, 0x01, 0x01, 0x08, 0x4e, 0x40, 
+-      0x68, 0x36, 0x19, 0x80, 0x30, 0x20, 0x72, 0x83, 
+-      0x2d, 0x01, 0xd1, 0x0b, 0x20, 0x33, 0x06, 0x40, 
+-      0x6e, 0x40, 0x23, 0x0d, 0x06, 0x9b, 0x1a, 0xc0, 
+-      0x00, 0xd3, 0x4e, 0x3b, 0x68, 0x36, 0x19, 0x9b, 
+-      0x60, 0x58, 0xe0, 0x12, 0x2d, 0x02, 0xd1, 0x0a, 
+-      0x48, 0x38, 0x6c, 0xc0, 0x23, 0x0d, 0x06, 0x9b, 
+-      0x1a, 0xc3, 0x00, 0xd0, 0x4e, 0x34, 0x68, 0x36, 
+-      0x19, 0x80, 0x60, 0x43, 0xe0, 0x05, 0x68, 0x3b, 
+-      0x00, 0xd0, 0x4e, 0x31, 0x68, 0x36, 0x19, 0x80, 
+-      0x60, 0x43, 0x68, 0x3b, 0x01, 0x08, 0x4e, 0x2c, 
+-      0x68, 0x36, 0x19, 0x80, 0x62, 0x03, 0x68, 0x7b, 
+-      0x01, 0x08, 0x4e, 0x29, 0x68, 0x36, 0x19, 0x80, 
+-      0x62, 0x43, 0x01, 0x08, 0x4b, 0x26, 0x68, 0x1b, 
+-      0x18, 0xc0, 0x62, 0xc7, 0x01, 0x08, 0x4b, 0x24, 
+-      0x68, 0x1b, 0x18, 0xc0, 0x30, 0x20, 0x72, 0x45, 
+-      0x01, 0x08, 0x4b, 0x21, 0x68, 0x1b, 0x18, 0xc0, 
+-      0x30, 0x20, 0x72, 0x02, 0x20, 0x00, 0x60, 0x78, 
+-      0x20, 0x00, 0x72, 0x78, 0x20, 0x00, 0x4b, 0x20, 
+-      0x60, 0x18, 0x20, 0x00, 0x4b, 0x1f, 0x64, 0x18, 
+-      0x01, 0x08, 0x4b, 0x19, 0x68, 0x1b, 0x18, 0xc0, 
+-      0x6a, 0x40, 0x28, 0xbc, 0xdd, 0x01, 0x24, 0xbc, 
+-      0xe0, 0x04, 0x01, 0x08, 0x4b, 0x14, 0x68, 0x1b, 
+-      0x18, 0xc0, 0x6a, 0x44, 0x48, 0x18, 0x60, 0x04, 
+-      0x29, 0x01, 0xd1, 0x14, 0x20, 0x01, 0x4b, 0x17, 
+-      0x62, 0x98, 0x48, 0x17, 0x68, 0x03, 0x04, 0x1b, 
+-      0x0c, 0x1b, 0x60, 0x03, 0x48, 0x14, 0x04, 0x23, 
+-      0x68, 0x06, 0x43, 0x33, 0x60, 0x03, 0x48, 0x13, 
+-      0x68, 0x06, 0x23, 0x20, 0x43, 0x33, 0x60, 0x03, 
+-      0x20, 0x01, 0x4b, 0x0e, 0x63, 0x18, 0x48, 0x07, 
+-      0x69, 0x80, 0x28, 0x00, 0xd1, 0x04, 0x48, 0x0e, 
+-      0x68, 0x06, 0x23, 0x28, 0x43, 0x33, 0x60, 0x03, 
+-      0x20, 0x00, 0xe7, 0x31, 0xe7, 0x30, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7c, 0x44, 0x66, 0x00, 0x01, 0x00, 
+-      0x2e, 0x08, 0x5d, 0xd4, 0x66, 0x00, 0x00, 0x80, 
+-      0x9e, 0x00, 0x0a, 0x00, 0x9e, 0x00, 0x0a, 0x80, 
+-      0x62, 0x00, 0x03, 0x00, 0x62, 0x01, 0x00, 0x00, 
+-      0x62, 0x01, 0x00, 0x20, 0x62, 0x01, 0x00, 0x24, 
+-      0x64, 0x00, 0x00, 0x60, 0xb5, 0xf3, 0x1c, 0x0f, 
+-      0x98, 0x00, 0x06, 0x06, 0x0e, 0x36, 0xb0, 0x82, 
+-      0x4d, 0x68, 0x49, 0x69, 0x91, 0x01, 0x48, 0x69, 
+-      0x68, 0x00, 0x5d, 0x84, 0x2e, 0x20, 0xdb, 0x05, 
+-      0x20, 0xa2, 0xb0, 0x02, 0xb0, 0x02, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2c, 0xff, 0xd1, 0x02, 
+-      0x20, 0x4b, 0xb0, 0x02, 0xe7, 0xf6, 0x48, 0x62, 
+-      0x69, 0x80, 0x28, 0x00, 0xd1, 0x05, 0x2c, 0x02, 
+-      0xd0, 0x03, 0x2c, 0x03, 0xd0, 0x01, 0x2c, 0x04, 
+-      0xd1, 0x0b, 0x48, 0x5d, 0x69, 0x80, 0x28, 0x02, 
+-      0xd1, 0x01, 0x2c, 0x00, 0xd1, 0x05, 0x48, 0x5a, 
+-      0x69, 0x80, 0x28, 0x01, 0xd1, 0x04, 0x2c, 0x01, 
+-      0xd0, 0x02, 0x20, 0x4d, 0xb0, 0x02, 0xe7, 0xdd, 
+-      0x48, 0x54, 0x68, 0x00, 0x30, 0x60, 0x7e, 0x80, 
+-      0x28, 0x00, 0xd0, 0x02, 0x20, 0x4f, 0xb0, 0x02, 
+-      0xe7, 0xd4, 0x48, 0x50, 0x68, 0x00, 0x30, 0x80, 
+-      0x78, 0xc0, 0x28, 0x00, 0xd0, 0x02, 0x20, 0x50, 
+-      0xb0, 0x02, 0xe7, 0xcb, 0x68, 0x78, 0x28, 0x00, 
+-      0xd1, 0x02, 0x20, 0x4c, 0xb0, 0x02, 0xe7, 0xc5, 
+-      0x2c, 0x04, 0xd1, 0x08, 0x68, 0x79, 0x20, 0xbc, 
+-      0xf0, 0x01, 0xff, 0xac, 0x29, 0x00, 0xd0, 0x02, 
+-      0x20, 0x59, 0xb0, 0x02, 0xe7, 0xba, 0x48, 0x43, 
+-      0x68, 0x00, 0x30, 0x80, 0x78, 0x80, 0x21, 0x01, 
+-      0x40, 0x81, 0x48, 0x41, 0x68, 0x40, 0x40, 0x08, 
+-      0x07, 0x80, 0x0f, 0x80, 0xd0, 0x02, 0x20, 0x51, 
+-      0xb0, 0x02, 0xe7, 0xab, 0x20, 0x33, 0x06, 0x40, 
+-      0x6b, 0x80, 0x90, 0x00, 0x23, 0x04, 0x40, 0x18, 
+-      0xd0, 0x02, 0x20, 0x52, 0xb0, 0x02, 0xe7, 0xa1, 
+-      0x2c, 0x00, 0xd1, 0x04, 0x48, 0x37, 0x68, 0x01, 
+-      0x23, 0xfd, 0x40, 0x19, 0x60, 0x01, 0x20, 0x01, 
+-      0x49, 0x32, 0x68, 0x09, 0x31, 0x60, 0x76, 0x88, 
+-      0x68, 0x38, 0x49, 0x30, 0x68, 0x09, 0x67, 0x08, 
+-      0x68, 0x78, 0x49, 0x2e, 0x68, 0x09, 0x67, 0x48, 
+-      0x48, 0x2c, 0x68, 0x00, 0x67, 0xc7, 0x20, 0x00, 
+-      0x49, 0x2a, 0x68, 0x09, 0x31, 0x60, 0x76, 0x48, 
+-      0x48, 0x28, 0x68, 0x00, 0x30, 0x60, 0x76, 0x06, 
+-      0x20, 0x00, 0x60, 0x78, 0x20, 0x00, 0x72, 0x78, 
+-      0x48, 0x24, 0x68, 0x00, 0x5d, 0x80, 0x28, 0x01, 
+-      0xd1, 0x02, 0x20, 0x01, 0x49, 0x24, 0x62, 0x88, 
+-      0x98, 0x00, 0x01, 0x00, 0x19, 0x45, 0x48, 0x1f, 
+-      0x68, 0x00, 0x6f, 0x40, 0x28, 0xbc, 0xdd, 0x07, 
+-      0x48, 0x20, 0x60, 0xa8, 0x20, 0xbc, 0x49, 0x1b, 
+-      0x68, 0x09, 0x31, 0x80, 0x70, 0x08, 0xe0, 0x0d, 
+-      0x48, 0x18, 0x68, 0x00, 0x6f, 0x40, 0x23, 0x01, 
+-      0x07, 0x9b, 0x43, 0x18, 0x60, 0xa8, 0x48, 0x15, 
+-      0x68, 0x00, 0x6f, 0x40, 0x49, 0x13, 0x68, 0x09, 
+-      0x31, 0x80, 0x70, 0x08, 0x48, 0x11, 0x68, 0x00, 
+-      0x30, 0x80, 0x78, 0x80, 0x00, 0x43, 0x18, 0x18, 
+-      0x01, 0x80, 0x99, 0x01, 0x18, 0x41, 0x91, 0x01, 
+-      0x48, 0x0c, 0x68, 0x00, 0x6f, 0x00, 0x60, 0x28, 
+-      0x99, 0x01, 0x1d, 0x08, 0x60, 0x68, 0x20, 0x01, 
+-      0x06, 0x00, 0x60, 0xe8, 0x99, 0x00, 0x20, 0x01, 
+-      0x40, 0x88, 0x21, 0x33, 0x06, 0x49, 0x63, 0x48, 
+-      0x20, 0x00, 0xb0, 0x02, 0xe7, 0x3a, 0xb0, 0x02, 
+-      0xe7, 0x38, 0x00, 0x00, 0x9e, 0x00, 0x09, 0x80, 
+-      0x9e, 0x00, 0x0b, 0x80, 0x2e, 0x08, 0x7c, 0x44, 
+-      0x66, 0x00, 0x01, 0x00, 0x62, 0x00, 0x00, 0x1c, 
+-      0x62, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0xbc, 
+-      0xb5, 0xf3, 0x1c, 0x0f, 0xb0, 0x81, 0x98, 0x01, 
+-      0x06, 0x00, 0x0e, 0x00, 0x90, 0x00, 0xb0, 0x82, 
+-      0x48, 0xf9, 0x68, 0x00, 0x99, 0x02, 0x5c, 0x44, 
+-      0x98, 0x02, 0x28, 0x20, 0xdb, 0x05, 0x20, 0xa2, 
+-      0xb0, 0x03, 0xb0, 0x02, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x2c, 0xff, 0xd1, 0x02, 0x20, 0x4b, 
+-      0xb0, 0x03, 0xe7, 0xf6, 0x48, 0xf1, 0x69, 0x80, 
+-      0x28, 0x00, 0xd1, 0x05, 0x2c, 0x02, 0xd0, 0x03, 
+-      0x2c, 0x03, 0xd0, 0x01, 0x2c, 0x04, 0xd1, 0x0b, 
+-      0x48, 0xec, 0x69, 0x80, 0x28, 0x02, 0xd1, 0x01, 
+-      0x2c, 0x00, 0xd1, 0x05, 0x48, 0xe9, 0x69, 0x80, 
+-      0x28, 0x01, 0xd1, 0x04, 0x2c, 0x01, 0xd0, 0x02, 
+-      0x20, 0x4d, 0xb0, 0x03, 0xe7, 0xdd, 0x48, 0xe4, 
+-      0x68, 0x00, 0x30, 0x60, 0x7e, 0x80, 0x28, 0x00, 
+-      0xd0, 0x02, 0x20, 0x4f, 0xb0, 0x03, 0xe7, 0xd4, 
+-      0x68, 0x78, 0x28, 0x00, 0xd1, 0x02, 0x20, 0x4c, 
+-      0xb0, 0x03, 0xe7, 0xce, 0x2c, 0x04, 0xd1, 0x08, 
+-      0x68, 0x79, 0x20, 0xbc, 0xf0, 0x01, 0xfe, 0xce, 
+-      0x29, 0x00, 0xd0, 0x02, 0x20, 0x59, 0xb0, 0x03, 
+-      0xe7, 0xc3, 0x48, 0xd7, 0x68, 0x00, 0x30, 0x80, 
+-      0x78, 0xc0, 0x28, 0x00, 0xd0, 0x02, 0x20, 0x50, 
+-      0xb0, 0x03, 0xe7, 0xba, 0x2c, 0x00, 0xd1, 0x04, 
+-      0x48, 0xd3, 0x68, 0x01, 0x23, 0xfd, 0x40, 0x19, 
+-      0x60, 0x01, 0x48, 0xd2, 0x68, 0x01, 0x23, 0x8d, 
+-      0x05, 0x9b, 0x43, 0x19, 0x60, 0x01, 0x48, 0xd0, 
+-      0x21, 0x33, 0x06, 0x49, 0x60, 0x48, 0x20, 0x01, 
+-      0x49, 0xc9, 0x68, 0x09, 0x31, 0x60, 0x76, 0x88, 
+-      0x68, 0x38, 0x49, 0xc7, 0x68, 0x09, 0x67, 0x08, 
+-      0x68, 0x78, 0x49, 0xc5, 0x68, 0x09, 0x67, 0x48, 
+-      0x48, 0xc3, 0x68, 0x00, 0x67, 0xc7, 0x20, 0x00, 
+-      0x49, 0xc1, 0x68, 0x09, 0x31, 0x60, 0x76, 0x48, 
+-      0x98, 0x02, 0x49, 0xbf, 0x68, 0x09, 0x31, 0x60, 
+-      0x76, 0x08, 0x20, 0x00, 0x49, 0xbc, 0x68, 0x09, 
+-      0x6f, 0xc9, 0x60, 0x48, 0x20, 0x00, 0x49, 0xba, 
+-      0x68, 0x09, 0x6f, 0xc9, 0x72, 0x48, 0x48, 0xb8, 
+-      0x68, 0x00, 0x99, 0x02, 0x5c, 0x40, 0x28, 0x01, 
+-      0xd1, 0x02, 0x20, 0x01, 0x49, 0xb9, 0x62, 0x88, 
+-      0x48, 0xb3, 0x68, 0x00, 0x30, 0x80, 0x78, 0x81, 
+-      0x20, 0x01, 0x40, 0x88, 0x49, 0xb1, 0x68, 0x49, 
+-      0x40, 0x08, 0x07, 0x80, 0x0f, 0x80, 0xd0, 0x1b, 
+-      0x20, 0x00, 0x49, 0xad, 0x68, 0x09, 0x31, 0x60, 
+-      0x76, 0x88, 0x20, 0x51, 0x49, 0xaa, 0x68, 0x09, 
+-      0x6f, 0xc9, 0x72, 0x48, 0x48, 0xa8, 0x68, 0x00, 
+-      0x6f, 0xc0, 0x7a, 0x00, 0x28, 0xff, 0xd0, 0x07, 
+-      0x48, 0xa5, 0x68, 0x00, 0x6f, 0xc0, 0x7a, 0x01, 
+-      0x20, 0x01, 0x40, 0x88, 0xf0, 0x05, 0xfd, 0xb0, 
+-      0x20, 0x51, 0xb0, 0x03, 0xe7, 0x55, 0xe1, 0x6c, 
+-      0x20, 0x33, 0x06, 0x40, 0x6b, 0x81, 0x91, 0x00, 
+-      0x99, 0x00, 0x20, 0x04, 0x40, 0x08, 0xd0, 0x07, 
+-      0x20, 0x04, 0xf0, 0x00, 0xfc, 0xb3, 0x20, 0x33, 
+-      0x06, 0x40, 0x6b, 0x81, 0x91, 0x00, 0xe7, 0xf3, 
+-      0x4d, 0x9d, 0x99, 0x00, 0x01, 0x08, 0x19, 0x45, 
+-      0x48, 0x95, 0x68, 0x00, 0x6f, 0x40, 0x28, 0xbc, 
+-      0xdd, 0x07, 0x48, 0x9a, 0x60, 0xa8, 0x20, 0xbc, 
+-      0x49, 0x91, 0x68, 0x09, 0x31, 0x80, 0x70, 0x08, 
+-      0xe0, 0x0d, 0x48, 0x8f, 0x68, 0x00, 0x6f, 0x40, 
+-      0x23, 0x01, 0x07, 0x9b, 0x43, 0x18, 0x60, 0xa8, 
+-      0x48, 0x8b, 0x68, 0x00, 0x6f, 0x40, 0x49, 0x8a, 
+-      0x68, 0x09, 0x31, 0x80, 0x70, 0x08, 0x48, 0x90, 
+-      0x90, 0x01, 0x48, 0x87, 0x68, 0x00, 0x30, 0x80, 
+-      0x78, 0x80, 0x00, 0x43, 0x18, 0x18, 0x01, 0x80, 
+-      0x99, 0x01, 0x18, 0x40, 0x90, 0x01, 0x48, 0x82, 
+-      0x68, 0x00, 0x6f, 0x00, 0x60, 0x28, 0x98, 0x01, 
+-      0x30, 0x04, 0x60, 0x68, 0x20, 0x01, 0x06, 0x00, 
+-      0x60, 0xe8, 0x99, 0x00, 0x20, 0x01, 0x40, 0x88, 
+-      0x21, 0x33, 0x06, 0x49, 0x63, 0x48, 0x48, 0x83, 
+-      0x6b, 0x00, 0x23, 0x01, 0x06, 0x1b, 0x40, 0x18, 
+-      0xd1, 0x03, 0x20, 0x04, 0xf0, 0x00, 0xfc, 0x6a, 
+-      0xe7, 0xf5, 0x20, 0x01, 0x06, 0x00, 0x21, 0x33, 
+-      0x06, 0x49, 0x60, 0x48, 0x4e, 0x7c, 0x48, 0x72, 
+-      0x68, 0x00, 0x30, 0x80, 0x78, 0x80, 0x01, 0x00, 
+-      0x19, 0x86, 0x98, 0x01, 0x30, 0x04, 0x60, 0x30, 
+-      0x48, 0x78, 0x60, 0x70, 0x48, 0x6c, 0x68, 0x00, 
+-      0x30, 0x80, 0x78, 0x00, 0x23, 0x01, 0x07, 0x9b, 
+-      0x43, 0x18, 0x60, 0xb0, 0x20, 0x01, 0x05, 0x80, 
+-      0x60, 0xf0, 0x48, 0x67, 0x68, 0x00, 0x30, 0x80, 
+-      0x78, 0x81, 0x20, 0x01, 0x40, 0x88, 0x49, 0x65, 
+-      0x60, 0xc8, 0x48, 0x63, 0x68, 0x00, 0x30, 0x60, 
+-      0x7e, 0x00, 0x49, 0x61, 0x68, 0x09, 0x5c, 0x08, 
+-      0x28, 0x00, 0xd0, 0x48, 0x28, 0x01, 0xd0, 0x47, 
+-      0x28, 0x02, 0xd0, 0x02, 0x28, 0x03, 0xd0, 0x21, 
+-      0xe0, 0x5a, 0x48, 0x67, 0x68, 0x01, 0x23, 0x02, 
+-      0x43, 0x19, 0x60, 0x01, 0x48, 0x58, 0x68, 0x00, 
+-      0x6f, 0x40, 0x49, 0x57, 0x68, 0x09, 0x31, 0x80, 
+-      0x78, 0x09, 0x1a, 0x40, 0x28, 0xbc, 0xd8, 0x05, 
+-      0x48, 0x5f, 0x68, 0x01, 0x23, 0x10, 0x43, 0x19, 
+-      0x60, 0x01, 0xe0, 0x05, 0x48, 0x5c, 0x68, 0x01, 
+-      0x23, 0x10, 0x43, 0xdb, 0x40, 0x19, 0x60, 0x01, 
+-      0x48, 0x59, 0x68, 0x01, 0x23, 0x08, 0x43, 0x19, 
+-      0x60, 0x01, 0xe0, 0x39, 0x48, 0x56, 0x68, 0x01, 
+-      0x23, 0x04, 0x43, 0x19, 0x60, 0x01, 0x48, 0x48, 
+-      0x68, 0x00, 0x6f, 0x40, 0x49, 0x46, 0x68, 0x09, 
+-      0x31, 0x80, 0x78, 0x09, 0x1a, 0x40, 0x28, 0xbc, 
+-      0xd8, 0x05, 0x48, 0x4f, 0x68, 0x01, 0x23, 0x10, 
+-      0x43, 0x19, 0x60, 0x01, 0xe0, 0x05, 0x48, 0x4c, 
+-      0x68, 0x01, 0x23, 0x10, 0x43, 0xdb, 0x40, 0x19, 
+-      0x60, 0x01, 0x48, 0x49, 0x68, 0x01, 0x23, 0x08, 
+-      0x43, 0x19, 0x60, 0x01, 0xe0, 0x18, 0xe0, 0x17, 
+-      0x48, 0x46, 0x68, 0x01, 0x04, 0x09, 0x0c, 0x09, 
+-      0x60, 0x01, 0x48, 0x44, 0x49, 0x36, 0x68, 0x09, 
+-      0x31, 0x80, 0x78, 0x09, 0x04, 0x09, 0x68, 0x02, 
+-      0x43, 0x11, 0x60, 0x01, 0x48, 0x40, 0x68, 0x01, 
+-      0x23, 0x20, 0x43, 0xdb, 0x40, 0x19, 0x60, 0x01, 
+-      0x20, 0x01, 0x49, 0x34, 0x63, 0x08, 0xe7, 0xff, 
+-      0x48, 0x36, 0x6b, 0x00, 0x23, 0x01, 0x05, 0x9b, 
+-      0x40, 0x18, 0xd1, 0x03, 0x20, 0x04, 0xf0, 0x00, 
+-      0xfb, 0xd1, 0xe7, 0xf5, 0x20, 0x01, 0x05, 0x80, 
+-      0x21, 0x33, 0x06, 0x49, 0x60, 0x48, 0x48, 0x26, 
+-      0x68, 0x00, 0x30, 0x80, 0x78, 0x80, 0x23, 0x01, 
+-      0x40, 0x58, 0x49, 0x23, 0x68, 0x09, 0x31, 0x80, 
+-      0x70, 0x88, 0x48, 0x21, 0x68, 0x00, 0x6f, 0x40, 
+-      0x49, 0x1f, 0x68, 0x09, 0x31, 0x80, 0x78, 0x09, 
+-      0x1a, 0x40, 0x49, 0x1d, 0x68, 0x09, 0x67, 0x48, 
+-      0x48, 0x1b, 0x68, 0x00, 0x6f, 0xc0, 0x30, 0x04, 
+-      0x49, 0x19, 0x68, 0x09, 0x31, 0x80, 0x78, 0x09, 
+-      0x68, 0x02, 0x18, 0x89, 0x60, 0x01, 0x48, 0x16, 
+-      0x68, 0x00, 0x6f, 0x00, 0x49, 0x14, 0x68, 0x09, 
+-      0x31, 0x80, 0x78, 0x09, 0x18, 0x40, 0x49, 0x12, 
+-      0x68, 0x09, 0x67, 0x08, 0x48, 0x10, 0x68, 0x00, 
+-      0x6f, 0x40, 0x28, 0x00, 0xd0, 0x00, 0xe6, 0xb3, 
+-      0x48, 0x11, 0x21, 0x33, 0x06, 0x49, 0x60, 0x48, 
+-      0x48, 0x0e, 0x68, 0x01, 0x4b, 0x19, 0x40, 0x19, 
+-      0x60, 0x01, 0x20, 0x48, 0x49, 0x08, 0x68, 0x09, 
+-      0x6f, 0xc9, 0x72, 0x48, 0x20, 0x00, 0x49, 0x06, 
+-      0x68, 0x09, 0x31, 0x60, 0x76, 0x88, 0x48, 0x04, 
+-      0x68, 0x00, 0x6f, 0xc0, 0x7a, 0x00, 0x28, 0xff, 
+-      0xd0, 0x29, 0x48, 0x01, 0xe0, 0x20, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7c, 0x44, 0x66, 0x00, 0x01, 0x00, 
+-      0x62, 0x00, 0x00, 0x1c, 0x66, 0x00, 0x00, 0x08, 
+-      0x23, 0x48, 0x00, 0x00, 0x62, 0x01, 0x00, 0x00, 
+-      0x9e, 0x00, 0x09, 0x80, 0x40, 0x00, 0x00, 0xbc, 
+-      0x9e, 0x00, 0x0b, 0x80, 0x66, 0x00, 0x00, 0x80, 
+-      0x9e, 0x00, 0x09, 0xc0, 0x66, 0x00, 0x01, 0xf0, 
+-      0x64, 0x00, 0x00, 0x60, 0x62, 0x01, 0x00, 0x20, 
+-      0x62, 0x01, 0x00, 0x24, 0xfc, 0xb7, 0xff, 0xff, 
+-      0x68, 0x00, 0x6f, 0xc0, 0x7a, 0x01, 0x20, 0x01, 
+-      0x40, 0x88, 0xf0, 0x05, 0xfc, 0x45, 0x20, 0x00, 
+-      0xb0, 0x03, 0xe5, 0xea, 0xb0, 0x02, 0xb0, 0x01, 
+-      0xe5, 0xe7, 0xe5, 0xe6, 0xb5, 0xb0, 0x1c, 0x07, 
+-      0x06, 0x3d, 0x0e, 0x2d, 0x48, 0x5d, 0x68, 0x00, 
+-      0x5d, 0x44, 0x2d, 0x20, 0xdb, 0x03, 0x20, 0xa2, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x48, 0x59, 
+-      0x68, 0x00, 0x5d, 0x40, 0x28, 0xff, 0xd1, 0x01, 
+-      0x20, 0x4b, 0xe7, 0xf5, 0x48, 0x56, 0x69, 0x80, 
+-      0x28, 0x00, 0xd1, 0x05, 0x2c, 0x02, 0xd0, 0x03, 
+-      0x2c, 0x03, 0xd0, 0x01, 0x2c, 0x04, 0xd1, 0x0b, 
+-      0x48, 0x51, 0x69, 0x80, 0x28, 0x02, 0xd1, 0x01, 
+-      0x2c, 0x00, 0xd1, 0x05, 0x48, 0x4e, 0x69, 0x80, 
+-      0x28, 0x01, 0xd1, 0x04, 0x2c, 0x01, 0xd0, 0x02, 
+-      0x20, 0x4d, 0xe7, 0xdd, 0xe0, 0x90, 0x48, 0x4b, 
+-      0x68, 0x01, 0x4b, 0x4b, 0x43, 0x19, 0x60, 0x01, 
+-      0x48, 0x49, 0x21, 0x33, 0x06, 0x49, 0x60, 0x48, 
+-      0x48, 0x48, 0x68, 0x01, 0x23, 0x04, 0x43, 0x19, 
+-      0x60, 0x01, 0x20, 0x00, 0x49, 0x41, 0x68, 0x09, 
+-      0x31, 0x80, 0x70, 0x88, 0x20, 0x00, 0x49, 0x3f, 
+-      0x68, 0x09, 0x31, 0x80, 0x70, 0x48, 0x20, 0xff, 
+-      0x49, 0x3c, 0x68, 0x09, 0x55, 0x48, 0x2c, 0x00, 
+-      0xd1, 0x03, 0x20, 0x18, 0x21, 0x31, 0x06, 0x49, 
+-      0x62, 0x48, 0x01, 0x20, 0x49, 0x37, 0x68, 0x09, 
+-      0x18, 0x40, 0x30, 0x20, 0x7a, 0x80, 0x28, 0x00, 
+-      0xd0, 0x28, 0x20, 0x00, 0x49, 0x38, 0x60, 0x08, 
+-      0x20, 0x00, 0x49, 0x38, 0x64, 0x08, 0x20, 0x03, 
+-      0x49, 0x31, 0x61, 0x08, 0x21, 0x55, 0x01, 0x20, 
+-      0x4a, 0x2e, 0x68, 0x12, 0x18, 0x80, 0x6a, 0xc0, 
+-      0x72, 0x41, 0x21, 0x00, 0x01, 0x20, 0x4a, 0x2b, 
+-      0x68, 0x12, 0x18, 0x80, 0x30, 0x20, 0x72, 0x81, 
+-      0x01, 0x20, 0x49, 0x28, 0x68, 0x09, 0x18, 0x40, 
+-      0x6a, 0xc0, 0x7a, 0x00, 0x28, 0xff, 0xd0, 0x09, 
+-      0x01, 0x20, 0x49, 0x24, 0x68, 0x09, 0x18, 0x40, 
+-      0x6a, 0xc0, 0x7a, 0x01, 0x20, 0x01, 0x40, 0x88, 
+-      0xf0, 0x05, 0xfb, 0xbe, 0x48, 0x1f, 0x68, 0x00, 
+-      0x30, 0x60, 0x7e, 0x80, 0x28, 0x00, 0xd0, 0x2b, 
+-      0x48, 0x1c, 0x68, 0x00, 0x30, 0x80, 0x78, 0xc0, 
+-      0x28, 0x00, 0xd0, 0x0d, 0x20, 0x00, 0x49, 0x19, 
+-      0x68, 0x09, 0x31, 0x80, 0x70, 0xc8, 0x22, 0x00, 
+-      0xb4, 0x04, 0x1c, 0x28, 0x23, 0x00, 0x22, 0x00, 
+-      0x49, 0x1b, 0xf7, 0xf3, 0xfe, 0xcd, 0xb0, 0x01, 
+-      0x20, 0x55, 0x49, 0x12, 0x68, 0x09, 0x6f, 0xc9, 
+-      0x72, 0x48, 0x20, 0x00, 0x49, 0x0f, 0x68, 0x09, 
+-      0x31, 0x60, 0x76, 0x88, 0x48, 0x0d, 0x68, 0x00, 
+-      0x6f, 0xc0, 0x7a, 0x00, 0x28, 0xff, 0xd0, 0x07, 
+-      0x48, 0x0a, 0x68, 0x00, 0x6f, 0xc0, 0x7a, 0x01, 
+-      0x20, 0x01, 0x40, 0x88, 0xf0, 0x05, 0xfb, 0x8c, 
+-      0x48, 0x09, 0x21, 0x33, 0x06, 0x49, 0x60, 0x48, 
+-      0x48, 0x06, 0x68, 0x01, 0x4b, 0x0b, 0x40, 0x19, 
+-      0x60, 0x01, 0x20, 0x00, 0xe7, 0x4c, 0xe7, 0x4b, 
+-      0xe7, 0x4a, 0x00, 0x00, 0x2e, 0x08, 0x7c, 0x44, 
+-      0x66, 0x00, 0x01, 0x00, 0x66, 0x00, 0x00, 0x08, 
+-      0x23, 0x48, 0x00, 0x00, 0x66, 0x00, 0x01, 0x18, 
+-      0x9e, 0x00, 0x0a, 0x00, 0x9e, 0x00, 0x0a, 0x80, 
+-      0x00, 0x00, 0xff, 0xff, 0xfc, 0xb7, 0xff, 0xff, 
+-      0xb5, 0xff, 0x1c, 0x1f, 0x98, 0x00, 0x06, 0x02, 
+-      0x0e, 0x12, 0x99, 0x01, 0x06, 0x0d, 0x0e, 0x2d, 
+-      0x98, 0x02, 0x06, 0x04, 0x0e, 0x24, 0x48, 0x2d, 
+-      0x68, 0x00, 0x5c, 0x81, 0x2a, 0x20, 0xdb, 0x04, 
+-      0x20, 0xa2, 0xb0, 0x04, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x29, 0xff, 0xd1, 0x01, 0x20, 0x4b, 
+-      0xe7, 0xf7, 0x48, 0x27, 0x69, 0x80, 0x28, 0x00, 
+-      0xd1, 0x05, 0x29, 0x02, 0xd0, 0x03, 0x29, 0x03, 
+-      0xd0, 0x01, 0x29, 0x04, 0xd1, 0x0b, 0x48, 0x22, 
+-      0x69, 0x80, 0x28, 0x02, 0xd1, 0x01, 0x29, 0x00, 
+-      0xd1, 0x05, 0x48, 0x1f, 0x69, 0x80, 0x28, 0x01, 
+-      0xd1, 0x03, 0x29, 0x01, 0xd0, 0x01, 0x20, 0x4d, 
+-      0xe7, 0xdf, 0x29, 0x05, 0xd2, 0x2a, 0xa3, 0x02, 
+-      0x5c, 0x5b, 0x00, 0x5b, 0x44, 0x9f, 0x1c, 0x00, 
+-      0x03, 0x07, 0x04, 0x05, 0x06, 0x00, 0xe0, 0x24, 
+-      0xe0, 0x23, 0xe0, 0x22, 0xe0, 0x21, 0x01, 0x08, 
+-      0x4b, 0x12, 0x68, 0x1b, 0x18, 0xc0, 0x30, 0x20, 
+-      0x7a, 0x80, 0x28, 0x00, 0xd1, 0x05, 0x48, 0x0f, 
+-      0x68, 0x00, 0x30, 0x60, 0x7e, 0x80, 0x28, 0x00, 
+-      0xd0, 0x02, 0x20, 0x49, 0xe7, 0xc1, 0xe0, 0x13, 
+-      0x2d, 0x00, 0xd1, 0x05, 0x00, 0xa0, 0x4b, 0x0b, 
+-      0x18, 0xc0, 0x68, 0x00, 0x60, 0x38, 0xe0, 0x04, 
+-      0x68, 0x38, 0x00, 0xa6, 0x4b, 0x07, 0x18, 0xf3, 
+-      0x60, 0x18, 0xe0, 0x02, 0x20, 0x4a, 0xe7, 0xb0, 
+-      0xe7, 0xff, 0x20, 0x00, 0xe7, 0xad, 0xe7, 0xac, 
+-      0xe7, 0xab, 0x00, 0x00, 0x2e, 0x08, 0x7c, 0x44, 
+-      0x66, 0x00, 0x01, 0x00, 0x62, 0x01, 0x00, 0x80, 
+-      0xb5, 0xf7, 0xb0, 0x82, 0x98, 0x02, 0x06, 0x03, 
+-      0x0e, 0x1b, 0x93, 0x00, 0x99, 0x03, 0x06, 0x08, 
+-      0x0e, 0x00, 0x90, 0x01, 0x9a, 0x04, 0x06, 0x15, 
+-      0x0e, 0x2d, 0xb0, 0x84, 0x4a, 0xca, 0x4f, 0xcb, 
+-      0x48, 0xcb, 0x68, 0x00, 0x9b, 0x04, 0x5c, 0xc4, 
+-      0x48, 0xca, 0x90, 0x02, 0x21, 0x00, 0x23, 0x00, 
+-      0x93, 0x01, 0x9b, 0x04, 0x2b, 0x20, 0xdb, 0x05, 
+-      0x20, 0xa2, 0xb0, 0x06, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2c, 0xff, 0xd1, 0x02, 
+-      0x20, 0x4b, 0xb0, 0x06, 0xe7, 0xf6, 0x48, 0xc2, 
+-      0x69, 0x80, 0x28, 0x02, 0xd1, 0x01, 0x2c, 0x00, 
+-      0xd1, 0x03, 0x48, 0xbf, 0x69, 0x80, 0x28, 0x02, 
+-      0xd0, 0x02, 0x20, 0x4d, 0xb0, 0x06, 0xe7, 0xe9, 
+-      0x98, 0x05, 0x28, 0x01, 0xd1, 0x08, 0x48, 0xb8, 
+-      0x68, 0x00, 0x30, 0x80, 0x78, 0xc0, 0x28, 0x00, 
+-      0xd0, 0x02, 0x20, 0x50, 0xb0, 0x06, 0xe7, 0xdd, 
+-      0x98, 0x05, 0x28, 0x00, 0xd1, 0x05, 0x48, 0xb2, 
+-      0x68, 0x00, 0x30, 0x20, 0x7a, 0x80, 0x28, 0x00, 
+-      0xd0, 0x08, 0x98, 0x05, 0x28, 0x01, 0xd1, 0x08, 
+-      0x48, 0xad, 0x68, 0x00, 0x30, 0x60, 0x7e, 0x80, 
+-      0x28, 0x00, 0xd1, 0x02, 0x20, 0x5a, 0xb0, 0x06, 
+-      0xe7, 0xc8, 0x20, 0x00, 0x4b, 0xa8, 0x68, 0x1b, 
+-      0x6f, 0xdb, 0x72, 0x58, 0x98, 0x05, 0x28, 0x00, 
+-      0xd1, 0x50, 0x2d, 0x01, 0xd0, 0x01, 0x2d, 0x02, 
+-      0xd1, 0x32, 0x4e, 0xa6, 0x68, 0x30, 0x23, 0x01, 
+-      0x04, 0xdb, 0x43, 0x18, 0x60, 0x30, 0x20, 0x00, 
+-      0x4b, 0xa3, 0x60, 0x18, 0x48, 0x9e, 0x68, 0x00, 
+-      0x30, 0x80, 0x78, 0x40, 0x00, 0x43, 0x18, 0x18, 
+-      0x01, 0x80, 0x9b, 0x02, 0x18, 0xc0, 0x90, 0x02, 
+-      0x98, 0x02, 0x68, 0x01, 0x48, 0x9a, 0x69, 0x80, 
+-      0x07, 0x80, 0x0f, 0x80, 0x01, 0x80, 0x43, 0x01, 
+-      0x23, 0x20, 0x43, 0x19, 0x4b, 0x99, 0x43, 0x19, 
+-      0x98, 0x02, 0x60, 0x01, 0x4e, 0x98, 0x68, 0x30, 
+-      0x23, 0x01, 0x04, 0xdb, 0x43, 0x18, 0x60, 0x30, 
+-      0x4e, 0x92, 0x68, 0x30, 0x4b, 0x95, 0x40, 0x18, 
+-      0x60, 0x30, 0x2c, 0x00, 0xd1, 0x04, 0x20, 0x00, 
+-      0x4b, 0x8b, 0x68, 0x1b, 0x33, 0x20, 0x72, 0x98, 
+-      0x2d, 0x02, 0xd0, 0x04, 0x20, 0x01, 0x04, 0xc0, 
+-      0x23, 0x33, 0x06, 0x5b, 0x60, 0x18, 0x2c, 0x00, 
+-      0xd1, 0x0f, 0x20, 0xff, 0x02, 0x00, 0x40, 0x08, 
+-      0xd1, 0x0b, 0x2d, 0x02, 0xd0, 0x09, 0x48, 0x82, 
+-      0x68, 0x00, 0x30, 0x80, 0x78, 0x40, 0x23, 0x01, 
+-      0x40, 0x58, 0x4b, 0x7f, 0x68, 0x1b, 0x33, 0x80, 
+-      0x70, 0x58, 0xe0, 0xed, 0x2d, 0x01, 0xd1, 0x73, 
+-      0x2c, 0x00, 0xd1, 0x72, 0x20, 0x31, 0x06, 0x40, 
+-      0x68, 0x80, 0x23, 0x08, 0x40, 0x18, 0xd1, 0x3a, 
+-      0x48, 0x7a, 0x68, 0x06, 0x23, 0x05, 0x05, 0x9b, 
+-      0x43, 0x33, 0x60, 0x03, 0x68, 0x10, 0x4b, 0x7c, 
+-      0x40, 0x18, 0x60, 0x10, 0x32, 0xc0, 0x68, 0x10, 
+-      0x4b, 0x79, 0x40, 0x18, 0x60, 0x10, 0x20, 0x00, 
+-      0x4b, 0x6f, 0x68, 0x1b, 0x67, 0x58, 0x20, 0x00, 
+-      0x4b, 0x6d, 0x68, 0x1b, 0x33, 0x80, 0x70, 0x18, 
+-      0x48, 0x6d, 0x68, 0x80, 0x23, 0x02, 0x40, 0x18, 
+-      0xd1, 0x04, 0x20, 0x00, 0x4b, 0x68, 0x68, 0x1b, 
+-      0x33, 0x60, 0x76, 0x98, 0x20, 0x5b, 0x4b, 0x66, 
+-      0x68, 0x1b, 0x6f, 0xdb, 0x72, 0x58, 0x4e, 0x6d, 
+-      0x68, 0x30, 0x23, 0x02, 0x43, 0x18, 0x60, 0x30, 
+-      0x4e, 0x67, 0x68, 0x30, 0x23, 0x05, 0x05, 0x9b, 
+-      0x43, 0x18, 0x60, 0x30, 0x4e, 0x61, 0x68, 0x30, 
+-      0x4b, 0x67, 0x40, 0x18, 0x60, 0x30, 0x20, 0x5b, 
+-      0xb0, 0x06, 0xe7, 0x2b, 0xe0, 0xae, 0x48, 0x5d, 
+-      0x68, 0x06, 0x23, 0x01, 0x05, 0x9b, 0x43, 0x33, 
+-      0x60, 0x03, 0x20, 0x31, 0x06, 0x40, 0x6a, 0x00, 
+-      0x23, 0x04, 0x40, 0x18, 0xd1, 0x27, 0x9b, 0x01, 
+-      0x20, 0x31, 0x06, 0x40, 0x6b, 0x00, 0x18, 0x1b, 
+-      0x93, 0x01, 0x4e, 0x5c, 0x68, 0x30, 0x23, 0x3b, 
+-      0x40, 0x18, 0x60, 0x30, 0x4e, 0x57, 0x68, 0x30, 
+-      0x23, 0x0e, 0x43, 0x18, 0x60, 0x30, 0x4e, 0x55, 
+-      0x68, 0x30, 0x23, 0x0c, 0x40, 0x18, 0x60, 0x30, 
+-      0x20, 0x37, 0x23, 0x31, 0x06, 0x5b, 0x60, 0x98, 
+-      0x20, 0x01, 0x90, 0x00, 0x98, 0x00, 0x28, 0x64, 
+-      0xd3, 0x04, 0xe0, 0x07, 0x98, 0x00, 0x30, 0x01, 
+-      0x90, 0x00, 0xe7, 0xf7, 0xe7, 0xfa, 0xe0, 0x01, 
+-      0xe0, 0x36, 0xe0, 0x34, 0xe7, 0xd1, 0x4e, 0x46, 
+-      0x68, 0x30, 0x23, 0x01, 0x05, 0x9b, 0x43, 0x18, 
+-      0x60, 0x30, 0x4e, 0x40, 0x68, 0x30, 0x4b, 0x48, 
+-      0x40, 0x18, 0x60, 0x30, 0x48, 0x3c, 0x68, 0x40, 
+-      0x28, 0x00, 0xd0, 0x0d, 0x20, 0x5b, 0x4b, 0x38, 
+-      0x68, 0x1b, 0x6f, 0xdb, 0x72, 0x58, 0x20, 0x00, 
+-      0x4b, 0x35, 0x68, 0x1b, 0x33, 0x60, 0x76, 0x98, 
+-      0x20, 0x5b, 0xb0, 0x06, 0xe6, 0xda, 0xe0, 0x5d, 
+-      0x48, 0x31, 0x68, 0x00, 0x6f, 0xc0, 0x1d, 0x06, 
+-      0x48, 0x2f, 0x68, 0x00, 0x30, 0x80, 0x78, 0x00, 
+-      0x9b, 0x01, 0x1a, 0xc0, 0x68, 0x33, 0x18, 0xc0, 
+-      0x60, 0x30, 0x20, 0x5c, 0x4b, 0x2a, 0x68, 0x1b, 
+-      0x6f, 0xdb, 0x72, 0x58, 0x20, 0x00, 0x4b, 0x28, 
+-      0x68, 0x1b, 0x33, 0x60, 0x76, 0x98, 0xe0, 0x3f, 
+-      0x20, 0x33, 0x06, 0x40, 0x6b, 0x80, 0x90, 0x03, 
+-      0x23, 0x04, 0x40, 0x18, 0xd0, 0x03, 0x20, 0x52, 
+-      0xb0, 0x06, 0xe6, 0xb7, 0xe0, 0x3a, 0x98, 0x03, 
+-      0x01, 0x00, 0x19, 0xc7, 0x48, 0x1e, 0x68, 0x00, 
+-      0x6f, 0x40, 0x28, 0xbc, 0xdd, 0x07, 0x48, 0x29, 
+-      0x60, 0xb8, 0x20, 0xbc, 0x4b, 0x1a, 0x68, 0x1b, 
+-      0x33, 0x80, 0x70, 0x18, 0xe0, 0x0d, 0x48, 0x18, 
+-      0x68, 0x00, 0x6f, 0x40, 0x23, 0x01, 0x07, 0x9b, 
+-      0x43, 0x18, 0x60, 0xb8, 0x48, 0x14, 0x68, 0x00, 
+-      0x6f, 0x40, 0x4b, 0x13, 0x68, 0x1b, 0x33, 0x80, 
+-      0x70, 0x18, 0x48, 0x11, 0x68, 0x00, 0x30, 0x80, 
+-      0x78, 0x80, 0x00, 0x43, 0x18, 0x18, 0x01, 0x80, 
+-      0x18, 0x82, 0x48, 0x0d, 0x68, 0x00, 0x6f, 0x00, 
+-      0x60, 0x38, 0x1d, 0x10, 0x60, 0x78, 0x20, 0x01, 
+-      0x06, 0x00, 0x60, 0xf8, 0x9e, 0x03, 0x20, 0x01, 
+-      0x40, 0xb0, 0x23, 0x33, 0x06, 0x5b, 0x63, 0x58, 
+-      0x20, 0x00, 0xb0, 0x06, 0xe6, 0x7e, 0xb0, 0x04, 
+-      0xb0, 0x02, 0xe6, 0x7b, 0xe6, 0x7a, 0x00, 0x00, 
+-      0x9e, 0x00, 0x0b, 0x80, 0x9e, 0x00, 0x09, 0x80, 
+-      0x2e, 0x08, 0x7c, 0x44, 0x9e, 0x00, 0x0a, 0x00, 
+-      0x66, 0x00, 0x01, 0x00, 0x66, 0x00, 0x00, 0x08, 
+-      0x62, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x04, 0xff, 0xf7, 0xff, 0xff, 
+-      0xff, 0xff, 0x00, 0xff, 0x62, 0x00, 0x00, 0x1c, 
+-      0xfe, 0xbf, 0xff, 0xff, 0x62, 0x00, 0x00, 0x08, 
+-      0xff, 0xbf, 0xff, 0xff, 0x40, 0x00, 0x00, 0xbc, 
+-      0x48, 0x07, 0x69, 0x80, 0x28, 0x02, 0xd0, 0x03, 
+-      0x48, 0x05, 0x69, 0x80, 0x28, 0x03, 0xd1, 0x04, 
+-      0x20, 0x31, 0x06, 0x40, 0x6a, 0x80, 0x47, 0x70, 
+-      0xe0, 0x01, 0x20, 0x00, 0xe7, 0xfb, 0xe7, 0xfa, 
+-      0x66, 0x00, 0x01, 0x00, 0xb5, 0xb0, 0x27, 0x0f, 
+-      0x20, 0x31, 0x06, 0x40, 0x68, 0xc0, 0x09, 0x05, 
+-      0xf7, 0xff, 0xff, 0xe6, 0x43, 0xc4, 0x48, 0x18, 
+-      0x69, 0x80, 0x28, 0x00, 0xd0, 0x03, 0x48, 0x16, 
+-      0x69, 0x80, 0x28, 0x01, 0xd1, 0x03, 0x1c, 0x38, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x2d, 0x09, 
+-      0xd2, 0x1e, 0xa3, 0x02, 0x5d, 0x5b, 0x00, 0x5b, 
+-      0x44, 0x9f, 0x1c, 0x00, 0x05, 0x05, 0x05, 0x05, 
+-      0x05, 0x07, 0x07, 0x07, 0x0e, 0x00, 0x1c, 0x2f, 
+-      0xe0, 0x13, 0x20, 0x08, 0x40, 0x20, 0xd0, 0x01, 
+-      0x1c, 0x2f, 0xe0, 0x00, 0x27, 0x02, 0xe0, 0x0c, 
+-      0x20, 0x08, 0x40, 0x20, 0xd0, 0x06, 0x20, 0x02, 
+-      0x40, 0x20, 0xd0, 0x01, 0x27, 0x07, 0xe0, 0x00, 
+-      0x27, 0x08, 0xe0, 0x00, 0x27, 0x02, 0xe0, 0x00, 
+-      0xe7, 0xff, 0x1c, 0x38, 0xe7, 0xd8, 0xe7, 0xd7, 
+-      0x66, 0x00, 0x01, 0x00, 0x1c, 0x01, 0x29, 0x07, 
+-      0xd2, 0x0f, 0xa3, 0x02, 0x5c, 0x5b, 0x00, 0x5b, 
+-      0x44, 0x9f, 0x1c, 0x00, 0x04, 0x05, 0x06, 0x09, 
+-      0x08, 0x07, 0x0a, 0x00, 0xe0, 0x06, 0xe0, 0x05, 
+-      0xe0, 0x04, 0xe0, 0x03, 0xe0, 0x02, 0xe0, 0x01, 
+-      0xe0, 0x00, 0xe7, 0xff, 0x20, 0x00, 0x47, 0x70, 
+-      0xe7, 0xfd, 0x00, 0x00, 0x20, 0x1d, 0x02, 0x80, 
+-      0x69, 0x80, 0x49, 0x06, 0x60, 0x08, 0x20, 0x1d, 
+-      0x02, 0x80, 0x69, 0x40, 0x49, 0x04, 0x60, 0x08, 
+-      0x20, 0x1d, 0x02, 0x80, 0x69, 0xc0, 0x49, 0x03, 
+-      0x60, 0x08, 0x47, 0x70, 0x2e, 0x08, 0x94, 0x90, 
+-      0x2e, 0x08, 0x94, 0x94, 0x2e, 0x08, 0x94, 0x98, 
+-      0xb5, 0xf1, 0xb0, 0x81, 0x20, 0x00, 0x4d, 0x21, 
+-      0x95, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 
+-      0x43, 0xdb, 0x4c, 0x1f, 0x68, 0x64, 0x42, 0x8c, 
+-      0xdd, 0x21, 0x1c, 0x0c, 0x31, 0x01, 0x00, 0xa4, 
+-      0x9d, 0x00, 0x59, 0x2f, 0x42, 0x9f, 0xd0, 0xf8, 
+-      0x4c, 0x19, 0x68, 0x64, 0x42, 0x8c, 0xda, 0x00, 
+-      0xe0, 0x15, 0x32, 0x01, 0x1c, 0x0c, 0x31, 0x01, 
+-      0x00, 0xa4, 0x9d, 0x00, 0x59, 0x2b, 0x42, 0x9f, 
+-      0xd0, 0xf8, 0x02, 0x9c, 0x43, 0x3c, 0x1c, 0x25, 
+-      0x1c, 0x04, 0x30, 0x01, 0x00, 0xa4, 0x9e, 0x01, 
+-      0x51, 0x35, 0x4c, 0x0f, 0x68, 0x64, 0x42, 0x8c, 
+-      0xdb, 0x00, 0x32, 0x01, 0xe7, 0xd9, 0x28, 0x08, 
+-      0xd3, 0x02, 0xe0, 0x07, 0x30, 0x01, 0xe7, 0xfa, 
+-      0x25, 0x00, 0x43, 0xed, 0x00, 0x84, 0x9e, 0x01, 
+-      0x51, 0x35, 0xe7, 0xf7, 0x4c, 0x07, 0x68, 0x24, 
+-      0x2c, 0x00, 0xd1, 0x02, 0x24, 0x0d, 0x06, 0xe4, 
+-      0x61, 0x22, 0xb0, 0x01, 0xb0, 0x01, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x7c, 0xcc, 
+-      0x2e, 0x08, 0x7d, 0x94, 0x2e, 0x08, 0x94, 0x84, 
+-      0xb5, 0x80, 0x48, 0xdc, 0x68, 0x00, 0x28, 0x00, 
+-      0xd1, 0x04, 0x48, 0xda, 0x68, 0x00, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0xf7, 0xff, 0xff, 0x92, 
+-      0x48, 0xd7, 0x49, 0xd8, 0x60, 0x08, 0x48, 0xd8, 
+-      0x49, 0xd8, 0x60, 0x08, 0x48, 0xd8, 0x49, 0xd9, 
+-      0x60, 0x08, 0x48, 0xd3, 0x49, 0xd8, 0x68, 0x0b, 
+-      0x4a, 0xd8, 0x21, 0x00, 0xf0, 0x01, 0xf8, 0xda, 
+-      0x20, 0x00, 0x49, 0xd0, 0x68, 0x09, 0x60, 0x08, 
+-      0x20, 0x00, 0x49, 0xd0, 0x68, 0x09, 0x60, 0x08, 
+-      0x20, 0x00, 0x49, 0xd0, 0x68, 0x09, 0x60, 0x08, 
+-      0x20, 0x00, 0x49, 0xca, 0x68, 0x09, 0x23, 0x07, 
+-      0x02, 0x1b, 0x18, 0xc9, 0x66, 0x88, 0x48, 0xce, 
+-      0x49, 0xc6, 0x68, 0x09, 0x23, 0x07, 0x02, 0x1b, 
+-      0x18, 0xc9, 0x66, 0xc8, 0x20, 0x00, 0x49, 0xc5, 
+-      0x68, 0x09, 0x23, 0x07, 0x02, 0x1b, 0x18, 0xc9, 
+-      0x66, 0x88, 0x48, 0xc7, 0x49, 0xc1, 0x68, 0x09, 
+-      0x23, 0x07, 0x02, 0x1b, 0x18, 0xc9, 0x66, 0xc8, 
+-      0x20, 0x00, 0x49, 0xc0, 0x68, 0x09, 0x23, 0x07, 
+-      0x02, 0x1b, 0x18, 0xc9, 0x66, 0x88, 0x48, 0xc0, 
+-      0x49, 0xbc, 0x68, 0x09, 0x23, 0x07, 0x02, 0x1b, 
+-      0x18, 0xc9, 0x66, 0xc8, 0x27, 0x00, 0x2f, 0x19, 
+-      0xd3, 0x02, 0xe0, 0x38, 0x37, 0x01, 0xe7, 0xfa, 
+-      0x48, 0xba, 0x00, 0xb9, 0x4a, 0xb1, 0x68, 0x12, 
+-      0x18, 0x89, 0x23, 0x0d, 0x01, 0xdb, 0x18, 0xc9, 
+-      0x62, 0x08, 0x48, 0xb6, 0x00, 0xb9, 0x4a, 0xad, 
+-      0x68, 0x12, 0x18, 0x89, 0x23, 0x07, 0x02, 0x1b, 
+-      0x18, 0xc9, 0x60, 0x48, 0x48, 0xb1, 0x00, 0xb9, 
+-      0x4a, 0xaa, 0x68, 0x12, 0x18, 0x89, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc9, 0x62, 0x08, 0x48, 0xad, 
+-      0x00, 0xb9, 0x4a, 0xa6, 0x68, 0x12, 0x18, 0x89, 
+-      0x23, 0x07, 0x02, 0x1b, 0x18, 0xc9, 0x60, 0x48, 
+-      0x48, 0xa8, 0x00, 0xb9, 0x4a, 0xa3, 0x68, 0x12, 
+-      0x18, 0x89, 0x23, 0x0d, 0x01, 0xdb, 0x18, 0xc9, 
+-      0x62, 0x08, 0x48, 0xa4, 0x00, 0xb9, 0x4a, 0x9f, 
+-      0x68, 0x12, 0x18, 0x89, 0x23, 0x07, 0x02, 0x1b, 
+-      0x18, 0xc9, 0x60, 0x48, 0xe7, 0xc6, 0x27, 0x00, 
+-      0x2f, 0x07, 0xd3, 0x02, 0xe0, 0x86, 0x37, 0x01, 
+-      0xe7, 0xfa, 0x48, 0x9c, 0x00, 0xb9, 0x19, 0xc9, 
+-      0x00, 0xc9, 0x4a, 0x92, 0x68, 0x12, 0x18, 0x89, 
+-      0x23, 0x0b, 0x01, 0xdb, 0x18, 0xc9, 0x60, 0x08, 
+-      0x48, 0x96, 0x00, 0xb9, 0x19, 0xc9, 0x00, 0xc9, 
+-      0x4a, 0x8c, 0x68, 0x12, 0x18, 0x89, 0x23, 0x05, 
+-      0x02, 0x1b, 0x18, 0xc9, 0x67, 0xc8, 0x48, 0x91, 
+-      0x00, 0xb9, 0x19, 0xc9, 0x00, 0xc9, 0x4a, 0x87, 
+-      0x68, 0x12, 0x18, 0x89, 0x23, 0x0b, 0x01, 0xdb, 
+-      0x18, 0xc9, 0x60, 0x48, 0x48, 0x8b, 0x00, 0xb9, 
+-      0x19, 0xc9, 0x00, 0xc9, 0x4a, 0x81, 0x68, 0x12, 
+-      0x18, 0x89, 0x23, 0x05, 0x02, 0x1b, 0x18, 0xc9, 
+-      0x67, 0x88, 0x48, 0x86, 0x00, 0xb9, 0x19, 0xc9, 
+-      0x00, 0xc9, 0x4a, 0x7e, 0x68, 0x12, 0x18, 0x89, 
+-      0x23, 0x0b, 0x01, 0xdb, 0x18, 0xc9, 0x60, 0x08, 
+-      0x48, 0x80, 0x00, 0xb9, 0x19, 0xc9, 0x00, 0xc9, 
+-      0x4a, 0x78, 0x68, 0x12, 0x18, 0x89, 0x23, 0x05, 
+-      0x02, 0x1b, 0x18, 0xc9, 0x67, 0xc8, 0x48, 0x7b, 
+-      0x00, 0xb9, 0x19, 0xc9, 0x00, 0xc9, 0x4a, 0x73, 
+-      0x68, 0x12, 0x18, 0x89, 0x23, 0x0b, 0x01, 0xdb, 
+-      0x18, 0xc9, 0x60, 0x48, 0x48, 0x75, 0x00, 0xb9, 
+-      0x19, 0xc9, 0x00, 0xc9, 0x4a, 0x6d, 0x68, 0x12, 
+-      0x18, 0x89, 0x23, 0x05, 0x02, 0x1b, 0x18, 0xc9, 
+-      0x67, 0x88, 0x48, 0x70, 0x00, 0xb9, 0x19, 0xc9, 
+-      0x00, 0xc9, 0x4a, 0x6a, 0x68, 0x12, 0x18, 0x89, 
+-      0x23, 0x0b, 0x01, 0xdb, 0x18, 0xc9, 0x60, 0x08, 
+-      0x48, 0x6a, 0x00, 0xb9, 0x19, 0xc9, 0x00, 0xc9, 
+-      0x4a, 0x64, 0x68, 0x12, 0x18, 0x89, 0x23, 0x05, 
+-      0x02, 0x1b, 0x18, 0xc9, 0x67, 0xc8, 0x48, 0x65, 
+-      0x00, 0xb9, 0x19, 0xc9, 0x00, 0xc9, 0x4a, 0x5f, 
+-      0x68, 0x12, 0x18, 0x89, 0x23, 0x0b, 0x01, 0xdb, 
+-      0x18, 0xc9, 0x60, 0x48, 0x48, 0x5f, 0x00, 0xb9, 
+-      0x19, 0xc9, 0x00, 0xc9, 0x4a, 0x59, 0x68, 0x12, 
+-      0x18, 0x89, 0x23, 0x05, 0x02, 0x1b, 0x18, 0xc9, 
+-      0x67, 0x88, 0xe7, 0x78, 0x27, 0x00, 0x2f, 0x12, 
+-      0xd3, 0x02, 0xe0, 0x56, 0x37, 0x01, 0xe7, 0xfa, 
+-      0x48, 0x56, 0x21, 0x4c, 0x43, 0x79, 0x4a, 0x4d, 
+-      0x68, 0x12, 0x18, 0x89, 0x62, 0xc8, 0x48, 0x53, 
+-      0x21, 0x4c, 0x43, 0x79, 0x4a, 0x49, 0x68, 0x12, 
+-      0x18, 0x89, 0x62, 0x88, 0x48, 0x4f, 0x21, 0x4c, 
+-      0x43, 0x79, 0x4a, 0x46, 0x68, 0x12, 0x18, 0x89, 
+-      0x63, 0x08, 0x48, 0x4c, 0x21, 0x4c, 0x43, 0x79, 
+-      0x4a, 0x42, 0x68, 0x12, 0x18, 0x89, 0x62, 0x48, 
+-      0x48, 0x48, 0x21, 0x4c, 0x43, 0x79, 0x4a, 0x41, 
+-      0x68, 0x12, 0x18, 0x89, 0x62, 0xc8, 0x48, 0x45, 
+-      0x21, 0x4c, 0x43, 0x79, 0x4a, 0x3d, 0x68, 0x12, 
+-      0x18, 0x89, 0x62, 0x88, 0x48, 0x41, 0x21, 0x4c, 
+-      0x43, 0x79, 0x4a, 0x3a, 0x68, 0x12, 0x18, 0x89, 
+-      0x63, 0x08, 0x48, 0x3e, 0x21, 0x4c, 0x43, 0x79, 
+-      0x4a, 0x36, 0x68, 0x12, 0x18, 0x89, 0x62, 0x48, 
+-      0x48, 0x3a, 0x21, 0x4c, 0x43, 0x79, 0x4a, 0x35, 
+-      0x68, 0x12, 0x18, 0x89, 0x62, 0xc8, 0x48, 0x37, 
+-      0x21, 0x4c, 0x43, 0x79, 0x4a, 0x31, 0x68, 0x12, 
+-      0x18, 0x89, 0x62, 0x88, 0x48, 0x33, 0x21, 0x4c, 
+-      0x43, 0x79, 0x4a, 0x2e, 0x68, 0x12, 0x18, 0x89, 
+-      0x63, 0x08, 0x48, 0x30, 0x21, 0x4c, 0x43, 0x79, 
+-      0x4a, 0x2a, 0x68, 0x12, 0x18, 0x89, 0x62, 0x48, 
+-      0xe7, 0xa8, 0x20, 0x00, 0x49, 0x25, 0x68, 0x09, 
+-      0x23, 0x0d, 0x01, 0xdb, 0x18, 0xc9, 0x61, 0xc8, 
+-      0x20, 0x00, 0x49, 0x22, 0x68, 0x09, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc9, 0x61, 0x88, 0x20, 0x00, 
+-      0x49, 0x1c, 0x68, 0x09, 0x23, 0x0d, 0x01, 0xdb, 
+-      0x18, 0xc9, 0x61, 0xc8, 0x20, 0x00, 0x49, 0x19, 
+-      0x68, 0x09, 0x23, 0x0d, 0x01, 0xdb, 0x18, 0xc9, 
+-      0x61, 0x88, 0x20, 0x00, 0x49, 0x19, 0x68, 0x09, 
+-      0x23, 0x0d, 0x01, 0xdb, 0x18, 0xc9, 0x61, 0xc8, 
+-      0x20, 0x00, 0x49, 0x16, 0x68, 0x09, 0x23, 0x0d, 
+-      0x01, 0xdb, 0x18, 0xc9, 0x61, 0x88, 0x20, 0x92, 
+-      0x49, 0x17, 0x60, 0x08, 0x27, 0x00, 0x2f, 0x08, 
+-      0xd3, 0x02, 0xe0, 0x08, 0x37, 0x01, 0xe7, 0xfa, 
+-      0x20, 0x00, 0x43, 0xc0, 0x00, 0xb9, 0x4b, 0x13, 
+-      0x18, 0xc9, 0x64, 0x08, 0xe7, 0xf6, 0x20, 0x10, 
+-      0x21, 0x0d, 0x06, 0xc9, 0x61, 0x08, 0x20, 0x01, 
+-      0x49, 0x0f, 0x60, 0x08, 0x48, 0x0e, 0x68, 0x00, 
+-      0xe6, 0x4d, 0xe6, 0x4c, 0x2e, 0x08, 0x60, 0x84, 
+-      0x2e, 0x08, 0x7d, 0xbc, 0x2e, 0x08, 0x7d, 0xb0, 
+-      0x2e, 0x08, 0x85, 0x54, 0x2e, 0x08, 0x7d, 0xb4, 
+-      0x2e, 0x08, 0x8c, 0xec, 0x2e, 0x08, 0x7d, 0xb8, 
+-      0x2e, 0x08, 0x94, 0x94, 0x00, 0x00, 0x16, 0xc8, 
+-      0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 
+-      0x2e, 0x08, 0x94, 0x88, 0x68, 0x00, 0x0d, 0x00, 
+-      0x2e, 0x08, 0x94, 0x84, 0xb5, 0x90, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0x1c, 0x39, 0x20, 0x00, 0xf0, 0x00, 
+-      0xf8, 0x4d, 0x1c, 0x39, 0x1c, 0x20, 0xf0, 0x00, 
+-      0xf8, 0x03, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0xf0, 0x1c, 0x04, 0x1c, 0x0f, 0x68, 0x78, 
+-      0x28, 0x07, 0xd9, 0x1d, 0x23, 0x03, 0x02, 0x5b, 
+-      0x18, 0xf8, 0x6d, 0x40, 0x28, 0x00, 0xd0, 0x06, 
+-      0x23, 0x03, 0x02, 0x5b, 0x18, 0xf8, 0x6d, 0x80, 
+-      0x04, 0x00, 0x0c, 0x00, 0xd1, 0x02, 0x20, 0x02, 
+-      0x60, 0xb8, 0xe0, 0x01, 0x20, 0x03, 0x60, 0xb8, 
+-      0x1d, 0xfd, 0x35, 0x05, 0x23, 0x65, 0x01, 0x1b, 
+-      0x18, 0xfe, 0x1c, 0x31, 0x1c, 0x28, 0x4a, 0x11, 
+-      0x68, 0x13, 0x22, 0x28, 0xf0, 0x00, 0xfe, 0xee, 
+-      0x2c, 0x06, 0xd0, 0x18, 0x00, 0xa0, 0x19, 0x00, 
+-      0x00, 0xc0, 0x19, 0xc0, 0x23, 0x2b, 0x01, 0x5b, 
+-      0x18, 0xc6, 0x00, 0xa0, 0x19, 0x00, 0x00, 0xc0, 
+-      0x19, 0xc0, 0x23, 0xb1, 0x00, 0xdb, 0x18, 0xc5, 
+-      0x20, 0x06, 0x1b, 0x00, 0x00, 0x82, 0x18, 0x12, 
+-      0x00, 0xd2, 0x1c, 0x31, 0x1c, 0x28, 0x4b, 0x04, 
+-      0x68, 0x1b, 0xf0, 0x00, 0xfe, 0xd3, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x94, 0x90, 
+-      0x2e, 0x08, 0x94, 0x98, 0xb5, 0xf0, 0x1c, 0x07, 
+-      0x1c, 0x0c, 0x2f, 0x10, 0xd0, 0x13, 0x20, 0x4c, 
+-      0x43, 0x78, 0x19, 0x00, 0x1d, 0xc6, 0x36, 0x01, 
+-      0x20, 0x4c, 0x43, 0x78, 0x19, 0x00, 0x1d, 0xc5, 
+-      0x35, 0x4d, 0x20, 0x10, 0x1b, 0xc0, 0x22, 0x4c, 
+-      0x43, 0x42, 0x1c, 0x31, 0x1c, 0x28, 0x4b, 0x03, 
+-      0x68, 0x1b, 0xf0, 0x00, 0xfe, 0xb3, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x94, 0x98, 
+-      0xb5, 0x90, 0x1c, 0x04, 0x1c, 0x0f, 0x1c, 0x39, 
+-      0x1c, 0x20, 0xf0, 0x00, 0xf8, 0x07, 0x1c, 0x39, 
+-      0x20, 0x00, 0xf0, 0x00, 0xf8, 0x33, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0xf0, 0x1c, 0x04, 
+-      0x1c, 0x0f, 0x00, 0xa0, 0x19, 0x00, 0x00, 0xc0, 
+-      0x19, 0xc0, 0x23, 0xb1, 0x00, 0xdb, 0x18, 0xc6, 
+-      0x00, 0xa0, 0x19, 0x00, 0x00, 0xc0, 0x19, 0xc0, 
+-      0x23, 0x2b, 0x01, 0x5b, 0x18, 0xc5, 0x20, 0x06, 
+-      0x1b, 0x00, 0x00, 0x82, 0x18, 0x12, 0x00, 0xd2, 
+-      0x1c, 0x31, 0x1c, 0x28, 0x4b, 0x09, 0x68, 0x1b, 
+-      0xf0, 0x00, 0xfe, 0x84, 0x1d, 0xfe, 0x36, 0x05, 
+-      0x23, 0x65, 0x01, 0x1b, 0x18, 0xfd, 0x1c, 0x31, 
+-      0x1c, 0x28, 0x4a, 0x05, 0x68, 0x13, 0x22, 0x28, 
+-      0xf0, 0x00, 0xfe, 0x78, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x94, 0x98, 
+-      0x2e, 0x08, 0x94, 0x90, 0xb5, 0xf0, 0x1c, 0x07, 
+-      0x1c, 0x0c, 0x20, 0x4c, 0x43, 0x78, 0x19, 0x00, 
+-      0x1d, 0xc6, 0x36, 0x4d, 0x20, 0x4c, 0x43, 0x78, 
+-      0x19, 0x00, 0x1d, 0xc5, 0x35, 0x01, 0x20, 0x10, 
+-      0x1b, 0xc0, 0x22, 0x4c, 0x43, 0x42, 0x1c, 0x31, 
+-      0x1c, 0x28, 0x4b, 0x03, 0x68, 0x1b, 0xf0, 0x00, 
+-      0xfe, 0x59, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x94, 0x98, 0xb4, 0xb0, 0x1c, 0x02, 
+-      0x1c, 0x0f, 0x20, 0x00, 0x1c, 0x03, 0x30, 0x01, 
+-      0x00, 0x9b, 0x18, 0x9c, 0x23, 0x07, 0x02, 0x1b, 
+-      0x18, 0xe3, 0x68, 0x5b, 0x10, 0x7c, 0x34, 0x01, 
+-      0x42, 0xa3, 0xd2, 0x00, 0xe7, 0xf2, 0x38, 0x01, 
+-      0x21, 0x18, 0x42, 0x81, 0xd8, 0x02, 0xe0, 0x1a, 
+-      0x39, 0x01, 0xe7, 0xfa, 0x00, 0x8b, 0x18, 0x9c, 
+-      0x23, 0x0d, 0x01, 0xdb, 0x18, 0xe3, 0x69, 0xdc, 
+-      0x00, 0x8b, 0x18, 0x9d, 0x23, 0x0d, 0x01, 0xdb, 
+-      0x18, 0xeb, 0x62, 0x1c, 0x00, 0x8b, 0x18, 0x9c, 
+-      0x23, 0x07, 0x02, 0x1b, 0x18, 0xe3, 0x68, 0x1c, 
+-      0x00, 0x8b, 0x18, 0x9d, 0x23, 0x07, 0x02, 0x1b, 
+-      0x18, 0xeb, 0x60, 0x5c, 0xe7, 0xe4, 0x23, 0x00, 
+-      0x2b, 0x00, 0xd0, 0x10, 0x10, 0x7b, 0x1c, 0x5c, 
+-      0x00, 0x83, 0x18, 0x9d, 0x23, 0x0d, 0x01, 0xdb, 
+-      0x18, 0xeb, 0x62, 0x1c, 0x10, 0x7b, 0x1c, 0x5c, 
+-      0x00, 0x83, 0x18, 0x9d, 0x23, 0x07, 0x02, 0x1b, 
+-      0x18, 0xeb, 0x60, 0x5c, 0xe0, 0x0e, 0x10, 0x7c, 
+-      0x00, 0x83, 0x18, 0x9d, 0x23, 0x0d, 0x01, 0xdb, 
+-      0x18, 0xeb, 0x62, 0x1c, 0x10, 0x7b, 0x1c, 0x5c, 
+-      0x00, 0x83, 0x18, 0x9d, 0x23, 0x07, 0x02, 0x1b, 
+-      0x18, 0xeb, 0x60, 0x5c, 0xbc, 0xb0, 0x47, 0x70, 
+-      0xb4, 0xb0, 0x1c, 0x02, 0x1c, 0x0f, 0x21, 0x00, 
+-      0x1c, 0x0b, 0x31, 0x01, 0x00, 0x9b, 0x18, 0x9c, 
+-      0x23, 0x07, 0x02, 0x1b, 0x18, 0xe3, 0x68, 0x5b, 
+-      0x10, 0x7c, 0x34, 0x01, 0x42, 0xa3, 0xd0, 0x00, 
+-      0xe7, 0xf2, 0x39, 0x01, 0x1c, 0x08, 0x28, 0x18, 
+-      0xd3, 0x02, 0xe0, 0x1a, 0x30, 0x01, 0xe7, 0xfa, 
+-      0x00, 0x83, 0x18, 0x9c, 0x23, 0x0d, 0x01, 0xdb, 
+-      0x18, 0xe3, 0x6a, 0x5c, 0x00, 0x83, 0x18, 0x9d, 
+-      0x23, 0x0d, 0x01, 0xdb, 0x18, 0xeb, 0x62, 0x1c, 
+-      0x00, 0x83, 0x18, 0x9c, 0x23, 0x07, 0x02, 0x1b, 
+-      0x18, 0xe3, 0x68, 0x9c, 0x00, 0x83, 0x18, 0x9d, 
+-      0x23, 0x07, 0x02, 0x1b, 0x18, 0xeb, 0x60, 0x5c, 
+-      0xe7, 0xe4, 0x4c, 0x06, 0x23, 0x07, 0x02, 0x1b, 
+-      0x18, 0xd3, 0x60, 0x1c, 0x4c, 0x03, 0x23, 0x07, 
+-      0x02, 0x1b, 0x18, 0xd3, 0x66, 0x5c, 0xbc, 0xb0, 
+-      0x47, 0x70, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 
+-      0xb4, 0xb0, 0x1c, 0x07, 0x1c, 0x0c, 0x1c, 0x15, 
+-      0x6a, 0xa1, 0x23, 0x01, 0x02, 0x9b, 0x43, 0x19, 
+-      0x62, 0x39, 0x21, 0x01, 0x02, 0x89, 0x43, 0x29, 
+-      0x62, 0x79, 0x6a, 0xe1, 0x05, 0x89, 0x0d, 0x89, 
+-      0x61, 0xf9, 0x6b, 0x61, 0x31, 0x01, 0x05, 0x89, 
+-      0x0d, 0x89, 0x61, 0xb9, 0x69, 0x61, 0x60, 0xf9, 
+-      0x69, 0xa1, 0x61, 0x39, 0x69, 0xe1, 0x61, 0x79, 
+-      0x68, 0xa1, 0x23, 0x01, 0x06, 0x1b, 0x40, 0x19, 
+-      0xd0, 0x02, 0x49, 0x0f, 0x60, 0xb9, 0xe0, 0x01, 
+-      0x21, 0x00, 0x60, 0xb9, 0x6a, 0x60, 0x28, 0x00, 
+-      0xd0, 0x0b, 0x68, 0x41, 0x60, 0x39, 0x78, 0x01, 
+-      0x00, 0x89, 0x4b, 0x0a, 0x18, 0xc9, 0x60, 0x79, 
+-      0x68, 0xb9, 0x88, 0x42, 0x43, 0x11, 0x60, 0xb9, 
+-      0xe0, 0x07, 0x21, 0x00, 0x60, 0x39, 0x21, 0x00, 
+-      0x60, 0x79, 0x68, 0xb9, 0x0c, 0x09, 0x04, 0x09, 
+-      0x60, 0xb9, 0xbc, 0xb0, 0x47, 0x70, 0x00, 0x00, 
+-      0xff, 0xff, 0x00, 0x00, 0x68, 0x00, 0x08, 0x00, 
+-      0xb4, 0x80, 0x1c, 0x02, 0x1c, 0x0f, 0x69, 0x79, 
+-      0x60, 0xd1, 0x69, 0xb9, 0x61, 0x11, 0x69, 0xf9, 
+-      0x61, 0x51, 0x68, 0xb9, 0x23, 0x01, 0x06, 0x1b, 
+-      0x40, 0x19, 0xd0, 0x02, 0x49, 0x0e, 0x60, 0x91, 
+-      0xe0, 0x01, 0x21, 0x00, 0x60, 0x91, 0x6a, 0x78, 
+-      0x28, 0x00, 0xd0, 0x0b, 0x68, 0x41, 0x60, 0x11, 
+-      0x78, 0x01, 0x00, 0x89, 0x4b, 0x09, 0x18, 0xc9, 
+-      0x60, 0x51, 0x68, 0x91, 0x88, 0x43, 0x43, 0x19, 
+-      0x60, 0x91, 0xe0, 0x07, 0x21, 0x00, 0x60, 0x11, 
+-      0x21, 0x00, 0x60, 0x51, 0x68, 0x91, 0x0c, 0x09, 
+-      0x04, 0x09, 0x60, 0x91, 0xbc, 0x80, 0x47, 0x70, 
+-      0xff, 0xff, 0x00, 0x00, 0x68, 0x00, 0x08, 0x00, 
+-      0x1c, 0x01, 0x48, 0x07, 0x62, 0x08, 0x48, 0x06, 
+-      0x62, 0x48, 0x48, 0x05, 0x61, 0xc8, 0x48, 0x04, 
+-      0x61, 0x88, 0x20, 0x00, 0x60, 0x08, 0x20, 0x00, 
+-      0x60, 0x48, 0x20, 0x00, 0x60, 0x88, 0x47, 0x70, 
+-      0x00, 0x00, 0xff, 0xff, 0xb5, 0xb0, 0x1c, 0x07, 
+-      0x1c, 0x0c, 0x2c, 0x07, 0xd2, 0x73, 0x25, 0x00, 
+-      0x2d, 0x07, 0xdb, 0x02, 0xe0, 0x2f, 0x35, 0x01, 
+-      0xe7, 0xfa, 0x00, 0xa8, 0x19, 0x40, 0x00, 0xc0, 
+-      0x19, 0xc0, 0x23, 0x0b, 0x01, 0xdb, 0x18, 0xc0, 
+-      0x68, 0x00, 0x00, 0xa9, 0x19, 0x49, 0x00, 0xc9, 
+-      0x19, 0xc9, 0x23, 0x0b, 0x01, 0xdb, 0x18, 0xc9, 
+-      0x68, 0x49, 0x42, 0x88, 0xd0, 0x1a, 0x00, 0xa8, 
+-      0x19, 0x40, 0x00, 0xc0, 0x19, 0xc0, 0x23, 0x0b, 
+-      0x01, 0xdb, 0x18, 0xc0, 0x68, 0x40, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x98, 0x1c, 0x02, 0x00, 0xa8, 
+-      0x19, 0x40, 0x00, 0xc0, 0x19, 0xc0, 0x23, 0x0b, 
+-      0x01, 0xdb, 0x18, 0xc0, 0x68, 0x00, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x98, 0x1c, 0x01, 0x48, 0xf8, 
+-      0xf0, 0x00, 0xfb, 0xd2, 0xe7, 0xcf, 0x23, 0xcf, 
+-      0x00, 0xdb, 0x18, 0xf8, 0xf7, 0xff, 0xfb, 0xb8, 
+-      0x25, 0x00, 0x2d, 0x07, 0xdb, 0x02, 0xe0, 0x54, 
+-      0x35, 0x01, 0xe7, 0xfa, 0x00, 0xa8, 0x19, 0x40, 
+-      0x00, 0xc0, 0x19, 0xc0, 0x23, 0x0b, 0x01, 0xdb, 
+-      0x18, 0xc0, 0x68, 0x00, 0x00, 0xa9, 0x19, 0x49, 
+-      0x00, 0xc9, 0x19, 0xc9, 0x23, 0x0b, 0x01, 0xdb, 
+-      0x18, 0xc9, 0x68, 0x49, 0x42, 0x88, 0xd0, 0x1a, 
+-      0x00, 0xa8, 0x19, 0x40, 0x00, 0xc0, 0x19, 0xc0, 
+-      0x23, 0x0b, 0x01, 0xdb, 0x18, 0xc0, 0x68, 0x40, 
+-      0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 0x1c, 0x02, 
+-      0x00, 0xa8, 0x19, 0x40, 0x00, 0xc0, 0x19, 0xc0, 
+-      0x23, 0x0b, 0x01, 0xdb, 0x18, 0xc0, 0x68, 0x00, 
+-      0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 0x1c, 0x01, 
+-      0x48, 0xdb, 0xf0, 0x00, 0xfb, 0x6b, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x6a, 0xc0, 0x21, 0x4c, 
+-      0x43, 0x69, 0x19, 0xc9, 0xe0, 0x00, 0xe0, 0x94, 
+-      0x6b, 0x09, 0x42, 0x88, 0xd0, 0x12, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x6b, 0x00, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x98, 0x1c, 0x02, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x6a, 0xc0, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x98, 0x1c, 0x01, 0x48, 0xcc, 
+-      0xf0, 0x00, 0xfb, 0x7a, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x30, 0x34, 0xf7, 0xff, 0xfb, 0x60, 
+-      0xe7, 0xaa, 0x25, 0x07, 0x2d, 0x11, 0xdb, 0x02, 
+-      0xe0, 0x4e, 0x35, 0x01, 0xe7, 0xfa, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x38, 0xff, 0x38, 0xff, 
+-      0x38, 0x02, 0x69, 0x80, 0x21, 0x4c, 0x43, 0x69, 
+-      0x19, 0xc9, 0x39, 0xff, 0x39, 0xff, 0x39, 0x02, 
+-      0x69, 0xc9, 0x42, 0x88, 0xd0, 0x18, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x38, 0xff, 0x38, 0xff, 
+-      0x38, 0x02, 0x69, 0xc0, 0x23, 0x01, 0x02, 0x9b, 
+-      0x43, 0x98, 0x1c, 0x02, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 
+-      0x69, 0x80, 0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 
+-      0x1c, 0x01, 0x48, 0xb1, 0xf0, 0x00, 0xfb, 0x16, 
+-      0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 0x6a, 0xc0, 
+-      0x21, 0x4c, 0x43, 0x69, 0x19, 0xc9, 0x6b, 0x09, 
+-      0x42, 0x88, 0xd0, 0x12, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x6b, 0x00, 0x23, 0x01, 0x02, 0x9b, 
+-      0x43, 0x98, 0x1c, 0x02, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x6a, 0xc0, 0x23, 0x01, 0x02, 0x9b, 
+-      0x43, 0x98, 0x1c, 0x01, 0x48, 0xa2, 0xf0, 0x00, 
+-      0xfb, 0x27, 0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 
+-      0x30, 0x34, 0xf7, 0xff, 0xfb, 0x0d, 0xe7, 0xb0, 
+-      0x25, 0x0a, 0x2d, 0x11, 0xdb, 0x02, 0xe0, 0x1f, 
+-      0x35, 0x01, 0xe7, 0xfa, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x6a, 0xc0, 0x21, 0x4c, 0x43, 0x69, 
+-      0x19, 0xc9, 0x6b, 0x09, 0x42, 0x88, 0xd0, 0x12, 
+-      0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 0x6b, 0x00, 
+-      0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 0x1c, 0x02, 
+-      0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 0x6a, 0xc0, 
+-      0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 0x1c, 0x01, 
+-      0x48, 0x8d, 0xf0, 0x00, 0xfa, 0xcf, 0xe7, 0xdf, 
+-      0xe1, 0xca, 0x2c, 0x0e, 0xd3, 0x73, 0x3c, 0x07, 
+-      0x1f, 0xe5, 0x42, 0xa5, 0xd3, 0x02, 0xe0, 0x1f, 
+-      0x35, 0x01, 0xe7, 0xfa, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x6a, 0xc0, 0x21, 0x4c, 0x43, 0x69, 
+-      0x19, 0xc9, 0x6b, 0x09, 0x42, 0x88, 0xd0, 0x12, 
+-      0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 0x6b, 0x00, 
+-      0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 0x1c, 0x02, 
+-      0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 0x6a, 0xc0, 
+-      0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 0x1c, 0x01, 
+-      0x48, 0x79, 0xf0, 0x00, 0xfa, 0xd5, 0xe7, 0xdf, 
+-      0x1c, 0x25, 0x2d, 0x11, 0xdb, 0x02, 0xe0, 0x50, 
+-      0x35, 0x01, 0xe7, 0xfa, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 
+-      0x69, 0x80, 0x21, 0x4c, 0x43, 0x69, 0x19, 0xc9, 
+-      0x39, 0xff, 0x39, 0xff, 0x39, 0x02, 0x69, 0xc9, 
+-      0x42, 0x88, 0xd0, 0x18, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 
+-      0x69, 0xc0, 0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 
+-      0x1c, 0x02, 0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 
+-      0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 0x69, 0x80, 
+-      0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 0x1c, 0x01, 
+-      0x48, 0x61, 0xf0, 0x00, 0xfa, 0x77, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x6a, 0xc0, 0x21, 0x4c, 
+-      0x43, 0x69, 0x19, 0xc9, 0x6b, 0x09, 0x42, 0x88, 
+-      0xd0, 0x12, 0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 
+-      0x6b, 0x00, 0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 
+-      0x1c, 0x02, 0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 
+-      0x6a, 0xc0, 0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 
+-      0x1c, 0x01, 0x48, 0x53, 0xf0, 0x00, 0xfa, 0x88, 
+-      0x20, 0x4c, 0x43, 0x68, 0xe0, 0x00, 0xe0, 0x29, 
+-      0x19, 0xc0, 0x30, 0x34, 0xf7, 0xff, 0xfa, 0x6c, 
+-      0xe7, 0xae, 0x25, 0x0a, 0x2d, 0x11, 0xdb, 0x02, 
+-      0xe0, 0x1f, 0x35, 0x01, 0xe7, 0xfa, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x6a, 0xc0, 0x21, 0x4c, 
+-      0x43, 0x69, 0x19, 0xc9, 0x6b, 0x09, 0x42, 0x88, 
+-      0xd0, 0x12, 0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 
+-      0x6b, 0x00, 0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 
+-      0x1c, 0x02, 0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 
+-      0x6a, 0xc0, 0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 
+-      0x1c, 0x01, 0x48, 0x3d, 0xf0, 0x00, 0xfa, 0x2e, 
+-      0xe7, 0xdf, 0xe1, 0x29, 0x3c, 0x07, 0x1c, 0x25, 
+-      0x2d, 0x07, 0xdb, 0x02, 0xe0, 0x2f, 0x35, 0x01, 
+-      0xe7, 0xfa, 0x00, 0xa8, 0x19, 0x40, 0x00, 0xc0, 
+-      0x19, 0xc0, 0x23, 0x0b, 0x01, 0xdb, 0x18, 0xc0, 
+-      0x68, 0x00, 0x00, 0xa9, 0x19, 0x49, 0x00, 0xc9, 
+-      0x19, 0xc9, 0x23, 0x0b, 0x01, 0xdb, 0x18, 0xc9, 
+-      0x68, 0x49, 0x42, 0x88, 0xd0, 0x1a, 0x00, 0xa8, 
+-      0x19, 0x40, 0x00, 0xc0, 0x19, 0xc0, 0x23, 0x0b, 
+-      0x01, 0xdb, 0x18, 0xc0, 0x68, 0x40, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x98, 0x1c, 0x02, 0x00, 0xa8, 
+-      0x19, 0x40, 0x00, 0xc0, 0x19, 0xc0, 0x23, 0x0b, 
+-      0x01, 0xdb, 0x18, 0xc0, 0x68, 0x00, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x98, 0x1c, 0x01, 0x48, 0x22, 
+-      0xf0, 0x00, 0xfa, 0x26, 0xe7, 0xcf, 0x25, 0x00, 
+-      0x42, 0xa5, 0xd3, 0x02, 0xe0, 0x1f, 0x35, 0x01, 
+-      0xe7, 0xfa, 0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 
+-      0x6a, 0xc0, 0x21, 0x4c, 0x43, 0x69, 0x19, 0xc9, 
+-      0x6b, 0x09, 0x42, 0x88, 0xd0, 0x12, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x6b, 0x00, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x98, 0x1c, 0x02, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x6a, 0xc0, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x98, 0x1c, 0x01, 0x48, 0x10, 
+-      0xf0, 0x00, 0xfa, 0x02, 0xe7, 0xdf, 0x1c, 0x25, 
+-      0x2d, 0x07, 0xdb, 0x02, 0xe0, 0x55, 0x35, 0x01, 
+-      0xe7, 0xfa, 0x00, 0xa8, 0x19, 0x40, 0x00, 0xc0, 
+-      0x19, 0xc0, 0x23, 0x0b, 0x01, 0xdb, 0x18, 0xc0, 
+-      0x68, 0x00, 0x00, 0xa9, 0x19, 0x49, 0x00, 0xc9, 
+-      0x19, 0xc9, 0x23, 0x0b, 0x01, 0xdb, 0x18, 0xc9, 
+-      0x68, 0x49, 0x42, 0x88, 0xd0, 0x1d, 0x00, 0xa8, 
+-      0x19, 0x40, 0x00, 0xc0, 0x19, 0xc0, 0xe0, 0x01, 
+-      0x2e, 0x08, 0x7d, 0x94, 0x23, 0x0b, 0x01, 0xdb, 
+-      0x18, 0xc0, 0x68, 0x40, 0x23, 0x01, 0x02, 0x9b, 
+-      0x43, 0x98, 0x1c, 0x02, 0x00, 0xa8, 0x19, 0x40, 
+-      0x00, 0xc0, 0x19, 0xc0, 0x23, 0x0b, 0x01, 0xdb, 
+-      0x18, 0xc0, 0x68, 0x00, 0x23, 0x01, 0x02, 0x9b, 
+-      0x43, 0x98, 0x1c, 0x01, 0x48, 0x50, 0xf0, 0x00, 
+-      0xf9, 0x9d, 0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 
+-      0x6a, 0xc0, 0x21, 0x4c, 0x43, 0x69, 0x19, 0xc9, 
+-      0x6b, 0x09, 0x42, 0x88, 0xd0, 0x12, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x6b, 0x00, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x98, 0x1c, 0x02, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x6a, 0xc0, 0x23, 0x01, 
+-      0x02, 0x9b, 0x43, 0x98, 0x1c, 0x01, 0x48, 0x42, 
+-      0xf0, 0x00, 0xf9, 0xae, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x30, 0x34, 0xf7, 0xff, 0xf9, 0x94, 
+-      0xe7, 0xa9, 0x25, 0x07, 0x2d, 0x11, 0xdb, 0x02, 
+-      0xe0, 0x4e, 0x35, 0x01, 0xe7, 0xfa, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x38, 0xff, 0x38, 0xff, 
+-      0x38, 0x02, 0x69, 0x80, 0x21, 0x4c, 0x43, 0x69, 
+-      0x19, 0xc9, 0x39, 0xff, 0x39, 0xff, 0x39, 0x02, 
+-      0x69, 0xc9, 0x42, 0x88, 0xd0, 0x18, 0x20, 0x4c, 
+-      0x43, 0x68, 0x19, 0xc0, 0x38, 0xff, 0x38, 0xff, 
+-      0x38, 0x02, 0x69, 0xc0, 0x23, 0x01, 0x02, 0x9b, 
+-      0x43, 0x98, 0x1c, 0x02, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x38, 0xff, 0x38, 0xff, 0x38, 0x02, 
+-      0x69, 0x80, 0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 
+-      0x1c, 0x01, 0x48, 0x27, 0xf0, 0x00, 0xf9, 0x4a, 
+-      0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 0x6a, 0xc0, 
+-      0x21, 0x4c, 0x43, 0x69, 0x19, 0xc9, 0x6b, 0x09, 
+-      0x42, 0x88, 0xd0, 0x12, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x6b, 0x00, 0x23, 0x01, 0x02, 0x9b, 
+-      0x43, 0x98, 0x1c, 0x02, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x6a, 0xc0, 0x23, 0x01, 0x02, 0x9b, 
+-      0x43, 0x98, 0x1c, 0x01, 0x48, 0x18, 0xf0, 0x00, 
+-      0xf9, 0x5b, 0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 
+-      0x30, 0x34, 0xf7, 0xff, 0xf9, 0x41, 0xe7, 0xb0, 
+-      0x25, 0x0a, 0x2d, 0x11, 0xdb, 0x02, 0xe0, 0x1f, 
+-      0x35, 0x01, 0xe7, 0xfa, 0x20, 0x4c, 0x43, 0x68, 
+-      0x19, 0xc0, 0x6a, 0xc0, 0x21, 0x4c, 0x43, 0x69, 
+-      0x19, 0xc9, 0x6b, 0x09, 0x42, 0x88, 0xd0, 0x12, 
+-      0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 0x6b, 0x00, 
+-      0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 0x1c, 0x02, 
+-      0x20, 0x4c, 0x43, 0x68, 0x19, 0xc0, 0x6a, 0xc0, 
+-      0x23, 0x01, 0x02, 0x9b, 0x43, 0x98, 0x1c, 0x01, 
+-      0x48, 0x03, 0xf0, 0x00, 0xf9, 0x03, 0xe7, 0xdf, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7d, 0x94, 0xb4, 0x90, 0x1c, 0x02, 
+-      0x1c, 0x0f, 0x3a, 0x01, 0x2f, 0x01, 0xd1, 0x0d, 
+-      0x09, 0x50, 0x00, 0x80, 0x49, 0x0d, 0x58, 0x08, 
+-      0x06, 0xd4, 0x0e, 0xe4, 0x21, 0x01, 0x40, 0xa1, 
+-      0x43, 0x08, 0x09, 0x51, 0x00, 0x89, 0x4b, 0x09, 
+-      0x50, 0x58, 0xe0, 0x0d, 0x09, 0x50, 0x00, 0x80, 
+-      0x49, 0x06, 0x58, 0x08, 0x06, 0xd4, 0x0e, 0xe4, 
+-      0x21, 0x01, 0x40, 0xa1, 0x43, 0xc9, 0x40, 0x01, 
+-      0x09, 0x50, 0x00, 0x80, 0x4b, 0x01, 0x50, 0x19, 
+-      0xbc, 0x90, 0x47, 0x70, 0x2e, 0x08, 0x94, 0x8c, 
+-      0xb4, 0x80, 0x1c, 0x01, 0x39, 0x01, 0x09, 0x48, 
+-      0x00, 0x80, 0x4a, 0x08, 0x58, 0x10, 0x06, 0xca, 
+-      0x0e, 0xd2, 0x27, 0x01, 0x40, 0x97, 0x1c, 0x3b, 
+-      0x40, 0x18, 0xd0, 0x03, 0x20, 0x01, 0xbc, 0x80, 
+-      0x47, 0x70, 0xe0, 0x01, 0x20, 0x00, 0xe7, 0xfa, 
+-      0xe7, 0xf9, 0x00, 0x00, 0x2e, 0x08, 0x94, 0x8c, 
+-      0xb4, 0xf0, 0x1c, 0x07, 0x1c, 0x0a, 0x68, 0x54, 
+-      0x6a, 0xf8, 0x05, 0x86, 0x0d, 0xb6, 0x2c, 0x07, 
+-      0xda, 0x01, 0x1c, 0x20, 0xe0, 0x00, 0x20, 0x07, 
+-      0x1c, 0x05, 0x21, 0x00, 0x42, 0xa9, 0xd3, 0x02, 
+-      0xe0, 0x15, 0x31, 0x01, 0xe7, 0xfa, 0x00, 0x88, 
+-      0x18, 0x40, 0x00, 0xc0, 0x18, 0x80, 0x23, 0x05, 
+-      0x02, 0x1b, 0x18, 0xc0, 0x6f, 0xc0, 0x42, 0xb0, 
+-      0xd1, 0x08, 0x00, 0x88, 0x18, 0x40, 0x00, 0xc0, 
+-      0x18, 0x80, 0x23, 0x2b, 0x01, 0x5b, 0x18, 0xc0, 
+-      0xbc, 0xf0, 0x47, 0x70, 0xe7, 0xe9, 0x1f, 0xe0, 
+-      0x28, 0x11, 0xda, 0x01, 0x1f, 0xe0, 0xe0, 0x00, 
+-      0x20, 0x11, 0x1c, 0x05, 0x21, 0x00, 0x42, 0xa9, 
+-      0xd3, 0x02, 0xe0, 0x0d, 0x31, 0x01, 0xe7, 0xfa, 
+-      0x20, 0x4c, 0x43, 0x48, 0x18, 0x80, 0x6a, 0x80, 
+-      0x42, 0xb0, 0xd1, 0x04, 0x20, 0x4c, 0x43, 0x48, 
+-      0x18, 0x80, 0x30, 0x0c, 0xe7, 0xe4, 0xe7, 0xf1, 
+-      0x20, 0x00, 0xe7, 0xe1, 0xe7, 0xe0, 0xb5, 0x90, 
+-      0x48, 0x07, 0x68, 0x04, 0x48, 0x07, 0x68, 0x07, 
+-      0x1c, 0x39, 0x1c, 0x20, 0x4a, 0x06, 0x68, 0x13, 
+-      0x22, 0xf3, 0x00, 0xd2, 0xf0, 0x00, 0xf9, 0xca, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7d, 0xb4, 0x2e, 0x08, 0x7d, 0xb8, 
+-      0x2e, 0x08, 0x94, 0x90, 0xb4, 0xf0, 0x1c, 0x01, 
+-      0xb0, 0x83, 0x22, 0x00, 0x68, 0x4b, 0x2b, 0x07, 
+-      0xdd, 0x01, 0x23, 0x07, 0xe0, 0x00, 0x68, 0x4b, 
+-      0x1c, 0x1c, 0x23, 0x00, 0x43, 0xdb, 0x93, 0x02, 
+-      0x23, 0x00, 0x43, 0xdb, 0x93, 0x01, 0x23, 0x00, 
+-      0x93, 0x00, 0x4b, 0x17, 0x68, 0x1b, 0x2b, 0x00, 
+-      0xd0, 0x07, 0x4b, 0x15, 0x68, 0x1b, 0x6a, 0xdb, 
+-      0x93, 0x02, 0x4b, 0x13, 0x68, 0x1b, 0x6b, 0x5b, 
+-      0x93, 0x01, 0x20, 0x00, 0x42, 0xa0, 0xd3, 0x02, 
+-      0xe0, 0x16, 0x30, 0x01, 0xe7, 0xfa, 0x00, 0x83, 
+-      0x18, 0x1b, 0x00, 0xdb, 0x18, 0x5d, 0x23, 0x05, 
+-      0x02, 0x1b, 0x18, 0xeb, 0x6e, 0x9f, 0x04, 0x3b, 
+-      0x0c, 0x1b, 0xd0, 0x08, 0x0c, 0x3b, 0x04, 0x1b, 
+-      0xd0, 0x05, 0x9b, 0x00, 0x18, 0xc5, 0x26, 0x01, 
+-      0x40, 0xae, 0x1c, 0x33, 0x43, 0x1a, 0xe7, 0xe8, 
+-      0x23, 0x0d, 0x01, 0xdb, 0x18, 0xcb, 0x61, 0xda, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0x47, 0x70, 0x00, 0x00, 
+-      0x2e, 0x08, 0x7c, 0x58, 0xb4, 0x80, 0x1c, 0x01, 
+-      0x20, 0x00, 0x68, 0x0a, 0x42, 0x90, 0xdb, 0x02, 
+-      0xe0, 0x07, 0x30, 0x01, 0xe7, 0xf9, 0x23, 0x00, 
+-      0x43, 0xdb, 0x68, 0x8a, 0x00, 0x87, 0x51, 0xd3, 
+-      0xe7, 0xf7, 0x22, 0x00, 0x43, 0xd2, 0x68, 0x8b, 
+-      0x68, 0x0f, 0x00, 0xbf, 0x51, 0xda, 0x23, 0x00, 
+-      0x43, 0xdb, 0x68, 0x8a, 0x68, 0x0f, 0x00, 0xbf, 
+-      0x19, 0xd2, 0x60, 0x53, 0x22, 0x00, 0x60, 0x4a, 
+-      0xbc, 0x80, 0x47, 0x70, 0xb4, 0xf0, 0x1c, 0x03, 
+-      0x1c, 0x0c, 0x1c, 0x17, 0x68, 0x9a, 0xca, 0x40, 
+-      0x42, 0xa6, 0xd2, 0x00, 0xe7, 0xfb, 0x3a, 0x04, 
+-      0x1c, 0x11, 0xc9, 0x40, 0x42, 0xbe, 0xd2, 0x00, 
+-      0xe7, 0xfb, 0x39, 0x04, 0x68, 0x10, 0x42, 0xa0, 
+-      0xd1, 0x02, 0x68, 0x08, 0x42, 0xb8, 0xd0, 0x02, 
+-      0x20, 0xff, 0xbc, 0xf0, 0x47, 0x70, 0x39, 0x04, 
+-      0x68, 0x98, 0x68, 0x5e, 0x00, 0xb6, 0x19, 0x85, 
+-      0x68, 0x58, 0x38, 0x02, 0x60, 0x58, 0x68, 0x50, 
+-      0x60, 0x10, 0x32, 0x04, 0x42, 0x8a, 0xd3, 0xfa, 
+-      0x68, 0x88, 0x60, 0x08, 0x31, 0x04, 0x42, 0xa9, 
+-      0xd3, 0xfa, 0x20, 0x00, 0xe7, 0xe9, 0xe7, 0xe8, 
+-      0xb4, 0xf0, 0x1c, 0x03, 0x1c, 0x0c, 0x1c, 0x17, 
+-      0x68, 0x58, 0x68, 0x1e, 0x3e, 0x01, 0x42, 0xb0, 
+-      0xdb, 0x02, 0x20, 0xff, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x68, 0x9a, 0xca, 0x40, 0x42, 0xa6, 0xd2, 0x00, 
+-      0xe7, 0xfb, 0x3a, 0x04, 0x1c, 0x15, 0xcd, 0x40, 
+-      0x42, 0xbe, 0xd2, 0x00, 0xe7, 0xfb, 0x68, 0x58, 
+-      0x30, 0x02, 0x60, 0x58, 0x68, 0x98, 0x68, 0x5e, 
+-      0x00, 0xb6, 0x19, 0x80, 0x1f, 0xc1, 0x39, 0x01, 
+-      0x68, 0x08, 0x60, 0x88, 0x39, 0x04, 0x1d, 0xc8, 
+-      0x30, 0x01, 0x42, 0xa8, 0xd8, 0xf8, 0x60, 0x8f, 
+-      0x68, 0x08, 0x60, 0x48, 0x39, 0x04, 0x1d, 0x08, 
+-      0x42, 0x90, 0xd8, 0xf9, 0x60, 0x14, 0x20, 0x00, 
+-      0xe7, 0xd8, 0xe7, 0xd7, 0xb5, 0xf0, 0x1c, 0x07, 
+-      0x1c, 0x0c, 0xb0, 0x81, 0x1c, 0x38, 0x21, 0x00, 
+-      0xf0, 0x0c, 0xff, 0xe0, 0x1c, 0x06, 0x1c, 0x38, 
+-      0x21, 0x01, 0xf0, 0x0c, 0xff, 0xdb, 0x90, 0x00, 
+-      0x1c, 0x31, 0x1c, 0x38, 0xf0, 0x00, 0xf8, 0x50, 
+-      0x49, 0x20, 0x68, 0x09, 0x60, 0x08, 0x99, 0x00, 
+-      0x1c, 0x38, 0xf0, 0x00, 0xf8, 0x49, 0x49, 0x1e, 
+-      0x68, 0x09, 0x60, 0x08, 0x48, 0x1b, 0x68, 0x00, 
+-      0x68, 0x05, 0x48, 0x1c, 0x68, 0x01, 0x23, 0x02, 
+-      0x43, 0xdb, 0x40, 0x19, 0x60, 0x01, 0x2c, 0x00, 
+-      0xd0, 0x0c, 0x48, 0x19, 0x68, 0x00, 0x78, 0x00, 
+-      0x28, 0x00, 0xd0, 0x07, 0x48, 0x14, 0x68, 0x00, 
+-      0x68, 0x05, 0x48, 0x14, 0x68, 0x01, 0x23, 0x02, 
+-      0x43, 0x19, 0x60, 0x01, 0x1c, 0x20, 0x49, 0x13, 
+-      0x68, 0x09, 0x70, 0x08, 0x48, 0x12, 0x63, 0xc5, 
+-      0x20, 0x3f, 0x04, 0x00, 0x40, 0x28, 0x0c, 0x00, 
+-      0x49, 0x10, 0x62, 0x08, 0x20, 0xff, 0x02, 0x00, 
+-      0x40, 0x28, 0x0a, 0x00, 0x49, 0x0d, 0x62, 0x48, 
+-      0x06, 0xa8, 0x0e, 0x80, 0x23, 0x80, 0x43, 0x18, 
+-      0x49, 0x0a, 0x62, 0x88, 0x1c, 0x28, 0xb0, 0x01, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0xb0, 0x01, 
+-      0xe7, 0xfa, 0x00, 0x00, 0x2e, 0x08, 0x94, 0x9c, 
+-      0x2e, 0x08, 0x94, 0xa0, 0x6a, 0x00, 0x00, 0x18, 
+-      0x2e, 0x08, 0x94, 0xa4, 0x2e, 0x08, 0x94, 0xa8, 
+-      0x68, 0x00, 0x0d, 0x00, 0x72, 0x00, 0x01, 0x00, 
+-      0xb4, 0x80, 0x1c, 0x02, 0x1c, 0x0f, 0x06, 0xb9, 
+-      0x0e, 0x89, 0x20, 0x01, 0x03, 0x80, 0x40, 0x10, 
+-      0x09, 0xc0, 0x43, 0x01, 0x20, 0xf0, 0x40, 0x10, 
+-      0x01, 0x40, 0x43, 0x01, 0x07, 0x10, 0x0f, 0x00, 
+-      0x03, 0x00, 0x43, 0x01, 0x20, 0x07, 0x02, 0xc0, 
+-      0x40, 0x10, 0x01, 0x40, 0x43, 0x01, 0x20, 0x07, 
+-      0x02, 0x00, 0x40, 0x10, 0x02, 0xc0, 0x43, 0x01, 
+-      0x1c, 0x08, 0xbc, 0x80, 0x47, 0x70, 0xe7, 0xfc, 
+-      0xb5, 0xff, 0x1c, 0x05, 0x1c, 0x0c, 0x1c, 0x17, 
+-      0x9b, 0x03, 0x06, 0x18, 0x16, 0x06, 0x20, 0x33, 
+-      0x06, 0x40, 0x6b, 0x80, 0x1c, 0x01, 0x20, 0x04, 
+-      0x40, 0x08, 0xd0, 0x05, 0x20, 0xd0, 0xb0, 0x04, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0xe0, 0x17, 
+-      0x23, 0x04, 0x43, 0xdb, 0x40, 0x19, 0x01, 0x08, 
+-      0x4b, 0x0a, 0x68, 0x1b, 0x18, 0xc2, 0x60, 0x15, 
+-      0x60, 0x54, 0x2e, 0xfe, 0xd0, 0x04, 0x20, 0x01, 
+-      0x40, 0xb0, 0x60, 0xd0, 0x4b, 0x06, 0x43, 0x1f, 
+-      0x60, 0x97, 0x20, 0x01, 0x40, 0x88, 0x23, 0x33, 
+-      0x06, 0x5b, 0x63, 0x58, 0x20, 0x00, 0xe7, 0xe2, 
+-      0xe7, 0xe1, 0x00, 0x00, 0x2e, 0x08, 0x20, 0x0c, 
+-      0x80, 0x00, 0x00, 0x00, 0xb4, 0xb0, 0x1c, 0x01, 
+-      0x06, 0x08, 0x16, 0x04, 0x4f, 0x0c, 0x22, 0x00, 
+-      0x20, 0x00, 0x28, 0x04, 0xd3, 0x02, 0xe0, 0x0b, 
+-      0x30, 0x01, 0xe7, 0xfa, 0x01, 0x03, 0x19, 0xdb, 
+-      0x68, 0x5b, 0x42, 0xa3, 0xd1, 0x03, 0x25, 0x01, 
+-      0x40, 0x85, 0x1c, 0x2b, 0x43, 0x1a, 0xe7, 0xf3, 
+-      0x23, 0x33, 0x06, 0x5b, 0x6c, 0x1b, 0x40, 0x13, 
+-      0xd0, 0x00, 0xe7, 0xf9, 0xbc, 0xb0, 0x47, 0x70, 
+-      0x9e, 0x00, 0x00, 0xc0, 0xe3, 0xa0, 0x14, 0x62, 
+-      0xe5, 0x91, 0x10, 0x14, 0xe2, 0x01, 0x00, 0xff, 
+-      0xe5, 0x9f, 0x10, 0x2c, 0xe5, 0xd1, 0x10, 0x00, 
+-      0xe3, 0x51, 0x00, 0xff, 0x0a, 0x00, 0x00, 0x05, 
+-      0xe5, 0x9f, 0x10, 0x1c, 0xe5, 0xd1, 0x10, 0x00, 
+-      0xe3, 0xa0, 0x20, 0x01, 0xe1, 0xa0, 0x11, 0x12, 
+-      0xe3, 0xa0, 0x24, 0x66, 0xe5, 0x82, 0x10, 0x10, 
+-      0xe3, 0xa0, 0x14, 0x62, 0xe5, 0x81, 0x00, 0x14, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x2e, 0x08, 0x7c, 0x48, 
+-      0x47, 0x00, 0x00, 0x00, 0x47, 0x08, 0x00, 0x00, 
+-      0x47, 0x10, 0x00, 0x00, 0x47, 0x18, 0x00, 0x00, 
+-      0x47, 0x20, 0x00, 0x00, 0x47, 0x28, 0x00, 0x00, 
+-      0x47, 0x30, 0x00, 0x00, 0x47, 0x38, 0x00, 0x00, 
+-      0x17, 0xcb, 0x40, 0x59, 0x1a, 0xc9, 0x17, 0xc2, 
+-      0x40, 0x50, 0x1a, 0x80, 0xd1, 0x01, 0xf0, 0x00, 
+-      0xfa, 0x07, 0xb4, 0x0c, 0x08, 0x4b, 0x1c, 0x02, 
+-      0x42, 0x9a, 0xd8, 0x00, 0x00, 0x52, 0xd3, 0xfb, 
+-      0x23, 0x00, 0xe0, 0x00, 0x08, 0x52, 0x42, 0x91, 
+-      0x41, 0x5b, 0x42, 0x91, 0xd3, 0x00, 0x1a, 0x89, 
+-      0x42, 0x82, 0xd1, 0xf7, 0x1c, 0x18, 0xbc, 0x0c, 
+-      0x40, 0x5a, 0x40, 0x50, 0x1a, 0x80, 0x40, 0x59, 
+-      0x1a, 0xc9, 0x47, 0x70, 0x08, 0x4b, 0x1c, 0x02, 
+-      0xd1, 0x01, 0xf0, 0x00, 0xf9, 0xe9, 0x42, 0x9a, 
+-      0xd8, 0x00, 0x00, 0x52, 0xd3, 0xfb, 0x23, 0x00, 
+-      0xe0, 0x00, 0x08, 0x52, 0x42, 0x91, 0x41, 0x5b, 
+-      0x42, 0x91, 0xd3, 0x00, 0x1a, 0x89, 0x42, 0x82, 
+-      0xd1, 0xf7, 0x1c, 0x18, 0x47, 0x70, 0x00, 0x00, 
+-      0x3a, 0x20, 0xd5, 0x09, 0x42, 0x53, 0x32, 0x20, 
+-      0x40, 0xd0, 0x46, 0x94, 0x1c, 0x0a, 0x40, 0x9a, 
+-      0x43, 0x10, 0x46, 0x62, 0x40, 0xd1, 0x47, 0x70, 
+-      0x1c, 0x08, 0x40, 0xd0, 0x21, 0x00, 0x47, 0x70, 
+-      0x40, 0x10, 0x40, 0x19, 0x47, 0x70, 0x00, 0x00, 
+-      0x47, 0x70, 0x00, 0x00, 0x1a, 0x43, 0x42, 0x93, 
+-      0xd3, 0x30, 0x46, 0x84, 0x07, 0x8b, 0xd0, 0x07, 
+-      0x1e, 0x52, 0xd3, 0x29, 0x78, 0x0b, 0x70, 0x03, 
+-      0x1c, 0x40, 0x1c, 0x49, 0x07, 0x8b, 0xd1, 0xf7, 
+-      0x07, 0x83, 0xd1, 0x17, 0x3a, 0x10, 0xd3, 0x05, 
+-      0xb4, 0xb0, 0xc9, 0xb8, 0xc0, 0xb8, 0x3a, 0x10, 
+-      0xd2, 0xfb, 0xbc, 0xb0, 0x32, 0x0c, 0xd3, 0x0f, 
+-      0xc9, 0x08, 0xc0, 0x08, 0x1f, 0x12, 0xd2, 0xfb, 
+-      0xe0, 0x0a, 0xc9, 0x08, 0x70, 0xc3, 0x0a, 0x1b, 
+-      0x70, 0x83, 0x0a, 0x1b, 0x70, 0x43, 0x0a, 0x1b, 
+-      0x70, 0x03, 0x1d, 0x00, 0x1f, 0x12, 0xd2, 0xf4, 
+-      0x1c, 0xd2, 0xd3, 0x05, 0x78, 0x0b, 0x70, 0x03, 
+-      0x1c, 0x49, 0x1c, 0x40, 0x1e, 0x52, 0xd2, 0xf9, 
+-      0x46, 0x60, 0x47, 0x70, 0x1c, 0x03, 0x43, 0x0b, 
+-      0x43, 0x13, 0x07, 0x9b, 0xd1, 0x04, 0x1f, 0x12, 
+-      0x58, 0x8b, 0x50, 0x83, 0xd1, 0xfb, 0x47, 0x70, 
+-      0x1e, 0x52, 0x5c, 0x8b, 0x54, 0x83, 0xd1, 0xfb, 
+-      0x47, 0x70, 0x00, 0x00, 0x42, 0x41, 0x46, 0x8c, 
+-      0x07, 0x83, 0xd0, 0x05, 0x78, 0x03, 0x2b, 0x00, 
+-      0xd0, 0x16, 0x1c, 0x40, 0x07, 0x83, 0xd1, 0xf9, 
+-      0x49, 0x0a, 0xc8, 0x04, 0x09, 0xc9, 0x1a, 0x53, 
+-      0x43, 0x93, 0x01, 0xc9, 0x40, 0x0b, 0xd0, 0xf8, 
+-      0x1f, 0x00, 0x0e, 0x13, 0xd0, 0x08, 0x1c, 0x40, 
+-      0x02, 0x13, 0x0e, 0x1b, 0xd0, 0x04, 0x1c, 0x40, 
+-      0x04, 0x13, 0x0e, 0x1b, 0xd0, 0x00, 0x1c, 0x40, 
+-      0x44, 0x60, 0x47, 0x70, 0x80, 0x80, 0x80, 0x80, 
+-      0x46, 0x84, 0x07, 0x83, 0xd0, 0x05, 0x1e, 0x52, 
+-      0xd3, 0x12, 0x70, 0x01, 0x1c, 0x40, 0x07, 0x83, 
+-      0xd1, 0xf9, 0x3a, 0x08, 0xd3, 0x07, 0x02, 0x0b, 
+-      0x43, 0x19, 0x04, 0x0b, 0x43, 0x19, 0x1c, 0x0b, 
+-      0xc0, 0x0a, 0x3a, 0x08, 0xd2, 0xfc, 0x1d, 0xd2, 
+-      0xd3, 0x02, 0x54, 0x81, 0x1e, 0x52, 0xd2, 0xfc, 
+-      0x46, 0x60, 0x47, 0x70, 0x46, 0x84, 0x1c, 0x03, 
+-      0x43, 0x0b, 0x07, 0x9b, 0xd1, 0x15, 0x1f, 0x12, 
+-      0xd3, 0x0b, 0xb4, 0xb0, 0x4c, 0x10, 0x01, 0xe5, 
+-      0xc9, 0x80, 0x1b, 0x3b, 0x43, 0xbb, 0x40, 0x2b, 
+-      0xd1, 0x0f, 0xc0, 0x80, 0x1f, 0x12, 0xd2, 0xf7, 
+-      0xbc, 0xb0, 0x1c, 0xd2, 0xd3, 0x11, 0x78, 0x0b, 
+-      0x70, 0x03, 0x1c, 0x49, 0x1c, 0x40, 0x2b, 0x00, 
+-      0xd0, 0x09, 0x1e, 0x52, 0xd2, 0xf7, 0x46, 0x60, 
+-      0x47, 0x70, 0xbc, 0xb0, 0x1f, 0x09, 0x1c, 0xd2, 
+-      0xe7, 0xf1, 0x70, 0x03, 0x1c, 0x40, 0x1e, 0x52, 
+-      0xd2, 0xfb, 0x46, 0x60, 0x47, 0x70, 0x00, 0x00, 
+-      0x01, 0x01, 0x01, 0x01, 0x1c, 0x02, 0x43, 0x0a, 
+-      0x07, 0x92, 0xd1, 0x13, 0x46, 0x84, 0xb4, 0x30, 
+-      0x4c, 0x0c, 0x01, 0xe5, 0xe0, 0x00, 0xc0, 0x04, 
+-      0xc9, 0x04, 0x1b, 0x13, 0x43, 0x93, 0x40, 0x2b, 
+-      0xd0, 0xf9, 0xe0, 0x01, 0x02, 0x12, 0x1c, 0x40, 
+-      0x0e, 0x13, 0x70, 0x03, 0xd1, 0xfa, 0xbc, 0x30, 
+-      0x46, 0x60, 0x47, 0x70, 0x1c, 0x03, 0x78, 0x0a, 
+-      0x70, 0x1a, 0x1c, 0x49, 0x1c, 0x5b, 0x2a, 0x00, 
+-      0xd1, 0xf9, 0x47, 0x70, 0x01, 0x01, 0x01, 0x01, 
+-      0xb5, 0x80, 0x00, 0x43, 0x15, 0x5f, 0x43, 0xff, 
+-      0x1c, 0x02, 0x0f, 0xc0, 0x07, 0xc0, 0x2f, 0x00, 
+-      0xd0, 0x15, 0x43, 0x0b, 0xd0, 0x0c, 0x28, 0x00, 
+-      0xd1, 0x07, 0x1c, 0x10, 0xf0, 0x00, 0xf9, 0x00, 
+-      0xf0, 0x00, 0xf9, 0x9a, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x21, 0x01, 0x1c, 0x10, 0xe0, 0x11, 
+-      0x21, 0x01, 0x07, 0xc8, 0xf0, 0x00, 0xfa, 0x98, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x03, 0x13, 
+-      0x43, 0x0b, 0xd1, 0x05, 0x28, 0x00, 0xd1, 0x03, 
+-      0x1c, 0x10, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x21, 0x01, 0x07, 0xc8, 0xf0, 0x00, 0xfa, 0x82, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x46, 0xbc, 0xb4, 0x60, 0x1c, 0x03, 0x43, 0x08, 
+-      0x07, 0x80, 0xd1, 0x1b, 0x1f, 0x12, 0xd3, 0x0b, 
+-      0x4e, 0x0f, 0xcb, 0x01, 0xc9, 0x80, 0x1b, 0xc0, 
+-      0xd1, 0x09, 0x1b, 0xbd, 0x43, 0xbd, 0x01, 0xf7, 
+-      0x40, 0x3d, 0xd1, 0x04, 0x1f, 0x12, 0xd2, 0xf4, 
+-      0x1c, 0xd2, 0xd3, 0x0e, 0xe0, 0x02, 0x1f, 0x1b, 
+-      0x1f, 0x09, 0x1c, 0xd2, 0x78, 0x18, 0x78, 0x0f, 
+-      0x1b, 0xc0, 0xd1, 0x06, 0x2f, 0x00, 0xd0, 0x04, 
+-      0x1c, 0x5b, 0x1c, 0x49, 0x1e, 0x52, 0xd2, 0xf5, 
+-      0x20, 0x00, 0xbc, 0x60, 0x46, 0x67, 0x47, 0x70, 
+-      0x01, 0x01, 0x01, 0x01, 0x47, 0x78, 0x00, 0x00, 
+-      0xe2, 0x10, 0xc1, 0x02, 0x12, 0x60, 0x00, 0x00, 
+-      0x03, 0x30, 0x00, 0x00, 0x03, 0xa0, 0x10, 0x00, 
+-      0x01, 0x2f, 0xff, 0x1e, 0xe3, 0x8c, 0xc1, 0x01, 
+-      0xe3, 0x8c, 0xc6, 0x1e, 0xe1, 0xb0, 0x28, 0x20, 
+-      0x01, 0xa0, 0x08, 0x00, 0x02, 0x4c, 0xc4, 0x01, 
+-      0xe1, 0xb0, 0x2c, 0x20, 0x01, 0xa0, 0x04, 0x00, 
+-      0x02, 0x4c, 0xc5, 0x02, 0xe1, 0xb0, 0x2e, 0x20, 
+-      0x01, 0xa0, 0x02, 0x00, 0x02, 0x4c, 0xc5, 0x01, 
+-      0xe1, 0xb0, 0x2f, 0x20, 0x01, 0xa0, 0x01, 0x00, 
+-      0x02, 0x4c, 0xc6, 0x02, 0xe1, 0xb0, 0x2f, 0xa0, 
+-      0x01, 0xa0, 0x00, 0x80, 0x02, 0x4c, 0xc6, 0x01, 
+-      0xe1, 0xa0, 0x00, 0x80, 0xe1, 0xa0, 0x1a, 0x00, 
+-      0xe1, 0x8c, 0x06, 0x20, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x22, 0x01, 0x07, 0xd2, 0x40, 0x50, 0x47, 0x70, 
+-      0xe2, 0x20, 0x01, 0x02, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x00, 0x40, 0x08, 0x40, 0x47, 0x70, 0x00, 0x00, 
+-      0x47, 0x78, 0x00, 0x00, 0xe3, 0xa0, 0xc4, 0xff, 
+-      0xe3, 0x8c, 0xc6, 0x0e, 0xe1, 0x5c, 0x00, 0x82, 
+-      0x9a, 0x00, 0x00, 0x0a, 0xe1, 0xb0, 0x00, 0x80, 
+-      0x03, 0x31, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0a, 
+-      0x3a, 0x00, 0x00, 0x12, 0xe1, 0x50, 0x00, 0x0c, 
+-      0x03, 0x51, 0x00, 0x00, 0x8a, 0x00, 0x01, 0x0c, 
+-      0xe1, 0xb0, 0x20, 0x82, 0x8a, 0x00, 0x00, 0x18, 
+-      0xe3, 0xa0, 0x00, 0x01, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x03, 0x53, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xf2, 
+-      0xea, 0x00, 0x01, 0x09, 0xe1, 0x50, 0x00, 0x0c, 
+-      0x03, 0x51, 0x00, 0x00, 0x8a, 0x00, 0x01, 0x02, 
+-      0xe1, 0xb0, 0x20, 0x82, 0x33, 0xa0, 0x00, 0x01, 
+-      0x23, 0xa0, 0x00, 0x00, 0x03, 0x33, 0x00, 0x00, 
+-      0x03, 0xa0, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe1, 0x50, 0x00, 0x0c, 0x03, 0x51, 0x00, 0x00, 
+-      0x8a, 0x00, 0x00, 0xf9, 0xe1, 0xb0, 0x20, 0x82, 
+-      0x23, 0xa0, 0x00, 0x00, 0x21, 0x2f, 0xff, 0x1e, 
+-      0xe1, 0x50, 0x00, 0x02, 0x01, 0x51, 0x00, 0x03, 
+-      0x33, 0xa0, 0x00, 0x01, 0x23, 0xa0, 0x00, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe1, 0x50, 0x00, 0x02, 
+-      0x01, 0x51, 0x00, 0x03, 0x83, 0xa0, 0x00, 0x01, 
+-      0x93, 0xa0, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe5, 0x9f, 0xc0, 0x28, 
+-      0xe8, 0xac, 0x7f, 0xff, 0xe2, 0x8f, 0x00, 0x0c, 
+-      0xe2, 0x4c, 0x10, 0x3c, 0xe2, 0x4e, 0xe0, 0x04, 
+-      0xe5, 0x8c, 0xe0, 0x00, 0xea, 0x00, 0x01, 0x91, 
+-      0x80, 0x00, 0x00, 0x20, 0x44, 0x69, 0x76, 0x69, 
+-      0x64, 0x65, 0x20, 0x62, 0x79, 0x20, 0x7a, 0x65, 
+-      0x72, 0x6f, 0x00, 0x00, 0x2e, 0x08, 0x21, 0x50, 
+-      0xb5, 0xf0, 0xb0, 0x8f, 0xf0, 0x00, 0xfd, 0x01, 
+-      0x1c, 0x04, 0x1c, 0x16, 0x1c, 0x0f, 0xf0, 0x00, 
+-      0xfd, 0x3b, 0x90, 0x03, 0x91, 0x04, 0x92, 0x05, 
+-      0xa3, 0x3e, 0xcb, 0x0c, 0x1c, 0x20, 0x1c, 0x39, 
+-      0xf0, 0x00, 0xfd, 0xae, 0x49, 0x3d, 0x22, 0x00, 
+-      0x4f, 0x3d, 0x28, 0x00, 0xd0, 0x0a, 0x48, 0x3d, 
+-      0xab, 0x03, 0xf0, 0x00, 0xfd, 0xfb, 0x90, 0x0c, 
+-      0x91, 0x0d, 0x92, 0x0e, 0xaa, 0x03, 0xca, 0x07, 
+-      0x1c, 0x3b, 0xe0, 0x08, 0x48, 0x38, 0xab, 0x03, 
+-      0x3e, 0x01, 0xf0, 0x00, 0xfd, 0xef, 0x90, 0x0c, 
+-      0x91, 0x0d, 0x92, 0x0e, 0x1c, 0x3b, 0xf0, 0x00, 
+-      0xfe, 0x03, 0x1c, 0x3b, 0xf0, 0x00, 0xfd, 0xe6, 
+-      0xab, 0x0c, 0xf0, 0x00, 0xfe, 0x17, 0x90, 0x09, 
+-      0x91, 0x0a, 0x92, 0x0b, 0xf0, 0x00, 0xfe, 0x48, 
+-      0x1c, 0x04, 0x1c, 0x15, 0x1c, 0x0f, 0x4a, 0x2d, 
+-      0xb4, 0x04, 0x23, 0x03, 0x1c, 0x2a, 0xf0, 0x00, 
+-      0xfe, 0x5b, 0x90, 0x01, 0x91, 0x02, 0x92, 0x03, 
+-      0xb0, 0x01, 0x4a, 0x29, 0xb4, 0x04, 0x23, 0x03, 
+-      0x1c, 0x20, 0x1c, 0x39, 0x1c, 0x2a, 0xf0, 0x00, 
+-      0xfe, 0x65, 0xb0, 0x01, 0x46, 0x6b, 0xf0, 0x00, 
+-      0xfd, 0xf9, 0xab, 0x09, 0xf0, 0x00, 0xfd, 0xdc, 
+-      0xab, 0x09, 0xf0, 0x00, 0xfd, 0xbf, 0x2e, 0x00, 
+-      0xd0, 0x2c, 0xb0, 0x86, 0xab, 0x0c, 0xc3, 0x07, 
+-      0x1c, 0x30, 0xf0, 0x00, 0xfe, 0x69, 0x1c, 0x0c, 
+-      0x1c, 0x05, 0x1c, 0x17, 0x4b, 0x1b, 0x1c, 0x1e, 
+-      0xf0, 0x00, 0xfd, 0xca, 0x90, 0x03, 0x91, 0x04, 
+-      0x92, 0x05, 0xab, 0x0c, 0xf0, 0x00, 0xfd, 0xaa, 
+-      0x90, 0x06, 0x91, 0x07, 0x92, 0x08, 0xab, 0x03, 
+-      0xf0, 0x00, 0xfe, 0x86, 0xab, 0x0c, 0xf0, 0x00, 
+-      0xfe, 0x83, 0x90, 0x00, 0x91, 0x01, 0x92, 0x02, 
+-      0x1c, 0x28, 0x1c, 0x21, 0x1c, 0x3a, 0x1d, 0xf3, 
+-      0x33, 0x05, 0xf0, 0x00, 0xfd, 0xb1, 0x46, 0x6b, 
+-      0xf0, 0x00, 0xfd, 0x94, 0xab, 0x06, 0xf0, 0x00, 
+-      0xfd, 0x91, 0xb0, 0x06, 0xb0, 0x0f, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x3f, 0xe6, 0xa0, 0x9e, 
+-      0x66, 0x7f, 0x3b, 0xcd, 0x80, 0x00, 0x00, 0x00, 
+-      0x2e, 0x03, 0x3b, 0x10, 0x80, 0x00, 0x3f, 0xff, 
+-      0x80, 0x00, 0x3f, 0xfe, 0x2e, 0x03, 0x3a, 0xbc, 
+-      0x2e, 0x03, 0x3a, 0xe0, 0x2e, 0x03, 0x3a, 0xa4, 
+-      0x47, 0x78, 0x00, 0x00, 0xe1, 0xa0, 0x38, 0x80, 
+-      0xe1, 0xa0, 0x38, 0xa3, 0xe1, 0xc0, 0x00, 0x03, 
+-      0xe1, 0xd1, 0xc0, 0x80, 0x5a, 0x00, 0x00, 0x0c, 
+-      0xe2, 0x53, 0x3b, 0x0f, 0x4a, 0x00, 0x00, 0x13, 
+-      0x12, 0x83, 0xc0, 0x01, 0x13, 0x5c, 0x0b, 0x02, 
+-      0xaa, 0x00, 0x00, 0x0d, 0xe1, 0xb0, 0xc5, 0xa2, 
+-      0x2a, 0x00, 0x00, 0x58, 0xe1, 0x80, 0x0a, 0x03, 
+-      0xe3, 0xc1, 0x11, 0x02, 0xe1, 0x80, 0x05, 0xa1, 
+-      0xe1, 0x8c, 0x1a, 0x81, 0xe3, 0xa0, 0x30, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe3, 0x10, 0x01, 0x01, 
+-      0x1a, 0x00, 0x00, 0x40, 0xe2, 0x00, 0x01, 0x02, 
+-      0xe3, 0xa0, 0x10, 0x00, 0xe3, 0xa0, 0x30, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe3, 0x33, 0x00, 0x00, 
+-      0x13, 0xa0, 0x33, 0x19, 0x11, 0x2f, 0xff, 0x1e, 
+-      0xe2, 0x93, 0x30, 0x34, 0x0a, 0x00, 0x00, 0x31, 
+-      0x42, 0x00, 0x01, 0x02, 0x43, 0xa0, 0x10, 0x00, 
+-      0x43, 0xa0, 0x30, 0x00, 0x41, 0x2f, 0xff, 0x1e, 
+-      0xe2, 0x53, 0x30, 0x20, 0x0a, 0x00, 0x00, 0x13, 
+-      0xba, 0x00, 0x00, 0x1a, 0xe1, 0xb0, 0xc3, 0x12, 
+-      0x4a, 0x00, 0x00, 0x05, 0xe2, 0x63, 0xc0, 0x20, 
+-      0xe1, 0x80, 0x0c, 0x31, 0xe1, 0xa0, 0x2c, 0x32, 
+-      0xe1, 0x82, 0x13, 0x11, 0xe3, 0xa0, 0x30, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe1, 0x96, 0xc0, 0x8c, 
+-      0xe2, 0x63, 0xc0, 0x20, 0xe1, 0x80, 0x0c, 0x31, 
+-      0xe1, 0xa0, 0x2c, 0x32, 0xe1, 0x82, 0x13, 0x11, 
+-      0xe3, 0xa0, 0x30, 0x00, 0x03, 0x11, 0x00, 0x01, 
+-      0x01, 0x2f, 0xff, 0x1e, 0xe2, 0x91, 0x10, 0x01, 
+-      0x22, 0x80, 0x00, 0x01, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe3, 0xa0, 0x30, 0x00, 0xe3, 0x32, 0x01, 0x02, 
+-      0x41, 0x2f, 0xff, 0x1e, 0x03, 0x11, 0x00, 0x01, 
+-      0x01, 0x2f, 0xff, 0x1e, 0xe2, 0x91, 0x10, 0x01, 
+-      0x22, 0x80, 0x00, 0x01, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe2, 0x83, 0x30, 0x20, 0xe1, 0xb0, 0xc3, 0x11, 
+-      0x4a, 0x00, 0x00, 0x04, 0xe2, 0x63, 0xc0, 0x20, 
+-      0xe1, 0xa0, 0x1c, 0x31, 0xe2, 0x00, 0x01, 0x02, 
+-      0xe3, 0xa0, 0x30, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe3, 0x3c, 0x01, 0x02, 0x01, 0x92, 0xc0, 0x06, 
+-      0xe2, 0x63, 0xc0, 0x20, 0xe1, 0xa0, 0x1c, 0x31, 
+-      0x03, 0x11, 0x00, 0x01, 0x12, 0x81, 0x10, 0x01, 
+-      0xe3, 0xa0, 0x30, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe3, 0x31, 0x01, 0x02, 0x03, 0x32, 0x00, 0x00, 
+-      0x03, 0xa0, 0x10, 0x00, 0x13, 0xa0, 0x10, 0x01, 
+-      0xe3, 0xa0, 0x30, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe3, 0x10, 0x02, 0x02, 0x1a, 0x00, 0x00, 0x0b, 
+-      0xe3, 0xa0, 0x30, 0x00, 0xe3, 0x31, 0x00, 0x00, 
+-      0x11, 0xb0, 0x10, 0x81, 0x43, 0xe0, 0x00, 0x00, 
+-      0x41, 0x2f, 0xff, 0x1e, 0x03, 0x32, 0x00, 0x00, 
+-      0x13, 0xa0, 0x34, 0x61, 0x11, 0x2f, 0xff, 0x1e, 
+-      0xe2, 0x00, 0x01, 0x02, 0xe3, 0x80, 0x02, 0x07, 
+-      0xe3, 0x80, 0x06, 0xff, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe1, 0xa0, 0x30, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe3, 0xc1, 0x11, 0x02, 0xe1, 0xa0, 0xcb, 0x02, 
+-      0xe1, 0x9c, 0xc0, 0x06, 0xe2, 0x00, 0xc1, 0x02, 
+-      0xe1, 0xa0, 0x0a, 0x03, 0xe1, 0x80, 0x05, 0xa1, 
+-      0xe1, 0xa0, 0x1a, 0x81, 0xe1, 0x81, 0x15, 0xa2, 
+-      0xe3, 0xa0, 0x30, 0x00, 0x0a, 0x00, 0x00, 0x06, 
+-      0xe2, 0x91, 0x10, 0x01, 0x22, 0x80, 0x00, 0x01, 
+-      0xe2, 0x90, 0x26, 0x01, 0xe1, 0x80, 0x00, 0x0c, 
+-      0x51, 0x2f, 0xff, 0x1e, 0xe3, 0xa0, 0x33, 0x19, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x03, 0x11, 0x00, 0x01, 
+-      0x01, 0x80, 0x00, 0x0c, 0x01, 0x2f, 0xff, 0x1e, 
+-      0xe2, 0x91, 0x10, 0x01, 0x22, 0x80, 0x00, 0x01, 
+-      0xe2, 0x90, 0x26, 0x01, 0xe1, 0x80, 0x00, 0x0c, 
+-      0x51, 0x2f, 0xff, 0x1e, 0xe3, 0xa0, 0x33, 0x19, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x47, 0x78, 0x00, 0x00, 
+-      0xe3, 0xa0, 0x20, 0x01, 0xea, 0x00, 0x00, 0x01, 
+-      0x47, 0x78, 0x00, 0x00, 0xe3, 0xa0, 0x20, 0x02, 
+-      0xe2, 0x00, 0x31, 0x02, 0xe5, 0x9f, 0x00, 0x18, 
+-      0xe5, 0x80, 0x20, 0x00, 0xe3, 0x31, 0x00, 0x00, 
+-      0x03, 0xa0, 0x00, 0x00, 0x15, 0x9f, 0x00, 0x0c, 
+-      0x18, 0x90, 0x00, 0x03, 0xe1, 0x80, 0x00, 0x03, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x2e, 0x08, 0x20, 0xb0, 
+-      0x2e, 0x08, 0x20, 0xbc, 0xe3, 0x10, 0x06, 0x01, 
+-      0x13, 0xa0, 0x00, 0x00, 0x11, 0x2f, 0xff, 0x1e, 
+-      0xea, 0x00, 0x00, 0x0a, 0xe3, 0x12, 0x07, 0x02, 
+-      0x0a, 0x00, 0x00, 0x08, 0xe1, 0x5c, 0x00, 0x80, 
+-      0x83, 0xa0, 0x00, 0x00, 0x81, 0x2f, 0xff, 0x1e, 
+-      0x03, 0x51, 0x00, 0x00, 0x03, 0xa0, 0x00, 0x00, 
+-      0x01, 0x2f, 0xff, 0x1e, 0xe3, 0x10, 0x07, 0x02, 
+-      0x13, 0xa0, 0x00, 0x00, 0x11, 0x2f, 0xff, 0x1e, 
+-      0xe3, 0xa0, 0x35, 0x06, 0xea, 0x00, 0x04, 0xee, 
+-      0xe1, 0x2f, 0xff, 0x1f, 0xea, 0x00, 0x00, 0x3e, 
+-      0xe5, 0x9f, 0x04, 0x5c, 0xe3, 0x50, 0x00, 0x00, 
+-      0x0a, 0x00, 0x00, 0x02, 0xe3, 0xa0, 0x00, 0x20, 
+-      0xe3, 0xa0, 0x10, 0x01, 0xef, 0x12, 0x34, 0x56, 
+-      0xe5, 0x9f, 0x04, 0x48, 0xe3, 0x50, 0x00, 0x00, 
+-      0x0a, 0x00, 0x00, 0x05, 0xe5, 0x90, 0x10, 0x00, 
+-      0xe5, 0x9f, 0x04, 0x3c, 0xe5, 0x90, 0x30, 0x00, 
+-      0xe5, 0x9f, 0x04, 0x38, 0xe5, 0x90, 0xd0, 0x00, 
+-      0xea, 0x00, 0x00, 0x0b, 0xe3, 0xa0, 0x00, 0x16, 
+-      0xe5, 0x9f, 0x44, 0x18, 0xe2, 0x84, 0x20, 0xa8, 
+-      0xe2, 0x84, 0x10, 0xa4, 0xe5, 0x81, 0x20, 0x00, 
+-      0xef, 0x12, 0x34, 0x56, 0xe2, 0x84, 0x00, 0xa8, 
+-      0xe5, 0x90, 0xd0, 0x08, 0xe5, 0x90, 0x30, 0x04, 
+-      0xe5, 0x90, 0x10, 0x00, 0xe3, 0x51, 0x00, 0x00, 
+-      0x05, 0x9f, 0x14, 0x04, 0xe2, 0x8f, 0x00, 0x10, 
+-      0xeb, 0x00, 0x00, 0x36, 0xe5, 0x9f, 0x03, 0xfc, 
+-      0xe5, 0x9f, 0x33, 0xfc, 0xeb, 0x00, 0x00, 0x12, 
+-      0xea, 0x00, 0x00, 0x4e, 0x2e, 0x00, 0x04, 0x04, 
+-      0x2e, 0x03, 0x3b, 0xfc, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xe9, 0x2d, 0x40, 0x00, 
+-      0xe3, 0x1c, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x03, 
+-      0xe1, 0xa0, 0xe0, 0x0f, 0xe1, 0x2f, 0xff, 0x1c, 
+-      0xe8, 0xbd, 0x40, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe3, 0x8f, 0xe0, 0x01, 0xe1, 0x2f, 0xff, 0x1c, 
+-      0x47, 0x78, 0x00, 0x00, 0xe8, 0xbd, 0x40, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x1c, 0x02, 0x1c, 0x13, 
+-      0x47, 0x78, 0x00, 0x00, 0xe9, 0x2d, 0x40, 0x00, 
+-      0xe3, 0x13, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x03, 
+-      0xe1, 0xa0, 0xe0, 0x0f, 0xe1, 0x2f, 0xff, 0x13, 
+-      0xe8, 0xbd, 0x40, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe3, 0x8f, 0xe0, 0x01, 0xe1, 0x2f, 0xff, 0x13, 
+-      0x47, 0x78, 0x00, 0x00, 0xe8, 0xbd, 0x40, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe5, 0x9f, 0xc0, 0x44, 
+-      0xe8, 0x8c, 0xff, 0xff, 0xe2, 0x8f, 0x00, 0x00, 
+-      0xea, 0x00, 0x0c, 0xac, 0x00, 0x80, 0x0e, 0x09, 
+-      0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x64, 
+-      0x65, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x6f, 0x6e, 
+-      0x6c, 0x79, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x6f, 
+-      0x6e, 0x20, 0x61, 0x20, 0x54, 0x68, 0x75, 0x6d, 
+-      0x62, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 
+-      0x69, 0x62, 0x6c, 0x65, 0x20, 0x70, 0x72, 0x6f, 
+-      0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x00, 0x00, 
+-      0x2e, 0x08, 0x21, 0x50, 0x47, 0x78, 0x00, 0x00, 
+-      0xe5, 0x9f, 0x73, 0x08, 0xe5, 0x87, 0x00, 0x00, 
+-      0xe2, 0x8f, 0x50, 0xc9, 0xe2, 0x85, 0x5c, 0x02, 
+-      0xe5, 0x87, 0x50, 0x10, 0xe2, 0x8f, 0x50, 0xe9, 
+-      0xe2, 0x85, 0x5c, 0x02, 0xe5, 0x87, 0x50, 0x14, 
+-      0xe1, 0xa0, 0x80, 0x0e, 0xe2, 0x87, 0x00, 0x04, 
+-      0xeb, 0x00, 0x02, 0x39, 0xe9, 0x2d, 0x01, 0x00, 
+-      0xe3, 0xa0, 0x00, 0x00, 0xe5, 0xc7, 0x00, 0x2c, 
+-      0xe2, 0x87, 0x00, 0x04, 0xeb, 0x00, 0x00, 0xce, 
+-      0xe3, 0xa0, 0x40, 0x00, 0xe2, 0x8d, 0x00, 0x04, 
+-      0xe5, 0x97, 0x10, 0x00, 0xe3, 0xa0, 0x30, 0x00, 
+-      0xe5, 0xc7, 0x30, 0x2e, 0xe2, 0x81, 0x30, 0x08, 
+-      0xe8, 0x91, 0x00, 0x06, 0xe5, 0x9f, 0xc2, 0xcc, 
+-      0xeb, 0xff, 0xff, 0xb7, 0xe8, 0xbd, 0x40, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x47, 0x78, 0x00, 0x00, 
+-      0xe3, 0xa0, 0x80, 0x01, 0xea, 0x00, 0x00, 0x01, 
+-      0x47, 0x78, 0x00, 0x00, 0xe3, 0xa0, 0x80, 0x00, 
+-      0xe1, 0xa0, 0x70, 0x00, 0xeb, 0x00, 0x02, 0x31, 
+-      0xe1, 0xa0, 0x00, 0x08, 0xeb, 0x00, 0x00, 0x0d, 
+-      0xe1, 0xa0, 0x20, 0x07, 0xe3, 0x52, 0x00, 0x00, 
+-      0x12, 0x8f, 0x00, 0x08, 0x15, 0x9f, 0x10, 0x00, 
+-      0xeb, 0x00, 0x0c, 0x6d, 0x41, 0x42, 0x45, 0x58, 
+-      0x00, 0x80, 0x0e, 0x06, 0x52, 0x65, 0x74, 0x75, 
+-      0x72, 0x6e, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 
+-      0x74, 0x6f, 0x6f, 0x20, 0x6c, 0x61, 0x72, 0x67, 
+-      0x65, 0x00, 0x00, 0x00, 0xe3, 0xa0, 0x00, 0x00, 
+-      0xe9, 0x2d, 0x40, 0x00, 0xe5, 0x9f, 0x32, 0x60, 
+-      0xeb, 0xff, 0xff, 0xa9, 0xe8, 0xbd, 0x40, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x47, 0x78, 0x00, 0x00, 
+-      0xe5, 0x9f, 0xc2, 0x28, 0xe5, 0xdc, 0x00, 0x2c, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe1, 0xa0, 0x30, 0x00, 
+-      0xe5, 0x9f, 0x12, 0x14, 0xe4, 0x81, 0xf0, 0x04, 
+-      0xe8, 0xb3, 0x00, 0x04, 0xe8, 0xa1, 0x00, 0x04, 
+-      0xe4, 0xd3, 0x20, 0x01, 0xe4, 0xc1, 0x20, 0x01, 
+-      0xe3, 0x52, 0x00, 0x00, 0x1a, 0xff, 0xff, 0xfb, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0x47, 0x78, 0x00, 0x00, 
+-      0xe1, 0xa0, 0x80, 0x01, 0xeb, 0xff, 0xff, 0xf2, 
+-      0xe5, 0x9f, 0x71, 0xe8, 0xe5, 0xd7, 0x20, 0x2f, 
+-      0xe3, 0x52, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x2c, 
+-      0xe3, 0xa0, 0x20, 0x01, 0xe5, 0xc7, 0x20, 0x2f, 
+-      0xeb, 0x00, 0x00, 0x3b, 0xe1, 0xa0, 0x10, 0x08, 
+-      0xeb, 0x00, 0x01, 0xfa, 0xe3, 0x50, 0x00, 0x00, 
+-      0x0a, 0x00, 0x00, 0x1b, 0xe2, 0x88, 0xb0, 0x40, 
+-      0xe9, 0x3b, 0x01, 0xef, 0xe9, 0x2c, 0x01, 0xef, 
+-      0xe9, 0x3b, 0x01, 0xef, 0xe9, 0x2c, 0x01, 0xef, 
+-      0xe5, 0x9f, 0x71, 0xa8, 0xe5, 0x97, 0x40, 0xa0, 
+-      0xe3, 0x84, 0x40, 0x80, 0xe1, 0x21, 0xf0, 0x04, 
+-      0xe1, 0xa0, 0xd0, 0x0c, 0xe1, 0xa0, 0xb0, 0x04, 
+-      0xe5, 0x9f, 0x01, 0x8c, 0xe5, 0x90, 0x00, 0x04, 
+-      0xe1, 0xa0, 0x10, 0x0d, 0xeb, 0x00, 0x02, 0x1a, 
+-      0xe3, 0xa0, 0x10, 0x00, 0xe5, 0xc7, 0x10, 0x2f, 
+-      0xe1, 0xa0, 0x10, 0x0d, 0xe3, 0x54, 0x00, 0x10, 
+-      0x1a, 0x00, 0x00, 0x02, 0xe3, 0xa0, 0x00, 0x17, 
+-      0xef, 0x12, 0x34, 0x56, 0xe3, 0x21, 0xf0, 0x93, 
+-      0xe1, 0xa0, 0x00, 0x00, 0xe2, 0x81, 0xe0, 0x3c, 
+-      0xe9, 0x5e, 0x7f, 0xff, 0xe1, 0xa0, 0x00, 0x00, 
+-      0xe8, 0xde, 0x80, 0x00, 0xe2, 0x8f, 0x00, 0x00, 
+-      0xea, 0x00, 0x0c, 0x2a, 0x00, 0x80, 0x0e, 0x07, 
+-      0x4e, 0x6f, 0x20, 0x53, 0x74, 0x61, 0x63, 0x6b, 
+-      0x20, 0x66, 0x6f, 0x72, 0x20, 0x54, 0x72, 0x61, 
+-      0x70, 0x20, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 
+-      0x72, 0x00, 0x00, 0x00, 0xe2, 0x8f, 0x00, 0x00, 
+-      0xea, 0x00, 0x0c, 0x20, 0x00, 0x80, 0x0e, 0x00, 
+-      0x52, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 
+-      0x65, 0x20, 0x54, 0x72, 0x61, 0x70, 0x00, 0x00, 
+-      0x47, 0x78, 0x00, 0x00, 0xe5, 0x9f, 0xc1, 0x04, 
+-      0xe3, 0xa0, 0x00, 0x00, 0xe5, 0xcc, 0x00, 0x2f, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x47, 0x78, 0x00, 0x00, 
+-      0xe5, 0x9f, 0x00, 0xf0, 0xe5, 0x90, 0x00, 0x00, 
+-      0xe5, 0x90, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe5, 0x9f, 0x00, 0xdc, 
+-      0xe2, 0x80, 0x00, 0x04, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe5, 0x9f, 0xc0, 0xcc, 
+-      0xe3, 0x50, 0x0b, 0x02, 0x33, 0xa0, 0x0b, 0x02, 
+-      0xe2, 0x8c, 0xc0, 0x04, 0xe9, 0x9c, 0x00, 0x0c, 
+-      0xe0, 0x53, 0x31, 0x00, 0x21, 0x53, 0x00, 0x02, 
+-      0x3a, 0x00, 0x00, 0x03, 0xe5, 0x81, 0x20, 0x00, 
+-      0xe0, 0x82, 0x21, 0x00, 0xe5, 0x8c, 0x20, 0x04, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe9, 0x2d, 0x50, 0x03, 
+-      0xe1, 0xa0, 0x10, 0x0c, 0xeb, 0x00, 0x00, 0x44, 
+-      0xe3, 0x50, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0d, 
+-      0xe5, 0x9d, 0xc0, 0x08, 0xe9, 0x9c, 0x40, 0x04, 
+-      0xe1, 0x5e, 0x00, 0x01, 0x10, 0x4e, 0x30, 0x02, 
+-      0xe0, 0x81, 0xe0, 0x00, 0x11, 0xa0, 0x00, 0x02, 
+-      0x11, 0xa0, 0x20, 0x01, 0xe9, 0x8c, 0x40, 0x04, 
+-      0x13, 0x53, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x03, 
+-      0xe8, 0xbd, 0x50, 0x03, 0xe5, 0x81, 0x00, 0x00, 
+-      0xe1, 0xa0, 0x01, 0x43, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe8, 0xbd, 0x50, 0x03, 0xe9, 0x9c, 0x00, 0x0c, 
+-      0xe0, 0x43, 0x00, 0x02, 0xe1, 0xb0, 0x01, 0x40, 
+-      0x03, 0xa0, 0x20, 0x00, 0x15, 0x8c, 0x30, 0x04, 
+-      0xe5, 0x81, 0x20, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe2, 0x80, 0x20, 0x03, 
+-      0xe3, 0xc2, 0x20, 0x03, 0xe5, 0x9f, 0xc0, 0x24, 
+-      0xe2, 0x8c, 0xc0, 0x08, 0xe8, 0x9c, 0x00, 0x03, 
+-      0xe0, 0x90, 0x20, 0x02, 0x31, 0x52, 0x00, 0x01, 
+-      0x35, 0x8c, 0x20, 0x00, 0x23, 0xa0, 0x00, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x47, 0x78, 0x00, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x2e, 0x08, 0x20, 0xcc, 
+-      0x2e, 0x08, 0x20, 0x98, 0x00, 0x00, 0x00, 0x00, 
+-      0x2e, 0x02, 0x5d, 0xa4, 0x2e, 0x02, 0x5d, 0xa0, 
+-      0x2e, 0x02, 0x5d, 0x9c, 0x2e, 0x08, 0x99, 0xfc, 
+-      0x2e, 0x00, 0x1c, 0x39, 0x2e, 0x01, 0xa1, 0x35, 
+-      0x2e, 0x01, 0x9f, 0xe9, 0x2e, 0x01, 0xa0, 0xa9, 
+-      0x47, 0x78, 0x00, 0x00, 0xe3, 0xa0, 0x00, 0x04, 
+-      0xe5, 0x90, 0x00, 0x00, 0xe2, 0x00, 0x04, 0xff, 
+-      0xe3, 0x50, 0x04, 0xea, 0x03, 0xa0, 0x00, 0x01, 
+-      0x13, 0xa0, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe2, 0x40, 0x0b, 0x05, 
+-      0xe3, 0x50, 0x0b, 0x1b, 0x33, 0xa0, 0x00, 0x01, 
+-      0x23, 0xa0, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe3, 0xa0, 0x00, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x47, 0x78, 0x00, 0x00, 
+-      0xe2, 0x8f, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 
+-      0x45, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x00, 0x00, 
+-      0x00, 0x02, 0x00, 0x00, 0x42, 0x72, 0x61, 0x6e, 
+-      0x63, 0x68, 0x20, 0x54, 0x68, 0x72, 0x6f, 0x75, 
+-      0x67, 0x68, 0x20, 0x5a, 0x65, 0x72, 0x6f, 0x00, 
+-      0x00, 0x02, 0x00, 0x01, 0x55, 0x6e, 0x64, 0x65, 
+-      0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x49, 0x6e, 
+-      0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 
+-      0x6e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 
+-      0x55, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 
+-      0x64, 0x20, 0x53, 0x57, 0x49, 0x20, 0x49, 0x6e, 
+-      0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x69, 0x6f, 
+-      0x6e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 
+-      0x50, 0x72, 0x65, 0x66, 0x65, 0x74, 0x63, 0x68, 
+-      0x20, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x00, 0x00, 
+-      0x00, 0x02, 0x00, 0x04, 0x44, 0x61, 0x74, 0x61, 
+-      0x20, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x00, 0x00, 
+-      0x00, 0x02, 0x00, 0x05, 0x41, 0x64, 0x64, 0x72, 
+-      0x65, 0x73, 0x73, 0x20, 0x45, 0x78, 0x63, 0x65, 
+-      0x70, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 
+-      0x00, 0x02, 0x00, 0x06, 0x55, 0x6e, 0x68, 0x61, 
+-      0x6e, 0x64, 0x6c, 0x65, 0x64, 0x20, 0x49, 0x6e, 
+-      0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x00, 
+-      0x00, 0x02, 0x00, 0x07, 0x55, 0x6e, 0x68, 0x61, 
+-      0x6e, 0x64, 0x6c, 0x65, 0x64, 0x20, 0x46, 0x61, 
+-      0x73, 0x74, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 
+-      0x72, 0x75, 0x70, 0x74, 0x00, 0x00, 0x00, 0x00, 
+-      0x2e, 0x01, 0x99, 0x2c, 0x2e, 0x01, 0x99, 0x44, 
+-      0x2e, 0x01, 0x99, 0x60, 0x2e, 0x01, 0x99, 0x80, 
+-      0x2e, 0x01, 0x99, 0x94, 0x2e, 0x01, 0x99, 0xa4, 
+-      0x2e, 0x01, 0x99, 0xbc, 0x2e, 0x01, 0x99, 0xd4, 
+-      0xe2, 0x4f, 0x20, 0x28, 0xe7, 0x92, 0x01, 0x00, 
+-      0xea, 0xff, 0xff, 0x1c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xb5, 0x04, 0xf0, 0x00, 
+-      0xf8, 0x04, 0xbc, 0x08, 0x60, 0x1a, 0xbc, 0x08, 
+-      0x47, 0x18, 0x47, 0x78, 0xe1, 0xb0, 0x00, 0x80, 
+-      0x03, 0x31, 0x00, 0x00, 0x01, 0xa0, 0x00, 0x60, 
+-      0x03, 0xa0, 0x20, 0x00, 0x01, 0x2f, 0xff, 0x1e, 
+-      0xe1, 0xa0, 0x2a, 0xa0, 0xe1, 0xc0, 0x0a, 0x82, 
+-      0xe1, 0xa0, 0x00, 0x60, 0xe3, 0x32, 0x00, 0x00, 
+-      0xe2, 0x42, 0x2c, 0x03, 0xe2, 0x42, 0x20, 0xfe, 
+-      0x0a, 0x00, 0x00, 0x06, 0xe3, 0x80, 0x04, 0x3f, 
+-      0xe3, 0x80, 0x06, 0x0e, 0xe2, 0x22, 0x3b, 0x01, 
+-      0xe3, 0x33, 0x00, 0x01, 0x11, 0x2f, 0xff, 0x1e, 
+-      0xe3, 0xa0, 0x10, 0x01, 0xea, 0xff, 0xfe, 0x39, 
+-      0xe2, 0x00, 0xc1, 0x02, 0xe1, 0xa0, 0x06, 0x00, 
+-      0xe2, 0x42, 0x20, 0x01, 0xe1, 0xb0, 0x00, 0x80, 
+-      0x4a, 0x00, 0x00, 0x02, 0xe1, 0xb0, 0x10, 0x81, 
+-      0x23, 0x80, 0x0a, 0x01, 0xea, 0xff, 0xff, 0xf9, 
+-      0xe1, 0xa0, 0x04, 0xc0, 0xe3, 0xc0, 0x05, 0x01, 
+-      0xe1, 0x8c, 0x01, 0x20, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe1, 0xb0, 0xc0, 0x80, 
+-      0x03, 0x31, 0x00, 0x00, 0xe1, 0xa0, 0x35, 0x0c, 
+-      0xe1, 0xa0, 0x0a, 0x2c, 0xe1, 0xa0, 0x25, 0x81, 
+-      0xe1, 0x83, 0x1a, 0xa1, 0x12, 0x80, 0x0b, 0x1e, 
+-      0xe1, 0xa0, 0x00, 0x60, 0x13, 0x81, 0x11, 0x02, 
+-      0xe1, 0xb0, 0xca, 0xcc, 0x0a, 0x00, 0x00, 0x02, 
+-      0xe3, 0x7c, 0x00, 0x01, 0x03, 0x80, 0x01, 0x01, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe3, 0x11, 0x01, 0x02, 
+-      0x01, 0x2f, 0xff, 0x1e, 0xe3, 0xd1, 0x11, 0x02, 
+-      0x0a, 0x00, 0x00, 0x15, 0xe1, 0xb0, 0x38, 0x21, 
+-      0x01, 0xa0, 0x18, 0x01, 0x03, 0xa0, 0xc0, 0x10, 
+-      0x13, 0xa0, 0xc0, 0x00, 0xe1, 0xb0, 0x3c, 0x21, 
+-      0x01, 0xa0, 0x14, 0x01, 0x02, 0x8c, 0xc0, 0x08, 
+-      0xe1, 0xb0, 0x3e, 0x21, 0x01, 0xa0, 0x12, 0x01, 
+-      0x02, 0x8c, 0xc0, 0x04, 0xe1, 0xb0, 0x3f, 0x21, 
+-      0x01, 0xa0, 0x11, 0x01, 0x02, 0x8c, 0xc0, 0x02, 
+-      0xe1, 0xb0, 0x3f, 0xa1, 0x01, 0xa0, 0x10, 0x81, 
+-      0x02, 0x8c, 0xc0, 0x01, 0xe2, 0x6c, 0x30, 0x20, 
+-      0xe1, 0x81, 0x13, 0x32, 0xe1, 0xa0, 0x2c, 0x12, 
+-      0xe0, 0x40, 0x00, 0x0c, 0xe2, 0x80, 0x00, 0x01, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe1, 0xb0, 0x38, 0x22, 
+-      0x01, 0xa0, 0x28, 0x02, 0x03, 0xa0, 0xc0, 0x10, 
+-      0x13, 0xa0, 0xc0, 0x00, 0xe1, 0xb0, 0x3c, 0x22, 
+-      0x01, 0xa0, 0x24, 0x02, 0x02, 0x8c, 0xc0, 0x08, 
+-      0xe1, 0xb0, 0x3e, 0x22, 0x01, 0xa0, 0x22, 0x02, 
+-      0x02, 0x8c, 0xc0, 0x04, 0xe1, 0xb0, 0x3f, 0x22, 
+-      0x01, 0xa0, 0x21, 0x02, 0x02, 0x8c, 0xc0, 0x02, 
+-      0xe1, 0xb0, 0x3f, 0xa2, 0x01, 0xa0, 0x20, 0x82, 
+-      0x02, 0x8c, 0xc0, 0x01, 0xe1, 0xa0, 0x10, 0x02, 
+-      0xe3, 0xa0, 0x20, 0x00, 0xe2, 0x40, 0x00, 0x1f, 
+-      0xe0, 0x40, 0x00, 0x0c, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe3, 0xa0, 0xc4, 0xff, 
+-      0xe3, 0x8c, 0xc6, 0x0e, 0xe1, 0x5c, 0x00, 0x82, 
+-      0x9a, 0x00, 0x00, 0x0a, 0xe1, 0xb0, 0x00, 0x80, 
+-      0x03, 0x31, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0a, 
+-      0x3a, 0x00, 0x00, 0x11, 0xe1, 0x50, 0x00, 0x0c, 
+-      0x03, 0x51, 0x00, 0x00, 0x8a, 0xff, 0xfd, 0xf2, 
+-      0xe1, 0xb0, 0x20, 0x82, 0x8a, 0x00, 0x00, 0x17, 
+-      0xe3, 0xa0, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x03, 0x53, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xf2, 
+-      0xea, 0xff, 0xfd, 0xef, 0xe1, 0x50, 0x00, 0x0c, 
+-      0x03, 0x51, 0x00, 0x00, 0x8a, 0xff, 0xfd, 0xe8, 
+-      0xe1, 0xb0, 0x20, 0x82, 0x03, 0x33, 0x00, 0x00, 
+-      0x83, 0xa0, 0x00, 0x01, 0x93, 0xa0, 0x00, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe1, 0x50, 0x00, 0x0c, 
+-      0x03, 0x51, 0x00, 0x00, 0x8a, 0xff, 0xfd, 0xe0, 
+-      0xe1, 0xb0, 0x20, 0x82, 0x23, 0xa0, 0x00, 0x01, 
+-      0x21, 0x2f, 0xff, 0x1e, 0xe1, 0x50, 0x00, 0x02, 
+-      0x01, 0x51, 0x00, 0x03, 0x93, 0xa0, 0x00, 0x00, 
+-      0x83, 0xa0, 0x00, 0x01, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe1, 0x50, 0x00, 0x02, 0x01, 0x51, 0x00, 0x03, 
+-      0x33, 0xa0, 0x00, 0x01, 0x23, 0xa0, 0x00, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x47, 0x78, 0x00, 0x00, 
+-      0xe9, 0x2d, 0x4b, 0xf0, 0xe8, 0x93, 0x00, 0x38, 
+-      0xe3, 0x10, 0x01, 0x01, 0x03, 0x13, 0x01, 0x01, 
+-      0x1a, 0x00, 0x00, 0x03, 0xeb, 0x00, 0x02, 0x30, 
+-      0xeb, 0x00, 0x03, 0x38, 0xe8, 0xbd, 0x4b, 0xf0, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe2, 0x4f, 0xe0, 0x14, 
+-      0xe3, 0xa0, 0xb0, 0x00, 0xea, 0x00, 0x02, 0x86, 
+-      0x47, 0x78, 0x00, 0x00, 0xe9, 0x2d, 0x4b, 0xf0, 
+-      0xe8, 0x93, 0x00, 0x38, 0xe3, 0x10, 0x01, 0x01, 
+-      0x03, 0x13, 0x01, 0x01, 0x1a, 0x00, 0x00, 0x03, 
+-      0xeb, 0x00, 0x03, 0x5e, 0xeb, 0x00, 0x03, 0x2b, 
+-      0xe8, 0xbd, 0x4b, 0xf0, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe2, 0x4f, 0xe0, 0x14, 0xe3, 0xa0, 0xb0, 0x00, 
+-      0xea, 0x00, 0x03, 0xf8, 0x47, 0x78, 0x00, 0x00, 
+-      0xe9, 0x2d, 0x4b, 0xf0, 0xe8, 0x93, 0x00, 0x38, 
+-      0xe3, 0xa0, 0xb0, 0x00, 0xe1, 0xd1, 0xc0, 0x80, 
+-      0x41, 0xd4, 0xc0, 0x83, 0x5a, 0x00, 0x00, 0x04, 
+-      0xe3, 0xa0, 0xb0, 0x04, 0xeb, 0x00, 0x04, 0x3f, 
+-      0xeb, 0x00, 0x03, 0x1c, 0xe8, 0xbd, 0x4b, 0xf0, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe3, 0x11, 0x01, 0x02, 
+-      0x0a, 0x00, 0x00, 0x08, 0xe3, 0x10, 0x01, 0x01, 
+-      0x03, 0x13, 0x01, 0x01, 0x02, 0x4f, 0xe0, 0x24, 
+-      0xe3, 0xa0, 0xb0, 0x04, 0x0a, 0x00, 0x05, 0x5b, 
+-      0xe0, 0x23, 0x00, 0x00, 0xe2, 0x00, 0x01, 0x02, 
+-      0xe8, 0xbd, 0x4b, 0xf0, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe3, 0x14, 0x01, 0x02, 0x03, 0xa0, 0x34, 0x62, 
+-      0x13, 0xa0, 0x34, 0x61, 0xea, 0x00, 0x02, 0x9d, 
+-      0x47, 0x78, 0x00, 0x00, 0xe9, 0x2d, 0x4b, 0xf0, 
+-      0xe1, 0xa0, 0x30, 0x00, 0xe1, 0xa0, 0x40, 0x01, 
+-      0xe1, 0xa0, 0x50, 0x02, 0xe3, 0x10, 0x01, 0x01, 
+-      0x1a, 0x00, 0x00, 0x03, 0xeb, 0x00, 0x03, 0x35, 
+-      0xeb, 0x00, 0x03, 0x02, 0xe8, 0xbd, 0x4b, 0xf0, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe2, 0x4f, 0xe0, 0x14, 
+-      0xe3, 0xa0, 0xb0, 0x00, 0xea, 0x00, 0x03, 0xcf, 
+-      0xb4, 0x77, 0x46, 0x76, 0x1e, 0x5d, 0x9b, 0x06, 
+-      0x1c, 0x1c, 0x34, 0x0c, 0xf7, 0xff, 0xff, 0x8c, 
+-      0x1c, 0x23, 0x34, 0x0c, 0xf7, 0xff, 0xff, 0x6e, 
+-      0x46, 0x6b, 0xf7, 0xff, 0xff, 0x85, 0x1e, 0x6d, 
+-      0xd1, 0xf6, 0xb0, 0x03, 0x46, 0xb6, 0xbc, 0x70, 
+-      0x47, 0x70, 0x00, 0x00, 0xb4, 0x77, 0x46, 0x76, 
+-      0x1e, 0x5d, 0x9b, 0x06, 0x1c, 0x1c, 0x34, 0x0c, 
+-      0xf7, 0xff, 0xff, 0x5c, 0x46, 0x6b, 0xf7, 0xff, 
+-      0xff, 0x73, 0x1c, 0x23, 0x34, 0x0c, 0xf7, 0xff, 
+-      0xff, 0x55, 0x1e, 0x6d, 0xd1, 0xf6, 0xb0, 0x03, 
+-      0x46, 0xb6, 0xbc, 0x70, 0x47, 0x70, 0x00, 0x00, 
+-      0x47, 0x78, 0x00, 0x00, 0xe1, 0xb0, 0x10, 0x00, 
+-      0xe2, 0x00, 0x01, 0x02, 0x42, 0x61, 0x10, 0x00, 
+-      0xe3, 0xa0, 0x20, 0x00, 0x01, 0x2f, 0xff, 0x1e, 
+-      0xe3, 0x80, 0x09, 0x01, 0xe3, 0x80, 0x00, 0x1e, 
+-      0xe1, 0xb0, 0xc8, 0x21, 0x01, 0xa0, 0x18, 0x01, 
+-      0x02, 0x40, 0x00, 0x10, 0xe1, 0xb0, 0xcc, 0x21, 
+-      0x01, 0xa0, 0x14, 0x01, 0x02, 0x40, 0x00, 0x08, 
+-      0xe1, 0xb0, 0xce, 0x21, 0x01, 0xa0, 0x12, 0x01, 
+-      0x02, 0x40, 0x00, 0x04, 0xe1, 0xb0, 0xcf, 0x21, 
+-      0x01, 0xa0, 0x11, 0x01, 0x02, 0x40, 0x00, 0x02, 
+-      0xe1, 0xb0, 0xcf, 0xa1, 0x01, 0xa0, 0x10, 0x81, 
+-      0x02, 0x40, 0x00, 0x01, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe9, 0x2d, 0x4b, 0xf0, 
+-      0xe8, 0x93, 0x00, 0x38, 0xe2, 0x23, 0x31, 0x02, 
+-      0xe3, 0x10, 0x01, 0x01, 0x03, 0x13, 0x01, 0x01, 
+-      0x1a, 0x00, 0x00, 0x03, 0xeb, 0x00, 0x01, 0xbe, 
+-      0xeb, 0x00, 0x02, 0xc6, 0xe8, 0xbd, 0x4b, 0xf0, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe2, 0x4f, 0xe0, 0x14, 
+-      0xe3, 0xa0, 0xb0, 0x00, 0xea, 0x00, 0x02, 0x14, 
+-      0x47, 0x78, 0x00, 0x00, 0xe3, 0xa0, 0xb0, 0x00, 
+-      0xe1, 0xa0, 0x20, 0x01, 0xe8, 0x80, 0x00, 0x0e, 
+-      0xe5, 0x9f, 0xc0, 0x38, 0xe5, 0x8c, 0xd0, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x47, 0x78, 0x00, 0x00, 
+-      0xe5, 0x9f, 0x20, 0x28, 0xe5, 0x92, 0x20, 0x00, 
+-      0xe5, 0x91, 0x40, 0x2c, 0xe5, 0x91, 0xc0, 0x34, 
+-      0xe1, 0x5c, 0x00, 0x02, 0x23, 0xa0, 0x00, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x47, 0x78, 0x00, 0x00, 
+-      0xe5, 0x9f, 0xc0, 0x08, 0xe5, 0x9c, 0xd0, 0x00, 
+-      0xe3, 0xa0, 0xb0, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x2e, 0x08, 0x21, 0x90, 0x47, 0x78, 0x00, 0x00, 
+-      0xe9, 0x2d, 0x40, 0x00, 0xe5, 0x9f, 0xc0, 0xe4, 
+-      0xe5, 0x9c, 0x00, 0x00, 0xe3, 0x50, 0x00, 0x00, 
+-      0xe3, 0xa0, 0x00, 0x04, 0x15, 0x8c, 0x00, 0x04, 
+-      0x0b, 0x00, 0x00, 0x01, 0xe8, 0xbd, 0x40, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe5, 0x9f, 0xc0, 0xcc, 
+-      0xea, 0xff, 0xfd, 0x6b, 0xe3, 0xa0, 0x10, 0x0a, 
+-      0xe3, 0x50, 0x01, 0x02, 0x13, 0x50, 0x01, 0x06, 
+-      0x13, 0x50, 0x01, 0x16, 0x03, 0xa0, 0x10, 0x03, 
+-      0xe3, 0x50, 0x01, 0x0a, 0x13, 0x50, 0x01, 0x0e, 
+-      0x03, 0xa0, 0x10, 0x05, 0xe5, 0x9f, 0x20, 0xa8, 
+-      0xe1, 0x50, 0x00, 0x02, 0xe2, 0x82, 0x20, 0xff, 
+-      0x21, 0x52, 0x00, 0x00, 0x23, 0xa0, 0x10, 0x02, 
+-      0xe3, 0x50, 0x01, 0x82, 0x03, 0xa0, 0x10, 0x02, 
+-      0xe3, 0x50, 0x01, 0x86, 0x03, 0xa0, 0x10, 0x07, 
+-      0xe5, 0x9f, 0x20, 0x88, 0xe0, 0x50, 0x20, 0x02, 
+-      0x13, 0x52, 0x00, 0x01, 0x03, 0xa0, 0x10, 0x05, 
+-      0xe1, 0xa0, 0x00, 0x01, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe9, 0x2d, 0x40, 0x02, 
+-      0xe1, 0xa0, 0x30, 0x00, 0xeb, 0xff, 0xff, 0xe4, 
+-      0xe8, 0xbd, 0x40, 0x02, 0xe5, 0x9f, 0xc0, 0x50, 
+-      0xe3, 0xa0, 0x20, 0x01, 0xe5, 0xcc, 0x20, 0x00, 
+-      0xe9, 0x2d, 0x00, 0x0a, 0xeb, 0xff, 0xff, 0xdc, 
+-      0xea, 0x00, 0x00, 0x09, 0x47, 0x78, 0x00, 0x00, 
+-      0xe5, 0x9f, 0xc0, 0x30, 0xe3, 0xa0, 0x10, 0x00, 
+-      0xe5, 0x8c, 0x10, 0x00, 0xe5, 0x9c, 0x00, 0x04, 
+-      0xe3, 0x50, 0x00, 0x00, 0x01, 0x2f, 0xff, 0x1e, 
+-      0xe5, 0x8c, 0x10, 0x04, 0xea, 0xff, 0xff, 0xd2, 
+-      0x47, 0x78, 0x00, 0x00, 0xe1, 0xa0, 0xc0, 0x0d, 
+-      0xe9, 0x2d, 0xd9, 0xf0, 0xe2, 0x4c, 0xb0, 0x04, 
+-      0xe3, 0xa0, 0x10, 0x01, 0xea, 0xff, 0xfd, 0x88, 
+-      0x2e, 0x08, 0x20, 0xb4, 0x2e, 0x08, 0x20, 0xc6, 
+-      0x2e, 0x01, 0xb5, 0xe1, 0x80, 0x00, 0x02, 0x00, 
+-      0x80, 0x80, 0x0e, 0xa0, 0xb5, 0xff, 0xa6, 0x23, 
+-      0xa5, 0x22, 0xa4, 0x22, 0x68, 0x5a, 0x68, 0x1f, 
+-      0x4b, 0x21, 0x60, 0x5a, 0x23, 0x00, 0x4a, 0x21, 
+-      0x70, 0x13, 0x70, 0x53, 0x70, 0x93, 0x4a, 0x20, 
+-      0x2a, 0x00, 0xd0, 0x02, 0x9a, 0x02, 0xf7, 0xff, 
+-      0xff, 0xfe, 0x48, 0x1e, 0x28, 0x00, 0xd0, 0x01, 
+-      0xf7, 0xff, 0xff, 0xfe, 0x48, 0x1c, 0x28, 0x00, 
+-      0xd0, 0x01, 0xf7, 0xff, 0xff, 0xfe, 0x48, 0x1b, 
+-      0x28, 0x00, 0xd0, 0x01, 0xf0, 0x01, 0xfc, 0xb2, 
+-      0x48, 0x19, 0x28, 0x00, 0xd0, 0x01, 0xf7, 0xff, 
+-      0xff, 0xfe, 0x48, 0x18, 0x28, 0x00, 0xd0, 0x01, 
+-      0xf0, 0x01, 0xfb, 0x18, 0x48, 0x16, 0x28, 0x00, 
+-      0xd0, 0x01, 0xf0, 0x01, 0xfc, 0x89, 0x48, 0x15, 
+-      0x28, 0x00, 0xd0, 0x01, 0xf7, 0xff, 0xff, 0xfe, 
+-      0xf7, 0xff, 0xff, 0xa0, 0x48, 0x12, 0x28, 0x00, 
+-      0xd0, 0x04, 0x1c, 0x30, 0x1c, 0x29, 0x1c, 0x22, 
+-      0xf0, 0x01, 0xfe, 0xa6, 0x2f, 0x00, 0xd0, 0x01, 
+-      0xf7, 0xfe, 0xfd, 0xcc, 0xb0, 0x04, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x3a, 0x74, 0x74, 0x00, 
+-      0x2e, 0x08, 0x21, 0x94, 0x2e, 0x08, 0x21, 0x94, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x2e, 0x01, 0xb9, 0x91, 
+-      0x00, 0x00, 0x00, 0x00, 0x2e, 0x01, 0xb6, 0x71, 
+-      0x2e, 0x01, 0xb9, 0x5d, 0x00, 0x00, 0x00, 0x00, 
+-      0x2e, 0x01, 0xbd, 0xb5, 0xb5, 0x90, 0x28, 0x00, 
+-      0xd0, 0x04, 0x48, 0x12, 0x28, 0x00, 0xd0, 0x01, 
+-      0xf7, 0xff, 0xff, 0xfe, 0x4f, 0x10, 0x68, 0x78, 
+-      0x28, 0x00, 0xd0, 0x03, 0xf7, 0xfe, 0xfd, 0x94, 
+-      0x20, 0x00, 0x60, 0x78, 0x4f, 0x0d, 0x78, 0x78, 
+-      0x24, 0x01, 0x28, 0x00, 0xd1, 0x05, 0x70, 0x7c, 
+-      0x48, 0x0b, 0x28, 0x00, 0xd0, 0x01, 0xf7, 0xff, 
+-      0xff, 0xfe, 0x78, 0xb8, 0x28, 0x00, 0xd1, 0x05, 
+-      0x70, 0xbc, 0x48, 0x08, 0x28, 0x00, 0xd0, 0x01, 
+-      0xf0, 0x01, 0xfe, 0xb2, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x2e, 0x08, 0x21, 0x94, 0x2e, 0x08, 0x21, 0x94, 
+-      0x00, 0x00, 0x00, 0x00, 0x2e, 0x01, 0xbe, 0x55, 
+-      0xb5, 0x90, 0x1c, 0x0c, 0x21, 0x01, 0x1c, 0x17, 
+-      0xf0, 0x01, 0xfa, 0xbc, 0x21, 0x00, 0x1c, 0x20, 
+-      0xf0, 0x01, 0xfa, 0xb8, 0x21, 0x02, 0x1c, 0x38, 
+-      0xf0, 0x01, 0xfa, 0xb4, 0x20, 0x01, 0xf7, 0xff, 
+-      0xfa, 0x5d, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0xf1, 0x20, 0x00, 0xb0, 0x89, 0x90, 0x06, 
+-      0x26, 0x00, 0x90, 0x05, 0x20, 0x01, 0x90, 0x04, 
+-      0x27, 0x00, 0x20, 0x00, 0x90, 0x03, 0x90, 0x02, 
+-      0x25, 0x00, 0x90, 0x01, 0xf0, 0x01, 0xfb, 0xe2, 
+-      0x1c, 0x04, 0x78, 0x00, 0x28, 0x00, 0xd0, 0x17, 
+-      0x49, 0xe3, 0x5d, 0xe0, 0x5c, 0x08, 0x08, 0x40, 
+-      0xd3, 0x06, 0x37, 0x01, 0x5d, 0xe0, 0x5c, 0x08, 
+-      0x08, 0x40, 0xd2, 0xfa, 0xe0, 0x00, 0x37, 0x01, 
+-      0x5d, 0xe0, 0x5c, 0x0a, 0x08, 0x52, 0xd2, 0x01, 
+-      0x28, 0x00, 0xd1, 0xf8, 0x98, 0x04, 0x30, 0x01, 
+-      0x90, 0x04, 0x5d, 0xe0, 0x28, 0x00, 0xd1, 0xe8, 
+-      0x98, 0x04, 0x00, 0x80, 0xf0, 0x01, 0xfc, 0x16, 
+-      0x4b, 0xd6, 0x93, 0x08, 0x60, 0x18, 0x1c, 0x78, 
+-      0xf0, 0x01, 0xfc, 0x10, 0x9b, 0x08, 0x60, 0x58, 
+-      0x48, 0xd3, 0x28, 0x00, 0xd0, 0x01, 0xf7, 0xff, 
+-      0xff, 0xfe, 0x21, 0x00, 0x20, 0x00, 0x90, 0x04, 
+-      0x48, 0xd0, 0x90, 0x07, 0x78, 0x27, 0x34, 0x01, 
+-      0x2e, 0x00, 0xd1, 0x58, 0x2f, 0x22, 0xd0, 0x01, 
+-      0x2f, 0x27, 0xd1, 0x02, 0x97, 0x05, 0x1c, 0x3e, 
+-      0xe0, 0x93, 0x98, 0x06, 0x42, 0x81, 0xd1, 0x4e, 
+-      0x98, 0x03, 0x28, 0x00, 0xd1, 0x4b, 0x25, 0x00, 
+-      0x43, 0xed, 0x1c, 0x2a, 0x95, 0x01, 0x22, 0x00, 
+-      0xab, 0x00, 0x70, 0x1a, 0x70, 0x5a, 0x1e, 0x60, 
+-      0x78, 0x02, 0x2a, 0x30, 0xdb, 0x04, 0x2a, 0x39, 
+-      0xdc, 0x02, 0x30, 0x01, 0x1f, 0xd5, 0x3d, 0x29, 
+-      0x78, 0x02, 0x2a, 0x3e, 0xd0, 0x01, 0x2a, 0x3c, 
+-      0xd1, 0x35, 0x2a, 0x3e, 0xd1, 0x0e, 0x22, 0x77, 
+-      0xab, 0x00, 0x70, 0x1a, 0x2d, 0x00, 0xd0, 0x63, 
+-      0x2d, 0x02, 0xdc, 0x62, 0x78, 0x42, 0x30, 0x01, 
+-      0x2a, 0x3e, 0xd1, 0x13, 0x22, 0x61, 0x70, 0x1a, 
+-      0x30, 0x01, 0xe0, 0x0f, 0x30, 0x01, 0x1c, 0x02, 
+-      0xe0, 0x02, 0x2b, 0x3e, 0xd0, 0x56, 0x32, 0x01, 
+-      0x78, 0x13, 0x2b, 0x00, 0xd0, 0x01, 0x2b, 0x20, 
+-      0xd1, 0xf7, 0x2d, 0x00, 0xdc, 0x4d, 0x22, 0x72, 
+-      0xab, 0x00, 0x70, 0x1a, 0x78, 0x02, 0x2a, 0x26, 
+-      0xd1, 0x24, 0x23, 0x01, 0x42, 0xdd, 0xd0, 0x19, 
+-      0x2d, 0x00, 0xdd, 0x5e, 0x78, 0x42, 0x30, 0x01, 
+-      0x2a, 0x30, 0xdb, 0x5b, 0x2a, 0x32, 0xdc, 0x3c, 
+-      0x30, 0x01, 0x1c, 0x2b, 0xd5, 0x04, 0x07, 0xdb, 
+-      0x0f, 0xdb, 0x42, 0x5b, 0xe0, 0x02, 0xe0, 0x42, 
+-      0x07, 0xdb, 0x0f, 0xdb, 0x33, 0x31, 0x42, 0x9a, 
+-      0xd1, 0x63, 0x22, 0x00, 0xab, 0x00, 0x70, 0x1a, 
+-      0x95, 0x01, 0xe0, 0x11, 0x22, 0x02, 0x92, 0x01, 
+-      0xaa, 0x00, 0x78, 0x12, 0x30, 0x01, 0x2a, 0x72, 
+-      0xd0, 0x09, 0xe0, 0x06, 0x23, 0x01, 0x42, 0xdd, 
+-      0xd1, 0x06, 0xaa, 0x00, 0x78, 0x12, 0x2a, 0x72, 
+-      0xd0, 0x01, 0x25, 0x01, 0xe0, 0x00, 0x25, 0x00, 
+-      0xaa, 0x00, 0x78, 0x12, 0x2a, 0x00, 0xd0, 0x16, 
+-      0x22, 0x01, 0x92, 0x03, 0x4a, 0x8c, 0x78, 0x03, 
+-      0x5c, 0xd3, 0x08, 0x5b, 0xd3, 0x04, 0x78, 0x43, 
+-      0x5c, 0xd3, 0x30, 0x01, 0x08, 0x5b, 0xd2, 0xfa, 
+-      0x78, 0x02, 0x2a, 0x22, 0xd0, 0x01, 0x2a, 0x27, 
+-      0xd1, 0x0c, 0x30, 0x01, 0x1c, 0x16, 0xe0, 0x09, 
+-      0xe0, 0x6a, 0xe0, 0xfb, 0xe0, 0x23, 0x78, 0x02, 
+-      0x2a, 0x00, 0xd0, 0x03, 0x4b, 0x80, 0x5c, 0x9a, 
+-      0x08, 0x52, 0xd3, 0x61, 0x22, 0x01, 0x92, 0x02, 
+-      0x1c, 0x04, 0x78, 0x27, 0x34, 0x01, 0x2e, 0x00, 
+-      0xd0, 0x15, 0x2f, 0x5c, 0xd1, 0x0b, 0x78, 0x20, 
+-      0x28, 0x22, 0xd0, 0x03, 0x28, 0x5c, 0xd0, 0x01, 
+-      0x28, 0x27, 0xd1, 0x04, 0x34, 0x01, 0x1c, 0x07, 
+-      0xe0, 0x09, 0xe0, 0xdf, 0xe0, 0xde, 0x1c, 0x30, 
+-      0x42, 0xb7, 0xd1, 0x04, 0x40, 0x7e, 0x78, 0x27, 
+-      0x34, 0x01, 0x42, 0x87, 0xd0, 0xfa, 0x2f, 0x00, 
+-      0xd0, 0x0c, 0x2e, 0x00, 0xd1, 0x03, 0x48, 0x6e, 
+-      0x5d, 0xc0, 0x08, 0x40, 0xd2, 0x06, 0x1c, 0x08, 
+-      0x9b, 0x08, 0x68, 0x5a, 0x54, 0x17, 0x31, 0x01, 
+-      0xe0, 0x97, 0xe0, 0xc7, 0x98, 0x06, 0x42, 0x81, 
+-      0xd1, 0x08, 0x98, 0x05, 0x28, 0x00, 0xd1, 0x05, 
+-      0x98, 0x02, 0x28, 0x00, 0xd0, 0x74, 0x98, 0x03, 
+-      0x28, 0x00, 0xd1, 0x72, 0x22, 0x00, 0x1c, 0x08, 
+-      0x9b, 0x08, 0x68, 0x5b, 0x54, 0x1a, 0x98, 0x02, 
+-      0x31, 0x01, 0x28, 0x00, 0xd0, 0x6a, 0x98, 0x03, 
+-      0x28, 0x00, 0xd0, 0x13, 0x01, 0xa8, 0x99, 0x07, 
+-      0x18, 0x42, 0x9b, 0x08, 0x68, 0x58, 0x99, 0x06, 
+-      0x18, 0x40, 0x46, 0x69, 0xf0, 0x01, 0xfc, 0x72, 
+-      0x28, 0x00, 0xd1, 0x07, 0x9b, 0x08, 0x68, 0x58, 
+-      0x99, 0x06, 0x18, 0x41, 0xa2, 0x58, 0xa0, 0x5e, 
+-      0xf7, 0xff, 0xfe, 0xb6, 0x23, 0x01, 0x98, 0x01, 
+-      0x42, 0xd8, 0xdd, 0x51, 0x98, 0x01, 0x28, 0x00, 
+-      0xda, 0x03, 0x40, 0x18, 0x42, 0x40, 0xe0, 0x02, 
+-      0xe0, 0x90, 0x07, 0xc0, 0x0f, 0xc0, 0x1c, 0x41, 
+-      0x98, 0x01, 0xf0, 0x01, 0xfd, 0x61, 0x01, 0x80, 
+-      0x99, 0x07, 0x18, 0x40, 0xf0, 0x01, 0xf9, 0xfc, 
+-      0x28, 0x00, 0xd1, 0x3d, 0xb0, 0x82, 0x98, 0x03, 
+-      0x01, 0x80, 0x99, 0x09, 0x18, 0x40, 0x90, 0x01, 
+-      0x9a, 0x03, 0x2a, 0x00, 0xda, 0x03, 0x07, 0xd2, 
+-      0x0f, 0xd2, 0x42, 0x52, 0xe0, 0x01, 0x07, 0xd2, 
+-      0x0f, 0xd2, 0x01, 0x90, 0x99, 0x09, 0x18, 0x40, 
+-      0x30, 0x40, 0x90, 0x00, 0x20, 0xff, 0x30, 0x01, 
+-      0xf0, 0x01, 0xfa, 0xe0, 0x1c, 0x01, 0x23, 0xff, 
+-      0x22, 0x01, 0x02, 0x52, 0x98, 0x01, 0x33, 0x01, 
+-      0xf0, 0x01, 0xfd, 0x56, 0x98, 0x01, 0x68, 0xc0, 
+-      0x23, 0x01, 0x02, 0xdb, 0x43, 0x18, 0x99, 0x01, 
+-      0x60, 0xc8, 0x08, 0xd8, 0xf0, 0x01, 0xfa, 0xce, 
+-      0x1c, 0x01, 0x23, 0xff, 0x22, 0x01, 0x02, 0x52, 
+-      0x98, 0x00, 0x33, 0x01, 0xf0, 0x01, 0xfd, 0x44, 
+-      0x98, 0x00, 0x68, 0xc0, 0x23, 0x01, 0x02, 0xdb, 
+-      0x43, 0x18, 0x99, 0x00, 0x60, 0xc8, 0xe0, 0x02, 
+-      0xe0, 0x13, 0xe0, 0x12, 0xe0, 0x05, 0xb0, 0x02, 
+-      0x20, 0x00, 0x90, 0x02, 0x90, 0x03, 0x99, 0x06, 
+-      0xe0, 0x0b, 0x9b, 0x08, 0x68, 0x58, 0x9a, 0x06, 
+-      0x18, 0x82, 0x98, 0x04, 0x1c, 0x43, 0x93, 0x04, 
+-      0x00, 0x80, 0x9b, 0x08, 0x68, 0x1b, 0x50, 0x1a, 
+-      0x91, 0x06, 0x2f, 0x00, 0xd0, 0x01, 0x26, 0x00, 
+-      0x96, 0x05, 0x2f, 0x00, 0xd0, 0x00, 0xe6, 0x9d, 
+-      0x2e, 0x00, 0xd0, 0x0a, 0xb0, 0x81, 0xab, 0x00, 
+-      0x70, 0x1e, 0x22, 0x00, 0x70, 0x5a, 0x46, 0x69, 
+-      0xa2, 0x24, 0xa0, 0x25, 0xf7, 0xff, 0xfe, 0x3c, 
+-      0xb0, 0x01, 0x22, 0x00, 0x98, 0x04, 0x00, 0x80, 
+-      0x9b, 0x08, 0x68, 0x19, 0x50, 0x0a, 0x98, 0x04, 
+-      0x28, 0x00, 0xdd, 0x0f, 0x9b, 0x08, 0x68, 0x18, 
+-      0x68, 0x01, 0x68, 0x09, 0x4b, 0x21, 0x40, 0x19, 
+-      0xa2, 0x21, 0x68, 0x12, 0x42, 0x91, 0xd1, 0x05, 
+-      0x9b, 0x04, 0x3b, 0x01, 0x93, 0x04, 0x30, 0x04, 
+-      0x9b, 0x08, 0x60, 0x18, 0x9a, 0x09, 0x9b, 0x08, 
+-      0x68, 0x19, 0x98, 0x04, 0xf7, 0xff, 0xf8, 0x0f, 
+-      0xf7, 0xff, 0xf8, 0x88, 0x1e, 0x61, 0xa2, 0x19, 
+-      0xa0, 0x19, 0xf7, 0xff, 0xfe, 0x15, 0xb0, 0x09, 
+-      0xb0, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x21, 0xac, 0x2e, 0x08, 0x21, 0x9c, 
+-      0x00, 0x00, 0x00, 0x00, 0x2e, 0x08, 0x95, 0xdc, 
+-      0x27, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x49, 0x2f, 
+-      0x4f, 0x20, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 
+-      0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x00, 0x00, 
+-      0x63, 0x61, 0x6e, 0x27, 0x74, 0x20, 0x6f, 0x70, 
+-      0x65, 0x6e, 0x20, 0x27, 0x00, 0x00, 0x00, 0x00, 
+-      0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 
+-      0x63, 0x6c, 0x6f, 0x73, 0x69, 0x6e, 0x67, 0x20, 
+-      0x00, 0x00, 0x00, 0x00, 0xdf, 0xdf, 0xdf, 0xdf, 
+-      0x52, 0x55, 0x4e, 0x00, 0x27, 0x0a, 0x00, 0x00, 
+-      0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 
+-      0x74, 0x65, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x69, 
+-      0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x20, 0x49, 
+-      0x2f, 0x4f, 0x20, 0x72, 0x65, 0x64, 0x69, 0x72, 
+-      0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x27, 
+-      0x00, 0x00, 0x00, 0x00, 0xe9, 0x2d, 0x40, 0x00, 
+-      0xe1, 0xa0, 0x68, 0x80, 0xe0, 0x56, 0x88, 0x83, 
+-      0xe0, 0x20, 0xe0, 0x03, 0xe2, 0x00, 0x01, 0x02, 
+-      0xe1, 0xa0, 0x38, 0xa6, 0x8a, 0x00, 0x00, 0x1a, 
+-      0x01, 0xa0, 0x90, 0x08, 0x0a, 0x00, 0x00, 0x2e, 
+-      0xe2, 0x68, 0x60, 0x00, 0xe1, 0xa0, 0x68, 0xa6, 
+-      0xe0, 0x83, 0x30, 0x06, 0xe1, 0xa0, 0x92, 0xa6, 
+-      0xe1, 0xc6, 0x62, 0x89, 0xe3, 0x59, 0x00, 0x02, 
+-      0x33, 0x39, 0x00, 0x00, 0xe2, 0x66, 0x90, 0x20, 
+-      0xe1, 0xa0, 0x89, 0x12, 0xe1, 0xa0, 0x26, 0x32, 
+-      0xe1, 0x82, 0x29, 0x11, 0xe1, 0xa0, 0x16, 0x31, 
+-      0x0a, 0x00, 0x00, 0x03, 0x11, 0x88, 0x81, 0x08, 
+-      0x11, 0x82, 0x81, 0x28, 0x11, 0xa0, 0x20, 0x01, 
+-      0x13, 0xa0, 0x10, 0x00, 0x3a, 0x00, 0x00, 0x04, 
+-      0x21, 0x88, 0x80, 0x02, 0x21, 0x88, 0x81, 0x08, 
+-      0x21, 0x81, 0x81, 0x28, 0x23, 0xa0, 0x20, 0x00, 
+-      0x23, 0xa0, 0x10, 0x00, 0xe3, 0xa0, 0x90, 0x00, 
+-      0xea, 0x00, 0x00, 0x15, 0xe1, 0xa0, 0x68, 0xa8, 
+-      0xe1, 0xa0, 0x82, 0xa6, 0xe1, 0xc6, 0x62, 0x88, 
+-      0xe3, 0x58, 0x00, 0x02, 0x33, 0x38, 0x00, 0x00, 
+-      0xe2, 0x66, 0x80, 0x20, 0xe1, 0xa0, 0x98, 0x15, 
+-      0xe1, 0xa0, 0x56, 0x35, 0xe1, 0x85, 0x58, 0x14, 
+-      0xe1, 0xa0, 0x46, 0x34, 0x0a, 0x00, 0x00, 0x03, 
+-      0x11, 0x89, 0x91, 0x09, 0x11, 0x85, 0x91, 0x29, 
+-      0x11, 0xa0, 0x50, 0x04, 0x13, 0xa0, 0x40, 0x00, 
+-      0x3a, 0x00, 0x00, 0x04, 0x21, 0x89, 0x90, 0x05, 
+-      0x21, 0x89, 0x91, 0x09, 0x21, 0x84, 0x91, 0x29, 
+-      0x23, 0xa0, 0x50, 0x00, 0x23, 0xa0, 0x40, 0x00, 
+-      0xe3, 0xa0, 0x80, 0x00, 0xe3, 0x1e, 0x01, 0x02, 
+-      0x1a, 0x00, 0x00, 0x09, 0xe0, 0x98, 0x60, 0x09, 
+-      0xe0, 0xb2, 0x20, 0x05, 0xe0, 0xb1, 0x10, 0x04, 
+-      0x38, 0xbd, 0x80, 0x00, 0xe2, 0x83, 0x30, 0x01, 
+-      0xe1, 0xb0, 0x10, 0x61, 0xe1, 0xb0, 0x20, 0x62, 
+-      0xe1, 0x86, 0x60, 0x86, 0xe1, 0xa0, 0x60, 0x66, 
+-      0xe8, 0xbd, 0x80, 0x00, 0xe0, 0x58, 0x60, 0x09, 
+-      0xe0, 0xd2, 0x20, 0x05, 0xe0, 0xd1, 0x10, 0x04, 
+-      0x2a, 0x00, 0x00, 0x03, 0xe2, 0x20, 0x01, 0x02, 
+-      0xe2, 0x76, 0x60, 0x00, 0xe2, 0xf2, 0x20, 0x00, 
+-      0xe2, 0xe1, 0x10, 0x00, 0xe3, 0x11, 0x01, 0x02, 
+-      0x18, 0xbd, 0x80, 0x00, 0xe0, 0x96, 0x60, 0x06, 
+-      0xe0, 0xb2, 0x20, 0x02, 0xe0, 0xa1, 0x10, 0x01, 
+-      0xe2, 0x43, 0x30, 0x01, 0xe3, 0x11, 0x01, 0x02, 
+-      0x18, 0xbd, 0x80, 0x00, 0xe1, 0x91, 0xe0, 0x02, 
+-      0x1b, 0x00, 0x06, 0x90, 0x18, 0xbd, 0x80, 0x00, 
+-      0xe3, 0xa0, 0x00, 0x00, 0xe3, 0xa0, 0x10, 0x00, 
+-      0xe2, 0x8d, 0xd0, 0x04, 0xe8, 0xbd, 0x4b, 0xf0, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe1, 0xa0, 0x98, 0x83, 
+-      0xe3, 0x79, 0x08, 0x02, 0x30, 0x09, 0x90, 0x04, 
+-      0xe0, 0x19, 0x90, 0x83, 0xe1, 0xa0, 0x88, 0x80, 
+-      0xe3, 0x78, 0x08, 0x02, 0x30, 0x08, 0x80, 0x01, 
+-      0xe0, 0x18, 0x80, 0x80, 0x4a, 0x00, 0x00, 0x14, 
+-      0xe3, 0x19, 0x01, 0x02, 0x1a, 0x00, 0x00, 0x22, 
+-      0xe9, 0x2d, 0x40, 0x00, 0xe0, 0x11, 0x60, 0x80, 
+-      0x43, 0xc1, 0x11, 0x02, 0x42, 0x80, 0x00, 0x01, 
+-      0xe0, 0x14, 0x60, 0x83, 0x43, 0xc4, 0x41, 0x02, 
+-      0x42, 0x83, 0x30, 0x01, 0xe3, 0x10, 0x01, 0x01, 
+-      0x11, 0xb0, 0x68, 0x80, 0x1b, 0x00, 0x05, 0xf8, 
+-      0xe3, 0x13, 0x01, 0x01, 0x11, 0xb0, 0x68, 0x83, 
+-      0x1b, 0x00, 0x06, 0x2f, 0xeb, 0xff, 0xff, 0x8a, 
+-      0xe3, 0x11, 0x01, 0x02, 0x18, 0xbd, 0x80, 0x00, 
+-      0xe1, 0x91, 0xe0, 0x02, 0x1b, 0x00, 0x06, 0x6d, 
+-      0xe8, 0xbd, 0x80, 0x00, 0xe3, 0x19, 0x01, 0x02, 
+-      0x0a, 0x00, 0x00, 0x09, 0xe1, 0x82, 0x80, 0x81, 
+-      0xe1, 0x88, 0x80, 0x05, 0xe1, 0x98, 0x80, 0x84, 
+-      0x1a, 0x00, 0x06, 0xb7, 0xe0, 0x23, 0x85, 0x0b, 
+-      0xe0, 0x38, 0x80, 0x00, 0x52, 0x00, 0x81, 0x02, 
+-      0x5a, 0x00, 0x00, 0x0a, 0xe3, 0x80, 0x04, 0x61, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe1, 0x92, 0x80, 0x81, 
+-      0x1a, 0x00, 0x06, 0xc0, 0xe2, 0x00, 0x81, 0x02, 
+-      0xea, 0x00, 0x00, 0x04, 0xe1, 0x95, 0x80, 0x84, 
+-      0x1a, 0x00, 0x06, 0xb3, 0xe2, 0x03, 0x81, 0x02, 
+-      0xe3, 0x1b, 0x06, 0x02, 0x12, 0x28, 0x81, 0x02, 
+-      0xe3, 0x1b, 0x06, 0x01, 0x12, 0x28, 0x81, 0x02, 
+-      0xe2, 0x8f, 0x00, 0x14, 0xe8, 0x90, 0x00, 0x07, 
+-      0xe1, 0x80, 0x00, 0x08, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x7f, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xe8, 0xbd, 0x4b, 0xf0, 0xe5, 0x9f, 0x20, 0x6c, 
+-      0xe5, 0x92, 0x10, 0x00, 0xe1, 0xa0, 0xc1, 0x83, 
+-      0xe1, 0xa0, 0xcd, 0xac, 0xe1, 0x81, 0x10, 0x0c, 
+-      0xe5, 0x82, 0x10, 0x00, 0xe3, 0x13, 0x03, 0x01, 
+-      0x1a, 0x00, 0x00, 0x05, 0xe3, 0x13, 0x04, 0x02, 
+-      0x1a, 0x00, 0x00, 0x07, 0xe3, 0x11, 0x08, 0x01, 
+-      0x0a, 0x00, 0x00, 0x44, 0xe2, 0x8f, 0x00, 0x54, 
+-      0xea, 0x00, 0x00, 0x06, 0xe3, 0x11, 0x07, 0x01, 
+-      0x0a, 0x00, 0x00, 0x34, 0xe2, 0x8f, 0x00, 0x74, 
+-      0xea, 0x00, 0x00, 0x02, 0xe3, 0x11, 0x08, 0x02, 
+-      0x0a, 0x00, 0x00, 0x30, 0xe2, 0x8f, 0x00, 0x8c, 
+-      0xe5, 0x9f, 0x10, 0x1c, 0xe2, 0x4e, 0xe0, 0x04, 
+-      0xe5, 0x81, 0xe0, 0x3c, 0xe3, 0xa0, 0xec, 0xde, 
+-      0xe3, 0x8e, 0xe0, 0xad, 0xe1, 0x8e, 0xe8, 0x0e, 
+-      0xe8, 0x81, 0x7f, 0xff, 0xea, 0x00, 0x00, 0x01, 
+-      0x2e, 0x08, 0x22, 0xac, 0x2e, 0x08, 0x22, 0xb0, 
+-      0xe5, 0x9f, 0xc1, 0x2c, 0xe3, 0x5c, 0x00, 0x00, 
+-      0x11, 0x2f, 0xff, 0x1c, 0xe6, 0x00, 0x00, 0x10, 
+-      0x80, 0x00, 0x02, 0x00, 0x46, 0x6c, 0x6f, 0x61, 
+-      0x74, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x6f, 0x69, 
+-      0x6e, 0x74, 0x20, 0x45, 0x78, 0x63, 0x65, 0x70, 
+-      0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x49, 0x6e, 
+-      0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x4f, 0x70, 
+-      0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 
+-      0x80, 0x00, 0x02, 0x01, 0x46, 0x6c, 0x6f, 0x61, 
+-      0x74, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x6f, 0x69, 
+-      0x6e, 0x74, 0x20, 0x45, 0x78, 0x63, 0x65, 0x70, 
+-      0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4f, 0x76, 
+-      0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x00, 0x00, 
+-      0x80, 0x00, 0x02, 0x02, 0x46, 0x6c, 0x6f, 0x61, 
+-      0x74, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x6f, 0x69, 
+-      0x6e, 0x74, 0x20, 0x45, 0x78, 0x63, 0x65, 0x70, 
+-      0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x44, 0x69, 
+-      0x76, 0x69, 0x64, 0x65, 0x20, 0x42, 0x79, 0x20, 
+-      0x5a, 0x65, 0x72, 0x6f, 0x00, 0x00, 0x00, 0x00, 
+-      0xe2, 0x00, 0x21, 0x02, 0xe3, 0x13, 0x07, 0x0f, 
+-      0x1a, 0x00, 0x00, 0x13, 0xe3, 0x13, 0x05, 0x02, 
+-      0x12, 0x8f, 0x00, 0x0c, 0x18, 0x90, 0x00, 0x03, 
+-      0x05, 0x9f, 0x00, 0x0c, 0xe1, 0x80, 0x00, 0x02, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x7f, 0xf0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 
+-      0xe3, 0x13, 0x07, 0x0f, 0x12, 0x00, 0x21, 0x02, 
+-      0x1a, 0x00, 0x00, 0x07, 0xe3, 0x13, 0x05, 0x02, 
+-      0x12, 0x8f, 0x00, 0x08, 0x18, 0x90, 0x00, 0x03, 
+-      0x05, 0x9f, 0x00, 0x08, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x7f, 0xc0, 0x00, 0x00, 0xe3, 0x13, 0x07, 0x02, 
+-      0x13, 0xa0, 0x00, 0x00, 0x13, 0xa0, 0x10, 0x00, 
+-      0x11, 0x2f, 0xff, 0x1e, 0xe3, 0x13, 0x07, 0x01, 
+-      0x13, 0xe0, 0x00, 0x00, 0x13, 0xe0, 0x10, 0x00, 
+-      0x11, 0x2f, 0xff, 0x1e, 0xe3, 0x13, 0x06, 0x01, 
+-      0x13, 0xa0, 0x00, 0x00, 0x13, 0xa0, 0x11, 0x02, 
+-      0x03, 0xa0, 0x01, 0x02, 0xe3, 0x32, 0x01, 0x02, 
+-      0x11, 0xe0, 0x00, 0x00, 0x11, 0xe0, 0x10, 0x01, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x2e, 0x01, 0x96, 0x91, 
+-      0xe3, 0x10, 0x02, 0x06, 0x1a, 0x00, 0x00, 0x0d, 
+-      0xe1, 0xb0, 0x80, 0x86, 0x0a, 0x00, 0x00, 0x0d, 
+-      0x22, 0x92, 0x20, 0x01, 0x22, 0x91, 0x10, 0x01, 
+-      0x23, 0xa0, 0x11, 0x02, 0xe2, 0xb3, 0x30, 0x00, 
+-      0x4a, 0x00, 0x00, 0x0a, 0xe2, 0x83, 0xc0, 0x01, 
+-      0xe3, 0xcc, 0xc1, 0x01, 0xe3, 0x5c, 0x09, 0x02, 
+-      0xc3, 0xa0, 0x33, 0x19, 0xe2, 0x00, 0x01, 0x02, 
+-      0xe1, 0x83, 0x00, 0x00, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0xe1, 0xa0, 0x30, 0x00, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0x21, 0xb0, 0x80, 0xa2, 0xea, 0xff, 0xff, 0xef, 
+-      0xe3, 0x11, 0x01, 0x02, 0x1a, 0x00, 0x00, 0x04, 
+-      0xe3, 0xa0, 0x10, 0x00, 0xe3, 0xa0, 0x20, 0x00, 
+-      0xe2, 0x00, 0x01, 0x02, 0xe3, 0xa0, 0x30, 0x00, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe1, 0xb0, 0xc8, 0x21, 
+-      0x01, 0xa0, 0xc8, 0x22, 0x01, 0x8c, 0x18, 0x01, 
+-      0x02, 0x83, 0x30, 0x10, 0xe1, 0xb0, 0xcc, 0x21, 
+-      0x01, 0xa0, 0xcc, 0x22, 0x01, 0x8c, 0x14, 0x01, 
+-      0x02, 0x83, 0x30, 0x08, 0xe1, 0xb0, 0xce, 0x21, 
+-      0x01, 0xa0, 0xce, 0x22, 0x01, 0x8c, 0x12, 0x01, 
+-      0x02, 0x83, 0x30, 0x04, 0xe1, 0xb0, 0xcf, 0x21, 
+-      0x01, 0xa0, 0xcf, 0x22, 0x01, 0x8c, 0x11, 0x01, 
+-      0x02, 0x83, 0x30, 0x02, 0xe1, 0xb0, 0xcf, 0xa1, 
+-      0x01, 0xa0, 0xcf, 0xa2, 0x01, 0x8c, 0x10, 0x81, 
+-      0x02, 0x83, 0x30, 0x01, 0xe1, 0xb0, 0x30, 0x03, 
+-      0x4a, 0xff, 0xff, 0xe4, 0x5a, 0xff, 0xff, 0xda, 
+-      0xe3, 0xc0, 0x81, 0x03, 0xe3, 0xc3, 0x91, 0x03, 
+-      0xe0, 0x20, 0x00, 0x03, 0xe2, 0x00, 0x01, 0x02, 
+-      0xe0, 0x88, 0x30, 0x09, 0xe2, 0x43, 0x3c, 0x3f, 
+-      0xe2, 0x43, 0x30, 0xfe, 0xe3, 0x32, 0x00, 0x00, 
+-      0x0a, 0x00, 0x00, 0x5d, 0xe3, 0x35, 0x00, 0x00, 
+-      0x0a, 0x00, 0x00, 0x3d, 0xe9, 0x2d, 0x48, 0x81, 
+-      0xe1, 0xa0, 0x08, 0x21, 0xe1, 0xc1, 0x78, 0x00, 
+-      0xe1, 0xa0, 0x68, 0x24, 0xe1, 0xc4, 0x88, 0x06, 
+-      0xe0, 0x09, 0x06, 0x90, 0xe0, 0x06, 0x06, 0x97, 
+-      0xe0, 0x07, 0x07, 0x98, 0xe0, 0x97, 0x78, 0x06, 
+-      0xe0, 0xa9, 0x98, 0x26, 0xe0, 0x08, 0x08, 0x90, 
+-      0xe0, 0x97, 0x78, 0x08, 0xe0, 0xa9, 0x08, 0x28, 
+-      0xe1, 0xa0, 0xb8, 0x22, 0xe1, 0xc2, 0xe8, 0x0b, 
+-      0xe1, 0xa0, 0x68, 0x25, 0xe1, 0xc5, 0x88, 0x06, 
+-      0xe0, 0x09, 0x06, 0x9b, 0xe0, 0x06, 0x06, 0x9e, 
+-      0xe0, 0x0e, 0x0e, 0x98, 0xe0, 0x9e, 0xe8, 0x06, 
+-      0xe0, 0xa9, 0x98, 0x26, 0xe0, 0x08, 0x08, 0x9b, 
+-      0xe0, 0x9e, 0xe8, 0x08, 0xe0, 0xa9, 0xb8, 0x28, 
+-      0xe0, 0x97, 0x70, 0x0b, 0xe2, 0xa0, 0x00, 0x00, 
+-      0xe0, 0x97, 0xb0, 0x0e, 0xe0, 0xb7, 0x70, 0x00, 
+-      0xe2, 0xa0, 0x00, 0x00, 0xe0, 0x51, 0x80, 0x02, 
+-      0xe3, 0xa0, 0x10, 0x00, 0xe3, 0xa0, 0x60, 0x00, 
+-      0x31, 0xe0, 0x10, 0x01, 0x30, 0x44, 0x60, 0x05, 
+-      0x10, 0x55, 0x90, 0x04, 0x03, 0xa0, 0x10, 0x00, 
+-      0x31, 0xe0, 0x10, 0x01, 0x30, 0x46, 0x60, 0x08, 
+-      0xe1, 0xa0, 0x48, 0x28, 0xe1, 0xc8, 0x58, 0x04, 
+-      0xe1, 0xa0, 0x88, 0x29, 0xe1, 0xc9, 0x98, 0x08, 
+-      0xe0, 0x22, 0x68, 0x94, 0xe0, 0x08, 0x08, 0x95, 
+-      0xe0, 0x06, 0x05, 0x99, 0xe0, 0x96, 0x68, 0x08, 
+-      0xe0, 0xa2, 0x28, 0x28, 0xe0, 0x09, 0x09, 0x94, 
+-      0xe0, 0x96, 0x68, 0x09, 0xe0, 0xa2, 0x28, 0x29, 
+-      0xe0, 0x9b, 0x60, 0x06, 0xe0, 0xb7, 0x20, 0x02, 
+-      0xe0, 0xb0, 0x10, 0x01, 0xe1, 0x8e, 0xe1, 0x0e, 
+-      0xe1, 0x86, 0x61, 0x2e, 0x48, 0xbd, 0x88, 0x81, 
+-      0xe0, 0x96, 0x60, 0x06, 0xe0, 0xb2, 0x20, 0x02, 
+-      0xe0, 0xa1, 0x10, 0x01, 0xe2, 0x43, 0x30, 0x01, 
+-      0xe8, 0xbd, 0x88, 0x81, 0xe1, 0xa0, 0x58, 0x24, 
+-      0xe1, 0xc4, 0x68, 0x05, 0xe1, 0xa0, 0x88, 0x21, 
+-      0xe1, 0xc1, 0x98, 0x08, 0xe0, 0x04, 0x08, 0x95, 
+-      0xe0, 0x08, 0x08, 0x96, 0xe0, 0x01, 0x06, 0x99, 
+-      0xe0, 0x91, 0x18, 0x08, 0xe0, 0xa4, 0x48, 0x28, 
+-      0xe0, 0x09, 0x09, 0x95, 0xe0, 0x91, 0x18, 0x09, 
+-      0xe0, 0xa4, 0x48, 0x29, 0xe1, 0xa0, 0x88, 0x22, 
+-      0xe1, 0xc2, 0x98, 0x08, 0xe0, 0x02, 0x08, 0x95, 
+-      0xe0, 0x08, 0x08, 0x96, 0xe0, 0x06, 0x06, 0x99, 
+-      0xe0, 0x96, 0x68, 0x08, 0xe0, 0xa2, 0x28, 0x28, 
+-      0xe0, 0x09, 0x09, 0x95, 0xe0, 0x96, 0x68, 0x09, 
+-      0xe0, 0xa2, 0x58, 0x29, 0xe0, 0x95, 0x20, 0x01, 
+-      0xe2, 0xb4, 0x10, 0x00, 0x41, 0xa0, 0xf0, 0x0e, 
+-      0xe0, 0x96, 0x60, 0x06, 0xe0, 0xb2, 0x20, 0x02, 
+-      0xe0, 0xa1, 0x10, 0x01, 0xe2, 0x43, 0x30, 0x01, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe3, 0x35, 0x00, 0x00, 
+-      0x0a, 0x00, 0x00, 0x24, 0xe1, 0xa0, 0x28, 0x21, 
+-      0xe1, 0xc1, 0x68, 0x02, 0xe1, 0xa0, 0x88, 0x24, 
+-      0xe1, 0xc4, 0x98, 0x08, 0xe0, 0x01, 0x08, 0x92, 
+-      0xe0, 0x08, 0x08, 0x96, 0xe0, 0x04, 0x06, 0x99, 
+-      0xe0, 0x94, 0x48, 0x08, 0xe0, 0xa1, 0x18, 0x28, 
+-      0xe0, 0x09, 0x09, 0x92, 0xe0, 0x94, 0x48, 0x09, 
+-      0xe0, 0xa1, 0x18, 0x29, 0xe1, 0xa0, 0x88, 0x25, 
+-      0xe1, 0xc5, 0x98, 0x08, 0xe0, 0x05, 0x08, 0x92, 
+-      0xe0, 0x08, 0x08, 0x96, 0xe0, 0x06, 0x06, 0x99, 
+-      0xe0, 0x96, 0x68, 0x08, 0xe0, 0xa5, 0x58, 0x28, 
+-      0xe0, 0x09, 0x09, 0x92, 0xe0, 0x96, 0x68, 0x09, 
+-      0xe0, 0xa5, 0x28, 0x29, 0xe0, 0x92, 0x20, 0x04, 
+-      0xe2, 0xb1, 0x10, 0x00, 0x41, 0xa0, 0xf0, 0x0e, 
+-      0xe0, 0x96, 0x60, 0x06, 0xe0, 0xb2, 0x20, 0x02, 
+-      0xe0, 0xa1, 0x10, 0x01, 0xe2, 0x43, 0x30, 0x01, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe3, 0xc0, 0x81, 0x03, 
+-      0xe3, 0xc3, 0x91, 0x03, 0xe0, 0x20, 0x00, 0x03, 
+-      0xe2, 0x00, 0x01, 0x02, 0xe0, 0x88, 0x30, 0x09, 
+-      0xe2, 0x43, 0x3c, 0x3f, 0xe2, 0x43, 0x30, 0xfe, 
+-      0xe1, 0xa0, 0x58, 0x24, 0xe1, 0xc4, 0x68, 0x05, 
+-      0xe1, 0xa0, 0x88, 0x21, 0xe1, 0xc1, 0x98, 0x08, 
+-      0xe0, 0x01, 0x08, 0x95, 0xe0, 0x08, 0x08, 0x96, 
+-      0xe0, 0x02, 0x06, 0x99, 0xe0, 0x92, 0x28, 0x08, 
+-      0xe0, 0xa1, 0x18, 0x28, 0xe0, 0x09, 0x09, 0x95, 
+-      0xe0, 0x92, 0x28, 0x09, 0xe0, 0xb1, 0x18, 0x29, 
+-      0xe3, 0xa0, 0x60, 0x00, 0x41, 0xa0, 0xf0, 0x0e, 
+-      0xe0, 0x92, 0x20, 0x02, 0xe0, 0xa1, 0x10, 0x01, 
+-      0xe2, 0x43, 0x30, 0x01, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0xe1, 0xa0, 0x98, 0x83, 0xe3, 0x79, 0x08, 0x02, 
+-      0x30, 0x09, 0x90, 0x04, 0xe0, 0x19, 0x90, 0x83, 
+-      0xe1, 0xa0, 0x88, 0x80, 0xe3, 0x78, 0x08, 0x02, 
+-      0x30, 0x08, 0x80, 0x01, 0xe0, 0x18, 0x80, 0x80, 
+-      0x4a, 0x00, 0x00, 0x1f, 0xe3, 0x19, 0x01, 0x02, 
+-      0x1a, 0x00, 0x00, 0x2f, 0xe1, 0x91, 0x80, 0x02, 
+-      0x11, 0x94, 0x80, 0x05, 0x0a, 0x00, 0x00, 0x13, 
+-      0xe0, 0x11, 0x60, 0x80, 0x43, 0xc1, 0x11, 0x02, 
+-      0x42, 0x80, 0x00, 0x01, 0xe0, 0x14, 0x60, 0x83, 
+-      0x43, 0xc4, 0x41, 0x02, 0x42, 0x83, 0x30, 0x01, 
+-      0xe3, 0xc0, 0x81, 0x03, 0xe3, 0xc3, 0x91, 0x03, 
+-      0xe0, 0x20, 0x00, 0x03, 0xe2, 0x00, 0x01, 0x02, 
+-      0xe0, 0x88, 0x30, 0x09, 0xe2, 0x43, 0x3c, 0x3f, 
+-      0xe2, 0x43, 0x30, 0xfe, 0xe9, 0x2d, 0x40, 0x00, 
+-      0xe3, 0x11, 0x01, 0x02, 0x0b, 0x00, 0x04, 0xed, 
+-      0xe3, 0x14, 0x01, 0x02, 0x0b, 0x00, 0x05, 0x04, 
+-      0xe8, 0xbd, 0x40, 0x00, 0xea, 0xff, 0xff, 0x44, 
+-      0xe0, 0x20, 0x00, 0x03, 0xe2, 0x00, 0x01, 0x02, 
+-      0xe3, 0xa0, 0x10, 0x00, 0xe3, 0xa0, 0x20, 0x00, 
+-      0xe3, 0xa0, 0x30, 0x00, 0xe3, 0xa0, 0x60, 0x00, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe3, 0x19, 0x01, 0x02, 
+-      0x0a, 0x00, 0x00, 0x09, 0xe1, 0x82, 0x80, 0x81, 
+-      0xe1, 0x88, 0x80, 0x05, 0xe1, 0x98, 0x80, 0x84, 
+-      0x1a, 0x00, 0x05, 0x2d, 0xe0, 0x20, 0x80, 0x03, 
+-      0xe2, 0x08, 0x81, 0x02, 0xe2, 0x8f, 0x00, 0x44, 
+-      0xe8, 0x90, 0x00, 0x07, 0xe1, 0x80, 0x00, 0x08, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe1, 0x92, 0x80, 0x81, 
+-      0x1a, 0x00, 0x05, 0x36, 0xe1, 0x94, 0x80, 0x05, 
+-      0x1a, 0xff, 0xff, 0xf5, 0xe3, 0x80, 0x04, 0x61, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe1, 0x95, 0x80, 0x84, 
+-      0x1a, 0x00, 0x05, 0x27, 0xe1, 0x91, 0x80, 0x02, 
+-      0x1a, 0xff, 0xff, 0xef, 0xe3, 0x80, 0x04, 0x61, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x40, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xe1, 0xa0, 0x80, 0x00, 
+-      0xe1, 0xa0, 0x00, 0x03, 0xe1, 0xa0, 0x30, 0x08, 
+-      0xe1, 0xa0, 0x80, 0x01, 0xe1, 0xa0, 0x10, 0x04, 
+-      0xe1, 0xa0, 0x40, 0x08, 0xe1, 0xa0, 0x80, 0x02, 
+-      0xe1, 0xa0, 0x20, 0x05, 0xe1, 0xa0, 0x50, 0x08, 
+-      0xe3, 0xc0, 0x81, 0x03, 0xe3, 0xc3, 0x91, 0x03, 
+-      0xe0, 0x20, 0x00, 0x03, 0xe2, 0x00, 0x01, 0x02, 
+-      0xe0, 0x49, 0x30, 0x08, 0xe2, 0x83, 0x3c, 0x3f, 
+-      0xe2, 0x83, 0x30, 0xff, 0xe9, 0x2d, 0x48, 0x89, 
+-      0xe1, 0xa0, 0x08, 0x21, 0xe1, 0xc1, 0x78, 0x00, 
+-      0xe1, 0xa0, 0xb8, 0x22, 0xe1, 0xc2, 0xe8, 0x0b, 
+-      0xe2, 0x8f, 0x6e, 0x36, 0xe7, 0xd6, 0x64, 0x20, 
+-      0xe0, 0x28, 0x66, 0x90, 0xe2, 0x68, 0x85, 0x02, 
+-      0xe0, 0x06, 0x06, 0x98, 0xe1, 0xa0, 0x69, 0xa6, 
+-      0xe2, 0x86, 0x60, 0x02, 0xe1, 0xa0, 0x86, 0xa1, 
+-      0xe0, 0x29, 0x66, 0x98, 0xe2, 0x69, 0x92, 0x02, 
+-      0xe1, 0xa0, 0x88, 0x29, 0xe1, 0xc9, 0x98, 0x08, 
+-      0xe0, 0x02, 0x06, 0x99, 0xe0, 0x01, 0x06, 0x98, 
+-      0xe0, 0x81, 0x68, 0x22, 0xe1, 0xa0, 0x63, 0x26, 
+-      0xe1, 0xb0, 0x40, 0xa4, 0xe1, 0xb0, 0x50, 0x65, 
+-      0x33, 0xa0, 0x30, 0x00, 0x23, 0xa0, 0x31, 0x02, 
+-      0xe1, 0xa0, 0x87, 0xa4, 0xe0, 0x09, 0x08, 0x96, 
+-      0xe1, 0xa0, 0x98, 0x29, 0xe0, 0x08, 0x0b, 0x99, 
+-      0xe0, 0x55, 0x50, 0x08, 0xe0, 0x08, 0x09, 0x90, 
+-      0xe0, 0xc4, 0x40, 0x08, 0xe0, 0x08, 0x0e, 0x99, 
+-      0xe0, 0x53, 0x38, 0x08, 0xe0, 0xd5, 0x58, 0x28, 
+-      0xe0, 0x08, 0x07, 0x99, 0x30, 0x45, 0x58, 0x08, 
+-      0x20, 0x55, 0x58, 0x08, 0xe0, 0xc4, 0x48, 0x28, 
+-      0xe1, 0xa0, 0x18, 0x09, 0xe1, 0xa0, 0x81, 0x24, 
+-      0xe0, 0x09, 0x08, 0x96, 0xe1, 0xa0, 0x98, 0x29, 
+-      0xe0, 0x08, 0x0b, 0x99, 0xe0, 0x53, 0x39, 0x88, 
+-      0xe0, 0xd5, 0x56, 0xa8, 0xe0, 0x08, 0x09, 0x90, 
+-      0x30, 0x45, 0x59, 0x88, 0x20, 0x55, 0x59, 0x88, 
+-      0xe0, 0xc4, 0x46, 0xa8, 0xe0, 0x08, 0x0e, 0x99, 
+-      0xe0, 0x53, 0x31, 0x88, 0xe0, 0xd5, 0x5e, 0xa8, 
+-      0xe0, 0x08, 0x07, 0x99, 0x30, 0x45, 0x51, 0x88, 
+-      0x20, 0x55, 0x51, 0x88, 0xe0, 0xc4, 0x4e, 0xa8, 
+-      0xe1, 0xa0, 0x4d, 0x04, 0xe1, 0x84, 0x43, 0x25, 
+-      0xe1, 0xa0, 0x5d, 0x05, 0xe1, 0x85, 0x53, 0x23, 
+-      0xe1, 0xa0, 0x3d, 0x03, 0xe0, 0x81, 0x11, 0x89, 
+-      0xe5, 0x9d, 0x80, 0x0c, 0xe3, 0x18, 0x00, 0x01, 
+-      0x1a, 0x00, 0x00, 0x94, 0xe1, 0xa0, 0x87, 0xa4, 
+-      0xe0, 0x09, 0x08, 0x96, 0xe1, 0xa0, 0x98, 0x29, 
+-      0xe0, 0x08, 0x0b, 0x99, 0xe0, 0x55, 0x50, 0x08, 
+-      0xe0, 0x08, 0x09, 0x90, 0xe0, 0xc4, 0x40, 0x08, 
+-      0xe0, 0x08, 0x0e, 0x99, 0xe0, 0x53, 0x38, 0x08, 
+-      0xe0, 0xd5, 0x58, 0x28, 0xe0, 0x08, 0x07, 0x99, 
+-      0x30, 0x45, 0x58, 0x08, 0x20, 0x55, 0x58, 0x08, 
+-      0xe0, 0xc4, 0x48, 0x28, 0xe1, 0xa0, 0x2b, 0x09, 
+-      0xe0, 0x81, 0x15, 0x29, 0xe1, 0xa0, 0x81, 0x24, 
+-      0xe0, 0x09, 0x08, 0x96, 0xe1, 0xa0, 0x98, 0x29, 
+-      0xe0, 0x08, 0x0b, 0x99, 0xe0, 0x53, 0x39, 0x88, 
+-      0xe0, 0xd5, 0x56, 0xa8, 0xe0, 0x08, 0x09, 0x90, 
+-      0x30, 0x45, 0x59, 0x88, 0x20, 0x55, 0x59, 0x88, 
+-      0xe0, 0xc4, 0x46, 0xa8, 0xe0, 0x08, 0x0e, 0x99, 
+-      0xe0, 0x53, 0x31, 0x88, 0xe0, 0xd5, 0x5e, 0xa8, 
+-      0xe0, 0x08, 0x07, 0x99, 0x30, 0x45, 0x51, 0x88, 
+-      0x20, 0x55, 0x51, 0x88, 0xe0, 0xc4, 0x4e, 0xa8, 
+-      0xe1, 0xa0, 0x4d, 0x04, 0xe1, 0x84, 0x43, 0x25, 
+-      0xe1, 0xa0, 0x5d, 0x05, 0xe1, 0x85, 0x53, 0x23, 
+-      0xe1, 0xa0, 0x3d, 0x03, 0xe0, 0x92, 0x24, 0x89, 
+-      0xe2, 0xa1, 0x10, 0x00, 0xe5, 0x9d, 0x80, 0x0c, 
+-      0xe3, 0x18, 0x00, 0x02, 0x1a, 0x00, 0x00, 0x3f, 
+-      0xe1, 0xa0, 0x87, 0xa4, 0xe0, 0x09, 0x08, 0x96, 
+-      0xe1, 0xa0, 0x98, 0x29, 0xe0, 0x08, 0x0b, 0x99, 
+-      0xe0, 0x55, 0x50, 0x08, 0xe0, 0x08, 0x09, 0x90, 
+-      0xe0, 0xc4, 0x40, 0x08, 0xe0, 0x08, 0x0e, 0x99, 
+-      0xe0, 0x53, 0x38, 0x08, 0xe0, 0xd5, 0x58, 0x28, 
+-      0xe0, 0x08, 0x07, 0x99, 0x30, 0x45, 0x58, 0x08, 
+-      0x20, 0x55, 0x58, 0x08, 0xe0, 0xc4, 0x48, 0x28, 
+-      0xe1, 0xa0, 0x47, 0x04, 0xe1, 0x84, 0x49, 0x25, 
+-      0xe1, 0xa0, 0x57, 0x05, 0xe1, 0x85, 0x59, 0x23, 
+-      0xe1, 0xa0, 0x37, 0x03, 0xe1, 0xa0, 0x6e, 0x09, 
+-      0xe0, 0x92, 0x22, 0x29, 0xe2, 0xa1, 0x10, 0x00, 
+-      0xe1, 0x87, 0x08, 0x00, 0xe1, 0x8e, 0x78, 0x0b, 
+-      0xe3, 0xa0, 0xe0, 0x00, 0xe0, 0x55, 0x90, 0x07, 
+-      0xe0, 0xd4, 0x80, 0x00, 0x21, 0xa0, 0x50, 0x09, 
+-      0x21, 0xa0, 0x40, 0x08, 0xe0, 0xae, 0xe0, 0x0e, 
+-      0xe3, 0xa0, 0xb0, 0x00, 0xe0, 0x93, 0x30, 0x03, 
+-      0xe0, 0xb5, 0x50, 0x05, 0xe0, 0xb4, 0x40, 0x04, 
+-      0xe0, 0xab, 0xb0, 0x0b, 0xe0, 0x55, 0x90, 0x07, 
+-      0xe0, 0xd4, 0x80, 0x00, 0xe2, 0xdb, 0xb0, 0x00, 
+-      0x21, 0xa0, 0x50, 0x09, 0x21, 0xa0, 0x40, 0x08, 
+-      0xe0, 0xae, 0xe0, 0x0e, 0xe3, 0xa0, 0xb0, 0x00, 
+-      0xe0, 0x93, 0x30, 0x03, 0xe0, 0xb5, 0x50, 0x05, 
+-      0xe0, 0xb4, 0x40, 0x04, 0xe0, 0xab, 0xb0, 0x0b, 
+-      0xe0, 0x55, 0x90, 0x07, 0xe0, 0xd4, 0x80, 0x00, 
+-      0xe2, 0xdb, 0xb0, 0x00, 0x21, 0xa0, 0x50, 0x09, 
+-      0x21, 0xa0, 0x40, 0x08, 0xe0, 0xae, 0xe0, 0x0e, 
+-      0xe1, 0x94, 0x80, 0x05, 0x13, 0x86, 0x60, 0x01, 
+-      0xe0, 0x96, 0x6e, 0x0e, 0xe2, 0xb2, 0x20, 0x00, 
+-      0xe2, 0xb1, 0x10, 0x00, 0x48, 0xbd, 0x88, 0x89, 
+-      0xe8, 0xbd, 0x48, 0x89, 0xe0, 0x96, 0x60, 0x06, 
+-      0xe0, 0xb2, 0x20, 0x02, 0xe0, 0xa1, 0x10, 0x01, 
+-      0xe2, 0x43, 0x30, 0x01, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0xe1, 0x87, 0x08, 0x00, 0xe1, 0x8e, 0x78, 0x0b, 
+-      0xe3, 0xa0, 0xe0, 0x00, 0xe0, 0x93, 0x30, 0x03, 
+-      0xe0, 0xb5, 0x50, 0x05, 0xe0, 0xa4, 0x40, 0x04, 
+-      0xe0, 0x55, 0x90, 0x07, 0xe0, 0xd4, 0x80, 0x00, 
+-      0x21, 0xa0, 0x50, 0x09, 0x21, 0xa0, 0x40, 0x08, 
+-      0xe0, 0xae, 0xe0, 0x0e, 0xe3, 0xa0, 0xb0, 0x00, 
+-      0xe0, 0x93, 0x30, 0x03, 0xe0, 0xb5, 0x50, 0x05, 
+-      0xe0, 0xb4, 0x40, 0x04, 0xe0, 0xab, 0xb0, 0x0b, 
+-      0xe0, 0x55, 0x90, 0x07, 0xe0, 0xd4, 0x80, 0x00, 
+-      0xe2, 0xdb, 0xb0, 0x00, 0x21, 0xa0, 0x50, 0x09, 
+-      0x21, 0xa0, 0x40, 0x08, 0xe0, 0xae, 0xe0, 0x0e, 
+-      0xe3, 0xa0, 0xb0, 0x00, 0xe0, 0x93, 0x30, 0x03, 
+-      0xe0, 0xb5, 0x50, 0x05, 0xe0, 0xb4, 0x40, 0x04, 
+-      0xe0, 0xab, 0xb0, 0x0b, 0xe0, 0x55, 0x90, 0x07, 
+-      0xe0, 0xd4, 0x80, 0x00, 0xe2, 0xdb, 0xb0, 0x00, 
+-      0x21, 0xa0, 0x50, 0x09, 0x21, 0xa0, 0x40, 0x08, 
+-      0xe0, 0xae, 0xe0, 0x0e, 0xe1, 0x84, 0x60, 0x05, 
+-      0xe0, 0x92, 0x24, 0x8e, 0xe2, 0xb1, 0x10, 0x00, 
+-      0x48, 0xbd, 0x88, 0x89, 0xe8, 0xbd, 0x48, 0x89, 
+-      0xe0, 0x92, 0x20, 0x02, 0xe0, 0xa1, 0x10, 0x01, 
+-      0xe2, 0x43, 0x30, 0x01, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0xe1, 0x87, 0x08, 0x00, 0xe1, 0x8e, 0x78, 0x0b, 
+-      0xe0, 0x93, 0x30, 0x03, 0xe0, 0xb5, 0x50, 0x05, 
+-      0xe0, 0xa4, 0x40, 0x04, 0xe0, 0x55, 0x90, 0x07, 
+-      0xe0, 0xd4, 0x80, 0x00, 0x21, 0xa0, 0x50, 0x09, 
+-      0x21, 0xa0, 0x40, 0x08, 0x22, 0x81, 0x10, 0x20, 
+-      0xe3, 0xa0, 0xb0, 0x00, 0xe0, 0x93, 0x30, 0x03, 
+-      0xe0, 0xb5, 0x50, 0x05, 0xe0, 0xb4, 0x40, 0x04, 
+-      0xe0, 0xab, 0xb0, 0x0b, 0xe0, 0x55, 0x90, 0x07, 
+-      0xe0, 0xd4, 0x80, 0x00, 0xe2, 0xdb, 0xb0, 0x00, 
+-      0x21, 0xa0, 0x50, 0x09, 0x21, 0xa0, 0x40, 0x08, 
+-      0x22, 0x81, 0x10, 0x10, 0xe3, 0xa0, 0xb0, 0x00, 
+-      0xe0, 0x93, 0x30, 0x03, 0xe0, 0xb5, 0x50, 0x05, 
+-      0xe0, 0xb4, 0x40, 0x04, 0xe0, 0xab, 0xb0, 0x0b, 
+-      0xe0, 0x55, 0x90, 0x07, 0xe0, 0xd4, 0x80, 0x00, 
+-      0xe2, 0xdb, 0xb0, 0x00, 0x21, 0xa0, 0x50, 0x09, 
+-      0x21, 0xa0, 0x40, 0x08, 0x22, 0x81, 0x10, 0x08, 
+-      0xe1, 0x84, 0x60, 0x05, 0xe3, 0xa0, 0x20, 0x00, 
+-      0xe3, 0x31, 0x00, 0x00, 0x48, 0xbd, 0x88, 0x89, 
+-      0xe8, 0xbd, 0x48, 0x89, 0xe1, 0xa0, 0x10, 0x81, 
+-      0xe2, 0x43, 0x30, 0x01, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0x80, 0x80, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 
+-      0x79, 0x78, 0x77, 0x76, 0x76, 0x75, 0x74, 0x73, 
+-      0x72, 0x71, 0x71, 0x70, 0x6f, 0x6e, 0x6e, 0x6d, 
+-      0x6c, 0x6c, 0x6b, 0x6a, 0x6a, 0x69, 0x68, 0x68, 
+-      0x67, 0x66, 0x66, 0x65, 0x64, 0x64, 0x63, 0x63, 
+-      0x62, 0x61, 0x61, 0x60, 0x60, 0x5f, 0x5f, 0x5e, 
+-      0x5e, 0x5d, 0x5d, 0x5c, 0x5c, 0x5b, 0x5b, 0x5a, 
+-      0x5a, 0x59, 0x59, 0x58, 0x58, 0x57, 0x57, 0x56, 
+-      0x56, 0x55, 0x55, 0x55, 0x54, 0x54, 0x53, 0x53, 
+-      0x52, 0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x50, 
+-      0x4f, 0x4f, 0x4f, 0x4e, 0x4e, 0x4d, 0x4d, 0x4d, 
+-      0x4c, 0x4c, 0x4c, 0x4b, 0x4b, 0x4b, 0x4a, 0x4a, 
+-      0x4a, 0x49, 0x49, 0x49, 0x48, 0x48, 0x48, 0x47, 
+-      0x47, 0x47, 0x47, 0x46, 0x46, 0x46, 0x45, 0x45, 
+-      0x45, 0x44, 0x44, 0x44, 0x44, 0x43, 0x43, 0x43, 
+-      0x43, 0x42, 0x42, 0x42, 0x42, 0x41, 0x41, 0x41, 
+-      0xe1, 0xa0, 0x98, 0x83, 0xe3, 0x79, 0x08, 0x02, 
+-      0x30, 0x09, 0x90, 0x04, 0xe0, 0x19, 0x90, 0x83, 
+-      0xe1, 0xa0, 0x88, 0x80, 0xe3, 0x78, 0x08, 0x02, 
+-      0x30, 0x08, 0x80, 0x01, 0xe0, 0x18, 0x80, 0x80, 
+-      0x4a, 0x00, 0x00, 0x20, 0xe3, 0x19, 0x01, 0x02, 
+-      0x1a, 0x00, 0x00, 0x32, 0xe3, 0x1b, 0x00, 0x04, 
+-      0x1a, 0x00, 0x00, 0x08, 0xe1, 0xa0, 0x80, 0x00, 
+-      0xe1, 0xa0, 0x00, 0x03, 0xe1, 0xa0, 0x30, 0x08, 
+-      0xe1, 0xa0, 0x80, 0x01, 0xe1, 0xa0, 0x10, 0x04, 
+-      0xe1, 0xa0, 0x40, 0x08, 0xe1, 0xa0, 0x80, 0x02, 
+-      0xe1, 0xa0, 0x20, 0x05, 0xe1, 0xa0, 0x50, 0x08, 
+-      0xe0, 0x11, 0x60, 0x80, 0x43, 0xc1, 0x11, 0x02, 
+-      0x42, 0x80, 0x00, 0x01, 0xe0, 0x14, 0x60, 0x83, 
+-      0x43, 0xc4, 0x41, 0x02, 0x42, 0x83, 0x30, 0x01, 
+-      0xe3, 0xc0, 0x81, 0x03, 0xe3, 0xc3, 0x91, 0x03, 
+-      0xe0, 0x20, 0x00, 0x03, 0xe2, 0x00, 0x01, 0x02, 
+-      0xe0, 0x49, 0x30, 0x08, 0xe2, 0x83, 0x3c, 0x3f, 
+-      0xe2, 0x83, 0x30, 0xff, 0xe9, 0x2d, 0x40, 0x00, 
+-      0xe3, 0x11, 0x01, 0x02, 0x0b, 0x00, 0x03, 0xa1, 
+-      0xe3, 0x14, 0x01, 0x02, 0x0b, 0x00, 0x03, 0x86, 
+-      0xe8, 0xbd, 0x40, 0x00, 0xea, 0xff, 0xfe, 0xb6, 
+-      0xe3, 0x19, 0x01, 0x02, 0x0a, 0x00, 0x00, 0x05, 
+-      0xe1, 0x82, 0x80, 0x81, 0xe1, 0x88, 0x80, 0x05, 
+-      0xe1, 0x98, 0x80, 0x84, 0x1a, 0x00, 0x03, 0xb6, 
+-      0xe3, 0x80, 0x04, 0x61, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0xe1, 0x92, 0x80, 0x81, 0x1a, 0x00, 0x03, 0xc3, 
+-      0xe0, 0x20, 0x80, 0x03, 0xe2, 0x08, 0x81, 0x02, 
+-      0xe3, 0x1b, 0x00, 0x04, 0x02, 0x8f, 0x00, 0x50, 
+-      0x12, 0x8f, 0x00, 0x40, 0xe8, 0x90, 0x00, 0x07, 
+-      0xe1, 0x80, 0x00, 0x08, 0xe3, 0xa0, 0x30, 0x00, 
+-      0xe3, 0xa0, 0x60, 0x00, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0xe1, 0x95, 0x80, 0x84, 0x1a, 0x00, 0x03, 0xae, 
+-      0xe0, 0x20, 0x80, 0x03, 0xe2, 0x08, 0x81, 0x02, 
+-      0xe3, 0x1b, 0x00, 0x04, 0x12, 0x8f, 0x00, 0x20, 
+-      0x02, 0x8f, 0x00, 0x10, 0xe8, 0x90, 0x00, 0x07, 
+-      0xe1, 0x80, 0x00, 0x08, 0xe3, 0xa0, 0x30, 0x00, 
+-      0xe3, 0xa0, 0x60, 0x00, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x7f, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xb5, 0x00, 0x49, 0x02, 0xf0, 0x00, 0xf9, 0x2a, 
+-      0xbc, 0x08, 0x47, 0x18, 0xff, 0xff, 0xff, 0xfd, 
+-      0xb5, 0x80, 0x1c, 0x07, 0x28, 0x0a, 0xd2, 0x14, 
+-      0xa3, 0x01, 0x5c, 0x1b, 0x00, 0x5b, 0x44, 0x9f, 
+-      0x10, 0x04, 0x10, 0x06, 0x08, 0x0a, 0x0c, 0x10, 
+-      0x0e, 0x0e, 0xa0, 0x0f, 0xe0, 0x0c, 0xa0, 0x1a, 
+-      0xe0, 0x0a, 0xa0, 0x33, 0xe0, 0x08, 0xa0, 0x3f, 
+-      0xe0, 0x06, 0xa0, 0x4b, 0xe0, 0x04, 0xa0, 0x52, 
+-      0xe0, 0x02, 0x1c, 0x38, 0xf0, 0x00, 0xff, 0x89, 
+-      0x21, 0x03, 0xf0, 0x00, 0xf9, 0x27, 0x2f, 0x04, 
+-      0xd1, 0x05, 0x20, 0x01, 0xf7, 0xfe, 0xf8, 0xd4, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0xf7, 0xfe, 
+-      0xfd, 0xb3, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x41, 0x62, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 
+-      0x20, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 
+-      0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x2e, 
+-      0x67, 0x2e, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, 
+-      0x28, 0x29, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 
+-      0x69, 0x6f, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 
+-      0x49, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x20, 
+-      0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 
+-      0x69, 0x6f, 0x6e, 0x20, 0x28, 0x63, 0x61, 0x6c, 
+-      0x6c, 0x20, 0x74, 0x6f, 0x20, 0x6e, 0x6f, 0x6e, 
+-      0x2d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 
+-      0x6e, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x63, 
+-      0x6f, 0x72, 0x72, 0x75, 0x70, 0x74, 0x65, 0x64, 
+-      0x29, 0x0a, 0x5b, 0x69, 0x73, 0x20, 0x74, 0x68, 
+-      0x65, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x69, 
+-      0x6e, 0x67, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 
+-      0x20, 0x65, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 
+-      0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 
+-      0x6c, 0x65, 0x64, 0x3f, 0x5d, 0x00, 0x00, 0x00, 
+-      0x49, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 
+-      0x74, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 
+-      0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 
+-      0x75, 0x73, 0x65, 0x72, 0x20, 0x2d, 0x20, 0x70, 
+-      0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 0x74, 
+-      0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 
+-      0x64, 0x00, 0x00, 0x00, 0x49, 0x6c, 0x6c, 0x65, 
+-      0x67, 0x61, 0x6c, 0x20, 0x61, 0x64, 0x64, 0x72, 
+-      0x65, 0x73, 0x73, 0x20, 0x28, 0x65, 0x2e, 0x67, 
+-      0x2e, 0x20, 0x77, 0x69, 0x6c, 0x64, 0x6c, 0x79, 
+-      0x20, 0x6f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, 
+-      0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x62, 
+-      0x6f, 0x75, 0x6e, 0x64, 0x73, 0x29, 0x00, 0x00, 
+-      0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 
+-      0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x71, 0x75, 
+-      0x65, 0x73, 0x74, 0x20, 0x72, 0x65, 0x63, 0x65, 
+-      0x69, 0x76, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 
+-      0x55, 0x73, 0x65, 0x72, 0x2d, 0x64, 0x65, 0x66, 
+-      0x69, 0x6e, 0x65, 0x64, 0x20, 0x73, 0x69, 0x67, 
+-      0x6e, 0x61, 0x6c, 0x00, 0xb5, 0x00, 0x20, 0x01, 
+-      0x49, 0x05, 0x70, 0x08, 0xa0, 0x05, 0x21, 0x03, 
+-      0xf0, 0x00, 0xf8, 0x78, 0x20, 0x64, 0xf7, 0xfe, 
+-      0xf8, 0x27, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x21, 0x94, 0x53, 0x74, 0x61, 0x63, 
+-      0x6b, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 
+-      0x6f, 0x77, 0x0a, 0x00, 0xb5, 0x00, 0x28, 0x07, 
+-      0xd1, 0x03, 0xf7, 0xff, 0xff, 0xe3, 0xbc, 0x08, 
+-      0x47, 0x18, 0xf7, 0xff, 0xff, 0x19, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0x00, 0xf7, 0xff, 0xff, 0xf2, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0x90, 0x28, 0x00, 
+-      0xdd, 0x01, 0x28, 0x0b, 0xdb, 0x05, 0x20, 0x03, 
+-      0x49, 0x0b, 0x60, 0x08, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x87, 0x4b, 0x09, 0x59, 0xd9, 
+-      0x4a, 0x09, 0x42, 0x91, 0xd1, 0x02, 0xf7, 0xff, 
+-      0xff, 0xdd, 0xe0, 0x05, 0x4c, 0x07, 0x42, 0xa1, 
+-      0xd0, 0x02, 0x51, 0xda, 0xf7, 0xfd, 0xfa, 0xee, 
+-      0x20, 0x00, 0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x20, 0xb0, 0x2e, 0x08, 0x94, 0xac, 
+-      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 
+-      0x28, 0x00, 0xdd, 0x09, 0x28, 0x0b, 0xda, 0x07, 
+-      0x00, 0x80, 0x49, 0x04, 0x58, 0x08, 0x49, 0x04, 
+-      0x42, 0x88, 0xd0, 0x01, 0x20, 0x01, 0x47, 0x70, 
+-      0x20, 0x00, 0x47, 0x70, 0x2e, 0x08, 0x94, 0xac, 
+-      0xff, 0xff, 0xff, 0xff, 0x28, 0x00, 0xdd, 0x01, 
+-      0x28, 0x0b, 0xdb, 0x01, 0x48, 0x03, 0x47, 0x70, 
+-      0x00, 0x83, 0x4a, 0x03, 0x58, 0xd0, 0x50, 0xd1, 
+-      0x47, 0x70, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 
+-      0x2e, 0x08, 0x94, 0xac, 0xb5, 0x90, 0x27, 0x01, 
+-      0x4c, 0x05, 0x1c, 0x38, 0x1c, 0x21, 0xf7, 0xff, 
+-      0xff, 0xe9, 0x37, 0x01, 0x2f, 0x0b, 0xdb, 0xf8, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0xff, 0xff, 0xff, 0xff, 0xb5, 0x90, 0x1c, 0x0c, 
+-      0x1c, 0x07, 0x48, 0x12, 0x28, 0x00, 0xd0, 0x09, 
+-      0x48, 0x11, 0x78, 0x00, 0x28, 0x00, 0xd1, 0x05, 
+-      0x1c, 0x38, 0x1c, 0x21, 0xf0, 0x00, 0xfb, 0x44, 
+-      0x28, 0x00, 0xd1, 0x13, 0x08, 0x60, 0xd3, 0x02, 
+-      0x20, 0x0a, 0xf0, 0x00, 0xf8, 0xd3, 0x78, 0x38, 
+-      0x28, 0x00, 0xd0, 0x06, 0x78, 0x38, 0x37, 0x01, 
+-      0xf0, 0x00, 0xf8, 0xcc, 0x78, 0x38, 0x28, 0x00, 
+-      0xd1, 0xf8, 0x08, 0xa0, 0xd3, 0x02, 0x20, 0x0a, 
+-      0xf0, 0x00, 0xf8, 0xc4, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x01, 0xbd, 0x35, 
+-      0x2e, 0x08, 0x21, 0x94, 0xb5, 0x80, 0xb0, 0x83, 
+-      0x90, 0x00, 0x91, 0x01, 0xf7, 0xfd, 0xfb, 0x1e, 
+-      0x90, 0x02, 0x46, 0x69, 0x20, 0x01, 0xf0, 0x01, 
+-      0xf8, 0x61, 0x23, 0x01, 0x1c, 0x07, 0x42, 0xd8, 
+-      0xd1, 0x05, 0x21, 0x00, 0x20, 0x13, 0xf0, 0x01, 
+-      0xf8, 0x59, 0x49, 0x03, 0x60, 0x08, 0x1c, 0x38, 
+-      0xb0, 0x03, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x20, 0xb0, 0xb5, 0x80, 0xb0, 0x81, 
+-      0x90, 0x00, 0x46, 0x69, 0x20, 0x02, 0xf0, 0x01, 
+-      0xf8, 0x49, 0x1c, 0x07, 0xd0, 0x05, 0x21, 0x00, 
+-      0x20, 0x13, 0xf0, 0x01, 0xf8, 0x43, 0x49, 0x03, 
+-      0x60, 0x08, 0x1c, 0x38, 0xb0, 0x01, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x20, 0xb0, 
+-      0xb5, 0x80, 0xb0, 0x84, 0x90, 0x00, 0x91, 0x01, 
+-      0x92, 0x02, 0x46, 0x69, 0x20, 0x05, 0xf0, 0x01, 
+-      0xf8, 0x31, 0x1c, 0x07, 0xd0, 0x05, 0x21, 0x00, 
+-      0x20, 0x13, 0xf0, 0x01, 0xf8, 0x2b, 0x49, 0x03, 
+-      0x60, 0x08, 0x1c, 0x38, 0xb0, 0x04, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x20, 0xb0, 
+-      0xb5, 0x80, 0xb0, 0x84, 0x90, 0x00, 0x91, 0x01, 
+-      0x92, 0x02, 0x93, 0x03, 0x46, 0x69, 0x20, 0x06, 
+-      0xf0, 0x01, 0xf8, 0x18, 0x1c, 0x07, 0xd0, 0x05, 
+-      0x21, 0x00, 0x20, 0x13, 0xf0, 0x01, 0xf8, 0x12, 
+-      0x49, 0x03, 0x60, 0x08, 0x1c, 0x38, 0xb0, 0x04, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x20, 0xb0, 0xb5, 0x00, 0xb0, 0x81, 
+-      0x90, 0x00, 0x46, 0x69, 0x20, 0x08, 0xf0, 0x01, 
+-      0xf8, 0x01, 0xb0, 0x01, 0xbc, 0x08, 0x47, 0x18, 
+-      0xb5, 0x00, 0x69, 0x40, 0xb0, 0x81, 0x90, 0x00, 
+-      0x46, 0x69, 0x20, 0x09, 0xf0, 0x00, 0xff, 0xf6, 
+-      0xb0, 0x01, 0xbc, 0x08, 0x47, 0x18, 0xb5, 0x80, 
+-      0xb0, 0x82, 0x90, 0x00, 0x91, 0x01, 0x46, 0x69, 
+-      0x20, 0x0a, 0xf0, 0x00, 0xff, 0xeb, 0x1c, 0x07, 
+-      0xd5, 0x05, 0x21, 0x00, 0x20, 0x13, 0xf0, 0x00, 
+-      0xff, 0xe5, 0x49, 0x03, 0x60, 0x08, 0x1c, 0x38, 
+-      0xb0, 0x02, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x20, 0xb0, 0xb5, 0x80, 0xb0, 0x81, 
+-      0x90, 0x00, 0x46, 0x69, 0x20, 0x0b, 0xf0, 0x00, 
+-      0xff, 0xd5, 0x1c, 0x07, 0xd5, 0x05, 0x21, 0x00, 
+-      0x20, 0x13, 0xf0, 0x00, 0xff, 0xcf, 0x49, 0x03, 
+-      0x60, 0x08, 0x1c, 0x38, 0xb0, 0x01, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x20, 0xb0, 
+-      0xb5, 0x00, 0xb0, 0x81, 0x90, 0x00, 0x46, 0x69, 
+-      0x20, 0x0c, 0xf0, 0x00, 0xff, 0xbf, 0xb0, 0x01, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0x00, 0xb0, 0x83, 
+-      0x90, 0x00, 0x91, 0x01, 0x92, 0x02, 0x46, 0x69, 
+-      0x20, 0x0d, 0xf0, 0x00, 0xff, 0xb3, 0xb0, 0x03, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0x01, 0x46, 0x69, 
+-      0x20, 0x03, 0xf0, 0x00, 0xff, 0xab, 0xb0, 0x01, 
+-      0xbc, 0x08, 0x47, 0x18, 0xb5, 0x80, 0xb0, 0x82, 
+-      0x90, 0x00, 0xf7, 0xfd, 0xfa, 0x5b, 0x90, 0x01, 
+-      0x46, 0x69, 0x20, 0x12, 0xf0, 0x00, 0xff, 0x9e, 
+-      0x1c, 0x07, 0xd0, 0x05, 0x21, 0x00, 0x20, 0x13, 
+-      0xf0, 0x00, 0xff, 0x98, 0x49, 0x03, 0x60, 0x08, 
+-      0x1c, 0x38, 0xb0, 0x02, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x20, 0xb0, 
+-      0xb5, 0x80, 0xb0, 0x82, 0x90, 0x00, 0xf7, 0xfd, 
+-      0xfa, 0x41, 0x90, 0x01, 0x46, 0x69, 0x20, 0x0e, 
+-      0xf0, 0x00, 0xff, 0x84, 0x1c, 0x07, 0xd0, 0x05, 
+-      0x21, 0x00, 0x20, 0x13, 0xf0, 0x00, 0xff, 0x7e, 
+-      0x49, 0x03, 0x60, 0x08, 0x1c, 0x38, 0xb0, 0x02, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x20, 0xb0, 0xb5, 0x80, 0xb0, 0x84, 
+-      0x90, 0x00, 0x1c, 0x0f, 0xf7, 0xfd, 0xfa, 0x26, 
+-      0x90, 0x01, 0x97, 0x02, 0x1c, 0x38, 0xf7, 0xfd, 
+-      0xfa, 0x21, 0x90, 0x03, 0x46, 0x69, 0x20, 0x0f, 
+-      0xf0, 0x00, 0xff, 0x64, 0x1c, 0x07, 0xd0, 0x05, 
+-      0x21, 0x00, 0x20, 0x13, 0xf0, 0x00, 0xff, 0x5e, 
+-      0x49, 0x03, 0x60, 0x08, 0x1c, 0x38, 0xb0, 0x04, 
+-      0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x20, 0xb0, 0xb5, 0x80, 0xb0, 0x82, 
+-      0x4f, 0x08, 0x97, 0x00, 0x20, 0xff, 0x30, 0x01, 
+-      0x90, 0x01, 0x46, 0x69, 0x20, 0x15, 0xf0, 0x00, 
+-      0xff, 0x49, 0x28, 0x00, 0xd0, 0x01, 0x20, 0x00, 
+-      0xe0, 0x00, 0x1c, 0x38, 0xb0, 0x02, 0xbc, 0x80, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x94, 0xdc, 
+-      0xb5, 0x00, 0x21, 0x00, 0x20, 0x10, 0xf0, 0x00, 
+-      0xff, 0x39, 0x49, 0x02, 0x68, 0x09, 0x1a, 0x40, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x21, 0xa4, 
+-      0xb5, 0x00, 0x21, 0x00, 0x20, 0x10, 0xf0, 0x00, 
+-      0xff, 0x2d, 0x49, 0x02, 0x60, 0x08, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x21, 0xa4, 
+-      0xb5, 0x80, 0x21, 0x00, 0x1c, 0x07, 0x20, 0x11, 
+-      0xf0, 0x00, 0xff, 0x20, 0x2f, 0x00, 0xd0, 0x00, 
+-      0x60, 0x38, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x20, 0x00, 0x47, 0x70, 0xb4, 0x80, 0x20, 0x03, 
+-      0x43, 0xc0, 0x23, 0x00, 0x49, 0x07, 0x54, 0x0b, 
+-      0x30, 0x01, 0xd4, 0xfc, 0x20, 0x00, 0x4a, 0x06, 
+-      0x5c, 0x17, 0x54, 0x0f, 0x18, 0x0f, 0x37, 0x80, 
+-      0x70, 0x3b, 0x30, 0x01, 0x28, 0x80, 0xd3, 0xf7, 
+-      0xbc, 0x80, 0x47, 0x70, 0x2e, 0x08, 0x21, 0xac, 
+-      0x2e, 0x03, 0x3b, 0x58, 0xb5, 0x80, 0x49, 0x07, 
+-      0x68, 0x09, 0xf7, 0xfd, 0xf9, 0x13, 0x1c, 0x07, 
+-      0xd1, 0x03, 0xa1, 0x05, 0xa0, 0x05, 0xf0, 0x00, 
+-      0xfc, 0xe7, 0x1c, 0x38, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x20, 0xa8, 
+-      0x00, 0x00, 0x00, 0x00, 0x4e, 0x6f, 0x20, 0x73, 
+-      0x74, 0x6f, 0x72, 0x65, 0x20, 0x6c, 0x65, 0x66, 
+-      0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x49, 0x2f, 
+-      0x4f, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 
+-      0x20, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 
+-      0x6c, 0x69, 0x6b, 0x65, 0x00, 0x00, 0x00, 0x00, 
+-      0x23, 0x80, 0x68, 0xc1, 0x43, 0x19, 0x60, 0xc1, 
+-      0x21, 0x00, 0x60, 0x01, 0x60, 0x81, 0x47, 0x70, 
+-      0xb5, 0xf7, 0x68, 0xd5, 0x69, 0x56, 0x1c, 0x0c, 
+-      0x1c, 0x17, 0x0d, 0x68, 0xd3, 0x05, 0x23, 0x10, 
+-      0x43, 0x1d, 0x1c, 0x30, 0xf7, 0xff, 0xfe, 0xfc, 
+-      0x61, 0xb8, 0x48, 0x12, 0x40, 0x28, 0xd0, 0x08, 
+-      0x69, 0xb9, 0x1c, 0x30, 0xf7, 0xff, 0xfe, 0xc7, 
+-      0x28, 0x00, 0xdb, 0x10, 0x4b, 0x0e, 0x40, 0x1d, 
+-      0x60, 0xfd, 0x99, 0x00, 0x1c, 0x30, 0x1c, 0x22, 
+-      0x1c, 0x2b, 0xf7, 0xff, 0xfe, 0x75, 0x00, 0x41, 
+-      0x08, 0x49, 0x1a, 0x61, 0x69, 0xba, 0x18, 0x51, 
+-      0x61, 0xb9, 0x28, 0x00, 0xd0, 0x08, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xff, 0xce, 0x20, 0x00, 0x43, 0xc0, 
+-      0xb0, 0x03, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x20, 0x00, 0xe7, 0xf9, 0x00, 0x02, 0x00, 0x10, 
+-      0xff, 0xfd, 0xff, 0xef, 0xb5, 0xb0, 0x48, 0x15, 
+-      0x68, 0xc1, 0x4b, 0x15, 0x40, 0x19, 0x1c, 0x1d, 
+-      0x42, 0x99, 0xd1, 0x01, 0xf0, 0x00, 0xfc, 0xd6, 
+-      0x48, 0x12, 0x68, 0xc1, 0x4b, 0x10, 0x40, 0x19, 
+-      0x42, 0xa9, 0xd1, 0x01, 0xf0, 0x00, 0xfc, 0xce, 
+-      0x48, 0x0f, 0x68, 0xc1, 0x4b, 0x0c, 0x40, 0x19, 
+-      0x42, 0xa9, 0xd1, 0x01, 0xf0, 0x00, 0xfc, 0xc6, 
+-      0x27, 0x00, 0x4c, 0x0c, 0x01, 0xb8, 0x19, 0x00, 
+-      0x68, 0xc1, 0x4b, 0x07, 0x40, 0x19, 0x42, 0xa9, 
+-      0xd1, 0x01, 0xf0, 0x00, 0xfc, 0xbb, 0x37, 0x01, 
+-      0x2f, 0x0d, 0xdb, 0xf3, 0xbc, 0xb0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x95, 0xdc, 
+-      0x00, 0x00, 0x02, 0x02, 0x2e, 0x08, 0x96, 0x1c, 
+-      0x2e, 0x08, 0x96, 0x5c, 0x2e, 0x08, 0x96, 0x9c, 
+-      0xb5, 0xf0, 0x1c, 0x07, 0x69, 0x04, 0x6a, 0xc0, 
+-      0x68, 0x79, 0x42, 0x88, 0xd9, 0x00, 0x1c, 0x01, 
+-      0x68, 0xf8, 0x4b, 0x13, 0x40, 0x18, 0x07, 0x82, 
+-      0x0f, 0x92, 0x25, 0x00, 0x60, 0xf8, 0x2a, 0x01, 
+-      0xd0, 0x1a, 0x22, 0x82, 0x40, 0x02, 0x15, 0x1e, 
+-      0x2a, 0x02, 0xd1, 0x0a, 0x0c, 0x40, 0xd3, 0x13, 
+-      0x42, 0xa1, 0xd0, 0x0a, 0x1b, 0x09, 0x1c, 0x20, 
+-      0x1c, 0x3a, 0xf7, 0xff, 0xff, 0x75, 0x28, 0x00, 
+-      0xd0, 0x03, 0x1c, 0x30, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x62, 0xfc, 0x60, 0x7c, 0x60, 0xbd, 
+-      0x68, 0xf8, 0x4b, 0x04, 0x40, 0x18, 0x60, 0xf8, 
+-      0x1c, 0x28, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0xff, 0xf7, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 
+-      0xb5, 0x80, 0x1c, 0x07, 0x68, 0xc0, 0x23, 0x20, 
+-      0x43, 0xdb, 0x40, 0x18, 0x60, 0xf8, 0x69, 0xb8, 
+-      0x6a, 0xb9, 0x42, 0x88, 0xd0, 0x0d, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xff, 0xbe, 0x68, 0xf8, 0x4b, 0x08, 
+-      0x40, 0x18, 0x23, 0x10, 0x43, 0x18, 0x60, 0xf8, 
+-      0x6a, 0xb8, 0x61, 0xb8, 0x69, 0x38, 0x62, 0xf8, 
+-      0x60, 0x78, 0x68, 0xf8, 0x4b, 0x03, 0x40, 0x18, 
+-      0x60, 0xf8, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xbf, 0xbf, 
+-      0xb5, 0xf0, 0x1c, 0x07, 0x69, 0x40, 0xb0, 0x83, 
+-      0x90, 0x01, 0x69, 0x38, 0x90, 0x00, 0x25, 0x00, 
+-      0x68, 0xfe, 0x07, 0xb0, 0xd1, 0x01, 0x43, 0xc0, 
+-      0xe0, 0x48, 0x09, 0x30, 0xd2, 0x40, 0x24, 0x10, 
+-      0x1c, 0x38, 0xf0, 0x00, 0xfc, 0x3f, 0x1c, 0x05, 
+-      0x0d, 0x70, 0xd3, 0x1b, 0x24, 0x00, 0x49, 0x21, 
+-      0x91, 0x02, 0x01, 0xa0, 0x99, 0x02, 0x18, 0x40, 
+-      0x42, 0xb8, 0xd0, 0x10, 0x68, 0xc1, 0x07, 0x8a, 
+-      0xd0, 0x0d, 0x69, 0x42, 0x9b, 0x01, 0x42, 0x9a, 
+-      0xd1, 0x09, 0x0d, 0x49, 0xd3, 0x07, 0x68, 0xc1, 
+-      0x4b, 0x19, 0x40, 0x19, 0x60, 0xc1, 0x68, 0xf8, 
+-      0x40, 0x18, 0x60, 0xf8, 0xe0, 0x02, 0x34, 0x01, 
+-      0x2c, 0x10, 0xdb, 0xe6, 0x2c, 0x10, 0xd1, 0x06, 
+-      0x98, 0x01, 0xf7, 0xff, 0xfd, 0x83, 0x28, 0x00, 
+-      0xda, 0x01, 0x25, 0x00, 0x43, 0xed, 0x0b, 0x30, 
+-      0xd3, 0x04, 0x98, 0x00, 0x49, 0x0f, 0x68, 0x09, 
+-      0xf7, 0xfc, 0xff, 0xe0, 0x0d, 0xf0, 0x05, 0xc0, 
+-      0x23, 0xa5, 0x05, 0xdb, 0x42, 0xd8, 0xd1, 0x07, 
+-      0x48, 0x0b, 0x28, 0x00, 0xd0, 0x04, 0x1c, 0x38, 
+-      0x1c, 0x29, 0xf7, 0xff, 0xff, 0xfe, 0x1c, 0x05, 
+-      0x22, 0x40, 0x21, 0x00, 0x1c, 0x38, 0xf7, 0xfd, 
+-      0xf8, 0x8f, 0x1c, 0x28, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x95, 0xdc, 
+-      0xff, 0xef, 0xff, 0xff, 0x2e, 0x08, 0x20, 0xac, 
+-      0x00, 0x00, 0x00, 0x00, 0xb5, 0xf7, 0x1c, 0x10, 
+-      0x1c, 0x0c, 0x1c, 0x17, 0xf7, 0xff, 0xff, 0x98, 
+-      0x78, 0x20, 0x34, 0x01, 0x28, 0x61, 0xd0, 0x09, 
+-      0x28, 0x72, 0xd0, 0x04, 0x28, 0x77, 0xd1, 0x25, 
+-      0x26, 0x02, 0x25, 0x04, 0xe0, 0x04, 0x26, 0x01, 
+-      0x25, 0x00, 0xe0, 0x01, 0x4e, 0x1a, 0x25, 0x08, 
+-      0x78, 0x20, 0x34, 0x01, 0x28, 0x2b, 0xd0, 0x06, 
+-      0x28, 0x62, 0xd1, 0x09, 0x23, 0x04, 0x43, 0x1e, 
+-      0x23, 0x01, 0x43, 0x1d, 0xe7, 0xf4, 0x23, 0x03, 
+-      0x43, 0x1e, 0x23, 0x02, 0x43, 0x1d, 0xe7, 0xef, 
+-      0x1f, 0xe0, 0x38, 0x19, 0x7f, 0xc0, 0x28, 0x74, 
+-      0xd1, 0x01, 0x23, 0x10, 0x43, 0x1d, 0x98, 0x00, 
+-      0x1c, 0x29, 0xf7, 0xff, 0xfd, 0x0b, 0x23, 0x01, 
+-      0x42, 0xd8, 0xd1, 0x04, 0x20, 0x00, 0xb0, 0x03, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x21, 0x00, 
+-      0x60, 0x79, 0x61, 0x39, 0x21, 0x01, 0x03, 0x09, 
+-      0x61, 0x78, 0x61, 0xf9, 0x60, 0xfe, 0x09, 0x28, 
+-      0xd3, 0x04, 0x22, 0x02, 0x21, 0x00, 0x1c, 0x38, 
+-      0xf0, 0x00, 0xfb, 0xc4, 0x1c, 0x38, 0xe7, 0xea, 
+-      0x00, 0x00, 0x80, 0x02, 0xb5, 0x90, 0x23, 0x03, 
+-      0x4f, 0x08, 0x01, 0x9a, 0x19, 0xd2, 0x68, 0xd4, 
+-      0x07, 0xa4, 0xd1, 0x04, 0xf7, 0xff, 0xff, 0xaa, 
+-      0xbc, 0x90, 0xbc, 0x08, 0x47, 0x18, 0x33, 0x01, 
+-      0x2b, 0x10, 0xdb, 0xf2, 0x20, 0x00, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x95, 0xdc, 
+-      0xb5, 0xf0, 0x1c, 0x04, 0x1c, 0x0f, 0x4d, 0x10, 
+-      0x68, 0xe8, 0x08, 0x80, 0xd3, 0x18, 0x20, 0x01, 
+-      0x4e, 0x0e, 0x70, 0x30, 0x40, 0x38, 0xd0, 0x03, 
+-      0x20, 0x0a, 0x1c, 0x29, 0xf0, 0x00, 0xfc, 0x1e, 
+-      0x1c, 0x20, 0x1c, 0x29, 0xf0, 0x00, 0xfc, 0x2c, 
+-      0x08, 0xb8, 0xd3, 0x03, 0x20, 0x0a, 0x1c, 0x29, 
+-      0xf0, 0x00, 0xfc, 0x14, 0x20, 0x00, 0x70, 0x30, 
+-      0x20, 0x01, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x20, 0x00, 0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x96, 0x5c, 0x2e, 0x08, 0x21, 0x94, 
+-      0xb5, 0x80, 0x1c, 0x07, 0xa0, 0x06, 0x21, 0x01, 
+-      0xf7, 0xff, 0xfc, 0x80, 0x21, 0x02, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfc, 0x7c, 0x20, 0x01, 0xf7, 0xfd, 
+-      0xfc, 0x25, 0xbc, 0x80, 0xbc, 0x08, 0x47, 0x18, 
+-      0x43, 0x6f, 0x75, 0x6c, 0x64, 0x6e, 0x27, 0x74, 
+-      0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x00, 
+-      0xb5, 0xf0, 0x1c, 0x04, 0x1c, 0x15, 0x1c, 0x0f, 
+-      0x48, 0x20, 0x22, 0x01, 0x02, 0x92, 0x21, 0x00, 
+-      0x1c, 0x06, 0xf7, 0xfc, 0xff, 0xd5, 0x4a, 0x1e, 
+-      0x1c, 0x28, 0xa1, 0x1e, 0xf7, 0xff, 0xff, 0x4e, 
+-      0x28, 0x00, 0xd1, 0x02, 0x1c, 0x28, 0xf7, 0xff, 
+-      0xff, 0xd3, 0x1c, 0x20, 0x1c, 0x32, 0xa1, 0x1a, 
+-      0xf7, 0xff, 0xff, 0x44, 0x28, 0x00, 0xd1, 0x02, 
+-      0x1c, 0x20, 0xf7, 0xff, 0xff, 0xc9, 0x4a, 0x17, 
+-      0x1c, 0x38, 0x1c, 0x15, 0xa1, 0x13, 0xf7, 0xff, 
+-      0xff, 0x39, 0x28, 0x00, 0xd1, 0x02, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xff, 0xbe, 0x1c, 0x30, 0x26, 0x01, 
+-      0x03, 0x36, 0x08, 0xf2, 0x21, 0x00, 0x1c, 0x33, 
+-      0xf0, 0x00, 0xf8, 0x52, 0x28, 0x00, 0xd0, 0x02, 
+-      0x1c, 0x20, 0xf7, 0xff, 0xff, 0xb1, 0x22, 0x01, 
+-      0x02, 0x52, 0x21, 0x00, 0x1c, 0x28, 0x1c, 0x33, 
+-      0xf0, 0x00, 0xf8, 0x46, 0x28, 0x00, 0xd0, 0x02, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xff, 0xa5, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x95, 0xdc, 
+-      0x2e, 0x08, 0x96, 0x5c, 0x77, 0x00, 0x00, 0x00, 
+-      0x72, 0x00, 0x00, 0x00, 0x2e, 0x08, 0x96, 0x1c, 
+-      0xb5, 0x90, 0x27, 0x03, 0x4c, 0x09, 0x01, 0xb8, 
+-      0x19, 0x00, 0xf7, 0xff, 0xfe, 0xa5, 0x37, 0x01, 
+-      0x2f, 0x10, 0xdb, 0xf8, 0x27, 0x00, 0x01, 0xb8, 
+-      0x19, 0x00, 0xf7, 0xff, 0xfe, 0x9d, 0x37, 0x01, 
+-      0x2f, 0x03, 0xdb, 0xf8, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x95, 0xdc, 
+-      0xb5, 0xb0, 0x01, 0x80, 0x1c, 0x0f, 0x4c, 0x0a, 
+-      0x19, 0x00, 0x1c, 0x05, 0xf7, 0xff, 0xfe, 0x8c, 
+-      0x01, 0xb8, 0x19, 0x00, 0x23, 0x01, 0x05, 0x1b, 
+-      0x68, 0xc1, 0x43, 0x19, 0x60, 0xc1, 0x4b, 0x05, 
+-      0x40, 0x19, 0x60, 0xe9, 0x69, 0x40, 0x61, 0x68, 
+-      0x1c, 0x38, 0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 
+-      0x2e, 0x08, 0x95, 0xdc, 0x00, 0x10, 0x8f, 0x03, 
+-      0xb4, 0xf0, 0x1c, 0x1f, 0x68, 0xc3, 0x07, 0x9e, 
+-      0x0f, 0xb6, 0x25, 0x01, 0x1c, 0x1c, 0x2e, 0x00, 
+-      0xd0, 0x13, 0x1c, 0x1e, 0x0d, 0xf3, 0xd2, 0x10, 
+-      0x02, 0x2b, 0x42, 0x9a, 0xd0, 0x09, 0x00, 0x5b, 
+-      0x42, 0x9a, 0xd0, 0x06, 0x00, 0x5b, 0x42, 0x9a, 
+-      0xd1, 0x07, 0x27, 0x01, 0x1d, 0xc1, 0x31, 0x1d, 
+-      0xe0, 0x06, 0x1e, 0x7e, 0x4b, 0x08, 0x42, 0x9e, 
+-      0xd3, 0x02, 0x1c, 0x28, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x61, 0x01, 0x23, 0x0f, 0x02, 0x1b, 0x43, 0x9c, 
+-      0x60, 0x41, 0x61, 0xc7, 0x1c, 0x21, 0x43, 0x11, 
+-      0x60, 0xc1, 0x20, 0x00, 0xbc, 0xf0, 0x47, 0x70, 
+-      0x00, 0xff, 0xff, 0xff, 0xe2, 0x00, 0x01, 0x02, 
+-      0xe3, 0x31, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x17, 
+-      0xe3, 0xa0, 0x80, 0x00, 0xe1, 0xb0, 0x98, 0x21, 
+-      0x01, 0xa0, 0x18, 0x01, 0x02, 0x88, 0x80, 0x10, 
+-      0xe1, 0xb0, 0x9c, 0x21, 0x01, 0xa0, 0x14, 0x01, 
+-      0x02, 0x88, 0x80, 0x08, 0xe1, 0xb0, 0x9e, 0x21, 
+-      0x01, 0xa0, 0x12, 0x01, 0x02, 0x88, 0x80, 0x04, 
+-      0xe1, 0xb0, 0x9f, 0x21, 0x01, 0xa0, 0x11, 0x01, 
+-      0x02, 0x88, 0x80, 0x02, 0xe1, 0xb0, 0x9f, 0xa1, 
+-      0x01, 0xa0, 0x10, 0x81, 0x02, 0x88, 0x80, 0x01, 
+-      0xe0, 0x58, 0x98, 0xa6, 0x81, 0xa0, 0x19, 0x31, 
+-      0x81, 0xa0, 0x88, 0xa6, 0xe2, 0x68, 0x60, 0x20, 
+-      0xe1, 0x81, 0x16, 0x32, 0xe1, 0xa0, 0x28, 0x12, 
+-      0x30, 0x40, 0x00, 0x09, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0xe3, 0x56, 0x05, 0x01, 0x3a, 0x00, 0x00, 0x16, 
+-      0xe1, 0xb0, 0x10, 0x02, 0x01, 0xa0, 0xf0, 0x0e, 
+-      0xe3, 0xa0, 0x20, 0x00, 0xe3, 0xa0, 0x80, 0x20, 
+-      0xe1, 0xb0, 0x98, 0x21, 0x01, 0xa0, 0x18, 0x01, 
+-      0x02, 0x88, 0x80, 0x10, 0xe1, 0xb0, 0x9c, 0x21, 
+-      0x01, 0xa0, 0x14, 0x01, 0x02, 0x88, 0x80, 0x08, 
+-      0xe1, 0xb0, 0x9e, 0x21, 0x01, 0xa0, 0x12, 0x01, 
+-      0x02, 0x88, 0x80, 0x04, 0xe1, 0xb0, 0x9f, 0x21, 
+-      0x01, 0xa0, 0x11, 0x01, 0x02, 0x88, 0x80, 0x02, 
+-      0xe1, 0xb0, 0x9f, 0xa1, 0x01, 0xa0, 0x10, 0x81, 
+-      0x02, 0x88, 0x80, 0x01, 0xe0, 0x58, 0x98, 0xa6, 
+-      0x81, 0xa0, 0x19, 0x31, 0x30, 0x40, 0x00, 0x09, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe1, 0xa0, 0x88, 0xa6, 
+-      0xe2, 0x68, 0x90, 0x20, 0xe1, 0xa0, 0x18, 0x11, 
+-      0xe1, 0x81, 0x19, 0x32, 0xe1, 0xa0, 0x28, 0x12, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe2, 0x03, 0x31, 0x02, 
+-      0xe3, 0x34, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x17, 
+-      0xe3, 0xa0, 0x80, 0x00, 0xe1, 0xb0, 0x98, 0x24, 
+-      0x01, 0xa0, 0x48, 0x04, 0x02, 0x88, 0x80, 0x10, 
+-      0xe1, 0xb0, 0x9c, 0x24, 0x01, 0xa0, 0x44, 0x04, 
+-      0x02, 0x88, 0x80, 0x08, 0xe1, 0xb0, 0x9e, 0x24, 
+-      0x01, 0xa0, 0x42, 0x04, 0x02, 0x88, 0x80, 0x04, 
+-      0xe1, 0xb0, 0x9f, 0x24, 0x01, 0xa0, 0x41, 0x04, 
+-      0x02, 0x88, 0x80, 0x02, 0xe1, 0xb0, 0x9f, 0xa4, 
+-      0x01, 0xa0, 0x40, 0x84, 0x02, 0x88, 0x80, 0x01, 
+-      0xe0, 0x58, 0x98, 0xa6, 0x81, 0xa0, 0x49, 0x34, 
+-      0x81, 0xa0, 0x88, 0xa6, 0xe2, 0x68, 0x60, 0x20, 
+-      0xe1, 0x84, 0x46, 0x35, 0xe1, 0xa0, 0x58, 0x15, 
+-      0x30, 0x43, 0x30, 0x09, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0xe3, 0x56, 0x05, 0x01, 0x3a, 0x00, 0x00, 0x16, 
+-      0xe1, 0xb0, 0x40, 0x05, 0x01, 0xa0, 0xf0, 0x0e, 
+-      0xe3, 0xa0, 0x50, 0x00, 0xe3, 0xa0, 0x80, 0x20, 
+-      0xe1, 0xb0, 0x98, 0x24, 0x01, 0xa0, 0x48, 0x04, 
+-      0x02, 0x88, 0x80, 0x10, 0xe1, 0xb0, 0x9c, 0x24, 
+-      0x01, 0xa0, 0x44, 0x04, 0x02, 0x88, 0x80, 0x08, 
+-      0xe1, 0xb0, 0x9e, 0x24, 0x01, 0xa0, 0x42, 0x04, 
+-      0x02, 0x88, 0x80, 0x04, 0xe1, 0xb0, 0x9f, 0x24, 
+-      0x01, 0xa0, 0x41, 0x04, 0x02, 0x88, 0x80, 0x02, 
+-      0xe1, 0xb0, 0x9f, 0xa4, 0x01, 0xa0, 0x40, 0x84, 
+-      0x02, 0x88, 0x80, 0x01, 0xe0, 0x58, 0x98, 0xa6, 
+-      0x81, 0xa0, 0x49, 0x34, 0x30, 0x43, 0x30, 0x09, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe1, 0xa0, 0x88, 0xa6, 
+-      0xe2, 0x68, 0x90, 0x20, 0xe1, 0xa0, 0x48, 0x14, 
+-      0xe1, 0x84, 0x49, 0x35, 0xe1, 0xa0, 0x58, 0x15, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe3, 0xa0, 0x20, 0x00, 
+-      0xe2, 0x16, 0x01, 0x02, 0x12, 0x66, 0x10, 0x00, 
+-      0x01, 0xb0, 0x10, 0x06, 0x03, 0xa0, 0x30, 0x00, 
+-      0x01, 0xa0, 0xf0, 0x0e, 0xe3, 0xa0, 0x39, 0x01, 
+-      0xe3, 0x83, 0x30, 0x1e, 0xe3, 0xa0, 0x60, 0x00, 
+-      0xe3, 0x31, 0x00, 0x00, 0x01, 0xa0, 0x10, 0x02, 
+-      0x03, 0xa0, 0x20, 0x00, 0x02, 0x43, 0x30, 0x20, 
+-      0xe3, 0xa0, 0x80, 0x00, 0xe1, 0xb0, 0x98, 0x21, 
+-      0x01, 0xa0, 0x18, 0x01, 0x02, 0x88, 0x80, 0x10, 
+-      0xe1, 0xb0, 0x9c, 0x21, 0x01, 0xa0, 0x14, 0x01, 
+-      0x02, 0x88, 0x80, 0x08, 0xe1, 0xb0, 0x9e, 0x21, 
+-      0x01, 0xa0, 0x12, 0x01, 0x02, 0x88, 0x80, 0x04, 
+-      0xe1, 0xb0, 0x9f, 0x21, 0x01, 0xa0, 0x11, 0x01, 
+-      0x02, 0x88, 0x80, 0x02, 0xe1, 0xb0, 0x9f, 0xa1, 
+-      0x01, 0xa0, 0x10, 0x81, 0x02, 0x88, 0x80, 0x01, 
+-      0xe2, 0x78, 0x90, 0x20, 0xe1, 0x81, 0x19, 0x32, 
+-      0xe1, 0xa0, 0x28, 0x12, 0xe0, 0x43, 0x30, 0x08, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe3, 0x34, 0x00, 0x00, 
+-      0x01, 0xa0, 0x40, 0x05, 0x03, 0xa0, 0x50, 0x00, 
+-      0x02, 0x43, 0x30, 0x20, 0xe3, 0xa0, 0x80, 0x00, 
+-      0xe1, 0xb0, 0x98, 0x24, 0x01, 0xa0, 0x48, 0x04, 
+-      0x02, 0x88, 0x80, 0x10, 0xe1, 0xb0, 0x9c, 0x24, 
+-      0x01, 0xa0, 0x44, 0x04, 0x02, 0x88, 0x80, 0x08, 
+-      0xe1, 0xb0, 0x9e, 0x24, 0x01, 0xa0, 0x42, 0x04, 
+-      0x02, 0x88, 0x80, 0x04, 0xe1, 0xb0, 0x9f, 0x24, 
+-      0x01, 0xa0, 0x41, 0x04, 0x02, 0x88, 0x80, 0x02, 
+-      0xe1, 0xb0, 0x9f, 0xa4, 0x01, 0xa0, 0x40, 0x84, 
+-      0x02, 0x88, 0x80, 0x01, 0xe2, 0x78, 0x90, 0x20, 
+-      0xe1, 0x84, 0x49, 0x35, 0xe1, 0xa0, 0x58, 0x15, 
+-      0xe0, 0x43, 0x30, 0x08, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0xe3, 0x31, 0x00, 0x00, 0x01, 0xa0, 0x10, 0x02, 
+-      0x03, 0xa0, 0x20, 0x00, 0x02, 0x83, 0x30, 0x20, 
+-      0xe3, 0xa0, 0x80, 0x00, 0xe1, 0xb0, 0x98, 0x21, 
+-      0x01, 0xa0, 0x18, 0x01, 0x02, 0x88, 0x80, 0x10, 
+-      0xe1, 0xb0, 0x9c, 0x21, 0x01, 0xa0, 0x14, 0x01, 
+-      0x02, 0x88, 0x80, 0x08, 0xe1, 0xb0, 0x9e, 0x21, 
+-      0x01, 0xa0, 0x12, 0x01, 0x02, 0x88, 0x80, 0x04, 
+-      0xe1, 0xb0, 0x9f, 0x21, 0x01, 0xa0, 0x11, 0x01, 
+-      0x02, 0x88, 0x80, 0x02, 0xe1, 0xb0, 0x9f, 0xa1, 
+-      0x01, 0xa0, 0x10, 0x81, 0x02, 0x88, 0x80, 0x01, 
+-      0xe2, 0x78, 0x90, 0x20, 0xe1, 0x81, 0x19, 0x32, 
+-      0xe1, 0xa0, 0x28, 0x12, 0xe0, 0x83, 0x30, 0x08, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x40, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xe1, 0x92, 0x80, 0x81, 
+-      0x0a, 0x00, 0x00, 0x05, 0xe3, 0x11, 0x01, 0x01, 
+-      0x0a, 0x00, 0x00, 0x0c, 0xe1, 0x95, 0x80, 0x84, 
+-      0x0a, 0x00, 0x00, 0x0a, 0xe3, 0x14, 0x01, 0x01, 
+-      0x1a, 0x00, 0x00, 0x08, 0xe3, 0x14, 0x01, 0x01, 
+-      0x0a, 0x00, 0x00, 0x28, 0xe1, 0xa0, 0x00, 0x03, 
+-      0xe1, 0xa0, 0x10, 0x04, 0xe1, 0xa0, 0x20, 0x05, 
+-      0xea, 0x00, 0x00, 0x04, 0xe3, 0x11, 0x01, 0x01, 
+-      0x0a, 0x00, 0x00, 0x22, 0xea, 0x00, 0x00, 0x01, 
+-      0xe3, 0x11, 0x01, 0x01, 0x0a, 0x00, 0x00, 0x1f, 
+-      0xe3, 0x1b, 0x00, 0x01, 0x1a, 0x00, 0x00, 0x16, 
+-      0xe3, 0x1b, 0x00, 0x02, 0x1a, 0x00, 0x00, 0x0c, 
+-      0xe3, 0x1b, 0x0c, 0x02, 0x1a, 0x00, 0x00, 0x05, 
+-      0xe3, 0xc0, 0x81, 0x03, 0xe3, 0xa0, 0x90, 0xff, 
+-      0xe3, 0x89, 0x9c, 0x43, 0xe1, 0x58, 0x00, 0x09, 
+-      0x33, 0xc2, 0x20, 0x01, 0x03, 0x82, 0x20, 0x01, 
+-      0xe2, 0x00, 0x01, 0x03, 0xe3, 0x80, 0x00, 0xff, 
+-      0xe3, 0x80, 0x0c, 0x7f, 0xe1, 0x30, 0x00, 0x00, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe2, 0x00, 0x01, 0x03, 
+-      0xe3, 0x80, 0x00, 0xff, 0xe3, 0x80, 0x0c, 0x43, 
+-      0xe1, 0xa0, 0x25, 0xa2, 0xe1, 0xa0, 0x25, 0x82, 
+-      0xe3, 0x81, 0x11, 0x02, 0xe1, 0x30, 0x00, 0x00, 
+-      0xe1, 0xa0, 0xf0, 0x0e, 0xe2, 0x00, 0x01, 0x03, 
+-      0xe3, 0x80, 0x00, 0x7f, 0xe3, 0x80, 0x09, 0x01, 
+-      0xe3, 0xa0, 0x20, 0x00, 0xe3, 0xc1, 0x10, 0xff, 
+-      0xe3, 0x81, 0x11, 0x02, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0xe3, 0x80, 0x04, 0x61, 0xe1, 0xa0, 0xf0, 0x0e, 
+-      0xb5, 0x80, 0x1c, 0x0f, 0x29, 0x0f, 0xdd, 0x04, 
+-      0x11, 0x39, 0xf7, 0xff, 0xff, 0xf9, 0x07, 0x3f, 
+-      0x0f, 0x3f, 0x2f, 0x09, 0xdd, 0x02, 0x1d, 0xf9, 
+-      0x31, 0x29, 0xe0, 0x01, 0x1d, 0xf9, 0x31, 0x50, 
+-      0x70, 0x01, 0x30, 0x01, 0xbc, 0x80, 0xbc, 0x08, 
+-      0x47, 0x18, 0xb5, 0x90, 0x1c, 0x07, 0x48, 0x0d, 
+-      0x68, 0x01, 0x29, 0x00, 0xd1, 0x12, 0x4c, 0x0c, 
+-      0x1c, 0x20, 0xa1, 0x0c, 0x22, 0x14, 0xf7, 0xfc, 
+-      0xfc, 0xa1, 0x1d, 0xe0, 0x30, 0x0b, 0x1c, 0x39, 
+-      0xf7, 0xff, 0xff, 0xda, 0x21, 0x29, 0x70, 0x01, 
+-      0x21, 0x00, 0x70, 0x41, 0x1c, 0x20, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x30, 0x08, 0xbc, 0x90, 
+-      0xbc, 0x08, 0x47, 0x18, 0x2e, 0x08, 0x20, 0xcc, 
+-      0x2e, 0x08, 0x99, 0xdc, 0x55, 0x6e, 0x6b, 0x6e, 
+-      0x6f, 0x77, 0x6e, 0x20, 0x53, 0x69, 0x67, 0x6e, 
+-      0x61, 0x6c, 0x20, 0x28, 0x30, 0x78, 0x00, 0x00, 
+-      0xb5, 0x90, 0x1c, 0x04, 0x1c, 0x0f, 0xa0, 0x09, 
+-      0x21, 0x01, 0xf7, 0xff, 0xf9, 0x6f, 0x21, 0x00, 
+-      0x1c, 0x20, 0xf7, 0xff, 0xf9, 0x6b, 0x21, 0x02, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xf9, 0x67, 0x20, 0x01, 
+-      0xf7, 0xfd, 0xf9, 0x10, 0xbc, 0x90, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x2a, 0x2a, 0x2a, 0x20, 
+-      0x66, 0x61, 0x74, 0x61, 0x6c, 0x20, 0x65, 0x72, 
+-      0x72, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x72, 
+-      0x75, 0x6e, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 
+-      0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x3a, 0x20, 
+-      0x00, 0x00, 0x00, 0x00, 0xb5, 0xb0, 0x1c, 0x07, 
+-      0x68, 0xc0, 0x07, 0x81, 0xd0, 0x1f, 0x23, 0x20, 
+-      0x40, 0x18, 0xd0, 0x01, 0x6a, 0xbd, 0xe0, 0x04, 
+-      0x68, 0x79, 0x69, 0xba, 0x18, 0x89, 0x69, 0x3a, 
+-      0x1a, 0x8d, 0x28, 0x00, 0xd0, 0x02, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xfb, 0xa2, 0x68, 0xf8, 0x4b, 0x0a, 
+-      0x40, 0x18, 0x60, 0xf8, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfb, 0x67, 0x1c, 0x04, 0x22, 0x00, 0x1c, 0x38, 
+-      0x1c, 0x29, 0xf0, 0x00, 0xf8, 0x27, 0x1c, 0x20, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x20, 0x00, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0xff, 0xff, 0xcf, 0xff, 0xb5, 0xb0, 0x24, 0x00, 
+-      0x28, 0x00, 0xd0, 0x03, 0xf7, 0xff, 0xff, 0xce, 
+-      0x1c, 0x04, 0xe0, 0x0c, 0x27, 0x00, 0x4d, 0x08, 
+-      0x01, 0xb8, 0x19, 0x40, 0xf7, 0xff, 0xff, 0xc6, 
+-      0x28, 0x00, 0xd0, 0x01, 0x24, 0x00, 0x43, 0xe4, 
+-      0x37, 0x01, 0x2f, 0x10, 0xdb, 0xf4, 0x1c, 0x20, 
+-      0xbc, 0xb0, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0x2e, 0x08, 0x95, 0xdc, 0xb5, 0xf7, 0x68, 0xc5, 
+-      0x69, 0x46, 0x1c, 0x0c, 0x1c, 0x07, 0xb0, 0x81, 
+-      0x48, 0x3c, 0x40, 0x28, 0xd0, 0x04, 0x1c, 0x38, 
+-      0xf7, 0xff, 0xf9, 0x92, 0x28, 0x00, 0xd0, 0x01, 
+-      0x20, 0x02, 0xe0, 0x6a, 0x9a, 0x03, 0x2a, 0x00, 
+-      0xd0, 0x26, 0x2a, 0x01, 0xd0, 0x0b, 0x2a, 0x02, 
+-      0xd1, 0x24, 0x1c, 0x30, 0xf7, 0xff, 0xf9, 0xbc, 
+-      0x28, 0x00, 0xda, 0x09, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfa, 0xa7, 0x20, 0x01, 0xe0, 0x59, 0x1c, 0x38, 
+-      0xf0, 0x00, 0xf8, 0x8c, 0x19, 0x04, 0xe0, 0x13, 
+-      0x68, 0x79, 0x6a, 0xfa, 0x42, 0x8a, 0xd9, 0x00, 
+-      0x1c, 0x11, 0x69, 0xba, 0x18, 0x89, 0x69, 0x3a, 
+-      0x1a, 0x89, 0x68, 0xfa, 0x09, 0x92, 0xd3, 0x03, 
+-      0x6a, 0xba, 0x42, 0x8a, 0xdd, 0x00, 0x1c, 0x11, 
+-      0x42, 0x81, 0xdd, 0x00, 0x1c, 0x08, 0x18, 0x24, 
+-      0x2c, 0x00, 0xda, 0x03, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfa, 0x87, 0xe7, 0xcd, 0x0b, 0xa8, 0xd3, 0x04, 
+-      0x68, 0x78, 0x6a, 0xf9, 0x42, 0x81, 0xd2, 0x00, 
+-      0x62, 0xf8, 0x69, 0xb8, 0x42, 0xa0, 0xdc, 0x10, 
+-      0x68, 0x79, 0x6a, 0xfa, 0x42, 0x8a, 0xd9, 0x01, 
+-      0x1c, 0x13, 0xe0, 0x00, 0x1c, 0x0b, 0x18, 0x1b, 
+-      0x69, 0x3e, 0x1b, 0x9b, 0x42, 0xa3, 0xdb, 0x04, 
+-      0x6b, 0x3b, 0x93, 0x00, 0x18, 0xc3, 0x42, 0xa3, 
+-      0xdc, 0x06, 0x20, 0x20, 0x43, 0x28, 0x21, 0x00, 
+-      0x60, 0x39, 0x60, 0xb9, 0x62, 0xbc, 0xe0, 0x14, 
+-      0x1a, 0x24, 0x08, 0xa8, 0xd3, 0x03, 0x9b, 0x00, 
+-      0x1b, 0x18, 0x42, 0x40, 0x60, 0xb8, 0x08, 0x68, 
+-      0xd3, 0x06, 0x42, 0x8a, 0xd9, 0x00, 0x1c, 0x11, 
+-      0x1b, 0x88, 0x1b, 0x00, 0x42, 0x40, 0x60, 0x38, 
+-      0x19, 0x30, 0x23, 0x20, 0x43, 0x9d, 0x60, 0x78, 
+-      0x1c, 0x28, 0x4b, 0x05, 0x40, 0x18, 0x60, 0xf8, 
+-      0x20, 0x00, 0xb0, 0x01, 0xb0, 0x03, 0xbc, 0xf0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x00, 0x10, 0x00, 0x03, 
+-      0xff, 0xf7, 0xcf, 0xbf, 0xb5, 0x00, 0x68, 0x8a, 
+-      0x68, 0x4b, 0x3a, 0x01, 0xd5, 0x03, 0xf0, 0x00, 
+-      0xf8, 0x3f, 0xbc, 0x08, 0x47, 0x18, 0x06, 0x00, 
+-      0x0e, 0x00, 0x70, 0x18, 0x33, 0x01, 0x60, 0x8a, 
+-      0x60, 0x4b, 0xbc, 0x08, 0x47, 0x18, 0x00, 0x00, 
+-      0xb5, 0xb0, 0x1c, 0x07, 0x78, 0x00, 0x1c, 0x0c, 
+-      0x37, 0x01, 0x28, 0x00, 0xd0, 0x0e, 0x25, 0x00, 
+-      0x43, 0xed, 0x1c, 0x21, 0xf0, 0x00, 0xf8, 0xe8, 
+-      0x42, 0xa8, 0xd1, 0x03, 0x1c, 0x28, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x78, 0x38, 0x37, 0x01, 
+-      0x28, 0x00, 0xd1, 0xf2, 0x20, 0x00, 0xbc, 0xb0, 
+-      0xbc, 0x08, 0x47, 0x18, 0x68, 0xc1, 0x07, 0x8a, 
+-      0xd1, 0x04, 0x20, 0x01, 0x49, 0x09, 0x60, 0x08, 
+-      0x42, 0x40, 0x47, 0x70, 0x09, 0x8a, 0xd3, 0x01, 
+-      0x6a, 0x80, 0xe0, 0x04, 0x68, 0x42, 0x69, 0x83, 
+-      0x18, 0xd2, 0x69, 0x00, 0x1a, 0x10, 0x0d, 0x09, 
+-      0xd3, 0xf3, 0x28, 0x00, 0xdd, 0xf1, 0x38, 0x01, 
+-      0x47, 0x70, 0x00, 0x00, 0x2e, 0x08, 0x20, 0xb0, 
+-      0xb5, 0xf0, 0x1c, 0x04, 0x68, 0xc8, 0x1c, 0x0f, 
+-      0x4b, 0x5a, 0x40, 0x18, 0x23, 0x01, 0x05, 0x9b, 
+-      0x43, 0x18, 0x60, 0xc8, 0x09, 0x80, 0xd3, 0x02, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xfa, 0x95, 0x06, 0x26, 
+-      0x0e, 0x36, 0x68, 0xb9, 0x29, 0x00, 0xda, 0x12, 
+-      0x68, 0xf8, 0x0a, 0x82, 0xd2, 0x0f, 0x22, 0x00, 
+-      0x43, 0xd2, 0x1a, 0x51, 0x23, 0x09, 0x03, 0x5b, 
+-      0x43, 0x18, 0x60, 0xf8, 0x60, 0xb9, 0x68, 0x79, 
+-      0x70, 0x0e, 0x31, 0x01, 0x60, 0x79, 0x1c, 0x30, 
+-      0xbc, 0xf0, 0xbc, 0x08, 0x47, 0x18, 0x68, 0xf8, 
+-      0x49, 0x49, 0x40, 0x01, 0x29, 0x02, 0xd0, 0x03, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xf9, 0xcd, 0xe0, 0x7f, 
+-      0x49, 0x46, 0x40, 0x01, 0x23, 0x01, 0x03, 0xdb, 
+-      0x42, 0x99, 0xd1, 0x0b, 0x22, 0x02, 0x21, 0x00, 
+-      0x1c, 0x38, 0xf7, 0xff, 0xfe, 0xfb, 0x68, 0xf8, 
+-      0x09, 0x80, 0xd3, 0x02, 0x1c, 0x38, 0xf7, 0xff, 
+-      0xfa, 0x63, 0x68, 0xf8, 0x25, 0x09, 0x03, 0x6d, 
+-      0x43, 0x05, 0x60, 0xfd, 0x69, 0x38, 0x28, 0x00, 
+-      0xd1, 0x2f, 0x1c, 0x38, 0xf7, 0xff, 0xf8, 0x88, 
+-      0x28, 0x00, 0xd0, 0x18, 0x68, 0xf8, 0x0a, 0x00, 
+-      0x07, 0x80, 0xd0, 0x09, 0x69, 0xf8, 0xf7, 0xff, 
+-      0xf9, 0x7d, 0x61, 0x38, 0x60, 0x78, 0x23, 0x01, 
+-      0x02, 0xdb, 0x43, 0x1d, 0x68, 0xf8, 0xe0, 0x1a, 
+-      0x1d, 0xf8, 0x30, 0x1d, 0x61, 0x38, 0x60, 0x78, 
+-      0x20, 0x01, 0x23, 0x01, 0x02, 0x9b, 0x43, 0x1d, 
+-      0x61, 0xf8, 0x60, 0xfd, 0xe0, 0x11, 0x69, 0xf8, 
+-      0xf7, 0xff, 0xf9, 0x68, 0x61, 0x38, 0x60, 0x78, 
+-      0x23, 0x01, 0x02, 0xdb, 0x43, 0x1d, 0x68, 0xf8, 
+-      0x43, 0x28, 0x60, 0xf8, 0x0a, 0x29, 0x07, 0x89, 
+-      0xd1, 0x03, 0x08, 0xdb, 0x43, 0x1d, 0x43, 0x28, 
+-      0x60, 0xf8, 0x0a, 0x68, 0xd3, 0x19, 0x68, 0x78, 
+-      0x6a, 0xf9, 0x69, 0x3c, 0x42, 0x81, 0xd9, 0x00, 
+-      0x1c, 0x08, 0x1b, 0x01, 0xd0, 0x05, 0x1c, 0x20, 
+-      0x1c, 0x3a, 0xf7, 0xff, 0xf9, 0x7d, 0x28, 0x00, 
+-      0xd1, 0x26, 0x1c, 0x60, 0x62, 0xf8, 0x60, 0x78, 
+-      0x69, 0xf8, 0x1e, 0x41, 0x63, 0x38, 0x60, 0xb9, 
+-      0x70, 0x26, 0x1c, 0x30, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x69, 0x38, 0x68, 0x7a, 0x70, 0x14, 
+-      0x32, 0x01, 0x60, 0x7a, 0x6a, 0xf9, 0x42, 0x91, 
+-      0xd8, 0x00, 0x1c, 0x11, 0x1a, 0x09, 0x69, 0xfa, 
+-      0x63, 0x3a, 0x0a, 0xeb, 0xd2, 0x03, 0x2e, 0x0a, 
+-      0xd0, 0x01, 0x42, 0x8a, 0xdc, 0x0d, 0x62, 0xf8, 
+-      0x22, 0x00, 0x60, 0x78, 0x60, 0xba, 0x1c, 0x3a, 
+-      0xf7, 0xff, 0xf9, 0x56, 0x28, 0x00, 0xd0, 0x04, 
+-      0x20, 0x00, 0x43, 0xc0, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x1c, 0x30, 0xbc, 0xf0, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0xff, 0xf7, 0xff, 0xff, 
+-      0x00, 0x00, 0x10, 0x8a, 0x00, 0x00, 0xa0, 0x10, 
+-      0xb5, 0x00, 0x68, 0x8a, 0x68, 0x4b, 0x3a, 0x01, 
+-      0xd5, 0x03, 0xf7, 0xff, 0xff, 0x39, 0xbc, 0x08, 
+-      0x47, 0x18, 0x06, 0x00, 0x0e, 0x00, 0x70, 0x18, 
+-      0x33, 0x01, 0x60, 0x8a, 0x60, 0x4b, 0xbc, 0x08, 
+-      0x47, 0x18, 0x00, 0x00, 0x47, 0x78, 0x46, 0xc0, 
+-      0xe9, 0x2d, 0x40, 0x00, 0xe2, 0x8f, 0xe0, 0x00, 
+-      0xef, 0x12, 0x34, 0x56, 0xe8, 0xbd, 0x40, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe1, 0xa0, 0x10, 0x00, 
+-      0xe3, 0xa0, 0x00, 0x18, 0xe5, 0x9f, 0x10, 0x18, 
+-      0xef, 0x12, 0x34, 0x56, 0xea, 0xff, 0xff, 0xfe, 
+-      0xe1, 0xa0, 0x10, 0x00, 0xe3, 0xa0, 0x00, 0x18, 
+-      0xe5, 0x9f, 0x10, 0x08, 0xef, 0x12, 0x34, 0x56, 
+-      0xea, 0xff, 0xff, 0xfe, 0x00, 0x02, 0x00, 0x26, 
+-      0x00, 0x02, 0x00, 0x23, 0xe8, 0xb0, 0x01, 0xf0, 
+-      0xe8, 0xa1, 0x01, 0xf0, 0xe8, 0xb0, 0x01, 0xf8, 
+-      0xe8, 0xa1, 0x01, 0xf8, 0xe8, 0xb0, 0x01, 0xf8, 
+-      0xe8, 0xa1, 0x01, 0xf8, 0xe8, 0xb0, 0x01, 0xf8, 
+-      0xe8, 0xa1, 0x01, 0xf8, 0xe8, 0xb0, 0x01, 0xf8, 
+-      0xe8, 0xa1, 0x01, 0xf8, 0xe8, 0xb0, 0x01, 0xf8, 
+-      0xe8, 0xa1, 0x01, 0xf8, 0xe8, 0xb0, 0x01, 0xf8, 
+-      0xe8, 0xa1, 0x01, 0xf8, 0xe8, 0xb0, 0x01, 0xf8, 
+-      0xe8, 0xa1, 0x01, 0xf8, 0xe2, 0x52, 0x20, 0xbc, 
+-      0x1a, 0xff, 0xff, 0xed, 0xe8, 0xbd, 0x01, 0xf8, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe4, 0x90, 0x40, 0x04, 
+-      0xe1, 0x85, 0x54, 0x24, 0xe4, 0x81, 0x50, 0x04, 
+-      0xe1, 0xa0, 0x5c, 0x04, 0xe2, 0x53, 0x30, 0x04, 
+-      0x1a, 0xff, 0xff, 0xf9, 0xe5, 0x9f, 0xf0, 0x88, 
+-      0xe4, 0x90, 0x40, 0x04, 0xe1, 0x85, 0x5c, 0x24, 
+-      0xe4, 0x81, 0x50, 0x04, 0xe1, 0xa0, 0x54, 0x04, 
+-      0xe2, 0x53, 0x30, 0x04, 0x1a, 0xff, 0xff, 0xf9, 
+-      0xe5, 0x9f, 0xf0, 0x70, 0xe4, 0x90, 0x40, 0x04, 
+-      0xe1, 0xa0, 0x58, 0x24, 0xe0, 0xc1, 0x50, 0xb2, 
+-      0xe0, 0xc1, 0x40, 0xb2, 0xe2, 0x53, 0x30, 0x04, 
+-      0x1a, 0xff, 0xff, 0xf9, 0xe5, 0x9f, 0xf0, 0x4c, 
+-      0xe2, 0x03, 0x40, 0x0f, 0xe0, 0x53, 0x40, 0x04, 
+-      0x0a, 0x00, 0x00, 0x0a, 0xe9, 0x2d, 0x00, 0xc4, 
+-      0xe1, 0xa0, 0x20, 0x03, 0xe1, 0xa0, 0x30, 0x04, 
+-      0xe8, 0xb0, 0x00, 0xf0, 0xe8, 0xa1, 0x00, 0xf0, 
+-      0xe2, 0x53, 0x30, 0x10, 0x1a, 0xff, 0xff, 0xfb, 
+-      0xe1, 0xa0, 0x30, 0x02, 0xe8, 0xbd, 0x00, 0xc4, 
+-      0xe2, 0x13, 0x30, 0x0f, 0x0a, 0x00, 0x00, 0x03, 
+-      0xe4, 0x90, 0x40, 0x04, 0xe4, 0x81, 0x40, 0x04, 
+-      0xe2, 0x53, 0x30, 0x04, 0x1a, 0xff, 0xff, 0xfb, 
+-      0xe5, 0x9f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x2e, 0x01, 0xc9, 0xe4, 0x2e, 0x01, 0xc9, 0x88, 
+-      0x2e, 0x01, 0xc9, 0xb8, 0xe9, 0x2d, 0x00, 0x38, 
+-      0xe3, 0x52, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x3f, 
+-      0xe3, 0xe0, 0x30, 0x03, 0xe0, 0x12, 0x30, 0x03, 
+-      0x0a, 0x00, 0x00, 0x30, 0xe2, 0x10, 0x30, 0x01, 
+-      0x0a, 0x00, 0x00, 0x03, 0xe4, 0xd0, 0x30, 0x01, 
+-      0xe4, 0xc1, 0x30, 0x01, 0xe2, 0x52, 0x20, 0x01, 
+-      0x0a, 0x00, 0x00, 0x36, 0xe2, 0x10, 0x30, 0x02, 
+-      0x0a, 0x00, 0x00, 0x05, 0xe0, 0xd0, 0x30, 0xb2, 
+-      0xe1, 0xa0, 0x44, 0x23, 0xe4, 0xc1, 0x40, 0x01, 
+-      0xe4, 0xc1, 0x30, 0x01, 0xe2, 0x52, 0x20, 0x02, 
+-      0x0a, 0x00, 0x00, 0x2e, 0xe3, 0xe0, 0x30, 0x03, 
+-      0xe0, 0x12, 0x30, 0x03, 0x0a, 0x00, 0x00, 0x1f, 
+-      0xe2, 0x11, 0x40, 0x01, 0x0a, 0x00, 0x00, 0x19, 
+-      0xe2, 0x11, 0x40, 0x02, 0x1a, 0x00, 0x00, 0x0b, 
+-      0xe2, 0x41, 0x10, 0x01, 0xe5, 0x91, 0x50, 0x00, 
+-      0xe1, 0xa0, 0x5c, 0x25, 0xe1, 0xa0, 0x5c, 0x05, 
+-      0xe5, 0x9f, 0xf0, 0xa8, 0xe5, 0x91, 0x40, 0x00, 
+-      0xe1, 0xa0, 0x44, 0x04, 0xe1, 0xa0, 0x44, 0x24, 
+-      0xe1, 0x85, 0x50, 0x04, 0xe5, 0x81, 0x50, 0x00, 
+-      0xe2, 0x81, 0x10, 0x01, 0xea, 0x00, 0x00, 0x0f, 
+-      0xe2, 0x41, 0x10, 0x03, 0xe5, 0x91, 0x50, 0x00, 
+-      0xe1, 0xa0, 0x54, 0x25, 0xe1, 0xa0, 0x54, 0x05, 
+-      0xe5, 0x9f, 0xf0, 0x7c, 0xe5, 0x91, 0x40, 0x00, 
+-      0xe1, 0xa0, 0x4c, 0x04, 0xe1, 0xa0, 0x4c, 0x24, 
+-      0xe1, 0x85, 0x50, 0x04, 0xe5, 0x81, 0x50, 0x00, 
+-      0xe2, 0x81, 0x10, 0x03, 0xea, 0x00, 0x00, 0x03, 
+-      0xe2, 0x11, 0x40, 0x02, 0x0a, 0x00, 0x00, 0x00, 
+-      0xe5, 0x9f, 0xf0, 0x5c, 0xe5, 0x9f, 0xf0, 0x48, 
+-      0xe2, 0x12, 0x20, 0x03, 0x0a, 0x00, 0x00, 0x09, 
+-      0xe4, 0xd0, 0x40, 0x01, 0xe4, 0xc1, 0x40, 0x01, 
+-      0xe2, 0x52, 0x20, 0x01, 0x0a, 0x00, 0x00, 0x05, 
+-      0xe4, 0xd0, 0x40, 0x01, 0xe4, 0xc1, 0x40, 0x01, 
+-      0xe2, 0x52, 0x20, 0x01, 0x0a, 0x00, 0x00, 0x01, 
+-      0xe4, 0xd0, 0x40, 0x01, 0xe4, 0xc1, 0x40, 0x01, 
+-      0xe8, 0xbd, 0x00, 0x38, 0xe3, 0x8e, 0xe0, 0x01, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe9, 0x2d, 0x01, 0xf8, 
+-      0xe5, 0x9f, 0xf0, 0x18, 0x2e, 0x01, 0xc8, 0x58, 
+-      0x2e, 0x01, 0xc8, 0x90, 0x2e, 0x01, 0xc8, 0xac, 
+-      0x2e, 0x01, 0xc8, 0x58, 0x2e, 0x01, 0xc8, 0x74, 
+-      0x2e, 0x01, 0xc8, 0xac, 0x2e, 0x01, 0xc8, 0x90, 
+-      0x2e, 0x01, 0xc8, 0x08, 0xe9, 0x2d, 0x5f, 0xff, 
+-      0xe1, 0x4f, 0x00, 0x00, 0xe9, 0x2d, 0x00, 0x01, 
+-      0xe2, 0x8f, 0x00, 0x01, 0xe1, 0x2f, 0xff, 0x10, 
+-      0x21, 0xff, 0x48, 0x37, 0x68, 0x00, 0x40, 0x52, 
+-      0x42, 0x08, 0xd1, 0x0b, 0x32, 0x20, 0x0a, 0x00, 
+-      0x42, 0x08, 0xd1, 0x07, 0x32, 0x20, 0x0a, 0x00, 
+-      0x42, 0x08, 0xd1, 0x03, 0x0a, 0x00, 0x42, 0x08, 
+-      0xd0, 0x23, 0x32, 0x20, 0x21, 0x0f, 0x42, 0x08, 
+-      0xd1, 0x01, 0x32, 0x10, 0x09, 0x00, 0x21, 0x01, 
+-      0x42, 0x08, 0xd1, 0x08, 0x1d, 0x12, 0x21, 0x02, 
+-      0x42, 0x08, 0xd1, 0x04, 0x1d, 0x12, 0x21, 0x04, 
+-      0x42, 0x08, 0xd1, 0x00, 0x1d, 0x12, 0x48, 0x25, 
+-      0x68, 0x00, 0xb4, 0x01, 0x08, 0x90, 0x21, 0x01, 
+-      0x40, 0x81, 0x48, 0x21, 0x60, 0x01, 0x48, 0x1d, 
+-      0x58, 0x82, 0x48, 0x01, 0x46, 0x86, 0x47, 0x10, 
+-      0x2e, 0x01, 0xca, 0xc1, 0xbc, 0x02, 0x48, 0x1d, 
+-      0x60, 0x01, 0x00, 0x00, 0x47, 0x78, 0x00, 0x00, 
+-      0xe8, 0xbd, 0x00, 0x01, 0xe1, 0x69, 0xf0, 0x00, 
+-      0xe8, 0xbd, 0x5f, 0xff, 0xe2, 0x5e, 0xf0, 0x04, 
+-      0x48, 0x12, 0x21, 0x20, 0x4a, 0x12, 0x60, 0x02, 
+-      0x1d, 0x00, 0x1e, 0x49, 0xd1, 0xfb, 0x20, 0x00, 
+-      0x47, 0x70, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x46, 0x73, 0x49, 0x0e, 0x60, 0x08, 0x20, 0x00, 
+-      0x47, 0x18, 0x46, 0x73, 0x49, 0x0c, 0x60, 0x08, 
+-      0x20, 0x00, 0x47, 0x18, 0x46, 0x73, 0x48, 0x0b, 
+-      0x68, 0x00, 0x47, 0x18, 0x46, 0x73, 0x49, 0x09, 
+-      0x60, 0x08, 0x47, 0x18, 0x46, 0x73, 0x4a, 0x03, 
+-      0x00, 0x80, 0x18, 0x12, 0x68, 0x10, 0x60, 0x11, 
+-      0x47, 0x18, 0x00, 0x00, 0x2e, 0x08, 0x3a, 0xf4, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x66, 0x00, 0x00, 0x10, 
+-      0x66, 0x00, 0x00, 0x14, 0x66, 0x00, 0x00, 0x18, 
+-      0x66, 0x00, 0x00, 0x1c, 0xe9, 0x2d, 0x5f, 0xf0, 
+-      0xe1, 0x4f, 0x40, 0x00, 0xe3, 0x14, 0x00, 0x20, 
+-      0x11, 0x5e, 0x40, 0xb2, 0x13, 0xc4, 0x4c, 0xff, 
+-      0x05, 0x1e, 0x40, 0x04, 0x03, 0xc4, 0x44, 0xff, 
+-      0xe5, 0x9f, 0x50, 0x14, 0xe7, 0x95, 0x51, 0x04, 
+-      0xe5, 0x9f, 0xe0, 0x00, 0xe1, 0x2f, 0xff, 0x15, 
+-      0x2e, 0x01, 0xcb, 0x70, 0xe8, 0xbd, 0x5f, 0xf0, 
+-      0xe1, 0xb0, 0xf0, 0x0e, 0x2e, 0x08, 0x1f, 0xe8, 
+-      0x00, 0x00, 0x00, 0xc0, 0x46, 0x73, 0x47, 0x78, 
+-      0xe1, 0x0f, 0x10, 0x00, 0xe3, 0x81, 0x00, 0x80, 
+-      0xe1, 0x29, 0xf0, 0x00, 0xe2, 0x01, 0x00, 0x80, 
+-      0xe1, 0x2f, 0xff, 0x13, 0x46, 0x73, 0x00, 0x00, 
+-      0x47, 0x78, 0x00, 0x00, 0xe1, 0x4f, 0x10, 0x00, 
+-      0xe3, 0x81, 0x00, 0x80, 0xe1, 0x69, 0xf0, 0x00, 
+-      0xe2, 0x01, 0x00, 0x80, 0xe1, 0x2f, 0xff, 0x13, 
+-      0x46, 0x73, 0x00, 0x00, 0x47, 0x78, 0x00, 0x00, 
+-      0xe1, 0x0f, 0x10, 0x00, 0xe3, 0x81, 0x00, 0x40, 
+-      0xe1, 0x29, 0xf0, 0x00, 0xe2, 0x01, 0x00, 0x40, 
+-      0xe1, 0x2f, 0xff, 0x13, 0x46, 0x73, 0x00, 0x00, 
+-      0x47, 0x78, 0x00, 0x00, 0xe1, 0x4f, 0x10, 0x00, 
+-      0xe3, 0x81, 0x00, 0x40, 0xe1, 0x69, 0xf0, 0x00, 
+-      0xe2, 0x01, 0x00, 0x40, 0xe1, 0x2f, 0xff, 0x13, 
+-      0x46, 0x73, 0x00, 0x00, 0x47, 0x78, 0x00, 0x00, 
+-      0xe1, 0x0f, 0x00, 0x00, 0xe3, 0xc0, 0x00, 0x80, 
+-      0xe1, 0x29, 0xf0, 0x00, 0xe3, 0xa0, 0x00, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x13, 0x46, 0x73, 0x00, 0x00, 
+-      0x47, 0x78, 0x00, 0x00, 0xe1, 0x4f, 0x00, 0x00, 
+-      0xe3, 0xc0, 0x00, 0x80, 0xe1, 0x69, 0xf0, 0x00, 
+-      0xe3, 0xa0, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x13, 
+-      0x46, 0x73, 0x00, 0x00, 0x47, 0x78, 0x00, 0x00, 
+-      0xe1, 0x0f, 0x00, 0x00, 0xe3, 0xc0, 0x00, 0x40, 
+-      0xe1, 0x29, 0xf0, 0x00, 0xe3, 0xa0, 0x00, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x13, 0x46, 0x73, 0x00, 0x00, 
+-      0x47, 0x78, 0x00, 0x00, 0xe1, 0x4f, 0x00, 0x00, 
+-      0xe3, 0xc0, 0x00, 0x40, 0xe1, 0x69, 0xf0, 0x00, 
+-      0xe3, 0xa0, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x13, 
+-      0x46, 0x73, 0x49, 0x02, 0x60, 0x08, 0x20, 0x00, 
+-      0x46, 0x9f, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 
+-      0x46, 0x73, 0x49, 0x02, 0x60, 0x08, 0x20, 0x00, 
+-      0x46, 0x9f, 0x00, 0x00, 0x66, 0x00, 0x00, 0x04, 
+-      0x46, 0x73, 0x48, 0x03, 0x68, 0x00, 0x47, 0x18, 
+-      0x46, 0x73, 0x49, 0x01, 0x60, 0x08, 0x47, 0x18, 
+-      0x66, 0x00, 0x00, 0x08, 0x00, 0x00, 0x46, 0x6c, 
+-      0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x80, 
+-      0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x02, 0xd0, 
+-      0x00, 0x00, 0x02, 0xd0, 0x00, 0x00, 0x00, 0x15, 
+-      0x00, 0x03, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x04, 0x90, 0x85, 0x00, 0x00, 0xa6, 0xee, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xd0, 
+-      0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x08, 0x08, 0xa0, 0x00, 0x08, 0x08, 0x28, 
+-      0x00, 0x08, 0x88, 0x68, 0x00, 0x08, 0xa0, 0x98, 
+-      0x00, 0x08, 0x88, 0x68, 0x00, 0x08, 0x28, 0x98, 
+-      0x00, 0x08, 0xac, 0xf4, 0x00, 0x08, 0xb8, 0x7c, 
+-      0x00, 0x02, 0x02, 0x88, 0x00, 0x02, 0x08, 0x22, 
+-      0x00, 0x02, 0x88, 0xaa, 0x00, 0x02, 0x22, 0xaa, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x04, 0x04, 0x24, 0x00, 0x04, 0x04, 0x24, 
+-      0x00, 0x04, 0x28, 0x6c, 0x00, 0x04, 0x28, 0x6c, 
+-      0x00, 0x01, 0x10, 0x44, 0x00, 0x01, 0x20, 0x44, 
+-      0x00, 0x01, 0x11, 0xaa, 0x00, 0x01, 0x88, 0x55, 
+-      0x00, 0x01, 0x44, 0xaa, 0x00, 0x01, 0x44, 0x55, 
+-      0x00, 0x20, 0x80, 0xa0, 0x00, 0x20, 0x80, 0xc0, 
+-      0x00, 0x20, 0x20, 0xa0, 0x00, 0x20, 0x40, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x10, 0x13, 0x16, 0x1a, 0x1b, 0x1d, 0x22, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x10, 0x13, 0x16, 0x1a, 0x1b, 0x1d, 0x22, 
+-      0x10, 0x10, 0x16, 0x18, 0x1b, 0x1d, 0x22, 0x25, 
+-      0x13, 0x16, 0x1a, 0x1b, 0x1d, 0x22, 0x22, 0x26, 
+-      0x16, 0x16, 0x1a, 0x1b, 0x1d, 0x22, 0x25, 0x28, 
+-      0x16, 0x1a, 0x1b, 0x1d, 0x20, 0x23, 0x28, 0x30, 
+-      0x1a, 0x1b, 0x1d, 0x20, 0x23, 0x28, 0x30, 0x3a, 
+-      0x1a, 0x1b, 0x1d, 0x22, 0x26, 0x2e, 0x38, 0x45, 
+-      0x1b, 0x1d, 0x23, 0x26, 0x2e, 0x38, 0x45, 0x53, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x04, 0xd6, 0x00, 0x00, 0x1b, 0x08, 0x00, 
+-      0x00, 0x1f, 0xde, 0x00, 0x00, 0x00, 0x50, 0x00, 
+-      0x00, 0x09, 0xce, 0x00, 0x00, 0x13, 0x4c, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+-      0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x03, 0x05, 0x28, 0x20, 0x01, 
+-      0x00, 0x00, 0x02, 0x40, 0x71, 0x01, 0x00, 0x68, 
+-      0xe0, 0x7f, 0xb0, 0x7f, 0x60, 0x40, 0xe0, 0x1d, 
+-      0x90, 0x10, 0xb4, 0x81, 0xe8, 0xc0, 0xe0, 0xc2, 
+-      0x90, 0x18, 0x00, 0x8a, 0x70, 0xc0, 0x0f, 0x87, 
+-      0xe3, 0xe8, 0xc0, 0x00, 0x70, 0x40, 0xe0, 0x01, 
+-      0xe0, 0x86, 0x00, 0x26, 0xd0, 0x28, 0xe0, 0x0e, 
+-      0xd0, 0x0e, 0x0f, 0x0b, 0x70, 0x1d, 0xe0, 0x67, 
+-      0x0f, 0x87, 0x0f, 0x87, 0x0f, 0x87, 0x0f, 0x87, 
+-      0x0f, 0x87, 0x02, 0x20, 0xd0, 0x01, 0xe0, 0x25, 
+-      0x0f, 0x45, 0x6f, 0x81, 0xdf, 0xa6, 0xe0, 0x36, 
+-      0xe1, 0x30, 0xa0, 0x37, 0xc0, 0x00, 0xe0, 0x26, 
+-      0x00, 0x33, 0xdf, 0x00, 0xe0, 0x32, 0x0f, 0xc5, 
+-      0x0f, 0x87, 0x00, 0x27, 0xd0, 0x4c, 0xe0, 0x21, 
+-      0x00, 0x33, 0xdf, 0x60, 0x00, 0x27, 0xd0, 0x56, 
+-      0x60, 0x01, 0xe0, 0x2d, 0x03, 0xa0, 0xd0, 0x41, 
+-      0xa0, 0x78, 0x00, 0x60, 0xd0, 0x41, 0xa0, 0x77, 
+-      0x00, 0x22, 0xd0, 0x58, 0xa0, 0x76, 0x00, 0x21, 
+-      0xd0, 0x7c, 0x00, 0x4a, 0xd0, 0x72, 0x70, 0x40, 
+-      0x00, 0x06, 0x0f, 0x87, 0x00, 0x22, 0xdc, 0xf8, 
+-      0xf0, 0x4a, 0xe1, 0x70, 0x07, 0xef, 0xdd, 0xbf, 
+-      0x4f, 0x36, 0x1d, 0x99, 0x4d, 0x80, 0x10, 0x18, 
+-      0xdd, 0x50, 0x60, 0x35, 0xdd, 0x72, 0xdd, 0x10, 
+-      0x3d, 0xb4, 0xec, 0x57, 0x2d, 0x36, 0x1d, 0x03, 
+-      0xbd, 0x04, 0xe4, 0x2b, 0x01, 0x46, 0x00, 0x06, 
+-      0xac, 0xf6, 0x80, 0x3f, 0x0d, 0x0a, 0x10, 0x02, 
+-      0x7d, 0x40, 0x10, 0x1e, 0xb0, 0x20, 0xbc, 0xe0, 
+-      0x00, 0x06, 0x00, 0xc6, 0xe0, 0x52, 0xb7, 0x60, 
+-      0xb7, 0x60, 0xc0, 0x5d, 0x30, 0x5f, 0xe4, 0x72, 
+-      0xc7, 0x5e, 0x00, 0xed, 0xd0, 0x28, 0x70, 0x40, 
+-      0xb0, 0x7f, 0x60, 0x40, 0xc0, 0x1d, 0x30, 0x1c, 
+-      0xf8, 0x7e, 0x00, 0x21, 0xd0, 0x01, 0x00, 0x26, 
+-      0xd0, 0x78, 0xa0, 0x38, 0x80, 0x3f, 0x70, 0x01, 
+-      0xb0, 0x3f, 0x60, 0x01, 0x0f, 0x87, 0x80, 0x34, 
+-      0x03, 0xef, 0xd8, 0x3f, 0xa8, 0x38, 0x01, 0x35, 
+-      0xdc, 0x33, 0xe0, 0x46, 0xc0, 0x1c, 0xe4, 0xa5, 
+-      0x97, 0x2e, 0x30, 0x1c, 0xe8, 0x8e, 0x00, 0x21, 
+-      0xd0, 0x00, 0xa0, 0x38, 0xc0, 0x5d, 0x00, 0x23, 
+-      0xd0, 0x00, 0x30, 0x40, 0x30, 0x5e, 0xe4, 0x99, 
+-      0x20, 0x5e, 0xc0, 0x01, 0x30, 0x1c, 0xec, 0xa4, 
+-      0xe0, 0x9d, 0x20, 0x5f, 0xc0, 0x1c, 0x30, 0x01, 
+-      0xf4, 0xa5, 0xc0, 0x1c, 0x30, 0x1d, 0xec, 0xa4, 
+-      0xe4, 0xa5, 0x90, 0x38, 0x00, 0x1b, 0xe8, 0xa5, 
+-      0xa0, 0x66, 0xb1, 0x3f, 0xe4, 0xb3, 0xe8, 0xb1, 
+-      0xc0, 0x4b, 0x30, 0x44, 0xf8, 0xb3, 0x60, 0x45, 
+-      0xb1, 0x7c, 0x01, 0x20, 0xd0, 0x00, 0xa0, 0x05, 
+-      0x80, 0x40, 0x72, 0xc5, 0x00, 0x06, 0x90, 0x55, 
+-      0xd0, 0x01, 0x00, 0x40, 0xa0, 0x55, 0x0f, 0x87, 
+-      0x01, 0x46, 0x00, 0x06, 0x03, 0xef, 0xd0, 0x3f, 
+-      0xa0, 0x38, 0xb0, 0x01, 0xa0, 0x37, 0x80, 0x3f, 
+-      0x82, 0x34, 0x80, 0x3f, 0xf2, 0x1a, 0x80, 0x34, 
+-      0x80, 0x3f, 0xf2, 0x1a, 0xd8, 0x00, 0xd8, 0x40, 
+-      0xd8, 0x80, 0xd8, 0xc0, 0xd9, 0x00, 0xd9, 0x40, 
+-      0xd9, 0x80, 0xd9, 0xc0, 0xda, 0x00, 0xda, 0x40, 
+-      0xda, 0x80, 0xda, 0xc0, 0xdb, 0x00, 0xdb, 0x40, 
+-      0xdb, 0x80, 0xdb, 0xc0, 0xdc, 0x00, 0xdc, 0x40, 
+-      0xdc, 0x80, 0xdc, 0xc0, 0xdd, 0x00, 0xdd, 0x40, 
+-      0xdd, 0x80, 0xdd, 0xc0, 0xde, 0x00, 0xde, 0x40, 
+-      0xde, 0x80, 0xde, 0xc0, 0xdf, 0x00, 0xdf, 0x40, 
+-      0xdf, 0x80, 0xdf, 0xc0, 0xde, 0x80, 0xde, 0xc1, 
+-      0x00, 0x28, 0xd0, 0x60, 0x6e, 0x81, 0x80, 0x00, 
+-      0x80, 0x05, 0x00, 0xe3, 0xd1, 0x88, 0x00, 0x73, 
+-      0xd5, 0x80, 0x60, 0x06, 0xb1, 0xbc, 0x00, 0xfa, 
+-      0xd0, 0x80, 0x60, 0x06, 0x00, 0x26, 0xd0, 0x6c, 
+-      0x6e, 0x81, 0x04, 0xf4, 0xdc, 0x00, 0x00, 0xee, 
+-      0xd1, 0x94, 0x60, 0x06, 0x00, 0xed, 0xd0, 0x50, 
+-      0x6e, 0x81, 0x00, 0x22, 0xd0, 0x70, 0x6e, 0x81, 
+-      0x00, 0xee, 0xd0, 0x74, 0x6e, 0x81, 0xd0, 0x4c, 
+-      0x6e, 0x81, 0xd0, 0x02, 0x00, 0xef, 0xd0, 0x6c, 
+-      0x60, 0x01, 0xd0, 0x03, 0x00, 0xef, 0xd0, 0x70, 
+-      0x60, 0x01, 0x00, 0xe0, 0xd0, 0x48, 0xd0, 0x02, 
+-      0x60, 0x01, 0x00, 0x32, 0xdf, 0x20, 0xa0, 0x1c, 
+-      0x00, 0x21, 0xd0, 0x60, 0xa0, 0x76, 0x00, 0x34, 
+-      0xd5, 0x70, 0x80, 0x3f, 0x00, 0x23, 0xd0, 0x5c, 
+-      0x00, 0x4a, 0xd0, 0x72, 0x70, 0x40, 0x00, 0x06, 
+-      0x00, 0x22, 0xd1, 0xa4, 0x6e, 0xc6, 0xd0, 0x58, 
+-      0x6e, 0xc1, 0xd0, 0xc9, 0x00, 0xed, 0xd0, 0x54, 
+-      0x60, 0xc1, 0x00, 0x22, 0xd0, 0x40, 0x60, 0xc1, 
+-      0x00, 0x22, 0xd0, 0x60, 0x60, 0xc1, 0x82, 0x34, 
+-      0x80, 0x3f, 0xd6, 0xd9, 0x01, 0x2d, 0xd6, 0x0c, 
+-      0x16, 0x08, 0xd0, 0x55, 0xd0, 0x2c, 0x60, 0x40, 
+-      0xd0, 0x70, 0x00, 0xfb, 0xd1, 0x00, 0x60, 0x01, 
+-      0x00, 0x2b, 0xd4, 0x10, 0x00, 0x29, 0xd4, 0x40, 
+-      0x00, 0x2b, 0xd0, 0x90, 0xc0, 0xc2, 0xd1, 0x18, 
+-      0xd1, 0x44, 0xa1, 0x50, 0x00, 0x21, 0xd0, 0xb6, 
+-      0xd0, 0xd7, 0x00, 0x29, 0xd0, 0x04, 0x64, 0x00, 
+-      0xb0, 0x3c, 0x64, 0x40, 0x80, 0x34, 0x80, 0x3f, 
+-      0xd0, 0x40, 0x00, 0x35, 0xd0, 0x00, 0x60, 0x01, 
+-      0xd0, 0x48, 0x6e, 0x81, 0xd0, 0x44, 0x6e, 0x81, 
+-      0x00, 0x64, 0xd1, 0x80, 0x6e, 0x86, 0x01, 0x3c, 
+-      0xd2, 0x39, 0xe0, 0x46, 0xd0, 0x00, 0xd0, 0x40, 
+-      0xd0, 0x80, 0xd0, 0xc0, 0xd1, 0x00, 0xd1, 0x40, 
+-      0xd1, 0x80, 0xd1, 0xc0, 0xd2, 0x00, 0xd2, 0x40, 
+-      0xd2, 0x80, 0xd2, 0xc0, 0xd3, 0x00, 0xd3, 0x40, 
+-      0xd3, 0x80, 0xd3, 0xc0, 0xd4, 0x00, 0xd4, 0x40, 
+-      0xd4, 0x80, 0xd4, 0xc0, 0xd5, 0x00, 0xd5, 0x40, 
+-      0xd5, 0x80, 0xd5, 0xc0, 0xd6, 0x00, 0xd6, 0x40, 
+-      0xd6, 0x80, 0xd6, 0xc0, 0xd7, 0x00, 0xd7, 0x40, 
+-      0xd7, 0x80, 0xd7, 0xc0, 0x0f, 0xc5, 0x50, 0x00, 
+-      0x01, 0x46, 0x00, 0x06, 0xde, 0x80, 0xde, 0xc1, 
+-      0x03, 0x2f, 0xd0, 0x33, 0xa0, 0x38, 0xb0, 0x01, 
+-      0xa0, 0x37, 0x80, 0x3f, 0x08, 0x20, 0xdf, 0x00, 
+-      0x82, 0x34, 0x80, 0x3f, 0x00, 0xee, 0xd0, 0x08, 
+-      0x77, 0xc0, 0xb0, 0x04, 0x77, 0x80, 0xb0, 0x04, 
+-      0xc0, 0x5f, 0x30, 0x5e, 0x60, 0x40, 0xd7, 0x00, 
+-      0xb7, 0x01, 0x80, 0x34, 0x80, 0x3f, 0x00, 0x60, 
+-      0xd0, 0x80, 0x00, 0xec, 0xd0, 0x40, 0x60, 0x81, 
+-      0xb0, 0x7c, 0x60, 0x81, 0x00, 0xa0, 0xd0, 0x80, 
+-      0xb0, 0x74, 0x60, 0x81, 0xb0, 0x7c, 0x60, 0x81, 
+-      0x00, 0x68, 0xd0, 0x80, 0x6e, 0x82, 0x00, 0xef, 
+-      0xd0, 0x8c, 0x6e, 0x82, 0x00, 0x06, 0xd0, 0x11, 
+-      0xa0, 0x38, 0x80, 0x3f, 0x08, 0x20, 0xd0, 0x40, 
+-      0x10, 0x48, 0xa0, 0x4a, 0xa0, 0x5b, 0x0c, 0x20, 
+-      0xd0, 0x00, 0x10, 0x08, 0xa0, 0x27, 0xa0, 0x0a, 
+-      0x90, 0x4d, 0x0f, 0xff, 0xd8, 0x1f, 0x40, 0x40, 
+-      0xa0, 0x4d, 0x80, 0x0a, 0x80, 0x07, 0x80, 0x1b, 
+-      0x80, 0x27, 0x00, 0x60, 0xd0, 0x00, 0xa0, 0x09, 
+-      0x80, 0x28, 0x01, 0x20, 0xd0, 0x67, 0xa0, 0x69, 
+-      0x80, 0x2a, 0x82, 0x29, 0x80, 0x6a, 0x84, 0x29, 
+-      0xd0, 0x54, 0x10, 0x4f, 0xa0, 0x6a, 0x01, 0x20, 
+-      0xd0, 0x00, 0xa0, 0x29, 0x80, 0x2b, 0x02, 0x30, 
+-      0xd0, 0x00, 0xa0, 0x38, 0x80, 0x3f, 0x01, 0xb0, 
+-      0xd0, 0x10, 0xa0, 0x37, 0x80, 0x3f, 0x02, 0x30, 
+-      0xd0, 0x01, 0xa0, 0x38, 0x00, 0xea, 0xd0, 0x00, 
+-      0xd0, 0x4e, 0x0f, 0x0b, 0x70, 0x40, 0x00, 0x06, 
+-      0x00, 0x21, 0xd0, 0x88, 0x00, 0xe1, 0xd0, 0x60, 
+-      0x60, 0x81, 0x00, 0x2b, 0xd0, 0x80, 0x00, 0xe0, 
+-      0xd0, 0x6c, 0x60, 0x81, 0xb0, 0x7c, 0x00, 0x29, 
+-      0xd0, 0x80, 0x60, 0x81, 0xb0, 0x7c, 0xd0, 0x82, 
+-      0x60, 0x81, 0xb0, 0x7c, 0xd0, 0x85, 0x60, 0x81, 
+-      0xb0, 0x7c, 0x03, 0xaa, 0xd0, 0x98, 0x60, 0x81, 
+-      0xb0, 0x7c, 0x6e, 0x81, 0x00, 0x27, 0xd0, 0x40, 
+-      0x6e, 0x81, 0xb0, 0x7c, 0x6e, 0x81, 0xb0, 0x7c, 
+-      0x6e, 0x81, 0x00, 0x27, 0xd1, 0x90, 0x6e, 0x86, 
+-      0x00, 0x21, 0xd1, 0xb8, 0x6e, 0x86, 0x00, 0x66, 
+-      0xd1, 0xa0, 0xd0, 0x00, 0x01, 0x64, 0xd0, 0x58, 
+-      0x30, 0x01, 0x60, 0x06, 0x00, 0xed, 0xd1, 0xbc, 
+-      0x6e, 0x86, 0x00, 0xec, 0xd1, 0xb8, 0x6e, 0x86, 
+-      0xb1, 0x84, 0x6e, 0x86, 0x00, 0xee, 0xd1, 0x84, 
+-      0x70, 0x46, 0x00, 0x65, 0xd1, 0x94, 0x60, 0x46, 
+-      0x00, 0x64, 0xd1, 0xbc, 0x6e, 0x86, 0x00, 0x65, 
+-      0xd1, 0x80, 0x6e, 0x86, 0xb1, 0xbc, 0x6e, 0x86, 
+-      0xb1, 0xbc, 0x6e, 0x86, 0x00, 0xed, 0xd1, 0xa8, 
+-      0x6e, 0x86, 0xd0, 0x0e, 0xb1, 0xbc, 0x60, 0x06, 
+-      0xb1, 0xbc, 0x60, 0x06, 0x00, 0x65, 0xd1, 0xa4, 
+-      0x60, 0x06, 0x00, 0x28, 0xd1, 0xa4, 0x6e, 0x86, 
+-      0x00, 0x27, 0xd1, 0x98, 0x6e, 0x86, 0x00, 0x64, 
+-      0xd1, 0xa4, 0x6e, 0x86, 0xd2, 0x01, 0x00, 0x64, 
+-      0xd0, 0x60, 0x62, 0x01, 0x00, 0x64, 0xd1, 0x80, 
+-      0x70, 0x46, 0x6e, 0x86, 0x00, 0xef, 0xd1, 0x98, 
+-      0x70, 0x86, 0x08, 0x20, 0xd0, 0xcf, 0x30, 0xc1, 
+-      0xea, 0x42, 0xd0, 0x81, 0x00, 0x21, 0xd1, 0xa8, 
+-      0x60, 0x86, 0x00, 0xed, 0xd1, 0xa0, 0x6e, 0xc6, 
+-      0x00, 0x65, 0xd1, 0x98, 0x6e, 0xc6, 0x00, 0x22, 
+-      0xd0, 0x00, 0xa0, 0x05, 0x80, 0x40, 0x00, 0xc6, 
+-      0x01, 0x73, 0xd4, 0x3d, 0xe0, 0x46, 0x50, 0x00, 
+-      0x08, 0x20, 0xd0, 0x00, 0x5f, 0x00, 0x00, 0x64, 
+-      0xd0, 0x60, 0x70, 0xc1, 0x00, 0xec, 0xd0, 0x40, 
+-      0x71, 0x81, 0xb0, 0x7c, 0x71, 0xc1, 0xc0, 0x87, 
+-      0x30, 0x86, 0xf9, 0x83, 0x10, 0xee, 0xe9, 0x76, 
+-      0x10, 0xe1, 0xe9, 0x76, 0xe2, 0x57, 0x00, 0x63, 
+-      0xd0, 0xbf, 0x72, 0x06, 0xb1, 0xbc, 0x41, 0x82, 
+-      0x02, 0x1b, 0xe9, 0x8d, 0x72, 0x86, 0xb1, 0xbc, 
+-      0x41, 0x82, 0xd0, 0x75, 0x30, 0x48, 0xe9, 0xfe, 
+-      0xb0, 0x7f, 0xea, 0x00, 0x02, 0x1c, 0xe9, 0x96, 
+-      0x15, 0xa3, 0xea, 0x57, 0x10, 0xf0, 0xe9, 0x9a, 
+-      0x10, 0xfa, 0xf9, 0xa1, 0x15, 0xa3, 0xea, 0x57, 
+-      0x00, 0x21, 0xd0, 0x4c, 0x70, 0x41, 0x10, 0x61, 
+-      0xfa, 0x57, 0x00, 0xed, 0xd0, 0x08, 0x70, 0x40, 
+-      0xd0, 0x85, 0x40, 0x42, 0x60, 0x40, 0x00, 0x64, 
+-      0xd0, 0x64, 0x62, 0x01, 0x12, 0x2b, 0xe9, 0xeb, 
+-      0x12, 0x3b, 0xe9, 0xd5, 0x00, 0xec, 0xd0, 0x40, 
+-      0x61, 0x81, 0x12, 0x2d, 0xe9, 0xbf, 0x12, 0x30, 
+-      0xe9, 0xd4, 0x12, 0x36, 0xe9, 0xd4, 0x12, 0x3a, 
+-      0xe9, 0xd4, 0xd0, 0x62, 0x30, 0x48, 0xe9, 0xf2, 
+-      0x12, 0x2e, 0xe9, 0xf9, 0xe1, 0x76, 0x00, 0xed, 
+-      0xd0, 0x08, 0x70, 0x40, 0xd0, 0x85, 0x40, 0x42, 
+-      0x60, 0x40, 0xb0, 0x08, 0x00, 0x21, 0xd0, 0x41, 
+-      0x60, 0x40, 0x00, 0x64, 0xd0, 0x60, 0x62, 0x01, 
+-      0xf2, 0x5a, 0x00, 0xed, 0xd0, 0x20, 0xd0, 0x41, 
+-      0x60, 0x40, 0x10, 0xe1, 0xea, 0x3a, 0xe2, 0x57, 
+-      0xe2, 0x53, 0x10, 0xee, 0xf9, 0xe9, 0x01, 0x46, 
+-      0x82, 0x34, 0x80, 0x3f, 0x97, 0x2e, 0xc7, 0x5c, 
+-      0xa7, 0x66, 0x81, 0x34, 0x80, 0x3f, 0x00, 0x21, 
+-      0xd0, 0x01, 0xa0, 0x38, 0x00, 0xc6, 0x00, 0x21, 
+-      0xd0, 0x15, 0x0b, 0x09, 0x00, 0x4d, 0xb0, 0x01, 
+-      0xed, 0xe5, 0xd2, 0x1a, 0xe1, 0xec, 0xf1, 0x18, 
+-      0x00, 0xec, 0xd0, 0x40, 0x71, 0x81, 0xd0, 0x4e, 
+-      0x60, 0x46, 0xe2, 0x54, 0xc0, 0x0a, 0x10, 0x06, 
+-      0x52, 0x80, 0x00, 0xed, 0xd0, 0x40, 0x62, 0x81, 
+-      0xe2, 0x53, 0x00, 0x64, 0xd0, 0x60, 0x62, 0x01, 
+-      0xf2, 0x5a, 0xe1, 0x70, 0x12, 0xa3, 0xf6, 0x57, 
+-      0x15, 0xa1, 0xfa, 0x57, 0x12, 0xa0, 0xea, 0x23, 
+-      0x00, 0x65, 0xd1, 0x1c, 0xd0, 0x75, 0x30, 0x48, 
+-      0xea, 0x0a, 0xb1, 0x3c, 0x71, 0x04, 0x11, 0x20, 
+-      0xfa, 0x11, 0x00, 0xec, 0xd0, 0x40, 0x61, 0x81, 
+-      0xe2, 0x57, 0x12, 0xa1, 0xea, 0x33, 0x00, 0xe2, 
+-      0xd0, 0x60, 0x70, 0x01, 0xb0, 0x7c, 0x70, 0x41, 
+-      0x10, 0x0c, 0x50, 0x40, 0x0c, 0x30, 0xd0, 0x00, 
+-      0x31, 0x01, 0xee, 0x21, 0x21, 0x00, 0xe6, 0x57, 
+-      0xe2, 0x23, 0x31, 0x00, 0xfe, 0x57, 0xd0, 0x75, 
+-      0x30, 0x48, 0xea, 0x28, 0xf2, 0x5a, 0xe2, 0x0d, 
+-      0x00, 0xec, 0xd0, 0x40, 0x71, 0x81, 0x00, 0x63, 
+-      0xd1, 0x3f, 0xb1, 0xbc, 0x41, 0x84, 0x61, 0x81, 
+-      0xd0, 0x50, 0x60, 0x46, 0xe2, 0x57, 0x00, 0xed, 
+-      0xd0, 0x7c, 0x70, 0x41, 0x08, 0x20, 0xd0, 0x00, 
+-      0x10, 0x08, 0xe2, 0x1c, 0xd2, 0x84, 0x00, 0xed, 
+-      0xd1, 0xa4, 0x62, 0x86, 0xd5, 0x00, 0xb5, 0x01, 
+-      0x01, 0x46, 0x82, 0x34, 0x80, 0x3f, 0xc7, 0x5e, 
+-      0x97, 0x2e, 0x81, 0x34, 0x80, 0x3f, 0x02, 0xe8, 
+-      0xd0, 0x30, 0xa0, 0x37, 0xa0, 0x38, 0x08, 0x20, 
+-      0xdf, 0x00, 0x80, 0x73, 0x80, 0x3f, 0x00, 0xc6, 
+-      0x01, 0x7a, 0xde, 0x1a, 0xe0, 0x46, 0xf2, 0x5a, 
+-      0x00, 0x64, 0xd0, 0x60, 0x62, 0x01, 0x02, 0x3c, 
+-      0xdc, 0x89, 0xe0, 0x46, 0x00, 0x28, 0xd0, 0x64, 
+-      0x70, 0x81, 0x00, 0x22, 0xd0, 0x00, 0x50, 0x80, 
+-      0x60, 0x81, 0x0f, 0xc5, 0x50, 0x00, 0x50, 0x00, 
+-      0x00, 0xed, 0xd1, 0xa4, 0x72, 0x86, 0x00, 0xef, 
+-      0xd1, 0x90, 0x70, 0x46, 0x10, 0x5c, 0x10, 0x65, 
+-      0xed, 0x7d, 0xd0, 0x46, 0xc0, 0x0a, 0x10, 0x40, 
+-      0x60, 0x46, 0x00, 0x22, 0xd0, 0x73, 0x30, 0x54, 
+-      0xe9, 0x8e, 0x12, 0xa4, 0xe9, 0xb5, 0x15, 0x20, 
+-      0xe9, 0xc0, 0xb0, 0x7b, 0xe9, 0xc3, 0xb0, 0x41, 
+-      0xe9, 0xc9, 0xc0, 0x54, 0x10, 0x5c, 0x10, 0x6e, 
+-      0xe9, 0xc6, 0xe1, 0xb5, 0x00, 0x28, 0xd1, 0xb0, 
+-      0xd0, 0x00, 0x60, 0x06, 0x12, 0xa4, 0xf9, 0xb2, 
+-      0x00, 0xed, 0xd1, 0x9c, 0x62, 0x86, 0xd2, 0x80, 
+-      0x00, 0xed, 0xd1, 0xa4, 0x62, 0x86, 0xd0, 0x02, 
+-      0x00, 0xec, 0xd1, 0xbc, 0x60, 0x06, 0x00, 0x64, 
+-      0xd1, 0xa0, 0x72, 0x06, 0x12, 0x21, 0xf9, 0xa6, 
+-      0xd2, 0x0d, 0x62, 0x06, 0x00, 0xed, 0xd1, 0xa0, 
+-      0x61, 0x86, 0xd0, 0x0e, 0x00, 0xed, 0xd1, 0xac, 
+-      0x60, 0x06, 0xb1, 0xbc, 0x60, 0x06, 0x00, 0x65, 
+-      0xd1, 0xa4, 0x60, 0x06, 0x01, 0x7e, 0xd2, 0x32, 
+-      0xe1, 0xcb, 0x01, 0x46, 0x90, 0x49, 0x00, 0x60, 
+-      0xd0, 0x00, 0x50, 0x40, 0xa0, 0x49, 0x80, 0x3f, 
+-      0x00, 0xc6, 0x0c, 0x09, 0x05, 0x0d, 0xe1, 0x70, 
+-      0x01, 0xbf, 0xd0, 0x41, 0xe1, 0xcb, 0x01, 0xbb, 
+-      0xda, 0x10, 0xe1, 0xcb, 0x01, 0xbd, 0xda, 0x0b, 
+-      0xe1, 0xcb, 0x03, 0xb9, 0xd8, 0x10, 0x01, 0x46, 
+-      0x90, 0x49, 0x00, 0x60, 0xd1, 0x00, 0x50, 0x44, 
+-      0x30, 0x44, 0xa0, 0x49, 0x80, 0x3f, 0x00, 0xc6, 
+-      0xe0, 0x46, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 
+-      0x01, 0xfa, 0xd4, 0x3d, 0x00, 0x25, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0x00, 0x26, 0xd0, 0x18, 0xd0, 0x40, 
+-      0x60, 0x40, 0x00, 0x28, 0xd0, 0x24, 0x70, 0x40, 
+-      0xd0, 0x82, 0x50, 0x42, 0x60, 0x40, 0x00, 0xec, 
+-      0xd0, 0xa4, 0x70, 0xc2, 0x10, 0xe0, 0xf9, 0x81, 
+-      0x00, 0xec, 0xd1, 0x98, 0xd0, 0x41, 0x60, 0x46, 
+-      0x70, 0xc2, 0x10, 0xe0, 0xe9, 0x8e, 0xd0, 0x40, 
+-      0x60, 0x46, 0xe1, 0x81, 0xd0, 0x40, 0x00, 0xe6, 
+-      0xd0, 0x10, 0x60, 0x40, 0xb0, 0x3c, 0x60, 0x40, 
+-      0xb0, 0x3c, 0x60, 0x40, 0xd0, 0xe0, 0x00, 0xea, 
+-      0xd0, 0x40, 0x00, 0xe8, 0xd0, 0x82, 0x01, 0x46, 
+-      0x70, 0x01, 0xb0, 0x7c, 0x60, 0x02, 0xb0, 0xbc, 
+-      0x00, 0x06, 0x00, 0xc6, 0xb0, 0xc1, 0xed, 0x9b, 
+-      0x80, 0x49, 0xd6, 0x44, 0xd5, 0x43, 0x00, 0xe0, 
+-      0xd1, 0x80, 0x00, 0x06, 0x0b, 0x09, 0x01, 0x0d, 
+-      0x0b, 0x09, 0x61, 0x06, 0xb1, 0xbc, 0x01, 0x4d, 
+-      0x09, 0x09, 0x61, 0x46, 0xb1, 0xbc, 0x00, 0xcd, 
+-      0x09, 0x09, 0x10, 0xe4, 0xed, 0xb8, 0x60, 0xc6, 
+-      0xb1, 0xbc, 0x00, 0xcd, 0x60, 0xc6, 0x00, 0xed, 
+-      0xd0, 0x04, 0x70, 0x00, 0x10, 0x20, 0xf9, 0xd8, 
+-      0xd0, 0x0a, 0x40, 0x03, 0xe9, 0xc9, 0x10, 0xe2, 
+-      0xe9, 0xc9, 0x10, 0xe7, 0xe9, 0xc9, 0x10, 0xe8, 
+-      0xf9, 0xd8, 0x01, 0x46, 0x90, 0x10, 0x00, 0x20, 
+-      0xd0, 0x44, 0x50, 0x40, 0x00, 0xc6, 0xa0, 0x50, 
+-      0x00, 0xa0, 0xd0, 0x00, 0xa0, 0x05, 0x80, 0x40, 
+-      0x00, 0xed, 0xd1, 0xa4, 0xd0, 0x04, 0x60, 0x06, 
+-      0x00, 0xee, 0xd1, 0xac, 0x73, 0x86, 0x10, 0xe3, 
+-      0xe5, 0xe3, 0xe9, 0xe8, 0x00, 0xe7, 0xd0, 0x40, 
+-      0x00, 0xae, 0xd0, 0xbb, 0xe1, 0xec, 0x01, 0x24, 
+-      0xd0, 0x6b, 0x00, 0xea, 0xd0, 0xa6, 0xe1, 0xec, 
+-      0x01, 0x21, 0xd0, 0x7b, 0x00, 0xe8, 0xd0, 0x90, 
+-      0x13, 0xa0, 0xf9, 0xef, 0xc0, 0x42, 0x00, 0xe0, 
+-      0xd1, 0xa8, 0x60, 0x46, 0xb1, 0x98, 0x0b, 0xc9, 
+-      0x00, 0x4d, 0x09, 0x09, 0x10, 0x44, 0x00, 0x8d, 
+-      0x20, 0x42, 0x10, 0x5f, 0x60, 0x46, 0xb1, 0xb8, 
+-      0x00, 0x90, 0xea, 0x1c, 0x0a, 0x89, 0x00, 0x8d, 
+-      0x60, 0x86, 0xb1, 0xbc, 0x08, 0x49, 0x00, 0x4d, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x08, 0x49, 0x00, 0x4d, 
+-      0x60, 0x46, 0x10, 0x60, 0xea, 0x10, 0x00, 0xe8, 
+-      0xd1, 0x80, 0xf2, 0xb0, 0x10, 0x60, 0xfa, 0x1c, 
+-      0x08, 0x49, 0x00, 0xe0, 0xd1, 0xa4, 0x00, 0x4d, 
+-      0x60, 0x46, 0x10, 0x60, 0xea, 0x20, 0x00, 0xe9, 
+-      0xd1, 0x80, 0xf2, 0xb0, 0x10, 0x60, 0xea, 0x20, 
+-      0x00, 0xe0, 0xd1, 0x88, 0xd0, 0x40, 0x60, 0x46, 
+-      0xd0, 0x00, 0x00, 0xe0, 0xd1, 0xa8, 0x70, 0x46, 
+-      0x00, 0xef, 0xd1, 0x9c, 0x70, 0x86, 0xb0, 0xb0, 
+-      0xee, 0x2a, 0xd0, 0x81, 0x00, 0x90, 0xea, 0x2d, 
+-      0x20, 0x01, 0x10, 0x41, 0x10, 0x9f, 0x10, 0xa0, 
+-      0xee, 0x2a, 0x10, 0x1c, 0x00, 0x65, 0xd1, 0xa8, 
+-      0x60, 0x06, 0x01, 0xb4, 0xd6, 0x3a, 0xe0, 0x46, 
+-      0x02, 0x31, 0xde, 0x13, 0x00, 0x27, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0x0c, 0x09, 0x00, 0x06, 0x05, 0x0d, 
+-      0x00, 0x22, 0xd0, 0x72, 0x30, 0x54, 0xe9, 0xea, 
+-      0xb0, 0x7d, 0xfa, 0x05, 0x09, 0x09, 0x01, 0xcd, 
+-      0x11, 0xe1, 0xf9, 0xc7, 0x80, 0x09, 0x80, 0x27, 
+-      0x0a, 0x09, 0xd6, 0x45, 0x00, 0xe1, 0xd1, 0xa0, 
+-      0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 0x08, 0x49, 
+-      0x00, 0x4d, 0x60, 0x46, 0x00, 0x50, 0xe9, 0x91, 
+-      0xd4, 0x01, 0xb1, 0xbc, 0x08, 0x89, 0x00, 0x4d, 
+-      0x60, 0x46, 0x00, 0xe0, 0xd1, 0x80, 0x08, 0x89, 
+-      0x00, 0x4d, 0x08, 0x89, 0x10, 0x4c, 0x71, 0x06, 
+-      0x21, 0x01, 0x61, 0x06, 0xb1, 0xbc, 0x00, 0x4d, 
+-      0x0b, 0x49, 0x10, 0x4c, 0x71, 0x46, 0x21, 0x41, 
+-      0x61, 0x46, 0xb1, 0xb0, 0x00, 0x4d, 0x10, 0x5f, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x0a, 0x09, 0x00, 0x4d, 
+-      0x10, 0x4a, 0x70, 0x86, 0x20, 0x81, 0x60, 0x86, 
+-      0x00, 0xe1, 0xd1, 0xac, 0x08, 0x49, 0x00, 0x4d, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x08, 0x89, 0x00, 0x4d, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x09, 0x49, 0x00, 0x8d, 
+-      0x60, 0x86, 0xc0, 0x02, 0x00, 0xe0, 0xd1, 0xa8, 
+-      0x70, 0xc6, 0x10, 0xc0, 0xd0, 0x20, 0x30, 0x01, 
+-      0x10, 0xc0, 0x60, 0xc6, 0xe1, 0x75, 0x11, 0xe2, 
+-      0xf9, 0x75, 0x00, 0xe2, 0xd1, 0x80, 0x08, 0xc9, 
+-      0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 0x08, 0x49, 
+-      0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 0x10, 0x60, 
+-      0xf9, 0xd7, 0xb1, 0xb4, 0xe1, 0xde, 0xd2, 0x03, 
+-      0x0a, 0x09, 0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 
+-      0xb2, 0x01, 0xf9, 0xd8, 0x0b, 0xc9, 0x00, 0x4d, 
+-      0x10, 0x49, 0x10, 0x56, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x0b, 0x89, 0x00, 0x4d, 0x10, 0x4a, 0x10, 0x56, 
+-      0x60, 0x46, 0xe1, 0x75, 0x0b, 0x2c, 0xd4, 0x40, 
+-      0xf3, 0xb0, 0xe1, 0x77, 0x00, 0xe0, 0xd0, 0x6c, 
+-      0x00, 0xe0, 0xd1, 0x80, 0xd0, 0x0a, 0xf1, 0xfe, 
+-      0x00, 0xe1, 0xd1, 0xb0, 0xd0, 0x02, 0xf1, 0xfe, 
+-      0x00, 0xe0, 0xd1, 0x80, 0x76, 0x86, 0xb1, 0xbc, 
+-      0x73, 0x46, 0xe2, 0x3c, 0x70, 0x81, 0x60, 0x86, 
+-      0xb1, 0xbc, 0xb0, 0x7c, 0xb0, 0x01, 0xed, 0xfe, 
+-      0x0f, 0xc5, 0x00, 0xe1, 0xd1, 0xa0, 0x70, 0x46, 
+-      0xd0, 0x8f, 0x40, 0x42, 0x00, 0x25, 0xd0, 0xe0, 
+-      0x00, 0x24, 0xd1, 0x20, 0x10, 0x6a, 0xea, 0x1e, 
+-      0x00, 0x66, 0xd0, 0xe0, 0x00, 0x62, 0xd1, 0x00, 
+-      0x10, 0x66, 0xea, 0x1e, 0x00, 0x6e, 0xd0, 0xc0, 
+-      0x10, 0x64, 0xea, 0x1e, 0x00, 0x2b, 0xd0, 0xd0, 
+-      0x00, 0x29, 0xd1, 0x00, 0x00, 0xe0, 0xd1, 0x80, 
+-      0x76, 0x86, 0x16, 0xa0, 0xe9, 0xee, 0x30, 0xda, 
+-      0xe5, 0xee, 0xb1, 0xbc, 0x73, 0x46, 0x13, 0x60, 
+-      0xe9, 0xee, 0x31, 0x0d, 0xe5, 0xee, 0xd0, 0x82, 
+-      0xb1, 0xbc, 0x70, 0x46, 0x10, 0x60, 0xe9, 0xee, 
+-      0xb0, 0x81, 0xee, 0x2c, 0x00, 0xe0, 0xd0, 0x40, 
+-      0x00, 0xe0, 0xd1, 0xac, 0xd0, 0x0a, 0xf1, 0xfe, 
+-      0x00, 0xe1, 0xd0, 0x70, 0xd0, 0x02, 0xf1, 0xfe, 
+-      0x00, 0xec, 0xd1, 0x98, 0xd0, 0x40, 0x60, 0x46, 
+-      0x00, 0xe0, 0xd0, 0x8c, 0x70, 0x82, 0x00, 0x21, 
+-      0xd0, 0x70, 0x60, 0x81, 0xd0, 0x40, 0x00, 0x25, 
+-      0xd0, 0x20, 0x30, 0x1a, 0xfa, 0x50, 0x00, 0x24, 
+-      0xd0, 0x20, 0x30, 0x0d, 0xfa, 0x50, 0xd0, 0x41, 
+-      0x00, 0x21, 0xd1, 0x84, 0x60, 0x46, 0xb6, 0xb1, 
+-      0x16, 0x9c, 0x01, 0x7a, 0xde, 0x1a, 0xe0, 0x46, 
+-      0x02, 0x31, 0xde, 0x13, 0x00, 0x27, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0x00, 0xec, 0xd0, 0xa8, 0x70, 0xc2, 
+-      0x10, 0xe0, 0xf9, 0x77, 0x00, 0xec, 0xd1, 0x9c, 
+-      0xd0, 0x41, 0x60, 0x46, 0x70, 0xc2, 0x10, 0xe0, 
+-      0xe9, 0x84, 0xd0, 0x40, 0x60, 0x46, 0xe1, 0x77, 
+-      0x0b, 0x49, 0x00, 0xe2, 0xd1, 0xa0, 0x00, 0x4d, 
+-      0x10, 0x5f, 0x00, 0x6f, 0xd0, 0xff, 0x40, 0x43, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x0b, 0x09, 0x00, 0x4d, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x08, 0x89, 0x00, 0x4d, 
+-      0x60, 0x46, 0x10, 0x61, 0xf9, 0x9b, 0xd3, 0xc2, 
+-      0x00, 0xec, 0xd1, 0xbc, 0x63, 0xc6, 0x0c, 0x09, 
+-      0x90, 0x4d, 0x10, 0x60, 0xe5, 0x9c, 0x00, 0x06, 
+-      0x05, 0x0d, 0x00, 0x22, 0xd0, 0x72, 0x30, 0x54, 
+-      0xf9, 0xa9, 0x0b, 0xa0, 0xd4, 0x40, 0xf3, 0xb0, 
+-      0xe1, 0xa0, 0x00, 0xec, 0xd1, 0x9c, 0xd0, 0x40, 
+-      0x60, 0x46, 0x01, 0x7a, 0xde, 0x1a, 0xe0, 0x46, 
+-      0x0b, 0x09, 0x00, 0x4d, 0x0b, 0x09, 0x00, 0x4d, 
+-      0x0a, 0x09, 0x01, 0x4d, 0x0a, 0x09, 0x00, 0x4d, 
+-      0x01, 0x59, 0xe9, 0x96, 0x09, 0x09, 0x00, 0x4d, 
+-      0x10, 0x5f, 0x10, 0x61, 0xf9, 0x96, 0x09, 0x09, 
+-      0x01, 0x4d, 0x11, 0x5f, 0x0b, 0xc9, 0x00, 0x4d, 
+-      0xc0, 0x01, 0x10, 0x5f, 0x11, 0x4e, 0x51, 0x41, 
+-      0x08, 0x49, 0x00, 0x4d, 0x0b, 0xc9, 0x10, 0x0f, 
+-      0x00, 0x4d, 0x50, 0x01, 0x00, 0xed, 0xd1, 0xb6, 
+-      0x01, 0x46, 0x00, 0x06, 0xa0, 0x3c, 0xa1, 0x7d, 
+-      0x60, 0x06, 0x00, 0xc6, 0xd5, 0x00, 0xb5, 0x01, 
+-      0x01, 0x7a, 0xde, 0x1a, 0xe0, 0x46, 0x50, 0x00, 
+-      0x00, 0xec, 0xd0, 0xac, 0x70, 0xc2, 0x10, 0xe0, 
+-      0xf9, 0x70, 0x00, 0xec, 0xd1, 0xa0, 0xd0, 0x41, 
+-      0x60, 0x46, 0x70, 0xc2, 0x10, 0xe0, 0xe9, 0x7f, 
+-      0xd0, 0x40, 0x60, 0x46, 0xe1, 0x70, 0x0a, 0x89, 
+-      0x0b, 0xcd, 0x00, 0xe3, 0xd1, 0x80, 0x6b, 0xc6, 
+-      0x08, 0xc9, 0x05, 0x8d, 0x15, 0xa3, 0xee, 0x6e, 
+-      0x15, 0xa0, 0xea, 0x6e, 0x90, 0x4d, 0xd0, 0x9f, 
+-      0xd0, 0xdf, 0x40, 0x81, 0x10, 0x55, 0x40, 0xc1, 
+-      0x01, 0x46, 0x82, 0x34, 0x80, 0x3f, 0xc8, 0x1d, 
+-      0x81, 0x34, 0x80, 0x3f, 0x00, 0xc6, 0xd1, 0x23, 
+-      0x31, 0x03, 0x11, 0x02, 0x38, 0x04, 0xb0, 0x8d, 
+-      0x10, 0x9d, 0x28, 0x02, 0xc0, 0x60, 0x00, 0x65, 
+-      0xd1, 0x94, 0x71, 0x06, 0x68, 0x06, 0x30, 0x44, 
+-      0x00, 0xed, 0xd1, 0xa8, 0x70, 0x06, 0x10, 0x20, 
+-      0xe9, 0xb0, 0x00, 0xee, 0xd0, 0xc0, 0x70, 0xc3, 
+-      0x20, 0x43, 0xb0, 0x01, 0xf9, 0xac, 0x60, 0x06, 
+-      0x00, 0x64, 0xd1, 0xbc, 0x71, 0x06, 0xc0, 0x04, 
+-      0x21, 0x01, 0x61, 0x06, 0x10, 0x20, 0xf5, 0xbb, 
+-      0x11, 0x20, 0xe5, 0xbb, 0xb0, 0x41, 0x00, 0x65, 
+-      0xd1, 0x80, 0x71, 0x06, 0x21, 0x01, 0x61, 0x06, 
+-      0x00, 0xed, 0xd1, 0xac, 0x71, 0x06, 0x15, 0xa1, 
+-      0xe9, 0xcb, 0xb1, 0x3f, 0x61, 0x06, 0x15, 0xa3, 
+-      0xf9, 0xd6, 0xd0, 0xbf, 0xe1, 0xd3, 0xd0, 0x40, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x70, 0x86, 0x61, 0x06, 
+-      0x31, 0x02, 0xe5, 0xd3, 0x20, 0x84, 0x00, 0x65, 
+-      0xd1, 0xa4, 0x60, 0x86, 0xd9, 0x40, 0x00, 0xec, 
+-      0xd1, 0x94, 0x79, 0x06, 0xb1, 0x84, 0x78, 0xc6, 
+-      0xc0, 0x63, 0x30, 0x64, 0xe9, 0xf8, 0x00, 0xa7, 
+-      0xd0, 0xff, 0x7a, 0x63, 0x00, 0x65, 0xd0, 0x00, 
+-      0x71, 0x00, 0x31, 0x29, 0xe5, 0xf8, 0xc0, 0x63, 
+-      0xc8, 0xc1, 0xb0, 0x78, 0x40, 0x43, 0xc0, 0xa4, 
+-      0x30, 0x81, 0xe9, 0xf2, 0x7a, 0x41, 0x31, 0x29, 
+-      0xf5, 0xe8, 0x21, 0x29, 0x61, 0x00, 0xb8, 0xfc, 
+-      0x79, 0x63, 0xb8, 0xfc, 0x48, 0xc3, 0x68, 0xc6, 
+-      0x00, 0xed, 0xd1, 0xb8, 0x69, 0x46, 0x80, 0x28, 
+-      0x0b, 0xc9, 0x00, 0x4d, 0x08, 0x49, 0x10, 0x41, 
+-      0x00, 0xe3, 0xd1, 0x84, 0x00, 0x8d, 0x20, 0x42, 
+-      0x60, 0x46, 0x00, 0xee, 0xd1, 0xa4, 0x70, 0x86, 
+-      0x10, 0xa1, 0xee, 0x18, 0xe6, 0x6b, 0x90, 0x86, 
+-      0x00, 0x90, 0xea, 0x18, 0x00, 0xed, 0xd0, 0x1c, 
+-      0x70, 0x80, 0xb0, 0x81, 0xe6, 0x6b, 0x60, 0x80, 
+-      0xb1, 0xa8, 0x70, 0x86, 0x10, 0xa0, 0xfa, 0x6b, 
+-      0x00, 0x21, 0xd0, 0x38, 0x70, 0x80, 0x10, 0xa0, 
+-      0xfa, 0x6b, 0x0f, 0xef, 0xd0, 0xbf, 0x30, 0x81, 
+-      0xfa, 0x22, 0x60, 0x00, 0x08, 0x20, 0xd0, 0x00, 
+-      0x5f, 0x00, 0x15, 0xa3, 0xea, 0x6b, 0x00, 0xee, 
+-      0xd1, 0x80, 0x79, 0x46, 0x00, 0xf8, 0xd0, 0x00, 
+-      0xc4, 0x40, 0x00, 0xe3, 0xd1, 0x84, 0x78, 0x46, 
+-      0x0f, 0xef, 0xd0, 0x3f, 0x30, 0x21, 0xea, 0x48, 
+-      0x00, 0xe0, 0xd1, 0x90, 0x78, 0x06, 0xc0, 0xa1, 
+-      0x18, 0x43, 0x28, 0x42, 0x18, 0x43, 0x28, 0x42, 
+-      0x18, 0x1e, 0xd8, 0x80, 0x08, 0x11, 0xea, 0x41, 
+-      0x28, 0xa1, 0x18, 0x01, 0x18, 0x5f, 0x18, 0x60, 
+-      0xee, 0x3e, 0xc0, 0x51, 0x30, 0x62, 0xee, 0x4e, 
+-      0xc8, 0x91, 0x18, 0x9f, 0x00, 0x21, 0xd1, 0xb8, 
+-      0xd0, 0x01, 0x60, 0x06, 0x00, 0xef, 0xd0, 0x10, 
+-      0xd0, 0x72, 0x60, 0x40, 0x01, 0x46, 0x82, 0x34, 
+-      0x80, 0x3f, 0xc8, 0xdc, 0xc9, 0x1d, 0x81, 0x34, 
+-      0x80, 0x3f, 0x00, 0xc6, 0x38, 0xe4, 0xee, 0x5e, 
+-      0xea, 0x52, 0x28, 0xe5, 0x01, 0x46, 0x90, 0x6d, 
+-      0x28, 0xc1, 0x00, 0xc6, 0x38, 0xe2, 0xf6, 0x6b, 
+-      0xdb, 0x08, 0xf1, 0x16, 0xf1, 0x18, 0x00, 0x21, 
+-      0xd1, 0xb4, 0x61, 0x86, 0xe2, 0x52, 0x01, 0xf7, 
+-      0xd2, 0x19, 0xe0, 0x46, 0xd5, 0x00, 0xb5, 0x01, 
+-      0x01, 0x7a, 0xde, 0x1a, 0xe0, 0x46, 0x50, 0x00, 
+-      0x02, 0x31, 0xde, 0x13, 0x00, 0x27, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0xdb, 0x09, 0x00, 0xe3, 0xd0, 0x1c, 
+-      0x6b, 0x00, 0xda, 0xc1, 0x00, 0xe6, 0xd1, 0x98, 
+-      0x70, 0x06, 0xb1, 0x84, 0x60, 0x06, 0xb1, 0x84, 
+-      0x60, 0x06, 0x05, 0x9f, 0xe9, 0x9f, 0x08, 0x49, 
+-      0xd1, 0x17, 0x46, 0x44, 0x00, 0x4d, 0x10, 0x43, 
+-      0x26, 0x41, 0x08, 0xc9, 0x05, 0xcd, 0xb5, 0xc1, 
+-      0xe5, 0xcc, 0xc0, 0x57, 0x15, 0xc6, 0x25, 0xc1, 
+-      0x15, 0xa3, 0xf9, 0x9f, 0x08, 0x49, 0xd1, 0x0f, 
+-      0x46, 0x44, 0x00, 0x4d, 0x10, 0x44, 0x26, 0x41, 
+-      0x08, 0xc9, 0x06, 0x0d, 0xb6, 0x01, 0xe5, 0xcc, 
+-      0xc0, 0x58, 0x16, 0x06, 0x26, 0x01, 0x08, 0x49, 
+-      0x00, 0x4d, 0x10, 0x60, 0xe9, 0xa6, 0x0a, 0x09, 
+-      0x00, 0x4d, 0xe1, 0x9f, 0x0c, 0x09, 0x90, 0x4d, 
+-      0x10, 0x60, 0xe5, 0xa7, 0x00, 0x06, 0x05, 0x0d, 
+-      0x00, 0x22, 0xd0, 0x72, 0x30, 0x54, 0xf9, 0xb3, 
+-      0xd4, 0x40, 0xf3, 0xb0, 0xe1, 0xab, 0xb0, 0x7d, 
+-      0xf9, 0xb8, 0x02, 0x34, 0xd4, 0x44, 0xe0, 0x46, 
+-      0x00, 0xec, 0xd1, 0xa0, 0xd0, 0x40, 0x60, 0x46, 
+-      0x02, 0x3c, 0xdc, 0x89, 0x00, 0xec, 0xd1, 0x80, 
+-      0x70, 0x46, 0xb1, 0xbc, 0x70, 0x86, 0x30, 0x81, 
+-      0xe8, 0x46, 0x15, 0x63, 0xe9, 0xc9, 0x05, 0x5e, 
+-      0xe8, 0x46, 0x01, 0x73, 0xd4, 0x3d, 0xe0, 0x46, 
+-      0xd5, 0x00, 0xb5, 0x01, 0x01, 0x7a, 0xde, 0x1a, 
+-      0xe0, 0x46, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 
+-      0xcc, 0xc0, 0xcd, 0x01, 0xcd, 0x42, 0xcd, 0x83, 
+-      0x00, 0xa0, 0xd0, 0x01, 0xa0, 0x38, 0xc8, 0x7f, 
+-      0xc8, 0x06, 0xb1, 0xbe, 0xf3, 0x96, 0xc8, 0x80, 
+-      0xf3, 0x92, 0x58, 0x80, 0xf3, 0x96, 0xc8, 0xc0, 
+-      0xf3, 0x96, 0xc9, 0x00, 0xf3, 0x92, 0x58, 0xc0, 
+-      0xf3, 0x96, 0xc9, 0x40, 0xf3, 0x92, 0x59, 0x40, 
+-      0xc0, 0x22, 0xc0, 0x65, 0xc0, 0x86, 0xf3, 0x9a, 
+-      0xf3, 0x96, 0xc8, 0x80, 0xf3, 0x92, 0x59, 0x00, 
+-      0xf3, 0x96, 0xc9, 0x40, 0xf3, 0x96, 0xc9, 0x80, 
+-      0xf3, 0x92, 0x59, 0x40, 0xf3, 0x96, 0xc9, 0xc0, 
+-      0xf3, 0x92, 0x58, 0x80, 0xc0, 0x23, 0xc0, 0x62, 
+-      0xd0, 0x88, 0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 
+-      0xc8, 0xc0, 0xf3, 0x92, 0x58, 0xc0, 0xf3, 0x96, 
+-      0xc8, 0x80, 0xf3, 0x92, 0x59, 0xc0, 0xc0, 0x24, 
+-      0xc0, 0x67, 0xd0, 0x90, 0x20, 0x86, 0xf3, 0x9a, 
+-      0xf3, 0x96, 0xc9, 0x00, 0xf3, 0x92, 0x59, 0x80, 
+-      0xf3, 0x96, 0xc9, 0xc0, 0xf3, 0x96, 0xca, 0x00, 
+-      0xf3, 0x92, 0x59, 0xc0, 0xf3, 0x96, 0xca, 0x40, 
+-      0xf3, 0x92, 0x59, 0x00, 0xc0, 0x25, 0xc0, 0x64, 
+-      0xd0, 0x98, 0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 
+-      0xc9, 0x40, 0xf3, 0x92, 0x58, 0x80, 0xf3, 0x96, 
+-      0xc9, 0x00, 0xf3, 0x92, 0x59, 0x00, 0xc0, 0x23, 
+-      0xc0, 0x64, 0xd0, 0x84, 0x20, 0x86, 0xf3, 0x9a, 
+-      0xf3, 0x96, 0xc8, 0xc0, 0xf3, 0x92, 0x59, 0x40, 
+-      0xf3, 0x96, 0xc9, 0x00, 0xf3, 0x92, 0x5a, 0x40, 
+-      0xc0, 0x26, 0xc0, 0x69, 0xd0, 0xa0, 0x20, 0x86, 
+-      0xf3, 0x9a, 0xf3, 0x96, 0xc9, 0x80, 0xf3, 0x92, 
+-      0x5a, 0x00, 0xf3, 0x96, 0xca, 0x40, 0xf3, 0x92, 
+-      0x5a, 0x40, 0xf3, 0x96, 0xca, 0x80, 0xf3, 0x92, 
+-      0x59, 0x80, 0xc0, 0x27, 0xc0, 0x66, 0xd0, 0xa8, 
+-      0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 0xc9, 0xc0, 
+-      0xf3, 0x92, 0x59, 0x00, 0xf3, 0x96, 0xc9, 0x80, 
+-      0xf3, 0x92, 0x58, 0xc0, 0xc0, 0x22, 0xc0, 0x63, 
+-      0xd0, 0x8c, 0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x92, 
+-      0x59, 0x80, 0xc0, 0x25, 0xc0, 0x66, 0xd0, 0x94, 
+-      0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 0xc8, 0x80, 
+-      0xf3, 0x92, 0x59, 0xc0, 0xf3, 0x96, 0xc8, 0xc0, 
+-      0xf3, 0x92, 0x5a, 0x80, 0xc0, 0x28, 0xc0, 0x6a, 
+-      0xd0, 0xb0, 0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 
+-      0xc9, 0x40, 0xf3, 0x92, 0x59, 0x40, 0xc0, 0x29, 
+-      0xc0, 0x65, 0xd0, 0xb8, 0x20, 0x86, 0xf3, 0x9a, 
+-      0xf3, 0x96, 0xc9, 0x80, 0xf3, 0x92, 0x58, 0xc0, 
+-      0xf3, 0x96, 0xca, 0x00, 0xf3, 0x92, 0x58, 0x80, 
+-      0xc0, 0x24, 0xc0, 0x62, 0xd0, 0x9c, 0x20, 0x86, 
+-      0xf3, 0x9a, 0xf3, 0x92, 0x5a, 0x00, 0xc0, 0x27, 
+-      0xc0, 0x68, 0xd0, 0xa4, 0x20, 0x86, 0xf3, 0x9a, 
+-      0xf3, 0x96, 0xca, 0x80, 0xf3, 0x92, 0x59, 0x80, 
+-      0xf3, 0x96, 0xca, 0x40, 0xf3, 0x92, 0x5a, 0x40, 
+-      0xf3, 0x96, 0xc9, 0x40, 0xf3, 0x92, 0x5a, 0x80, 
+-      0xc0, 0x23, 0xc0, 0x6a, 0xd0, 0xac, 0x20, 0x86, 
+-      0xf3, 0x9a, 0xf3, 0x92, 0x59, 0x40, 0xc0, 0x26, 
+-      0xc0, 0x65, 0xd0, 0xb4, 0x20, 0x86, 0xf3, 0x9a, 
+-      0xf3, 0x96, 0xc9, 0x00, 0xf3, 0x92, 0x59, 0x00, 
+-      0xc0, 0x29, 0xc0, 0x64, 0xd0, 0xbc, 0x20, 0x86, 
+-      0xf3, 0x9a, 0xc0, 0x33, 0xc0, 0x74, 0xc0, 0xb5, 
+-      0xc0, 0xf6, 0xd0, 0x40, 0x00, 0xa0, 0xd8, 0x00, 
+-      0xa8, 0x38, 0x08, 0x45, 0x0a, 0x09, 0x00, 0x0d, 
+-      0x0f, 0xc5, 0x50, 0x00, 0x0a, 0x09, 0x00, 0x0d, 
+-      0x10, 0x08, 0x0f, 0xc5, 0x01, 0x46, 0x00, 0x06, 
+-      0xa0, 0x7c, 0xa0, 0x3d, 0x60, 0x42, 0x00, 0xc6, 
+-      0x0f, 0xc5, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 
+-      0x14, 0x48, 0xd0, 0x81, 0x00, 0xef, 0xd1, 0x8c, 
+-      0x71, 0x46, 0x11, 0x60, 0xfb, 0xb1, 0x60, 0x86, 
+-      0x71, 0x46, 0x31, 0x42, 0xfb, 0xb1, 0x00, 0xec, 
+-      0xd1, 0x0c, 0x74, 0x84, 0x00, 0x68, 0xd0, 0x80, 
+-      0x70, 0x02, 0x10, 0x20, 0xfb, 0xc4, 0xc4, 0x82, 
+-      0xc4, 0xd2, 0xb4, 0xfc, 0xda, 0x00, 0xda, 0x4f, 
+-      0x0a, 0x09, 0x0f, 0xef, 0xd0, 0x3f, 0xb4, 0x7f, 
+-      0xca, 0x29, 0x1a, 0x18, 0x4a, 0x00, 0x1a, 0x48, 
+-      0x00, 0x8d, 0x2a, 0x42, 0xd0, 0x03, 0x40, 0x11, 
+-      0xfb, 0xe3, 0xb4, 0x44, 0x00, 0xa0, 0xd0, 0xc0, 
+-      0x30, 0xd3, 0xff, 0xe3, 0xb4, 0xfe, 0x01, 0x46, 
+-      0x00, 0x06, 0xaa, 0x3d, 0xaa, 0x7c, 0x6a, 0x53, 
+-      0x00, 0xc6, 0xb4, 0xfe, 0xb4, 0x7c, 0x1a, 0x61, 
+-      0xfb, 0xc8, 0xb4, 0x43, 0x00, 0xef, 0xd0, 0x3f, 
+-      0x40, 0x11, 0xeb, 0xf7, 0xb0, 0xc4, 0xe7, 0xf7, 
+-      0xeb, 0xee, 0x61, 0x53, 0x64, 0x52, 0x64, 0xc4, 
+-      0x00, 0x28, 0xd1, 0x24, 0x70, 0x04, 0x00, 0x21, 
+-      0xd0, 0x80, 0x50, 0x02, 0x60, 0x04, 0x61, 0x46, 
+-      0x0a, 0x09, 0x0f, 0xc5, 0x50, 0x00, 0x50, 0x00, 
+-      0x02, 0x31, 0xde, 0x13, 0x00, 0x27, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0x01, 0xfa, 0xd4, 0x3d, 0x00, 0x25, 
+-      0xdc, 0xd8, 0xf0, 0x4a, 0x09, 0x09, 0x01, 0xcd, 
+-      0x11, 0xe8, 0xf9, 0xe2, 0x00, 0xe3, 0xd1, 0x9c, 
+-      0x09, 0x09, 0x05, 0xcd, 0xb5, 0xc1, 0x09, 0x09, 
+-      0x00, 0x4d, 0xb0, 0x41, 0x10, 0x46, 0x25, 0xc1, 
+-      0x09, 0x09, 0x06, 0x0d, 0xb6, 0x01, 0x09, 0x09, 
+-      0x00, 0x4d, 0x08, 0x89, 0xb0, 0x41, 0x10, 0x46, 
+-      0x26, 0x01, 0x00, 0x8d, 0x08, 0x89, 0x10, 0x82, 
+-      0xd0, 0x04, 0xc0, 0x55, 0x00, 0x40, 0x40, 0x40, 
+-      0x05, 0x4d, 0x08, 0x49, 0x0b, 0x0d, 0xd1, 0x00, 
+-      0x15, 0x63, 0xe9, 0xa2, 0xd1, 0x01, 0x55, 0x41, 
+-      0xdb, 0x01, 0x4b, 0x15, 0xa1, 0x1b, 0x08, 0x89, 
+-      0x00, 0x4d, 0x08, 0x49, 0x10, 0x41, 0xd1, 0x19, 
+-      0x46, 0x44, 0x26, 0x41, 0x00, 0xcd, 0x08, 0x49, 
+-      0x10, 0xc4, 0x00, 0x4d, 0x08, 0x49, 0x10, 0x41, 
+-      0x20, 0x81, 0xa0, 0x89, 0x00, 0x4d, 0x10, 0x43, 
+-      0x20, 0xc1, 0xa0, 0xe8, 0x08, 0x49, 0x00, 0x4d, 
+-      0x1b, 0x03, 0x5b, 0x01, 0xbb, 0x3f, 0x6b, 0x06, 
+-      0x08, 0x49, 0xb1, 0xbc, 0x00, 0x4d, 0x60, 0x46, 
+-      0x08, 0x49, 0xb1, 0xbc, 0x0a, 0xcd, 0x1a, 0xc2, 
+-      0x4a, 0xd9, 0x1a, 0xde, 0x6a, 0xc6, 0x08, 0x49, 
+-      0xb1, 0xbc, 0x00, 0x4d, 0x60, 0x46, 0x10, 0x60, 
+-      0xea, 0x3e, 0xb1, 0xbc, 0x08, 0x49, 0x00, 0x4d, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x08, 0xc9, 0x00, 0x4d, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x08, 0x49, 0x00, 0x4d, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x09, 0xc9, 0x00, 0x4d, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x0a, 0x09, 0x00, 0x4d, 
+-      0x60, 0x46, 0xe2, 0x3e, 0x11, 0xe3, 0xfa, 0x00, 
+-      0x00, 0xe7, 0xd0, 0xc0, 0xd0, 0x84, 0xb0, 0x81, 
+-      0xe6, 0x3e, 0x08, 0x49, 0x00, 0x4d, 0x60, 0x43, 
+-      0xb0, 0xfc, 0x10, 0x60, 0xe9, 0xe7, 0x10, 0xa3, 
+-      0xf9, 0xf4, 0x00, 0xe8, 0xd1, 0x80, 0xe1, 0xf8, 
+-      0x10, 0xa2, 0xf9, 0xfa, 0x00, 0xe9, 0xd1, 0x80, 
+-      0xf2, 0xb0, 0xe1, 0xe7, 0xd2, 0x3f, 0x0a, 0x09, 
+-      0x00, 0x4d, 0xb2, 0x01, 0xf5, 0xfb, 0xe1, 0xe7, 
+-      0x11, 0xe7, 0xfa, 0x3e, 0xd4, 0x01, 0x00, 0xe1, 
+-      0xd0, 0x24, 0x70, 0x00, 0x10, 0x21, 0xea, 0x0d, 
+-      0x15, 0x63, 0xfa, 0x0d, 0xd4, 0x03, 0x44, 0x2c, 
+-      0xb4, 0x3f, 0x00, 0xe6, 0xd1, 0x90, 0x0b, 0x09, 
+-      0x00, 0x4d, 0x09, 0x49, 0x10, 0x45, 0x00, 0x8d, 
+-      0x50, 0x81, 0xd0, 0x40, 0x10, 0x87, 0x10, 0x98, 
+-      0x30, 0x42, 0xf2, 0x61, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x0b, 0x09, 0x00, 0x0d, 0x09, 0x49, 0x00, 0x0d, 
+-      0xb4, 0x01, 0xfa, 0x0f, 0x00, 0xe6, 0xd0, 0x18, 
+-      0x30, 0x06, 0xe6, 0x29, 0x60, 0x46, 0xb1, 0xbc, 
+-      0xe2, 0x22, 0x00, 0xe0, 0xd1, 0x88, 0x70, 0x46, 
+-      0x10, 0x63, 0xea, 0x39, 0x10, 0x64, 0xea, 0x39, 
+-      0x00, 0xe6, 0xd1, 0x90, 0xd0, 0x00, 0x60, 0x06, 
+-      0xb1, 0xbc, 0x60, 0x06, 0xb1, 0xbc, 0x60, 0x06, 
+-      0xe2, 0x3e, 0x00, 0xef, 0xd1, 0x84, 0x70, 0x46, 
+-      0x10, 0x60, 0xfa, 0x30, 0x0c, 0x09, 0x90, 0x4d, 
+-      0x10, 0x60, 0xe6, 0x3f, 0x00, 0x06, 0x05, 0x0d, 
+-      0x00, 0x22, 0xd0, 0x72, 0x30, 0x54, 0xfa, 0x4b, 
+-      0xd4, 0x40, 0xf3, 0xb0, 0xe2, 0x43, 0xb0, 0x7d, 
+-      0xe9, 0x7a, 0x00, 0xec, 0xd1, 0xa0, 0xd0, 0x40, 
+-      0x60, 0x46, 0x02, 0x3c, 0xdc, 0x89, 0x00, 0xec, 
+-      0xd1, 0x80, 0x70, 0x46, 0xb1, 0xbc, 0x70, 0x86, 
+-      0x30, 0x81, 0xe8, 0x46, 0x15, 0x63, 0xea, 0x5e, 
+-      0x05, 0x5e, 0xe8, 0x46, 0x01, 0x73, 0xd4, 0x3d, 
+-      0xe0, 0x46, 0x00, 0xe0, 0xd0, 0x00, 0x70, 0xc0, 
+-      0x10, 0xc1, 0x00, 0xe0, 0xd0, 0x08, 0x70, 0x00, 
+-      0x10, 0x23, 0xea, 0x75, 0xc0, 0x83, 0x10, 0x9d, 
+-      0x30, 0xc2, 0x10, 0x9f, 0x30, 0xc2, 0x00, 0xef, 
+-      0xd0, 0xac, 0x70, 0x82, 0x10, 0xa3, 0xea, 0x75, 
+-      0x10, 0xc1, 0xc0, 0x83, 0x30, 0x81, 0xe6, 0x7e, 
+-      0xc0, 0x83, 0x20, 0x81, 0xf6, 0x7f, 0xd0, 0x40, 
+-      0x30, 0x43, 0x0f, 0xc5, 0xc0, 0x43, 0x0f, 0xc5, 
+-      0x00, 0xed, 0xd1, 0xa4, 0x72, 0x86, 0x15, 0xa3, 
+-      0xee, 0x23, 0x15, 0xa1, 0xe6, 0x23, 0x08, 0x20, 
+-      0xd0, 0x00, 0x5f, 0x00, 0xd8, 0xc4, 0x15, 0x63, 
+-      0xe9, 0x7e, 0x48, 0xd5, 0x18, 0xde, 0x18, 0xe0, 
+-      0xe9, 0xc2, 0x00, 0xed, 0xd1, 0xb4, 0x79, 0xc6, 
+-      0x19, 0xe0, 0xe9, 0x8c, 0x00, 0xed, 0xd0, 0x3a, 
+-      0x79, 0xc6, 0x69, 0xc0, 0xd9, 0xc0, 0x69, 0xc6, 
+-      0x00, 0xed, 0xd0, 0x38, 0x79, 0x40, 0x19, 0x60, 
+-      0xe9, 0x98, 0x00, 0x28, 0xd0, 0x24, 0x70, 0x40, 
+-      0x02, 0x20, 0xd0, 0x80, 0x50, 0x42, 0x60, 0x40, 
+-      0x15, 0xa3, 0xe9, 0x9f, 0x00, 0xec, 0xd1, 0xb8, 
+-      0x79, 0xc6, 0x69, 0x46, 0xc9, 0x67, 0x00, 0xec, 
+-      0xd9, 0xb4, 0x70, 0x66, 0x00, 0xec, 0xd1, 0xbc, 
+-      0x70, 0x06, 0x10, 0x20, 0xed, 0xbe, 0x10, 0x60, 
+-      0xe9, 0xc1, 0x00, 0xe0, 0xda, 0xa8, 0x7a, 0xaa, 
+-      0xc0, 0x2a, 0x10, 0x1f, 0x00, 0x22, 0xd0, 0xa0, 
+-      0x70, 0x82, 0x20, 0x6a, 0x00, 0x9f, 0xe9, 0xb5, 
+-      0x20, 0x40, 0x19, 0x60, 0xf9, 0xb8, 0xc9, 0x41, 
+-      0xb0, 0x48, 0x30, 0x65, 0xf5, 0xbd, 0xb0, 0x70, 
+-      0xed, 0xbe, 0xd9, 0x40, 0x00, 0xed, 0xd1, 0xbc, 
+-      0x69, 0x46, 0x69, 0x66, 0x12, 0xa4, 0xea, 0x21, 
+-      0x00, 0xec, 0xd1, 0xbc, 0x73, 0xc6, 0x15, 0xa3, 
+-      0xe9, 0xdf, 0x33, 0xe3, 0xe5, 0xd3, 0xed, 0xd2, 
+-      0x63, 0xc6, 0x00, 0x21, 0xd1, 0xa8, 0x63, 0xc6, 
+-      0x00, 0xed, 0xd1, 0xa0, 0x63, 0xc6, 0x15, 0xa1, 
+-      0xf9, 0xdc, 0x12, 0xa3, 0xe5, 0xe3, 0xd3, 0xc2, 
+-      0x00, 0xec, 0xd1, 0xbc, 0x63, 0xc6, 0xe1, 0xe3, 
+-      0x12, 0xa3, 0xea, 0x21, 0xe1, 0xe3, 0x12, 0xa2, 
+-      0xf6, 0x21, 0x13, 0xe0, 0xfa, 0x21, 0x00, 0xee, 
+-      0xd1, 0x8c, 0x78, 0x06, 0xb1, 0xbc, 0x78, 0x46, 
+-      0xb1, 0xbc, 0x78, 0x86, 0xd1, 0x88, 0x72, 0x46, 
+-      0xd1, 0x84, 0x73, 0x06, 0x13, 0x20, 0xf9, 0xe3, 
+-      0x00, 0x64, 0xd1, 0xa0, 0x70, 0x46, 0xd0, 0xa2, 
+-      0x30, 0x81, 0xe9, 0xff, 0x10, 0x70, 0xea, 0x11, 
+-      0x10, 0x6d, 0xea, 0x14, 0x10, 0x76, 0xea, 0x19, 
+-      0x10, 0x7a, 0xea, 0x28, 0xe2, 0x3b, 0x18, 0xe0, 
+-      0xea, 0x3b, 0x00, 0xed, 0xd1, 0x80, 0x70, 0x86, 
+-      0xb0, 0x81, 0xd0, 0x3f, 0x40, 0x02, 0x10, 0x20, 
+-      0xea, 0x0c, 0x60, 0x86, 0xf3, 0x8a, 0xe1, 0xe3, 
+-      0xc0, 0x02, 0x10, 0x1a, 0x50, 0x80, 0x60, 0x86, 
+-      0xe2, 0x3b, 0x15, 0xa3, 0xea, 0x21, 0xe2, 0xe9, 
+-      0xd2, 0x80, 0x00, 0xed, 0xd1, 0xa4, 0x62, 0x86, 
+-      0xe3, 0x0c, 0x00, 0xed, 0xd1, 0x88, 0xd0, 0x60, 
+-      0x70, 0x06, 0x50, 0x40, 0x60, 0x46, 0x15, 0xa3, 
+-      0xfb, 0x0c, 0xd5, 0x84, 0xe3, 0x0c, 0xd5, 0x00, 
+-      0xb5, 0x01, 0x01, 0x7a, 0xde, 0x1a, 0xe0, 0x46, 
+-      0x00, 0xed, 0xd1, 0x88, 0xd0, 0x60, 0x70, 0x06, 
+-      0x50, 0x40, 0x60, 0x46, 0x15, 0xa2, 0xe7, 0x0c, 
+-      0xee, 0x21, 0x00, 0x21, 0xd1, 0x8c, 0x18, 0xe0, 
+-      0xfa, 0x39, 0x70, 0x46, 0x10, 0x61, 0xea, 0x70, 
+-      0xe2, 0x21, 0x65, 0x86, 0xe2, 0x21, 0x18, 0xe0, 
+-      0xea, 0x70, 0xd1, 0x80, 0x73, 0x06, 0x15, 0xa2, 
+-      0xee, 0x68, 0x00, 0x22, 0xd1, 0x80, 0x70, 0x46, 
+-      0x6b, 0x06, 0xcb, 0x01, 0xb1, 0xb4, 0x70, 0x46, 
+-      0x6a, 0xc6, 0xca, 0xc1, 0x00, 0x65, 0xd1, 0x98, 
+-      0x70, 0x46, 0x10, 0x61, 0xfa, 0x50, 0x02, 0x41, 
+-      0xc3, 0x21, 0xc7, 0xe0, 0x02, 0x50, 0xea, 0x56, 
+-      0xc3, 0x20, 0xc7, 0xe1, 0xd1, 0x88, 0xd0, 0x01, 
+-      0x02, 0x40, 0x62, 0x46, 0x0f, 0xef, 0xd0, 0x7f, 
+-      0x30, 0x6f, 0xfa, 0x5f, 0xc3, 0x20, 0xc7, 0x4c, 
+-      0xd0, 0x00, 0x00, 0x65, 0xd1, 0x98, 0x70, 0x46, 
+-      0x60, 0x06, 0xb0, 0x41, 0x43, 0x01, 0xe2, 0x70, 
+-      0xc3, 0x22, 0xc7, 0xcc, 0xc7, 0x60, 0xc7, 0xa1, 
+-      0x02, 0x50, 0xea, 0x70, 0xc7, 0x61, 0xc7, 0xa0, 
+-      0xdb, 0x80, 0xd1, 0x00, 0x00, 0xef, 0xd1, 0xa8, 
+-      0x70, 0x46, 0x10, 0x60, 0xfa, 0x7a, 0x00, 0xe0, 
+-      0xd1, 0x88, 0x70, 0x46, 0x00, 0x22, 0xd1, 0xb0, 
+-      0x70, 0x86, 0x30, 0x81, 0xea, 0x82, 0x60, 0x46, 
+-      0xd0, 0x20, 0xf3, 0x06, 0x10, 0x63, 0xea, 0x87, 
+-      0x10, 0x64, 0xea, 0x87, 0xe2, 0x95, 0x00, 0xef, 
+-      0xd1, 0x6c, 0x71, 0x45, 0xc0, 0x05, 0x30, 0x01, 
+-      0xf6, 0x95, 0xdb, 0x82, 0xd1, 0x01, 0x10, 0x63, 
+-      0xea, 0x95, 0xd1, 0x02, 0x11, 0x62, 0xea, 0x95, 
+-      0xd1, 0x03, 0xd1, 0x8c, 0x61, 0x06, 0xdb, 0x40, 
+-      0x00, 0xe0, 0xd0, 0x00, 0x71, 0x00, 0xc0, 0x84, 
+-      0x10, 0x9c, 0xb0, 0x96, 0xfa, 0xa0, 0xb1, 0x38, 
+-      0xb0, 0x96, 0xfa, 0xa3, 0xb1, 0x30, 0x00, 0x29, 
+-      0xd1, 0x84, 0x00, 0x22, 0xd0, 0x74, 0x70, 0x86, 
+-      0x70, 0xc1, 0x61, 0x06, 0x30, 0xc2, 0xea, 0xae, 
+-      0x60, 0x81, 0xdb, 0x41, 0xb0, 0x3c, 0xb1, 0xbc, 
+-      0xb0, 0x7c, 0x71, 0x00, 0x70, 0x86, 0x70, 0xc1, 
+-      0x61, 0x06, 0x30, 0xc2, 0xea, 0xb9, 0x60, 0x81, 
+-      0xdb, 0x41, 0x00, 0xee, 0xd1, 0xb4, 0x70, 0x06, 
+-      0xb1, 0xbc, 0x70, 0x46, 0x30, 0x40, 0xea, 0xc2, 
+-      0x60, 0x06, 0xdb, 0x41, 0x00, 0x24, 0xd0, 0x60, 
+-      0x30, 0x81, 0xea, 0xc7, 0x30, 0x81, 0x50, 0x02, 
+-      0xea, 0xca, 0xd0, 0x01, 0x00, 0x22, 0xd1, 0xbc, 
+-      0x70, 0x86, 0x30, 0x80, 0xea, 0xd2, 0x60, 0x06, 
+-      0xd0, 0x10, 0xf3, 0x06, 0x00, 0x22, 0xd1, 0xa4, 
+-      0x71, 0x06, 0xd0, 0x01, 0x41, 0x00, 0x5b, 0x44, 
+-      0x5b, 0x6e, 0x6b, 0x46, 0x00, 0x28, 0xd0, 0x70, 
+-      0x70, 0x41, 0x10, 0x62, 0xfa, 0xe6, 0xd1, 0x84, 
+-      0x70, 0x06, 0x10, 0x20, 0xfa, 0xdf, 0x00, 0x22, 
+-      0xd0, 0x00, 0xf3, 0x06, 0x02, 0x7d, 0xde, 0x68, 
+-      0xe0, 0x46, 0x00, 0xed, 0xd1, 0x88, 0x71, 0x06, 
+-      0x01, 0x1f, 0xfa, 0xfd, 0xd0, 0x41, 0x41, 0x01, 
+-      0xd0, 0x62, 0x00, 0x65, 0xd0, 0x30, 0x70, 0x00, 
+-      0x10, 0x21, 0xea, 0xfa, 0xee, 0xf9, 0x1a, 0xe1, 
+-      0xfa, 0xfa, 0xd0, 0x52, 0x51, 0x01, 0x61, 0x06, 
+-      0xe3, 0x0c, 0x18, 0xe0, 0xea, 0x70, 0xc7, 0x60, 
+-      0xc7, 0xe1, 0x02, 0x50, 0xea, 0x70, 0xc7, 0x61, 
+-      0xc7, 0xe0, 0xe2, 0x70, 0x00, 0x28, 0xdc, 0xa4, 
+-      0x7c, 0x72, 0x5c, 0x40, 0x6c, 0x72, 0x0f, 0xc5, 
+-      0x18, 0xe0, 0xeb, 0x82, 0xd9, 0x0d, 0x00, 0xee, 
+-      0xd1, 0xa4, 0x70, 0x06, 0x10, 0x21, 0xfb, 0x7f, 
+-      0xd9, 0x0c, 0x90, 0x06, 0x00, 0x10, 0xeb, 0x7f, 
+-      0x00, 0x21, 0xd1, 0x88, 0x7a, 0x06, 0x1a, 0x20, 
+-      0xeb, 0x7f, 0xd9, 0x00, 0x00, 0xed, 0xd1, 0xbc, 
+-      0x79, 0x46, 0x19, 0x60, 0xeb, 0x7f, 0x39, 0x68, 
+-      0xc0, 0xe5, 0xc0, 0x25, 0x10, 0x13, 0xb0, 0x0f, 
+-      0xef, 0x7f, 0xb0, 0x22, 0xe7, 0x7f, 0x00, 0xe0, 
+-      0xd1, 0xa8, 0x71, 0x46, 0x11, 0x5f, 0x29, 0x45, 
+-      0x00, 0x22, 0xd0, 0x18, 0x00, 0x22, 0xd4, 0x54, 
+-      0x00, 0x22, 0xd0, 0x9c, 0x70, 0x00, 0x74, 0x51, 
+-      0x70, 0x42, 0x34, 0x40, 0xe7, 0x3c, 0xd0, 0x40, 
+-      0x00, 0x22, 0xd4, 0x50, 0x74, 0x51, 0x34, 0x40, 
+-      0xef, 0x42, 0x20, 0x45, 0x60, 0x42, 0x39, 0x41, 
+-      0x19, 0x60, 0xf7, 0x5e, 0x00, 0x65, 0xd1, 0xa8, 
+-      0x7a, 0x86, 0x29, 0x6a, 0x19, 0x59, 0xb9, 0x7e, 
+-      0xf7, 0x75, 0x15, 0xa3, 0xf7, 0x57, 0x00, 0xed, 
+-      0xd1, 0xac, 0x70, 0x06, 0x00, 0xed, 0xd1, 0xb0, 
+-      0x70, 0x46, 0x30, 0x01, 0xfb, 0x7f, 0x00, 0x65, 
+-      0xd1, 0x84, 0x70, 0x46, 0xb0, 0x7f, 0x60, 0x46, 
+-      0xd5, 0x84, 0xe3, 0x7f, 0x11, 0x41, 0xd0, 0x4a, 
+-      0x00, 0xed, 0xd1, 0xa0, 0x74, 0x46, 0xd0, 0x00, 
+-      0x60, 0x06, 0x30, 0xc5, 0x39, 0x45, 0xe7, 0x6e, 
+-      0x14, 0x60, 0xeb, 0x6b, 0xf3, 0x85, 0xb0, 0x41, 
+-      0xef, 0x65, 0xe3, 0x71, 0x00, 0x66, 0xd1, 0xa0, 
+-      0x60, 0xc6, 0x15, 0xa3, 0xeb, 0x7f, 0xf3, 0x85, 
+-      0xe3, 0x7f, 0xd9, 0x01, 0x00, 0x66, 0xd1, 0xa0, 
+-      0x70, 0x06, 0x30, 0x03, 0xe7, 0x7e, 0x10, 0x1d, 
+-      0x10, 0x3b, 0xe7, 0x7f, 0x60, 0xc6, 0x00, 0x66, 
+-      0xd1, 0xa4, 0x69, 0x06, 0x15, 0xa4, 0xea, 0x23, 
+-      0xe2, 0x3b, 0x00, 0x65, 0xdd, 0x08, 0x7c, 0xf4, 
+-      0xbc, 0xff, 0x6c, 0xf4, 0x00, 0xef, 0xdd, 0x10, 
+-      0x7c, 0xf4, 0xbc, 0xfe, 0x6c, 0xf4, 0xc0, 0x3f, 
+-      0xf1, 0x18, 0xf1, 0x16, 0xf1, 0x18, 0x00, 0x05, 
+-      0x08, 0x20, 0xd0, 0x40, 0x5f, 0x01, 0x15, 0x63, 
+-      0xe9, 0x77, 0x05, 0x5e, 0xeb, 0x08, 0x00, 0x22, 
+-      0xd1, 0xa0, 0x6b, 0x06, 0x00, 0x22, 0xd1, 0xa8, 
+-      0x6b, 0xc6, 0x00, 0x22, 0xd1, 0xac, 0x6a, 0xc6, 
+-      0x00, 0xee, 0xd0, 0x0c, 0x00, 0xe6, 0xd1, 0x9c, 
+-      0x70, 0x40, 0x30, 0x5f, 0xe9, 0x8d, 0xb0, 0x3c, 
+-      0xb1, 0xb4, 0x70, 0x40, 0x30, 0x5f, 0xe9, 0x8d, 
+-      0xb1, 0xb4, 0x00, 0xe6, 0xd0, 0x10, 0xd0, 0x83, 
+-      0x70, 0x40, 0x60, 0x46, 0xb0, 0x3c, 0xb1, 0xbc, 
+-      0xb0, 0x81, 0xed, 0x90, 0x00, 0xee, 0xd0, 0x0c, 
+-      0x00, 0xe6, 0xd1, 0x9c, 0x70, 0x40, 0x30, 0x4c, 
+-      0xe9, 0xa3, 0xb0, 0x3c, 0xb1, 0xb4, 0x70, 0x40, 
+-      0x30, 0x4c, 0xe9, 0xa3, 0xb1, 0xb4, 0x00, 0xe6, 
+-      0xd0, 0x00, 0x61, 0x80, 0x00, 0x21, 0xd1, 0xb4, 
+-      0x70, 0x06, 0x10, 0x20, 0xe9, 0xae, 0xd0, 0x00, 
+-      0x60, 0x06, 0xf1, 0x18, 0x00, 0x21, 0xd1, 0x8c, 
+-      0x70, 0x46, 0x65, 0x86, 0xde, 0xc0, 0x00, 0xee, 
+-      0xd0, 0x20, 0x70, 0x00, 0x10, 0x22, 0xfd, 0xb9, 
+-      0xde, 0xc2, 0x00, 0x21, 0xd0, 0x04, 0x70, 0x00, 
+-      0x10, 0x21, 0xe9, 0xc0, 0x15, 0xa3, 0xe9, 0xdc, 
+-      0xd0, 0x02, 0x4c, 0x00, 0x10, 0x63, 0xe9, 0xc5, 
+-      0xcc, 0x3b, 0xd0, 0x04, 0x63, 0x00, 0xd0, 0x00, 
+-      0x70, 0x00, 0x30, 0x1f, 0xfb, 0x08, 0xd0, 0x18, 
+-      0x70, 0x00, 0x10, 0x20, 0xed, 0xc7, 0xd0, 0x04, 
+-      0x70, 0x80, 0x10, 0xa0, 0xeb, 0x08, 0xf1, 0x16, 
+-      0x00, 0x21, 0xd0, 0x9a, 0xc0, 0x39, 0x30, 0x1f, 
+-      0x10, 0x18, 0x30, 0x02, 0xfd, 0xcf, 0xe3, 0x08, 
+-      0x00, 0xe0, 0xd9, 0x04, 0x79, 0x24, 0xb9, 0x38, 
+-      0x19, 0x1c, 0xdc, 0x88, 0x4c, 0xac, 0xd0, 0x02, 
+-      0x40, 0x2c, 0x10, 0x02, 0x0c, 0x80, 0x10, 0x63, 
+-      0xea, 0x70, 0x15, 0x63, 0xf9, 0xec, 0xf1, 0x18, 
+-      0x00, 0xef, 0xdc, 0x00, 0x7c, 0x30, 0x00, 0x24, 
+-      0xd0, 0x30, 0x70, 0x00, 0x10, 0x21, 0xf9, 0xf6, 
+-      0xbc, 0x3b, 0xe1, 0xfd, 0x10, 0x22, 0xf9, 0xfa, 
+-      0xbc, 0x38, 0xe1, 0xfd, 0x10, 0x23, 0xf9, 0xfd, 
+-      0xbc, 0x3c, 0x1e, 0xe0, 0xea, 0x03, 0x15, 0x63, 
+-      0xfa, 0x02, 0xbe, 0xfc, 0xdc, 0x12, 0x0e, 0xde, 
+-      0xfa, 0x09, 0xc0, 0x24, 0x30, 0x30, 0xf6, 0x09, 
+-      0x2c, 0x00, 0xd0, 0x2c, 0x6c, 0x00, 0x1e, 0xe0, 
+-      0xea, 0x0f, 0xcc, 0x24, 0x1c, 0x1f, 0xd9, 0x40, 
+-      0x06, 0x50, 0xea, 0x22, 0xc0, 0x24, 0xb0, 0x12, 
+-      0xfe, 0x22, 0xd9, 0x74, 0x79, 0x65, 0x19, 0x5f, 
+-      0x30, 0x25, 0xee, 0x1b, 0x29, 0x40, 0x19, 0x5f, 
+-      0x19, 0x41, 0xc0, 0x25, 0x20, 0x30, 0x30, 0x24, 
+-      0xe6, 0x22, 0x3c, 0x00, 0xd0, 0x38, 0x69, 0x40, 
+-      0x1c, 0x05, 0xbc, 0x38, 0x3c, 0x32, 0x5c, 0x3b, 
+-      0xbc, 0x3f, 0xd8, 0xec, 0x78, 0xe3, 0xc0, 0xa3, 
+-      0x10, 0xb2, 0xf6, 0x2f, 0xd0, 0x92, 0x02, 0xe4, 
+-      0xd8, 0x00, 0xd0, 0xc0, 0x20, 0xe0, 0xb0, 0x81, 
+-      0xee, 0x32, 0xd0, 0x30, 0x60, 0xc0, 0x00, 0xac, 
+-      0xd0, 0x20, 0xc0, 0xc0, 0xd8, 0x40, 0xc1, 0x23, 
+-      0xd4, 0x64, 0x34, 0x63, 0xdc, 0x40, 0x0c, 0x1f, 
+-      0xfa, 0x5b, 0xc0, 0x65, 0xb0, 0x41, 0xe6, 0x47, 
+-      0x68, 0x40, 0xb0, 0x3c, 0xe2, 0x42, 0xc0, 0xc0, 
+-      0x34, 0x65, 0xdc, 0x48, 0x4c, 0x70, 0x1c, 0x5f, 
+-      0x20, 0xf1, 0x15, 0x63, 0xfa, 0x5c, 0xf2, 0x54, 
+-      0xc1, 0x11, 0xc0, 0x83, 0xf2, 0xa5, 0xe2, 0x6f, 
+-      0xb1, 0x01, 0xe6, 0x5a, 0x68, 0x40, 0x28, 0x60, 
+-      0xb0, 0x3c, 0xe2, 0x54, 0x0f, 0xc5, 0xd9, 0x40, 
+-      0xb1, 0x12, 0x11, 0x01, 0x21, 0x25, 0xf2, 0x54, 
+-      0xc1, 0x11, 0xb1, 0x01, 0xe6, 0x6f, 0x20, 0x31, 
+-      0x68, 0x40, 0x30, 0x31, 0xb0, 0x3c, 0x28, 0x60, 
+-      0x70, 0x43, 0x30, 0x31, 0x60, 0x40, 0x20, 0x31, 
+-      0xb0, 0x3c, 0xb0, 0xf8, 0xe2, 0x61, 0xe2, 0xf7, 
+-      0xd8, 0xec, 0x78, 0xe3, 0x00, 0xa8, 0xd0, 0x80, 
+-      0x00, 0xa8, 0xd1, 0x44, 0x00, 0xac, 0xd0, 0x20, 
+-      0xc0, 0xc0, 0x0c, 0x1f, 0xfa, 0xb3, 0xd9, 0x78, 
+-      0x79, 0x65, 0x39, 0x25, 0x19, 0x5f, 0xc9, 0xa5, 
+-      0x19, 0x83, 0x20, 0x26, 0x20, 0xe6, 0x20, 0xa6, 
+-      0x21, 0x66, 0xc1, 0x23, 0xc0, 0x64, 0x10, 0x5f, 
+-      0x10, 0x9d, 0x20, 0x81, 0x31, 0x01, 0x30, 0x44, 
+-      0xf6, 0x8e, 0x21, 0x01, 0x30, 0x84, 0x10, 0x83, 
+-      0xc4, 0x64, 0x34, 0x63, 0xdc, 0x48, 0x4c, 0x70, 
+-      0x1c, 0x5f, 0x15, 0x63, 0xfa, 0xc3, 0x20, 0xb1, 
+-      0xf2, 0xa5, 0xc1, 0x24, 0x11, 0x1f, 0xc0, 0x85, 
+-      0x30, 0xb1, 0xf2, 0xa5, 0xc1, 0x11, 0xc0, 0x83, 
+-      0x0c, 0x9d, 0xfa, 0xa3, 0xb0, 0xbc, 0xf2, 0xa5, 
+-      0xe2, 0xec, 0xb1, 0x01, 0xe6, 0x5a, 0x70, 0x42, 
+-      0xb0, 0xb8, 0x60, 0x40, 0xb0, 0x3c, 0xe2, 0xa5, 
+-      0xb1, 0x01, 0xe6, 0x5a, 0x70, 0x42, 0xb0, 0xb8, 
+-      0x60, 0x40, 0xb0, 0x38, 0xe2, 0xac, 0x00, 0xac, 
+-      0xd0, 0x24, 0xc1, 0x23, 0xb1, 0x12, 0xf2, 0xac, 
+-      0xd1, 0x24, 0x31, 0x23, 0x00, 0xa8, 0xd0, 0x84, 
+-      0xf2, 0xac, 0xd1, 0x12, 0x00, 0xa8, 0xd0, 0x84, 
+-      0xc0, 0x03, 0xf2, 0xac, 0xe2, 0xec, 0xd8, 0x82, 
+-      0x48, 0x95, 0x18, 0x81, 0xb1, 0x01, 0xe6, 0xd9, 
+-      0x20, 0xb1, 0x70, 0x42, 0x30, 0xb1, 0x20, 0x22, 
+-      0x60, 0x40, 0x30, 0x22, 0xb0, 0xbc, 0xb0, 0x3c, 
+-      0x30, 0xb1, 0x70, 0x42, 0x20, 0xb1, 0x30, 0x22, 
+-      0x60, 0x40, 0x20, 0x22, 0xb0, 0xbc, 0xb0, 0x3c, 
+-      0xe2, 0xc6, 0xc1, 0x11, 0xc0, 0x85, 0x30, 0xb1, 
+-      0x20, 0xe2, 0xb1, 0x01, 0xe6, 0xec, 0x70, 0x42, 
+-      0xb0, 0xb8, 0x20, 0x22, 0x60, 0x40, 0x30, 0x22, 
+-      0xb0, 0x3c, 0x70, 0x43, 0xb0, 0xf8, 0x30, 0x22, 
+-      0x60, 0x40, 0x20, 0x22, 0xb0, 0x3c, 0xe2, 0xdd, 
+-      0xd0, 0x08, 0x5c, 0x00, 0x3c, 0x32, 0xd0, 0x04, 
+-      0x40, 0x30, 0x3c, 0x00, 0x15, 0x63, 0xfa, 0xf7, 
+-      0x1e, 0xe0, 0xea, 0xf7, 0xbc, 0x3c, 0x00, 0xac, 
+-      0xd0, 0xa0, 0x00, 0xa8, 0xd0, 0x00, 0x00, 0x20, 
+-      0xd1, 0x24, 0x70, 0x42, 0xb0, 0xbc, 0x60, 0x40, 
+-      0xb0, 0x3c, 0xb1, 0x01, 0xee, 0xfd, 0xd0, 0x30, 
+-      0x30, 0x30, 0xef, 0x03, 0xd0, 0x04, 0x63, 0x00, 
+-      0x08, 0x20, 0xd0, 0x40, 0x3f, 0x01, 0x02, 0xba, 
+-      0xde, 0x3c, 0xe0, 0x46, 0x50, 0x00, 0x50, 0x00, 
+-      0x01, 0x46, 0xd0, 0x08, 0x94, 0x89, 0xd0, 0x8c, 
+-      0x44, 0x82, 0x14, 0x9e, 0x30, 0x12, 0xd0, 0x88, 
+-      0x10, 0x80, 0x00, 0xe8, 0xd1, 0x80, 0x70, 0xc6, 
+-      0x00, 0x06, 0xa0, 0xbd, 0xa0, 0xfc, 0x80, 0x3f, 
+-      0xb1, 0xbe, 0x60, 0xc6, 0x00, 0x06, 0x80, 0xa9, 
+-      0x80, 0x3f, 0x80, 0x2a, 0x80, 0x3f, 0x00, 0x21, 
+-      0xd0, 0x3c, 0x00, 0x0a, 0xb1, 0x82, 0xd0, 0x6b, 
+-      0x70, 0x46, 0x00, 0x06, 0x80, 0x07, 0x01, 0x20, 
+-      0xd0, 0x67, 0xa0, 0x69, 0x80, 0x2a, 0x82, 0x29, 
+-      0x80, 0x6a, 0x84, 0x29, 0xd0, 0x54, 0x10, 0x4f, 
+-      0xa0, 0x6a, 0x01, 0x20, 0xd0, 0x00, 0xa0, 0x29, 
+-      0x80, 0x2b, 0x0c, 0x20, 0xd0, 0x00, 0x10, 0x08, 
+-      0xa0, 0x27, 0x90, 0x09, 0xd0, 0x41, 0x40, 0x01, 
+-      0xd0, 0x44, 0x40, 0x70, 0x20, 0x01, 0xa0, 0x27, 
+-      0x80, 0x3f, 0x00, 0xc6, 0x15, 0x63, 0xe9, 0xae, 
+-      0x05, 0x5e, 0xe9, 0xbe, 0x00, 0xe0, 0xd0, 0x40, 
+-      0x70, 0x81, 0x10, 0x9c, 0xb0, 0x96, 0xf9, 0xb7, 
+-      0x00, 0x21, 0xd0, 0x40, 0xe1, 0xbb, 0xb0, 0x96, 
+-      0xf9, 0xbe, 0x00, 0x22, 0xd0, 0x40, 0x27, 0xc1, 
+-      0x27, 0x41, 0x27, 0x81, 0x90, 0x83, 0x00, 0x64, 
+-      0xd0, 0x10, 0x60, 0x80, 0x01, 0x46, 0x82, 0x34, 
+-      0x80, 0x3f, 0x00, 0x64, 0xd0, 0x14, 0x67, 0x40, 
+-      0x80, 0x34, 0x80, 0x3f, 0x00, 0xc6, 0x90, 0xae, 
+-      0x00, 0x64, 0xd0, 0x18, 0x60, 0x80, 0x90, 0xa6, 
+-      0x00, 0x64, 0xd0, 0x1c, 0x60, 0x80, 0x15, 0x63, 
+-      0xe9, 0xe3, 0x0c, 0x1f, 0xe9, 0xe3, 0x05, 0x50, 
+-      0xf9, 0xe3, 0x15, 0xa3, 0xf9, 0xe3, 0x90, 0x4d, 
+-      0x10, 0x60, 0xe5, 0xdb, 0x00, 0x06, 0x05, 0x0d, 
+-      0x01, 0x7a, 0xde, 0x1a, 0xe0, 0x46, 0x15, 0xa3, 
+-      0xf9, 0xfb, 0x00, 0x21, 0xd0, 0x04, 0x70, 0x00, 
+-      0x10, 0x21, 0xe9, 0xfb, 0xd0, 0x38, 0x70, 0x00, 
+-      0x15, 0x63, 0xe9, 0xef, 0x10, 0x1f, 0x15, 0x21, 
+-      0xe5, 0xe0, 0xd0, 0x64, 0x30, 0x54, 0xe5, 0xe0, 
+-      0xc0, 0x40, 0xb0, 0x7f, 0x30, 0x54, 0xe9, 0xfb, 
+-      0x0c, 0x09, 0x05, 0x0d, 0xe1, 0xef, 0xc0, 0x5f, 
+-      0x10, 0x58, 0x10, 0x48, 0x00, 0xee, 0xd0, 0x8c, 
+-      0xd0, 0xc3, 0x70, 0x02, 0x30, 0x01, 0xea, 0x10, 
+-      0xb0, 0xbc, 0xb0, 0xc1, 0xee, 0x01, 0x00, 0x26, 
+-      0xd0, 0x20, 0x70, 0x40, 0xb0, 0x7f, 0x60, 0x40, 
+-      0x15, 0xa3, 0xea, 0x0f, 0xb0, 0x88, 0x77, 0xc2, 
+-      0x80, 0x07, 0x09, 0x49, 0xd4, 0x00, 0xd4, 0x40, 
+-      0xd4, 0x80, 0xd4, 0xc0, 0x00, 0x4d, 0xa0, 0x6c, 
+-      0xd3, 0x80, 0xd0, 0xa1, 0x00, 0x88, 0xd0, 0xa9, 
+-      0x00, 0x4d, 0x00, 0x50, 0xfa, 0x1a, 0x0c, 0x49, 
+-      0x00, 0x8d, 0xc0, 0x42, 0x10, 0x60, 0xea, 0x2a, 
+-      0xb0, 0x5e, 0xb0, 0x43, 0xfe, 0x34, 0xd0, 0x61, 
+-      0x23, 0x81, 0xe2, 0x1f, 0x0c, 0x09, 0x05, 0x0d, 
+-      0x15, 0x20, 0xfe, 0x31, 0xd0, 0x65, 0x30, 0x54, 
+-      0xee, 0x10, 0x03, 0xb4, 0xd6, 0x29, 0xe0, 0x46, 
+-      0xc6, 0xd4, 0xb6, 0xc1, 0xe6, 0x31, 0xd0, 0x64, 
+-      0x30, 0x5b, 0xfe, 0x31, 0xd7, 0x00, 0xb7, 0x01, 
+-      0xd3, 0x81, 0x00, 0x27, 0xd0, 0x10, 0xd0, 0x81, 
+-      0x60, 0x80, 0x15, 0x63, 0xfa, 0x54, 0x00, 0x22, 
+-      0xdc, 0xd8, 0x03, 0xf8, 0xd0, 0x10, 0xf0, 0x4a, 
+-      0x15, 0xa3, 0xfa, 0x51, 0x02, 0xf7, 0xdc, 0x26, 
+-      0x0c, 0x10, 0xf8, 0x46, 0x02, 0xfc, 0xd8, 0x22, 
+-      0xe0, 0x46, 0x02, 0xf2, 0xd6, 0x2b, 0xe0, 0x46, 
+-      0x00, 0x22, 0xdc, 0xd8, 0x03, 0xfa, 0xd0, 0x10, 
+-      0xf0, 0x4a, 0x03, 0x35, 0xda, 0x20, 0x15, 0xa3, 
+-      0xe8, 0x46, 0x03, 0x30, 0xdc, 0x27, 0xe0, 0x46, 
+-      0x03, 0x76, 0xd0, 0x73, 0x00, 0x24, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0xe1, 0xe0, 0xe1, 0xec, 0xe2, 0x12, 
+-      0xe2, 0x14, 0xe1, 0xc7, 0xe1, 0x30, 0x30, 0x5a, 
+-      0xe5, 0x8d, 0x06, 0x50, 0xe9, 0x83, 0xc0, 0x54, 
+-      0x30, 0x5b, 0xb0, 0x42, 0xf8, 0x11, 0x37, 0x1a, 
+-      0xb6, 0xff, 0xd0, 0x64, 0x30, 0x5b, 0xfc, 0x11, 
+-      0xc0, 0x39, 0x30, 0x31, 0x10, 0x12, 0x10, 0x20, 
+-      0xe9, 0x88, 0x03, 0x10, 0xe9, 0x93, 0x0f, 0x19, 
+-      0xf9, 0x8f, 0xd1, 0x44, 0xe1, 0x79, 0x03, 0xde, 
+-      0xf9, 0xba, 0x03, 0xdf, 0xe9, 0x99, 0xd3, 0x40, 
+-      0xca, 0x50, 0xd1, 0x42, 0xe2, 0xea, 0xc0, 0x50, 
+-      0x10, 0x54, 0xc0, 0x90, 0x10, 0x8c, 0x10, 0x92, 
+-      0x10, 0xe0, 0xe5, 0xa8, 0xc0, 0x01, 0x10, 0x01, 
+-      0x20, 0x40, 0xc0, 0x02, 0x10, 0x01, 0x20, 0x80, 
+-      0x10, 0x60, 0xfd, 0xab, 0xb0, 0x7f, 0x10, 0xa0, 
+-      0xfd, 0xae, 0xb0, 0xbf, 0x10, 0x5f, 0x10, 0x9f, 
+-      0x00, 0xef, 0xd0, 0x3e, 0x20, 0x52, 0x20, 0x83, 
+-      0x20, 0x93, 0x10, 0x4c, 0x10, 0x82, 0x40, 0x80, 
+-      0x50, 0x42, 0x0f, 0xc5, 0xcb, 0xaa, 0xcb, 0xeb, 
+-      0xca, 0x50, 0xd0, 0xc0, 0xb0, 0xc1, 0xf1, 0x9b, 
+-      0xcb, 0x01, 0xd0, 0xc1, 0xf1, 0x9b, 0xcb, 0x41, 
+-      0xba, 0x7f, 0xbb, 0x3f, 0xe2, 0xea, 0xcc, 0x5b, 
+-      0x1c, 0x42, 0x2c, 0x5b, 0xc0, 0x31, 0x1c, 0x43, 
+-      0x2c, 0x40, 0x1c, 0x48, 0xcc, 0xb1, 0x1c, 0x9f, 
+-      0x06, 0xd0, 0xe9, 0xd5, 0x01, 0x69, 0xd0, 0x20, 
+-      0x3c, 0x80, 0xc0, 0x1c, 0x10, 0x08, 0x20, 0x1f, 
+-      0x2c, 0x40, 0x2c, 0x80, 0x01, 0xb5, 0xd4, 0x00, 
+-      0x2c, 0x80, 0xde, 0x84, 0xde, 0xc4, 0xe3, 0x1e, 
+-      0xd3, 0xc2, 0xf2, 0xd3, 0x13, 0xa0, 0xed, 0xe5, 
+-      0xf2, 0x32, 0xb3, 0x81, 0xe9, 0xec, 0x80, 0x07, 
+-      0xd4, 0x00, 0xc4, 0x50, 0xd3, 0x08, 0xe2, 0x95, 
+-      0xd0, 0x71, 0x20, 0x56, 0x00, 0x48, 0xd1, 0x8c, 
+-      0x03, 0x0d, 0x41, 0x8c, 0xe9, 0xfa, 0x06, 0x5e, 
+-      0xfa, 0x03, 0x08, 0x89, 0x03, 0xcd, 0x13, 0xe3, 
+-      0xf9, 0xfa, 0xd3, 0xc4, 0x06, 0x5e, 0xfa, 0x03, 
+-      0xd0, 0x43, 0x40, 0x4c, 0xea, 0x03, 0x08, 0x49, 
+-      0x00, 0x8d, 0x10, 0x87, 0x53, 0x02, 0x01, 0x46, 
+-      0x90, 0x2c, 0x00, 0xc6, 0x03, 0x1c, 0xea, 0x0a, 
+-      0x09, 0x49, 0x00, 0x0d, 0xd0, 0x9f, 0x40, 0x02, 
+-      0xb0, 0x20, 0x03, 0x19, 0xea, 0x10, 0xb0, 0x20, 
+-      0xa0, 0x2c, 0xe2, 0x5b, 0x06, 0x5f, 0xfa, 0x80, 
+-      0xd4, 0x00, 0xc4, 0x50, 0xc4, 0x90, 0xc4, 0xd0, 
+-      0xe2, 0x8d, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 
+-      0x03, 0x76, 0xd0, 0x73, 0x00, 0x24, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0xe1, 0xd3, 0xe1, 0xdc, 0xe2, 0x00, 
+-      0xe2, 0x02, 0xe1, 0xac, 0xe1, 0x30, 0x30, 0x5a, 
+-      0xe5, 0x91, 0x06, 0x50, 0xe9, 0x83, 0xc0, 0x54, 
+-      0x30, 0x5b, 0xb0, 0x42, 0xf8, 0x11, 0x37, 0x1a, 
+-      0xb6, 0xff, 0xd0, 0x64, 0x30, 0x5b, 0xfc, 0x11, 
+-      0xbc, 0x10, 0xd0, 0x10, 0x0c, 0x1e, 0xf9, 0x8e, 
+-      0xbc, 0x10, 0xd0, 0x30, 0xc0, 0x40, 0x30, 0x70, 
+-      0xed, 0x8e, 0x03, 0x10, 0xe9, 0x97, 0x0f, 0x19, 
+-      0xf9, 0x93, 0xd1, 0x44, 0xe1, 0x79, 0x03, 0xdf, 
+-      0xe9, 0xa1, 0xd3, 0x40, 0xca, 0x50, 0xcb, 0x52, 
+-      0x03, 0x1d, 0xf9, 0xa8, 0xca, 0x12, 0xca, 0x52, 
+-      0xe1, 0xa5, 0x03, 0x1d, 0xf9, 0xa8, 0xca, 0x12, 
+-      0xca, 0x53, 0xca, 0xae, 0xca, 0xef, 0xb1, 0x7e, 
+-      0x03, 0x1e, 0xfa, 0xea, 0xb1, 0x7e, 0xe2, 0xea, 
+-      0x00, 0x24, 0xd0, 0x00, 0x2c, 0x40, 0x2c, 0x80, 
+-      0x17, 0x20, 0xf9, 0xd2, 0x00, 0xa8, 0xd0, 0x00, 
+-      0xcc, 0x5b, 0x1c, 0x5f, 0x1c, 0x43, 0x20, 0x31, 
+-      0x7c, 0x40, 0xb0, 0x3c, 0x7e, 0x80, 0xcc, 0xb1, 
+-      0xce, 0xfa, 0x1c, 0x9f, 0x1e, 0xdf, 0x01, 0x69, 
+-      0xd0, 0x3c, 0x0c, 0x99, 0xe9, 0xc4, 0x3c, 0x80, 
+-      0x0e, 0xd9, 0xe9, 0xc7, 0x3e, 0xc0, 0x3e, 0xf2, 
+-      0x3e, 0xb1, 0xd0, 0x01, 0x40, 0x1b, 0x10, 0x05, 
+-      0x20, 0x1f, 0x2c, 0x40, 0x2c, 0x80, 0xd0, 0x30, 
+-      0x70, 0x00, 0x2c, 0x80, 0xe3, 0x1e, 0xd3, 0xc2, 
+-      0xf2, 0xd3, 0x13, 0xa0, 0xed, 0xd8, 0xf2, 0x32, 
+-      0xb3, 0x81, 0xe9, 0xdc, 0x80, 0x07, 0xe2, 0x95, 
+-      0x0d, 0x09, 0xd1, 0x8c, 0x03, 0x0d, 0x41, 0x8c, 
+-      0xe9, 0xe8, 0x06, 0x5e, 0xf9, 0xf1, 0x08, 0x89, 
+-      0x03, 0xcd, 0x13, 0xe3, 0xf9, 0xe8, 0xd3, 0xc4, 
+-      0x06, 0x5e, 0xf9, 0xf1, 0xd0, 0x43, 0x40, 0x4c, 
+-      0xe9, 0xf1, 0x08, 0x49, 0x00, 0x8d, 0x10, 0x87, 
+-      0x53, 0x02, 0x01, 0x46, 0x90, 0x2c, 0x00, 0xc6, 
+-      0x03, 0x1c, 0xe9, 0xf8, 0x09, 0x49, 0x00, 0x0d, 
+-      0xd0, 0x9f, 0x40, 0x02, 0xb0, 0x20, 0x03, 0x19, 
+-      0xe9, 0xfe, 0xb0, 0x20, 0xa0, 0x2c, 0xe2, 0x5b, 
+-      0x06, 0x5f, 0xfa, 0x80, 0xd4, 0x00, 0xc4, 0x50, 
+-      0xc4, 0x90, 0xc4, 0xd0, 0xe2, 0x8d, 0x50, 0x00, 
+-      0x03, 0x76, 0xd0, 0x73, 0x00, 0x24, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0xe1, 0xc1, 0xe1, 0xca, 0xe1, 0xee, 
+-      0xe1, 0xf0, 0xe1, 0xa8, 0xe1, 0x30, 0x30, 0x5a, 
+-      0xe5, 0x8d, 0x06, 0x50, 0xe9, 0x83, 0xc0, 0x54, 
+-      0x30, 0x5b, 0xb0, 0x42, 0xf8, 0x11, 0x37, 0x1a, 
+-      0xb6, 0xff, 0xd0, 0x64, 0x30, 0x5b, 0xfc, 0x11, 
+-      0xc0, 0x39, 0x30, 0x31, 0x10, 0x12, 0x10, 0x20, 
+-      0xe9, 0x88, 0x03, 0x10, 0xe9, 0x93, 0x0f, 0x19, 
+-      0xf9, 0x8f, 0xd1, 0x44, 0xe1, 0x79, 0x03, 0xdf, 
+-      0xe9, 0x9d, 0xd3, 0x40, 0xca, 0x50, 0xcb, 0x52, 
+-      0x03, 0x1d, 0xf9, 0xa4, 0xca, 0x12, 0xca, 0x52, 
+-      0xe1, 0xa1, 0x03, 0x1d, 0xf9, 0xa4, 0xca, 0x12, 
+-      0xca, 0x53, 0xca, 0xae, 0xca, 0xef, 0xb1, 0x7e, 
+-      0x03, 0x1e, 0xfa, 0xea, 0xb1, 0x7e, 0xe2, 0xea, 
+-      0xcc, 0x5b, 0x1c, 0x42, 0x2c, 0x5b, 0xc0, 0x31, 
+-      0x1c, 0x43, 0x2c, 0x40, 0x1c, 0x48, 0xcc, 0xb1, 
+-      0x1c, 0x9f, 0x06, 0xd0, 0xe9, 0xb6, 0x01, 0x69, 
+-      0xd0, 0x20, 0x3c, 0x80, 0xc0, 0x1c, 0x10, 0x08, 
+-      0x20, 0x1f, 0x2c, 0x40, 0x2c, 0x80, 0xd0, 0x30, 
+-      0x70, 0x00, 0x2c, 0x80, 0xde, 0x84, 0xde, 0xc4, 
+-      0xe3, 0x1e, 0xd3, 0xc2, 0xf2, 0xd3, 0x13, 0xa0, 
+-      0xed, 0xc6, 0xf2, 0x32, 0xb3, 0x81, 0xe9, 0xca, 
+-      0x80, 0x07, 0xe2, 0x95, 0x0d, 0x09, 0xd1, 0x8c, 
+-      0x03, 0x0d, 0x41, 0x8c, 0xe9, 0xd6, 0x06, 0x5e, 
+-      0xf9, 0xdf, 0x08, 0x89, 0x03, 0xcd, 0x13, 0xe3, 
+-      0xf9, 0xd6, 0xd3, 0xc4, 0x06, 0x5e, 0xf9, 0xdf, 
+-      0xd0, 0x43, 0x40, 0x4c, 0xe9, 0xdf, 0x08, 0x49, 
+-      0x00, 0x8d, 0x10, 0x87, 0x53, 0x02, 0x01, 0x46, 
+-      0x90, 0x2c, 0x00, 0xc6, 0x03, 0x1c, 0xe9, 0xe6, 
+-      0x09, 0x49, 0x00, 0x0d, 0xd0, 0x9f, 0x40, 0x02, 
+-      0xb0, 0x20, 0x03, 0x19, 0xe9, 0xec, 0xb0, 0x20, 
+-      0xa0, 0x2c, 0xe2, 0x5b, 0x06, 0x5f, 0xfa, 0x80, 
+-      0xd4, 0x00, 0xc4, 0x50, 0xc4, 0x90, 0xc4, 0xd0, 
+-      0xe2, 0x8d, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 
+-      0x03, 0x76, 0xd0, 0x73, 0x00, 0x24, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0xe1, 0xdb, 0xe1, 0xe9, 0xe2, 0x00, 
+-      0xe2, 0x02, 0xe1, 0xc3, 0xe1, 0x65, 0x30, 0x5a, 
+-      0xe5, 0x8d, 0x06, 0x50, 0xe9, 0x83, 0xc0, 0x54, 
+-      0x30, 0x5b, 0xb0, 0x42, 0xf8, 0x11, 0x37, 0x1a, 
+-      0xb6, 0xff, 0xd0, 0x52, 0x30, 0x5b, 0xfc, 0x11, 
+-      0xc0, 0x39, 0x30, 0x31, 0x10, 0x11, 0x10, 0x20, 
+-      0xe9, 0x88, 0x03, 0x10, 0xe9, 0x93, 0x0f, 0x19, 
+-      0xf9, 0x8f, 0xd1, 0x44, 0xe1, 0x79, 0x03, 0xd0, 
+-      0xf9, 0x98, 0xca, 0x50, 0x03, 0xde, 0xf9, 0x9a, 
+-      0xd1, 0x42, 0xe2, 0xea, 0xcb, 0xaa, 0xcb, 0xeb, 
+-      0xc0, 0x50, 0x10, 0x54, 0xc0, 0x90, 0x10, 0x8c, 
+-      0x10, 0x92, 0xd0, 0xc1, 0x05, 0x50, 0xe9, 0xa5, 
+-      0xb0, 0xc2, 0x10, 0x60, 0xfd, 0xa8, 0xb0, 0x7f, 
+-      0x10, 0xa0, 0xfd, 0xab, 0xb0, 0xbf, 0x10, 0x5f, 
+-      0x10, 0x9f, 0x00, 0xef, 0xd0, 0x3e, 0x20, 0x52, 
+-      0x20, 0x83, 0x20, 0x93, 0x10, 0x4c, 0x10, 0x82, 
+-      0x40, 0x80, 0x50, 0x42, 0xd0, 0x81, 0x14, 0x1f, 
+-      0x14, 0x01, 0x05, 0x50, 0xe9, 0xbd, 0x50, 0x42, 
+-      0xe1, 0xbe, 0x54, 0x02, 0xca, 0x10, 0xca, 0x50, 
+-      0xcb, 0x01, 0xcb, 0x41, 0xe2, 0xea, 0xcc, 0x5b, 
+-      0x1c, 0x42, 0x2c, 0x5b, 0xc0, 0x31, 0x1c, 0x43, 
+-      0x2c, 0x40, 0x1c, 0x49, 0xcc, 0xb1, 0x1c, 0x9f, 
+-      0xc0, 0x1c, 0x10, 0x08, 0x20, 0x1f, 0x05, 0x50, 
+-      0xf9, 0xd2, 0xb0, 0x3c, 0x2c, 0x40, 0x2c, 0x80, 
+-      0x01, 0xb5, 0xd4, 0x00, 0x2c, 0x80, 0x02, 0xe4, 
+-      0xde, 0x80, 0xde, 0xc1, 0xe3, 0x1e, 0xd3, 0xc0, 
+-      0xf2, 0xd3, 0x13, 0xa0, 0xed, 0xe0, 0xf2, 0x32, 
+-      0xb3, 0x81, 0xe9, 0xe9, 0x80, 0x07, 0xd4, 0x02, 
+-      0x44, 0x15, 0x14, 0x1f, 0xc4, 0x50, 0xd3, 0x08, 
+-      0xe2, 0x95, 0xd0, 0x71, 0x20, 0x56, 0x00, 0x48, 
+-      0xd1, 0x8c, 0x03, 0x0d, 0x41, 0x8c, 0xe9, 0xf7, 
+-      0x08, 0x89, 0x03, 0xcd, 0x13, 0xe3, 0xf9, 0xf6, 
+-      0xd3, 0xc4, 0xe1, 0xf7, 0xb3, 0xc1, 0x01, 0x46, 
+-      0x90, 0x2c, 0x00, 0xc6, 0x03, 0x1c, 0xe9, 0xfe, 
+-      0x09, 0x49, 0x00, 0x0d, 0xa0, 0x2c, 0xe2, 0x5b, 
+-      0x06, 0x5f, 0xfa, 0x7f, 0xd4, 0x02, 0x44, 0x15, 
+-      0x14, 0x1f, 0xc4, 0x50, 0xc4, 0x90, 0xc4, 0xd0, 
+-      0xe2, 0x8d, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 
+-      0x03, 0x76, 0xd0, 0x73, 0x00, 0x24, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0xe1, 0xc9, 0xe1, 0xd2, 0xe1, 0xe7, 
+-      0xe1, 0xe9, 0xe1, 0xab, 0xe1, 0x30, 0x30, 0x5a, 
+-      0xe5, 0x91, 0x06, 0x50, 0xe9, 0x83, 0xc0, 0x54, 
+-      0x30, 0x5b, 0xb0, 0x42, 0xf8, 0x11, 0x37, 0x1a, 
+-      0xb6, 0xff, 0xd0, 0x52, 0x30, 0x5b, 0xfc, 0x11, 
+-      0xbc, 0x10, 0xd0, 0x10, 0x0c, 0x1e, 0xf9, 0x8e, 
+-      0xbc, 0x10, 0xd0, 0x20, 0xc0, 0x40, 0x30, 0x70, 
+-      0xed, 0x8e, 0x03, 0x10, 0xe9, 0x97, 0x0f, 0x19, 
+-      0xf9, 0x93, 0xd1, 0x44, 0xe1, 0x79, 0x03, 0xd0, 
+-      0xf9, 0xa0, 0xca, 0x50, 0xcb, 0x52, 0x03, 0x1d, 
+-      0xf9, 0xa7, 0xca, 0x12, 0xca, 0x52, 0xe1, 0xa4, 
+-      0x03, 0x1d, 0xf9, 0xa7, 0xca, 0x12, 0xca, 0x53, 
+-      0xca, 0xae, 0xca, 0xef, 0xb1, 0x7e, 0x03, 0x1e, 
+-      0xfa, 0xea, 0xb1, 0x7e, 0xe2, 0xea, 0x00, 0x24, 
+-      0xd0, 0x00, 0x2c, 0x40, 0x2c, 0x80, 0x17, 0x20, 
+-      0xf9, 0xc8, 0x00, 0x2a, 0xd0, 0x00, 0x20, 0x1b, 
+-      0x20, 0x1b, 0x05, 0x50, 0xf9, 0xb8, 0xb0, 0x3f, 
+-      0x10, 0x02, 0x7c, 0x40, 0xcc, 0xb1, 0x1c, 0x9f, 
+-      0x01, 0x69, 0xd0, 0x3c, 0x0c, 0x99, 0xe9, 0xc1, 
+-      0x3c, 0x80, 0xde, 0xa0, 0x2c, 0x5f, 0x2c, 0x9f, 
+-      0xd0, 0x30, 0x70, 0x00, 0x2c, 0x80, 0xde, 0xc1, 
+-      0xe3, 0x1e, 0xd3, 0xc0, 0xf2, 0xd3, 0x13, 0xa0, 
+-      0xed, 0xce, 0xf2, 0x32, 0xb3, 0x81, 0xe9, 0xd2, 
+-      0x80, 0x07, 0xe2, 0x95, 0x0d, 0x09, 0xd1, 0x8c, 
+-      0x03, 0x0d, 0x41, 0x8c, 0xe9, 0xde, 0x08, 0x89, 
+-      0x03, 0xcd, 0x13, 0xe3, 0xf9, 0xdd, 0xd3, 0xc4, 
+-      0xe1, 0xde, 0xb3, 0xc1, 0x01, 0x46, 0x90, 0x2c, 
+-      0x00, 0xc6, 0x03, 0x1c, 0xe9, 0xe5, 0x09, 0x49, 
+-      0x00, 0x0d, 0xa0, 0x2c, 0xe2, 0x5b, 0x06, 0x5f, 
+-      0xfa, 0x7f, 0xd4, 0x00, 0xc4, 0x50, 0xc4, 0x90, 
+-      0xc4, 0xd0, 0xe2, 0x8d, 0x50, 0x00, 0x50, 0x00, 
+-      0x03, 0x76, 0xd0, 0x73, 0x00, 0x24, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0xe1, 0xa3, 0xc0, 0x00, 0xc0, 0x00, 
+-      0xc0, 0x00, 0xe1, 0x8a, 0xe1, 0x30, 0x30, 0x5a, 
+-      0xe5, 0x87, 0x37, 0x1a, 0xb6, 0xff, 0xd0, 0x64, 
+-      0x30, 0x5b, 0xfd, 0xb4, 0xc0, 0x39, 0x30, 0x31, 
+-      0x10, 0x12, 0x10, 0x20, 0xe9, 0x82, 0xd1, 0x42, 
+-      0xd3, 0x40, 0xe2, 0xea, 0xcc, 0x5b, 0x1c, 0x42, 
+-      0x2c, 0x5b, 0xc0, 0x31, 0x1c, 0x43, 0x2c, 0x40, 
+-      0x1c, 0x48, 0xcc, 0xb1, 0x1c, 0x9f, 0x06, 0xd0, 
+-      0xe9, 0x98, 0x01, 0x69, 0xd0, 0x20, 0x3c, 0x80, 
+-      0xc0, 0x1c, 0x10, 0x08, 0x20, 0x1f, 0x2c, 0x40, 
+-      0x2c, 0x80, 0x01, 0xb5, 0xd4, 0x00, 0x2c, 0x80, 
+-      0xde, 0x84, 0xde, 0xc4, 0xe3, 0x1e, 0xf2, 0xd3, 
+-      0xc0, 0x5c, 0xb0, 0x7f, 0x30, 0x5a, 0xe5, 0xc8, 
+-      0x00, 0x26, 0xd0, 0x00, 0x70, 0x00, 0x10, 0x20, 
+-      0xe9, 0xbf, 0x00, 0xe0, 0xd0, 0x44, 0x70, 0x41, 
+-      0x10, 0x5c, 0x30, 0x5b, 0xb0, 0x41, 0xed, 0xc8, 
+-      0x0f, 0x17, 0xf9, 0xb4, 0x0f, 0x49, 0xf2, 0xd3, 
+-      0x0f, 0x19, 0xf9, 0xb8, 0xdf, 0x00, 0x00, 0x06, 
+-      0x03, 0xb4, 0xd6, 0x29, 0xe0, 0x46, 0xc0, 0x5b, 
+-      0x30, 0x54, 0xb0, 0x7e, 0xe5, 0xc8, 0x0f, 0x17, 
+-      0xf9, 0xc3, 0x02, 0xf2, 0xd6, 0x2b, 0xe0, 0x46, 
+-      0xd3, 0x08, 0xd3, 0xc0, 0xe2, 0x95, 0x50, 0x00, 
+-      0x03, 0x76, 0xd0, 0x73, 0x00, 0x24, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0xe1, 0xb5, 0xc0, 0x00, 0xc0, 0x00, 
+-      0xc0, 0x00, 0xe1, 0x8e, 0xe1, 0x30, 0x30, 0x5a, 
+-      0xe5, 0x8b, 0x37, 0x1a, 0xb6, 0xff, 0xd0, 0x64, 
+-      0x30, 0x5b, 0xfd, 0xc6, 0xbc, 0x10, 0xd0, 0x10, 
+-      0x0c, 0x1e, 0xf9, 0x88, 0xbc, 0x10, 0xd0, 0x30, 
+-      0xc0, 0x40, 0x30, 0x70, 0xed, 0x88, 0xd1, 0x42, 
+-      0xd3, 0x40, 0xe2, 0xea, 0x00, 0x24, 0xd0, 0x00, 
+-      0x2c, 0x40, 0x2c, 0x80, 0x17, 0x20, 0xf9, 0xb4, 
+-      0x00, 0xa8, 0xd0, 0x00, 0xcc, 0x5b, 0x1c, 0x5f, 
+-      0x1c, 0x43, 0x20, 0x31, 0x7c, 0x40, 0xb0, 0x3c, 
+-      0x7e, 0x80, 0xcc, 0xb1, 0xce, 0xfa, 0x1c, 0x9f, 
+-      0x1e, 0xdf, 0x01, 0x69, 0xd0, 0x3c, 0x0c, 0x99, 
+-      0xe9, 0xa6, 0x3c, 0x80, 0x0e, 0xd9, 0xe9, 0xa9, 
+-      0x3e, 0xc0, 0x3e, 0xf2, 0x3e, 0xb1, 0xd0, 0x01, 
+-      0x40, 0x1b, 0x10, 0x05, 0x20, 0x1f, 0x2c, 0x40, 
+-      0x2c, 0x80, 0xd0, 0x30, 0x70, 0x00, 0x2c, 0x80, 
+-      0xe3, 0x1e, 0xf2, 0xd3, 0xc0, 0x5c, 0xb0, 0x7f, 
+-      0x30, 0x5a, 0xe5, 0xda, 0x00, 0x26, 0xd0, 0x00, 
+-      0x70, 0x00, 0x10, 0x20, 0xe9, 0xd1, 0x00, 0xe0, 
+-      0xd0, 0x44, 0x70, 0x41, 0x10, 0x5c, 0x30, 0x5b, 
+-      0xb0, 0x41, 0xed, 0xda, 0x0f, 0x17, 0xf9, 0xc6, 
+-      0x0f, 0x49, 0xf2, 0xd3, 0x0f, 0x19, 0xf9, 0xca, 
+-      0xdf, 0x00, 0x00, 0x06, 0x03, 0xb4, 0xd6, 0x29, 
+-      0xe0, 0x46, 0xc0, 0x5b, 0x30, 0x54, 0xb0, 0x7e, 
+-      0xe5, 0xda, 0x0f, 0x17, 0xf9, 0xd5, 0x02, 0xf7, 
+-      0xdc, 0x26, 0xe0, 0x46, 0xd3, 0x08, 0xd3, 0xc0, 
+-      0xe2, 0x95, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 
+-      0x03, 0x76, 0xd0, 0x73, 0x00, 0x24, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0xe1, 0xa2, 0xc0, 0x00, 0xc0, 0x00, 
+-      0xc0, 0x00, 0xe1, 0x8a, 0xe1, 0x65, 0x30, 0x5a, 
+-      0xe5, 0x87, 0x37, 0x1a, 0xb6, 0xff, 0xd0, 0x52, 
+-      0x30, 0x5b, 0xfd, 0xb3, 0xc0, 0x39, 0x30, 0x31, 
+-      0x10, 0x11, 0x10, 0x20, 0xe9, 0x82, 0xd1, 0x42, 
+-      0xd3, 0x41, 0xe2, 0xea, 0xcc, 0x5b, 0x1c, 0x42, 
+-      0x2c, 0x5b, 0xc0, 0x31, 0x1c, 0x43, 0x2c, 0x40, 
+-      0x1c, 0x49, 0xcc, 0xb1, 0x1c, 0x9f, 0xc0, 0x1c, 
+-      0x10, 0x08, 0x20, 0x1f, 0x05, 0x50, 0xf9, 0x99, 
+-      0xb0, 0x3c, 0x2c, 0x40, 0x2c, 0x80, 0x01, 0xb5, 
+-      0xd4, 0x00, 0x2c, 0x80, 0x02, 0xe4, 0xde, 0x80, 
+-      0xde, 0xc1, 0xe3, 0x1e, 0xf2, 0xd3, 0xc0, 0x5c, 
+-      0xb0, 0x7f, 0x30, 0x5a, 0xe5, 0xc7, 0x00, 0x26, 
+-      0xd0, 0x00, 0x70, 0x00, 0x10, 0x20, 0xe9, 0xbe, 
+-      0x00, 0xe0, 0xd0, 0x44, 0x70, 0x41, 0x10, 0x5b, 
+-      0x30, 0x5b, 0xb0, 0x41, 0xed, 0xc7, 0x0f, 0x17, 
+-      0xf9, 0xb3, 0x0f, 0x49, 0xf2, 0xd3, 0x0f, 0x19, 
+-      0xf9, 0xb7, 0xdf, 0x00, 0x00, 0x06, 0x03, 0xb4, 
+-      0xd6, 0x29, 0xe0, 0x46, 0xc0, 0x5b, 0x30, 0x54, 
+-      0xb0, 0x7e, 0xe5, 0xc7, 0x0f, 0x17, 0xf9, 0xc2, 
+-      0x03, 0x30, 0xdc, 0x27, 0xe0, 0x46, 0xd3, 0x08, 
+-      0xd3, 0xc0, 0xe2, 0x95, 0x50, 0x00, 0x50, 0x00, 
+-      0x03, 0x76, 0xd0, 0x73, 0x00, 0x24, 0xdc, 0xd8, 
+-      0xf0, 0x4a, 0xe1, 0xac, 0xc0, 0x00, 0xc0, 0x00, 
+-      0xc0, 0x00, 0xe1, 0x8e, 0xe1, 0x30, 0x30, 0x5a, 
+-      0xe5, 0x8b, 0x37, 0x1a, 0xb6, 0xff, 0xd0, 0x52, 
+-      0x30, 0x5b, 0xfd, 0xbd, 0xbc, 0x10, 0xd0, 0x10, 
+-      0x0c, 0x1e, 0xf9, 0x88, 0xbc, 0x10, 0xd0, 0x20, 
+-      0xc0, 0x40, 0x30, 0x70, 0xed, 0x88, 0xd1, 0x42, 
+-      0xd3, 0x41, 0xe2, 0xea, 0x00, 0x24, 0xd0, 0x00, 
+-      0x2c, 0x40, 0x2c, 0x80, 0x17, 0x20, 0xf9, 0xab, 
+-      0x00, 0x2a, 0xd0, 0x00, 0x20, 0x1b, 0x20, 0x1b, 
+-      0x05, 0x50, 0xf9, 0x9b, 0xb0, 0x3f, 0x10, 0x02, 
+-      0x7c, 0x40, 0xcc, 0xb1, 0x1c, 0x9f, 0x01, 0x69, 
+-      0xd0, 0x3c, 0x0c, 0x99, 0xe9, 0xa4, 0x3c, 0x80, 
+-      0xde, 0xa0, 0x2c, 0x5f, 0x2c, 0x9f, 0xd0, 0x30, 
+-      0x70, 0x00, 0x2c, 0x80, 0xde, 0xc1, 0xe3, 0x1e, 
+-      0xf2, 0xd3, 0xc0, 0x5c, 0xb0, 0x7f, 0x30, 0x5a, 
+-      0xe5, 0xd1, 0x00, 0x26, 0xd0, 0x00, 0x70, 0x00, 
+-      0x10, 0x20, 0xe9, 0xc8, 0x00, 0xe0, 0xd0, 0x44, 
+-      0x70, 0x41, 0x10, 0x5b, 0x30, 0x5b, 0xb0, 0x41, 
+-      0xed, 0xd1, 0x0f, 0x17, 0xf9, 0xbd, 0x0f, 0x49, 
+-      0xf2, 0xd3, 0x0f, 0x19, 0xf9, 0xc1, 0xdf, 0x00, 
+-      0x00, 0x06, 0x03, 0xb4, 0xd6, 0x29, 0xe0, 0x46, 
+-      0xc0, 0x5b, 0x30, 0x54, 0xb0, 0x7e, 0xe5, 0xd1, 
+-      0x0f, 0x17, 0xf9, 0xcc, 0x03, 0x35, 0xda, 0x20, 
+-      0xe0, 0x46, 0xd3, 0x08, 0xd3, 0xc0, 0xe2, 0x95, 
+-      0xd0, 0x61, 0x23, 0x81, 0x0c, 0x49, 0xd0, 0x61, 
+-      0x00, 0x8d, 0x10, 0xa0, 0xea, 0x3b, 0x30, 0x42, 
+-      0xe6, 0x30, 0x23, 0x82, 0x0f, 0xc5, 0x0c, 0x09, 
+-      0x05, 0x0d, 0x15, 0x20, 0xfe, 0x45, 0xd0, 0x65, 
+-      0x15, 0x63, 0xea, 0x43, 0xd0, 0x53, 0x30, 0x54, 
+-      0xee, 0x4a, 0x0f, 0x17, 0xfa, 0x45, 0x03, 0xb4, 
+-      0xd6, 0x29, 0xe0, 0x46, 0x80, 0x07, 0x09, 0x49, 
+-      0xd4, 0x00, 0xd4, 0x40, 0xd4, 0x80, 0xd4, 0xc0, 
+-      0x00, 0x4d, 0xa0, 0x6c, 0xd0, 0xa1, 0x00, 0x88, 
+-      0xd0, 0xa9, 0x00, 0x4d, 0x00, 0x50, 0xfa, 0x53, 
+-      0xf2, 0x32, 0xd3, 0x80, 0xe1, 0x76, 0xd1, 0xc2, 
+-      0x41, 0xcf, 0x11, 0xdf, 0xd0, 0x41, 0x01, 0xc1, 
+-      0x00, 0xef, 0xd0, 0xbe, 0x03, 0x10, 0xf9, 0x77, 
+-      0x80, 0x07, 0x21, 0x96, 0x11, 0xa2, 0xe9, 0x78, 
+-      0x03, 0x1d, 0xea, 0x73, 0xc0, 0xd7, 0xc2, 0x90, 
+-      0xf2, 0xa4, 0xc4, 0x0a, 0x03, 0xd0, 0xea, 0x72, 
+-      0xc2, 0x91, 0xf2, 0xa4, 0xc4, 0x4a, 0x03, 0x1e, 
+-      0xea, 0x8d, 0xc0, 0xd8, 0xc2, 0x92, 0xf2, 0xa4, 
+-      0xc4, 0x8a, 0x03, 0xd0, 0xea, 0x7d, 0xc2, 0x93, 
+-      0xf2, 0xa4, 0xc4, 0xca, 0xe2, 0x8d, 0xd3, 0xc0, 
+-      0xc0, 0xd7, 0xc2, 0x90, 0xf2, 0xa4, 0xc4, 0x0a, 
+-      0x03, 0xd0, 0xea, 0x88, 0xc2, 0x91, 0xf2, 0xa4, 
+-      0xc4, 0x4a, 0x08, 0x49, 0x00, 0x4d, 0x10, 0x61, 
+-      0xf8, 0x11, 0x03, 0x1f, 0xea, 0x93, 0x0d, 0xc9, 
+-      0x00, 0x4d, 0xd0, 0x1a, 0xe2, 0x98, 0x03, 0x10, 
+-      0xfa, 0x97, 0xd0, 0x1d, 0xe2, 0x98, 0xd0, 0x18, 
+-      0x0f, 0x16, 0xfa, 0x98, 0xd0, 0x4c, 0x40, 0x4c, 
+-      0x10, 0x6c, 0xea, 0xa2, 0x03, 0xde, 0xfa, 0xa2, 
+-      0x0f, 0x12, 0xfa, 0xa0, 0x00, 0x08, 0xe2, 0xd9, 
+-      0xd2, 0x00, 0x13, 0xe1, 0xee, 0xa9, 0x08, 0x49, 
+-      0x02, 0x0d, 0x00, 0xc8, 0xc2, 0xca, 0x12, 0x94, 
+-      0xd0, 0x1f, 0x30, 0x07, 0x12, 0xc0, 0xc2, 0x43, 
+-      0x12, 0x5a, 0x00, 0x0d, 0x03, 0xde, 0xea, 0xb6, 
+-      0x0e, 0xc9, 0x04, 0x8d, 0x02, 0x48, 0x22, 0x80, 
+-      0x12, 0x88, 0xd0, 0x0b, 0x30, 0x03, 0x12, 0x80, 
+-      0xd0, 0x19, 0x20, 0x03, 0x12, 0x80, 0x00, 0x0d, 
+-      0x22, 0xc0, 0x12, 0xc8, 0xd0, 0x0b, 0x30, 0x09, 
+-      0x12, 0xc0, 0x12, 0xd8, 0xd0, 0x16, 0x20, 0x09, 
+-      0x20, 0x07, 0x12, 0xc0, 0x42, 0xc2, 0x22, 0x8b, 
+-      0x22, 0x88, 0x03, 0xde, 0xea, 0xd2, 0x0e, 0xc9, 
+-      0xc4, 0x4a, 0x04, 0xcd, 0x0f, 0xc5, 0x01, 0x46, 
+-      0x90, 0x4d, 0x00, 0xc6, 0x10, 0x60, 0xe6, 0xd3, 
+-      0x0f, 0xc5, 0x01, 0xb5, 0xd4, 0x00, 0xca, 0x9d, 
+-      0xcb, 0x9e, 0xca, 0xea, 0xcb, 0xee, 0x2a, 0xc0, 
+-      0x2b, 0xc0, 0xca, 0x10, 0xca, 0x51, 0xcb, 0x12, 
+-      0xcb, 0x53, 0xd1, 0x40, 0xd3, 0x41, 0xb7, 0x3f, 
+-      0xc0, 0x5c, 0xe1, 0x7b, 0xd0, 0xc0, 0xc1, 0x28, 
+-      0xc2, 0x2a, 0xc2, 0xab, 0xf1, 0x7a, 0x0f, 0x17, 
+-      0xfa, 0xef, 0xcc, 0xe8, 0xcd, 0x29, 0xcd, 0x6c, 
+-      0xcd, 0xad, 0xc8, 0x08, 0xc8, 0x49, 0xca, 0x0a, 
+-      0xca, 0x4b, 0xf3, 0x31, 0xd0, 0xc1, 0xc1, 0x34, 
+-      0xc2, 0x2a, 0xc2, 0xab, 0xf1, 0x7a, 0x00, 0x28, 
+-      0xd9, 0xc0, 0xc8, 0x88, 0xc8, 0xc9, 0xa9, 0xf8, 
+-      0xca, 0x8a, 0xca, 0xcb, 0x11, 0x62, 0xe9, 0x79, 
+-      0xd0, 0xc0, 0xc1, 0x35, 0xc2, 0x2e, 0xc2, 0xaf, 
+-      0xf1, 0x7a, 0xc9, 0x08, 0xc9, 0x49, 0xa9, 0xf8, 
+-      0xcb, 0x0a, 0xcb, 0x4b, 0xd0, 0xc1, 0xc1, 0x36, 
+-      0xc2, 0x2e, 0xc2, 0xaf, 0xf1, 0x7a, 0xc0, 0x27, 
+-      0xc9, 0x88, 0xc9, 0xc9, 0xa0, 0x38, 0xcb, 0x8a, 
+-      0xcb, 0xcb, 0xe1, 0x79, 0x5f, 0x0d, 0x07, 0x7d, 
+-      0xde, 0x07, 0x11, 0x5e, 0x30, 0x05, 0xcd, 0xc0, 
+-      0x00, 0x28, 0xd0, 0x00, 0xa0, 0x38, 0x11, 0x61, 
+-      0xf9, 0x75, 0x00, 0xe2, 0xd0, 0x00, 0x0f, 0x1d, 
+-      0xeb, 0x29, 0x00, 0x2d, 0xdf, 0x4b, 0xf3, 0x3f, 
+-      0xe1, 0x75, 0x04, 0xeb, 0xd0, 0x00, 0x11, 0x62, 
+-      0xeb, 0x36, 0xb0, 0x20, 0x0f, 0x19, 0xfb, 0x36, 
+-      0xac, 0xe0, 0x01, 0xa4, 0xde, 0x00, 0x5e, 0x0d, 
+-      0x00, 0x2d, 0xdf, 0x7a, 0xdd, 0xc0, 0xd8, 0x80, 
+-      0xd9, 0x00, 0xd9, 0x80, 0x5f, 0x00, 0x01, 0x46, 
+-      0x00, 0x28, 0xd0, 0x01, 0x00, 0x06, 0xa0, 0x37, 
+-      0x80, 0x3f, 0x00, 0xc6, 0x0f, 0xc5, 0xad, 0xda, 
+-      0xc6, 0xb1, 0xd0, 0x01, 0x01, 0xa3, 0xde, 0x1d, 
+-      0x40, 0x30, 0x3e, 0x00, 0x80, 0x3f, 0x0e, 0x0a, 
+-      0x66, 0xda, 0xc8, 0x28, 0xc8, 0x69, 0xc8, 0xaa, 
+-      0xc8, 0xeb, 0x0c, 0x1e, 0xfb, 0x68, 0x26, 0xba, 
+-      0x07, 0x7d, 0xdc, 0x00, 0x1d, 0xcf, 0x1d, 0xd1, 
+-      0x5d, 0xc0, 0x00, 0x2d, 0xdf, 0x64, 0x0f, 0x87, 
+-      0xad, 0xda, 0x80, 0x3f, 0x0e, 0x0a, 0x66, 0xda, 
+-      0xc9, 0x2c, 0xc9, 0x6d, 0xc9, 0xae, 0xc9, 0xef, 
+-      0x0f, 0x2f, 0xd0, 0x37, 0x4f, 0x00, 0x0f, 0x1a, 
+-      0xeb, 0xbe, 0x01, 0xa4, 0xde, 0x20, 0xd0, 0x01, 
+-      0x40, 0x3c, 0x2e, 0x00, 0x00, 0x2d, 0xdf, 0x7a, 
+-      0xac, 0xe0, 0x0f, 0x87, 0x0e, 0x0a, 0x76, 0xe0, 
+-      0xbf, 0x79, 0xbe, 0x3c, 0x0f, 0x1b, 0xeb, 0x9e, 
+-      0x0f, 0x87, 0x0e, 0x0a, 0x76, 0xe1, 0xbf, 0x79, 
+-      0xbe, 0x34, 0x18, 0xa0, 0xeb, 0xb9, 0x0f, 0x87, 
+-      0xad, 0x20, 0x80, 0x3f, 0x0e, 0x0a, 0x76, 0xe2, 
+-      0xbf, 0x79, 0xbe, 0x3c, 0x0f, 0x87, 0x0e, 0x0a, 
+-      0x76, 0xe3, 0x0f, 0x1b, 0xeb, 0xb3, 0xbf, 0x77, 
+-      0xbe, 0x0c, 0x19, 0x20, 0xeb, 0xb9, 0x0f, 0x87, 
+-      0xad, 0x60, 0x80, 0x3f, 0x0e, 0x0a, 0x76, 0xe4, 
+-      0xbe, 0x3c, 0xbf, 0x75, 0x0f, 0x15, 0xf8, 0x1c, 
+-      0x1f, 0x0a, 0x1f, 0x16, 0x0f, 0x87, 0x0e, 0x0a, 
+-      0x76, 0xe5, 0xbf, 0x79, 0xbe, 0x34, 0x19, 0xa0, 
+-      0xeb, 0xb9, 0x0f, 0x87, 0xad, 0xa0, 0x80, 0x3f, 
+-      0x0e, 0x0a, 0x76, 0xe6, 0xbe, 0x3c, 0xbf, 0x79, 
+-      0x0f, 0x87, 0x0e, 0x0a, 0x76, 0xe7, 0x0f, 0x15, 
+-      0xeb, 0xbe, 0x00, 0x2f, 0xdf, 0x72, 0x1d, 0xe0, 
+-      0xf8, 0x1c, 0x00, 0x28, 0xd0, 0x01, 0xa0, 0x38, 
+-      0x80, 0x3f, 0x0f, 0x87, 0xd0, 0x01, 0x4d, 0xc0, 
+-      0x1f, 0x0f, 0x1f, 0x11, 0x00, 0x2f, 0xdf, 0x76, 
+-      0xc6, 0xb2, 0x03, 0x7d, 0xde, 0x0e, 0x01, 0xa3, 
+-      0xde, 0x2d, 0x5d, 0xc0, 0x0f, 0x87, 0x1e, 0xe1, 
+-      0xeb, 0xdb, 0xad, 0xda, 0x80, 0x3f, 0x0e, 0x0a, 
+-      0x66, 0xda, 0x0c, 0x1e, 0xfb, 0xe4, 0x26, 0xbb, 
+-      0x03, 0xff, 0xdd, 0xff, 0x4d, 0xc0, 0x00, 0xa3, 
+-      0xde, 0x2d, 0xbf, 0x56, 0x0f, 0x87, 0x07, 0x7d, 
+-      0xde, 0x0e, 0x5d, 0xc0, 0x00, 0xa3, 0xde, 0x1d, 
+-      0xad, 0xda, 0x80, 0x3f, 0x0e, 0x0a, 0x66, 0xda, 
+-      0xdf, 0x5c, 0xd0, 0x0e, 0x4f, 0x00, 0x0f, 0x87, 
+-      0xd0, 0x06, 0x40, 0x3c, 0xeb, 0xf0, 0xbf, 0x3e, 
+-      0xb0, 0x04, 0xe7, 0xf2, 0xeb, 0xf6, 0xbf, 0x0c, 
+-      0xbf, 0x3a, 0x0f, 0x87, 0x0f, 0x1d, 0xfb, 0x4b, 
+-      0xbf, 0x38, 0x0f, 0x87, 0x0f, 0x1c, 0xfb, 0xcb, 
+-      0xbf, 0x30, 0x0f, 0x87, 0x50, 0x00, 0x50, 0x00, 
+-      0x0f, 0x17, 0xf9, 0x70, 0x90, 0x4d, 0x10, 0x60, 
+-      0xe5, 0x72, 0x0f, 0x49, 0x90, 0x4d, 0x10, 0x60, 
+-      0xe5, 0x76, 0x0f, 0x19, 0xf9, 0x79, 0x01, 0x46, 
+-      0xd0, 0x11, 0xa0, 0x38, 0x80, 0x3f, 0x00, 0xc6, 
+-      0xdf, 0x00, 0x00, 0x06, 0x08, 0x20, 0xd0, 0x00, 
+-      0x10, 0x08, 0xa0, 0x0a, 0xa0, 0x1b, 0x0c, 0x20, 
+-      0xd0, 0x00, 0x10, 0x08, 0xa0, 0x27, 0x90, 0x4d, 
+-      0x0f, 0xff, 0xd8, 0x1f, 0x40, 0x40, 0xa0, 0x4d, 
+-      0x80, 0x0a, 0xd0, 0x00, 0x06, 0x50, 0xf9, 0x95, 
+-      0xd0, 0x01, 0xa0, 0x09, 0x80, 0x1b, 0xa0, 0x27, 
+-      0x01, 0x20, 0xd0, 0x67, 0xa0, 0x69, 0x80, 0x2a, 
+-      0x82, 0x29, 0x80, 0x6a, 0x84, 0x29, 0xd0, 0x54, 
+-      0x10, 0x4f, 0xa0, 0x6a, 0x01, 0x20, 0xd0, 0x40, 
+-      0xa0, 0x69, 0x80, 0x2b, 0x80, 0x07, 0x08, 0x20, 
+-      0xdf, 0x00, 0x02, 0x30, 0xd0, 0x00, 0xa0, 0x38, 
+-      0x80, 0x3f, 0x01, 0xb0, 0xd0, 0x10, 0xa0, 0x37, 
+-      0x80, 0x3f, 0x02, 0x30, 0xd0, 0x01, 0xa0, 0x38, 
+-      0xd0, 0x10, 0xa0, 0x38, 0x15, 0x63, 0xe9, 0xba, 
+-      0x05, 0x5e, 0xf9, 0xfa, 0xc0, 0xdf, 0x00, 0xe0, 
+-      0xd1, 0x80, 0x70, 0x06, 0x10, 0x1c, 0xc1, 0x40, 
+-      0x11, 0x48, 0xd3, 0x10, 0x00, 0x21, 0xd0, 0x80, 
+-      0xb0, 0x16, 0xe9, 0xca, 0xd3, 0x20, 0x10, 0x81, 
+-      0xb0, 0x16, 0xf9, 0xfa, 0x30, 0xc2, 0xd2, 0x64, 
+-      0xd0, 0x92, 0x00, 0xee, 0xd0, 0x54, 0x70, 0x41, 
+-      0x30, 0x43, 0xed, 0xd7, 0xd2, 0x6c, 0x72, 0x49, 
+-      0xc0, 0x89, 0xb0, 0xbf, 0x10, 0x9f, 0x22, 0x42, 
+-      0x04, 0x31, 0xd0, 0x10, 0xc0, 0x42, 0x30, 0x49, 
+-      0xe5, 0xde, 0x10, 0x03, 0xc1, 0x0c, 0xc1, 0x83, 
+-      0xb1, 0xbe, 0x01, 0x46, 0x00, 0x06, 0xa0, 0x3d, 
+-      0xa0, 0x3c, 0x60, 0x06, 0x00, 0xc6, 0xb1, 0xbc, 
+-      0xb1, 0x01, 0xed, 0xe1, 0xc1, 0x0c, 0x21, 0x85, 
+-      0x01, 0x46, 0x00, 0x06, 0xa0, 0x3d, 0xa0, 0x3c, 
+-      0x60, 0x06, 0x00, 0xc6, 0xb1, 0xbc, 0xb1, 0x01, 
+-      0xed, 0xec, 0x02, 0xe4, 0xd0, 0x00, 0x20, 0xc0, 
+-      0xb2, 0x41, 0xed, 0xd8, 0x15, 0xa3, 0xfa, 0x00, 
+-      0xbc, 0x10, 0x0c, 0x1e, 0xfa, 0x00, 0xbc, 0x10, 
+-      0xd0, 0x04, 0x70, 0x00, 0x10, 0x20, 0xfa, 0x00, 
+-      0x00, 0x27, 0xd0, 0x10, 0xd0, 0x40, 0x60, 0x40, 
+-      0x00, 0x26, 0xd0, 0x14, 0x60, 0x40, 0xb0, 0x28, 
+-      0x70, 0x40, 0xb0, 0x7f, 0x60, 0x40, 0x01, 0x7a, 
+-      0xde, 0x1a, 0xe0, 0x46, 0x50, 0x00, 0x50, 0x00, 
+-      0x00, 0x28, 0xd1, 0xb0, 0x70, 0x06, 0xd0, 0x81, 
+-      0x60, 0x86, 0x10, 0x20, 0xe9, 0xab, 0xb0, 0x3f, 
+-      0x60, 0x06, 0x00, 0xec, 0xd1, 0x84, 0x70, 0x46, 
+-      0xb1, 0x84, 0x70, 0x86, 0x30, 0x42, 0xe9, 0xab, 
+-      0x70, 0x42, 0xd0, 0x35, 0x30, 0x40, 0xf9, 0xab, 
+-      0x00, 0x63, 0xd0, 0x3f, 0xb0, 0xbc, 0x40, 0x80, 
+-      0x70, 0xc2, 0x10, 0xe3, 0xe5, 0xab, 0xb0, 0xbc, 
+-      0x40, 0x80, 0x60, 0x86, 0x00, 0x28, 0xd0, 0x24, 
+-      0x70, 0x40, 0x00, 0x22, 0xd0, 0x80, 0x50, 0x42, 
+-      0x60, 0x40, 0x00, 0x64, 0xd0, 0x60, 0xd0, 0x90, 
+-      0x60, 0x81, 0x00, 0xed, 0xd1, 0x88, 0x70, 0x46, 
+-      0x10, 0xe4, 0xe9, 0xa8, 0x00, 0x21, 0xd0, 0xe8, 
+-      0xd0, 0x00, 0x60, 0x03, 0xd0, 0x81, 0x40, 0x42, 
+-      0x60, 0x46, 0x02, 0x3c, 0xdc, 0x89, 0xe0, 0x46, 
+-      0xd0, 0x82, 0x50, 0x42, 0x60, 0x46, 0x00, 0x23, 
+-      0xd5, 0x3e, 0x01, 0x7a, 0xde, 0x1a, 0xe0, 0x46, 
+-      0x01, 0x46, 0xdf, 0x5c, 0x08, 0x20, 0xd1, 0x00, 
+-      0xcf, 0x04, 0x11, 0x08, 0xa1, 0x0a, 0xa1, 0x1b, 
+-      0x11, 0x1f, 0xa1, 0x27, 0xd2, 0x80, 0xb2, 0x81, 
+-      0x90, 0x4d, 0xc0, 0x01, 0x10, 0x14, 0x00, 0x16, 
+-      0xe9, 0x8d, 0x80, 0x33, 0x80, 0x3f, 0x92, 0x8b, 
+-      0x00, 0x23, 0xd0, 0x3f, 0x42, 0x80, 0xe9, 0x8d, 
+-      0x0f, 0xff, 0xdf, 0xff, 0x40, 0x01, 0xa0, 0x0d, 
+-      0xe1, 0x94, 0xa1, 0x0a, 0x00, 0xea, 0xd0, 0x00, 
+-      0xd0, 0x8e, 0x00, 0x06, 0x0f, 0x0b, 0x70, 0x80, 
+-      0x80, 0x73, 0x80, 0x0a, 0xd0, 0x00, 0x06, 0x50, 
+-      0xf9, 0x9a, 0xd0, 0x01, 0xd0, 0x44, 0x40, 0x70, 
+-      0x20, 0x01, 0x15, 0x63, 0xf9, 0xa1, 0x80, 0x1b, 
+-      0xe1, 0xa2, 0x80, 0x5b, 0xa0, 0x27, 0x01, 0x20, 
+-      0xd0, 0x67, 0xa0, 0x69, 0x80, 0x2a, 0x82, 0x29, 
+-      0x80, 0x6a, 0x84, 0x29, 0xd0, 0x54, 0x10, 0x4f, 
+-      0xa0, 0x6a, 0x01, 0x20, 0xd0, 0x40, 0xa0, 0x69, 
+-      0x80, 0x2b, 0x80, 0x07, 0x08, 0x20, 0xd0, 0x00, 
+-      0xcf, 0x00, 0x02, 0x30, 0xd0, 0x00, 0xa0, 0x38, 
+-      0x80, 0x3f, 0x01, 0xb2, 0xd2, 0x10, 0xa0, 0x37, 
+-      0x80, 0x3f, 0x02, 0x30, 0xd0, 0x01, 0xa0, 0x38, 
+-      0x00, 0x30, 0xd0, 0x10, 0xa0, 0x38, 0x80, 0x3f, 
+-      0x00, 0xc6, 0x00, 0x28, 0xd1, 0x24, 0x70, 0x04, 
+-      0xd0, 0x41, 0x50, 0x01, 0x60, 0x04, 0x00, 0x27, 
+-      0xd0, 0x18, 0x70, 0x40, 0xb0, 0x7f, 0x60, 0x40, 
+-      0x00, 0x26, 0xd0, 0x20, 0x70, 0x40, 0xb0, 0x7f, 
+-      0x60, 0x40, 0x08, 0x20, 0xdf, 0x00, 0xd4, 0x00, 
+-      0xd4, 0x40, 0xd4, 0x80, 0xd4, 0xc0, 0xd3, 0x81, 
+-      0x12, 0xa0, 0xed, 0xe3, 0xd0, 0x08, 0x0a, 0x09, 
+-      0x00, 0x4d, 0xb0, 0x01, 0xed, 0xdf, 0x03, 0xbf, 
+-      0xd4, 0x27, 0xe0, 0x46, 0x50, 0x00, 0x50, 0x00, 
+-      0x02, 0x24, 0xd0, 0x00, 0xa0, 0x37, 0x00, 0x27, 
+-      0xd3, 0xd0, 0x00, 0x26, 0xd0, 0x04, 0x73, 0xcf, 
+-      0x13, 0xe1, 0xe9, 0x7b, 0xb0, 0x3c, 0xf2, 0x00, 
+-      0x00, 0x26, 0xd0, 0x40, 0xd0, 0x00, 0x60, 0x01, 
+-      0x00, 0x26, 0xd0, 0x14, 0xf2, 0x00, 0x00, 0x26, 
+-      0xd0, 0x18, 0xf2, 0x00, 0x00, 0xee, 0xd0, 0x1c, 
+-      0x71, 0x40, 0xd1, 0x24, 0x15, 0x63, 0xe9, 0x8d, 
+-      0x11, 0x1f, 0xc7, 0x1a, 0xb7, 0x01, 0xd3, 0x81, 
+-      0xc4, 0xd4, 0xf2, 0x04, 0x00, 0x26, 0xd0, 0x18, 
+-      0x70, 0x40, 0xb0, 0x54, 0xfd, 0x9b, 0x00, 0xed, 
+-      0xd0, 0x24, 0xd0, 0x44, 0x60, 0x40, 0x13, 0xe1, 
+-      0xf9, 0xbc, 0x15, 0xa3, 0xf9, 0xa1, 0x0c, 0x10, 
+-      0xe9, 0xb9, 0x11, 0x61, 0xe5, 0xb3, 0xed, 0xb9, 
+-      0x15, 0xa3, 0xf9, 0xab, 0x00, 0x26, 0xd0, 0x14, 
+-      0x70, 0x40, 0x10, 0x62, 0xf5, 0xb3, 0x15, 0x22, 
+-      0xe5, 0xb3, 0xc0, 0x44, 0x30, 0x54, 0xe5, 0xb3, 
+-      0x34, 0xd4, 0xf5, 0xb3, 0xe1, 0xbf, 0x03, 0xb4, 
+-      0xd6, 0x29, 0x00, 0x26, 0xd0, 0x40, 0x60, 0x01, 
+-      0xe1, 0xdb, 0x03, 0xb4, 0xd6, 0x29, 0xe0, 0x46, 
+-      0x01, 0x7a, 0xde, 0x1a, 0xe0, 0x46, 0x80, 0x07, 
+-      0x09, 0x49, 0xd4, 0x00, 0xd4, 0x40, 0xd4, 0x80, 
+-      0xd4, 0xc0, 0x00, 0x4d, 0xa0, 0x6c, 0xd3, 0x80, 
+-      0xd0, 0xa1, 0x00, 0x88, 0xd0, 0xa9, 0x00, 0x4d, 
+-      0x00, 0x50, 0xf9, 0xc9, 0x0c, 0x49, 0xd0, 0x61, 
+-      0x00, 0x8d, 0x10, 0xa0, 0xe9, 0x90, 0x30, 0x42, 
+-      0xf5, 0xd8, 0xd0, 0x61, 0x23, 0x81, 0xe1, 0xce, 
+-      0x23, 0x82, 0x13, 0xa1, 0xf9, 0x90, 0xd0, 0x42, 
+-      0x15, 0xa1, 0xf9, 0xdf, 0xb0, 0x7f, 0x00, 0x26, 
+-      0xd0, 0x14, 0x70, 0x00, 0x30, 0x01, 0xf5, 0xe8, 
+-      0x16, 0xe0, 0xe5, 0xe8, 0xb6, 0xc1, 0xbc, 0x20, 
+-      0xc0, 0x44, 0x30, 0x5b, 0xfd, 0xb9, 0xc0, 0x44, 
+-      0x30, 0x54, 0xe5, 0xb9, 0x15, 0x63, 0xf9, 0xf8, 
+-      0x15, 0xa3, 0xf9, 0xf5, 0x03, 0x3c, 0xd8, 0x1c, 
+-      0xe0, 0x46, 0x03, 0x39, 0xda, 0x17, 0xe0, 0x46, 
+-      0x15, 0xa3, 0xf9, 0xfd, 0x03, 0x72, 0xde, 0x19, 
+-      0xe0, 0x46, 0x03, 0x70, 0xd0, 0x17, 0xe0, 0x46, 
+-      0x70, 0x40, 0xb0, 0x7f, 0x60, 0x40, 0x0f, 0xc5, 
+-      0xdf, 0x00, 0x0c, 0x09, 0x05, 0x0d, 0x08, 0x20, 
+-      0xdf, 0x00, 0x0f, 0xc5, 0x50, 0x00, 0x50, 0x00, 
+-      0x00, 0xef, 0xd0, 0x14, 0x70, 0x40, 0x10, 0x60, 
+-      0xe9, 0x45, 0xb0, 0x04, 0x70, 0x40, 0xb0, 0x41, 
+-      0xed, 0x44, 0x00, 0xed, 0xd0, 0x24, 0xd0, 0x44, 
+-      0x60, 0x40, 0x00, 0x64, 0xd0, 0x20, 0x70, 0x00, 
+-      0x10, 0x30, 0xe9, 0x45, 0x00, 0x21, 0xd0, 0x28, 
+-      0x60, 0x40, 0x00, 0x64, 0xd2, 0xc0, 0x70, 0x0b, 
+-      0x00, 0x11, 0xe9, 0x6a, 0x08, 0x20, 0xd0, 0x4f, 
+-      0x30, 0x40, 0xe9, 0x55, 0xb0, 0x4f, 0xf9, 0x6a, 
+-      0x03, 0xef, 0xdf, 0xbf, 0xaf, 0xb8, 0xdf, 0x80, 
+-      0x0f, 0x87, 0xd0, 0x18, 0x70, 0x00, 0x10, 0x20, 
+-      0xed, 0x6c, 0xdf, 0x84, 0xd0, 0x40, 0x60, 0x7e, 
+-      0x00, 0x27, 0xd0, 0x54, 0x70, 0x41, 0x10, 0x60, 
+-      0x01, 0xa0, 0xd0, 0x40, 0xa0, 0x78, 0x80, 0x34, 
+-      0x80, 0x3f, 0x01, 0x3c, 0xd2, 0x39, 0x00, 0x21, 
+-      0xdf, 0x86, 0x0f, 0x87, 0xd0, 0x40, 0x60, 0x4b, 
+-      0x03, 0xe6, 0xd0, 0x08, 0xe0, 0x36, 0x50, 0x00, 
+-      0x00, 0x28, 0xd0, 0x24, 0x72, 0xc0, 0xd0, 0x40, 
+-      0x60, 0x40, 0xd0, 0x0c, 0x52, 0xc0, 0xc0, 0x1c, 
+-      0x30, 0x1d, 0xf5, 0x3c, 0x20, 0x1f, 0x30, 0x1e, 
+-      0x90, 0x6d, 0x20, 0x01, 0x00, 0x22, 0xd0, 0x58, 
+-      0x60, 0x01, 0x00, 0xe3, 0xd0, 0x48, 0x70, 0x41, 
+-      0x30, 0x40, 0xf5, 0x47, 0xb2, 0xc8, 0x00, 0xe3, 
+-      0xd0, 0x4c, 0x70, 0x41, 0x30, 0x40, 0xfd, 0x4d, 
+-      0xb2, 0xc4, 0x00, 0x28, 0xd0, 0x20, 0x70, 0x00, 
+-      0x42, 0xc0, 0xa2, 0xc5, 0x12, 0xe0, 0xe9, 0x55, 
+-      0x80, 0x40, 0x80, 0x34, 0x80, 0x3f, 0xcf, 0x95, 
+-      0x82, 0x34, 0x80, 0x3f, 0x03, 0xe8, 0xd0, 0x00, 
+-      0x1f, 0xa3, 0xe9, 0x60, 0x03, 0xea, 0xd0, 0x00, 
+-      0x00, 0x27, 0xd0, 0x4c, 0x7f, 0x81, 0x00, 0x27, 
+-      0xd0, 0x54, 0x70, 0x41, 0x10, 0x60, 0x03, 0xa0, 
+-      0xd0, 0x40, 0xa0, 0x78, 0xe0, 0x3c, 0x50, 0x00, 
+-      0xc0, 0x84, 0x10, 0x8c, 0x10, 0x92, 0xd0, 0x41, 
+-      0x30, 0x4d, 0x40, 0x43, 0x10, 0x43, 0x20, 0x81, 
+-      0xd1, 0x8f, 0x41, 0x82, 0x10, 0x9c, 0x20, 0x9b, 
+-      0xc1, 0xc2, 0x10, 0x82, 0x20, 0x87, 0xc0, 0x42, 
+-      0x10, 0x43, 0x20, 0x81, 0x10, 0x88, 0x22, 0x02, 
+-      0x10, 0x97, 0x01, 0xd0, 0xe9, 0x48, 0xb0, 0x96, 
+-      0x10, 0x88, 0x22, 0x82, 0xc0, 0x5c, 0x10, 0x48, 
+-      0xc0, 0x84, 0x10, 0x91, 0x10, 0x86, 0x20, 0x42, 
+-      0x41, 0x0d, 0x11, 0x02, 0x20, 0x44, 0x22, 0x01, 
+-      0x22, 0x81, 0x02, 0xe4, 0xd2, 0x40, 0xc2, 0xca, 
+-      0xb2, 0xe0, 0x01, 0xd0, 0xe9, 0x5e, 0xc2, 0xca, 
+-      0x22, 0xc9, 0xb2, 0xa0, 0x22, 0x48, 0xd0, 0x78, 
+-      0x03, 0x50, 0xf9, 0x69, 0xd0, 0x7c, 0x01, 0x9d, 
+-      0xf9, 0x69, 0xc2, 0x48, 0xb2, 0x60, 0xc2, 0xca, 
+-      0xb2, 0xf0, 0x11, 0x82, 0x41, 0x81, 0x22, 0x06, 
+-      0x11, 0x9f, 0x41, 0x81, 0x22, 0x86, 0x0f, 0xc5, 
+-      0xc0, 0x84, 0x10, 0x8c, 0x10, 0x92, 0xd1, 0x8f, 
+-      0x41, 0x82, 0x10, 0x9c, 0xc1, 0xdb, 0x11, 0xc1, 
+-      0x21, 0xc3, 0x20, 0x87, 0xc1, 0xc2, 0x10, 0x82, 
+-      0x20, 0x87, 0xc0, 0x42, 0x10, 0x43, 0x20, 0x81, 
+-      0x10, 0x88, 0x22, 0x02, 0x10, 0x97, 0x01, 0xd0, 
+-      0xe9, 0x46, 0xb0, 0x96, 0x10, 0x88, 0x22, 0x82, 
+-      0xc0, 0x5c, 0x10, 0x48, 0xc0, 0x84, 0x10, 0x91, 
+-      0x10, 0x86, 0x20, 0x42, 0xd0, 0x81, 0x41, 0x02, 
+-      0x11, 0x02, 0x20, 0x44, 0x22, 0x01, 0x22, 0x81, 
+-      0x02, 0xe4, 0xd2, 0x40, 0xc2, 0xca, 0xb2, 0xe0, 
+-      0x01, 0xd0, 0xe9, 0x5d, 0xc2, 0xca, 0x22, 0xc9, 
+-      0xb2, 0xa0, 0x22, 0x48, 0x11, 0x9f, 0x11, 0x83, 
+-      0x22, 0x06, 0x11, 0x9c, 0x11, 0x83, 0x22, 0x86, 
+-      0x0f, 0xc5, 0xd0, 0x41, 0x40, 0x44, 0x20, 0x55, 
+-      0x10, 0x62, 0xf9, 0x6f, 0x01, 0xb5, 0xd4, 0x00, 
+-      0xc2, 0x9f, 0xc2, 0x1f, 0x22, 0x80, 0xe1, 0x30, 
+-      0x0f, 0x11, 0xf9, 0x51, 0x90, 0x38, 0x80, 0x3f, 
+-      0x00, 0x1b, 0xf9, 0x51, 0x00, 0x27, 0xd0, 0x04, 
+-      0x70, 0x40, 0x30, 0x71, 0xf9, 0x51, 0xb0, 0x3c, 
+-      0x70, 0x40, 0x30, 0x5d, 0xf9, 0x51, 0xb0, 0x08, 
+-      0x70, 0x40, 0xb0, 0x7f, 0x60, 0x40, 0x10, 0x63, 
+-      0xe5, 0x5d, 0x02, 0x20, 0xd0, 0x01, 0xa0, 0x37, 
+-      0x00, 0x26, 0xd0, 0x24, 0x70, 0x40, 0xb0, 0x7f, 
+-      0x60, 0x40, 0xb0, 0x08, 0x70, 0x40, 0xb0, 0x41, 
+-      0x60, 0x40, 0x00, 0x26, 0xd0, 0x30, 0x70, 0x40, 
+-      0xb0, 0x7f, 0x60, 0x40, 0xb0, 0x30, 0xd0, 0x40, 
+-      0x60, 0x40, 0xb0, 0x3c, 0x6c, 0x40, 0xb0, 0x3c, 
+-      0x67, 0x40, 0x00, 0x33, 0xdf, 0xb0, 0xe0, 0x36, 
+-      0x00, 0x26, 0xd0, 0x1c, 0x70, 0x40, 0xb0, 0x7f, 
+-      0x60, 0x40, 0xb0, 0x3c, 0x70, 0x40, 0xb0, 0x41, 
+-      0x60, 0x40, 0x08, 0x20, 0xdf, 0x00, 0x80, 0x35, 
+-      0xc0, 0x3c, 0x10, 0x08, 0xa0, 0x0a, 0xa0, 0x27, 
+-      0xa0, 0x1b, 0xdf, 0x5c, 0x01, 0xa0, 0xd0, 0x00, 
+-      0xa0, 0x38, 0x80, 0x3f, 0x80, 0x34, 0x80, 0x3f, 
+-      0x03, 0xbb, 0xd8, 0x1e, 0xcf, 0x95, 0x82, 0x34, 
+-      0x80, 0x3f, 0x03, 0xe8, 0xd0, 0x00, 0x1f, 0xa3, 
+-      0xe9, 0x55, 0x1f, 0xa0, 0xe9, 0x55, 0x03, 0xea, 
+-      0xd0, 0x00, 0x00, 0x21, 0xdf, 0x86, 0xe0, 0x3c, 
+-      0x89, 0x78, 0x89, 0x37, 0x00, 0xee, 0xd0, 0x14, 
+-      0x76, 0x00, 0xd0, 0x30, 0x76, 0x40, 0x26, 0x58, 
+-      0xd6, 0xd9, 0x00, 0xee, 0xd0, 0x20, 0x75, 0x40, 
+-      0xd0, 0x1c, 0x71, 0x40, 0xd0, 0x20, 0x71, 0x00, 
+-      0xd0, 0x24, 0x70, 0x80, 0xc4, 0x02, 0xd0, 0x28, 
+-      0x70, 0xc0, 0x00, 0x21, 0xd0, 0x10, 0x72, 0x00, 
+-      0x93, 0x90, 0xd4, 0x81, 0x13, 0x96, 0x43, 0x92, 
+-      0x34, 0x8e, 0x00, 0x22, 0xd1, 0xa4, 0x71, 0x86, 
+-      0xde, 0x40, 0x7e, 0x79, 0xd0, 0x18, 0x70, 0x40, 
+-      0xb0, 0x41, 0xf5, 0x58, 0xd3, 0x42, 0x50, 0x4d, 
+-      0x60, 0x40, 0x10, 0x60, 0xe5, 0x62, 0xd0, 0x54, 
+-      0x70, 0x01, 0xb0, 0x3c, 0x60, 0x01, 0x04, 0x2d, 
+-      0xd0, 0x30, 0xe0, 0x36, 0x00, 0x22, 0xd0, 0x60, 
+-      0x71, 0xc1, 0xd0, 0x4f, 0x41, 0xc1, 0x04, 0x20, 
+-      0xd0, 0x28, 0xe0, 0x36, 0x50, 0x00, 0x50, 0x00, 
+-      0x04, 0x22, 0xd0, 0x18, 0xd3, 0x44, 0x72, 0x8d, 
+-      0x12, 0xa0, 0xe8, 0x36, 0xc0, 0x47, 0x10, 0x5d, 
+-      0x30, 0x4e, 0xf8, 0x36, 0xb2, 0x3e, 0x60, 0x4d, 
+-      0x00, 0xed, 0xd0, 0x48, 0x70, 0x01, 0xde, 0x45, 
+-      0x50, 0x39, 0x00, 0x1b, 0xf9, 0x44, 0xb0, 0x01, 
+-      0x00, 0x1c, 0xf9, 0x47, 0xb0, 0x04, 0x60, 0x01, 
+-      0xd0, 0x40, 0x62, 0x81, 0xce, 0x4a, 0xd0, 0x43, 
+-      0x41, 0xc1, 0xd0, 0x58, 0x61, 0xc1, 0x90, 0x43, 
+-      0x00, 0xe0, 0xd0, 0x28, 0x70, 0x00, 0x10, 0x1f, 
+-      0x20, 0x40, 0xb1, 0xc1, 0xf5, 0x54, 0x00, 0x21, 
+-      0xd0, 0x08, 0x60, 0x40, 0x00, 0xe6, 0xd0, 0x40, 
+-      0x70, 0x41, 0xd2, 0x94, 0x60, 0x4a, 0x04, 0x2c, 
+-      0xd0, 0x08, 0x01, 0x90, 0xf8, 0x36, 0x04, 0x2d, 
+-      0xd0, 0x30, 0xe0, 0x36, 0x50, 0x00, 0x50, 0x00, 
+-      0xc0, 0x47, 0x10, 0x5d, 0x30, 0x4e, 0xf9, 0x41, 
+-      0x90, 0x43, 0x00, 0xe0, 0xd0, 0x28, 0x70, 0x00, 
+-      0x20, 0x40, 0x00, 0x21, 0xd0, 0x08, 0x60, 0x40, 
+-      0x00, 0x26, 0xd0, 0x74, 0x70, 0x01, 0xb0, 0x3f, 
+-      0x60, 0x01, 0x00, 0xed, 0xd0, 0x48, 0x70, 0x41, 
+-      0x00, 0x5e, 0xf9, 0x4b, 0x00, 0x21, 0xd0, 0x00, 
+-      0x73, 0x80, 0xd4, 0x81, 0x34, 0x8e, 0x00, 0x34, 
+-      0xd3, 0x70, 0xe0, 0x36, 0x50, 0x00, 0x50, 0x00, 
+-      0xd1, 0x88, 0xd1, 0xc8, 0x01, 0x1b, 0xe9, 0x39, 
+-      0x11, 0x9f, 0x11, 0xdf, 0xd4, 0x80, 0xd3, 0x81, 
+-      0xe1, 0x43, 0x00, 0xed, 0xd0, 0x08, 0x70, 0x00, 
+-      0x00, 0x10, 0xf9, 0x37, 0x0c, 0x1f, 0xf9, 0x36, 
+-      0x13, 0xa1, 0xe9, 0x43, 0xbe, 0x7c, 0x00, 0x69, 
+-      0xd2, 0x54, 0x12, 0x48, 0xc0, 0x39, 0x30, 0x18, 
+-      0xe5, 0x4b, 0xd2, 0x70, 0x72, 0x49, 0x22, 0x79, 
+-      0x00, 0x21, 0xd0, 0x00, 0x63, 0x80, 0x04, 0x24, 
+-      0xd0, 0x38, 0x02, 0x10, 0xe9, 0x56, 0xd0, 0x41, 
+-      0x51, 0x41, 0xe0, 0x36, 0x15, 0x61, 0xe8, 0x36, 
+-      0xd5, 0x80, 0xd3, 0x00, 0xd3, 0x40, 0x04, 0x28, 
+-      0xd0, 0x18, 0xe0, 0x36, 0x50, 0x00, 0x50, 0x00, 
+-      0x00, 0x21, 0xd0, 0x18, 0x73, 0x00, 0xb0, 0x04, 
+-      0x73, 0x80, 0xd2, 0x80, 0xb0, 0x38, 0x72, 0xc0, 
+-      0x31, 0x0d, 0xc0, 0x0e, 0x10, 0x0b, 0x10, 0x20, 
+-      0xe9, 0x42, 0xf5, 0x3f, 0x22, 0x8d, 0x10, 0x01, 
+-      0x13, 0x5f, 0xe1, 0x3b, 0x33, 0x8b, 0x15, 0x61, 
+-      0xf9, 0x49, 0x00, 0x21, 0xd0, 0x64, 0x70, 0x41, 
+-      0x33, 0x81, 0x03, 0xd0, 0xe9, 0x4c, 0x20, 0x0b, 
+-      0x13, 0xdf, 0x12, 0xc1, 0x13, 0xe0, 0xf9, 0x49, 
+-      0x10, 0x03, 0xc0, 0x50, 0x10, 0x4b, 0x13, 0x0b, 
+-      0x23, 0x00, 0x13, 0x20, 0xe9, 0x5c, 0xf5, 0x59, 
+-      0x22, 0x81, 0x13, 0x01, 0x10, 0x5f, 0xe1, 0x55, 
+-      0x12, 0x99, 0x12, 0x87, 0x21, 0x0a, 0x00, 0xa0, 
+-      0xd2, 0x80, 0xc3, 0x0a, 0x03, 0x90, 0xe9, 0x66, 
+-      0x22, 0x82, 0x23, 0x03, 0x10, 0x81, 0x10, 0xc1, 
+-      0x13, 0x9f, 0x13, 0xa0, 0xed, 0x62, 0xc0, 0x8a, 
+-      0xc0, 0xcc, 0x04, 0x26, 0xd0, 0x38, 0xe0, 0x36, 
+-      0x15, 0x61, 0xf9, 0x3d, 0x07, 0x32, 0xd0, 0x00, 
+-      0x30, 0x03, 0xed, 0x3d, 0xc0, 0x03, 0x10, 0x1d, 
+-      0x30, 0xc0, 0xc0, 0x02, 0x10, 0x1d, 0x30, 0x80, 
+-      0xe1, 0x32, 0x10, 0x94, 0x10, 0xd4, 0x00, 0x21, 
+-      0xd0, 0x20, 0x73, 0x00, 0xc5, 0x8c, 0xd3, 0x4e, 
+-      0x01, 0x1b, 0xe9, 0x48, 0x13, 0x1f, 0xd3, 0x4f, 
+-      0x43, 0x4c, 0x13, 0x1c, 0xc0, 0x0c, 0x10, 0x03, 
+-      0x20, 0x0c, 0xc0, 0x40, 0x10, 0x42, 0x20, 0x40, 
+-      0x10, 0x46, 0x20, 0x4d, 0x10, 0x42, 0x2e, 0x41, 
+-      0x10, 0x5c, 0x10, 0x43, 0x00, 0x59, 0xe9, 0x5b, 
+-      0x01, 0x69, 0xd0, 0x20, 0x30, 0x40, 0x22, 0x41, 
+-      0x04, 0x28, 0xd0, 0x18, 0xe0, 0x36, 0x50, 0x00, 
+-      0x2c, 0x14, 0xd0, 0x34, 0x63, 0x00, 0xd0, 0x38, 
+-      0x72, 0xc0, 0xc0, 0x51, 0x10, 0x5c, 0x30, 0x4b, 
+-      0x10, 0x44, 0xd4, 0xc0, 0xd5, 0x00, 0xc0, 0x18, 
+-      0x30, 0x39, 0xed, 0x5f, 0xd4, 0xd0, 0xc5, 0x01, 
+-      0xd0, 0x18, 0x70, 0x00, 0x0c, 0x1f, 0xe9, 0x48, 
+-      0x10, 0x20, 0xfd, 0x48, 0xd4, 0xc0, 0xd5, 0x00, 
+-      0x10, 0x22, 0xe5, 0x4e, 0xd4, 0xc0, 0xbc, 0x30, 
+-      0xd5, 0x00, 0xb5, 0x10, 0xb0, 0x3f, 0xf9, 0x52, 
+-      0x3c, 0x01, 0x3c, 0x01, 0x02, 0x1f, 0xe9, 0x5f, 
+-      0x00, 0xa8, 0xd3, 0xc0, 0xd3, 0xa4, 0x00, 0xaa, 
+-      0xd0, 0x10, 0x70, 0x4f, 0xb3, 0xfc, 0x60, 0x40, 
+-      0xb0, 0x3c, 0xb3, 0x81, 0xed, 0x59, 0x00, 0x21, 
+-      0xd0, 0x28, 0x70, 0x00, 0x10, 0x20, 0xf9, 0x69, 
+-      0x02, 0x1f, 0xf9, 0x6a, 0x90, 0x10, 0x00, 0x1e, 
+-      0xe9, 0x6a, 0xb1, 0x7c, 0x04, 0x2a, 0xd0, 0x18, 
+-      0xe0, 0x36, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 
+-      0x01, 0x5e, 0xf9, 0x35, 0x01, 0x50, 0xe9, 0x35, 
+-      0xb1, 0x78, 0xd2, 0x00, 0x01, 0x5c, 0xf9, 0x5f, 
+-      0xc0, 0x18, 0x30, 0x39, 0xed, 0x5f, 0x11, 0x9f, 
+-      0xce, 0x58, 0xc2, 0x59, 0x00, 0xaa, 0xd2, 0x10, 
+-      0x14, 0x82, 0x22, 0x12, 0xc0, 0x0c, 0x10, 0x1f, 
+-      0x10, 0x03, 0x22, 0x00, 0x70, 0x48, 0x03, 0x10, 
+-      0xe9, 0x4c, 0xb2, 0x38, 0xbe, 0x60, 0xb2, 0x60, 
+-      0x2e, 0x41, 0x10, 0x5f, 0x00, 0x59, 0xe9, 0x53, 
+-      0x01, 0x69, 0xd0, 0x3c, 0x30, 0x40, 0x22, 0x41, 
+-      0x13, 0x41, 0x2e, 0x4d, 0x13, 0x5d, 0x13, 0x43, 
+-      0x22, 0x4d, 0x14, 0xe0, 0xe9, 0x5f, 0x33, 0x0b, 
+-      0x13, 0x04, 0x2c, 0x0c, 0x35, 0x0c, 0xc3, 0x46, 
+-      0xc3, 0x87, 0x04, 0x62, 0xd0, 0x10, 0x15, 0x62, 
+-      0xfc, 0x36, 0x04, 0x60, 0xd0, 0x10, 0xe0, 0x36, 
+-      0x00, 0x22, 0xd0, 0x74, 0x74, 0x01, 0xb0, 0x7c, 
+-      0x74, 0x41, 0xb0, 0x7c, 0x71, 0x41, 0xd1, 0x18, 
+-      0xc0, 0x10, 0x10, 0x1c, 0xb0, 0x16, 0xf9, 0x45, 
+-      0x00, 0x24, 0xd0, 0x20, 0x30, 0x11, 0xf9, 0x45, 
+-      0xb1, 0x70, 0x01, 0x50, 0xf9, 0x45, 0xb1, 0x20, 
+-      0x14, 0x41, 0xc0, 0x90, 0x00, 0x2b, 0xd0, 0xd0, 
+-      0x01, 0x50, 0xe9, 0x4b, 0xc0, 0xd0, 0x00, 0x35, 
+-      0xdc, 0x00, 0x20, 0x11, 0x10, 0x1f, 0xa0, 0x1c, 
+-      0x00, 0x21, 0xd0, 0x2c, 0x70, 0x00, 0x10, 0x05, 
+-      0x51, 0x40, 0xd0, 0x1c, 0x61, 0x40, 0xd0, 0x20, 
+-      0x61, 0x00, 0xd0, 0x24, 0x60, 0x80, 0xd0, 0x28, 
+-      0x60, 0xc0, 0x04, 0x2d, 0xd0, 0x30, 0x00, 0x22, 
+-      0xd0, 0x64, 0xb1, 0x81, 0x61, 0x81, 0xe0, 0x36, 
+-      0x90, 0x50, 0xd0, 0x3c, 0x10, 0x41, 0x60, 0x40, 
+-      0x15, 0x62, 0xfd, 0x3d, 0xc0, 0x10, 0x10, 0x1e, 
+-      0x10, 0x07, 0x21, 0x00, 0x10, 0x16, 0x34, 0x00, 
+-      0xc0, 0x90, 0xd3, 0x40, 0x00, 0x24, 0xd3, 0xc0, 
+-      0x04, 0x23, 0xd0, 0x18, 0x01, 0x9f, 0xe8, 0x36, 
+-      0xd0, 0x54, 0x70, 0x41, 0x73, 0x41, 0x04, 0x2e, 
+-      0xd0, 0x28, 0xe0, 0x36, 0x50, 0x00, 0x50, 0x00, 
+-      0x00, 0xef, 0xd3, 0x30, 0x73, 0x0c, 0xd0, 0x0c, 
+-      0x70, 0x00, 0xc0, 0x40, 0x13, 0x24, 0xf5, 0x42, 
+-      0x13, 0x22, 0xe9, 0x41, 0xe5, 0x43, 0xd3, 0x00, 
+-      0x10, 0x22, 0xf9, 0x41, 0xd0, 0x01, 0xd0, 0x43, 
+-      0xd3, 0x01, 0x21, 0x00, 0xd3, 0x40, 0x03, 0x10, 
+-      0xf9, 0x47, 0xd3, 0x40, 0xe1, 0x61, 0x00, 0x23, 
+-      0xd0, 0x00, 0x10, 0x61, 0xe9, 0x50, 0xb0, 0x33, 
+-      0x10, 0x63, 0xe9, 0x50, 0x00, 0x22, 0xd0, 0x1a, 
+-      0xc3, 0xc0, 0xd2, 0xc0, 0x00, 0x10, 0xe9, 0x55, 
+-      0x22, 0xd0, 0x10, 0x1f, 0x14, 0x01, 0x10, 0x20, 
+-      0xed, 0x52, 0x14, 0x18, 0x12, 0xd8, 0xc0, 0x8b, 
+-      0x32, 0xd0, 0x12, 0xc3, 0x33, 0x4b, 0x13, 0x47, 
+-      0x21, 0x0d, 0x04, 0x23, 0xd0, 0x18, 0xe0, 0x36, 
+-      0x00, 0x24, 0xd0, 0x30, 0xd0, 0x40, 0x60, 0x40, 
+-      0xd3, 0xc7, 0x43, 0xc4, 0x31, 0x0f, 0xd5, 0xd4, 
+-      0x25, 0xcf, 0x15, 0xc4, 0x10, 0xdf, 0xc2, 0xc6, 
+-      0xc3, 0x07, 0x11, 0x81, 0xb1, 0x3b, 0x15, 0x64, 
+-      0xe9, 0x47, 0x10, 0xdf, 0x12, 0xc1, 0x11, 0x81, 
+-      0x11, 0xc1, 0xb1, 0x3f, 0xb5, 0xf8, 0x90, 0x10, 
+-      0x00, 0x16, 0xf9, 0x5e, 0xb5, 0xfc, 0xd0, 0x20, 
+-      0x40, 0x39, 0x2e, 0x4b, 0x22, 0x4c, 0x12, 0x20, 
+-      0xe9, 0x59, 0x20, 0x39, 0x00, 0x1b, 0xe9, 0x59, 
+-      0x2c, 0x13, 0x35, 0x13, 0x0e, 0x5a, 0xf9, 0x59, 
+-      0xb2, 0x38, 0x02, 0xe3, 0xd0, 0x00, 0x0e, 0x5a, 
+-      0xe9, 0x5e, 0x2e, 0x40, 0x01, 0xee, 0xd2, 0x80, 
+-      0x42, 0x84, 0xc0, 0x03, 0x30, 0x02, 0xf5, 0x6b, 
+-      0x31, 0x0a, 0x12, 0x98, 0x20, 0x03, 0xf5, 0x69, 
+-      0x12, 0x9f, 0x12, 0x87, 0x51, 0x0a, 0x00, 0x34, 
+-      0xd4, 0xf0, 0xe0, 0x36, 0x50, 0x00, 0x50, 0x00, 
+-      0xd3, 0xc7, 0x43, 0xc4, 0x15, 0x61, 0xf9, 0x48, 
+-      0x10, 0xc1, 0xd5, 0xe0, 0xd1, 0x80, 0xd1, 0xc0, 
+-      0x31, 0x0f, 0x13, 0xe1, 0xe9, 0x3c, 0xd3, 0xc0, 
+-      0x00, 0x24, 0xd0, 0x30, 0x63, 0xc0, 0x25, 0xcf, 
+-      0x15, 0xc2, 0xd0, 0x03, 0x40, 0x16, 0x25, 0xc0, 
+-      0x15, 0xc2, 0x15, 0x81, 0x35, 0x91, 0xe1, 0x5c, 
+-      0x00, 0x24, 0xd0, 0x30, 0x63, 0xc0, 0x01, 0x50, 
+-      0xe9, 0x54, 0x15, 0xa0, 0xf9, 0x55, 0x00, 0x24, 
+-      0xd0, 0x34, 0x70, 0x00, 0x10, 0x20, 0xe9, 0x55, 
+-      0xd3, 0xc0, 0x31, 0x0f, 0xd5, 0xfc, 0x25, 0xcf, 
+-      0x15, 0xc3, 0x14, 0xa0, 0xe9, 0x5c, 0xb5, 0xfc, 
+-      0x00, 0x34, 0xd4, 0xf0, 0xe0, 0x36, 0x50, 0x00, 
+-      0xc4, 0x91, 0x34, 0x96, 0xed, 0x34, 0xd4, 0x80, 
+-      0x14, 0x84, 0xb3, 0xc1, 0xe5, 0x41, 0xc0, 0x52, 
+-      0x10, 0x5e, 0x34, 0x81, 0xb3, 0xc1, 0xe5, 0x41, 
+-      0xc0, 0x52, 0x10, 0x5c, 0x24, 0x81, 0xb3, 0xc1, 
+-      0xe5, 0x37, 0x02, 0xe8, 0xd0, 0x00, 0xb4, 0xb0, 
+-      0x14, 0x9b, 0x00, 0x24, 0xd0, 0x60, 0x30, 0x52, 
+-      0xed, 0x4a, 0x24, 0x81, 0x20, 0x12, 0xa0, 0x1c, 
+-      0x10, 0x8a, 0x50, 0x83, 0xa0, 0x96, 0xa1, 0x50, 
+-      0xa1, 0x11, 0xc0, 0x52, 0xd4, 0x84, 0x10, 0x6c, 
+-      0xed, 0x56, 0xd4, 0x81, 0xd1, 0x00, 0xb1, 0x17, 
+-      0x00, 0x23, 0xd1, 0x40, 0xc2, 0xb9, 0x22, 0x86, 
+-      0x12, 0x20, 0xf9, 0x66, 0x02, 0xe3, 0xd0, 0x40, 
+-      0x02, 0x9a, 0xe9, 0x63, 0x22, 0x81, 0x02, 0x5a, 
+-      0xe9, 0x66, 0x22, 0x41, 0x75, 0xd7, 0xc3, 0xd7, 
+-      0xd0, 0xd7, 0x00, 0x21, 0xd0, 0xb6, 0x8b, 0x38, 
+-      0x00, 0x33, 0xdd, 0x08, 0xe0, 0x36, 0x50, 0x00, 
+-      0xd0, 0x7c, 0x60, 0x01, 0xae, 0x52, 0xd0, 0x60, 
+-      0x40, 0x79, 0x00, 0x13, 0xe8, 0xc9, 0xa2, 0x94, 
+-      0x22, 0x86, 0x13, 0xe0, 0xe4, 0xd0, 0x13, 0xc1, 
+-      0x15, 0x62, 0xfc, 0xd1, 0x13, 0xc1, 0xe0, 0xd1, 
+-      0xc3, 0xd7, 0x03, 0xd9, 0xe8, 0xd4, 0x22, 0x8d, 
+-      0x15, 0x62, 0xfc, 0xda, 0x03, 0xda, 0xe8, 0xda, 
+-      0x22, 0x8d, 0x22, 0x8d, 0xce, 0x4a, 0x22, 0x86, 
+-      0x00, 0x14, 0xe8, 0xe0, 0xa2, 0x53, 0x22, 0x47, 
+-      0x03, 0xd1, 0xe8, 0xe8, 0x22, 0x4e, 0x15, 0x62, 
+-      0xfc, 0xe8, 0x03, 0xd2, 0xe8, 0xe8, 0x22, 0x4e, 
+-      0x12, 0x20, 0xe9, 0x09, 0x20, 0x79, 0x00, 0x5b, 
+-      0xe8, 0xf4, 0x15, 0x20, 0xfc, 0xf1, 0x2c, 0x13, 
+-      0x35, 0x13, 0x0e, 0x5b, 0xe8, 0xf4, 0xb2, 0x38, 
+-      0x02, 0x9a, 0xe8, 0xfb, 0x70, 0x08, 0xd0, 0x7c, 
+-      0x42, 0x81, 0x22, 0x98, 0x22, 0x80, 0x02, 0x5a, 
+-      0xe9, 0x11, 0x70, 0x08, 0xd0, 0x78, 0x42, 0x41, 
+-      0x22, 0x59, 0x10, 0x1f, 0x22, 0x40, 0x00, 0x19, 
+-      0xe9, 0x11, 0x01, 0x69, 0xd0, 0x7c, 0x32, 0x41, 
+-      0xe1, 0x11, 0x02, 0xe3, 0xd0, 0x40, 0x02, 0x9a, 
+-      0xe9, 0x0e, 0x22, 0x81, 0x02, 0x5a, 0xe9, 0x11, 
+-      0x22, 0x41, 0x0e, 0x5a, 0xe9, 0x15, 0xce, 0x4a, 
+-      0x3e, 0x46, 0x0f, 0x87, 0xdd, 0x48, 0xe1, 0x19, 
+-      0xdd, 0x40, 0xdc, 0xc8, 0xdd, 0x3c, 0x7d, 0x34, 
+-      0x1d, 0x19, 0x3d, 0x35, 0x4d, 0x33, 0x4c, 0xec, 
+-      0x3d, 0x33, 0xf9, 0x17, 0x0f, 0xc5, 0x50, 0x00, 
+-      0xd0, 0x39, 0xd0, 0x35, 0xd0, 0x1d, 0xd0, 0x2d, 
+-      0xd0, 0x3f, 0xd0, 0x2e, 0xd0, 0x3c, 0xd0, 0x37, 
+-      0xd0, 0x33, 0xd0, 0x19, 0xd0, 0x33, 0xd0, 0x2e, 
+-      0xd0, 0x3d, 0xd0, 0x3e, 0xd0, 0x27, 0xd0, 0x3e, 
+-      0xd0, 0x3a, 0xd0, 0x2f, 0xd0, 0x32, 0x00, 0x00, 
+-      0x00, 0x00, 0x46, 0x44, 0x00, 0x00, 0x10, 0x00, 
+-      0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x50, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
+-      0x00, 0x00, 0x02, 0xd0, 0x00, 0x00, 0x02, 0xd0, 
+-      0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x46, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x90, 0x85, 
+-      0x00, 0x00, 0xa6, 0xee, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x02, 0xd0, 0x00, 0x00, 0x01, 0xe0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xa0, 
+-      0x00, 0x08, 0x08, 0x28, 0x00, 0x08, 0x88, 0x68, 
+-      0x00, 0x08, 0xa0, 0x98, 0x00, 0x08, 0x88, 0x68, 
+-      0x00, 0x08, 0x28, 0x98, 0x00, 0x08, 0xac, 0xf4, 
+-      0x00, 0x08, 0xb8, 0x7c, 0x00, 0x02, 0x02, 0x88, 
+-      0x00, 0x02, 0x08, 0x22, 0x00, 0x02, 0x88, 0xaa, 
+-      0x00, 0x02, 0x22, 0xaa, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x24, 
+-      0x00, 0x04, 0x04, 0x24, 0x00, 0x04, 0x28, 0x6c, 
+-      0x00, 0x04, 0x28, 0x6c, 0x00, 0x01, 0x10, 0x44, 
+-      0x00, 0x01, 0x20, 0x44, 0x00, 0x01, 0x11, 0xaa, 
+-      0x00, 0x01, 0x88, 0x55, 0x00, 0x01, 0x44, 0xaa, 
+-      0x00, 0x01, 0x44, 0x55, 0x00, 0x20, 0x80, 0xa0, 
+-      0x00, 0x20, 0x80, 0xc0, 0x00, 0x20, 0x20, 0xa0, 
+-      0x00, 0x20, 0x40, 0xc0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 
+-      0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x13, 0x16, 
+-      0x1a, 0x1b, 0x1d, 0x22, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x13, 0x16, 
+-      0x1a, 0x1b, 0x1d, 0x22, 0x10, 0x10, 0x16, 0x18, 
+-      0x1b, 0x1d, 0x22, 0x25, 0x13, 0x16, 0x1a, 0x1b, 
+-      0x1d, 0x22, 0x22, 0x26, 0x16, 0x16, 0x1a, 0x1b, 
+-      0x1d, 0x22, 0x25, 0x28, 0x16, 0x1a, 0x1b, 0x1d, 
+-      0x20, 0x23, 0x28, 0x30, 0x1a, 0x1b, 0x1d, 0x20, 
+-      0x23, 0x28, 0x30, 0x3a, 0x1a, 0x1b, 0x1d, 0x22, 
+-      0x26, 0x2e, 0x38, 0x45, 0x1b, 0x1d, 0x23, 0x26, 
+-      0x2e, 0x38, 0x45, 0x53, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd6, 0x00, 
+-      0x00, 0x1b, 0x08, 0x00, 0x00, 0x1f, 0xde, 0x00, 
+-      0x00, 0x00, 0x50, 0x00, 0x00, 0x08, 0x39, 0x00, 
+-      0x00, 0x10, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 
+-      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 
+-      0x05, 0x28, 0x20, 0x01, 0x00, 0x00, 0x01, 0xe0, 
+-      0x71, 0x01, 0x00, 0x68, 0xe0, 0x7f, 0xb0, 0x7f, 
+-      0x60, 0x40, 0xe0, 0x1d, 0x90, 0x10, 0xb4, 0x81, 
+-      0xe8, 0xc0, 0xe0, 0xc2, 0x90, 0x18, 0x00, 0x8a, 
+-      0x70, 0xc0, 0x0f, 0x87, 0xe3, 0xe8, 0xc0, 0x00, 
+-      0x70, 0x40, 0xe0, 0x01, 0xe0, 0x86, 0x00, 0x26, 
+-      0xd0, 0x28, 0xe0, 0x0e, 0xd0, 0x0e, 0x0f, 0x0b, 
+-      0x70, 0x1d, 0xe0, 0x67, 0x0f, 0x87, 0x0f, 0x87, 
+-      0x0f, 0x87, 0x0f, 0x87, 0x0f, 0x87, 0x02, 0x20, 
+-      0xd0, 0x01, 0xe0, 0x25, 0x0f, 0x45, 0x6f, 0x81, 
+-      0xdf, 0xa6, 0xe0, 0x36, 0xe1, 0x30, 0xa0, 0x37, 
+-      0xc0, 0x00, 0xe0, 0x26, 0x00, 0x33, 0xde, 0xc8, 
+-      0xe0, 0x32, 0x0f, 0xc5, 0x0f, 0x87, 0x00, 0x27, 
+-      0xd0, 0x4c, 0xe0, 0x21, 0x00, 0x33, 0xdf, 0x28, 
+-      0x00, 0x27, 0xd0, 0x56, 0x60, 0x01, 0xe0, 0x2d, 
+-      0x03, 0xa0, 0xd0, 0x41, 0xa0, 0x78, 0x00, 0x60, 
+-      0xd0, 0x41, 0xa0, 0x77, 0x00, 0x22, 0xd0, 0x58, 
+-      0xa0, 0x76, 0x00, 0x21, 0xd0, 0x7c, 0x00, 0x4a, 
+-      0xd0, 0x72, 0x70, 0x40, 0x00, 0x06, 0x0f, 0x87, 
+-      0x00, 0x22, 0xdc, 0xf8, 0xf0, 0x4a, 0xe1, 0x70, 
+-      0x07, 0xef, 0xdd, 0xbf, 0x4f, 0x36, 0x1d, 0x99, 
+-      0x4d, 0x80, 0x10, 0x18, 0xdd, 0x50, 0x60, 0x35, 
+-      0xdd, 0x72, 0xdd, 0x10, 0x3d, 0xb4, 0xec, 0x57, 
+-      0x2d, 0x36, 0x1d, 0x03, 0xbd, 0x04, 0xe4, 0x2b, 
+-      0x01, 0x46, 0x00, 0x06, 0xac, 0xf6, 0x80, 0x3f, 
+-      0x0d, 0x0a, 0x10, 0x02, 0x7d, 0x40, 0x10, 0x1e, 
+-      0xb0, 0x20, 0xbc, 0xe0, 0x00, 0x06, 0x00, 0xc6, 
+-      0xe0, 0x52, 0xb7, 0x60, 0xb7, 0x60, 0xc0, 0x5d, 
+-      0x30, 0x5f, 0xe4, 0x72, 0xc7, 0x5e, 0x00, 0xed, 
+-      0xd0, 0x28, 0x70, 0x40, 0xb0, 0x7f, 0x60, 0x40, 
+-      0xc0, 0x1d, 0x30, 0x1c, 0xf8, 0x7e, 0x00, 0x21, 
+-      0xd0, 0x01, 0x00, 0x26, 0xd0, 0x78, 0xa0, 0x38, 
+-      0x80, 0x3f, 0x70, 0x01, 0xb0, 0x3f, 0x60, 0x01, 
+-      0x0f, 0x87, 0x80, 0x34, 0x03, 0xef, 0xd8, 0x3f, 
+-      0xa8, 0x38, 0x01, 0x35, 0xdc, 0x33, 0xe0, 0x46, 
+-      0xc0, 0x1c, 0xe4, 0xa5, 0x97, 0x2e, 0x30, 0x1c, 
+-      0xe8, 0x8e, 0x00, 0x21, 0xd0, 0x00, 0xa0, 0x38, 
+-      0xc0, 0x5d, 0x00, 0x23, 0xd0, 0x00, 0x30, 0x40, 
+-      0x30, 0x5e, 0xe4, 0x99, 0x20, 0x5e, 0xc0, 0x01, 
+-      0x30, 0x1c, 0xec, 0xa4, 0xe0, 0x9d, 0x20, 0x5f, 
+-      0xc0, 0x1c, 0x30, 0x01, 0xf4, 0xa5, 0xc0, 0x1c, 
+-      0x30, 0x1d, 0xec, 0xa4, 0xe4, 0xa5, 0x90, 0x38, 
+-      0x00, 0x1b, 0xe8, 0xa5, 0xa0, 0x66, 0xb1, 0x3f, 
+-      0xe4, 0xb3, 0xe8, 0xb1, 0xc0, 0x4b, 0x30, 0x44, 
+-      0xf8, 0xb3, 0x60, 0x45, 0xb1, 0x7c, 0x01, 0x20, 
+-      0xd0, 0x00, 0xa0, 0x05, 0x80, 0x40, 0x72, 0xc5, 
+-      0x00, 0x06, 0x90, 0x55, 0xd0, 0x01, 0x00, 0x40, 
+-      0xa0, 0x55, 0x0f, 0x87, 0x01, 0x46, 0x00, 0x06, 
+-      0x03, 0xef, 0xd0, 0x3f, 0xa0, 0x38, 0xb0, 0x01, 
+-      0xa0, 0x37, 0x80, 0x3f, 0x82, 0x34, 0x80, 0x3f, 
+-      0xf2, 0x1a, 0x80, 0x34, 0x80, 0x3f, 0xf2, 0x1a, 
+-      0xd8, 0x00, 0xd8, 0x40, 0xd8, 0x80, 0xd8, 0xc0, 
+-      0xd9, 0x00, 0xd9, 0x40, 0xd9, 0x80, 0xd9, 0xc0, 
+-      0xda, 0x00, 0xda, 0x40, 0xda, 0x80, 0xda, 0xc0, 
+-      0xdb, 0x00, 0xdb, 0x40, 0xdb, 0x80, 0xdb, 0xc0, 
+-      0xdc, 0x00, 0xdc, 0x40, 0xdc, 0x80, 0xdc, 0xc0, 
+-      0xdd, 0x00, 0xdd, 0x40, 0xdd, 0x80, 0xdd, 0xc0, 
+-      0xde, 0x00, 0xde, 0x40, 0xde, 0x80, 0xde, 0xc0, 
+-      0xdf, 0x00, 0xdf, 0x40, 0xdf, 0x80, 0xdf, 0xc0, 
+-      0xde, 0x80, 0xde, 0xc1, 0x00, 0x28, 0xd0, 0x60, 
+-      0x6e, 0x81, 0x80, 0x00, 0x80, 0x05, 0x00, 0xe3, 
+-      0xd1, 0x88, 0x00, 0x73, 0xd5, 0x80, 0x60, 0x06, 
+-      0xb1, 0xbc, 0x00, 0xfa, 0xd0, 0x80, 0x60, 0x06, 
+-      0x00, 0x26, 0xd0, 0x6c, 0x6e, 0x81, 0x04, 0x32, 
+-      0xd2, 0x00, 0x00, 0xee, 0xd1, 0x94, 0x60, 0x06, 
+-      0x00, 0xed, 0xd0, 0x50, 0x6e, 0x81, 0x00, 0x22, 
+-      0xd0, 0x70, 0x6e, 0x81, 0x00, 0xee, 0xd0, 0x74, 
+-      0x6e, 0x81, 0xd0, 0x4c, 0x6e, 0x81, 0xd0, 0x02, 
+-      0x00, 0xef, 0xd0, 0x6c, 0x60, 0x01, 0xd0, 0x03, 
+-      0x00, 0xef, 0xd0, 0x70, 0x60, 0x01, 0x00, 0xe0, 
+-      0xd0, 0x48, 0xd0, 0x02, 0x60, 0x01, 0x00, 0x32, 
+-      0xd6, 0xf0, 0xa0, 0x1c, 0x00, 0x21, 0xd0, 0x60, 
+-      0xa0, 0x76, 0x00, 0x34, 0xd5, 0x48, 0x80, 0x3f, 
+-      0x00, 0x23, 0xd0, 0x5c, 0x00, 0x4a, 0xd0, 0x72, 
+-      0x70, 0x40, 0x00, 0x06, 0x00, 0x22, 0xd1, 0xa4, 
+-      0x6e, 0xc6, 0xd0, 0x58, 0x6e, 0xc1, 0xd0, 0xc9, 
+-      0x00, 0xed, 0xd0, 0x54, 0x60, 0xc1, 0x00, 0x22, 
+-      0xd0, 0x40, 0x60, 0xc1, 0x00, 0x22, 0xd0, 0x60, 
+-      0x60, 0xc1, 0x82, 0x34, 0x80, 0x3f, 0xd6, 0xd9, 
+-      0x01, 0x20, 0xd6, 0x22, 0x16, 0x08, 0xd0, 0x5e, 
+-      0xd0, 0x2c, 0x60, 0x40, 0xd0, 0x70, 0x01, 0x74, 
+-      0xd6, 0x00, 0x60, 0x01, 0x00, 0x2b, 0xd4, 0x10, 
+-      0x00, 0x27, 0xd4, 0x60, 0x00, 0x2b, 0xd0, 0x90, 
+-      0xc0, 0xc2, 0xd1, 0x08, 0xd1, 0x44, 0xa1, 0x50, 
+-      0x00, 0x21, 0xd0, 0xb6, 0xd0, 0xd7, 0x00, 0x29, 
+-      0xd0, 0x04, 0x64, 0x00, 0xb0, 0x3c, 0x64, 0x40, 
+-      0x80, 0x34, 0x80, 0x3f, 0xd0, 0x40, 0x00, 0x35, 
+-      0xd0, 0x00, 0x60, 0x01, 0xd0, 0x48, 0x6e, 0x81, 
+-      0xd0, 0x44, 0x6e, 0x81, 0x00, 0x64, 0xd1, 0x80, 
+-      0x6e, 0x86, 0x01, 0x3c, 0xd2, 0x39, 0xe0, 0x46, 
+-      0xd0, 0x00, 0xd0, 0x40, 0xd0, 0x80, 0xd0, 0xc0, 
+-      0xd1, 0x00, 0xd1, 0x40, 0xd1, 0x80, 0xd1, 0xc0, 
+-      0xd2, 0x00, 0xd2, 0x40, 0xd2, 0x80, 0xd2, 0xc0, 
+-      0xd3, 0x00, 0xd3, 0x40, 0xd3, 0x80, 0xd3, 0xc0, 
+-      0xd4, 0x00, 0xd4, 0x40, 0xd4, 0x80, 0xd4, 0xc0, 
+-      0xd5, 0x00, 0xd5, 0x40, 0xd5, 0x80, 0xd5, 0xc0, 
+-      0xd6, 0x00, 0xd6, 0x40, 0xd6, 0x80, 0xd6, 0xc0, 
+-      0xd7, 0x00, 0xd7, 0x40, 0xd7, 0x80, 0xd7, 0xc0, 
+-      0x0f, 0xc5, 0x50, 0x00, 0x01, 0x46, 0x00, 0x06, 
+-      0xde, 0x80, 0xde, 0xc1, 0x03, 0x2f, 0xd0, 0x33, 
+-      0xa0, 0x38, 0xb0, 0x01, 0xa0, 0x37, 0x80, 0x3f, 
+-      0x08, 0x20, 0xdf, 0x00, 0x82, 0x34, 0x80, 0x3f, 
+-      0x00, 0xee, 0xd0, 0x08, 0x77, 0xc0, 0xb0, 0x04, 
+-      0x77, 0x80, 0xb0, 0x04, 0xc0, 0x5f, 0x30, 0x5e, 
+-      0x60, 0x40, 0xd7, 0x00, 0xb7, 0x01, 0x80, 0x34, 
+-      0x80, 0x3f, 0x00, 0x60, 0xd0, 0x80, 0x00, 0xec, 
+-      0xd0, 0x40, 0x60, 0x81, 0xb0, 0x7c, 0x60, 0x81, 
+-      0x00, 0xa0, 0xd0, 0x80, 0xb0, 0x74, 0x60, 0x81, 
+-      0xb0, 0x7c, 0x60, 0x81, 0x00, 0x68, 0xd0, 0x80, 
+-      0x6e, 0x82, 0x00, 0xef, 0xd0, 0x8c, 0x6e, 0x82, 
+-      0x00, 0x06, 0xd0, 0x11, 0xa0, 0x38, 0x80, 0x3f, 
+-      0x08, 0x20, 0xd0, 0x40, 0x10, 0x48, 0xa0, 0x4a, 
+-      0xa0, 0x5b, 0x0c, 0x20, 0xd0, 0x00, 0x10, 0x08, 
+-      0xa0, 0x27, 0xa0, 0x0a, 0x90, 0x4d, 0x0f, 0xff, 
+-      0xd8, 0x1f, 0x40, 0x40, 0xa0, 0x4d, 0x80, 0x0a, 
+-      0x80, 0x07, 0x80, 0x1b, 0x80, 0x27, 0x00, 0x60, 
+-      0xd0, 0x00, 0xa0, 0x09, 0x80, 0x28, 0x01, 0x20, 
+-      0xd0, 0x67, 0xa0, 0x69, 0x80, 0x2a, 0x82, 0x29, 
+-      0x80, 0x6a, 0x84, 0x29, 0xd0, 0x54, 0x10, 0x4f, 
+-      0xa0, 0x6a, 0x01, 0x20, 0xd0, 0x00, 0xa0, 0x29, 
+-      0x80, 0x2b, 0x02, 0x30, 0xd0, 0x00, 0xa0, 0x38, 
+-      0x80, 0x3f, 0x01, 0xb0, 0xd0, 0x10, 0xa0, 0x37, 
+-      0x80, 0x3f, 0x02, 0x30, 0xd0, 0x01, 0xa0, 0x38, 
+-      0x00, 0xea, 0xd0, 0x00, 0xd0, 0x4e, 0x0f, 0x0b, 
+-      0x70, 0x40, 0x00, 0x06, 0x00, 0x21, 0xd0, 0x88, 
+-      0x00, 0xe1, 0xd0, 0x60, 0x60, 0x81, 0x00, 0x2b, 
+-      0xd0, 0x80, 0x00, 0xe0, 0xd0, 0x6c, 0x60, 0x81, 
+-      0xb0, 0x7c, 0x00, 0x27, 0xd0, 0xa0, 0x60, 0x81, 
+-      0xb0, 0x7c, 0xd0, 0x82, 0x60, 0x81, 0xb0, 0x7c, 
+-      0xd0, 0x85, 0x60, 0x81, 0xb0, 0x7c, 0x03, 0xaa, 
+-      0xd0, 0x98, 0x60, 0x81, 0xb0, 0x7c, 0x6e, 0x81, 
+-      0x00, 0x27, 0xd0, 0x40, 0x6e, 0x81, 0xb0, 0x7c, 
+-      0x6e, 0x81, 0xb0, 0x7c, 0x6e, 0x81, 0x00, 0x27, 
+-      0xd1, 0x90, 0x6e, 0x86, 0x00, 0x21, 0xd1, 0xb8, 
+-      0x6e, 0x86, 0x00, 0x66, 0xd1, 0xa0, 0xd0, 0x00, 
+-      0x01, 0x26, 0xd0, 0x58, 0x30, 0x01, 0x60, 0x06, 
+-      0x00, 0xed, 0xd1, 0xbc, 0x6e, 0x86, 0x00, 0xec, 
+-      0xd1, 0xb8, 0x6e, 0x86, 0xb1, 0x84, 0x6e, 0x86, 
+-      0x00, 0xee, 0xd1, 0x84, 0x70, 0x46, 0x00, 0x65, 
+-      0xd1, 0x94, 0x60, 0x46, 0x00, 0x64, 0xd1, 0xbc, 
+-      0x6e, 0x86, 0x00, 0x65, 0xd1, 0x80, 0x6e, 0x86, 
+-      0xb1, 0xbc, 0x6e, 0x86, 0xb1, 0xbc, 0x6e, 0x86, 
+-      0x00, 0xed, 0xd1, 0xa8, 0x6e, 0x86, 0xd0, 0x0e, 
+-      0xb1, 0xbc, 0x60, 0x06, 0xb1, 0xbc, 0x60, 0x06, 
+-      0x00, 0x65, 0xd1, 0xa4, 0x60, 0x06, 0x00, 0x28, 
+-      0xd1, 0xa4, 0x6e, 0x86, 0x00, 0x27, 0xd1, 0x98, 
+-      0x6e, 0x86, 0x00, 0x64, 0xd1, 0xa4, 0x6e, 0x86, 
+-      0xd2, 0x01, 0x00, 0x64, 0xd0, 0x60, 0x62, 0x01, 
+-      0x00, 0x64, 0xd1, 0x80, 0x70, 0x46, 0x6e, 0x86, 
+-      0x00, 0xef, 0xd1, 0x98, 0x70, 0x86, 0x08, 0x20, 
+-      0xd0, 0xcf, 0x30, 0xc1, 0xea, 0x42, 0xd0, 0x81, 
+-      0x00, 0x21, 0xd1, 0xa8, 0x60, 0x86, 0x00, 0xed, 
+-      0xd1, 0xa0, 0x6e, 0xc6, 0x00, 0x65, 0xd1, 0x98, 
+-      0x6e, 0xc6, 0x00, 0x22, 0xd0, 0x00, 0xa0, 0x05, 
+-      0x80, 0x40, 0x00, 0xc6, 0x01, 0x73, 0xd4, 0x3d, 
+-      0xe0, 0x46, 0x50, 0x00, 0x08, 0x20, 0xd0, 0x00, 
+-      0x5f, 0x00, 0x00, 0x64, 0xd0, 0x60, 0x70, 0xc1, 
+-      0x00, 0xec, 0xd0, 0x40, 0x71, 0x81, 0xb0, 0x7c, 
+-      0x71, 0xc1, 0xc0, 0x87, 0x30, 0x86, 0xf9, 0x83, 
+-      0x10, 0xee, 0xe9, 0x76, 0x10, 0xe1, 0xe9, 0x76, 
+-      0xe2, 0x57, 0x00, 0x63, 0xd0, 0xbf, 0x72, 0x06, 
+-      0xb1, 0xbc, 0x41, 0x82, 0x02, 0x1b, 0xe9, 0x8d, 
+-      0x72, 0x86, 0xb1, 0xbc, 0x41, 0x82, 0xd0, 0x75, 
+-      0x30, 0x48, 0xe9, 0xfe, 0xb0, 0x7f, 0xea, 0x00, 
+-      0x02, 0x1c, 0xe9, 0x96, 0x15, 0xa3, 0xea, 0x57, 
+-      0x10, 0xf0, 0xe9, 0x9a, 0x10, 0xfa, 0xf9, 0xa1, 
+-      0x15, 0xa3, 0xea, 0x57, 0x00, 0x21, 0xd0, 0x4c, 
+-      0x70, 0x41, 0x10, 0x61, 0xfa, 0x57, 0x00, 0xed, 
+-      0xd0, 0x08, 0x70, 0x40, 0xd0, 0x85, 0x40, 0x42, 
+-      0x60, 0x40, 0x00, 0x64, 0xd0, 0x64, 0x62, 0x01, 
+-      0x12, 0x2b, 0xe9, 0xeb, 0x12, 0x3b, 0xe9, 0xd5, 
+-      0x00, 0xec, 0xd0, 0x40, 0x61, 0x81, 0x12, 0x2d, 
+-      0xe9, 0xbf, 0x12, 0x30, 0xe9, 0xd4, 0x12, 0x36, 
+-      0xe9, 0xd4, 0x12, 0x3a, 0xe9, 0xd4, 0xd0, 0x62, 
+-      0x30, 0x48, 0xe9, 0xf2, 0x12, 0x2e, 0xe9, 0xf9, 
+-      0xe1, 0x76, 0x00, 0xed, 0xd0, 0x08, 0x70, 0x40, 
+-      0xd0, 0x85, 0x40, 0x42, 0x60, 0x40, 0xb0, 0x08, 
+-      0x00, 0x21, 0xd0, 0x41, 0x60, 0x40, 0x00, 0x64, 
+-      0xd0, 0x60, 0x62, 0x01, 0xf2, 0x5a, 0x00, 0xed, 
+-      0xd0, 0x20, 0xd0, 0x41, 0x60, 0x40, 0x10, 0xe1, 
+-      0xea, 0x3a, 0xe2, 0x57, 0xe2, 0x53, 0x10, 0xee, 
+-      0xf9, 0xe9, 0x01, 0x46, 0x82, 0x34, 0x80, 0x3f, 
+-      0x97, 0x2e, 0xc7, 0x5c, 0xa7, 0x66, 0x81, 0x34, 
+-      0x80, 0x3f, 0x00, 0x21, 0xd0, 0x01, 0xa0, 0x38, 
+-      0x00, 0xc6, 0x00, 0x21, 0xd0, 0x15, 0x0b, 0x09, 
+-      0x00, 0x4d, 0xb0, 0x01, 0xed, 0xe5, 0xd2, 0x1a, 
+-      0xe1, 0xec, 0xf1, 0x18, 0x00, 0xec, 0xd0, 0x40, 
+-      0x71, 0x81, 0xd0, 0x4e, 0x60, 0x46, 0xe2, 0x54, 
+-      0xc0, 0x0a, 0x10, 0x06, 0x52, 0x80, 0x00, 0xed, 
+-      0xd0, 0x40, 0x62, 0x81, 0xe2, 0x53, 0x00, 0x64, 
+-      0xd0, 0x60, 0x62, 0x01, 0xf2, 0x5a, 0xe1, 0x70, 
+-      0x12, 0xa3, 0xf6, 0x57, 0x15, 0xa1, 0xfa, 0x57, 
+-      0x12, 0xa0, 0xea, 0x23, 0x00, 0x65, 0xd1, 0x1c, 
+-      0xd0, 0x75, 0x30, 0x48, 0xea, 0x0a, 0xb1, 0x3c, 
+-      0x71, 0x04, 0x11, 0x20, 0xfa, 0x11, 0x00, 0xec, 
+-      0xd0, 0x40, 0x61, 0x81, 0xe2, 0x57, 0x12, 0xa1, 
+-      0xea, 0x33, 0x00, 0xe2, 0xd0, 0x60, 0x70, 0x01, 
+-      0xb0, 0x7c, 0x70, 0x41, 0x10, 0x0c, 0x50, 0x40, 
+-      0x0c, 0x30, 0xd0, 0x00, 0x31, 0x01, 0xee, 0x21, 
+-      0x21, 0x00, 0xe6, 0x57, 0xe2, 0x23, 0x31, 0x00, 
+-      0xfe, 0x57, 0xd0, 0x75, 0x30, 0x48, 0xea, 0x28, 
+-      0xf2, 0x5a, 0xe2, 0x0d, 0x00, 0xec, 0xd0, 0x40, 
+-      0x71, 0x81, 0x00, 0x63, 0xd1, 0x3f, 0xb1, 0xbc, 
+-      0x41, 0x84, 0x61, 0x81, 0xd0, 0x50, 0x60, 0x46, 
+-      0xe2, 0x57, 0x00, 0xed, 0xd0, 0x7c, 0x70, 0x41, 
+-      0x08, 0x20, 0xd0, 0x00, 0x10, 0x08, 0xe2, 0x1c, 
+-      0xd2, 0x84, 0x00, 0xed, 0xd1, 0xa4, 0x62, 0x86, 
+-      0xd5, 0x00, 0xb5, 0x01, 0x01, 0x46, 0x82, 0x34, 
+-      0x80, 0x3f, 0xc7, 0x5e, 0x97, 0x2e, 0x81, 0x34, 
+-      0x80, 0x3f, 0x02, 0xe8, 0xd0, 0x30, 0xa0, 0x37, 
+-      0xa0, 0x38, 0x08, 0x20, 0xdf, 0x00, 0x80, 0x73, 
+-      0x80, 0x3f, 0x00, 0xc6, 0x01, 0x7a, 0xde, 0x1a, 
+-      0xe0, 0x46, 0xf2, 0x5a, 0x00, 0x64, 0xd0, 0x60, 
+-      0x62, 0x01, 0x02, 0x3c, 0xda, 0x89, 0xe0, 0x46, 
+-      0x00, 0x28, 0xd0, 0x64, 0x70, 0x81, 0x00, 0x22, 
+-      0xd0, 0x00, 0x50, 0x80, 0x60, 0x81, 0x0f, 0xc5, 
+-      0x50, 0x00, 0x50, 0x00, 0x00, 0xed, 0xd1, 0xa4, 
+-      0x72, 0x86, 0x00, 0xef, 0xd1, 0x90, 0x70, 0x46, 
+-      0x10, 0x5c, 0x10, 0x65, 0xed, 0x7d, 0xd0, 0x46, 
+-      0xc0, 0x0a, 0x10, 0x40, 0x60, 0x46, 0x00, 0x22, 
+-      0xd0, 0x73, 0x30, 0x54, 0xe9, 0x8e, 0x12, 0xa4, 
+-      0xe9, 0xb5, 0x15, 0x20, 0xe9, 0xc0, 0xb0, 0x7b, 
+-      0xe9, 0xc3, 0xb0, 0x41, 0xe9, 0xc9, 0xc0, 0x54, 
+-      0x10, 0x5c, 0x10, 0x6e, 0xe9, 0xc6, 0xe1, 0xb5, 
+-      0x00, 0x28, 0xd1, 0xb0, 0xd0, 0x00, 0x60, 0x06, 
+-      0x12, 0xa4, 0xf9, 0xb2, 0x00, 0xed, 0xd1, 0x9c, 
+-      0x62, 0x86, 0xd2, 0x80, 0x00, 0xed, 0xd1, 0xa4, 
+-      0x62, 0x86, 0xd0, 0x02, 0x00, 0xec, 0xd1, 0xbc, 
+-      0x60, 0x06, 0x00, 0x64, 0xd1, 0xa0, 0x72, 0x06, 
+-      0x12, 0x21, 0xf9, 0xa6, 0xd2, 0x0d, 0x62, 0x06, 
+-      0x00, 0xed, 0xd1, 0xa0, 0x61, 0x86, 0xd0, 0x0e, 
+-      0x00, 0xed, 0xd1, 0xac, 0x60, 0x06, 0xb1, 0xbc, 
+-      0x60, 0x06, 0x00, 0x65, 0xd1, 0xa4, 0x60, 0x06, 
+-      0x01, 0x7e, 0xd2, 0x31, 0xe1, 0xcb, 0x01, 0x46, 
+-      0x90, 0x49, 0x00, 0x60, 0xd0, 0x00, 0x50, 0x40, 
+-      0xa0, 0x49, 0x80, 0x3f, 0x00, 0xc6, 0x0c, 0x09, 
+-      0x05, 0x0d, 0xe1, 0x70, 0x01, 0xbe, 0xde, 0x41, 
+-      0xe1, 0xcb, 0x01, 0xbb, 0xd8, 0x10, 0xe1, 0xcb, 
+-      0x01, 0xbd, 0xd8, 0x0b, 0xe1, 0xcb, 0x03, 0xb8, 
+-      0xda, 0x10, 0x01, 0x46, 0x90, 0x49, 0x00, 0x60, 
+-      0xd1, 0x00, 0x50, 0x44, 0x30, 0x44, 0xa0, 0x49, 
+-      0x80, 0x3f, 0x00, 0xc6, 0xe0, 0x46, 0x50, 0x00, 
+-      0x50, 0x00, 0x50, 0x00, 0x01, 0xfa, 0xd2, 0x3d, 
+-      0x00, 0x25, 0xdc, 0xd8, 0xf0, 0x4a, 0x00, 0x26, 
+-      0xd0, 0x18, 0xd0, 0x40, 0x60, 0x40, 0x00, 0x28, 
+-      0xd0, 0x24, 0x70, 0x40, 0xd0, 0x82, 0x50, 0x42, 
+-      0x60, 0x40, 0x00, 0xec, 0xd0, 0xa4, 0x70, 0xc2, 
+-      0x10, 0xe0, 0xf9, 0x81, 0x00, 0xec, 0xd1, 0x98, 
+-      0xd0, 0x41, 0x60, 0x46, 0x70, 0xc2, 0x10, 0xe0, 
+-      0xe9, 0x8e, 0xd0, 0x40, 0x60, 0x46, 0xe1, 0x81, 
+-      0xd0, 0x40, 0x00, 0xe6, 0xd0, 0x10, 0x60, 0x40, 
+-      0xb0, 0x3c, 0x60, 0x40, 0xb0, 0x3c, 0x60, 0x40, 
+-      0xd0, 0xe0, 0x00, 0xea, 0xd0, 0x40, 0x00, 0xe8, 
+-      0xd0, 0x82, 0x01, 0x46, 0x70, 0x01, 0xb0, 0x7c, 
+-      0x60, 0x02, 0xb0, 0xbc, 0x00, 0x06, 0x00, 0xc6, 
+-      0xb0, 0xc1, 0xed, 0x9b, 0x80, 0x49, 0xd6, 0x44, 
+-      0xd5, 0x43, 0x00, 0xe0, 0xd1, 0x80, 0x00, 0x06, 
+-      0x0b, 0x09, 0x01, 0x0d, 0x0b, 0x09, 0x61, 0x06, 
+-      0xb1, 0xbc, 0x01, 0x4d, 0x09, 0x09, 0x61, 0x46, 
+-      0xb1, 0xbc, 0x00, 0xcd, 0x09, 0x09, 0x10, 0xe4, 
+-      0xed, 0xb8, 0x60, 0xc6, 0xb1, 0xbc, 0x00, 0xcd, 
+-      0x60, 0xc6, 0x00, 0xed, 0xd0, 0x04, 0x70, 0x00, 
+-      0x10, 0x20, 0xf9, 0xd3, 0x10, 0xe3, 0xe9, 0xc4, 
+-      0x10, 0xe6, 0xf9, 0xd3, 0x01, 0x46, 0x90, 0x10, 
+-      0x00, 0x20, 0xd0, 0x44, 0x50, 0x40, 0x00, 0xc6, 
+-      0xa0, 0x50, 0x00, 0xa0, 0xd0, 0x00, 0xa0, 0x05, 
+-      0x80, 0x40, 0x00, 0xed, 0xd1, 0xa4, 0xd0, 0x04, 
+-      0x60, 0x06, 0x00, 0xee, 0xd1, 0xac, 0x73, 0x86, 
+-      0x10, 0xe3, 0xe5, 0xde, 0xe9, 0xe3, 0x00, 0xe7, 
+-      0xd0, 0x40, 0x00, 0xae, 0xd0, 0xbb, 0xe1, 0xe7, 
+-      0x01, 0x24, 0xd0, 0x6b, 0x00, 0xea, 0xd0, 0xa6, 
+-      0xe1, 0xe7, 0x01, 0x21, 0xd0, 0x7b, 0x00, 0xe8, 
+-      0xd0, 0x90, 0x13, 0xa0, 0xf9, 0xea, 0xc0, 0x42, 
+-      0x00, 0xe0, 0xd1, 0xa8, 0x60, 0x46, 0xb1, 0x98, 
+-      0x0b, 0xc9, 0x00, 0x4d, 0x09, 0x09, 0x10, 0x44, 
+-      0x00, 0x8d, 0x20, 0x42, 0x10, 0x5f, 0x60, 0x46, 
+-      0xb1, 0xb8, 0x00, 0x90, 0xea, 0x17, 0x0a, 0x89, 
+-      0x00, 0x8d, 0x60, 0x86, 0xb1, 0xbc, 0x08, 0x49, 
+-      0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 0x08, 0x49, 
+-      0x00, 0x4d, 0x60, 0x46, 0x10, 0x60, 0xea, 0x0b, 
+-      0x00, 0xe8, 0xd1, 0x80, 0xf2, 0xb0, 0x10, 0x60, 
+-      0xfa, 0x17, 0x08, 0x49, 0x00, 0xe0, 0xd1, 0xa4, 
+-      0x00, 0x4d, 0x60, 0x46, 0x10, 0x60, 0xea, 0x1b, 
+-      0x00, 0xe9, 0xd1, 0x80, 0xf2, 0xb0, 0x10, 0x60, 
+-      0xea, 0x1b, 0x00, 0xe0, 0xd1, 0x88, 0xd0, 0x40, 
+-      0x60, 0x46, 0xd0, 0x00, 0x00, 0xe0, 0xd1, 0xa8, 
+-      0x70, 0x46, 0x00, 0xef, 0xd1, 0x9c, 0x70, 0x86, 
+-      0xb0, 0xb0, 0xee, 0x25, 0xd0, 0x81, 0x00, 0x90, 
+-      0xea, 0x28, 0x20, 0x01, 0x10, 0x41, 0x10, 0x9f, 
+-      0x10, 0xa0, 0xee, 0x25, 0x10, 0x1c, 0x00, 0x65, 
+-      0xd1, 0xa8, 0x60, 0x06, 0x01, 0xb4, 0xd4, 0x3a, 
+-      0xe0, 0x46, 0x50, 0x00, 0x02, 0x31, 0xdc, 0x13, 
+-      0x00, 0x27, 0xdc, 0xd8, 0xf0, 0x4a, 0x0c, 0x09, 
+-      0x00, 0x06, 0x05, 0x0d, 0x00, 0x22, 0xd0, 0x72, 
+-      0x30, 0x54, 0xe9, 0xea, 0xb0, 0x7d, 0xfa, 0x05, 
+-      0x09, 0x09, 0x01, 0xcd, 0x11, 0xe1, 0xf9, 0xc7, 
+-      0x80, 0x09, 0x80, 0x27, 0x0a, 0x09, 0xd6, 0x45, 
+-      0x00, 0xe1, 0xd1, 0xa0, 0x00, 0x4d, 0x60, 0x46, 
+-      0xb1, 0xbc, 0x08, 0x49, 0x00, 0x4d, 0x60, 0x46, 
+-      0x00, 0x50, 0xe9, 0x91, 0xd4, 0x01, 0xb1, 0xbc, 
+-      0x08, 0x89, 0x00, 0x4d, 0x60, 0x46, 0x00, 0xe0, 
+-      0xd1, 0x80, 0x08, 0x89, 0x00, 0x4d, 0x08, 0x89, 
+-      0x10, 0x4c, 0x71, 0x06, 0x21, 0x01, 0x61, 0x06, 
+-      0xb1, 0xbc, 0x00, 0x4d, 0x0b, 0x49, 0x10, 0x4c, 
+-      0x71, 0x46, 0x21, 0x41, 0x61, 0x46, 0xb1, 0xb0, 
+-      0x00, 0x4d, 0x10, 0x5f, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x0a, 0x09, 0x00, 0x4d, 0x10, 0x4a, 0x70, 0x86, 
+-      0x20, 0x81, 0x60, 0x86, 0x00, 0xe1, 0xd1, 0xac, 
+-      0x08, 0x49, 0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x08, 0x89, 0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x09, 0x49, 0x00, 0x8d, 0x60, 0x86, 0xc0, 0x02, 
+-      0x00, 0xe0, 0xd1, 0xa8, 0x70, 0xc6, 0x10, 0xc0, 
+-      0xd0, 0x20, 0x30, 0x01, 0x10, 0xc0, 0x60, 0xc6, 
+-      0xe1, 0x75, 0x11, 0xe2, 0xf9, 0x75, 0x00, 0xe2, 
+-      0xd1, 0x80, 0x08, 0xc9, 0x00, 0x4d, 0x60, 0x46, 
+-      0xb1, 0xbc, 0x08, 0x49, 0x00, 0x4d, 0x60, 0x46, 
+-      0xb1, 0xbc, 0x10, 0x60, 0xf9, 0xd7, 0xb1, 0xb4, 
+-      0xe1, 0xde, 0xd2, 0x03, 0x0a, 0x09, 0x00, 0x4d, 
+-      0x60, 0x46, 0xb1, 0xbc, 0xb2, 0x01, 0xf9, 0xd8, 
+-      0x0b, 0xc9, 0x00, 0x4d, 0x10, 0x49, 0x10, 0x56, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x0b, 0x89, 0x00, 0x4d, 
+-      0x10, 0x4a, 0x10, 0x56, 0x60, 0x46, 0xe1, 0x75, 
+-      0x0b, 0x2c, 0xd4, 0x40, 0xf3, 0xb0, 0xe1, 0x77, 
+-      0x00, 0xe0, 0xd0, 0x6c, 0x00, 0xe0, 0xd1, 0x80, 
+-      0xd0, 0x0a, 0xf1, 0xfe, 0x00, 0xe1, 0xd1, 0xb0, 
+-      0xd0, 0x02, 0xf1, 0xfe, 0x00, 0xe0, 0xd1, 0x80, 
+-      0x76, 0x86, 0xb1, 0xbc, 0x73, 0x46, 0xe2, 0x3c, 
+-      0x70, 0x81, 0x60, 0x86, 0xb1, 0xbc, 0xb0, 0x7c, 
+-      0xb0, 0x01, 0xed, 0xfe, 0x0f, 0xc5, 0x00, 0xe1, 
+-      0xd1, 0xa0, 0x70, 0x46, 0xd0, 0x8f, 0x40, 0x42, 
+-      0x00, 0x25, 0xd0, 0xe0, 0x00, 0x24, 0xd1, 0x20, 
+-      0x10, 0x6a, 0xea, 0x1e, 0x00, 0x66, 0xd0, 0xe0, 
+-      0x00, 0x62, 0xd1, 0x00, 0x10, 0x66, 0xea, 0x1e, 
+-      0x00, 0x6e, 0xd0, 0xc0, 0x10, 0x64, 0xea, 0x1e, 
+-      0x00, 0x2b, 0xd0, 0xd0, 0x00, 0x29, 0xd1, 0x00, 
+-      0x00, 0xe0, 0xd1, 0x80, 0x76, 0x86, 0x16, 0xa0, 
+-      0xe9, 0xee, 0x30, 0xda, 0xe5, 0xee, 0xb1, 0xbc, 
+-      0x73, 0x46, 0x13, 0x60, 0xe9, 0xee, 0x31, 0x0d, 
+-      0xe5, 0xee, 0xd0, 0x82, 0xb1, 0xbc, 0x70, 0x46, 
+-      0x10, 0x60, 0xe9, 0xee, 0xb0, 0x81, 0xee, 0x2c, 
+-      0x00, 0xe0, 0xd0, 0x40, 0x00, 0xe0, 0xd1, 0xac, 
+-      0xd0, 0x0a, 0xf1, 0xfe, 0x00, 0xe1, 0xd0, 0x70, 
+-      0xd0, 0x02, 0xf1, 0xfe, 0x00, 0xec, 0xd1, 0x98, 
+-      0xd0, 0x40, 0x60, 0x46, 0x00, 0xe0, 0xd0, 0x8c, 
+-      0x70, 0x82, 0x00, 0x21, 0xd0, 0x70, 0x60, 0x81, 
+-      0xd0, 0x40, 0x00, 0x25, 0xd0, 0x20, 0x30, 0x1a, 
+-      0xfa, 0x50, 0x00, 0x23, 0xd0, 0x30, 0x30, 0x0d, 
+-      0xfa, 0x50, 0xd0, 0x41, 0x00, 0x21, 0xd1, 0x84, 
+-      0x60, 0x46, 0xb6, 0xb1, 0x16, 0x9c, 0x01, 0x7a, 
+-      0xde, 0x1a, 0xe0, 0x46, 0x02, 0x31, 0xdc, 0x13, 
+-      0x00, 0x27, 0xdc, 0xd8, 0xf0, 0x4a, 0x00, 0xec, 
+-      0xd0, 0xa8, 0x70, 0xc2, 0x10, 0xe0, 0xf9, 0x77, 
+-      0x00, 0xec, 0xd1, 0x9c, 0xd0, 0x41, 0x60, 0x46, 
+-      0x70, 0xc2, 0x10, 0xe0, 0xe9, 0x84, 0xd0, 0x40, 
+-      0x60, 0x46, 0xe1, 0x77, 0x0b, 0x49, 0x00, 0xe2, 
+-      0xd1, 0xa0, 0x00, 0x4d, 0x10, 0x5f, 0x00, 0x6f, 
+-      0xd0, 0xff, 0x40, 0x43, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x0b, 0x09, 0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x08, 0x89, 0x00, 0x4d, 0x60, 0x46, 0x10, 0x61, 
+-      0xf9, 0x9b, 0xd3, 0xc2, 0x00, 0xec, 0xd1, 0xbc, 
+-      0x63, 0xc6, 0x0c, 0x09, 0x90, 0x4d, 0x10, 0x60, 
+-      0xe5, 0x9c, 0x00, 0x06, 0x05, 0x0d, 0x00, 0x22, 
+-      0xd0, 0x72, 0x30, 0x54, 0xf9, 0xa9, 0x0b, 0xa0, 
+-      0xd4, 0x40, 0xf3, 0xb0, 0xe1, 0xa0, 0x00, 0xec, 
+-      0xd1, 0x9c, 0xd0, 0x40, 0x60, 0x46, 0x01, 0x7a, 
+-      0xde, 0x1a, 0xe0, 0x46, 0x0b, 0x09, 0x00, 0x4d, 
+-      0x0b, 0x09, 0x00, 0x4d, 0x0a, 0x09, 0x01, 0x4d, 
+-      0x0a, 0x09, 0x00, 0x4d, 0x01, 0x59, 0xe9, 0x96, 
+-      0x09, 0x09, 0x00, 0x4d, 0x10, 0x5f, 0x10, 0x61, 
+-      0xf9, 0x96, 0x09, 0x09, 0x01, 0x4d, 0x11, 0x5f, 
+-      0x0b, 0xc9, 0x00, 0x4d, 0xc0, 0x01, 0x10, 0x5f, 
+-      0x11, 0x4e, 0x51, 0x41, 0x08, 0x49, 0x00, 0x4d, 
+-      0x0b, 0xc9, 0x10, 0x0f, 0x00, 0x4d, 0x50, 0x01, 
+-      0x00, 0xed, 0xd1, 0xb6, 0x01, 0x46, 0x00, 0x06, 
+-      0xa0, 0x3c, 0xa1, 0x7d, 0x60, 0x06, 0x00, 0xc6, 
+-      0xd5, 0x00, 0xb5, 0x01, 0x01, 0x7a, 0xde, 0x1a, 
+-      0xe0, 0x46, 0x50, 0x00, 0x00, 0xec, 0xd0, 0xac, 
+-      0x70, 0xc2, 0x10, 0xe0, 0xf9, 0x70, 0x00, 0xec, 
+-      0xd1, 0xa0, 0xd0, 0x41, 0x60, 0x46, 0x70, 0xc2, 
+-      0x10, 0xe0, 0xe9, 0x7f, 0xd0, 0x40, 0x60, 0x46, 
+-      0xe1, 0x70, 0x0a, 0x89, 0x0b, 0xcd, 0x00, 0xe3, 
+-      0xd1, 0x80, 0x6b, 0xc6, 0x08, 0xc9, 0x05, 0x8d, 
+-      0x15, 0xa3, 0xee, 0x6e, 0x15, 0xa0, 0xea, 0x6e, 
+-      0x90, 0x4d, 0xd0, 0x9f, 0xd0, 0xdf, 0x40, 0x81, 
+-      0x10, 0x55, 0x40, 0xc1, 0x01, 0x46, 0x82, 0x34, 
+-      0x80, 0x3f, 0xc8, 0x1d, 0x81, 0x34, 0x80, 0x3f, 
+-      0x00, 0xc6, 0xd1, 0x23, 0x31, 0x03, 0x11, 0x02, 
+-      0x38, 0x04, 0xb0, 0x8d, 0x10, 0x9d, 0x28, 0x02, 
+-      0xc0, 0x60, 0x00, 0x65, 0xd1, 0x94, 0x71, 0x06, 
+-      0x68, 0x06, 0x30, 0x44, 0x00, 0xed, 0xd1, 0xa8, 
+-      0x70, 0x06, 0x10, 0x20, 0xe9, 0xb0, 0x00, 0xee, 
+-      0xd0, 0xc0, 0x70, 0xc3, 0x20, 0x43, 0xb0, 0x01, 
+-      0xf9, 0xac, 0x60, 0x06, 0x00, 0x64, 0xd1, 0xbc, 
+-      0x71, 0x06, 0xc0, 0x04, 0x21, 0x01, 0x61, 0x06, 
+-      0x10, 0x20, 0xf5, 0xbb, 0x11, 0x20, 0xe5, 0xbb, 
+-      0xb0, 0x41, 0x00, 0x65, 0xd1, 0x80, 0x71, 0x06, 
+-      0x21, 0x01, 0x61, 0x06, 0x00, 0xed, 0xd1, 0xac, 
+-      0x71, 0x06, 0x15, 0xa1, 0xe9, 0xcb, 0xb1, 0x3f, 
+-      0x61, 0x06, 0x15, 0xa3, 0xf9, 0xd6, 0xd0, 0xbf, 
+-      0xe1, 0xd3, 0xd0, 0x40, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x70, 0x86, 0x61, 0x06, 0x31, 0x02, 0xe5, 0xd3, 
+-      0x20, 0x84, 0x00, 0x65, 0xd1, 0xa4, 0x60, 0x86, 
+-      0xd9, 0x40, 0x00, 0xec, 0xd1, 0x94, 0x79, 0x06, 
+-      0xb1, 0x84, 0x78, 0xc6, 0xc0, 0x63, 0x30, 0x64, 
+-      0xe9, 0xf8, 0x00, 0xa7, 0xd0, 0xff, 0x7a, 0x63, 
+-      0x00, 0x65, 0xd0, 0x00, 0x71, 0x00, 0x31, 0x29, 
+-      0xe5, 0xf8, 0xc0, 0x63, 0xc8, 0xc1, 0xb0, 0x78, 
+-      0x40, 0x43, 0xc0, 0xa4, 0x30, 0x81, 0xe9, 0xf2, 
+-      0x7a, 0x41, 0x31, 0x29, 0xf5, 0xe8, 0x21, 0x29, 
+-      0x61, 0x00, 0xb8, 0xfc, 0x79, 0x63, 0xb8, 0xfc, 
+-      0x48, 0xc3, 0x68, 0xc6, 0x00, 0xed, 0xd1, 0xb8, 
+-      0x69, 0x46, 0x80, 0x28, 0x0b, 0xc9, 0x00, 0x4d, 
+-      0x08, 0x49, 0x10, 0x41, 0x00, 0xe3, 0xd1, 0x84, 
+-      0x00, 0x8d, 0x20, 0x42, 0x60, 0x46, 0x00, 0xee, 
+-      0xd1, 0xa4, 0x70, 0x86, 0x10, 0xa1, 0xee, 0x18, 
+-      0xe6, 0x6b, 0x90, 0x86, 0x00, 0x90, 0xea, 0x18, 
+-      0x00, 0xed, 0xd0, 0x1c, 0x70, 0x80, 0xb0, 0x81, 
+-      0xe6, 0x6b, 0x60, 0x80, 0xb1, 0xa8, 0x70, 0x86, 
+-      0x10, 0xa0, 0xfa, 0x6b, 0x00, 0x21, 0xd0, 0x38, 
+-      0x70, 0x80, 0x10, 0xa0, 0xfa, 0x6b, 0x0f, 0xef, 
+-      0xd0, 0xbf, 0x30, 0x81, 0xfa, 0x22, 0x60, 0x00, 
+-      0x08, 0x20, 0xd0, 0x00, 0x5f, 0x00, 0x15, 0xa3, 
+-      0xea, 0x6b, 0x00, 0xee, 0xd1, 0x80, 0x79, 0x46, 
+-      0x00, 0xf8, 0xd0, 0x00, 0xc4, 0x40, 0x00, 0xe3, 
+-      0xd1, 0x84, 0x78, 0x46, 0x0f, 0xef, 0xd0, 0x3f, 
+-      0x30, 0x21, 0xea, 0x48, 0x00, 0xe0, 0xd1, 0x90, 
+-      0x78, 0x06, 0xc0, 0xa1, 0x18, 0x43, 0x28, 0x42, 
+-      0x18, 0x43, 0x28, 0x42, 0x18, 0x1e, 0xd8, 0x80, 
+-      0x08, 0x11, 0xea, 0x41, 0x28, 0xa1, 0x18, 0x01, 
+-      0x18, 0x5f, 0x18, 0x60, 0xee, 0x3e, 0xc0, 0x51, 
+-      0x30, 0x62, 0xee, 0x4e, 0xc8, 0x91, 0x18, 0x9f, 
+-      0x00, 0x21, 0xd1, 0xb8, 0xd0, 0x01, 0x60, 0x06, 
+-      0x00, 0xef, 0xd0, 0x10, 0xd0, 0x72, 0x60, 0x40, 
+-      0x01, 0x46, 0x82, 0x34, 0x80, 0x3f, 0xc8, 0xdc, 
+-      0xc9, 0x1d, 0x81, 0x34, 0x80, 0x3f, 0x00, 0xc6, 
+-      0x38, 0xe4, 0xee, 0x5e, 0xea, 0x52, 0x28, 0xe5, 
+-      0x01, 0x46, 0x90, 0x6d, 0x28, 0xc1, 0x00, 0xc6, 
+-      0x38, 0xe2, 0xf6, 0x6b, 0xdb, 0x08, 0xf1, 0x16, 
+-      0xf1, 0x18, 0x00, 0x21, 0xd1, 0xb4, 0x61, 0x86, 
+-      0xe2, 0x52, 0x01, 0xf7, 0xd0, 0x19, 0xe0, 0x46, 
+-      0xd5, 0x00, 0xb5, 0x01, 0x01, 0x7a, 0xde, 0x1a, 
+-      0xe0, 0x46, 0x50, 0x00, 0x02, 0x31, 0xdc, 0x13, 
+-      0x00, 0x27, 0xdc, 0xd8, 0xf0, 0x4a, 0xdb, 0x09, 
+-      0x00, 0xe3, 0xd0, 0x1c, 0x6b, 0x00, 0xda, 0xc1, 
+-      0x00, 0xe6, 0xd1, 0x98, 0x70, 0x06, 0xb1, 0x84, 
+-      0x60, 0x06, 0xb1, 0x84, 0x60, 0x06, 0x05, 0x9f, 
+-      0xe9, 0x9f, 0x08, 0x49, 0xd1, 0x17, 0x46, 0x44, 
+-      0x00, 0x4d, 0x10, 0x43, 0x26, 0x41, 0x08, 0xc9, 
+-      0x05, 0xcd, 0xb5, 0xc1, 0xe5, 0xcc, 0xc0, 0x57, 
+-      0x15, 0xc6, 0x25, 0xc1, 0x15, 0xa3, 0xf9, 0x9f, 
+-      0x08, 0x49, 0xd1, 0x0f, 0x46, 0x44, 0x00, 0x4d, 
+-      0x10, 0x44, 0x26, 0x41, 0x08, 0xc9, 0x06, 0x0d, 
+-      0xb6, 0x01, 0xe5, 0xcc, 0xc0, 0x58, 0x16, 0x06, 
+-      0x26, 0x01, 0x08, 0x49, 0x00, 0x4d, 0x10, 0x60, 
+-      0xe9, 0xa6, 0x0a, 0x09, 0x00, 0x4d, 0xe1, 0x9f, 
+-      0x0c, 0x09, 0x90, 0x4d, 0x10, 0x60, 0xe5, 0xa7, 
+-      0x00, 0x06, 0x05, 0x0d, 0x00, 0x22, 0xd0, 0x72, 
+-      0x30, 0x54, 0xf9, 0xb3, 0xd4, 0x40, 0xf3, 0xb0, 
+-      0xe1, 0xab, 0xb0, 0x7d, 0xf9, 0xb8, 0x02, 0x34, 
+-      0xd2, 0x44, 0xe0, 0x46, 0x00, 0xec, 0xd1, 0xa0, 
+-      0xd0, 0x40, 0x60, 0x46, 0x02, 0x3c, 0xda, 0x89, 
+-      0x00, 0xec, 0xd1, 0x80, 0x70, 0x46, 0xb1, 0xbc, 
+-      0x70, 0x86, 0x30, 0x81, 0xe8, 0x46, 0x15, 0x63, 
+-      0xe9, 0xc9, 0x05, 0x5e, 0xe8, 0x46, 0x01, 0x73, 
+-      0xd4, 0x3d, 0xe0, 0x46, 0xd5, 0x00, 0xb5, 0x01, 
+-      0x01, 0x7a, 0xde, 0x1a, 0xe0, 0x46, 0x50, 0x00, 
+-      0x50, 0x00, 0x50, 0x00, 0xcc, 0xc0, 0xcd, 0x01, 
+-      0xcd, 0x42, 0xcd, 0x83, 0x00, 0xa0, 0xd0, 0x01, 
+-      0xa0, 0x38, 0xc8, 0x7f, 0xc8, 0x06, 0xb1, 0xbe, 
+-      0xf3, 0x96, 0xc8, 0x80, 0xf3, 0x92, 0x58, 0x80, 
+-      0xf3, 0x96, 0xc8, 0xc0, 0xf3, 0x96, 0xc9, 0x00, 
+-      0xf3, 0x92, 0x58, 0xc0, 0xf3, 0x96, 0xc9, 0x40, 
+-      0xf3, 0x92, 0x59, 0x40, 0xc0, 0x22, 0xc0, 0x65, 
+-      0xc0, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 0xc8, 0x80, 
+-      0xf3, 0x92, 0x59, 0x00, 0xf3, 0x96, 0xc9, 0x40, 
+-      0xf3, 0x96, 0xc9, 0x80, 0xf3, 0x92, 0x59, 0x40, 
+-      0xf3, 0x96, 0xc9, 0xc0, 0xf3, 0x92, 0x58, 0x80, 
+-      0xc0, 0x23, 0xc0, 0x62, 0xd0, 0x88, 0x20, 0x86, 
+-      0xf3, 0x9a, 0xf3, 0x96, 0xc8, 0xc0, 0xf3, 0x92, 
+-      0x58, 0xc0, 0xf3, 0x96, 0xc8, 0x80, 0xf3, 0x92, 
+-      0x59, 0xc0, 0xc0, 0x24, 0xc0, 0x67, 0xd0, 0x90, 
+-      0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 0xc9, 0x00, 
+-      0xf3, 0x92, 0x59, 0x80, 0xf3, 0x96, 0xc9, 0xc0, 
+-      0xf3, 0x96, 0xca, 0x00, 0xf3, 0x92, 0x59, 0xc0, 
+-      0xf3, 0x96, 0xca, 0x40, 0xf3, 0x92, 0x59, 0x00, 
+-      0xc0, 0x25, 0xc0, 0x64, 0xd0, 0x98, 0x20, 0x86, 
+-      0xf3, 0x9a, 0xf3, 0x96, 0xc9, 0x40, 0xf3, 0x92, 
+-      0x58, 0x80, 0xf3, 0x96, 0xc9, 0x00, 0xf3, 0x92, 
+-      0x59, 0x00, 0xc0, 0x23, 0xc0, 0x64, 0xd0, 0x84, 
+-      0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 0xc8, 0xc0, 
+-      0xf3, 0x92, 0x59, 0x40, 0xf3, 0x96, 0xc9, 0x00, 
+-      0xf3, 0x92, 0x5a, 0x40, 0xc0, 0x26, 0xc0, 0x69, 
+-      0xd0, 0xa0, 0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 
+-      0xc9, 0x80, 0xf3, 0x92, 0x5a, 0x00, 0xf3, 0x96, 
+-      0xca, 0x40, 0xf3, 0x92, 0x5a, 0x40, 0xf3, 0x96, 
+-      0xca, 0x80, 0xf3, 0x92, 0x59, 0x80, 0xc0, 0x27, 
+-      0xc0, 0x66, 0xd0, 0xa8, 0x20, 0x86, 0xf3, 0x9a, 
+-      0xf3, 0x96, 0xc9, 0xc0, 0xf3, 0x92, 0x59, 0x00, 
+-      0xf3, 0x96, 0xc9, 0x80, 0xf3, 0x92, 0x58, 0xc0, 
+-      0xc0, 0x22, 0xc0, 0x63, 0xd0, 0x8c, 0x20, 0x86, 
+-      0xf3, 0x9a, 0xf3, 0x92, 0x59, 0x80, 0xc0, 0x25, 
+-      0xc0, 0x66, 0xd0, 0x94, 0x20, 0x86, 0xf3, 0x9a, 
+-      0xf3, 0x96, 0xc8, 0x80, 0xf3, 0x92, 0x59, 0xc0, 
+-      0xf3, 0x96, 0xc8, 0xc0, 0xf3, 0x92, 0x5a, 0x80, 
+-      0xc0, 0x28, 0xc0, 0x6a, 0xd0, 0xb0, 0x20, 0x86, 
+-      0xf3, 0x9a, 0xf3, 0x96, 0xc9, 0x40, 0xf3, 0x92, 
+-      0x59, 0x40, 0xc0, 0x29, 0xc0, 0x65, 0xd0, 0xb8, 
+-      0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 0xc9, 0x80, 
+-      0xf3, 0x92, 0x58, 0xc0, 0xf3, 0x96, 0xca, 0x00, 
+-      0xf3, 0x92, 0x58, 0x80, 0xc0, 0x24, 0xc0, 0x62, 
+-      0xd0, 0x9c, 0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x92, 
+-      0x5a, 0x00, 0xc0, 0x27, 0xc0, 0x68, 0xd0, 0xa4, 
+-      0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 0xca, 0x80, 
+-      0xf3, 0x92, 0x59, 0x80, 0xf3, 0x96, 0xca, 0x40, 
+-      0xf3, 0x92, 0x5a, 0x40, 0xf3, 0x96, 0xc9, 0x40, 
+-      0xf3, 0x92, 0x5a, 0x80, 0xc0, 0x23, 0xc0, 0x6a, 
+-      0xd0, 0xac, 0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x92, 
+-      0x59, 0x40, 0xc0, 0x26, 0xc0, 0x65, 0xd0, 0xb4, 
+-      0x20, 0x86, 0xf3, 0x9a, 0xf3, 0x96, 0xc9, 0x00, 
+-      0xf3, 0x92, 0x59, 0x00, 0xc0, 0x29, 0xc0, 0x64, 
+-      0xd0, 0xbc, 0x20, 0x86, 0xf3, 0x9a, 0xc0, 0x33, 
+-      0xc0, 0x74, 0xc0, 0xb5, 0xc0, 0xf6, 0xd0, 0x40, 
+-      0x00, 0xa0, 0xd8, 0x00, 0xa8, 0x38, 0x08, 0x45, 
+-      0x0a, 0x09, 0x00, 0x0d, 0x0f, 0xc5, 0x50, 0x00, 
+-      0x0a, 0x09, 0x00, 0x0d, 0x10, 0x08, 0x0f, 0xc5, 
+-      0x01, 0x46, 0x00, 0x06, 0xa0, 0x7c, 0xa0, 0x3d, 
+-      0x60, 0x42, 0x00, 0xc6, 0x0f, 0xc5, 0x50, 0x00, 
+-      0x50, 0x00, 0x50, 0x00, 0x14, 0x48, 0xd0, 0x81, 
+-      0x00, 0xef, 0xd1, 0x8c, 0x71, 0x46, 0x11, 0x60, 
+-      0xfb, 0xb1, 0x60, 0x86, 0x71, 0x46, 0x31, 0x42, 
+-      0xfb, 0xb1, 0x00, 0xec, 0xd1, 0x0c, 0x74, 0x84, 
+-      0x00, 0x68, 0xd0, 0x80, 0x70, 0x02, 0x10, 0x20, 
+-      0xfb, 0xc4, 0xc4, 0x82, 0xc4, 0xd2, 0xb4, 0xfc, 
+-      0xda, 0x00, 0xda, 0x4f, 0x0a, 0x09, 0x0f, 0xef, 
+-      0xd0, 0x3f, 0xb4, 0x7f, 0xca, 0x29, 0x1a, 0x18, 
+-      0x4a, 0x00, 0x1a, 0x48, 0x00, 0x8d, 0x2a, 0x42, 
+-      0xd0, 0x03, 0x40, 0x11, 0xfb, 0xe3, 0xb4, 0x44, 
+-      0x00, 0xa0, 0xd0, 0xc0, 0x30, 0xd3, 0xff, 0xe3, 
+-      0xb4, 0xfe, 0x01, 0x46, 0x00, 0x06, 0xaa, 0x3d, 
+-      0xaa, 0x7c, 0x6a, 0x53, 0x00, 0xc6, 0xb4, 0xfe, 
+-      0xb4, 0x7c, 0x1a, 0x61, 0xfb, 0xc8, 0xb4, 0x43, 
+-      0x00, 0xef, 0xd0, 0x3f, 0x40, 0x11, 0xeb, 0xf7, 
+-      0xb0, 0xc4, 0xe7, 0xf7, 0xeb, 0xee, 0x61, 0x53, 
+-      0x64, 0x52, 0x64, 0xc4, 0x00, 0x28, 0xd1, 0x24, 
+-      0x70, 0x04, 0x00, 0x21, 0xd0, 0x80, 0x50, 0x02, 
+-      0x60, 0x04, 0x61, 0x46, 0x0a, 0x09, 0x0f, 0xc5, 
+-      0x50, 0x00, 0x50, 0x00, 0x02, 0x31, 0xdc, 0x13, 
+-      0x00, 0x27, 0xdc, 0xd8, 0xf0, 0x4a, 0x01, 0xfa, 
+-      0xd2, 0x3d, 0x00, 0x25, 0xdc, 0xd8, 0xf0, 0x4a, 
+-      0x09, 0x09, 0x01, 0xcd, 0x11, 0xe8, 0xf9, 0xe2, 
+-      0x00, 0xe3, 0xd1, 0x9c, 0x09, 0x09, 0x05, 0xcd, 
+-      0xb5, 0xc1, 0x09, 0x09, 0x00, 0x4d, 0xb0, 0x41, 
+-      0x10, 0x46, 0x25, 0xc1, 0x09, 0x09, 0x06, 0x0d, 
+-      0xb6, 0x01, 0x09, 0x09, 0x00, 0x4d, 0x08, 0x89, 
+-      0xb0, 0x41, 0x10, 0x46, 0x26, 0x01, 0x00, 0x8d, 
+-      0x08, 0x89, 0x10, 0x82, 0xd0, 0x04, 0xc0, 0x55, 
+-      0x00, 0x40, 0x40, 0x40, 0x05, 0x4d, 0x08, 0x49, 
+-      0x0b, 0x0d, 0xd1, 0x00, 0x15, 0x63, 0xe9, 0xa2, 
+-      0xd1, 0x01, 0x55, 0x41, 0xdb, 0x01, 0x4b, 0x15, 
+-      0xa1, 0x1b, 0x08, 0x89, 0x00, 0x4d, 0x08, 0x49, 
+-      0x10, 0x41, 0xd1, 0x19, 0x46, 0x44, 0x26, 0x41, 
+-      0x00, 0xcd, 0x08, 0x49, 0x10, 0xc4, 0x00, 0x4d, 
+-      0x08, 0x49, 0x10, 0x41, 0x20, 0x81, 0xa0, 0x89, 
+-      0x00, 0x4d, 0x10, 0x43, 0x20, 0xc1, 0xa0, 0xe8, 
+-      0x08, 0x49, 0x00, 0x4d, 0x1b, 0x03, 0x5b, 0x01, 
+-      0xbb, 0x3f, 0x6b, 0x06, 0x08, 0x49, 0xb1, 0xbc, 
+-      0x00, 0x4d, 0x60, 0x46, 0x08, 0x49, 0xb1, 0xbc, 
+-      0x0a, 0xcd, 0x1a, 0xc2, 0x4a, 0xd9, 0x1a, 0xde, 
+-      0x6a, 0xc6, 0x08, 0x49, 0xb1, 0xbc, 0x00, 0x4d, 
+-      0x60, 0x46, 0x10, 0x60, 0xea, 0x3e, 0xb1, 0xbc, 
+-      0x08, 0x49, 0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x08, 0xc9, 0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x08, 0x49, 0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x09, 0xc9, 0x00, 0x4d, 0x60, 0x46, 0xb1, 0xbc, 
+-      0x0a, 0x09, 0x00, 0x4d, 0x60, 0x46, 0xe2, 0x3e, 
+-      0x11, 0xe3, 0xfa, 0x00, 0x00, 0xe7, 0xd0, 0xc0, 
+-      0xd0, 0x84, 0xb0, 0x81, 0xe6, 0x3e, 0x08, 0x49, 
+-      0x00, 0x4d, 0x60, 0x43, 0xb0, 0xfc, 0x10, 0x60, 
+-      0xe9, 0xe7, 0x10, 0xa3, 0xf9, 0xf4, 0x00, 0xe8, 
+-      0xd1, 0x80, 0xe1, 0xf8, 0x10, 0xa2, 0xf9, 0xfa, 
+-      0x00, 0xe9, 0xd1, 0x80, 0xf2, 0xb0, 0xe1, 0xe7, 
+-      0xd2, 0x3f, 0x0a, 0x09, 0x00, 0x4d, 0xb2, 0x01, 
+-      0xf5, 0xfb, 0xe1, 0xe7, 0x11, 0xe7, 0xfa, 0x3e, 
+-      0xd4, 0x01, 0x00, 0xe1, 0xd0, 0x24, 0x70, 0x00, 
+-      0x10, 0x21, 0xea, 0x0d, 0x15, 0x63, 0xfa, 0x0d, 
+-      0xd4, 0x03, 0x44, 0x2c, 0xb4, 0x3f, 0x00, 0xe6, 
+-      0xd1, 0x90, 0x0b, 0x09, 0x00, 0x4d, 0x09, 0x49, 
+-      0x10, 0x45, 0x00, 0x8d, 0x50, 0x81, 0xd0, 0x40, 
+-      0x10, 0x87, 0x10, 0x98, 0x30, 0x42, 0xf2, 0x61, 
+-      0x60, 0x46, 0xb1, 0xbc, 0x0b, 0x09, 0x00, 0x0d, 
+-      0x09, 0x49, 0x00, 0x0d, 0xb4, 0x01, 0xfa, 0x0f, 
+-      0x00, 0xe6, 0xd0, 0x18, 0x30, 0x06, 0xe6, 0x29, 
+-      0x60, 0x46, 0xb1, 0xbc, 0xe2, 0x22, 0x00, 0xe0, 
+-      0xd1, 0x88, 0x70, 0x46, 0x10, 0x63, 0xea, 0x39, 
+-      0x10, 0x64, 0xea, 0x39, 0x00, 0xe6, 0xd1, 0x90, 
+-      0xd0, 0x00, 0x60, 0x06, 0xb1, 0xbc, 0x60, 0x06, 
+-      0xb1, 0xbc, 0x60, 0x06, 0xe2, 0x3e, 0x00, 0xef, 
+-      0xd1, 0x84, 0x70, 0x46, 0x10, 0x60, 0xfa, 0x30, 
+-      0x0c, 0x09, 0x90, 0x4d, 0x10, 0x60, 0xe6, 0x3f, 
+-      0x00, 0x06, 0x05, 0x0d, 0x00, 0x22, 0xd0, 0x72, 
+-      0x30, 0x54, 0xfa, 0x4b, 0xd4, 0x40, 0xf3, 0xb0, 
+-      0xe2, 0x43, 0xb0, 0x7d, 0xe9, 0x7a, 0x00, 0xec, 
+-      0xd1, 0xa0, 0xd0, 0x40, 0x60, 0x46, 0x02, 0x3c, 
+-      0xda, 0x89, 0x00, 0xec, 0xd1, 0x80, 0x70, 0x46, 
+-      0xb1, 0xbc, 0x70, 0x86, 0x30, 0x81, 0xe8, 0x46, 
+-      0x15, 0x63, 0xea, 0x5e, 0x05, 0x5e, 0xe8, 0x46, 
+-      0x01, 0x73, 0xd4, 0x3d, 0xe0, 0x46, 0x00, 0xe0, 
+-      0xd0, 0x00, 0x70, 0xc0, 0x10, 0xc1, 0x00, 0xe0, 
+-      0xd0, 0x08, 0x70, 0x00, 0x10, 0x23, 0xea, 0x75, 
+-      0xc0, 0x83, 0x10, 0x9d, 0x30, 0xc2, 0x10, 0x9f, 
+-      0x30, 0xc2, 0x00, 0xef, 0xd0, 0xac, 0x70, 0x82, 
+-      0x10, 0xa3, 0xea, 0x75, 0x10, 0xc1, 0xc0, 0x83, 
+-      0x30, 0x81, 0xe6, 0x7e, 0xc0, 0x83, 0x20, 0x81, 
+-      0xf6, 0x7f, 0xd0, 0x40, 0x30, 0x43, 0x0f, 0xc5, 
+-      0xc0, 0x43, 0x0f, 0xc5, 0x00, 0xed, 0xd1, 0xa4, 
+-      0x72, 0x86, 0x15, 0xa3, 0xee, 0x23, 0x15, 0xa1, 
+-      0xe6, 0x23, 0x08, 0x20, 0xd0, 0x00, 0x5f, 0x00, 
+-      0xd8, 0xc4, 0x15, 0x63, 0xe9, 0x7e, 0x48, 0xd5, 
+-      0x18, 0xde, 0x18, 0xe0, 0xe9, 0xc2, 0x00, 0xed, 
+-      0xd1, 0xb4, 0x79, 0xc6, 0x19, 0xe0, 0xe9, 0x8c, 
+-      0x00, 0xed, 0xd0, 0x3a, 0x79, 0xc6, 0x69, 0xc0, 
+-      0xd9, 0xc0, 0x69, 0xc6, 0x00, 0xed, 0xd0, 0x38, 
+-      0x79, 0x40, 0x19, 0x60, 0xe9, 0x98, 0x00, 0x28, 
+-      0xd0, 0x24, 0x70, 0x40, 0x02, 0x20, 0xd0, 0x80, 
+-      0x50, 0x42, 0x60, 0x40, 0x15, 0xa3, 0xe9, 0x9f, 
+-      0x00, 0xec, 0xd1, 0xb8, 0x79, 0xc6, 0x69, 0x46, 
+-      0xc9, 0x67, 0x00, 0xec, 0xd9, 0xb4, 0x70, 0x66, 
+-      0x00, 0xec, 0xd1, 0xbc, 0x70, 0x06, 0x10, 0x20, 
+-      0xed, 0xbe, 0x10, 0x60, 0xe9, 0xc1, 0x00, 0xe0, 
+-      0xda, 0xa8, 0x7a, 0xaa, 0xc0, 0x2a, 0x10, 0x1f, 
+-      0x00, 0x22, 0xd0, 0xa0, 0x70, 0x82, 0x20, 0x6a, 
+-      0x00, 0x9f, 0xe9, 0xb5, 0x20, 0x40, 0x19, 0x60, 
+-      0xf9, 0xb8, 0xc9, 0x41, 0xb0, 0x48, 0x30, 0x65, 
+-      0xf5, 0xbd, 0xb0, 0x70, 0xed, 0xbe, 0xd9, 0x40, 
+-      0x00, 0xed, 0xd1, 0xbc, 0x69, 0x46, 0x69, 0x66, 
+-      0x12, 0xa4, 0xea, 0x21, 0x00, 0xec, 0xd1, 0xbc, 
+-      0x73, 0xc6, 0x15, 0xa3, 0xe9, 0xdf, 0x33, 0xe3, 
+-      0xe5, 0xd3, 0xed, 0xd2, 0x63, 0xc6, 0x00, 0x21, 
+-      0xd1, 0xa8, 0x63, 0xc6, 0x00, 0xed, 0xd1, 0xa0, 
+-      0x63, 0xc6, 0x15, 0xa1, 0xf9, 0xdc, 0x12, 0xa3, 
+-      0xe5, 0xe3, 0xd3, 0xc2, 0x00, 0xec, 0xd1, 0xbc, 
+-      0x63, 0xc6, 0xe1, 0xe3, 0x12, 0xa3, 0xea, 0x21, 
+-      0xe1, 0xe3, 0x12, 0xa2, 0xf6, 0x21, 0x13, 0xe0, 
+-      0xfa, 0x21, 0x00, 0xee, 0xd1, 0x8c, 0x78, 0x06, 
+-      0xb1, 0xbc, 0x78, 0x46, 0xb1, 0xbc, 0x78, 0x86, 
+-      0xd1, 0x88, 0x72, 0x46, 0xd1, 0x84, 0x73, 0x06, 
+-      0x13, 0x20, 0xf9, 0xe3, 0x00, 0x64, 0xd1, 0xa0, 
+-      0x70, 0x46, 0xd0, 0xa2, 0x30, 0x81, 0xe9, 0xff, 
+-      0x10, 0x70, 0xea, 0x11, 0x10, 0x6d, 0xea, 0x14, 
+-      0x10, 0x76, 0xea, 0x19, 0x10, 0x7a, 0xea, 0x28, 
+-      0xe2, 0x3b, 0x18, 0xe0, 0xea, 0x3b, 0x00, 0xed, 
+-      0xd1, 0x80, 0x70, 0x86, 0xb0, 0x81, 0xd0, 0x3f, 
+-      0x40, 0x02, 0x10, 0x20, 0xea, 0x0c, 0x60, 0x86, 
+-      0xf3, 0x8a, 0xe1, 0xe3, 0xc0, 0x02, 0x10, 0x1a, 
+-      0x50, 0x80, 0x60, 0x86, 0xe2, 0x3b, 0x15, 0xa3, 
+-      0xea, 0x21, 0xe2, 0xe9, 0xd2, 0x80, 0x00, 0xed, 
+-      0xd1, 0xa4, 0x62, 0x86, 0xe3, 0x0c, 0x00, 0xed, 
+-      0xd1, 0x88, 0xd0, 0x60, 0x70, 0x06, 0x50, 0x40, 
+-      0x60, 0x46, 0x15, 0xa3, 0xfb, 0x0c, 0xd5, 0x84, 
+-      0xe3, 0x0c, 0xd5, 0x00, 0xb5, 0x01, 0x01, 0x7a, 
+-      0xde, 0x1a, 0xe0, 0x46, 0x00, 0xed, 0xd1, 0x88, 
+-      0xd0, 0x60, 0x70, 0x06, 0x50, 0x40, 0x60, 0x46, 
+-      0x15, 0xa2, 0xe7, 0x0c, 0xee, 0x21, 0x00, 0x21, 
+-      0xd1, 0x8c, 0x18, 0xe0, 0xfa, 0x39, 0x70, 0x46, 
+-      0x10, 0x61, 0xea, 0x70, 0xe2, 0x21, 0x65, 0x86, 
+-      0xe2, 0x21, 0x18, 0xe0, 0xea, 0x70, 0xd1, 0x80, 
+-      0x73, 0x06, 0x15, 0xa2, 0xee, 0x68, 0x00, 0x22, 
+-      0xd1, 0x80, 0x70, 0x46, 0x6b, 0x06, 0xcb, 0x01, 
+-      0xb1, 0xb4, 0x70, 0x46, 0x6a, 0xc6, 0xca, 0xc1, 
+-      0x00, 0x65, 0xd1, 0x98, 0x70, 0x46, 0x10, 0x61, 
+-      0xfa, 0x50, 0x02, 0x41, 0xc3, 0x21, 0xc7, 0xe0, 
+-      0x02, 0x50, 0xea, 0x56, 0xc3, 0x20, 0xc7, 0xe1, 
+-      0xd1, 0x88, 0xd0, 0x01, 0x02, 0x40, 0x62, 0x46, 
+-      0x0f, 0xef, 0xd0, 0x7f, 0x30, 0x6f, 0xfa, 0x5f, 
+-      0xc3, 0x20, 0xc7, 0x4c, 0xd0, 0x00, 0x00, 0x65, 
+-      0xd1, 0x98, 0x70, 0x46, 0x60, 0x06, 0xb0, 0x41, 
+-      0x43, 0x01, 0xe2, 0x70, 0xc3, 0x22, 0xc7, 0xcc, 
+-      0xc7, 0x60, 0xc7, 0xa1, 0x02, 0x50, 0xea, 0x70, 
+-      0xc7, 0x61, 0xc7, 0xa0, 0xdb, 0x80, 0xd1, 0x00, 
+-      0x00, 0xef, 0xd1, 0xa8, 0x70, 0x46, 0x10, 0x60, 
+-      0xfa, 0x7a, 0x00, 0xe0, 0xd1, 0x88, 0x70, 0x46, 
+-      0x00, 0x22, 0xd1, 0xb0, 0x70, 0x86, 0x30, 0x81, 
+-      0xea, 0x82, 0x60, 0x46, 0xd0, 0x20, 0xf3, 0x06, 
+-      0x10, 0x63, 0xea, 0x87, 0x10, 0x64, 0xea, 0x87, 
+-      0xe2, 0x95, 0x00, 0xef, 0xd1, 0x6c, 0x71, 0x45, 
+-      0xc0, 0x05, 0x30, 0x01, 0xf6, 0x95, 0xdb, 0x82, 
+-      0xd1, 0x01, 0x10, 0x63, 0xea, 0x95, 0xd1, 0x02, 
+-      0x11, 0x62, 0xea, 0x95, 0xd1, 0x03, 0xd1, 0x8c, 
+-      0x61, 0x06, 0xdb, 0x40, 0x00, 0xe0, 0xd0, 0x00, 
+-      0x71, 0x00, 0xc0, 0x84, 0x10, 0x9c, 0xb0, 0x96, 
+-      0xfa, 0xa0, 0xb1, 0x38, 0xb0, 0x96, 0xfa, 0xa3, 
+-      0xb1, 0x30, 0x00, 0x29, 0xd1, 0x84, 0x00, 0x22, 
+-      0xd0, 0x74, 0x70, 0x86, 0x70, 0xc1, 0x61, 0x06, 
+-      0x30, 0xc2, 0xea, 0xae, 0x60, 0x81, 0xdb, 0x41, 
+-      0xb0, 0x3c, 0xb1, 0xbc, 0xb0, 0x7c, 0x71, 0x00, 
+-      0x70, 0x86, 0x70, 0xc1, 0x61, 0x06, 0x30, 0xc2, 
+-      0xea, 0xb9, 0x60, 0x81, 0xdb, 0x41, 0x00, 0xee, 
+-      0xd1, 0xb4, 0x70, 0x06, 0xb1, 0xbc, 0x70, 0x46, 
+-      0x30, 0x40, 0xea, 0xc2, 0x60, 0x06, 0xdb, 0x41, 
+-      0x00, 0x23, 0xd0, 0x70, 0x30, 0x81, 0xea, 0xc7, 
+-      0x30, 0x81, 0x50, 0x02, 0xea, 0xca, 0xd0, 0x01, 
+-      0x00, 0x22, 0xd1, 0xbc, 0x70, 0x86, 0x30, 0x80, 
+-      0xea, 0xd2, 0x60, 0x06, 0xd0, 0x10, 0xf3, 0x06, 
+-      0x00, 0x22, 0xd1, 0xa4, 0x71, 0x06, 0xd0, 0x01, 
+-      0x41, 0x00, 0x5b, 0x44, 0x5b, 0x6e, 0x6b, 0x46, 
+-      0x00, 0x28, 0xd0, 0x70, 0x70, 0x41, 0x10, 0x62, 
+-      0xfa, 0xe6, 0xd1, 0x84, 0x70, 0x06, 0x10, 0x20, 
+-      0xfa, 0xdf, 0x00, 0x22, 0xd0, 0x00, 0xf3, 0x06, 
+-      0x02, 0x7d, 0xdc, 0x62, 0xe0, 0x46, 0x00, 0xed, 
+-      0xd1, 0x88, 0x71, 0x06, 0x01, 0x1f, 0xfa, 0xfd, 
+-      0xd0, 0x41, 0x41, 0x01, 0xd0, 0x62, 0x00, 0x65, 
+-      0xd0, 0x30, 0x70, 0x00, 0x10, 0x21, 0xea, 0xfa, 
+-      0xee, 0xf9, 0x1a, 0xe1, 0xfa, 0xfa, 0xd0, 0x52, 
+-      0x51, 0x01, 0x61, 0x06, 0xe3, 0x0c, 0x18, 0xe0, 
+-      0xea, 0x70, 0xc7, 0x60, 0xc7, 0xe1, 0x02, 0x50, 
+-      0xea, 0x70, 0xc7, 0x61, 0xc7, 0xe0, 0xe2, 0x70, 
+-      0x00, 0x28, 0xdc, 0xa4, 0x7c, 0x72, 0x5c, 0x40, 
+-      0x6c, 0x72, 0x0f, 0xc5, 0x18, 0xe0, 0xeb, 0x82, 
+-      0xd9, 0x0d, 0x00, 0xee, 0xd1, 0xa4, 0x70, 0x06, 
+-      0x10, 0x21, 0xfb, 0x7f, 0xd9, 0x0c, 0x90, 0x06, 
+-      0x00, 0x10, 0xeb, 0x7f, 0x00, 0x21, 0xd1, 0x88, 
+-      0x7a, 0x06, 0x1a, 0x20, 0xeb, 0x7f, 0xd9, 0x00, 
+-      0x00, 0xed, 0xd1, 0xbc, 0x79, 0x46, 0x19, 0x60, 
+-      0xeb, 0x7f, 0x39, 0x68, 0xc0, 0xe5, 0xc0, 0x25, 
+-      0x10, 0x13, 0xb0, 0x0f, 0xef, 0x7f, 0xb0, 0x22, 
+-      0xe7, 0x7f, 0x00, 0xe0, 0xd1, 0xa8, 0x71, 0x46, 
+-      0x11, 0x5f, 0x29, 0x45, 0x00, 0x22, 0xd0, 0x18, 
+-      0x00, 0x22, 0xd4, 0x54, 0x00, 0x22, 0xd0, 0x9c, 
+-      0x70, 0x00, 0x74, 0x51, 0x70, 0x42, 0x34, 0x40, 
+-      0xe7, 0x3c, 0xd0, 0x40, 0x00, 0x22, 0xd4, 0x50, 
+-      0x74, 0x51, 0x34, 0x40, 0xef, 0x42, 0x20, 0x45, 
+-      0x60, 0x42, 0x39, 0x41, 0x19, 0x60, 0xf7, 0x5e, 
+-      0x00, 0x65, 0xd1, 0xa8, 0x7a, 0x86, 0x29, 0x6a, 
+-      0x19, 0x59, 0xb9, 0x7e, 0xf7, 0x75, 0x15, 0xa3, 
+-      0xf7, 0x57, 0x00, 0xed, 0xd1, 0xac, 0x70, 0x06, 
+-      0x00, 0xed, 0xd1, 0xb0, 0x70, 0x46, 0x30, 0x01, 
+-      0xfb, 0x7f, 0x00, 0x65, 0xd1, 0x84, 0x70, 0x46, 
+-      0xb0, 0x7f, 0x60, 0x46, 0xd5, 0x84, 0xe3, 0x7f, 
+-      0x11, 0x41, 0xd0, 0x4a, 0x00, 0xed, 0xd1, 0xa0, 
+-      0x74, 0x46, 0xd0, 0x00, 0x60, 0x06, 0x30, 0xc5, 
+-      0x39, 0x45, 0xe7, 0x6e, 0x14, 0x60, 0xeb, 0x6b, 
+-      0xf3, 0x85, 0xb0, 0x41, 0xef, 0x65, 0xe3, 0x71, 
+-      0x00, 0x66, 0xd1, 0xa0, 0x60, 0xc6, 0x15, 0xa3, 
+-      0xeb, 0x7f, 0xf3, 0x85, 0xe3, 0x7f, 0xd9, 0x01, 
+-      0x00, 0x66, 0xd1, 0xa0, 0x70, 0x06, 0x30, 0x03, 
+-      0xe7, 0x7e, 0x10, 0x1d, 0x10, 0x3b, 0xe7, 0x7f, 
+-      0x60, 0xc6, 0x00, 0x66, 0xd1, 0xa4, 0x69, 0x06, 
+-      0x15, 0xa4, 0xea, 0x23, 0xe2, 0x3b, 0x00, 0x65, 
+-      0xdd, 0x08, 0x7c, 0xf4, 0xbc, 0xff, 0x6c, 0xf4, 
+-      0x00, 0xef, 0xdd, 0x10, 0x7c, 0xf4, 0xbc, 0xfe, 
+-      0x6c, 0xf4, 0xc0, 0x3f, 0xf1, 0x18, 0xf1, 0x16, 
+-      0xf1, 0x18, 0x00, 0x05, 0x08, 0x20, 0xd0, 0x40, 
+-      0x5f, 0x01, 0x15, 0x63, 0xe9, 0x77, 0x05, 0x5e, 
+-      0xea, 0xf2, 0x00, 0x22, 0xd1, 0xa0, 0x6b, 0x06, 
+-      0x00, 0x22, 0xd1, 0xa8, 0x6b, 0xc6, 0x00, 0x22, 
+-      0xd1, 0xac, 0x6a, 0xc6, 0x00, 0xee, 0xd0, 0x0c, 
+-      0x00, 0xe6, 0xd1, 0x9c, 0x70, 0x40, 0x30, 0x5f, 
+-      0xe9, 0x8d, 0xb0, 0x3c, 0xb1, 0xb4, 0x70, 0x40, 
+-      0x30, 0x5f, 0xe9, 0x8d, 0xb1, 0xb4, 0x00, 0xe6, 
+-      0xd0, 0x10, 0xd0, 0x83, 0x70, 0x40, 0x60, 0x46, 
+-      0xb0, 0x3c, 0xb1, 0xbc, 0xb0, 0x81, 0xed, 0x90, 
+-      0x00, 0xee, 0xd0, 0x0c, 0x00, 0xe6, 0xd1, 0x9c, 
+-      0x70, 0x40, 0x30, 0x4c, 0xe9, 0xa3, 0xb0, 0x3c, 
+-      0xb1, 0xb4, 0x70, 0x40, 0x30, 0x4c, 0xe9, 0xa3, 
+-      0xb1, 0xb4, 0x00, 0xe6, 0xd0, 0x00, 0x61, 0x80, 
+-      0x00, 0x21, 0xd1, 0xb4, 0x70, 0x06, 0x10, 0x20, 
+-      0xe9, 0xae, 0xd0, 0x00, 0x60, 0x06, 0xf1, 0x18, 
+-      0x00, 0x21, 0xd1, 0x8c, 0x70, 0x46, 0x65, 0x86, 
+-      0xde, 0xc0, 0x00, 0xee, 0xd0, 0x20, 0x70, 0x00, 
+-      0x10, 0x22, 0xfd, 0xb9, 0xde, 0xc2, 0x00, 0x21, 
+-      0xd0, 0x04, 0x70, 0x00, 0x10, 0x21, 0xe9, 0xc0, 
+-      0x15, 0xa3, 0xe9, 0xdc, 0xd0, 0x02, 0x4c, 0x00, 
+-      0x10, 0x63, 0xe9, 0xc5, 0xcc, 0x3b, 0xd0, 0x04, 
+-      0x63, 0x00, 0xd0, 0x00, 0x70, 0x00, 0x30, 0x1f, 
+-      0xfa, 0xf2, 0xd0, 0x18, 0x70, 0x00, 0x10, 0x20, 
+-      0xed, 0xc7, 0xd0, 0x04, 0x70, 0x80, 0x10, 0xa0, 
+-      0xea, 0xf2, 0xf1, 0x16, 0x00, 0x21, 0xd0, 0x9a, 
+-      0xc0, 0x39, 0x30, 0x1f, 0x10, 0x18, 0x30, 0x02, 
+-      0xfd, 0xcf, 0xe2, 0xf2, 0x00, 0xe0, 0xd9, 0x04, 
+-      0x79, 0x24, 0xb9, 0x38, 0x19, 0x1c, 0xd0, 0x1e, 
+-      0x30, 0x24, 0xf5, 0xe5, 0x29, 0x00, 0xdc, 0x88, 
+-      0x4c, 0xac, 0xd0, 0x02, 0x40, 0x2c, 0x10, 0x02, 
+-      0x0c, 0x80, 0x10, 0x63, 0xea, 0x5a, 0x15, 0x63, 
+-      0xf9, 0xf0, 0xf1, 0x18, 0xdc, 0x1e, 0x1e, 0xe0, 
+-      0xe9, 0xf6, 0x15, 0x63, 0xf9, 0xf6, 0xbe, 0xfc, 
+-      0xd0, 0x2c, 0x6c, 0x00, 0xcc, 0x24, 0xd9, 0x40, 
+-      0x06, 0x50, 0xea, 0x0c, 0xc0, 0x24, 0xb0, 0x0f, 
+-      0xfe, 0x0c, 0xd9, 0x74, 0x79, 0x65, 0x19, 0x5f, 
+-      0x30, 0x25, 0xee, 0x05, 0x29, 0x40, 0x19, 0x5f, 
+-      0x19, 0x41, 0xc0, 0x25, 0x20, 0x30, 0x30, 0x24, 
+-      0xe6, 0x0c, 0x3c, 0x00, 0xd0, 0x38, 0x69, 0x40, 
+-      0x1c, 0x05, 0xbc, 0x38, 0x3c, 0x32, 0x5c, 0x3b, 
+-      0xbc, 0x3f, 0xd8, 0xec, 0x78, 0xe3, 0xc0, 0xa3, 
+-      0x10, 0xaf, 0xf6, 0x19, 0xd0, 0x8f, 0x02, 0xe4, 
+-      0xd8, 0x00, 0xd0, 0xc0, 0x20, 0xe0, 0xb0, 0x81, 
+-      0xee, 0x1c, 0xd0, 0x30, 0x60, 0xc0, 0x00, 0xab, 
+-      0xd0, 0x30, 0xc0, 0xc0, 0xd8, 0x40, 0xc1, 0x23, 
+-      0xd4, 0x5e, 0x34, 0x63, 0xdc, 0x40, 0x0c, 0x1f, 
+-      0xfa, 0x45, 0xc0, 0x65, 0xb0, 0x41, 0xe6, 0x31, 
+-      0x68, 0x40, 0xb0, 0x3c, 0xe2, 0x2c, 0xc0, 0xc0, 
+-      0x34, 0x65, 0xdc, 0x48, 0x4c, 0x70, 0x1c, 0x5f, 
+-      0x20, 0xf1, 0x15, 0x63, 0xfa, 0x46, 0xf2, 0x3e, 
+-      0xc1, 0x11, 0xc0, 0x83, 0xf2, 0x8f, 0xe2, 0x59, 
+-      0xb1, 0x01, 0xe6, 0x44, 0x68, 0x40, 0x28, 0x60, 
+-      0xb0, 0x3c, 0xe2, 0x3e, 0x0f, 0xc5, 0xd9, 0x40, 
+-      0xb1, 0x0f, 0x11, 0x01, 0x21, 0x25, 0xf2, 0x3e, 
+-      0xc1, 0x11, 0xb1, 0x01, 0xe6, 0x59, 0x20, 0x31, 
+-      0x68, 0x40, 0x30, 0x31, 0xb0, 0x3c, 0x28, 0x60, 
+-      0x70, 0x43, 0x30, 0x31, 0x60, 0x40, 0x20, 0x31, 
+-      0xb0, 0x3c, 0xb0, 0xf8, 0xe2, 0x4b, 0xe2, 0xe1, 
+-      0xd8, 0xec, 0x78, 0xe3, 0x00, 0xa8, 0xd0, 0x80, 
+-      0x00, 0xa8, 0xd1, 0x44, 0x00, 0xab, 0xd0, 0x30, 
+-      0xc0, 0xc0, 0x0c, 0x1f, 0xfa, 0x9d, 0xd9, 0x78, 
+-      0x79, 0x65, 0x39, 0x25, 0x19, 0x5f, 0xc9, 0xa5, 
+-      0x19, 0x83, 0x20, 0x26, 0x20, 0xe6, 0x20, 0xa6, 
+-      0x21, 0x66, 0xc1, 0x23, 0xc0, 0x64, 0x10, 0x5f, 
+-      0x10, 0x9d, 0x20, 0x81, 0x31, 0x01, 0x30, 0x44, 
+-      0xf6, 0x78, 0x21, 0x01, 0x30, 0x84, 0x10, 0x83, 
+-      0xc4, 0x64, 0x34, 0x63, 0xdc, 0x48, 0x4c, 0x70, 
+-      0x1c, 0x5f, 0x15, 0x63, 0xfa, 0xad, 0x20, 0xb1, 
+-      0xf2, 0x8f, 0xc1, 0x24, 0x11, 0x1f, 0xc0, 0x85, 
+-      0x30, 0xb1, 0xf2, 0x8f, 0xc1, 0x11, 0xc0, 0x83, 
+-      0x0c, 0x9d, 0xfa, 0x8d, 0xb0, 0xbc, 0xf2, 0x8f, 
+-      0xe2, 0xd6, 0xb1, 0x01, 0xe6, 0x44, 0x70, 0x42, 
+-      0xb0, 0xb8, 0x60, 0x40, 0xb0, 0x3c, 0xe2, 0x8f, 
+-      0xb1, 0x01, 0xe6, 0x44, 0x70, 0x42, 0xb0, 0xb8, 
+-      0x60, 0x40, 0xb0, 0x38, 0xe2, 0x96, 0x00, 0xab, 
+-      0xd0, 0x34, 0xc1, 0x23, 0xb1, 0x0f, 0xf2, 0x96, 
+-      0xd1, 0x1e, 0x31, 0x23, 0x00, 0xa8, 0xd0, 0x84, 
+-      0xf2, 0x96, 0xd1, 0x0f, 0x00, 0xa8, 0xd0, 0x84, 
+-      0xc0, 0x03, 0xf2, 0x96, 0xe2, 0xd6, 0xd8, 0x82, 
+-      0x48, 0x95, 0x18, 0x81, 0xb1, 0x01, 0xe6, 0xc3, 
+-      0x20, 0xb1, 0x70, 0x42, 0x30, 0xb1, 0x20, 0x22, 
+-      0x60, 0x40, 0x30, 0x22, 0xb0, 0xbc, 0xb0, 0x3c, 
+-      0x30, 0xb1, 0x70, 0x42, 0x20, 0xb1, 0x30, 0x22, 
+-      0x60, 0x40, 0x20, 0x22, 0xb0, 0xbc, 0xb0, 0x3c, 
+-      0xe2, 0xb0, 0xc1, 0x11, 0xc0, 0x85, 0x30, 0xb1, 
+-      0x20, 0xe2, 0xb1, 0x01, 0xe6, 0xd6, 0x70, 0x42, 
+-      0xb0, 0xb8, 0x20, 0x22, 0x60, 0x40, 0x30, 0x22, 
+-      0xb0, 0x3c, 0x70, 0x43, 0xb0, 0xf8, 0x30, 0x22, 
+-      0x60, 0x40, 0x20, 0x22, 0xb0, 0x3c, 0xe2, 0xc7, 
+-      0xd0, 0x08, 0x5c, 0x00, 0x3c, 0x32, 0xd0, 0x04, 
+-      0x40, 0x30, 0x3c, 0x00, 0x15, 0x63, 0xfa, 0xe1, 
+-      0x1e, 0xe0, 0xea, 0xe1, 0xbc, 0x3c, 0x00, 0xab, 
+-      0xd0, 0xb0, 0x00, 0xa8, 0xd0, 0x00, 0x00, 0x20, 
+-      0xd1, 0x1e, 0x70, 0x42, 0xb0, 0xbc, 0x60, 0x40, 
+-      0xb0, 0x3c, 0xb1, 0x01, 0xee, 0xe7, 0xd0, 0x30, 
+-      0x30, 0x30, 0xee, 0xed, 0xd0, 0x04, 0x63, 0x00, 
+-      0x08, 0x20, 0xd0, 0x40, 0x3f, 0x01, 0x02, 0xba, 
+-      0xd0, 0x3c, 0xe0, 0x46, 0x01, 0x46, 0xd0, 0x08, 
+-      0x94, 0x89, 0xd0, 0x8c, 0x44, 0x82, 0x14, 0x9e, 
+-      0x30, 0x12, 0xd0, 0x88, 0x10, 0x80, 0x00, 0xe8, 
+-      0xd1, 0x80, 0x70, 0xc6, 0x00, 0x06, 0xa0, 0xbd, 
+-      0xa0, 0xfc, 0x80, 0x3f, 0xb1, 0xbe, 0x60, 0xc6, 
+-      0x00, 0x06, 0x80, 0xa9, 0x80, 0x3f, 0x80, 0x2a, 
+-      0x80, 0x3f, 0x00, 0x21, 0xd0, 0x3c, 0x00, 0x0a, 
+-      0xb1, 0x82, 0xd0, 0x6b, 0x70, 0x46, 0x00, 0x06, 
+-      0x80, 0x07, 0x01, 0x20, 0xd0, 0x67, 0xa0, 0x69, 
+-      0x80, 0x2a, 0x82, 0x29, 0x80, 0x6a, 0x84, 0x29, 
+-      0xd0, 0x54, 0x10, 0x4f, 0xa0, 0x6a, 0x01, 0x20, 
+-      0xd0, 0x00, 0xa0, 0x29, 0x80, 0x2b, 0x0c, 0x20, 
+-      0xd0, 0x00, 0x10, 0x08, 0xa0, 0x27, 0x90, 0x09, 
+-      0xd0, 0x41, 0x40, 0x01, 0xd0, 0x44, 0x40, 0x70, 
+-      0x20, 0x01, 0xa0, 0x27, 0x80, 0x3f, 0x00, 0xc6, 
+-      0x15, 0x63, 0xe9, 0xae, 0x05, 0x5e, 0xe9, 0xbe, 
+-      0x00, 0xe0, 0xd0, 0x40, 0x70, 0x81, 0x10, 0x9c, 
+-      0xb0, 0x96, 0xf9, 0xb7, 0x00, 0x21, 0xd0, 0x40, 
+-      0xe1, 0xbb, 0xb0, 0x96, 0xf9, 0xbe, 0x00, 0x22, 
+-      0xd0, 0x40, 0x27, 0xc1, 0x27, 0x41, 0x27, 0x81, 
+-      0x90, 0x83, 0x00, 0x64, 0xd0, 0x10, 0x60, 0x80, 
+-      0x01, 0x46, 0x82, 0x34, 0x80, 0x3f, 0x00, 0x64, 
+-      0xd0, 0x14, 0x67, 0x40, 0x80, 0x34, 0x80, 0x3f, 
+-      0x00, 0xc6, 0x90, 0xae, 0x00, 0x64, 0xd0, 0x18, 
+-      0x60, 0x80, 0x90, 0xa6, 0x00, 0x64, 0xd0, 0x1c, 
+-      0x60, 0x80, 0x15, 0x63, 0xe9, 0xe3, 0x0c, 0x1f, 
+-      0xe9, 0xe3, 0x05, 0x50, 0xf9, 0xe3, 0x15, 0xa3, 
+-      0xf9, 0xe3, 0x90, 0x4d, 0x10, 0x60, 0xe5, 0xdb, 
+-      0x00, 0x06, 0x05, 0x0d, 0x01, 0x7a, 0xde, 0x1a, 
+-      0xe0, 0x46, 0x15, 0xa3, 0xf9, 0xfb, 0x00, 0x21, 
+-      0xd0, 0x04, 0x70, 0x00, 0x10, 0x21, 0xe9, 0xfb, 
+-      0xd0, 0x38, 0x70, 0x00, 0x15, 0x63, 0xe9, 0xef, 
+-      0x10, 0x1f, 0x15, 0x21, 0xe5, 0xe0, 0xd0, 0x5e, 
+-      0x30, 0x54, 0xe5, 0xe0, 0xc0, 0x40, 0xb0, 0x7f, 
+-      0x30, 0x54, 0xe9, 0xfb, 0x0c, 0x09, 0x05, 0x0d, 
+-      0xe1, 0xef, 0xc0, 0x5f, 0x10, 0x58, 0x10, 0x48, 
+-      0x00, 0xee, 0xd0, 0x8c, 0xd0, 0xc3, 0x70, 0x02, 
+-      0x30, 0x01, 0xea, 0x10, 0xb0, 0xbc, 0xb0, 0xc1, 
+-      0xee, 0x01, 0x00, 0x26, 0xd0, 0x20, 0x70, 0x40, 
+-      0xb0, 0x7f, 0x60, 0x40, 0x15, 0xa3, 0xea, 0x0f, 
+-      0xb0, 0x88, 0x77, 0xc2, 0x80, 0x07, 0x09, 0x49, 
+-      0xd4, 0x00, 0xd4, 0x40, 0xd4, 0x80, 0xd4, 0xc0, 
+-      0x00, 0x4d, 0xa0, 0x6c, 0xd3, 0x80, 0xd0, 0xa1, 
+-      0x00, 0x88, 0xd0, 0xa9, 0x00, 0x4d, 0x00, 0x50, 
+-      0xfa, 0x1a, 0x0c, 0x49, 0x00, 0x8d, 0xc0, 0x42, 
+-      0x10, 0x60, 0xea, 0x2a, 0xb0, 0x5e, 0xb0, 0x43, 
+-      0xfe, 0x34, 0xd0, 0x61, 0x23, 0x81, 0xe2, 0x1f, 
+-      0x0c, 0x09, 0x05, 0x0d, 0x15, 0x20, 0xfe, 0x31, 
+-      0xd0, 0x5f, 0x30, 0x54, 0xee, 0x10, 0x03, 0xb3, 
+-      0xd8, 0x29, 0xe0, 0x46, 0xc6, 0xd4, 0xb6, 0xc1, 
+-      0xe6, 0x31, 0xd0, 0x5e, 0x30, 0x5b, 0xfe, 0x31, 
+-      0xd7, 0x00, 0xb7, 0x01, 0xd3, 0x81, 0x00, 0x27, 
+-      0xd0, 0x10, 0xd0, 0x81, 0x60, 0x80, 0x15, 0x63, 
+-      0xfa, 0x54, 0x00, 0x22, 0xdc, 0xd8, 0x03, 0xf7, 
+-      0xd2, 0x10, 0xf0, 0x4a, 0x15, 0xa3, 0xfa, 0x51, 
+-      0x02, 0xf6, 0xde, 0x26, 0x0c, 0x10, 0xf8, 0x46, 
+-      0x02, 0xfb, 0xda, 0x22, 0xe0, 0x46, 0x02, 0xf1, 
+-      0xd8, 0x2b, 0xe0, 0x46, 0x00, 0x22, 0xdc, 0xd8, 
+-      0x03, 0xf9, 0xd2, 0x10, 0xf0, 0x4a, 0x03, 0x34, 
+-      0xdc, 0x20, 0x15, 0xa3, 0xe8, 0x46, 0x02, 0xff, 
+-      0xde, 0x27, 0xe0, 0x46, 0x03, 0x75, 0xd2, 0x73, 
+-      0x00, 0x24, 0xdc, 0xd8, 0xf0, 0x4a, 0xe1, 0xe0, 
+-      0xe1, 0xec, 0xe2, 0x12, 0xe2, 0x14, 0xe1, 0xc7, 
+-      0xe1, 0x30, 0x30, 0x5a, 0xe5, 0x8d, 0x06, 0x50, 
+-      0xe9, 0x83, 0xc0, 0x54, 0x30, 0x5b, 0xb0, 0x42, 
+-      0xf8, 0x11, 0x37, 0x1a, 0xb6, 0xff, 0xd0, 0x5e, 
+-      0x30, 0x5b, 0xfc, 0x11, 0xc0, 0x39, 0x30, 0x31, 
+-      0x10, 0x12, 0x10, 0x20, 0xe9, 0x88, 0x03, 0x10, 
+-      0xe9, 0x93, 0x0f, 0x19, 0xf9, 0x8f, 0xd1, 0x44, 
+-      0xe1, 0x79, 0x03, 0xde, 0xf9, 0xba, 0x03, 0xdf, 
+-      0xe9, 0x99, 0xd3, 0x40, 0xca, 0x50, 0xd1, 0x42, 
+-      0xe2, 0xea, 0xc0, 0x50, 0x10, 0x54, 0xc0, 0x90, 
+-      0x10, 0x8c, 0x10, 0x92, 0x10, 0xe0, 0xe5, 0xa8, 
+-      0xc0, 0x01, 0x10, 0x01, 0x20, 0x40, 0xc0, 0x02, 
+-      0x10, 0x01, 0x20, 0x80, 0x10, 0x60, 0xfd, 0xab, 
+-      0xb0, 0x7f, 0x10, 0xa0, 0xfd, 0xae, 0xb0, 0xbf, 
+-      0x10, 0x5f, 0x10, 0x9f, 0x00, 0xef, 0xd0, 0x3e, 
+-      0x20, 0x52, 0x20, 0x83, 0x20, 0x93, 0x10, 0x4c, 
+-      0x10, 0x82, 0x40, 0x80, 0x50, 0x42, 0x0f, 0xc5, 
+-      0xcb, 0xaa, 0xcb, 0xeb, 0xca, 0x50, 0xd0, 0xc0, 
+-      0xb0, 0xc1, 0xf1, 0x9b, 0xcb, 0x01, 0xd0, 0xc1, 
+-      0xf1, 0x9b, 0xcb, 0x41, 0xba, 0x7f, 0xbb, 0x3f, 
+-      0xe2, 0xea, 0xcc, 0x5b, 0x1c, 0x42, 0x2c, 0x5b, 
+-      0xc0, 0x31, 0x1c, 0x43, 0x2c, 0x40, 0x1c, 0x48, 
+-      0xcc, 0xb1, 0x1c, 0x9f, 0x06, 0xd0, 0xe9, 0xd5, 
+-      0x01, 0x69, 0xd0, 0x20, 0x3c, 0x80, 0xc0, 0x1c, 
+-      0x10, 0x08, 0x20, 0x1f, 0x2c, 0x40, 0x2c, 0x80, 
+-      0x01, 0x74, 0xd6, 0x00, 0x2c, 0x80, 0xde, 0x84, 
+-      0xde, 0xc4, 0xe3, 0x1e, 0xd3, 0xc2, 0xf2, 0xd3, 
+-      0x13, 0xa0, 0xed, 0xe5, 0xf2, 0x32, 0xb3, 0x81, 
+-      0xe9, 0xec, 0x80, 0x07, 0xd4, 0x00, 0xc4, 0x50, 
+-      0xd3, 0x08, 0xe2, 0x95, 0xd0, 0x71, 0x20, 0x56, 
+-      0x00, 0x48, 0xd1, 0x8c, 0x03, 0x0d, 0x41, 0x8c, 
+-      0xe9, 0xfa, 0x06, 0x5e, 0xfa, 0x03, 0x08, 0x89, 
+-      0x03, 0xcd, 0x13, 0xe3, 0xf9, 0xfa, 0xd3, 0xc4, 
+-      0x06, 0x5e, 0xfa, 0x03, 0xd0, 0x43, 0x40, 0x4c, 
+-      0xea, 0x03, 0x08, 0x49, 0x00, 0x8d, 0x10, 0x87, 
+-      0x53, 0x02, 0x01, 0x46, 0x90, 0x2c, 0x00, 0xc6, 
+-      0x03, 0x1c, 0xea, 0x0a, 0x09, 0x49, 0x00, 0x0d, 
+-      0xd0, 0x9f, 0x40, 0x02, 0xb0, 0x20, 0x03, 0x19, 
+-      0xea, 0x10, 0xb0, 0x20, 0xa0, 0x2c, 0xe2, 0x5b, 
+-      0x06, 0x5f, 0xfa, 0x80, 0xd4, 0x00, 0xc4, 0x50, 
+-      0xc4, 0x90, 0xc4, 0xd0, 0xe2, 0x8d, 0x50, 0x00, 
+-      0x50, 0x00, 0x50, 0x00, 0x03, 0x75, 0xd2, 0x73, 
+-      0x00, 0x24, 0xdc, 0xd8, 0xf0, 0x4a, 0xe1, 0xd3, 
+-      0xe1, 0xdc, 0xe2, 0x00, 0xe2, 0x02, 0xe1, 0xac, 
+-      0xe1, 0x30, 0x30, 0x5a, 0xe5, 0x91, 0x06, 0x50, 
+-      0xe9, 0x83, 0xc0, 0x54, 0x30, 0x5b, 0xb0, 0x42, 
+-      0xf8, 0x11, 0x37, 0x1a, 0xb6, 0xff, 0xd0, 0x5e, 
+-      0x30, 0x5b, 0xfc, 0x11, 0xbc, 0x10, 0xd0, 0x10, 
+-      0x0c, 0x1e, 0xf9, 0x8e, 0xbc, 0x10, 0xd0, 0x30, 
+-      0xc0, 0x40, 0x30, 0x70, 0xed, 0x8e, 0x03, 0x10, 
+-      0xe9, 0x97, 0x0f, 0x19, 0xf9, 0x93, 0xd1, 0x44, 
+-      0xe1, 0x79, 0x03, 0xdf, 0xe9, 0xa1, 0xd3, 0x40, 
+-      0xca, 0x50, 0xcb, 0x52, 0x03, 0x1d, 0xf9, 0xa8, 
+-      0xca, 0x12, 0xca, 0x52, 0xe1, 0xa5, 0x03, 0x1d, 
+-      0xf9, 0xa8, 0xca, 0x12, 0xca, 0x53, 0xca, 0xae, 
+-      0xca, 0xef, 0xb1, 0x7e, 0x03, 0x1e, 0xfa, 0xea, 
+-      0xb1, 0x7e, 0xe2, 0xea, 0x00, 0x24, 0xd0, 0x00, 
+-      0x2c, 0x40, 0x2c, 0x80, 0x17, 0x20, 0xf9, 0xd2, 
+-      0x00, 0xa8, 0xd0, 0x00, 0xcc, 0x5b, 0x1c, 0x5f, 
+-      0x1c, 0x43, 0x20, 0x31, 0x7c, 0x40, 0xb0, 0x3c, 
+-      0x7e, 0x80, 0xcc, 0xb1, 0xce, 0xfa, 0x1c, 0x9f, 
+-      0x1e, 0xdf, 0x01, 0x69, 0xd0, 0x3c, 0x0c, 0x99, 
+-      0xe9, 0xc4, 0x3c, 0x80, 0x0e, 0xd9, 0xe9, 0xc7, 
+-      0x3e, 0xc0, 0x3e, 0xf2, 0x3e, 0xb1, 0xd0, 0x01, 
+-      0x40, 0x1b, 0x10, 0x05, 0x20, 0x1f, 0x2c, 0x40, 
+-      0x2c, 0x80, 0xd0, 0x30, 0x70, 0x00, 0x2c, 0x80, 
+-      0xe3, 0x1e, 0xd3, 0xc2, 0xf2, 0xd3, 0x13, 0xa0, 
+-      0xed, 0xd8, 0xf2, 0x32, 0xb3, 0x81, 0xe9, 0xdc, 
+-      0x80, 0x07, 0xe2, 0x95, 0x0d, 0x09, 0xd1, 0x8c, 
+-      0x03, 0x0d, 0x41, 0x8c, 0xe9, 0xe8, 0x06, 0x5e, 
+-      0xf9, 0xf1, 0x08, 0x89, 0x03, 0xcd, 0x13, 0xe3, 
+-      0xf9, 0xe8, 0xd3, 0xc4, 0x06, 0x5e, 0xf9, 0xf1, 
+-      0xd0, 0x43, 0x40, 0x4c, 0xe9, 0xf1, 0x08, 0x49, 
+-      0x00, 0x8d, 0x10, 0x87, 0x53, 0x02, 0x01, 0x46, 
+-      0x90, 0x2c, 0x00, 0xc6, 0x03, 0x1c, 0xe9, 0xf8, 
+-      0x09, 0x49, 0x00, 0x0d, 0xd0, 0x9f, 0x40, 0x02, 
+-      0xb0, 0x20, 0x03, 0x19, 0xe9, 0xfe, 0xb0, 0x20, 
+-      0xa0, 0x2c, 0xe2, 0x5b, 0x06, 0x5f, 0xfa, 0x80, 
+-      0xd4, 0x00, 0xc4, 0x50, 0xc4, 0x90, 0xc4, 0xd0, 
+-      0xe2, 0x8d, 0x50, 0x00, 0x03, 0x75, 0xd2, 0x73, 
+-      0x00, 0x24, 0xdc, 0xd8, 0xf0, 0x4a, 0xe1, 0xc1, 
+-      0xe1, 0xca, 0xe1, 0xee, 0xe1, 0xf0, 0xe1, 0xa8, 
+-      0xe1, 0x30, 0x30, 0x5a, 0xe5, 0x8d, 0x06, 0x50, 
+-      0xe9, 0x83, 0xc0, 0x54, 0x30, 0x5b, 0xb0, 0x42, 
+-      0xf8, 0x11, 0x37, 0x1a, 0xb6, 0xff, 0xd0, 0x5e, 
+-      0x30, 0x5b, 0xfc, 0x11, 0xc0, 0x39, 0x30, 0x31, 
+-      0x10, 0x12, 0x10, 0x20, 0xe9, 0x88, 0x03, 0x10, 
+-      0xe9, 0x93, 0x0f, 0x19, 0xf9, 0x8f, 0xd1, 0x44, 
+-      0xe1, 0x79, 0x03, 0xdf, 0xe9, 0x9d, 0xd3, 0x40, 
+-      0xca, 0x50, 0xcb, 0x52, 0x03, 0x1d, 0xf9, 0xa4, 
+-      0xca, 0x12, 0xca, 0x52, 0xe1, 0xa1, 0x03, 0x1d, 
+-      0xf9, 0xa4, 0xca, 0x12, 0xca, 0x53, 0xca, 0xae, 
+-      0xca, 0xef, 0xb1, 0x7e, 0x03, 0x1e, 0xfa, 0xea, 
+-      0xb1, 0x7e, 0xe2, 0xea, 0xcc, 0x5b, 0x1c, 0x42, 
+-      0x2c, 0x5b, 0xc0, 0x31, 0x1c, 0x43, 0x2c, 0x40, 
+-      0x1c, 0x48, 0xcc, 0xb1, 0x1c, 0x9f, 0x06, 0xd0, 
+-      0xe9, 0xb6, 0x01, 0x69, 0xd0, 0x20, 0x3c, 0x80, 
+-      0xc0, 0x1c, 0x10, 0x08, 0x20, 0x1f, 0x2c, 0x40, 
+-      0x2c, 0x80, 0xd0, 0x30, 0x70, 0x00, 0x2c, 0x80, 
+-      0xde, 0x84, 0xde, 0xc4, 0xe3, 0x1e, 0xd3, 0xc2, 
+-      0xf2, 0xd3, 0x13, 0xa0, 0xed, 0xc6, 0xf2, 0x32, 
+-      0xb3, 0x81, 0xe9, 0xca, 0x80, 0x07, 0xe2, 0x95, 
+-      0x0d, 0x09, 0xd1, 0x8c, 0x03, 0x0d, 0x41, 0x8c, 
+-      0xe9, 0xd6, 0x06, 0x5e, 0xf9, 0xdf, 0x08, 0x89, 
+-      0x03, 0xcd, 0x13, 0xe3, 0xf9, 0xd6, 0xd3, 0xc4, 
+-      0x06, 0x5e, 0xf9, 0xdf, 0xd0, 0x43, 0x40, 0x4c, 
+-      0xe9, 0xdf, 0x08, 0x49, 0x00, 0x8d, 0x10, 0x87, 
+-      0x53, 0x02, 0x01, 0x46, 0x90, 0x2c, 0x00, 0xc6, 
+-      0x03, 0x1c, 0xe9, 0xe6, 0x09, 0x49, 0x00, 0x0d, 
+-      0xd0, 0x9f, 0x40, 0x02, 0xb0, 0x20, 0x03, 0x19, 
+-      0xe9, 0xec, 0xb0, 0x20, 0xa0, 0x2c, 0xe2, 0x5b, 
+-      0x06, 0x5f, 0xfa, 0x80, 0xd4, 0x00, 0xc4, 0x50, 
+-      0xc4, 0x90, 0xc4, 0xd0, 0xe2, 0x8d, 0x50, 0x00, 
+-      0x50, 0x00, 0x50, 0x00, 0x03, 0x75, 0xd2, 0x73, 
+-      0x00, 0x24, 0xdc, 0xd8, 0xf0, 0x4a, 0xe1, 0xdb, 
+-      0xe1, 0xe9, 0xe2, 0x00, 0xe2, 0x02, 0xe1, 0xc3, 
+-      0xe1, 0x65, 0x30, 0x5a, 0xe5, 0x8d, 0x06, 0x50, 
+-      0xe9, 0x83, 0xc0, 0x54, 0x30, 0x5b, 0xb0, 0x42, 
+-      0xf8, 0x11, 0x37, 0x1a, 0xb6, 0xff, 0xd0, 0x4f, 
+-      0x30, 0x5b, 0xfc, 0x11, 0xc0, 0x39, 0x30, 0x31, 
+-      0x10, 0x11, 0x10, 0x20, 0xe9, 0x88, 0x03, 0x10, 
+-      0xe9, 0x93, 0x0f, 0x19, 0xf9, 0x8f, 0xd1, 0x44, 
+-      0xe1, 0x79, 0x03, 0xd0, 0xf9, 0x98, 0xca, 0x50, 
+-      0x03, 0xde, 0xf9, 0x9a, 0xd1, 0x42, 0xe2, 0xea, 
+-      0xcb, 0xaa, 0xcb, 0xeb, 0xc0, 0x50, 0x10, 0x54, 
+-      0xc0, 0x90, 0x10, 0x8c, 0x10, 0x92, 0xd0, 0xc1, 
+-      0x05, 0x50, 0xe9, 0xa5, 0xb0, 0xc2, 0x10, 0x60, 
+-      0xfd, 0xa8, 0xb0, 0x7f, 0x10, 0xa0, 0xfd, 0xab, 
+-      0xb0, 0xbf, 0x10, 0x5f, 0x10, 0x9f, 0x00, 0xef, 
+-      0xd0, 0x3e, 0x20, 0x52, 0x20, 0x83, 0x20, 0x93, 
+-      0x10, 0x4c, 0x10, 0x82, 0x40, 0x80, 0x50, 0x42, 
+-      0xd0, 0x81, 0x14, 0x1f, 0x14, 0x01, 0x05, 0x50, 
+-      0xe9, 0xbd, 0x50, 0x42, 0xe1, 0xbe, 0x54, 0x02, 
+-      0xca, 0x10, 0xca, 0x50, 0xcb, 0x01, 0xcb, 0x41, 
+-      0xe2, 0xea, 0xcc, 0x5b, 0x1c, 0x42, 0x2c, 0x5b, 
+-      0xc0, 0x31, 0x1c, 0x43, 0x2c, 0x40, 0x1c, 0x49, 
+-      0xcc, 0xb1, 0x1c, 0x9f, 0xc0, 0x1c, 0x10, 0x08, 
+-      0x20, 0x1f, 0x05, 0x50, 0xf9, 0xd2, 0xb0, 0x3c, 
+-      0x2c, 0x40, 0x2c, 0x80, 0x01, 0x74, 0xd6, 0x00, 
+-      0x2c, 0x80, 0x02, 0xe4, 0xde, 0x80, 0xde, 0xc1, 
+-      0xe3, 0x1e, 0xd3, 0xc0, 0xf2, 0xd3, 0x13, 0xa0, 
+-      0xed, 0xe0, 0xf2, 0x32, 0xb3, 0x81, 0xe9, 0xe9, 
+-      0x80, 0x07, 0xd4, 0x02, 0x44, 0x15, 0x14, 0x1f, 
+-      0xc4, 0x50, 0xd3, 0x08, 0xe2, 0x95, 0xd0, 0x71, 
+-      0x20, 0x56, 0x00, 0x48, 0xd1, 0x8c, 0x03, 0x0d, 
+-      0x41, 0x8c, 0xe9, 0xf7, 0x08, 0x89, 0x03, 0xcd, 
+-      0x13, 0xe3, 0xf9, 0xf6, 0xd3, 0xc4, 0xe1, 0xf7, 
+-      0xb3, 0xc1, 0x01, 0x46, 0x90, 0x2c, 0x00, 0xc6, 
+-      0x03, 0x1c, 0xe9, 0xfe, 0x09, 0x49, 0x00, 0x0d, 
+-      0xa0, 0x2c, 0xe2, 0x5b, 0x06, 0x5f, 0xfa, 0x7f, 
+-      0xd4, 0x02, 0x44, 0x15, 0x14, 0x1f, 0xc4, 0x50, 
+-      0xc4, 0x90, 0xc4, 0xd0, 0xe2, 0x8d, 0x50, 0x00, 
+-      0x50, 0x00, 0x50, 0x00, 0x03, 0x75, 0xd2, 0x73, 
+-      0x00, 0x24, 0xdc, 0xd8, 0xf0, 0x4a, 0xe1, 0xc9, 
+-      0xe1, 0xd2, 0xe1, 0xe7, 0xe1, 0xe9, 0xe1, 0xab, 
+-      0xe1, 0x30, 0x30, 0x5a, 0xe5, 0x91, 0x06, 0x50, 
+-      0xe9, 0x83, 0xc0, 0x54, 0x30, 0x5b, 0xb0, 0x42, 
+-      0xf8, 0x11, 0x37, 0x1a, 0xb6, 0xff, 0xd0, 0x4f, 
+-      0x30, 0x5b, 0xfc, 0x11, 0xbc, 0x10, 0xd0, 0x10, 
+-      0x0c, 0x1e, 0xf9, 0x8e, 0xbc, 0x10, 0xd0, 0x20, 
+-      0xc0, 0x40, 0x30, 0x70, 0xed, 0x8e, 0x03, 0x10, 
+-      0xe9, 0x97, 0x0f, 0x19, 0xf9, 0x93, 0xd1, 0x44, 
+-      0xe1, 0x79, 0x03, 0xd0, 0xf9, 0xa0, 0xca, 0x50, 
+-      0xcb, 0x52, 0x03, 0x1d, 0xf9, 0xa7, 0xca, 0x12, 
+-      0xca, 0x52, 0xe1, 0xa4, 0x03, 0x1d, 0xf9, 0xa7, 
+-      0xca, 0x12, 0xca, 0x53, 0xca, 0xae, 0xca, 0xef, 
+-      0xb1, 0x7e, 0x03, 0x1e, 0xfa, 0xea, 0xb1, 0x7e, 
+-      0xe2, 0xea, 0x00, 0x24, 0xd0, 0x00, 0x2c, 0x40, 
+-      0x2c, 0x80, 0x17, 0x20, 0xf9, 0xc8, 0x00, 0x2a, 
+-      0xd0, 0x00, 0x20, 0x1b, 0x20, 0x1b, 0x05, 0x50, 
+-      0xf9, 0xb8, 0xb0, 0x3f, 0x10, 0x02, 0x7c, 0x40, 
+-      0xcc, 0xb1, 0x1c, 0x9f, 0x01, 0x69, 0xd0, 0x3c, 
+-      0x0c, 0x99, 0xe9, 0xc1, 0x3c, 0x80, 0xde, 0xa0, 
+-      0x2c, 0x5f, 0x2c, 0x9f, 0xd0, 0x30, 0x70, 0x00, 
+-      0x2c, 0x80, 0xde, 0xc1, 0xe3, 0x1e, 0xd3, 0xc0, 
+-      0xf2, 0xd3, 0x13, 0xa0, 0xed, 0xce, 0xf2, 0x32, 
+-      0xb3, 0x81, 0xe9, 0xd2, 0x80, 0x07, 0xe2, 0x95, 
+-      0x0d, 0x09, 0xd1, 0x8c, 0x03, 0x0d, 0x41, 0x8c, 
+-      0xe9, 0xde, 0x08, 0x89, 0x03, 0xcd, 0x13, 0xe3, 
+-      0xf9, 0xdd, 0xd3, 0xc4, 0xe1, 0xde, 0xb3, 0xc1, 
+-      0x01, 0x46, 0x90, 0x2c, 0x00, 0xc6, 0x03, 0x1c, 
+-      0xe9, 0xe5, 0x09, 0x49, 0x00, 0x0d, 0xa0, 0x2c, 
+-      0xe2, 0x5b, 0x06, 0x5f, 0xfa, 0x7f, 0xd4, 0x00, 
+-      0xc4, 0x50, 0xc4, 0x90, 0xc4, 0xd0, 0xe2, 0x8d, 
+-      0x50, 0x00, 0x50, 0x00, 0x03, 0x75, 0xd2, 0x73, 
+-      0x00, 0x24, 0xdc, 0xd8, 0xf0, 0x4a, 0xe1, 0xa3, 
+-      0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xe1, 0x8a, 
+-      0xe1, 0x30, 0x30, 0x5a, 0xe5, 0x87, 0x37, 0x1a, 
+-      0xb6, 0xff, 0xd0, 0x5e, 0x30, 0x5b, 0xfd, 0xb4, 
+-      0xc0, 0x39, 0x30, 0x31, 0x10, 0x12, 0x10, 0x20, 
+-      0xe9, 0x82, 0xd1, 0x42, 0xd3, 0x40, 0xe2, 0xea, 
+-      0xcc, 0x5b, 0x1c, 0x42, 0x2c, 0x5b, 0xc0, 0x31, 
+-      0x1c, 0x43, 0x2c, 0x40, 0x1c, 0x48, 0xcc, 0xb1, 
+-      0x1c, 0x9f, 0x06, 0xd0, 0xe9, 0x98, 0x01, 0x69, 
+-      0xd0, 0x20, 0x3c, 0x80, 0xc0, 0x1c, 0x10, 0x08, 
+-      0x20, 0x1f, 0x2c, 0x40, 0x2c, 0x80, 0x01, 0x74, 
+-      0xd6, 0x00, 0x2c, 0x80, 0xde, 0x84, 0xde, 0xc4, 
+-      0xe3, 0x1e, 0xf2, 0xd3, 0xc0, 0x5c, 0xb0, 0x7f, 
+-      0x30, 0x5a, 0xe5, 0xc8, 0x00, 0x26, 0xd0, 0x00, 
+-      0x70, 0x00, 0x10, 0x20, 0xe9, 0xbf, 0x00, 0xe0, 
+-      0xd0, 0x44, 0x70, 0x41, 0x10, 0x5c, 0x30, 0x5b, 
+-      0xb0, 0x41, 0xed, 0xc8, 0x0f, 0x17, 0xf9, 0xb4, 
+-      0x0f, 0x49, 0xf2, 0xd3, 0x0f, 0x19, 0xf9, 0xb8, 
+-      0xdf, 0x00, 0x00, 0x06, 0x03, 0xb3, 0xd8, 0x29, 
+-      0xe0, 0x46, 0xc0, 0x5b, 0x30, 0x54, 0xb0, 0x7e, 
+-      0xe5, 0xc8, 0x0f, 0x17, 0xf9, 0xc3, 0x02, 0xf1, 
+-      0xd8, 0x2b, 0xe0, 0x46, 0xd3, 0x08, 0xd3, 0xc0, 
+-      0xe2, 0x95, 0x50, 0x00, 0x03, 0x75, 0xd2, 0x73, 
+-      0x00, 0x24, 0xdc, 0xd8, 0xf0, 0x4a, 0xe1, 0xb5, 
+-      0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xe1, 0x8e, 
+-      0xe1, 0x30, 0x30, 0x5a, 0xe5, 0x8b, 0x37, 0x1a, 
+-      0xb6, 0xff, 0xd0, 0x5e, 0x30, 0x5b, 0xfd, 0xc6, 
+-      0xbc, 0x10, 0xd0, 0x10, 0x0c, 0x1e, 0xf9, 0x88, 
+-      0xbc, 0x10, 0xd0, 0x30, 0xc0, 0x40, 0x30, 0x70, 
+-      0xed, 0x88, 0xd1, 0x42, 0xd3, 0x40, 0xe2, 0xea, 
+-      0x00, 0x24, 0xd0, 0x00, 0x2c, 0x40, 0x2c, 0x80, 
+-      0x17, 0x20, 0xf9, 0xb4, 0x00, 0xa8, 0xd0, 0x00, 
+-      0xcc, 0x5b, 0x1c, 0x5f, 0x1c, 0x43, 0x20, 0x31, 
+-      0x7c, 0x40, 0xb0, 0x3c, 0x7e, 0x80, 0xcc, 0xb1, 
+-      0xce, 0xfa, 0x1c, 0x9f, 0x1e, 0xdf, 0x01, 0x69, 
+-      0xd0, 0x3c, 0x0c, 0x99, 0xe9, 0xa6, 0x3c, 0x80, 
+-      0x0e, 0xd9, 0xe9, 0xa9, 0x3e, 0xc0, 0x3e, 0xf2, 
+-      0x3e, 0xb1, 0xd0, 0x01, 0x40, 0x1b, 0x10, 0x05, 
+-      0x20, 0x1f, 0x2c, 0x40, 0x2c, 0x80, 0xd0, 0x30, 
+-      0x70, 0x00, 0x2c, 0x80, 0xe3, 0x1e, 0xf2, 0xd3, 
+-      0xc0, 0x5c, 0xb0, 0x7f, 0x30, 0x5a, 0xe5, 0xda, 
+-      0x00, 0x26, 0xd0, 0x00, 0x70, 0x00, 0x10, 0x20, 
+-      0xe9, 0xd1, 0x00, 0xe0, 0xd0, 0x44, 0x70, 0x41, 
+-      0x10, 0x5c, 0x30, 0x5b, 0xb0, 0x41, 0xed, 0xda, 
+-      0x0f, 0x17, 0xf9, 0xc6, 0x0f, 0x49, 0xf2, 0xd3, 
+-      0x0f, 0x19, 0xf9, 0xca, 0xdf, 0x00, 0x00, 0x06, 
+-      0x03, 0xb3, 0xd8, 0x29, 0xe0, 0x46, 0xc0, 0x5b, 
+-      0x30, 0x54, 0xb0, 0x7e, 0xe5, 0xda, 0x0f, 0x17, 
+-      0xf9, 0xd5, 0x02, 0xf6, 0xde, 0x26, 0xe0, 0x46, 
+-      0xd3, 0x08, 0xd3, 0xc0, 0xe2, 0x95, 0x50, 0x00, 
+-      0x50, 0x00, 0x50, 0x00, 0x03, 0x75, 0xd2, 0x73, 
+-      0x00, 0x24, 0xdc, 0xd8, 0xf0, 0x4a, 0xe1, 0xa2, 
+-      0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xe1, 0x8a, 
+-      0xe1, 0x65, 0x30, 0x5a, 0xe5, 0x87, 0x37, 0x1a, 
+-      0xb6, 0xff, 0xd0, 0x4f, 0x30, 0x5b, 0xfd, 0xb3, 
+-      0xc0, 0x39, 0x30, 0x31, 0x10, 0x11, 0x10, 0x20, 
+-      0xe9, 0x82, 0xd1, 0x42, 0xd3, 0x41, 0xe2, 0xea, 
+-      0xcc, 0x5b, 0x1c, 0x42, 0x2c, 0x5b, 0xc0, 0x31, 
+-      0x1c, 0x43, 0x2c, 0x40, 0x1c, 0x49, 0xcc, 0xb1, 
+-      0x1c, 0x9f, 0xc0, 0x1c, 0x10, 0x08, 0x20, 0x1f, 
+-      0x05, 0x50, 0xf9, 0x99, 0xb0, 0x3c, 0x2c, 0x40, 
+-      0x2c, 0x80, 0x01, 0x74, 0xd6, 0x00, 0x2c, 0x80, 
+-      0x02, 0xe4, 0xde, 0x80, 0xde, 0xc1, 0xe3, 0x1e, 
+-      0xf2, 0xd3, 0xc0, 0x5c, 0xb0, 0x7f, 0x30, 0x5a, 
+-      0xe5, 0xc7, 0x00, 0x26, 0xd0, 0x00, 0x70, 0x00, 
+-      0x10, 0x20, 0xe9, 0xbe, 0x00, 0xe0, 0xd0, 0x44, 
+-      0x70, 0x41, 0x10, 0x5b, 0x30, 0x5b, 0xb0, 0x41, 
+-      0xed, 0xc7, 0x0f, 0x17, 0xf9, 0xb3, 0x0f, 0x49, 
+-      0xf2, 0xd3, 0x0f, 0x19, 0xf9, 0xb7, 0xdf, 0x00, 
+-      0x00, 0x06, 0x03, 0xb3, 0xd8, 0x29, 0xe0, 0x46, 
+-      0xc0, 0x5b, 0x30, 0x54, 0xb0, 0x7e, 0xe5, 0xc7, 
+-      0x0f, 0x17, 0xf9, 0xc2, 0x02, 0xff, 0xde, 0x27, 
+-      0xe0, 0x46, 0xd3, 0x08, 0xd3, 0xc0, 0xe2, 0x95, 
+-      0x50, 0x00, 0x50, 0x00, 0x03, 0x75, 0xd2, 0x73, 
+-      0x00, 0x24, 0xdc, 0xd8, 0xf0, 0x4a, 0xe1, 0xac, 
+-      0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xe1, 0x8e, 
+-      0xe1, 0x30, 0x30, 0x5a, 0xe5, 0x8b, 0x37, 0x1a, 
+-      0xb6, 0xff, 0xd0, 0x4f, 0x30, 0x5b, 0xfd, 0xbd, 
+-      0xbc, 0x10, 0xd0, 0x10, 0x0c, 0x1e, 0xf9, 0x88, 
+-      0xbc, 0x10, 0xd0, 0x20, 0xc0, 0x40, 0x30, 0x70, 
+-      0xed, 0x88, 0xd1, 0x42, 0xd3, 0x41, 0xe2, 0xea, 
+-      0x00, 0x24, 0xd0, 0x00, 0x2c, 0x40, 0x2c, 0x80, 
+-      0x17, 0x20, 0xf9, 0xab, 0x00, 0x2a, 0xd0, 0x00, 
+-      0x20, 0x1b, 0x20, 0x1b, 0x05, 0x50, 0xf9, 0x9b, 
+-      0xb0, 0x3f, 0x10, 0x02, 0x7c, 0x40, 0xcc, 0xb1, 
+-      0x1c, 0x9f, 0x01, 0x69, 0xd0, 0x3c, 0x0c, 0x99, 
+-      0xe9, 0xa4, 0x3c, 0x80, 0xde, 0xa0, 0x2c, 0x5f, 
+-      0x2c, 0x9f, 0xd0, 0x30, 0x70, 0x00, 0x2c, 0x80, 
+-      0xde, 0xc1, 0xe3, 0x1e, 0xf2, 0xd3, 0xc0, 0x5c, 
+-      0xb0, 0x7f, 0x30, 0x5a, 0xe5, 0xd1, 0x00, 0x26, 
+-      0xd0, 0x00, 0x70, 0x00, 0x10, 0x20, 0xe9, 0xc8, 
+-      0x00, 0xe0, 0xd0, 0x44, 0x70, 0x41, 0x10, 0x5b, 
+-      0x30, 0x5b, 0xb0, 0x41, 0xed, 0xd1, 0x0f, 0x17, 
+-      0xf9, 0xbd, 0x0f, 0x49, 0xf2, 0xd3, 0x0f, 0x19, 
+-      0xf9, 0xc1, 0xdf, 0x00, 0x00, 0x06, 0x03, 0xb3, 
+-      0xd8, 0x29, 0xe0, 0x46, 0xc0, 0x5b, 0x30, 0x54, 
+-      0xb0, 0x7e, 0xe5, 0xd1, 0x0f, 0x17, 0xf9, 0xcc, 
+-      0x03, 0x34, 0xdc, 0x20, 0xe0, 0x46, 0xd3, 0x08, 
+-      0xd3, 0xc0, 0xe2, 0x95, 0xd0, 0x61, 0x23, 0x81, 
+-      0x0c, 0x49, 0xd0, 0x61, 0x00, 0x8d, 0x10, 0xa0, 
+-      0xea, 0x3b, 0x30, 0x42, 0xe6, 0x30, 0x23, 0x82, 
+-      0x0f, 0xc5, 0x0c, 0x09, 0x05, 0x0d, 0x15, 0x20, 
+-      0xfe, 0x45, 0xd0, 0x5f, 0x15, 0x63, 0xea, 0x43, 
+-      0xd0, 0x50, 0x30, 0x54, 0xee, 0x4a, 0x0f, 0x17, 
+-      0xfa, 0x45, 0x03, 0xb3, 0xd8, 0x29, 0xe0, 0x46, 
+-      0x80, 0x07, 0x09, 0x49, 0xd4, 0x00, 0xd4, 0x40, 
+-      0xd4, 0x80, 0xd4, 0xc0, 0x00, 0x4d, 0xa0, 0x6c, 
+-      0xd0, 0xa1, 0x00, 0x88, 0xd0, 0xa9, 0x00, 0x4d, 
+-      0x00, 0x50, 0xfa, 0x53, 0xf2, 0x32, 0xd3, 0x80, 
+-      0xe1, 0x76, 0xd1, 0xc2, 0x41, 0xcf, 0x11, 0xdf, 
+-      0xd0, 0x41, 0x01, 0xc1, 0x00, 0xef, 0xd0, 0xbe, 
+-      0x03, 0x10, 0xf9, 0x77, 0x80, 0x07, 0x21, 0x96, 
+-      0x11, 0xa2, 0xe9, 0x78, 0x03, 0x1d, 0xea, 0x73, 
+-      0xc0, 0xd7, 0xc2, 0x90, 0xf2, 0xa4, 0xc4, 0x0a, 
+-      0x03, 0xd0, 0xea, 0x72, 0xc2, 0x91, 0xf2, 0xa4, 
+-      0xc4, 0x4a, 0x03, 0x1e, 0xea, 0x8d, 0xc0, 0xd8, 
+-      0xc2, 0x92, 0xf2, 0xa4, 0xc4, 0x8a, 0x03, 0xd0, 
+-      0xea, 0x7d, 0xc2, 0x93, 0xf2, 0xa4, 0xc4, 0xca, 
+-      0xe2, 0x8d, 0xd3, 0xc0, 0xc0, 0xd7, 0xc2, 0x90, 
+-      0xf2, 0xa4, 0xc4, 0x0a, 0x03, 0xd0, 0xea, 0x88, 
+-      0xc2, 0x91, 0xf2, 0xa4, 0xc4, 0x4a, 0x08, 0x49, 
+-      0x00, 0x4d, 0x10, 0x61, 0xf8, 0x11, 0x03, 0x1f, 
+-      0xea, 0x93, 0x0d, 0xc9, 0x00, 0x4d, 0xd0, 0x1a, 
+-      0xe2, 0x98, 0x03, 0x10, 0xfa, 0x97, 0xd0, 0x1d, 
+-      0xe2, 0x98, 0xd0, 0x18, 0x0f, 0x16, 0xfa, 0x98, 
+-      0xd0, 0x4c, 0x40, 0x4c, 0x10, 0x6c, 0xea, 0xa2, 
+-      0x03, 0xde, 0xfa, 0xa2, 0x0f, 0x12, 0xfa, 0xa0, 
+-      0x00, 0x08, 0xe2, 0xd9, 0xd2, 0x00, 0x13, 0xe1, 
+-      0xee, 0xa9, 0x08, 0x49, 0x02, 0x0d, 0x00, 0xc8, 
+-      0xc2, 0xca, 0x12, 0x94, 0xd0, 0x1f, 0x30, 0x07, 
+-      0x12, 0xc0, 0xc2, 0x43, 0x12, 0x5a, 0x00, 0x0d, 
+-      0x03, 0xde, 0xea, 0xb6, 0x0e, 0xc9, 0x04, 0x8d, 
+-      0x02, 0x48, 0x22, 0x80, 0x12, 0x88, 0xd0, 0x0b, 
+-      0x30, 0x03, 0x12, 0x80, 0xd0, 0x19, 0x20, 0x03, 
+-      0x12, 0x80, 0x00, 0x0d, 0x22, 0xc0, 0x12, 0xc8, 
+-      0xd0, 0x0b, 0x30, 0x09, 0x12, 0xc0, 0x12, 0xd8, 
+-      0xd0, 0x16, 0x20, 0x09, 0x20, 0x07, 0x12, 0xc0, 
+-      0x42, 0xc2, 0x22, 0x8b, 0x22, 0x88, 0x03, 0xde, 
+-      0xea, 0xd2, 0x0e, 0xc9, 0xc4, 0x4a, 0x04, 0xcd, 
+-      0x0f, 0xc5, 0x01, 0x46, 0x90, 0x4d, 0x00, 0xc6, 
+-      0x10, 0x60, 0xe6, 0xd3, 0x0f, 0xc5, 0x01, 0x74, 
+-      0xd6, 0x00, 0xca, 0x9d, 0xcb, 0x9e, 0xca, 0xea, 
+-      0xcb, 0xee, 0x2a, 0xc0, 0x2b, 0xc0, 0xca, 0x10, 
+-      0xca, 0x51, 0xcb, 0x12, 0xcb, 0x53, 0xd1, 0x40, 
+-      0xd3, 0x41, 0xb7, 0x3f, 0xc0, 0x5c, 0xe1, 0x7b, 
+-      0xd0, 0xc0, 0xc1, 0x28, 0xc2, 0x2a, 0xc2, 0xab, 
+-      0xf1, 0x7a, 0x0f, 0x17, 0xfa, 0xef, 0xcc, 0xe8, 
+-      0xcd, 0x29, 0xcd, 0x6c, 0xcd, 0xad, 0xc8, 0x08, 
+-      0xc8, 0x49, 0xca, 0x0a, 0xca, 0x4b, 0xf3, 0x31, 
+-      0xd0, 0xc1, 0xc1, 0x34, 0xc2, 0x2a, 0xc2, 0xab, 
+-      0xf1, 0x7a, 0x00, 0x28, 0xd9, 0xc0, 0xc8, 0x88, 
+-      0xc8, 0xc9, 0xa9, 0xf8, 0xca, 0x8a, 0xca, 0xcb, 
+-      0x11, 0x62, 0xe9, 0x79, 0xd0, 0xc0, 0xc1, 0x35, 
+-      0xc2, 0x2e, 0xc2, 0xaf, 0xf1, 0x7a, 0xc9, 0x08, 
+-      0xc9, 0x49, 0xa9, 0xf8, 0xcb, 0x0a, 0xcb, 0x4b, 
+-      0xd0, 0xc1, 0xc1, 0x36, 0xc2, 0x2e, 0xc2, 0xaf, 
+-      0xf1, 0x7a, 0xc0, 0x27, 0xc9, 0x88, 0xc9, 0xc9, 
+-      0xa0, 0x38, 0xcb, 0x8a, 0xcb, 0xcb, 0xe1, 0x79, 
+-      0x5f, 0x0d, 0x07, 0x7d, 0xde, 0x07, 0x11, 0x5e, 
+-      0x30, 0x05, 0xcd, 0xc0, 0x00, 0x28, 0xd0, 0x00, 
+-      0xa0, 0x38, 0x11, 0x61, 0xf9, 0x75, 0x00, 0xe2, 
+-      0xd0, 0x00, 0x0f, 0x1d, 0xeb, 0x29, 0x00, 0x2d, 
+-      0xdf, 0x4b, 0xf3, 0x3f, 0xe1, 0x75, 0x04, 0xeb, 
+-      0xd0, 0x00, 0x11, 0x62, 0xeb, 0x36, 0xb0, 0x20, 
+-      0x0f, 0x19, 0xfb, 0x36, 0xac, 0xe0, 0x01, 0xa4, 
+-      0xde, 0x00, 0x5e, 0x0d, 0x00, 0x2d, 0xdf, 0x7a, 
+-      0xdd, 0xc0, 0xd8, 0x80, 0xd9, 0x00, 0xd9, 0x80, 
+-      0x5f, 0x00, 0x01, 0x46, 0x00, 0x28, 0xd0, 0x01, 
+-      0x00, 0x06, 0xa0, 0x37, 0x80, 0x3f, 0x00, 0xc6, 
+-      0x0f, 0xc5, 0xad, 0xda, 0xc6, 0xb1, 0xd0, 0x01, 
+-      0x01, 0xa3, 0xde, 0x1d, 0x40, 0x30, 0x3e, 0x00, 
+-      0x80, 0x3f, 0x0e, 0x0a, 0x66, 0xda, 0xc8, 0x28, 
+-      0xc8, 0x69, 0xc8, 0xaa, 0xc8, 0xeb, 0x0c, 0x1e, 
+-      0xfb, 0x68, 0x26, 0xba, 0x07, 0x7d, 0xdc, 0x00, 
+-      0x1d, 0xcf, 0x1d, 0xd1, 0x5d, 0xc0, 0x00, 0x2d, 
+-      0xdf, 0x64, 0x0f, 0x87, 0xad, 0xda, 0x80, 0x3f, 
+-      0x0e, 0x0a, 0x66, 0xda, 0xc9, 0x2c, 0xc9, 0x6d, 
+-      0xc9, 0xae, 0xc9, 0xef, 0x0f, 0x2f, 0xd0, 0x37, 
+-      0x4f, 0x00, 0x0f, 0x1a, 0xeb, 0xbe, 0x01, 0xa4, 
+-      0xde, 0x20, 0xd0, 0x01, 0x40, 0x3c, 0x2e, 0x00, 
+-      0x00, 0x2d, 0xdf, 0x7a, 0xac, 0xe0, 0x0f, 0x87, 
+-      0x0e, 0x0a, 0x76, 0xe0, 0xbf, 0x79, 0xbe, 0x3c, 
+-      0x0f, 0x1b, 0xeb, 0x9e, 0x0f, 0x87, 0x0e, 0x0a, 
+-      0x76, 0xe1, 0xbf, 0x79, 0xbe, 0x34, 0x18, 0xa0, 
+-      0xeb, 0xb9, 0x0f, 0x87, 0xad, 0x20, 0x80, 0x3f, 
+-      0x0e, 0x0a, 0x76, 0xe2, 0xbf, 0x79, 0xbe, 0x3c, 
+-      0x0f, 0x87, 0x0e, 0x0a, 0x76, 0xe3, 0x0f, 0x1b, 
+-      0xeb, 0xb3, 0xbf, 0x77, 0xbe, 0x0c, 0x19, 0x20, 
+-      0xeb, 0xb9, 0x0f, 0x87, 0xad, 0x60, 0x80, 0x3f, 
+-      0x0e, 0x0a, 0x76, 0xe4, 0xbe, 0x3c, 0xbf, 0x75, 
+-      0x0f, 0x15, 0xf8, 0x1c, 0x1f, 0x0a, 0x1f, 0x16, 
+-      0x0f, 0x87, 0x0e, 0x0a, 0x76, 0xe5, 0xbf, 0x79, 
+-      0xbe, 0x34, 0x19, 0xa0, 0xeb, 0xb9, 0x0f, 0x87, 
+-      0xad, 0xa0, 0x80, 0x3f, 0x0e, 0x0a, 0x76, 0xe6, 
+-      0xbe, 0x3c, 0xbf, 0x79, 0x0f, 0x87, 0x0e, 0x0a, 
+-      0x76, 0xe7, 0x0f, 0x15, 0xeb, 0xbe, 0x00, 0x2f, 
+-      0xdf, 0x72, 0x1d, 0xe0, 0xf8, 0x1c, 0x00, 0x28, 
+-      0xd0, 0x01, 0xa0, 0x38, 0x80, 0x3f, 0x0f, 0x87, 
+-      0xd0, 0x01, 0x4d, 0xc0, 0x1f, 0x0f, 0x1f, 0x11, 
+-      0x00, 0x2f, 0xdf, 0x76, 0xc6, 0xb2, 0x03, 0x7d, 
+-      0xde, 0x0e, 0x01, 0xa3, 0xde, 0x2d, 0x5d, 0xc0, 
+-      0x0f, 0x87, 0x1e, 0xe1, 0xeb, 0xdb, 0xad, 0xda, 
+-      0x80, 0x3f, 0x0e, 0x0a, 0x66, 0xda, 0x0c, 0x1e, 
+-      0xfb, 0xe4, 0x26, 0xbb, 0x03, 0xff, 0xdd, 0xff, 
+-      0x4d, 0xc0, 0x00, 0xa3, 0xde, 0x2d, 0xbf, 0x56, 
+-      0x0f, 0x87, 0x07, 0x7d, 0xde, 0x0e, 0x5d, 0xc0, 
+-      0x00, 0xa3, 0xde, 0x1d, 0xad, 0xda, 0x80, 0x3f, 
+-      0x0e, 0x0a, 0x66, 0xda, 0xdf, 0x5c, 0xd0, 0x0e, 
+-      0x4f, 0x00, 0x0f, 0x87, 0xd0, 0x06, 0x40, 0x3c, 
+-      0xeb, 0xf0, 0xbf, 0x3e, 0xb0, 0x04, 0xe7, 0xf2, 
+-      0xeb, 0xf6, 0xbf, 0x0c, 0xbf, 0x3a, 0x0f, 0x87, 
+-      0x0f, 0x1d, 0xfb, 0x4b, 0xbf, 0x38, 0x0f, 0x87, 
+-      0x0f, 0x1c, 0xfb, 0xcb, 0xbf, 0x30, 0x0f, 0x87, 
+-      0x50, 0x00, 0x50, 0x00, 0x0f, 0x17, 0xf9, 0x70, 
+-      0x90, 0x4d, 0x10, 0x60, 0xe5, 0x72, 0x0f, 0x49, 
+-      0x90, 0x4d, 0x10, 0x60, 0xe5, 0x76, 0x0f, 0x19, 
+-      0xf9, 0x79, 0x01, 0x46, 0xd0, 0x11, 0xa0, 0x38, 
+-      0x80, 0x3f, 0x00, 0xc6, 0xdf, 0x00, 0x00, 0x06, 
+-      0x08, 0x20, 0xd0, 0x00, 0x10, 0x08, 0xa0, 0x0a, 
+-      0xa0, 0x1b, 0x0c, 0x20, 0xd0, 0x00, 0x10, 0x08, 
+-      0xa0, 0x27, 0x90, 0x4d, 0x0f, 0xff, 0xd8, 0x1f, 
+-      0x40, 0x40, 0xa0, 0x4d, 0x80, 0x0a, 0xd0, 0x00, 
+-      0x06, 0x50, 0xf9, 0x95, 0xd0, 0x01, 0xa0, 0x09, 
+-      0x80, 0x1b, 0xa0, 0x27, 0x01, 0x20, 0xd0, 0x67, 
+-      0xa0, 0x69, 0x80, 0x2a, 0x82, 0x29, 0x80, 0x6a, 
+-      0x84, 0x29, 0xd0, 0x54, 0x10, 0x4f, 0xa0, 0x6a, 
+-      0x01, 0x20, 0xd0, 0x40, 0xa0, 0x69, 0x80, 0x2b, 
+-      0x80, 0x07, 0x08, 0x20, 0xdf, 0x00, 0x02, 0x30, 
+-      0xd0, 0x00, 0xa0, 0x38, 0x80, 0x3f, 0x01, 0xb0, 
+-      0xd0, 0x10, 0xa0, 0x37, 0x80, 0x3f, 0x02, 0x30, 
+-      0xd0, 0x01, 0xa0, 0x38, 0xd0, 0x10, 0xa0, 0x38, 
+-      0x15, 0x63, 0xe9, 0xba, 0x05, 0x5e, 0xf9, 0xfa, 
+-      0xc0, 0xdf, 0x00, 0xe0, 0xd1, 0x80, 0x70, 0x06, 
+-      0x10, 0x1c, 0xc1, 0x40, 0x11, 0x48, 0xd3, 0x10, 
+-      0x00, 0x21, 0xd0, 0x80, 0xb0, 0x16, 0xe9, 0xca, 
+-      0xd3, 0x20, 0x10, 0x81, 0xb0, 0x16, 0xf9, 0xfa, 
+-      0x30, 0xc2, 0xd2, 0x5e, 0xd0, 0x8f, 0x00, 0xee, 
+-      0xd0, 0x54, 0x70, 0x41, 0x30, 0x43, 0xed, 0xd7, 
+-      0xd2, 0x6c, 0x72, 0x49, 0xc0, 0x89, 0xb0, 0xbf, 
+-      0x10, 0x9f, 0x22, 0x42, 0x04, 0x31, 0xd0, 0x10, 
+-      0xc0, 0x42, 0x30, 0x49, 0xe5, 0xde, 0x10, 0x03, 
+-      0xc1, 0x0c, 0xc1, 0x83, 0xb1, 0xbe, 0x01, 0x46, 
+-      0x00, 0x06, 0xa0, 0x3d, 0xa0, 0x3c, 0x60, 0x06, 
+-      0x00, 0xc6, 0xb1, 0xbc, 0xb1, 0x01, 0xed, 0xe1, 
+-      0xc1, 0x0c, 0x21, 0x85, 0x01, 0x46, 0x00, 0x06, 
+-      0xa0, 0x3d, 0xa0, 0x3c, 0x60, 0x06, 0x00, 0xc6, 
+-      0xb1, 0xbc, 0xb1, 0x01, 0xed, 0xec, 0x02, 0xe4, 
+-      0xd0, 0x00, 0x20, 0xc0, 0xb2, 0x41, 0xed, 0xd8, 
+-      0x15, 0xa3, 0xfa, 0x00, 0xbc, 0x10, 0x0c, 0x1e, 
+-      0xfa, 0x00, 0xbc, 0x10, 0xd0, 0x04, 0x70, 0x00, 
+-      0x10, 0x20, 0xfa, 0x00, 0x00, 0x27, 0xd0, 0x10, 
+-      0xd0, 0x40, 0x60, 0x40, 0x00, 0x26, 0xd0, 0x14, 
+-      0x60, 0x40, 0xb0, 0x28, 0x70, 0x40, 0xb0, 0x7f, 
+-      0x60, 0x40, 0x01, 0x7a, 0xde, 0x1a, 0xe0, 0x46, 
+-      0x50, 0x00, 0x50, 0x00, 0x00, 0x28, 0xd1, 0xb0, 
+-      0x70, 0x06, 0xd0, 0x81, 0x60, 0x86, 0x10, 0x20, 
+-      0xe9, 0xab, 0xb0, 0x3f, 0x60, 0x06, 0x00, 0xec, 
+-      0xd1, 0x84, 0x70, 0x46, 0xb1, 0x84, 0x70, 0x86, 
+-      0x30, 0x42, 0xe9, 0xab, 0x70, 0x42, 0xd0, 0x35, 
+-      0x30, 0x40, 0xf9, 0xab, 0x00, 0x63, 0xd0, 0x3f, 
+-      0xb0, 0xbc, 0x40, 0x80, 0x70, 0xc2, 0x10, 0xe3, 
+-      0xe5, 0xab, 0xb0, 0xbc, 0x40, 0x80, 0x60, 0x86, 
+-      0x00, 0x28, 0xd0, 0x24, 0x70, 0x40, 0x00, 0x22, 
+-      0xd0, 0x80, 0x50, 0x42, 0x60, 0x40, 0x00, 0x64, 
+-      0xd0, 0x60, 0xd0, 0x90, 0x60, 0x81, 0x00, 0xed, 
+-      0xd1, 0x88, 0x70, 0x46, 0x10, 0xe4, 0xe9, 0xa8, 
+-      0x00, 0x21, 0xd0, 0xe8, 0xd0, 0x00, 0x60, 0x03, 
+-      0xd0, 0x81, 0x40, 0x42, 0x60, 0x46, 0x02, 0x3c, 
+-      0xda, 0x89, 0xe0, 0x46, 0xd0, 0x82, 0x50, 0x42, 
+-      0x60, 0x46, 0x00, 0x23, 0xd5, 0x3e, 0x01, 0x7a, 
+-      0xde, 0x1a, 0xe0, 0x46, 0x01, 0x46, 0xdf, 0x5c, 
+-      0x08, 0x20, 0xd1, 0x00, 0xcf, 0x04, 0x11, 0x08, 
+-      0xa1, 0x0a, 0xa1, 0x1b, 0x11, 0x1f, 0xa1, 0x27, 
+-      0xd2, 0x80, 0xb2, 0x81, 0x90, 0x4d, 0xc0, 0x01, 
+-      0x10, 0x14, 0x00, 0x16, 0xe9, 0x8d, 0x80, 0x33, 
+-      0x80, 0x3f, 0x92, 0x8b, 0x00, 0x23, 0xd0, 0x3f, 
+-      0x42, 0x80, 0xe9, 0x8d, 0x0f, 0xff, 0xdf, 0xff, 
+-      0x40, 0x01, 0xa0, 0x0d, 0xe1, 0x94, 0xa1, 0x0a, 
+-      0x00, 0xea, 0xd0, 0x00, 0xd0, 0x8e, 0x00, 0x06, 
+-      0x0f, 0x0b, 0x70, 0x80, 0x80, 0x73, 0x80, 0x0a, 
+-      0xd0, 0x00, 0x06, 0x50, 0xf9, 0x9a, 0xd0, 0x01, 
+-      0xd0, 0x44, 0x40, 0x70, 0x20, 0x01, 0x15, 0x63, 
+-      0xf9, 0xa1, 0x80, 0x1b, 0xe1, 0xa2, 0x80, 0x5b, 
+-      0xa0, 0x27, 0x01, 0x20, 0xd0, 0x67, 0xa0, 0x69, 
+-      0x80, 0x2a, 0x82, 0x29, 0x80, 0x6a, 0x84, 0x29, 
+-      0xd0, 0x54, 0x10, 0x4f, 0xa0, 0x6a, 0x01, 0x20, 
+-      0xd0, 0x40, 0xa0, 0x69, 0x80, 0x2b, 0x80, 0x07, 
+-      0x08, 0x20, 0xd0, 0x00, 0xcf, 0x00, 0x02, 0x30, 
+-      0xd0, 0x00, 0xa0, 0x38, 0x80, 0x3f, 0x01, 0xb2, 
+-      0xd2, 0x10, 0xa0, 0x37, 0x80, 0x3f, 0x02, 0x30, 
+-      0xd0, 0x01, 0xa0, 0x38, 0x00, 0x30, 0xd0, 0x10, 
+-      0xa0, 0x38, 0x80, 0x3f, 0x00, 0xc6, 0x00, 0x28, 
+-      0xd1, 0x24, 0x70, 0x04, 0xd0, 0x41, 0x50, 0x01, 
+-      0x60, 0x04, 0x00, 0x27, 0xd0, 0x18, 0x70, 0x40, 
+-      0xb0, 0x7f, 0x60, 0x40, 0x00, 0x26, 0xd0, 0x20, 
+-      0x70, 0x40, 0xb0, 0x7f, 0x60, 0x40, 0x08, 0x20, 
+-      0xdf, 0x00, 0xd4, 0x00, 0xd4, 0x40, 0xd4, 0x80, 
+-      0xd4, 0xc0, 0xd3, 0x81, 0x12, 0xa0, 0xed, 0xe3, 
+-      0xd0, 0x08, 0x0a, 0x09, 0x00, 0x4d, 0xb0, 0x01, 
+-      0xed, 0xdf, 0x03, 0xbe, 0xd6, 0x27, 0xe0, 0x46, 
+-      0x50, 0x00, 0x50, 0x00, 0x02, 0x24, 0xd0, 0x00, 
+-      0xa0, 0x37, 0x00, 0x27, 0xd3, 0xd0, 0x00, 0x26, 
+-      0xd0, 0x04, 0x73, 0xcf, 0x13, 0xe1, 0xe9, 0x7b, 
+-      0xb0, 0x3c, 0xf2, 0x00, 0x00, 0x26, 0xd0, 0x40, 
+-      0xd0, 0x00, 0x60, 0x01, 0x00, 0x26, 0xd0, 0x14, 
+-      0xf2, 0x00, 0x00, 0x26, 0xd0, 0x18, 0xf2, 0x00, 
+-      0x00, 0xee, 0xd0, 0x1c, 0x71, 0x40, 0xd1, 0x1e, 
+-      0x15, 0x63, 0xe9, 0x8d, 0x11, 0x1f, 0xc7, 0x1a, 
+-      0xb7, 0x01, 0xd3, 0x81, 0xc4, 0xd4, 0xf2, 0x04, 
+-      0x00, 0x26, 0xd0, 0x18, 0x70, 0x40, 0xb0, 0x54, 
+-      0xfd, 0x9b, 0x00, 0xed, 0xd0, 0x24, 0xd0, 0x44, 
+-      0x60, 0x40, 0x13, 0xe1, 0xf9, 0xbc, 0x15, 0xa3, 
+-      0xf9, 0xa1, 0x0c, 0x10, 0xe9, 0xb9, 0x11, 0x61, 
+-      0xe5, 0xb3, 0xed, 0xb9, 0x15, 0xa3, 0xf9, 0xab, 
+-      0x00, 0x26, 0xd0, 0x14, 0x70, 0x40, 0x10, 0x62, 
+-      0xf5, 0xb3, 0x15, 0x22, 0xe5, 0xb3, 0xc0, 0x44, 
+-      0x30, 0x54, 0xe5, 0xb3, 0x34, 0xd4, 0xf5, 0xb3, 
+-      0xe1, 0xbf, 0x03, 0xb3, 0xd8, 0x29, 0x00, 0x26, 
+-      0xd0, 0x40, 0x60, 0x01, 0xe1, 0xdb, 0x03, 0xb3, 
+-      0xd8, 0x29, 0xe0, 0x46, 0x01, 0x7a, 0xde, 0x1a, 
+-      0xe0, 0x46, 0x80, 0x07, 0x09, 0x49, 0xd4, 0x00, 
+-      0xd4, 0x40, 0xd4, 0x80, 0xd4, 0xc0, 0x00, 0x4d, 
+-      0xa0, 0x6c, 0xd3, 0x80, 0xd0, 0xa1, 0x00, 0x88, 
+-      0xd0, 0xa9, 0x00, 0x4d, 0x00, 0x50, 0xf9, 0xc9, 
+-      0x0c, 0x49, 0xd0, 0x61, 0x00, 0x8d, 0x10, 0xa0, 
+-      0xe9, 0x90, 0x30, 0x42, 0xf5, 0xd8, 0xd0, 0x61, 
+-      0x23, 0x81, 0xe1, 0xce, 0x23, 0x82, 0x13, 0xa1, 
+-      0xf9, 0x90, 0xd0, 0x42, 0x15, 0xa1, 0xf9, 0xdf, 
+-      0xb0, 0x7f, 0x00, 0x26, 0xd0, 0x14, 0x70, 0x00, 
+-      0x30, 0x01, 0xf5, 0xe8, 0x16, 0xe0, 0xe5, 0xe8, 
+-      0xb6, 0xc1, 0xbc, 0x20, 0xc0, 0x44, 0x30, 0x5b, 
+-      0xfd, 0xb9, 0xc0, 0x44, 0x30, 0x54, 0xe5, 0xb9, 
+-      0x15, 0x63, 0xf9, 0xf8, 0x15, 0xa3, 0xf9, 0xf5, 
+-      0x03, 0x3b, 0xda, 0x1c, 0xe0, 0x46, 0x03, 0x38, 
+-      0xdc, 0x17, 0xe0, 0x46, 0x15, 0xa3, 0xf9, 0xfd, 
+-      0x03, 0x72, 0xd0, 0x19, 0xe0, 0x46, 0x03, 0x3f, 
+-      0xd2, 0x17, 0xe0, 0x46, 0x70, 0x40, 0xb0, 0x7f, 
+-      0x60, 0x40, 0x0f, 0xc5, 0xdf, 0x00, 0x0c, 0x09, 
+-      0x05, 0x0d, 0x08, 0x20, 0xdf, 0x00, 0x0f, 0xc5, 
+-      0x50, 0x00, 0x50, 0x00, 0x00, 0xef, 0xd0, 0x14, 
+-      0x70, 0x40, 0x10, 0x60, 0xe9, 0x45, 0xb0, 0x04, 
+-      0x70, 0x40, 0xb0, 0x41, 0xed, 0x44, 0x00, 0xed, 
+-      0xd0, 0x24, 0xd0, 0x44, 0x60, 0x40, 0x00, 0x64, 
+-      0xd0, 0x20, 0x70, 0x00, 0x10, 0x30, 0xe9, 0x45, 
+-      0x00, 0x21, 0xd0, 0x28, 0x60, 0x40, 0x00, 0x64, 
+-      0xd2, 0xc0, 0x70, 0x0b, 0x00, 0x11, 0xe9, 0x6a, 
+-      0x08, 0x20, 0xd0, 0x4f, 0x30, 0x40, 0xe9, 0x55, 
+-      0xb0, 0x4f, 0xf9, 0x6a, 0x03, 0xef, 0xdf, 0xbf, 
+-      0xaf, 0xb8, 0xdf, 0x80, 0x0f, 0x87, 0xd0, 0x18, 
+-      0x70, 0x00, 0x10, 0x20, 0xed, 0x6c, 0xdf, 0x84, 
+-      0xd0, 0x40, 0x60, 0x7e, 0x00, 0x27, 0xd0, 0x54, 
+-      0x70, 0x41, 0x10, 0x60, 0x01, 0xa0, 0xd0, 0x40, 
+-      0xa0, 0x78, 0x80, 0x34, 0x80, 0x3f, 0x01, 0x3c, 
+-      0xd2, 0x39, 0x00, 0x21, 0xdf, 0x86, 0x0f, 0x87, 
+-      0xd0, 0x40, 0x60, 0x4b, 0x03, 0xe5, 0xd0, 0x10, 
+-      0xe0, 0x36, 0x50, 0x00, 0x00, 0x28, 0xd0, 0x24, 
+-      0x72, 0xc0, 0xd0, 0x40, 0x60, 0x40, 0xd0, 0x0c, 
+-      0x52, 0xc0, 0xc0, 0x1c, 0x30, 0x1d, 0xf5, 0x3c, 
+-      0x20, 0x1f, 0x30, 0x1e, 0x90, 0x6d, 0x20, 0x01, 
+-      0x00, 0x22, 0xd0, 0x58, 0x60, 0x01, 0x00, 0xe3, 
+-      0xd0, 0x48, 0x70, 0x41, 0x30, 0x40, 0xf5, 0x47, 
+-      0xb2, 0xc8, 0x00, 0xe3, 0xd0, 0x4c, 0x70, 0x41, 
+-      0x30, 0x40, 0xfd, 0x4d, 0xb2, 0xc4, 0x00, 0x28, 
+-      0xd0, 0x20, 0x70, 0x00, 0x42, 0xc0, 0xa2, 0xc5, 
+-      0x12, 0xe0, 0xe9, 0x55, 0x80, 0x40, 0x80, 0x34, 
+-      0x80, 0x3f, 0xcf, 0x95, 0x82, 0x34, 0x80, 0x3f, 
+-      0x03, 0xe7, 0xd0, 0x08, 0x1f, 0xa3, 0xe9, 0x60, 
+-      0x03, 0xe9, 0xd0, 0x08, 0x00, 0x27, 0xd0, 0x4c, 
+-      0x7f, 0x81, 0x00, 0x27, 0xd0, 0x54, 0x70, 0x41, 
+-      0x10, 0x60, 0x03, 0xa0, 0xd0, 0x40, 0xa0, 0x78, 
+-      0xe0, 0x3c, 0x50, 0x00, 0xc0, 0x84, 0x10, 0x8c, 
+-      0x10, 0x92, 0xd0, 0x41, 0x30, 0x4d, 0x40, 0x43, 
+-      0x10, 0x43, 0x20, 0x81, 0xd1, 0x8f, 0x41, 0x82, 
+-      0x10, 0x9c, 0x20, 0x9b, 0xc1, 0xc2, 0x10, 0x82, 
+-      0x20, 0x87, 0xc0, 0x42, 0x10, 0x43, 0x20, 0x81, 
+-      0x10, 0x88, 0x22, 0x02, 0x10, 0x97, 0x01, 0xd0, 
+-      0xe9, 0x48, 0xb0, 0x96, 0x10, 0x88, 0x22, 0x82, 
+-      0xc0, 0x5c, 0x10, 0x48, 0xc0, 0x84, 0x10, 0x91, 
+-      0x10, 0x86, 0x20, 0x42, 0x41, 0x0d, 0x11, 0x02, 
+-      0x20, 0x44, 0x22, 0x01, 0x22, 0x81, 0x02, 0xe4, 
+-      0xd2, 0x40, 0xc2, 0xca, 0xb2, 0xe0, 0x01, 0xd0, 
+-      0xe9, 0x5e, 0xc2, 0xca, 0x22, 0xc9, 0xb2, 0xa0, 
+-      0x22, 0x48, 0xd0, 0x78, 0x03, 0x50, 0xf9, 0x69, 
+-      0xd0, 0x7c, 0x01, 0x9d, 0xf9, 0x69, 0xc2, 0x48, 
+-      0xb2, 0x60, 0xc2, 0xca, 0xb2, 0xf0, 0x11, 0x82, 
+-      0x41, 0x81, 0x22, 0x06, 0x11, 0x9f, 0x41, 0x81, 
+-      0x22, 0x86, 0x0f, 0xc5, 0xc0, 0x84, 0x10, 0x8c, 
+-      0x10, 0x92, 0xd1, 0x8f, 0x41, 0x82, 0x10, 0x9c, 
+-      0xc1, 0xdb, 0x11, 0xc1, 0x21, 0xc3, 0x20, 0x87, 
+-      0xc1, 0xc2, 0x10, 0x82, 0x20, 0x87, 0xc0, 0x42, 
+-      0x10, 0x43, 0x20, 0x81, 0x10, 0x88, 0x22, 0x02, 
+-      0x10, 0x97, 0x01, 0xd0, 0xe9, 0x46, 0xb0, 0x96, 
+-      0x10, 0x88, 0x22, 0x82, 0xc0, 0x5c, 0x10, 0x48, 
+-      0xc0, 0x84, 0x10, 0x91, 0x10, 0x86, 0x20, 0x42, 
+-      0xd0, 0x81, 0x41, 0x02, 0x11, 0x02, 0x20, 0x44, 
+-      0x22, 0x01, 0x22, 0x81, 0x02, 0xe4, 0xd2, 0x40, 
+-      0xc2, 0xca, 0xb2, 0xe0, 0x01, 0xd0, 0xe9, 0x5d, 
+-      0xc2, 0xca, 0x22, 0xc9, 0xb2, 0xa0, 0x22, 0x48, 
+-      0x11, 0x9f, 0x11, 0x83, 0x22, 0x06, 0x11, 0x9c, 
+-      0x11, 0x83, 0x22, 0x86, 0x0f, 0xc5, 0xd0, 0x41, 
+-      0x40, 0x44, 0x20, 0x55, 0x10, 0x62, 0xf9, 0x6f, 
+-      0x01, 0x74, 0xd6, 0x00, 0xc2, 0x9f, 0xc2, 0x1f, 
+-      0x22, 0x80, 0xe1, 0x30, 0x0f, 0x11, 0xf9, 0x51, 
+-      0x90, 0x38, 0x80, 0x3f, 0x00, 0x1b, 0xf9, 0x51, 
+-      0x00, 0x27, 0xd0, 0x04, 0x70, 0x40, 0x30, 0x71, 
+-      0xf9, 0x51, 0xb0, 0x3c, 0x70, 0x40, 0x30, 0x5d, 
+-      0xf9, 0x51, 0xb0, 0x08, 0x70, 0x40, 0xb0, 0x7f, 
+-      0x60, 0x40, 0x10, 0x63, 0xe5, 0x5d, 0x02, 0x20, 
+-      0xd0, 0x01, 0xa0, 0x37, 0x00, 0x26, 0xd0, 0x24, 
+-      0x70, 0x40, 0xb0, 0x7f, 0x60, 0x40, 0xb0, 0x08, 
+-      0x70, 0x40, 0xb0, 0x41, 0x60, 0x40, 0x00, 0x26, 
+-      0xd0, 0x30, 0x70, 0x40, 0xb0, 0x7f, 0x60, 0x40, 
+-      0xb0, 0x30, 0xd0, 0x40, 0x60, 0x40, 0xb0, 0x3c, 
+-      0x6c, 0x40, 0xb0, 0x3c, 0x67, 0x40, 0x00, 0x33, 
+-      0xdf, 0x78, 0xe0, 0x36, 0x00, 0x26, 0xd0, 0x1c, 
+-      0x70, 0x40, 0xb0, 0x7f, 0x60, 0x40, 0xb0, 0x3c, 
+-      0x70, 0x40, 0xb0, 0x41, 0x60, 0x40, 0x08, 0x20, 
+-      0xdf, 0x00, 0x80, 0x35, 0xc0, 0x3c, 0x10, 0x08, 
+-      0xa0, 0x0a, 0xa0, 0x27, 0xa0, 0x1b, 0xdf, 0x5c, 
+-      0x01, 0xa0, 0xd0, 0x00, 0xa0, 0x38, 0x80, 0x3f, 
+-      0x80, 0x34, 0x80, 0x3f, 0x03, 0xba, 0xda, 0x1e, 
+-      0xcf, 0x95, 0x82, 0x34, 0x80, 0x3f, 0x03, 0xe7, 
+-      0xd0, 0x08, 0x1f, 0xa3, 0xe9, 0x55, 0x1f, 0xa0, 
+-      0xe9, 0x55, 0x03, 0xe9, 0xd0, 0x08, 0x00, 0x21, 
+-      0xdf, 0x86, 0xe0, 0x3c, 0x89, 0x78, 0x89, 0x37, 
+-      0x00, 0xee, 0xd0, 0x14, 0x76, 0x00, 0xd0, 0x30, 
+-      0x76, 0x40, 0x26, 0x58, 0xd6, 0xd9, 0x00, 0xee, 
+-      0xd0, 0x20, 0x75, 0x40, 0xd0, 0x1c, 0x71, 0x40, 
+-      0xd0, 0x20, 0x71, 0x00, 0xd0, 0x24, 0x70, 0x80, 
+-      0xc4, 0x02, 0xd0, 0x28, 0x70, 0xc0, 0x00, 0x21, 
+-      0xd0, 0x10, 0x72, 0x00, 0x93, 0x90, 0xd4, 0x81, 
+-      0x13, 0x96, 0x43, 0x92, 0x34, 0x8e, 0x00, 0x22, 
+-      0xd1, 0xa4, 0x71, 0x86, 0xde, 0x40, 0x7e, 0x79, 
+-      0xd0, 0x18, 0x70, 0x40, 0xb0, 0x41, 0xf5, 0x58, 
+-      0xd3, 0x42, 0x50, 0x4d, 0x60, 0x40, 0x10, 0x60, 
+-      0xe5, 0x62, 0xd0, 0x54, 0x70, 0x01, 0xb0, 0x3c, 
+-      0x60, 0x01, 0x04, 0x2d, 0xd0, 0x08, 0xe0, 0x36, 
+-      0x00, 0x22, 0xd0, 0x60, 0x71, 0xc1, 0xd0, 0x4f, 
+-      0x41, 0xc1, 0x03, 0xef, 0xd0, 0x30, 0xe0, 0x36, 
+-      0x50, 0x00, 0x50, 0x00, 0x04, 0x21, 0xd0, 0x20, 
+-      0xd3, 0x44, 0x72, 0x8d, 0x12, 0xa0, 0xe8, 0x36, 
+-      0xc0, 0x47, 0x10, 0x5d, 0x30, 0x4e, 0xf8, 0x36, 
+-      0xb2, 0x3e, 0x60, 0x4d, 0x00, 0xed, 0xd0, 0x48, 
+-      0x70, 0x01, 0xde, 0x45, 0x50, 0x39, 0x00, 0x1b, 
+-      0xf9, 0x44, 0xb0, 0x01, 0x00, 0x1c, 0xf9, 0x47, 
+-      0xb0, 0x04, 0x60, 0x01, 0xd0, 0x40, 0x62, 0x81, 
+-      0xce, 0x4a, 0xd0, 0x43, 0x41, 0xc1, 0xd0, 0x58, 
+-      0x61, 0xc1, 0x90, 0x43, 0x00, 0xe0, 0xd0, 0x28, 
+-      0x70, 0x00, 0x10, 0x1f, 0x20, 0x40, 0xb1, 0xc1, 
+-      0xf5, 0x54, 0x00, 0x21, 0xd0, 0x08, 0x60, 0x40, 
+-      0x00, 0xe6, 0xd0, 0x40, 0x70, 0x41, 0xd2, 0x94, 
+-      0x60, 0x4a, 0x04, 0x2b, 0xd0, 0x10, 0x01, 0x90, 
+-      0xf8, 0x36, 0x04, 0x2d, 0xd0, 0x08, 0xe0, 0x36, 
+-      0x50, 0x00, 0x50, 0x00, 0xc0, 0x47, 0x10, 0x5d, 
+-      0x30, 0x4e, 0xf9, 0x41, 0x90, 0x43, 0x00, 0xe0, 
+-      0xd0, 0x28, 0x70, 0x00, 0x20, 0x40, 0x00, 0x21, 
+-      0xd0, 0x08, 0x60, 0x40, 0x00, 0x26, 0xd0, 0x74, 
+-      0x70, 0x01, 0xb0, 0x3f, 0x60, 0x01, 0x00, 0xed, 
+-      0xd0, 0x48, 0x70, 0x41, 0x00, 0x5e, 0xf9, 0x4b, 
+-      0x00, 0x21, 0xd0, 0x00, 0x73, 0x80, 0xd4, 0x81, 
+-      0x34, 0x8e, 0x00, 0x34, 0xd3, 0x48, 0xe0, 0x36, 
+-      0x50, 0x00, 0x50, 0x00, 0xd1, 0x88, 0xd1, 0xc8, 
+-      0x01, 0x1b, 0xe9, 0x39, 0x11, 0x9f, 0x11, 0xdf, 
+-      0xd4, 0x80, 0xd3, 0x81, 0xe1, 0x43, 0x00, 0xed, 
+-      0xd0, 0x08, 0x70, 0x00, 0x00, 0x10, 0xf9, 0x37, 
+-      0x0c, 0x1f, 0xf9, 0x36, 0x13, 0xa1, 0xe9, 0x43, 
+-      0xbe, 0x7c, 0x00, 0x65, 0xd2, 0x46, 0x12, 0x48, 
+-      0xc0, 0x39, 0x30, 0x18, 0xe5, 0x4b, 0xd2, 0x70, 
+-      0x72, 0x49, 0x22, 0x79, 0x00, 0x21, 0xd0, 0x00, 
+-      0x63, 0x80, 0x04, 0x24, 0xd0, 0x00, 0x02, 0x10, 
+-      0xe9, 0x56, 0xd0, 0x41, 0x51, 0x41, 0xe0, 0x36, 
+-      0x15, 0x61, 0xe8, 0x36, 0xd5, 0x80, 0xd3, 0x00, 
+-      0xd3, 0x40, 0x04, 0x27, 0xd0, 0x20, 0xe0, 0x36, 
+-      0x50, 0x00, 0x50, 0x00, 0x00, 0x21, 0xd0, 0x18, 
+-      0x73, 0x00, 0xb0, 0x04, 0x73, 0x80, 0xd2, 0x80, 
+-      0xb0, 0x38, 0x72, 0xc0, 0x31, 0x0d, 0xc0, 0x0e, 
+-      0x10, 0x0b, 0x10, 0x20, 0xe9, 0x42, 0xf5, 0x3f, 
+-      0x22, 0x8d, 0x10, 0x01, 0x13, 0x5f, 0xe1, 0x3b, 
+-      0x33, 0x8b, 0x15, 0x61, 0xf9, 0x49, 0x00, 0x21, 
+-      0xd0, 0x64, 0x70, 0x41, 0x33, 0x81, 0x03, 0xd0, 
+-      0xe9, 0x4c, 0x20, 0x0b, 0x13, 0xdf, 0x12, 0xc1, 
+-      0x13, 0xe0, 0xf9, 0x49, 0x10, 0x03, 0xc0, 0x50, 
+-      0x10, 0x4b, 0x13, 0x0b, 0x23, 0x00, 0x13, 0x20, 
+-      0xe9, 0x5c, 0xf5, 0x59, 0x22, 0x81, 0x13, 0x01, 
+-      0x10, 0x5f, 0xe1, 0x55, 0x12, 0x99, 0x12, 0x87, 
+-      0x21, 0x0a, 0x00, 0xa0, 0xd2, 0x80, 0xc3, 0x0a, 
+-      0x03, 0x90, 0xe9, 0x66, 0x22, 0x82, 0x23, 0x03, 
+-      0x10, 0x81, 0x10, 0xc1, 0x13, 0x9f, 0x13, 0xa0, 
+-      0xed, 0x62, 0xc0, 0x8a, 0xc0, 0xcc, 0x04, 0x26, 
+-      0xd0, 0x00, 0xe0, 0x36, 0x15, 0x61, 0xf9, 0x3d, 
+-      0x07, 0x32, 0xd0, 0x00, 0x30, 0x03, 0xed, 0x3d, 
+-      0xc0, 0x03, 0x10, 0x1d, 0x30, 0xc0, 0xc0, 0x02, 
+-      0x10, 0x1d, 0x30, 0x80, 0xe1, 0x32, 0x10, 0x94, 
+-      0x10, 0xd4, 0x00, 0x21, 0xd0, 0x20, 0x73, 0x00, 
+-      0xc5, 0x8c, 0xd3, 0x4e, 0x01, 0x1b, 0xe9, 0x48, 
+-      0x13, 0x1f, 0xd3, 0x4f, 0x43, 0x4c, 0x13, 0x1c, 
+-      0xc0, 0x0c, 0x10, 0x03, 0x20, 0x0c, 0xc0, 0x40, 
+-      0x10, 0x42, 0x20, 0x40, 0x10, 0x46, 0x20, 0x4d, 
+-      0x10, 0x42, 0x2e, 0x41, 0x10, 0x5c, 0x10, 0x43, 
+-      0x00, 0x59, 0xe9, 0x5b, 0x01, 0x69, 0xd0, 0x20, 
+-      0x30, 0x40, 0x22, 0x41, 0x04, 0x27, 0xd0, 0x20, 
+-      0xe0, 0x36, 0x50, 0x00, 0x2c, 0x14, 0xd0, 0x34, 
+-      0x63, 0x00, 0xd0, 0x38, 0x72, 0xc0, 0xc0, 0x51, 
+-      0x10, 0x5c, 0x30, 0x4b, 0x10, 0x44, 0xd4, 0xc0, 
+-      0xd5, 0x00, 0xc0, 0x18, 0x30, 0x39, 0xed, 0x5f, 
+-      0xd4, 0xd0, 0xc5, 0x01, 0xd0, 0x18, 0x70, 0x00, 
+-      0x0c, 0x1f, 0xe9, 0x48, 0x10, 0x20, 0xfd, 0x48, 
+-      0xd4, 0xc0, 0xd5, 0x00, 0x10, 0x22, 0xe5, 0x4e, 
+-      0xd4, 0xc0, 0xbc, 0x30, 0xd5, 0x00, 0xb5, 0x10, 
+-      0xb0, 0x3f, 0xf9, 0x52, 0x3c, 0x01, 0x3c, 0x01, 
+-      0x02, 0x1f, 0xe9, 0x5f, 0x00, 0xa8, 0xd3, 0xc0, 
+-      0xd3, 0x9e, 0x00, 0xa9, 0xd0, 0x38, 0x70, 0x4f, 
+-      0xb3, 0xfc, 0x60, 0x40, 0xb0, 0x3c, 0xb3, 0x81, 
+-      0xed, 0x59, 0x00, 0x21, 0xd0, 0x28, 0x70, 0x00, 
+-      0x10, 0x20, 0xf9, 0x69, 0x02, 0x1f, 0xf9, 0x6a, 
+-      0x90, 0x10, 0x00, 0x1e, 0xe9, 0x6a, 0xb1, 0x7c, 
+-      0x04, 0x29, 0xd0, 0x20, 0xe0, 0x36, 0x50, 0x00, 
+-      0x50, 0x00, 0x50, 0x00, 0x01, 0x5e, 0xf9, 0x35, 
+-      0x01, 0x50, 0xe9, 0x35, 0xb1, 0x78, 0xd2, 0x00, 
+-      0x01, 0x5c, 0xf9, 0x5f, 0xc0, 0x18, 0x30, 0x39, 
+-      0xed, 0x5f, 0x11, 0x9f, 0xce, 0x58, 0xc2, 0x59, 
+-      0x00, 0xa9, 0xd2, 0x38, 0x14, 0x82, 0x22, 0x12, 
+-      0xc0, 0x0c, 0x10, 0x1f, 0x10, 0x03, 0x22, 0x00, 
+-      0x70, 0x48, 0x03, 0x10, 0xe9, 0x4c, 0xb2, 0x38, 
+-      0xbe, 0x60, 0xb2, 0x60, 0x2e, 0x41, 0x10, 0x5f, 
+-      0x00, 0x59, 0xe9, 0x53, 0x01, 0x69, 0xd0, 0x3c, 
+-      0x30, 0x40, 0x22, 0x41, 0x13, 0x41, 0x2e, 0x4d, 
+-      0x13, 0x5d, 0x13, 0x43, 0x22, 0x4d, 0x14, 0xe0, 
+-      0xe9, 0x5f, 0x33, 0x0b, 0x13, 0x04, 0x2c, 0x0c, 
+-      0x35, 0x0c, 0xc3, 0x46, 0xc3, 0x87, 0x04, 0x61, 
+-      0xd0, 0x28, 0x15, 0x62, 0xfc, 0x36, 0x04, 0x2f, 
+-      0xd0, 0x28, 0xe0, 0x36, 0x00, 0x22, 0xd0, 0x74, 
+-      0x74, 0x01, 0xb0, 0x7c, 0x74, 0x41, 0xb0, 0x7c, 
+-      0x00, 0x27, 0xd0, 0x20, 0x30, 0x11, 0xf5, 0x3b, 
+-      0x24, 0x40, 0x71, 0x41, 0xd1, 0x08, 0xc0, 0x10, 
+-      0x10, 0x1c, 0xb0, 0x16, 0xf9, 0x4a, 0x00, 0x23, 
+-      0xd0, 0x30, 0x30, 0x11, 0xf9, 0x4a, 0xb1, 0x70, 
+-      0x01, 0x50, 0xf9, 0x4a, 0xb1, 0x20, 0x14, 0x41, 
+-      0xc0, 0x90, 0x00, 0x2b, 0xd0, 0xd0, 0x01, 0x50, 
+-      0xe9, 0x50, 0xc0, 0xd0, 0x00, 0x34, 0xdc, 0x00, 
+-      0x20, 0x11, 0x10, 0x1f, 0xa0, 0x1c, 0x00, 0x21, 
+-      0xd0, 0x2c, 0x70, 0x00, 0x10, 0x05, 0x51, 0x40, 
+-      0xd0, 0x1c, 0x61, 0x40, 0xd0, 0x20, 0x61, 0x00, 
+-      0xd0, 0x24, 0x60, 0x80, 0xd0, 0x28, 0x60, 0xc0, 
+-      0x04, 0x2d, 0xd0, 0x08, 0x00, 0x22, 0xd0, 0x64, 
+-      0xb1, 0x81, 0x61, 0x81, 0xe0, 0x36, 0x50, 0x00, 
+-      0x50, 0x00, 0x50, 0x00, 0x90, 0x50, 0xd0, 0x3c, 
+-      0x10, 0x41, 0x60, 0x40, 0x15, 0x62, 0xfd, 0x3d, 
+-      0xc0, 0x10, 0x10, 0x1e, 0x10, 0x07, 0x21, 0x00, 
+-      0x10, 0x16, 0x34, 0x00, 0xc0, 0x90, 0xd3, 0x40, 
+-      0x00, 0x24, 0xd3, 0xc0, 0x04, 0x22, 0xd0, 0x20, 
+-      0x01, 0x9f, 0xe8, 0x36, 0xd0, 0x54, 0x70, 0x41, 
+-      0x73, 0x41, 0x04, 0x2e, 0xd0, 0x00, 0xe0, 0x36, 
+-      0x50, 0x00, 0x50, 0x00, 0x00, 0xef, 0xd3, 0x30, 
+-      0x73, 0x0c, 0xd0, 0x0c, 0x70, 0x00, 0xc0, 0x40, 
+-      0x13, 0x24, 0xf5, 0x42, 0x13, 0x22, 0xe9, 0x41, 
+-      0xe5, 0x43, 0xd3, 0x00, 0x10, 0x22, 0xf9, 0x41, 
+-      0xd0, 0x01, 0xd0, 0x43, 0xd3, 0x01, 0x21, 0x00, 
+-      0xd3, 0x40, 0x03, 0x10, 0xf9, 0x47, 0xd3, 0x40, 
+-      0xe1, 0x61, 0x00, 0x23, 0xd0, 0x00, 0x10, 0x61, 
+-      0xe9, 0x50, 0xb0, 0x33, 0x10, 0x63, 0xe9, 0x50, 
+-      0x00, 0x22, 0xd0, 0x1a, 0xc3, 0xc0, 0xd2, 0xc0, 
+-      0x00, 0x10, 0xe9, 0x55, 0x22, 0xd0, 0x10, 0x1f, 
+-      0x14, 0x01, 0x10, 0x20, 0xed, 0x52, 0x14, 0x18, 
+-      0x12, 0xd8, 0xc0, 0x8b, 0x32, 0xd0, 0x12, 0xc3, 
+-      0x33, 0x4b, 0x13, 0x47, 0x21, 0x0d, 0x04, 0x22, 
+-      0xd0, 0x20, 0xe0, 0x36, 0x00, 0x24, 0xd0, 0x30, 
+-      0xd0, 0x40, 0x60, 0x40, 0xd3, 0xc7, 0x43, 0xc4, 
+-      0x31, 0x0f, 0xd5, 0xd4, 0x25, 0xcf, 0x15, 0xc4, 
+-      0x10, 0xdf, 0xc2, 0xc6, 0xc3, 0x07, 0x11, 0x81, 
+-      0xb1, 0x3b, 0x15, 0x64, 0xe9, 0x47, 0x10, 0xdf, 
+-      0x12, 0xc1, 0x11, 0x81, 0x11, 0xc1, 0xb1, 0x3f, 
+-      0xb5, 0xf8, 0x90, 0x10, 0x00, 0x16, 0xf9, 0x5e, 
+-      0xb5, 0xfc, 0xd0, 0x20, 0x40, 0x39, 0x2e, 0x4b, 
+-      0x22, 0x4c, 0x12, 0x20, 0xe9, 0x59, 0x20, 0x39, 
+-      0x00, 0x1b, 0xe9, 0x59, 0x2c, 0x13, 0x35, 0x13, 
+-      0x0e, 0x5a, 0xf9, 0x59, 0xb2, 0x38, 0x02, 0xe3, 
+-      0xd0, 0x00, 0x0e, 0x5a, 0xe9, 0x5e, 0x2e, 0x40, 
+-      0x01, 0xee, 0xd2, 0x80, 0x42, 0x84, 0xc0, 0x03, 
+-      0x30, 0x02, 0xf5, 0x6b, 0x31, 0x0a, 0x12, 0x98, 
+-      0x20, 0x03, 0xf5, 0x69, 0x12, 0x9f, 0x12, 0x87, 
+-      0x51, 0x0a, 0x00, 0x34, 0xd4, 0xc8, 0xe0, 0x36, 
+-      0x50, 0x00, 0x50, 0x00, 0xd3, 0xc7, 0x43, 0xc4, 
+-      0x15, 0x61, 0xf9, 0x48, 0x10, 0xc1, 0xd5, 0xe0, 
+-      0xd1, 0x80, 0xd1, 0xc0, 0x31, 0x0f, 0x13, 0xe1, 
+-      0xe9, 0x3c, 0xd3, 0xc0, 0x00, 0x24, 0xd0, 0x30, 
+-      0x63, 0xc0, 0x25, 0xcf, 0x15, 0xc2, 0xd0, 0x03, 
+-      0x40, 0x16, 0x25, 0xc0, 0x15, 0xc2, 0x15, 0x81, 
+-      0x35, 0x91, 0xe1, 0x5c, 0x00, 0x24, 0xd0, 0x30, 
+-      0x63, 0xc0, 0x01, 0x50, 0xe9, 0x54, 0x15, 0xa0, 
+-      0xf9, 0x55, 0x00, 0x24, 0xd0, 0x34, 0x70, 0x00, 
+-      0x10, 0x20, 0xe9, 0x55, 0xd3, 0xc0, 0x31, 0x0f, 
+-      0xd5, 0xfc, 0x25, 0xcf, 0x15, 0xc3, 0x14, 0xa0, 
+-      0xe9, 0x5c, 0xb5, 0xfc, 0x00, 0x34, 0xd4, 0xc8, 
+-      0xe0, 0x36, 0x50, 0x00, 0xc4, 0x91, 0x34, 0x96, 
+-      0xed, 0x34, 0xd4, 0x80, 0x14, 0x84, 0xb3, 0xc1, 
+-      0xe5, 0x41, 0xc0, 0x52, 0x10, 0x5e, 0x34, 0x81, 
+-      0xb3, 0xc1, 0xe5, 0x41, 0xc0, 0x52, 0x10, 0x5c, 
+-      0x24, 0x81, 0xb3, 0xc1, 0xe5, 0x37, 0x02, 0x68, 
+-      0xd0, 0x00, 0xb4, 0xb0, 0x14, 0x9b, 0x00, 0x23, 
+-      0xd0, 0x70, 0x30, 0x52, 0xed, 0x4a, 0x24, 0x81, 
+-      0x20, 0x12, 0xa0, 0x1c, 0x10, 0x8a, 0x50, 0x83, 
+-      0xa0, 0x96, 0xa1, 0x50, 0xa1, 0x11, 0xc0, 0x52, 
+-      0xd4, 0x84, 0x10, 0x6c, 0xed, 0x56, 0xd4, 0x81, 
+-      0xd1, 0x00, 0xb1, 0x13, 0x00, 0x23, 0xd1, 0x40, 
+-      0xc2, 0xb9, 0x22, 0x86, 0x12, 0x20, 0xf9, 0x66, 
+-      0x02, 0xe3, 0xd0, 0x40, 0x02, 0x9a, 0xe9, 0x63, 
+-      0x22, 0x81, 0x02, 0x5a, 0xe9, 0x66, 0x22, 0x41, 
+-      0x75, 0xd7, 0xc3, 0xd7, 0xd0, 0xd7, 0x00, 0x21, 
+-      0xd0, 0xb6, 0x8b, 0x38, 0x00, 0x33, 0xdc, 0xd0, 
+-      0xe0, 0x36, 0x50, 0x00, 0xd0, 0x7c, 0x60, 0x01, 
+-      0xae, 0x52, 0xd0, 0x60, 0x40, 0x79, 0x00, 0x13, 
+-      0xe8, 0xc9, 0xa2, 0x94, 0x22, 0x86, 0x13, 0xe0, 
+-      0xe4, 0xd0, 0x13, 0xc1, 0x15, 0x62, 0xfc, 0xd1, 
+-      0x13, 0xc1, 0xe0, 0xd1, 0xc3, 0xd7, 0x03, 0xd9, 
+-      0xe8, 0xd4, 0x22, 0x8d, 0x15, 0x62, 0xfc, 0xda, 
+-      0x03, 0xda, 0xe8, 0xda, 0x22, 0x8d, 0x22, 0x8d, 
+-      0xce, 0x4a, 0x22, 0x86, 0x00, 0x14, 0xe8, 0xe0, 
+-      0xa2, 0x53, 0x22, 0x47, 0x03, 0xd1, 0xe8, 0xe8, 
+-      0x22, 0x4e, 0x15, 0x62, 0xfc, 0xe8, 0x03, 0xd2, 
+-      0xe8, 0xe8, 0x22, 0x4e, 0x12, 0x20, 0xe9, 0x09, 
+-      0x20, 0x79, 0x00, 0x5b, 0xe8, 0xf4, 0x15, 0x20, 
+-      0xfc, 0xf1, 0x2c, 0x13, 0x35, 0x13, 0x0e, 0x5b, 
+-      0xe8, 0xf4, 0xb2, 0x38, 0x02, 0x9a, 0xe8, 0xfb, 
+-      0x70, 0x08, 0xd0, 0x7c, 0x42, 0x81, 0x22, 0x98, 
+-      0x22, 0x80, 0x02, 0x5a, 0xe9, 0x11, 0x70, 0x08, 
+-      0xd0, 0x78, 0x42, 0x41, 0x22, 0x59, 0x10, 0x1f, 
+-      0x22, 0x40, 0x00, 0x19, 0xe9, 0x11, 0x01, 0x69, 
+-      0xd0, 0x7c, 0x32, 0x41, 0xe1, 0x11, 0x02, 0xe3, 
+-      0xd0, 0x40, 0x02, 0x9a, 0xe9, 0x0e, 0x22, 0x81, 
+-      0x02, 0x5a, 0xe9, 0x11, 0x22, 0x41, 0x0e, 0x5a, 
+-      0xe9, 0x15, 0xce, 0x4a, 0x3e, 0x46, 0x0f, 0x87, 
+-      0xdd, 0x48, 0xe1, 0x19, 0xdd, 0x40, 0xdc, 0xc8, 
+-      0xdd, 0x3c, 0x7d, 0x34, 0x1d, 0x19, 0x3d, 0x35, 
+-      0x4d, 0x33, 0x4c, 0xec, 0x3d, 0x33, 0xf9, 0x17, 
+-      0x0f, 0xc5, 0x50, 0x00, 0xd0, 0x39, 0xd0, 0x35, 
+-      0xd0, 0x1d, 0xd0, 0x2d, 0xd0, 0x3f, 0xd0, 0x2e, 
+-      0xd0, 0x3c, 0xd0, 0x37, 0xd0, 0x38, 0xd0, 0x19, 
+-      0xd0, 0x33, 0xd0, 0x2e, 0xd0, 0x3d, 0xd0, 0x3e, 
+-      0xd0, 0x27, 0xd0, 0x3e, 0xd0, 0x3a, 0xd0, 0x2f, 
+-      0xd0, 0x32, 0x00, 0x00, 0x47, 0x78, 0x46, 0xc0, 
+-      0xe1, 0x01, 0x00, 0x90, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0x47, 0x78, 0x00, 0x00, 0xe9, 0x2d, 0x40, 0x00, 
+-      0xe5, 0x9f, 0x20, 0x6c, 0xe0, 0x21, 0x10, 0x01, 
+-      0xe1, 0x02, 0x00, 0x91, 0xe3, 0x50, 0x00, 0x00, 
+-      0x1a, 0x00, 0x00, 0x02, 0xe3, 0xa0, 0x00, 0x00, 
+-      0xeb, 0x00, 0x38, 0x99, 0xea, 0xff, 0xff, 0xf7, 
+-      0xe8, 0xbd, 0x40, 0x00, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xb5, 0x00, 0x4a, 0x12, 0x68, 0x10, 0x28, 0x00, 
+-      0xd1, 0x03, 0x20, 0x00, 0xf7, 0xf1, 0xff, 0xc6, 
+-      0xe7, 0xf7, 0xbd, 0x00, 0x47, 0x78, 0x00, 0x00, 
+-      0xe9, 0x2d, 0x40, 0x00, 0xe5, 0x9f, 0x20, 0x2c, 
+-      0xe3, 0xa0, 0x10, 0x01, 0xe1, 0x02, 0x00, 0x91, 
+-      0xe3, 0x50, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x02, 
+-      0xe3, 0xa0, 0x00, 0x00, 0xeb, 0x00, 0x38, 0x88, 
+-      0xea, 0xff, 0xff, 0xf7, 0xe8, 0xbd, 0x00, 0x01, 
+-      0xe1, 0x2f, 0xff, 0x10, 0x48, 0x02, 0x40, 0x49, 
+-      0x60, 0x01, 0x47, 0x70, 0x70, 0x00, 0x00, 0x34, 
+-      0x2e, 0x08, 0x1f, 0xa8, 0x47, 0x78, 0x46, 0xc0, 
+-      0xe1, 0xa0, 0x09, 0x00, 0xe1, 0xb0, 0x10, 0x01, 
+-      0x03, 0xc0, 0x01, 0x02, 0x13, 0x80, 0x01, 0x02, 
+-      0xe3, 0xa0, 0x13, 0x3f, 0xe3, 0xa0, 0x30, 0x0e, 
+-      0xe1, 0xb0, 0x10, 0x81, 0x3a, 0x00, 0x00, 0x04, 
+-      0xe1, 0xb0, 0x00, 0x80, 0x32, 0x21, 0x13, 0x03, 
+-      0xe2, 0x53, 0x30, 0x01, 0x1a, 0xff, 0xff, 0xf9, 
+-      0xea, 0x00, 0x00, 0x03, 0xe1, 0xb0, 0x00, 0x80, 
+-      0x22, 0x21, 0x13, 0x03, 0xe2, 0x53, 0x30, 0x01, 
+-      0x1a, 0xff, 0xff, 0xf4, 0xe1, 0xa0, 0x0d, 0x21, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0xe9, 0x2d, 0x41, 0xf0, 
+-      0xe2, 0x4d, 0xd0, 0x14, 0xe3, 0xa0, 0xc0, 0x44, 
+-      0xe2, 0x8c, 0xc4, 0x66, 0xe5, 0x9c, 0xc0, 0x00, 
+-      0xe5, 0x9f, 0x01, 0x94, 0xe5, 0x80, 0xc0, 0x00, 
+-      0xe1, 0xa0, 0xc1, 0x4c, 0xe2, 0x0c, 0xc0, 0x03, 
+-      0xe5, 0x9f, 0x01, 0x88, 0xe5, 0xc0, 0xc0, 0x00, 
+-      0xe5, 0x9f, 0x01, 0x84, 0xe5, 0x90, 0x00, 0x00, 
+-      0xe0, 0x80, 0x64, 0x0c, 0xe1, 0xa0, 0x70, 0x06, 
+-      0xe8, 0xb7, 0x00, 0x01, 0xe2, 0x00, 0x40, 0x1f, 
+-      0xe2, 0x8f, 0x2f, 0x69, 0xe7, 0x92, 0x21, 0x04, 
+-      0xe3, 0x52, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x51, 
+-      0xe5, 0x9f, 0x32, 0x1c, 0xe2, 0x83, 0x50, 0xbc, 
+-      0xe5, 0x9f, 0x12, 0x1c, 0xe1, 0x55, 0x00, 0x01, 
+-      0x03, 0xa0, 0x50, 0x00, 0xe5, 0x9f, 0x12, 0x04, 
+-      0xe1, 0x51, 0x00, 0x05, 0x0a, 0x00, 0x00, 0x45, 
+-      0xe5, 0x9f, 0x81, 0xf4, 0xe0, 0x88, 0x80, 0x03, 
+-      0xe5, 0x9f, 0x11, 0x5c, 0xe1, 0xa0, 0x36, 0x20, 
+-      0xe2, 0x03, 0x30, 0x0f, 0xe1, 0x81, 0x10, 0x03, 
+-      0xe5, 0x9f, 0x21, 0x48, 0xe7, 0x92, 0x31, 0x04, 
+-      0xe1, 0xa0, 0x39, 0x83, 0xe1, 0xa0, 0x35, 0xa3, 
+-      0xe1, 0x81, 0x10, 0x03, 0xe1, 0xa0, 0x33, 0xa0, 
+-      0xe2, 0x03, 0x30, 0x01, 0xe1, 0xa0, 0x3b, 0x03, 
+-      0xe1, 0x81, 0x10, 0x03, 0xe1, 0xa0, 0x35, 0x20, 
+-      0xe2, 0x03, 0x30, 0x03, 0xe1, 0xa0, 0x32, 0x03, 
+-      0xe1, 0x81, 0x10, 0x03, 0xe1, 0xa0, 0x3a, 0xa0, 
+-      0xe2, 0x03, 0x30, 0x01, 0xe1, 0xa0, 0x3b, 0x83, 
+-      0xe1, 0x81, 0x10, 0x03, 0xe1, 0xa0, 0x34, 0xa0, 
+-      0xe2, 0x03, 0x30, 0x01, 0xe1, 0xa0, 0x3a, 0x83, 
+-      0xe1, 0x81, 0x10, 0x03, 0xe2, 0x00, 0x30, 0x60, 
+-      0xe1, 0xa0, 0x30, 0x83, 0xe1, 0x81, 0x10, 0x03, 
+-      0xe8, 0xa8, 0x00, 0x02, 0xe5, 0x9f, 0x00, 0xf0, 
+-      0xe3, 0xa0, 0x10, 0x30, 0xe5, 0x80, 0x10, 0x00, 
+-      0xe5, 0x9f, 0x00, 0x9c, 0xe5, 0xd0, 0x40, 0x00, 
+-      0xe2, 0x84, 0x10, 0x01, 0xe5, 0xc0, 0x10, 0x00, 
+-      0xe2, 0x04, 0x40, 0x00, 0xe5, 0x9f, 0x00, 0x98, 
+-      0xe5, 0x90, 0x10, 0x00, 0xe3, 0x11, 0x00, 0x10, 
+-      0x1a, 0x00, 0x00, 0x1a, 0xe5, 0x80, 0x10, 0x00, 
+-      0xe5, 0x8f, 0x51, 0x4c, 0xe1, 0xa0, 0x22, 0x04, 
+-      0xe1, 0x82, 0x10, 0x0c, 0xe5, 0x9f, 0x00, 0xac, 
+-      0xe0, 0x80, 0x02, 0x01, 0xe5, 0x80, 0x70, 0x00, 
+-      0xe5, 0x80, 0x80, 0x04, 0xe5, 0x9f, 0x10, 0x5c, 
+-      0xe5, 0x80, 0x10, 0x08, 0xe5, 0x9f, 0x10, 0x58, 
+-      0xe5, 0x80, 0x10, 0x0c, 0xe5, 0x9f, 0x00, 0x58, 
+-      0xe5, 0x90, 0x10, 0x00, 0xe0, 0x84, 0x00, 0x01, 
+-      0xe3, 0xa0, 0x20, 0x01, 0xe1, 0xa0, 0x00, 0x12, 
+-      0xe3, 0xa0, 0x10, 0x40, 0xe2, 0x81, 0x14, 0x66, 
+-      0xe5, 0x81, 0x00, 0x00, 0xe3, 0xa0, 0x10, 0x01, 
+-      0xe1, 0xa0, 0x0c, 0x11, 0xe3, 0xa0, 0x10, 0xb8, 
+-      0xe2, 0x81, 0x14, 0x66, 0xe5, 0x81, 0x00, 0x00, 
+-      0xe2, 0x8d, 0xd0, 0x14, 0xe8, 0xbd, 0x81, 0xf0, 
+-      0xe5, 0x9f, 0x10, 0xf0, 0xe2, 0x81, 0x10, 0x01, 
+-      0xe5, 0x8f, 0x10, 0xe8, 0xea, 0xff, 0xff, 0xf4, 
+-      0xe5, 0x9f, 0xf0, 0x08, 0xa0, 0x00, 0x05, 0xc4, 
+-      0x80, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x10, 
+-      0x00, 0x00, 0x06, 0xf4, 0xa0, 0x00, 0x04, 0x28, 
+-      0xa0, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x05, 0x50, 
+-      0x2c, 0x00, 0x1f, 0xe8, 0x2c, 0x00, 0x1f, 0xea, 
+-      0x2c, 0x00, 0x1f, 0xf4, 0x00, 0x00, 0x05, 0xe0, 
+-      0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x12, 
+-      0x2c, 0x00, 0x02, 0x00, 0x64, 0x00, 0x04, 0x00, 
+-      0x64, 0x00, 0x00, 0x80, 0x47, 0x00, 0x00, 0x00, 
+-      0x9e, 0x00, 0x00, 0xc0, 0x66, 0x00, 0x00, 0x50, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x07, 
+-      0xe1, 0xb0, 0xf0, 0x0e, 0xe5, 0x9f, 0xf1, 0x00, 
+-      0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x08, 
+-      0xea, 0x00, 0x00, 0x02, 0xe5, 0x9f, 0xf0, 0xec, 
+-      0xe2, 0x5e, 0xf0, 0x04, 0x2c, 0x00, 0x00, 0xe8, 
+-      0xe1, 0x0f, 0x00, 0x00, 0xe3, 0xc0, 0x00, 0x1f, 
+-      0xe3, 0x80, 0x00, 0x1b, 0xe1, 0x29, 0xf0, 0x00, 
+-      0xe5, 0x9f, 0xd0, 0xd8, 0xe5, 0x9f, 0x00, 0xd8, 
+-      0xe0, 0x8d, 0xd0, 0x00, 0xe1, 0x0f, 0x00, 0x00, 
+-      0xe3, 0xc0, 0x00, 0x1f, 0xe3, 0x80, 0x00, 0x13, 
+-      0xe1, 0x29, 0xf0, 0x00, 0xe5, 0x9f, 0xd0, 0xc4, 
+-      0xe5, 0x9f, 0x00, 0xc4, 0xe0, 0x8d, 0xd0, 0x00, 
+-      0xe1, 0x0f, 0x00, 0x00, 0xe3, 0xc0, 0x00, 0x1f, 
+-      0xe3, 0x80, 0x00, 0x12, 0xe1, 0x29, 0xf0, 0x00, 
+-      0xe5, 0x9f, 0xd0, 0xb0, 0xe5, 0x9f, 0x00, 0xb0, 
+-      0xe0, 0x8d, 0xd0, 0x00, 0xe1, 0x0f, 0x00, 0x00, 
+-      0xe3, 0xc0, 0x00, 0x9f, 0xe3, 0x80, 0x00, 0x10, 
+-      0xe1, 0x29, 0xf0, 0x00, 0xe5, 0x9f, 0xd0, 0x60, 
+-      0xeb, 0x00, 0x00, 0x08, 0xe5, 0x9f, 0x00, 0x64, 
+-      0xe5, 0x9f, 0x10, 0x5c, 0xeb, 0x00, 0x37, 0xa7, 
+-      0xe5, 0x9f, 0x00, 0x60, 0xe5, 0x9f, 0x10, 0x58, 
+-      0xeb, 0x00, 0x37, 0xa7, 0xe5, 0x9f, 0xe0, 0x58, 
+-      0xe3, 0x8e, 0xe0, 0x01, 0xe1, 0x2f, 0xff, 0x1e, 
+-      0xe5, 0x9f, 0x00, 0x8c, 0xe5, 0x9f, 0x10, 0x8c, 
+-      0xe5, 0x9f, 0x30, 0x8c, 0xe1, 0x50, 0x00, 0x01, 
+-      0x0a, 0x00, 0x00, 0x03, 0xe1, 0x51, 0x00, 0x03, 
+-      0x34, 0x90, 0x20, 0x04, 0x34, 0x81, 0x20, 0x04, 
+-      0x3a, 0xff, 0xff, 0xfb, 0xe5, 0x9f, 0x10, 0x74, 
+-      0xe3, 0xa0, 0x20, 0x00, 0xe1, 0x53, 0x00, 0x01, 
+-      0x34, 0x83, 0x20, 0x04, 0x3a, 0xff, 0xff, 0xfc, 
+-      0xe1, 0x2f, 0xff, 0x1e, 0x2e, 0x1b, 0xff, 0xf0, 
+-      0x2e, 0x1b, 0x7f, 0xf0, 0x2e, 0x1b, 0x7f, 0xef, 
+-      0x2e, 0x08, 0x9a, 0x00, 0xcc, 0x1f, 0xff, 0xef, 
+-      0xcc, 0x1f, 0x7f, 0xf0, 0x2e, 0x00, 0x1c, 0x39, 
+-      0x2e, 0x01, 0xca, 0x48, 0x2e, 0x01, 0xcb, 0x40, 
+-      0x2e, 0x08, 0x32, 0xf4, 0x00, 0x00, 0x08, 0x00, 
+-      0x2e, 0x08, 0x22, 0xf4, 0x00, 0x00, 0x08, 0x00, 
+-      0x2e, 0x08, 0x2a, 0xf4, 0x00, 0x00, 0x08, 0x00, 
+-      0x2e, 0x08, 0x59, 0xb0, 0xe5, 0x9f, 0xf0, 0x04, 
+-      0xe5, 0x9f, 0xf0, 0x04, 0xe5, 0x9f, 0xf0, 0x04, 
+-      0x2e, 0x08, 0x59, 0xb0, 0x2e, 0x08, 0x59, 0xb1, 
+-      0x2e, 0x08, 0x59, 0xb2, 0x2e, 0x03, 0x3b, 0xfc, 
+-      0x2e, 0x08, 0x00, 0x00, 0x2e, 0x08, 0x3b, 0x70, 
+-      0x2e, 0x08, 0x99, 0xfc, 0x1d, 0x77, 0x1e, 0x16, 
+-      0x03, 0x00, 0x03, 0x03, 0x1d, 0x7f, 0x50, 0x50, 
+-      0x4f, 0x5d, 0x49, 0x5d, 0x40, 0x4a, 0x44, 0x43, 
+-      0x01, 0x49, 0x4d, 0x56, 0x48, 0x4b, 0x5d, 0x4f, 
+-      0x5d, 0x4d, 0x4f, 0x0a, 0x78, 0x71, 0x73, 0x7f, 
+-      0x70, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1b, 
+-      0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 
+-      0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 
+-      0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 
+-      0x08, 0x0f, 0x0f, 0x0d, 0x13, 0x0d, 0x11, 0x0e, 
+-      0x07, 0x08, 0x09, 0x0d, 0x0d, 0x15, 0x10, 0x05, 
+-      0x08, 0x08, 0x09, 0x0e, 0x07, 0x08, 0x07, 0x07, 
+-      0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 
+-      0x0d, 0x0d, 0x07, 0x07, 0x0e, 0x0e, 0x0e, 0x0d, 
+-      0x18, 0x0f, 0x10, 0x11, 0x11, 0x10, 0x0f, 0x13, 
+-      0x11, 0x06, 0x0c, 0x10, 0x0d, 0x13, 0x11, 0x13, 
+-      0x10, 0x13, 0x11, 0x10, 0x0e, 0x11, 0x0f, 0x17, 
+-      0x0f, 0x10, 0x0f, 0x07, 0x07, 0x07, 0x0c, 0x0d, 
+-      0x08, 0x0d, 0x0e, 0x0c, 0x0e, 0x0d, 0x07, 0x0e, 
+-      0x0e, 0x05, 0x06, 0x0c, 0x06, 0x14, 0x0e, 0x0d, 
+-      0x0e, 0x0e, 0x08, 0x0c, 0x07, 0x0e, 0x0b, 0x11, 
+-      0x0b, 0x0c, 0x0c, 0x08, 0x06, 0x08, 0x0e, 0x12, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 
+-      0x07, 0xc0, 0x00, 0x00, 0x19, 0x80, 0x00, 0x00, 
+-      0x0f, 0xfe, 0x00, 0x00, 0x0c, 0xc0, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x0c, 0xc0, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x07, 0xc0, 0x00, 0x00, 0x19, 0x80, 0x00, 0x00, 
+-      0x1e, 0x0f, 0x00, 0x00, 0x0c, 0xc0, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x0c, 0xc0, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00, 0x00, 
+-      0x06, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00, 0x00, 
+-      0x0e, 0xe0, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 
+-      0x30, 0x01, 0x80, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00, 0x00, 
+-      0x0c, 0x60, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x3f, 0xe0, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x00, 0x00, 
+-      0x0c, 0x60, 0x00, 0x00, 0x70, 0xe0, 0x00, 0x00, 
+-      0x60, 0x00, 0xc0, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x00, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 
+-      0x60, 0x00, 0xc0, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x00, 0x00, 
+-      0x18, 0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 
+-      0x60, 0x00, 0xc0, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0xf0, 0x00, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 
+-      0x60, 0x00, 0xc0, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0xfe, 0x00, 0x00, 0x00, 0x30, 0x78, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 
+-      0x60, 0x00, 0xc0, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0xfe, 0x00, 0x00, 0x00, 0x30, 0x1c, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x3e, 0x60, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x70, 0x60, 0x00, 0x00, 
+-      0x30, 0x01, 0x80, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x32, 0x0c, 0x00, 0x00, 
+-      0x60, 0x0c, 0x00, 0x00, 0x60, 0xe0, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x38, 0x0e, 0x00, 0x00, 0x30, 0x70, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x37, 0x1c, 0x00, 0x00, 
+-      0x60, 0x0c, 0x00, 0x00, 0x71, 0xe0, 0x00, 0x00, 
+-      0x1e, 0x0f, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x1c, 0x1c, 0x00, 0x00, 0x38, 0xf0, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x10, 0x02, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x33, 0xf8, 0x00, 0x00, 
+-      0xe0, 0x0e, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 
+-      0x0f, 0xfe, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 
+-      0x0f, 0xf8, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x1f, 0xfe, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x31, 0xf0, 0x00, 0x00, 
+-      0xc0, 0x06, 0x00, 0x00, 0x1e, 0x30, 0x00, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x07, 0xf0, 0x00, 0x00, 0x0f, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 
+-      0x1f, 0xc0, 0x00, 0x00, 0x1e, 0x03, 0x00, 0x00, 
+-      0x07, 0x80, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x06, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x00, 0x0e, 0x70, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x33, 0x07, 0x00, 0x00, 
+-      0x0f, 0xc0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x0c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x00, 0x0e, 0x70, 0x00, 0x00, 
+-      0x7a, 0xf0, 0x00, 0x00, 0x61, 0x86, 0x00, 0x00, 
+-      0x1c, 0xe0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x00, 
+-      0x62, 0x30, 0x00, 0x00, 0x61, 0x8e, 0x00, 0x00, 
+-      0x18, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x3f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x00, 
+-      0x62, 0x00, 0x00, 0x00, 0x61, 0x8c, 0x00, 0x00, 
+-      0x18, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x66, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 
+-      0x72, 0x00, 0x00, 0x00, 0x61, 0x9c, 0x00, 0x00, 
+-      0x0c, 0xe0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x33, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 
+-      0x7a, 0x00, 0x00, 0x00, 0x61, 0xb8, 0x00, 0x00, 
+-      0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x33, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0xc0, 0x00, 0x00, 
+-      0x3f, 0x80, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 
+-      0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0xc0, 0x00, 0x00, 
+-      0x0f, 0xe0, 0x00, 0x00, 0x1e, 0x73, 0xc0, 0x00, 
+-      0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0xc0, 0x00, 0x00, 
+-      0x02, 0xe0, 0x00, 0x00, 0x00, 0x66, 0x60, 0x00, 
+-      0x39, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x39, 0xc0, 0x00, 0x00, 
+-      0x02, 0x70, 0x00, 0x00, 0x00, 0xec, 0x30, 0x00, 
+-      0x70, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 
+-      0x02, 0x30, 0x00, 0x00, 0x00, 0xcc, 0x30, 0x00, 
+-      0x60, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 
+-      0x62, 0x30, 0x00, 0x00, 0x01, 0xcc, 0x30, 0x00, 
+-      0x60, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x31, 0x80, 0x00, 0x00, 
+-      0x72, 0x70, 0x00, 0x00, 0x01, 0x8c, 0x30, 0x00, 
+-      0x70, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x73, 0x80, 0x00, 0x00, 
+-      0x3a, 0xf0, 0x00, 0x00, 0x03, 0x8c, 0x30, 0x00, 
+-      0x38, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x73, 0x80, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x03, 0x06, 0x60, 0x00, 
+-      0x3f, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0x07, 0x03, 0xc0, 0x00, 
+-      0x0f, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x0f, 0xc0, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 
+-      0x0f, 0xc0, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x01, 0xc0, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 
+-      0x1f, 0xe0, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 
+-      0x1f, 0xc0, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 
+-      0x38, 0xe0, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 
+-      0x38, 0xf0, 0x00, 0x00, 0x70, 0xe0, 0x00, 0x00, 
+-      0x03, 0xc0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 
+-      0x38, 0xe0, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0xf0, 0x00, 0x00, 
+-      0x70, 0x60, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x70, 0x70, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 
+-      0x03, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 
+-      0x30, 0x60, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x70, 0x70, 0x00, 0x00, 0x1d, 0x80, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 
+-      0x06, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 
+-      0x30, 0x60, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x78, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x19, 0x80, 0x00, 0x00, 
+-      0x00, 0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 
+-      0x0e, 0xc0, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 
+-      0x30, 0x60, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x03, 0xe0, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 
+-      0x3e, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x00, 0x70, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 
+-      0x0c, 0xc0, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 
+-      0x67, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x38, 0xe0, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x00, 0x60, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 
+-      0x1c, 0xc0, 0x00, 0x00, 0x70, 0xe0, 0x00, 0x00, 
+-      0x7f, 0xe0, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+-      0x1f, 0xc0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 
+-      0x38, 0xc0, 0x00, 0x00, 0x60, 0x70, 0x00, 0x00, 
+-      0x78, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x1f, 0xc0, 0x00, 0x00, 0x38, 0xf0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x70, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 
+-      0x30, 0xc0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x70, 0x70, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x30, 0xe0, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0xe0, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x70, 0xc0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x60, 0x70, 0x00, 0x00, 0x0f, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x7f, 0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0xe0, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 
+-      0x3e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x7f, 0xf0, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x78, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x70, 0x70, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x30, 0x70, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x38, 0xe0, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x38, 0x60, 0x00, 0x00, 0x70, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x7f, 0xf0, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x1f, 0xe0, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x1f, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x7f, 0xf0, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0xff, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x30, 0x0f, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 
+-      0x38, 0x06, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 
+-      0x03, 0xff, 0xc0, 0x00, 0x07, 0xc0, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x30, 0x1e, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x3c, 0x07, 0x80, 0x00, 
+-      0x38, 0x06, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 
+-      0x07, 0xc1, 0xe0, 0x00, 0x07, 0xc0, 0x00, 0x00, 
+-      0x30, 0x1c, 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 
+-      0x30, 0x1c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x1e, 0x0f, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x30, 0x3c, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x3c, 0x07, 0x80, 0x00, 
+-      0x3c, 0x06, 0x00, 0x00, 0x1e, 0x0f, 0x00, 0x00, 
+-      0x0e, 0x00, 0x70, 0x00, 0x06, 0xc0, 0x00, 0x00, 
+-      0x30, 0x0c, 0x00, 0x00, 0x38, 0x07, 0x00, 0x00, 
+-      0x30, 0x0e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x30, 0x70, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x3c, 0x07, 0x80, 0x00, 
+-      0x3e, 0x06, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 
+-      0x1c, 0x79, 0xb8, 0x00, 0x0e, 0xe0, 0x00, 0x00, 
+-      0x30, 0x0c, 0x00, 0x00, 0x30, 0x07, 0x00, 0x00, 
+-      0x30, 0x07, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x03, 0x80, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x30, 0xe0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x36, 0x0d, 0x80, 0x00, 
+-      0x36, 0x06, 0x00, 0x00, 0x30, 0x01, 0x80, 0x00, 
+-      0x39, 0xff, 0x9c, 0x00, 0x0c, 0x60, 0x00, 0x00, 
+-      0x30, 0x0c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x30, 0x07, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x31, 0xc0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x36, 0x0d, 0x80, 0x00, 
+-      0x37, 0x06, 0x00, 0x00, 0x70, 0x01, 0xc0, 0x00, 
+-      0x31, 0xcf, 0x9c, 0x00, 0x0c, 0x60, 0x00, 0x00, 
+-      0x30, 0x1c, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x30, 0x03, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x37, 0x80, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x36, 0x0d, 0x80, 0x00, 
+-      0x33, 0x06, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 
+-      0x33, 0x87, 0x0c, 0x00, 0x1c, 0x70, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x30, 0x03, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x3f, 0xfe, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x37, 0x1d, 0x80, 0x00, 
+-      0x31, 0x86, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 
+-      0x77, 0x03, 0x0c, 0x00, 0x18, 0x30, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x30, 0x03, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x60, 0x3f, 0x80, 0x00, 
+-      0x3f, 0xfe, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x33, 0x19, 0x80, 0x00, 
+-      0x31, 0xc6, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 
+-      0x67, 0x03, 0x0c, 0x00, 0x38, 0x38, 0x00, 0x00, 
+-      0x30, 0x1c, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x30, 0x03, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x60, 0x3f, 0x80, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x3d, 0xe0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x33, 0x19, 0x80, 0x00, 
+-      0x30, 0xc6, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 
+-      0x66, 0x03, 0x0c, 0x00, 0x3f, 0xf8, 0x00, 0x00, 
+-      0x30, 0x0e, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x30, 0x03, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x60, 0x01, 0x80, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x33, 0x19, 0x80, 0x00, 
+-      0x30, 0x66, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 
+-      0x66, 0x07, 0x1c, 0x00, 0x3f, 0xf8, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x70, 0x03, 0x00, 0x00, 
+-      0x30, 0x07, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x70, 0x01, 0x80, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0xc0, 0x00, 0x00, 0x30, 0x70, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x31, 0xb1, 0x80, 0x00, 
+-      0x30, 0x76, 0x00, 0x00, 0x70, 0x01, 0xc0, 0x00, 
+-      0x66, 0x06, 0x18, 0x00, 0x70, 0x1c, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x07, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x01, 0x80, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x60, 0xc0, 0x00, 0x00, 0x30, 0x38, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x31, 0xb1, 0x80, 0x00, 
+-      0x30, 0x36, 0x00, 0x00, 0x30, 0x01, 0x80, 0x00, 
+-      0x67, 0x0e, 0x38, 0x00, 0x60, 0x0c, 0x00, 0x00, 
+-      0x30, 0x0e, 0x00, 0x00, 0x38, 0x06, 0x00, 0x00, 
+-      0x30, 0x0e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x60, 0xc0, 0x00, 0x00, 0x30, 0x3c, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x31, 0xf1, 0x80, 0x00, 
+-      0x30, 0x3e, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 
+-      0x77, 0x1e, 0x70, 0x00, 0x60, 0x0c, 0x00, 0x00, 
+-      0x30, 0x1e, 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 
+-      0x30, 0x1c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x1e, 0x0f, 0x80, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x71, 0xc0, 0x00, 0x00, 0x30, 0x1c, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x31, 0xf1, 0x80, 0x00, 
+-      0x30, 0x1e, 0x00, 0x00, 0x1e, 0x0f, 0x00, 0x00, 
+-      0x73, 0xff, 0xe0, 0x00, 0xe0, 0x0e, 0x00, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x3f, 0x80, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x30, 0xe1, 0x80, 0x00, 
+-      0x30, 0x0e, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 
+-      0x39, 0xe7, 0xc0, 0x00, 0xc0, 0x06, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x1f, 0x00, 0x00, 0x00, 0x30, 0x07, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x30, 0xe1, 0x80, 0x00, 
+-      0x30, 0x0e, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 
+-      0x3c, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0xc0, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 
+-      0xff, 0xfc, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0xc0, 0x06, 0x00, 0x00, 0xc0, 0x38, 0x06, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 
+-      0x7f, 0xfc, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0xc0, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 
+-      0xff, 0xfc, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0xe0, 0x0e, 0x00, 0x00, 0xe0, 0x7c, 0x0e, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x7f, 0xfc, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0xe0, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x1e, 0x00, 0x00, 0x1e, 0x0f, 0x00, 0x00, 
+-      0x30, 0x1e, 0x00, 0x00, 0x3c, 0x1c, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x60, 0x0c, 0x00, 0x00, 0xe0, 0x7c, 0x0e, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x30, 0x1c, 0x00, 0x00, 
+-      0x00, 0x38, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x0e, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x0e, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x60, 0x6c, 0x0c, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x01, 0x80, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x60, 0xec, 0x0c, 0x00, 
+-      0x0e, 0xe0, 0x00, 0x00, 0x1c, 0x38, 0x00, 0x00, 
+-      0x00, 0x70, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x70, 0x01, 0xc0, 0x00, 
+-      0x30, 0x06, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x30, 0x18, 0x00, 0x00, 0x70, 0xee, 0x1c, 0x00, 
+-      0x06, 0xc0, 0x00, 0x00, 0x0e, 0x70, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x39, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x0e, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 
+-      0x30, 0x1e, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x70, 0xc6, 0x1c, 0x00, 
+-      0x07, 0xc0, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 
+-      0x01, 0xc0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x30, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x1c, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x18, 0x30, 0x00, 0x00, 0x30, 0xc6, 0x18, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x70, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x18, 0x30, 0x00, 0x00, 0x31, 0xc7, 0x18, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 
+-      0x30, 0xe0, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x31, 0x83, 0x18, 0x00, 
+-      0x07, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 
+-      0x30, 0x70, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x0c, 0x60, 0x00, 0x00, 0x39, 0x83, 0x38, 0x00, 
+-      0x0e, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x70, 0x01, 0xc0, 0x00, 
+-      0x30, 0x38, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x0e, 0xe0, 0x00, 0x00, 0x1b, 0x83, 0xb0, 0x00, 
+-      0x0e, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x31, 0x80, 0x00, 
+-      0x30, 0x38, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 
+-      0x0e, 0xe0, 0x00, 0x00, 0x1b, 0x01, 0xb0, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x38, 0x3f, 0x80, 0x00, 
+-      0x30, 0x1c, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x07, 0xc0, 0x00, 0x00, 0x1f, 0x01, 0xf0, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x1e, 0x1f, 0x00, 0x00, 
+-      0x30, 0x1e, 0x00, 0x00, 0x3c, 0x1c, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 
+-      0x07, 0xc0, 0x00, 0x00, 0x1f, 0x01, 0xf0, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x80, 0x00, 
+-      0x30, 0x0e, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x1e, 0x00, 0xe0, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0xff, 0xfc, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 
+-      0x30, 0x07, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x0e, 0x00, 0xe0, 0x00, 
+-      0xe0, 0x0e, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0xff, 0xfc, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x06, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 
+-      0x33, 0xc0, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x0f, 0xb0, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0xfe, 0x00, 0x00, 0x00, 0x0f, 0x30, 0x00, 0x00, 
+-      0x33, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x37, 0xcf, 0x80, 0x00, 
+-      0x33, 0xc0, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 
+-      0xfe, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x3f, 0xdf, 0x80, 0x00, 
+-      0x37, 0xe0, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0xe0, 0x00, 0x00, 
+-      0x3c, 0x70, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x38, 0xf0, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x38, 0xf0, 0x00, 0x00, 
+-      0x3c, 0x70, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x31, 0x80, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x3c, 0xf9, 0xc0, 0x00, 
+-      0x3c, 0x70, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x70, 0x60, 0x00, 0x00, 
+-      0x70, 0x70, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x38, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x70, 0xc0, 0x00, 
+-      0x38, 0x30, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 
+-      0x30, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xc0, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 
+-      0x30, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xc0, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 
+-      0x30, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xc0, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3e, 0x60, 0x00, 0x00, 
+-      0x30, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x33, 0x80, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xc0, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x60, 0x00, 0x00, 
+-      0x30, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x60, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x33, 0x80, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xc0, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x60, 0xe0, 0x00, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x70, 0x60, 0x00, 0x00, 
+-      0x70, 0x70, 0x00, 0x00, 0x70, 0x30, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xc0, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x71, 0xe0, 0x00, 0x00, 
+-      0x3c, 0x70, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x38, 0xf0, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x38, 0xf0, 0x00, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0xe0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xc0, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x1f, 0xf0, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xc0, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x00, 0x00, 
+-      0x33, 0xc0, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x0f, 0x30, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x0f, 0x30, 0x00, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x70, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x60, 0xc0, 0x00, 
+-      0x30, 0x30, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x60, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+-      0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+-      0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x37, 0xc0, 0x00, 0x00, 0x0f, 0x30, 0x00, 0x00, 
+-      0x37, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 
+-      0xfe, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0xc0, 0x60, 0x00, 0x00, 0xc0, 0x81, 0x80, 0x00, 
+-      0xe0, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 
+-      0x3f, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0xfe, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0xc0, 0x60, 0x00, 0x00, 0xc1, 0xc1, 0x80, 0x00, 
+-      0x60, 0xc0, 0x00, 0x00, 0x60, 0xe0, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x3c, 0x70, 0x00, 0x00, 0x38, 0xf0, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x70, 0xe0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0xe0, 0xe0, 0x00, 0x00, 0xe1, 0xc1, 0x80, 0x00, 
+-      0x31, 0xc0, 0x00, 0x00, 0x70, 0xe0, 0x00, 0x00, 
+-      0x01, 0xe0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x60, 0xc0, 0x00, 0x00, 0x63, 0xe3, 0x00, 0x00, 
+-      0x3b, 0x80, 0x00, 0x00, 0x30, 0xc0, 0x00, 0x00, 
+-      0x01, 0xc0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x3e, 0x08, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x30, 0x18, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x71, 0xc0, 0x00, 0x00, 0x63, 0x63, 0x00, 0x00, 
+-      0x1f, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x7f, 0x98, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x30, 0x18, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x31, 0x80, 0x00, 0x00, 0x67, 0x63, 0x00, 0x00, 
+-      0x0f, 0x00, 0x00, 0x00, 0x39, 0xc0, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x67, 0xf8, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x30, 0x18, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x31, 0x80, 0x00, 0x00, 0x37, 0x76, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x19, 0x80, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x41, 0xf0, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x30, 0x18, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x3b, 0x80, 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x19, 0x80, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x30, 0x18, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 
+-      0x1b, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x00, 0x00, 
+-      0x1f, 0x00, 0x00, 0x00, 0x1d, 0x80, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x30, 0x70, 0x00, 0x00, 
+-      0x1f, 0x00, 0x00, 0x00, 0x1e, 0x3c, 0x00, 0x00, 
+-      0x3b, 0x80, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x3c, 0x70, 0x00, 0x00, 0x38, 0xf0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x70, 0xe0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x38, 0xf0, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 
+-      0x31, 0x80, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x37, 0xe0, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x3e, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 
+-      0x60, 0xc0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 
+-      0x7f, 0xe0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 
+-      0x33, 0xc0, 0x00, 0x00, 0x0f, 0x30, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 
+-      0x1e, 0x00, 0x00, 0x00, 0x0f, 0x30, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 
+-      0xe0, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x7f, 0xe0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 
+-      0x00, 0x00, 0x00, 0x21, 0x16, 0x16, 0x16, 0x16, 
+-      0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 
+-      0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 
+-      0x16, 0x16, 0x16, 0x16, 0x0a, 0x12, 0x13, 0x10, 
+-      0x17, 0x10, 0x15, 0x10, 0x08, 0x09, 0x0a, 0x10, 
+-      0x10, 0x1a, 0x13, 0x06, 0x0a, 0x0a, 0x0b, 0x11, 
+-      0x08, 0x0a, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 
+-      0x11, 0x11, 0x11, 0x10, 0x1d, 0x13, 0x13, 0x15, 
+-      0x15, 0x13, 0x12, 0x17, 0x15, 0x07, 0x0f, 0x13, 
+-      0x10, 0x17, 0x15, 0x17, 0x13, 0x17, 0x15, 0x13, 
+-      0x13, 0x15, 0x13, 0x1e, 0x13, 0x13, 0x12, 0x08, 
+-      0x08, 0x08, 0x0e, 0x10, 0x0a, 0x10, 0x10, 0x0f, 
+-      0x10, 0x10, 0x08, 0x10, 0x10, 0x07, 0x07, 0x0e, 
+-      0x07, 0x19, 0x10, 0x10, 0x10, 0x10, 0x0a, 0x0f, 
+-      0x08, 0x10, 0x0d, 0x15, 0x0d, 0x0d, 0x0e, 0x0a, 
+-      0x08, 0x0a, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0xc7, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x8e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0xc7, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x8e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0xc7, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x8e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0xf8, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 
+-      0x0e, 0x38, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1e, 0x1c, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x0f, 0xff, 0xe0, 0x00, 
+-      0x0e, 0x38, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3c, 0x0c, 0x00, 0x00, 0x03, 0xb8, 0x00, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x1f, 0x83, 0xf0, 0x00, 
+-      0x0e, 0x38, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x07, 0xbc, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf8, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x78, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 
+-      0x0f, 0xf0, 0x00, 0x00, 0x78, 0x00, 0x3c, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x0f, 0x1e, 0x00, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0x78, 0x00, 0x3c, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x70, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 
+-      0x3c, 0x7c, 0x00, 0x00, 0x70, 0x00, 0x1c, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x70, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x70, 0x00, 0x1c, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x70, 0x00, 0x00, 0x1e, 0x0f, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x70, 0x00, 0x1c, 0x00, 
+-      0x78, 0x1e, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x78, 0x00, 0x00, 0x1c, 0x07, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x70, 0x00, 0x1c, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x7f, 0x80, 0x00, 0x00, 
+-      0x38, 0x3e, 0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 
+-      0x00, 0xfc, 0x00, 0x00, 0x70, 0x00, 0x1c, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x7f, 0x80, 0x00, 0x00, 
+-      0x38, 0x1f, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x1f, 0xfc, 0x00, 0x00, 0x78, 0x00, 0x3c, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x7f, 0x80, 0x00, 0x00, 
+-      0x38, 0x07, 0x80, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x3f, 0x9c, 0x00, 0x00, 0x78, 0x00, 0x3c, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x38, 0x03, 0x80, 0x00, 
+-      0x78, 0x1c, 0x00, 0x00, 0x3c, 0x00, 0x78, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x3c, 0x01, 0xe0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x78, 0x03, 0xc0, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x1e, 0x00, 0xf8, 0x00, 
+-      0x78, 0x1e, 0x00, 0x00, 0x3c, 0x01, 0xe0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x39, 0xc3, 0x80, 0x00, 0x70, 0x01, 0xc0, 0x00, 
+-      0x70, 0x3c, 0x00, 0x00, 0x1f, 0x83, 0xf0, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x1f, 0x07, 0xc0, 0x00, 
+-      0x38, 0x3c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x39, 0xe7, 0x00, 0x00, 0x70, 0x01, 0xc0, 0x00, 
+-      0x78, 0x7c, 0x00, 0x00, 0x0f, 0xff, 0xe0, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x0f, 0xff, 0x80, 0x00, 
+-      0x3c, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0xff, 0x00, 0x00, 0xe0, 0x01, 0xe0, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 
+-      0x1f, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x7c, 0x00, 0x00, 0xe0, 0x00, 0xe0, 0x00, 
+-      0x1f, 0x8e, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 
+-      0x0f, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x73, 0x80, 0x00, 0x00, 
+-      0x07, 0x1c, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 
+-      0x0f, 0x80, 0x60, 0x00, 0x03, 0xe0, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 
+-      0xe0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x73, 0x80, 0x00, 0x00, 
+-      0x07, 0x1c, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 
+-      0x1f, 0xc0, 0xe0, 0x00, 0x07, 0xf0, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x73, 0x80, 0x00, 0x00, 
+-      0x0f, 0x3c, 0x00, 0x00, 0x3d, 0xb8, 0x00, 0x00, 
+-      0x38, 0xe0, 0xc0, 0x00, 0x0f, 0x78, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x76, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x73, 0x80, 0x00, 0x00, 
+-      0x0e, 0x38, 0x00, 0x00, 0x79, 0xbc, 0x00, 0x00, 
+-      0x30, 0x61, 0xc0, 0x00, 0x0e, 0x38, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x73, 0x80, 0x00, 0x00, 
+-      0x0e, 0x38, 0x00, 0x00, 0x71, 0x9c, 0x00, 0x00, 
+-      0x30, 0x61, 0x80, 0x00, 0x0e, 0x38, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x73, 0x80, 0x00, 0x00, 
+-      0xff, 0xfe, 0x00, 0x00, 0x71, 0x80, 0x00, 0x00, 
+-      0x30, 0x63, 0x80, 0x00, 0x0e, 0x38, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x73, 0x80, 0x00, 0x00, 
+-      0xff, 0xfe, 0x00, 0x00, 0x79, 0x80, 0x00, 0x00, 
+-      0x30, 0x63, 0x00, 0x00, 0x0f, 0x78, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xff, 0xfe, 0x00, 0x00, 0x7d, 0x80, 0x00, 0x00, 
+-      0x30, 0x67, 0x00, 0x00, 0x07, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x39, 0xc0, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1e, 0x78, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 
+-      0x38, 0xe6, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x19, 0x80, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 
+-      0x1f, 0xce, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 
+-      0x0f, 0x8c, 0x7c, 0x00, 0x1f, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x70, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 
+-      0x00, 0x1c, 0xfe, 0x00, 0x3e, 0xe2, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3c, 0xf0, 0x00, 0x00, 0x01, 0xbe, 0x00, 0x00, 
+-      0x00, 0x19, 0xc7, 0x00, 0x38, 0x73, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xff, 0xfe, 0x00, 0x00, 0x01, 0x9e, 0x00, 0x00, 
+-      0x00, 0x39, 0x83, 0x00, 0x78, 0x3f, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xff, 0xfe, 0x00, 0x00, 0x01, 0x8e, 0x00, 0x00, 
+-      0x00, 0x31, 0x83, 0x00, 0x70, 0x3f, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xff, 0xfe, 0x00, 0x00, 0x71, 0x8e, 0x00, 0x00, 
+-      0x00, 0x71, 0x83, 0x00, 0x70, 0x1f, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0xe0, 0x00, 0x00, 0x71, 0x8e, 0x00, 0x00, 
+-      0x00, 0x61, 0x83, 0x00, 0x70, 0x0f, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0xe0, 0x00, 0x00, 0x79, 0x9e, 0x00, 0x00, 
+-      0x00, 0xe1, 0x83, 0x00, 0x78, 0x1f, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x79, 0xe0, 0x00, 0x00, 0x3d, 0xbc, 0x00, 0x00, 
+-      0x00, 0xc1, 0xc7, 0x00, 0x3c, 0x7f, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x71, 0xc0, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 
+-      0x01, 0xc0, 0xfe, 0x00, 0x1f, 0xfb, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x71, 0xc0, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 
+-      0x01, 0x80, 0x7c, 0x00, 0x0f, 0xe1, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 
+-      0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 
+-      0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 
+-      0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 
+-      0x00, 0x60, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 
+-      0x0f, 0xe0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x1f, 0xfc, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 
+-      0x3f, 0xfe, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0xf0, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 
+-      0x1f, 0xf0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x1f, 0xfc, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 
+-      0x3f, 0xfe, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 
+-      0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 
+-      0x01, 0xe0, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 
+-      0x3f, 0xfe, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 
+-      0x03, 0xe0, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 
+-      0x7c, 0x7c, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x1e, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x0f, 0xe0, 0x00, 0x00, 0x78, 0x3c, 0x00, 0x00, 
+-      0x70, 0x3c, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x78, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x78, 0x0e, 0x00, 0x00, 0x78, 0x1e, 0x00, 0x00, 
+-      0x1e, 0xe0, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x1c, 0xe0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x03, 0xb8, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x00, 0x78, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 
+-      0x7f, 0xfe, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x10, 0xe0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x3c, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 
+-      0x7b, 0xe0, 0x00, 0x00, 0x73, 0xf0, 0x00, 0x00, 
+-      0x00, 0x70, 0x00, 0x00, 0x1c, 0x38, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 
+-      0x7f, 0xfe, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 
+-      0x00, 0x1e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 
+-      0x00, 0x78, 0x00, 0x00, 0x0f, 0x38, 0x00, 0x00, 
+-      0x7f, 0xf8, 0x00, 0x00, 0x77, 0xf8, 0x00, 0x00, 
+-      0x00, 0xf0, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 
+-      0x7f, 0xfe, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 
+-      0x00, 0x3c, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x03, 0xf0, 0x00, 0x00, 0x0e, 0x38, 0x00, 0x00, 
+-      0x7f, 0xfc, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 
+-      0x78, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 
+-      0x00, 0x78, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x1c, 0x38, 0x00, 0x00, 
+-      0x78, 0x3c, 0x00, 0x00, 0x7c, 0x3e, 0x00, 0x00, 
+-      0x01, 0xe0, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 
+-      0x3c, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 
+-      0x00, 0xf0, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 
+-      0x00, 0x3c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 
+-      0x00, 0x1e, 0x00, 0x00, 0x78, 0x1e, 0x00, 0x00, 
+-      0x01, 0xc0, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 
+-      0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 
+-      0x01, 0xe0, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 
+-      0x00, 0x1e, 0x00, 0x00, 0x78, 0x38, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x01, 0xc0, 0x00, 0x00, 0x78, 0x1e, 0x00, 0x00, 
+-      0x1f, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 
+-      0x7f, 0xfe, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 
+-      0x03, 0xc0, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x03, 0xc0, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x0f, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 
+-      0x7f, 0xfe, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 
+-      0x7f, 0xfe, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x78, 0x1e, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x78, 0x0e, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x70, 0x0e, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x78, 0x1e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x78, 0x1e, 0x00, 0x00, 0x38, 0x1e, 0x00, 0x00, 
+-      0x07, 0x80, 0x00, 0x00, 0x78, 0x1e, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 
+-      0x07, 0x80, 0x00, 0x00, 0x7c, 0x3e, 0x00, 0x00, 
+-      0x78, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 
+-      0x3f, 0xf8, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 
+-      0x1f, 0xf0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 
+-      0x0f, 0xc0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, 
+-      0x01, 0xf0, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 
+-      0x01, 0xfe, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x3f, 0xff, 0x80, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x00, 0xff, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x38, 0x01, 0xe0, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x7c, 0x00, 0x7c, 0x00, 0x3c, 0x00, 0xe0, 0x00, 
+-      0x01, 0xff, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 
+-      0x07, 0xff, 0x80, 0x00, 0x3f, 0xff, 0x00, 0x00, 
+-      0x3f, 0xff, 0x80, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x07, 0xff, 0xc0, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x38, 0x03, 0xc0, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x7c, 0x00, 0x7c, 0x00, 0x3c, 0x00, 0xe0, 0x00, 
+-      0x07, 0xff, 0x80, 0x00, 0x01, 0xff, 0xff, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 
+-      0x3f, 0xff, 0x80, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x0f, 0xff, 0xe0, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x38, 0x07, 0x80, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x7e, 0x00, 0xfc, 0x00, 0x3e, 0x00, 0xe0, 0x00, 
+-      0x0f, 0xff, 0xe0, 0x00, 0x03, 0xf8, 0x3f, 0x80, 
+-      0x03, 0xb8, 0x00, 0x00, 0x38, 0x0f, 0x80, 0x00, 
+-      0x1f, 0x83, 0xe0, 0x00, 0x38, 0x07, 0xc0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x1f, 0x83, 0xf0, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x38, 0x0f, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x7e, 0x00, 0xfc, 0x00, 0x3f, 0x00, 0xe0, 0x00, 
+-      0x1f, 0x83, 0xf0, 0x00, 0x07, 0xc0, 0x07, 0xc0, 
+-      0x07, 0xbc, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 
+-      0x3e, 0x01, 0xe0, 0x00, 0x38, 0x01, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3e, 0x00, 0xf0, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x38, 0x1e, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x7f, 0x01, 0xfc, 0x00, 0x3f, 0x00, 0xe0, 0x00, 
+-      0x3e, 0x00, 0xf8, 0x00, 0x07, 0x80, 0x03, 0xe0, 
+-      0x07, 0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 
+-      0x3c, 0x00, 0xf0, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3c, 0x00, 0x78, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x38, 0x3c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x77, 0x01, 0xdc, 0x00, 0x3b, 0x80, 0xe0, 0x00, 
+-      0x3c, 0x00, 0x78, 0x00, 0x0f, 0x0f, 0x1d, 0xe0, 
+-      0x07, 0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 
+-      0x78, 0x00, 0x70, 0x00, 0x38, 0x00, 0xf0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x30, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x38, 0x78, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x77, 0x01, 0xdc, 0x00, 0x3b, 0xc0, 0xe0, 0x00, 
+-      0x78, 0x00, 0x3c, 0x00, 0x1e, 0x3f, 0xbc, 0xf0, 
+-      0x0f, 0x1e, 0x00, 0x00, 0x38, 0x0f, 0x00, 0x00, 
+-      0x78, 0x00, 0x00, 0x00, 0x38, 0x00, 0x70, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x78, 0x00, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x38, 0xf0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x77, 0x83, 0xdc, 0x00, 0x39, 0xc0, 0xe0, 0x00, 
+-      0x78, 0x00, 0x3c, 0x00, 0x1e, 0x7f, 0xfc, 0xf0, 
+-      0x0e, 0x0e, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x70, 0x00, 
+-      0x3f, 0xff, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x39, 0xe0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x73, 0x83, 0x9c, 0x00, 0x38, 0xe0, 0xe0, 0x00, 
+-      0x70, 0x00, 0x1c, 0x00, 0x1c, 0xf9, 0xf8, 0x70, 
+-      0x0e, 0x0e, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x70, 0x00, 
+-      0x3f, 0xff, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x3b, 0xe0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x73, 0x83, 0x9c, 0x00, 0x38, 0xe0, 0xe0, 0x00, 
+-      0x70, 0x00, 0x1c, 0x00, 0x3c, 0xf0, 0xf8, 0x70, 
+-      0x1e, 0x0f, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x70, 0x00, 
+-      0x3f, 0xff, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x70, 0x0f, 0xf8, 0x00, 0x3f, 0xff, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x73, 0xc7, 0x9c, 0x00, 0x38, 0x70, 0xe0, 0x00, 
+-      0x70, 0x00, 0x1c, 0x00, 0x39, 0xe0, 0x78, 0x70, 
+-      0x1c, 0x07, 0x00, 0x00, 0x38, 0x07, 0x80, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x70, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0x0f, 0xf8, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x71, 0xc7, 0x1c, 0x00, 0x38, 0x38, 0xe0, 0x00, 
+-      0x70, 0x00, 0x1c, 0x00, 0x39, 0xe0, 0x78, 0x70, 
+-      0x1f, 0xff, 0x00, 0x00, 0x38, 0x03, 0xc0, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x70, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0x0f, 0xf8, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x3e, 0x78, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x71, 0xc7, 0x1c, 0x00, 0x38, 0x38, 0xe0, 0x00, 
+-      0x70, 0x00, 0x1c, 0x00, 0x39, 0xc0, 0x70, 0x70, 
+-      0x3f, 0xff, 0x80, 0x00, 0x38, 0x01, 0xc0, 0x00, 
+-      0x78, 0x00, 0x60, 0x00, 0x38, 0x00, 0xf0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x78, 0x00, 0x38, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x71, 0xef, 0x1c, 0x00, 0x38, 0x1c, 0xe0, 0x00, 
+-      0x78, 0x00, 0x3c, 0x00, 0x39, 0xc0, 0xf0, 0xf0, 
+-      0x3f, 0xff, 0x80, 0x00, 0x38, 0x01, 0xc0, 0x00, 
+-      0x78, 0x00, 0xf0, 0x00, 0x38, 0x00, 0xf0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x78, 0x00, 0x38, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x70, 0x38, 0x00, 0x00, 
+-      0x38, 0x3e, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0xee, 0x1c, 0x00, 0x38, 0x1e, 0xe0, 0x00, 
+-      0x78, 0x00, 0x3c, 0x00, 0x39, 0xc0, 0xf0, 0xe0, 
+-      0x38, 0x03, 0x80, 0x00, 0x38, 0x01, 0xc0, 0x00, 
+-      0x3c, 0x00, 0xf0, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3c, 0x00, 0x38, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x70, 0x38, 0x00, 0x00, 
+-      0x38, 0x1e, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0xee, 0x1c, 0x00, 0x38, 0x0e, 0xe0, 0x00, 
+-      0x3c, 0x00, 0x78, 0x00, 0x39, 0xe1, 0xe1, 0xc0, 
+-      0x78, 0x03, 0xc0, 0x00, 0x38, 0x03, 0xc0, 0x00, 
+-      0x3e, 0x01, 0xe0, 0x00, 0x38, 0x01, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3e, 0x00, 0x78, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, 
+-      0x38, 0x0f, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0xfe, 0x1c, 0x00, 0x38, 0x07, 0xe0, 0x00, 
+-      0x1e, 0x00, 0xf8, 0x00, 0x3d, 0xe3, 0xe3, 0xc0, 
+-      0x70, 0x01, 0xc0, 0x00, 0x38, 0x07, 0xc0, 0x00, 
+-      0x1f, 0x87, 0xe0, 0x00, 0x38, 0x07, 0xc0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x1f, 0x81, 0xf8, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x7c, 0xf8, 0x00, 0x00, 
+-      0x38, 0x07, 0x80, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0x7c, 0x1c, 0x00, 0x38, 0x07, 0xe0, 0x00, 
+-      0x1f, 0x83, 0xf0, 0x00, 0x3c, 0xff, 0xe7, 0x80, 
+-      0x70, 0x01, 0xc0, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x3f, 0xff, 0x80, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x0f, 0xff, 0xf0, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 
+-      0x38, 0x07, 0x80, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x70, 0x7c, 0x1c, 0x00, 0x38, 0x03, 0xe0, 0x00, 
+-      0x0f, 0xff, 0xe0, 0x00, 0x1e, 0xfe, 0xff, 0x00, 
+-      0xe0, 0x01, 0xe0, 0x00, 0x3f, 0xff, 0x00, 0x00, 
+-      0x07, 0xff, 0x80, 0x00, 0x3f, 0xff, 0x00, 0x00, 
+-      0x3f, 0xff, 0x80, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x03, 0xff, 0xe0, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 
+-      0x38, 0x03, 0xc0, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x70, 0x7c, 0x1c, 0x00, 0x38, 0x01, 0xe0, 0x00, 
+-      0x03, 0xff, 0xc0, 0x00, 0x1e, 0x3c, 0x7c, 0x78, 
+-      0xe0, 0x00, 0xe0, 0x00, 0x3f, 0xfc, 0x00, 0x00, 
+-      0x01, 0xfe, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 
+-      0x3f, 0xff, 0x80, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0xff, 0x00, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 
+-      0x38, 0x01, 0xe0, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x70, 0x38, 0x1c, 0x00, 0x38, 0x01, 0xe0, 0x00, 
+-      0x00, 0xfe, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x01, 0xf0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x0f, 0xe0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x01, 0xff, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 
+-      0xe0, 0x0f, 0x80, 0x38, 0x78, 0x03, 0xc0, 0x00, 
+-      0xf0, 0x01, 0xe0, 0x00, 0x7f, 0xff, 0x00, 0x00, 
+-      0x3f, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 
+-      0xfc, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 
+-      0x07, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x0f, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0xf0, 0x01, 0xe0, 0x00, 
+-      0xf0, 0x0f, 0x80, 0x78, 0x3c, 0x07, 0x80, 0x00, 
+-      0x70, 0x03, 0xc0, 0x00, 0x7f, 0xff, 0x00, 0x00, 
+-      0x3f, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 
+-      0xfc, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x0f, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 
+-      0x1f, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x70, 0x01, 0xc0, 0x00, 
+-      0xf0, 0x1f, 0xc0, 0x78, 0x1c, 0x07, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x7f, 0xff, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x07, 0xc0, 0x00, 
+-      0x1f, 0x83, 0xf0, 0x00, 0x38, 0x03, 0xe0, 0x00, 
+-      0x3e, 0x0f, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x70, 0x01, 0xc0, 0x00, 
+-      0x70, 0x1f, 0xc0, 0x70, 0x1e, 0x0f, 0x00, 0x00, 
+-      0x3c, 0x07, 0x80, 0x00, 0x00, 0x0f, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x03, 0xc0, 0x00, 
+-      0x1e, 0x00, 0xf8, 0x00, 0x38, 0x01, 0xe0, 0x00, 
+-      0x3c, 0x07, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x78, 0x03, 0xc0, 0x00, 
+-      0x70, 0x1d, 0xc0, 0x70, 0x0f, 0x1e, 0x00, 0x00, 
+-      0x1e, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x01, 0xc0, 0x00, 
+-      0x3c, 0x00, 0x78, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x38, 0x03, 0x80, 0x00, 
+-      0x78, 0x1d, 0xc0, 0xf0, 0x07, 0xbc, 0x00, 0x00, 
+-      0x0e, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x1c, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x01, 0xc0, 0x00, 
+-      0x38, 0x00, 0x3c, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x38, 0x07, 0x80, 0x00, 
+-      0x78, 0x3d, 0xe0, 0xf0, 0x07, 0xbc, 0x00, 0x00, 
+-      0x0f, 0x1e, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x1c, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x01, 0xc0, 0x00, 
+-      0x78, 0x00, 0x3c, 0x00, 0x38, 0x01, 0xe0, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x3c, 0x07, 0x80, 0x00, 
+-      0x38, 0x38, 0xe0, 0xe0, 0x03, 0xf8, 0x00, 0x00, 
+-      0x07, 0x1c, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x38, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x03, 0xc0, 0x00, 
+-      0x70, 0x00, 0x1c, 0x00, 0x38, 0x03, 0xe0, 0x00, 
+-      0x1f, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x1c, 0x07, 0x00, 0x00, 
+-      0x38, 0x38, 0xe0, 0xe0, 0x01, 0xf0, 0x00, 0x00, 
+-      0x07, 0xbc, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x38, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x07, 0xc0, 0x00, 
+-      0x70, 0x00, 0x1c, 0x00, 0x3f, 0xff, 0xc0, 0x00, 
+-      0x0f, 0xf8, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x1e, 0x0f, 0x00, 0x00, 
+-      0x3c, 0x38, 0xe1, 0xe0, 0x00, 0xe0, 0x00, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x70, 0x00, 0x1c, 0x00, 0x3f, 0xff, 0x80, 0x00, 
+-      0x03, 0xfe, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x1e, 0x0f, 0x00, 0x00, 
+-      0x3c, 0x78, 0xf1, 0xe0, 0x01, 0xf0, 0x00, 0x00, 
+-      0x01, 0xf0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x70, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 
+-      0x70, 0x00, 0x1c, 0x00, 0x3f, 0xff, 0x00, 0x00, 
+-      0x00, 0x7f, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x0e, 0x0e, 0x00, 0x00, 
+-      0x1c, 0x70, 0x71, 0xc0, 0x01, 0xf0, 0x00, 0x00, 
+-      0x01, 0xf0, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x70, 0x00, 0x1c, 0x00, 0x38, 0x3c, 0x00, 0x00, 
+-      0x00, 0x07, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x0f, 0x1e, 0x00, 0x00, 
+-      0x1c, 0x70, 0x71, 0xc0, 0x03, 0xb8, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x78, 0x00, 0x3c, 0x00, 0x38, 0x1e, 0x00, 0x00, 
+-      0x00, 0x03, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x07, 0x1c, 0x00, 0x00, 
+-      0x1e, 0x70, 0x73, 0xc0, 0x07, 0xbc, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x78, 0x08, 0x38, 0x00, 0x38, 0x0f, 0x00, 0x00, 
+-      0x70, 0x03, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x38, 0x00, 0xe0, 0x00, 0x07, 0x1c, 0x00, 0x00, 
+-      0x1e, 0xf0, 0x7b, 0xc0, 0x0f, 0x1e, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3c, 0x0e, 0x78, 0x00, 0x38, 0x07, 0x80, 0x00, 
+-      0x78, 0x03, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x3c, 0x01, 0xe0, 0x00, 0x07, 0xbc, 0x00, 0x00, 
+-      0x0e, 0xe0, 0x3b, 0x80, 0x0f, 0x1e, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x1e, 0x0f, 0xf0, 0x00, 0x38, 0x03, 0x80, 0x00, 
+-      0x78, 0x07, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x3c, 0x01, 0xe0, 0x00, 0x03, 0xb8, 0x00, 0x00, 
+-      0x0e, 0xe0, 0x3b, 0x80, 0x1e, 0x0f, 0x00, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x1f, 0x83, 0xe0, 0x00, 0x38, 0x03, 0xc0, 0x00, 
+-      0x3e, 0x0f, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x1f, 0x07, 0xc0, 0x00, 0x03, 0xf8, 0x00, 0x00, 
+-      0x0f, 0xe0, 0x3f, 0x80, 0x3c, 0x07, 0x80, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x0f, 0xff, 0xf0, 0x00, 0x38, 0x01, 0xe0, 0x00, 
+-      0x1f, 0xff, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x0f, 0xff, 0x80, 0x00, 0x03, 0xf8, 0x00, 0x00, 
+-      0x0f, 0xe0, 0x3f, 0x80, 0x38, 0x03, 0x80, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0xff, 0xff, 0x80, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x03, 0xff, 0xf8, 0x00, 0x38, 0x00, 0xe0, 0x00, 
+-      0x0f, 0xfe, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x07, 0xff, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 
+-      0x07, 0xc0, 0x1f, 0x00, 0x78, 0x03, 0xc0, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0xff, 0xff, 0x80, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x01, 0xff, 0x3c, 0x00, 0x38, 0x00, 0xf0, 0x00, 
+-      0x07, 0xf8, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 
+-      0x03, 0xfe, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 
+-      0x07, 0xc0, 0x1f, 0x00, 0xf0, 0x01, 0xe0, 0x00, 
+-      0x00, 0xe0, 0x00, 0x00, 0xff, 0xff, 0x80, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+-      0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+-      0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0xf0, 0x00, 0x00, 0x39, 0xf0, 0x00, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0x0f, 0x9c, 0x00, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 
+-      0x0f, 0x9c, 0x00, 0x00, 0x39, 0xf0, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x3c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x39, 0xf0, 0xf8, 0x00, 0x39, 0xf0, 0x00, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 
+-      0x1f, 0xf0, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 
+-      0x1f, 0xfc, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x78, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3f, 0xfb, 0xfc, 0x00, 0x3f, 0xf8, 0x00, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3c, 0x7c, 0x00, 0x00, 0x3e, 0x3c, 0x00, 0x00, 
+-      0x3c, 0x78, 0x00, 0x00, 0x3c, 0x7c, 0x00, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3c, 0x7c, 0x00, 0x00, 0x3e, 0x3c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0xf0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3e, 0x3f, 0x1e, 0x00, 0x3e, 0x3c, 0x00, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x3c, 0x1c, 0x00, 0x00, 
+-      0x38, 0x3c, 0x00, 0x00, 0x38, 0x3c, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x3c, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x39, 0xe0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3c, 0x1e, 0x0e, 0x00, 0x3c, 0x1c, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x1e, 0x00, 0x00, 
+-      0x78, 0x1c, 0x00, 0x00, 0x78, 0x3c, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x78, 0x1c, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3b, 0xc0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x0e, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x78, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3f, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x0e, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0xfc, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x00, 
+-      0x7f, 0xfe, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3f, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x0e, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xfc, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x00, 
+-      0x7f, 0xfe, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3f, 0xc0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x0e, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3f, 0x9c, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3b, 0xc0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x0e, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x78, 0x1c, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x39, 0xe0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x0e, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x70, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x3c, 0x1e, 0x00, 0x00, 
+-      0x78, 0x1c, 0x00, 0x00, 0x78, 0x3c, 0x00, 0x00, 
+-      0x78, 0x0e, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x78, 0x3c, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0xf0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x0e, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x78, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x3c, 0x00, 0x00, 0x3c, 0x1c, 0x00, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x38, 0x3c, 0x00, 0x00, 
+-      0x38, 0x1e, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x3c, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0xf0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x0e, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x78, 0x7c, 0x00, 0x00, 0x3e, 0x3c, 0x00, 0x00, 
+-      0x3c, 0x78, 0x00, 0x00, 0x3c, 0x7c, 0x00, 0x00, 
+-      0x3e, 0x3c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3c, 0x7c, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x78, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x0e, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3f, 0xfc, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 
+-      0x1f, 0xf0, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x1f, 0xfc, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x0e, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0x8e, 0x00, 0x00, 0x39, 0xf0, 0x00, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0x0f, 0x9c, 0x00, 0x00, 
+-      0x07, 0xf0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x0f, 0x9c, 0x00, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x3c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x0e, 0x00, 0x38, 0x1c, 0x00, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x78, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x7c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0xc0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0xc0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0xc0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x39, 0xf0, 0x00, 0x00, 
+-      0x0f, 0x9c, 0x00, 0x00, 0x3b, 0xc0, 0x00, 0x00, 
+-      0x1f, 0xe0, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0xe0, 0x38, 0x00, 0x01, 
+-      0xe0, 0x70, 0x3c, 0x00, 0xe0, 0x38, 0x00, 0x00, 
+-      0xe0, 0x38, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x3f, 0xf8, 0x00, 0x00, 
+-      0x1f, 0xfc, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x3f, 0xf0, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0xf0, 0x78, 0x00, 0x00, 
+-      0xe0, 0x70, 0x38, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0xf0, 0x78, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x3e, 0x3c, 0x00, 0x00, 
+-      0x3c, 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 
+-      0x78, 0x78, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0xe0, 0xf8, 0x38, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x70, 0x70, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x1f, 0x01, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x3c, 0x1c, 0x00, 0x00, 
+-      0x38, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x70, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0xe0, 0xf8, 0x38, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x70, 0x70, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x7f, 0xe3, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x38, 0x1e, 0x00, 0x00, 
+-      0x78, 0x3c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x70, 0xd8, 0x70, 0x00, 0x1d, 0xc0, 0x00, 0x00, 
+-      0x78, 0xf0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x7c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x71, 0xdc, 0x70, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x38, 0xe0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 
+-      0x1e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1e, 0x00, 0x00, 0x00, 0x61, 0xff, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3f, 0xc0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x71, 0x8c, 0x70, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x38, 0xe0, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x0f, 0x00, 0x00, 0x00, 0x40, 0x7c, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x1f, 0xf0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x31, 0x8c, 0x60, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x39, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x78, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x1d, 0xc0, 0x00, 0x00, 
+-      0x33, 0x8e, 0xe0, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x1d, 0xc0, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x78, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x38, 0x0e, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x3c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x1d, 0xc0, 0x00, 0x00, 
+-      0x3b, 0x06, 0xe0, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x1d, 0xc0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x3c, 0x1e, 0x00, 0x00, 
+-      0x78, 0x3c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x70, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x0d, 0x80, 0x00, 0x00, 
+-      0x1b, 0x06, 0xe0, 0x00, 0x1d, 0xc0, 0x00, 0x00, 
+-      0x1f, 0xc0, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x1e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x3c, 0x1c, 0x00, 0x00, 
+-      0x38, 0x3c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x78, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x38, 0x3c, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x1f, 0x07, 0xc0, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x3e, 0x3c, 0x00, 0x00, 
+-      0x3c, 0x7c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x3c, 0x7c, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 
+-      0x1e, 0x07, 0xc0, 0x00, 0x38, 0xe0, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x3f, 0xf8, 0x00, 0x00, 
+-      0x1f, 0xfc, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x1f, 0xf8, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 
+-      0x1f, 0xfc, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x1e, 0x03, 0xc0, 0x00, 0x70, 0x70, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x40, 0x00, 0x39, 0xe0, 0x00, 0x00, 
+-      0x07, 0x9c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x0f, 0xe0, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 
+-      0x0f, 0x9c, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x0e, 0x03, 0x80, 0x00, 0xe0, 0x38, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0xff, 0xc0, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0xc0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0xc0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0xc0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 
+-      0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 
+-      0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 
+-      0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 
+-      0x0b, 0x15, 0x17, 0x13, 0x1a, 0x13, 0x19, 0x13, 
+-      0x09, 0x0b, 0x0c, 0x13, 0x13, 0x1e, 0x17, 0x06, 
+-      0x0b, 0x0b, 0x0d, 0x14, 0x09, 0x0b, 0x09, 0x09, 
+-      0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 
+-      0x13, 0x13, 0x09, 0x09, 0x14, 0x14, 0x14, 0x13, 
+-      0x23, 0x17, 0x17, 0x19, 0x19, 0x17, 0x15, 0x1a, 
+-      0x19, 0x09, 0x11, 0x17, 0x13, 0x1d, 0x19, 0x1a, 
+-      0x17, 0x1a, 0x19, 0x17, 0x15, 0x19, 0x17, 0x22, 
+-      0x17, 0x15, 0x15, 0x09, 0x09, 0x09, 0x11, 0x13, 
+-      0x0b, 0x12, 0x12, 0x11, 0x12, 0x12, 0x0a, 0x12, 
+-      0x13, 0x07, 0x07, 0x11, 0x07, 0x1b, 0x13, 0x12, 
+-      0x12, 0x12, 0x0b, 0x11, 0x09, 0x13, 0x11, 0x17, 
+-      0x10, 0x11, 0x10, 0x0b, 0x09, 0x0b, 0x14, 0x1a, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 
+-      0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 
+-      0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 
+-      0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 
+-      0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 
+-      0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 
+-      0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 
+-      0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 
+-      0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 
+-      0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 
+-      0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 
+-      0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 
+-      0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 
+-      0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 
+-      0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 
+-      0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 
+-      0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 
+-      0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 
+-      0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x01, 0xc7, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 
+-      0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x01, 0xc7, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 
+-      0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x01, 0xc7, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 
+-      0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x00, 
+-      0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 
+-      0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfe, 0x00, 
+-      0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x07, 
+-      0x1c, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 
+-      0x00, 0x07, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0x00, 
+-      0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 
+-      0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 
+-      0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 
+-      0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 
+-      0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0x00, 
+-      0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x07, 
+-      0x1c, 0x00, 0x00, 0x00, 0x07, 0xe1, 0xf8, 0x00, 
+-      0x00, 0x07, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x07, 0x00, 
+-      0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x07, 
+-      0x1c, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x7c, 0x00, 
+-      0x00, 0x07, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x07, 0x00, 
+-      0x00, 0x00, 0x01, 0xef, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1e, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x07, 0x00, 
+-      0x00, 0x00, 0x01, 0xc7, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1e, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x07, 0x00, 
+-      0x00, 0x00, 0x03, 0xc7, 0x80, 0x00, 0x00, 0x0f, 
+-      0xf8, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 
+-      0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0e, 0x00, 
+-      0x00, 0x00, 0x03, 0xc7, 0x80, 0x00, 0x00, 0x1f, 
+-      0xfe, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x0f, 0x00, 
+-      0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0e, 0x00, 
+-      0x00, 0x00, 0x03, 0x83, 0x80, 0x00, 0x00, 0x3f, 
+-      0xff, 0x00, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 
+-      0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 
+-      0x00, 0x00, 0x07, 0x83, 0xc0, 0x00, 0x00, 0x78, 
+-      0x1f, 0x00, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 
+-      0x00, 0x3e, 0x1f, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 
+-      0x00, 0x00, 0x07, 0x01, 0xc0, 0x00, 0x00, 0x70, 
+-      0x07, 0x00, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 
+-      0x00, 0x3c, 0x0f, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 
+-      0x00, 0x00, 0x0f, 0x01, 0xe0, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 
+-      0x00, 0x78, 0x07, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1f, 0x00, 
+-      0x00, 0x00, 0x0f, 0x01, 0xe0, 0x00, 0x00, 0x00, 
+-      0x3f, 0x00, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 
+-      0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0f, 0x80, 
+-      0x00, 0x00, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x07, 
+-      0xff, 0x00, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 
+-      0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x7f, 0xc0, 0x00, 0x00, 0x00, 0x1c, 0x07, 0xc0, 
+-      0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x1f, 
+-      0xff, 0x00, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 
+-      0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x7f, 0xc0, 0x00, 0x00, 0x00, 0x1c, 0x01, 0xe0, 
+-      0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x3f, 
+-      0xf7, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x0f, 0x00, 
+-      0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x7f, 0xc0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xf0, 
+-      0x00, 0x00, 0x1c, 0x00, 0x70, 0x00, 0x00, 0x7c, 
+-      0x07, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 
+-      0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x1c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x70, 
+-      0x00, 0x00, 0x3c, 0x00, 0x78, 0x00, 0x00, 0x70, 
+-      0x07, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1e, 0x00, 
+-      0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 0x1e, 0x00, 
+-      0x3c, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x70, 
+-      0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0x00, 0x70, 
+-      0x0f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1e, 0x00, 
+-      0x00, 0x78, 0x07, 0x80, 0x00, 0x00, 0x1e, 0x00, 
+-      0x3c, 0x00, 0x00, 0x38, 0x07, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xf0, 0xf0, 
+-      0x00, 0x00, 0x78, 0x00, 0x3c, 0x00, 0x00, 0x70, 
+-      0x1f, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x7c, 0x00, 
+-      0x00, 0x3c, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 
+-      0x78, 0x00, 0x00, 0x3c, 0x07, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xf9, 0xf0, 
+-      0x00, 0x00, 0x78, 0x00, 0x3c, 0x00, 0x00, 0x7c, 
+-      0x3f, 0x00, 0x00, 0x00, 0x07, 0xe1, 0xf8, 0x00, 
+-      0x00, 0x3e, 0x1f, 0x00, 0x00, 0x00, 0x0f, 0xc1, 
+-      0xf8, 0x00, 0x00, 0x3e, 0x1f, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x7f, 0xe0, 
+-      0x00, 0x00, 0x70, 0x00, 0x1c, 0x00, 0x00, 0x3f, 
+-      0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 
+-      0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 
+-      0xf0, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 
+-      0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 
+-      0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 
+-      0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 
+-      0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 
+-      0x04, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x3f, 0xc0, 
+-      0x00, 0x00, 0xf0, 0x00, 0x1e, 0x00, 0x00, 0x3f, 
+-      0xf7, 0x80, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 
+-      0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 
+-      0xe0, 0x00, 0x00, 0x1f, 0xfb, 0x80, 0x00, 0x00, 
+-      0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 
+-      0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 
+-      0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 
+-      0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x0f, 0xff, 
+-      0xfc, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1f, 0x80, 
+-      0x00, 0x00, 0xe0, 0x00, 0x0e, 0x00, 0x00, 0x0f, 
+-      0xe3, 0x80, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 
+-      0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 
+-      0x80, 0x00, 0x00, 0x07, 0xe3, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x00, 0x01, 
+-      0xc3, 0x80, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 
+-      0x00, 0x07, 0xc0, 0x0e, 0x00, 0x00, 0x00, 0xf8, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x00, 0x01, 
+-      0xc7, 0x80, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 
+-      0x00, 0x1f, 0xe0, 0x1e, 0x00, 0x00, 0x01, 0xfe, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x00, 0x03, 
+-      0xc7, 0x80, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 
+-      0x00, 0x1c, 0x70, 0x1c, 0x00, 0x00, 0x03, 0xfe, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x00, 0x03, 
+-      0xc7, 0x00, 0x00, 0x00, 0x3e, 0xde, 0x00, 0x00, 
+-      0x00, 0x3c, 0x78, 0x3c, 0x00, 0x00, 0x07, 0x8f, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x76, 0xe0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x00, 0x03, 
+-      0x87, 0x00, 0x00, 0x00, 0x3c, 0xcf, 0x00, 0x00, 
+-      0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x07, 0x07, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x00, 0x03, 
+-      0x87, 0x00, 0x00, 0x00, 0x38, 0xc7, 0x00, 0x00, 
+-      0x00, 0x38, 0x38, 0x78, 0x00, 0x00, 0x07, 0x07, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x00, 0x03, 
+-      0x8f, 0x00, 0x00, 0x00, 0x38, 0xc0, 0x00, 0x00, 
+-      0x00, 0x38, 0x38, 0x70, 0x00, 0x00, 0x07, 0x07, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x00, 0x7f, 
+-      0xff, 0xc0, 0x00, 0x00, 0x38, 0xc0, 0x00, 0x00, 
+-      0x00, 0x38, 0x38, 0xf0, 0x00, 0x00, 0x07, 0x8f, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x1e, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 
+-      0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x70, 0xc0, 0x00, 0x00, 0x00, 0x7f, 
+-      0xff, 0xc0, 0x00, 0x00, 0x3c, 0xc0, 0x00, 0x00, 
+-      0x00, 0x38, 0x38, 0xe0, 0x00, 0x00, 0x03, 0x9e, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x39, 0xc0, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 
+-      0xff, 0xc0, 0x00, 0x00, 0x1e, 0xc0, 0x00, 0x00, 
+-      0x00, 0x3c, 0x79, 0xe0, 0x00, 0x00, 0x03, 0xfc, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 
+-      0x0e, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 
+-      0x00, 0x1c, 0x71, 0xc0, 0x00, 0x00, 0x01, 0xf8, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 
+-      0x1e, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 
+-      0x00, 0x1f, 0xe3, 0xc0, 0x00, 0x00, 0x03, 0xf0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 
+-      0x1e, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 
+-      0x00, 0x07, 0xc3, 0x8f, 0x80, 0x00, 0x07, 0xf0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 
+-      0x00, 0x00, 0x07, 0xbf, 0xc0, 0x00, 0x0f, 0x78, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 
+-      0x00, 0x00, 0x07, 0x38, 0xe0, 0x00, 0x1e, 0x3c, 
+-      0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 
+-      0xff, 0xc0, 0x00, 0x00, 0x00, 0xc7, 0x80, 0x00, 
+-      0x00, 0x00, 0x0f, 0x78, 0xf0, 0x00, 0x3c, 0x1e, 
+-      0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 
+-      0xff, 0xc0, 0x00, 0x00, 0x00, 0xc3, 0x80, 0x00, 
+-      0x00, 0x00, 0x0e, 0x70, 0x70, 0x00, 0x38, 0x1e, 
+-      0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 
+-      0xff, 0xc0, 0x00, 0x00, 0x00, 0xc3, 0x80, 0x00, 
+-      0x00, 0x00, 0x1e, 0x70, 0x70, 0x00, 0x38, 0x0f, 
+-      0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 
+-      0x38, 0x00, 0x00, 0x00, 0x70, 0xc3, 0x80, 0x00, 
+-      0x00, 0x00, 0x1c, 0x70, 0x70, 0x00, 0x38, 0x07, 
+-      0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 
+-      0x38, 0x00, 0x00, 0x00, 0x78, 0xc7, 0x80, 0x00, 
+-      0x00, 0x00, 0x3c, 0x70, 0x70, 0x00, 0x3c, 0x03, 
+-      0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 
+-      0x38, 0x00, 0x00, 0x00, 0x78, 0xc7, 0x80, 0x00, 
+-      0x00, 0x00, 0x38, 0x70, 0x70, 0x00, 0x3c, 0x07, 
+-      0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 
+-      0x78, 0x00, 0x00, 0x00, 0x3e, 0xdf, 0x00, 0x00, 
+-      0x00, 0x00, 0x70, 0x78, 0xf0, 0x00, 0x1f, 0x1f, 
+-      0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 
+-      0x78, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 
+-      0x00, 0x00, 0x70, 0x38, 0xe0, 0x00, 0x0f, 0xff, 
+-      0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 
+-      0x70, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 
+-      0x00, 0x00, 0xe0, 0x3f, 0xc0, 0x00, 0x07, 0xfe, 
+-      0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x70, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 
+-      0x00, 0x00, 0xe0, 0x0f, 0x80, 0x00, 0x03, 0xf8, 
+-      0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1e, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x80, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 
+-      0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x07, 
+-      0xf8, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x01, 0xfc, 
+-      0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 
+-      0x0f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x0f, 
+-      0xfe, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 
+-      0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 
+-      0x0f, 0xfe, 0x00, 0x00, 0x00, 0x0f, 0xfe, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 
+-      0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x1f, 
+-      0xff, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 
+-      0x00, 0x3f, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 
+-      0x80, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 
+-      0x1f, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 
+-      0x1f, 0x1f, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 
+-      0x00, 0x00, 0x3e, 0x0f, 0x80, 0x00, 0x00, 0x3e, 
+-      0x1f, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 
+-      0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x0f, 
+-      0x80, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+-      0x1e, 0x0f, 0x00, 0x00, 0x00, 0x3e, 0x0f, 0x80, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 
+-      0x3c, 0x07, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x00, 
+-      0x00, 0x00, 0x78, 0x03, 0xc0, 0x00, 0x00, 0x78, 
+-      0x07, 0x80, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 
+-      0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x03, 
+-      0xc0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x3c, 0x07, 0x80, 0x00, 0x00, 0x3c, 0x03, 0x80, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 
+-      0x00, 0x00, 0x00, 0x3c, 0x07, 0x80, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x0f, 0xf0, 0x00, 
+-      0x00, 0x00, 0x70, 0x03, 0xc0, 0x00, 0x00, 0x70, 
+-      0x03, 0x80, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 
+-      0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x01, 
+-      0xc0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x78, 0x03, 0x80, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 
+-      0x00, 0x00, 0x00, 0x3c, 0x03, 0x80, 0x00, 0x00, 
+-      0x78, 0x03, 0xc0, 0x00, 0x00, 0x1f, 0x70, 0x00, 
+-      0x00, 0x00, 0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 
+-      0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 0x01, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 
+-      0x00, 0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 
+-      0x78, 0x03, 0xc0, 0x00, 0x00, 0x1e, 0x70, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x03, 0x80, 0x00, 0x00, 0x01, 0xee, 0x00, 0x00, 
+-      0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 0x01, 0xc0, 
+-      0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x18, 0x70, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x07, 0x80, 0x00, 0x00, 0x03, 0xce, 0x00, 0x00, 
+-      0x00, 0x3b, 0xf8, 0x00, 0x00, 0x00, 0x78, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x3c, 0x07, 0x80, 0x00, 0x00, 0x70, 0x01, 0xc0, 
+-      0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 
+-      0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xf8, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 
+-      0x1f, 0x00, 0x00, 0x00, 0x03, 0xce, 0x00, 0x00, 
+-      0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x71, 0xfc, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x1e, 0x0f, 0x00, 0x00, 0x00, 0x70, 0x01, 0xc0, 
+-      0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 
+-      0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xfe, 
+-      0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x01, 
+-      0xfe, 0x00, 0x00, 0x00, 0x07, 0x8e, 0x00, 0x00, 
+-      0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x77, 0xfe, 
+-      0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0x0f, 0xfe, 0x00, 0x00, 0x00, 0x78, 0x03, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 
+-      0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x3f, 
+-      0x80, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x01, 
+-      0xfe, 0x00, 0x00, 0x00, 0x0f, 0x0e, 0x00, 0x00, 
+-      0x00, 0x7c, 0x0f, 0x80, 0x00, 0x00, 0x7f, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x07, 0xfc, 0x00, 0x00, 0x00, 0x78, 0x07, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 
+-      0xc0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01, 
+-      0xff, 0x80, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 
+-      0x00, 0x78, 0x03, 0x80, 0x00, 0x00, 0x7e, 0x0f, 
+-      0x80, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0x00, 0x00, 0x00, 0x3e, 0x0f, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 
+-      0xc0, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0x80, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x7c, 0x03, 
+-      0xc0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 
+-      0x3e, 0x0f, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 
+-      0xc0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0xc0, 0x00, 0x00, 0x3c, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x78, 0x03, 
+-      0xc0, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 
+-      0x78, 0x03, 0x80, 0x00, 0x00, 0x0f, 0xfd, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0x80, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0xc0, 0x00, 0x00, 0x78, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x70, 0x01, 
+-      0xc0, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x78, 0x03, 0xc0, 0x00, 0x00, 0x07, 0xf1, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 
+-      0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xfe, 
+-      0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 
+-      0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x70, 0x01, 
+-      0xc0, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x03, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 
+-      0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xf8, 
+-      0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x78, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 
+-      0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x70, 0x01, 
+-      0xc0, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x03, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 
+-      0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x1f, 0xc0, 
+-      0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x78, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x70, 
+-      0x01, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 
+-      0x00, 0x70, 0x01, 0xc0, 0x00, 0x00, 0x70, 0x01, 
+-      0xc0, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 
+-      0x70, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x03, 0x80, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x78, 
+-      0x03, 0xc0, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x78, 0x03, 0xc0, 0x00, 0x00, 0x38, 0x03, 
+-      0xc0, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 
+-      0x78, 0x03, 0xc0, 0x00, 0x00, 0x70, 0x07, 0x80, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3c, 0x07, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 
+-      0x07, 0x80, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x78, 0x07, 0x80, 0x00, 0x00, 0x3c, 0x03, 
+-      0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 
+-      0x78, 0x03, 0xc0, 0x00, 0x00, 0x78, 0x07, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x3e, 
+-      0x0f, 0x80, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x3e, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x0f, 
+-      0x80, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 
+-      0x3e, 0x0f, 0x80, 0x00, 0x00, 0x3c, 0x1f, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x1f, 
+-      0xff, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 
+-      0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 
+-      0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x0f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x0f, 
+-      0xfe, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xfe, 
+-      0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 
+-      0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x03, 
+-      0xf8, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 
+-      0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xf8, 
+-      0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 
+-      0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x7c, 0x00, 
+-      0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x00, 
+-      0x7f, 0x80, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00, 
+-      0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 
+-      0xe0, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x7c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1f, 0x00, 0x07, 0xc0, 0x00, 0x1e, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 
+-      0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x7c, 0x00, 
+-      0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x01, 
+-      0xff, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 
+-      0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 
+-      0xe0, 0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0xf8, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1f, 0x80, 0x0f, 0xc0, 0x00, 0x1e, 0x00, 
+-      0x1c, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 
+-      0x00, 0x7f, 0xff, 0xe0, 0x00, 0x00, 0xfe, 0x00, 
+-      0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x03, 
+-      0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 
+-      0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 
+-      0xe0, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x01, 0xf0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1f, 0x80, 0x0f, 0xc0, 0x00, 0x1f, 0x00, 
+-      0x1c, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 
+-      0x00, 0xfe, 0x07, 0xf0, 0x00, 0x00, 0xfe, 0x00, 
+-      0x00, 0x00, 0x1c, 0x01, 0xf0, 0x00, 0x00, 0x07, 
+-      0xc1, 0xf0, 0x00, 0x00, 0x1c, 0x01, 0xf8, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x07, 0xe0, 0xfc, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x03, 0xe0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1f, 0x80, 0x0f, 0xc0, 0x00, 0x1f, 0x80, 
+-      0x1c, 0x00, 0x00, 0x07, 0xe1, 0xf8, 0x00, 0x00, 
+-      0x01, 0xf0, 0x00, 0xf8, 0x00, 0x00, 0xee, 0x00, 
+-      0x00, 0x00, 0x1c, 0x00, 0xf0, 0x00, 0x00, 0x0f, 
+-      0x00, 0x78, 0x00, 0x00, 0x1c, 0x00, 0x78, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0x80, 0x1e, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x07, 0xc0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1f, 0xc0, 0x1f, 0xc0, 0x00, 0x1f, 0x80, 
+-      0x1c, 0x00, 0x00, 0x0f, 0x80, 0x7c, 0x00, 0x00, 
+-      0x03, 0xc0, 0x00, 0x7c, 0x00, 0x01, 0xef, 0x00, 
+-      0x00, 0x00, 0x1c, 0x00, 0x70, 0x00, 0x00, 0x1e, 
+-      0x00, 0x3c, 0x00, 0x00, 0x1c, 0x00, 0x3c, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x0f, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1d, 0xc0, 0x1d, 0xc0, 0x00, 0x1f, 0xc0, 
+-      0x1c, 0x00, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x00, 
+-      0x07, 0x80, 0x00, 0x3c, 0x00, 0x01, 0xc7, 0x00, 
+-      0x00, 0x00, 0x1c, 0x00, 0x70, 0x00, 0x00, 0x1c, 
+-      0x00, 0x3c, 0x00, 0x00, 0x1c, 0x00, 0x1c, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x1e, 0x00, 0x0f, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x1f, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1d, 0xc0, 0x1d, 0xc0, 0x00, 0x1d, 0xc0, 
+-      0x1c, 0x00, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x00, 
+-      0x0f, 0x03, 0xe3, 0x9e, 0x00, 0x03, 0xc7, 0x80, 
+-      0x00, 0x00, 0x1c, 0x00, 0x70, 0x00, 0x00, 0x1c, 
+-      0x00, 0x18, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x06, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x3e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1d, 0xe0, 0x1d, 0xc0, 0x00, 0x1c, 0xe0, 
+-      0x1c, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x00, 
+-      0x0f, 0x0f, 0xf7, 0x8e, 0x00, 0x03, 0xc7, 0x80, 
+-      0x00, 0x00, 0x1c, 0x00, 0xf0, 0x00, 0x00, 0x3c, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x7c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0xe0, 0x39, 0xc0, 0x00, 0x1c, 0xf0, 
+-      0x1c, 0x00, 0x00, 0x3c, 0x00, 0x0f, 0x00, 0x00, 
+-      0x1e, 0x1f, 0xff, 0x8f, 0x00, 0x03, 0x83, 0x80, 
+-      0x00, 0x00, 0x1c, 0x01, 0xe0, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0xf8, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0xe0, 0x39, 0xc0, 0x00, 0x1c, 0x70, 
+-      0x1c, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 
+-      0x1c, 0x3e, 0x3f, 0x0f, 0x00, 0x07, 0x83, 0xc0, 
+-      0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0xfc, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1d, 
+-      0xf0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0xf0, 0x39, 0xc0, 0x00, 0x1c, 0x78, 
+-      0x1c, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 
+-      0x1c, 0x3c, 0x1f, 0x07, 0x00, 0x07, 0x01, 0xc0, 
+-      0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 
+-      0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 
+-      0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0xfc, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1f, 
+-      0xf8, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0xf0, 0x79, 0xc0, 0x00, 0x1c, 0x3c, 
+-      0x1c, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 
+-      0x3c, 0x78, 0x0f, 0x07, 0x00, 0x0f, 0x01, 0xe0, 
+-      0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 
+-      0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 
+-      0x80, 0x00, 0x00, 0x38, 0x03, 0xff, 0x00, 0x00, 
+-      0x1f, 0xff, 0xfc, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1f, 
+-      0xfc, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x70, 0x71, 0xc0, 0x00, 0x1c, 0x1c, 
+-      0x1c, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 
+-      0x38, 0x70, 0x0f, 0x07, 0x00, 0x0f, 0x01, 0xe0, 
+-      0x00, 0x00, 0x1c, 0x01, 0xf0, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 
+-      0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 
+-      0x80, 0x00, 0x00, 0x38, 0x03, 0xff, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1f, 
+-      0x9c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x70, 0x71, 0xc0, 0x00, 0x1c, 0x1e, 
+-      0x1c, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 
+-      0x38, 0xf0, 0x0f, 0x07, 0x00, 0x0f, 0xff, 0xe0, 
+-      0x00, 0x00, 0x1c, 0x00, 0x78, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x38, 0x03, 0xff, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1f, 
+-      0x1e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x78, 0xf1, 0xc0, 0x00, 0x1c, 0x0f, 
+-      0x1c, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 
+-      0x38, 0xe0, 0x0e, 0x07, 0x00, 0x1f, 0xff, 0xf0, 
+-      0x00, 0x00, 0x1c, 0x00, 0x78, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1e, 
+-      0x0f, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x38, 0xe1, 0xc0, 0x00, 0x1c, 0x07, 
+-      0x1c, 0x00, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 
+-      0x38, 0xe0, 0x0e, 0x0f, 0x00, 0x1f, 0xff, 0xf0, 
+-      0x00, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x3c, 
+-      0x00, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x1e, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x3c, 0x00, 0x07, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x07, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x38, 0xe1, 0xc0, 0x00, 0x1c, 0x07, 
+-      0x9c, 0x00, 0x00, 0x3c, 0x00, 0x0f, 0x00, 0x00, 
+-      0x38, 0xe0, 0x1e, 0x0e, 0x00, 0x1c, 0x00, 0x70, 
+-      0x00, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x1c, 
+-      0x00, 0x1e, 0x00, 0x00, 0x1c, 0x00, 0x1c, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x1c, 0x00, 0x07, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x70, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x03, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x3d, 0xe1, 0xc0, 0x00, 0x1c, 0x03, 
+-      0x9c, 0x00, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x00, 
+-      0x38, 0xe0, 0x1e, 0x1e, 0x00, 0x3c, 0x00, 0x78, 
+-      0x00, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x1e, 
+-      0x00, 0x1e, 0x00, 0x00, 0x1c, 0x00, 0x1c, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x1e, 0x00, 0x07, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x70, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x03, 0xc0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x1d, 0xc1, 0xc0, 0x00, 0x1c, 0x01, 
+-      0xdc, 0x00, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x00, 
+-      0x38, 0xe0, 0x3c, 0x1c, 0x00, 0x38, 0x00, 0x38, 
+-      0x00, 0x00, 0x1c, 0x00, 0x78, 0x00, 0x00, 0x1e, 
+-      0x00, 0x3c, 0x00, 0x00, 0x1c, 0x00, 0x3c, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x70, 0x1c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x01, 0xe0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x1d, 0xc1, 0xc0, 0x00, 0x1c, 0x01, 
+-      0xfc, 0x00, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x00, 
+-      0x3c, 0xf0, 0x7c, 0x3c, 0x00, 0x78, 0x00, 0x3c, 
+-      0x00, 0x00, 0x1c, 0x00, 0x78, 0x00, 0x00, 0x0f, 
+-      0x00, 0x7c, 0x00, 0x00, 0x1c, 0x00, 0x78, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0x80, 0x1f, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x78, 0x3c, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0xf0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x1f, 0xc1, 0xc0, 0x00, 0x1c, 0x00, 
+-      0xfc, 0x00, 0x00, 0x0f, 0x80, 0x7c, 0x00, 0x00, 
+-      0x3c, 0x78, 0xfc, 0xf8, 0x00, 0x78, 0x00, 0x3c, 
+-      0x00, 0x00, 0x1c, 0x01, 0xf0, 0x00, 0x00, 0x07, 
+-      0xe1, 0xf8, 0x00, 0x00, 0x1c, 0x01, 0xf8, 0x00, 
+-      0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x07, 0xe0, 0x7f, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x7c, 0x78, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x70, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1c, 0x1f, 0x81, 0xc0, 0x00, 0x1c, 0x00, 
+-      0xfc, 0x00, 0x00, 0x07, 0xe1, 0xf8, 0x00, 0x00, 
+-      0x1c, 0x7f, 0xff, 0xf0, 0x00, 0x70, 0x00, 0x1c, 
+-      0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x03, 
+-      0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 
+-      0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x78, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 
+-      0x00, 0x1c, 0x0f, 0x81, 0xc0, 0x00, 0x1c, 0x00, 
+-      0x7c, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 
+-      0x1e, 0x3f, 0xdf, 0xe0, 0x00, 0xf0, 0x00, 0x1e, 
+-      0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x01, 
+-      0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 
+-      0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x3c, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 
+-      0x00, 0x1c, 0x0f, 0x81, 0xc0, 0x00, 0x1c, 0x00, 
+-      0x3c, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 
+-      0x0f, 0x1f, 0x0f, 0x87, 0x80, 0xe0, 0x00, 0x0e, 
+-      0x00, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 
+-      0x7f, 0x80, 0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 
+-      0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 
+-      0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 
+-      0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x1c, 
+-      0x00, 0x1e, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 
+-      0x00, 0x1c, 0x0f, 0x01, 0xc0, 0x00, 0x1c, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 
+-      0x0f, 0x80, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x07, 0xc0, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0xf0, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0xfe, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0x00, 
+-      0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x01, 
+-      0xfe, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0xe0, 0x00, 
+-      0x0e, 0x00, 0x00, 0xe0, 0x03, 0xe0, 0x03, 0x80, 
+-      0x3c, 0x00, 0x78, 0x00, 0x00, 0xf0, 0x00, 0x78, 
+-      0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x3f, 
+-      0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 
+-      0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, 0xc0, 
+-      0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x03, 
+-      0xff, 0x80, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0xf0, 0x00, 
+-      0x1e, 0x00, 0x00, 0xf0, 0x03, 0xe0, 0x07, 0x80, 
+-      0x1e, 0x00, 0xf0, 0x00, 0x00, 0x70, 0x00, 0x70, 
+-      0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x3f, 
+-      0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 
+-      0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xe0, 
+-      0x00, 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x0f, 
+-      0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0xf0, 0x00, 
+-      0x1e, 0x00, 0x00, 0xf0, 0x07, 0xe0, 0x07, 0x80, 
+-      0x0e, 0x00, 0xe0, 0x00, 0x00, 0x78, 0x00, 0xf0, 
+-      0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x3f, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0xf0, 0x00, 0x00, 0x07, 0xc1, 0xf0, 
+-      0x00, 0x00, 0x1c, 0x00, 0xf8, 0x00, 0x00, 0x0f, 
+-      0x83, 0xe0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x78, 0x00, 
+-      0x3c, 0x00, 0x00, 0x70, 0x07, 0xf0, 0x07, 0x00, 
+-      0x0f, 0x01, 0xe0, 0x00, 0x00, 0x3c, 0x01, 0xe0, 
+-      0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x78, 0x00, 0x00, 0x0f, 0x00, 0x78, 
+-      0x00, 0x00, 0x1c, 0x00, 0x3c, 0x00, 0x00, 0x1e, 
+-      0x00, 0xf0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x78, 0x00, 
+-      0x3c, 0x00, 0x00, 0x70, 0x07, 0x70, 0x07, 0x00, 
+-      0x07, 0x83, 0xc0, 0x00, 0x00, 0x1c, 0x01, 0xc0, 
+-      0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x78, 0x00, 0x00, 0x1e, 0x00, 0x3c, 
+-      0x00, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 
+-      0x00, 0xf0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x38, 0x00, 
+-      0x38, 0x00, 0x00, 0x78, 0x07, 0x70, 0x0f, 0x00, 
+-      0x03, 0x83, 0x80, 0x00, 0x00, 0x1e, 0x03, 0xc0, 
+-      0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x78, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x38, 0x00, 0x00, 0x1c, 0x00, 0x3c, 
+-      0x00, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 
+-      0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x3c, 0x00, 
+-      0x78, 0x00, 0x00, 0x78, 0x0f, 0x78, 0x0f, 0x00, 
+-      0x03, 0xc7, 0x80, 0x00, 0x00, 0x0f, 0x07, 0x80, 
+-      0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x38, 0x00, 0x00, 0x1c, 0x00, 0x1c, 
+-      0x00, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x3c, 0x00, 
+-      0x78, 0x00, 0x00, 0x38, 0x0e, 0x38, 0x0e, 0x00, 
+-      0x01, 0xef, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x38, 0x00, 0x00, 0x3c, 0x00, 0x1e, 
+-      0x00, 0x00, 0x1c, 0x00, 0x3c, 0x00, 0x00, 0x1e, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 
+-      0x70, 0x00, 0x00, 0x38, 0x0e, 0x38, 0x0e, 0x00, 
+-      0x00, 0xfe, 0x00, 0x00, 0x00, 0x07, 0x8f, 0x00, 
+-      0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x78, 0x00, 0x00, 0x38, 0x00, 0x0e, 
+-      0x00, 0x00, 0x1c, 0x00, 0x3c, 0x00, 0x00, 0x0f, 
+-      0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1e, 0x00, 
+-      0xf0, 0x00, 0x00, 0x3c, 0x0e, 0x38, 0x1e, 0x00, 
+-      0x00, 0x7c, 0x00, 0x00, 0x00, 0x03, 0x8e, 0x00, 
+-      0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x1e, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x78, 0x00, 0x00, 0x38, 0x00, 0x0e, 
+-      0x00, 0x00, 0x1c, 0x00, 0xf8, 0x00, 0x00, 0x0f, 
+-      0xf8, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x1e, 0x00, 
+-      0xf0, 0x00, 0x00, 0x3c, 0x1e, 0x3c, 0x1e, 0x00, 
+-      0x00, 0x7c, 0x00, 0x00, 0x00, 0x03, 0xde, 0x00, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x01, 0xf0, 0x00, 0x00, 0x38, 0x00, 0x0e, 
+-      0x00, 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x07, 
+-      0xff, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x0f, 0x01, 
+-      0xe0, 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 
+-      0x00, 0x7c, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 
+-      0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0xe0, 0x00, 0x00, 0x38, 0x00, 0x0e, 
+-      0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x01, 
+-      0xff, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x0f, 0x01, 
+-      0xe0, 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 
+-      0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 
+-      0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0xc0, 0x00, 0x00, 0x38, 0x00, 0x0e, 
+-      0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 
+-      0x3f, 0xe0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x07, 0x01, 
+-      0xc0, 0x00, 0x00, 0x1e, 0x3c, 0x1c, 0x3c, 0x00, 
+-      0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 
+-      0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1f, 0xff, 0x80, 0x00, 0x00, 0x38, 0x00, 0x0e, 
+-      0x00, 0x00, 0x1c, 0x0f, 0x00, 0x00, 0x00, 0x00, 
+-      0x03, 0xf0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x07, 0x83, 
+-      0xc0, 0x00, 0x00, 0x1e, 0x3c, 0x1e, 0x3c, 0x00, 
+-      0x01, 0xef, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x0e, 
+-      0x00, 0x00, 0x1c, 0x07, 0x80, 0x00, 0x00, 0x00, 
+-      0x00, 0xf8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x07, 0x83, 
+-      0xc0, 0x00, 0x00, 0x0e, 0x38, 0x0e, 0x38, 0x00, 
+-      0x01, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x1e, 
+-      0x00, 0x00, 0x1c, 0x07, 0xc0, 0x00, 0x00, 0x38, 
+-      0x00, 0x78, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x03, 0xc7, 
+-      0x80, 0x00, 0x00, 0x0e, 0x38, 0x0e, 0x38, 0x00, 
+-      0x03, 0xc7, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1c, 
+-      0x00, 0x00, 0x1c, 0x03, 0xe0, 0x00, 0x00, 0x38, 
+-      0x00, 0x38, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x03, 0xc7, 
+-      0x80, 0x00, 0x00, 0x0f, 0x78, 0x0f, 0x78, 0x00, 
+-      0x07, 0x83, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x07, 0x3c, 
+-      0x00, 0x00, 0x1c, 0x01, 0xf0, 0x00, 0x00, 0x3c, 
+-      0x00, 0x38, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1e, 0x00, 0x3c, 0x00, 0x00, 0x01, 0xc7, 
+-      0x00, 0x00, 0x00, 0x0f, 0x70, 0x07, 0x78, 0x00, 
+-      0x0f, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x07, 0xb8, 
+-      0x00, 0x00, 0x1c, 0x00, 0xf0, 0x00, 0x00, 0x1c, 
+-      0x00, 0x78, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x1e, 0x00, 0x3c, 0x00, 0x00, 0x01, 0xef, 
+-      0x00, 0x00, 0x00, 0x07, 0x70, 0x07, 0x70, 0x00, 
+-      0x0e, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x07, 0xf8, 
+-      0x00, 0x00, 0x1c, 0x00, 0x78, 0x00, 0x00, 0x1e, 
+-      0x00, 0xf8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x0f, 0x00, 0x78, 0x00, 0x00, 0x01, 0xef, 
+-      0x00, 0x00, 0x00, 0x07, 0xf0, 0x07, 0xf0, 0x00, 
+-      0x1e, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc1, 0xf0, 
+-      0x00, 0x00, 0x1c, 0x00, 0x78, 0x00, 0x00, 0x0f, 
+-      0xc1, 0xf0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x0f, 0xc1, 0xf8, 0x00, 0x00, 0x00, 0xfe, 
+-      0x00, 0x00, 0x00, 0x07, 0xf0, 0x07, 0xf0, 0x00, 
+-      0x3c, 0x00, 0x78, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf8, 
+-      0x00, 0x00, 0x1c, 0x00, 0x3c, 0x00, 0x00, 0x0f, 
+-      0xff, 0xe0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x07, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xfe, 
+-      0x00, 0x00, 0x00, 0x07, 0xe0, 0x03, 0xf0, 0x00, 
+-      0x38, 0x00, 0x38, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfe, 
+-      0x00, 0x00, 0x1c, 0x00, 0x3e, 0x00, 0x00, 0x03, 
+-      0xff, 0xc0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x03, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x7c, 
+-      0x00, 0x00, 0x00, 0x03, 0xe0, 0x03, 0xe0, 0x00, 
+-      0x78, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x9f, 
+-      0x00, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x00, 0x00, 
+-      0xff, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7c, 
+-      0x00, 0x00, 0x00, 0x03, 0xe0, 0x03, 0xe0, 0x00, 
+-      0xf0, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x70, 0x00, 
+-      0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x01, 0xff, 0xff, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x01, 0xff, 0xff, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x01, 0xff, 0xff, 0xe0, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x00, 
+-      0x00, 0x00, 0x39, 0xf8, 0x00, 0x00, 0x00, 0x03, 
+-      0xf0, 0x00, 0x00, 0x00, 0x07, 0xe7, 0x00, 0x00, 
+-      0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0xff, 0x80, 
+-      0x00, 0x00, 0x00, 0x07, 0xe7, 0x00, 0x00, 0x00, 
+-      0x38, 0xfc, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x0f, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x39, 0xf0, 0x7e, 0x00, 0x00, 0x39, 0xfc, 
+-      0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 
+-      0x00, 0x00, 0x3b, 0xfc, 0x00, 0x00, 0x00, 0x0f, 
+-      0xfc, 0x00, 0x00, 0x00, 0x0f, 0xf7, 0x00, 0x00, 
+-      0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0xff, 0x80, 
+-      0x00, 0x00, 0x00, 0x0f, 0xf7, 0x00, 0x00, 0x00, 
+-      0x3b, 0xfe, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x1f, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x3b, 0xfc, 0xff, 0x00, 0x00, 0x3b, 0xff, 
+-      0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x00, 
+-      0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x1f, 
+-      0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 
+-      0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0xff, 0x80, 
+-      0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 
+-      0x3f, 0xff, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x3e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x3f, 0xfd, 0xff, 0x80, 0x00, 0x3f, 0xff, 
+-      0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1f, 0x00, 
+-      0x00, 0x00, 0x3f, 0x1f, 0x00, 0x00, 0x00, 0x3e, 
+-      0x1e, 0x00, 0x00, 0x00, 0x3e, 0x3f, 0x00, 0x00, 
+-      0x00, 0x3e, 0x1f, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x3e, 0x3f, 0x00, 0x00, 0x00, 
+-      0x3f, 0x0f, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x78, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x3f, 0x1f, 0x8f, 0x80, 0x00, 0x3f, 0x0f, 
+-      0x80, 0x00, 0x00, 0x3e, 0x1f, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 
+-      0x00, 0x00, 0x3e, 0x07, 0x00, 0x00, 0x00, 0x3c, 
+-      0x0f, 0x00, 0x00, 0x00, 0x38, 0x1f, 0x00, 0x00, 
+-      0x00, 0x38, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x3c, 0x1f, 0x00, 0x00, 0x00, 
+-      0x3c, 0x07, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0xf0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x3c, 0x1f, 0x07, 0x80, 0x00, 0x3c, 0x07, 
+-      0x80, 0x00, 0x00, 0x3c, 0x0f, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 
+-      0x00, 0x00, 0x3c, 0x07, 0x80, 0x00, 0x00, 0x78, 
+-      0x07, 0x00, 0x00, 0x00, 0x78, 0x0f, 0x00, 0x00, 
+-      0x00, 0x78, 0x07, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x78, 0x0f, 0x00, 0x00, 0x00, 
+-      0x3c, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x39, 
+-      0xe0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x3c, 0x0f, 0x03, 0x80, 0x00, 0x3c, 0x03, 
+-      0x80, 0x00, 0x00, 0x78, 0x07, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 
+-      0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 
+-      0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3b, 
+-      0xc0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x00, 
+-      0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 
+-      0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0xc0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 
+-      0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 
+-      0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0xe0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf7, 0x00, 
+-      0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 
+-      0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0xe0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x07, 0x00, 
+-      0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 
+-      0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 
+-      0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3c, 
+-      0xf0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 
+-      0x00, 0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 
+-      0x07, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 
+-      0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x78, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x70, 0x03, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0f, 0x00, 
+-      0x00, 0x00, 0x3c, 0x07, 0x80, 0x00, 0x00, 0x78, 
+-      0x0f, 0x00, 0x00, 0x00, 0x78, 0x0f, 0x00, 0x00, 
+-      0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x78, 0x0f, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x78, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x78, 0x07, 0x80, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x1f, 0x00, 
+-      0x00, 0x00, 0x3c, 0x0f, 0x00, 0x00, 0x00, 0x38, 
+-      0x0f, 0x00, 0x00, 0x00, 0x3c, 0x0f, 0x00, 0x00, 
+-      0x00, 0x3c, 0x07, 0x80, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x38, 0x0f, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x3c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x3c, 0x0f, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x3f, 0x00, 
+-      0x00, 0x00, 0x3f, 0x1f, 0x00, 0x00, 0x00, 0x3e, 
+-      0x3e, 0x00, 0x00, 0x00, 0x3e, 0x3f, 0x00, 0x00, 
+-      0x00, 0x3e, 0x0f, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x3e, 0x3f, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x1e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x3e, 0x1f, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x00, 
+-      0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x1f, 
+-      0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 
+-      0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x1e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf7, 0x80, 
+-      0x00, 0x00, 0x3b, 0xfc, 0x00, 0x00, 0x00, 0x0f, 
+-      0xf8, 0x00, 0x00, 0x00, 0x0f, 0xf7, 0x00, 0x00, 
+-      0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x0f, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe3, 0x80, 
+-      0x00, 0x00, 0x39, 0xf8, 0x00, 0x00, 0x00, 0x07, 
+-      0xf0, 0x00, 0x00, 0x00, 0x07, 0xe7, 0x00, 0x00, 
+-      0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0x07, 0xe7, 0x00, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 
+-      0x07, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x0e, 0x03, 0x80, 0x00, 0x38, 0x03, 
+-      0x80, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x78, 0x0f, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x7c, 0x3e, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 
+-      0xc0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 
+-      0xc0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 
+-      0xc0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x39, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xe7, 0x00, 
+-      0x00, 0x00, 0x39, 0xe0, 0x00, 0x00, 0x00, 0x0f, 
+-      0xf0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0xf0, 0x07, 
+-      0x80, 0x00, 0x01, 0xe0, 0x38, 0x0f, 0x00, 0x00, 
+-      0xf0, 0x0f, 0x00, 0x00, 0x00, 0x70, 0x07, 0x00, 
+-      0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x3b, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0xf7, 0x00, 
+-      0x00, 0x00, 0x3b, 0xe0, 0x00, 0x00, 0x00, 0x1f, 
+-      0xf8, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0xf0, 0x07, 
+-      0x80, 0x00, 0x00, 0xe0, 0x3c, 0x0e, 0x00, 0x00, 
+-      0x78, 0x0f, 0x00, 0x00, 0x00, 0x78, 0x0f, 0x00, 
+-      0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x3f, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 
+-      0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x3f, 
+-      0xfc, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 0x07, 
+-      0x00, 0x00, 0x00, 0xf0, 0x7c, 0x1e, 0x00, 0x00, 
+-      0x38, 0x1e, 0x00, 0x00, 0x00, 0x38, 0x0e, 0x00, 
+-      0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x3f, 0x1f, 0x00, 0x00, 0x00, 0x3e, 0x3f, 0x00, 
+-      0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x78, 
+-      0x3e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x78, 0x0f, 
+-      0x00, 0x00, 0x00, 0xf0, 0x7c, 0x1e, 0x00, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x00, 0x38, 0x0e, 0x00, 
+-      0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 
+-      0x40, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x3e, 0x0f, 0x00, 0x00, 0x00, 0x38, 0x1f, 0x00, 
+-      0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x70, 
+-      0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x0e, 
+-      0x00, 0x00, 0x00, 0x70, 0x7c, 0x1c, 0x00, 0x00, 
+-      0x1e, 0x38, 0x00, 0x00, 0x00, 0x3c, 0x1e, 0x00, 
+-      0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 
+-      0xc0, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x3c, 0x07, 0x80, 0x00, 0x00, 0x78, 0x0f, 0x00, 
+-      0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x70, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x38, 0x0e, 
+-      0x00, 0x00, 0x00, 0x70, 0xec, 0x1c, 0x00, 0x00, 
+-      0x0e, 0x78, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 
+-      0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x1e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf1, 
+-      0xc0, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x3c, 0x03, 0x80, 0x00, 0x00, 0x70, 0x0f, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x7e, 
+-      0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x3c, 0x1e, 
+-      0x00, 0x00, 0x00, 0x78, 0xee, 0x3c, 0x00, 0x00, 
+-      0x0f, 0xf0, 0x00, 0x00, 0x00, 0x1e, 0x1c, 0x00, 
+-      0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x3c, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x71, 0xff, 
+-      0xc0, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 0x07, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0xe0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x1c, 0x1c, 
+-      0x00, 0x00, 0x00, 0x38, 0xee, 0x38, 0x00, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0x00, 0x1e, 0x1c, 0x00, 
+-      0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x78, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x60, 0x7f, 
+-      0x80, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 0x07, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0xfc, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x1e, 0x3c, 
+-      0x00, 0x00, 0x00, 0x38, 0xe6, 0x38, 0x00, 0x00, 
+-      0x03, 0xe0, 0x00, 0x00, 0x00, 0x0e, 0x38, 0x00, 
+-      0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x70, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x40, 0x1f, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 0x07, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x0f, 
+-      0xfe, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x0e, 0x38, 
+-      0x00, 0x00, 0x00, 0x3d, 0xc6, 0x78, 0x00, 0x00, 
+-      0x03, 0xc0, 0x00, 0x00, 0x00, 0x0f, 0x38, 0x00, 
+-      0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x78, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 0x07, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x01, 
+-      0xff, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x0e, 0x38, 
+-      0x00, 0x00, 0x00, 0x1d, 0xc7, 0x70, 0x00, 0x00, 
+-      0x07, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0x38, 0x00, 
+-      0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x3c, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x38, 0x03, 0x80, 0x00, 0x00, 0x70, 0x07, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x0f, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x03, 0x80, 0x00, 0x00, 0x0f, 0x78, 
+-      0x00, 0x00, 0x00, 0x1d, 0xc7, 0x70, 0x00, 0x00, 
+-      0x07, 0xf0, 0x00, 0x00, 0x00, 0x07, 0x70, 0x00, 
+-      0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x1e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x3c, 0x07, 0x80, 0x00, 0x00, 0x78, 0x0f, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x70, 
+-      0x07, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x07, 0x80, 0x00, 0x00, 0x07, 0x70, 
+-      0x00, 0x00, 0x00, 0x1d, 0xc3, 0x70, 0x00, 0x00, 
+-      0x0f, 0x70, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 
+-      0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x3c, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x0f, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x78, 
+-      0x07, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x3c, 0x07, 0x80, 0x00, 0x00, 0x07, 0xf0, 
+-      0x00, 0x00, 0x00, 0x0f, 0x83, 0xe0, 0x00, 0x00, 
+-      0x1e, 0x78, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 
+-      0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x3f, 0x1f, 0x00, 0x00, 0x00, 0x3e, 0x3f, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3c, 
+-      0x1f, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 
+-      0x00, 0x3e, 0x1f, 0x80, 0x00, 0x00, 0x03, 0xe0, 
+-      0x00, 0x00, 0x00, 0x0f, 0x83, 0xe0, 0x00, 0x00, 
+-      0x3c, 0x3c, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 
+-      0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x3f, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0xfe, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 
+-      0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x03, 0xe0, 
+-      0x00, 0x00, 0x00, 0x0f, 0x83, 0xe0, 0x00, 0x00, 
+-      0x38, 0x1c, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 
+-      0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x3b, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0xf7, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x1f, 
+-      0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 
+-      0x00, 0x1f, 0xfb, 0x80, 0x00, 0x00, 0x03, 0xe0, 
+-      0x00, 0x00, 0x00, 0x0f, 0x03, 0xc0, 0x00, 0x00, 
+-      0x78, 0x1e, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 
+-      0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 
+-      0x39, 0xf0, 0x00, 0x00, 0x00, 0x03, 0xe7, 0x00, 
+-      0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x07, 
+-      0xf0, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 
+-      0x00, 0x07, 0xe3, 0x80, 0x00, 0x00, 0x01, 0xc0, 
+-      0x00, 0x00, 0x00, 0x07, 0x01, 0xc0, 0x00, 0x00, 
+-      0xf0, 0x0f, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 
+-      0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 
+-      0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 
+-      0xc0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 
+-      0xc0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 
+-      0xc0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 
+-      0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
+-      0xf0, 0x24, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x0c, 0x94, 
+-      0xea, 0xff, 0xfd, 0x70, 0xea, 0x00, 0x00, 0x01, 
+-      0xe3, 0x5c, 0x00, 0xb7, 0xa5, 0x9f, 0xf0, 0x04, 
+-      0xe0, 0x86, 0xc0, 0x0c, 0xe5, 0x9f, 0xf0, 0x00, 
+-      0x00, 0x00, 0x0f, 0x74, 0x00, 0x00, 0x0c, 0x98, 
+-      0x00, 0x00, 0x00, 0x0f, 0xf0, 0x24, 0x00, 0x09, 
+-      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 
+-      0x00, 0x00, 0x0e, 0x4c, 0xea, 0xff, 0xfd, 0x03, 
+-      0xea, 0x00, 0x00, 0x07, 0xe5, 0x9f, 0xc0, 0x1c, 
+-      0xe5, 0x9c, 0x30, 0x00, 0xe3, 0x83, 0x33, 0x33, 
+-      0xe1, 0x52, 0x00, 0x03, 0x05, 0x9f, 0xc0, 0x10, 
+-      0x05, 0x9c, 0xc0, 0x00, 0x03, 0x8c, 0x23, 0x33, 
+-      0xe5, 0x9f, 0xc0, 0x08, 0xe5, 0x9f, 0xf0, 0x08, 
+-      0x66, 0x00, 0x00, 0x60, 0x66, 0x00, 0x00, 0x5c, 
+-      0x66, 0x00, 0x00, 0x58, 0x00, 0x00, 0x0e, 0x50, 
+-      0x00, 0x00, 0x00, 0x01, 0xf0, 0x24, 0x00, 0x09, 
+-      0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 
+-      0x00, 0x00, 0x02, 0x6c, 0xa0, 0x00, 0x0b, 0x38, 
+-      0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x0f, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+-      0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 
+-      0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 
+-      0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 
+-      0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x13, 
+-      0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 
+-      0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 
+-      0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 
+-      0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x18, 
+-      0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1f, 
+-      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 
+-      0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 
+-      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 
+-      0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 
+-      0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 
+-      0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x3f, 0xfe, 0xb1, 0x72, 0x17, 0xf7, 
+-      0xd1, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xcd, 
+-      0xf3, 0x57, 0x93, 0xc0, 0x00, 0x00, 0x00, 0x00, 
+-      0x80, 0x00, 0x3f, 0xfe, 0xca, 0x20, 0xad, 0x9a, 
+-      0xb5, 0xe9, 0x46, 0xe9, 0x00, 0x00, 0x40, 0x03, 
+-      0x83, 0x12, 0x51, 0x00, 0xb5, 0x7f, 0x65, 0x09, 
+-      0x80, 0x00, 0x40, 0x05, 0x80, 0x3f, 0xf8, 0x95, 
+-      0x9d, 0xac, 0xd2, 0x28, 0x80, 0x00, 0x40, 0x04, 
+-      0x8e, 0xac, 0x02, 0x5b, 0x3e, 0x70, 0x76, 0xbb, 
+-      0x00, 0x00, 0x40, 0x07, 0x9c, 0x04, 0x1f, 0xd0, 
+-      0xa9, 0x33, 0xef, 0x60, 0x80, 0x00, 0x40, 0x08, 
+-      0xc0, 0x5f, 0xf4, 0xe0, 0x6c, 0x83, 0xbb, 0x96, 
+-      0x00, 0x00, 0x3f, 0xff, 0x80, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, 
+-      0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 
+-      0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x35, 
+-      0x00, 0x00, 0x3f, 0xfe, 0xb1, 0x73, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 
+-      0xff, 0xfe, 0x2f, 0xf1, 0x48, 0x3b, 0x9d, 0x27, 
+-      0x00, 0x00, 0x3f, 0xee, 0xe8, 0x08, 0x97, 0x58, 
+-      0x10, 0x16, 0xb3, 0x7d, 0x40, 0x40, 0x40, 0x40, 
+-      0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 
+-      0x41, 0x41, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 
+-      0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 
+-      0x40, 0x40, 0x40, 0x40, 0x05, 0x02, 0x02, 0x02, 
+-      0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 
+-      0x02, 0x02, 0x02, 0x02, 0x20, 0x20, 0x20, 0x20, 
+-      0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x02, 0x02, 
+-      0x02, 0x02, 0x02, 0x02, 0x02, 0x90, 0x90, 0x90, 
+-      0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
+-      0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x02, 
+-      0x02, 0x02, 0x02, 0x02, 0x02, 0x88, 0x88, 0x88, 
+-      0x88, 0x88, 0x88, 0x08, 0x08, 0x08, 0x08, 0x08, 
+-      0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
+-      0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x02, 
+-      0x02, 0x02, 0x02, 0x40, 0xe5, 0x9f, 0xc0, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1c, 0x2e, 0x01, 0x79, 0x19, 
+-      0xe5, 0x9f, 0xc0, 0x00, 0xe1, 0x2f, 0xff, 0x1c, 
+-      0x2e, 0x00, 0x5c, 0x7b, 0xe5, 0x9f, 0xc0, 0x00, 
+-      0xe1, 0x2f, 0xff, 0x1c, 0x2e, 0x00, 0x5d, 0x05, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x2e, 0x01, 0xc9, 0x08, 0x2e, 0x01, 0xca, 0x20, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x2e, 0x01, 0xc9, 0x08, 
+-      0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 
+-      0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 
+-      0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 
+-      0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
+-      0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x02, 0xcf, 0x00, 0x00, 0x02, 0x40, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x2c, 0x00, 0x01, 0x00, 0x43, 0x6f, 0x70, 0x79, 
+-      0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x46, 0x75, 
+-      0x6a, 0x69, 0x74, 0x73, 0x75, 0x20, 0x53, 0x69, 
+-      0x65, 0x6d, 0x65, 0x6e, 0x73, 0x20, 0x26, 0x20, 
+-      0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x67, 0x65, 
+-      0x6e, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x65, 
+-      0x67, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x6d, 
+-      0x65, 0x64, 0x69, 0x61, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x57, 0x5e, 0x61, 0xa3, 
+-      0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x0c, 
+-      0x6c, 0x00, 0x00, 0x24, 0x64, 0x00, 0x00, 0x28, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x4e, 0x20, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x07, 0xd0, 0x00, 0x00, 0x07, 0xd0, 
+-      0x00, 0x00, 0x13, 0x88, 0x02, 0x02, 0x01, 0x00, 
+-      0x00, 0x00, 0x4e, 0x20, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x07, 0xd0, 0x00, 0x00, 0x07, 0xd0, 
+-      0x00, 0x00, 0x13, 0x88, 0x02, 0x02, 0x01, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x2e, 0x08, 0x05, 0xc4, 
+-      0x2e, 0x08, 0x05, 0xc4, 0x2e, 0x08, 0x05, 0xcc, 
+-      0x2e, 0x08, 0x05, 0xcc, 0x2e, 0x08, 0x05, 0xd4, 
+-      0x2e, 0x08, 0x05, 0xd4, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 
+-      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 
+-      0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 
+-      0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 
+-      0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 
+-      0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 
+-      0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 
+-      0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
+-      0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 
+-      0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 
+-      0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 
+-      0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 
+-      0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 
+-      0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 
+-      0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 
+-      0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 
+-      0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 
+-      0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 
+-      0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 
+-      0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 
+-      0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 
+-      0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 
+-      0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 
+-      0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 
+-      0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 
+-      0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 
+-      0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 
+-      0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 
+-      0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 
+-      0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 
+-      0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 
+-      0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 
+-      0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
+-      0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 
+-      0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 
+-      0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 
+-      0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 
+-      0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 
+-      0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
+-      0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 
+-      0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 
+-      0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 
+-      0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 
+-      0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 
+-      0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 
+-      0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 
+-      0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 
+-      0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 
+-      0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 
+-      0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 
+-      0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 
+-      0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 
+-      0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 
+-      0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 
+-      0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 
+-      0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 
+-      0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 
+-      0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 
+-      0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 
+-      0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 
+-      0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 
+-      0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 
+-      0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 
+-      0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 
+-      0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 
+-      0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 
+-      0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+-      0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, 
+-      0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 
+-      0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 
+-      0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+-      0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 
+-      0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 
+-      0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 
+-      0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 
+-      0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 
+-      0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 
+-      0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 
+-      0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 
+-      0x00, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 
+-      0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 
+-      0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 
+-      0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x1c, 0x36, 0x32, 0x30, 0x78, 0x30, 
+-      0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 
+-      0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 
+-      0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 
+-      0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 
+-      0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 
+-      0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 
+-      0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 
+-      0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 
+-      0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 
+-      0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 
+-      0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 
+-      0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 
+-      0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 
+-      0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 
+-      0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 
+-      0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 
+-      0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 
+-      0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 
+-      0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 
+-      0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 
+-      0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x70, 0x00, 0x00, 
+-      0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 
+-      0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 
+-      0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x70, 0x00, 0x00, 
+-      0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 
+-      0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 
+-      0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 
+-      0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 
+-      0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x38, 0x6c, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xfe, 
+-      0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 
+-      0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x36, 0x36, 
+-      0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 
+-      0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 
+-      0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 
+-      0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 
+-      0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 
+-      0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 
+-      0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 
+-      0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 
+-      0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 
+-      0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
+-      0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 
+-      0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 
+-      0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
+-      0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 
+-      0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x60, 0xe0, 0x62, 0x66, 0x6c, 0x18, 0x30, 
+-      0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00, 
+-      0x00, 0x60, 0xe0, 0x62, 0x66, 0x6c, 0x18, 0x30, 
+-      0x66, 0xce, 0x9a, 0x3f, 0x06, 0x06, 0x00, 0x00, 
+-      0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 
+-      0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 
+-      0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 
+-      0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 
+-      0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 
+-      0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 
+-      0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 
+-      0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 
+-      0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 
+-      0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+-      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
+-      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
+-      0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 
+-      0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 
+-      0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 
+-      0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 
+-      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 
+-      0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 
+-      0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 
+-      0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 
+-      0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x18, 
+-      0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 
+-      0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 
+-      0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 
+-      0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 
+-      0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 
+-      0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 
+-      0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 
+-      0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 
+-      0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 
+-      0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 
+-      0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 
+-      0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 
+-      0x18, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 
+-      0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 
+-      0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
+-      0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x7e, 
+-      0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 
+-      0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
+-      0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 
+-      0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x6c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x3c, 0x66, 0x0c, 0x18, 0x32, 0x7e, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 
+-      0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x01, 0x2e, 0x00, 0x67, 0x20, 
+-      0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 
+-      0x2e, 0x08, 0x07, 0x98, 0x00, 0x00, 0x00, 0x00, 
+-      0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 
+-      0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 
+-      0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x39, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 
+-      0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x21, 
+-      0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 
+-      0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x38, 
+-      0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x39, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0xb1, 0x0e, 0xa6, 0x06, 0x53, 
+-      0x2e, 0x08, 0x17, 0xdc, 0x00, 0x00, 0x00, 0x02, 
+-      0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 
+-      0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x19, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 
+-      0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 
+-      0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0f, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 
+-      0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 
+-      0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 
+-      0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 
+-      0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 
+-      0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 
+-      0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 
+-      0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x19, 
+-      0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x04, 0xf5, 0x11, 0x38, 0x06, 0x53, 
+-      0x2e, 0x08, 0x19, 0x0c, 0x2e, 0x08, 0x19, 0x00, 
+-      0x2e, 0x08, 0x1a, 0x30, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 
+-      0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 
+-      0x00, 0x80, 0x10, 0x80, 0x00, 0x80, 0xda, 0x80, 
+-      0x00, 0x5a, 0x51, 0xf0, 0x00, 0x36, 0x91, 0x22, 
+-      0x00, 0xf0, 0x29, 0x6e, 0x00, 0x10, 0xd2, 0x92, 
+-      0x00, 0xca, 0x6a, 0xde, 0x00, 0xa6, 0xaa, 0x10, 
+-      0x00, 0x80, 0x3b, 0x80, 0x00, 0x80, 0xbc, 0x80, 
+-      0x00, 0x80, 0x7e, 0x80, 0x00, 0xcf, 0x22, 0x73, 
+-      0x00, 0x93, 0x48, 0x5d, 0x00, 0xa2, 0x73, 0x93, 
+-      0x00, 0x25, 0xae, 0xad, 0x00, 0xa7, 0x9f, 0x60, 
+-      0x00, 0x10, 0x10, 0x10, 0x00, 0x59, 0x10, 0x10, 
+-      0x00, 0xa2, 0x10, 0x10, 0x00, 0xeb, 0x10, 0x10, 
+-      0x00, 0x10, 0x10, 0x59, 0x00, 0x59, 0x10, 0x59, 
+-      0x00, 0xa2, 0x10, 0x59, 0x00, 0xeb, 0x10, 0x59, 
+-      0x00, 0x10, 0x10, 0xa2, 0x00, 0x59, 0x10, 0xa2, 
+-      0x00, 0xa2, 0x10, 0xa2, 0x00, 0xeb, 0x10, 0xa2, 
+-      0x00, 0x10, 0x10, 0xeb, 0x00, 0x59, 0x10, 0xeb, 
+-      0x00, 0xa2, 0x10, 0xeb, 0x00, 0xeb, 0x10, 0xeb, 
+-      0x00, 0x10, 0x2f, 0x10, 0x00, 0x59, 0x2f, 0x10, 
+-      0x00, 0xa2, 0x2f, 0x10, 0x00, 0xeb, 0x2f, 0x10, 
+-      0x00, 0x10, 0x2f, 0x59, 0x00, 0x59, 0x2f, 0x59, 
+-      0x00, 0xa2, 0x2f, 0x59, 0x00, 0xeb, 0x2f, 0x59, 
+-      0x00, 0x10, 0x2f, 0xa2, 0x00, 0x59, 0x2f, 0xa2, 
+-      0x00, 0xa2, 0x2f, 0xa2, 0x00, 0xeb, 0x2f, 0xa2, 
+-      0x00, 0x10, 0x2f, 0xeb, 0x00, 0x59, 0x2f, 0xeb, 
+-      0x00, 0xa2, 0x2f, 0xeb, 0x00, 0xeb, 0x2f, 0xeb, 
+-      0x00, 0x10, 0x4e, 0x10, 0x00, 0x59, 0x4e, 0x10, 
+-      0x00, 0xa2, 0x4e, 0x10, 0x00, 0xeb, 0x4e, 0x10, 
+-      0x00, 0x10, 0x4e, 0x59, 0x00, 0x59, 0x4e, 0x59, 
+-      0x00, 0xa2, 0x4e, 0x59, 0x00, 0xeb, 0x4e, 0x59, 
+-      0x00, 0x10, 0x4e, 0xa2, 0x00, 0x59, 0x4e, 0xa2, 
+-      0x00, 0xa2, 0x4e, 0xa2, 0x00, 0xeb, 0x4e, 0xa2, 
+-      0x00, 0x10, 0x4e, 0xeb, 0x00, 0x59, 0x4e, 0xeb, 
+-      0x00, 0xa2, 0x4e, 0xeb, 0x00, 0xeb, 0x4e, 0xeb, 
+-      0x00, 0x10, 0x6d, 0x10, 0x00, 0x59, 0x6d, 0x10, 
+-      0x00, 0xa2, 0x6d, 0x10, 0x00, 0xeb, 0x6d, 0x10, 
+-      0x00, 0x10, 0x6d, 0x59, 0x00, 0x59, 0x6d, 0x59, 
+-      0x00, 0xa2, 0x6d, 0x59, 0x00, 0xeb, 0x6d, 0x59, 
+-      0x00, 0x10, 0x6d, 0xa2, 0x00, 0x59, 0x6d, 0xa2, 
+-      0x00, 0xa2, 0x6d, 0xa2, 0x00, 0xeb, 0x6d, 0xa2, 
+-      0x00, 0x10, 0x6d, 0xeb, 0x00, 0x59, 0x6d, 0xeb, 
+-      0x00, 0xa2, 0x6d, 0xeb, 0x00, 0xeb, 0x6d, 0xeb, 
+-      0x00, 0x10, 0x8c, 0x10, 0x00, 0x59, 0x8c, 0x10, 
+-      0x00, 0xa2, 0x8c, 0x10, 0x00, 0xeb, 0x8c, 0x10, 
+-      0x00, 0x10, 0x8c, 0x59, 0x00, 0x59, 0x8c, 0x59, 
+-      0x00, 0xa2, 0x8c, 0x59, 0x00, 0xeb, 0x8c, 0x59, 
+-      0x00, 0x10, 0x8c, 0xa2, 0x00, 0x59, 0x8c, 0xa2, 
+-      0x00, 0xa2, 0x8c, 0xa2, 0x00, 0xeb, 0x8c, 0xa2, 
+-      0x00, 0x10, 0x8c, 0xeb, 0x00, 0x59, 0x8c, 0xeb, 
+-      0x00, 0xa2, 0x8c, 0xeb, 0x00, 0xeb, 0x8c, 0xeb, 
+-      0x00, 0x10, 0xab, 0x10, 0x00, 0x59, 0xab, 0x10, 
+-      0x00, 0xa2, 0xab, 0x10, 0x00, 0xeb, 0xab, 0x10, 
+-      0x00, 0x10, 0xab, 0x59, 0x00, 0x59, 0xab, 0x59, 
+-      0x00, 0xa2, 0xab, 0x59, 0x00, 0xeb, 0xab, 0x59, 
+-      0x00, 0x10, 0xab, 0xa2, 0x00, 0x59, 0xab, 0xa2, 
+-      0x00, 0xa2, 0xab, 0xa2, 0x00, 0xeb, 0xab, 0xa2, 
+-      0x00, 0x10, 0xab, 0xeb, 0x00, 0x59, 0xab, 0xeb, 
+-      0x00, 0xa2, 0xab, 0xeb, 0x00, 0xeb, 0xab, 0xeb, 
+-      0x00, 0x10, 0xca, 0x10, 0x00, 0x59, 0xca, 0x10, 
+-      0x00, 0xa2, 0xca, 0x10, 0x00, 0xeb, 0xca, 0x10, 
+-      0x00, 0x10, 0xca, 0x59, 0x00, 0x59, 0xca, 0x59, 
+-      0x00, 0xa2, 0xca, 0x59, 0x00, 0xeb, 0xca, 0x59, 
+-      0x00, 0x10, 0xca, 0xa2, 0x00, 0x59, 0xca, 0xa2, 
+-      0x00, 0xa2, 0xca, 0xa2, 0x00, 0xeb, 0xca, 0xa2, 
+-      0x00, 0x10, 0xca, 0xeb, 0x00, 0x59, 0xca, 0xeb, 
+-      0x00, 0xa2, 0xca, 0xeb, 0x00, 0xeb, 0xca, 0xeb, 
+-      0x00, 0x10, 0xe9, 0x10, 0x00, 0x59, 0xe9, 0x10, 
+-      0x00, 0xa2, 0xe9, 0x10, 0x00, 0xeb, 0xe9, 0x10, 
+-      0x00, 0x10, 0xe9, 0x59, 0x00, 0x59, 0xe9, 0x59, 
+-      0x00, 0xa2, 0xe9, 0x59, 0x00, 0xeb, 0xe9, 0x59, 
+-      0x00, 0x10, 0xe9, 0xa2, 0x00, 0x59, 0xe9, 0xa2, 
+-      0x00, 0xa2, 0xe9, 0xa2, 0x00, 0xeb, 0xe9, 0xa2, 
+-      0x00, 0x10, 0xe9, 0xeb, 0x00, 0x59, 0xe9, 0xeb, 
+-      0x00, 0xa2, 0xe9, 0xeb, 0x00, 0xeb, 0xe9, 0xeb, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0xff, 0xff, 0x24, 0xc0, 0xc1, 0x11, 0x11, 0x10, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0f, 0x6d, 0xbb, 0xeb, 
+-      0x8e, 0x01, 0xea, 0x25, 0x04, 0xd0, 0x82, 0x49, 
+-      0xed, 0x4c, 0x8f, 0xc2, 0x66, 0x0b, 0x65, 0xc5, 
+-      0x0c, 0xc2, 0x41, 0x19, 0x07, 0xa8, 0x94, 0x13, 
+-      0x42, 0x09, 0x27, 0xb5, 0x32, 0x3f, 0x09, 0x98, 
+-      0x2d, 0x97, 0x14, 0x33, 0x09, 0x04, 0x64, 0x00, 
+-      0xff, 0xff, 0x24, 0xc0, 0xe0, 0x11, 0x21, 0x00, 
+-      0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x13, 0x8e, 0xf7, 0xe7, 
+-      0x6e, 0x9c, 0x0c, 0xc3, 0xd2, 0xb4, 0x05, 0x16, 
+-      0x3c, 0x8e, 0x82, 0xd4, 0x16, 0x5e, 0x9c, 0x0c, 
+-      0xc3, 0xd2, 0xb4, 0x05, 0x16, 0x3c, 0x8e, 0x82, 
+-      0xd4, 0x16, 0x5e, 0x9c, 0x0c, 0xc3, 0xd2, 0xb4, 
+-      0x05, 0x16, 0x3c, 0x8e, 0x82, 0xd4, 0x16, 0x50, 
+-      0xff, 0xff, 0x24, 0xc0, 0xd4, 0x11, 0x20, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x0d, 0x4d, 0xf8, 0xd5, 
+-      0x9e, 0x7f, 0x02, 0x22, 0x08, 0xa3, 0xbd, 0x94, 
+-      0x53, 0x16, 0x79, 0xfc, 0x08, 0x88, 0x22, 0x8e, 
+-      0xf6, 0x51, 0x4c, 0x59, 0xe7, 0xf0, 0x22, 0x20, 
+-      0x8a, 0x3b, 0xd9, 0x45, 0x31, 0x67, 0x9f, 0xc0, 
+-      0x88, 0x82, 0x28, 0xef, 0x65, 0x14, 0xc4, 0x00, 
+-      0xff, 0xff, 0x24, 0xc0, 0xe8, 0x00, 0x10, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x14, 0x6d, 0xfb, 0x1d, 
+-      0x77, 0xc1, 0x38, 0x81, 0xfb, 0xb1, 0xd7, 0x7c, 
+-      0x13, 0x88, 0x1f, 0xbb, 0x1d, 0x77, 0xc1, 0x38, 
+-      0x81, 0xfb, 0xb1, 0xd7, 0x7c, 0x13, 0x88, 0x1f, 
+-      0xbb, 0x1d, 0x77, 0xc1, 0x38, 0x81, 0xfb, 0xb1, 
+-      0xd7, 0x7c, 0x13, 0x88, 0x1f, 0x80, 0x00, 0x00, 
+-      0xff, 0xff, 0x24, 0xc0, 0x9b, 0x00, 0x20, 0x00, 
+-      0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x50, 0x3d, 0x75, 0xf7, 
+-      0x14, 0x0a, 0xc3, 0x29, 0x9f, 0x51, 0xbc, 0xfb, 
+-      0xdc, 0x7b, 0x8a, 0x05, 0x61, 0x94, 0xcf, 0xa8, 
+-      0xde, 0x7d, 0xee, 0x3d, 0xc5, 0x02, 0xb0, 0xca, 
+-      0x67, 0xd4, 0x6f, 0x3e, 0xf7, 0x1e, 0xe2, 0x81, 
+-      0x58, 0x65, 0x33, 0xea, 0x37, 0x9f, 0x7b, 0x80, 
+-      0xff, 0xff, 0x24, 0xc0, 0x12, 0xe0, 0x00, 0x00, 
+-      0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xeb, 0x50, 0xfb, 0xe7, 
+-      0x78, 0x1f, 0xde, 0xa1, 0x62, 0x99, 0x11, 0x36, 
+-      0x02, 0x00, 0x97, 0xd6, 0x69, 0x98, 0x1f, 0xde, 
+-      0xa1, 0x62, 0x99, 0x11, 0x36, 0x02, 0x00, 0x97, 
+-      0xd6, 0x69, 0x98, 0x1f, 0xde, 0xa1, 0x62, 0x99, 
+-      0x11, 0x36, 0x02, 0x00, 0x97, 0xd6, 0x69, 0x90, 
+-      0xff, 0xff, 0x24, 0xc0, 0x11, 0xba, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xdf, 0x95, 0x03, 0xa1, 
+-      0x49, 0xc5, 0x45, 0xe7, 0x96, 0xe6, 0x1d, 0xdc, 
+-      0x0d, 0x50, 0xa4, 0xe2, 0xa2, 0xf3, 0xcb, 0x73, 
+-      0x0e, 0xee, 0x06, 0xa8, 0x52, 0x71, 0x51, 0x79, 
+-      0xe5, 0xb9, 0x87, 0x77, 0x03, 0x54, 0x29, 0x38, 
+-      0xa8, 0xbc, 0xf2, 0xdc, 0xc3, 0xbb, 0x81, 0xa0, 
+-      0xff, 0xff, 0x24, 0xc0, 0x11, 0x21, 0xc3, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0xe7, 0xae, 0x35, 0x0d, 
+-      0x42, 0x14, 0xc2, 0xf9, 0x4a, 0x13, 0x55, 0xa6, 
+-      0x6e, 0xf4, 0x88, 0x53, 0x0b, 0xe5, 0x28, 0x4d, 
+-      0x56, 0x99, 0xbb, 0xd2, 0x21, 0x4c, 0x2f, 0x94, 
+-      0xa1, 0x35, 0x5a, 0x66, 0xef, 0x48, 0x85, 0x30, 
+-      0xbe, 0x52, 0x84, 0xd5, 0x69, 0x9b, 0xbd, 0x20, 
+-      0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x2e, 0x08, 0x1f, 0x48, 
+-      0x2e, 0x08, 0x1f, 0x4c, 0x2e, 0x08, 0x1f, 0x50, 
+-      0x2e, 0x08, 0x1f, 0x58, 0x2e, 0x08, 0x1f, 0x5c, 
+-      0x2e, 0x08, 0x1f, 0x60, 0x6e, 0x00, 0x01, 0x00, 
+-      0x6e, 0x00, 0x01, 0x00, 0x6e, 0x00, 0x01, 0x08, 
+-      0x6e, 0x00, 0x01, 0x0c, 0x6e, 0x00, 0x01, 0x04, 
+-      0x6e, 0x00, 0x01, 0x10, 0x6e, 0x00, 0x01, 0x14, 
+-      0x2e, 0x08, 0x60, 0x58, 0x00, 0x00, 0x00, 0x0d, 
+-      0x00, 0x00, 0x00, 0x00, 0xb0, 0x25, 0x00, 0x18, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x0d, 0x00, 
+-      0x2e, 0x08, 0x1f, 0xac, 0x2e, 0x08, 0x1f, 0xb0, 
+-      0x2e, 0x08, 0x1f, 0xb4, 0x2e, 0x08, 0x1f, 0xb8, 
+-      0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x04, 
+-      0x70, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x0c, 
+-      0x70, 0x00, 0x00, 0x10, 0x70, 0x00, 0x00, 0x30, 
+-      0x2e, 0x01, 0xcc, 0x09, 0x2e, 0x01, 0xcb, 0x99, 
+-      0x2e, 0x01, 0xcb, 0x11, 0x2e, 0x01, 0xcb, 0x09, 
+-      0x2e, 0x01, 0xcc, 0x41, 0x2e, 0x01, 0xcb, 0xd1, 
+-      0x2e, 0x01, 0xcc, 0x85, 0x2e, 0x01, 0xcc, 0x7d, 
+-      0x00, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x09, 0x80, 
+-      0x80, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 
+-      0xe0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 
+-      0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 
+-      0xfe, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 
+-      0xff, 0x80, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 
+-      0xff, 0xe0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 
+-      0xff, 0xf8, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 
+-      0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 
+-      0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xc0, 0x00, 
+-      0xff, 0xff, 0xe0, 0x00, 0xff, 0xff, 0xf0, 0x00, 
+-      0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xfc, 0x00, 
+-      0xff, 0xff, 0xfe, 0x00, 0xff, 0xff, 0xff, 0x00, 
+-      0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xc0, 
+-      0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xf0, 
+-      0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xfc, 
+-      0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 
+-      0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x7f, 0xef, 0xff, 0xff, 
+-      0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+-      0x00, 0x00, 0x00, 0x00, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-      0x2e, 0x01, 0xca, 0xf0, 0x2e, 0x01, 0xca, 0xf0, 
+-};
+-
+--- linux-2.6.0/drivers/media/dvb/ttpci/av7110.h       2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/media/dvb/ttpci/av7110.h        2003-12-28 23:22:39.000000000 -0800
+@@ -1,8 +1,6 @@
+ #ifndef _AV7110_H_
+ #define _AV7110_H_
+-#define DVB_FIRM_PATH "/lib/DVB/"
+-
+ #include <linux/interrupt.h>
+ #include <linux/socket.h>
+ #include <linux/netdevice.h>
+@@ -169,7 +167,8 @@ enum av7110_pid_command { 
+       DelPIDFilter,
+       Scan,
+       SetDescr,
+-        SetIR
++        SetIR,
++        FlushTSQueue
+ };
+                       
+ enum av7110_mpeg_command {
+@@ -544,6 +543,18 @@ struct av7110 {
+         int                 dsp_dev;
+         u32                 ir_config;
++      
++      /* firmware stuff */
++      unsigned int device_initialized;
++
++      unsigned char *bin_fw;
++      unsigned long size_fw;
++
++      unsigned char *bin_dpram;
++      unsigned long size_dpram;
++
++      unsigned char *bin_root;
++      unsigned long size_root;
+ };
+--- linux-2.6.0/drivers/media/dvb/ttpci/budget-ci.c    2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/media/dvb/ttpci/budget-ci.c     2003-12-28 23:22:40.000000000 -0800
+@@ -41,75 +41,14 @@ struct budget_ci {
+       struct tasklet_struct msp430_irq_tasklet;
+ };
+-
+-
+-#ifndef BORROWED_FROM_AV7110_H_BUT_REALLY_BELONGS_IN_SAA7146_DEFS_H
+-
+-#define DEBINOSWAP 0x000e0000
+-#define GPIO_IRQHI 0x10
+-#define GPIO_INPUT 0x00
+-
+-void gpio_set(struct saa7146_dev* saa, u8 pin, u8 data)
+-{
+-        u32 value = 0;
+-
+-        /* sanity check */
+-        if(pin > 3)
+-                return;
+-
+-        /* read old register contents */
+-        value = saa7146_read(saa, GPIO_CTRL );
+-
+-        value &= ~(0xff << (8*pin));
+-        value |= (data << (8*pin));
+-
+-        saa7146_write(saa, GPIO_CTRL, value);
+-}
+-
+-
+-
+-static int wait_for_debi_done(struct saa7146_dev *saa)
+-{
+-      int start = jiffies;
+-
+-      /* wait for registers to be programmed */
+-      while (1) {
+-              if (saa7146_read(saa, MC2) & 2)
+-                      break;
+-              if (jiffies - start > HZ / 20) {
+-                      printk ("DVB (%s): timed out while waiting"
+-                              " for registers getting programmed\n",
+-                              __FUNCTION__);
+-                      return -ETIMEDOUT;
+-              }
+-      }
+-
+-      /* wait for transfer to complete */
+-      start = jiffies;
+-      while (1) {
+-              if (!(saa7146_read(saa, PSR) & SPCI_DEBI_S))
+-                      break;
+-              saa7146_read(saa, MC2);
+-              if (jiffies - start > HZ / 4) {
+-                      printk ("DVB (%s): timed out while waiting"
+-                              " for transfer completion\n",
+-                              __FUNCTION__);
+-                      return -ETIMEDOUT;
+-              }
+-      }
+-
+-      return 0;
+-}
+-
+-
+-static u32 debiread (struct saa7146_dev *saa, u32 config, int addr, int count)
++static u32 budget_debiread4 (struct saa7146_dev *saa, u32 config, int addr, int count)
+ {
+       u32 result = 0;
+       if (count > 4 || count <= 0)
+               return 0;
+-      if (wait_for_debi_done(saa) < 0)
++      if (saa7146_wait_for_debi_done(saa) < 0)
+               return 0;
+       saa7146_write (saa, DEBI_COMMAND,
+@@ -118,7 +57,7 @@ static u32 debiread (struct saa7146_dev 
+       saa7146_write(saa, DEBI_CONFIG, config);
+       saa7146_write(saa, MC2, (2 << 16) | 2);
+-      wait_for_debi_done(saa);
++      saa7146_wait_for_debi_done(saa);
+       result = saa7146_read(saa, DEBI_AD);
+       result &= (0xffffffffUL >> ((4 - count) * 8));
+@@ -126,20 +65,6 @@ static u32 debiread (struct saa7146_dev 
+       return result;
+ }
+-
+-
+-/* DEBI during interrupt */
+-static inline u32 irdebi(struct saa7146_dev *saa, u32 config, int addr, u32 val, int count)
+-{
+-      u32 res;
+-      res = debiread(saa, config, addr, count);
+-      return res;
+-}
+-#endif
+-
+-
+-
+-
+ /* from reading the following remotes:
+    Zenith Universal 7 / TV Mode 807 / VCR Mode 837
+    Hauppauge (from NOVA-CI-s box product)
+@@ -150,7 +75,7 @@ static  u16 key_map[64] = {
+       KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8,
+       KEY_9,
+       KEY_ENTER,
+-      0,
++      KEY_RED,
+       KEY_POWER,              /* RADIO on Hauppauge */
+       KEY_MUTE,
+       0,
+@@ -162,11 +87,11 @@ static  u16 key_map[64] = {
+       0, 0, 0, 0, 0, 0, 0,
+       KEY_UP, KEY_DOWN,
+       KEY_OPTION,             /* RESERVED on Hauppauge */
+-      0,
++      KEY_BREAK,
+       /* 0x2X */
+       KEY_CHANNELUP, KEY_CHANNELDOWN,
+       KEY_PREVIOUS,           /* Prev. Ch on Zenith, SOURCE on Hauppauge */
+-      0, 0, 0,
++      0, KEY_RESTART, KEY_OK,
+       KEY_CYCLEWINDOWS,       /* MINIMIZE on Hauppauge */
+       0,
+       KEY_ENTER,              /* VCR mode on Zenith */
+@@ -177,7 +102,7 @@ static  u16 key_map[64] = {
+       KEY_MENU,               /* FULL SCREEN on Hauppauge */
+       0,
+       /* 0x3X */
+-      0,
++      KEY_SLOW,
+       KEY_PREVIOUS,           /* VCR mode on Zenith */
+       KEY_REWIND,
+       0,
+@@ -189,7 +114,7 @@ static  u16 key_map[64] = {
+       KEY_C,
+       0,
+       KEY_EXIT,
+-      0,
++      KEY_POWER2,
+       KEY_TUNER,              /* VCR mode on Zenith */
+       0,
+ };
+@@ -217,7 +142,7 @@ static void msp430_ir_interrupt (unsigne
+       struct budget_ci *budget_ci = (struct budget_ci*) data;
+       struct saa7146_dev *saa = budget_ci->budget.dev;
+       struct input_dev *dev = &budget_ci->input_dev;
+-      unsigned int code = irdebi(saa, DEBINOSWAP, 0x1234, 0, 2) >> 8;
++      unsigned int code = budget_debiread4(saa, DEBINOSWAP, 0x1234, 2) >> 8;
+       if (code & 0x40) {
+               code &= 0x3f;
+@@ -271,7 +196,7 @@ static int msp430_ir_init (struct budget
+       saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
+-      gpio_set(saa, 3, GPIO_IRQHI);
++      saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); 
+       return 0;
+ }
+@@ -283,8 +208,8 @@ static void msp430_ir_deinit (struct bud
+       struct input_dev *dev = &budget_ci->input_dev;
+       saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
+-      gpio_set(saa, 3, GPIO_INPUT);
+-      gpio_set(saa, 2, GPIO_INPUT);
++      saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
++      saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
+       if (del_timer(&dev->timer))
+               input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
+--- linux-2.6.0/drivers/media/dvb/ttpci/budget.h       2003-07-02 14:53:14.000000000 -0700
++++ 25/drivers/media/dvb/ttpci/budget.h        2003-12-28 23:22:39.000000000 -0800
+@@ -64,8 +64,8 @@ static struct saa7146_pci_extension_data
+       .ext_priv = &x_var ## _info, \
+       .ext = &budget_extension };
+-#define TS_WIDTH  (4*188)
+-#define TS_HEIGHT (1024/4)
++#define TS_WIDTH  (376)
++#define TS_HEIGHT (512)
+ #define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
+ #define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
+--- linux-2.6.0/drivers/media/dvb/ttpci/ttpci-eeprom.c 2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/media/dvb/ttpci/ttpci-eeprom.c  2003-12-28 23:22:39.000000000 -0800
+@@ -142,3 +142,9 @@ int ttpci_eeprom_parse_mac(struct dvb_i2
+ }
+ EXPORT_SYMBOL(ttpci_eeprom_parse_mac);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
++MODULE_DESCRIPTION("Decode dvb_net MAC address from EEPROM of PCI DVB cards "
++              "made by Siemens, Technotrend, Hauppauge");
++
+--- linux-2.6.0/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c      2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c       2003-12-28 23:22:40.000000000 -0800
+@@ -742,11 +742,7 @@ static void ttusb_process_frame(struct t
+       }
+ }
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-static void ttusb_iso_irq(struct urb *urb)
+-#else
+ static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs)
+-#endif
+ {
+       struct ttusb *ttusb = urb->context;
+@@ -787,9 +783,7 @@ static void ttusb_iso_irq(struct urb *ur
+                       ttusb_process_frame(ttusb, data, len);
+               }
+       }
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       usb_submit_urb(urb, GFP_ATOMIC);
+-#endif
+ }
+ static void ttusb_free_iso_urbs(struct ttusb *ttusb)
+@@ -879,13 +873,6 @@ static int ttusb_start_iso_xfer(struct t
+               }
+       }
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-      for (i = 0; i < ISO_BUF_COUNT; i++) {
+-              int next = (i + 1) % ISO_BUF_COUNT;
+-              ttusb->iso_urb[i]->next = ttusb->iso_urb[next];
+-      }
+-#endif
+-
+       for (i = 0; i < ISO_BUF_COUNT; i++) {
+               if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_KERNEL))) {
+                       ttusb_stop_iso_xfer(ttusb);
+@@ -1076,22 +1063,6 @@ static struct file_operations stc_fops =
+ };
+ #endif
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-static void *ttusb_probe(struct usb_device *udev, unsigned int ifnum,
+-                const struct usb_device_id *id)
+-{
+-      struct ttusb *ttusb;
+-      int result, channel;
+-
+-      if (ifnum != 0)
+-              return NULL;
+-
+-      dprintk("%s: TTUSB DVB connected\n", __FUNCTION__);
+-
+-      if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL)))
+-              return NULL;
+-
+-#else
+ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+ {
+       struct usb_device *udev;
+@@ -1105,8 +1076,6 @@ static int ttusb_probe(struct usb_interf
+       if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL)))
+               return -ENOMEM;
+-#endif
+-
+       memset(ttusb, 0, sizeof(struct ttusb));
+       for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel) {
+@@ -1180,35 +1149,22 @@ static int ttusb_probe(struct usb_interf
+                          S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
+                          | S_IROTH | S_IWOTH, &stc_fops, ttusb);
+ #endif
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-      return (void *) ttusb;
+-#else
++
+       usb_set_intfdata(intf, (void *) ttusb);
+       return 0;
+-#endif
+ }
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-static void ttusb_disconnect(struct usb_device *udev, void *data)
+-{
+-      struct ttusb *ttusb = data;
+-#else
+ static void ttusb_disconnect(struct usb_interface *intf)
+ {
+       struct ttusb *ttusb = usb_get_intfdata(intf);
+       usb_set_intfdata(intf, NULL);
+-#endif
+       ttusb->disconnecting = 1;
+       ttusb_stop_iso_xfer(ttusb);
+-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69))
+-#undef devfs_remove
+-#define devfs_remove(x)       devfs_unregister(ttusb->stc_devfs_handle);
+-#endif
+ #if 0
+       devfs_remove(TTUSB_BUDGET_NAME);
+ #endif
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.mod.c   2003-12-28 23:22:40.000000000 -0800
+@@ -0,0 +1,51 @@
++#include <linux/module.h>
++#include <linux/vermagic.h>
++#include <linux/compiler.h>
++
++MODULE_INFO(vermagic, VERMAGIC_STRING);
++
++static const struct modversion_info ____versions[]
++__attribute__((section("__versions"))) = {
++      { 0x98a034c6, "struct_module" },
++      { 0x1b636da2, "usb_deregister" },
++      { 0x9c655b4f, "usb_register" },
++      { 0x37a0cba, "kfree" },
++      { 0xc490b263, "dvb_unregister_adapter" },
++      { 0xf0ca7c9b, "dvb_unregister_i2c_bus" },
++      { 0x213a4973, "dvb_dmxdev_release" },
++      { 0x12014018, "dvb_net_release" },
++      { 0x616af636, "dvb_net_init" },
++      { 0x6a8b7cf7, "dvb_dmx_release" },
++      { 0x107a341d, "dvb_dmxdev_init" },
++      { 0x8fa22872, "dvb_dmx_init" },
++      { 0x5117ed38, "dvb_add_frontend_ioctls" },
++      { 0xfc17c7e7, "dvb_register_i2c_bus" },
++      { 0x3ad6f025, "dvb_register_adapter" },
++      { 0x7ac96080, "kmem_cache_alloc" },
++      { 0xa73704a, "malloc_sizes" },
++      { 0xdfcbe89f, "usb_set_interface" },
++      { 0x4f0eac15, "usb_reset_configuration" },
++      { 0x1b49153f, "usb_unlink_urb" },
++      { 0xf136026d, "usb_alloc_urb" },
++      { 0xe6f8a15d, "dma_alloc_coherent" },
++      { 0xe8d874ea, "dma_free_coherent" },
++      { 0x8ee31378, "usb_free_urb" },
++      { 0x53e02b2e, "usb_submit_urb" },
++      { 0xda02d67, "jiffies" },
++      { 0x4f7c0ba8, "dvb_dmx_swfilter_packets" },
++      { 0x9d669763, "memcpy" },
++      { 0xd22b546, "__up_wakeup" },
++      { 0x1b7d4074, "printk" },
++      { 0x85eee601, "usb_bulk_msg" },
++      { 0x28c3bbf5, "__down_failed_interruptible" },
++      { 0xd533bec7, "__might_sleep" },
++};
++
++static const char __module_depends[]
++__attribute_used__
++__attribute__((section(".modinfo"))) =
++"depends=usbcore,dvb-core";
++
++MODULE_ALIAS("usb:v0B48p1003dl*dh*dc*dsc*dp*ic*isc*ip*");
++MODULE_ALIAS("usb:v0B48p1004dl*dh*dc*dsc*dp*ic*isc*ip*");
++MODULE_ALIAS("usb:v0B48p1005dl*dh*dc*dsc*dp*ic*isc*ip*");
+--- linux-2.6.0/drivers/media/dvb/ttusb-dec/Kconfig    2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/media/dvb/ttusb-dec/Kconfig     2003-12-28 23:22:40.000000000 -0800
+@@ -1,24 +1,26 @@
+ config DVB_TTUSB_DEC
+-      tristate "Technotrend/Hauppauge USB DEC2000-T devices"
+-      depends on DVB_CORE && USB && !STANDALONE
++      tristate "Technotrend/Hauppauge USB DEC devices"
++      depends on DVB_CORE && USB && FW_LOADER
+       help
+         Support for external USB adapters designed by Technotrend and
+-        produced by Hauppauge, shipped under the brand name 'DEC2000-T'.
++        produced by Hauppauge, shipped under the brand name 'DEC2000-t'
++        and 'DEC3000-s'.
+           Even if these devices have a MPEG decoder built in, they transmit
+         only compressed MPEG data over the USB bus, so you need
+         an external software decoder to watch TV on your computer.      
+-        Say Y if you own such a device and want to use it.
++        The DEC devices require firmware in order to boot into a mode in
++        which they are slaves to the PC.  See
++        linux/Documentation/dvb/FIRMWARE for details.
++
++        The firmware can be obtained and put into the default
++        locations as follows:
+-config DVB_TTUSB_DEC_FIRMWARE_FILE
+-      string "Full pathname of dec2000t.bin firmware file"
+-      depends on DVB_TTUSB_DEC
+-      default "/etc/dvb/dec2000t.bin"
+-      help
+-        The DEC2000-T requires a firmware in order to boot into a mode in
+-        which it is a slave to the PC.  The firmware file can obtained as
+-        follows:
+           wget http://hauppauge.lightpath.net/de/dec215a.exe
+           unzip -j dec215a.exe Software/Oem/STB/App/Boot/STB_PC_T.bin
+-          mv STB_PC_T.bin /etc/dvb/dec2000t.bin
++          mv STB_PC_T.bin /usr/lib/hotplug/firmware/dec2000t.bin
++          unzip -j dec215a.exe Software/Oem/STB/App/Boot/STB_PC_S.bin
++          mv STB_PC_S.bin /usr/lib/hotplug/firmware/dec3000s.bin
++
++        Say Y if you own such a device and want to use it.
+--- linux-2.6.0/drivers/media/dvb/ttusb-dec/Makefile   2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/media/dvb/ttusb-dec/Makefile    2003-12-28 23:22:40.000000000 -0800
+@@ -1,11 +1,3 @@
+-
+-obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o dec2000_frontend.o
++obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o
+ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
+-
+-host-progs    := fdump
+-
+-$(obj)/ttusb_dec.o: $(obj)/dsp_dec2000.h
+-
+-$(obj)/dsp_dec2000.h: $(patsubst "%", %, $(CONFIG_DVB_TTUSB_DEC_FIRMWARE_FILE)) $(obj)/fdump
+-      $(obj)/fdump $< dsp_dec2000 > $@
+--- linux-2.6.0/drivers/media/dvb/ttusb-dec/ttusb_dec.c        2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/media/dvb/ttusb-dec/ttusb_dec.c 2003-12-28 23:22:40.000000000 -0800
+@@ -19,19 +19,135 @@
+  *
+  */
+-#include <linux/version.h>
++#include <asm/semaphore.h>
++#include <linux/list.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
+ #include <linux/slab.h>
++#include <linux/spinlock.h>
+ #include <linux/usb.h>
++#include <linux/version.h>
++#include <linux/interrupt.h>
++#include <linux/firmware.h>
+-#include "ttusb_dec.h"
++#include "dmxdev.h"
++#include "dvb_demux.h"
++#include "dvb_i2c.h"
++#include "dvb_filter.h"
+ #include "dvb_frontend.h"
++#include "dvb_net.h"
+ static int debug = 0;
+ #define dprintk       if (debug) printk
++#define DRIVER_NAME           "TechnoTrend/Hauppauge DEC USB"
++
++#define COMMAND_PIPE          0x03
++#define RESULT_PIPE           0x84
++#define STREAM_PIPE           0x88
++
++#define COMMAND_PACKET_SIZE   0x3c
++#define ARM_PACKET_SIZE               0x1000
++
++#define ISO_BUF_COUNT         0x04
++#define FRAMES_PER_ISO_BUF    0x04
++#define ISO_FRAME_SIZE                0x0380
++
++#define       MAX_AV_PES_LENGTH       6144
++
++#define LOF_HI                        10600000
++#define LOF_LO                        9750000
++
++enum ttusb_model {
++      TTUSB_DEC2000T,
++      TTUSB_DEC3000S
++};
++
++struct ttusb_dec {
++      enum ttusb_model                model;
++      char                            *model_name;
++      char                            *firmware_name;
++
++      /* DVB bits */
++      struct dvb_adapter              *adapter;
++      struct dmxdev                   dmxdev;
++      struct dvb_demux                demux;
++      struct dmx_frontend             frontend;
++      struct dvb_i2c_bus              i2c_bus;
++      struct dvb_net                  dvb_net;
++      struct dvb_frontend_info        *frontend_info;
++      int (*frontend_ioctl) (struct dvb_frontend *, unsigned int, void *);
++
++      u16                     pid[DMX_PES_OTHER];
++      int                     hi_band;
++
++      /* USB bits */
++      struct usb_device       *udev;
++      u8                      trans_count;
++      unsigned int            command_pipe;
++      unsigned int            result_pipe;
++      unsigned int            stream_pipe;
++      int                     interface;
++      struct semaphore        usb_sem;
++
++      void                    *iso_buffer;
++      dma_addr_t              iso_dma_handle;
++      struct urb              *iso_urb[ISO_BUF_COUNT];
++      int                     iso_stream_count;
++      struct semaphore        iso_sem;
++
++      u8                      av_pes[MAX_AV_PES_LENGTH + 4];
++      int                     av_pes_state;
++      int                     av_pes_length;
++      int                     av_pes_payload_length;
++
++      struct dvb_filter_pes2ts        a_pes2ts;
++      struct dvb_filter_pes2ts        v_pes2ts;
++
++      u8                      v_pes[16 + MAX_AV_PES_LENGTH];
++      int                     v_pes_length;
++      int                     v_pes_postbytes;
++
++      struct list_head        urb_frame_list;
++      struct tasklet_struct   urb_tasklet;
++      spinlock_t              urb_frame_list_lock;
++
++      int                     active; /* Loaded successfully */
++};
++
++struct urb_frame {
++      u8                      data[ISO_FRAME_SIZE];
++      int                     length;
++      struct list_head        urb_frame_list;
++};
++
++static struct dvb_frontend_info dec2000t_frontend_info = {
++      .name                   = "TechnoTrend/Hauppauge DEC2000-t Frontend",
++      .type                   = FE_OFDM,
++      .frequency_min          = 51000000,
++      .frequency_max          = 858000000,
++      .frequency_stepsize     = 62500,
++      .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
++              FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
++              FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
++              FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
++              FE_CAN_HIERARCHY_AUTO,
++};
++
++static struct dvb_frontend_info dec3000s_frontend_info = {
++      .name                   = "TechnoTrend/Hauppauge DEC3000-s Frontend",
++      .type                   = FE_QPSK,
++      .frequency_min          = 950000,
++      .frequency_max          = 2150000,
++      .frequency_stepsize     = 125,
++      .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
++              FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
++              FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
++              FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
++              FE_CAN_HIERARCHY_AUTO,
++};
++
+ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
+                                 int param_length, const u8 params[],
+                                 int *result_length, u8 cmd_result[])
+@@ -129,22 +245,8 @@ static void ttusb_dec_set_pids(struct tt
+                                      ttusb_dec_av_pes2ts_cb, dec->demux.feed);
+               dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
+                                      ttusb_dec_av_pes2ts_cb, dec->demux.feed);
+-}
+-
+-static int ttusb_dec_i2c_master_xfer(struct dvb_i2c_bus *i2c,
+-                                   const struct i2c_msg msgs[], int num)
+-{
+-      int result, i;
+-
+-      dprintk("%s\n", __FUNCTION__);
+-
+-      for (i = 0; i < num; i++)
+-              if ((result = ttusb_dec_send_command(i2c->data, msgs[i].addr,
+-                                                   msgs[i].len, msgs[i].buf,
+-                                                   NULL, NULL)))
+-                      return result;
+-
+-      return 0;
++      dec->v_pes_length = 0;
++      dec->v_pes_postbytes = 0;
+ }
+ static void ttusb_dec_process_av_pes(struct ttusb_dec * dec, u8 * av_pes,
+@@ -194,7 +296,8 @@ static void ttusb_dec_process_av_pes(str
+                                      &av_pes[12], prebytes);
+                               dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
+-                                                dec->v_pes_length + prebytes);
++                                                dec->v_pes_length + prebytes,
++                                                1);
+                       }
+                       if (av_pes[5] & 0x10) {
+@@ -239,13 +342,14 @@ static void ttusb_dec_process_av_pes(str
+                       if (postbytes == 0)
+                               dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
+-                                                        dec->v_pes_length);
++                                                dec->v_pes_length, 1);
+                       break;
+               }
+       case 0x02:              /* MainAudioStream */
+-              dvb_filter_pes2ts(&dec->a_pes2ts, &av_pes[8], length - 12);
++              dvb_filter_pes2ts(&dec->a_pes2ts, &av_pes[8], length - 12,
++                                av_pes[5] & 0x10);
+               break;
+       default:
+@@ -367,11 +471,7 @@ static void ttusb_dec_process_urb_frame_
+       }
+ }
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-static void ttusb_dec_process_urb(struct urb *urb)
+-#else
+ static void ttusb_dec_process_urb(struct urb *urb, struct pt_regs *ptregs)
+-#endif
+ {
+       struct ttusb_dec *dec = urb->context;
+@@ -380,6 +480,7 @@ static void ttusb_dec_process_urb(struct
+               for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {
+                       struct usb_iso_packet_descriptor *d;
++
+                       u8 *b;
+                       int length;
+                       struct urb_frame *frame;
+@@ -412,10 +513,8 @@ static void ttusb_dec_process_urb(struct
+                               urb->status);
+       }
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       if (dec->iso_stream_count)
+               usb_submit_urb(urb, GFP_ATOMIC);
+-#endif
+ }
+ static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)
+@@ -433,9 +532,8 @@ static void ttusb_dec_setup_urbs(struct 
+               urb->complete = ttusb_dec_process_urb;
+               urb->pipe = dec->stream_pipe;
+               urb->transfer_flags = URB_ISO_ASAP;
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+               urb->interval = 1;
+-#endif
++
+               urb->number_of_packets = FRAMES_PER_ISO_BUF;
+               urb->transfer_buffer_length = ISO_FRAME_SIZE *
+                                             FRAMES_PER_ISO_BUF;
+@@ -502,8 +600,8 @@ static int ttusb_dec_start_iso_xfer(stru
+               ttusb_dec_setup_urbs(dec);
+               for (i = 0; i < ISO_BUF_COUNT; i++) {
+-                      if ((result = usb_submit_urb(dec->iso_urb[i]
+-                                                  , GFP_KERNEL))) {
++                      if ((result = usb_submit_urb(dec->iso_urb[i],
++                                                   GFP_ATOMIC))) {
+                               printk("%s: failed urb submission %d: "
+                                      "error %d\n", __FUNCTION__, i, result);
+@@ -525,10 +623,6 @@ static int ttusb_dec_start_iso_xfer(stru
+       up(&dec->iso_sem);
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-      ttusb_dec_set_streaming_interface(dec);
+-#endif
+-
+       return 0;
+ }
+@@ -659,7 +753,7 @@ static int ttusb_dec_alloc_iso_urbs(stru
+       for (i = 0; i < ISO_BUF_COUNT; i++) {
+               struct urb *urb;
+-              if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_KERNEL))) {
++              if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
+                       ttusb_dec_free_iso_urbs(dec);
+                       return -ENOMEM;
+               }
+@@ -669,13 +763,6 @@ static int ttusb_dec_alloc_iso_urbs(stru
+       ttusb_dec_setup_urbs(dec);
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-      for (i = 0; i < ISO_BUF_COUNT; i++) {
+-              int next = (i + 1) % ISO_BUF_COUNT;
+-              dec->iso_urb[i]->next = dec->iso_urb[next];
+-      }
+-#endif
+-
+       return 0;
+ }
+@@ -711,20 +798,45 @@ static void ttusb_dec_init_usb(struct tt
+       ttusb_dec_alloc_iso_urbs(dec);
+ }
+-#include "dsp_dec2000.h"
+-
+ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
+ {
+       int i, j, actual_len, result, size, trans_count;
+-      u8 b0[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x61,
++      u8 b0[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                   0x00 };
+       u8 b1[] = { 0x61 };
+       u8 b[ARM_PACKET_SIZE];
+-      u32 dsp_length = htonl(sizeof(dsp_dec2000));
++      u8 *firmware = NULL;
++      size_t firmware_size = 0;
++      u32 firmware_csum = 0;
++      u32 firmware_size_nl;
++      u32 firmware_csum_nl;
++      const struct firmware *fw_entry = NULL;
+       dprintk("%s\n", __FUNCTION__);
+-      memcpy(b0, &dsp_length, 4);
++      if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) {
++              printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
++                     __FUNCTION__, dec->firmware_name);
++              return 1;
++      }
++
++      firmware = fw_entry->data;
++      firmware_size = fw_entry->size;
++
++      switch (dec->model) {
++              case TTUSB_DEC2000T:
++                      firmware_csum = 0x1bc86100;
++                      break;
++
++              case TTUSB_DEC3000S:
++                      firmware_csum = 0x00000000;
++                      break;
++      }
++
++      firmware_size_nl = htonl(firmware_size);
++      memcpy(b0, &firmware_size_nl, 4);
++      firmware_csum_nl = htonl(firmware_csum);
++      memcpy(&b0[6], &firmware_csum_nl, 4);
+       result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
+@@ -734,8 +846,8 @@ static int ttusb_dec_boot_dsp(struct ttu
+       trans_count = 0;
+       j = 0;
+-      for (i = 0; i < sizeof(dsp_dec2000); i += COMMAND_PACKET_SIZE) {
+-              size = sizeof(dsp_dec2000) - i;
++      for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
++              size = firmware_size - i;
+               if (size > COMMAND_PACKET_SIZE)
+                       size = COMMAND_PACKET_SIZE;
+@@ -743,7 +855,7 @@ static int ttusb_dec_boot_dsp(struct ttu
+               b[j + 1] = trans_count++;
+               b[j + 2] = 0xf0;
+               b[j + 3] = size;
+-              memcpy(&b[j + 4], &dsp_dec2000[i], size);
++              memcpy(&b[j + 4], &firmware[i], size);
+               j += COMMAND_PACKET_SIZE + 4;
+@@ -764,7 +876,7 @@ static int ttusb_dec_boot_dsp(struct ttu
+       return result;
+ }
+-static void ttusb_dec_init_stb(struct ttusb_dec *dec)
++static int ttusb_dec_init_stb(struct ttusb_dec *dec)
+ {
+       u8 c[COMMAND_PACKET_SIZE];
+       int c_length;
+@@ -774,9 +886,14 @@ static void ttusb_dec_init_stb(struct tt
+       result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
+-      if (!result)
++      if (!result) {
+               if (c_length != 0x0c || (c_length == 0x0c && c[9] != 0x63))
+-                      ttusb_dec_boot_dsp(dec);
++                      return ttusb_dec_boot_dsp(dec);
++              else
++                      return 0;
++      }
++      else
++              return result;
+ }
+ static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
+@@ -785,22 +902,13 @@ static int ttusb_dec_init_dvb(struct ttu
+       dprintk("%s\n", __FUNCTION__);
+-      if ((result = dvb_register_adapter(&dec->adapter, "dec2000")) < 0) {
++      if ((result = dvb_register_adapter(&dec->adapter, dec->model_name)) < 0) {
+               printk("%s: dvb_register_adapter failed: error %d\n",
+                      __FUNCTION__, result);
+               return result;
+       }
+-      if (!(dec->i2c_bus = dvb_register_i2c_bus(ttusb_dec_i2c_master_xfer,
+-                                                dec, dec->adapter, 0))) {
+-              printk("%s: dvb_register_i2c_bus failed\n", __FUNCTION__);
+-
+-              dvb_unregister_adapter(dec->adapter);
+-
+-              return -ENOMEM;
+-      }
+-
+       dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+       dec->demux.priv = (void *)dec;
+@@ -814,8 +922,6 @@ static int ttusb_dec_init_dvb(struct ttu
+               printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__,
+                      result);
+-              dvb_unregister_i2c_bus(ttusb_dec_i2c_master_xfer, dec->adapter,
+-                                     0);
+               dvb_unregister_adapter(dec->adapter);
+               return result;
+@@ -830,8 +936,6 @@ static int ttusb_dec_init_dvb(struct ttu
+                      __FUNCTION__, result);
+               dvb_dmx_release(&dec->demux);
+-              dvb_unregister_i2c_bus(ttusb_dec_i2c_master_xfer, dec->adapter,
+-                                     0);
+               dvb_unregister_adapter(dec->adapter);
+               return result;
+@@ -846,8 +950,6 @@ static int ttusb_dec_init_dvb(struct ttu
+               dvb_dmxdev_release(&dec->dmxdev);
+               dvb_dmx_release(&dec->demux);
+-              dvb_unregister_i2c_bus(ttusb_dec_i2c_master_xfer, dec->adapter,
+-                                     0);
+               dvb_unregister_adapter(dec->adapter);
+               return result;
+@@ -861,8 +963,6 @@ static int ttusb_dec_init_dvb(struct ttu
+               dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
+               dvb_dmxdev_release(&dec->dmxdev);
+               dvb_dmx_release(&dec->demux);
+-              dvb_unregister_i2c_bus(ttusb_dec_i2c_master_xfer, dec->adapter,
+-                                     0);
+               dvb_unregister_adapter(dec->adapter);
+               return result;
+@@ -882,7 +982,6 @@ static void ttusb_dec_exit_dvb(struct tt
+       dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
+       dvb_dmxdev_release(&dec->dmxdev);
+       dvb_dmx_release(&dec->demux);
+-      dvb_unregister_i2c_bus(ttusb_dec_i2c_master_xfer, dec->adapter, 0);
+       dvb_unregister_adapter(dec->adapter);
+ }
+@@ -914,35 +1013,257 @@ static void ttusb_dec_exit_tasklet(struc
+       }
+ }
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-static void *ttusb_dec_probe(struct usb_device *udev, unsigned int ifnum,
+-                           const struct usb_device_id *id)
++static int ttusb_dec_2000t_frontend_ioctl(struct dvb_frontend *fe, unsigned int cmd,
++                                void *arg)
+ {
+-      struct ttusb_dec *dec;
++      struct ttusb_dec *dec = fe->data;
+       dprintk("%s\n", __FUNCTION__);
+-      if (ifnum != 0)
+-              return NULL;
++      switch (cmd) {
++
++      case FE_GET_INFO:
++              dprintk("%s: FE_GET_INFO\n", __FUNCTION__);
++              memcpy(arg, dec->frontend_info,
++                     sizeof (struct dvb_frontend_info));
++              break;
++
++      case FE_READ_STATUS: {
++                      fe_status_t *status = (fe_status_t *)arg;
++                      dprintk("%s: FE_READ_STATUS\n", __FUNCTION__);
++                      *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
++                                FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
++                      break;
++              }
++
++      case FE_READ_BER: {
++                      u32 *ber = (u32 *)arg;
++                      dprintk("%s: FE_READ_BER\n", __FUNCTION__);
++                      *ber = 0;
++                      return -ENOSYS;
++                      break;
++              }
++
++      case FE_READ_SIGNAL_STRENGTH: {
++                      dprintk("%s: FE_READ_SIGNAL_STRENGTH\n", __FUNCTION__);
++                      *(s32 *)arg = 0xFF;
++                      return -ENOSYS;
++                      break;
++              }
++
++      case FE_READ_SNR:
++              dprintk("%s: FE_READ_SNR\n", __FUNCTION__);
++              *(s32 *)arg = 0;
++              return -ENOSYS;
++              break;
++
++      case FE_READ_UNCORRECTED_BLOCKS:
++              dprintk("%s: FE_READ_UNCORRECTED_BLOCKS\n", __FUNCTION__);
++              *(u32 *)arg = 0;
++              return -ENOSYS;
++              break;
++
++      case FE_SET_FRONTEND: {
++                      struct dvb_frontend_parameters *p =
++                              (struct dvb_frontend_parameters *)arg;
++                      u8 b[] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
++                                 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
++                                 0x00, 0xff, 0x00, 0x00, 0x00, 0xff };
++                      u32 freq;
++
++                      dprintk("%s: FE_SET_FRONTEND\n", __FUNCTION__);
++
++                      dprintk("            frequency->%d\n", p->frequency);
++                      dprintk("            symbol_rate->%d\n",
++                              p->u.qam.symbol_rate);
++                      dprintk("            inversion->%d\n", p->inversion);
++
++                      freq = htonl(p->frequency / 1000);
++                      memcpy(&b[4], &freq, sizeof (u32));
++                      ttusb_dec_send_command(dec, 0x71, sizeof(b), b, NULL, NULL);
++
++                      break;
++              }
++
++      case FE_GET_FRONTEND:
++              dprintk("%s: FE_GET_FRONTEND\n", __FUNCTION__);
++              break;
++
++      case FE_SLEEP:
++              dprintk("%s: FE_SLEEP\n", __FUNCTION__);
++              return -ENOSYS;
++              break;
++
++      case FE_INIT:
++              dprintk("%s: FE_INIT\n", __FUNCTION__);
++              break;
++
++      case FE_RESET:
++              dprintk("%s: FE_RESET\n", __FUNCTION__);
++              break;
++
++      default:
++              dprintk("%s: unknown IOCTL (0x%X)\n", __FUNCTION__, cmd);
++              return -EINVAL;
+-      if (!(dec = kmalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
+-              printk("%s: couldn't allocate memory.\n", __FUNCTION__);
+-              return NULL;
+       }
+-      memset(dec, 0, sizeof(struct ttusb_dec));
++      return 0;
++}
+-      dec->udev = udev;
++static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, unsigned int cmd,
++                                void *arg)
++{
++      struct ttusb_dec *dec = fe->data;
+-      ttusb_dec_init_usb(dec);
+-      ttusb_dec_init_stb(dec);
+-      ttusb_dec_init_dvb(dec);
+-      ttusb_dec_init_v_pes(dec);
+-      ttusb_dec_init_tasklet(dec);
++      dprintk("%s\n", __FUNCTION__);
+-      return (void *)dec;
++      switch (cmd) {
++
++      case FE_GET_INFO:
++              dprintk("%s: FE_GET_INFO\n", __FUNCTION__);
++              memcpy(arg, dec->frontend_info,
++                     sizeof (struct dvb_frontend_info));
++              break;
++
++      case FE_READ_STATUS: {
++                      fe_status_t *status = (fe_status_t *)arg;
++                      dprintk("%s: FE_READ_STATUS\n", __FUNCTION__);
++                      *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
++                                FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
++                      break;
++              }
++
++      case FE_READ_BER: {
++                      u32 *ber = (u32 *)arg;
++                      dprintk("%s: FE_READ_BER\n", __FUNCTION__);
++                      *ber = 0;
++                      return -ENOSYS;
++                      break;
++              }
++
++      case FE_READ_SIGNAL_STRENGTH: {
++                      dprintk("%s: FE_READ_SIGNAL_STRENGTH\n", __FUNCTION__);
++                      *(s32 *)arg = 0xFF;
++                      return -ENOSYS;
++                      break;
++              }
++
++      case FE_READ_SNR:
++              dprintk("%s: FE_READ_SNR\n", __FUNCTION__);
++              *(s32 *)arg = 0;
++              return -ENOSYS;
++              break;
++
++      case FE_READ_UNCORRECTED_BLOCKS:
++              dprintk("%s: FE_READ_UNCORRECTED_BLOCKS\n", __FUNCTION__);
++              *(u32 *)arg = 0;
++              return -ENOSYS;
++              break;
++
++      case FE_SET_FRONTEND: {
++                      struct dvb_frontend_parameters *p =
++                              (struct dvb_frontend_parameters *)arg;
++                      u8 b[] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
++                                 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
++                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++                                 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
++                                 0x00, 0x00, 0x00, 0x00, 0x00 };
++                      u32 freq;
++                      u32 sym_rate;
++                      u32 band;
++
++
++                      dprintk("%s: FE_SET_FRONTEND\n", __FUNCTION__);
++
++                      dprintk("            frequency->%d\n", p->frequency);
++                      dprintk("            symbol_rate->%d\n",
++                              p->u.qam.symbol_rate);
++                      dprintk("            inversion->%d\n", p->inversion);
++
++                      freq = htonl(p->frequency * 1000 + (dec->hi_band ? LOF_HI : LOF_LO));
++                      memcpy(&b[4], &freq, sizeof(u32));
++                      sym_rate = htonl(p->u.qam.symbol_rate);
++                      memcpy(&b[12], &sym_rate, sizeof(u32));
++                      band = htonl(dec->hi_band ? LOF_HI : LOF_LO);
++                      memcpy(&b[24], &band, sizeof(u32));
++
++                      ttusb_dec_send_command(dec, 0x71, sizeof(b), b, NULL, NULL);
++
++                      break;
++              }
++
++      case FE_GET_FRONTEND:
++              dprintk("%s: FE_GET_FRONTEND\n", __FUNCTION__);
++              break;
++
++      case FE_SLEEP:
++              dprintk("%s: FE_SLEEP\n", __FUNCTION__);
++              return -ENOSYS;
++              break;
++
++      case FE_INIT:
++              dprintk("%s: FE_INIT\n", __FUNCTION__);
++              break;
++
++      case FE_RESET:
++              dprintk("%s: FE_RESET\n", __FUNCTION__);
++              break;
++
++      case FE_DISEQC_SEND_MASTER_CMD:
++              dprintk("%s: FE_DISEQC_SEND_MASTER_CMD\n", __FUNCTION__);
++              break;
++
++      case FE_DISEQC_SEND_BURST:
++              dprintk("%s: FE_DISEQC_SEND_BURST\n", __FUNCTION__);
++              break;
++
++      case FE_SET_TONE: {
++                      fe_sec_tone_mode_t tone = (fe_sec_tone_mode_t)arg;
++                      dprintk("%s: FE_SET_TONE\n", __FUNCTION__);
++                      dec->hi_band = (SEC_TONE_ON == tone);
++                      break;
++              }
++
++      case FE_SET_VOLTAGE:
++              dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);
++              break;
++
++      default:
++              dprintk("%s: unknown IOCTL (0x%X)\n", __FUNCTION__, cmd);
++              return -EINVAL;
++
++      }
++
++      return 0;
++}
++
++static void ttusb_dec_init_frontend(struct ttusb_dec *dec)
++{
++      dec->i2c_bus.adapter = dec->adapter;
++
++      switch (dec->model) {
++              case TTUSB_DEC2000T:
++                      dec->frontend_info = &dec2000t_frontend_info;
++                      dec->frontend_ioctl = ttusb_dec_2000t_frontend_ioctl;
++                      break;
++
++              case TTUSB_DEC3000S:
++                      dec->frontend_info = &dec3000s_frontend_info;
++                      dec->frontend_ioctl = ttusb_dec_3000s_frontend_ioctl;
++                      break;
++      }
++
++      dvb_register_frontend(dec->frontend_ioctl, &dec->i2c_bus, (void *)dec,
++                            dec->frontend_info);
++}
++
++static void ttusb_dec_exit_frontend(struct ttusb_dec *dec)
++{
++      dvb_unregister_frontend(dec->frontend_ioctl, &dec->i2c_bus);
+ }
+-#else
++
+ static int ttusb_dec_probe(struct usb_interface *intf,
+                          const struct usb_device_id *id)
+ {
+@@ -958,48 +1279,65 @@ static int ttusb_dec_probe(struct usb_in
+               return -ENOMEM;
+       }
++      usb_set_intfdata(intf, (void *)dec);
++
+       memset(dec, 0, sizeof(struct ttusb_dec));
++      switch (id->idProduct) {
++              case 0x1006:
++                      dec->model = TTUSB_DEC3000S;
++                      dec->model_name = "DEC3000-s";
++                      dec->firmware_name = "dec3000s.bin";
++                      break;
++
++              case 0x1008:
++                      dec->model = TTUSB_DEC2000T;
++                      dec->model_name = "DEC2000-t";
++                      dec->firmware_name = "dec2000t.bin";
++                      break;
++      }
++
+       dec->udev = udev;
+       ttusb_dec_init_usb(dec);
+-      ttusb_dec_init_stb(dec);
++      if (ttusb_dec_init_stb(dec)) {
++              ttusb_dec_exit_usb(dec);
++              return 0;
++      }
+       ttusb_dec_init_dvb(dec);
++      ttusb_dec_init_frontend(dec);
+       ttusb_dec_init_v_pes(dec);
+       ttusb_dec_init_tasklet(dec);
+-      usb_set_intfdata(intf, (void *)dec);
++      dec->active = 1;
++
+       ttusb_dec_set_streaming_interface(dec);
+       return 0;
+ }
+-#endif
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+-static void ttusb_dec_disconnect(struct usb_device *udev, void *data)
+-{
+-      struct ttusb_dec *dec = data;
+-#else
+ static void ttusb_dec_disconnect(struct usb_interface *intf)
+ {
+       struct ttusb_dec *dec = usb_get_intfdata(intf);
+       usb_set_intfdata(intf, NULL);
+-#endif
+       dprintk("%s\n", __FUNCTION__);
++      if (dec->active) {
+       ttusb_dec_exit_tasklet(dec);
+       ttusb_dec_exit_usb(dec);
++              ttusb_dec_exit_frontend(dec);
+       ttusb_dec_exit_dvb(dec);
++      }
+       kfree(dec);
+ }
+ static struct usb_device_id ttusb_dec_table[] = {
+-      {USB_DEVICE(0x0b48, 0x1006)},   /* Unconfirmed */
+-      {USB_DEVICE(0x0b48, 0x1007)},   /* Unconfirmed */
+-      {USB_DEVICE(0x0b48, 0x1008)},   /* DEC 2000 t */
++      {USB_DEVICE(0x0b48, 0x1006)},   /* DEC3000-s */
++      /*{USB_DEVICE(0x0b48, 0x1007)},    Unconfirmed */
++      {USB_DEVICE(0x0b48, 0x1008)},   /* DEC2000-t */
+       {}
+ };
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/media/dvb/ttusb-dec/ttusb_dec.mod.c     2003-12-28 23:22:40.000000000 -0800
+@@ -0,0 +1,13 @@
++#include <linux/module.h>
++#include <linux/vermagic.h>
++#include <linux/compiler.h>
++
++MODULE_INFO(vermagic, VERMAGIC_STRING);
++
++static const char __module_depends[]
++__attribute_used__
++__attribute__((section(".modinfo"))) =
++"depends=dvb-core";
++
++MODULE_ALIAS("usb:v0B48p1006dl*dh*dc*dsc*dp*ic*isc*ip*");
++MODULE_ALIAS("usb:v0B48p1008dl*dh*dc*dsc*dp*ic*isc*ip*");
+--- linux-2.6.0/drivers/media/video/video-buf.c        2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/media/video/video-buf.c 2003-12-28 23:22:12.000000000 -0800
+@@ -1078,7 +1078,7 @@ videobuf_vm_close(struct vm_area_struct 
+  */
+ static struct page*
+ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
+-                int write_access)
++                int *type)
+ {
+       struct page *page;
+@@ -1090,6 +1090,8 @@ videobuf_vm_nopage(struct vm_area_struct
+       if (!page)
+               return NOPAGE_OOM;
+       clear_user_page(page_address(page), vaddr, page);
++      if (type)
++              *type = VM_FAULT_MINOR;
+       return page;
+ }
+--- linux-2.6.0/drivers/message/i2o/i2o_block.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/message/i2o/i2o_block.c 2003-12-28 23:21:17.000000000 -0800
+@@ -885,10 +885,10 @@ static void i2o_block_biosparam(
+  *    Issue device specific ioctl calls.
+  */
+-static int i2ob_ioctl(struct inode *inode, struct file *file,
++static int i2ob_ioctl(struct block_device *bdev, struct file *file,
+                    unsigned int cmd, unsigned long arg)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
++      struct gendisk *disk = bdev->bd_disk;
+       struct i2ob_device *dev = disk->private_data;
+       /* Anyone capable of this syscall can do *real bad* things */
+@@ -901,7 +901,7 @@ static int i2ob_ioctl(struct inode *inod
+                       struct hd_geometry g;
+                       i2o_block_biosparam(get_capacity(disk), 
+                                       &g.cylinders, &g.heads, &g.sectors);
+-                      g.start = get_start_sect(inode->i_bdev);
++                      g.start = get_start_sect(bdev);
+                       return copy_to_user((void *)arg,&g, sizeof(g))?-EFAULT:0;
+               }
+               
+@@ -927,9 +927,8 @@ static int i2ob_ioctl(struct inode *inod
+  *    Close the block device down
+  */
+  
+-static int i2ob_release(struct inode *inode, struct file *file)
++static int i2ob_release(struct gendisk *disk)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct i2ob_device *dev = disk->private_data;
+       /*
+@@ -999,9 +998,9 @@ static int i2ob_release(struct inode *in
+  *    Open the block device.
+  */
+  
+-static int i2ob_open(struct inode *inode, struct file *file)
++static int i2ob_open(struct block_device *bdev, struct file *file)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
++      struct gendisk *disk = bdev->bd_disk;
+       struct i2ob_device *dev = disk->private_data;
+       if(!dev->i2odev)        
+--- linux-2.6.0/drivers/mtd/chips/jedec_probe.c        2003-06-14 12:18:51.000000000 -0700
++++ 25/drivers/mtd/chips/jedec_probe.c 2003-12-28 23:23:01.000000000 -0800
+@@ -8,6 +8,7 @@
+ #include <linux/config.h>
+ #include <linux/module.h>
++#include <linux/init.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <asm/io.h>
+--- linux-2.6.0/drivers/mtd/maps/pcmciamtd.c   2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/mtd/maps/pcmciamtd.c    2003-12-28 23:22:54.000000000 -0800
+@@ -125,7 +125,7 @@ static caddr_t remap_window(struct map_i
+               DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
+                     dev->offset, mrq.CardOffset);
+               mrq.Page = 0;
+-              if( (ret = CardServices(MapMemPage, win, &mrq)) != CS_SUCCESS) {
++              if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) {
+                       cs_error(dev->link.handle, MapMemPage, ret);
+                       return NULL;
+               }
+@@ -332,7 +332,7 @@ static void pcmciamtd_set_vpp(struct map
+       mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0;
+       DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
+-      ret = CardServices(ModifyConfiguration, link->handle, &mod);
++      ret = pcmcia_modify_configuration(link->handle, &mod);
+       if(ret != CS_SUCCESS) {
+               cs_error(link->handle, ModifyConfiguration, ret);
+       }
+@@ -355,9 +355,9 @@ static void pcmciamtd_release(dev_link_t
+                       iounmap(dev->win_base);
+                       dev->win_base = NULL;
+               }
+-              CardServices(ReleaseWindow, link->win);
++              pcmcia_release_window(link->win);
+       }
+-      CardServices(ReleaseConfiguration, link->handle);
++      pcmcia_release_configuration(link->handle);
+       link->state &= ~DEV_CONFIG;
+ }
+@@ -375,14 +375,14 @@ static void card_settings(struct pcmciam
+       tuple.TupleOffset = 0;
+       tuple.DesiredTuple = RETURN_FIRST_TUPLE;
+-      rc = CardServices(GetFirstTuple, link->handle, &tuple);
++      rc = pcmcia_get_first_tuple(link->handle, &tuple);
+       while(rc == CS_SUCCESS) {
+-              rc = CardServices(GetTupleData, link->handle, &tuple);
++              rc = pcmcia_get_tuple_data(link->handle, &tuple);
+               if(rc != CS_SUCCESS) {
+                       cs_error(link->handle, GetTupleData, rc);
+                       break;
+               }
+-              rc = CardServices(ParseTuple, link->handle, &tuple, &parse);
++              rc = pcmcia_parse_tuple(link->handle, &tuple, &parse);
+               if(rc != CS_SUCCESS) {
+                       cs_error(link->handle, ParseTuple, rc);
+                       break;
+@@ -455,7 +455,7 @@ static void card_settings(struct pcmciam
+                       DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
+               }
+               
+-              rc = CardServices(GetNextTuple, link->handle, &tuple, &parse);
++              rc = pcmcia_get_next_tuple(link->handle, &tuple);
+       }
+       if(!dev->pcmcia_map.size)
+               dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
+@@ -489,8 +489,8 @@ static void card_settings(struct pcmciam
+  * MTD device available to the system.
+  */
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void pcmciamtd_config(dev_link_t *link)
+ {
+@@ -512,7 +512,7 @@ static void pcmciamtd_config(dev_link_t 
+       link->state |= DEV_CONFIG;
+       DEBUG(2, "Validating CIS");
+-      ret = CardServices(ValidateCIS, link->handle, &cisinfo);
++      ret = pcmcia_validate_cis(link->handle, &cisinfo);
+       if(ret != CS_SUCCESS) {
+               cs_error(link->handle, GetTupleData, ret);
+       } else {
+@@ -547,8 +547,7 @@ static void pcmciamtd_config(dev_link_t 
+               int ret;
+               DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
+                     req.Size >> 10, req.AccessSpeed);
+-              link->win = (window_handle_t)link->handle;
+-              ret = CardServices(RequestWindow, &link->win, &req);
++              ret = pcmcia_request_window(&link->handle, &req, &link->win);
+               DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
+               if(ret) {
+                       req.Size >>= 1;
+@@ -569,7 +568,7 @@ static void pcmciamtd_config(dev_link_t 
+       DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
+               
+       /* Get write protect status */
+-      CS_CHECK(GetStatus, link->handle, &status);
++      CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status));
+       DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx",
+             status.CardState, (unsigned long)link->win);
+       dev->win_base = ioremap(req.Base, req.Size);
+@@ -586,7 +585,7 @@ static void pcmciamtd_config(dev_link_t 
+       dev->pcmcia_map.map_priv_2 = (unsigned long)link->win;
+       DEBUG(2, "Getting configuration");
+-      CS_CHECK(GetConfigurationInfo, link->handle, &t);
++      CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link->handle, &t));
+       DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2);
+       dev->vpp = (vpp) ? vpp : t.Vpp1;
+       link->conf.Attributes = 0;
+@@ -608,7 +607,7 @@ static void pcmciamtd_config(dev_link_t 
+       link->conf.ConfigIndex = 0;
+       link->conf.Present = t.Present;
+       DEBUG(2, "Setting Configuration");
+-      ret = CardServices(RequestConfiguration, link->handle, &link->conf);
++      ret = pcmcia_request_configuration(link->handle, &link->conf);
+       if(ret != CS_SUCCESS) {
+               cs_error(link->handle, RequestConfiguration, ret);
+       }
+@@ -757,7 +756,7 @@ static void pcmciamtd_detach(dev_link_t 
+       if (link->handle) {
+               int ret;
+               DEBUG(2, "Deregistering with card services");
+-              ret = CardServices(DeregisterClient, link->handle);
++              ret = pcmcia_deregister_client(link->handle);
+               if (ret != CS_SUCCESS)
+                       cs_error(link->handle, DeregisterClient, ret);
+       }
+@@ -804,7 +803,7 @@ static dev_link_t *pcmciamtd_attach(void
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+       DEBUG(2, "Calling RegisterClient");
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != 0) {
+               cs_error(link->handle, RegisterClient, ret);
+               pcmciamtd_detach(link);
+--- linux-2.6.0/drivers/mtd/mtd_blkdevs.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/mtd/mtd_blkdevs.c       2003-12-28 23:21:17.000000000 -0800
+@@ -141,14 +141,12 @@ static void mtd_blktrans_request(struct 
+ }
+-int blktrans_open(struct inode *i, struct file *f)
++static int blktrans_open(struct block_device *bdev, struct file *f)
+ {
+-      struct mtd_blktrans_dev *dev;
+-      struct mtd_blktrans_ops *tr;
++      struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
++      struct mtd_blktrans_ops *tr = dev->tr;
+       int ret = -ENODEV;
+-      dev = i->i_bdev->bd_disk->private_data;
+-      tr = dev->tr;
+       if (!try_module_get(dev->mtd->owner))
+               goto out;
+@@ -172,15 +170,12 @@ int blktrans_open(struct inode *i, struc
+       return ret;
+ }
+-int blktrans_release(struct inode *i, struct file *f)
++static int blktrans_release(struct gendisk *disk)
+ {
+-      struct mtd_blktrans_dev *dev;
+-      struct mtd_blktrans_ops *tr;
++      struct mtd_blktrans_dev *dev = disk->private_data;
++      struct mtd_blktrans_ops *tr = dev->tr;
+       int ret = 0;
+-      dev = i->i_bdev->bd_disk->private_data;
+-      tr = dev->tr;
+-
+       if (tr->release)
+               ret = tr->release(dev);
+@@ -194,10 +189,10 @@ int blktrans_release(struct inode *i, st
+ }
+-static int blktrans_ioctl(struct inode *inode, struct file *file, 
++static int blktrans_ioctl(struct block_device *bdev, struct file *file,
+                             unsigned int cmd, unsigned long arg)
+ {
+-      struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
++      struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
+       struct mtd_blktrans_ops *tr = dev->tr;
+       switch (cmd) {
+@@ -217,7 +212,7 @@ static int blktrans_ioctl(struct inode *
+                       if (ret)
+                               return ret;
+-                      g.start = get_start_sect(inode->i_bdev);
++                      g.start = get_start_sect(bdev);
+                       if (copy_to_user((void *)arg, &g, sizeof(g)))
+                               return -EFAULT;
+                       return 0;
+--- linux-2.6.0/drivers/net/3c501.c    2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/net/3c501.c     2003-12-28 23:21:00.000000000 -0800
+@@ -136,17 +136,14 @@ static const char version[] =
+ #include "3c501.h"
+-/* A zero-terminated list of I/O addresses to be probed.
+-   The 3c501 can be at many locations, but here are the popular ones. */
+-static unsigned int netcard_portlist[] __initdata = { 
+-      0x280, 0x300, 0
+-};
+-
+-
+ /*
+  *    The boilerplate probe code.
+  */
++static int io=0x280;
++static int irq=5;
++static int mem_start;
++
+ /**
+  * el1_probe:         -       probe for a 3c501
+  * @dev: The device structure passed in to probe. 
+@@ -160,23 +157,47 @@ static unsigned int netcard_portlist[] _
+  * probe and failing to find anything.
+  */
+  
+-int __init el1_probe(struct net_device *dev)
++struct net_device * __init el1_probe(int unit)
+ {
+-      int i;
+-      int base_addr = dev->base_addr;
++      struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
++      static unsigned ports[] = { 0x280, 0x300, 0};
++      unsigned *port;
++      int err = 0;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++              io = dev->base_addr;
++              irq = dev->irq;
++              mem_start = dev->mem_start & 7;
++      }
+       SET_MODULE_OWNER(dev);
+-      if (base_addr > 0x1ff)  /* Check a single specified location. */
+-              return el1_probe1(dev, base_addr);
+-      else if (base_addr != 0)        /* Don't probe at all. */
+-              return -ENXIO;
+-
+-      for (i = 0; netcard_portlist[i]; i++)
+-              if (el1_probe1(dev, netcard_portlist[i]) == 0)
+-                      return 0;
+-
+-      return -ENODEV;
++      if (io > 0x1ff) {       /* Check a single specified location. */
++              err = el1_probe1(dev, io);
++      } else if (io != 0) {
++              err = -ENXIO;           /* Don't probe at all. */
++      } else {
++              for (port = ports; *port && el1_probe1(dev, *port); port++)
++                      ;
++              if (!*port)
++                      err = -ENODEV;
++      }
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      release_region(dev->base_addr, EL1_IO_EXTENT);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /**
+@@ -240,6 +261,8 @@ static int __init el1_probe1(struct net_
+        *      high.
+        */
++      dev->irq = irq;
++
+       if (dev->irq < 2)
+       {
+               unsigned long irq_mask;
+@@ -267,8 +290,8 @@ static int __init el1_probe1(struct net_
+       dev->base_addr = ioaddr;
+       memcpy(dev->dev_addr, station_addr, ETH_ALEN);
+-      if (dev->mem_start & 0xf)
+-              el_debug = dev->mem_start & 0x7;
++      if (mem_start & 0xf)
++              el_debug = mem_start & 0x7;
+       if (autoirq)
+               dev->irq = autoirq;
+@@ -282,17 +305,7 @@ static int __init el1_probe1(struct net_
+       if (el_debug)
+               printk(KERN_DEBUG "%s", version);
+-      /*
+-       *      Initialize the device structure.
+-       */
+-
+-      dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-      if (dev->priv == NULL) {
+-              release_region(ioaddr, EL1_IO_EXTENT);
+-              return -ENOMEM;
+-      }
+       memset(dev->priv, 0, sizeof(struct net_local));
+-
+       lp=dev->priv;
+       spin_lock_init(&lp->lock);
+       
+@@ -308,13 +321,6 @@ static int __init el1_probe1(struct net_
+       dev->get_stats = &el1_get_stats;
+       dev->set_multicast_list = &set_multicast_list;
+       dev->ethtool_ops = &netdev_ethtool_ops;
+-
+-      /*
+-       *      Setup the generic properties
+-       */
+-
+-      ether_setup(dev);
+-
+       return 0;
+ }
+@@ -884,14 +890,8 @@ static struct ethtool_ops netdev_ethtool
+ #ifdef MODULE
+-static struct net_device dev_3c501 = {
+-      .init           = el1_probe,
+-      .base_addr      = 0x280,
+-      .irq            = 5,
+-};
++static struct net_device *dev_3c501;
+-static int io=0x280;
+-static int irq=5;
+ MODULE_PARM(io, "i");
+ MODULE_PARM(irq, "i");
+ MODULE_PARM_DESC(io, "EtherLink I/O base address");
+@@ -911,10 +911,9 @@ MODULE_PARM_DESC(irq, "EtherLink IRQ num
+  
+ int init_module(void)
+ {
+-      dev_3c501.irq=irq;
+-      dev_3c501.base_addr=io;
+-      if (register_netdev(&dev_3c501) != 0)
+-              return -EIO;
++      dev_3c501 = el1_probe(-1);
++      if (IS_ERR(dev_3c501))
++              return PTR_ERR(dev_3c501);
+       return 0;
+ }
+@@ -927,19 +926,10 @@ int init_module(void)
+  
+ void cleanup_module(void)
+ {
+-      unregister_netdev(&dev_3c501);
+-
+-      /*
+-       *      Free up the private structure, or leak memory :-)
+-       */
+-
+-      kfree(dev_3c501.priv);
+-      dev_3c501.priv = NULL;  /* gets re-allocated by el1_probe1 */
+-
+-      /*
+-       *      If we don't do this, we can't re-insmod it later.
+-       */
+-      release_region(dev_3c501.base_addr, EL1_IO_EXTENT);
++      struct net_device *dev = dev_3c501;
++      unregister_netdev(dev);
++      release_region(dev->base_addr, EL1_IO_EXTENT);
++      free_netdev(dev);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/3c501.h    2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/3c501.h     2003-12-28 23:21:00.000000000 -0800
+@@ -3,7 +3,6 @@
+  *    Index to functions.
+  */
+-int el1_probe(struct net_device *dev);
+ static int  el1_probe1(struct net_device *dev, int ioaddr);
+ static int  el_open(struct net_device *dev);
+ static void el_timeout(struct net_device *dev);
+--- linux-2.6.0/drivers/net/3c503.c    2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/net/3c503.c     2003-12-28 23:21:00.000000000 -0800
+@@ -60,7 +60,6 @@ static const char version[] =
+ #include "3c503.h"
+ #define WRD_COUNT 4
+-int el2_probe(struct net_device *dev);
+ static int el2_pio_probe(struct net_device *dev);
+ static int el2_probe1(struct net_device *dev, int ioaddr);
+@@ -90,11 +89,11 @@ static struct ethtool_ops netdev_ethtool
+    If the ethercard isn't found there is an optional probe for
+    ethercard jumpered to programmed-I/O mode.
+    */
+-int __init 
+-el2_probe(struct net_device *dev)
++static int __init do_el2_probe(struct net_device *dev)
+ {
+     int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
+     int base_addr = dev->base_addr;
++    int irq = dev->irq;
+     SET_MODULE_OWNER(dev);
+     
+@@ -104,16 +103,13 @@ el2_probe(struct net_device *dev)
+       return -ENXIO;
+     for (addr = addrs; *addr; addr++) {
+-      int i;
+-      unsigned int base_bits = isa_readb(*addr);
+-      /* Find first set bit. */
+-      for(i = 7; i >= 0; i--, base_bits >>= 1)
+-          if (base_bits & 0x1)
+-              break;
+-      if (base_bits != 1)
++      unsigned base_bits = isa_readb(*addr);
++      int i = ffs(base_bits) - 1;
++      if (i == -1 || base_bits != (1 << i))
+           continue;
+       if (el2_probe1(dev, netcard_portlist[i]) == 0)
+           return 0;
++      dev->irq = irq;
+     }
+ #if ! defined(no_probe_nonshared_memory)
+     return el2_pio_probe(dev);
+@@ -128,20 +124,54 @@ static int __init 
+ el2_pio_probe(struct net_device *dev)
+ {
+     int i;
+-    int base_addr = dev ? dev->base_addr : 0;
++    int base_addr = dev->base_addr;
++    int irq = dev->irq;
+     if (base_addr > 0x1ff)    /* Check a single specified location. */
+       return el2_probe1(dev, base_addr);
+     else if (base_addr != 0)  /* Don't probe at all. */
+       return -ENXIO;
+-    for (i = 0; netcard_portlist[i]; i++)
++    for (i = 0; netcard_portlist[i]; i++) {
+       if (el2_probe1(dev, netcard_portlist[i]) == 0)
+           return 0;
++      dev->irq = irq;
++    }
+     return -ENODEV;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      /* NB: el2_close() handles free_irq */
++      release_region(dev->base_addr, EL2_IO_EXTENT);
++}
++
++struct net_device * __init el2_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_el2_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ /* Probe for the Etherlink II card at I/O port base IOADDR,
+    returning non-zero on success.  If found, set the station
+    address and memory parameters in DEVICE. */
+@@ -152,15 +182,19 @@ el2_probe1(struct net_device *dev, int i
+     static unsigned version_printed;
+     unsigned long vendor_id;
+-    /* FIXME: code reads ioaddr + 0x400, we request ioaddr + 16 */
+     if (!request_region(ioaddr, EL2_IO_EXTENT, dev->name))
+       return -EBUSY;
++    if (!request_region(ioaddr + 0x400, 8, dev->name)) {
++      retval = -EBUSY;
++      goto out;
++    }
++
+     /* Reset and/or avoid any lurking NE2000 */
+     if (inb(ioaddr + 0x408) == 0xff) {
+       mdelay(1);
+       retval = -ENODEV;
+-      goto out;
++      goto out1;
+     }
+     /* We verify that it's a 3C503 board by checking the first three octets
+@@ -171,7 +205,7 @@ el2_probe1(struct net_device *dev, int i
+     if (   (iobase_reg  & (iobase_reg - 1))
+       || (membase_reg & (membase_reg - 1))) {
+       retval = -ENODEV;
+-      goto out;
++      goto out1;
+     }
+     saved_406 = inb_p(ioaddr + 0x406);
+     outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */
+@@ -184,19 +218,13 @@ el2_probe1(struct net_device *dev, int i
+       /* Restore the register we frobbed. */
+       outb(saved_406, ioaddr + 0x406);
+       retval = -ENODEV;
+-      goto out;
++      goto out1;
+     }
+     if (ei_debug  &&  version_printed++ == 0)
+       printk(version);
+     dev->base_addr = ioaddr;
+-    /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-    if (ethdev_init(dev)) {
+-      printk ("3c503: unable to allocate memory for dev->priv.\n");
+-      retval = -ENOMEM;
+-      goto out;
+-    }
+     printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
+@@ -322,7 +350,10 @@ el2_probe1(struct net_device *dev, int i
+       printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
+              dev->name, ei_status.name, (wordlength+1)<<3);
+     }
++    release_region(ioaddr + 0x400, 8);
+     return 0;
++out1:
++    release_region(ioaddr + 0x400, 8);
+ out:
+     release_region(ioaddr, EL2_IO_EXTENT);
+     return retval;
+@@ -633,7 +664,7 @@ static struct ethtool_ops netdev_ethtool
+ #ifdef MODULE
+ #define MAX_EL2_CARDS 4       /* Max number of EL2 cards per module */
+-static struct net_device dev_el2[MAX_EL2_CARDS];
++static struct net_device *dev_el2[MAX_EL2_CARDS];
+ static int io[MAX_EL2_CARDS];
+ static int irq[MAX_EL2_CARDS];
+ static int xcvr[MAX_EL2_CARDS];       /* choose int. or ext. xcvr */
+@@ -651,28 +682,34 @@ ISA device autoprobes on a running machi
+ int
+ init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_el2[this_dev];
+-              dev->irq = irq[this_dev];
+-              dev->base_addr = io[this_dev];
+-              dev->mem_end = xcvr[this_dev];  /* low 4bits = xcvr sel. */
+-              dev->init = el2_probe;
+               if (io[this_dev] == 0)  {
+                       if (this_dev != 0) break; /* only autoprobe 1st one */
+                       printk(KERN_NOTICE "3c503.c: Presently autoprobing (not recommended) for a single card.\n");
+               }
+-              if (register_netdev(dev) != 0) {
+-                      printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
+-                      if (found != 0) {       /* Got at least one. */
+-                              return 0;
++              dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
++              dev->irq = irq[this_dev];
++              dev->base_addr = io[this_dev];
++              dev->mem_end = xcvr[this_dev];  /* low 4bits = xcvr sel. */
++              if (do_el2_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_el2[found++] = dev;
++                              continue;
+                       }
+-                      return -ENXIO;
++                      cleanup_card(dev);
+               }
+-              found++;
++              free_netdev(dev);
++              printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
++              break;
+       }
+-      return 0;
++      if (found)
++              return 0;
++      return -ENXIO;
+ }
+ void
+@@ -681,13 +718,11 @@ cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_el2[this_dev];
+-              if (dev->priv != NULL) {
+-                      void *priv = dev->priv;
+-                      /* NB: el2_close() handles free_irq */
+-                      release_region(dev->base_addr, EL2_IO_EXTENT);
++              struct net_device *dev = dev_el2[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(priv);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/3c505.c    2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/net/3c505.c     2003-12-28 23:21:00.000000000 -0800
+@@ -1293,42 +1293,6 @@ static void elp_set_mc_list(struct net_d
+       }
+ }
+-/******************************************************
+- *
+- * initialise Etherlink Plus board
+- *
+- ******************************************************/
+-
+-static inline void elp_init(struct net_device *dev)
+-{
+-      elp_device *adapter = dev->priv;
+-
+-      /*
+-       * set ptrs to various functions
+-       */
+-      dev->open = elp_open;                           /* local */
+-      dev->stop = elp_close;                          /* local */
+-      dev->get_stats = elp_get_stats;                 /* local */
+-      dev->hard_start_xmit = elp_start_xmit;          /* local */
+-      dev->tx_timeout = elp_timeout;                  /* local */
+-      dev->watchdog_timeo = 10*HZ;
+-      dev->set_multicast_list = elp_set_mc_list;      /* local */
+-      dev->ethtool_ops = &netdev_ethtool_ops;         /* local */
+-
+-      /* Setup the generic properties */
+-      ether_setup(dev);
+-
+-      /*
+-       * setup ptr to adapter specific information
+-       */
+-      memset(&(adapter->stats), 0, sizeof(struct net_device_stats));
+-
+-      /*
+-       * memory information
+-       */
+-      dev->mem_start = dev->mem_end = 0;
+-}
+-
+ /************************************************************
+  *
+  * A couple of tests to see if there's 3C505 or not
+@@ -1442,12 +1406,13 @@ static int __init elp_autodetect(struct 
+  * work at all if it was in a weird state).
+  */
+-int __init elplus_probe(struct net_device *dev)
++static int __init elplus_setup(struct net_device *dev)
+ {
+-      elp_device *adapter;
++      elp_device *adapter = dev->priv;
+       int i, tries, tries1, okay;
+       unsigned long timeout;
+       unsigned long cookie = 0;
++      int err = -ENODEV;
+       SET_MODULE_OWNER(dev);
+@@ -1456,17 +1421,8 @@ int __init elplus_probe(struct net_devic
+        */
+       dev->base_addr = elp_autodetect(dev);
+-      if (!(dev->base_addr))
+-              return -ENODEV;
+-
+-      /*
+-       * setup ptr to adapter specific information
+-       */
+-      adapter = (elp_device *) (dev->priv = kmalloc(sizeof(elp_device), GFP_KERNEL));
+-      if (adapter == NULL) {
+-              printk(KERN_ERR "%s: out of memory\n", dev->name);
++      if (!dev->base_addr)
+               return -ENODEV;
+-      }
+       adapter->send_pcb_semaphore = 0;
+@@ -1544,8 +1500,7 @@ int __init elplus_probe(struct net_devic
+               outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev);
+       }
+       printk(KERN_ERR "%s: failed to initialise 3c505\n", dev->name);
+-      release_region(dev->base_addr, ELP_IO_EXTENT);
+-      return -ENODEV;
++      goto out;
+       okay:
+       if (dev->irq) {         /* Is there a preset IRQ? */
+@@ -1560,14 +1515,14 @@ int __init elplus_probe(struct net_devic
+       case 0:
+               printk(KERN_ERR "%s: IRQ probe failed: check 3c505 jumpers.\n",
+                      dev->name);
+-              return -ENODEV;
++              goto out;
+       case 1:
+       case 6:
+       case 8:
+       case 13:
+               printk(KERN_ERR "%s: Impossible IRQ %d reported by probe_irq_off().\n",
+                      dev->name, dev->irq);
+-              return -ENODEV;
++                     goto out;
+       }
+       /*
+        *  Now we have the IRQ number so we can disable the interrupts from
+@@ -1636,16 +1591,48 @@ int __init elplus_probe(struct net_devic
+               printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
+       }
+-      /*
+-       * initialise the device
+-       */
+-      elp_init(dev);
++      dev->open = elp_open;                           /* local */
++      dev->stop = elp_close;                          /* local */
++      dev->get_stats = elp_get_stats;                 /* local */
++      dev->hard_start_xmit = elp_start_xmit;          /* local */
++      dev->tx_timeout = elp_timeout;                  /* local */
++      dev->watchdog_timeo = 10*HZ;
++      dev->set_multicast_list = elp_set_mc_list;      /* local */
++      dev->ethtool_ops = &netdev_ethtool_ops;         /* local */
++
++      memset(&(adapter->stats), 0, sizeof(struct net_device_stats));
++      dev->mem_start = dev->mem_end = 0;
++
++      err = register_netdev(dev);
++      if (err)
++              goto out;
+       return 0;
++out:
++      release_region(dev->base_addr, ELP_IO_EXTENT);
++      return err;
++}
++
++struct net_device * __init elplus_probe(int unit)
++{
++      struct net_device *dev = alloc_etherdev(sizeof(elp_device));
++      int err;
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = elplus_setup(dev);
++      if (err) {
++              free_netdev(dev);
++              return ERR_PTR(err);
++      }
++      return dev;
+ }
+ #ifdef MODULE
+-static struct net_device dev_3c505[ELP_MAX_CARDS];
++static struct net_device *dev_3c505[ELP_MAX_CARDS];
+ static int io[ELP_MAX_CARDS];
+ static int irq[ELP_MAX_CARDS];
+ static int dma[ELP_MAX_CARDS];
+@@ -1661,10 +1648,12 @@ int init_module(void)
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_3c505[this_dev];
++              struct net_device *dev = alloc_etherdev(sizeof(elp_device));
++              if (!dev)
++                      break;
++
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+-              dev->init = elplus_probe;
+               if (dma[this_dev]) {
+                       dev->dma = dma[this_dev];
+               } else {
+@@ -1672,16 +1661,22 @@ int init_module(void)
+                       printk(KERN_WARNING "3c505.c: warning, using default DMA channel,\n");
+               }
+               if (io[this_dev] == 0) {
+-                      if (this_dev) break;
++                      if (this_dev) {
++                              free_netdev(dev);
++                              break;
++                      }
+                       printk(KERN_NOTICE "3c505.c: module autoprobe not recommended, give io=xx.\n");
+               }
+-              if (register_netdev(dev) != 0) {
++              if (elplus_setup(dev) != 0) {
+                       printk(KERN_WARNING "3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
+-                      if (found != 0) return 0;
+-                      return -ENXIO;
++                      free_netdev(dev);
++                      break;
+               }
++              dev_3c505[this_dev] = dev;
+               found++;
+       }
++      if (!found)
++              return -ENODEV;
+       return 0;
+ }
+@@ -1690,12 +1685,11 @@ void cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_3c505[this_dev];
+-              if (dev->priv != NULL) {
++              struct net_device *dev = dev_3c505[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(dev->priv);
+-                      dev->priv = NULL;
+                       release_region(dev->base_addr, ELP_IO_EXTENT);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/3c507.c    2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/3c507.c     2003-12-28 23:21:00.000000000 -0800
+@@ -74,10 +74,6 @@ static unsigned int net_debug = NET_DEBU
+ #define debug net_debug
+-/* A zero-terminated list of common I/O addresses to be probed. */
+-static unsigned int netcard_portlist[] __initdata =
+-      { 0x300, 0x320, 0x340, 0x280, 0};
+-
+ /*
+                       Details of the i82586.
+@@ -286,8 +282,6 @@ static unsigned short init_words[] = {
+ /* Index to functions, as function prototypes. */
+-extern int el16_probe(struct net_device *dev);        /* Called from Space.c */
+-
+ static int    el16_probe1(struct net_device *dev, int ioaddr);
+ static int    el16_open(struct net_device *dev);
+ static int    el16_send_packet(struct sk_buff *skb, struct net_device *dev);
+@@ -301,6 +295,10 @@ static void hardware_send_packet(struct 
+ static void init_82586_mem(struct net_device *dev);
+ static struct ethtool_ops netdev_ethtool_ops;
++static int io = 0x300;
++static int irq;
++static int mem_start;
++
\f
+ /* Check for a network adaptor of this type, and return '0' iff one exists.
+       If dev->base_addr == 0, probe all likely locations.
+@@ -309,23 +307,50 @@ static struct ethtool_ops netdev_ethtool
+       device and return success.
+       */
+-int __init el16_probe(struct net_device *dev)
++struct net_device * __init el16_probe(int unit)
+ {
+-      int base_addr = dev->base_addr;
+-      int i;
++      struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
++      static unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0};
++      unsigned *port;
++      int err = -ENODEV;
++
++      if (!dev)
++              return ERR_PTR(-ENODEV);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++              io = dev->base_addr;
++              irq = dev->irq;
++              mem_start = dev->mem_start & 15;
++      }
+       SET_MODULE_OWNER(dev);
+-      if (base_addr > 0x1ff)  /* Check a single specified location. */
+-              return el16_probe1(dev, base_addr);
+-      else if (base_addr != 0)
+-              return -ENXIO;          /* Don't probe at all. */
+-
+-      for (i = 0; netcard_portlist[i]; i++)
+-              if (el16_probe1(dev, netcard_portlist[i]) == 0)
+-                      return 0;
++      if (io > 0x1ff)         /* Check a single specified location. */
++              err = el16_probe1(dev, io);
++      else if (io != 0)
++              err = -ENXIO;           /* Don't probe at all. */
++      else {
++              for (port = ports; *port; port++) {
++                      err = el16_probe1(dev, *port);
++                      if (!err)
++                              break;
++              }
++      }
+-      return -ENODEV;
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, EL16_IO_EXTENT);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ static int __init el16_probe1(struct net_device *dev, int ioaddr)
+@@ -383,8 +408,8 @@ static int __init el16_probe1(struct net
+               printk(" %02x", dev->dev_addr[i]);
+       }
+-      if ((dev->mem_start & 0xf) > 0)
+-              net_debug = dev->mem_start & 7;
++      if (mem_start)
++              net_debug = mem_start & 7;
+ #ifdef MEM_BASE
+       dev->mem_start = MEM_BASE;
+@@ -416,27 +441,18 @@ static int __init el16_probe1(struct net
+       if (net_debug)
+               printk(version);
+-      /* Initialize the device structure. */
+-      lp = dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-      if (dev->priv == NULL) {
+-              retval = -ENOMEM;
+-              goto out;
+-      }
+-      memset(dev->priv, 0, sizeof(struct net_local));
++      lp = dev->priv;
++      memset(lp, 0, sizeof(*lp));
+       spin_lock_init(&lp->lock);
+-      dev->open               = el16_open;
+-      dev->stop               = el16_close;
++      dev->open = el16_open;
++      dev->stop = el16_close;
+       dev->hard_start_xmit = el16_send_packet;
+       dev->get_stats  = el16_get_stats;
+       dev->tx_timeout = el16_tx_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
+       dev->ethtool_ops = &netdev_ethtool_ops;
+-
+-      ether_setup(dev);       /* Generic ethernet behaviour */
+-
+-      dev->flags&=~IFF_MULTICAST;     /* Multicast doesn't work */
+-
++      dev->flags &= ~IFF_MULTICAST;   /* Multicast doesn't work */
+       return 0;
+ out:
+       release_region(ioaddr, EL16_IO_EXTENT);
+@@ -899,9 +915,7 @@ static struct ethtool_ops netdev_ethtool
+ };
+ #ifdef MODULE
+-static struct net_device dev_3c507;
+-static int io = 0x300;
+-static int irq;
++static struct net_device *dev_3c507;
+ MODULE_PARM(io, "i");
+ MODULE_PARM(irq, "i");
+ MODULE_PARM_DESC(io, "EtherLink16 I/O base address");
+@@ -911,26 +925,18 @@ int init_module(void)
+ {
+       if (io == 0)
+               printk("3c507: You should not use auto-probing with insmod!\n");
+-      dev_3c507.base_addr = io;
+-      dev_3c507.irq       = irq;
+-      dev_3c507.init      = el16_probe;
+-      if (register_netdev(&dev_3c507) != 0) {
+-              printk("3c507: register_netdev() returned non-zero.\n");
+-              return -EIO;
+-      }
+-      return 0;
++      dev_3c507 = el16_probe(-1);
++      return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
+ }
+ void
+ cleanup_module(void)
+ {
+-      unregister_netdev(&dev_3c507);
+-      kfree(dev_3c507.priv);
+-      dev_3c507.priv = NULL;
+-
+-      /* If we don't do this, we can't re-insmod it later. */
+-      free_irq(dev_3c507.irq, &dev_3c507);
+-      release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
++      struct net_device *dev = dev_3c507;
++      unregister_netdev(dev);
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, EL16_IO_EXTENT);
++      free_netdev(dev);
+ }
+ #endif /* MODULE */
+ MODULE_LICENSE("GPL");
+--- linux-2.6.0/drivers/net/3c515.c    2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/net/3c515.c     2003-12-28 23:21:00.000000000 -0800
+@@ -307,7 +307,8 @@ struct boom_tx_desc {
+ struct corkscrew_private {
+       const char *product_name;
+-      struct net_device *next_module;
++      struct list_head list;
++      struct net_device *our_dev;
+       /* The Rx and Tx rings are here to keep them quad-word-aligned. */
+       struct boom_rx_desc rx_ring[RX_RING_SIZE];
+       struct boom_tx_desc tx_ring[TX_RING_SIZE];
+@@ -329,6 +330,7 @@ struct corkscrew_private {
+               full_bus_master_tx:1, full_bus_master_rx:1,     /* Boomerang  */
+               tx_full:1;
+       spinlock_t lock;
++      struct device *dev;
+ };
+ /* The action to take with a media selection timer tick.
+@@ -367,17 +369,12 @@ static struct isapnp_device_id corkscrew
+ MODULE_DEVICE_TABLE(isapnp, corkscrew_isapnp_adapters);
+-static int corkscrew_isapnp_phys_addr[3];
+-
+ static int nopnp;
+ #endif /* __ISAPNP__ */
+-static int corkscrew_scan(struct net_device *dev);
+-static struct net_device *corkscrew_found_device(struct net_device *dev,
+-                                               int ioaddr, int irq,
+-                                               int product_index,
+-                                               int options);
+-static int corkscrew_probe1(struct net_device *dev);
++static struct net_device *corkscrew_scan(int unit);
++static void corkscrew_setup(struct net_device *dev, int ioaddr,
++                          struct pnp_dev *idev, int card_number);
+ static int corkscrew_open(struct net_device *dev);
+ static void corkscrew_timer(unsigned long arg);
+ static int corkscrew_start_xmit(struct sk_buff *skb,
+@@ -413,47 +410,99 @@ static int options[MAX_UNITS] = { -1, -1
+ #ifdef MODULE
+ static int debug = -1;
+ /* A list of all installed Vortex devices, for removing the driver module. */
+-static struct net_device *root_corkscrew_dev;
++/* we will need locking (and refcounting) if we ever use it for more */
++static LIST_HEAD(root_corkscrew_dev);
+ int init_module(void)
+ {
+-      int cards_found;
+-
++      int found = 0;
+       if (debug >= 0)
+               corkscrew_debug = debug;
+       if (corkscrew_debug)
+               printk(version);
+-
+-      root_corkscrew_dev = NULL;
+-      cards_found = corkscrew_scan(NULL);
+-      return cards_found ? 0 : -ENODEV;
++      while (corkscrew_scan(-1))
++              found++;
++      return found ? 0 : -ENODEV;
+ }
+ #else
+-int tc515_probe(struct net_device *dev)
++struct net_device *tc515_probe(int unit)
+ {
+-      int cards_found = 0;
++      struct net_device *dev = corkscrew_scan(unit);
++      static int printed;
+-      SET_MODULE_OWNER(dev);
+-
+-      cards_found = corkscrew_scan(dev);
++      if (!dev)
++              return ERR_PTR(-ENODEV);
+-      if (corkscrew_debug > 0 && cards_found)
++      if (corkscrew_debug > 0 && !printed) {
++              printed = 1;
+               printk(version);
++      }
+-      return cards_found ? 0 : -ENODEV;
++      return dev;
+ }
+ #endif                                /* not MODULE */
+-static int corkscrew_scan(struct net_device *dev)
++static int check_device(unsigned ioaddr)
++{
++      int timer;
++
++      if (!request_region(ioaddr, CORKSCREW_TOTAL_SIZE, "3c515"))
++              return 0;
++      /* Check the resource configuration for a matching ioaddr. */
++      if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0)) {
++              release_region(ioaddr, CORKSCREW_TOTAL_SIZE);
++              return 0;
++      }
++      /* Verify by reading the device ID from the EEPROM. */
++      outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
++      /* Pause for at least 162 us. for the read to take place. */
++      for (timer = 4; timer >= 0; timer--) {
++              udelay(162);
++              if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0)
++                      break;
++      }
++      if (inw(ioaddr + Wn0EepromData) != 0x6d50) {
++              release_region(ioaddr, CORKSCREW_TOTAL_SIZE);
++              return 0;
++      }
++      return 1;
++}
++
++static void cleanup_card(struct net_device *dev)
+ {
+-      int cards_found = 0;
++      struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
++      list_del_init(&vp->list);
++      if (dev->dma)
++              free_dma(dev->dma);
++      outw(TotalReset, dev->base_addr + EL3_CMD);
++      release_region(dev->base_addr, CORKSCREW_TOTAL_SIZE);
++      if (vp->dev)
++              pnp_device_detach(to_pnp_dev(vp->dev));
++}
++
++static struct net_device *corkscrew_scan(int unit)
++{
++      struct net_device *dev;
++      static int cards_found = 0;
+       static int ioaddr;
++      int err;
+ #ifdef __ISAPNP__
+       short i;
+       static int pnp_cards;
+ #endif
++      dev = alloc_etherdev(sizeof(struct corkscrew_private));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
++
++      SET_MODULE_OWNER(dev);
++
+ #ifdef __ISAPNP__
+       if(nopnp == 1)
+               goto no_pnp;
+@@ -470,7 +519,7 @@ static int corkscrew_scan(struct net_dev
+                       if (pnp_activate_dev(idev) < 0) {
+                               printk("pnp activate failed (out of resources?)\n");
+                               pnp_device_detach(idev);
+-                              return -ENOMEM;
++                              continue;
+                       }
+                       if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) {
+                               pnp_device_detach(idev);
+@@ -478,40 +527,22 @@ static int corkscrew_scan(struct net_dev
+                       }
+                       ioaddr = pnp_port_start(idev, 0);
+                       irq = pnp_irq(idev, 0);
+-                      if(corkscrew_debug)
+-                              printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n",
+-                                      (char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
+-                                      
+-                      if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0)) {
++                      if (!check_device(ioaddr)) {
+                               pnp_device_detach(idev);
+                               continue;
+                       }
+-                      /* Verify by reading the device ID from the EEPROM. */
+-                      {
+-                              int timer;
+-                              outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
+-                              /* Pause for at least 162 us. for the read to take place. */
+-                              for (timer = 4; timer >= 0; timer--) {
+-                                      udelay(162);
+-                                      if ((inw(ioaddr + Wn0EepromCmd) & 0x0200)
+-                                              == 0)
+-                                                      break;
+-                              }
+-                              if (inw(ioaddr + Wn0EepromData) != 0x6d50) {
+-                                      pnp_device_detach(idev);
+-                                      continue;
+-                              }
+-                      }
++                      if(corkscrew_debug)
++                              printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n",
++                                      (char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
+                       printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
+                               inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
+                       /* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
+-                      corkscrew_isapnp_phys_addr[pnp_cards] = ioaddr;
+-                      corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID, dev
+-                                      && dev->mem_start ? dev->
+-                                      mem_start : options[cards_found]);
+-                      dev = 0;
++                      corkscrew_setup(dev, ioaddr, idev, cards_found++);
+                       pnp_cards++;
+-                      cards_found++;
++                      err = register_netdev(dev);
++                      if (!err)
++                              return dev;
++                      cleanup_card(dev);
+               }
+       }
+ no_pnp:
+@@ -519,122 +550,64 @@ no_pnp:
+       /* Check all locations on the ISA bus -- evil! */
+       for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) {
+-              int irq;
+-#ifdef __ISAPNP__
+-              /* Make sure this was not already picked up by isapnp */
+-              if(ioaddr == corkscrew_isapnp_phys_addr[0]) continue;
+-              if(ioaddr == corkscrew_isapnp_phys_addr[1]) continue;
+-              if(ioaddr == corkscrew_isapnp_phys_addr[2]) continue;
+-#endif /* __ISAPNP__ */
+-              if (check_region(ioaddr, CORKSCREW_TOTAL_SIZE))
++              if (!check_device(ioaddr))
+                       continue;
+-              /* Check the resource configuration for a matching ioaddr. */
+-              if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0))
+-                      continue;
+-              /* Verify by reading the device ID from the EEPROM. */
+-              {
+-                      int timer;
+-                      outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
+-                      /* Pause for at least 162 us. for the read to take place. */
+-                      for (timer = 4; timer >= 0; timer--) {
+-                              udelay(162);
+-                              if ((inw(ioaddr + Wn0EepromCmd) & 0x0200)
+-                                  == 0)
+-                                      break;
+-                      }
+-                      if (inw(ioaddr + Wn0EepromData) != 0x6d50)
+-                              continue;
+-              }
++
+               printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
+                    inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
+-              irq = inw(ioaddr + 0x2002) & 15;
+-              corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID,
+-                                     dev && dev->mem_start ?  dev->mem_start :
+-                                       (cards_found >= MAX_UNITS ? -1 :
+-                                              options[cards_found]));
+-              dev = 0;
+-              cards_found++;
++              corkscrew_setup(dev, ioaddr, NULL, cards_found++);
++              err = register_netdev(dev);
++              if (!err)
++                      return dev;
++              cleanup_card(dev);
+       }
+-      if (corkscrew_debug)
+-              printk(KERN_INFO "%d 3c515 cards found.\n", cards_found);
+-      return cards_found;
++      free_netdev(dev);
++      return NULL;
+ }
+-static struct net_device *corkscrew_found_device(struct net_device *dev,
+-                                               int ioaddr, int irq,
+-                                               int product_index,
+-                                               int options)
++static void corkscrew_setup(struct net_device *dev, int ioaddr,
++                          struct pnp_dev *idev, int card_number)
+ {
+-      struct corkscrew_private *vp;
+-
+-#ifdef MODULE
+-      /* Allocate and fill new device structure. */
+-      int dev_size = sizeof(struct net_device) + sizeof(struct corkscrew_private) + 15;       /* Pad for alignment */
++      struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
++      unsigned int eeprom[0x40], checksum = 0;        /* EEPROM contents */
++      int i;
++      int irq;
+-      dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL);
+-      if (!dev)
+-              return NULL;
+-      memset(dev, 0, dev_size);
+-      /* Align the Rx and Tx ring entries.  */
+-      dev->priv = (void *) (((long) dev + sizeof(struct net_device) + 15) & ~15);
+-      vp = (struct corkscrew_private *) dev->priv;
+-      dev->base_addr = ioaddr;
+-      dev->irq = irq;
+-      dev->dma = (product_index == CORKSCREW_ID ? inw(ioaddr + 0x2000) & 7 : 0);
+-      dev->init = corkscrew_probe1;
+-      vp->product_name = "3c515";
+-      vp->options = options;
+-      if (options >= 0) {
+-              vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
+-              vp->full_duplex = (options & 8) ? 1 : 0;
+-              vp->bus_master = (options & 16) ? 1 : 0;
++      if (idev) {
++              irq = pnp_irq(idev, 0);
++              vp->dev = &idev->dev;
+       } else {
+-              vp->media_override = 7;
+-              vp->full_duplex = 0;
+-              vp->bus_master = 0;
++              irq = inw(ioaddr + 0x2002) & 15;
+       }
+-      ether_setup(dev);
+-      vp->next_module = root_corkscrew_dev;
+-      root_corkscrew_dev = dev;
+-      SET_MODULE_OWNER(dev);
+-      if (register_netdev(dev) != 0) {
+-              kfree(dev);
+-              return NULL;
+-      }
+-#else                         /* not a MODULE */
+-      /* Caution: quad-word alignment required for rings! */
+-      dev->priv = kmalloc(sizeof(struct corkscrew_private), GFP_KERNEL);
+-      if (!dev->priv)
+-              return NULL;
+-      memset(dev->priv, 0, sizeof(struct corkscrew_private));
+-      dev = init_etherdev(dev, sizeof(struct corkscrew_private));
++
+       dev->base_addr = ioaddr;
+       dev->irq = irq;
+-      dev->dma = (product_index == CORKSCREW_ID ? inw(ioaddr + 0x2000) & 7 : 0);
+-      vp = (struct corkscrew_private *) dev->priv;
++      dev->dma = inw(ioaddr + 0x2000) & 7;
+       vp->product_name = "3c515";
+-      vp->options = options;
+-      if (options >= 0) {
+-              vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
+-              vp->full_duplex = (options & 8) ? 1 : 0;
+-              vp->bus_master = (options & 16) ? 1 : 0;
++      vp->options = dev->mem_start;
++      vp->our_dev = dev;
++
++      if (!vp->options) {
++               if (card_number >= MAX_UNITS)
++                      vp->options = -1;
++              else
++                      vp->options = options[card_number];
++      }
++
++      if (vp->options >= 0) {
++              vp->media_override = vp->options & 7;
++              if (vp->media_override == 2)
++                      vp->media_override = 0;
++              vp->full_duplex = (vp->options & 8) ? 1 : 0;
++              vp->bus_master = (vp->options & 16) ? 1 : 0;
+       } else {
+               vp->media_override = 7;
+               vp->full_duplex = 0;
+               vp->bus_master = 0;
+       }
+-
+-      corkscrew_probe1(dev);
+-#endif                                /* MODULE */
+-      return dev;
+-}
+-
+-static int corkscrew_probe1(struct net_device *dev)
+-{
+-      int ioaddr = dev->base_addr;
+-      struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+-      unsigned int eeprom[0x40], checksum = 0;        /* EEPROM contents */
+-      int i;
++#ifdef MODULE
++      list_add(&vp->list, &root_corkscrew_dev);
++#endif
+       printk(KERN_INFO "%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
+@@ -706,9 +679,6 @@ static int corkscrew_probe1(struct net_d
+       /* vp->full_bus_master_rx = 0; */
+       vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
+-      /* We do a request_region() to register /proc/ioports info. */
+-      request_region(ioaddr, CORKSCREW_TOTAL_SIZE, vp->product_name);
+-
+       /* The 3c51x-specific entries in the device structure. */
+       dev->open = &corkscrew_open;
+       dev->hard_start_xmit = &corkscrew_start_xmit;
+@@ -718,8 +688,6 @@ static int corkscrew_probe1(struct net_d
+       dev->get_stats = &corkscrew_get_stats;
+       dev->set_multicast_list = &set_rx_mode;
+       dev->ethtool_ops = &netdev_ethtool_ops;
+-
+-      return 0;
+ }
\f
+@@ -1607,20 +1575,16 @@ static struct ethtool_ops netdev_ethtool
+ #ifdef MODULE
+ void cleanup_module(void)
+ {
+-      struct net_device *next_dev;
+-
+-      while (root_corkscrew_dev) {
+-              next_dev =
+-                  ((struct corkscrew_private *) root_corkscrew_dev->
+-                   priv)->next_module;
+-              if (root_corkscrew_dev->dma)
+-                      free_dma(root_corkscrew_dev->dma);
+-              unregister_netdev(root_corkscrew_dev);
+-              outw(TotalReset, root_corkscrew_dev->base_addr + EL3_CMD);
+-              release_region(root_corkscrew_dev->base_addr,
+-                             CORKSCREW_TOTAL_SIZE);
+-              free_netdev(root_corkscrew_dev);
+-              root_corkscrew_dev = next_dev;
++      while (!list_empty(&root_corkscrew_dev)) {
++              struct net_device *dev;
++              struct corkscrew_private *vp;
++
++              vp = list_entry(root_corkscrew_dev.next,
++                              struct corkscrew_private, list);
++              dev = vp->our_dev;
++              unregister_netdev(dev);
++              cleanup_card(dev);
++              free_netdev(dev);
+       }
+ }
+ #endif                                /* MODULE */
+--- linux-2.6.0/drivers/net/3c523.c    2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/3c523.c     2003-12-28 23:21:00.000000000 -0800
+@@ -410,7 +410,7 @@ static int elmc_getinfo(char *buf, int s
+ /*****************************************************************/
+-int __init elmc_probe(struct net_device *dev)
++static int __init do_elmc_probe(struct net_device *dev)
+ {
+       static int slot;
+       int base_addr = dev->base_addr;
+@@ -420,7 +420,7 @@ int __init elmc_probe(struct net_device 
+       int i = 0;
+       unsigned int size = 0;
+       int retval;
+-      struct priv *pr;
++      struct priv *pr = dev->priv;
+       SET_MODULE_OWNER(dev);
+       if (MCA_bus == 0) {
+@@ -455,10 +455,9 @@ int __init elmc_probe(struct net_device 
+       }
+       /* we didn't find any 3c523 in the slots we checked for */
+-      if (slot == MCA_NOTFOUND) {
+-              retval = ((base_addr || irq) ? -ENXIO : -ENODEV);
+-              goto err_out;
+-      }
++      if (slot == MCA_NOTFOUND)
++              return ((base_addr || irq) ? -ENXIO : -ENODEV);
++
+       mca_set_adapter_name(slot, "3Com 3c523 Etherlink/MC");
+       mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
+@@ -497,13 +496,7 @@ int __init elmc_probe(struct net_device 
+               break;
+       }
+-      pr = dev->priv = kmalloc(sizeof(struct priv), GFP_KERNEL);
+-      if (dev->priv == NULL) {
+-              retval = -ENOMEM;
+-              goto err_out;
+-      }
+       memset(pr, 0, sizeof(struct priv));
+-
+       pr->slot = slot;
+       printk(KERN_INFO "%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
+@@ -530,8 +523,6 @@ int __init elmc_probe(struct net_device 
+       if (!check586(dev, dev->mem_start, size)) {
+               printk(KERN_ERR "%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
+                      dev->mem_start);
+-              kfree(dev->priv);
+-              dev->priv = NULL;
+               retval = -ENODEV;
+               goto err_out;
+       }
+@@ -573,8 +564,6 @@ int __init elmc_probe(struct net_device 
+ #endif
+       dev->ethtool_ops = &netdev_ethtool_ops;
+       
+-      ether_setup(dev);
+-
+       /* note that we haven't actually requested the IRQ from the kernel.
+          That gets done in elmc_open().  I'm not sure that's such a good idea,
+          but it works, so I'll go with it. */
+@@ -585,9 +574,41 @@ int __init elmc_probe(struct net_device 
+       return 0;
+ err_out:
++      mca_set_adapter_procfn(slot, NULL, NULL);
+       release_region(dev->base_addr, ELMC_IO_EXTENT);
+       return retval;
+ }
++ 
++static void cleanup_card(struct net_device *dev)
++{
++      mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot, NULL, NULL);
++      release_region(dev->base_addr, ELMC_IO_EXTENT);
++}
++
++struct net_device * __init elmc_probe(int unit)
++{
++      struct net_device *dev = alloc_etherdev(sizeof(struct priv));
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_elmc_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
+ /**********************************************
+  * init the chip (elmc-interrupt should be disabled?!)
+@@ -1245,7 +1266,7 @@ static struct ethtool_ops netdev_ethtool
+ /* Increase if needed ;) */
+ #define MAX_3C523_CARDS 4
+-static struct net_device dev_elmc[MAX_3C523_CARDS];
++static struct net_device *dev_elmc[MAX_3C523_CARDS];
+ static int irq[MAX_3C523_CARDS];
+ static int io[MAX_3C523_CARDS];
+ MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
+@@ -1258,16 +1279,24 @@ int init_module(void)
+       int this_dev,found = 0;
+       /* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */        
+-      for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) 
+-              {
+-              struct net_device *dev = &dev_elmc[this_dev];
++      for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
++              struct net_device *dev = alloc_etherdev(sizeof(struct priv));
++              if (!dev)
++                      break;
+               dev->irq=irq[this_dev];
+               dev->base_addr=io[this_dev];
+-              dev->init=elmc_probe;
+-              if(register_netdev(dev)!=0) {
+-                      if(io[this_dev]==0) break;
+-                      printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
+-              } else found++;
++              if (do_elmc_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_elmc[this_dev] = dev;
++                              found++;
++                              continue;
++                      }
++                      cleanup_card(dev);
++              }
++              free_netdev(dev);
++              if (io[this_dev]==0)
++                      break;
++              printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
+       }
+       if(found==0) {
+@@ -1279,31 +1308,12 @@ int init_module(void)
+ void cleanup_module(void)
+ {
+       int this_dev;
+-      for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
+-
+-              struct net_device *dev = &dev_elmc[this_dev];
+-              if(dev->priv) {
+-                      /* shutdown interrupts on the card */
+-                      elmc_id_reset586();
+-                      if (dev->irq != 0) {
+-                              /* this should be done by close, but if we failed to
+-                                 initialize properly something may have gotten hosed. */
+-                              free_irq(dev->irq, dev);
+-                              dev->irq = 0;
+-                      }
+-                      if (dev->base_addr != 0) {
+-                              release_region(dev->base_addr, ELMC_IO_EXTENT);
+-                              dev->base_addr = 0;
+-                      }
+-                      irq[this_dev] = 0;
+-                      io[this_dev] = 0;
++      for (this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
++              struct net_device *dev = dev_elmc[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-
+-                      mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot,
+-                             NULL, NULL);
+-
+-                      kfree(dev->priv);
+-                      dev->priv = NULL;
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/3c527.c    2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/3c527.c     2003-12-28 23:21:00.000000000 -0800
+@@ -1,9 +1,10 @@
+-/* 3c527.c: 3Com Etherlink/MC32 driver for Linux 2.4
++/* 3c527.c: 3Com Etherlink/MC32 driver for Linux 2.4 and 2.6.
+  *
+  *    (c) Copyright 1998 Red Hat Software Inc
+  *    Written by Alan Cox. 
+  *    Further debugging by Carl Drougge.
+- *      Modified by Richard Procter (rnp@netlink.co.nz)
++ *      Initial SMP support by Felipe W Damasio <felipewd@terra.com.br>
++ *      Heavily modified by Richard Procter <rnp@paradise.net.nz>
+  *
+  *    Based on skeleton.c written 1993-94 by Donald Becker and ne2.c
+  *    (for the MCA stuff) written by Wim Dumon.
+@@ -17,11 +18,11 @@
+  */
+ #define DRV_NAME              "3c527"
+-#define DRV_VERSION           "0.6a"
+-#define DRV_RELDATE           "2001/11/17"
++#define DRV_VERSION           "0.7-SMP"
++#define DRV_RELDATE           "2003/09/21"
+ static const char *version =
+-DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Richard Proctor (rnp@netlink.co.nz)\n";
++DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Richard Procter <rnp@paradise.net.nz>\n";
+ /**
+  * DOC: Traps for the unwary
+@@ -100,7 +101,9 @@ DRV_NAME ".c:v" DRV_VERSION " " DRV_RELD
+ #include <linux/string.h>
+ #include <linux/wait.h>
+ #include <linux/ethtool.h>
++#include <linux/completion.h>
++#include <asm/semaphore.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+ #include <asm/bitops.h>
+@@ -143,19 +146,19 @@ static unsigned int mc32_debug = NET_DEB
+ static const int WORKAROUND_82586=1;
+ /* Pointers to buffers and their on-card records */
+-
+ struct mc32_ring_desc 
+ {
+       volatile struct skb_header *p;                    
+       struct sk_buff *skb;          
+ };
+-
+ /* Information that needs to be kept for each board. */
+ struct mc32_local 
+ {
+-      struct net_device_stats net_stats;
+       int slot;
++
++      u32 base;
++      struct net_device_stats net_stats;
+       volatile struct mc32_mailbox *rx_box;
+       volatile struct mc32_mailbox *tx_box;
+       volatile struct mc32_mailbox *exec_box;
+@@ -165,22 +168,23 @@ struct mc32_local 
+         u16 tx_len;             /* Transmit list count */ 
+         u16 rx_len;             /* Receive list count */
+-      u32 base;
+-      u16 exec_pending;
+-      u16 mc_reload_wait;     /* a multicast load request is pending */
++      u16 xceiver_desired_state; /* HALTED or RUNNING */
++      u16 cmd_nonblocking;    /* Thread is uninterested in command result */
++      u16 mc_reload_wait;     /* A multicast load request is pending */
+       u32 mc_list_valid;      /* True when the mclist is set */
+-      u16 xceiver_state;      /* Current transceiver state. bitmapped */ 
+-      u16 desired_state;      /* The state we want the transceiver to be in */ 
+-      atomic_t tx_count;      /* buffers left */
+-      wait_queue_head_t event;
+       struct mc32_ring_desc tx_ring[TX_RING_LEN];     /* Host Transmit ring */
+       struct mc32_ring_desc rx_ring[RX_RING_LEN];     /* Host Receive ring */
++      atomic_t tx_count;      /* buffers left */
++      atomic_t tx_ring_head;  /* index to tx en-queue end */
+       u16 tx_ring_tail;       /* index to tx de-queue end */
+-      u16 tx_ring_head;       /* index to tx en-queue end */
+       u16 rx_ring_tail;       /* index to rx de-queue end */ 
++
++      struct semaphore cmd_mutex;    /* Serialises issuing of execute commands */
++        struct completion execution_cmd; /* Card has completed an execute command */
++      struct completion xceiver_cmd;   /* Card has completed a tx or rx command */
+ };
+ /* The station (ethernet) address prefix, used for a sanity check. */
+@@ -208,8 +212,6 @@ static inline u16 next_tx(u16 tx) { retu
+ /* Index to functions, as function prototypes. */
+-extern int mc32_probe(struct net_device *dev);
+-
+ static int    mc32_probe1(struct net_device *dev, int ioaddr);
+ static int      mc32_command(struct net_device *dev, u16 cmd, void *data, int len);
+ static int    mc32_open(struct net_device *dev);
+@@ -222,9 +224,19 @@ static void       mc32_set_multicast_list(stru
+ static void   mc32_reset_multicast_list(struct net_device *dev);
+ static struct ethtool_ops netdev_ethtool_ops;
++static void cleanup_card(struct net_device *dev)
++{
++      struct mc32_local *lp=dev->priv;
++      unsigned slot = lp->slot;
++      mca_mark_as_unused(slot);
++      mca_set_adapter_name(slot, NULL);
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, MC32_IO_EXTENT);
++}
++
+ /**
+  * mc32_probe         -       Search for supported boards
+- * @dev: device to probe
++ * @unit: interface number to use
+  *
+  * Because MCA bus is a real bus and we can scan for cards we could do a
+  * single scan for all boards here. Right now we use the passed in device
+@@ -232,11 +244,18 @@ static struct ethtool_ops netdev_ethtool
+  * in particular.
+  */
+-int __init mc32_probe(struct net_device *dev)
++struct net_device *__init mc32_probe(int unit)
+ {
++      struct net_device *dev = alloc_etherdev(sizeof(struct mc32_local));
+       static int current_mca_slot = -1;
+       int i;
+-      int adapter_found = 0;
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (unit >= 0)
++              sprintf(dev->name, "eth%d", unit);
+       SET_MODULE_OWNER(dev);
+@@ -247,22 +266,28 @@ int __init mc32_probe(struct net_device 
+          Autodetecting MCA cards is extremely simple. 
+          Just search for the card. */
+-      for(i = 0; (mc32_adapters[i].name != NULL) && !adapter_found; i++) {
++      for(i = 0; (mc32_adapters[i].name != NULL); i++) {
+               current_mca_slot = 
+                       mca_find_unused_adapter(mc32_adapters[i].id, 0);
+-              if((current_mca_slot != MCA_NOTFOUND) && !adapter_found) {
++              if(current_mca_slot != MCA_NOTFOUND) {
+                       if(!mc32_probe1(dev, current_mca_slot))
+                       {
+                               mca_set_adapter_name(current_mca_slot, 
+                                               mc32_adapters[i].name);
+                               mca_mark_as_used(current_mca_slot);
+-                              return 0;
++                              err = register_netdev(dev);
++                              if (err) {
++                                      cleanup_card(dev);
++                                      free_netdev(dev);
++                                      dev = ERR_PTR(err);
++                              }
++                              return dev;
+                       }
+                       
+               }
+       }
+-      return -ENODEV;
++      return ERR_PTR(-ENODEV);
+ }
+ /**
+@@ -282,7 +307,7 @@ static int __init mc32_probe1(struct net
+       int i, err;
+       u8 POS;
+       u32 base;
+-      struct mc32_local *lp;
++      struct mc32_local *lp = dev->priv;
+       static u16 mca_io_bases[]={
+               0x7280,0x7290,
+               0x7680,0x7690,
+@@ -409,24 +434,14 @@ static int __init mc32_probe1(struct net
+        *      Grab the IRQ
+        */
+-      i = request_irq(dev->irq, &mc32_interrupt, SA_SHIRQ, dev->name, dev);
+-      if (i) {
++      err = request_irq(dev->irq, &mc32_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
++      if (err) {
+               release_region(dev->base_addr, MC32_IO_EXTENT);
+               printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
+-              return i;
++              goto err_exit_ports; 
+       }
+-
+-      /* Initialize the device structure. */
+-      dev->priv = kmalloc(sizeof(struct mc32_local), GFP_KERNEL);
+-      if (dev->priv == NULL)
+-      {
+-              err = -ENOMEM;
+-              goto err_exit_irq; 
+-      }
+-
+-      memset(dev->priv, 0, sizeof(struct mc32_local));
+-      lp = dev->priv;
++      memset(lp, 0, sizeof(struct mc32_local));
+       lp->slot = slot;
+       i=0;
+@@ -440,7 +455,7 @@ static int __init mc32_probe1(struct net
+               {
+                       printk(KERN_ERR "%s: failed to boot adapter.\n", dev->name);
+                       err = -ENODEV; 
+-                      goto err_exit_free;
++                      goto err_exit_irq;
+               }
+               udelay(1000);
+               if(inb(dev->base_addr+2)&(1<<5))
+@@ -455,7 +470,7 @@ static int __init mc32_probe1(struct net
+               else
+                       printk(KERN_ERR "%s: unknown failure %d.\n", dev->name, base);
+               err = -ENODEV; 
+-              goto err_exit_free;
++              goto err_exit_irq;
+       }
+       
+       base=0;
+@@ -471,7 +486,7 @@ static int __init mc32_probe1(struct net
+                       {
+                               printk(KERN_ERR "%s: mailbox read fail (%d).\n", dev->name, i);
+                               err = -ENODEV;
+-                              goto err_exit_free;
++                              goto err_exit_irq;
+                       }
+               }
+@@ -498,7 +513,9 @@ static int __init mc32_probe1(struct net
+       lp->tx_len              = lp->exec_box->data[9];   /* Transmit list count */ 
+       lp->rx_len              = lp->exec_box->data[11];  /* Receive list count */
+-      init_waitqueue_head(&lp->event);
++      init_MUTEX_LOCKED(&lp->cmd_mutex);
++      init_completion(&lp->execution_cmd);
++      init_completion(&lp->xceiver_cmd);
+       
+       printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
+               dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
+@@ -511,20 +528,12 @@ static int __init mc32_probe1(struct net
+       dev->tx_timeout         = mc32_timeout;
+       dev->watchdog_timeo     = HZ*5; /* Board does all the work */
+       dev->ethtool_ops        = &netdev_ethtool_ops;
+-      
+-      lp->xceiver_state = HALTED; 
+-      
+-      lp->tx_ring_tail=lp->tx_ring_head=0;
+-      /* Fill in the fields of the device structure with ethernet values. */
+-      ether_setup(dev);
+-      
+       return 0;
+-err_exit_free:
+-      kfree(dev->priv);
+ err_exit_irq:
+       free_irq(dev->irq, dev);
++err_exit_ports:
+       release_region(dev->base_addr, MC32_IO_EXTENT);
+       return err;
+ }
+@@ -539,7 +548,7 @@ err_exit_irq:
+  *    status of any pending commands and takes very little time at all.
+  */
+  
+-static void mc32_ready_poll(struct net_device *dev)
++static inline void mc32_ready_poll(struct net_device *dev)
+ {
+       int ioaddr = dev->base_addr;
+       while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR));
+@@ -554,31 +563,38 @@ static void mc32_ready_poll(struct net_d
+  *    @len: Length of the data block
+  *
+  *    Send a command from interrupt state. If there is a command
+- *    currently being executed then we return an error of -1. It simply
+- *    isn't viable to wait around as commands may be slow. Providing we
+- *    get in, we busy wait for the board to become ready to accept the
+- *    command and issue it. We do not wait for the command to complete
+- *    --- the card will interrupt us when it's done.
++ *    currently being executed then we return an error of -1. It
++ *    simply isn't viable to wait around as commands may be
++ *    slow. This can theoretically be starved on SMP, but it's hard
++ *    to see a realistic situation.  We do not wait for the command
++ *    to complete --- we rely on the interrupt handler to tidy up
++ *    after us.
+  */
+ static int mc32_command_nowait(struct net_device *dev, u16 cmd, void *data, int len)
+ {
+       struct mc32_local *lp = (struct mc32_local *)dev->priv;
+       int ioaddr = dev->base_addr;
++      int ret = -1;
+-      if(lp->exec_pending)
+-              return -1;
+-      
+-      lp->exec_pending=3;
+-      lp->exec_box->mbox=0;
+-      lp->exec_box->mbox=cmd;
+-      memcpy((void *)lp->exec_box->data, data, len);
+-      barrier();      /* the memcpy forgot the volatile so be sure */
++      if (down_trylock(&lp->cmd_mutex) == 0)
++      {
++              lp->cmd_nonblocking=1;
++              lp->exec_box->mbox=0;
++              lp->exec_box->mbox=cmd;
++              memcpy((void *)lp->exec_box->data, data, len);
++              barrier();      /* the memcpy forgot the volatile so be sure */
++
++              /* Send the command */
++              mc32_ready_poll(dev);
++              outb(1<<6, ioaddr+HOST_CMD);
+-      /* Send the command */
+-      while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR));
+-      outb(1<<6, ioaddr+HOST_CMD);    
+-      return 0;
++              ret = 0;
++
++              /* Interrupt handler will signal mutex on completion */
++      }
++
++      return ret;
+ }
+@@ -592,76 +608,47 @@ static int mc32_command_nowait(struct ne
+  *    Sends exec commands in a user context. This permits us to wait around
+  *    for the replies and also to wait for the command buffer to complete
+  *    from a previous command before we execute our command. After our 
+- *    command completes we will complete any pending multicast reload
++ *    command completes we will attempt any pending multicast reload
+  *    we blocked off by hogging the exec buffer.
+  *
+  *    You feed the card a command, you wait, it interrupts you get a 
+  *    reply. All well and good. The complication arises because you use
+  *    commands for filter list changes which come in at bh level from things
+  *    like IPV6 group stuff.
+- *
+- *    We have a simple state machine
+- *
+- *    0       - nothing issued
+- *
+- *    1       - command issued, wait reply
+- *
+- *    2       - reply waiting - reader then goes to state 0
+- *
+- *    3       - command issued, trash reply. In which case the irq
+- *              takes it back to state 0
+- *
+  */
+   
+ static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len)
+ {
+       struct mc32_local *lp = (struct mc32_local *)dev->priv;
+       int ioaddr = dev->base_addr;
+-      unsigned long flags;
+       int ret = 0;
+       
++      down(&lp->cmd_mutex);
++
+       /*
+-       *      Wait for a command
+-       */
+-       
+-      save_flags(flags);
+-      cli();
+-       
+-      while(lp->exec_pending)
+-              sleep_on(&lp->event);
+-              
+-      /*
+-       *      Issue mine
++       *     My Turn
+        */
+-      lp->exec_pending=1;
+-      
+-      restore_flags(flags);
+-      
++      lp->cmd_nonblocking=0;
+       lp->exec_box->mbox=0;
+       lp->exec_box->mbox=cmd;
+       memcpy((void *)lp->exec_box->data, data, len);
+       barrier();      /* the memcpy forgot the volatile so be sure */
+-      /* Send the command */
+-      while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR));
+-      outb(1<<6, ioaddr+HOST_CMD);    
++      mc32_ready_poll(dev);
++      outb(1<<6, ioaddr+HOST_CMD);
+-      save_flags(flags);
+-      cli();
+-
+-      while(lp->exec_pending!=2)
+-              sleep_on(&lp->event);
+-      lp->exec_pending=0;
+-      restore_flags(flags);
++      wait_for_completion(&lp->execution_cmd);
+       
+       if(lp->exec_box->mbox&(1<<13))
+               ret = -1;
++      up(&lp->cmd_mutex);
++
+       /*
+-       *      A multicast set got blocked - do it now
+-       */
+-              
++       *      A multicast set got blocked - try it now
++         */
++
+       if(lp->mc_reload_wait)
+       {
+               mc32_reset_multicast_list(dev);
+@@ -678,11 +665,9 @@ static int mc32_command(struct net_devic
+  *    This may be called from the interrupt state, where it is used
+  *    to restart the rx ring if the card runs out of rx buffers. 
+  *    
+- *    First, we check if it's ok to start the transceiver. We then show
+- *    the card where to start in the rx ring and issue the
+- *    commands to start reception and transmission. We don't wait
+- *    around for these to complete.
+- */ 
++ *    We must first check if it's ok to (re)start the transceiver. See
++ *      mc32_close for details.
++ */
+ static void mc32_start_transceiver(struct net_device *dev) {
+@@ -690,24 +675,20 @@ static void mc32_start_transceiver(struc
+       int ioaddr = dev->base_addr;
+       /* Ignore RX overflow on device closure */ 
+-      if (lp->desired_state==HALTED)  
++      if (lp->xceiver_desired_state==HALTED)
+               return; 
++      /* Give the card the offset to the post-EOL-bit RX descriptor */
+       mc32_ready_poll(dev); 
+-
+-      lp->tx_box->mbox=0;
+       lp->rx_box->mbox=0;
+-
+-      /* Give the card the offset to the post-EOL-bit RX descriptor */ 
+       lp->rx_box->data[0]=lp->rx_ring[prev_rx(lp->rx_ring_tail)].p->next; 
+-
+       outb(HOST_CMD_START_RX, ioaddr+HOST_CMD);      
+       mc32_ready_poll(dev); 
++      lp->tx_box->mbox=0;
+       outb(HOST_CMD_RESTRT_TX, ioaddr+HOST_CMD);   /* card ignores this on RX restart */ 
+       
+       /* We are not interrupted on start completion */ 
+-      lp->xceiver_state=RUNNING; 
+ }
+@@ -727,25 +708,17 @@ static void mc32_halt_transceiver(struct
+ {
+       struct mc32_local *lp = (struct mc32_local *)dev->priv;
+       int ioaddr = dev->base_addr;
+-      unsigned long flags;
+       mc32_ready_poll(dev);   
+-
+-      lp->tx_box->mbox=0;
+       lp->rx_box->mbox=0;
+-
+       outb(HOST_CMD_SUSPND_RX, ioaddr+HOST_CMD);                      
++      wait_for_completion(&lp->xceiver_cmd);
++
+       mc32_ready_poll(dev); 
++      lp->tx_box->mbox=0;
+       outb(HOST_CMD_SUSPND_TX, ioaddr+HOST_CMD);      
+-              
+-      save_flags(flags);
+-      cli();
+-              
+-      while(lp->xceiver_state!=HALTED) 
+-              sleep_on(&lp->event); 
+-              
+-      restore_flags(flags);   
+-} 
++      wait_for_completion(&lp->xceiver_cmd);
++}
+ /**
+@@ -756,7 +729,7 @@ static void mc32_halt_transceiver(struct
+  *    the point where mc32_start_transceiver() can be called.
+  *
+  *    The card sets up the receive ring for us. We are required to use the
+- *    ring it provides although we can change the size of the ring.
++ *    ring it provides, although the size of the ring is configurable.
+  *
+  *    We allocate an sk_buff for each ring entry in turn and
+  *    initalise its house-keeping info. At the same time, we read
+@@ -777,7 +750,7 @@ static int mc32_load_rx_ring(struct net_
+       
+       rx_base=lp->rx_chain;
+-      for(i=0;i<RX_RING_LEN;i++)
++      for(i=0; i<RX_RING_LEN; i++)
+       {
+               lp->rx_ring[i].skb=alloc_skb(1532, GFP_KERNEL);
+               skb_reserve(lp->rx_ring[i].skb, 18);  
+@@ -814,21 +787,19 @@ static int mc32_load_rx_ring(struct net_
+  *
+  *    Free the buffer for each ring slot. This may be called 
+  *      before mc32_load_rx_ring(), eg. on error in mc32_open().
++ *      Requires rx skb pointers to point to a valid skb, or NULL.
+  */
+ static void mc32_flush_rx_ring(struct net_device *dev)
+ {
+       struct mc32_local *lp = (struct mc32_local *)dev->priv;
+-      
+-      struct sk_buff *skb;
+       int i; 
+       for(i=0; i < RX_RING_LEN; i++) 
+       { 
+-              skb = lp->rx_ring[i].skb;
+-              if (skb!=NULL) {
+-                      kfree_skb(skb);
+-                      skb=NULL; 
++              if (lp->rx_ring[i].skb) {
++                      dev_kfree_skb(lp->rx_ring[i].skb);
++                      lp->rx_ring[i].skb = NULL;
+               }
+               lp->rx_ring[i].p=NULL; 
+       } 
+@@ -860,7 +831,7 @@ static void mc32_load_tx_ring(struct net
+       tx_base=lp->tx_box->data[0]; 
+-      for(i=0;i<lp->tx_len;i++) 
++      for(i=0 ; i<TX_RING_LEN ; i++)
+       {
+               p=isa_bus_to_virt(lp->base+tx_base);
+               lp->tx_ring[i].p=p; 
+@@ -869,11 +840,12 @@ static void mc32_load_tx_ring(struct net
+               tx_base=p->next;
+       }
+-      /* -1 so that tx_ring_head cannot "lap" tx_ring_tail,           */
+-      /* which would be bad news for mc32_tx_ring as cur. implemented */ 
++      /* -1 so that tx_ring_head cannot "lap" tx_ring_tail */
++      /* see mc32_tx_ring */
+       atomic_set(&lp->tx_count, TX_RING_LEN-1); 
+-      lp->tx_ring_head=lp->tx_ring_tail=0; 
++      atomic_set(&lp->tx_ring_head, 0); 
++      lp->tx_ring_tail=0; 
+ } 
+@@ -881,47 +853,29 @@ static void mc32_load_tx_ring(struct net
+  *    mc32_flush_tx_ring      -       free transmit ring
+  *    @lp: Local data of 3c527 to flush the tx ring of
+  *
+- *    We have to consider two cases here. We want to free the pending
+- *    buffers only. If the ring buffer head is past the start then the
+- *    ring segment we wish to free wraps through zero. The tx ring 
+- *    house-keeping variables are then reset.
++ *      If the ring is non-empty, zip over the it, freeing any
++ *      allocated skb_buffs.  The tx ring house-keeping variables are
++ *      then reset. Requires rx skb pointers to point to a valid skb,
++ *      or NULL.
+  */
+ static void mc32_flush_tx_ring(struct net_device *dev)
+ {
+       struct mc32_local *lp = (struct mc32_local *)dev->priv;
+-      
+-      if(lp->tx_ring_tail!=lp->tx_ring_head)
++      int i;
++
++      for (i=0; i < TX_RING_LEN; i++)
+       {
+-              int i;  
+-              if(lp->tx_ring_tail < lp->tx_ring_head)
++              if (lp->tx_ring[i].skb)
+               {
+-                      for(i=lp->tx_ring_tail;i<lp->tx_ring_head;i++)
+-                      {
+-                              dev_kfree_skb(lp->tx_ring[i].skb);
+-                              lp->tx_ring[i].skb=NULL;
+-                              lp->tx_ring[i].p=NULL; 
+-                      }
+-              }
+-              else
+-              {
+-                      for(i=lp->tx_ring_tail; i<TX_RING_LEN; i++) 
+-                      {
+-                              dev_kfree_skb(lp->tx_ring[i].skb);
+-                              lp->tx_ring[i].skb=NULL;
+-                              lp->tx_ring[i].p=NULL; 
+-                      }
+-                      for(i=0; i<lp->tx_ring_head; i++) 
+-                      {
+-                              dev_kfree_skb(lp->tx_ring[i].skb);
+-                              lp->tx_ring[i].skb=NULL;
+-                              lp->tx_ring[i].p=NULL; 
+-                      }
++                      dev_kfree_skb(lp->tx_ring[i].skb);
++                      lp->tx_ring[i].skb = NULL;
+               }
+       }
+-      
++
+       atomic_set(&lp->tx_count, 0); 
+-      lp->tx_ring_tail=lp->tx_ring_head=0;
++      atomic_set(&lp->tx_ring_head, 0); 
++      lp->tx_ring_tail=0;
+ }
+       
+@@ -958,6 +912,12 @@ static int mc32_open(struct net_device *
+       regs|=HOST_CTRL_INTE;
+       outb(regs, ioaddr+HOST_CTRL);
+       
++      /*
++       *      Allow ourselves to issue commands
++       */
++
++      up(&lp->cmd_mutex);
++
+       /*
+        *      Send the indications on command
+@@ -1010,7 +970,7 @@ static int mc32_open(struct net_device *
+               return -ENOBUFS;
+       }
+-      lp->desired_state = RUNNING; 
++      lp->xceiver_desired_state = RUNNING;
+       
+       /* And finally, set the ball rolling... */
+       mc32_start_transceiver(dev);
+@@ -1047,61 +1007,64 @@ static void mc32_timeout(struct net_devi
+  *    Transmit a buffer. This normally means throwing the buffer onto
+  *    the transmit queue as the queue is quite large. If the queue is
+  *    full then we set tx_busy and return. Once the interrupt handler
+- *    gets messages telling it to reclaim transmit queue entries we will
++ *    gets messages telling it to reclaim transmit queue entries, we will
+  *    clear tx_busy and the kernel will start calling this again.
+  *
+- *    We use cli rather than spinlocks. Since I have no access to an SMP
+- *    MCA machine I don't plan to change it. It is probably the top 
+- *    performance hit for this driver on SMP however.
++ *      We do not disable interrupts or acquire any locks; this can
++ *      run concurrently with mc32_tx_ring(), and the function itself
++ *      is serialised at a higher layer. However, similarly for the
++ *      card itself, we must ensure that we update tx_ring_head only
++ *      after we've established a valid packet on the tx ring (and
++ *      before we let the card "see" it, to prevent it racing with the
++ *      irq handler).
++ * 
+  */
+ static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct mc32_local *lp = (struct mc32_local *)dev->priv;
+-      unsigned long flags;
+-
++      u32 head = atomic_read(&lp->tx_ring_head);
++      
+       volatile struct skb_header *p, *np;
+       netif_stop_queue(dev);
+-      save_flags(flags);
+-      cli();
+-              
+-      if(atomic_read(&lp->tx_count)==0)
+-      {
+-              restore_flags(flags);
++      if(atomic_read(&lp->tx_count)==0) {
+               return 1;
+       }
++      skb = skb_padto(skb, ETH_ZLEN);
++      if (skb == NULL) {
++              netif_wake_queue(dev);
++              return 0;
++      }
++
+       atomic_dec(&lp->tx_count); 
+       /* P is the last sending/sent buffer as a pointer */
+-      p=lp->tx_ring[lp->tx_ring_head].p; 
++      p=lp->tx_ring[head].p;
+               
+-      lp->tx_ring_head=next_tx(lp->tx_ring_head); 
++      head = next_tx(head);
+       /* NP is the buffer we will be loading */
+-      np=lp->tx_ring[lp->tx_ring_head].p; 
+-
+-      if (skb->len < ETH_ZLEN) {
+-              skb = skb_padto(skb, ETH_ZLEN);
+-              if (skb == NULL)
+-                      goto out;
+-      }
+-
++      np=lp->tx_ring[head].p; 
++      
+       /* We will need this to flush the buffer out */
+-      lp->tx_ring[lp->tx_ring_head].skb = skb;
+-         
+-      np->length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; 
+-                      
++      lp->tx_ring[head].skb=skb;
++
++      np->length      = unlikely(skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;                  
+       np->data        = isa_virt_to_bus(skb->data);
+       np->status      = 0;
+       np->control     = CONTROL_EOP | CONTROL_EOL;     
+       wmb();
+               
+-      p->control     &= ~CONTROL_EOL;     /* Clear EOL on p */ 
+-out:  
+-      restore_flags(flags);
++      /*
++       * The new frame has been setup; we can now
++       * let the interrupt handler and card "see" it
++       */
++
++      atomic_set(&lp->tx_ring_head, head); 
++      p->control     &= ~CONTROL_EOL;
+       netif_wake_queue(dev);
+       return 0;
+@@ -1182,10 +1145,11 @@ static void mc32_rx_ring(struct net_devi
+ {
+       struct mc32_local *lp=dev->priv;                
+       volatile struct skb_header *p;
+-      u16 rx_ring_tail = lp->rx_ring_tail;
+-      u16 rx_old_tail = rx_ring_tail; 
+-
++      u16 rx_ring_tail;
++      u16 rx_old_tail;
+       int x=0;
++
++      rx_old_tail = rx_ring_tail = lp->rx_ring_tail;
+       
+       do
+       { 
+@@ -1275,9 +1239,14 @@ static void mc32_tx_ring(struct net_devi
+       struct mc32_local *lp=(struct mc32_local *)dev->priv;
+       volatile struct skb_header *np;
+-      /* NB: lp->tx_count=TX_RING_LEN-1 so that tx_ring_head cannot "lap" tail here */
++      /*
++       * We rely on head==tail to mean 'queue empty'.
++       * This is why lp->tx_count=TX_RING_LEN-1: in order to prevent
++       * tx_ring_head wrapping to tail and confusing a 'queue empty'
++       * condition with 'queue full'
++       */
+-      while (lp->tx_ring_tail != lp->tx_ring_head)  
++      while (lp->tx_ring_tail != atomic_read(&lp->tx_ring_head))  
+       {   
+               u16 t; 
+@@ -1388,8 +1357,7 @@ static irqreturn_t mc32_interrupt(int ir
+                               break;
+                       case 3: /* Halt */
+                       case 4: /* Abort */
+-                              lp->xceiver_state |= TX_HALTED; 
+-                              wake_up(&lp->event);
++                              complete(&lp->xceiver_cmd);
+                               break;
+                       default:
+                               printk("%s: strange tx ack %d\n", dev->name, status&7);
+@@ -1404,8 +1372,7 @@ static irqreturn_t mc32_interrupt(int ir
+                               break;
+                       case 3: /* Halt */
+                       case 4: /* Abort */
+-                              lp->xceiver_state |= RX_HALTED;
+-                              wake_up(&lp->event);
++                              complete(&lp->xceiver_cmd);
+                               break;
+                       case 6:
+                               /* Out of RX buffers stat */
+@@ -1421,26 +1388,17 @@ static irqreturn_t mc32_interrupt(int ir
+               status>>=3;
+               if(status&1)
+               {
+-
+-                      /* 0=no 1=yes 2=replied, get cmd, 3 = wait reply & dump it */
+-                      
+-                      if(lp->exec_pending!=3) {
+-                              lp->exec_pending=2;
+-                              wake_up(&lp->event);
+-                      }
+-                      else 
+-                      {                               
+-                              lp->exec_pending=0;
+-
+-                              /* A new multicast set may have been
+-                                 blocked while the old one was
+-                                 running. If so, do it now. */
++                      /*
++                       * No thread is waiting: we need to tidy
++                       * up ourself.
++                       */
+                                  
++                      if (lp->cmd_nonblocking) {
++                              up(&lp->cmd_mutex);
+                               if (lp->mc_reload_wait) 
+                                       mc32_reset_multicast_list(dev);
+-                              else 
+-                                      wake_up(&lp->event);                           
+                       }
++                      else complete(&lp->execution_cmd);
+               }
+               if(status&2)
+               {
+@@ -1493,12 +1451,12 @@ static irqreturn_t mc32_interrupt(int ir
+ static int mc32_close(struct net_device *dev)
+ {
+       struct mc32_local *lp = (struct mc32_local *)dev->priv;
+-
+       int ioaddr = dev->base_addr;
++
+       u8 regs;
+       u16 one=1;
+       
+-      lp->desired_state = HALTED;
++      lp->xceiver_desired_state = HALTED;
+       netif_stop_queue(dev);
+       /*
+@@ -1511,11 +1469,10 @@ static int mc32_close(struct net_device 
+       mc32_halt_transceiver(dev); 
+       
+-      /* Catch any waiting commands */
++      /* Ensure we issue no more commands beyond this point */
++
++      down(&lp->cmd_mutex);
+       
+-      while(lp->exec_pending==1)
+-              sleep_on(&lp->event);
+-             
+       /* Ok the card is now stopping */       
+       
+       regs=inb(ioaddr+HOST_CTRL);
+@@ -1542,12 +1499,9 @@ static int mc32_close(struct net_device 
+ static struct net_device_stats *mc32_get_stats(struct net_device *dev)
+ {
+-      struct mc32_local *lp;
++      struct mc32_local *lp = (struct mc32_local *)dev->priv;
+       
+       mc32_update_stats(dev); 
+-
+-      lp = (struct mc32_local *)dev->priv;
+-
+       return &lp->net_stats;
+ }
+@@ -1684,7 +1638,7 @@ static struct ethtool_ops netdev_ethtool
+ #ifdef MODULE
+-static struct net_device this_device;
++static struct net_device *this_device;
+ /**
+  *    init_module             -       entry point
+@@ -1696,12 +1650,9 @@ static struct net_device this_device;
+ int init_module(void)
+ {
+-      int result;
+-      
+-      this_device.init = mc32_probe;
+-      if ((result = register_netdev(&this_device)) != 0)
+-              return result;
+-
++      this_device = mc32_probe(-1);
++      if (IS_ERR(this_device))
++              return PTR_ERR(this_device);
+       return 0;
+ }
+@@ -1718,24 +1669,9 @@ int init_module(void)
+ void cleanup_module(void)
+ {
+-      int slot;
+-      
+-      unregister_netdev(&this_device);
+-
+-      /*
+-       * If we don't do this, we can't re-insmod it later.
+-       */
+-       
+-      if (this_device.priv)
+-      {
+-              struct mc32_local *lp=this_device.priv;
+-              slot = lp->slot;
+-              mca_mark_as_unused(slot);
+-              mca_set_adapter_name(slot, NULL);
+-              kfree(this_device.priv);
+-      }
+-      free_irq(this_device.irq, &this_device);
+-      release_region(this_device.base_addr, MC32_IO_EXTENT);
++      unregister_netdev(this_device);
++      cleanup_card(this_device);
++      free_netdev(this_device);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/3c527.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/net/3c527.h     2003-12-28 23:21:00.000000000 -0800
+@@ -27,10 +27,8 @@
+ #define HOST_RAMPAGE          8
+-#define RX_HALTED (1<<0)
+-#define TX_HALTED (1<<1)  
+-#define HALTED (RX_HALTED | TX_HALTED)
+-#define RUNNING 0
++#define HALTED 0
++#define RUNNING 1
+ struct mc32_mailbox
+ {
+--- linux-2.6.0/drivers/net/3c59x.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/net/3c59x.c     2003-12-28 23:21:00.000000000 -0800
+@@ -920,6 +920,18 @@ static struct net_device *compaq_net_dev
+ static int vortex_cards_found;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void poll_vortex(struct net_device *dev)
++{
++      struct vortex_private *vp = (struct vortex_private *)dev->priv;
++      unsigned long flags;
++      local_save_flags(flags);
++      local_irq_disable();
++      (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev,NULL);
++      local_irq_restore(flags);
++} 
++#endif
++
+ #ifdef CONFIG_PM
+ static int vortex_suspend (struct pci_dev *pdev, u32 state)
+@@ -1450,6 +1462,9 @@ static int __devinit vortex_probe1(struc
+       dev->set_multicast_list = set_rx_mode;
+       dev->tx_timeout = vortex_tx_timeout;
+       dev->watchdog_timeo = (watchdog * HZ) / 1000;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++      dev->poll_controller = poll_vortex; 
++#endif
+       if (pdev) {
+               vp->pm_state_valid = 1;
+               pci_save_state(VORTEX_PCI(vp), vp->power_state);
+--- linux-2.6.0/drivers/net/68360enet.c        2003-06-14 12:17:59.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,951 +0,0 @@
+-/*
+- * Ethernet driver for Motorola MPC8xx.
+- * Copyright (c) 2000 Michael Leslie <mleslie@lineo.com>
+- * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+- *
+- * I copied the basic skeleton from the lance driver, because I did not
+- * know how to write the Linux driver, but I did know how the LANCE worked.
+- *
+- * This version of the driver is somewhat selectable for the different
+- * processor/board combinations.  It works for the boards I know about
+- * now, and should be easily modified to include others.  Some of the
+- * configuration information is contained in "commproc.h" and the
+- * remainder is here.
+- *
+- * Buffer descriptors are kept in the CPM dual port RAM, and the frame
+- * buffers are in the host memory.
+- *
+- * Right now, I am very watseful with the buffers.  I allocate memory
+- * pages and then divide them into 2K frame buffers.  This way I know I
+- * have buffers large enough to hold one frame within one buffer descriptor.
+- * Once I get this working, I will use 64 or 128 byte CPM buffers, which
+- * will be much more memory efficient and will easily handle lots of
+- * small packets.
+- *
+- */
+-#include <linux/config.h>
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/ptrace.h>
+-#include <linux/errno.h>
+-#include <linux/ioport.h>
+-#include <linux/interrupt.h>
+-#include <linux/pci.h>
+-#include <linux/init.h>
+-#include <linux/delay.h>
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-#include <linux/skbuff.h>
+-#include <linux/spinlock.h> 
+-
+-#include <asm/irq.h>
+-#include <asm/m68360.h>
+-/* #include <asm/8xx_immap.h> */
+-/* #include <asm/pgtable.h> */
+-/* #include <asm/mpc8xx.h> */
+-#include <asm/bitops.h>
+-/* #include <asm/uaccess.h> */
+-#include <asm/commproc.h>
+-
+-
+-/*
+- *                            Theory of Operation
+- *
+- * The MPC8xx CPM performs the Ethernet processing on SCC1.  It can use
+- * an aribtrary number of buffers on byte boundaries, but must have at
+- * least two receive buffers to prevent constant overrun conditions.
+- *
+- * The buffer descriptors are allocated from the CPM dual port memory
+- * with the data buffers allocated from host memory, just like all other
+- * serial communication protocols.  The host memory buffers are allocated
+- * from the free page pool, and then divided into smaller receive and
+- * transmit buffers.  The size of the buffers should be a power of two,
+- * since that nicely divides the page.  This creates a ring buffer
+- * structure similar to the LANCE and other controllers.
+- *
+- * Like the LANCE driver:
+- * The driver runs as two independent, single-threaded flows of control.  One
+- * is the send-packet routine, which enforces single-threaded use by the
+- * cep->tx_busy flag.  The other thread is the interrupt handler, which is
+- * single threaded by the hardware and other software.
+- *
+- * The send packet thread has partial control over the Tx ring and the
+- * 'cep->tx_busy' flag.  It sets the tx_busy flag whenever it's queuing a Tx
+- * packet. If the next queue slot is empty, it clears the tx_busy flag when
+- * finished otherwise it sets the 'lp->tx_full' flag.
+- *
+- * The MBX has a control register external to the MPC8xx that has some
+- * control of the Ethernet interface.  Information is in the manual for
+- * your board.
+- *
+- * The RPX boards have an external control/status register.  Consult the
+- * programming documents for details unique to your board.
+- *
+- * For the TQM8xx(L) modules, there is no control register interface.
+- * All functions are directly controlled using I/O pins.  See commproc.h.
+- */
+-
+-
+-/* The transmitter timeout
+- */
+-#define TX_TIMEOUT    (2*HZ)
+-
+-/* The number of Tx and Rx buffers.  These are allocated statically here.
+- * We don't need to allocate pages for the transmitter.  We just use
+- * the skbuffer directly.
+- */
+-#ifdef CONFIG_ENET_BIG_BUFFERS
+-#define RX_RING_SIZE          64
+-#define TX_RING_SIZE          64      /* Must be power of two */
+-#define TX_RING_MOD_MASK      63      /*   for this to work */
+-#else
+-#define RX_RING_SIZE          8
+-#define TX_RING_SIZE          8       /* Must be power of two */
+-#define TX_RING_MOD_MASK      7       /*   for this to work */
+-#endif
+-
+-#define CPM_ENET_RX_FRSIZE  2048 /* overkill left over from ppc page-based allocation */
+-static char rx_buf_pool[RX_RING_SIZE * CPM_ENET_RX_FRSIZE];
+-
+-
+-/* The CPM stores dest/src/type, data, and checksum for receive packets.
+- */
+-#define PKT_MAXBUF_SIZE               1518
+-#define PKT_MINBUF_SIZE               64
+-#define PKT_MAXBLR_SIZE               1520
+-
+-/* The CPM buffer descriptors track the ring buffers.  The rx_bd_base and
+- * tx_bd_base always point to the base of the buffer descriptors.  The
+- * cur_rx and cur_tx point to the currently available buffer.
+- * The dirty_tx tracks the current buffer that is being sent by the
+- * controller.  The cur_tx and dirty_tx are equal under both completely
+- * empty and completely full conditions.  The empty/ready indicator in
+- * the buffer descriptor determines the actual condition.
+- */
+-struct scc_enet_private {
+-      /* The saved address of a sent-in-place packet/buffer, for skfree(). */
+-      struct  sk_buff* tx_skbuff[TX_RING_SIZE];
+-      ushort  skb_cur;
+-      ushort  skb_dirty;
+-
+-      /* CPM dual port RAM relative addresses.
+-      */
+-      QUICC_BD        *rx_bd_base;            /* Address of Rx and Tx buffers. */
+-      QUICC_BD        *tx_bd_base;
+-      QUICC_BD        *cur_rx, *cur_tx;               /* The next free ring entry */
+-      QUICC_BD        *dirty_tx;      /* The ring entries to be free()ed. */
+-      volatile struct scc_regs        *sccp;
+-      /* struct       net_device_stats stats; */
+-      struct  net_device_stats stats;
+-      uint    tx_full;
+-      /* spinlock_t lock; */
+-      volatile unsigned int lock;
+-};
+-
+-
+-
+-static int scc_enet_open(struct net_device *dev);
+-static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+-static int scc_enet_rx(struct net_device *dev);
+-static irqreturn_t scc_enet_interrupt(int vec, void *dev_id, struct pt_regs *fp);
+-static int scc_enet_close(struct net_device *dev);
+-/* static struct net_device_stats *scc_enet_get_stats(struct net_device *dev); */
+-static struct net_device_stats *scc_enet_get_stats(struct net_device *dev);
+-static void set_multicast_list(struct net_device *dev);
+-
+-/* Get this from various configuration locations (depends on board).
+-*/
+-/*static      ushort  my_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };*/
+-
+-/* Typically, 860(T) boards use SCC1 for Ethernet, and other 8xx boards
+- * use SCC2.  This is easily extended if necessary.
+- */
+-
+-#define CONFIG_SCC1_ENET /* by default */
+-
+-#ifdef CONFIG_SCC1_ENET
+-#define CPM_CR_ENET CPM_CR_CH_SCC1
+-#define PROFF_ENET    PROFF_SCC1
+-#define SCC_ENET      0
+-#define CPMVEC_ENET   CPMVEC_SCC1
+-#endif
+-
+-#ifdef CONFIG_SCC2_ENET
+-#define CPM_CR_ENET   CPM_CR_CH_SCC2
+-#define PROFF_ENET    PROFF_SCC2
+-#define SCC_ENET      1               /* Index, not number! */
+-#define CPMVEC_ENET   CPMVEC_SCC2
+-#endif
+-
+-static int
+-scc_enet_open(struct net_device *dev)
+-{
+-
+-      /* I should reset the ring buffers here, but I don't yet know
+-       * a simple way to do that.
+-       * mleslie: That's no biggie. Worth doing, too.
+-       */
+-
+-      /* netif_start_queue(dev); */
+-      return 0;                                       /* Always succeed */
+-}
+-
+-
+-static int
+-scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+-{
+-      struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+-      volatile QUICC_BD       *bdp;
+-
+-      /* Fill in a Tx ring entry */
+-      bdp = cep->cur_tx;
+-
+-#ifndef final_version
+-      if (bdp->status & BD_ENET_TX_READY) {
+-              /* Ooops.  All transmit buffers are full.  Bail out.
+-               * This should not happen, since cep->tx_busy should be set.
+-               */
+-              printk("%s: tx queue full!.\n", dev->name);
+-              return 1;
+-      }
+-#endif
+-
+-      /* Clear all of the status flags.
+-       */
+-      bdp->status &= ~BD_ENET_TX_STATS;
+-
+-      /* If the frame is short, tell CPM to pad it.
+-      */
+-      if (skb->len <= ETH_ZLEN)
+-              bdp->status |= BD_ENET_TX_PAD;
+-      else
+-              bdp->status &= ~BD_ENET_TX_PAD;
+-
+-      /* Set buffer length and buffer pointer.
+-      */
+-      bdp->length = skb->len;
+-      /* bdp->buf = __pa(skb->data); */
+-      bdp->buf = skb->data;
+-
+-      /* Save skb pointer.
+-      */
+-      cep->tx_skbuff[cep->skb_cur] = skb;
+-
+-      /* cep->stats.tx_bytes += skb->len; */ /* TODO: It would really be nice... */
+-
+-      cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
+-      
+-
+-      /* Push the data cache so the CPM does not get stale memory
+-       * data.
+-       */
+-/*    flush_dcache_range((unsigned long)(skb->data), */
+-/*                                    (unsigned long)(skb->data + skb->len)); */
+-
+-      /* spin_lock_irq(&cep->lock); */ /* TODO: SPINLOCK */
+-      local_irq_disable();
+-      if (cep->lock > 0) {
+-              printk ("scc_enet_start_xmit() lock == %d\n", cep->lock);
+-      } else {
+-              cep->lock++;
+-      }
+-
+-      /* Send it on its way.  Tell CPM its ready, interrupt when done,
+-       * its the last BD of the frame, and to put the CRC on the end.
+-       */
+-      bdp->status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+-
+-      dev->trans_start = jiffies;
+-
+-      /* If this was the last BD in the ring, start at the beginning again.
+-      */
+-      if (bdp->status & BD_ENET_TX_WRAP)
+-              bdp = cep->tx_bd_base;
+-      else
+-              bdp++;
+-
+-      if (bdp->status & BD_ENET_TX_READY) {
+-              /* netif_stop_queue(dev); */
+-              cep->tx_full = 1;
+-      }
+-
+-      cep->cur_tx = (QUICC_BD *)bdp;
+-
+-      /* spin_unlock_irq(&cep->lock); */ /* TODO: SPINLOCK */
+-      cep->lock--;
+-      sti();
+-
+-      return 0;
+-}
+-
+-#if 0
+-static void
+-scc_enet_timeout(struct net_device *dev)
+-{
+-      struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+-
+-      printk("%s: transmit timed out.\n", dev->name);
+-      cep->stats.tx_errors++;
+-#ifndef final_version
+-      {
+-              int     i;
+-              QUICC_BD        *bdp;
+-              printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n",
+-                     cep->cur_tx, cep->tx_full ? " (full)" : "",
+-                     cep->cur_rx);
+-              bdp = cep->tx_bd_base;
+-              for (i = 0 ; i < TX_RING_SIZE; i++, bdp++)
+-                      printk("%04x %04x %08x\n",
+-                             bdp->status,
+-                             bdp->length,
+-                             (int)(bdp->buf));
+-              bdp = cep->rx_bd_base;
+-              for (i = 0 ; i < RX_RING_SIZE; i++, bdp++)
+-                      printk("%04x %04x %08x\n",
+-                             bdp->status,
+-                             bdp->length,
+-                             (int)(bdp->buf));
+-      }
+-#endif
+-/*    if (!cep->tx_full) */
+-/*            netif_wake_queue(dev); */
+-}
+-#endif
+-
+-/* The interrupt handler.
+- * This is called from the CPM handler, not the MPC core interrupt.
+- */
+-static irqreturn_t scc_enet_interrupt(int vec, void *dev_id, struct pt_regs *fp)
+-{
+-      struct  net_device *dev = (struct net_device *)dev_id;
+-      volatile struct scc_enet_private *cep;
+-      volatile QUICC_BD       *bdp;
+-      ushort  int_events;
+-      int     must_restart;
+-
+-      cep = (struct scc_enet_private *)dev->priv;
+-
+-      /* Get the interrupt events that caused us to be here.
+-      */
+-      int_events = cep->sccp->scc_scce;
+-      cep->sccp->scc_scce = int_events;
+-      must_restart = 0;
+-
+-      /* Handle receive event in its own function.
+-      */
+-      if (int_events & SCCE_ENET_RXF)
+-              scc_enet_rx(dev_id);
+-
+-      /* Check for a transmit error.  The manual is a little unclear
+-       * about this, so the debug code until I get it figured out.  It
+-       * appears that if TXE is set, then TXB is not set.  However,
+-       * if carrier sense is lost during frame transmission, the TXE
+-       * bit is set, "and continues the buffer transmission normally."
+-       * I don't know if "normally" implies TXB is set when the buffer
+-       * descriptor is closed.....trial and error :-).
+-       */
+-
+-      /* Transmit OK, or non-fatal error.  Update the buffer descriptors.
+-      */
+-      if (int_events & (SCCE_ENET_TXE | SCCE_ENET_TXB)) {
+-          /* spin_lock(&cep->lock); */ /* TODO: SPINLOCK */
+-              /* local_irq_disable(); */
+-              if (cep->lock > 0) {
+-                      printk ("scc_enet_interrupt() lock == %d\n", cep->lock);
+-              } else {
+-                      cep->lock++;
+-              }
+-
+-          bdp = cep->dirty_tx;
+-          while ((bdp->status&BD_ENET_TX_READY)==0) {
+-              if ((bdp==cep->cur_tx) && (cep->tx_full == 0))
+-                  break;
+-
+-              if (bdp->status & BD_ENET_TX_HB)        /* No heartbeat */
+-                      cep->stats.tx_heartbeat_errors++;
+-              if (bdp->status & BD_ENET_TX_LC)        /* Late collision */
+-                      cep->stats.tx_window_errors++;
+-              if (bdp->status & BD_ENET_TX_RL)        /* Retrans limit */
+-                      cep->stats.tx_aborted_errors++;
+-              if (bdp->status & BD_ENET_TX_UN)        /* Underrun */
+-                      cep->stats.tx_fifo_errors++;
+-              if (bdp->status & BD_ENET_TX_CSL)       /* Carrier lost */
+-                      cep->stats.tx_carrier_errors++;
+-
+-
+-              /* No heartbeat or Lost carrier are not really bad errors.
+-               * The others require a restart transmit command.
+-               */
+-              if (bdp->status &
+-                  (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
+-                      must_restart = 1;
+-                      cep->stats.tx_errors++;
+-              }
+-
+-              cep->stats.tx_packets++;
+-
+-              /* Deferred means some collisions occurred during transmit,
+-               * but we eventually sent the packet OK.
+-               */
+-              if (bdp->status & BD_ENET_TX_DEF)
+-                      cep->stats.collisions++;
+-
+-              /* Free the sk buffer associated with this last transmit.
+-              */
+-              /* dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]); */
+-              dev_kfree_skb (cep->tx_skbuff[cep->skb_dirty]);
+-              cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;
+-
+-              /* Update pointer to next buffer descriptor to be transmitted.
+-              */
+-              if (bdp->status & BD_ENET_TX_WRAP)
+-                      bdp = cep->tx_bd_base;
+-              else
+-                      bdp++;
+-
+-              /* I don't know if we can be held off from processing these
+-               * interrupts for more than one frame time.  I really hope
+-               * not.  In such a case, we would now want to check the
+-               * currently available BD (cur_tx) and determine if any
+-               * buffers between the dirty_tx and cur_tx have also been
+-               * sent.  We would want to process anything in between that
+-               * does not have BD_ENET_TX_READY set.
+-               */
+-
+-              /* Since we have freed up a buffer, the ring is no longer
+-               * full.
+-               */
+-              if (cep->tx_full) {
+-                      cep->tx_full = 0;
+-/*                    if (netif_queue_stopped(dev)) */
+-/*                            netif_wake_queue(dev); */
+-              }
+-
+-              cep->dirty_tx = (QUICC_BD *)bdp;
+-          }
+-
+-          if (must_restart) {
+-                      volatile QUICC *cp;
+-
+-              /* Some transmit errors cause the transmitter to shut
+-               * down.  We now issue a restart transmit.  Since the
+-               * errors close the BD and update the pointers, the restart
+-               * _should_ pick up without having to reset any of our
+-               * pointers either.
+-               */
+-              cp = pquicc;
+-              cp->cp_cr =
+-                  mk_cr_cmd(CPM_CR_ENET, CPM_CR_RESTART_TX) | CPM_CR_FLG;
+-              while (cp->cp_cr & CPM_CR_FLG);
+-          }
+-          /* spin_unlock(&cep->lock); */ /* TODO: SPINLOCK */
+-              /* sti(); */
+-              cep->lock--;
+-      }
+-
+-      /* Check for receive busy, i.e. packets coming but no place to
+-       * put them.  This "can't happen" because the receive interrupt
+-       * is tossing previous frames.
+-       */
+-      if (int_events & SCCE_ENET_BSY) {
+-              cep->stats.rx_dropped++;
+-              printk("CPM ENET: BSY can't happen.\n");
+-      }
+-
+-      return IRQ_HANDLED;
+-}
+-
+-/* During a receive, the cur_rx points to the current incoming buffer.
+- * When we update through the ring, if the next incoming buffer has
+- * not been given to the system, we just set the empty indicator,
+- * effectively tossing the packet.
+- */
+-static int
+-scc_enet_rx(struct net_device *dev)
+-{
+-      struct  scc_enet_private *cep;
+-      volatile QUICC_BD       *bdp;
+-      struct  sk_buff *skb;
+-      ushort  pkt_len;
+-
+-      cep = (struct scc_enet_private *)dev->priv;
+-
+-      /* First, grab all of the stats for the incoming packet.
+-       * These get messed up if we get called due to a busy condition.
+-       */
+-      bdp = cep->cur_rx;
+-
+-      for (;;) {
+-              if (bdp->status & BD_ENET_RX_EMPTY)
+-                      break;
+-              
+-#ifndef final_version
+-              /* Since we have allocated space to hold a complete frame, both
+-               * the first and last indicators should be set.
+-               */
+-              if ((bdp->status & (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) !=
+-                      (BD_ENET_RX_FIRST | BD_ENET_RX_LAST))
+-                      printk("CPM ENET: rcv is not first+last\n");
+-#endif
+-
+-              /* Frame too long or too short.
+-               */
+-              if (bdp->status & (BD_ENET_RX_LG | BD_ENET_RX_SH))
+-                      cep->stats.rx_length_errors++;
+-              if (bdp->status & BD_ENET_RX_NO)        /* Frame alignment */
+-                      cep->stats.rx_frame_errors++;
+-              if (bdp->status & BD_ENET_RX_CR)        /* CRC Error */
+-                      cep->stats.rx_crc_errors++;
+-              if (bdp->status & BD_ENET_RX_OV)        /* FIFO overrun */
+-                      cep->stats.rx_crc_errors++;
+-
+-              /* Report late collisions as a frame error.
+-               * On this error, the BD is closed, but we don't know what we
+-               * have in the buffer.  So, just drop this frame on the floor.
+-               */
+-              if (bdp->status & BD_ENET_RX_CL) {
+-                      cep->stats.rx_frame_errors++;
+-              }
+-              else {
+-                      
+-                      /* Process the incoming frame.
+-                       */
+-                      cep->stats.rx_packets++;
+-                      pkt_len = bdp->length;
+-                      /* cep->stats.rx_bytes += pkt_len; */  /* TODO: It would really be nice... */
+-
+-                      /* This does 16 byte alignment, much more than we need.
+-                       * The packet length includes FCS, but we don't want to
+-                       * include that when passing upstream as it messes up
+-                       * bridging applications.
+-                       */
+-                      skb = dev_alloc_skb(pkt_len-4);
+-
+-                      if (skb == NULL) {
+-                              printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+-                              cep->stats.rx_dropped++;
+-                      }
+-                      else {
+-                              skb->dev = dev;
+-                              skb_put(skb,pkt_len-4); /* Make room */
+-                              eth_copy_and_sum(skb, (unsigned char *)bdp->buf, pkt_len-4, 0);
+-                              skb->protocol=eth_type_trans(skb,dev);
+-                              netif_rx(skb);
+-                      }
+-              }
+-
+-              /* Clear the status flags for this buffer.
+-               */
+-              bdp->status &= ~BD_ENET_RX_STATS;
+-
+-              /* Mark the buffer empty.
+-               */
+-              bdp->status |= BD_ENET_RX_EMPTY;
+-
+-              /* Update BD pointer to next entry.
+-               */
+-              if (bdp->status & BD_ENET_RX_WRAP)
+-                      bdp = cep->rx_bd_base;
+-              else
+-                      bdp++;
+-
+-      }
+-      cep->cur_rx = (QUICC_BD *)bdp;
+-
+-      return 0;
+-}
+-
+-static int
+-scc_enet_close(struct net_device *dev)
+-{
+-      /* Don't know what to do yet.
+-      */
+-      /* netif_stop_queue(dev); */
+-
+-      return 0;
+-}
+-
+-/* static struct net_device_stats *scc_enet_get_stats(struct net_device *dev) */
+-static struct net_device_stats *scc_enet_get_stats(struct net_device *dev)
+-{
+-      struct scc_enet_private *cep = (struct scc_enet_private *)dev->priv;
+-
+-      return &cep->stats;
+-}
+-
+-/* Set or clear the multicast filter for this adaptor.
+- * Skeleton taken from sunlance driver.
+- * The CPM Ethernet implementation allows Multicast as well as individual
+- * MAC address filtering.  Some of the drivers check to make sure it is
+- * a group multicast address, and discard those that are not.  I guess I
+- * will do the same for now, but just remove the test if you want
+- * individual filtering as well (do the upper net layers want or support
+- * this kind of feature?).
+- */
+-
+-static void set_multicast_list(struct net_device *dev)
+-{
+-      struct  scc_enet_private *cep;
+-      struct  dev_mc_list *dmi;
+-      u_char  *mcptr, *tdptr;
+-      volatile scc_enet_t *ep;
+-      int     i, j;
+-      volatile QUICC *cp = pquicc;
+-
+-      cep = (struct scc_enet_private *)dev->priv;
+-
+-      /* Get pointer to SCC area in parameter RAM.
+-      */
+-      ep = (scc_enet_t *)dev->base_addr;
+-
+-      if (dev->flags&IFF_PROMISC) {
+-        
+-              /* Log any net taps. */
+-              printk("%s: Promiscuous mode enabled.\n", dev->name);
+-              cep->sccp->scc_psmr |= ETHER_PRO; 
+-      } else {
+-
+-              cep->sccp->scc_psmr &= ~ETHER_PRO;
+-
+-              if (dev->flags & IFF_ALLMULTI) {
+-                      /* Catch all multicast addresses, so set the
+-                       * filter to all 1's.
+-                       */
+-                      ep->sen_gaddr1 = 0xffff;
+-                      ep->sen_gaddr2 = 0xffff;
+-                      ep->sen_gaddr3 = 0xffff;
+-                      ep->sen_gaddr4 = 0xffff;
+-              }
+-              else {
+-                      /* Clear filter and add the addresses in the list.
+-                      */
+-                      ep->sen_gaddr1 = 0;
+-                      ep->sen_gaddr2 = 0;
+-                      ep->sen_gaddr3 = 0;
+-                      ep->sen_gaddr4 = 0;
+-
+-                      dmi = dev->mc_list;
+-
+-                      for (i=0; i<dev->mc_count; i++) {
+-                              
+-                              /* Only support group multicast for now.
+-                              */
+-                              if (!(dmi->dmi_addr[0] & 1))
+-                                      continue;
+-
+-                              /* The address in dmi_addr is LSB first,
+-                               * and taddr is MSB first.  We have to
+-                               * copy bytes MSB first from dmi_addr.
+-                               */
+-                              mcptr = (u_char *)dmi->dmi_addr + 5;
+-                              tdptr = (u_char *)&ep->sen_taddrh;
+-                              for (j=0; j<6; j++)
+-                                      *tdptr++ = *mcptr--;
+-
+-                              /* Ask CPM to run CRC and set bit in
+-                               * filter mask.
+-                               */
+-                              cp->cp_cr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_SET_GADDR) | CPM_CR_FLG;
+-                              /* this delay is necessary here -- Cort */
+-                              udelay(10);
+-                              while (cp->cp_cr & CPM_CR_FLG);
+-                      }
+-              }
+-      }
+-}
+-
+-
+-/* Initialize the CPM Ethernet on SCC.
+- */
+-int scc_enet_init(void)
+-{
+-      struct net_device *dev;
+-      struct scc_enet_private *cep;
+-      int i, j;
+-      unsigned char   *eap;
+-      /* unsigned long        mem_addr; */
+-      /* pte_t                *pte; */
+-      /* bd_t         *bd; */ /* `board tag' used by ppc - TODO: integrate uC bootloader vars */
+-      volatile        QUICC_BD        *bdp;
+-      volatile        QUICC   *cp;
+-      volatile struct scc_regs        *sccp;
+-      volatile struct ethernet_pram   *ep;
+-      /* volatile     immap_t         *immap; */
+-
+-      cp = pquicc;    /* Get pointer to Communication Processor */
+-
+-      /* immap = (immap_t *)IMAP_ADDR; */     /* and to internal registers */
+-
+-      /* bd = (bd_t *)__res; */
+-
+-      /* Allocate some private information.
+-      */
+-      cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
+-      memset(cep, 0, sizeof(*cep));
+-      /* __clear_user(cep,sizeof(*cep)); */
+-      /* spin_lock_init(&cep->lock); */ /* TODO: SPINLOCK */
+-
+-      /* Create an Ethernet device instance.
+-       */
+-      dev = init_etherdev(0, 0);
+-
+-      /* Get pointer to SCC area in parameter RAM.
+-      */
+-      /* ep = (ethernet_pram *)(&cp->cp_dparam[PROFF_ENET]); */
+-      ep = &pquicc->pram[SCC_ENET].enet_scc;
+-
+-      /* And another to the SCC register area.
+-      */
+-      sccp = &pquicc->scc_regs[SCC_ENET];
+-      cep->sccp = sccp;               /* Keep the pointer handy */
+-
+-      /* Disable receive and transmit in case EPPC-Bug started it.
+-      */
+-      sccp->scc_gsmr.w.low &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+-
+-      /* Set up 360 pins for SCC interface to ethernet transceiver.
+-       * Pin mappings (PA_xx and PC_xx) are defined in commproc.h
+-       */
+-
+-      /* Configure port A pins for Txd and Rxd.
+-       */
+-      pquicc->pio_papar |= (PA_ENET_RXD | PA_ENET_TXD);
+-      pquicc->pio_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
+-      pquicc->pio_paodr &= ~PA_ENET_TXD;
+-
+-      /* Configure port C pins to enable CLSN and RENA.
+-       */
+-      pquicc->pio_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+-      pquicc->pio_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+-      pquicc->pio_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
+-
+-      /* Configure port A for TCLK and RCLK.
+-      */
+-      pquicc->pio_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
+-      pquicc->pio_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
+-
+-      /* Configure Serial Interface clock routing.
+-       * First, clear all SCC bits to zero, then set the ones we want.
+-       */
+-      pquicc->si_sicr &= ~SICR_ENET_MASK;
+-      pquicc->si_sicr |= SICR_ENET_CLKRT;
+-
+-
+-      /* Allocate space for the buffer descriptors in the DP ram.
+-       * These are relative offsets in the DP ram address space.
+-       * Initialize base addresses for the buffer descriptors.
+-       */
+-      i = m360_cpm_dpalloc(sizeof(QUICC_BD) * RX_RING_SIZE);
+-      ep->rbase = i;
+-      cep->rx_bd_base = (QUICC_BD *)((uint)pquicc + i);
+-
+-      i = m360_cpm_dpalloc(sizeof(QUICC_BD) * TX_RING_SIZE);
+-      ep->tbase = i;
+-      cep->tx_bd_base = (QUICC_BD *)((uint)pquicc + i);
+-
+-      cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
+-      cep->cur_rx = cep->rx_bd_base;
+-
+-      /* Issue init Rx BD command for SCC.
+-       * Manual says to perform an Init Rx parameters here.  We have
+-       * to perform both Rx and Tx because the SCC may have been
+-       * already running. [In uCquicc's case, I don't think that is so - mles]
+-       * In addition, we have to do it later because we don't yet have
+-       * all of the BD control/status set properly.
+-      cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_RX) | CPM_CR_FLG;
+-      while (cp->cp_cpcr & CPM_CR_FLG);
+-       */
+-
+-      /* Initialize function code registers for big-endian.
+-      */
+-      ep->rfcr = (SCC_EB | SCC_FC_DMA);
+-      ep->tfcr = (SCC_EB | SCC_FC_DMA);
+-
+-      /* Set maximum bytes per receive buffer.
+-       * This appears to be an Ethernet frame size, not the buffer
+-       * fragment size.  It must be a multiple of four.
+-       */
+-      ep->mrblr  = PKT_MAXBLR_SIZE;
+-
+-      /* Set CRC preset and mask.
+-       */
+-      ep->c_pres = 0xffffffff;
+-      ep->c_mask = 0xdebb20e3; /* see 360UM p. 7-247 */
+-
+-      ep->crcec  = 0; /* CRC Error counter */
+-      ep->alec   = 0; /* alignment error counter */
+-      ep->disfc  = 0; /* discard frame counter */
+-
+-      ep->pads   = 0x8888;    /* Tx short frame pad character */
+-      ep->ret_lim = 0x000f;   /* Retry limit threshold */
+-
+-      ep->mflr   = PKT_MAXBUF_SIZE;   /* maximum frame length register */
+-      ep->minflr = PKT_MINBUF_SIZE;   /* minimum frame length register */
+-
+-      ep->maxd1 = PKT_MAXBLR_SIZE;    /* maximum DMA1 length */
+-      ep->maxd2 = PKT_MAXBLR_SIZE;    /* maximum DMA2 length */
+-
+-      /* Clear hash tables, group and individual.
+-       */
+-      ep->gaddr1 = ep->gaddr2 = ep->gaddr3 = ep->gaddr4 = 0;
+-      ep->iaddr1 = ep->iaddr2 = ep->iaddr3 = ep->iaddr4 = 0;
+-
+-      /* Set Ethernet station address.
+-       *
+-       * The uCbootloader provides a hook to the kernel to retrieve
+-       * stuff like the MAC address. This is retrieved in config_BSP()
+-       */
+-#if defined (CONFIG_UCQUICC)
+-      {
+-              extern unsigned char *scc1_hwaddr;
+-
+-              eap = (char *)ep->paddr.b;
+-              for (i=5; i>=0; i--)
+-                      *eap++ = dev->dev_addr[i] = scc1_hwaddr[i];
+-      }
+-#endif
+-
+-
+-/* #ifndef CONFIG_MBX */
+-/*    eap = (unsigned char *)&(ep->paddrh); */
+-
+-/*    for (i=5; i>=0; i--) */
+-/*            *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i]; */
+-/* #else */
+-/*    for (i=5; i>=0; i--) */
+-/*            dev->dev_addr[i] = *eap++; */
+-/* #endif */
+-
+-      ep->p_per   = 0;        /* 'cause the book says so */
+-      ep->taddr_l = 0;        /* temp address (LSB) */
+-      ep->taddr_m = 0;
+-      ep->taddr_h = 0;        /* temp address (MSB) */
+-
+-      /* Now allocate the host memory pages and initialize the
+-       * buffer descriptors.
+-       */
+-      /* initialize rx buffer descriptors */
+-      bdp = cep->tx_bd_base;
+-      for (j=0; j<(TX_RING_SIZE-1); j++) {
+-              bdp->buf = 0;
+-              bdp->status = 0;
+-              bdp++;
+-      }
+-      bdp->buf = 0;
+-      bdp->status = BD_SC_WRAP;
+-
+-
+-      /* initialize rx buffer descriptors */
+-      bdp = cep->rx_bd_base;
+-      for (j=0; j<(RX_RING_SIZE-1); j++) {
+-              bdp->buf = &rx_buf_pool[j * CPM_ENET_RX_FRSIZE];
+-              bdp->status = BD_SC_EMPTY | BD_SC_INTRPT;
+-              bdp++;
+-      }
+-      bdp->buf = &rx_buf_pool[j * CPM_ENET_RX_FRSIZE];
+-      bdp->status = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
+-
+-
+-
+-      /* Let's re-initialize the channel now.  We have to do it later
+-       * than the manual describes because we have just now finished
+-       * the BD initialization.
+-       */
+-      cp->cp_cr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+-      while (cp->cp_cr & CPM_CR_FLG);
+-
+-      cep->skb_cur = cep->skb_dirty = 0;
+-
+-      sccp->scc_scce = 0xffff;        /* Clear any pending events */
+-
+-      /* Enable interrupts for transmit error, complete frame
+-       * received, and any transmit buffer we have also set the
+-       * interrupt flag.
+-       */
+-      sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);
+-
+-      /* Install our interrupt handler.
+-       */
+-      /* cpm_install_handler(CPMVEC_ENET, scc_enet_interrupt, dev); */
+-      request_irq(CPMVEC_ENET, scc_enet_interrupt,
+-              IRQ_FLG_LOCK, dev->name, (void *)dev);
+-
+-      /* Set GSMR_H to enable all normal operating modes.
+-       * Set GSMR_L to enable Ethernet to MC68160.
+-       */
+-      sccp->scc_gsmr.w.high = 0;
+-      sccp->scc_gsmr.w.low  = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 |
+-                                                       SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET);
+-
+-      /* Set sync/delimiters.
+-       */
+-      sccp->scc_dsr = 0xd555;
+-
+-      /* Set processing mode.  Use Ethernet CRC, catch broadcast, and
+-       * start frame search 22 bit times after RENA.
+-       */
+-      sccp->scc_psmr = (SCC_PMSR_ENCRC       /* Ethernet CRC mode */
+-                        /* | SCC_PSMR_HBC */ /* Enable heartbeat */
+-                        /* | SCC_PMSR_PRO */ /* Promiscuous mode */
+-                        /* | SCC_PMSR_FDE */ /* Full duplex enable */
+-                        | ETHER_NIB_22);
+-      /* sccp->scc_psmr = (SCC_PMSR_PRO | ETHER_CRC_32 | ETHER_NIB_22); */
+-
+-
+-      /* It is now OK to enable the Ethernet transmitter.
+-       * Unfortunately, there are board implementation differences here.
+-       */
+-#if defined(CONFIG_UCQUICC)
+-/*     immap->im_ioport.iop_pcpar |= PC_ENET_TENA; */
+-/*     immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA; */
+-       cp->pio_pcpar |=  PC_ENET_TENA; /* t_en */
+-       cp->pio_pcdir &= ~PC_ENET_TENA;
+-
+-       cp->pip_pbpar &= ~(0x00000200); /* power up ethernet transceiver */
+-       cp->pip_pbdir |=  (0x00000200);
+-       cp->pip_pbdat |=  (0x00000200);
+-#endif
+-
+-
+-      dev->base_addr = (unsigned long)ep;
+-      dev->priv = cep;
+-#if 0
+-      dev->name = "CPM_ENET";
+-#endif
+-
+-      /* The CPM Ethernet specific entries in the device structure. */
+-      dev->open = scc_enet_open;
+-      dev->hard_start_xmit = scc_enet_start_xmit;
+-      /* dev->tx_timeout = scc_enet_timeout; */
+-      /* dev->watchdog_timeo = TX_TIMEOUT; */
+-      dev->stop = scc_enet_close;
+-      dev->get_stats = scc_enet_get_stats;
+-      dev->set_multicast_list = set_multicast_list;
+-
+-      /* And last, enable the transmit and receive processing.
+-      */
+-      sccp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+-
+-      printk("%s: CPM ENET Version 0.3, ", dev->name);
+-      for (i=0; i<5; i++)
+-              printk("%02x:", dev->dev_addr[i]);
+-      printk("%02x\n", dev->dev_addr[5]);
+-
+-      return 0;
+-}
+-
+-
+-
+-int m68360_enet_probe(struct device *dev)
+-{
+-      return(scc_enet_init ());
+-}
+-
+-
+-/*
+- * Local variables:
+- *  c-indent-level: 4
+- *  c-basic-offset: 4
+- *  tab-width: 4
+- * End:
+- */
+--- linux-2.6.0/drivers/net/8139too.c  2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/8139too.c   2003-12-28 23:22:01.000000000 -0800
+@@ -92,7 +92,7 @@
+ */
+ #define DRV_NAME      "8139too"
+-#define DRV_VERSION   "0.9.26"
++#define DRV_VERSION   "0.9.27"
+ #include <linux/config.h>
+@@ -117,17 +117,17 @@
+ #define RTL8139_DRIVER_NAME   DRV_NAME " Fast Ethernet driver " DRV_VERSION
+ #define PFX DRV_NAME ": "
++/* Default Message level */
++#define RTL8139_DEF_MSG_ENABLE   (NETIF_MSG_DRV   | \
++                                 NETIF_MSG_PROBE  | \
++                                 NETIF_MSG_LINK)
++
+ /* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */
+ #ifdef CONFIG_8139TOO_PIO
+ #define USE_IO_OPS 1
+ #endif
+-/* use a 16K rx ring buffer instead of the default 32K */
+-#ifdef CONFIG_SH_DREAMCAST
+-#define USE_BUF16K 1
+-#endif
+-
+ /* define to 1 to enable copious debugging info */
+ #undef RTL8139_DEBUG
+@@ -146,9 +146,9 @@
+ #  define assert(expr) do {} while (0)
+ #else
+ #  define assert(expr) \
+-        if(!(expr)) {                                 \
+-        printk( "Assertion failed! %s,%s,%s,line=%d\n",       \
+-        #expr,__FILE__,__FUNCTION__,__LINE__);                \
++        if(unlikely(!(expr))) {                                       \
++        printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n",       \
++        #expr,__FILE__,__FUNCTION__,__LINE__);                        \
+         }
+ #endif
+@@ -159,9 +159,6 @@
+ static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+-/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+-static int max_interrupt_work = 20;
+-
+ /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
+    The RTL chips use a 64 element hash table based on the Ethernet CRC.  */
+ static int multicast_filter_limit = 32;
+@@ -169,16 +166,16 @@ static int multicast_filter_limit = 32;
+ /* bitmapped message enable number */
+ static int debug = -1;
+-/* Size of the in-memory receive ring. */
+-#ifdef USE_BUF16K
+-#define RX_BUF_LEN_IDX        1       /* 0==8K, 1==16K, 2==32K, 3==64K */
+-#else
+-#define RX_BUF_LEN_IDX        2       /* 0==8K, 1==16K, 2==32K, 3==64K */
+-#endif
+-#define RX_BUF_LEN    (8192 << RX_BUF_LEN_IDX)
++/* Ring size is now a config option */
++#define RX_BUF_LEN    (8192 << CONFIG_8139_RXBUF_IDX)
+ #define RX_BUF_PAD    16
+ #define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
++
++#if RX_BUF_LEN == 65536
++#define RX_BUF_TOT_LEN        RX_BUF_LEN
++#else
+ #define RX_BUF_TOT_LEN        (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
++#endif
+ /* Number of Tx descriptor registers. */
+ #define NUM_TX_DESC   4
+@@ -251,6 +248,10 @@ static struct pci_device_id rtl8139_pci_
+       {0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+       {0x1432, 0x9130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+       {0x02ac, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
++      {0x018a, 0x0106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
++      {0x126c, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
++      {0x1743, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
++      {0x021b, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 }, 
+ #ifdef CONFIG_SH_SECUREEDGE5410
+       /* Bogus 8139 silicon reports 8129 without external PROM :-( */
+@@ -450,7 +451,7 @@ enum RxConfigBits {
+       RxCfgRcv32K = (1 << 12),
+       RxCfgRcv64K = (1 << 11) | (1 << 12),
+-      /* Disable packet wrap at end of Rx buffer */
++      /* Disable packet wrap at end of Rx buffer. (not possible with 64k) */
+       RxNoWrap = (1 << 7),
+ };
+@@ -560,6 +561,7 @@ struct rtl8139_private {
+       int drv_flags;
+       struct pci_dev *pci_dev;
+       u32 pci_state[16];
++      u32 msg_enable;
+       struct net_device_stats stats;
+       unsigned char *rx_ring;
+       unsigned int cur_rx;    /* Index into the Rx buffer of next Rx pkt. */
+@@ -574,6 +576,7 @@ struct rtl8139_private {
+       char twistie, twist_row, twist_col;     /* Twister tune state. */
+       unsigned int default_port:4;    /* Last dev->if_port value. */
+       spinlock_t lock;
++      spinlock_t rx_lock;
+       chip_t chipset;
+       pid_t thr_pid;
+       wait_queue_head_t thr_wait;
+@@ -590,13 +593,11 @@ MODULE_DESCRIPTION ("RealTek RTL-8139 Fa
+ MODULE_LICENSE("GPL");
+ MODULE_PARM (multicast_filter_limit, "i");
+-MODULE_PARM (max_interrupt_work, "i");
+ MODULE_PARM (media, "1-" __MODULE_STRING(MAX_UNITS) "i");
+ MODULE_PARM (full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+ MODULE_PARM (debug, "i");
+ MODULE_PARM_DESC (debug, "8139too bitmapped message enable number");
+ MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered multicast addresses");
+-MODULE_PARM_DESC (max_interrupt_work, "8139too maximum events handled per interrupt");
+ MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
+ MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
+@@ -610,6 +611,10 @@ static void rtl8139_tx_timeout (struct n
+ static void rtl8139_init_ring (struct net_device *dev);
+ static int rtl8139_start_xmit (struct sk_buff *skb,
+                              struct net_device *dev);
++static int rtl8139_poll(struct net_device *dev, int *budget);
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void rtl8139_poll_controller(struct net_device *dev);
++#endif
+ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
+                              struct pt_regs *regs);
+ static int rtl8139_close (struct net_device *dev);
+@@ -682,16 +687,32 @@ static const u16 rtl8139_intr_mask =
+       PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
+       TxErr | TxOK | RxErr | RxOK;
+-#ifdef USE_BUF16K 
++static const u16 rtl8139_norx_intr_mask =
++      PCIErr | PCSTimeout | RxUnderrun |
++      TxErr | TxOK | RxErr ;
++
++#if CONFIG_8139_RXBUF_IDX == 0
++static const unsigned int rtl8139_rx_config =
++      RxCfgRcv8K | RxNoWrap |
++      (RX_FIFO_THRESH << RxCfgFIFOShift) |
++      (RX_DMA_BURST << RxCfgDMAShift);
++#elif CONFIG_8139_RXBUF_IDX == 1
+ static const unsigned int rtl8139_rx_config =
+       RxCfgRcv16K | RxNoWrap |
+       (RX_FIFO_THRESH << RxCfgFIFOShift) |
+       (RX_DMA_BURST << RxCfgDMAShift);
+-#else
++#elif CONFIG_8139_RXBUF_IDX == 2
+ static const unsigned int rtl8139_rx_config =
+       RxCfgRcv32K | RxNoWrap |
+       (RX_FIFO_THRESH << RxCfgFIFOShift) |
+       (RX_DMA_BURST << RxCfgDMAShift);
++#elif CONFIG_8139_RXBUF_IDX == 3
++static const unsigned int rtl8139_rx_config =
++      RxCfgRcv64K |
++      (RX_FIFO_THRESH << RxCfgFIFOShift) |
++      (RX_DMA_BURST << RxCfgDMAShift);
++#else
++#error "Invalid configuration for 8139_RXBUF_IDX"
+ #endif
+ static const unsigned int rtl8139_tx_config =
+@@ -868,9 +889,7 @@ static int __devinit rtl8139_init_board 
+ match:
+       DPRINTK ("chipset id (%d) == index %d, '%s'\n",
+-              tmp,
+-              tp->chipset,
+-              rtl_chip_info[tp->chipset].name);
++               version, i, rtl_chip_info[i].name);
+       if (tp->chipset >= CH_8139B) {
+               u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
+@@ -964,6 +983,8 @@ static int __devinit rtl8139_init_one (s
+       /* The Rtl8139-specific entries in the device structure. */
+       dev->open = rtl8139_open;
+       dev->hard_start_xmit = rtl8139_start_xmit;
++      dev->poll = rtl8139_poll;
++      dev->weight = 64;
+       dev->stop = rtl8139_close;
+       dev->get_stats = rtl8139_get_stats;
+       dev->set_multicast_list = rtl8139_set_rx_mode;
+@@ -971,6 +992,9 @@ static int __devinit rtl8139_init_one (s
+       dev->ethtool_ops = &rtl8139_ethtool_ops;
+       dev->tx_timeout = rtl8139_tx_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++      dev->poll_controller = rtl8139_poll_controller;
++#endif
+       /* note: the hardware is not capable of sg/csum/highdma, however
+        * through the use of skb_copy_and_csum_dev we enable these
+@@ -986,7 +1010,10 @@ static int __devinit rtl8139_init_one (s
+       /* note: tp->chipset set in rtl8139_init_board */
+       tp->drv_flags = board_info[ent->driver_data].hw_flags;
+       tp->mmio_addr = ioaddr;
++      tp->msg_enable =
++              (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
+       spin_lock_init (&tp->lock);
++      spin_lock_init (&tp->rx_lock);
+       init_waitqueue_head (&tp->thr_wait);
+       init_completion (&tp->thr_exited);
+       tp->mii.dev = dev;
+@@ -1288,9 +1315,7 @@ static int rtl8139_open (struct net_devi
+ {
+       struct rtl8139_private *tp = dev->priv;
+       int retval;
+-#ifdef RTL8139_DEBUG
+       void *ioaddr = tp->mmio_addr;
+-#endif
+       retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);
+       if (retval)
+@@ -1319,8 +1344,10 @@ static int rtl8139_open (struct net_devi
+       rtl8139_init_ring (dev);
+       rtl8139_hw_start (dev);
++      netif_start_queue (dev);
+-      DPRINTK ("%s: rtl8139_open() ioaddr %#lx IRQ %d"
++      if (netif_msg_ifup(tp))
++              printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d"
+                       " GP Pins %2.2x %s-duplex.\n",
+                       dev->name, pci_resource_start (tp->pci_dev, 1),
+                       dev->irq, RTL_R8 (MediaStatus),
+@@ -1337,7 +1364,7 @@ static void rtl_check_media (struct net_
+       struct rtl8139_private *tp = dev->priv;
+       if (tp->phys[0] >= 0) {
+-              mii_check_media(&tp->mii, 1, init_media);
++              mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
+       }
+ }
+@@ -1407,8 +1434,6 @@ static void rtl8139_hw_start (struct net
+       /* Enable all known interrupts by setting the interrupt mask. */
+       RTL_W16 (IntrMask, rtl8139_intr_mask);
+-
+-      netif_start_queue (dev);
+ }
+@@ -1631,7 +1656,7 @@ static inline void rtl8139_start_thread(
+       }
+ }
+-static void rtl8139_tx_clear (struct rtl8139_private *tp)
++static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
+ {
+       tp->cur_tx = 0;
+       tp->dirty_tx = 0;
+@@ -1661,6 +1686,7 @@ static void rtl8139_tx_timeout (struct n
+       if (tmp8 & CmdTxEnb)
+               RTL_W8 (ChipCmd, CmdRxEnb);
++      spin_lock(&tp->rx_lock);
+       /* Disable interrupts by clearing the interrupt mask. */
+       RTL_W16 (IntrMask, 0x0000);
+@@ -1679,9 +1705,12 @@ static void rtl8139_tx_timeout (struct n
+       spin_unlock_irqrestore (&tp->lock, flags);
+       /* ...and finally, reset everything */
+-      rtl8139_hw_start (dev);
+-
+-      netif_wake_queue (dev);
++      if (netif_running(dev)) {
++              rtl8139_hw_start (dev);
++              netif_wake_queue (dev);
++      }
++      spin_unlock(&tp->rx_lock);
++      
+ }
+@@ -1695,6 +1724,7 @@ static int rtl8139_start_xmit (struct sk
+       /* Calculate the next Tx descriptor entry. */
+       entry = tp->cur_tx % NUM_TX_DESC;
++      /* Note: the chip doesn't have auto-pad! */
+       if (likely(len < TX_BUF_SIZE)) {
+               if (len < ETH_ZLEN)
+                       memset(tp->tx_buf[entry], 0, ETH_ZLEN);
+@@ -1706,7 +1736,6 @@ static int rtl8139_start_xmit (struct sk
+               return 0;
+       }
+-      /* Note: the chip doesn't have auto-pad! */
+       spin_lock_irq(&tp->lock);
+       RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
+                  tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
+@@ -1720,8 +1749,9 @@ static int rtl8139_start_xmit (struct sk
+               netif_stop_queue (dev);
+       spin_unlock_irq(&tp->lock);
+-      DPRINTK ("%s: Queued Tx packet size %u to slot %d.\n",
+-               dev->name, len, entry);
++      if (netif_msg_tx_queued(tp))
++              printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
++                      dev->name, len, entry);
+       return 0;
+ }
+@@ -1751,8 +1781,9 @@ static void rtl8139_tx_interrupt (struct
+               /* Note: TxCarrierLost is always asserted at 100mbps. */
+               if (txstatus & (TxOutOfWindow | TxAborted)) {
+                       /* There was an major error, log it. */
+-                      DPRINTK ("%s: Transmit error, Tx status %8.8x.\n",
+-                               dev->name, txstatus);
++                      if (netif_msg_tx_err(tp))
++                              printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
++                                      dev->name, txstatus);
+                       tp->stats.tx_errors++;
+                       if (txstatus & TxAborted) {
+                               tp->stats.tx_aborted_errors++;
+@@ -1792,8 +1823,7 @@ static void rtl8139_tx_interrupt (struct
+       if (tp->dirty_tx != dirty_tx) {
+               tp->dirty_tx = dirty_tx;
+               mb();
+-              if (netif_queue_stopped (dev))
+-                      netif_wake_queue (dev);
++              netif_wake_queue (dev);
+       }
+ }
+@@ -1807,8 +1837,9 @@ static void rtl8139_rx_err (u32 rx_statu
+       int tmp_work;
+ #endif
+-      DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n",
+-               dev->name, rx_status);
++      if (netif_msg_rx_err (tp)) 
++              printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n",
++                      dev->name, rx_status);
+       tp->stats.rx_errors++;
+       if (!(rx_status & RxStatusOK)) {
+               if (rx_status & RxTooLong) {
+@@ -1880,30 +1911,41 @@ static void rtl8139_rx_err (u32 rx_statu
+ #endif
+ }
+-static void rtl8139_rx_interrupt (struct net_device *dev,
+-                                struct rtl8139_private *tp, void *ioaddr)
+-{
+-      unsigned char *rx_ring;
+-      u16 cur_rx;
+-
+-      assert (dev != NULL);
+-      assert (tp != NULL);
+-      assert (ioaddr != NULL);
++#if CONFIG_8139_RXBUF_IDX == 3
++static __inline__ void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
++                               u32 offset, unsigned int size)
++{
++      u32 left = RX_BUF_LEN - offset;
++
++      if (size > left) {
++              memcpy(skb->data, ring + offset, left);
++              memcpy(skb->data+left, ring, size - left);
++      } else
++              memcpy(skb->data, ring + offset, size);
++}
++#endif
+-      rx_ring = tp->rx_ring;
+-      cur_rx = tp->cur_rx;
++static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
++                    int budget)
++{
++      void *ioaddr = tp->mmio_addr;
++      int received = 0;
++      unsigned char *rx_ring = tp->rx_ring;
++      unsigned int cur_rx = tp->cur_rx;
+       DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
+                " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
+                RTL_R16 (RxBufAddr),
+                RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
+-      while ((RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
+-              int ring_offset = cur_rx % RX_BUF_LEN;
++      while (netif_running(dev) && received < budget 
++             && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
++              u32 ring_offset = cur_rx % RX_BUF_LEN;
+               u32 rx_status;
+               unsigned int rx_size;
+               unsigned int pkt_size;
+               struct sk_buff *skb;
++              u16 status;
+               rmb();
+@@ -1912,8 +1954,9 @@ static void rtl8139_rx_interrupt (struct
+               rx_size = rx_status >> 16;
+               pkt_size = rx_size - 4;
+-              DPRINTK ("%s:  rtl8139_rx() status %4.4x, size %4.4x,"
+-                       " cur %4.4x.\n", dev->name, rx_status,
++              if (netif_msg_rx_status(tp))
++                      printk(KERN_DEBUG "%s:  rtl8139_rx() status %4.4x, size %4.4x,"
++                              " cur %4.4x.\n", dev->name, rx_status,
+                        rx_size, cur_rx);
+ #if RTL8139_DEBUG > 2
+               {
+@@ -1930,9 +1973,9 @@ static void rtl8139_rx_interrupt (struct
+                * Theoretically, this should never happen
+                * since EarlyRx is disabled.
+                */
+-              if (rx_size == 0xfff0) {
++              if (unlikely(rx_size == 0xfff0)) {
+                       tp->xstats.early_rx++;
+-                      break;
++                      goto done;
+               }
+               /* If Rx err or invalid rx_size/rx_status received
+@@ -1940,55 +1983,69 @@ static void rtl8139_rx_interrupt (struct
+                * Rx process gets reset, so we abort any further
+                * Rx processing.
+                */
+-              if ((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
+-                  (rx_size < 8) ||
+-                  (!(rx_status & RxStatusOK))) {
++              if (unlikely((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
++                           (rx_size < 8) ||
++                           (!(rx_status & RxStatusOK)))) {
+                       rtl8139_rx_err (rx_status, dev, tp, ioaddr);
+-                      return;
++                      return -1;
+               }
+               /* Malloc up new buffer, compatible with net-2e. */
+               /* Omit the four octet CRC from the length. */
+-              /* TODO: consider allocating skb's outside of
+-               * interrupt context, both to speed interrupt processing,
+-               * and also to reduce the chances of having to
+-               * drop packets here under memory pressure.
+-               */
+-
+               skb = dev_alloc_skb (pkt_size + 2);
+-              if (skb) {
++              if (likely(skb)) {
+                       skb->dev = dev;
+                       skb_reserve (skb, 2);   /* 16 byte align the IP fields. */
+-
++#if CONFIG_8139_RXBUF_IDX == 3
++                      wrap_copy(skb, rx_ring, ring_offset+4, pkt_size);
++#else
+                       eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0);
++#endif
+                       skb_put (skb, pkt_size);
+                       skb->protocol = eth_type_trans (skb, dev);
+-                      netif_rx (skb);
++
+                       dev->last_rx = jiffies;
+                       tp->stats.rx_bytes += pkt_size;
+                       tp->stats.rx_packets++;
++
++                      netif_receive_skb (skb);
+               } else {
+-                      printk (KERN_WARNING
+-                              "%s: Memory squeeze, dropping packet.\n",
+-                              dev->name);
++                      if (net_ratelimit()) 
++                              printk (KERN_WARNING
++                                      "%s: Memory squeeze, dropping packet.\n",
++                                      dev->name);
+                       tp->stats.rx_dropped++;
+               }
++              received++;
+               cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
+-              RTL_W16 (RxBufPtr, cur_rx - 16);
++              RTL_W16 (RxBufPtr, (u16) (cur_rx - 16));
+-              if (RTL_R16 (IntrStatus) & RxAckBits)
++              /* Clear out errors and receive interrupts */
++              status = RTL_R16 (IntrStatus) & RxAckBits;
++              if (likely(status != 0)) {
++                      if (unlikely(status & (RxFIFOOver | RxOverflow))) {
++                              tp->stats.rx_errors++;
++                              if (status & RxFIFOOver)
++                                      tp->stats.rx_fifo_errors++;
++                      }
+                       RTL_W16_F (IntrStatus, RxAckBits);
++              }
+       }
++ done:
++
++#if RTL8139_DEBUG > 1
+       DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
+                " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
+                RTL_R16 (RxBufAddr),
+                RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
++#endif
+       tp->cur_rx = cur_rx;
++      return received;
+ }
+@@ -2014,14 +2071,12 @@ static void rtl8139_weird_interrupt (str
+               status &= ~RxUnderrun;
+       }
+-      /* XXX along with rtl8139_rx_err, are we double-counting errors? */
+-      if (status &
+-          (RxUnderrun | RxOverflow | RxErr | RxFIFOOver))
++      if (status & (RxUnderrun | RxErr))
+               tp->stats.rx_errors++;
+       if (status & PCSTimeout)
+               tp->stats.rx_length_errors++;
+-      if (status & (RxUnderrun | RxFIFOOver))
++      if (status & RxUnderrun)
+               tp->stats.rx_fifo_errors++;
+       if (status & PCIErr) {
+               u16 pci_cmd_status;
+@@ -2033,6 +2088,39 @@ static void rtl8139_weird_interrupt (str
+       }
+ }
++static int rtl8139_poll(struct net_device *dev, int *budget)
++{
++      struct rtl8139_private *tp = dev->priv;
++      void *ioaddr = tp->mmio_addr;
++      int orig_budget = min(*budget, dev->quota);
++      int done = 1;
++
++      spin_lock(&tp->rx_lock);
++      if (likely(RTL_R16(IntrStatus) & RxAckBits)) {
++              int work_done;
++
++              work_done = rtl8139_rx(dev, tp, orig_budget);
++              if (likely(work_done > 0)) {
++                      *budget -= work_done;
++                      dev->quota -= work_done;
++                      done = (work_done < orig_budget);
++              }
++      }
++
++      if (done) {
++              /*
++               * Order is important since data can get interrupted
++               * again when we think we are done.
++               */
++              local_irq_disable();
++              RTL_W16_F(IntrMask, rtl8139_intr_mask);
++              __netif_rx_complete(dev);
++              local_irq_enable();
++      }
++      spin_unlock(&tp->rx_lock);
++
++      return !done;
++}
+ /* The interrupt handler does all of the Rx thread work and cleans up
+    after the Tx thread. */
+@@ -2041,68 +2129,59 @@ static irqreturn_t rtl8139_interrupt (in
+ {
+       struct net_device *dev = (struct net_device *) dev_instance;
+       struct rtl8139_private *tp = dev->priv;
+-      int boguscnt = max_interrupt_work;
+       void *ioaddr = tp->mmio_addr;
+-      int ackstat, status;
++      u16 status, ackstat;
+       int link_changed = 0; /* avoid bogus "uninit" warning */
+       int handled = 0;
+       spin_lock (&tp->lock);
++      status = RTL_R16 (IntrStatus);
+-      do {
+-              status = RTL_R16 (IntrStatus);
++      /* shared irq? */
++      if (unlikely((status & rtl8139_intr_mask) == 0)) 
++              goto out;
+-              /* h/w no longer present (hotplug?) or major error, bail */
+-              if (status == 0xFFFF)
+-                      break;
++      handled = 1;
+-              if ((status &
+-                   (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
+-                    RxFIFOOver | TxErr | TxOK | RxErr | RxOK)) == 0)
+-                      break;
++      /* h/w no longer present (hotplug?) or major error, bail */
++      if (unlikely(status == 0xFFFF)) 
++              goto out;
+-              handled = 1;
++      /* close possible race's with dev_close */
++      if (unlikely(!netif_running(dev))) {
++              RTL_W16 (IntrMask, 0);
++              goto out;
++      }
+-              /* Acknowledge all of the current interrupt sources ASAP, but
+-                 an first get an additional status bit from CSCR. */
+-              if (status & RxUnderrun)
+-                      link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
++      /* Acknowledge all of the current interrupt sources ASAP, but
++         an first get an additional status bit from CSCR. */
++      if (unlikely(status & RxUnderrun))
++              link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
+-              /* The chip takes special action when we clear RxAckBits,
+-               * so we clear them later in rtl8139_rx_interrupt
+-               */
+-              ackstat = status & ~(RxAckBits | TxErr);
++      ackstat = status & ~(RxAckBits | TxErr);
++      if (ackstat)
+               RTL_W16 (IntrStatus, ackstat);
+-              DPRINTK ("%s: interrupt  status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n",
+-                       dev->name, status, ackstat, RTL_R16 (IntrStatus));
+-
+-              if (netif_running (dev) && (status & RxAckBits))
+-                      rtl8139_rx_interrupt (dev, tp, ioaddr);
+-
+-              /* Check uncommon events with one test. */
+-              if (status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
+-                            RxFIFOOver | RxErr))
+-                      rtl8139_weird_interrupt (dev, tp, ioaddr,
+-                                               status, link_changed);
+-
+-              if (netif_running (dev) && (status & (TxOK | TxErr))) {
+-                      rtl8139_tx_interrupt (dev, tp, ioaddr);
+-                      if (status & TxErr)
+-                              RTL_W16 (IntrStatus, TxErr);
++      /* Receive packets are processed by poll routine.
++         If not running start it now. */
++      if (status & RxAckBits){
++              if (netif_rx_schedule_prep(dev)) {
++                      RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
++                      __netif_rx_schedule (dev);
+               }
+-
+-              boguscnt--;
+-      } while (boguscnt > 0);
+-
+-      if (boguscnt <= 0) {
+-              printk (KERN_WARNING "%s: Too much work at interrupt, "
+-                      "IntrStatus=0x%4.4x.\n", dev->name, status);
+-
+-              /* Clear all interrupt sources. */
+-              RTL_W16 (IntrStatus, 0xffff);
+       }
++      /* Check uncommon events with one test. */
++      if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
++              rtl8139_weird_interrupt (dev, tp, ioaddr,
++                                       status, link_changed);
++
++      if (status & (TxOK | TxErr)) {
++              rtl8139_tx_interrupt (dev, tp, ioaddr);
++              if (status & TxErr)
++                      RTL_W16 (IntrStatus, TxErr);
++      }
++ out:
+       spin_unlock (&tp->lock);
+       DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
+@@ -2110,6 +2189,18 @@ static irqreturn_t rtl8139_interrupt (in
+       return IRQ_RETVAL(handled);
+ }
++#ifdef CONFIG_NET_POLL_CONTROLLER
++/*
++ * Polling receive - used by netconsole and other diagnostic tools
++ * to allow network i/o with interrupts disabled.
++ */
++static void rtl8139_poll_controller(struct net_device *dev)
++{
++      disable_irq(dev->irq);
++      rtl8139_interrupt(dev->irq, dev, NULL);
++      enable_irq(dev->irq);
++}
++#endif
+ static int rtl8139_close (struct net_device *dev)
+ {
+@@ -2130,8 +2221,9 @@ static int rtl8139_close (struct net_dev
+               }
+               wait_for_completion (&tp->thr_exited);
+       }
+-
+-      DPRINTK ("%s: Shutting down ethercard, status was 0x%4.4x.\n",
++      
++      if (netif_msg_ifdown(tp))
++              printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
+                       dev->name, RTL_R16 (IntrStatus));
+       spin_lock_irqsave (&tp->lock, flags);
+@@ -2289,12 +2381,14 @@ static u32 rtl8139_get_link(struct net_d
+ static u32 rtl8139_get_msglevel(struct net_device *dev)
+ {
+-      return debug;
++      struct rtl8139_private *np = dev->priv;
++      return np->msg_enable;
+ }
+ static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
+ {
+-      debug = datum;
++      struct rtl8139_private *np = dev->priv;
++      np->msg_enable = datum;
+ }
+ /* TODO: we are too slack to do reg dumping for pio, for now */
+@@ -2475,10 +2569,11 @@ static int rtl8139_suspend (struct pci_d
+       tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+       RTL_W32 (RxMissed, 0);
++      spin_unlock_irqrestore (&tp->lock, flags);
++
+       pci_set_power_state (pdev, 3);
+       pci_save_state (pdev, tp->pci_state);
+-      spin_unlock_irqrestore (&tp->lock, flags);
+       return 0;
+ }
+--- linux-2.6.0/drivers/net/82596.c    2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/82596.c     2003-12-28 23:21:00.000000000 -0800
+@@ -1129,21 +1129,40 @@ static void print_eth(unsigned char *add
+       printk(" %02X%02X, %s\n", add[12], add[13], str);
+ }
+-int __init i82596_probe(struct net_device *dev)
++static int io = 0x300;
++static int irq = 10;
++
++struct net_device * __init i82596_probe(int unit)
+ {
++      struct net_device *dev;
+       int i;
+       struct i596_private *lp;
+       char eth_addr[8];
+       static int probed;
++      int err;
+       if (probed)
+-              return -ENODEV;
++              return ERR_PTR(-ENODEV);
+       probed++;
++
++      dev = alloc_etherdev(0);
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      } else {
++              dev->base_addr = io;
++              dev->irq = irq;
++      }
++
+ #ifdef ENABLE_MVME16x_NET
+       if (MACH_IS_MVME16x) {
+               if (mvme16x_config & MVME16x_CONFIG_NO_ETHERNET) {
+                       printk(KERN_NOTICE "Ethernet probe disabled - chip not present\n");
+-                      return -ENODEV;
++                      err = -ENODEV;
++                      goto out;
+               }
+               memcpy(eth_addr, (void *) 0xfffc1f2c, 6);       /* YUCK! Get addr from NOVRAM */
+               dev->base_addr = MVME_I596_BASE;
+@@ -1174,7 +1193,8 @@ int __init i82596_probe(struct net_devic
+               if (!request_region(ioaddr, I596_TOTAL_SIZE, dev->name)) {
+                       printk(KERN_ERR "82596: IO address 0x%04x in use\n", ioaddr);
+-                      return -EBUSY;
++                      err = -EBUSY;
++                      goto out;
+               }
+               for (i = 0; i < 8; i++) {
+@@ -1190,8 +1210,8 @@ int __init i82596_probe(struct net_devic
+               if ((checksum % 0x100) || 
+                   (memcmp(eth_addr, "\x00\x00\x49", 3) != 0)) {
+-                      release_region(ioaddr, I596_TOTAL_SIZE);
+-                      return -ENODEV;
++                      err = -ENODEV;
++                      goto out1;
+               }
+               dev->base_addr = ioaddr;
+@@ -1200,13 +1220,10 @@ int __init i82596_probe(struct net_devic
+ #endif
+       dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0);
+       if (!dev->mem_start) {
+-#ifdef ENABLE_APRICOT
+-              release_region(dev->base_addr, I596_TOTAL_SIZE);
+-#endif
+-              return -ENOMEM;
++              err = -ENOMEM;
++              goto out1;
+       }
+-      ether_setup(dev);
+       DEB(DEB_PROBE,printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr));
+       for (i = 0; i < 6; i++)
+@@ -1244,7 +1261,26 @@ int __init i82596_probe(struct net_devic
+       lp->scb.rfd = I596_NULL;
+       lp->lock = SPIN_LOCK_UNLOCKED;
+-      return 0;
++      err = register_netdev(dev);
++      if (err)
++              goto out2;
++      return dev;
++out2:
++#ifdef __mc68000__
++      /* XXX This assumes default cache mode to be IOMAP_FULL_CACHING,
++       * XXX which may be invalid (CONFIG_060_WRITETHROUGH)
++       */
++      kernel_set_cachemode((void *)(dev->mem_start), 4096,
++                      IOMAP_FULL_CACHING);
++#endif
++      free_page ((u32)(dev->mem_start));
++out1:
++#ifdef ENABLE_APRICOT
++      release_region(dev->base_addr, I596_TOTAL_SIZE);
++#endif
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+@@ -1532,11 +1568,9 @@ static void set_multicast_list(struct ne
+ }
+ #ifdef MODULE
+-static struct net_device dev_82596 = { .init = i82596_probe };
++static struct net_device *dev_82596;
+ #ifdef ENABLE_APRICOT
+-static int io = 0x300;
+-static int irq = 10;
+ MODULE_PARM(irq, "i");
+ MODULE_PARM_DESC(irq, "Apricot IRQ number");
+ #endif
+@@ -1547,34 +1581,31 @@ static int debug = -1;
+ int init_module(void)
+ {
+-#ifdef ENABLE_APRICOT
+-      dev_82596.base_addr = io;
+-      dev_82596.irq = irq;
+-#endif
+       if (debug >= 0)
+               i596_debug = debug;
+-      if (register_netdev(&dev_82596) != 0)
+-              return -EIO;
++      dev_82596 = i82596_probe(-1);
++      if (IS_ERR(dev_82596))
++              return PTR_ERR(dev_82596);
+       return 0;
+ }
+ void cleanup_module(void)
+ {
+-      unregister_netdev(&dev_82596);
++      unregister_netdev(dev_82596);
+ #ifdef __mc68000__
+       /* XXX This assumes default cache mode to be IOMAP_FULL_CACHING,
+        * XXX which may be invalid (CONFIG_060_WRITETHROUGH)
+        */
+-      kernel_set_cachemode((void *)(dev_82596.mem_start), 4096,
++      kernel_set_cachemode((void *)(dev_82596->mem_start), 4096,
+                       IOMAP_FULL_CACHING);
+ #endif
+-      free_page ((u32)(dev_82596.mem_start));
+-      dev_82596.priv = NULL;
++      free_page ((u32)(dev_82596->mem_start));
+ #ifdef ENABLE_APRICOT
+       /* If we don't do this, we can't re-insmod it later. */
+-      release_region(dev_82596.base_addr, I596_TOTAL_SIZE);
++      release_region(dev_82596->base_addr, I596_TOTAL_SIZE);
+ #endif
++      free_netdev(dev_82596);
+ }
+ #endif                                /* MODULE */
+--- linux-2.6.0/drivers/net/8390.c     2003-09-27 18:57:44.000000000 -0700
++++ 25/drivers/net/8390.c      2003-12-28 23:21:00.000000000 -0800
+@@ -157,15 +157,8 @@ static void do_set_multicast_list(struct
+ int ei_open(struct net_device *dev)
+ {
+       unsigned long flags;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+-      /* This can't happen unless somebody forgot to call ethdev_init(). */
+-      if (ei_local == NULL) 
+-      {
+-              printk(KERN_EMERG "%s: ei_open passed a non-existent device!\n", dev->name);
+-              return -ENXIO;
+-      }
+-      
+       /* The card I/O part of the driver (e.g. 3c503) can hook a Tx timeout
+           wrapper that does e.g. media check & then calls ei_tx_timeout. */
+       if (dev->tx_timeout == NULL)
+@@ -196,7 +189,7 @@ int ei_open(struct net_device *dev)
+  */
+ int ei_close(struct net_device *dev)
+ {
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       unsigned long flags;
+       /*
+@@ -221,7 +214,7 @@ int ei_close(struct net_device *dev)
+ void ei_tx_timeout(struct net_device *dev)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       int txsr, isr, tickssofar = jiffies - dev->trans_start;
+       unsigned long flags;
+@@ -267,7 +260,7 @@ void ei_tx_timeout(struct net_device *de
+ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       int length, send_length, output_page;
+       unsigned long flags;
+       char scratch[ETH_ZLEN];
+@@ -435,7 +428,7 @@ irqreturn_t ei_interrupt(int irq, void *
+       }
+     
+       e8390_base = dev->base_addr;
+-      ei_local = (struct ei_device *) dev->priv;
++      ei_local = (struct ei_device *) netdev_priv(dev);
+       /*
+        *      Protect the irq test too.
+@@ -540,7 +533,7 @@ irqreturn_t ei_interrupt(int irq, void *
+ static void ei_tx_err(struct net_device *dev)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       unsigned char txsr = inb_p(e8390_base+EN0_TSR);
+       unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
+@@ -583,7 +576,7 @@ static void ei_tx_err(struct net_device 
+ static void ei_tx_intr(struct net_device *dev)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       int status = inb(e8390_base + EN0_TSR);
+     
+       outb_p(ENISR_TX, e8390_base + EN0_ISR); /* Ack intr. */
+@@ -675,7 +668,7 @@ static void ei_tx_intr(struct net_device
+ static void ei_receive(struct net_device *dev)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       unsigned char rxing_page, this_frame, next_frame;
+       unsigned short current_offset;
+       int rx_pkt_count = 0;
+@@ -813,7 +806,7 @@ static void ei_rx_overrun(struct net_dev
+ {
+       long e8390_base = dev->base_addr;
+       unsigned char was_txing, must_resend = 0;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+     
+       /*
+        * Record whether a Tx was in progress and then issue the
+@@ -881,7 +874,7 @@ static void ei_rx_overrun(struct net_dev
+ static struct net_device_stats *get_stats(struct net_device *dev)
+ {
+       long ioaddr = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       unsigned long flags;
+     
+       /* If the card is stopped, just return the present stats. */
+@@ -936,7 +929,7 @@ static void do_set_multicast_list(struct
+ {
+       long e8390_base = dev->base_addr;
+       int i;
+-      struct ei_device *ei_local = (struct ei_device*)dev->priv;
++      struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev);
+       if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) 
+       {
+@@ -990,53 +983,34 @@ static void do_set_multicast_list(struct
+ static void set_multicast_list(struct net_device *dev)
+ {
+       unsigned long flags;
+-      struct ei_device *ei_local = (struct ei_device*)dev->priv;
++      struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev);
+       
+       spin_lock_irqsave(&ei_local->page_lock, flags);
+       do_set_multicast_list(dev);
+       spin_unlock_irqrestore(&ei_local->page_lock, flags);
+ }     
+-static inline void ei_device_init(struct ei_device *ei_local)
+-{
+-      spin_lock_init(&ei_local->page_lock);
+-}
+-
+ /**
+- * ethdev_init - init rest of 8390 device struct
++ * ethdev_setup - init rest of 8390 device struct
+  * @dev: network device structure to init
+  *
+  * Initialize the rest of the 8390 device structure.  Do NOT __init
+  * this, as it is used by 8390 based modular drivers too.
+  */
+-int ethdev_init(struct net_device *dev)
++static void ethdev_setup(struct net_device *dev)
+ {
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       if (ei_debug > 1)
+               printk(version);
+     
+-      if (dev->priv == NULL) 
+-      {
+-              dev->priv = kmalloc(sizeof(struct ei_device), GFP_KERNEL);
+-              if (dev->priv == NULL)
+-                      return -ENOMEM;
+-              memset(dev->priv, 0, sizeof(struct ei_device));
+-              ei_device_init(dev->priv);
+-      }
+-    
+       dev->hard_start_xmit = &ei_start_xmit;
+       dev->get_stats  = get_stats;
+       dev->set_multicast_list = &set_multicast_list;
+       ether_setup(dev);
+-        
+-      return 0;
+-}
+-/* wrapper to make alloc_netdev happy; probably should just cast... */
+-static void __ethdev_init(struct net_device *dev)
+-{
+-      ethdev_init(dev);
++      spin_lock_init(&ei_local->page_lock);
+ }
+ /**
+@@ -1044,15 +1018,10 @@ static void __ethdev_init(struct net_dev
+  *
+  * Allocate 8390-specific net_device.
+  */
+-struct net_device *alloc_ei_netdev(void)
++struct net_device *__alloc_ei_netdev(int size)
+ {
+-      struct net_device *dev;
+-      
+-      dev = alloc_netdev(sizeof(struct ei_device), "eth%d", __ethdev_init);
+-      if (dev)
+-              ei_device_init(dev->priv);
+-
+-      return dev;
++      return alloc_netdev(sizeof(struct ei_device) + size, "eth%d",
++                              ethdev_setup);
+ }
\f
+@@ -1072,7 +1041,7 @@ struct net_device *alloc_ei_netdev(void)
+ void NS8390_init(struct net_device *dev, int startp)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       int i;
+       int endcfg = ei_local->word16
+           ? (0x48 | ENDCFG_WTS | (ei_local->bigendian ? ENDCFG_BOS : 0))
+@@ -1136,7 +1105,7 @@ static void NS8390_trigger_send(struct n
+                                                               int start_page)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev);
+    
+       outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD);
+     
+@@ -1156,9 +1125,8 @@ EXPORT_SYMBOL(ei_open);
+ EXPORT_SYMBOL(ei_close);
+ EXPORT_SYMBOL(ei_interrupt);
+ EXPORT_SYMBOL(ei_tx_timeout);
+-EXPORT_SYMBOL(ethdev_init);
+ EXPORT_SYMBOL(NS8390_init);
+-EXPORT_SYMBOL(alloc_ei_netdev);
++EXPORT_SYMBOL(__alloc_ei_netdev);
+ #if defined(MODULE)
+--- linux-2.6.0/drivers/net/8390.h     2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/8390.h      2003-12-28 23:21:00.000000000 -0800
+@@ -39,12 +39,15 @@ extern int ei_debug;
+ #define ei_debug 1
+ #endif
+-extern int ethdev_init(struct net_device *dev);
+ extern void NS8390_init(struct net_device *dev, int startp);
+ extern int ei_open(struct net_device *dev);
+ extern int ei_close(struct net_device *dev);
+ extern irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+-extern struct net_device *alloc_ei_netdev(void);
++extern struct net_device *__alloc_ei_netdev(int size);
++static inline struct net_device *alloc_ei_netdev(void)
++{
++      return __alloc_ei_netdev(0);
++}
+ /* You have one of these per-board */
+ struct ei_device {
+@@ -84,7 +87,7 @@ struct ei_device {
+ /* The maximum time waited (in jiffies) before assuming a Tx failed. (20ms) */
+ #define TX_TIMEOUT (20*HZ/100)
+-#define ei_status (*(struct ei_device *)(dev->priv))
++#define ei_status (*(struct ei_device *)netdev_priv(dev))
+ /* Some generic ethernet register configurations. */
+ #define E8390_TX_IRQ_MASK     0xa     /* For register EN0_ISR */
+--- linux-2.6.0/drivers/net/a2065.c    2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/a2065.c     2003-12-28 23:21:00.000000000 -0800
+@@ -737,7 +737,7 @@ static int __init a2065_probe(void)
+                       continue;
+               }
+-              dev = init_etherdev(NULL, sizeof(struct lance_private));
++              dev = alloc_etherdev(sizeof(struct lance_private));
+               if (dev == NULL) {
+                       release_resource(r1);
+@@ -791,17 +791,22 @@ static int __init a2065_probe(void)
+               dev->set_multicast_list = &lance_set_multicast;
+               dev->dma = 0;
+-#ifdef MODULE
+-              priv->next_module = root_a2065_dev;
+-              root_a2065_dev = priv;
+-#endif
+-              ether_setup(dev);
+               init_timer(&priv->multicast_timer);
+               priv->multicast_timer.data = (unsigned long) dev;
+               priv->multicast_timer.function =
+                       (void (*)(unsigned long)) &lance_set_multicast;
+-              res = 0;
++              res = register_netdev(dev);
++              if (res) {
++                      release_resource(r1);
++                      release_resource(r2);
++                      free_netdev(dev);
++                      break;
++              }
++#ifdef MODULE
++              priv->next_module = root_a2065_dev;
++              root_a2065_dev = priv;
++#endif
+       }
+       return res;
+ }
+--- linux-2.6.0/drivers/net/ac3200.c   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ac3200.c    2003-12-28 23:21:00.000000000 -0800
+@@ -75,7 +75,6 @@ static const char *port_name[4] = { "10b
+ #define AC_START_PG           0x00    /* First page of 8390 TX buffer */
+ #define AC_STOP_PG            0x80    /* Last page +1 of the 8390 RX ring */
+-int ac3200_probe(struct net_device *dev);
+ static int ac_probe1(int ioaddr, struct net_device *dev);
+ static int ac_open(struct net_device *dev);
+@@ -96,9 +95,11 @@ static int ac_close_card(struct net_devi
+       or the unique value in the station address PROM.
+       */
+-int __init ac3200_probe(struct net_device *dev)
++static int __init do_ac3200_probe(struct net_device *dev)
+ {
+       unsigned short ioaddr = dev->base_addr;
++      int irq = dev->irq;
++      int mem_start = dev->mem_start;
+       SET_MODULE_OWNER(dev);
+@@ -110,13 +111,50 @@ int __init ac3200_probe(struct net_devic
+       if ( ! EISA_bus)
+               return -ENXIO;
+-      for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000)
++      for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
+               if (ac_probe1(ioaddr, dev) == 0)
+                       return 0;
++              dev->irq = irq;
++              dev->mem_start = mem_start;
++      }
+       return -ENODEV;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      /* Someday free_irq may be in ac_close_card() */
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, AC_IO_EXTENT);
++      if (ei_status.reg0)
++              iounmap((void *)dev->mem_start);
++}
++
++struct net_device * __init ac3200_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_ac3200_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ static int __init ac_probe1(int ioaddr, struct net_device *dev)
+ {
+       int i, retval;
+@@ -156,13 +194,6 @@ static int __init ac_probe1(int ioaddr, 
+       }
+ #endif
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev)) {
+-              printk (", unable to allocate memory for dev->priv.\n");
+-              retval = -ENOMEM;
+-              goto out;
+-      }
+-
+       /* Assign and allocate the interrupt now. */
+       if (dev->irq == 0) {
+               dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
+@@ -210,7 +241,7 @@ static int __init ac_probe1(int ioaddr, 
+                       printk(KERN_CRIT "ac3200.c: or to an address above 0x%lx.\n", virt_to_phys(high_memory));
+                       printk(KERN_CRIT "ac3200.c: Driver NOT installed.\n");
+                       retval = -EINVAL;
+-                      goto out2;
++                      goto out1;
+               }
+               dev->mem_start = (unsigned long)ioremap(dev->mem_start, AC_STOP_PG*0x100);
+               if (dev->mem_start == 0) {
+@@ -218,7 +249,7 @@ static int __init ac_probe1(int ioaddr, 
+                       printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
+                       printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
+                       retval = -EINVAL;
+-                      goto out2;
++                      goto out1;
+               }
+               ei_status.reg0 = 1;     /* Use as remap flag */
+               printk("ac3200.c: remapped %dkB card memory to virtual address %#lx\n",
+@@ -247,11 +278,8 @@ static int __init ac_probe1(int ioaddr, 
+       dev->stop = &ac_close_card;
+       NS8390_init(dev, 0);
+       return 0;
+-out2:
+-      free_irq(dev->irq, dev);
+ out1:
+-      kfree(dev->priv);
+-      dev->priv = NULL;
++      free_irq(dev->irq, dev);
+ out:
+       release_region(ioaddr, AC_IO_EXTENT);
+       return retval;
+@@ -338,7 +366,7 @@ static int ac_close_card(struct net_devi
+ #ifdef MODULE
+ #define MAX_AC32_CARDS        4       /* Max number of AC32 cards per module */
+-static struct net_device dev_ac32[MAX_AC32_CARDS];
++static struct net_device *dev_ac32[MAX_AC32_CARDS];
+ static int io[MAX_AC32_CARDS];
+ static int irq[MAX_AC32_CARDS];
+ static int mem[MAX_AC32_CARDS];
+@@ -354,26 +382,32 @@ MODULE_LICENSE("GPL");
+ int
+ init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ac32[this_dev];
++              if (io[this_dev] == 0 && this_dev != 0)
++                      break;
++              dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+               dev->mem_start = mem[this_dev];         /* Currently ignored by driver */
+-              dev->init = ac3200_probe;
+-              /* Default is to only install one card. */
+-              if (io[this_dev] == 0 && this_dev != 0) break;
+-              if (register_netdev(dev) != 0) {
+-                      printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
+-                      if (found != 0) {       /* Got at least one. */
+-                              return 0;
++              if (do_ac3200_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_ac32[found++] = dev;
++                              continue;
+                       }
+-                      return -ENXIO;
++                      cleanup_card(dev);
+               }
+-              found++;
+-      }
+-      return 0;
++              free_netdev(dev);
++              printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
++              break;
++      }
++      if (found)
++              return 0;
++      return -ENXIO;
+ }
+ void
+@@ -382,16 +416,11 @@ cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ac32[this_dev];
+-              if (dev->priv != NULL) {
+-                      /* Someday free_irq may be in ac_close_card() */
+-                      free_irq(dev->irq, dev);
+-                      release_region(dev->base_addr, AC_IO_EXTENT);
+-                      if (ei_status.reg0)
+-                              iounmap((void *)dev->mem_start);
++              struct net_device *dev = dev_ac32[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(dev->priv);
+-                      dev->priv = NULL;
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/amd8111e.c 2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/amd8111e.c  2003-12-28 23:21:00.000000000 -0800
+@@ -1153,6 +1153,17 @@ err_no_interrupt:
+       return IRQ_RETVAL(handled);
+ }
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void amd8111e_poll(struct net_device *dev)
++{ 
++      unsigned long flags;
++      local_save_flags(flags); 
++      local_irq_disable();
++      amd8111e_interrupt(0, dev, NULL);
++      local_irq_restore(flags); 
++} 
++#endif
++
+ /*
+ This function closes the network interface and updates the statistics so that most recent statistics will be available after the interface is down.
+ */
+@@ -1884,6 +1895,9 @@ static int __devinit amd8111e_probe_one(
+       dev->irq =pdev->irq;
+       dev->tx_timeout = amd8111e_tx_timeout; 
+       dev->watchdog_timeo = AMD8111E_TX_TIMEOUT; 
++#ifdef CONFIG_NET_POLL_CONTROLLER
++      dev->poll_controller = amd8111e_poll; 
++#endif
+ #if AMD8111E_VLAN_TAG_USED
+       dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+--- linux-2.6.0/drivers/net/apne.c     2003-06-14 12:18:51.000000000 -0700
++++ 25/drivers/net/apne.c      2003-12-28 23:21:00.000000000 -0800
+@@ -72,7 +72,7 @@
+ #define NESM_STOP_PG  0x80    /* Last page +1 of RX ring */
+-int apne_probe(struct net_device *dev);
++struct net_device * __init apne_probe(int unit);
+ static int apne_probe1(struct net_device *dev, int ioaddr);
+ static int apne_open(struct net_device *dev);
+@@ -116,28 +116,37 @@ static const char version[] =
+ static int apne_owned;        /* signal if card already owned */
+-int __init apne_probe(struct net_device *dev)
++struct net_device * __init apne_probe(int unit)
+ {
++      struct net_device *dev;
+ #ifndef MANUAL_CONFIG
+       char tuple[8];
+ #endif
++      int err;
+       if (apne_owned)
+-              return -ENODEV;
+-
+-      SET_MODULE_OWNER(dev);
++              return ERR_PTR(-ENODEV);
+       if ( !(AMIGAHW_PRESENT(PCMCIA)) )
+-              return (-ENODEV);
++              return ERR_PTR(-ENODEV);
+                                 
+       printk("Looking for PCMCIA ethernet card : ");
+                                         
+       /* check if a card is inserted */
+       if (!(PCMCIA_INSERTED)) {
+               printk("NO PCMCIA card inserted\n");
+-              return (-ENODEV);
++              return ERR_PTR(-ENODEV);
+       }
+-                                                                                                
++
++      dev = alloc_ei_netdev();
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
++      SET_MODULE_OWNER(dev);
++
+       /* disable pcmcia irq for readtuple */
+       pcmcia_disable_irq();
+@@ -145,17 +154,41 @@ int __init apne_probe(struct net_device 
+       if ((pcmcia_copy_tuple(CISTPL_FUNCID, tuple, 8) < 3) ||
+               (tuple[2] != CISTPL_FUNCID_NETWORK)) {
+               printk("not an ethernet card\n");
+-              return (-ENODEV);
++              /* XXX: shouldn't we re-enable irq here? */
++              free_netdev(dev);
++              return ERR_PTR(-ENODEV);
+       }
+ #endif
+       printk("ethernet PCMCIA card inserted\n");
+-      if (init_pcmcia())
+-              return apne_probe1(dev, IOBASE);
+-      else
+-              return (-ENODEV);
++      if (!init_pcmcia()) {
++              /* XXX: shouldn't we re-enable irq here? */
++              free_netdev(dev);
++              return ERR_PTR(-ENODEV);
++      }
++      if (!request_region(IOBASE, 0x20, dev->name)) {
++              free_netdev(dev);
++              return ERR_PTR(-EBUSY);
++      }
++
++      err = apne_probe1(dev, IOBASE);
++      if (err) {
++              release_region(IOBASE, 0x20);
++              free_netdev(dev);
++              return ERR_PTR(err);
++      }
++      err = register_netdev(dev);
++      if (!err)
++              return dev;
++
++      pcmcia_disable_irq();
++      free_irq(IRQ_AMIGA_PORTS, dev);
++      pcmcia_reset();
++      release_region(IOBASE, 0x20);
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ static int __init apne_probe1(struct net_device *dev, int ioaddr)
+@@ -280,13 +313,6 @@ static int __init apne_probe1(struct net
+     i = request_irq(IRQ_AMIGA_PORTS, apne_interrupt, SA_SHIRQ, dev->name, dev);
+     if (i) return i;
+-    /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-    if (ethdev_init(dev)) {
+-      printk (" unable to get memory for dev->priv.\n");
+-      free_irq(IRQ_AMIGA_PORTS, dev);
+-      return -ENOMEM;
+-    }
+-
+     for(i = 0; i < ETHER_ADDR_LEN; i++) {
+       printk(" %2.2x", SA_prom[i]);
+       dev->dev_addr[i] = SA_prom[i];
+@@ -534,32 +560,27 @@ static irqreturn_t apne_interrupt(int ir
+ }
+ #ifdef MODULE
+-static struct net_device apne_dev;
++static struct net_device *apne_dev;
+ int init_module(void)
+ {
+-      int err;
+-
+-      apne_dev.init = apne_probe;
+-      if ((err = register_netdev(&apne_dev))) {
+-              if (err == -EIO)
+-                      printk("No PCMCIA NEx000 ethernet card found.\n");
+-              return (err);
+-      }
+-      return (0);
++      apne_dev = apne_probe(-1);
++      if (IS_ERR(apne_dev))
++              return PTR_ERR(apne_dev);
++      return 0;
+ }
+ void cleanup_module(void)
+ {
+-      unregister_netdev(&apne_dev);
++      unregister_netdev(apne_dev);
+       pcmcia_disable_irq();
+-      free_irq(IRQ_AMIGA_PORTS, &apne_dev);
++      free_irq(IRQ_AMIGA_PORTS, apne_dev);
+       pcmcia_reset();
+-      apne_owned = 0;
++      free_netdev(apne_dev);
+ }
+ #endif
+--- linux-2.6.0/drivers/net/appletalk/ipddp.c  2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/net/appletalk/ipddp.c   2003-12-28 23:21:00.000000000 -0800
+@@ -28,6 +28,7 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/netdevice.h>
++#include <linux/etherdevice.h>
+ #include <linux/ip.h>
+ #include <linux/atalk.h>
+ #include <linux/if_arp.h>
+@@ -55,34 +56,24 @@ static struct ipddp_route* ipddp_find_ro
+ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+-static int __init ipddp_init(struct net_device *dev)
++static struct net_device * __init ipddp_init(void)
+ {
+       static unsigned version_printed;
++      struct net_device *dev;
++      int err;
++
++      dev = alloc_etherdev(sizeof(struct net_device_stats));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+       SET_MODULE_OWNER(dev);
++      strcpy(dev->name, "ipddp%d");
+       if (version_printed++ == 0)
+                 printk(version);
+-      /* Let the user now what mode we are in */
+-      if(ipddp_mode == IPDDP_ENCAP)
+-              printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n", 
+-                      dev->name);
+-      if(ipddp_mode == IPDDP_DECAP)
+-              printk("%s: Appletalk-IP Decap. mode by Jay Schulist <jschlst@samba.org>\n", 
+-                      dev->name);
+-
+-      /* Fill in the device structure with ethernet-generic values. */
+-        ether_setup(dev);
+-
+       /* Initalize the device structure. */
+         dev->hard_start_xmit = ipddp_xmit;
+-
+-        dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
+-        if(!dev->priv)
+-                return -ENOMEM;
+-        memset(dev->priv,0,sizeof(struct net_device_stats));
+-
+         dev->get_stats      = ipddp_get_stats;
+         dev->do_ioctl       = ipddp_ioctl;
+@@ -97,7 +88,21 @@ static int __init ipddp_init(struct net_
+          */
+         dev->hard_header_len = 14+8+sizeof(struct ddpehdr)+1;
+-        return 0;
++      err = register_netdev(dev);
++      if (err) {
++              free_netdev(dev);
++              return ERR_PTR(err);
++      }
++
++      /* Let the user now what mode we are in */
++      if(ipddp_mode == IPDDP_ENCAP)
++              printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n", 
++                      dev->name);
++      if(ipddp_mode == IPDDP_DECAP)
++              printk("%s: Appletalk-IP Decap. mode by Jay Schulist <jschlst@samba.org>\n", 
++                      dev->name);
++
++        return dev;
+ }
+ /*
+@@ -281,23 +286,16 @@ static int ipddp_ioctl(struct net_device
+         }
+ }
+-static struct net_device dev_ipddp;
++static struct net_device *dev_ipddp;
+ MODULE_LICENSE("GPL");
+ MODULE_PARM(ipddp_mode, "i");
+ static int __init ipddp_init_module(void)
+ {
+-      int err;
+-
+-      dev_ipddp.init = ipddp_init;
+-      err=dev_alloc_name(&dev_ipddp, "ipddp%d");
+-        if(err < 0)
+-                return err;
+-
+-      if(register_netdev(&dev_ipddp) != 0)
+-                return -EIO;
+-
++      dev_ipddp = ipddp_init();
++        if (IS_ERR(dev_ipddp))
++                return PTR_ERR(dev_ipddp);
+       return 0;
+ }
+@@ -305,8 +303,8 @@ static void __exit ipddp_cleanup_module(
+ {
+         struct ipddp_route *p;
+-      unregister_netdev(&dev_ipddp);
+-        kfree(dev_ipddp.priv);
++      unregister_netdev(dev_ipddp);
++        free_netdev(dev_ipddp);
+         while (ipddp_route_list) {
+                 p = ipddp_route_list->next;
+--- linux-2.6.0/drivers/net/appletalk/ltpc.c   2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/appletalk/ltpc.c    2003-12-28 23:21:00.000000000 -0800
+@@ -1213,7 +1213,7 @@ out3:
+ out2:
+       release_region(io, 8);
+ out1:
+-      kfree(dev);
++      free_netdev(dev);
+ out:
+       return ERR_PTR(err);
+ }
+--- linux-2.6.0/drivers/net/arcnet/arcnet.c    2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/arcnet/arcnet.c     2003-12-28 23:21:00.000000000 -0800
+@@ -92,6 +92,7 @@ EXPORT_SYMBOL(arc_proto_null);
+ EXPORT_SYMBOL(arcnet_unregister_proto);
+ EXPORT_SYMBOL(arcnet_debug);
+ EXPORT_SYMBOL(arcdev_setup);
++EXPORT_SYMBOL(alloc_arcdev);
+ EXPORT_SYMBOL(arcnet_interrupt);
+ /* Internal function prototypes */
+@@ -331,6 +332,11 @@ void arcdev_setup(struct net_device *dev
+       dev->rebuild_header = arcnet_rebuild_header;
+ }
++struct net_device *alloc_arcdev(char *name)
++{
++      return alloc_netdev(sizeof(struct arcnet_local),
++                          name && *name ? name : "arc%d", arcdev_setup);
++}
+ /*
+  * Open/initialize the board.  This is called sometime after booting when
+--- linux-2.6.0/drivers/net/arcnet/arc-rimi.c  2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/arcnet/arc-rimi.c   2003-12-28 23:21:00.000000000 -0800
+@@ -26,6 +26,7 @@
+  */
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/moduleparam.h>
+ #include <linux/ioport.h>
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+@@ -85,8 +86,6 @@ static void arcrimi_copy_from_card(struc
+  */
+ static int __init arcrimi_probe(struct net_device *dev)
+ {
+-      int retval;
+-
+       BUGLVL(D_NORMAL) printk(VERSION);
+       BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n");
+@@ -114,11 +113,7 @@ static int __init arcrimi_probe(struct n
+                      "ID!\n");
+               return -ENODEV;
+       }
+-      retval = arcrimi_found(dev);
+-      if (retval < 0) {
+-              release_mem_region(dev->mem_start, BUFFER_SIZE);
+-      }
+-      return retval;
++      return arcrimi_found(dev);
+ }
+@@ -129,11 +124,13 @@ static int __init arcrimi_probe(struct n
+ static int __init arcrimi_found(struct net_device *dev)
+ {
+       struct arcnet_local *lp;
+-      u_long first_mirror, last_mirror, shmem;
++      unsigned long first_mirror, last_mirror, shmem;
+       int mirror_size;
++      int err;
+       /* reserve the irq */
+       if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
++              release_mem_region(dev->mem_start, BUFFER_SIZE);
+               BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
+               return -ENODEV;
+       }
+@@ -168,11 +165,7 @@ static int __init arcrimi_found(struct n
+       /* initialize the rest of the device structure. */
+-      lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
+-      if (!lp) {
+-              BUGMSG(D_NORMAL, "Can't allocate device data!\n");
+-              goto err_free_irq;
+-      }
++      lp = dev->priv;
+       lp->card_name = "RIM I";
+       lp->hw.command = arcrimi_command;
+       lp->hw.status = arcrimi_status;
+@@ -181,18 +174,6 @@ static int __init arcrimi_found(struct n
+       lp->hw.owner = THIS_MODULE;
+       lp->hw.copy_to_card = arcrimi_copy_to_card;
+       lp->hw.copy_from_card = arcrimi_copy_from_card;
+-      lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+-      if (!lp->mem_start) {
+-              BUGMSG(D_NORMAL, "Can't remap device memory!\n");
+-              goto err_free_dev_priv;
+-      }
+-      /* Fill in the fields of the device structure with generic
+-       * values.
+-       */
+-      arcdev_setup(dev);
+-
+-      /* get and check the station ID from offset 1 in shmem */
+-      dev->dev_addr[0] = readb(lp->mem_start + 1);
+       /*
+        * re-reserve the memory region - arcrimi_probe() alloced this reqion
+@@ -200,25 +181,40 @@ static int __init arcrimi_found(struct n
+        * with the correct size.  There is a VERY slim chance this could
+        * fail.
+        */
+-      release_mem_region(dev->mem_start, BUFFER_SIZE);
++      release_mem_region(shmem, BUFFER_SIZE);
+       if (!request_mem_region(dev->mem_start,
+                               dev->mem_end - dev->mem_start + 1,
+                               "arcnet (90xx)")) {
+               BUGMSG(D_NORMAL, "Card memory already allocated\n");
+-              goto err_free_dev_priv;
++              goto err_free_irq;
+       }
++      lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
++      if (!lp->mem_start) {
++              BUGMSG(D_NORMAL, "Can't remap device memory!\n");
++              goto err_release_mem;
++      }
++
++      /* get and check the station ID from offset 1 in shmem */
++      dev->dev_addr[0] = readb(lp->mem_start + 1);
++
+       BUGMSG(D_NORMAL, "ARCnet RIM I: station %02Xh found at IRQ %d, "
+              "ShMem %lXh (%ld*%d bytes).\n",
+              dev->dev_addr[0],
+              dev->irq, dev->mem_start,
+        (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
++      err = register_netdev(dev);
++      if (err)
++              goto err_unmap;
++
+       return 0;
+-      err_free_dev_priv:
+-      kfree(dev->priv);
+-      err_free_irq:
++err_unmap:
++      iounmap(lp->mem_start);
++err_release_mem:
++      release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
++err_free_irq:
+       free_irq(dev->irq, dev);
+       return -EIO;
+ }
+@@ -294,94 +290,79 @@ static void arcrimi_copy_from_card(struc
+       TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
+ }
+-#ifdef MODULE
++static int node;
++static int io;                        /* use the insmod io= irq= node= options */
++static int irq;
++static char device[9];                /* use eg. device=arc1 to change name */
++
++module_param(node, int, 0);
++module_param(io, int, 0);
++module_param(irq, int, 0);
++module_param_string(device, device, sizeof(device), 0);
++MODULE_LICENSE("GPL");
+ static struct net_device *my_dev;
+-/* Module parameters */
+-
+-static int node = 0;
+-static int io = 0x0;          /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
+-static int irq = 0;           /* or use the insmod io= irq= shmem= options */
+-static char *device;          /* use eg. device="arc1" to change name */
+-
+-MODULE_PARM(node, "i");
+-MODULE_PARM(io, "i");
+-MODULE_PARM(irq, "i");
+-MODULE_PARM(device, "s");
+-MODULE_LICENSE("GPL");
+-
+-int init_module(void)
++static int __init arc_rimi_init(void)
+ {
+       struct net_device *dev;
+-      int err;
+-      dev = dev_alloc(device ? : "arc%d", &err);
++      dev = alloc_arcdev(device);
+       if (!dev)
+-              return err;
++              return -ENOMEM;
+       if (node && node != 0xff)
+               dev->dev_addr[0] = node;
+-      dev->base_addr = io;
++      dev->mem_start = io;
+       dev->irq = irq;
+       if (dev->irq == 2)
+               dev->irq = 9;
+-      if (arcrimi_probe(dev))
++      if (arcrimi_probe(dev)) {
++              free_netdev(dev);
+               return -EIO;
++      }
+       my_dev = dev;
+       return 0;
+ }
+-void cleanup_module(void)
++static void __exit arc_rimi_exit(void)
+ {
+       struct net_device *dev = my_dev;
+       struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+       unregister_netdev(dev);
+-      free_irq(dev->irq, dev);
+       iounmap(lp->mem_start);
+       release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+-      kfree(dev->priv);
++      free_irq(dev->irq, dev);
+       free_netdev(dev);
+ }
+-#else
+-
++#ifndef MODULE
+ static int __init arcrimi_setup(char *s)
+ {
+-      struct net_device *dev;
+       int ints[8];
+-
+       s = get_options(s, 8, ints);
+       if (!ints[0])
+               return 1;
+-      dev = alloc_bootmem(sizeof(struct net_device));
+-      memset(dev, 0, sizeof(struct net_device));
+-      dev->init = arcrimi_probe;
+-
+       switch (ints[0]) {
+       default:                /* ERROR */
+               printk("arcrimi: Too many arguments.\n");
+       case 3:         /* Node ID */
+-              dev->dev_addr[0] = ints[3];
++              node = ints[3];
+       case 2:         /* IRQ */
+-              dev->irq = ints[2];
++              irq = ints[2];
+       case 1:         /* IO address */
+-              dev->mem_start = ints[1];
++              io = ints[1];
+       }
+       if (*s)
+-              strncpy(dev->name, s, 9);
+-      else
+-              strcpy(dev->name, "arc%d");
+-      if (register_netdev(dev))
+-              printk(KERN_ERR "arc-rimi: Cannot register arcnet device\n");
+-
++              snprintf(device, sizeof(device), "%s", s);
+       return 1;
+ }
+-
+ __setup("arcrimi=", arcrimi_setup);
+-
+ #endif                                /* MODULE */
++
++module_init(arc_rimi_init)
++module_exit(arc_rimi_exit)
+--- linux-2.6.0/drivers/net/arcnet/com20020.c  2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/arcnet/com20020.c   2003-12-28 23:21:00.000000000 -0800
+@@ -172,11 +172,6 @@ int com20020_found(struct net_device *de
+       dev->set_multicast_list = com20020_set_mc_list;
+-      /* Fill in the fields of the device structure with generic
+-       * values.
+-       */
+-      arcdev_setup(dev);
+-
+       if (!dev->dev_addr[0])
+               dev->dev_addr[0] = inb(ioaddr + 8);     /* FIXME: do this some other way! */
+@@ -221,7 +216,7 @@ int com20020_found(struct net_device *de
+              lp->setup >> 1, 
+              clockrates[3 - ((lp->setup2 & 0xF0) >> 4) + ((lp->setup & 0x0F) >> 1)]);
+-      if (!dev->init && register_netdev(dev)) {
++      if (register_netdev(dev)) {
+               free_irq(dev->irq, dev);
+               return -EIO;
+       }
+@@ -332,19 +327,10 @@ static void com20020_set_mc_list(struct 
+       }
+ }
+-void com20020_remove(struct net_device *dev)
+-{
+-      unregister_netdev(dev);
+-      free_irq(dev->irq, dev);
+-      kfree(dev->priv);
+-      free_netdev(dev);
+-}
+-
+ #ifdef MODULE
+ EXPORT_SYMBOL(com20020_check);
+ EXPORT_SYMBOL(com20020_found);
+-EXPORT_SYMBOL(com20020_remove);
+ MODULE_LICENSE("GPL");
+--- linux-2.6.0/drivers/net/arcnet/com20020-isa.c      2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/arcnet/com20020-isa.c       2003-12-28 23:21:00.000000000 -0800
+@@ -26,6 +26,7 @@
+  * **********************
+  */
+ #include <linux/module.h>
++#include <linux/moduleparam.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/ioport.h>
+@@ -117,49 +118,41 @@ out:
+       return err;
+ }
+-
+-#ifdef MODULE
+-
+-static struct net_device *my_dev;
+-
+-/* Module parameters */
+-
+ static int node = 0;
+ static int io = 0x0;          /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
+ static int irq = 0;           /* or use the insmod io= irq= shmem= options */
+-static char *device;          /* use eg. device="arc1" to change name */
++static char device[9];                /* use eg. device="arc1" to change name */
+ static int timeout = 3;
+ static int backplane = 0;
+ static int clockp = 0;
+ static int clockm = 0;
+-MODULE_PARM(node, "i");
+-MODULE_PARM(io, "i");
+-MODULE_PARM(irq, "i");
+-MODULE_PARM(device, "s");
+-MODULE_PARM(timeout, "i");
+-MODULE_PARM(backplane, "i");
+-MODULE_PARM(clockp, "i");
+-MODULE_PARM(clockm, "i");
++module_param(node, int, 0);
++module_param(io, int, 0);
++module_param(irq, int, 0);
++module_param_string(device, device, sizeof(device), 0);
++module_param(timeout, int, 0);
++module_param(backplane, int, 0);
++module_param(clockp, int, 0);
++module_param(clockm, int, 0);
++
+ MODULE_LICENSE("GPL");
+-int init_module(void)
++static struct net_device *my_dev;
++
++static int __init com20020_init(void)
+ {
+       struct net_device *dev;
+       struct arcnet_local *lp;
+-      int err;
+-      dev = dev_alloc(device ? : "arc%d", &err);
++      dev = alloc_arcdev(device);
+       if (!dev)
+-              return err;
+-      lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
+-      if (!lp)
+               return -ENOMEM;
+-      memset(lp, 0, sizeof(struct arcnet_local));
+       if (node && node != 0xff)
+               dev->dev_addr[0] = node;
++      lp = dev->priv;
+       lp->backplane = backplane;
+       lp->clockp = clockp & 7;
+       lp->clockm = clockm & 3;
+@@ -172,21 +165,24 @@ int init_module(void)
+       if (dev->irq == 2)
+               dev->irq = 9;
+-      if (com20020isa_probe(dev))
++      if (com20020isa_probe(dev)) {
++              free_netdev(dev);
+               return -EIO;
++      }
+       my_dev = dev;
+       return 0;
+ }
+-void cleanup_module(void)
++static void __exit com20020_exit(void)
+ {
+-      com20020_remove(my_dev);
++      unregister_netdev(my_dev);
++      free_irq(my_dev->irq, my_dev);
+       release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
++      free_netdev(my_dev);
+ }
+-#else
+-
++#ifndef MODULE
+ static int __init com20020isa_setup(char *s)
+ {
+       struct net_device *dev;
+@@ -196,37 +192,31 @@ static int __init com20020isa_setup(char
+       s = get_options(s, 8, ints);
+       if (!ints[0])
+               return 1;
+-      dev = alloc_bootmem(sizeof(struct net_device) + sizeof(struct arcnet_local));
+-      memset(dev, 0, sizeof(struct net_device) + sizeof(struct arcnet_local));
+-      lp = dev->priv = (struct arcnet_local *) (dev + 1);
+-      dev->init = com20020isa_probe;
+       switch (ints[0]) {
+       default:                /* ERROR */
+               printk("com90xx: Too many arguments.\n");
+       case 6:         /* Timeout */
+-              lp->timeout = ints[6];
++              timeout = ints[6];
+       case 5:         /* CKP value */
+-              lp->clockp = ints[5];
++              clockp = ints[5];
+       case 4:         /* Backplane flag */
+-              lp->backplane = ints[4];
++              backplane = ints[4];
+       case 3:         /* Node ID */
+-              dev->dev_addr[0] = ints[3];
++              node = ints[3];
+       case 2:         /* IRQ */
+-              dev->irq = ints[2];
++              irq = ints[2];
+       case 1:         /* IO address */
+-              dev->base_addr = ints[1];
++              io = ints[1];
+       }
+       if (*s)
+-              strncpy(dev->name, s, 9);
+-      else
+-              strcpy(dev->name, "arc%d");
+-      if (register_netdev(dev))
+-              printk(KERN_ERR "com20020: Cannot register arcnet device\n");
+-
++              snprintf(device, sizeof(device), "%s", s);
+       return 1;
+ }
+ __setup("com20020=", com20020isa_setup);
+ #endif                                /* MODULE */
++
++module_init(com20020_init)
++module_exit(com20020_exit)
+--- linux-2.6.0/drivers/net/arcnet/com20020-pci.c      2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/arcnet/com20020-pci.c       2003-12-28 23:21:00.000000000 -0800
+@@ -27,6 +27,7 @@
+  * **********************
+  */
+ #include <linux/module.h>
++#include <linux/moduleparam.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/ioport.h>
+@@ -46,18 +47,18 @@
+ /* Module parameters */
+ static int node;
+-static char *device;          /* use eg. device="arc1" to change name */
++static char device[9];                /* use eg. device="arc1" to change name */
+ static int timeout = 3;
+ static int backplane;
+ static int clockp;
+ static int clockm;
+-MODULE_PARM(node, "i");
+-MODULE_PARM(device, "s");
+-MODULE_PARM(timeout, "i");
+-MODULE_PARM(backplane, "i");
+-MODULE_PARM(clockp, "i");
+-MODULE_PARM(clockm, "i");
++module_param(node, int, 0);
++module_param_string(device, device, sizeof(device), 0);
++module_param(timeout, int, 0);
++module_param(backplane, int, 0);
++module_param(clockp, int, 0);
++module_param(clockm, int, 0);
+ MODULE_LICENSE("GPL");
+ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+@@ -68,15 +69,11 @@ static int __devinit com20020pci_probe(s
+       if (pci_enable_device(pdev))
+               return -EIO;
+-      dev = dev_alloc(device ? : "arc%d", &err);
++      dev = alloc_arcdev(device);
+       if (!dev)
+-              return err;
+-      lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
+-      if (!lp) {
+-              err = -ENOMEM;
+-              goto out_dev;
+-      }
+-      memset(lp, 0, sizeof(struct arcnet_local));
++              return -ENOMEM;
++      lp = dev->priv;
++
+       pci_set_drvdata(pdev, dev);
+       // SOHARD needs PCI base addr 4
+@@ -89,6 +86,13 @@ static int __devinit com20020pci_probe(s
+               ioaddr = pci_resource_start(pdev, 2);
+       }
++      if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com20020-pci")) {
++              BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
++                     ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
++              err = -EBUSY;
++              goto out_dev;
++      }
++
+       // Dummy access after Reset
+       // ARCNET controller needs this access to detect bustype
+       outb(0x00,ioaddr+1);
+@@ -105,12 +109,6 @@ static int __devinit com20020pci_probe(s
+       lp->timeout = timeout;
+       lp->hw.owner = THIS_MODULE;
+-      if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com20020-pci")) {
+-              BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n",
+-                     ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
+-              err = -EBUSY;
+-              goto out_priv;
+-      }
+       if (ASTATUS() == 0xFF) {
+               BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
+                      "but seems empty!\n", ioaddr);
+@@ -129,18 +127,18 @@ static int __devinit com20020pci_probe(s
+ out_port:
+       release_region(ioaddr, ARCNET_TOTAL_SIZE);
+-out_priv:
+-      kfree(dev->priv);
+ out_dev:
+-      kfree(dev);
++      free_netdev(dev);
+       return err;
+ }
+ static void __devexit com20020pci_remove(struct pci_dev *pdev)
+ {
+       struct net_device *dev = pci_get_drvdata(pdev);
+-      com20020_remove(dev);
++      unregister_netdev(dev);
++      free_irq(dev->irq, dev);
+       release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
++      free_netdev(dev);
+ }
+ static struct pci_device_id com20020pci_id_table[] = {
+--- linux-2.6.0/drivers/net/arcnet/com90io.c   2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/arcnet/com90io.c    2003-12-28 23:21:00.000000000 -0800
+@@ -27,6 +27,7 @@
+  */
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/moduleparam.h>
+ #include <linux/ioport.h>
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+@@ -234,6 +235,7 @@ static int __init com90io_found(struct n
+ {
+       struct arcnet_local *lp;
+       int ioaddr = dev->base_addr;
++      int err;
+       /* Reserve the irq */
+       if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (COM90xx-IO)", dev)) {
+@@ -246,15 +248,6 @@ static int __init com90io_found(struct n
+               return -EBUSY;
+       }
+-      /* Initialize the rest of the device structure. */
+-      dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
+-      if (!dev->priv) {
+-              free_irq(dev->irq, dev);
+-              release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+-              return -ENOMEM;
+-      }
+-      memset(dev->priv, 0, sizeof(struct arcnet_local));
+-
+       lp = (struct arcnet_local *) (dev->priv);
+       lp->card_name = "COM90xx I/O";
+       lp->hw.command = com90io_command;
+@@ -265,12 +258,6 @@ static int __init com90io_found(struct n
+       lp->hw.copy_to_card = com90io_copy_to_card;
+       lp->hw.copy_from_card = com90io_copy_from_card;
+-      /*
+-       * Fill in the fields of the device structure with generic
+-       * values.
+-       */
+-      arcdev_setup(dev);
+-
+       lp->config = (0x16 | IOMAPflag) & ~ENABLE16flag;
+       SETCONF();
+@@ -278,6 +265,14 @@ static int __init com90io_found(struct n
+       dev->dev_addr[0] = get_buffer_byte(dev, 1);
++      err = register_netdev(dev);
++      if (err) {
++              outb((inb(_CONFIG) & ~IOMAPflag), _CONFIG);
++              free_irq(dev->irq, dev);
++              release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
++              return err;
++      }
++
+       BUGMSG(D_NORMAL, "COM90IO: station %02Xh found at %03lXh, IRQ %d.\n",
+              dev->dev_addr[0], dev->base_addr, dev->irq);
+@@ -361,44 +356,67 @@ static void com90io_copy_from_card(struc
+       TIME("get_whole_buffer", count, get_whole_buffer(dev, bufnum * 512 + offset, count, buf));
+ }
+-
+-#ifdef MODULE
+-
+-static struct net_device *my_dev;
+-
+-/* Module parameters */
+-
+ static int io;                        /* use the insmod io= irq= shmem= options */
+ static int irq;
+-static char *device;          /* use eg. device=arc1 to change name */
++static char device[9];                /* use eg. device=arc1 to change name */
+-MODULE_PARM(io, "i");
+-MODULE_PARM(irq, "i");
+-MODULE_PARM(device, "s");
++module_param(io, int, 0);
++module_param(irq, int, 0);
++module_param_string(device, device, sizeof(device), 0);
+ MODULE_LICENSE("GPL");
+-int init_module(void)
++#ifndef MODULE
++static int __init com90io_setup(char *s)
++{
++      int ints[4];
++      s = get_options(s, 4, ints);
++      if (!ints[0])
++              return 0;
++      switch (ints[0]) {
++      default:                /* ERROR */
++              printk("com90io: Too many arguments.\n");
++      case 2:         /* IRQ */
++              irq = ints[2];
++      case 1:         /* IO address */
++              io = ints[1];
++      }
++      if (*s)
++              snprintf(device, sizeof(device), "%s", s);
++      return 1;
++}
++__setup("com90io=", com90io_setup);
++#endif
++
++static struct net_device *my_dev;
++
++static int __init com90io_init(void)
+ {
+       struct net_device *dev;
+       int err;
+-      dev = dev_alloc(device ? : "arc%d", &err);
++      dev = alloc_arcdev(device);
+       if (!dev)
+-              return err;
++              return -ENOMEM;
++
++      SET_MODULE_OWNER(dev);
+       dev->base_addr = io;
+       dev->irq = irq;
+       if (dev->irq == 2)
+               dev->irq = 9;
+-      if (com90io_probe(dev))
+-              return -EIO;
++      err = com90io_probe(dev);
++
++      if (err) {
++              free_netdev(dev);
++              return err;
++      }
+       my_dev = dev;
+       return 0;
+ }
+-void cleanup_module(void)
++static void __exit com90io_exit(void)
+ {
+       struct net_device *dev = my_dev;
+       int ioaddr = dev->base_addr;
+@@ -410,42 +428,8 @@ void cleanup_module(void)
+       free_irq(dev->irq, dev);
+       release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+-      kfree(dev->priv);
+       free_netdev(dev);
+ }
+-#else
+-
+-static int __init com90io_setup(char *s)
+-{
+-      struct net_device *dev;
+-      int ints[4];
+-
+-      s = get_options(s, 4, ints);
+-      if (!ints[0])
+-              return 0;
+-      dev = alloc_bootmem(sizeof(struct net_device));
+-      memset(dev, 0, sizeof(struct net_device));
+-      dev->init = com90io_probe;
+-
+-      switch (ints[0]) {
+-      default:                /* ERROR */
+-              printk("com90io: Too many arguments.\n");
+-      case 2:         /* IRQ */
+-              dev->irq = ints[2];
+-      case 1:         /* IO address */
+-              dev->base_addr = ints[1];
+-      }
+-      if (*s)
+-              strncpy(dev->name, s, 9);
+-      else
+-              strcpy(dev->name, "arc%d");
+-      if (register_netdev(dev))
+-              printk(KERN_ERR "com90io: Cannot register arcnet device\n");
+-
+-      return 1;
+-}
+-
+-__setup("com90io=", com90io_setup);
+-
+-#endif                                /* MODULE */
++module_init(com90io_init)
++module_exit(com90io_exit)
+--- linux-2.6.0/drivers/net/arcnet/com90xx.c   2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/arcnet/com90xx.c    2003-12-28 23:21:00.000000000 -0800
+@@ -25,6 +25,7 @@
+  * **********************
+  */
+ #include <linux/module.h>
++#include <linux/moduleparam.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+ #include <linux/delay.h>
+@@ -52,8 +53,7 @@
+ /* Internal function declarations */
+-static int com90xx_found(struct net_device *dev, int ioaddr, int airq,
+-                       u_long shmem);
++static int com90xx_found(int ioaddr, int airq, u_long shmem);
+ static void com90xx_command(struct net_device *dev, int command);
+ static int com90xx_status(struct net_device *dev);
+ static void com90xx_setmask(struct net_device *dev, int mask);
+@@ -98,32 +98,43 @@ static int numcards;
+ static int com90xx_skip_probe __initdata = 0;
+-static int __init com90xx_probe(struct net_device *dev)
++/* Module parameters */
++
++static int io;                        /* use the insmod io= irq= shmem= options */
++static int irq;
++static int shmem;
++static char device[9];                /* use eg. device=arc1 to change name */
++
++module_param(io, int, 0);
++module_param(irq, int, 0);
++module_param(shmem, int, 0);
++module_param_string(device, device, sizeof(device), 0);
++
++static void __init com90xx_probe(void)
+ {
+-      int count, status, ioaddr, numprint, airq, retval = -ENODEV,
+-       openparen = 0;
++      int count, status, ioaddr, numprint, airq, openparen = 0;
+       unsigned long airqmask;
+       int ports[(0x3f0 - 0x200) / 16 + 1] =
+       {0};
+       u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] =
+       {0};
+       int numports, numshmems, *port;
+-      u_long *shmem;
++      u_long *p;
+-      if (!dev && com90xx_skip_probe)
+-              return -ENODEV;
++      if (!io && !irq && !shmem && !*device && com90xx_skip_probe)
++              return;
+       BUGLVL(D_NORMAL) printk(VERSION);
+       /* set up the arrays where we'll store the possible probe addresses */
+       numports = numshmems = 0;
+-      if (dev && dev->base_addr)
+-              ports[numports++] = dev->base_addr;
++      if (io)
++              ports[numports++] = io;
+       else
+               for (count = 0x200; count <= 0x3f0; count += 16)
+                       ports[numports++] = count;
+-      if (dev && dev->mem_start)
+-              shmems[numshmems++] = dev->mem_start;
++      if (shmem)
++              shmems[numshmems++] = shmem;
+       else
+               for (count = 0xA0000; count <= 0xFF800; count += 2048)
+                       shmems[numshmems++] = count;
+@@ -143,22 +154,19 @@ static int __init com90xx_probe(struct n
+               ioaddr = *port;
+-              if (check_region(*port, ARCNET_TOTAL_SIZE)) {
++              if (!request_region(*port, ARCNET_TOTAL_SIZE, "arcnet (90xx)")) {
+                       BUGMSG2(D_INIT_REASONS, "(check_region)\n");
+                       BUGMSG2(D_INIT_REASONS, "S1: ");
+                       BUGLVL(D_INIT_REASONS) numprint = 0;
+-                      *port = ports[numports - 1];
+-                      numports--;
+-                      port--;
++                      *port-- = ports[--numports];
+                       continue;
+               }
+               if (ASTATUS() == 0xFF) {
+                       BUGMSG2(D_INIT_REASONS, "(empty)\n");
+                       BUGMSG2(D_INIT_REASONS, "S1: ");
+                       BUGLVL(D_INIT_REASONS) numprint = 0;
+-                      *port = ports[numports - 1];
+-                      numports--;
+-                      port--;
++                      release_region(*port, ARCNET_TOTAL_SIZE);
++                      *port-- = ports[--numports];
+                       continue;
+               }
+               inb(_RESET);    /* begin resetting card */
+@@ -171,14 +179,14 @@ static int __init com90xx_probe(struct n
+       if (!numports) {
+               BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n");
+-              return -ENODEV;
++              return;
+       }
+       /* Stage 2: we have now reset any possible ARCnet cards, so we can't
+        * do anything until they finish.  If D_INIT, print the list of
+        * cards that are left.
+        */
+       numprint = -1;
+-      for (port = &ports[0]; port - ports < numports; port++) {
++      for (port = &ports[0]; port < ports + numports; port++) {
+               numprint++;
+               numprint %= 8;
+               if (!numprint) {
+@@ -194,8 +202,8 @@ static int __init com90xx_probe(struct n
+        * 0xD1 byte in the right place, or are read-only.
+        */
+       numprint = -1;
+-      for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
+-              u_long ptr = *shmem;
++      for (p = &shmems[0]; p < shmems + numshmems; p++) {
++              u_long ptr = *p;
+               numprint++;
+               numprint %= 8;
+@@ -203,15 +211,13 @@ static int __init com90xx_probe(struct n
+                       BUGMSG2(D_INIT, "\n");
+                       BUGMSG2(D_INIT, "S3: ");
+               }
+-              BUGMSG2(D_INIT, "%lXh ", *shmem);
++              BUGMSG2(D_INIT, "%lXh ", *p);
+-              if (check_mem_region(*shmem, BUFFER_SIZE)) {
++              if (!request_mem_region(*p, BUFFER_SIZE, "arcnet (90xx)")) {
+                       BUGMSG2(D_INIT_REASONS, "(check_mem_region)\n");
+                       BUGMSG2(D_INIT_REASONS, "Stage 3: ");
+                       BUGLVL(D_INIT_REASONS) numprint = 0;
+-                      *shmem = shmems[numshmems - 1];
+-                      numshmems--;
+-                      shmem--;
++                      *p-- = shmems[--numshmems];
+                       continue;
+               }
+               if (isa_readb(ptr) != TESTvalue) {
+@@ -219,9 +225,8 @@ static int __init com90xx_probe(struct n
+                               isa_readb(ptr), TESTvalue);
+                       BUGMSG2(D_INIT_REASONS, "S3: ");
+                       BUGLVL(D_INIT_REASONS) numprint = 0;
+-                      *shmem = shmems[numshmems - 1];
+-                      numshmems--;
+-                      shmem--;
++                      release_mem_region(*p, BUFFER_SIZE);
++                      *p-- = shmems[--numshmems];
+                       continue;
+               }
+               /* By writing 0x42 to the TESTvalue location, we also make
+@@ -233,9 +238,8 @@ static int __init com90xx_probe(struct n
+               if (isa_readb(ptr) != 0x42) {
+                       BUGMSG2(D_INIT_REASONS, "(read only)\n");
+                       BUGMSG2(D_INIT_REASONS, "S3: ");
+-                      *shmem = shmems[numshmems - 1];
+-                      numshmems--;
+-                      shmem--;
++                      release_mem_region(*p, BUFFER_SIZE);
++                      *p-- = shmems[--numshmems];
+                       continue;
+               }
+               BUGMSG2(D_INIT_REASONS, "\n");
+@@ -246,20 +250,22 @@ static int __init com90xx_probe(struct n
+       if (!numshmems) {
+               BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n");
+-              return -ENODEV;
++              for (port = &ports[0]; port < ports + numports; port++)
++                      release_region(*port, ARCNET_TOTAL_SIZE);
++              return;
+       }
+       /* Stage 4: something of a dummy, to report the shmems that are
+        * still possible after stage 3.
+        */
+       numprint = -1;
+-      for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
++      for (p = &shmems[0]; p < shmems + numshmems; p++) {
+               numprint++;
+               numprint %= 8;
+               if (!numprint) {
+                       BUGMSG2(D_INIT, "\n");
+                       BUGMSG2(D_INIT, "S4: ");
+               }
+-              BUGMSG2(D_INIT, "%lXh ", *shmem);
++              BUGMSG2(D_INIT, "%lXh ", *p);
+       }
+       BUGMSG2(D_INIT, "\n");
+@@ -271,7 +277,8 @@ static int __init com90xx_probe(struct n
+        * after the first one is found.
+        */
+       numprint = -1;
+-      for (port = &ports[0]; port - ports < numports; port++) {
++      for (port = &ports[0]; port < ports + numports; port++) {
++              int found = 0;
+               numprint++;
+               numprint %= 8;
+               if (!numprint) {
+@@ -288,9 +295,8 @@ static int __init com90xx_probe(struct n
+                       BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);
+                       BUGMSG2(D_INIT_REASONS, "S5: ");
+                       BUGLVL(D_INIT_REASONS) numprint = 0;
+-                      *port = ports[numports - 1];
+-                      numports--;
+-                      port--;
++                      release_region(*port, ARCNET_TOTAL_SIZE);
++                      *port-- = ports[--numports];
+                       continue;
+               }
+               ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
+@@ -300,15 +306,14 @@ static int __init com90xx_probe(struct n
+                               status);
+                       BUGMSG2(D_INIT_REASONS, "S5: ");
+                       BUGLVL(D_INIT_REASONS) numprint = 0;
+-                      *port = ports[numports - 1];
+-                      numports--;
+-                      port--;
++                      release_region(*port, ARCNET_TOTAL_SIZE);
++                      *port-- = ports[--numports];
+                       continue;
+               }
+               /* skip this completely if an IRQ was given, because maybe
+                * we're on a machine that locks during autoirq!
+                */
+-              if (!dev || !dev->irq) {
++              if (!irq) {
+                       /* if we do this, we're sure to get an IRQ since the
+                        * card has just reset and the NORXflag is on until
+                        * we tell it to start receiving.
+@@ -323,13 +328,12 @@ static int __init com90xx_probe(struct n
+                               BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);
+                               BUGMSG2(D_INIT_REASONS, "S5: ");
+                               BUGLVL(D_INIT_REASONS) numprint = 0;
+-                              *port = ports[numports - 1];
+-                              numports--;
+-                              port--;
++                              release_region(*port, ARCNET_TOTAL_SIZE);
++                              *port-- = ports[--numports];
+                               continue;
+                       }
+               } else {
+-                      airq = dev->irq;
++                      airq = irq;
+               }
+               BUGMSG2(D_INIT, "(%d,", airq);
+@@ -354,21 +358,20 @@ static int __init com90xx_probe(struct n
+               mdelay(RESETtime);
+ #endif
+-              for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
+-                      u_long ptr = *shmem;
++              for (p = &shmems[0]; p < shmems + numshmems; p++) {
++                      u_long ptr = *p;
+                       if (isa_readb(ptr) == TESTvalue) {      /* found one */
+-                              BUGMSG2(D_INIT, "%lXh)\n", *shmem);
++                              BUGMSG2(D_INIT, "%lXh)\n", *p);
+                               openparen = 0;
+                               /* register the card */
+-                              retval = com90xx_found(dev, *port, airq, *shmem);
++                              if (com90xx_found(*port, airq, *p) == 0)
++                                      found = 1;
+                               numprint = -1;
+                               /* remove shmem from the list */
+-                              *shmem = shmems[numshmems - 1];
+-                              numshmems--;
+-
++                              *p = shmems[--numshmems];
+                               break;  /* go to the next I/O port */
+                       } else {
+                               BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr));
+@@ -380,44 +383,39 @@ static int __init com90xx_probe(struct n
+                       BUGLVL(D_INIT_REASONS) printk("S5: ");
+                       BUGLVL(D_INIT_REASONS) numprint = 0;
+               }
+-              *port = ports[numports - 1];
+-              numports--;
+-              port--;
++              if (!found)
++                      release_region(*port, ARCNET_TOTAL_SIZE);
++              *port-- = ports[--numports];
+       }
+       BUGLVL(D_INIT_REASONS) printk("\n");
+       /* Now put back TESTvalue on all leftover shmems. */
+-      for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)
+-              isa_writeb(TESTvalue, *shmem);
+-
+-      if (retval && dev && !numcards)
+-              BUGMSG2(D_NORMAL, "S5: No ARCnet cards found.\n");
+-      return retval;
++      for (p = &shmems[0]; p < shmems + numshmems; p++) {
++              isa_writeb(TESTvalue, *p);
++              release_mem_region(*p, BUFFER_SIZE);
++      }
+ }
+ /* Set up the struct net_device associated with this card.  Called after
+  * probing succeeds.
+  */
+-static int __init com90xx_found(struct net_device *dev0, int ioaddr, int airq,
+-                              u_long shmem)
++static int __init com90xx_found(int ioaddr, int airq, u_long shmem)
+ {
+-      struct net_device *dev = dev0;
++      struct net_device *dev = NULL;
+       struct arcnet_local *lp;
+       u_long first_mirror, last_mirror;
+-      int mirror_size, err;
++      int mirror_size;
+-      /* allocate struct net_device if we don't have one yet */
+-      if (!dev && !(dev = dev_alloc("arc%d", &err))) {
++      /* allocate struct net_device */
++      dev = alloc_arcdev(device);
++      if (!dev) {
+               BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n");
+-              return err;
+-      }
+-      lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
+-      if (!lp) {
+-              BUGMSG(D_NORMAL, "Can't allocate device data!\n");
+-              goto err_free_dev;
++              release_mem_region(shmem, BUFFER_SIZE);
++              return -ENOMEM;
+       }
++      lp = dev->priv;
+       /* find the real shared memory start/end points, including mirrors */
+       /* guess the actual size of one "memory mirror" - the number of
+@@ -442,8 +440,18 @@ static int __init com90xx_found(struct n
+       dev->mem_start = first_mirror;
+       dev->mem_end = last_mirror + MIRROR_SIZE - 1;
++      release_mem_region(shmem, BUFFER_SIZE);
++      if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)"))
++              goto err_free_dev;
++
++      /* reserve the irq */
++      if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
++              BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
++              goto err_release_mem;
++      }
++      dev->irq = airq;
++
+       /* Initialize the rest of the device structure. */
+-      memset(lp, 0, sizeof(struct arcnet_local));
+       lp->card_name = "COM90xx";
+       lp->hw.command = com90xx_command;
+       lp->hw.status = com90xx_status;
+@@ -455,24 +463,12 @@ static int __init com90xx_found(struct n
+       lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+       if (!lp->mem_start) {
+               BUGMSG(D_NORMAL, "Can't remap device memory!\n");
+-              goto err_free_dev_priv;
++              goto err_free_irq;
+       }
+-      /* Fill in the fields of the device structure with generic values. */
+-      arcdev_setup(dev);
+       /* get and check the station ID from offset 1 in shmem */
+       dev->dev_addr[0] = readb(lp->mem_start + 1);
+-      /* reserve the irq */
+-      if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
+-              BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
+-              goto err_unmap;
+-      }
+-      dev->irq = airq;
+-
+-      /* reserve the I/O and memory regions - guaranteed to work by check_region */
+-      request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (90xx)");
+-      request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)");
+       dev->base_addr = ioaddr;
+       BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, "
+@@ -481,23 +477,20 @@ static int __init com90xx_found(struct n
+              dev->base_addr, dev->irq, dev->mem_start,
+        (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
+-      if (!dev0 && register_netdev(dev))
+-              goto err_release;
++      if (register_netdev(dev))
++              goto err_unmap;
+       cards[numcards++] = dev;
+       return 0;
+-      err_release:
++err_unmap:
++      iounmap(lp->mem_start);
++err_free_irq:
+       free_irq(dev->irq, dev);
+-      release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
++err_release_mem:
+       release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+-      err_unmap:
+-      iounmap(lp->mem_start);
+-      err_free_dev_priv:
+-      kfree(dev->priv);
+-      err_free_dev:
+-      if (!dev0)
+-              kfree(dev);
++err_free_dev:
++      free_netdev(dev);
+       return -EIO;
+ }
+@@ -587,37 +580,13 @@ static void com90xx_copy_from_card(struc
+ }
+-/* Module parameters */
+-
+-static int io;                        /* use the insmod io= irq= shmem= options */
+-static int irq;
+-static int shmem;
+-static char *device;          /* use eg. device=arc1 to change name */
+-
+-MODULE_PARM(io, "i");
+-MODULE_PARM(irq, "i");
+-MODULE_PARM(shmem, "i");
+-MODULE_PARM(device, "s");
+ MODULE_LICENSE("GPL");
+ static int __init com90xx_init(void)
+ {
+-      struct net_device *dev;
+-      int err;
+-
+-      if (io || irq || shmem || device) {
+-              dev = dev_alloc(device ? : "arc%d", &err);
+-              if (!dev)
+-                      return err;
+-              dev->base_addr = io;
+-              dev->irq = irq;
+-              if (dev->irq == 2)
+-                      dev->irq = 9;
+-              dev->mem_start = shmem;
+-              com90xx_probe(dev);
+-      } else
+-              com90xx_probe(NULL);
+-
++      if (irq == 2)
++              irq = 9;
++      com90xx_probe();
+       if (!numcards)
+               return -EIO;
+       return 0;
+@@ -638,7 +607,6 @@ static void __exit com90xx_exit(void)
+               iounmap(lp->mem_start);
+               release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
+               release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+-              kfree(dev->priv);
+               free_netdev(dev);
+       }
+ }
+@@ -669,9 +637,7 @@ static int __init com90xx_setup(char *s)
+       }
+       if (*s)
+-              strncpy(device, s, 9);
+-      else
+-              strcpy(device, "arc%d");
++              snprintf(device, sizeof(device), "%s", s);
+       return 1;
+ }
+--- linux-2.6.0/drivers/net/ariadne.c  2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/ariadne.c   2003-12-28 23:21:00.000000000 -0800
+@@ -168,7 +168,7 @@ static int __init ariadne_probe(void)
+           continue;
+       }
+-      dev = init_etherdev(NULL, sizeof(struct ariadne_private));
++      dev = alloc_etherdev(sizeof(struct ariadne_private));
+       if (dev == NULL) {
+           release_resource(r1);
+@@ -205,11 +205,17 @@ static int __init ariadne_probe(void)
+       dev->get_stats = &ariadne_get_stats;
+       dev->set_multicast_list = &set_multicast_list;
++      res = register_netdev(dev);
++      if (res) {
++          release_resource(r1);
++          release_resource(r2);
++          free_netdev(dev);
++          break;
++      }
+ #ifdef MODULE
+       priv->next_module = root_ariadne_dev;
+       root_ariadne_dev = priv;
+ #endif
+-      res = 0;
+     }
+     return res;
+ }
+--- linux-2.6.0/drivers/net/arm/am79c961a.c    2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/arm/am79c961a.c     2003-12-28 23:21:00.000000000 -0800
+@@ -722,7 +722,7 @@ static int __init am79c961_init(void)
+ release:
+       release_region(dev->base_addr, 0x18);
+ nodev:
+-      kfree(dev);
++      free_netdev(dev);
+ out:
+       return ret;
+ }
+--- linux-2.6.0/drivers/net/arm/ether00.c      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/arm/ether00.c       2003-12-28 23:21:00.000000000 -0800
+@@ -923,8 +923,6 @@ static int ether00_add_device(struct pld
+               result = -ENOMEM;
+               goto out_release;
+       }
+-      memset(dev,0,sizeof(struct net_device));
+-      memset(dev->priv, 0, sizeof(struct net_priv));
+       priv = dev->priv;
+       priv->tq_memupdate.routine=ether00_mem_update;
+@@ -966,7 +964,7 @@ static int ether00_add_device(struct pld
+  out_unmap:
+       iounmap(map_addr);
+  out_kfree:
+-      kfree(dev);
++      free_netdev(dev);
+  out_release:
+       release_mem_region(dev_info->base_addr, MAC_REG_SIZE);
+       return result;
+--- linux-2.6.0/drivers/net/arm/ether1.c       2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/arm/ether1.c        2003-12-28 23:21:00.000000000 -0800
+@@ -1068,7 +1068,7 @@ ether1_probe(struct expansion_card *ec, 
+ release:
+       release_region(dev->base_addr, 16);
+       release_region(dev->base_addr + 0x800, 4096);
+-      kfree(dev);
++      free_netdev(dev);
+ out:
+       return ret;
+ }
+--- linux-2.6.0/drivers/net/arm/ether3.c       2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/arm/ether3.c        2003-12-28 23:21:00.000000000 -0800
+@@ -908,7 +908,7 @@ ether3_probe(struct expansion_card *ec, 
+ failed:
+       release_region(dev->base_addr, 128);
+ free:
+-      kfree(dev);
++      free_netdev(dev);
+ out:
+       return ret;
+ }
+--- linux-2.6.0/drivers/net/arm/etherh.c       2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/arm/etherh.c        2003-12-28 23:21:00.000000000 -0800
+@@ -551,15 +551,12 @@ etherh_probe(struct expansion_card *ec, 
+       etherh_banner();
+-      dev = alloc_etherdev(sizeof(struct etherh_priv));
++      dev = alloc_ei_netdev();
+       if (!dev) {
+               ret = -ENOMEM;
+               goto out;
+       }
+-      /*
+-       * alloc_etherdev allocs and zeros dev->priv
+-       */
+       eh = dev->priv;
+       spin_lock_init(&eh->eidev.page_lock);
+@@ -622,21 +619,12 @@ etherh_probe(struct expansion_card *ec, 
+               goto free;
+       }
+-      if (ethdev_init(dev)) {
+-              ret = -ENODEV;
+-              goto release;
+-      }
+-
+       /*
+        * If we're in the NIC slot, make sure the IRQ is enabled
+        */
+       if (dev->irq == 11)
+               etherh_set_ctrl(eh, ETHERH_CP_IE);
+-      /*
+-       * Unfortunately, ethdev_init eventually calls
+-       * ether_setup, which re-writes dev->flags.
+-       */
+       switch (ec->cid.product) {
+       case PROD_ANT_ETHERM:
+               dev_type = "ANT EtherM";
+@@ -705,7 +693,7 @@ etherh_probe(struct expansion_card *ec, 
+  release:
+       release_region(dev->base_addr, 16);
+  free:
+-      kfree(dev);
++      free_netdev(dev);
+  out:
+       return ret;
+ }
+--- linux-2.6.0/drivers/net/at1700.c   2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/at1700.c    2003-12-28 23:21:00.000000000 -0800
+@@ -81,12 +81,12 @@ static int fmv18x_probe_list[] __initdat
+  */
+ #ifndef CONFIG_X86_PC9800
+-static int at1700_probe_list[] __initdata = {
++static unsigned at1700_probe_list[] __initdata = {
+       0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
+ };
+ #else /* CONFIG_X86_PC9800 */
+-static int at1700_probe_list[] __initdata = {
++static unsigned at1700_probe_list[] __initdata = {
+       0x1d6, 0x1d8, 0x1da, 0x1d4, 0xd4, 0xd2, 0xd8, 0xd0, 0
+ };
+@@ -196,8 +196,6 @@ struct net_local {
+ /* Index to functions, as function prototypes. */
+-extern int at1700_probe(struct net_device *dev);
+-
+ static int at1700_probe1(struct net_device *dev, int ioaddr);
+ static int read_eeprom(long ioaddr, int location);
+ static int net_open(struct net_device *dev);
+@@ -232,24 +230,78 @@ static struct at1720_mca_adapters_struct
+    (detachable devices only).
+    */
+-int __init at1700_probe(struct net_device *dev)
++#ifndef CONFIG_X86_PC9800
++static int io = 0x260;
++#else
++static int io = 0xd0;
++#endif
++
++static int irq;
++
++static void cleanup_card(struct net_device *dev)
+ {
+-      int i;
+-      int base_addr = dev->base_addr;
++#ifdef CONFIG_MCA     
++      struct net_local *lp = dev->priv;
++      if (lp->mca_slot)
++              mca_mark_as_unused(lp->mca_slot);
++#endif        
++      free_irq(dev->irq, NULL);
++#ifndef CONFIG_X86_PC9800
++      release_region(dev->base_addr, AT1700_IO_EXTENT);
++#else
++      {
++              int i;
++              for (i = 0; i < 0x2000; i += 0x200)
++                      release_region(dev->base_addr + i, 2);
++      }
++#endif
++}
++
++struct net_device * __init at1700_probe(int unit)
++{
++      struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
++      unsigned *port;
++      int err = 0;
++
++      if (!dev)
++              return ERR_PTR(-ENODEV);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++              io = dev->base_addr;
++              irq = dev->irq;
++      } else {
++              dev->base_addr = io;
++              dev->irq = irq;
++      }
+       SET_MODULE_OWNER(dev);
+-      if (base_addr > 0x1ff)          /* Check a single specified location. */
+-              return at1700_probe1(dev, base_addr);
+-      else if (base_addr != 0)        /* Don't probe at all. */
+-              return -ENXIO;
+-
+-      for (i = 0; at1700_probe_list[i]; i++) {
+-              int ioaddr = at1700_probe_list[i];
+-              if (at1700_probe1(dev, ioaddr) == 0)
+-                      return 0;
++      if (io > 0x1ff) {       /* Check a single specified location. */
++              err = at1700_probe1(dev, io);
++      } else if (io != 0) {   /* Don't probe at all. */
++              err = -ENXIO;
++      } else {
++              for (port = at1700_probe_list; *port; port++) {
++                      if (at1700_probe1(dev, *port) == 0)
++                              break;
++                      dev->irq = irq;
++              }
++              if (!*port)
++                      err = -ENODEV;
+       }
+-      return -ENODEV;
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /* The Fujitsu datasheet suggests that the NIC be probed for by checking its
+@@ -267,7 +319,7 @@ static int __init at1700_probe1(struct n
+       char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
+       unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
+       int slot, ret = -ENODEV;
+-      struct net_local *lp;
++      struct net_local *lp = dev->priv;
+       
+ #ifndef CONFIG_X86_PC9800
+       if (!request_region(ioaddr, AT1700_IO_EXTENT, dev->name))
+@@ -284,9 +336,10 @@ static int __init at1700_probe1(struct n
+       }
+ #endif
+-              /* Resetting the chip doesn't reset the ISA interface, so don't bother.
+-         That means we have to be careful with the register values we probe for.
+-         */
++      /* Resetting the chip doesn't reset the ISA interface, so don't bother.
++         That means we have to be careful with the register values we probe
++         for.
++       */
+ #ifdef notdef
+       printk("at1700 probe at %#x, eeprom is %4.4x %4.4x %4.4x ctrl %4.4x.\n",
+                  ioaddr, read_eeprom(ioaddr, 4), read_eeprom(ioaddr, 5),
+@@ -331,15 +384,13 @@ static int __init at1700_probe1(struct n
+                                               break;
+                                       /* probing for a card at a particular IO/IRQ */
+-                              if (dev &&
+-                                      ((dev->irq && dev->irq != irq) ||
+-                                       (dev->base_addr && dev->base_addr != ioaddr))) {
++                              if ((dev->irq && dev->irq != irq) ||
++                                  (dev->base_addr && dev->base_addr != ioaddr)) {
+                                       slot++;         /* probing next slot */
+                                       continue;
+                               }
+-                              if (dev)
+-                                      dev->irq = irq;
++                              dev->irq = irq;
+                               
+                               /* claim the slot */
+                               mca_set_adapter_name( slot, at1720_mca_adapters[j].name );
+@@ -476,13 +527,7 @@ found:
+       if (net_debug)
+               printk(version);
+-      /* Initialize the device structure. */
+-      dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-      if (dev->priv == NULL) {
+-              ret = -ENOMEM;
+-              goto err_out;
+-      }
+-      memset(dev->priv, 0, sizeof(struct net_local));
++      memset(lp, 0, sizeof(struct net_local));
+       dev->open               = net_open;
+       dev->stop               = net_close;
+@@ -492,11 +537,7 @@ found:
+       dev->tx_timeout = net_tx_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
+-      lp = (struct net_local *)dev->priv;
+-      lp->lock = SPIN_LOCK_UNLOCKED;
+-
+-      /* Fill in the fields of 'dev' with ethernet-generic values. */
+-      ether_setup(dev);
++      spin_lock_init(&lp->lock);
+       lp->jumpered = is_fmv18x;
+       lp->mca_slot = slot;
+@@ -505,14 +546,11 @@ found:
+       if (ret) {
+               printk ("  AT1700 at %#3x is unusable due to a conflict on"
+                               "IRQ %d.\n", ioaddr, irq);
+-              goto err_out_priv;
++              goto err_out;
+       }
+       return 0;
+-err_out_priv:
+-      kfree(dev->priv);
+-      dev->priv = NULL;
+ err_out:
+ #ifndef CONFIG_X86_PC9800
+       release_region(ioaddr, AT1700_IO_EXTENT);
+@@ -940,14 +978,7 @@ set_rx_mode(struct net_device *dev)
+ }
+ #ifdef MODULE
+-static struct net_device dev_at1700;
+-#ifndef CONFIG_X86_PC9800
+-static int io = 0x260;
+-#else
+-static int io = 0xd0;
+-#endif
+-
+-static int irq;
++static struct net_device *dev_at1700;
+ MODULE_PARM(io, "i");
+ MODULE_PARM(irq, "i");
+@@ -960,41 +991,18 @@ int init_module(void)
+ {
+       if (io == 0)
+               printk("at1700: You should not use auto-probing with insmod!\n");
+-      dev_at1700.base_addr = io;
+-      dev_at1700.irq       = irq;
+-      dev_at1700.init      = at1700_probe;
+-      if (register_netdev(&dev_at1700) != 0) {
+-              printk("at1700: register_netdev() returned non-zero.\n");
+-              return -EIO;
+-      }
++      dev_at1700 = at1700_probe(-1);
++      if (IS_ERR(dev_at1700))
++              return PTR_ERR(dev_at1700);
+       return 0;
+ }
+ void
+ cleanup_module(void)
+ {
+-#ifdef CONFIG_MCA     
+-      struct net_local *lp = dev_at1700.priv;
+-      if(lp->mca_slot)
+-      {
+-              mca_mark_as_unused(lp->mca_slot);
+-      }
+-#endif        
+-      unregister_netdev(&dev_at1700);
+-      kfree(dev_at1700.priv);
+-      dev_at1700.priv = NULL;
+-
+-      /* If we don't do this, we can't re-insmod it later. */
+-      free_irq(dev_at1700.irq, NULL);
+-#ifndef CONFIG_X86_PC9800
+-      release_region(dev_at1700.base_addr, AT1700_IO_EXTENT);
+-#else
+-      {
+-              int i;
+-              for (i = 0; i < 0x2000; i += 0x200)
+-                      release_region(dev_at1700.base_addr + i, 2);
+-      }
+-#endif
++      unregister_netdev(dev_at1700);
++      cleanup_card(dev_at1700);
++      free_netdev(dev_at1700);
+ }
+ #endif /* MODULE */
+ MODULE_LICENSE("GPL");
+--- linux-2.6.0/drivers/net/atari_bionet.c     2003-06-14 12:18:23.000000000 -0700
++++ 25/drivers/net/atari_bionet.c      2003-12-28 23:21:00.000000000 -0800
+@@ -148,8 +148,6 @@ unsigned char *phys_nic_packet;
+ /* Index to functions, as function prototypes.
+  */
+-extern int bionet_probe(struct net_device *dev);
+-
+ static int bionet_open(struct net_device *dev);
+ static int bionet_send_packet(struct sk_buff *skb, struct net_device *dev);
+ static void bionet_poll_rx(struct net_device *);
+@@ -321,15 +319,26 @@ end:
+ /* Check for a network adaptor of this type, and return '0' if one exists.
+  */
+-int __init 
+-bionet_probe(struct net_device *dev){
++struct net_device * __init bionet_probe(int unit)
++{
++      struct net_device *dev;
+       unsigned char station_addr[6];
+       static unsigned version_printed;
+       static int no_more_found;       /* avoid "Probing for..." printed 4 times */
+       int i;
++      int err;
+       if (!MACH_IS_ATARI || no_more_found)
+-              return -ENODEV;
++              return ERR_PTR(-ENODEV);
++
++      dev = alloc_etherdev(sizeof(struct net_local));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
++      SET_MODULE_OWNER(dev);
+       printk("Probing for BioNet 100 Adapter...\n");
+@@ -347,11 +356,10 @@ bionet_probe(struct net_device *dev){
+       ||  station_addr[2] != 'O' ) {
+               no_more_found = 1;
+               printk( "No BioNet 100 found.\n" );
+-              return -ENODEV;
++              free_netdev(dev);
++              return ERR_PTR(-ENODEV);
+       }
+-      SET_MODULE_OWNER(dev);
+-
+       if (bionet_debug > 0 && version_printed++ == 0)
+               printk(version);
+@@ -369,12 +377,6 @@ bionet_probe(struct net_device *dev){
+                       nic_packet, phys_nic_packet );
+       }
+-      if (dev->priv == NULL)
+-              dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-      if (!dev->priv)
+-              return -ENOMEM;
+-      memset(dev->priv, 0, sizeof(struct net_local));
+-
+       dev->open               = bionet_open;
+       dev->stop               = bionet_close;
+       dev->hard_start_xmit    = bionet_send_packet;
+@@ -390,8 +392,11 @@ bionet_probe(struct net_device *dev){
+ #endif
+               dev->dev_addr[i]  = station_addr[i];
+       }
+-      ether_setup(dev);
+-      return 0;
++      err = register_netdev(dev);
++      if (!err)
++              return dev;
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /* Open/initialize the board.  This is called (in the current kernel)
+@@ -640,25 +645,20 @@ static struct net_device_stats *net_get_
+ #ifdef MODULE
+-static struct net_device bio_dev;
+-
+-int
+-init_module(void) {
+-      int err;
++static struct net_device *bio_dev;
+-      bio_dev.init = bionet_probe;
+-      if ((err = register_netdev(&bio_dev))) {
+-              if (err == -EEXIST)  {
+-                      printk("BIONET: devices already present. Module not loaded.\n");
+-              }
+-              return err;
+-      }
++int init_module(void)
++{
++      bio_dev = bionet_probe(-1);
++      if (IS_ERR(bio_dev))
++              return PTR_ERR(bio_dev);
+       return 0;
+ }
+-void
+-cleanup_module(void) {
+-      unregister_netdev(&bio_dev);
++void cleanup_module(void)
++{
++      unregister_netdev(bio_dev);
++      free_netdev(bio_dev);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/atarilance.c       2003-06-14 12:18:03.000000000 -0700
++++ 25/drivers/net/atarilance.c        2003-12-28 23:21:00.000000000 -0800
+@@ -371,26 +371,39 @@ static void *slow_memcpy( void *dst, con
+ }
+-int __init atarilance_probe( struct net_device *dev )
+-{     
++struct net_device * __init atarilance_probe(int unit)
++{
+       int i;
+       static int found;
+-
+-      SET_MODULE_OWNER(dev);
++      struct net_device *dev;
++      int err = -ENODEV;
+       if (!MACH_IS_ATARI || found)
+               /* Assume there's only one board possible... That seems true, since
+                * the Riebl/PAM board's address cannot be changed. */
+-              return( ENODEV );
++              return ERR_PTR(-ENODEV);
++
++      dev = alloc_etherdev(sizeof(struct lance_private));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
++      SET_MODULE_OWNER(dev);
+       for( i = 0; i < N_LANCE_ADDR; ++i ) {
+               if (lance_probe1( dev, &lance_addr_list[i] )) {
+                       found = 1;
+-                      return( 0 );
++                      err = register_netdev(dev);
++                      if (!err)
++                              return dev;
++                      free_irq(dev->irq, dev);
++                      break;
+               }
+       }
+-
+-      return( ENODEV );
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+@@ -511,12 +524,6 @@ static unsigned long __init lance_probe1
+       return( 0 );
+   probe_ok:
+-      init_etherdev( dev, sizeof(struct lance_private) );
+-      if (!dev->priv) {
+-              dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
+-              if (!dev->priv)
+-                      return 0;
+-      }
+       lp = (struct lance_private *)dev->priv;
+       MEM = (struct lance_memory *)memaddr;
+       IO = lp->iobase = (struct lance_ioreg *)ioaddr;
+@@ -1171,26 +1178,21 @@ static int lance_set_mac_address( struct
\f
+ #ifdef MODULE
+-static struct net_device atarilance_dev;
++static struct net_device *atarilance_dev;
+ int init_module(void)
+-
+-{     int err;
+-
+-      atarilance_dev.init = atarilance_probe;
+-      if ((err = register_netdev( &atarilance_dev ))) {
+-              if (err == -EIO)  {
+-                      printk( "No Atari Lance board found. Module not loaded.\n");
+-              }
+-              return( err );
+-      }
+-      return( 0 );
++{
++      atarilance_dev = atarilance_probe(-1);
++      if (IS_ERR(atarilance_dev))
++              return PTR_ERR(atarilance_dev);
++      return 0;
+ }
+ void cleanup_module(void)
+-
+ {
+-      unregister_netdev( &atarilance_dev );
++      unregister_netdev(atarilance_dev);
++      free_irq(atarilance_dev->irq, atarilance_dev);
++      free_netdev(atarilance_dev);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/atari_pamsnet.c    2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/net/atari_pamsnet.c     2003-12-28 23:21:00.000000000 -0800
+@@ -110,8 +110,6 @@ static char *version =
+ #undef READ
+ #undef WRITE
+-extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_private);
+-
+ /* use 0 for production, 1 for verification, >2 for debug
+  */
+ #ifndef NET_DEBUG
+@@ -158,8 +156,6 @@ static int send_1_5 (int lun, unsigned c
+ static int    get_status (void);
+ static int    calc_received (void *start_address);
+-extern int pamsnet_probe(struct net_device *dev);
+-
+ static int pamsnet_open(struct net_device *dev);
+ static int pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev);
+ static void pamsnet_poll_rx(struct net_device *);
+@@ -562,12 +558,12 @@ bad:
+ /* Check for a network adaptor of this type, and return '0' if one exists.
+  */
+-int __init 
+-pamsnet_probe (dev)
+-      struct net_device *dev;
++struct net_device * __init pamsnet_probe (int unit)
+ {
++      struct net_device *dev;
+       int i;
+       HADDR *hwaddr;
++      int err;
+       unsigned char station_addr[6];
+       static unsigned version_printed;
+@@ -575,12 +571,18 @@ pamsnet_probe (dev)
+       static int no_more_found;
+       if (no_more_found)
+-              return -ENODEV;
++              return ERR_PTR(-ENODEV);
++      no_more_found = 1;
++      dev = alloc_etherdev(sizeof(struct net_local));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
+       SET_MODULE_OWNER(dev);
+-      no_more_found = 1;
+-
+       printk("Probing for PAM's Net/GK Adapter...\n");
+       /* Allocate the DMA buffer here since we need it for probing! */
+@@ -618,11 +620,12 @@ pamsnet_probe (dev)
+       ENABLE_IRQ();
+       stdma_release();
+-      if (lance_target < 0)
++      if (lance_target < 0) {
+               printk("No PAM's Net/GK found.\n");
++              free_netdev(dev);
++              return ERR_PTR(-ENODEV);
++      }
+-      if ((dev == NULL) || (lance_target < 0))
+-              return -ENODEV;
+       if (pamsnet_debug > 0 && version_printed++ == 0)
+               printk(version);
+@@ -632,12 +635,6 @@ pamsnet_probe (dev)
+               station_addr[3], station_addr[4], station_addr[5]);
+       /* Initialize the device structure. */
+-      if (dev->priv == NULL)
+-              dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-      if (!dev->priv)
+-              return -ENOMEM;
+-      memset(dev->priv, 0, sizeof(struct net_local));
+-
+       dev->open               = pamsnet_open;
+       dev->stop               = pamsnet_close;
+       dev->hard_start_xmit    = pamsnet_send_packet;
+@@ -653,9 +650,12 @@ pamsnet_probe (dev)
+ #endif
+               dev->dev_addr[i]  = station_addr[i];
+       }
+-      ether_setup(dev);
++      err = register_netdev(dev);
++      if (!err)
++              return dev;
+-      return(0);
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /* Open/initialize the board.  This is called (in the current kernel)
+@@ -866,25 +866,20 @@ static struct net_device_stats *net_get_
+ #ifdef MODULE
+-static struct net_device pam_dev;
+-
+-int
+-init_module(void) {
+-      int err;
++static struct net_device *pam_dev;
+-      pam_dev.init = pamsnet_probe;
+-      if ((err = register_netdev(&pam_dev))) {
+-              if (err == -EEXIST)  {
+-                      printk("PAM's Net/GK: devices already present. Module not loaded.\n");
+-              }
+-              return err;
+-      }
++int init_module(void)
++{
++      pam_dev = pamsnet_probe(-1);
++      if (IS_ERR(pam_dev))
++              return PTR_ERR(pam_dev);
+       return 0;
+ }
+-void
+-cleanup_module(void) {
+-      unregister_netdev(&pam_dev);
++void cleanup_module(void)
++{
++      unregister_netdev(pam_dev);
++      free_netdev(pam_dev);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/atp.c      2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/atp.c       2003-12-28 23:21:00.000000000 -0800
+@@ -195,7 +195,7 @@ static void atp_timed_checker(unsigned l
+ /* Index to functions, as function prototypes. */
+-static int atp_probe1(struct net_device *dev, long ioaddr);
++static int atp_probe1(long ioaddr);
+ static void get_node_ID(struct net_device *dev);
+ static unsigned short eeprom_op(long ioaddr, unsigned int cmd);
+ static int net_open(struct net_device *dev);
+@@ -224,13 +224,13 @@ static struct net_device *root_atp_dev;
+    
+    FIXME: we should use the parport layer for this
+    */
+-static int __init atp_init(struct net_device *dev)
++static int __init atp_init(void)
+ {
+       int *port, ports[] = {0x378, 0x278, 0x3bc, 0};
+-      int base_addr = dev ? dev->base_addr : io[0];
++      int base_addr = io[0];
+       if (base_addr > 0x1ff)          /* Check a single specified location. */
+-              return atp_probe1(dev, base_addr);
++              return atp_probe1(base_addr);
+       else if (base_addr == 1)        /* Don't probe at all. */
+               return -ENXIO;
+@@ -239,17 +239,19 @@ static int __init atp_init(struct net_de
+               outb(0x57, ioaddr + PAR_DATA);
+               if (inb(ioaddr + PAR_DATA) != 0x57)
+                       continue;
+-              if (atp_probe1(dev, ioaddr) == 0)
++              if (atp_probe1(ioaddr) == 0)
+                       return 0;
+       }
+       return -ENODEV;
+ }
+-static int __init atp_probe1(struct net_device *dev, long ioaddr)
++static int __init atp_probe1(long ioaddr)
+ {
++      struct net_device *dev = NULL;
+       struct net_local *lp;
+       int saved_ctrl_reg, status, i;
++      int res;
+       outb(0xff, ioaddr + PAR_DATA);
+       /* Save the original value of the Control register, in case we guessed
+@@ -296,7 +298,7 @@ static int __init atp_probe1(struct net_
+               return -ENODEV;
+       }
+-      dev = init_etherdev(dev, sizeof(struct net_local));
++      dev = alloc_etherdev(sizeof(struct net_local));
+       if (!dev)
+               return -ENOMEM;
+       SET_MODULE_OWNER(dev);
+@@ -331,24 +333,13 @@ static int __init atp_probe1(struct net_
+                  dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+       /* Reset the ethernet hardware and activate the printer pass-through. */
+-    write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);
+-
+-      /* Initialize the device structure. */
+-      ether_setup(dev);
+-      if (dev->priv == NULL)
+-              dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-      if (dev->priv == NULL)
+-              return -ENOMEM;
+-      memset(dev->priv, 0, sizeof(struct net_local));
++      write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);
+       lp = (struct net_local *)dev->priv;
+       lp->chip_type = RTL8002;
+       lp->addr_mode = CMR2h_Normal;
+       spin_lock_init(&lp->lock);
+-      lp->next_module = root_atp_dev;
+-      root_atp_dev = dev;
+-
+       /* For the ATP adapter the "if_port" is really the data transfer mode. */
+       if (xcvr[0])
+               dev->if_port = xcvr[0];
+@@ -366,6 +357,15 @@ static int __init atp_probe1(struct net_
+       dev->tx_timeout         = tx_timeout;
+       dev->watchdog_timeo     = TX_TIMEOUT;
++      res = register_netdev(dev);
++      if (res) {
++              free_netdev(dev);
++              return res;
++      }
++
++      lp->next_module = root_atp_dev;
++      root_atp_dev = dev;
++
+       return 0;
+ }
+@@ -933,7 +933,7 @@ static void set_rx_mode_8012(struct net_
+ static int __init atp_init_module(void) {
+       if (debug)                                      /* Emit version even if no cards detected. */
+               printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+-      return atp_init(NULL);
++      return atp_init();
+ }
+ static void __exit atp_cleanup_module(void) {
+--- linux-2.6.0/drivers/net/au1000_eth.c       2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/au1000_eth.c        2003-12-28 23:21:00.000000000 -0800
+@@ -56,7 +56,7 @@ static void *dma_alloc(size_t, dma_addr_
+ static void dma_free(void *, size_t);
+ static void hard_stop(struct net_device *);
+ static void enable_rx_tx(struct net_device *dev);
+-static int __init au1000_probe1(struct net_device *, long, int, int);
++static int __init au1000_probe1(long, int, int);
+ static int au1000_init(struct net_device *);
+ static int au1000_open(struct net_device *);
+ static int au1000_close(struct net_device *);
+@@ -644,17 +644,17 @@ static int __init au1000_init_module(voi
+               }
+               // check for valid entries, au1100 only has one entry
+               if (base_addr && irq) {
+-                      if (au1000_probe1(NULL, base_addr, irq, i) != 0) {
++                      if (au1000_probe1(base_addr, irq, i) != 0)
+                               return -ENODEV;
+-                      }
+               }
+       }
+       return 0;
+ }
+ static int __init
+-au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num)
++au1000_probe1(long ioaddr, int irq, int port_num)
+ {
++      struct net_device *dev;
+       static unsigned version_printed = 0;
+       struct au1000_private *aup = NULL;
+       int i, retval = 0;
+@@ -668,15 +668,16 @@ au1000_probe1(struct net_device *dev, lo
+       if (version_printed++ == 0)
+               printk(version);
+-      if (!dev)
+-              dev = init_etherdev(NULL, sizeof(struct au1000_private));
++      retval = -ENOMEM;
++      dev = alloc_etherdev(sizeof(struct au1000_private));
+       if (!dev) {
+-              printk (KERN_ERR "au1000 eth: init_etherdev failed\n");  
+-              release_region(ioaddr, MAC_IOSIZE);
+-              return -ENODEV;
++              printk (KERN_ERR "au1000 eth: alloc_etherdev failed\n");  
++              goto out;
+       }
++      SET_MODULE_OWNER(dev);
++
+       printk("%s: Au1xxx ethernet found at 0x%lx, irq %d\n", 
+              dev->name, ioaddr, irq);
+@@ -685,10 +686,8 @@ au1000_probe1(struct net_device *dev, lo
+       /* Allocate the data buffers */
+       aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * 
+                       (NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr);
+-      if (!aup->vaddr) {
+-              retval = -ENOMEM;
+-              goto free_region;
+-      }
++      if (!aup->vaddr)
++              goto out1;
+       /* aup->mac is the base address of the MAC's registers */
+       aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr);
+@@ -749,10 +748,11 @@ au1000_probe1(struct net_device *dev, lo
+               MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
+       au_sync_delay(2);
+-      if (mii_probe(dev) != 0) {
+-               goto free_region;
+-      }
++      retval = mii_probe(dev);
++      if (retval)
++               goto out2;
++      retval = -EINVAL;
+       pDBfree = NULL;
+       /* setup the data buffer descriptors and attach a buffer to each one */
+       pDB = aup->db;
+@@ -767,13 +767,13 @@ au1000_probe1(struct net_device *dev, lo
+       for (i=0; i<NUM_RX_DMA; i++) {
+               pDB = GetFreeDB(aup);
+-              if (!pDB) goto free_region;
++              if (!pDB) goto out2;
+               aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+               aup->rx_db_inuse[i] = pDB;
+       }
+       for (i=0; i<NUM_TX_DMA; i++) {
+               pDB = GetFreeDB(aup);
+-              if (!pDB) goto free_region;
++              if (!pDB) goto out2;
+               aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+               aup->tx_dma_ring[i]->len = 0;
+               aup->tx_db_inuse[i] = pDB;
+@@ -792,26 +792,25 @@ au1000_probe1(struct net_device *dev, lo
+       dev->tx_timeout = au1000_tx_timeout;
+       dev->watchdog_timeo = ETH_TX_TIMEOUT;
+-
+-      /* Fill in the fields of the device structure with ethernet values. */
+-      ether_setup(dev);
+-
+       /* 
+        * The boot code uses the ethernet controller, so reset it to start 
+        * fresh.  au1000_init() expects that the device is in reset state.
+        */
+       reset_mac(dev);
++
++      retval = register_netdev(dev);
++      if (retval)
++              goto out2;
+       return 0;
+-free_region:
++out2:
++      dma_free(aup->vaddr, MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS));
++out1:
++      free_netdev(dev);
++out:
+       release_region(PHYSADDR(ioaddr), MAC_IOSIZE);
+-      unregister_netdev(dev);
+-      if (aup->vaddr) 
+-              dma_free((void *)aup->vaddr, 
+-                              MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS));
+       printk(KERN_ERR "%s: au1000_probe1 failed.  Returns %d\n",
+              dev->name, retval);
+-      free_netdev(dev);
+       return retval;
+ }
+@@ -933,15 +932,12 @@ static int au1000_open(struct net_device
+       int retval;
+       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+-      MOD_INC_USE_COUNT;
+-
+       if (au1000_debug > 4)
+               printk("%s: open: dev=%p\n", dev->name, dev);
+       if ((retval = au1000_init(dev))) {
+               printk(KERN_ERR "%s: error in au1000_init\n", dev->name);
+               free_irq(dev->irq, dev);
+-              MOD_DEC_USE_COUNT;
+               return retval;
+       }
+       netif_start_queue(dev);
+@@ -950,7 +946,6 @@ static int au1000_open(struct net_device
+                                       dev->name, dev))) {
+               printk(KERN_ERR "%s: unable to get IRQ %d\n", 
+                               dev->name, dev->irq);
+-              MOD_DEC_USE_COUNT;
+               return retval;
+       }
+@@ -984,8 +979,6 @@ static int au1000_close(struct net_devic
+       spin_unlock_irqrestore(&aup->lock, flags);
+       reset_mac(dev);
+-      kfree(dev);
+-      MOD_DEC_USE_COUNT;
+       return 0;
+ }
+--- linux-2.6.0/drivers/net/bagetlance.c       2003-06-14 12:17:56.000000000 -0700
++++ 25/drivers/net/bagetlance.c        2003-12-28 23:21:00.000000000 -0800
+@@ -465,30 +465,43 @@ void *slow_memcpy( void *dst, const void
+ }
+-int __init bagetlance_probe( struct net_device *dev )
+-
+-{     int i;
++struct net_device * __init bagetlance_probe(int unit)
++{
++      struct net_device *dev;
++      int i;
+       static int found;
+-
+-      SET_MODULE_OWNER(dev);
++      int err = -ENODEV;
+       if (found)
+               /* Assume there's only one board possible... That seems true, since
+                * the Riebl/PAM board's address cannot be changed. */
+-              return( -ENODEV );
++              return ERR_PTR(-ENODEV);
++
++      dev = alloc_etherdev(sizeof(struct lance_private));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      SET_MODULE_OWNER(dev);
+       for( i = 0; i < N_LANCE_ADDR; ++i ) {
+               if (lance_probe1( dev, &lance_addr_list[i] )) {
+                       found = 1;
+-                      return( 0 );
++                      break;
+               }
+       }
+-
+-      return( -ENODEV );
++      if (!found)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      free_irq(dev->irq, dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+-
+-
+ /* Derived from hwreg_present() in vme/config.c: */
+ static int __init addr_accessible( volatile void *regp, 
+@@ -527,6 +540,7 @@ static int __init lance_probe1( struct n
+       if (!addr_accessible( memaddr, 1, 1 )) goto probe_fail;
+       if ((unsigned long)memaddr >= KSEG2) {
++                      /* FIXME: do we need to undo that on cleanup paths? */
+                       extern int kseg2_alloc_io (unsigned long addr, unsigned long size);
+                       if (kseg2_alloc_io((unsigned long)memaddr, BAGET_LANCE_MEM_SIZE)) {
+                                       printk("bagetlance: unable map lance memory\n");
+@@ -580,12 +594,6 @@ static int __init lance_probe1( struct n
+       return( 0 );
+   probe_ok:
+-      init_etherdev( dev, sizeof(struct lance_private) );
+-      if (!dev->priv) {
+-              dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
+-              if (!dev->priv)
+-                      return 0;
+-      }
+       lp = (struct lance_private *)dev->priv;
+       MEM = (struct lance_memory *)memaddr;
+       IO = lp->iobase = (struct lance_ioreg *)ioaddr;
+@@ -617,8 +625,9 @@ static int __init lance_probe1( struct n
+       if (lp->cardtype == PAM_CARD ||
+               memaddr == (unsigned short *)0xffe00000) {
+               /* PAMs card and Riebl on ST use level 5 autovector */
+-              request_irq(BAGET_LANCE_IRQ, lance_interrupt, IRQ_TYPE_PRIO,
+-                          "PAM/Riebl-ST Ethernet", dev);
++              if (request_irq(BAGET_LANCE_IRQ, lance_interrupt, IRQ_TYPE_PRIO,
++                          "PAM/Riebl-ST Ethernet", dev))
++                      goto probe_fail;
+               dev->irq = (unsigned short)BAGET_LANCE_IRQ;
+       }
+       else {
+@@ -629,10 +638,11 @@ static int __init lance_probe1( struct n
+               unsigned long irq = BAGET_LANCE_IRQ; 
+               if (!irq) {
+                       printk( "Lance: request for VME interrupt failed\n" );
+-                      return( 0 );
++                      goto probe_fail;
+               }
+-              request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
+-                          "Riebl-VME Ethernet", dev);
++              if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
++                          "Riebl-VME Ethernet", dev))
++                      goto probe_fail;
+               dev->irq = irq;
+       }
+@@ -1331,26 +1341,21 @@ static int lance_set_mac_address( struct
+ #ifdef MODULE
+-static struct net_device bagetlance_dev;
++static struct net_device *bagetlance_dev;
+ int init_module(void)
+-
+-{     int err;
+-
+-      bagetlance_dev.init = bagetlance_probe;
+-      if ((err = register_netdev( &bagetlance_dev ))) {
+-              if (err == -EIO)  {
+-                      printk( "No Vme Lance board found. Module not loaded.\n");
+-              }
+-              return( err );
+-      }
+-      return( 0 );
++{
++      bagetlance_dev = bagetlance_probe(-1);
++      if (IS_ERR(bagetlance_dev))
++              return PTR_ERR(bagetlance_dev);
++      return 0;
+ }
+ void cleanup_module(void)
+-
+ {
+-      unregister_netdev( &bagetlance_dev );
++      unregister_netdev(bagetlance_dev);
++      free_irq(bagetlance_dev->irq, bagetlance_dev);
++      free_netdev(bagetlance_dev);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/bonding/bond_3ad.c 2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/bonding/bond_3ad.c  2003-12-28 23:21:00.000000000 -0800
+@@ -47,8 +47,13 @@
+  *    - Send LACPDU as highest priority packet to further fix the above
+  *      problem on very high Tx traffic load where packets may get dropped
+  *      by the slave.
++ *
++ * 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
++ *    - Code cleanup and style changes
+  */
++//#define BONDING_DEBUG 1
++
+ #include <linux/skbuff.h>
+ #include <linux/if_ether.h>
+ #include <linux/netdevice.h>
+@@ -119,6 +124,7 @@
+ static struct mac_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}};
+ static u16 ad_ticks_per_sec;
++static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
+ // ================= 3AD api to bonding and kernel code ==================
+ static u16 __get_link_speed(struct port *port);
+@@ -196,13 +202,11 @@ static inline struct bonding *__get_bond
+  */
+ static inline struct port *__get_first_port(struct bonding *bond)
+ {
+-      struct slave *slave = bond->next;
+-
+-      if (slave == (struct slave *)bond) {
++      if (bond->slave_cnt == 0) {
+               return NULL;
+       }
+-      return &(SLAVE_AD_INFO(slave).port);
++      return &(SLAVE_AD_INFO(bond->first_slave).port);
+ }
+ /**
+@@ -218,7 +222,7 @@ static inline struct port *__get_next_po
+       struct slave *slave = port->slave;
+       // If there's no bond for this port, or this is the last slave
+-      if ((bond == NULL) || (slave->next == bond->next)) {
++      if ((bond == NULL) || (slave->next == bond->first_slave)) {
+               return NULL;
+       }
+@@ -236,12 +240,12 @@ static inline struct aggregator *__get_f
+ {
+       struct bonding *bond = __get_bond_by_port(port);
+-      // If there's no bond for this port, or this is the last slave
+-      if ((bond == NULL) || (bond->next == (struct slave *)bond)) {
++      // If there's no bond for this port, or bond has no slaves
++      if ((bond == NULL) || (bond->slave_cnt == 0)) {
+               return NULL;
+       }
+-      return &(SLAVE_AD_INFO(bond->next).aggregator);
++      return &(SLAVE_AD_INFO(bond->first_slave).aggregator);
+ }
+ /**
+@@ -257,7 +261,7 @@ static inline struct aggregator *__get_n
+       struct bonding *bond = bond_get_bond_by_slave(slave);
+       // If there's no bond for this aggregator, or this is the last slave
+-      if ((bond == NULL) || (slave->next == bond->next)) {
++      if ((bond == NULL) || (slave->next == bond->first_slave)) {
+               return NULL;
+       }
+@@ -392,7 +396,7 @@ static u16 __get_link_speed(struct port 
+               }
+       }
+-      BOND_PRINT_DBG(("Port %d Received link speed %d update from adapter", port->actor_port_number, speed));
++      dprintk("Port %d Received link speed %d update from adapter\n", port->actor_port_number, speed);
+       return speed;
+ }
+@@ -418,12 +422,12 @@ static u8 __get_duplex(struct port *port
+               switch (slave->duplex) {
+               case DUPLEX_FULL:
+                       retval=0x1;
+-                      BOND_PRINT_DBG(("Port %d Received status full duplex update from adapter", port->actor_port_number));
++                      dprintk("Port %d Received status full duplex update from adapter\n", port->actor_port_number);
+                       break;
+               case DUPLEX_HALF:
+               default:
+                       retval=0x0;
+-                      BOND_PRINT_DBG(("Port %d Received status NOT full duplex update from adapter", port->actor_port_number));
++                      dprintk("Port %d Received status NOT full duplex update from adapter\n", port->actor_port_number);
+                       break;
+               }
+       }
+@@ -1059,7 +1063,7 @@ static void ad_mux_machine(struct port *
+       // check if the state machine was changed
+       if (port->sm_mux_state != last_state) {
+-              BOND_PRINT_DBG(("Mux Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_mux_state));
++              dprintk("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_mux_state);
+               switch (port->sm_mux_state) {
+               case AD_MUX_DETACHED:
+                       __detach_bond_from_agg(port);
+@@ -1158,7 +1162,7 @@ static void ad_rx_machine(struct lacpdu 
+       // check if the State machine was changed or new lacpdu arrived
+       if ((port->sm_rx_state != last_state) || (lacpdu)) {
+-              BOND_PRINT_DBG(("Rx Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_rx_state));
++              dprintk("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_rx_state);
+               switch (port->sm_rx_state) {
+               case AD_RX_INITIALIZE:
+                       if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) {
+@@ -1204,7 +1208,7 @@ static void ad_rx_machine(struct lacpdu 
+                       // detect loopback situation
+                       if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
+                               // INFO_RECEIVED_LOOPBACK_FRAMES
+-                              printk(KERN_ERR "bonding: An illegal loopback occurred on adapter (%s)\n",
++                              printk(KERN_ERR DRV_NAME ": An illegal loopback occurred on adapter (%s)\n",
+                                               port->slave->dev->name);
+                               printk(KERN_ERR "Check the configuration to verify that all Adapters "
+                                               "are connected to 802.3ad compliant switch ports\n");
+@@ -1245,7 +1249,7 @@ static void ad_tx_machine(struct port *p
+                       __update_lacpdu_from_port(port);
+                       // send the lacpdu
+                       if (ad_lacpdu_send(port) >= 0) {
+-                              BOND_PRINT_DBG(("Sent LACPDU on port %d", port->actor_port_number));
++                              dprintk("Sent LACPDU on port %d\n", port->actor_port_number);
+                               // mark ntt as false, so it will not be sent again until demanded
+                               port->ntt = 0;
+                       }
+@@ -1318,7 +1322,7 @@ static void ad_periodic_machine(struct p
+       // check if the state machine was changed
+       if (port->sm_periodic_state != last_state) {
+-              BOND_PRINT_DBG(("Periodic Machine: Port=%d, Last State=%d, Curr State=%d", port->actor_port_number, last_state, port->sm_periodic_state));
++              dprintk("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_periodic_state);
+               switch (port->sm_periodic_state) {
+               case AD_NO_PERIODIC:
+                       port->sm_periodic_timer_counter = 0;       // zero timer
+@@ -1375,7 +1379,7 @@ static void ad_port_selection_logic(stru
+                               port->next_port_in_aggregator=NULL;
+                               port->actor_port_aggregator_identifier=0;
+-                              BOND_PRINT_DBG(("Port %d left LAG %d", port->actor_port_number, temp_aggregator->aggregator_identifier));
++                              dprintk("Port %d left LAG %d\n", port->actor_port_number, temp_aggregator->aggregator_identifier);
+                               // if the aggregator is empty, clear its parameters, and set it ready to be attached
+                               if (!temp_aggregator->lag_ports) {
+                                       ad_clear_agg(temp_aggregator);
+@@ -1384,7 +1388,7 @@ static void ad_port_selection_logic(stru
+                       }
+               }
+               if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
+-                      printk(KERN_WARNING "bonding: Warning: Port %d (on %s) was "
++                      printk(KERN_WARNING DRV_NAME ": Warning: Port %d (on %s) was "
+                              "related to aggregator %d but was not on its port list\n",
+                              port->actor_port_number, port->slave->dev->name,
+                              port->aggregator->aggregator_identifier);
+@@ -1417,7 +1421,7 @@ static void ad_port_selection_logic(stru
+                       port->next_port_in_aggregator=aggregator->lag_ports;
+                       port->aggregator->num_of_ports++;
+                       aggregator->lag_ports=port;
+-                      BOND_PRINT_DBG(("Port %d joined LAG %d(existing LAG)", port->actor_port_number, port->aggregator->aggregator_identifier));
++                      dprintk("Port %d joined LAG %d(existing LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+                       // mark this port as selected
+                       port->sm_vars |= AD_PORT_SELECTED;
+@@ -1454,9 +1458,9 @@ static void ad_port_selection_logic(stru
+                       // mark this port as selected
+                       port->sm_vars |= AD_PORT_SELECTED;
+-                      BOND_PRINT_DBG(("Port %d joined LAG %d(new LAG)", port->actor_port_number, port->aggregator->aggregator_identifier));
++                      dprintk("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+               } else {
+-                      printk(KERN_ERR "bonding: Port %d (on %s) did not find a suitable aggregator\n",
++                      printk(KERN_ERR DRV_NAME ": Port %d (on %s) did not find a suitable aggregator\n",
+                              port->actor_port_number, port->slave->dev->name);
+               }
+       }
+@@ -1580,30 +1584,30 @@ static void ad_agg_selection_logic(struc
+                   aggregator;
+                   aggregator = __get_next_agg(aggregator)) {
+-                      BOND_PRINT_DBG(("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d",
++                      dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
+                                       aggregator->aggregator_identifier, aggregator->num_of_ports,
+                                       aggregator->actor_oper_aggregator_key, aggregator->partner_oper_aggregator_key,
+-                                      aggregator->is_individual, aggregator->is_active));
++                                      aggregator->is_individual, aggregator->is_active);
+               }
+               // check if any partner replys
+               if (best_aggregator->is_individual) {
+-                      printk(KERN_WARNING "bonding: Warning: No 802.3ad response from the link partner "
++                      printk(KERN_WARNING DRV_NAME ": Warning: No 802.3ad response from the link partner "
+                                       "for any adapters in the bond\n");
+               }
+               // check if there are more than one aggregator
+               if (num_of_aggs > 1) {
+-                      BOND_PRINT_DBG(("Warning: More than one Link Aggregation Group was "
+-                                      "found in the bond. Only one group will function in the bond"));
++                      dprintk("Warning: More than one Link Aggregation Group was "
++                              "found in the bond. Only one group will function in the bond\n");
+               }
+               best_aggregator->is_active = 1;
+-              BOND_PRINT_DBG(("LAG %d choosed as the active LAG", best_aggregator->aggregator_identifier));
+-              BOND_PRINT_DBG(("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d",
++              dprintk("LAG %d choosed as the active LAG\n", best_aggregator->aggregator_identifier);
++              dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
+                               best_aggregator->aggregator_identifier, best_aggregator->num_of_ports,
+                               best_aggregator->actor_oper_aggregator_key, best_aggregator->partner_oper_aggregator_key,
+-                              best_aggregator->is_individual, best_aggregator->is_active));
++                              best_aggregator->is_individual, best_aggregator->is_active);
+               // disable the ports that were related to the former active_aggregator
+               if (last_active_aggregator) {
+@@ -1644,7 +1648,7 @@ static void ad_clear_agg(struct aggregat
+               aggregator->lag_ports = NULL;
+               aggregator->is_active = 0;
+               aggregator->num_of_ports = 0;
+-              BOND_PRINT_DBG(("LAG %d was cleared", aggregator->aggregator_identifier));
++              dprintk("LAG %d was cleared\n", aggregator->aggregator_identifier);
+       }
+ }
+@@ -1729,7 +1733,7 @@ static void ad_initialize_port(struct po
+ static void ad_enable_collecting_distributing(struct port *port)
+ {
+       if (port->aggregator->is_active) {
+-              BOND_PRINT_DBG(("Enabling port %d(LAG %d)", port->actor_port_number, port->aggregator->aggregator_identifier));
++              dprintk("Enabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+               __enable_port(port);
+       }
+ }
+@@ -1742,7 +1746,7 @@ static void ad_enable_collecting_distrib
+ static void ad_disable_collecting_distributing(struct port *port)
+ {
+       if (port->aggregator && MAC_ADDRESS_COMPARE(&(port->aggregator->partner_system), &(null_mac_addr))) {
+-              BOND_PRINT_DBG(("Disabling port %d(LAG %d)", port->actor_port_number, port->aggregator->aggregator_identifier));
++              dprintk("Disabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+               __disable_port(port);
+       }
+ }
+@@ -1780,7 +1784,7 @@ static void ad_marker_info_send(struct p
+       // send the marker information
+       if (ad_marker_send(port, &marker) >= 0) {
+-              BOND_PRINT_DBG(("Sent Marker Information on port %d", port->actor_port_number));
++              dprintk("Sent Marker Information on port %d\n", port->actor_port_number);
+       }
+ }
+ #endif
+@@ -1803,7 +1807,7 @@ static void ad_marker_info_received(stru
+       // send the marker response
+       if (ad_marker_send(port, &marker) >= 0) {
+-              BOND_PRINT_DBG(("Sent Marker Response on port %d", port->actor_port_number));
++              dprintk("Sent Marker Response on port %d\n", port->actor_port_number);
+       }
+ }
+@@ -1890,13 +1894,13 @@ static u16 aggregator_identifier;
+ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast)
+ {                         
+       // check that the bond is not initialized yet
+-      if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->device->dev_addr))) {
++      if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->dev->dev_addr))) {
+               aggregator_identifier = 0;
+               BOND_AD_INFO(bond).lacp_fast = lacp_fast;
+               BOND_AD_INFO(bond).system.sys_priority = 0xFFFF;
+-              BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->device->dev_addr);
++              BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
+               // initialize how many times this module is called in one second(should be about every 100ms)
+               ad_ticks_per_sec = tick_resolution;
+@@ -1921,7 +1925,7 @@ int bond_3ad_bind_slave(struct slave *sl
+       struct aggregator *aggregator;
+       if (bond == NULL) {
+-              printk(KERN_CRIT "The slave %s is not attached to its bond\n", slave->dev->name);
++              printk(KERN_ERR "The slave %s is not attached to its bond\n", slave->dev->name);
+               return -1;
+       }
+@@ -1964,7 +1968,7 @@ int bond_3ad_bind_slave(struct slave *sl
+               ad_initialize_agg(aggregator);
+-              aggregator->aggregator_mac_address = *((struct mac_addr *)bond->device->dev_addr);
++              aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr);
+               aggregator->aggregator_identifier = (++aggregator_identifier);
+               aggregator->slave = slave;
+               aggregator->is_active = 0;
+@@ -1996,11 +2000,11 @@ void bond_3ad_unbind_slave(struct slave 
+       // if slave is null, the whole port is not initialized
+       if (!port->slave) {
+-              printk(KERN_WARNING "bonding: Trying to unbind an uninitialized port on %s\n", slave->dev->name);
++              printk(KERN_WARNING DRV_NAME ": Trying to unbind an uninitialized port on %s\n", slave->dev->name);
+               return;
+       }
+-      BOND_PRINT_DBG(("Unbinding Link Aggregation Group %d", aggregator->aggregator_identifier));
++      dprintk("Unbinding Link Aggregation Group %d\n", aggregator->aggregator_identifier);
+       /* Tell the partner that this port is not suitable for aggregation */
+       port->actor_oper_port_state &= ~AD_STATE_AGGREGATION;
+@@ -2024,10 +2028,10 @@ void bond_3ad_unbind_slave(struct slave 
+                       // if new aggregator found, copy the aggregator's parameters
+                       // and connect the related lag_ports to the new aggregator
+                       if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) {
+-                              BOND_PRINT_DBG(("Some port(s) related to LAG %d - replaceing with LAG %d", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier));
++                              dprintk("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier);
+                               if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
+-                                      printk(KERN_INFO "bonding: Removing an active aggregator\n");
++                                      printk(KERN_INFO DRV_NAME ": Removing an active aggregator\n");
+                                       // select new active aggregator
+                                        select_new_active_agg = 1;
+                               }
+@@ -2057,7 +2061,7 @@ void bond_3ad_unbind_slave(struct slave 
+                                       ad_agg_selection_logic(__get_first_agg(port));
+                               }
+                       } else {
+-                              printk(KERN_WARNING "bonding: Warning: unbinding aggregator, "
++                              printk(KERN_WARNING DRV_NAME ": Warning: unbinding aggregator, "
+                                      "and could not find a new aggregator for its ports\n");
+                       }
+               } else { // in case that the only port related to this aggregator is the one we want to remove
+@@ -2072,7 +2076,7 @@ void bond_3ad_unbind_slave(struct slave 
+               }
+       }
+-      BOND_PRINT_DBG(("Unbinding port %d", port->actor_port_number));
++      dprintk("Unbinding port %d\n", port->actor_port_number);
+       // find the aggregator that this port is connected to
+       temp_aggregator = __get_first_agg(port);
+       for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) {
+@@ -2123,13 +2127,13 @@ void bond_3ad_state_machine_handler(stru
+       read_lock(&bond->lock);
+-      //check if there are any slaves
+-      if (bond->next == (struct slave *)bond) {
+-              goto end;
++      if (bond->kill_timers) {
++              goto out;
+       }
+-      if ((bond->device->flags & IFF_UP) != IFF_UP) {
+-              goto end;
++      //check if there are any slaves
++      if (bond->slave_cnt == 0) {
++              goto re_arm;
+       }
+       // check if agg_select_timer timer after initialize is timed out
+@@ -2137,8 +2141,8 @@ void bond_3ad_state_machine_handler(stru
+               // select the active aggregator for the bond
+               if ((port = __get_first_port(bond))) {
+                       if (!port->slave) {
+-                              printk(KERN_WARNING "bonding: Warning: bond's first port is uninitialized\n");
+-                              goto end;
++                              printk(KERN_WARNING DRV_NAME ": Warning: bond's first port is uninitialized\n");
++                              goto re_arm;
+                       }
+                       aggregator = __get_first_agg(port);
+@@ -2149,8 +2153,8 @@ void bond_3ad_state_machine_handler(stru
+       // for each port run the state machines
+       for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
+               if (!port->slave) {
+-                      printk(KERN_WARNING "bonding: Warning: Found an uninitialized port\n");
+-                      goto end;
++                      printk(KERN_WARNING DRV_NAME ": Warning: Found an uninitialized port\n");
++                      goto re_arm;
+               }
+               ad_rx_machine(NULL, port);
+@@ -2165,14 +2169,10 @@ void bond_3ad_state_machine_handler(stru
+               }
+       }
+-end:
++re_arm:
++      mod_timer(&(BOND_AD_INFO(bond).ad_timer), jiffies + ad_delta_in_ticks);
++out:
+       read_unlock(&bond->lock);
+-
+-
+-      if ((bond->device->flags & IFF_UP) == IFF_UP) {
+-              /* re-arm the timer */
+-              mod_timer(&(BOND_AD_INFO(bond).ad_timer), jiffies + (AD_TIMER_INTERVAL * HZ / 1000));
+-      }
+ }
+ /**
+@@ -2194,14 +2194,14 @@ void bond_3ad_rx_indication(struct lacpd
+               port = &(SLAVE_AD_INFO(slave).port);
+               if (!port->slave) {
+-                      printk(KERN_WARNING "bonding: Warning: port of slave %s is uninitialized\n", slave->dev->name);
++                      printk(KERN_WARNING DRV_NAME ": Warning: port of slave %s is uninitialized\n", slave->dev->name);
+                       return;
+               }
+               switch (lacpdu->subtype) {
+               case AD_TYPE_LACPDU:
+                       __ntohs_lacpdu(lacpdu);
+-                      BOND_PRINT_DBG(("Received LACPDU on port %d", port->actor_port_number));
++                      dprintk("Received LACPDU on port %d\n", port->actor_port_number);
+                       ad_rx_machine(lacpdu, port);
+                       break;
+@@ -2210,17 +2210,17 @@ void bond_3ad_rx_indication(struct lacpd
+                       switch (((struct marker *)lacpdu)->tlv_type) {
+                       case AD_MARKER_INFORMATION_SUBTYPE:
+-                              BOND_PRINT_DBG(("Received Marker Information on port %d", port->actor_port_number));
++                              dprintk("Received Marker Information on port %d\n", port->actor_port_number);
+                               ad_marker_info_received((struct marker *)lacpdu, port);
+                               break;
+                       case AD_MARKER_RESPONSE_SUBTYPE:
+-                              BOND_PRINT_DBG(("Received Marker Response on port %d", port->actor_port_number));
++                              dprintk("Received Marker Response on port %d\n", port->actor_port_number);
+                               ad_marker_response_received((struct marker *)lacpdu, port);
+                               break;
+                       default:
+-                              BOND_PRINT_DBG(("Received an unknown Marker subtype on slot %d", port->actor_port_number));
++                              dprintk("Received an unknown Marker subtype on slot %d\n", port->actor_port_number);
+                       }
+               }
+       }
+@@ -2240,14 +2240,14 @@ void bond_3ad_adapter_speed_changed(stru
+       // if slave is null, the whole port is not initialized
+       if (!port->slave) {
+-              printk(KERN_WARNING "bonding: Warning: speed changed for uninitialized port on %s\n",
++              printk(KERN_WARNING DRV_NAME ": Warning: speed changed for uninitialized port on %s\n",
+                      slave->dev->name);
+               return;
+       }
+       port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
+       port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1);
+-      BOND_PRINT_DBG(("Port %d changed speed", port->actor_port_number));
++      dprintk("Port %d changed speed\n", port->actor_port_number);
+       // there is no need to reselect a new aggregator, just signal the
+       // state machines to reinitialize
+       port->sm_vars |= AD_PORT_BEGIN;
+@@ -2267,14 +2267,14 @@ void bond_3ad_adapter_duplex_changed(str
+       // if slave is null, the whole port is not initialized
+       if (!port->slave) {
+-              printk(KERN_WARNING "bonding: Warning: duplex changed for uninitialized port on %s\n",
++              printk(KERN_WARNING DRV_NAME ": Warning: duplex changed for uninitialized port on %s\n",
+                      slave->dev->name);
+               return;
+       }
+       port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
+       port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port);
+-      BOND_PRINT_DBG(("Port %d changed duplex", port->actor_port_number));
++      dprintk("Port %d changed duplex\n", port->actor_port_number);
+       // there is no need to reselect a new aggregator, just signal the
+       // state machines to reinitialize
+       port->sm_vars |= AD_PORT_BEGIN;
+@@ -2295,10 +2295,8 @@ void bond_3ad_handle_link_change(struct 
+       // if slave is null, the whole port is not initialized
+       if (!port->slave) {
+-#ifdef BONDING_DEBUG
+-              printk(KERN_WARNING "bonding: Warning: link status changed for uninitialized port on %s\n",
+-                     slave->dev->name);
+-#endif
++              printk(KERN_WARNING DRV_NAME ": Warning: link status changed for uninitialized port on %s\n",
++                      slave->dev->name);
+               return;
+       }
+@@ -2356,41 +2354,27 @@ int bond_3ad_get_active_agg_info(struct 
+ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
+ {
+-      slave_t *slave, *start_at;
+-      struct bonding *bond = (struct bonding *) dev->priv;
++      struct slave *slave, *start_at;
++      struct bonding *bond = dev->priv;
+       struct ethhdr *data = (struct ethhdr *)skb->data;
+       int slave_agg_no;
+       int slaves_in_agg;
+       int agg_id;
++      int i;
+       struct ad_info ad_info;
+-      if (!IS_UP(dev)) { /* bond down */
+-              dev_kfree_skb(skb);
+-              return 0;
+-      }
+-
+-      if (bond == NULL) {
+-              printk(KERN_CRIT "bonding: Error: bond is NULL on device %s\n", dev->name);
+-              dev_kfree_skb(skb);
+-              return 0;
+-      }
+-
++      /* make sure that the slaves list will
++       * not change during tx
++       */
+       read_lock(&bond->lock);
+-      slave = bond->prev;
+-      /* check if bond is empty */
+-      if ((slave == (struct slave *) bond) || (bond->slave_cnt == 0)) {
+-              printk(KERN_DEBUG "ERROR: bond is empty\n");
+-              dev_kfree_skb(skb);
+-              read_unlock(&bond->lock);
+-              return 0;
++      if (!BOND_IS_OK(bond)) {
++              goto free_out;
+       }
+       if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
+               printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n");
+-              dev_kfree_skb(skb);
+-              read_unlock(&bond->lock);
+-              return 0;
++              goto free_out;
+       }
+       slaves_in_agg = ad_info.ports;
+@@ -2399,21 +2383,12 @@ int bond_3ad_xmit_xor(struct sk_buff *sk
+       if (slaves_in_agg == 0) {
+               /*the aggregator is empty*/
+               printk(KERN_DEBUG "ERROR: active aggregator is empty\n");
+-              dev_kfree_skb(skb);
+-              read_unlock(&bond->lock);
+-              return 0;
++              goto free_out;
+       }
+-      /* we're at the root, get the first slave */
+-      if ((slave == NULL) || (slave->dev == NULL)) {
+-              /* no suitable interface, frame not sent */
+-              dev_kfree_skb(skb);
+-              read_unlock(&bond->lock);
+-              return 0;
+-      }
++      slave_agg_no = (data->h_dest[5]^bond->dev->dev_addr[5]) % slaves_in_agg;
+-      slave_agg_no = (data->h_dest[5]^slave->dev->dev_addr[5]) % slaves_in_agg;
+-      while (slave != (slave_t *)bond) {
++      bond_for_each_slave(bond, slave, i) {
+               struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
+               if (agg && (agg->aggregator_identifier == agg_id)) {
+@@ -2422,37 +2397,18 @@ int bond_3ad_xmit_xor(struct sk_buff *sk
+                               break;
+                       }
+               }
+-
+-              slave = slave->prev;
+-              if (slave == NULL) {
+-                      printk(KERN_ERR "bonding: Error: slave is NULL\n");
+-                      dev_kfree_skb(skb);
+-                      read_unlock(&bond->lock);
+-                      return 0;
+-              }
+       }
+-      if (slave == (slave_t *)bond) {
+-              printk(KERN_ERR "bonding: Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
+-              dev_kfree_skb(skb);
+-              read_unlock(&bond->lock);
+-              return 0;
++      if (slave_agg_no >= 0) {
++              printk(KERN_ERR DRV_NAME ": Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
++              goto free_out;
+       }
+       start_at = slave;
+-      do {
++      bond_for_each_slave_from(bond, slave, i, start_at) {
+               int slave_agg_id = 0;
+-              struct aggregator *agg;
+-
+-              if (slave == NULL) {
+-                      printk(KERN_ERR "bonding: Error: slave is NULL\n");
+-                      dev_kfree_skb(skb);
+-                      read_unlock(&bond->lock);
+-                      return 0;
+-              }
+-
+-              agg = SLAVE_AD_INFO(slave).port.aggregator;
++              struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
+               if (agg) {
+                       slave_agg_id = agg->aggregator_identifier;
+@@ -2463,20 +2419,24 @@ int bond_3ad_xmit_xor(struct sk_buff *sk
+                       skb->dev = slave->dev;                  
+                       skb->priority = 1;
+                       dev_queue_xmit(skb);
+-                      read_unlock(&bond->lock);
+-                      return 0;
++
++                      goto out;
+               }
+-      } while ((slave = slave->next) != start_at);
++      }
+-      /* no suitable interface, frame not sent */
+-      dev_kfree_skb(skb);
++out:
+       read_unlock(&bond->lock);
+       return 0;
++
++free_out:
++      /* no suitable interface, frame not sent */
++      dev_kfree_skb(skb);
++      goto out;
+ }
+ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype)
+ {
+-      struct bonding *bond = (struct bonding *)dev->priv;
++      struct bonding *bond = dev->priv;
+       struct slave *slave = NULL;
+       int ret = NET_RX_DROP;
+--- linux-2.6.0/drivers/net/bonding/bond_3ad.h 2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/bonding/bond_3ad.h  2003-12-28 23:21:00.000000000 -0800
+@@ -28,6 +28,9 @@
+  * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
+  *    - Renamed bond_3ad_link_status_changed() to
+  *      bond_3ad_handle_link_change() for compatibility with TLB.
++ *
++ * 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
++ *    - Code cleanup and style changes
+  */
+ #ifndef __BOND_3AD_H__
+--- linux-2.6.0/drivers/net/bonding/bond_alb.c 2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/bonding/bond_alb.c  2003-12-28 23:21:00.000000000 -0800
+@@ -28,8 +28,13 @@
+  * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
+  *    - Add support for setting bond's MAC address with special
+  *      handling required for ALB/TLB.
++ *
++ * 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
++ *    - Code cleanup and style changes
+  */
++//#define BONDING_DEBUG 1
++
+ #include <linux/skbuff.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+@@ -50,11 +55,11 @@
+ #define ALB_TIMER_TICKS_PER_SEC           10  /* should be a divisor of HZ */
+-#define BOND_TLB_REBALANCE_INTERVAL 10        /* in seconds, periodic re-balancing
+-                                       * used for division - never set
++#define BOND_TLB_REBALANCE_INTERVAL 10        /* In seconds, periodic re-balancing.
++                                       * Used for division - never set
+                                        * to zero !!!
+                                        */
+-#define BOND_ALB_LP_INTERVAL      1   /* in seconds periodic send of
++#define BOND_ALB_LP_INTERVAL      1   /* In seconds, periodic send of
+                                        * learning packets to the switch
+                                        */
+@@ -66,7 +71,7 @@
+ #define TLB_HASH_TABLE_SIZE 256       /* The size of the clients hash table.
+                                * Note that this value MUST NOT be smaller
+-                               * because the key hash table BYTE wide !
++                               * because the key hash table is BYTE wide !
+                                */
+@@ -86,12 +91,15 @@
+  */
+ #define RLB_PROMISC_TIMEOUT   10*ALB_TIMER_TICKS_PER_SEC
++static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
++static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC;
++
+ #pragma pack(1)
+ struct learning_pkt {
+       u8 mac_dst[ETH_ALEN];
+       u8 mac_src[ETH_ALEN];
+       u16 type;
+-      u8 padding[ETH_ZLEN - (2*ETH_ALEN + 2)];
++      u8 padding[ETH_ZLEN - ETH_HLEN];
+ };
+ struct arp_pkt {
+@@ -110,13 +118,12 @@ struct arp_pkt {
+ /* Forward declaration */
+ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]);
+-static inline u8
+-_simple_hash(u8 *hash_start, int hash_size)
++static inline u8 _simple_hash(u8 *hash_start, int hash_size)
+ {
+       int i;
+       u8 hash = 0;
+-      for (i=0; i<hash_size; i++) {
++      for (i = 0; i < hash_size; i++) {
+               hash ^= hash_start[i];
+       }
+@@ -125,193 +132,151 @@ _simple_hash(u8 *hash_start, int hash_si
+ /*********************** tlb specific functions ***************************/
+-static inline void
+-_lock_tx_hashtbl(struct bonding *bond)
++static inline void _lock_tx_hashtbl(struct bonding *bond)
+ {
+       spin_lock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
+ }
+-static inline void
+-_unlock_tx_hashtbl(struct bonding *bond)
++static inline void _unlock_tx_hashtbl(struct bonding *bond)
+ {
+       spin_unlock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
+ }
+ /* Caller must hold tx_hashtbl lock */
+-static inline void
+-tlb_init_table_entry(struct bonding *bond, u8 index, u8 save_load)
++static inline void tlb_init_table_entry(struct tlb_client_info *entry, int save_load)
+ {
+-      struct tlb_client_info *entry;
+-
+-      if (BOND_ALB_INFO(bond).tx_hashtbl == NULL) {
+-              return;
+-      }
+-
+-      entry = &(BOND_ALB_INFO(bond).tx_hashtbl[index]);
+-      /* at end of cycle, save the load that was transmitted to the client
+-       * during the cycle, and set the tx_bytes counter to 0 for counting
+-       * the load during the next cycle
+-       */
+       if (save_load) {
+               entry->load_history = 1 + entry->tx_bytes /
+-                      BOND_TLB_REBALANCE_INTERVAL;
++                                    BOND_TLB_REBALANCE_INTERVAL;
+               entry->tx_bytes = 0;
+       }
++
+       entry->tx_slave = NULL;
+       entry->next = TLB_NULL_INDEX;
+       entry->prev = TLB_NULL_INDEX;
+ }
+-static inline void
+-tlb_init_slave(struct slave *slave)
++static inline void tlb_init_slave(struct slave *slave)
+ {
+-      struct tlb_slave_info *slave_info = &(SLAVE_TLB_INFO(slave));
+-
+-      slave_info->load = 0;
+-      slave_info->head = TLB_NULL_INDEX;
++      SLAVE_TLB_INFO(slave).load = 0;
++      SLAVE_TLB_INFO(slave).head = TLB_NULL_INDEX;
+ }
+ /* Caller must hold bond lock for read */
+-static inline void
+-tlb_clear_slave(struct bonding *bond, struct slave *slave, u8 save_load)
++static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_load)
+ {
+-      struct tlb_client_info *tx_hash_table = NULL;
+-      u32 index, next_index;
++      struct tlb_client_info *tx_hash_table;
++      u32 index;
+-      /* clear slave from tx_hashtbl */
+       _lock_tx_hashtbl(bond);
++
++      /* clear slave from tx_hashtbl */
+       tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl;
+-      if (tx_hash_table) {
+-              index = SLAVE_TLB_INFO(slave).head;
+-              while (index != TLB_NULL_INDEX) {
+-                      next_index = tx_hash_table[index].next;
+-                      tlb_init_table_entry(bond, index, save_load);
+-                      index = next_index;
+-              }
++      index = SLAVE_TLB_INFO(slave).head;
++      while (index != TLB_NULL_INDEX) {
++              u32 next_index = tx_hash_table[index].next;
++              tlb_init_table_entry(&tx_hash_table[index], save_load);
++              index = next_index;
+       }
++
+       _unlock_tx_hashtbl(bond);
+       tlb_init_slave(slave);
+ }
+ /* Must be called before starting the monitor timer */
+-static int
+-tlb_initialize(struct bonding *bond)
++static int tlb_initialize(struct bonding *bond)
+ {
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
++      int size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
+       int i;
+-      size_t size;
+-
+-#if(TLB_HASH_TABLE_SIZE != 256)
+-      /* Key to the hash table is byte wide. Check the size! */
+-      #error Hash Table size is wrong.
+-#endif
+       spin_lock_init(&(bond_info->tx_hashtbl_lock));
+       _lock_tx_hashtbl(bond);
+-      if (bond_info->tx_hashtbl != NULL) {
+-              printk (KERN_ERR "%s: TLB hash table is not NULL\n",
+-                      bond->device->name);
+-              _unlock_tx_hashtbl(bond);
+-              return -1;
+-      }
+-      size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
+       bond_info->tx_hashtbl = kmalloc(size, GFP_KERNEL);
+-      if (bond_info->tx_hashtbl == NULL) {
+-              printk (KERN_ERR "%s: Failed to allocate TLB hash table\n",
+-                      bond->device->name);
++      if (!bond_info->tx_hashtbl) {
++              printk(KERN_ERR DRV_NAME
++                     ": Error: %s: Failed to allocate TLB hash table\n",
++                     bond->dev->name);
+               _unlock_tx_hashtbl(bond);
+               return -1;
+       }
+       memset(bond_info->tx_hashtbl, 0, size);
+-      for (i=0; i<TLB_HASH_TABLE_SIZE; i++) {
+-              tlb_init_table_entry(bond, i, 1);
++
++      for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) {
++              tlb_init_table_entry(&bond_info->tx_hashtbl[i], 1);
+       }
++
+       _unlock_tx_hashtbl(bond);
+       return 0;
+ }
+ /* Must be called only after all slaves have been released */
+-static void
+-tlb_deinitialize(struct bonding *bond)
++static void tlb_deinitialize(struct bonding *bond)
+ {
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+       _lock_tx_hashtbl(bond);
+-      if (bond_info->tx_hashtbl == NULL) {
+-              _unlock_tx_hashtbl(bond);
+-              return;
+-      }
++
+       kfree(bond_info->tx_hashtbl);
+       bond_info->tx_hashtbl = NULL;
++
+       _unlock_tx_hashtbl(bond);
+ }
+ /* Caller must hold bond lock for read */
+-static struct slave*
+-tlb_get_least_loaded_slave(struct bonding *bond)
++static struct slave *tlb_get_least_loaded_slave(struct bonding *bond)
+ {
+-      struct slave *slave;
+-      struct slave *least_loaded;
+-      s64 curr_gap, max_gap;
++      struct slave *slave, *least_loaded;
++      s64 max_gap;
++      int i, found = 0;
+       /* Find the first enabled slave */
+-      slave = bond_get_first_slave(bond);
+-      while (slave) {
++      bond_for_each_slave(bond, slave, i) {
+               if (SLAVE_IS_OK(slave)) {
++                      found = 1;
+                       break;
+               }
+-              slave = bond_get_next_slave(bond, slave);
+       }
+-      if (!slave) {
++      if (!found) {
+               return NULL;
+       }
+       least_loaded = slave;
+-      max_gap = (s64)(slave->speed * 1000000) -
+-                      (s64)(SLAVE_TLB_INFO(slave).load * 8);
++      max_gap = (s64)(slave->speed << 20) - /* Convert to Megabit per sec */
++                      (s64)(SLAVE_TLB_INFO(slave).load << 3); /* Bytes to bits */
+       /* Find the slave with the largest gap */
+-      slave = bond_get_next_slave(bond, slave);
+-      while (slave) {
++      bond_for_each_slave_from(bond, slave, i, least_loaded) {
+               if (SLAVE_IS_OK(slave)) {
+-                      curr_gap = (s64)(slave->speed * 1000000) -
+-                                      (s64)(SLAVE_TLB_INFO(slave).load * 8);
+-                      if (max_gap < curr_gap) {
++                      s64 gap = (s64)(slave->speed << 20) -
++                                      (s64)(SLAVE_TLB_INFO(slave).load << 3);
++                      if (max_gap < gap) {
+                               least_loaded = slave;
+-                              max_gap = curr_gap;
++                              max_gap = gap;
+                       }
+               }
+-              slave = bond_get_next_slave(bond, slave);
+       }
+       return least_loaded;
+ }
+ /* Caller must hold bond lock for read */
+-struct slave*
+-tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
++struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
+ {
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+-      struct tlb_client_info *hash_table = NULL;
+-      struct slave *assigned_slave = NULL;
++      struct tlb_client_info *hash_table;
++      struct slave *assigned_slave;
+       _lock_tx_hashtbl(bond);
+       hash_table = bond_info->tx_hashtbl;
+-      if (hash_table == NULL) {
+-              printk (KERN_ERR "%s: TLB hash table is NULL\n",
+-                      bond->device->name);
+-              _unlock_tx_hashtbl(bond);
+-              return NULL;
+-      }
+-
+       assigned_slave = hash_table[hash_index].tx_slave;
+       if (!assigned_slave) {
+               assigned_slave = tlb_get_least_loaded_slave(bond);
+@@ -345,14 +310,12 @@ tlb_choose_channel(struct bonding *bond,
+ }
+ /*********************** rlb specific functions ***************************/
+-static inline void
+-_lock_rx_hashtbl(struct bonding *bond)
++static inline void _lock_rx_hashtbl(struct bonding *bond)
+ {
+       spin_lock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+ }
+-static inline void
+-_unlock_rx_hashtbl(struct bonding *bond)
++static inline void _unlock_rx_hashtbl(struct bonding *bond)
+ {
+       spin_unlock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+ }
+@@ -360,26 +323,20 @@ _unlock_rx_hashtbl(struct bonding *bond)
+ /* when an ARP REPLY is received from a client update its info
+  * in the rx_hashtbl
+  */
+-static void
+-rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
++static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
+ {
+-      u32 hash_index;
+-      struct rlb_client_info *client_info = NULL;
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
++      struct rlb_client_info *client_info;
++      u32 hash_index;
+       _lock_rx_hashtbl(bond);
+-      if (bond_info->rx_hashtbl == NULL) {
+-              _unlock_rx_hashtbl(bond);
+-              return;
+-      }
+-      hash_index = _simple_hash((u8*)&(arp->ip_src), 4);
++      hash_index = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src));
+       client_info = &(bond_info->rx_hashtbl[hash_index]);
+       if ((client_info->assigned) &&
+           (client_info->ip_src == arp->ip_dst) &&
+           (client_info->ip_dst == arp->ip_src)) {
+-
+               /* update the clients MAC address */
+               memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);
+               client_info->ntt = 1;
+@@ -389,66 +346,60 @@ rlb_update_entry_from_arp(struct bonding
+       _unlock_rx_hashtbl(bond);
+ }
+-static int
+-rlb_arp_recv(struct sk_buff *skb,
+-           struct net_device *dev,
+-           struct packet_type* ptype)
++static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype)
+ {
+-      struct bonding *bond = (struct bonding *)dev->priv;
+-      int ret = NET_RX_DROP;
++      struct bonding *bond = bond_dev->priv;
+       struct arp_pkt *arp = (struct arp_pkt *)skb->data;
++      int res = NET_RX_DROP;
+-      if (!(dev->flags & IFF_MASTER)) {
++      if (!(bond_dev->flags & IFF_MASTER)) {
+               goto out;
+       }
+       if (!arp) {
+-              printk(KERN_ERR "Packet has no ARP data\n");
++              dprintk("Packet has no ARP data\n");
+               goto out;
+       }
+       if (skb->len < sizeof(struct arp_pkt)) {
+-              printk(KERN_ERR "Packet is too small to be an ARP\n");
++              dprintk("Packet is too small to be an ARP\n");
+               goto out;
+       }
+       if (arp->op_code == htons(ARPOP_REPLY)) {
+               /* update rx hash table for this ARP */
+               rlb_update_entry_from_arp(bond, arp);
+-              BOND_PRINT_DBG(("Server received an ARP Reply from client"));
++              dprintk("Server received an ARP Reply from client\n");
+       }
+-      ret = NET_RX_SUCCESS;
++      res = NET_RX_SUCCESS;
+ out:
+       dev_kfree_skb(skb);
+-      return ret;
++      return res;
+ }
+ /* Caller must hold bond lock for read */
+-static struct slave*
+-rlb_next_rx_slave(struct bonding *bond)
++static struct slave *rlb_next_rx_slave(struct bonding *bond)
+ {
+-      struct slave *rx_slave = NULL, *slave = NULL;
+-      unsigned int i = 0;
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
++      struct slave *rx_slave, *slave, *start_at;
++      int i = 0;
+-      slave = bond_info->next_rx_slave;
+-      if (slave == NULL) {
+-              slave = bond->next;
++      if (bond_info->next_rx_slave) {
++              start_at = bond_info->next_rx_slave;
++      } else {
++              start_at = bond->first_slave;
+       }
+-      /* this loop uses the circular linked list property of the
+-       * slave's list to go through all slaves
+-       */
+-      for (i = 0; i < bond->slave_cnt; i++, slave = slave->next) {
++      rx_slave = NULL;
++      bond_for_each_slave_from(bond, slave, i, start_at) {
+               if (SLAVE_IS_OK(slave)) {
+                       if (!rx_slave) {
+                               rx_slave = slave;
+-                      }
+-                      else if (slave->speed > rx_slave->speed) {
++                      } else if (slave->speed > rx_slave->speed) {
+                               rx_slave = slave;
+                       }
+               }
+@@ -464,48 +415,41 @@ rlb_next_rx_slave(struct bonding *bond)
+ /* teach the switch the mac of a disabled slave
+  * on the primary for fault tolerance
+  *
+- * Caller must hold bond->ptrlock for write or bond lock for write
++ * Caller must hold bond->curr_slave_lock for write or bond lock for write
+  */
+-static void
+-rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[])
++static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[])
+ {
+-      if (!bond->current_slave) {
++      if (!bond->curr_active_slave) {
+               return;
+       }
++
+       if (!bond->alb_info.primary_is_promisc) {
+               bond->alb_info.primary_is_promisc = 1;
+-              dev_set_promiscuity(bond->current_slave->dev, 1);
++              dev_set_promiscuity(bond->curr_active_slave->dev, 1);
+       }
++
+       bond->alb_info.rlb_promisc_timeout_counter = 0;
+-      alb_send_learning_packets(bond->current_slave, addr);
++      alb_send_learning_packets(bond->curr_active_slave, addr);
+ }
+ /* slave being removed should not be active at this point
+  *
+  * Caller must hold bond lock for read
+  */
+-static void
+-rlb_clear_slave(struct bonding *bond, struct slave *slave)
++static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
+ {
+-      struct rlb_client_info *rx_hash_table = NULL;
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+-      u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
++      struct rlb_client_info *rx_hash_table;
+       u32 index, next_index;
+       /* clear slave from rx_hashtbl */
+       _lock_rx_hashtbl(bond);
+-      rx_hash_table = bond_info->rx_hashtbl;
+-
+-      if (rx_hash_table == NULL) {
+-              _unlock_rx_hashtbl(bond);
+-              return;
+-      }
++      rx_hash_table = bond_info->rx_hashtbl;
+       index = bond_info->rx_hashtbl_head;
+       for (; index != RLB_NULL_INDEX; index = next_index) {
+               next_index = rx_hash_table[index].next;
+-
+               if (rx_hash_table[index].slave == slave) {
+                       struct slave *assigned_slave = rlb_next_rx_slave(bond);
+@@ -533,23 +477,24 @@ rlb_clear_slave(struct bonding *bond, st
+       _unlock_rx_hashtbl(bond);
+-      write_lock(&bond->ptrlock);
+-      if (slave != bond->current_slave) {
++      write_lock(&bond->curr_slave_lock);
++
++      if (slave != bond->curr_active_slave) {
+               rlb_teach_disabled_mac_on_primary(bond, slave->dev->dev_addr);
+       }
+-      write_unlock(&bond->ptrlock);
++
++      write_unlock(&bond->curr_slave_lock);
+ }
+-static void
+-rlb_update_client(struct rlb_client_info *client_info)
++static void rlb_update_client(struct rlb_client_info *client_info)
+ {
+-      int i = 0;
++      int i;
+-      if (client_info->slave == NULL) {
++      if (!client_info->slave) {
+               return;
+       }
+-      for (i=0; i<RLB_ARP_BURST_SIZE; i++) {
++      for (i = 0; i < RLB_ARP_BURST_SIZE; i++) {
+               arp_send(ARPOP_REPLY, ETH_P_ARP,
+                        client_info->ip_dst,
+                        client_info->slave->dev,
+@@ -561,20 +506,14 @@ rlb_update_client(struct rlb_client_info
+ }
+ /* sends ARP REPLIES that update the clients that need updating */
+-static void
+-rlb_update_rx_clients(struct bonding *bond)
++static void rlb_update_rx_clients(struct bonding *bond)
+ {
+-      u32 hash_index;
+-      struct rlb_client_info *client_info = NULL;
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
++      struct rlb_client_info *client_info;
++      u32 hash_index;
+       _lock_rx_hashtbl(bond);
+-      if (bond_info->rx_hashtbl == NULL) {
+-              _unlock_rx_hashtbl(bond);
+-              return;
+-      }
+-
+       hash_index = bond_info->rx_hashtbl_head;
+       for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
+               client_info = &(bond_info->rx_hashtbl[hash_index]);
+@@ -595,22 +534,15 @@ rlb_update_rx_clients(struct bonding *bo
+ }
+ /* The slave was assigned a new mac address - update the clients */
+-static void
+-rlb_req_update_slave_clients(struct bonding *bond, struct slave *slave)
++static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *slave)
+ {
+-      u32 hash_index;
+-      u8 ntt = 0;
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+-      u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+-      struct rlb_client_info* client_info = NULL;
++      struct rlb_client_info *client_info;
++      int ntt = 0;
++      u32 hash_index;
+       _lock_rx_hashtbl(bond);
+-      if (bond_info->rx_hashtbl == NULL) {
+-              _unlock_rx_hashtbl(bond);
+-              return;
+-      }
+-
+       hash_index = bond_info->rx_hashtbl_head;
+       for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
+               client_info = &(bond_info->rx_hashtbl[hash_index]);
+@@ -633,37 +565,31 @@ rlb_req_update_slave_clients(struct bond
+ }
+ /* mark all clients using src_ip to be updated */
+-static void
+-rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
++static void rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
+ {
+-      u32 hash_index;
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+-      u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+-      struct rlb_client_info *client_info = NULL;
++      struct rlb_client_info *client_info;
++      u32 hash_index;
+       _lock_rx_hashtbl(bond);
+-      if (bond_info->rx_hashtbl == NULL) {
+-              _unlock_rx_hashtbl(bond);
+-              return;
+-      }
+-
+       hash_index = bond_info->rx_hashtbl_head;
+       for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
+               client_info = &(bond_info->rx_hashtbl[hash_index]);
+               if (!client_info->slave) {
+-                      printk(KERN_ERR "Bonding: Error: found a client with no"
+-                             " channel in the client's hash table\n");
++                      printk(KERN_ERR DRV_NAME
++                             ": Error: found a client with no channel in "
++                             "the client's hash table\n");
+                       continue;
+               }
+               /*update all clients using this src_ip, that are not assigned
+-               * to the team's address (current_slave) and have a known
++               * to the team's address (curr_active_slave) and have a known
+                * unicast mac address.
+                */
+               if ((client_info->ip_src == src_ip) &&
+                   memcmp(client_info->slave->dev->dev_addr,
+-                         bond->device->dev_addr, ETH_ALEN) &&
++                         bond->dev->dev_addr, ETH_ALEN) &&
+                   memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
+                       client_info->ntt = 1;
+                       bond_info->rx_ntt = 1;
+@@ -674,30 +600,22 @@ rlb_req_update_subnet_clients(struct bon
+ }
+ /* Caller must hold both bond and ptr locks for read */
+-struct slave*
+-rlb_choose_channel(struct bonding *bond, struct arp_pkt *arp)
++struct slave *rlb_choose_channel(struct bonding *bond, struct arp_pkt *arp)
+ {
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+-      struct rlb_client_info *client_info = NULL;
++      struct slave *assigned_slave;
++      struct rlb_client_info *client_info;
+       u32 hash_index = 0;
+-      struct slave *assigned_slave = NULL;
+-      u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+       _lock_rx_hashtbl(bond);
+-      if (bond_info->rx_hashtbl == NULL) {
+-              _unlock_rx_hashtbl(bond);
+-              return NULL;
+-      }
+-
+-      hash_index = _simple_hash((u8 *)&arp->ip_dst, 4);
++      hash_index = _simple_hash((u8 *)&arp->ip_dst, sizeof(arp->ip_src));
+       client_info = &(bond_info->rx_hashtbl[hash_index]);
+-      if (client_info->assigned == 1) {
++      if (client_info->assigned) {
+               if ((client_info->ip_src == arp->ip_src) &&
+                   (client_info->ip_dst == arp->ip_dst)) {
+                       /* the entry is already assigned to this client */
+-
+                       if (memcmp(arp->mac_dst, mac_bcast, ETH_ALEN)) {
+                               /* update mac address from arp */
+                               memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
+@@ -710,12 +628,12 @@ rlb_choose_channel(struct bonding *bond,
+                       }
+               } else {
+                       /* the entry is already assigned to some other client,
+-                       * move the old client to primary (current_slave) so
++                       * move the old client to primary (curr_active_slave) so
+                        * that the new client can be assigned to this entry.
+                        */
+-                      if (bond->current_slave &&
+-                          client_info->slave != bond->current_slave) {
+-                              client_info->slave = bond->current_slave;
++                      if (bond->curr_active_slave &&
++                          client_info->slave != bond->curr_active_slave) {
++                              client_info->slave = bond->curr_active_slave;
+                               rlb_update_client(client_info);
+                       }
+               }
+@@ -736,8 +654,7 @@ rlb_choose_channel(struct bonding *bond,
+               if (memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
+                       client_info->ntt = 1;
+                       bond->alb_info.rx_ntt = 1;
+-              }
+-              else {
++              } else {
+                       client_info->ntt = 0;
+               }
+@@ -760,10 +677,9 @@ rlb_choose_channel(struct bonding *bond,
+ /* chooses (and returns) transmit channel for arp reply
+  * does not choose channel for other arp types since they are
+- * sent on the current_slave
++ * sent on the curr_active_slave
+  */
+-static struct slave*
+-rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
++static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
+ {
+       struct arp_pkt *arp = (struct arp_pkt *)skb->nh.raw;
+       struct slave *tx_slave = NULL;
+@@ -776,9 +692,8 @@ rlb_arp_xmit(struct sk_buff *skb, struct
+               if (tx_slave) {
+                       memcpy(arp->mac_src,tx_slave->dev->dev_addr, ETH_ALEN);
+               }
+-              BOND_PRINT_DBG(("Server sent ARP Reply packet"));
++              dprintk("Server sent ARP Reply packet\n");
+       } else if (arp->op_code == __constant_htons(ARPOP_REQUEST)) {
+-
+               /* Create an entry in the rx_hashtbl for this client as a
+                * place holder.
+                * When the arp reply is received the entry will be updated
+@@ -797,34 +712,29 @@ rlb_arp_xmit(struct sk_buff *skb, struct
+                * updated with their assigned mac.
+                */
+               rlb_req_update_subnet_clients(bond, arp->ip_src);
+-              BOND_PRINT_DBG(("Server sent ARP Request packet"));
++              dprintk("Server sent ARP Request packet\n");
+       }
+       return tx_slave;
+ }
+ /* Caller must hold bond lock for read */
+-static void
+-rlb_rebalance(struct bonding *bond)
++static void rlb_rebalance(struct bonding *bond)
+ {
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+-      struct slave *assigned_slave = NULL;
++      struct slave *assigned_slave;
++      struct rlb_client_info *client_info;
++      int ntt;
+       u32 hash_index;
+-      struct rlb_client_info *client_info = NULL;
+-      u8 ntt = 0;
+       _lock_rx_hashtbl(bond);
+-      if (bond_info->rx_hashtbl == NULL) {
+-              _unlock_rx_hashtbl(bond);
+-              return;
+-      }
+-
++      ntt = 0;
+       hash_index = bond_info->rx_hashtbl_head;
+       for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
+               client_info = &(bond_info->rx_hashtbl[hash_index]);
+               assigned_slave = rlb_next_rx_slave(bond);
+-              if (assigned_slave && (client_info->slave != assigned_slave)){
++              if (assigned_slave && (client_info->slave != assigned_slave)) {
+                       client_info->slave = assigned_slave;
+                       client_info->ntt = 1;
+                       ntt = 1;
+@@ -839,96 +749,83 @@ rlb_rebalance(struct bonding *bond)
+ }
+ /* Caller must hold rx_hashtbl lock */
+-static inline void
+-rlb_init_table_entry(struct rlb_client_info *entry)
++static void rlb_init_table_entry(struct rlb_client_info *entry)
+ {
++      memset(entry, 0, sizeof(struct rlb_client_info));
+       entry->next = RLB_NULL_INDEX;
+       entry->prev = RLB_NULL_INDEX;
+-      entry->assigned = 0;
+-      entry->ntt = 0;
+ }
+-static int
+-rlb_initialize(struct bonding *bond)
++static int rlb_initialize(struct bonding *bond)
+ {
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+       struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
++      int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
+       int i;
+-      size_t size;
+       spin_lock_init(&(bond_info->rx_hashtbl_lock));
+       _lock_rx_hashtbl(bond);
+-      if (bond_info->rx_hashtbl != NULL) {
+-              printk (KERN_ERR "%s: RLB hash table is not NULL\n",
+-                      bond->device->name);
+-              _unlock_rx_hashtbl(bond);
+-              return -1;
+-      }
+-      size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
+       bond_info->rx_hashtbl = kmalloc(size, GFP_KERNEL);
+-      if (bond_info->rx_hashtbl == NULL) {
+-              printk (KERN_ERR "%s: Failed to allocate"
+-                      " RLB hash table\n", bond->device->name);
++      if (!bond_info->rx_hashtbl) {
++              printk(KERN_ERR DRV_NAME
++                     ": Error: %s: Failed to allocate RLB hash table\n",
++                     bond->dev->name);
+               _unlock_rx_hashtbl(bond);
+               return -1;
+       }
+       bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
+-      for (i=0; i<RLB_HASH_TABLE_SIZE; i++) {
++      for (i = 0; i < RLB_HASH_TABLE_SIZE; i++) {
+               rlb_init_table_entry(bond_info->rx_hashtbl + i);
+       }
+-      _unlock_rx_hashtbl(bond);
+-      /* register to receive ARPs */
++      _unlock_rx_hashtbl(bond);
+       /*initialize packet type*/
+       pk_type->type = __constant_htons(ETH_P_ARP);
+-      pk_type->dev = bond->device;
++      pk_type->dev = bond->dev;
+       pk_type->func = rlb_arp_recv;
++      /* register to receive ARPs */
+       dev_add_pack(pk_type);
+       return 0;
+ }
+-static void
+-rlb_deinitialize(struct bonding *bond)
++static void rlb_deinitialize(struct bonding *bond)
+ {
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+       dev_remove_pack(&(bond_info->rlb_pkt_type));
+       _lock_rx_hashtbl(bond);
+-      if (bond_info->rx_hashtbl == NULL) {
+-              _unlock_rx_hashtbl(bond);
+-              return;
+-      }
++
+       kfree(bond_info->rx_hashtbl);
+       bond_info->rx_hashtbl = NULL;
++
+       _unlock_rx_hashtbl(bond);
+ }
+ /*********************** tlb/rlb shared functions *********************/
+-static void
+-alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
++static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
+ {
+-      struct sk_buff *skb = NULL;
+       struct learning_pkt pkt;
+-      char *data = NULL;
++      int size = sizeof(struct learning_pkt);
+       int i;
+-      unsigned int size = sizeof(struct learning_pkt);
+       memset(&pkt, 0, size);
+       memcpy(pkt.mac_dst, mac_addr, ETH_ALEN);
+       memcpy(pkt.mac_src, mac_addr, ETH_ALEN);
+       pkt.type = __constant_htons(ETH_P_LOOP);
+-      for (i=0; i < MAX_LP_RETRY; i++) {
+-              skb = NULL;
++      for (i = 0; i < MAX_LP_RETRY; i++) {
++              struct sk_buff *skb;
++              char *data;
++
+               skb = dev_alloc_skb(size);
+               if (!skb) {
+                       return;
+@@ -936,28 +833,26 @@ alb_send_learning_packets(struct slave *
+               data = skb_put(skb, size);
+               memcpy(data, &pkt, size);
++
+               skb->mac.raw = data;
+               skb->nh.raw = data + ETH_HLEN;
+               skb->protocol = pkt.type;
+               skb->priority = TC_PRIO_CONTROL;
+               skb->dev = slave->dev;
++
+               dev_queue_xmit(skb);
+       }
+-
+ }
+ /* hw is a boolean parameter that determines whether we should try and
+  * set the hw address of the device as well as the hw address of the
+  * net_device
+  */
+-static int
+-alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
++static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
+ {
+-      struct net_device *dev = NULL;
++      struct net_device *dev = slave->dev;
+       struct sockaddr s_addr;
+-      dev = slave->dev;
+-
+       if (!hw) {
+               memcpy(dev->dev_addr, addr, dev->addr_len);
+               return 0;
+@@ -968,26 +863,23 @@ alb_set_slave_mac_addr(struct slave *sla
+       memcpy(s_addr.sa_data, addr, dev->addr_len);
+       s_addr.sa_family = dev->type;
+       if (dev->set_mac_address(dev, &s_addr)) {
+-              printk(KERN_DEBUG "bonding: Error: alb_set_slave_mac_addr:"
+-                                " dev->set_mac_address of dev %s failed!"
+-                                " ALB mode requires that the base driver"
+-                                " support setting the hw address also when"
+-                                " the network device's interface is open\n",
+-                                dev->name);
++              printk(KERN_ERR DRV_NAME
++                     ": Error: dev->set_mac_address of dev %s failed! ALB "
++                     "mode requires that the base driver support setting "
++                     "the hw address also when the network device's "
++                     "interface is open\n",
++                     dev->name);
+               return -EOPNOTSUPP;
+       }
+       return 0;
+ }
+-/* Caller must hold bond lock for write or ptrlock for write*/
+-static void
+-alb_swap_mac_addr(struct bonding *bond,
+-                struct slave *slave1,
+-                struct slave *slave2)
++/* Caller must hold bond lock for write or curr_slave_lock for write*/
++static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct slave *slave2)
+ {
+-      u8 tmp_mac_addr[ETH_ALEN];
+       struct slave *disabled_slave = NULL;
+-      u8 slaves_state_differ;
++      u8 tmp_mac_addr[ETH_ALEN];
++      int slaves_state_differ;
+       slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
+@@ -1004,8 +896,7 @@ alb_swap_mac_addr(struct bonding *bond,
+                        */
+                       rlb_req_update_slave_clients(bond, slave1);
+               }
+-      }
+-      else {
++      } else {
+               disabled_slave = slave1;
+       }
+@@ -1017,15 +908,14 @@ alb_swap_mac_addr(struct bonding *bond,
+                        */
+                       rlb_req_update_slave_clients(bond, slave2);
+               }
+-      }
+-      else {
++      } else {
+               disabled_slave = slave2;
+       }
+       if (bond->alb_info.rlb_enabled && slaves_state_differ) {
+-                      /* A disabled slave was assigned an active mac addr */
+-                      rlb_teach_disabled_mac_on_primary(bond,
+-                              disabled_slave->dev->dev_addr);
++              /* A disabled slave was assigned an active mac addr */
++              rlb_teach_disabled_mac_on_primary(bond,
++                                                disabled_slave->dev->dev_addr);
+       }
+ }
+@@ -1043,10 +933,8 @@ alb_swap_mac_addr(struct bonding *bond,
+  *
+  * Caller must hold bond lock
+  */
+-static void
+-alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
++static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
+ {
+-      struct slave *tmp_slave;
+       int perm_curr_diff;
+       int perm_bond_diff;
+@@ -1054,20 +942,23 @@ alb_change_hw_addr_on_detach(struct bond
+                               slave->dev->dev_addr,
+                               ETH_ALEN);
+       perm_bond_diff = memcmp(slave->perm_hwaddr,
+-                              bond->device->dev_addr,
++                              bond->dev->dev_addr,
+                               ETH_ALEN);
++
+       if (perm_curr_diff && perm_bond_diff) {
+-              tmp_slave = bond_get_first_slave(bond);
+-              while (tmp_slave) {
++              struct slave *tmp_slave;
++              int i, found = 0;
++
++              bond_for_each_slave(bond, tmp_slave, i) {
+                       if (!memcmp(slave->perm_hwaddr,
+-                                 tmp_slave->dev->dev_addr,
+-                                 ETH_ALEN)) {
++                                  tmp_slave->dev->dev_addr,
++                                  ETH_ALEN)) {
++                              found = 1;
+                               break;
+                       }
+-                      tmp_slave = bond_get_next_slave(bond, tmp_slave);
+               }
+-              if (tmp_slave) {
++              if (found) {
+                       alb_swap_mac_addr(bond, slave, tmp_slave);
+               }
+       }
+@@ -1098,10 +989,10 @@ alb_change_hw_addr_on_detach(struct bond
+  * caller must hold the bond lock for write since the mac addresses are compared
+  * and may be swapped.
+  */
+-static int
+-alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
++static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
+ {
+-      struct slave *tmp_slave1, *tmp_slave2;
++      struct slave *tmp_slave1, *tmp_slave2, *free_mac_slave;
++      int i, j, found = 0;
+       if (bond->slave_cnt == 0) {
+               /* this is the first slave */
+@@ -1112,65 +1003,68 @@ alb_handle_addr_collision_on_attach(stru
+        * check uniqueness of slave's mac address against the other
+        * slaves in the bond.
+        */
+-      if (memcmp(slave->perm_hwaddr, bond->device->dev_addr, ETH_ALEN)) {
+-              tmp_slave1 = bond_get_first_slave(bond);
+-              for (; tmp_slave1; tmp_slave1 = bond_get_next_slave(bond, tmp_slave1)) {
++      if (memcmp(slave->perm_hwaddr, bond->dev->dev_addr, ETH_ALEN)) {
++              bond_for_each_slave(bond, tmp_slave1, i) {
+                       if (!memcmp(tmp_slave1->dev->dev_addr, slave->dev->dev_addr,
+                                   ETH_ALEN)) {
++                              found = 1;
+                               break;
+                       }
+               }
+-              if (tmp_slave1) {
++
++              if (found) {
+                       /* a slave was found that is using the mac address
+                        * of the new slave
+                        */
+-                      printk(KERN_ERR "bonding: Warning: the hw address "
+-                             "of slave %s is not unique - cannot enslave it!"
+-                             , slave->dev->name);
++                      printk(KERN_ERR DRV_NAME
++                             ": Error: the hw address of slave %s is not "
++                             "unique - cannot enslave it!",
++                             slave->dev->name);
+                       return -EINVAL;
+               }
++
+               return 0;
+       }
+-      /* the slave's address is equal to the address of the bond
+-       * search for a spare address in the bond for this slave.
++      /* The slave's address is equal to the address of the bond.
++       * Search for a spare address in the bond for this slave.
+        */
+-      tmp_slave1 = bond_get_first_slave(bond);
+-      for (; tmp_slave1; tmp_slave1 = bond_get_next_slave(bond, tmp_slave1)) {
+-
+-              tmp_slave2 = bond_get_first_slave(bond);
+-              for (; tmp_slave2; tmp_slave2 = bond_get_next_slave(bond, tmp_slave2)) {
++      free_mac_slave = NULL;
++      bond_for_each_slave(bond, tmp_slave1, i) {
++              found = 0;
++              bond_for_each_slave(bond, tmp_slave2, j) {
+                       if (!memcmp(tmp_slave1->perm_hwaddr,
+                                   tmp_slave2->dev->dev_addr,
+                                   ETH_ALEN)) {
+-
++                              found = 1;
+                               break;
+                       }
+               }
+-              if (!tmp_slave2) {
++              if (!found) {
+                       /* no slave has tmp_slave1's perm addr
+                        * as its curr addr
+                        */
++                      free_mac_slave = tmp_slave1;
+                       break;
+               }
+       }
+-      if (tmp_slave1) {
+-              alb_set_slave_mac_addr(slave, tmp_slave1->perm_hwaddr,
++      if (free_mac_slave) {
++              alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr,
+                                      bond->alb_info.rlb_enabled);
+-              printk(KERN_WARNING "bonding: Warning: the hw address "
+-                     "of slave %s is in use by the bond; "
+-                     "giving it the hw address of %s\n",
+-                     slave->dev->name, tmp_slave1->dev->name);
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning: the hw address of slave %s is in use by "
++                     "the bond; giving it the hw address of %s\n",
++                     slave->dev->name, free_mac_slave->dev->name);
+       } else {
+-              printk(KERN_CRIT "bonding: Error: the hw address "
+-                     "of slave %s is in use by the bond; "
+-                     "couldn't find a slave with a free hw "
+-                     "address to give it (this should not have "
+-                     "happened)\n", slave->dev->name);
++              printk(KERN_ERR DRV_NAME
++                     ": Error: the hw address of slave %s is in use by the "
++                     "bond; couldn't find a slave with a free hw address to "
++                     "give it (this should not have happened)\n",
++                     slave->dev->name);
+               return -EFAULT;
+       }
+@@ -1188,37 +1082,36 @@ alb_handle_addr_collision_on_attach(stru
+  *
+  * For each slave, this function sets the interface to the new address and then
+  * changes its dev_addr field to its previous value.
+- * 
++ *
+  * Unwinding assumes bond's mac address has not yet changed.
+  */
+-static inline int
+-alb_set_mac_address(struct bonding *bond, void *addr)
++static int alb_set_mac_address(struct bonding *bond, void *addr)
+ {
+       struct sockaddr sa;
+-      struct slave *slave;
++      struct slave *slave, *stop_at;
+       char tmp_addr[ETH_ALEN];
+-      int error;
++      int res;
++      int i;
+       if (bond->alb_info.rlb_enabled) {
+               return 0;
+       }
+-      slave = bond_get_first_slave(bond);
+-      for (; slave; slave = bond_get_next_slave(bond, slave)) {
++      bond_for_each_slave(bond, slave, i) {
+               if (slave->dev->set_mac_address == NULL) {
+-                      error = -EOPNOTSUPP;
++                      res = -EOPNOTSUPP;
+                       goto unwind;
+               }
+               /* save net_device's current hw address */
+               memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
+-              error = slave->dev->set_mac_address(slave->dev, addr);
++              res = slave->dev->set_mac_address(slave->dev, addr);
+               /* restore net_device's hw address */
+               memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
+-              if (error) {
++              if (res) {
+                       goto unwind;
+               }
+       }
+@@ -1226,22 +1119,23 @@ alb_set_mac_address(struct bonding *bond
+       return 0;
+ unwind:
+-      memcpy(sa.sa_data, bond->device->dev_addr, bond->device->addr_len);
+-      sa.sa_family = bond->device->type;
+-      slave = bond_get_first_slave(bond);
+-      for (; slave; slave = bond_get_next_slave(bond, slave)) {
++      memcpy(sa.sa_data, bond->dev->dev_addr, bond->dev->addr_len);
++      sa.sa_family = bond->dev->type;
++
++      /* unwind from head to the slave that failed */
++      stop_at = slave;
++      bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
+               memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
+               slave->dev->set_mac_address(slave->dev, &sa);
+               memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
+       }
+-      return error;
++      return res;
+ }
+ /************************ exported alb funcions ************************/
+-int
+-bond_alb_initialize(struct bonding *bond, int rlb_enabled)
++int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
+ {
+       int res;
+@@ -1263,8 +1157,7 @@ bond_alb_initialize(struct bonding *bond
+       return 0;
+ }
+-void
+-bond_alb_deinitialize(struct bonding *bond)
++void bond_alb_deinitialize(struct bonding *bond)
+ {
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+@@ -1275,49 +1168,38 @@ bond_alb_deinitialize(struct bonding *bo
+       }
+ }
+-int
+-bond_alb_xmit(struct sk_buff *skb, struct net_device *dev)
++int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
+ {
+-      struct bonding *bond = (struct bonding *) dev->priv;
+-      struct ethhdr *eth_data = (struct ethhdr *)skb->data;
++      struct bonding *bond = bond_dev->priv;
++      struct ethhdr *eth_data = (struct ethhdr *)skb->mac.raw = skb->data;
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+       struct slave *tx_slave = NULL;
+-      char do_tx_balance = 1;
++      static u32 ip_bcast = 0xffffffff;
+       int hash_size = 0;
++      int do_tx_balance = 1;
+       u32 hash_index = 0;
+       u8 *hash_start = NULL;
+-      u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+-
+-      if (!IS_UP(dev)) { /* bond down */
+-              dev_kfree_skb(skb);
+-              return 0;
+-      }
+-      /* make sure that the current_slave and the slaves list do
++      /* make sure that the curr_active_slave and the slaves list do
+        * not change during tx
+        */
+       read_lock(&bond->lock);
++      read_lock(&bond->curr_slave_lock);
+-      if (bond->slave_cnt == 0) {
+-              /* no suitable interface, frame not sent */
+-              dev_kfree_skb(skb);
+-              read_unlock(&bond->lock);
+-              return 0;
++      if (!BOND_IS_OK(bond)) {
++              goto free_out;
+       }
+-      read_lock(&bond->ptrlock);
+-
+       switch (ntohs(skb->protocol)) {
+       case ETH_P_IP:
+               if ((memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) ||
+-                  (skb->nh.iph->daddr == 0xffffffff)) {
++                  (skb->nh.iph->daddr == ip_bcast)) {
+                       do_tx_balance = 0;
+                       break;
+               }
+               hash_start = (char*)&(skb->nh.iph->daddr);
+-              hash_size = 4;
++              hash_size = sizeof(skb->nh.iph->daddr);
+               break;
+-
+       case ETH_P_IPV6:
+               if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) {
+                       do_tx_balance = 0;
+@@ -1325,9 +1207,8 @@ bond_alb_xmit(struct sk_buff *skb, struc
+               }
+               hash_start = (char*)&(skb->nh.ipv6h->daddr);
+-              hash_size = 16;
++              hash_size = sizeof(skb->nh.ipv6h->daddr);
+               break;
+-
+       case ETH_P_IPX:
+               if (ipx_hdr(skb)->ipx_checksum !=
+                   __constant_htons(IPX_NO_CHECKSUM)) {
+@@ -1349,14 +1230,12 @@ bond_alb_xmit(struct sk_buff *skb, struc
+               hash_start = (char*)eth_data->h_dest;
+               hash_size = ETH_ALEN;
+               break;
+-
+       case ETH_P_ARP:
+               do_tx_balance = 0;
+               if (bond_info->rlb_enabled) {
+                       tx_slave = rlb_arp_xmit(skb, bond);
+               }
+               break;
+-
+       default:
+               do_tx_balance = 0;
+               break;
+@@ -1369,16 +1248,16 @@ bond_alb_xmit(struct sk_buff *skb, struc
+       if (!tx_slave) {
+               /* unbalanced or unassigned, send through primary */
+-              tx_slave = bond->current_slave;
++              tx_slave = bond->curr_active_slave;
+               bond_info->unbalanced_load += skb->len;
+       }
+       if (tx_slave && SLAVE_IS_OK(tx_slave)) {
+               skb->dev = tx_slave->dev;
+-              if (tx_slave != bond->current_slave) {
++              if (tx_slave != bond->curr_active_slave) {
+                       memcpy(eth_data->h_source,
+-                              tx_slave->dev->dev_addr,
+-                              ETH_ALEN);
++                             tx_slave->dev->dev_addr,
++                             ETH_ALEN);
+               }
+               dev_queue_xmit(skb);
+       } else {
+@@ -1386,26 +1265,35 @@ bond_alb_xmit(struct sk_buff *skb, struc
+               if (tx_slave) {
+                       tlb_clear_slave(bond, tx_slave, 0);
+               }
+-              dev_kfree_skb(skb);
++              goto free_out;
+       }
+-      read_unlock(&bond->ptrlock);
++out:
++      read_unlock(&bond->curr_slave_lock);
+       read_unlock(&bond->lock);
+       return 0;
++
++free_out:
++      dev_kfree_skb(skb);
++      goto out;
+ }
+-void
+-bond_alb_monitor(struct bonding *bond)
++void bond_alb_monitor(struct bonding *bond)
+ {
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+-      struct slave *slave = NULL;
++      struct slave *slave;
++      int i;
+       read_lock(&bond->lock);
+-      if ((bond->slave_cnt == 0) || !(bond->device->flags & IFF_UP)) {
++      if (bond->kill_timers) {
++              goto out;
++      }
++
++      if (bond->slave_cnt == 0) {
+               bond_info->tx_rebalance_counter = 0;
+               bond_info->lp_counter = 0;
+-              goto out;
++              goto re_arm;
+       }
+       bond_info->tx_rebalance_counter++;
+@@ -1413,51 +1301,53 @@ bond_alb_monitor(struct bonding *bond)
+       /* send learning packets */
+       if (bond_info->lp_counter >= BOND_ALB_LP_TICKS) {
+-              /* change of current_slave involves swapping of mac addresses.
++              /* change of curr_active_slave involves swapping of mac addresses.
+                * in order to avoid this swapping from happening while
+-               * sending the learning packets, the ptrlock must be held for
++               * sending the learning packets, the curr_slave_lock must be held for
+                * read.
+                */
+-              read_lock(&bond->ptrlock);
+-              slave = bond_get_first_slave(bond);
+-              while (slave) {
++              read_lock(&bond->curr_slave_lock);
++
++              bond_for_each_slave(bond, slave, i) {
+                       alb_send_learning_packets(slave,slave->dev->dev_addr);
+-                      slave = bond_get_next_slave(bond, slave);
+               }
+-              read_unlock(&bond->ptrlock);
++
++              read_unlock(&bond->curr_slave_lock);
+               bond_info->lp_counter = 0;
+       }
+       /* rebalance tx traffic */
+       if (bond_info->tx_rebalance_counter >= BOND_TLB_REBALANCE_TICKS) {
+-              read_lock(&bond->ptrlock);
+-              slave = bond_get_first_slave(bond);
+-              while (slave) {
++
++              read_lock(&bond->curr_slave_lock);
++
++              bond_for_each_slave(bond, slave, i) {
+                       tlb_clear_slave(bond, slave, 1);
+-                      if (slave == bond->current_slave) {
++                      if (slave == bond->curr_active_slave) {
+                               SLAVE_TLB_INFO(slave).load =
+                                       bond_info->unbalanced_load /
+                                               BOND_TLB_REBALANCE_INTERVAL;
+                               bond_info->unbalanced_load = 0;
+                       }
+-                      slave = bond_get_next_slave(bond, slave);
+               }
+-              read_unlock(&bond->ptrlock);
++
++              read_unlock(&bond->curr_slave_lock);
++
+               bond_info->tx_rebalance_counter = 0;
+       }
+       /* handle rlb stuff */
+       if (bond_info->rlb_enabled) {
+               /* the following code changes the promiscuity of the
+-               * the current_slave. It needs to be locked with a
++               * the curr_active_slave. It needs to be locked with a
+                * write lock to protect from other code that also
+                * sets the promiscuity.
+                */
+-              write_lock(&bond->ptrlock);
++              write_lock(&bond->curr_slave_lock);
++
+               if (bond_info->primary_is_promisc &&
+-                  (++bond_info->rlb_promisc_timeout_counter >=
+-                      RLB_PROMISC_TIMEOUT)) {
++                  (++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) {
+                       bond_info->rlb_promisc_timeout_counter = 0;
+@@ -1465,12 +1355,13 @@ bond_alb_monitor(struct bonding *bond)
+                        * because a slave was disabled then
+                        * it can now leave promiscuous mode.
+                        */
+-                      dev_set_promiscuity(bond->current_slave->dev, -1);
++                      dev_set_promiscuity(bond->curr_active_slave->dev, -1);
+                       bond_info->primary_is_promisc = 0;
+               }
+-              write_unlock(&bond->ptrlock);
+-              if (bond_info->rlb_rebalance == 1) {
++              write_unlock(&bond->curr_slave_lock);
++
++              if (bond_info->rlb_rebalance) {
+                       bond_info->rlb_rebalance = 0;
+                       rlb_rebalance(bond);
+               }
+@@ -1490,28 +1381,23 @@ bond_alb_monitor(struct bonding *bond)
+               }
+       }
++re_arm:
++      mod_timer(&(bond_info->alb_timer), jiffies + alb_delta_in_ticks);
+ out:
+       read_unlock(&bond->lock);
+-
+-      if (bond->device->flags & IFF_UP) {
+-              /* re-arm the timer */
+-              mod_timer(&(bond_info->alb_timer),
+-                      jiffies + (HZ/ALB_TIMER_TICKS_PER_SEC));
+-      }
+ }
+-/* assumption: called before the slave is attched to the bond
++/* assumption: called before the slave is attached to the bond
+  * and not locked by the bond lock
+  */
+-int
+-bond_alb_init_slave(struct bonding *bond, struct slave *slave)
++int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
+ {
+-      int err = 0;
++      int res;
+-      err = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
++      res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
+                                    bond->alb_info.rlb_enabled);
+-      if (err) {
+-              return err;
++      if (res) {
++              return res;
+       }
+       /* caller must hold the bond lock for write since the mac addresses
+@@ -1519,12 +1405,12 @@ bond_alb_init_slave(struct bonding *bond
+        */
+       write_lock_bh(&bond->lock);
+-      err = alb_handle_addr_collision_on_attach(bond, slave);
++      res = alb_handle_addr_collision_on_attach(bond, slave);
+       write_unlock_bh(&bond->lock);
+-      if (err) {
+-              return err;
++      if (res) {
++              return res;
+       }
+       tlb_init_slave(slave);
+@@ -1540,8 +1426,7 @@ bond_alb_init_slave(struct bonding *bond
+ }
+ /* Caller must hold bond lock for write */
+-void
+-bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
++void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
+ {
+       if (bond->slave_cnt > 1) {
+               alb_change_hw_addr_on_detach(bond, slave);
+@@ -1556,9 +1441,7 @@ bond_alb_deinit_slave(struct bonding *bo
+ }
+ /* Caller must hold bond lock for read */
+-void
+-bond_alb_handle_link_change(struct bonding *bond, struct slave *slave,
+-                          char link)
++void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link)
+ {
+       struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+@@ -1582,109 +1465,111 @@ bond_alb_handle_link_change(struct bondi
+ }
+ /**
+- * bond_alb_assign_current_slave - assign new current_slave
++ * bond_alb_handle_active_change - assign new curr_active_slave
+  * @bond: our bonding struct
+  * @new_slave: new slave to assign
+  *
+- * Set the bond->current_slave to @new_slave and handle
++ * Set the bond->curr_active_slave to @new_slave and handle
+  * mac address swapping and promiscuity changes as needed.
+  *
+- * Caller must hold bond ptrlock for write (or bond lock for write)
++ * Caller must hold bond curr_slave_lock for write (or bond lock for write)
+  */
+-void
+-bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave)
++void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave)
+ {
+-      struct slave *swap_slave = bond->current_slave;
++      struct slave *swap_slave;
++      int i;
+-      if (bond->current_slave == new_slave) {
++      if (bond->curr_active_slave == new_slave) {
+               return;
+       }
+-      if (bond->current_slave && bond->alb_info.primary_is_promisc) {
+-              dev_set_promiscuity(bond->current_slave->dev, -1);
++      if (bond->curr_active_slave && bond->alb_info.primary_is_promisc) {
++              dev_set_promiscuity(bond->curr_active_slave->dev, -1);
+               bond->alb_info.primary_is_promisc = 0;
+               bond->alb_info.rlb_promisc_timeout_counter = 0;
+       }
+-      bond->current_slave = new_slave;
++      swap_slave = bond->curr_active_slave;
++      bond->curr_active_slave = new_slave;
+       if (!new_slave || (bond->slave_cnt == 0)) {
+               return;
+       }
+-      /* set the new current_slave to the bonds mac address
+-       * i.e. swap mac addresses of old current_slave and new current_slave
++      /* set the new curr_active_slave to the bonds mac address
++       * i.e. swap mac addresses of old curr_active_slave and new curr_active_slave
+        */
+       if (!swap_slave) {
++              struct slave *tmp_slave;
+               /* find slave that is holding the bond's mac address */
+-              swap_slave = bond_get_first_slave(bond);
+-              while (swap_slave) {
+-                      if (!memcmp(swap_slave->dev->dev_addr,
+-                              bond->device->dev_addr, ETH_ALEN)) {
++              bond_for_each_slave(bond, tmp_slave, i) {
++                      if (!memcmp(tmp_slave->dev->dev_addr,
++                                  bond->dev->dev_addr, ETH_ALEN)) {
++                              swap_slave = tmp_slave;
+                               break;
+                       }
+-                      swap_slave = bond_get_next_slave(bond, swap_slave);
+               }
+       }
+-      /* current_slave must be set before calling alb_swap_mac_addr */
++      /* curr_active_slave must be set before calling alb_swap_mac_addr */
+       if (swap_slave) {
+               /* swap mac address */
+               alb_swap_mac_addr(bond, swap_slave, new_slave);
+       } else {
+               /* set the new_slave to the bond mac address */
+-              alb_set_slave_mac_addr(new_slave, bond->device->dev_addr,
++              alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr,
+                                      bond->alb_info.rlb_enabled);
+               /* fasten bond mac on new current slave */
+-              alb_send_learning_packets(new_slave, bond->device->dev_addr);
++              alb_send_learning_packets(new_slave, bond->dev->dev_addr);
+       }
+ }
+-int
+-bond_alb_set_mac_address(struct net_device *dev, void *addr)
++int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
+ {
+-      struct bonding *bond = dev->priv;
++      struct bonding *bond = bond_dev->priv;
+       struct sockaddr *sa = addr;
+-      struct slave *swap_slave = NULL;
+-      int error = 0;
++      struct slave *slave, *swap_slave;
++      int res;
++      int i;
+       if (!is_valid_ether_addr(sa->sa_data)) {
+               return -EADDRNOTAVAIL;
+       }
+-      error = alb_set_mac_address(bond, addr);
+-      if (error) {
+-              return error;
++      res = alb_set_mac_address(bond, addr);
++      if (res) {
++              return res;
+       }
+-      memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
++      memcpy(bond_dev->dev_addr, sa->sa_data, bond_dev->addr_len);
+-      /* If there is no current_slave there is nothing else to do.
++      /* If there is no curr_active_slave there is nothing else to do.
+        * Otherwise we'll need to pass the new address to it and handle
+        * duplications.
+        */
+-      if (bond->current_slave == NULL) {
++      if (!bond->curr_active_slave) {
+               return 0;
+       }
+-      swap_slave = bond_get_first_slave(bond);
+-      while (swap_slave) {
+-              if (!memcmp(swap_slave->dev->dev_addr, dev->dev_addr, ETH_ALEN)) {
++      swap_slave = NULL;
++
++      bond_for_each_slave(bond, slave, i) {
++              if (!memcmp(slave->dev->dev_addr, bond_dev->dev_addr, ETH_ALEN)) {
++                      swap_slave = slave;
+                       break;
+               }
+-              swap_slave = bond_get_next_slave(bond, swap_slave);
+       }
+       if (swap_slave) {
+-              alb_swap_mac_addr(bond, swap_slave, bond->current_slave);
++              alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave);
+       } else {
+-              alb_set_slave_mac_addr(bond->current_slave, dev->dev_addr,
++              alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr,
+                                      bond->alb_info.rlb_enabled);
+-              alb_send_learning_packets(bond->current_slave, dev->dev_addr);
++              alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr);
+               if (bond->alb_info.rlb_enabled) {
+                       /* inform clients mac address has changed */
+-                      rlb_req_update_slave_clients(bond, bond->current_slave);
++                      rlb_req_update_slave_clients(bond, bond->curr_active_slave);
+               }
+       }
+--- linux-2.6.0/drivers/net/bonding/bond_alb.h 2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/bonding/bond_alb.h  2003-12-28 23:21:00.000000000 -0800
+@@ -24,6 +24,9 @@
+  * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
+  *    - Add support for setting bond's MAC address with special
+  *      handling required for ALB/TLB.
++ *
++ * 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
++ *    - Code cleanup and style changes
+  */
+ #ifndef __BOND_ALB_H__
+@@ -126,10 +129,10 @@ void bond_alb_deinitialize(struct bondin
+ int bond_alb_init_slave(struct bonding *bond, struct slave *slave);
+ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave);
+ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link);
+-void bond_alb_assign_current_slave(struct bonding *bond, struct slave *new_slave);
+-int bond_alb_xmit(struct sk_buff *skb, struct net_device *dev);
++void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave);
++int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
+ void bond_alb_monitor(struct bonding *bond);
+-int bond_alb_set_mac_address(struct net_device *dev, void *addr);
++int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
+ #endif /* __BOND_ALB_H__ */
+--- linux-2.6.0/drivers/net/bonding/bonding.h  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/bonding/bonding.h   2003-12-28 23:21:00.000000000 -0800
+@@ -9,7 +9,7 @@
+  *
+  *    This software may be used and distributed according to the terms
+  *    of the GNU Public License, incorporated herein by reference.
+- * 
++ *
+  *
+  * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
+  *            Tsippy Mendelson <tsippy.mendelson at intel dot com> and
+@@ -22,159 +22,205 @@
+  *
+  * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
+  *    - Added support for Transmit load balancing mode.
++ *
++ * 2003/09/24 - Shmulik Hen <shmulik.hen at intel dot com>
++ *    - Code cleanup and style changes
+  */
+- 
++
+ #ifndef _LINUX_BONDING_H
+ #define _LINUX_BONDING_H
+ #include <linux/timer.h>
+ #include <linux/proc_fs.h>
++#include <linux/if_bonding.h>
+ #include "bond_3ad.h"
+ #include "bond_alb.h"
+-#ifdef BONDING_DEBUG
+-
+-// use this like so: BOND_PRINT_DBG(("foo = %d, bar = %d", foo, bar));
+-#define BOND_PRINT_DBG(X)                                     \
+-do {                                                          \
+-      printk(KERN_DEBUG "%s (%d)", __FUNCTION__, __LINE__); \
+-      printk X;                                             \
+-      printk("\n");                                         \
+-} while(0)
++#define DRV_VERSION   "2.5.0"
++#define DRV_RELDATE   "December 1, 2003"
++#define DRV_NAME      "bonding"
++#define DRV_DESCRIPTION       "Ethernet Channel Bonding Driver"
++#ifdef BONDING_DEBUG
++#define dprintk(fmt, args...) \
++      printk(KERN_DEBUG     \
++             DRV_NAME ": %s() %d: " fmt, __FUNCTION__, __LINE__ , ## args )
+ #else
+-#define BOND_PRINT_DBG(X)
++#define dprintk(fmt, args...)
+ #endif /* BONDING_DEBUG */
+-#define IS_UP(dev)  ((((dev)->flags & (IFF_UP)) == (IFF_UP)) && \
+-                   (netif_running(dev) && netif_carrier_ok(dev)))
++#define IS_UP(dev)                                       \
++            ((((dev)->flags & IFF_UP) == IFF_UP)      && \
++             netif_running(dev)                       && \
++             netif_carrier_ok(dev))
+-/* Checks whether the dev is ready for transmit. We do not check netif_running
+- * since a device can be stopped by the driver for short periods of time for
+- * maintainance. dev_queue_xmit() handles this by queing the packet until the
+- * the dev is running again. Keeping packets ordering requires sticking the
+- * same dev as much as possible
+- */
+-#define SLAVE_IS_OK(slave) \
+-                   ((((slave)->dev->flags & (IFF_UP)) == (IFF_UP)) && \
+-                   netif_carrier_ok((slave)->dev) && \
++/*
++ * Checks whether bond is ready for transmit.
++ *
++ * Caller must hold bond->lock
++ */
++#define BOND_IS_OK(bond)                           \
++                 (((bond)->dev->flags & IFF_UP) && \
++                  netif_running((bond)->dev)    && \
++                  ((bond)->slave_cnt > 0))
++
++/*
++ * Checks whether slave is ready for transmit.
++ */
++#define SLAVE_IS_OK(slave)                            \
++                  (((slave)->dev->flags & IFF_UP)  && \
++                   netif_running((slave)->dev)     && \
+                    ((slave)->link == BOND_LINK_UP) && \
+                    ((slave)->state == BOND_STATE_ACTIVE))
+-typedef struct slave {
++#define USES_PRIMARY(mode)                            \
++              (((mode) == BOND_MODE_ACTIVEBACKUP) ||  \
++               ((mode) == BOND_MODE_TLB)          ||  \
++               ((mode) == BOND_MODE_ALB))
++
++/*
++ * Less bad way to call ioctl from within the kernel; this needs to be
++ * done some other way to get the call out of interrupt context.
++ * Needs "ioctl" variable to be supplied by calling context.
++ */
++#define IOCTL(dev, arg, cmd) ({               \
++      int res = 0;                    \
++      mm_segment_t fs = get_fs();     \
++      set_fs(get_ds());               \
++      res = ioctl(dev, arg, cmd);     \
++      set_fs(fs);                     \
++      res; })
++
++/**
++ * bond_for_each_slave_from - iterate the slaves list from a starting point
++ * @bond:     the bond holding this list.
++ * @pos:      current slave.
++ * @cnt:      counter for max number of moves
++ * @start:    starting point.
++ *
++ * Caller must hold bond->lock
++ */
++#define bond_for_each_slave_from(bond, pos, cnt, start)       \
++      for (cnt = 0, pos = start;                              \
++           cnt < (bond)->slave_cnt;                           \
++             cnt++, pos = (pos)->next)
++
++/**
++ * bond_for_each_slave_from_to - iterate the slaves list from start point to stop point
++ * @bond:     the bond holding this list.
++ * @pos:      current slave.
++ * @cnt:      counter for number max of moves
++ * @start:    start point.
++ * @stop:     stop point.
++ *
++ * Caller must hold bond->lock
++ */
++#define bond_for_each_slave_from_to(bond, pos, cnt, start, stop)      \
++      for (cnt = 0, pos = start;                                      \
++           ((cnt < (bond)->slave_cnt) && (pos != (stop)->next));      \
++             cnt++, pos = (pos)->next)
++
++/**
++ * bond_for_each_slave - iterate the slaves list from head
++ * @bond:     the bond holding this list.
++ * @pos:      current slave.
++ * @cnt:      counter for max number of moves
++ *
++ * Caller must hold bond->lock
++ */
++#define bond_for_each_slave(bond, pos, cnt)   \
++              bond_for_each_slave_from(bond, pos, cnt, (bond)->first_slave)
++
++
++struct slave {
++      struct net_device *dev; /* first - usefull for panic debug */
+       struct slave *next;
+       struct slave *prev;
+-      struct net_device *dev;
+-      short  delay;
+-      unsigned long jiffies;
+-      char   link;    /* one of BOND_LINK_XXXX */
+-      char   state;   /* one of BOND_STATE_XXXX */
+-      unsigned short original_flags;
+-      u32 link_failure_count;
++      s16    delay;
++      u32    jiffies;
++      s8     link;    /* one of BOND_LINK_XXXX */
++      s8     state;   /* one of BOND_STATE_XXXX */
++      u32    original_flags;
++      u32    link_failure_count;
+       u16    speed;
+       u8     duplex;
+       u8     perm_hwaddr[ETH_ALEN];
+       struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
+       struct tlb_slave_info tlb_info;
+-} slave_t;
++};
+ /*
+  * Here are the locking policies for the two bonding locks:
+  *
+  * 1) Get bond->lock when reading/writing slave list.
+- * 2) Get bond->ptrlock when reading/writing bond->current_slave.
++ * 2) Get bond->curr_slave_lock when reading/writing bond->curr_active_slave.
+  *    (It is unnecessary when the write-lock is put with bond->lock.)
+- * 3) When we lock with bond->ptrlock, we must lock with bond->lock
++ * 3) When we lock with bond->curr_slave_lock, we must lock with bond->lock
+  *    beforehand.
+  */
+-typedef struct bonding {
+-      slave_t *next;
+-      slave_t *prev;
+-      slave_t *current_slave;
+-      slave_t *primary_slave;
+-      slave_t *current_arp_slave;
+-      __s32 slave_cnt;
++struct bonding {
++      struct   net_device *dev; /* first - usefull for panic debug */
++      struct   slave *first_slave;
++      struct   slave *curr_active_slave;
++      struct   slave *current_arp_slave;
++      struct   slave *primary_slave;
++      s32      slave_cnt; /* never change this value outside the attach/detach wrappers */
+       rwlock_t lock;
+-      rwlock_t ptrlock;
+-      struct timer_list mii_timer;
+-      struct timer_list arp_timer;
+-      struct net_device_stats stats;
++      rwlock_t curr_slave_lock;
++      struct   timer_list mii_timer;
++      struct   timer_list arp_timer;
++      s8       kill_timers;
++      struct   net_device_stats stats;
+ #ifdef CONFIG_PROC_FS
+-      struct proc_dir_entry *bond_proc_file;
+-      char procdir_name[IFNAMSIZ];
++      struct   proc_dir_entry *proc_entry;
++      char     proc_file_name[IFNAMSIZ];
+ #endif /* CONFIG_PROC_FS */
+-      struct list_head bond_list;
+-      struct net_device *device;
+-      struct dev_mc_list *mc_list;
+-      unsigned short flags;
+-      struct ad_bond_info ad_info;
+-      struct alb_bond_info alb_info;
+-} bonding_t;
+-
+-/* Forward declarations */
+-void bond_set_slave_active_flags(slave_t *slave);
+-void bond_set_slave_inactive_flags(slave_t *slave);
+-
+-/**
+- * These functions can be used for iterating the slave list
+- * (which is circular)
+- * Caller must hold bond lock for read
+- */
+-extern inline struct slave*
+-bond_get_first_slave(struct bonding *bond)
+-{
+-      /* if there are no slaves return NULL */
+-      if (bond->next == (slave_t *)bond) {
+-              return NULL;
+-      }
+-      return bond->next;
+-}
+-
+-/**
+- * Caller must hold bond lock for read
+- */
+-extern inline struct slave*
+-bond_get_next_slave(struct bonding *bond, struct slave *slave)
+-{
+-      /* If we have reached the last slave return NULL */
+-      if (slave->next == bond->next) {
+-              return NULL;
+-      }
+-      return slave->next;
+-}
++      struct   list_head bond_list;
++      struct   dev_mc_list *mc_list;
++      u16      flags;
++      struct   ad_bond_info ad_info;
++      struct   alb_bond_info alb_info;
++};
+ /**
+  * Returns NULL if the net_device does not belong to any of the bond's slaves
+  *
+  * Caller must hold bond lock for read
+  */
+-extern inline struct slave*
+-bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev)
++extern inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev)
+ {
+-      struct slave *our_slave = bond->next;
+-
+-      /* check if the list of slaves is empty */
+-      if (our_slave == (slave_t *)bond) {
+-              return NULL;
+-      }
++      struct slave *slave = NULL;
++      int i;
+-      for (; our_slave; our_slave = bond_get_next_slave(bond, our_slave)) {
+-              if (our_slave->dev == slave_dev) {
++      bond_for_each_slave(bond, slave, i) {
++              if (slave->dev == slave_dev) {
+                       break;
+               }
+       }
+-      return our_slave;
++
++      return slave;
+ }
+-extern inline struct bonding*
+-bond_get_bond_by_slave(struct slave *slave)
++extern inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
+ {
+       if (!slave || !slave->dev->master) {
+               return NULL;
+       }
+-      return (struct bonding *)(slave->dev->master->priv);
++      return (struct bonding *)slave->dev->master->priv;
++}
++
++extern inline void bond_set_slave_inactive_flags(struct slave *slave)
++{
++      slave->state = BOND_STATE_BACKUP;
++      slave->dev->flags |= IFF_NOARP;
++}
++
++extern inline void bond_set_slave_active_flags(struct slave *slave)
++{
++      slave->state = BOND_STATE_ACTIVE;
++      slave->dev->flags &= ~IFF_NOARP;
+ }
+ #endif /* _LINUX_BONDING_H */
+--- linux-2.6.0/drivers/net/bonding/bond_main.c        2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/bonding/bond_main.c 2003-12-28 23:21:05.000000000 -0800
+@@ -1,7 +1,7 @@
+ /*
+  * originally based on the dummy device.
+  *
+- * Copyright 1999, Thomas Davis, tadavis@lbl.gov.  
++ * Copyright 1999, Thomas Davis, tadavis@lbl.gov.
+  * Licensed under the GPL. Based on dummy.c, and eql.c devices.
+  *
+  * bonding.c: an Ethernet Bonding driver
+@@ -15,9 +15,9 @@
+  *
+  * How it works:
+  *    ifconfig bond0 ipaddress netmask up
+- *      will setup a network device, with an ip address.  No mac address 
+- *    will be assigned at this time.  The hw mac address will come from 
+- *    the first slave bonded to the channel.  All slaves will then use 
++ *      will setup a network device, with an ip address.  No mac address
++ *    will be assigned at this time.  The hw mac address will come from
++ *    the first slave bonded to the channel.  All slaves will then use
+  *    this hw mac address.
+  *
+  *    ifconfig bond0 down
+@@ -26,7 +26,7 @@
+  *    ifenslave bond0 eth0
+  *    will attach eth0 to bond0 as a slave.  eth0 hw mac address will either
+  *    a: be used as initial mac address
+- *    b: if a hw mac address already is there, eth0's hw mac address 
++ *    b: if a hw mac address already is there, eth0's hw mac address
+  *       will then be set from bond0.
+  *
+  * v0.1 - first working version.
+@@ -93,14 +93,14 @@
+  *
+  * 2001/4/5 - Chad N. Tindel <ctindel at ieee dot org>
+  *     - Ported to 2.4 Kernel
+- * 
++ *
+  * 2001/5/2 - Jeffrey E. Mast <jeff at mastfamily dot com>
+  *     - When a device is detached from a bond, the slave device is no longer
+  *       left thinking that is has a master.
+  *
+  * 2001/5/16 - Jeffrey E. Mast <jeff at mastfamily dot com>
+- *     - memset did not appropriately initialized the bond rw_locks. Used 
+- *       rwlock_init to initialize to unlocked state to prevent deadlock when 
++ *     - memset did not appropriately initialized the bond rw_locks. Used
++ *       rwlock_init to initialize to unlocked state to prevent deadlock when
+  *       first attempting a lock
+  *     - Called SET_MODULE_OWNER for bond device
+  *
+@@ -119,7 +119,7 @@
+  *
+  * 2001/6/01 - Chad N. Tindel <ctindel at ieee dot org>
+  *     - Added /proc support for getting bond and slave information.
+- *       Information is in /proc/net/<bond device>/info. 
++ *       Information is in /proc/net/<bond device>/info.
+  *     - Changed the locking when calling bond_close to prevent deadlock.
+  *
+  * 2001/8/05 - Janice Girouard <girouard at us.ibm.com>
+@@ -144,8 +144,8 @@
+  *       but only for an up link.
+  *
+  * 2001/9/20 - Chad N. Tindel <ctindel at ieee dot org>
+- *     - Add the device field to bonding_t.  Previously the net_device 
+- *       corresponding to a bond wasn't available from the bonding_t 
++ *     - Add the device field to bonding_t.  Previously the net_device
++ *       corresponding to a bond wasn't available from the bonding_t
+  *       structure.
+  *
+  * 2001/9/25 - Janice Girouard <girouard at us.ibm.com>
+@@ -155,10 +155,10 @@
+  *     - Various memory leak fixes
+  *
+  * 2001/11/5 - Mark Huth <mark dot huth at mvista dot com>
+- *     - Don't take rtnl lock in bond_mii_monitor as it deadlocks under 
+- *       certain hotswap conditions.  
++ *     - Don't take rtnl lock in bond_mii_monitor as it deadlocks under
++ *       certain hotswap conditions.
+  *       Note:  this same change may be required in bond_arp_monitor ???
+- *     - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr 
++ *     - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr
+  *     - Handle hot swap ethernet interface deregistration events to remove
+  *       kernel oops following hot swap of enslaved interface
+  *
+@@ -222,23 +222,23 @@
+  *     - fix deletion of multicast groups after unloading module
+  *
+  * 2002/11/06 - Kameshwara Rayaprolu <kameshwara.rao * wipro_com>
+- *     - Changes to prevent panic from closing the device twice; if we close 
+- *       the device in bond_release, we must set the original_flags to down 
++ *     - Changes to prevent panic from closing the device twice; if we close
++ *       the device in bond_release, we must set the original_flags to down
+  *       so it won't be closed again by the network layer.
+  *
+  * 2002/11/07 - Tony Cureington <tony.cureington * hp_com>
+  *     - Fix arp_target_hw_addr memory leak
+- *     - Created activebackup_arp_monitor function to handle arp monitoring 
+- *       in active backup mode - the bond_arp_monitor had several problems... 
+- *       such as allowing slaves to tx arps sequentially without any delay 
++ *     - Created activebackup_arp_monitor function to handle arp monitoring
++ *       in active backup mode - the bond_arp_monitor had several problems...
++ *       such as allowing slaves to tx arps sequentially without any delay
+  *       for a response
+  *     - Renamed bond_arp_monitor to loadbalance_arp_monitor and re-wrote
+  *       this function to just handle arp monitoring in load-balancing mode;
+  *       it is a lot more compact now
+- *     - Changes to ensure one and only one slave transmits in active-backup 
++ *     - Changes to ensure one and only one slave transmits in active-backup
+  *       mode
+- *     - Robustesize parameters; warn users about bad combinations of 
+- *       parameters; also if miimon is specified and a network driver does 
++ *     - Robustesize parameters; warn users about bad combinations of
++ *       parameters; also if miimon is specified and a network driver does
+  *       not support MII or ETHTOOL, inform the user of this
+  *     - Changes to support link_failure_count when in arp monitoring mode
+  *     - Fix up/down delay reported in /proc
+@@ -248,7 +248,7 @@
+  *
+  * 2002/11/16 - Laurent Deniel <laurent.deniel at free.fr>
+  *     - fix multicast handling in activebackup_arp_monitor
+- *     - remove one unnecessary and confusing current_slave == slave test 
++ *     - remove one unnecessary and confusing curr_active_slave == slave test
+  *     in activebackup_arp_monitor
+  *
+  *  2002/11/17 - Laurent Deniel <laurent.deniel at free.fr>
+@@ -267,7 +267,7 @@
+  *      One change: an invalid choice will cause module load failure,
+  *      rather than the previous behavior of just picking one.
+  *    - Minor cleanups; got rid of dup ctype stuff, atoi function
+- * 
++ *
+  * 2003/02/07 - Jay Vosburgh <fubar at us dot ibm dot com>
+  *    - Added use_carrier module parameter that causes miimon to
+  *      use netif_carrier_ok() test instead of MII/ETHTOOL ioctls.
+@@ -330,7 +330,7 @@
+  *      new/old ifenslave and new/old bonding.
+  *
+  * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
+- *    - Fixed bug in bond_release_all(): save old value of current_slave
++ *    - Fixed bug in bond_release_all(): save old value of curr_active_slave
+  *      before setting it to NULL.
+  *    - Changed driver versioning scheme to include version number instead
+  *      of release date (that is already in another field). There are 3
+@@ -358,7 +358,7 @@
+  *
+  * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
+  *    - Added support for Transmit load balancing mode.
+- *    - Concentrate all assignments of current_slave to a single point
++ *    - Concentrate all assignments of curr_active_slave to a single point
+  *      so specific modes can take actions when the primary adapter is
+  *      changed.
+  *    - Take the updelay parameter into consideration during bond_enslave
+@@ -426,8 +426,36 @@
+  *    - Convert /proc to seq_file interface.
+  *      Change /proc/net/bondX/info to /proc/net/bonding/bondX.
+  *      Set version to 2.4.1.
++ *
++ * 2003/11/20 - Amir Noam <amir.noam at intel dot com>
++ *    - Fix /proc creation/destruction.
++ *
++ * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
++ *    - Massive cleanup - Set version to 2.5.0
++ *      Code changes:
++ *      o Consolidate format of prints and debug prints.
++ *      o Remove bonding_t/slave_t typedefs and consolidate all casts.
++ *      o Remove dead code and unnecessary checks.
++ *      o Consolidate starting/stopping timers.
++ *      o Consolidate handling of primary module param throughout the code.
++ *      o Removed multicast module param support - all settings are done
++ *        according to mode.
++ *      o Slave list iteration - bond is no longer part of the list,
++ *        added cyclic list iteration macros.
++ *      o Consolidate error handling in all xmit functions.
++ *      Style changes:
++ *      o Consolidate function naming and declarations.
++ *      o Consolidate function params and local variables names.
++ *      o Consolidate return values.
++ *      o Consolidate curly braces.
++ *      o Consolidate conditionals format.
++ *      o Change struct member names and types.
++ *      o Chomp trailing spaces, remove empty lines, fix indentations.
++ *      o Re-organize code according to context.
+  */
++//#define BONDING_DEBUG 1
++
+ #include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+@@ -452,7 +480,6 @@
+ #include <asm/dma.h>
+ #include <asm/uaccess.h>
+ #include <linux/errno.h>
+-
+ #include <linux/netdevice.h>
+ #include <linux/inetdevice.h>
+ #include <linux/etherdevice.h>
+@@ -461,58 +488,72 @@
+ #include <linux/rtnetlink.h>
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+-
+-#include <linux/if_bonding.h>
+ #include <linux/smp.h>
+ #include <linux/if_ether.h>
+ #include <net/arp.h>
+ #include <linux/mii.h>
+ #include <linux/ethtool.h>
++#include <linux/if_bonding.h>
+ #include "bonding.h"
+ #include "bond_3ad.h"
+ #include "bond_alb.h"
+-#define DRV_VERSION   "2.4.1"
+-#define DRV_RELDATE   "September 15, 2003"
+-#define DRV_NAME      "bonding"
+-#define DRV_DESCRIPTION       "Ethernet Channel Bonding Driver"
+-
+-static const char *version =
+-DRV_NAME ".c:v" DRV_VERSION " (" DRV_RELDATE ")\n";
++/*---------------------------- Module parameters ----------------------------*/
+ /* monitor all links that often (in milliseconds). <=0 disables monitoring */
+-#ifndef BOND_LINK_MON_INTERV
+ #define BOND_LINK_MON_INTERV  0
+-#endif
+-
+-#ifndef BOND_LINK_ARP_INTERV
+ #define BOND_LINK_ARP_INTERV  0
+-#endif
++#define MAX_ARP_IP_TARGETS    16
+-#ifndef MAX_ARP_IP_TARGETS
+-#define MAX_ARP_IP_TARGETS 16
+-#endif
++static int max_bonds  = BOND_DEFAULT_MAX_BONDS;
++static int miimon     = BOND_LINK_MON_INTERV;
++static int updelay    = 0;
++static int downdelay  = 0;
++static int use_carrier        = 1;
++static char *mode     = NULL;
++static char *primary  = NULL;
++static char *lacp_rate        = NULL;
++static int arp_interval = BOND_LINK_ARP_INTERV;
++static char *arp_ip_target[MAX_ARP_IP_TARGETS] = { NULL, };
++
++MODULE_PARM(max_bonds, "i");
++MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
++MODULE_PARM(miimon, "i");
++MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
++MODULE_PARM(updelay, "i");
++MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds");
++MODULE_PARM(downdelay, "i");
++MODULE_PARM_DESC(downdelay, "Delay before considering link down, in milliseconds");
++MODULE_PARM(use_carrier, "i");
++MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)");
++MODULE_PARM(mode, "s");
++MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor");
++MODULE_PARM(primary, "s");
++MODULE_PARM_DESC(primary, "Primary network device to use");
++MODULE_PARM(lacp_rate, "s");
++MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)");
++MODULE_PARM(arp_interval, "i");
++MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
++MODULE_PARM(arp_ip_target, "1-" __MODULE_STRING(MAX_ARP_IP_TARGETS) "s");
++MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
+-#define USES_PRIMARY(mode) \
+-              (((mode) == BOND_MODE_ACTIVEBACKUP) || \
+-               ((mode) == BOND_MODE_TLB) || \
+-               ((mode) == BOND_MODE_ALB))
++/*----------------------------- Global variables ----------------------------*/
+-struct bond_parm_tbl {
+-      char *modename;
+-      int mode;
+-};
++static const char *version =
++      DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
+-static int arp_interval = BOND_LINK_ARP_INTERV;
+-static char *arp_ip_target[MAX_ARP_IP_TARGETS] = { NULL, };
+-static u32 arp_target[MAX_ARP_IP_TARGETS] = { 0, } ;
+-static int arp_ip_count = 0;
+-static u32 my_ip = 0;
+-char *arp_target_hw_addr = NULL;
++static LIST_HEAD(bond_dev_list);
+-static char *primary= NULL;
++#ifdef CONFIG_PROC_FS
++static struct proc_dir_entry *bond_proc_dir = NULL;
++#endif
+-static int app_abi_ver = 0;
++static u32 arp_target[MAX_ARP_IP_TARGETS] = { 0, } ;
++static int arp_ip_count       = 0;
++static u32 my_ip      = 0;
++static int bond_mode  = BOND_MODE_ROUNDROBIN;
++static int lacp_fast  = 0;
++static int app_abi_ver        = 0;
+ static int orig_app_abi_ver = -1; /* This is used to save the first ABI version
+                                  * we receive from the application. Once set,
+                                  * it won't be changed, and the module will
+@@ -521,14 +562,16 @@ static int orig_app_abi_ver = -1; /* Thi
+                                  * another ABI version.
+                                  */
+-static int max_bonds  = BOND_DEFAULT_MAX_BONDS;
+-static int miimon     = BOND_LINK_MON_INTERV;
+-static int use_carrier        = 1;
+-static int bond_mode  = BOND_MODE_ROUNDROBIN;
+-static int updelay    = 0;
+-static int downdelay  = 0;
++struct bond_parm_tbl {
++      char *modename;
++      int mode;
++};
+-static char *mode     = NULL;
++static struct bond_parm_tbl bond_lacp_tbl[] = {
++{     "slow",         AD_LACP_SLOW},
++{     "fast",         AD_LACP_FAST},
++{     NULL,           -1},
++};
+ static struct bond_parm_tbl bond_mode_tbl[] = {
+ {     "balance-rr",           BOND_MODE_ROUNDROBIN},
+@@ -541,101 +584,9 @@ static struct bond_parm_tbl bond_mode_tb
+ {     NULL,                   -1},
+ };
+-static int multicast_mode     = BOND_MULTICAST_ALL;
+-static char *multicast                = NULL;
+-
+-static struct bond_parm_tbl bond_mc_tbl[] = {
+-{     "disabled",             BOND_MULTICAST_DISABLED},
+-{     "active",               BOND_MULTICAST_ACTIVE},
+-{     "all",                  BOND_MULTICAST_ALL},
+-{     NULL,                   -1},
+-};
+-
+-static int lacp_fast          = 0;
+-static char *lacp_rate                = NULL;
+-
+-static struct bond_parm_tbl bond_lacp_tbl[] = {
+-{     "slow",         AD_LACP_SLOW},
+-{     "fast",         AD_LACP_FAST},
+-{     NULL,           -1},
+-};
+-
+-static LIST_HEAD(bond_dev_list);
+-#ifdef CONFIG_PROC_FS
+-static struct proc_dir_entry *bond_proc_dir = NULL;
+-#endif
+-
+-MODULE_PARM(max_bonds, "i");
+-MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
+-MODULE_PARM(miimon, "i");
+-MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
+-MODULE_PARM(use_carrier, "i");
+-MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)");
+-MODULE_PARM(mode, "s");
+-MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor");
+-MODULE_PARM(arp_interval, "i");
+-MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
+-MODULE_PARM(arp_ip_target, "1-" __MODULE_STRING(MAX_ARP_IP_TARGETS) "s");
+-MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
+-MODULE_PARM(updelay, "i");
+-MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds");
+-MODULE_PARM(downdelay, "i");
+-MODULE_PARM_DESC(downdelay, "Delay before considering link down, in milliseconds");
+-MODULE_PARM(primary, "s");
+-MODULE_PARM_DESC(primary, "Primary network device to use");
+-MODULE_PARM(multicast, "s");
+-MODULE_PARM_DESC(multicast, "Mode for multicast support : 0 for none, 1 for active slave, 2 for all slaves (default)");
+-MODULE_PARM(lacp_rate, "s");
+-MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)");
+-
+-static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *dev);
+-static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev);
+-static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev);
+-static struct net_device_stats *bond_get_stats(struct net_device *dev);
+-static void bond_mii_monitor(struct net_device *dev);
+-static void loadbalance_arp_monitor(struct net_device *dev);
+-static void activebackup_arp_monitor(struct net_device *dev);
+-static void bond_mc_list_destroy(struct bonding *bond);
+-static void bond_mc_add(bonding_t *bond, void *addr, int alen);
+-static void bond_mc_delete(bonding_t *bond, void *addr, int alen);
+-static int bond_mc_list_copy (struct dev_mc_list *src, struct bonding *dst, int gpf_flag);
+-static inline int dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2);
+-static void bond_set_promiscuity(bonding_t *bond, int inc);
+-static void bond_set_allmulti(bonding_t *bond, int inc);
+-static struct dev_mc_list* bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct dev_mc_list *mc_list);
+-static void bond_mc_update(bonding_t *bond, slave_t *new, slave_t *old);
+-static int bond_enslave(struct net_device *master, struct net_device *slave);
+-static int bond_release(struct net_device *master, struct net_device *slave);
+-static int bond_release_all(struct net_device *master);
+-static int bond_sethwaddr(struct net_device *master, struct net_device *slave);
+-static void change_active_interface(struct bonding *bond, struct slave *new);
+-static void reselect_active_interface(struct bonding *bond);
+-static struct slave *find_best_interface(struct bonding *bond);
+-
+-
+-/* #define BONDING_DEBUG 1 */
+-#ifdef BONDING_DEBUG
+-#define dprintk(x...) printk(x...)
+-#else /* BONDING_DEBUG */
+-#define dprintk(x...) do {} while (0)
+-#endif /* BONDING_DEBUG */
+-
+-/* several macros */
+-
+-static void arp_send_all(slave_t *slave)
+-{     
+-      int i; 
+-
+-      for (i = 0; (i<MAX_ARP_IP_TARGETS) && arp_target[i]; i++) { 
+-              arp_send(ARPOP_REQUEST, ETH_P_ARP, arp_target[i], slave->dev, 
+-                       my_ip, arp_target_hw_addr, slave->dev->dev_addr,
+-                       arp_target_hw_addr); 
+-      } 
+-}
+- 
++/*---------------------------- General routines -----------------------------*/
+-static const char *
+-bond_mode_name(void)
++static const char *bond_mode_name(void)
+ {
+       switch (bond_mode) {
+       case BOND_MODE_ROUNDROBIN :
+@@ -657,149 +608,7 @@ bond_mode_name(void)
+       }
+ }
+-static const char *
+-multicast_mode_name(void)
+-{
+-      switch(multicast_mode) {
+-      case BOND_MULTICAST_DISABLED :
+-              return "disabled";
+-      case BOND_MULTICAST_ACTIVE :
+-              return "active slave only";
+-      case BOND_MULTICAST_ALL :
+-              return "all slaves";
+-      default :
+-              return "unknown";
+-      }
+-}
+-
+-void bond_set_slave_inactive_flags(slave_t *slave)
+-{
+-      slave->state = BOND_STATE_BACKUP;
+-      slave->dev->flags |= IFF_NOARP;
+-}
+-
+-void bond_set_slave_active_flags(slave_t *slave)
+-{
+-      slave->state = BOND_STATE_ACTIVE;
+-      slave->dev->flags &= ~IFF_NOARP;
+-}
+-
+-/*
+- * This function counts and verifies the the number of attached
+- * slaves, checking the count against the expected value (given that incr
+- * is either 1 or -1, for add or removal of a slave).  Only
+- * bond_xmit_xor() uses the slave_cnt value, but this is still a good
+- * consistency check.
+- */
+-static inline void
+-update_slave_cnt(bonding_t *bond, int incr)
+-{
+-      slave_t *slave = NULL;
+-      int expect = bond->slave_cnt + incr;
+-
+-      bond->slave_cnt = 0;
+-      for (slave = bond->prev; slave != (slave_t*)bond;
+-           slave = slave->prev) {
+-              bond->slave_cnt++;
+-      }
+-
+-      if (expect != bond->slave_cnt)
+-              BUG();
+-}
+-
+-/* 
+- * This function detaches the slave <slave> from the list <bond>.
+- * WARNING: no check is made to verify if the slave effectively
+- * belongs to <bond>. It returns <slave> in case it's needed.
+- * Nothing is freed on return, structures are just unchained.
+- * If the bond->current_slave pointer was pointing to <slave>,
+- * it should be changed by the calling function.
+- *
+- * bond->lock held for writing by caller.
+- */
+-static slave_t *
+-bond_detach_slave(bonding_t *bond, slave_t *slave)
+-{
+-      if ((bond == NULL) || (slave == NULL) ||
+-         ((void *)bond == (void *)slave)) {
+-              printk(KERN_ERR
+-                      "bond_detach_slave(): trying to detach "
+-                      "slave %p from bond %p\n", bond, slave);
+-              return slave;
+-      }
+-
+-      if (bond->next == slave) {  /* is the slave at the head ? */
+-              if (bond->prev == slave) {  /* is the slave alone ? */
+-                      bond->prev = bond->next = (slave_t *)bond;
+-              } else { /* not alone */
+-                      bond->next        = slave->next;
+-                      slave->next->prev = (slave_t *)bond;
+-                      bond->prev->next  = slave->next;
+-              }
+-      } else {
+-              slave->prev->next = slave->next;
+-              if (bond->prev == slave) {  /* is this slave the last one ? */
+-                      bond->prev = slave->prev;
+-              } else {
+-                      slave->next->prev = slave->prev;
+-              }
+-      }
+-
+-      update_slave_cnt(bond, -1);
+-
+-      return slave;
+-}
+-
+-/*
+- * This function attaches the slave <slave> to the list <bond>.
+- *
+- * bond->lock held for writing by caller.
+- */
+-static void
+-bond_attach_slave(struct bonding *bond, struct slave *new_slave)
+-{
+-      /* 
+-       * queue to the end of the slaves list, make the first element its
+-       * successor, the last one its predecessor, and make it the bond's
+-       * predecessor. 
+-       *
+-       * Just to clarify, so future bonding driver hackers don't go through
+-       * the same confusion stage I did trying to figure this out, the
+-       * slaves are stored in a double linked circular list, sortof.
+-       * In the ->next direction, the last slave points to the first slave,
+-       * bypassing bond; only the slaves are in the ->next direction.
+-       * In the ->prev direction, however, the first slave points to bond
+-       * and bond points to the last slave.
+-       *
+-       * It looks like a circle with a little bubble hanging off one side
+-       * in the ->prev direction only.
+-       *
+-       * When going through the list once, its best to start at bond->prev
+-       * and go in the ->prev direction, testing for bond.  Doing this
+-       * in the ->next direction doesn't work.  Trust me, I know this now.
+-       * :)  -mts 2002.03.14
+-       */
+-      new_slave->prev       = bond->prev;
+-      new_slave->prev->next = new_slave;
+-      bond->prev            = new_slave;
+-      new_slave->next       = bond->next;
+-
+-      update_slave_cnt(bond, 1);
+-}
+-
+-
+-/*
+- * Less bad way to call ioctl from within the kernel; this needs to be
+- * done some other way to get the call out of interrupt context.
+- * Needs "ioctl" variable to be supplied by calling context.
+- */
+-#define IOCTL(dev, arg, cmd) ({               \
+-      int ret;                        \
+-      mm_segment_t fs = get_fs();     \
+-      set_fs(get_ds());               \
+-      ret = ioctl(dev, arg, cmd);     \
+-      set_fs(fs);                     \
+-      ret; })
++/*------------------------------- Link status -------------------------------*/
+ /*
+  * Get link speed and duplex from the slave's base driver
+@@ -809,16 +618,16 @@ bond_attach_slave(struct bonding *bond, 
+  */
+ static int bond_update_speed_duplex(struct slave *slave)
+ {
+-      struct net_device *dev = slave->dev;
++      struct net_device *slave_dev = slave->dev;
+       static int (* ioctl)(struct net_device *, struct ifreq *, int);
+       struct ifreq ifr;
+       struct ethtool_cmd etool;
+-      ioctl = dev->do_ioctl;
++      ioctl = slave_dev->do_ioctl;
+       if (ioctl) {
+               etool.cmd = ETHTOOL_GSET;
+               ifr.ifr_data = (char*)&etool;
+-              if (IOCTL(dev, &ifr, SIOCETHTOOL) == 0) {
++              if (IOCTL(slave_dev, &ifr, SIOCETHTOOL) == 0) {
+                       slave->speed = etool.speed;
+                       slave->duplex = etool.duplex;
+               } else {
+@@ -829,20 +638,20 @@ static int bond_update_speed_duplex(stru
+       }
+       switch (slave->speed) {
+-              case SPEED_10:
+-              case SPEED_100:
+-              case SPEED_1000:
+-                      break;
+-              default:
+-                      goto err_out;
++      case SPEED_10:
++      case SPEED_100:
++      case SPEED_1000:
++              break;
++      default:
++              goto err_out;
+       }
+       switch (slave->duplex) {
+-              case DUPLEX_FULL:
+-              case DUPLEX_HALF:
+-                      break;
+-              default:
+-                      goto err_out;
++      case DUPLEX_FULL:
++      case DUPLEX_HALF:
++              break;
++      default:
++              goto err_out;
+       }
+       return 0;
+@@ -854,7 +663,7 @@ err_out:
+       return -1;
+ }
+-/* 
++/*
+  * if <dev> supports MII link status reporting, check its link status.
+  *
+  * We either do MII/ETHTOOL ioctls, or check netif_carrier_ok(),
+@@ -870,8 +679,7 @@ err_out:
+  * It'd be nice if there was a good way to tell if a driver supports
+  * netif_carrier, but there really isn't.
+  */
+-static int
+-bond_check_dev_link(struct net_device *dev, int reporting)
++static int bond_check_dev_link(struct net_device *slave_dev, int reporting)
+ {
+       static int (* ioctl)(struct net_device *, struct ifreq *, int);
+       struct ifreq ifr;
+@@ -879,10 +687,10 @@ bond_check_dev_link(struct net_device *d
+       struct ethtool_value etool;
+       if (use_carrier) {
+-              return netif_carrier_ok(dev) ? BMSR_LSTATUS : 0;
++              return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
+       }
+-      ioctl = dev->do_ioctl;
++      ioctl = slave_dev->do_ioctl;
+       if (ioctl) {
+               /* TODO: set pointer to correct ioctl on a per team member */
+               /*       bases to make this more efficient. that is, once  */
+@@ -898,476 +706,495 @@ bond_check_dev_link(struct net_device *d
+               /* Yes, the mii is overlaid on the ifreq.ifr_ifru */
+               mii = (struct mii_ioctl_data *)&ifr.ifr_data;
+-              if (IOCTL(dev, &ifr, SIOCGMIIPHY) == 0) {
++              if (IOCTL(slave_dev, &ifr, SIOCGMIIPHY) == 0) {
+                       mii->reg_num = MII_BMSR;
+-                      if (IOCTL(dev, &ifr, SIOCGMIIREG) == 0) {
+-                              return mii->val_out & BMSR_LSTATUS;
++                      if (IOCTL(slave_dev, &ifr, SIOCGMIIREG) == 0) {
++                              return (mii->val_out & BMSR_LSTATUS);
+                       }
+               }
+               /* try SIOCETHTOOL ioctl, some drivers cache ETHTOOL_GLINK */
+               /* for a period of time so we attempt to get link status   */
+               /* from it last if the above MII ioctls fail...            */
+-              etool.cmd = ETHTOOL_GLINK;
+-              ifr.ifr_data = (char*)&etool;
+-              if (IOCTL(dev, &ifr, SIOCETHTOOL) == 0) {
++              etool.cmd = ETHTOOL_GLINK;
++              ifr.ifr_data = (char*)&etool;
++              if (IOCTL(slave_dev, &ifr, SIOCETHTOOL) == 0) {
+                       if (etool.data == 1) {
+                               return BMSR_LSTATUS;
+-                      } else { 
+-#ifdef BONDING_DEBUG
+-                              printk(KERN_INFO 
+-                                      ":: SIOCETHTOOL shows link down \n");
+-#endif
++                      } else {
++                              dprintk("SIOCETHTOOL shows link down\n");
+                               return 0;
+-                      } 
++                      }
+               }
+-
+       }
+- 
++
+       /*
+        * If reporting, report that either there's no dev->do_ioctl,
+        * or both SIOCGMIIREG and SIOCETHTOOL failed (meaning that we
+        * cannot report link status).  If not reporting, pretend
+        * we're ok.
+        */
+-      return reporting ? -1 : BMSR_LSTATUS;
++      return (reporting ? -1 : BMSR_LSTATUS);
+ }
+-static u16 bond_check_mii_link(bonding_t *bond)
+-{
+-      int has_active_interface = 0;
+-
+-      read_lock_bh(&bond->lock);
+-      read_lock(&bond->ptrlock);
+-      has_active_interface = (bond->current_slave != NULL);
+-      read_unlock(&bond->ptrlock);
+-      read_unlock_bh(&bond->lock);
++/*----------------------------- Multicast list ------------------------------*/
+-      return (has_active_interface ? BMSR_LSTATUS : 0);
++/*
++ * Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise
++ */
++static inline int bond_is_dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2)
++{
++      return memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0 &&
++                      dmi1->dmi_addrlen == dmi2->dmi_addrlen;
+ }
+-/* register to receive lacpdus on a bond */
+-static void bond_register_lacpdu(struct bonding *bond)
++/*
++ * returns dmi entry if found, NULL otherwise
++ */
++static struct dev_mc_list *bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct dev_mc_list *mc_list)
+ {
+-      struct packet_type* pk_type = &(BOND_AD_INFO(bond).ad_pkt_type);
++      struct dev_mc_list *idmi;
+-      /* initialize packet type */
+-      pk_type->type = PKT_TYPE_LACPDU;
+-      pk_type->dev = bond->device;
+-      pk_type->func = bond_3ad_lacpdu_recv;
++      for (idmi = mc_list; idmi; idmi = idmi->next) {
++              if (bond_is_dmi_same(dmi, idmi)) {
++                      return idmi;
++              }
++      }
+-      dev_add_pack(pk_type);
++      return NULL;
+ }
+-/* unregister to receive lacpdus on a bond */
+-static void bond_unregister_lacpdu(struct bonding *bond)
++/*
++ * Push the promiscuity flag down to appropriate slaves
++ */
++static void bond_set_promiscuity(struct bonding *bond, int inc)
+ {
+-      dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
++      if (USES_PRIMARY(bond_mode)) {
++              /* write lock already acquired */
++              if (bond->curr_active_slave) {
++                      dev_set_promiscuity(bond->curr_active_slave->dev, inc);
++              }
++      } else {
++              struct slave *slave;
++              int i;
++              bond_for_each_slave(bond, slave, i) {
++                      dev_set_promiscuity(slave->dev, inc);
++              }
++      }
+ }
+-static int bond_open(struct net_device *dev)
++/*
++ * Push the allmulti flag down to all slaves
++ */
++static void bond_set_allmulti(struct bonding *bond, int inc)
+ {
+-      struct bonding *bond = (struct bonding *)(dev->priv);
+-      struct timer_list *timer = &((struct bonding *)(dev->priv))->mii_timer;
+-      struct timer_list *arp_timer = &((struct bonding *)(dev->priv))->arp_timer;
+-
+-      if ((bond_mode == BOND_MODE_TLB) ||
+-          (bond_mode == BOND_MODE_ALB)) {
+-              struct timer_list *alb_timer = &(BOND_ALB_INFO(bond).alb_timer);
+-
+-              /* bond_alb_initialize must be called before the timer
+-               * is started.
+-               */
+-              if (bond_alb_initialize(bond, (bond_mode == BOND_MODE_ALB))) {
+-                      /* something went wrong - fail the open operation */
+-                      return -1;
++      if (USES_PRIMARY(bond_mode)) {
++              /* write lock already acquired */
++              if (bond->curr_active_slave) {
++                      dev_set_allmulti(bond->curr_active_slave->dev, inc);
++              }
++      } else {
++              struct slave *slave;
++              int i;
++              bond_for_each_slave(bond, slave, i) {
++                      dev_set_allmulti(slave->dev, inc);
+               }
+-
+-              init_timer(alb_timer);
+-              alb_timer->expires  = jiffies + 1;
+-              alb_timer->data     = (unsigned long)bond;
+-              alb_timer->function = (void *)&bond_alb_monitor;
+-              add_timer(alb_timer);
+-      }
+-
+-      if (miimon > 0) {  /* link check interval, in milliseconds. */
+-              init_timer(timer);
+-              timer->expires  = jiffies + (miimon * HZ / 1000);
+-              timer->data     = (unsigned long)dev;
+-              timer->function = (void *)&bond_mii_monitor;
+-              add_timer(timer);
+       }
++}
+-      if (arp_interval> 0) {  /* arp interval, in milliseconds. */
+-              init_timer(arp_timer);
+-              arp_timer->expires  = jiffies + (arp_interval * HZ / 1000);
+-              arp_timer->data     = (unsigned long)dev;
+-              if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+-                      arp_timer->function = (void *)&activebackup_arp_monitor;
+-              } else {
+-                      arp_timer->function = (void *)&loadbalance_arp_monitor;
++/*
++ * Add a Multicast address to slaves
++ * according to mode
++ */
++static void bond_mc_add(struct bonding *bond, void *addr, int alen)
++{
++      if (USES_PRIMARY(bond_mode)) {
++              /* write lock already acquired */
++              if (bond->curr_active_slave) {
++                      dev_mc_add(bond->curr_active_slave->dev, addr, alen, 0);
++              }
++      } else {
++              struct slave *slave;
++              int i;
++              bond_for_each_slave(bond, slave, i) {
++                      dev_mc_add(slave->dev, addr, alen, 0);
+               }
+-              add_timer(arp_timer);
+       }
+-
+-      if (bond_mode == BOND_MODE_8023AD) {
+-              struct timer_list *ad_timer = &(BOND_AD_INFO(bond).ad_timer);
+-              init_timer(ad_timer);
+-              ad_timer->expires  = jiffies + (AD_TIMER_INTERVAL * HZ / 1000);
+-              ad_timer->data     = (unsigned long)bond;
+-              ad_timer->function = (void *)&bond_3ad_state_machine_handler;
+-              add_timer(ad_timer);
+-
+-              /* register to receive LACPDUs */
+-              bond_register_lacpdu(bond);
+-      }
+-
+-      return 0;
+ }
+-static int bond_close(struct net_device *master)
++/*
++ * Remove a multicast address from slave
++ * according to mode
++ */
++static void bond_mc_delete(struct bonding *bond, void *addr, int alen)
+ {
+-      bonding_t *bond = (struct bonding *) master->priv;
+-
+-      write_lock_bh(&bond->lock);
+-
+-      if (miimon > 0) {  /* link check interval, in milliseconds. */
+-              del_timer(&bond->mii_timer);
+-      }
+-      if (arp_interval> 0) {  /* arp interval, in milliseconds. */
+-              del_timer(&bond->arp_timer);
+-                if (arp_target_hw_addr != NULL) {
+-                      kfree(arp_target_hw_addr); 
+-                      arp_target_hw_addr = NULL;
++      if (USES_PRIMARY(bond_mode)) {
++              /* write lock already acquired */
++              if (bond->curr_active_slave) {
++                      dev_mc_delete(bond->curr_active_slave->dev, addr, alen, 0);
++              }
++      } else {
++              struct slave *slave;
++              int i;
++              bond_for_each_slave(bond, slave, i) {
++                      dev_mc_delete(slave->dev, addr, alen, 0);
+               }
+       }
++}
+-      if (bond_mode == BOND_MODE_8023AD) {
+-              del_timer_sync(&(BOND_AD_INFO(bond).ad_timer));
++/*
++ * Totally destroys the mc_list in bond
++ */
++static void bond_mc_list_destroy(struct bonding *bond)
++{
++      struct dev_mc_list *dmi;
+-              /* Unregister the receive of LACPDUs */
+-              bond_unregister_lacpdu(bond);
++      dmi = bond->mc_list;
++      while (dmi) {
++              bond->mc_list = dmi->next;
++              kfree(dmi);
++              dmi = bond->mc_list;
+       }
++}
+-      bond_mc_list_destroy (bond);
+-
+-      write_unlock_bh(&bond->lock);
++/*
++ * Copy all the Multicast addresses from src to the bonding device dst
++ */
++static int bond_mc_list_copy(struct dev_mc_list *mc_list, struct bonding *bond, int gpf_flag)
++{
++      struct dev_mc_list *dmi, *new_dmi;
+-      /* Release the bonded slaves */
+-      bond_release_all(master);
++      for (dmi = mc_list; dmi; dmi = dmi->next) {
++              new_dmi = kmalloc(sizeof(struct dev_mc_list), gpf_flag);
+-      if ((bond_mode == BOND_MODE_TLB) ||
+-          (bond_mode == BOND_MODE_ALB)) {
+-              del_timer_sync(&(BOND_ALB_INFO(bond).alb_timer));
++              if (!new_dmi) {
++                      /* FIXME: Potential memory leak !!! */
++                      return -ENOMEM;
++              }
+-              bond_alb_deinitialize(bond);
++              new_dmi->next = bond->mc_list;
++              bond->mc_list = new_dmi;
++              new_dmi->dmi_addrlen = dmi->dmi_addrlen;
++              memcpy(new_dmi->dmi_addr, dmi->dmi_addr, dmi->dmi_addrlen);
++              new_dmi->dmi_users = dmi->dmi_users;
++              new_dmi->dmi_gusers = dmi->dmi_gusers;
+       }
+       return 0;
+ }
+-/* 
++/*
+  * flush all members of flush->mc_list from device dev->mc_list
+  */
+-static void bond_mc_list_flush(struct net_device *dev, struct net_device *flush)
+-{ 
+-      struct dev_mc_list *dmi; 
+- 
+-      for (dmi = flush->mc_list; dmi != NULL; dmi = dmi->next) 
+-              dev_mc_delete(dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
++static void bond_mc_list_flush(struct net_device *bond_dev, struct net_device *slave_dev)
++{
++      struct dev_mc_list *dmi;
++
++      for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
++              dev_mc_delete(slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
++      }
+       if (bond_mode == BOND_MODE_8023AD) {
+               /* del lacpdu mc addr from mc list */
+               u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
+-              dev_mc_delete(dev, lacpdu_multicast, ETH_ALEN, 0);
++              dev_mc_delete(slave_dev, lacpdu_multicast, ETH_ALEN, 0);
+       }
+ }
++/*--------------------------- Active slave change ---------------------------*/
++
+ /*
+- * Totally destroys the mc_list in bond
++ * Update the mc list and multicast-related flags for the new and
++ * old active slaves (if any) according to the multicast mode, and
++ * promiscuous flags unconditionally.
+  */
+-static void bond_mc_list_destroy(struct bonding *bond)
++static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct slave *old_active)
+ {
+       struct dev_mc_list *dmi;
+-      dmi = bond->mc_list; 
+-      while (dmi) { 
+-              bond->mc_list = dmi->next; 
+-              kfree(dmi); 
+-              dmi = bond->mc_list; 
+-      }
+-}
+-
+-/*
+- * Add a Multicast address to every slave in the bonding group
+- */
+-static void bond_mc_add(bonding_t *bond, void *addr, int alen)
+-{ 
+-      slave_t *slave;
+-      switch (multicast_mode) {
+-      case BOND_MULTICAST_ACTIVE :
+-              /* write lock already acquired */
+-              if (bond->current_slave != NULL)
+-                      dev_mc_add(bond->current_slave->dev, addr, alen, 0);
+-              break;
+-      case BOND_MULTICAST_ALL :
+-              for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev)
+-                      dev_mc_add(slave->dev, addr, alen, 0);
+-              break;
+-      case BOND_MULTICAST_DISABLED :
+-              break;
++      if (!USES_PRIMARY(bond_mode)) {
++              /* nothing to do -  mc list is already up-to-date on
++               * all slaves
++               */
++              return;
+       }
+-} 
+-/*
+- * Remove a multicast address from every slave in the bonding group
+- */
+-static void bond_mc_delete(bonding_t *bond, void *addr, int alen)
+-{ 
+-      slave_t *slave; 
+-      switch (multicast_mode) {
+-      case BOND_MULTICAST_ACTIVE :
+-              /* write lock already acquired */
+-              if (bond->current_slave != NULL)
+-                      dev_mc_delete(bond->current_slave->dev, addr, alen, 0);
+-              break;
+-      case BOND_MULTICAST_ALL :
+-              for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev)
+-                      dev_mc_delete(slave->dev, addr, alen, 0);
+-              break;
+-      case BOND_MULTICAST_DISABLED :
+-              break;
+-      }
+-} 
++      if (old_active) {
++              if (bond->dev->flags & IFF_PROMISC) {
++                      dev_set_promiscuity(old_active->dev, -1);
++              }
+-/*
+- * Copy all the Multicast addresses from src to the bonding device dst
+- */
+-static int bond_mc_list_copy (struct dev_mc_list *src, struct bonding *dst,
+- int gpf_flag)
+-{
+-      struct dev_mc_list *dmi, *new_dmi;
++              if (bond->dev->flags & IFF_ALLMULTI) {
++                      dev_set_allmulti(old_active->dev, -1);
++              }
+-      for (dmi = src; dmi != NULL; dmi = dmi->next) { 
+-              new_dmi = kmalloc(sizeof(struct dev_mc_list), gpf_flag);
++              for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
++                      dev_mc_delete(old_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
++              }
++      }
+-              if (new_dmi == NULL) {
+-                      return -ENOMEM; 
++      if (new_active) {
++              if (bond->dev->flags & IFF_PROMISC) {
++                      dev_set_promiscuity(new_active->dev, 1);
+               }
+-              new_dmi->next = dst->mc_list; 
+-              dst->mc_list = new_dmi;
++              if (bond->dev->flags & IFF_ALLMULTI) {
++                      dev_set_allmulti(new_active->dev, 1);
++              }
+-              new_dmi->dmi_addrlen = dmi->dmi_addrlen; 
+-              memcpy(new_dmi->dmi_addr, dmi->dmi_addr, dmi->dmi_addrlen); 
+-              new_dmi->dmi_users = dmi->dmi_users;
+-              new_dmi->dmi_gusers = dmi->dmi_gusers; 
+-      } 
+-      return 0;
++              for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
++                      dev_mc_add(new_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
++              }
++      }
+ }
+-/*
+- * Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise
+- */
+-static inline int dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2)
+-{ 
+-      return memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0 &&
+-       dmi1->dmi_addrlen == dmi2->dmi_addrlen;
+-} 
+-
+-/*
+- * Push the promiscuity flag down to appropriate slaves
++/**
++ * find_best_interface - select the best available slave to be the active one
++ * @bond: our bonding struct
++ *
++ * Warning: Caller must hold curr_slave_lock for writing.
+  */
+-static void bond_set_promiscuity(bonding_t *bond, int inc)
+-{ 
+-      slave_t *slave; 
++static struct slave *bond_find_best_slave(struct bonding *bond)
++{
++      struct slave *new_active, *old_active;
++      struct slave *bestslave = NULL;
++      int mintime;
++      int i;
+-      if (USES_PRIMARY(bond_mode)) {
+-              if (bond->current_slave) {
+-                      dev_set_promiscuity(bond->current_slave->dev, inc);
+-              }
++      new_active = old_active = bond->curr_active_slave;
+-      } else { 
+-              for (slave = bond->prev; slave != (slave_t*)bond;
+-                   slave = slave->prev) {
+-                      dev_set_promiscuity(slave->dev, inc);
++      if (!new_active) { /* there were no active slaves left */
++              if (bond->slave_cnt > 0) {  /* found one slave */
++                      new_active = bond->first_slave;
++              } else {
++                      return NULL; /* still no slave, return NULL */
+               }
+       }
+-} 
+-/*
+- * Push the allmulti flag down to all slaves
+- */
+-static void bond_set_allmulti(bonding_t *bond, int inc)
+-{ 
+-      slave_t *slave; 
+-      switch (multicast_mode) {
+-      case BOND_MULTICAST_ACTIVE : 
+-              /* write lock already acquired */
+-              if (bond->current_slave != NULL)
+-                      dev_set_allmulti(bond->current_slave->dev, inc);
+-              break;
+-      case BOND_MULTICAST_ALL :
+-              for (slave = bond->prev; slave != (slave_t*)bond; slave = slave->prev)
+-                      dev_set_allmulti(slave->dev, inc);
+-              break;
+-      case BOND_MULTICAST_DISABLED :
+-              break;
++      mintime = updelay;
++
++      /* first try the primary link; if arping, a link must tx/rx traffic
++       * before it can be considered the curr_active_slave - also, we would skip
++       * slaves between the curr_active_slave and primary_slave that may be up
++       * and able to arp
++       */
++      if ((bond->primary_slave) &&
++          (!arp_interval) &&
++          (IS_UP(bond->primary_slave->dev))) {
++              new_active = bond->primary_slave;
+       }
+-} 
+-/* 
+- * returns dmi entry if found, NULL otherwise 
+- */
+-static struct dev_mc_list* bond_mc_list_find_dmi(struct dev_mc_list *dmi,
+- struct dev_mc_list *mc_list)
+-{ 
+-      struct dev_mc_list *idmi;
++      /* remember where to stop iterating over the slaves */
++      old_active = new_active;
+-      for (idmi = mc_list; idmi != NULL; idmi = idmi->next) {
+-              if (dmi_same(dmi, idmi)) {
+-                      return idmi; 
++      bond_for_each_slave_from(bond, new_active, i, old_active) {
++              if (IS_UP(new_active->dev)) {
++                      if (new_active->link == BOND_LINK_UP) {
++                              return new_active;
++                      } else if (new_active->link == BOND_LINK_BACK) {
++                              /* link up, but waiting for stabilization */
++                              if (new_active->delay < mintime) {
++                                      mintime = new_active->delay;
++                                      bestslave = new_active;
++                              }
++                      }
+               }
+       }
+-      return NULL;
+-} 
+-static void set_multicast_list(struct net_device *master)
++      return bestslave;
++}
++
++/**
++ * change_active_interface - change the active slave into the specified one
++ * @bond: our bonding struct
++ * @new: the new slave to make the active one
++ *
++ * Set the new slave to the bond's settings and unset them on the old
++ * curr_active_slave.
++ * Setting include flags, mc-list, promiscuity, allmulti, etc.
++ *
++ * If @new's link state is %BOND_LINK_BACK we'll set it to %BOND_LINK_UP,
++ * because it is apparently the best available slave we have, even though its
++ * updelay hasn't timed out yet.
++ *
++ * Warning: Caller must hold curr_slave_lock for writing.
++ */
++static void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
+ {
+-      bonding_t *bond = master->priv;
+-      struct dev_mc_list *dmi;
++      struct slave *old_active = bond->curr_active_slave;
+-      write_lock_bh(&bond->lock);
++      if (old_active == new_active) {
++              return;
++      }
+-      /*
+-       * Do promisc before checking multicast_mode
+-       */
+-      if ( (master->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC) )
+-              bond_set_promiscuity(bond, 1); 
++      if (new_active) {
++              if (new_active->link == BOND_LINK_BACK) {
++                      if (USES_PRIMARY(bond_mode)) {
++                              printk(KERN_INFO DRV_NAME
++                                     ": %s: making interface %s the new "
++                                     "active one %d ms earlier.\n",
++                                     bond->dev->name, new_active->dev->name,
++                                     (updelay - new_active->delay) * miimon);
++                      }
+-      if ( !(master->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC) ) 
+-              bond_set_promiscuity(bond, -1); 
++                      new_active->delay = 0;
++                      new_active->link = BOND_LINK_UP;
++                      new_active->jiffies = jiffies;
+-      if (multicast_mode == BOND_MULTICAST_DISABLED) {
+-              bond->flags = master->flags;
+-              write_unlock_bh(&bond->lock);
+-              return;
++                      if (bond_mode == BOND_MODE_8023AD) {
++                              bond_3ad_handle_link_change(new_active, BOND_LINK_UP);
++                      }
++
++                      if ((bond_mode == BOND_MODE_TLB) ||
++                          (bond_mode == BOND_MODE_ALB)) {
++                              bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP);
++                      }
++              } else {
++                      if (USES_PRIMARY(bond_mode)) {
++                              printk(KERN_INFO DRV_NAME
++                                     ": %s: making interface %s the new "
++                                     "active one.\n",
++                                     bond->dev->name, new_active->dev->name);
++                      }
++              }
+       }
+-      /* set allmulti flag to slaves */ 
+-      if ( (master->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI) ) 
+-              bond_set_allmulti(bond, 1); 
++      if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
++              if (old_active) {
++                      bond_set_slave_inactive_flags(old_active);
++              }
++
++              if (new_active) {
++                      bond_set_slave_active_flags(new_active);
++              }
++      }
+-      if ( !(master->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI) )
+-              bond_set_allmulti(bond, -1); 
++      if (USES_PRIMARY(bond_mode)) {
++              bond_mc_swap(bond, new_active, old_active);
++      }
+-      bond->flags = master->flags; 
++      if ((bond_mode == BOND_MODE_TLB) ||
++          (bond_mode == BOND_MODE_ALB)) {
++              bond_alb_handle_active_change(bond, new_active);
++      } else {
++              bond->curr_active_slave = new_active;
++      }
++}
+-      /* looking for addresses to add to slaves' mc list */ 
+-      for (dmi = master->mc_list; dmi != NULL; dmi = dmi->next) { 
+-              if (bond_mc_list_find_dmi(dmi, bond->mc_list) == NULL) 
+-               bond_mc_add(bond, dmi->dmi_addr, dmi->dmi_addrlen); 
+-      } 
++/**
++ * bond_select_active_slave - select a new active slave, if needed
++ * @bond: our bonding struct
++ *
++ * This functions shoud be called when one of the following occurs:
++ * - The old curr_active_slave has been released or lost its link.
++ * - The primary_slave has got its link back.
++ * - A slave has got its link back and there's no old curr_active_slave.
++ *
++ * Warning: Caller must hold curr_slave_lock for writing.
++ */
++static void bond_select_active_slave(struct bonding *bond)
++{
++      struct slave *best_slave;
+-      /* looking for addresses to delete from slaves' list */ 
+-      for (dmi = bond->mc_list; dmi != NULL; dmi = dmi->next) { 
+-              if (bond_mc_list_find_dmi(dmi, master->mc_list) == NULL) 
+-               bond_mc_delete(bond, dmi->dmi_addr, dmi->dmi_addrlen); 
++      best_slave = bond_find_best_slave(bond);
++      if (best_slave != bond->curr_active_slave) {
++              bond_change_active_slave(bond, best_slave);
+       }
++}
++/*--------------------------- slave list handling ---------------------------*/
+-      /* save master's multicast list */ 
+-      bond_mc_list_destroy (bond);
+-      bond_mc_list_copy (master->mc_list, bond, GFP_ATOMIC);
++/*
++ * This function attaches the slave to the end of list.
++ *
++ * bond->lock held for writing by caller.
++ */
++static void bond_attach_slave(struct bonding *bond, struct slave *new_slave)
++{
++      if (bond->first_slave == NULL) { /* attaching the first slave */
++              new_slave->next = new_slave;
++              new_slave->prev = new_slave;
++              bond->first_slave = new_slave;
++      } else {
++              new_slave->next = bond->first_slave;
++              new_slave->prev = bond->first_slave->prev;
++              new_slave->next->prev = new_slave;
++              new_slave->prev->next = new_slave;
++      }
+-      write_unlock_bh(&bond->lock);
++      bond->slave_cnt++;
+ }
+ /*
+- * Update the mc list and multicast-related flags for the new and 
+- * old active slaves (if any) according to the multicast mode, and
+- * promiscuous flags unconditionally.
++ * This function detaches the slave from the list.
++ * WARNING: no check is made to verify if the slave effectively
++ * belongs to <bond>.
++ * Nothing is freed on return, structures are just unchained.
++ * If any slave pointer in bond was pointing to <slave>,
++ * it should be changed by the calling function.
++ *
++ * bond->lock held for writing by caller.
+  */
+-static void bond_mc_update(bonding_t *bond, slave_t *new, slave_t *old)
++static void bond_detach_slave(struct bonding *bond, struct slave *slave)
+ {
+-      struct dev_mc_list *dmi;
++      if (slave->next) {
++              slave->next->prev = slave->prev;
++      }
+-      if (USES_PRIMARY(bond_mode)) {
+-              if (bond->device->flags & IFF_PROMISC) {
+-                      if (old)
+-                              dev_set_promiscuity(old->dev, -1);
+-                      if (new)
+-                              dev_set_promiscuity(new->dev, 1);
+-              }
++      if (slave->prev) {
++              slave->prev->next = slave->next;
+       }
+-      switch(multicast_mode) {
+-      case BOND_MULTICAST_ACTIVE :            
+-              if (bond->device->flags & IFF_ALLMULTI) {
+-                      if (old)
+-                              dev_set_allmulti(old->dev, -1);
+-                      if (new)
+-                              dev_set_allmulti(new->dev, 1);
+-              }
+-              /* first remove all mc addresses from old slave if any,
+-                 and _then_ add them to new active slave */
+-              if (old) {
+-                      for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next)
+-                              dev_mc_delete(old->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
+-              }
+-              if (new) {
+-                      for (dmi = bond->device->mc_list; dmi != NULL; dmi = dmi->next)
+-                              dev_mc_add(new->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
++      if (bond->first_slave == slave) { /* slave is the first slave */
++              if (bond->slave_cnt > 1) { /* there are more slave */
++                      bond->first_slave = slave->next;
++              } else {
++                      bond->first_slave = NULL; /* slave was the last one */
+               }
+-              break;
+-      case BOND_MULTICAST_ALL :
+-              /* nothing to do: mc list is already up-to-date on all slaves */
+-              break;
+-      case BOND_MULTICAST_DISABLED :
+-              break;
+       }
++
++      slave->next = NULL;
++      slave->prev = NULL;
++      bond->slave_cnt--;
++}
++
++/*---------------------------------- IOCTL ----------------------------------*/
++
++static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
++{
++      dprintk("bond_dev=%p\n", bond_dev);
++      dprintk("slave_dev=%p\n", slave_dev);
++      dprintk("slave_dev->addr_len=%d\n", slave_dev->addr_len);
++      memcpy(bond_dev->dev_addr, slave_dev->dev_addr, slave_dev->addr_len);
++      return 0;
+ }
+ /* enslave device <slave> to bond device <master> */
+-static int bond_enslave(struct net_device *master_dev, 
+-                        struct net_device *slave_dev)
++static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
+ {
+-      bonding_t *bond = NULL;
+-      slave_t *new_slave = NULL;
+-      unsigned long rflags = 0;
+-      int err = 0;
++      struct bonding *bond = bond_dev->priv;
++      struct slave *new_slave = NULL;
+       struct dev_mc_list *dmi;
+-      struct in_ifaddr **ifap;
+-      struct in_ifaddr *ifa;
+-      int link_reporting;
+       struct sockaddr addr;
+-
+-      if (master_dev == NULL || slave_dev == NULL) {
+-              return -ENODEV;
+-      }
+-      bond = (struct bonding *) master_dev->priv;
++      int link_reporting;
++      int res = 0;
+       if (slave_dev->do_ioctl == NULL) {
+-              printk(KERN_DEBUG
+-                      "Warning : no link monitoring support for %s\n",
+-                      slave_dev->name);
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning : no link monitoring support for %s\n",
++                     slave_dev->name);
+       }
+-
+       /* bond must be initialized by bond_open() before enslaving */
+-      if (!(master_dev->flags & IFF_UP)) {
+-#ifdef BONDING_DEBUG
+-              printk(KERN_CRIT "Error, master_dev is not up\n");
+-#endif
++      if (!(bond_dev->flags & IFF_UP)) {
++              dprintk("Error, master_dev is not up\n");
+               return -EPERM;
+       }
+       /* already enslaved */
+-      if (master_dev->flags & IFF_SLAVE || slave_dev->flags & IFF_SLAVE) {
+-#ifdef BONDING_DEBUG
+-              printk(KERN_CRIT "Error, Device was already enslaved\n");
+-#endif
++      if (slave_dev->flags & IFF_SLAVE) {
++              dprintk("Error, Device was already enslaved\n");
+               return -EBUSY;
+       }
+@@ -1376,19 +1203,19 @@ static int bond_enslave(struct net_devic
+                * slave interface to be closed.
+                */
+               if ((slave_dev->flags & IFF_UP)) {
+-#ifdef BONDING_DEBUG
+-                      printk(KERN_CRIT "Error, slave_dev is up\n");
+-#endif
++                      printk(KERN_ERR DRV_NAME
++                             ": Error: %s is up\n",
++                             slave_dev->name);
+                       return -EPERM;
+               }
+               if (slave_dev->set_mac_address == NULL) {
+-                      printk(KERN_CRIT
+-                             "The slave device you specified does not support"
+-                             " setting the MAC address.\n");
+-                      printk(KERN_CRIT
+-                             "Your kernel likely does not support slave"
+-                             " devices.\n");
++                      printk(KERN_ERR DRV_NAME
++                             ": Error: The slave device you specified does "
++                             "not support setting the MAC address.\n");
++                      printk(KERN_ERR
++                             "Your kernel likely does not support slave "
++                             "devices.\n");
+                       return -EOPNOTSUPP;
+               }
+@@ -1397,26 +1224,29 @@ static int bond_enslave(struct net_devic
+                * slave interface to be open.
+                */
+               if (!(slave_dev->flags & IFF_UP)) {
+-#ifdef BONDING_DEBUG
+-                      printk(KERN_CRIT "Error, slave_dev is not running\n");
+-#endif
++                      printk(KERN_ERR DRV_NAME
++                             ": Error: %s is not running\n",
++                             slave_dev->name);
+                       return -EINVAL;
+               }
+               if ((bond_mode == BOND_MODE_8023AD) ||
+-                  (bond_mode == BOND_MODE_TLB) ||
++                  (bond_mode == BOND_MODE_TLB)    ||
+                   (bond_mode == BOND_MODE_ALB)) {
+-                      printk(KERN_ERR
+-                             "bonding: Error: to use %s mode, you must "
+-                             "upgrade ifenslave.\n", bond_mode_name());
++                      printk(KERN_ERR DRV_NAME
++                             ": Error: to use %s mode, you must upgrade "
++                             "ifenslave.\n",
++                             bond_mode_name());
+                       return -EOPNOTSUPP;
+               }
+       }
+-      if ((new_slave = kmalloc(sizeof(slave_t), GFP_KERNEL)) == NULL) {
++      new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL);
++      if (!new_slave) {
+               return -ENOMEM;
+       }
+-      memset(new_slave, 0, sizeof(slave_t));
++
++      memset(new_slave, 0, sizeof(struct slave));
+       /* save slave's original flags before calling
+        * netdev_set_master and dev_open
+@@ -1430,37 +1260,29 @@ static int bond_enslave(struct net_devic
+                */
+               memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);
+-              if (bond->slave_cnt > 0) {
+-                      /* set slave to master's mac address
+-                       * The application already set the master's
+-                       * mac address to that of the first slave
+-                       */
+-                      memcpy(addr.sa_data, master_dev->dev_addr, master_dev->addr_len);
+-                      addr.sa_family = slave_dev->type;
+-                      err = slave_dev->set_mac_address(slave_dev, &addr);
+-                      if (err) {
+-#ifdef BONDING_DEBUG
+-                              printk(KERN_CRIT "Error %d calling set_mac_address\n", err);
+-#endif
+-                              goto err_free;
+-                      }
++              /* set slave to master's mac address
++               * The application already set the master's
++               * mac address to that of the first slave
++               */
++              memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
++              addr.sa_family = slave_dev->type;
++              res = slave_dev->set_mac_address(slave_dev, &addr);
++              if (res) {
++                      dprintk("Error %d calling set_mac_address\n", res);
++                      goto err_free;
+               }
+               /* open the slave since the application closed it */
+-              err = dev_open(slave_dev);
+-              if (err) {
+-#ifdef BONDING_DEBUG
+-                      printk(KERN_CRIT "Openning slave %s failed\n", slave_dev->name);
+-#endif
++              res = dev_open(slave_dev);
++              if (res) {
++                      dprintk("Openning slave %s failed\n", slave_dev->name);
+                       goto err_restore_mac;
+               }
+       }
+-      err = netdev_set_master(slave_dev, master_dev);
+-      if (err) {
+-#ifdef BONDING_DEBUG
+-              printk(KERN_CRIT "Error %d calling netdev_set_master\n", err);
+-#endif
++      res = netdev_set_master(slave_dev, bond_dev);
++      if (res) {
++              dprintk("Error %d calling netdev_set_master\n", res);
+               if (app_abi_ver < 1) {
+                       goto err_free;
+               } else {
+@@ -1475,32 +1297,32 @@ static int bond_enslave(struct net_devic
+               /* bond_alb_init_slave() must be called before all other stages since
+                * it might fail and we do not want to have to undo everything
+                */
+-              err = bond_alb_init_slave(bond, new_slave);
+-              if (err) {
++              res = bond_alb_init_slave(bond, new_slave);
++              if (res) {
+                       goto err_unset_master;
+               }
+       }
+-      /* set promiscuity level to new slave */ 
+-      if (master_dev->flags & IFF_PROMISC) {
+-              /* If the mode USES_PRIMARY, then the new slave gets the
+-               * master's promisc (and mc) settings only if it becomes the
+-               * current_slave, and that is taken care of later when calling
+-               * bond_change_active()
+-               */
+-              if (!USES_PRIMARY(bond_mode)) {
+-                      dev_set_promiscuity(slave_dev, 1); 
++      /* If the mode USES_PRIMARY, then the new slave gets the
++       * master's promisc (and mc) settings only if it becomes the
++       * curr_active_slave, and that is taken care of later when calling
++       * bond_change_active()
++       */
++      if (!USES_PRIMARY(bond_mode)) {
++              /* set promiscuity level to new slave */
++              if (bond_dev->flags & IFF_PROMISC) {
++                      dev_set_promiscuity(slave_dev, 1);
+               }
+-      }
+- 
+-      if (multicast_mode == BOND_MULTICAST_ALL) {
++
+               /* set allmulti level to new slave */
+-              if (master_dev->flags & IFF_ALLMULTI) 
+-                      dev_set_allmulti(slave_dev, 1); 
+-              
+-              /* upload master's mc_list to new slave */ 
+-              for (dmi = master_dev->mc_list; dmi != NULL; dmi = dmi->next) 
++              if (bond_dev->flags & IFF_ALLMULTI) {
++                      dev_set_allmulti(slave_dev, 1);
++              }
++
++              /* upload master's mc_list to new slave */
++              for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
+                       dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
++              }
+       }
+       if (bond_mode == BOND_MODE_8023AD) {
+@@ -1511,15 +1333,16 @@ static int bond_enslave(struct net_devic
+       }
+       write_lock_bh(&bond->lock);
+-      
++
+       bond_attach_slave(bond, new_slave);
++
+       new_slave->delay = 0;
+       new_slave->link_failure_count = 0;
+-      if (miimon > 0 && !use_carrier) {
++      if (miimon && !use_carrier) {
+               link_reporting = bond_check_dev_link(slave_dev, 1);
+-              if ((link_reporting == -1) && (arp_interval == 0)) {
++              if ((link_reporting == -1) && !arp_interval) {
+                       /*
+                        * miimon is set but a bonded network driver
+                        * does not support ETHTOOL/MII and
+@@ -1528,115 +1351,97 @@ static int bond_enslave(struct net_devic
+                        * here (because netif_carrier is always
+                        * supported); thus, we don't need to change
+                        * the messages for netif_carrier.
+-                       */ 
+-                      printk(KERN_ERR
+-                              "bond_enslave(): MII and ETHTOOL support not "
+-                              "available for interface %s, and "
+-                              "arp_interval/arp_ip_target module parameters "
+-                              "not specified, thus bonding will not detect "
+-                              "link failures! see bonding.txt for details.\n",
+-                              slave_dev->name);
++                       */
++                      printk(KERN_WARNING DRV_NAME
++                             ": Warning: MII and ETHTOOL support not "
++                             "available for interface %s, and "
++                             "arp_interval/arp_ip_target module parameters "
++                             "not specified, thus bonding will not detect "
++                             "link failures! see bonding.txt for details.\n",
++                             slave_dev->name);
+               } else if (link_reporting == -1) {
+-                      /* unable  get link status using mii/ethtool */
+-                      printk(KERN_WARNING 
+-                             "bond_enslave: can't get link status from "
++                      /* unable get link status using mii/ethtool */
++                      printk(KERN_WARNING DRV_NAME
++                             ": Warning: can't get link status from "
+                              "interface %s; the network driver associated "
+-                             "with this interface does not support "
+-                             "MII or ETHTOOL link status reporting, thus "
+-                             "miimon has no effect on this interface.\n", 
++                             "with this interface does not support MII or "
++                             "ETHTOOL link status reporting, thus miimon "
++                             "has no effect on this interface.\n",
+                              slave_dev->name);
+               }
+       }
+       /* check for initial state */
+-      if ((miimon <= 0) ||
++      if (!miimon ||
+           (bond_check_dev_link(slave_dev, 0) == BMSR_LSTATUS)) {
+               if (updelay) {
+-#ifdef BONDING_DEBUG
+-                      printk(KERN_CRIT "Initial state of slave_dev is "
+-                             "BOND_LINK_BACK\n");
+-#endif
++                      dprintk("Initial state of slave_dev is "
++                              "BOND_LINK_BACK\n");
+                       new_slave->link  = BOND_LINK_BACK;
+                       new_slave->delay = updelay;
+-              }
+-              else {
+-#ifdef BONDING_DEBUG
+-                      printk(KERN_DEBUG "Initial state of slave_dev is "
++              } else {
++                      dprintk("Initial state of slave_dev is "
+                               "BOND_LINK_UP\n");
+-#endif
+                       new_slave->link  = BOND_LINK_UP;
+               }
+               new_slave->jiffies = jiffies;
+-      }
+-      else {
+-#ifdef BONDING_DEBUG
+-              printk(KERN_CRIT "Initial state of slave_dev is "
++      } else {
++              dprintk("Initial state of slave_dev is "
+                       "BOND_LINK_DOWN\n");
+-#endif
+               new_slave->link  = BOND_LINK_DOWN;
+       }
+       if (bond_update_speed_duplex(new_slave) &&
+           (new_slave->link != BOND_LINK_DOWN)) {
+-
+-              printk(KERN_WARNING
+-                     "bond_enslave(): failed to get speed/duplex from %s, "
+-                     "speed forced to 100Mbps, duplex forced to Full.\n",
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning: failed to get speed/duplex from %s, speed "
++                     "forced to 100Mbps, duplex forced to Full.\n",
+                      new_slave->dev->name);
++
+               if (bond_mode == BOND_MODE_8023AD) {
+                       printk(KERN_WARNING
+-                             "Operation of 802.3ad mode requires ETHTOOL support "
+-                             "in base driver for proper aggregator selection.\n");
++                             "Operation of 802.3ad mode requires ETHTOOL "
++                             "support in base driver for proper aggregator "
++                             "selection.\n");
+               }
+       }
+-      /* if we're in active-backup mode, we need one and only one active
+-       * interface. The backup interfaces will have their NOARP flag set
+-       * because we need them to be completely deaf and not to respond to
+-       * any ARP request on the network to avoid fooling a switch. Thus,
+-       * since we guarantee that current_slave always point to the last
+-       * usable interface, we just have to verify this interface's flag.
+-       */
+-      if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+-              if (((bond->current_slave == NULL)
+-                      || (bond->current_slave->dev->flags & IFF_NOARP))
+-                      && (new_slave->link != BOND_LINK_DOWN)) {
+-#ifdef BONDING_DEBUG
+-                      printk(KERN_CRIT "This is the first active slave\n");
+-#endif
++      if (USES_PRIMARY(bond_mode) && primary) {
++              /* if there is a primary slave, remember it */
++              if (strcmp(primary, new_slave->dev->name) == 0) {
++                      bond->primary_slave = new_slave;
++              }
++      }
++
++      switch (bond_mode) {
++      case BOND_MODE_ACTIVEBACKUP:
++              /* if we're in active-backup mode, we need one and only one active
++               * interface. The backup interfaces will have their NOARP flag set
++               * because we need them to be completely deaf and not to respond to
++               * any ARP request on the network to avoid fooling a switch. Thus,
++               * since we guarantee that curr_active_slave always point to the last
++               * usable interface, we just have to verify this interface's flag.
++               */
++              if (((!bond->curr_active_slave) ||
++                   (bond->curr_active_slave->dev->flags & IFF_NOARP)) &&
++                  (new_slave->link != BOND_LINK_DOWN)) {
++                      dprintk("This is the first active slave\n");
+                       /* first slave or no active slave yet, and this link
+                          is OK, so make this interface the active one */
+-                      change_active_interface(bond, new_slave);
+-              }
+-              else {
+-#ifdef BONDING_DEBUG
+-                      printk(KERN_CRIT "This is just a backup slave\n");
+-#endif
++                      bond_change_active_slave(bond, new_slave);
++              } else {
++                      dprintk("This is just a backup slave\n");
+                       bond_set_slave_inactive_flags(new_slave);
+               }
+-              if (((struct in_device *)slave_dev->ip_ptr) != NULL) {
+-                      read_lock_irqsave(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
+-                      ifap= &(((struct in_device *)slave_dev->ip_ptr)->ifa_list);
+-                      ifa = *ifap;
+-                      if (ifa != NULL)
+-                              my_ip = ifa->ifa_address;
+-                      read_unlock_irqrestore(&(((struct in_device *)slave_dev->ip_ptr)->lock), rflags);
+-              }
+-
+-              /* if there is a primary slave, remember it */
+-              if (primary != NULL) {
+-                      if (strcmp(primary, new_slave->dev->name) == 0) {
+-                              bond->primary_slave = new_slave;
+-                      }
+-              }
+-      } else if (bond_mode == BOND_MODE_8023AD) {
++              break;
++      case BOND_MODE_8023AD:
+               /* in 802.3ad mode, the internal mechanism
+                * will activate the slaves in the selected
+                * aggregator
+                */
+               bond_set_slave_inactive_flags(new_slave);
+               /* if this is the first slave */
+-              if (new_slave == bond->next) {
++              if (bond->slave_cnt == 1) {
+                       SLAVE_AD_INFO(new_slave).id = 1;
+                       /* Initialize AD with the number of times that the AD timer is called in 1 second
+                        * can be called only after the mac address of the bond is set
+@@ -1645,40 +1450,37 @@ static int bond_enslave(struct net_devic
+                                           lacp_fast);
+               } else {
+                       SLAVE_AD_INFO(new_slave).id =
+-                      SLAVE_AD_INFO(new_slave->prev).id + 1;
++                              SLAVE_AD_INFO(new_slave->prev).id + 1;
+               }
+               bond_3ad_bind_slave(new_slave);
+-      } else if ((bond_mode == BOND_MODE_TLB) ||
+-                 (bond_mode == BOND_MODE_ALB)) {
++              break;
++      case BOND_MODE_TLB:
++      case BOND_MODE_ALB:
+               new_slave->state = BOND_STATE_ACTIVE;
+-              if ((bond->current_slave == NULL) && (new_slave->link != BOND_LINK_DOWN)) {
++              if ((!bond->curr_active_slave) &&
++                  (new_slave->link != BOND_LINK_DOWN)) {
+                       /* first slave or no active slave yet, and this link
+                        * is OK, so make this interface the active one
+                        */
+-                      change_active_interface(bond, new_slave);
++                      bond_change_active_slave(bond, new_slave);
+               }
++              break;
++      default:
++              dprintk("This slave is always active in trunk mode\n");
+-              /* if there is a primary slave, remember it */
+-              if (primary != NULL) {
+-                      if (strcmp(primary, new_slave->dev->name) == 0) {
+-                              bond->primary_slave = new_slave;
+-                      }
+-              }
+-      } else {
+-#ifdef BONDING_DEBUG
+-              printk(KERN_CRIT "This slave is always active in trunk mode\n");
+-#endif
+               /* always active in trunk mode */
+               new_slave->state = BOND_STATE_ACTIVE;
+-              /* In trunking mode there is little meaning to current_slave
++              /* In trunking mode there is little meaning to curr_active_slave
+                * anyway (it holds no special properties of the bond device),
+                * so we can change it without calling change_active_interface()
+                */
+-              if (bond->current_slave == NULL) 
+-                      bond->current_slave = new_slave;
+-      }
++              if (!bond->curr_active_slave) {
++                      bond->curr_active_slave = new_slave;
++              }
++              break;
++      } /* switch(bond_mode) */
+       write_unlock_bh(&bond->lock);
+@@ -1692,38 +1494,34 @@ static int bond_enslave(struct net_devic
+                */
+               int ndx = 0;
+-              for (ndx = 0; ndx < slave_dev->addr_len; ndx++) {
+-#ifdef BONDING_DEBUG
+-                      printk(KERN_DEBUG
+-                             "Checking ndx=%d of master_dev->dev_addr\n", ndx);
+-#endif
+-                      if (master_dev->dev_addr[ndx] != 0) {
+-#ifdef BONDING_DEBUG
+-                              printk(KERN_DEBUG
+-                                     "Found non-zero byte at ndx=%d\n", ndx);
+-#endif
++              for (ndx = 0; ndx < bond_dev->addr_len; ndx++) {
++                      dprintk("Checking ndx=%d of bond_dev->dev_addr\n",
++                              ndx);
++                      if (bond_dev->dev_addr[ndx] != 0) {
++                              dprintk("Found non-zero byte at ndx=%d\n",
++                                      ndx);
+                               break;
+                       }
+               }
+-              if (ndx == slave_dev->addr_len) {
++
++              if (ndx == bond_dev->addr_len) {
+                       /*
+                        * We got all the way through the address and it was
+                        * all 0's.
+                        */
+-#ifdef BONDING_DEBUG
+-                      printk(KERN_DEBUG "%s doesn't have a MAC address yet.  ",
+-                             master_dev->name);
+-                      printk(KERN_DEBUG "Going to give assign it from %s.\n",
+-                             slave_dev->name);
+-#endif
+-                      bond_sethwaddr(master_dev, slave_dev);
++                      dprintk("%s doesn't have a MAC address yet.  \n",
++                              bond_dev->name);
++                      dprintk("Going to give assign it from %s.\n",
++                              slave_dev->name);
++                      bond_sethwaddr(bond_dev, slave_dev);
+               }
+       }
+-      printk (KERN_INFO "%s: enslaving %s as a%s interface with a%s link.\n",
+-              master_dev->name, slave_dev->name,
+-              new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup",
+-              new_slave->link != BOND_LINK_DOWN ? "n up" : " down");
++      printk(KERN_INFO DRV_NAME
++             ": %s: enslaving %s as a%s interface with a%s link.\n",
++             bond_dev->name, slave_dev->name,
++             new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup",
++             new_slave->link != BOND_LINK_DOWN ? "n up" : " down");
+       /* enslave is successful */
+       return 0;
+@@ -1742,435 +1540,204 @@ err_restore_mac:
+ err_free:
+       kfree(new_slave);
+-      return err;
++      return res;
+ }
+-/* 
+- * This function changes the active slave to slave <slave_dev>.
+- * It returns -EINVAL in the following cases.
+- *  - <slave_dev> is not found in the list.
+- *  - There is not active slave now.
+- *  - <slave_dev> is already active.
+- *  - The link state of <slave_dev> is not BOND_LINK_UP.
+- *  - <slave_dev> is not running.
+- * In these cases, this fuction does nothing.
+- * In the other cases, currnt_slave pointer is changed and 0 is returned.
++/*
++ * Try to release the slave device <slave> from the bond device <master>
++ * It is legal to access curr_active_slave without a lock because all the function
++ * is write-locked.
++ *
++ * The rules for slave state should be:
++ *   for Active/Backup:
++ *     Active stays on all backups go down
++ *   for Bonded connections:
++ *     The first up interface should be left on and all others downed.
+  */
+-static int bond_change_active(struct net_device *master_dev, struct net_device *slave_dev)
++static int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
+ {
+-      bonding_t *bond;
+-      slave_t *slave;
+-      slave_t *oldactive = NULL;
+-      slave_t *newactive = NULL;
+-      int ret = 0;
+-
+-      if (master_dev == NULL || slave_dev == NULL) {
+-              return -ENODEV;
+-      }
++      struct bonding *bond = bond_dev->priv;
++      struct slave *slave;
++      struct sockaddr addr;
++      int mac_addr_differ;
+-      /* Verify that master_dev is indeed the master of slave_dev */
++      /* slave is not a slave or master is not master of this slave */
+       if (!(slave_dev->flags & IFF_SLAVE) ||
+-          (slave_dev->master != master_dev)) {
+-
++          (slave_dev->master != bond_dev)) {
++              printk(KERN_ERR DRV_NAME
++                     ": Error: %s: cannot release %s.\n",
++                     bond_dev->name, slave_dev->name);
+               return -EINVAL;
+       }
+-      bond = (struct bonding *) master_dev->priv;
+       write_lock_bh(&bond->lock);
+-      slave = (slave_t *)bond;
+-      oldactive = bond->current_slave;
+-
+-      while ((slave = slave->prev) != (slave_t *)bond) {
+-              if(slave_dev == slave->dev) {
+-                      newactive = slave;
+-                      break;
+-              }
+-      }
+-
+-      /*
+-       * Changing to the current active: do nothing; return success.
+-       */
+-      if (newactive && (newactive == oldactive)) {
+-              write_unlock_bh(&bond->lock);
+-              return 0;
+-      }
+-
+-      if ((newactive != NULL)&&
+-          (oldactive != NULL)&&
+-          (newactive->link == BOND_LINK_UP)&&
+-          IS_UP(newactive->dev)) {
+-              change_active_interface(bond, newactive);
+-      } else {
+-              ret = -EINVAL;
+-      }
+-      write_unlock_bh(&bond->lock);
+-      return ret;
+-}
+-/**
+- * find_best_interface - select the best available slave to be the active one
+- * @bond: our bonding struct
+- *
+- * Warning: Caller must hold ptrlock for writing.
+- */
+-static struct slave *find_best_interface(struct bonding *bond)
+-{
+-      struct slave *newslave, *oldslave;
+-      struct slave *bestslave = NULL;
+-      int mintime;
+-
+-      newslave = oldslave = bond->current_slave;
+-
+-      if (newslave == NULL) { /* there were no active slaves left */
+-              if (bond->next != (slave_t *)bond) {  /* found one slave */
+-                      newslave = bond->next;
+-              } else {
+-                      return NULL; /* still no slave, return NULL */
+-              }
++      slave = bond_get_slave_by_dev(bond, slave_dev);
++      if (!slave) {
++              /* not a slave of this bond */
++              printk(KERN_INFO DRV_NAME
++                     ": %s: %s not enslaved\n",
++                     bond_dev->name, slave_dev->name);
++              return -EINVAL;
+       }
+-      mintime = updelay;
+-
+-      /* first try the primary link; if arping, a link must tx/rx traffic 
+-       * before it can be considered the current_slave - also, we would skip 
+-       * slaves between the current_slave and primary_slave that may be up 
+-       * and able to arp
+-       */
+-      if ((bond->primary_slave != NULL) && (arp_interval == 0)) {
+-              if (IS_UP(bond->primary_slave->dev)) 
+-                      newslave = bond->primary_slave;
++      mac_addr_differ = memcmp(bond_dev->dev_addr,
++                               slave->perm_hwaddr,
++                               ETH_ALEN);
++      if (!mac_addr_differ && (bond->slave_cnt > 1)) {
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning: the permanent HWaddr of %s "
++                     "- %02X:%02X:%02X:%02X:%02X:%02X - is "
++                     "still in use by %s. Set the HWaddr of "
++                     "%s to a different address to avoid "
++                     "conflicts.\n",
++                     slave_dev->name,
++                     slave->perm_hwaddr[0],
++                     slave->perm_hwaddr[1],
++                     slave->perm_hwaddr[2],
++                     slave->perm_hwaddr[3],
++                     slave->perm_hwaddr[4],
++                     slave->perm_hwaddr[5],
++                     bond_dev->name,
++                     slave_dev->name);
+       }
+-      /* remember where to stop iterating over the slaves */
+-      oldslave = newslave;
+-
+-      do {
+-              if (IS_UP(newslave->dev)) {
+-                      if (newslave->link == BOND_LINK_UP) {
+-                              return newslave;
+-                      }
+-                      else if (newslave->link == BOND_LINK_BACK) {
+-                              /* link up, but waiting for stabilization */
+-                              if (newslave->delay < mintime) {
+-                                      mintime = newslave->delay;
+-                                      bestslave = newslave;
+-                              }
+-                      }
+-              }
+-      } while ((newslave = newslave->next) != oldslave);
+-
+-      return bestslave;
+-}
+-
+-/**
+- * change_active_interface - change the active slave into the specified one
+- * @bond: our bonding struct
+- * @new: the new slave to make the active one
+- * 
+- * Set the new slave to the bond's settings and unset them on the old
+- * current_slave.
+- * Setting include flags, mc-list, promiscuity, allmulti, etc.
+- *
+- * If @new's link state is %BOND_LINK_BACK we'll set it to %BOND_LINK_UP,
+- * because it is apparently the best available slave we have, even though its
+- * updelay hasn't timed out yet.
+- *
+- * Warning: Caller must hold ptrlock for writing.
+- */
+-static void change_active_interface(struct bonding *bond, struct slave *new)
+-{
+-      struct slave *old = bond->current_slave;
+-
+-      if (old == new) {
+-              return;
++      /* Inform AD package of unbinding of slave. */
++      if (bond_mode == BOND_MODE_8023AD) {
++              /* must be called before the slave is
++               * detached from the list
++               */
++              bond_3ad_unbind_slave(slave);
+       }
+-      if (new) {
+-              if (new->link == BOND_LINK_BACK) {
+-                      if (USES_PRIMARY(bond_mode)) {
+-                              printk (KERN_INFO
+-                                      "%s: making interface %s the new "
+-                                      "active one %d ms earlier.\n",
+-                                      bond->device->name, new->dev->name,
+-                                      (updelay - new->delay) * miimon);
+-                      }
++      printk(KERN_INFO DRV_NAME
++             ": %s: releasing %s interface %s\n",
++             bond_dev->name,
++             (slave->state == BOND_STATE_ACTIVE)
++             ? "active" : "backup",
++             slave_dev->name);
+-                      new->delay = 0;
+-                      new->link = BOND_LINK_UP;
+-                      new->jiffies = jiffies;
++      bond->current_arp_slave = NULL;
+-                      if (bond_mode == BOND_MODE_8023AD) {
+-                              bond_3ad_handle_link_change(new, BOND_LINK_UP);
+-                      }
++      /* release the slave from its bond */
++      bond_detach_slave(bond, slave);
+-                      if ((bond_mode == BOND_MODE_TLB) ||
+-                          (bond_mode == BOND_MODE_ALB)) {
+-                              bond_alb_handle_link_change(bond, new, BOND_LINK_UP);
+-                      }
+-              } else {
+-                      if (USES_PRIMARY(bond_mode)) {
+-                              printk (KERN_INFO
+-                                      "%s: making interface %s the new active one.\n",
+-                                      bond->device->name, new->dev->name);
+-                      }
+-              }
++      if (bond->primary_slave == slave) {
++              bond->primary_slave = NULL;
+       }
+-      if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
+-              if (old) {
+-                      bond_set_slave_inactive_flags(old);
+-              }
+-
+-              if (new) {
+-                      bond_set_slave_active_flags(new);
+-              }
++      if (bond->curr_active_slave == slave) {
++              bond_change_active_slave(bond, NULL);
++              bond_select_active_slave(bond);
+       }
+-      if (USES_PRIMARY(bond_mode)) {
+-              bond_mc_update(bond, new, old);
++      if (!bond->curr_active_slave) {
++              printk(KERN_INFO DRV_NAME
++                     ": %s: now running without any active "
++                     "interface !\n",
++                     bond_dev->name);
+       }
+       if ((bond_mode == BOND_MODE_TLB) ||
+           (bond_mode == BOND_MODE_ALB)) {
+-              bond_alb_assign_current_slave(bond, new);
+-      } else {
+-              bond->current_slave = new;
+-      }
+-}
+-
+-/**
+- * reselect_active_interface - select a new active slave, if needed
+- * @bond: our bonding struct
+- *
+- * This functions shoud be called when one of the following occurs:
+- * - The old current_slave has been released or lost its link.
+- * - The primary_slave has got its link back.
+- * - A slave has got its link back and there's no old current_slave.
+- *
+- * Warning: Caller must hold ptrlock for writing.
+- */
+-static void reselect_active_interface(struct bonding *bond)
+-{
+-      struct slave *best_slave;
+-
+-      best_slave = find_best_interface(bond);
+-
+-      if (best_slave != bond->current_slave) {
+-              change_active_interface(bond, best_slave);
+-      }
+-}
+-
+-/*
+- * Try to release the slave device <slave> from the bond device <master>
+- * It is legal to access current_slave without a lock because all the function
+- * is write-locked.
+- *
+- * The rules for slave state should be:
+- *   for Active/Backup:
+- *     Active stays on all backups go down
+- *   for Bonded connections:
+- *     The first up interface should be left on and all others downed.
+- */
+-static int bond_release(struct net_device *master, struct net_device *slave)
+-{
+-      bonding_t *bond;
+-      slave_t *our_slave, *old_current;
+-      struct sockaddr addr;
+-      
+-      if (master == NULL || slave == NULL)  {
+-              return -ENODEV;
+-      }
+-
+-      bond = (struct bonding *) master->priv;
+-
+-      /* master already enslaved, or slave not enslaved,
+-         or no slave for this master */
+-      if ((master->flags & IFF_SLAVE) || !(slave->flags & IFF_SLAVE)) {
+-              printk (KERN_DEBUG "%s: cannot release %s.\n", master->name, slave->name);
+-              return -EINVAL;
++              /* must be called only after the slave has been
++               * detached from the list and the curr_active_slave
++               * has been replaced (if our_slave == old_current)
++               */
++              bond_alb_deinit_slave(bond, slave);
+       }
+-      write_lock_bh(&bond->lock);
+-      bond->current_arp_slave = NULL;
+-      our_slave = (slave_t *)bond;
+-      old_current = bond->current_slave;
+-      while ((our_slave = our_slave->prev) != (slave_t *)bond) {
+-              if (our_slave->dev == slave) {
+-                      int mac_addr_differ = memcmp(bond->device->dev_addr,
+-                                               our_slave->perm_hwaddr,
+-                                               ETH_ALEN);
+-                      if (!mac_addr_differ && (bond->slave_cnt > 1)) {
+-                              printk(KERN_WARNING "WARNING: the permanent HWaddr of %s "
+-                              "- %02X:%02X:%02X:%02X:%02X:%02X - "
+-                              "is still in use by %s. Set the HWaddr "
+-                              "of %s to a different address "
+-                              "to avoid conflicts.\n",
+-                                     slave->name,
+-                                     our_slave->perm_hwaddr[0],
+-                                     our_slave->perm_hwaddr[1],
+-                                     our_slave->perm_hwaddr[2],
+-                                     our_slave->perm_hwaddr[3],
+-                                     our_slave->perm_hwaddr[4],
+-                                     our_slave->perm_hwaddr[5],
+-                                     bond->device->name,
+-                                     slave->name);
+-                      }
+-
+-                      /* Inform AD package of unbinding of slave. */
+-                      if (bond_mode == BOND_MODE_8023AD) {
+-                              /* must be called before the slave is
+-                               * detached from the list
+-                               */
+-                              bond_3ad_unbind_slave(our_slave);
+-                      }
+-
+-                      printk (KERN_INFO "%s: releasing %s interface %s\n",
+-                              master->name,
+-                              (our_slave->state == BOND_STATE_ACTIVE) ? "active" : "backup",
+-                              slave->name);
+-
+-                      /* release the slave from its bond */
+-                      bond_detach_slave(bond, our_slave);
+-
+-                      if (bond->primary_slave == our_slave) {
+-                              bond->primary_slave = NULL;
+-                      }
+-
+-                      if (bond->current_slave == our_slave) {
+-                              change_active_interface(bond, NULL);
+-                              reselect_active_interface(bond);
+-                      }
+-
+-                      if (bond->current_slave == NULL) {
+-                              printk(KERN_INFO
+-                                      "%s: now running without any active interface !\n",
+-                                      master->name);
+-                      }
+-
+-                      if ((bond_mode == BOND_MODE_TLB) ||
+-                          (bond_mode == BOND_MODE_ALB)) {
+-                              /* must be called only after the slave has been
+-                               * detached from the list and the current_slave
+-                               * has been replaced (if our_slave == old_current)
+-                               */
+-                              bond_alb_deinit_slave(bond, our_slave);
+-                      }
+-
+-                      break;
+-              }
+-
+-      }
+       write_unlock_bh(&bond->lock);
+-      
+-      if (our_slave == (slave_t *)bond) {
+-              /* if we get here, it's because the device was not found */
+-              printk (KERN_INFO "%s: %s not enslaved\n", master->name, slave->name);
+-              return -EINVAL;
+-      }
+-      /* unset promiscuity level from slave */
+-      if (master->flags & IFF_PROMISC) {
+-              /* If the mode USES_PRIMARY, then we should only remove its
+-               * promisc settings if it was the current_slave, but that was
+-               * already taken care of above when we detached the slave
+-               */
+-              if (!USES_PRIMARY(bond_mode)) {
+-                      dev_set_promiscuity(slave, -1); 
++      /* If the mode USES_PRIMARY, then we should only remove its
++       * promisc and mc settings if it was the curr_active_slave, but that was
++       * already taken care of above when we detached the slave
++       */
++      if (!USES_PRIMARY(bond_mode)) {
++              /* unset promiscuity level from slave */
++              if (bond_dev->flags & IFF_PROMISC) {
++                      dev_set_promiscuity(slave_dev, -1);
+               }
+-      }
+-      /* undo settings and restore original values */
+-      if (multicast_mode == BOND_MULTICAST_ALL) {
+-              /* flush master's mc_list from slave */ 
+-              bond_mc_list_flush (slave, master); 
++              /* unset allmulti level from slave */
++              if (bond_dev->flags & IFF_ALLMULTI) {
++                      dev_set_allmulti(slave_dev, -1);
++              }
+-              /* unset allmulti level from slave */ 
+-              if (master->flags & IFF_ALLMULTI)
+-                      dev_set_allmulti(slave, -1); 
++              /* flush master's mc_list from slave */
++              bond_mc_list_flush(bond_dev, slave_dev);
+       }
+-      netdev_set_master(slave, NULL);
++      netdev_set_master(slave_dev, NULL);
+       /* close slave before restoring its mac address */
+-      dev_close(slave);
++      dev_close(slave_dev);
+       if (app_abi_ver >= 1) {
+               /* restore original ("permanent") mac address */
+-              memcpy(addr.sa_data, our_slave->perm_hwaddr, ETH_ALEN);
+-              addr.sa_family = slave->type;
+-              slave->set_mac_address(slave, &addr);
++              memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
++              addr.sa_family = slave_dev->type;
++              slave_dev->set_mac_address(slave_dev, &addr);
+       }
+       /* restore the original state of the
+        * IFF_NOARP flag that might have been
+        * set by bond_set_slave_inactive_flags()
+        */
+-      if ((our_slave->original_flags & IFF_NOARP) == 0) {
+-              slave->flags &= ~IFF_NOARP;
++      if ((slave->original_flags & IFF_NOARP) == 0) {
++              slave_dev->flags &= ~IFF_NOARP;
+       }
+-      kfree(our_slave);
++      kfree(slave);
+       /* if the last slave was removed, zero the mac address
+        * of the master so it will be set by the application
+        * to the mac address of the first slave
+        */
+-      if (bond->next == (slave_t*)bond) {
+-              memset(master->dev_addr, 0, master->addr_len);
++      if (bond->slave_cnt == 0) {
++              memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
+       }
+       return 0;  /* deletion OK */
+ }
+-/* 
++/*
+  * This function releases all slaves.
+  */
+-static int bond_release_all(struct net_device *master)
++static int bond_release_all(struct net_device *bond_dev)
+ {
+-      bonding_t *bond;
+-      slave_t *our_slave, *old_current;
++      struct bonding *bond = bond_dev->priv;
++      struct slave *slave;
+       struct net_device *slave_dev;
+       struct sockaddr addr;
+-      int err = 0;
+-
+-      if (master == NULL)  {
+-              return -ENODEV;
+-      }
+-
+-      if (master->flags & IFF_SLAVE) {
+-              return -EINVAL;
+-      }
+-
+-      bond = (struct bonding *) master->priv;
+       write_lock_bh(&bond->lock);
+-      if (bond->next == (struct slave *) bond) {
+-              err = -EINVAL;
++
++      if (bond->slave_cnt == 0) {
+               goto out;
+       }
+-      old_current = bond->current_slave;
+-      change_active_interface(bond, NULL);
+       bond->current_arp_slave = NULL;
+       bond->primary_slave = NULL;
++      bond_change_active_slave(bond, NULL);
+-      while ((our_slave = bond->prev) != (slave_t *)bond) {
++      while ((slave = bond->first_slave) != NULL) {
+               /* Inform AD package of unbinding of slave
+                * before slave is detached from the list.
+                */
+               if (bond_mode == BOND_MODE_8023AD) {
+-                      bond_3ad_unbind_slave(our_slave);
++                      bond_3ad_unbind_slave(slave);
+               }
+-              slave_dev = our_slave->dev;
+-              bond_detach_slave(bond, our_slave);
++              slave_dev = slave->dev;
++              bond_detach_slave(bond, slave);
+               if ((bond_mode == BOND_MODE_TLB) ||
+                   (bond_mode == BOND_MODE_ALB)) {
+                       /* must be called only after the slave
+                        * has been detached from the list
+                        */
+-                      bond_alb_deinit_slave(bond, our_slave);
++                      bond_alb_deinit_slave(bond, slave);
+               }
+               /* now that the slave is detached, unlock and perform
+@@ -2179,20 +1746,23 @@ static int bond_release_all(struct net_d
+                */
+               write_unlock_bh(&bond->lock);
+-              /* unset promiscuity level from slave */
+-              if (master->flags & IFF_PROMISC) {
+-                      if (!USES_PRIMARY(bond_mode)) {
+-                              dev_set_promiscuity(slave_dev, -1); 
++              /* If the mode USES_PRIMARY, then we should only remove its
++               * promisc and mc settings if it was the curr_active_slave, but that was
++               * already taken care of above when we detached the slave
++               */
++              if (!USES_PRIMARY(bond_mode)) {
++                      /* unset promiscuity level from slave */
++                      if (bond_dev->flags & IFF_PROMISC) {
++                              dev_set_promiscuity(slave_dev, -1);
++                      }
++
++                      /* unset allmulti level from slave */
++                      if (bond_dev->flags & IFF_ALLMULTI) {
++                              dev_set_allmulti(slave_dev, -1);
+                       }
+-              }
+-              if (multicast_mode == BOND_MULTICAST_ALL) {
+-                      /* flush master's mc_list from slave */ 
+-                      bond_mc_list_flush (slave_dev, master); 
+-
+-                      /* unset allmulti level from slave */ 
+-                      if (master->flags & IFF_ALLMULTI)
+-                              dev_set_allmulti(slave_dev, -1); 
++                      /* flush master's mc_list from slave */
++                      bond_mc_list_flush(bond_dev, slave_dev);
+               }
+               netdev_set_master(slave_dev, NULL);
+@@ -2202,7 +1772,7 @@ static int bond_release_all(struct net_d
+               if (app_abi_ver >= 1) {
+                       /* restore original ("permanent") mac address*/
+-                      memcpy(addr.sa_data, our_slave->perm_hwaddr, ETH_ALEN);
++                      memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
+                       addr.sa_family = slave_dev->type;
+                       slave_dev->set_mac_address(slave_dev, &addr);
+               }
+@@ -2210,11 +1780,11 @@ static int bond_release_all(struct net_d
+               /* restore the original state of the IFF_NOARP flag that might have
+                * been set by bond_set_slave_inactive_flags()
+                */
+-              if ((our_slave->original_flags & IFF_NOARP) == 0) {
++              if ((slave->original_flags & IFF_NOARP) == 0) {
+                       slave_dev->flags &= ~IFF_NOARP;
+               }
+-              kfree(our_slave);
++              kfree(slave);
+               /* re-acquire the lock before getting the next slave */
+               write_lock_bh(&bond->lock);
+@@ -2224,72 +1794,234 @@ static int bond_release_all(struct net_d
+        * set by the application to the mac address of the
+        * first slave
+        */
+-      memset(master->dev_addr, 0, master->addr_len);
++      memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
+-      printk (KERN_INFO "%s: released all slaves\n", master->name);
++      printk(KERN_INFO DRV_NAME
++             ": %s: released all slaves\n",
++             bond_dev->name);
+ out:
+       write_unlock_bh(&bond->lock);
+-      return err;
++      return 0;
+ }
+-/* this function is called regularly to monitor each slave's link. */
+-static void bond_mii_monitor(struct net_device *master)
+-{
+-      bonding_t *bond = (struct bonding *) master->priv;
+-      slave_t *slave, *oldcurrent;
+-      int slave_died = 0;
+-      int do_failover = 0;
++/*
++ * This function changes the active slave to slave <slave_dev>.
++ * It returns -EINVAL in the following cases.
++ *  - <slave_dev> is not found in the list.
++ *  - There is not active slave now.
++ *  - <slave_dev> is already active.
++ *  - The link state of <slave_dev> is not BOND_LINK_UP.
++ *  - <slave_dev> is not running.
++ * In these cases, this fuction does nothing.
++ * In the other cases, currnt_slave pointer is changed and 0 is returned.
++ */
++static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_device *slave_dev)
++{
++      struct bonding *bond = bond_dev->priv;
++      struct slave *old_active = NULL;
++      struct slave *new_active = NULL;
++      int res = 0;
++
++      /* Verify that master_dev is indeed the master of slave_dev */
++      if (!(slave_dev->flags & IFF_SLAVE) ||
++          (slave_dev->master != bond_dev)) {
++              return -EINVAL;
++      }
++
++      write_lock_bh(&bond->lock);
++
++      old_active = bond->curr_active_slave;
++      new_active = bond_get_slave_by_dev(bond, slave_dev);
++
++      /*
++       * Changing to the current active: do nothing; return success.
++       */
++      if (new_active && (new_active == old_active)) {
++              write_unlock_bh(&bond->lock);
++              return 0;
++      }
++
++      if ((new_active) &&
++          (old_active) &&
++          (new_active->link == BOND_LINK_UP) &&
++          IS_UP(new_active->dev)) {
++              bond_change_active_slave(bond, new_active);
++      } else {
++              res = -EINVAL;
++      }
++
++      write_unlock_bh(&bond->lock);
++
++      return res;
++}
++
++static int bond_ethtool_ioctl(struct net_device *bond_dev, struct ifreq *ifr)
++{
++      struct ethtool_drvinfo info;
++      void *addr = ifr->ifr_data;
++      uint32_t cmd;
++
++      if (get_user(cmd, (uint32_t *)addr)) {
++              return -EFAULT;
++      }
++
++      switch (cmd) {
++      case ETHTOOL_GDRVINFO:
++              if (copy_from_user(&info, addr, sizeof(info))) {
++                      return -EFAULT;
++              }
++
++              if (strcmp(info.driver, "ifenslave") == 0) {
++                      int new_abi_ver;
++                      char *endptr;
++
++                      new_abi_ver = simple_strtoul(info.fw_version,
++                                                   &endptr, 0);
++                      if (*endptr) {
++                              printk(KERN_ERR DRV_NAME
++                                     ": Error: got invalid ABI "
++                                     "version from application\n");
++
++                              return -EINVAL;
++                      }
++
++                      if (orig_app_abi_ver == -1) {
++                              orig_app_abi_ver  = new_abi_ver;
++                      }
++
++                      app_abi_ver = new_abi_ver;
++              }
++
++              strncpy(info.driver,  DRV_NAME, 32);
++              strncpy(info.version, DRV_VERSION, 32);
++              snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);
++
++              if (copy_to_user(addr, &info, sizeof(info))) {
++                      return -EFAULT;
++              }
++
++              return 0;
++      default:
++              return -EOPNOTSUPP;
++      }
++}
++
++static int bond_info_query(struct net_device *bond_dev, struct ifbond *info)
++{
++      struct bonding *bond = bond_dev->priv;
++
++      info->bond_mode = bond_mode;
++      info->miimon = miimon;
++
++      read_lock_bh(&bond->lock);
++      info->num_slaves = bond->slave_cnt;
++      read_unlock_bh(&bond->lock);
++
++      return 0;
++}
++
++static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *info)
++{
++      struct bonding *bond = bond_dev->priv;
++      struct slave *slave;
++      int i, found = 0;
++
++      if (info->slave_id < 0) {
++              return -ENODEV;
++      }
++
++      read_lock_bh(&bond->lock);
++
++      bond_for_each_slave(bond, slave, i) {
++              if (i == (int)info->slave_id) {
++                      found = 1;
++                      break;
++              }
++      }
++
++      read_unlock_bh(&bond->lock);
++
++      if (found) {
++              strcpy(info->slave_name, slave->dev->name);
++              info->link = slave->link;
++              info->state = slave->state;
++              info->link_failure_count = slave->link_failure_count;
++      } else {
++              return -ENODEV;
++      }
++
++      return 0;
++}
++
++/*-------------------------------- Monitoring -------------------------------*/
++
++/* this function is called regularly to monitor each slave's link. */
++static void bond_mii_monitor(struct net_device *bond_dev)
++{
++      struct bonding *bond = bond_dev->priv;
++      struct slave *slave, *oldcurrent;
++      int do_failover = 0;
++      int delta_in_ticks = (miimon * HZ) / 1000;
++      int i;
+       read_lock(&bond->lock);
++      if (bond->kill_timers) {
++              goto out;
++      }
++
++      if (bond->slave_cnt == 0) {
++              goto re_arm;
++      }
++
+       /* we will try to read the link status of each of our slaves, and
+        * set their IFF_RUNNING flag appropriately. For each slave not
+        * supporting MII status, we won't do anything so that a user-space
+        * program could monitor the link itself if needed.
+        */
+-      slave = (slave_t *)bond;
++      read_lock(&bond->curr_slave_lock);
++      oldcurrent = bond->curr_active_slave;
++      read_unlock(&bond->curr_slave_lock);
+-      read_lock(&bond->ptrlock);
+-      oldcurrent = bond->current_slave;
+-      read_unlock(&bond->ptrlock);
+-
+-      while ((slave = slave->prev) != (slave_t *)bond) {
+-              struct net_device *dev = slave->dev;
++      bond_for_each_slave(bond, slave, i) {
++              struct net_device *slave_dev = slave->dev;
+               int link_state;
+               u16 old_speed = slave->speed;
+               u8 old_duplex = slave->duplex;
+-              
+-              link_state = bond_check_dev_link(dev, 0);
++
++              link_state = bond_check_dev_link(slave_dev, 0);
+               switch (slave->link) {
+               case BOND_LINK_UP:      /* the link was up */
+                       if (link_state == BMSR_LSTATUS) {
+                               /* link stays up, nothing more to do */
+                               break;
+-                      }
+-                      else { /* link going down */
++                      } else { /* link going down */
+                               slave->link  = BOND_LINK_FAIL;
+                               slave->delay = downdelay;
++
+                               if (slave->link_failure_count < UINT_MAX) {
+                                       slave->link_failure_count++;
+                               }
+-                              if (downdelay > 0) {
+-                                      printk (KERN_INFO
+-                                              "%s: link status down for %sinterface "
+-                                              "%s, disabling it in %d ms.\n",
+-                                              master->name,
+-                                              IS_UP(dev)
+-                                              ? ((bond_mode == BOND_MODE_ACTIVEBACKUP)
+-                                                 ? ((slave == oldcurrent)
+-                                                    ? "active " : "backup ")
+-                                                 : "")
+-                                              : "idle ",
+-                                              dev->name,
+-                                              downdelay * miimon);
+-                                      }
++
++                              if (downdelay) {
++                                      printk(KERN_INFO DRV_NAME
++                                             ": %s: link status down for %s "
++                                             "interface %s, disabling it in "
++                                             "%d ms.\n",
++                                             bond_dev->name,
++                                             IS_UP(slave_dev)
++                                             ? ((bond_mode == BOND_MODE_ACTIVEBACKUP)
++                                                ? ((slave == oldcurrent)
++                                                   ? "active " : "backup ")
++                                                : "")
++                                             : "idle ",
++                                             slave_dev->name,
++                                             downdelay * miimon);
++                              }
+                       }
+                       /* no break ! fall through the BOND_LINK_FAIL test to
+                          ensure proper action to be taken
+@@ -2300,6 +2032,7 @@ static void bond_mii_monitor(struct net_
+                               if (slave->delay <= 0) {
+                                       /* link down for too long time */
+                                       slave->link = BOND_LINK_DOWN;
++
+                                       /* in active/backup mode, we must
+                                        * completely disable this interface
+                                        */
+@@ -2308,11 +2041,12 @@ static void bond_mii_monitor(struct net_
+                                               bond_set_slave_inactive_flags(slave);
+                                       }
+-                                      printk(KERN_INFO
+-                                              "%s: link status definitely down "
+-                                              "for interface %s, disabling it",
+-                                              master->name,
+-                                              dev->name);
++                                      printk(KERN_INFO DRV_NAME
++                                             ": %s: link status definitely "
++                                             "down for interface %s, "
++                                             "disabling it\n",
++                                             bond_dev->name,
++                                             slave_dev->name);
+                                       /* notify ad that the link status has changed */
+                                       if (bond_mode == BOND_MODE_8023AD) {
+@@ -2327,8 +2061,6 @@ static void bond_mii_monitor(struct net_
+                                       if (slave == oldcurrent) {
+                                               do_failover = 1;
+                                       }
+-
+-                                      slave_died = 1;
+                               } else {
+                                       slave->delay--;
+                               }
+@@ -2336,12 +2068,12 @@ static void bond_mii_monitor(struct net_
+                               /* link up again */
+                               slave->link  = BOND_LINK_UP;
+                               slave->jiffies = jiffies;
+-                              printk(KERN_INFO
+-                                      "%s: link status up again after %d ms "
+-                                      "for interface %s.\n",
+-                                      master->name,
+-                                      (downdelay - slave->delay) * miimon,
+-                                      dev->name);
++                              printk(KERN_INFO DRV_NAME
++                                     ": %s: link status up again after %d "
++                                     "ms for interface %s.\n",
++                                     bond_dev->name,
++                                     (downdelay - slave->delay) * miimon,
++                                     slave_dev->name);
+                       }
+                       break;
+               case BOND_LINK_DOWN:    /* the link was down */
+@@ -2351,16 +2083,17 @@ static void bond_mii_monitor(struct net_
+                       } else {        /* link going up */
+                               slave->link  = BOND_LINK_BACK;
+                               slave->delay = updelay;
+-                              
+-                              if (updelay > 0) {
++
++                              if (updelay) {
+                                       /* if updelay == 0, no need to
+                                          advertise about a 0 ms delay */
+-                                      printk (KERN_INFO
+-                                              "%s: link status up for interface"
+-                                              " %s, enabling it in %d ms.\n",
+-                                              master->name,
+-                                              dev->name,
+-                                              updelay * miimon);
++                                      printk(KERN_INFO DRV_NAME
++                                             ": %s: link status up for "
++                                             "interface %s, enabling it "
++                                             "in %d ms.\n",
++                                             bond_dev->name,
++                                             slave_dev->name,
++                                             updelay * miimon);
+                               }
+                       }
+                       /* no break ! fall through the BOND_LINK_BACK state in
+@@ -2370,12 +2103,13 @@ static void bond_mii_monitor(struct net_
+                       if (link_state != BMSR_LSTATUS) {
+                               /* link down again */
+                               slave->link  = BOND_LINK_DOWN;
+-                              printk(KERN_INFO
+-                                      "%s: link status down again after %d ms "
+-                                      "for interface %s.\n",
+-                                      master->name,
+-                                      (updelay - slave->delay) * miimon,
+-                                      dev->name);
++
++                              printk(KERN_INFO DRV_NAME
++                                     ": %s: link status down again after %d "
++                                     "ms for interface %s.\n",
++                                     bond_dev->name,
++                                     (updelay - slave->delay) * miimon,
++                                     slave_dev->name);
+                       } else {
+                               /* link stays up */
+                               if (slave->delay == 0) {
+@@ -2386,8 +2120,7 @@ static void bond_mii_monitor(struct net_
+                                       if (bond_mode == BOND_MODE_8023AD) {
+                                               /* prevent it from being the active one */
+                                               slave->state = BOND_STATE_BACKUP;
+-                                      }
+-                                      else if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
++                                      } else if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
+                                               /* make it immediately active */
+                                               slave->state = BOND_STATE_ACTIVE;
+                                       } else if (slave != bond->primary_slave) {
+@@ -2395,12 +2128,12 @@ static void bond_mii_monitor(struct net_
+                                               slave->state = BOND_STATE_BACKUP;
+                                       }
+-                                      printk(KERN_INFO
+-                                              "%s: link status definitely up "
+-                                              "for interface %s.\n",
+-                                              master->name,
+-                                              dev->name);
+-      
++                                      printk(KERN_INFO DRV_NAME
++                                             ": %s: link status definitely "
++                                             "up for interface %s.\n",
++                                             bond_dev->name,
++                                             slave_dev->name);
++
+                                       /* notify ad that the link status has changed */
+                                       if (bond_mode == BOND_MODE_8023AD) {
+                                               bond_3ad_handle_link_change(slave, BOND_LINK_UP);
+@@ -2411,7 +2144,7 @@ static void bond_mii_monitor(struct net_
+                                               bond_alb_handle_link_change(bond, slave, BOND_LINK_UP);
+                                       }
+-                                      if ((oldcurrent == NULL) ||
++                                      if ((!oldcurrent) ||
+                                           (slave == bond->primary_slave)) {
+                                               do_failover = 1;
+                                       }
+@@ -2420,7 +2153,12 @@ static void bond_mii_monitor(struct net_
+                               }
+                       }
+                       break;
+-              } /* end of switch */
++              default:
++                      /* Should not happen */
++                      printk(KERN_ERR "bonding: Error: %s  Illegal value (link=%d)\n",
++                             slave->dev->name, slave->link);
++                      goto out;
++              } /* end of switch (slave->link) */
+               bond_update_speed_duplex(slave);
+@@ -2428,112 +2166,110 @@ static void bond_mii_monitor(struct net_
+                       if (old_speed != slave->speed) {
+                               bond_3ad_adapter_speed_changed(slave);
+                       }
++
+                       if (old_duplex != slave->duplex) {
+                               bond_3ad_adapter_duplex_changed(slave);
+                       }
+               }
+-      } /* end of while */
++      } /* end of for */
+       if (do_failover) {
+-              write_lock(&bond->ptrlock);
++              write_lock(&bond->curr_slave_lock);
++
++              bond_select_active_slave(bond);
+-              reselect_active_interface(bond);
+-              if (oldcurrent && !bond->current_slave) {
+-                      printk(KERN_INFO
+-                              "%s: now running without any active interface !\n",
+-                              master->name);
++              if (oldcurrent && !bond->curr_active_slave) {
++                      printk(KERN_INFO DRV_NAME
++                             ": %s: now running without any active "
++                             "interface !\n",
++                             bond_dev->name);
+               }
+-              write_unlock(&bond->ptrlock);
++              write_unlock(&bond->curr_slave_lock);
+       }
++re_arm:
++      mod_timer(&bond->mii_timer, jiffies + delta_in_ticks);
++out:
+       read_unlock(&bond->lock);
+-      /* re-arm the timer */
+-      mod_timer(&bond->mii_timer, jiffies + (miimon * HZ / 1000));
+ }
+-/* 
+- * this function is called regularly to monitor each slave's link 
++static void bond_arp_send_all(struct slave *slave)
++{
++      int i;
++
++      for (i = 0; (i<MAX_ARP_IP_TARGETS) && arp_target[i]; i++) {
++              arp_send(ARPOP_REQUEST, ETH_P_ARP, arp_target[i], slave->dev,
++                       my_ip, NULL, slave->dev->dev_addr,
++                       NULL);
++      }
++}
++
++/*
++ * this function is called regularly to monitor each slave's link
+  * ensuring that traffic is being sent and received when arp monitoring
+- * is used in load-balancing mode. if the adapter has been dormant, then an 
+- * arp is transmitted to generate traffic. see activebackup_arp_monitor for 
+- * arp monitoring in active backup mode. 
++ * is used in load-balancing mode. if the adapter has been dormant, then an
++ * arp is transmitted to generate traffic. see activebackup_arp_monitor for
++ * arp monitoring in active backup mode.
+  */
+-static void loadbalance_arp_monitor(struct net_device *master)
++static void bond_loadbalance_arp_mon(struct net_device *bond_dev)
+ {
+-      bonding_t *bond;
+-      slave_t *slave, *oldcurrent;
+-      int the_delta_in_ticks =  arp_interval * HZ / 1000;
+-      int next_timer = jiffies + (arp_interval * HZ / 1000);
++      struct bonding *bond = bond_dev->priv;
++      struct slave *slave, *oldcurrent;
+       int do_failover = 0;
++      int delta_in_ticks = (arp_interval * HZ) / 1000;
++      int i;
+-      bond = (struct bonding *) master->priv; 
+-      if (master->priv == NULL) {
+-              mod_timer(&bond->arp_timer, next_timer);
+-              return;
+-      }
++      read_lock(&bond->lock);
+-      /* TODO: investigate why rtnl_shlock_nowait and rtnl_exlock_nowait
+-       * are called below and add comment why they are required... 
+-       */
+-      if ((!IS_UP(master)) || rtnl_shlock_nowait()) {
+-              mod_timer(&bond->arp_timer, next_timer);
+-              return;
++      if (bond->kill_timers) {
++              goto out;
+       }
+-      if (rtnl_exlock_nowait()) {
+-              rtnl_shunlock();
+-              mod_timer(&bond->arp_timer, next_timer);
+-              return;
++      if (bond->slave_cnt == 0) {
++              goto re_arm;
+       }
+-      read_lock(&bond->lock);
+-
+-      read_lock(&bond->ptrlock);
+-      oldcurrent = bond->current_slave;
+-      read_unlock(&bond->ptrlock);
++      read_lock(&bond->curr_slave_lock);
++      oldcurrent = bond->curr_active_slave;
++      read_unlock(&bond->curr_slave_lock);
+       /* see if any of the previous devices are up now (i.e. they have
+-       * xmt and rcv traffic). the current_slave does not come into
++       * xmt and rcv traffic). the curr_active_slave does not come into
+        * the picture unless it is null. also, slave->jiffies is not needed
+        * here because we send an arp on each slave and give a slave as
+        * long as it needs to get the tx/rx within the delta.
+        * TODO: what about up/down delay in arp mode? it wasn't here before
+-       *       so it can wait 
++       *       so it can wait
+        */
+-      slave = (slave_t *)bond;
+-      while ((slave = slave->prev) != (slave_t *)bond)  {
+-
+-              if (slave->link != BOND_LINK_UP) {
+-
+-                      if (((jiffies - slave->dev->trans_start) <= 
+-                                              the_delta_in_ticks) &&  
+-                           ((jiffies - slave->dev->last_rx) <= 
+-                                              the_delta_in_ticks)) {
++      bond_for_each_slave(bond, slave, i) {
++              if (slave->link != BOND_LINK_UP) {
++                      if (((jiffies - slave->dev->trans_start) <= delta_in_ticks) &&
++                          ((jiffies - slave->dev->last_rx) <= delta_in_ticks)) {
+                               slave->link  = BOND_LINK_UP;
+                               slave->state = BOND_STATE_ACTIVE;
+                               /* primary_slave has no meaning in round-robin
+-                               * mode. the window of a slave being up and 
+-                               * current_slave being null after enslaving
++                               * mode. the window of a slave being up and
++                               * curr_active_slave being null after enslaving
+                                * is closed.
+                                */
+-                              if (oldcurrent == NULL) {
+-                                      printk(KERN_INFO
+-                                              "%s: link status definitely up "
+-                                              "for interface %s, ",
+-                                              master->name,
+-                                              slave->dev->name);
++                              if (!oldcurrent) {
++                                      printk(KERN_INFO DRV_NAME
++                                             ": %s: link status definitely "
++                                             "up for interface %s, ",
++                                             bond_dev->name,
++                                             slave->dev->name);
+                                       do_failover = 1;
+                               } else {
+-                                      printk(KERN_INFO
+-                                              "%s: interface %s is now up\n",
+-                                              master->name,
+-                                              slave->dev->name);
++                                      printk(KERN_INFO DRV_NAME
++                                             ": %s: interface %s is now up\n",
++                                             bond_dev->name,
++                                             slave->dev->name);
+                               }
+-                      } 
++                      }
+               } else {
+                       /* slave->link == BOND_LINK_UP */
+@@ -2541,224 +2277,233 @@ static void loadbalance_arp_monitor(stru
+                        * when the source ip is 0, so don't take the link down
+                        * if we don't know our ip yet
+                        */
+-                      if (((jiffies - slave->dev->trans_start) >= 
+-                            (2*the_delta_in_ticks)) ||
+-                           (((jiffies - slave->dev->last_rx) >= 
+-                             (2*the_delta_in_ticks)) && my_ip !=0)) {
++                      if (((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) ||
++                          (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) &&
++                           my_ip)) {
++
+                               slave->link  = BOND_LINK_DOWN;
+                               slave->state = BOND_STATE_BACKUP;
++
+                               if (slave->link_failure_count < UINT_MAX) {
+                                       slave->link_failure_count++;
+                               }
+-                              printk(KERN_INFO
+-                                     "%s: interface %s is now down.\n",
+-                                     master->name,
++
++                              printk(KERN_INFO DRV_NAME
++                                     ": %s: interface %s is now down.\n",
++                                     bond_dev->name,
+                                      slave->dev->name);
+                               if (slave == oldcurrent) {
+                                       do_failover = 1;
+                               }
+                       }
+-              } 
++              }
+-              /* note: if switch is in round-robin mode, all links 
++              /* note: if switch is in round-robin mode, all links
+                * must tx arp to ensure all links rx an arp - otherwise
+-               * links may oscillate or not come up at all; if switch is 
+-               * in something like xor mode, there is nothing we can 
+-               * do - all replies will be rx'ed on same link causing slaves 
++               * links may oscillate or not come up at all; if switch is
++               * in something like xor mode, there is nothing we can
++               * do - all replies will be rx'ed on same link causing slaves
+                * to be unstable during low/no traffic periods
+                */
+               if (IS_UP(slave->dev)) {
+-                      arp_send_all(slave);
++                      bond_arp_send_all(slave);
+               }
+       }
+       if (do_failover) {
+-              write_lock(&bond->ptrlock);
++              write_lock(&bond->curr_slave_lock);
+-              reselect_active_interface(bond);
+-              if (oldcurrent && !bond->current_slave) {
+-                      printk(KERN_INFO
+-                              "%s: now running without any active interface !\n",
+-                              master->name);
++              bond_select_active_slave(bond);
++
++              if (oldcurrent && !bond->curr_active_slave) {
++                      printk(KERN_INFO DRV_NAME
++                             ": %s: now running without any active "
++                             "interface !\n",
++                             bond_dev->name);
+               }
+-              write_unlock(&bond->ptrlock);
++              write_unlock(&bond->curr_slave_lock);
+       }
++re_arm:
++      mod_timer(&bond->arp_timer, jiffies + delta_in_ticks);
++out:
+       read_unlock(&bond->lock);
+-      rtnl_exunlock();
+-      rtnl_shunlock();
+-
+-      /* re-arm the timer */
+-      mod_timer(&bond->arp_timer, next_timer);
+ }
+-/* 
++/*
+  * When using arp monitoring in active-backup mode, this function is
+  * called to determine if any backup slaves have went down or a new
+  * current slave needs to be found.
+- * The backup slaves never generate traffic, they are considered up by merely 
+- * receiving traffic. If the current slave goes down, each backup slave will 
+- * be given the opportunity to tx/rx an arp before being taken down - this 
+- * prevents all slaves from being taken down due to the current slave not 
++ * The backup slaves never generate traffic, they are considered up by merely
++ * receiving traffic. If the current slave goes down, each backup slave will
++ * be given the opportunity to tx/rx an arp before being taken down - this
++ * prevents all slaves from being taken down due to the current slave not
+  * sending any traffic for the backups to receive. The arps are not necessarily
+- * necessary, any tx and rx traffic will keep the current slave up. While any 
+- * rx traffic will keep the backup slaves up, the current slave is responsible 
+- * for generating traffic to keep them up regardless of any other traffic they 
++ * necessary, any tx and rx traffic will keep the current slave up. While any
++ * rx traffic will keep the backup slaves up, the current slave is responsible
++ * for generating traffic to keep them up regardless of any other traffic they
+  * may have received.
+  * see loadbalance_arp_monitor for arp monitoring in load balancing mode
+  */
+-static void activebackup_arp_monitor(struct net_device *master)
++static void bond_activebackup_arp_mon(struct net_device *bond_dev)
+ {
+-      bonding_t *bond;
+-      slave_t *slave;
+-      int the_delta_in_ticks =  arp_interval * HZ / 1000;
+-      int next_timer = jiffies + (arp_interval * HZ / 1000);
+-
+-      bond = (struct bonding *) master->priv; 
+-      if (master->priv == NULL) {
+-              mod_timer(&bond->arp_timer, next_timer);
+-              return;
+-      }
++      struct bonding *bond = bond_dev->priv;
++      struct slave *slave;
++      int delta_in_ticks = (arp_interval * HZ) / 1000;
++      int i;
+-      if (!IS_UP(master)) {
+-              mod_timer(&bond->arp_timer, next_timer);
+-              return;
++      read_lock(&bond->lock);
++
++      if (bond->kill_timers) {
++              goto out;
+       }
+-      read_lock(&bond->lock);
++      if (bond->slave_cnt == 0) {
++              goto re_arm;
++      }
+-      /* determine if any slave has come up or any backup slave has 
+-       * gone down 
++      /* determine if any slave has come up or any backup slave has
++       * gone down
+        * TODO: what about up/down delay in arp mode? it wasn't here before
+-       *       so it can wait 
++       *       so it can wait
+        */
+-      slave = (slave_t *)bond;
+-      while ((slave = slave->prev) != (slave_t *)bond)  {
+-
+-              if (slave->link != BOND_LINK_UP) {
+-                      if ((jiffies - slave->dev->last_rx) <=
+-                          the_delta_in_ticks) {
++      bond_for_each_slave(bond, slave, i) {
++              if (slave->link != BOND_LINK_UP) {
++                      if ((jiffies - slave->dev->last_rx) <= delta_in_ticks) {
+                               slave->link = BOND_LINK_UP;
+-                              write_lock(&bond->ptrlock);
+-                              if ((bond->current_slave == NULL) &&
+-                                  ((jiffies - slave->dev->trans_start) <=
+-                                   the_delta_in_ticks)) {
+-                                      change_active_interface(bond, slave);
++
++                              write_lock(&bond->curr_slave_lock);
++
++                              if ((!bond->curr_active_slave) &&
++                                  ((jiffies - slave->dev->trans_start) <= delta_in_ticks)) {
++                                      bond_change_active_slave(bond, slave);
+                                       bond->current_arp_slave = NULL;
+-                              } else if (bond->current_slave != slave) {
+-                                      /* this slave has just come up but we 
++                              } else if (bond->curr_active_slave != slave) {
++                                      /* this slave has just come up but we
+                                        * already have a current slave; this
+                                        * can also happen if bond_enslave adds
+-                                       * a new slave that is up while we are 
++                                       * a new slave that is up while we are
+                                        * searching for a new slave
+                                        */
+                                       bond_set_slave_inactive_flags(slave);
+                                       bond->current_arp_slave = NULL;
+                               }
+-                              if (slave == bond->current_slave) {
+-                                      printk(KERN_INFO
+-                                              "%s: %s is up and now the "
+-                                              "active interface\n",
+-                                              master->name,
+-                                              slave->dev->name);
++                              if (slave == bond->curr_active_slave) {
++                                      printk(KERN_INFO DRV_NAME
++                                             ": %s: %s is up and now the "
++                                             "active interface\n",
++                                             bond_dev->name,
++                                             slave->dev->name);
+                               } else {
+-                                      printk(KERN_INFO
+-                                              "%s: backup interface %s is "
+-                                              "now up\n",
+-                                              master->name,
+-                                              slave->dev->name);
++                                      printk(KERN_INFO DRV_NAME
++                                             ": %s: backup interface %s is "
++                                             "now up\n",
++                                             bond_dev->name,
++                                             slave->dev->name);
+                               }
+-                              write_unlock(&bond->ptrlock);
++                              write_unlock(&bond->curr_slave_lock);
+                       }
+               } else {
+-                      read_lock(&bond->ptrlock);
+-                      if ((slave != bond->current_slave) &&
+-                          (bond->current_arp_slave == NULL) &&
+-                          (((jiffies - slave->dev->last_rx) >=
+-                           3*the_delta_in_ticks) && (my_ip != 0))) {
+-                              /* a backup slave has gone down; three times 
+-                               * the delta allows the current slave to be 
++                      read_lock(&bond->curr_slave_lock);
++
++                      if ((slave != bond->curr_active_slave) &&
++                          (!bond->current_arp_slave) &&
++                          (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) &&
++                           my_ip)) {
++                              /* a backup slave has gone down; three times
++                               * the delta allows the current slave to be
+                                * taken out before the backup slave.
+                                * note: a non-null current_arp_slave indicates
+-                               * the current_slave went down and we are 
+-                               * searching for a new one; under this 
+-                               * condition we only take the current_slave 
+-                               * down - this gives each slave a chance to 
++                               * the curr_active_slave went down and we are
++                               * searching for a new one; under this
++                               * condition we only take the curr_active_slave
++                               * down - this gives each slave a chance to
+                                * tx/rx traffic before being taken out
+                                */
+-                              read_unlock(&bond->ptrlock);
++
++                              read_unlock(&bond->curr_slave_lock);
++
+                               slave->link  = BOND_LINK_DOWN;
++
+                               if (slave->link_failure_count < UINT_MAX) {
+                                       slave->link_failure_count++;
+                               }
++
+                               bond_set_slave_inactive_flags(slave);
+-                              printk(KERN_INFO
+-                                      "%s: backup interface %s is now down\n",
+-                                      master->name,
+-                                      slave->dev->name);
++
++                              printk(KERN_INFO DRV_NAME
++                                     ": %s: backup interface %s is now down\n",
++                                     bond_dev->name,
++                                     slave->dev->name);
+                       } else {
+-                              read_unlock(&bond->ptrlock);
++                              read_unlock(&bond->curr_slave_lock);
+                       }
+               }
+       }
+-      read_lock(&bond->ptrlock);
+-      slave = bond->current_slave;
+-      read_unlock(&bond->ptrlock);
+-
+-      if (slave != NULL) {
++      read_lock(&bond->curr_slave_lock);
++      slave = bond->curr_active_slave;
++      read_unlock(&bond->curr_slave_lock);
++      if (slave) {
+               /* if we have sent traffic in the past 2*arp_intervals but
+-               * haven't xmit and rx traffic in that time interval, select 
++               * haven't xmit and rx traffic in that time interval, select
+                * a different slave. slave->jiffies is only updated when
+-               * a slave first becomes the current_slave - not necessarily
+-               * after every arp; this ensures the slave has a full 2*delta 
+-               * before being taken out. if a primary is being used, check 
+-               * if it is up and needs to take over as the current_slave
++               * a slave first becomes the curr_active_slave - not necessarily
++               * after every arp; this ensures the slave has a full 2*delta
++               * before being taken out. if a primary is being used, check
++               * if it is up and needs to take over as the curr_active_slave
+                */
+-              if ((((jiffies - slave->dev->trans_start) >= 
+-                     (2*the_delta_in_ticks)) ||
+-                   (((jiffies - slave->dev->last_rx) >= 
+-                     (2*the_delta_in_ticks)) && (my_ip != 0))) &&
+-                  ((jiffies - slave->jiffies) >= 2*the_delta_in_ticks)) {
++              if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) ||
++                   (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) &&
++                    my_ip)) &&
++                  ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) {
+                       slave->link  = BOND_LINK_DOWN;
++
+                       if (slave->link_failure_count < UINT_MAX) {
+                               slave->link_failure_count++;
+                       }
+-                      printk(KERN_INFO "%s: link status down for "
+-                                       "active interface %s, disabling it",
+-                             master->name,
++
++                      printk(KERN_INFO DRV_NAME
++                             ": %s: link status down for active interface "
++                             "%s, disabling it\n",
++                             bond_dev->name,
+                              slave->dev->name);
+-                      write_lock(&bond->ptrlock);
+-                      reselect_active_interface(bond);
+-                      slave = bond->current_slave;
+-                      write_unlock(&bond->ptrlock);
++
++                      write_lock(&bond->curr_slave_lock);
++
++                      bond_select_active_slave(bond);
++                      slave = bond->curr_active_slave;
++
++                      write_unlock(&bond->curr_slave_lock);
++
+                       bond->current_arp_slave = slave;
+-                      if (slave != NULL) {
++
++                      if (slave) {
+                               slave->jiffies = jiffies;
+                       }
+-
+-              } else if ((bond->primary_slave != NULL) && 
+-                         (bond->primary_slave != slave) && 
++              } else if ((bond->primary_slave) &&
++                         (bond->primary_slave != slave) &&
+                          (bond->primary_slave->link == BOND_LINK_UP)) {
+-                      /* at this point, slave is the current_slave */
+-                      printk(KERN_INFO 
+-                             "%s: changing from interface %s to primary "
++                      /* at this point, slave is the curr_active_slave */
++                      printk(KERN_INFO DRV_NAME
++                             ": %s: changing from interface %s to primary "
+                              "interface %s\n",
+-                             master->name, 
+-                             slave->dev->name, 
++                             bond_dev->name,
++                             slave->dev->name,
+                              bond->primary_slave->dev->name);
+-                             
++
+                       /* primary is up so switch to it */
+-                      write_lock(&bond->ptrlock);
+-                      change_active_interface(bond, bond->primary_slave);
+-                      write_unlock(&bond->ptrlock);
++                      write_lock(&bond->curr_slave_lock);
++                      bond_change_active_slave(bond, bond->primary_slave);
++                      write_unlock(&bond->curr_slave_lock);
++
+                       slave = bond->primary_slave;
+                       slave->jiffies = jiffies;
+               } else {
+@@ -2768,567 +2513,606 @@ static void activebackup_arp_monitor(str
+               /* the current slave must tx an arp to ensure backup slaves
+                * rx traffic
+                */
+-              if ((slave != NULL) && (my_ip != 0)) {
+-                      arp_send_all(slave);
++              if (slave && my_ip) {
++                      bond_arp_send_all(slave);
+               }
+       }
+-      /* if we don't have a current_slave, search for the next available 
+-       * backup slave from the current_arp_slave and make it the candidate 
+-       * for becoming the current_slave
++      /* if we don't have a curr_active_slave, search for the next available
++       * backup slave from the current_arp_slave and make it the candidate
++       * for becoming the curr_active_slave
+        */
+-      if (slave == NULL) { 
+-
+-              if ((bond->current_arp_slave == NULL) ||
+-                  (bond->current_arp_slave == (slave_t *)bond)) {
+-                      bond->current_arp_slave = bond->prev;
+-              } 
++      if (!slave) {
++              if (!bond->current_arp_slave) {
++                      bond->current_arp_slave = bond->first_slave;
++              }
+-              if (bond->current_arp_slave != (slave_t *)bond) {
++              if (bond->current_arp_slave) {
+                       bond_set_slave_inactive_flags(bond->current_arp_slave);
+-                      slave = bond->current_arp_slave->next;
+                       /* search for next candidate */
+-                      do {
++                      bond_for_each_slave_from(bond, slave, i, bond->current_arp_slave) {
+                               if (IS_UP(slave->dev)) {
+                                       slave->link = BOND_LINK_BACK;
+                                       bond_set_slave_active_flags(slave);
+-                                      arp_send_all(slave);
++                                      bond_arp_send_all(slave);
+                                       slave->jiffies = jiffies;
+                                       bond->current_arp_slave = slave;
+                                       break;
+                               }
+-                              /* if the link state is up at this point, we 
+-                               * mark it down - this can happen if we have 
+-                               * simultaneous link failures and 
+-                               * reselect_active_interface doesn't make this 
+-                               * one the current slave so it is still marked 
++                              /* if the link state is up at this point, we
++                               * mark it down - this can happen if we have
++                               * simultaneous link failures and
++                               * reselect_active_interface doesn't make this
++                               * one the current slave so it is still marked
+                                * up when it is actually down
+                                */
+                               if (slave->link == BOND_LINK_UP) {
+                                       slave->link  = BOND_LINK_DOWN;
+-                                      if (slave->link_failure_count < 
+-                                                      UINT_MAX) {
++                                      if (slave->link_failure_count < UINT_MAX) {
+                                               slave->link_failure_count++;
+                                       }
+                                       bond_set_slave_inactive_flags(slave);
+-                                      printk(KERN_INFO
+-                                              "%s: backup interface "
+-                                              "%s is now down.\n",
+-                                              master->name,
+-                                              slave->dev->name);
++
++                                      printk(KERN_INFO DRV_NAME
++                                             ": %s: backup interface %s is "
++                                             "now down.\n",
++                                             bond_dev->name,
++                                             slave->dev->name);
+                               }
+-                      } while ((slave = slave->next) != 
+-                                      bond->current_arp_slave->next);
++                      }
+               }
+       }
++re_arm:
++      mod_timer(&bond->arp_timer, jiffies + delta_in_ticks);
++out:
+       read_unlock(&bond->lock);
+-      mod_timer(&bond->arp_timer, next_timer);
+ }
+-static int bond_sethwaddr(struct net_device *master, struct net_device *slave)
+-{
+-#ifdef BONDING_DEBUG
+-      printk(KERN_CRIT "bond_sethwaddr: master=%x\n", (unsigned int)master);
+-      printk(KERN_CRIT "bond_sethwaddr: slave=%x\n", (unsigned int)slave);
+-      printk(KERN_CRIT "bond_sethwaddr: slave->addr_len=%d\n", slave->addr_len);
+-#endif
+-      memcpy(master->dev_addr, slave->dev_addr, slave->addr_len);
+-      return 0;
+-}
++/*------------------------------ proc/seq_file-------------------------------*/
+-static int bond_info_query(struct net_device *master, struct ifbond *info)
+-{
+-      bonding_t *bond = (struct bonding *) master->priv;
+-      slave_t *slave;
++#ifdef CONFIG_PROC_FS
+-      info->bond_mode = bond_mode;
+-      info->num_slaves = 0;
+-      info->miimon = miimon;
++#define SEQ_START_TOKEN ((void *)1)
++
++static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
++{
++      struct bonding *bond = seq->private;
++      loff_t off = 0;
++      struct slave *slave;
++      int i;
++      /* make sure the bond won't be taken away */
++      read_lock(&dev_base_lock);
+       read_lock_bh(&bond->lock);
+-      for (slave = bond->prev; slave != (slave_t *)bond; slave = slave->prev) {
+-              info->num_slaves++;
++
++      if (*pos == 0) {
++              return SEQ_START_TOKEN;
+       }
+-      read_unlock_bh(&bond->lock);
+-      return 0;
++      bond_for_each_slave(bond, slave, i) {
++              if (++off == *pos) {
++                      return slave;
++              }
++      }
++
++      return NULL;
+ }
+-static int bond_slave_info_query(struct net_device *master, 
+-                                      struct ifslave *info)
++static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+-      bonding_t *bond = (struct bonding *) master->priv;
+-      slave_t *slave;
+-      int cur_ndx = 0;
+-
+-      if (info->slave_id < 0) {
+-              return -ENODEV;
+-      }
++      struct bonding *bond = seq->private;
++      struct slave *slave = v;
+-      read_lock_bh(&bond->lock);
+-      for (slave = bond->prev; 
+-               slave != (slave_t *)bond && cur_ndx < info->slave_id; 
+-               slave = slave->prev) {
+-              cur_ndx++;
++      ++*pos;
++      if (v == SEQ_START_TOKEN) {
++              return bond->first_slave;
+       }
+-      read_unlock_bh(&bond->lock);
+-      if (slave != (slave_t *)bond) {
+-              strcpy(info->slave_name, slave->dev->name);
+-              info->link = slave->link;
+-              info->state = slave->state;
+-              info->link_failure_count = slave->link_failure_count;
+-      } else {
+-              return -ENODEV;
+-      }
++      slave = slave->next;
+-      return 0;
++      return (slave == bond->first_slave) ? NULL : slave;
+ }
+-static int bond_ethtool_ioctl(struct net_device *master_dev, struct ifreq *ifr)
++static void bond_info_seq_stop(struct seq_file *seq, void *v)
+ {
+-      void *addr = ifr->ifr_data;
+-      uint32_t cmd;
++      struct bonding *bond = seq->private;
+-      if (get_user(cmd, (uint32_t *) addr))
+-              return -EFAULT;
++      read_unlock_bh(&bond->lock);
++      read_unlock(&dev_base_lock);
++}
+-      switch (cmd) {
++static void bond_info_show_master(struct seq_file *seq, struct bonding *bond)
++{
++      struct slave *curr;
+-      case ETHTOOL_GDRVINFO:
+-              {
+-                      struct ethtool_drvinfo info;
+-                      char *endptr;
++      read_lock(&bond->curr_slave_lock);
++      curr = bond->curr_active_slave;
++      read_unlock(&bond->curr_slave_lock);
+-                      if (copy_from_user(&info, addr, sizeof(info)))
+-                              return -EFAULT;
++      seq_printf(seq, "Bonding Mode: %s\n", bond_mode_name());
+-                      if (strcmp(info.driver, "ifenslave") == 0) {
+-                              int new_abi_ver;
++      if (USES_PRIMARY(bond_mode)) {
++              if (curr) {
++                      seq_printf(seq,
++                                 "Currently Active Slave: %s\n",
++                                 curr->dev->name);
++              }
++      }
+-                              new_abi_ver = simple_strtoul(info.fw_version,
+-                                                           &endptr, 0);
+-                              if (*endptr) {
+-                                      printk(KERN_ERR
+-                                             "bonding: Error: got invalid ABI"
+-                                             " version from application\n");
++      seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down");
++      seq_printf(seq, "MII Polling Interval (ms): %d\n", miimon);
++      seq_printf(seq, "Up Delay (ms): %d\n", updelay * miimon);
++      seq_printf(seq, "Down Delay (ms): %d\n", downdelay * miimon);
+-                                      return -EINVAL;
+-                              }
++      if (bond_mode == BOND_MODE_8023AD) {
++              struct ad_info ad_info;
+-                              if (orig_app_abi_ver == -1) {
+-                                      orig_app_abi_ver  = new_abi_ver;
+-                              }
++              seq_puts(seq, "\n802.3ad info\n");
+-                              app_abi_ver = new_abi_ver;
+-                      }
++              if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
++                      seq_printf(seq, "bond %s has no active aggregator\n",
++                                 bond->dev->name);
++              } else {
++                      seq_printf(seq, "Active Aggregator Info:\n");
+-                      strncpy(info.driver,  DRV_NAME, 32);
+-                      strncpy(info.version, DRV_VERSION, 32);
+-                      snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);
++                      seq_printf(seq, "\tAggregator ID: %d\n",
++                                 ad_info.aggregator_id);
++                      seq_printf(seq, "\tNumber of ports: %d\n",
++                                 ad_info.ports);
++                      seq_printf(seq, "\tActor Key: %d\n",
++                                 ad_info.actor_key);
++                      seq_printf(seq, "\tPartner Key: %d\n",
++                                 ad_info.partner_key);
++                      seq_printf(seq, "\tPartner Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
++                                 ad_info.partner_system[0],
++                                 ad_info.partner_system[1],
++                                 ad_info.partner_system[2],
++                                 ad_info.partner_system[3],
++                                 ad_info.partner_system[4],
++                                 ad_info.partner_system[5]);
++              }
++      }
++}
+-                      if (copy_to_user(addr, &info, sizeof(info)))
+-                              return -EFAULT;
++static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave)
++{
++      seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
++      seq_printf(seq, "MII Status: %s\n",
++                 (slave->link == BOND_LINK_UP) ?  "up" : "down");
++      seq_printf(seq, "Link Failure Count: %d\n",
++                 slave->link_failure_count);
++
++      if (app_abi_ver >= 1) {
++              seq_printf(seq,
++                         "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
++                         slave->perm_hwaddr[0],
++                         slave->perm_hwaddr[1],
++                         slave->perm_hwaddr[2],
++                         slave->perm_hwaddr[3],
++                         slave->perm_hwaddr[4],
++                         slave->perm_hwaddr[5]);
++      }
+-                      return 0;
++      if (bond_mode == BOND_MODE_8023AD) {
++              const struct aggregator *agg
++                      = SLAVE_AD_INFO(slave).port.aggregator;
++
++              if (agg) {
++                      seq_printf(seq, "Aggregator ID: %d\n",
++                                 agg->aggregator_identifier);
++              } else {
++                      seq_puts(seq, "Aggregator ID: N/A\n");
+               }
+-              break;
+-      default:
+-              return -EOPNOTSUPP;
+       }
+ }
+-static int bond_ioctl(struct net_device *master_dev, struct ifreq *ifr, int cmd)
++static int bond_info_seq_show(struct seq_file *seq, void *v)
+ {
+-      struct net_device *slave_dev = NULL;
+-      struct ifbond *u_binfo = NULL, k_binfo;
+-      struct ifslave *u_sinfo = NULL, k_sinfo;
+-      struct mii_ioctl_data *mii = NULL;
+-      int prev_abi_ver = orig_app_abi_ver;
+-      int ret = 0;
++      if (v == SEQ_START_TOKEN) {
++              seq_printf(seq, "%s\n", version);
++              bond_info_show_master(seq, seq->private);
++      } else {
++              bond_info_show_slave(seq, v);
++      }
+-#ifdef BONDING_DEBUG
+-      printk(KERN_INFO "bond_ioctl: master=%s, cmd=%d\n", 
+-              master_dev->name, cmd);
+-#endif
++      return 0;
++}
+-      switch (cmd) {
+-      case SIOCETHTOOL:
+-              return bond_ethtool_ioctl(master_dev, ifr);
++static struct seq_operations bond_info_seq_ops = {
++      .start = bond_info_seq_start,
++      .next  = bond_info_seq_next,
++      .stop  = bond_info_seq_stop,
++      .show  = bond_info_seq_show,
++};
+-      case SIOCGMIIPHY:
+-              mii = (struct mii_ioctl_data *)&ifr->ifr_data;
+-              if (mii == NULL) {
+-                      return -EINVAL;
+-              }
+-              mii->phy_id = 0;
+-              /* Fall Through */
+-      case SIOCGMIIREG:
+-              /* 
+-               * We do this again just in case we were called by SIOCGMIIREG
+-               * instead of SIOCGMIIPHY.
+-               */
+-              mii = (struct mii_ioctl_data *)&ifr->ifr_data;
+-              if (mii == NULL) {
+-                      return -EINVAL;
+-              }
+-              if (mii->reg_num == 1) {
+-                      mii->val_out = bond_check_mii_link(
+-                              (struct bonding *)master_dev->priv);
+-              }
+-              return 0;
+-      case BOND_INFO_QUERY_OLD:
+-      case SIOCBONDINFOQUERY:
+-              u_binfo = (struct ifbond *)ifr->ifr_data;
+-              if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) {
+-                      return -EFAULT;
+-              }
+-              ret = bond_info_query(master_dev, &k_binfo);
+-              if (ret == 0) {
+-                      if (copy_to_user(u_binfo, &k_binfo, sizeof(ifbond))) {
+-                              return -EFAULT;
+-                      }
++static int bond_info_open(struct inode *inode, struct file *file)
++{
++      struct seq_file *seq;
++      struct proc_dir_entry *proc;
++      int res;
++
++      res = seq_open(file, &bond_info_seq_ops);
++      if (!res) {
++              /* recover the pointer buried in proc_dir_entry data */
++              seq = file->private_data;
++              proc = PDE(inode);
++              seq->private = proc->data;
++      }
++
++      return res;
++}
++
++static struct file_operations bond_info_fops = {
++      .owner   = THIS_MODULE,
++      .open    = bond_info_open,
++      .read    = seq_read,
++      .llseek  = seq_lseek,
++      .release = seq_release,
++};
++
++static int bond_create_proc_entry(struct bonding *bond)
++{
++      struct net_device *bond_dev = bond->dev;
++
++      if (bond_proc_dir) {
++              bond->proc_entry = create_proc_entry(bond_dev->name,
++                                                   S_IRUGO,
++                                                   bond_proc_dir);
++              if (bond->proc_entry == NULL) {
++                      printk(KERN_WARNING DRV_NAME
++                             ": Warning: Cannot create /proc/net/%s/%s\n",
++                             DRV_NAME, bond_dev->name);
++              } else {
++                      bond->proc_entry->data = bond;
++                      bond->proc_entry->proc_fops = &bond_info_fops;
++                      bond->proc_entry->owner = THIS_MODULE;
++                      memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
+               }
+-              return ret;
+-      case BOND_SLAVE_INFO_QUERY_OLD:
+-      case SIOCBONDSLAVEINFOQUERY:
+-              u_sinfo = (struct ifslave *)ifr->ifr_data;
+-              if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) {
+-                      return -EFAULT;
++      }
++
++      return 0;
++}
++
++static void bond_remove_proc_entry(struct bonding *bond)
++{
++      if (bond_proc_dir && bond->proc_entry) {
++              remove_proc_entry(bond->proc_file_name, bond_proc_dir);
++              memset(bond->proc_file_name, 0, IFNAMSIZ);
++              bond->proc_entry = NULL;
++      }
++}
++
++/* Create the bonding directory under /proc/net, if doesn't exist yet.
++ * Caller must hold rtnl_lock.
++ */
++static void bond_create_proc_dir(void)
++{
++      int len = strlen(DRV_NAME);
++
++      for (bond_proc_dir = proc_net->subdir; bond_proc_dir;
++           bond_proc_dir = bond_proc_dir->next) {
++              if ((bond_proc_dir->namelen == len) &&
++                  !memcmp(bond_proc_dir->name, DRV_NAME, len)) {
++                      break;
+               }
+-              ret = bond_slave_info_query(master_dev, &k_sinfo);
+-              if (ret == 0) {
+-                      if (copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave))) {
+-                              return -EFAULT;
+-                      }
++      }
++
++      if (!bond_proc_dir) {
++              bond_proc_dir = proc_mkdir(DRV_NAME, proc_net);
++              if (bond_proc_dir) {
++                      bond_proc_dir->owner = THIS_MODULE;
++              } else {
++                      printk(KERN_WARNING DRV_NAME
++                              ": Warning: cannot create /proc/net/%s\n",
++                              DRV_NAME);
+               }
+-              return ret;
+       }
++}
+-      if (!capable(CAP_NET_ADMIN)) {
+-              return -EPERM;
++/* Destroy the bonding directory under /proc/net, if empty.
++ * Caller must hold rtnl_lock.
++ */
++static void bond_destroy_proc_dir(void)
++{
++      struct proc_dir_entry *de;
++
++      if (!bond_proc_dir) {
++              return;
+       }
+-      if (orig_app_abi_ver == -1) {
+-              /* no orig_app_abi_ver was provided yet, so we'll use the
+-               * current one from now on, even if it's 0
+-               */
+-              orig_app_abi_ver = app_abi_ver;
++      /* verify that the /proc dir is empty */
++      for (de = bond_proc_dir->subdir; de; de = de->next) {
++              /* ignore . and .. */
++              if (*(de->name) != '.') {
++                      break;
++              }
++      }
+-      } else if (orig_app_abi_ver != app_abi_ver) {
+-              printk(KERN_ERR
+-                     "bonding: Error: already using ifenslave ABI "
+-                     "version %d; to upgrade ifenslave to version %d, "
+-                     "you must first reload bonding.\n",
+-                     orig_app_abi_ver, app_abi_ver);
+-              return -EINVAL;
++      if (de) {
++              if (bond_proc_dir->owner == THIS_MODULE) {
++                      bond_proc_dir->owner = NULL;
++              }
++      } else {
++              remove_proc_entry(DRV_NAME, proc_net);
++              bond_proc_dir = NULL;
+       }
++}
++#endif /* CONFIG_PROC_FS */
+-      slave_dev = dev_get_by_name(ifr->ifr_slave);
++/*-------------------------- netdev event handling --------------------------*/
+-#ifdef BONDING_DEBUG
+-      printk(KERN_INFO "slave_dev=%x: \n", (unsigned int)slave_dev);
+-      printk(KERN_INFO "slave_dev->name=%s: \n", slave_dev->name);
++/*
++ * Change device name
++ */
++static int bond_event_changename(struct bonding *bond)
++{
++#ifdef CONFIG_PROC_FS
++      bond_remove_proc_entry(bond);
++      bond_create_proc_entry(bond);
+ #endif
+-      if (slave_dev == NULL) {
+-              ret = -ENODEV;
+-      } else {
+-              switch (cmd) {
+-              case BOND_ENSLAVE_OLD:
+-              case SIOCBONDENSLAVE:           
+-                      ret = bond_enslave(master_dev, slave_dev);
+-                      break;
+-              case BOND_RELEASE_OLD:                  
+-              case SIOCBONDRELEASE:   
+-                      ret = bond_release(master_dev, slave_dev); 
+-                      break;
+-              case BOND_SETHWADDR_OLD:
+-              case SIOCBONDSETHWADDR:
+-                      ret = bond_sethwaddr(master_dev, slave_dev);
+-                      break;
+-              case BOND_CHANGE_ACTIVE_OLD:
+-              case SIOCBONDCHANGEACTIVE:
+-                      if (USES_PRIMARY(bond_mode)) {
+-                              ret = bond_change_active(master_dev, slave_dev);
+-                      }
+-                      else {
+-                              ret = -EINVAL;
+-                      }
+-                      break;
+-              default:
+-                      ret = -EOPNOTSUPP;
+-              }
+-              dev_put(slave_dev);
++      return NOTIFY_DONE;
++}
++
++static int bond_master_netdev_event(unsigned long event, struct net_device *bond_dev)
++{
++      struct bonding *event_bond = bond_dev->priv;
++
++      switch (event) {
++      case NETDEV_CHANGENAME:
++              return bond_event_changename(event_bond);
++      case NETDEV_UNREGISTER:
++              /*
++               * TODO: remove a bond from the list?
++               */
++              break;
++      default:
++              break;
+       }
+-      if (ret < 0) {
+-              /* The ioctl failed, so there's no point in changing the
+-               * orig_app_abi_ver. We'll restore it's value just in case
+-               * we've changed it earlier in this function.
++      return NOTIFY_DONE;
++}
++
++static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev)
++{
++      struct net_device *bond_dev = slave_dev->master;
++
++      switch (event) {
++      case NETDEV_UNREGISTER:
++              if (bond_dev) {
++                      bond_release(bond_dev, slave_dev);
++              }
++              break;
++      case NETDEV_CHANGE:
++              /*
++               * TODO: is this what we get if somebody
++               * sets up a hierarchical bond, then rmmod's
++               * one of the slave bonding devices?
+                */
+-              orig_app_abi_ver = prev_abi_ver;
++              break;
++      case NETDEV_DOWN:
++              /*
++               * ... Or is it this?
++               */
++              break;
++      case NETDEV_CHANGEMTU:
++              /*
++               * TODO: Should slaves be allowed to
++               * independently alter their MTU?  For
++               * an active-backup bond, slaves need
++               * not be the same type of device, so
++               * MTUs may vary.  For other modes,
++               * slaves arguably should have the
++               * same MTUs. To do this, we'd need to
++               * take over the slave's change_mtu
++               * function for the duration of their
++               * servitude.
++               */
++              break;
++      case NETDEV_CHANGENAME:
++              /*
++               * TODO: handle changing the primary's name
++               */
++              break;
++      default:
++              break;
+       }
+-      return ret;
+-}
+-
+-#ifdef CONFIG_NET_FASTROUTE
+-static int bond_accept_fastpath(struct net_device *dev, struct dst_entry *dst)
+-{
+-      return -1;
++      return NOTIFY_DONE;
+ }
+-#endif
+-/* 
+- * in broadcast mode, we send everything to all usable interfaces.
++/*
++ * bond_netdev_event: handle netdev notifier chain events.
++ *
++ * This function receives events for the netdev chain.  The caller (an
++ * ioctl handler calling notifier_call_chain) holds the necessary
++ * locks for us to safely manipulate the slave devices (RTNL lock,
++ * dev_probe_lock).
+  */
+-static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *dev)
++static int bond_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
+ {
+-      slave_t *slave, *start_at;
+-      struct bonding *bond = (struct bonding *) dev->priv;
+-      struct net_device *device_we_should_send_to = 0;
++      struct net_device *event_dev = (struct net_device *)ptr;
+-      if (!IS_UP(dev)) { /* bond down */
+-              dev_kfree_skb(skb);
+-              return 0;
++      dprintk("event_dev: %s, event: %lx\n",
++              (event_dev ? event_dev->name : "None"),
++              event);
++
++      if (event_dev->flags & IFF_MASTER) {
++              dprintk("IFF_MASTER\n");
++              return bond_master_netdev_event(event, event_dev);
+       }
+-      read_lock(&bond->lock);
+-
+-      read_lock(&bond->ptrlock);
+-      slave = start_at = bond->current_slave;
+-      read_unlock(&bond->ptrlock);
+-
+-      if (slave == NULL) { /* we're at the root, get the first slave */
+-              /* no suitable interface, frame not sent */
+-              read_unlock(&bond->lock);
+-              dev_kfree_skb(skb);
+-              return 0;
++      if (event_dev->flags & IFF_SLAVE) {
++              dprintk("IFF_SLAVE\n");
++              return bond_slave_netdev_event(event, event_dev);
+       }
+-      do {
+-              if (IS_UP(slave->dev)
+-                  && (slave->link == BOND_LINK_UP)
+-                  && (slave->state == BOND_STATE_ACTIVE)) {
+-                      if (device_we_should_send_to) {
+-                              struct sk_buff *skb2;
+-                              if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL) {
+-                                      printk(KERN_ERR "bond_xmit_broadcast: skb_clone() failed\n");
+-                                      continue;
+-                              }
+-
+-                              skb2->dev = device_we_should_send_to;
+-                              skb2->priority = 1;
+-                              dev_queue_xmit(skb2);
+-                      }
+-                      device_we_should_send_to = slave->dev;
+-              }
+-      } while ((slave = slave->next) != start_at);
++      return NOTIFY_DONE;
++}
+-      if (device_we_should_send_to) {
+-              skb->dev = device_we_should_send_to;
+-              skb->priority = 1;
+-              dev_queue_xmit(skb);
+-      } else
+-              dev_kfree_skb(skb);
++static struct notifier_block bond_netdev_notifier = {
++      .notifier_call = bond_netdev_event,
++};
+-      /* frame sent to all suitable interfaces */
+-      read_unlock(&bond->lock);
+-      return 0;
+-}
++/*-------------------------- Packet type handling ---------------------------*/
+-static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *dev)
++/* register to receive lacpdus on a bond */
++static void bond_register_lacpdu(struct bonding *bond)
+ {
+-      slave_t *slave, *start_at;
+-      struct bonding *bond = (struct bonding *) dev->priv;
++      struct packet_type *pk_type = &(BOND_AD_INFO(bond).ad_pkt_type);
+-      if (!IS_UP(dev)) { /* bond down */
+-              dev_kfree_skb(skb);
+-              return 0;
+-      }
++      /* initialize packet type */
++      pk_type->type = PKT_TYPE_LACPDU;
++      pk_type->dev = bond->dev;
++      pk_type->func = bond_3ad_lacpdu_recv;
+-      read_lock(&bond->lock);
++      dev_add_pack(pk_type);
++}
+-      read_lock(&bond->ptrlock);
+-      slave = start_at = bond->current_slave;
+-      read_unlock(&bond->ptrlock);
+-
+-      if (slave == NULL) { /* we're at the root, get the first slave */
+-              /* no suitable interface, frame not sent */
+-              dev_kfree_skb(skb);
+-              read_unlock(&bond->lock);
+-              return 0;
+-      }
++/* unregister to receive lacpdus on a bond */
++static void bond_unregister_lacpdu(struct bonding *bond)
++{
++      dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
++}
+-      do {
+-              if (IS_UP(slave->dev)
+-                  && (slave->link == BOND_LINK_UP)
+-                  && (slave->state == BOND_STATE_ACTIVE)) {
++/*-------------------------- Device entry points ----------------------------*/
+-                      skb->dev = slave->dev;
+-                      skb->priority = 1;
+-                      dev_queue_xmit(skb);
++static int bond_open(struct net_device *bond_dev)
++{
++      struct bonding *bond = bond_dev->priv;
++      struct timer_list *mii_timer = &bond->mii_timer;
++      struct timer_list *arp_timer = &bond->arp_timer;
+-                      write_lock(&bond->ptrlock);
+-                      bond->current_slave = slave->next;
+-                      write_unlock(&bond->ptrlock);
++      bond->kill_timers = 0;
++
++      if ((bond_mode == BOND_MODE_TLB) ||
++          (bond_mode == BOND_MODE_ALB)) {
++              struct timer_list *alb_timer = &(BOND_ALB_INFO(bond).alb_timer);
+-                      read_unlock(&bond->lock);
+-                      return 0;
++              /* bond_alb_initialize must be called before the timer
++               * is started.
++               */
++              if (bond_alb_initialize(bond, (bond_mode == BOND_MODE_ALB))) {
++                      /* something went wrong - fail the open operation */
++                      return -1;
+               }
+-      } while ((slave = slave->next) != start_at);
+-      /* no suitable interface, frame not sent */
+-      dev_kfree_skb(skb);
+-      read_unlock(&bond->lock);
+-      return 0;
+-}
++              init_timer(alb_timer);
++              alb_timer->expires  = jiffies + 1;
++              alb_timer->data     = (unsigned long)bond;
++              alb_timer->function = (void *)&bond_alb_monitor;
++              add_timer(alb_timer);
++      }
+-/* 
+- * in XOR mode, we determine the output device by performing xor on
+- * the source and destination hw adresses.  If this device is not 
+- * enabled, find the next slave following this xor slave. 
+- */
+-static int bond_xmit_xor(struct sk_buff *skb, struct net_device *dev)
+-{
+-      slave_t *slave, *start_at;
+-      struct bonding *bond = (struct bonding *) dev->priv;
+-      struct ethhdr *data = (struct ethhdr *)skb->data;
+-      int slave_no;
++      if (miimon) {  /* link check interval, in milliseconds. */
++              init_timer(mii_timer);
++              mii_timer->expires  = jiffies + 1;
++              mii_timer->data     = (unsigned long)bond_dev;
++              mii_timer->function = (void *)&bond_mii_monitor;
++              add_timer(mii_timer);
++      }
+-      if (!IS_UP(dev)) { /* bond down */
+-              dev_kfree_skb(skb);
+-              return 0;
++      if (arp_interval) {  /* arp interval, in milliseconds. */
++              init_timer(arp_timer);
++              arp_timer->expires  = jiffies + 1;
++              arp_timer->data     = (unsigned long)bond_dev;
++              if (bond_mode == BOND_MODE_ACTIVEBACKUP) {
++                      arp_timer->function = (void *)&bond_activebackup_arp_mon;
++              } else {
++                      arp_timer->function = (void *)&bond_loadbalance_arp_mon;
++              }
++              add_timer(arp_timer);
+       }
+-      read_lock(&bond->lock);
+-      slave = bond->prev;
++      if (bond_mode == BOND_MODE_8023AD) {
++              struct timer_list *ad_timer = &(BOND_AD_INFO(bond).ad_timer);
++              init_timer(ad_timer);
++              ad_timer->expires  = jiffies + 1;
++              ad_timer->data     = (unsigned long)bond;
++              ad_timer->function = (void *)&bond_3ad_state_machine_handler;
++              add_timer(ad_timer);
+-      /* we're at the root, get the first slave */
+-      if (bond->slave_cnt == 0) {
+-              /* no suitable interface, frame not sent */
+-              dev_kfree_skb(skb);
+-              read_unlock(&bond->lock);
+-              return 0;
++              /* register to receive LACPDUs */
++              bond_register_lacpdu(bond);
+       }
+-      slave_no = (data->h_dest[5]^slave->dev->dev_addr[5]) % bond->slave_cnt;
++      return 0;
++}
+-      while ( (slave_no > 0) && (slave != (slave_t *)bond) ) {
+-              slave = slave->prev;
+-              slave_no--;
+-      } 
+-      start_at = slave;
++static int bond_close(struct net_device *bond_dev)
++{
++      struct bonding *bond = bond_dev->priv;
+-      do {
+-              if (IS_UP(slave->dev)
+-                  && (slave->link == BOND_LINK_UP)
+-                  && (slave->state == BOND_STATE_ACTIVE)) {
++      write_lock_bh(&bond->lock);
+-                      skb->dev = slave->dev;
+-                      skb->priority = 1;
+-                      dev_queue_xmit(skb);
++      bond_mc_list_destroy(bond);
+-                      read_unlock(&bond->lock);
+-                      return 0;
+-              }
+-      } while ((slave = slave->next) != start_at);
++      if (bond_mode == BOND_MODE_8023AD) {
++              /* Unregister the receive of LACPDUs */
++              bond_unregister_lacpdu(bond);
++      }
+-      /* no suitable interface, frame not sent */
+-      dev_kfree_skb(skb);
+-      read_unlock(&bond->lock);
+-      return 0;
+-}
++      /* signal timers not to re-arm */
++      bond->kill_timers = 1;
+-/* 
+- * in active-backup mode, we know that bond->current_slave is always valid if
+- * the bond has a usable interface.
+- */
+-static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *dev)
+-{
+-      struct bonding *bond = (struct bonding *) dev->priv;
+-      int ret;
++      write_unlock_bh(&bond->lock);
+-      if (!IS_UP(dev)) { /* bond down */
+-              dev_kfree_skb(skb);
+-              return 0;
++      /* del_timer_sync must run without holding the bond->lock
++       * because a running timer might be trying to hold it too
++       */
++
++      if (miimon) {  /* link check interval, in milliseconds. */
++              del_timer_sync(&bond->mii_timer);
+       }
+-      /* if we are sending arp packets, try to at least 
+-         identify our own ip address */
+-      if ( (arp_interval > 0) && (my_ip == 0) &&
+-              (skb->protocol == __constant_htons(ETH_P_ARP) ) ) {
+-              char *the_ip = (((char *)skb->data)) 
+-                              + sizeof(struct ethhdr)  
+-                              + sizeof(struct arphdr) + 
+-                              ETH_ALEN;
+-              memcpy(&my_ip, the_ip, 4);
++      if (arp_interval) {  /* arp interval, in milliseconds. */
++              del_timer_sync(&bond->arp_timer);
+       }
+-      /* if we are sending arp packets and don't know 
+-       * the target hw address, save it so we don't need 
+-       * to use a broadcast address.
+-       * don't do this if in active backup mode because the slaves must 
+-       * receive packets to stay up, and the only ones they receive are 
+-       * broadcasts. 
+-       */
+-      if ( (bond_mode != BOND_MODE_ACTIVEBACKUP) && 
+-             (arp_ip_count == 1) &&
+-           (arp_interval > 0) && (arp_target_hw_addr == NULL) &&
+-           (skb->protocol == __constant_htons(ETH_P_IP) ) ) {
+-              struct ethhdr *eth_hdr = 
+-                      (struct ethhdr *) (((char *)skb->data));
+-              struct iphdr *ip_hdr = (struct iphdr *)(eth_hdr + 1);
+-
+-              if (arp_target[0] == ip_hdr->daddr) {
+-                      arp_target_hw_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
+-                      if (arp_target_hw_addr != NULL)
+-                              memcpy(arp_target_hw_addr, eth_hdr->h_dest, ETH_ALEN);
+-              }
++      switch (bond_mode) {
++      case BOND_MODE_8023AD:
++              del_timer_sync(&(BOND_AD_INFO(bond).ad_timer));
++              break;
++      case BOND_MODE_TLB:
++      case BOND_MODE_ALB:
++              del_timer_sync(&(BOND_ALB_INFO(bond).alb_timer));
++              break;
++      default:
++              break;
+       }
+-      read_lock(&bond->lock);
++      /* Release the bonded slaves */
++      bond_release_all(bond_dev);
+-      read_lock(&bond->ptrlock);
+-      if (bond->current_slave != NULL) { /* one usable interface */
+-              skb->dev = bond->current_slave->dev;
+-              read_unlock(&bond->ptrlock);
+-              skb->priority = 1;
+-              ret = dev_queue_xmit(skb);
+-              read_unlock(&bond->lock);
+-              return 0;
+-      }
+-      else {
+-              read_unlock(&bond->ptrlock);
++      if ((bond_mode == BOND_MODE_TLB) ||
++          (bond_mode == BOND_MODE_ALB)) {
++              /* Must be called only after all
++               * slaves have been released
++               */
++              bond_alb_deinitialize(bond);
+       }
+-      /* no suitable interface, frame not sent */
+-#ifdef BONDING_DEBUG
+-      printk(KERN_INFO "There was no suitable interface, so we don't transmit\n");
+-#endif
+-      dev_kfree_skb(skb);
+-      read_unlock(&bond->lock);
+       return 0;
+ }
+-static struct net_device_stats *bond_get_stats(struct net_device *dev)
++static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
+ {
+-      bonding_t *bond = dev->priv;
++      struct bonding *bond = bond_dev->priv;
+       struct net_device_stats *stats = &(bond->stats), *sstats;
+-      slave_t *slave;
++      struct slave *slave;
++      int i;
+       memset(stats, 0, sizeof(struct net_device_stats));
+       read_lock_bh(&bond->lock);
+-      for (slave = bond->prev; slave != (slave_t *)bond; slave = slave->prev) {
++      bond_for_each_slave(bond, slave, i) {
+               sstats = slave->dev->get_stats(slave->dev);
+- 
++
+               stats->rx_packets += sstats->rx_packets;
+               stats->rx_bytes += sstats->rx_bytes;
+               stats->rx_errors += sstats->rx_errors;
+@@ -3346,290 +3130,294 @@ static struct net_device_stats *bond_get
+               stats->rx_over_errors += sstats->rx_over_errors;
+               stats->rx_crc_errors += sstats->rx_crc_errors;
+               stats->rx_frame_errors += sstats->rx_frame_errors;
+-              stats->rx_fifo_errors += sstats->rx_fifo_errors;        
++              stats->rx_fifo_errors += sstats->rx_fifo_errors;
+               stats->rx_missed_errors += sstats->rx_missed_errors;
+-      
++
+               stats->tx_aborted_errors += sstats->tx_aborted_errors;
+               stats->tx_carrier_errors += sstats->tx_carrier_errors;
+               stats->tx_fifo_errors += sstats->tx_fifo_errors;
+               stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors;
+               stats->tx_window_errors += sstats->tx_window_errors;
+-
+       }
+       read_unlock_bh(&bond->lock);
++
+       return stats;
+ }
+-#ifdef CONFIG_PROC_FS
+-
+-#define SEQ_START_TOKEN ((void *)1)
+-
+-static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
++static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd)
+ {
+-      struct bonding *bond = seq->private;
+-      loff_t off = 0;
+-      struct slave *slave;
+-
+-      /* make sure the bond won't be taken away */
+-      read_lock(&dev_base_lock);
+-      read_lock_bh(&bond->lock);
+-
+-      if (*pos == 0) {
+-              return SEQ_START_TOKEN;
+-      }
++      struct net_device *slave_dev = NULL;
++      struct ifbond *u_binfo = NULL, k_binfo;
++      struct ifslave *u_sinfo = NULL, k_sinfo;
++      struct mii_ioctl_data *mii = NULL;
++      int prev_abi_ver = orig_app_abi_ver;
++      int res = 0;
+-      for (slave = bond->prev; slave != (slave_t *)bond;
+-           slave = slave->prev) {
++      dprintk("bond_ioctl: master=%s, cmd=%d\n",
++              bond_dev->name, cmd);
+-              if (++off == *pos) {
+-                      return slave;
++      switch (cmd) {
++      case SIOCETHTOOL:
++              return bond_ethtool_ioctl(bond_dev, ifr);
++      case SIOCGMIIPHY:
++              mii = (struct mii_ioctl_data *)&ifr->ifr_data;
++              if (!mii) {
++                      return -EINVAL;
++              }
++              mii->phy_id = 0;
++              /* Fall Through */
++      case SIOCGMIIREG:
++              /*
++               * We do this again just in case we were called by SIOCGMIIREG
++               * instead of SIOCGMIIPHY.
++               */
++              mii = (struct mii_ioctl_data *)&ifr->ifr_data;
++              if (!mii) {
++                      return -EINVAL;
+               }
+-      }
+-
+-      return NULL;
+-}
+-
+-static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+-{
+-      struct bonding *bond = seq->private;
+-      struct slave *slave = v;
+-
+-      ++*pos;
+-      if (v == SEQ_START_TOKEN) {
+-              slave = bond->prev;
+-      } else {
+-              slave = slave->prev;
+-      }
+-
+-      return (slave == (struct slave *) bond) ? NULL : slave;
+-}
+-
+-static void bond_info_seq_stop(struct seq_file *seq, void *v)
+-{
+-      struct bonding *bond = seq->private;
+-
+-      read_unlock_bh(&bond->lock);
+-      read_unlock(&dev_base_lock);
+-}
+-
+-static void bond_info_show_master(struct seq_file *seq, struct bonding *bond)
+-{
+-      struct slave *curr;
+-      read_lock(&bond->ptrlock);
+-      curr = bond->current_slave;
+-      read_unlock(&bond->ptrlock);
++              if (mii->reg_num == 1) {
++                      struct bonding *bond = bond_dev->priv;
++                      mii->val_out = 0;
++                      read_lock_bh(&bond->lock);
++                      read_lock(&bond->curr_slave_lock);
++                      if (bond->curr_active_slave) {
++                              mii->val_out = BMSR_LSTATUS;
++                      }
++                      read_unlock(&bond->curr_slave_lock);
++                      read_unlock_bh(&bond->lock);
++              }
+-      seq_printf(seq, "Bonding Mode: %s\n", bond_mode_name());
++              return 0;
++      case BOND_INFO_QUERY_OLD:
++      case SIOCBONDINFOQUERY:
++              u_binfo = (struct ifbond *)ifr->ifr_data;
+-      if (USES_PRIMARY(bond_mode)) {
+-              if (curr) {
+-                      seq_printf(seq,
+-                                 "Currently Active Slave: %s\n",
+-                                 curr->dev->name);
++              if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) {
++                      return -EFAULT;
+               }
+-      }
+-      seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down");
+-      seq_printf(seq, "MII Polling Interval (ms): %d\n", miimon);
+-      seq_printf(seq, "Up Delay (ms): %d\n", updelay * miimon);
+-      seq_printf(seq, "Down Delay (ms): %d\n", downdelay * miimon);
+-      seq_printf(seq, "Multicast Mode: %s\n", multicast_mode_name());
+-
+-      if (bond_mode == BOND_MODE_8023AD) {
+-              struct ad_info ad_info;
++              res = bond_info_query(bond_dev, &k_binfo);
++              if (res == 0) {
++                      if (copy_to_user(u_binfo, &k_binfo, sizeof(ifbond))) {
++                              return -EFAULT;
++                      }
++              }
+-              seq_puts(seq, "\n802.3ad info\n");
++              return res;
++      case BOND_SLAVE_INFO_QUERY_OLD:
++      case SIOCBONDSLAVEINFOQUERY:
++              u_sinfo = (struct ifslave *)ifr->ifr_data;
+-              if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
+-                      seq_printf(seq, "bond %s has no active aggregator\n",
+-                                 bond->device->name);
+-              } else {
+-                      seq_printf(seq, "Active Aggregator Info:\n");
++              if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) {
++                      return -EFAULT;
++              }
+-                      seq_printf(seq, "\tAggregator ID: %d\n",
+-                                 ad_info.aggregator_id);
+-                      seq_printf(seq, "\tNumber of ports: %d\n",
+-                                 ad_info.ports);
+-                      seq_printf(seq, "\tActor Key: %d\n",
+-                                 ad_info.actor_key);
+-                      seq_printf(seq, "\tPartner Key: %d\n",
+-                                 ad_info.partner_key);
+-                      seq_printf(seq, "\tPartner Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+-                                 ad_info.partner_system[0],
+-                                 ad_info.partner_system[1],
+-                                 ad_info.partner_system[2],
+-                                 ad_info.partner_system[3],
+-                                 ad_info.partner_system[4],
+-                                 ad_info.partner_system[5]);
++              res = bond_slave_info_query(bond_dev, &k_sinfo);
++              if (res == 0) {
++                      if (copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave))) {
++                              return -EFAULT;
++                      }
+               }
++
++              return res;
++      default:
++              /* Go on */
++              break;
+       }
+-}
+-static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave)
+-{
+-      seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
+-      seq_printf(seq, "MII Status: %s\n",
+-                 (slave->link == BOND_LINK_UP) ?  "up" : "down");
+-      seq_printf(seq, "Link Failure Count: %d\n",
+-                 slave->link_failure_count);
++      if (!capable(CAP_NET_ADMIN)) {
++              return -EPERM;
++      }
+-      if (app_abi_ver >= 1) {
+-              seq_printf(seq,
+-                         "Permanent HW addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
+-                         slave->perm_hwaddr[0],
+-                         slave->perm_hwaddr[1],
+-                         slave->perm_hwaddr[2],
+-                         slave->perm_hwaddr[3],
+-                         slave->perm_hwaddr[4],
+-                         slave->perm_hwaddr[5]);
++      if (orig_app_abi_ver == -1) {
++              /* no orig_app_abi_ver was provided yet, so we'll use the
++               * current one from now on, even if it's 0
++               */
++              orig_app_abi_ver = app_abi_ver;
++
++      } else if (orig_app_abi_ver != app_abi_ver) {
++              printk(KERN_ERR DRV_NAME
++                     ": Error: already using ifenslave ABI version %d; to "
++                     "upgrade ifenslave to version %d, you must first "
++                     "reload bonding.\n",
++                     orig_app_abi_ver, app_abi_ver);
++              return -EINVAL;
+       }
+-      if (bond_mode == BOND_MODE_8023AD) {
+-              const struct aggregator *agg
+-                      = SLAVE_AD_INFO(slave).port.aggregator;
++      slave_dev = dev_get_by_name(ifr->ifr_slave);
+-              if (agg) {
+-                      seq_printf(seq, "Aggregator ID: %d\n",
+-                                 agg->aggregator_identifier);
+-              } else {
+-                      seq_puts(seq, "Aggregator ID: N/A\n");
++      dprintk("slave_dev=%p: \n", slave_dev);
++
++      if (!slave_dev) {
++              res = -ENODEV;
++      } else {
++              dprintk("slave_dev->name=%s: \n", slave_dev->name);
++              switch (cmd) {
++              case BOND_ENSLAVE_OLD:
++              case SIOCBONDENSLAVE:
++                      res = bond_enslave(bond_dev, slave_dev);
++                      break;
++              case BOND_RELEASE_OLD:
++              case SIOCBONDRELEASE:
++                      res = bond_release(bond_dev, slave_dev);
++                      break;
++              case BOND_SETHWADDR_OLD:
++              case SIOCBONDSETHWADDR:
++                      res = bond_sethwaddr(bond_dev, slave_dev);
++                      break;
++              case BOND_CHANGE_ACTIVE_OLD:
++              case SIOCBONDCHANGEACTIVE:
++                      if (USES_PRIMARY(bond_mode)) {
++                              res = bond_ioctl_change_active(bond_dev, slave_dev);
++                      } else {
++                              res = -EINVAL;
++                      }
++                      break;
++              default:
++                      res = -EOPNOTSUPP;
+               }
++
++              dev_put(slave_dev);
+       }
+-}
+-static int bond_info_seq_show(struct seq_file *seq, void *v)
+-{
+-      if (v == SEQ_START_TOKEN) {
+-              seq_printf(seq, "%s\n", version);
+-              bond_info_show_master(seq, seq->private);
+-      } else {
+-              bond_info_show_slave(seq, v);
++      if (res < 0) {
++              /* The ioctl failed, so there's no point in changing the
++               * orig_app_abi_ver. We'll restore it's value just in case
++               * we've changed it earlier in this function.
++               */
++              orig_app_abi_ver = prev_abi_ver;
+       }
+-      return 0;
++      return res;
+ }
+-static struct seq_operations bond_info_seq_ops = {
+-      .start = bond_info_seq_start,
+-      .next  = bond_info_seq_next,
+-      .stop  = bond_info_seq_stop,
+-      .show  = bond_info_seq_show,
+-};
+-
+-static int bond_info_open(struct inode *inode, struct file *file)
++static void bond_set_multicast_list(struct net_device *bond_dev)
+ {
+-      struct seq_file *seq;
+-      struct proc_dir_entry *proc;
+-      int rc;
+-
+-      rc = seq_open(file, &bond_info_seq_ops);
+-      if (!rc) {
+-              /* recover the pointer buried in proc_dir_entry data */
+-              seq = file->private_data;
+-              proc = PDE(inode);
+-              seq->private = proc->data;
+-      }
+-      return rc;
+-}
++      struct bonding *bond = bond_dev->priv;
++      struct dev_mc_list *dmi;
+-static struct file_operations bond_info_fops = {
+-      .owner   = THIS_MODULE,
+-      .open    = bond_info_open,
+-      .read    = seq_read,
+-      .llseek  = seq_lseek,
+-      .release = seq_release,
+-};
++      write_lock_bh(&bond->lock);
+-static int bond_create_proc_info(struct bonding *bond)
+-{
+-      struct net_device *dev = bond->device;
++      /*
++       * Do promisc before checking multicast_mode
++       */
++      if ((bond_dev->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC)) {
++              bond_set_promiscuity(bond, 1);
++      }
+-      if (bond_proc_dir) {
+-              bond->bond_proc_file = create_proc_entry(dev->name,
+-                                                       S_IRUGO, 
+-                                                       bond_proc_dir);
+-              if (bond->bond_proc_file == NULL) {
+-                      printk(KERN_WARNING
+-                             "%s: Cannot create /proc/net/bonding/%s\n", 
+-                             dev->name, dev->name);
+-              } else {
+-                      bond->bond_proc_file->data = bond;
+-                      bond->bond_proc_file->proc_fops = &bond_info_fops;
+-                      bond->bond_proc_file->owner = THIS_MODULE;
+-                      memcpy(bond->procdir_name, dev->name, IFNAMSIZ);
+-              }
++      if (!(bond_dev->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC)) {
++              bond_set_promiscuity(bond, -1);
+       }
+-      return 0;
+-}
++      /* set allmulti flag to slaves */
++      if ((bond_dev->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI)) {
++              bond_set_allmulti(bond, 1);
++      }
+-static void bond_destroy_proc_info(struct bonding *bond)
+-{
+-      if (bond_proc_dir && bond->bond_proc_file) {
+-              remove_proc_entry(bond->procdir_name, bond_proc_dir);
+-              memset(bond->procdir_name, 0, IFNAMSIZ);
+-              bond->bond_proc_file = NULL;
++      if (!(bond_dev->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI)) {
++              bond_set_allmulti(bond, -1);
+       }
+-}
+-/* Create the bonding directory under /proc/net, if doesn't exist yet.
+- * Caller must hold rtnl_lock.
+- */
+-static void bond_create_proc_dir(void)
+-{
+-      int len = strlen(DRV_NAME);
++      bond->flags = bond_dev->flags;
+-      for (bond_proc_dir = proc_net->subdir; bond_proc_dir;
+-           bond_proc_dir = bond_proc_dir->next) {
+-              if ((bond_proc_dir->namelen == len) &&
+-                  !memcmp(bond_proc_dir->name, DRV_NAME, len)) {
+-                      break;
++      /* looking for addresses to add to slaves' mc list */
++      for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
++              if (!bond_mc_list_find_dmi(dmi, bond->mc_list)) {
++                      bond_mc_add(bond, dmi->dmi_addr, dmi->dmi_addrlen);
+               }
+       }
+-      if (!bond_proc_dir) {
+-              bond_proc_dir = proc_mkdir(DRV_NAME, proc_net);
+-              if (bond_proc_dir) {
+-                      bond_proc_dir->owner = THIS_MODULE;
+-              } else {
+-                      printk(KERN_WARNING DRV_NAME
+-                              ": Warning: cannot create /proc/net/%s\n",
+-                              DRV_NAME);
++      /* looking for addresses to delete from slaves' list */
++      for (dmi = bond->mc_list; dmi; dmi = dmi->next) {
++              if (!bond_mc_list_find_dmi(dmi, bond_dev->mc_list)) {
++                      bond_mc_delete(bond, dmi->dmi_addr, dmi->dmi_addrlen);
+               }
+       }
++
++      /* save master's multicast list */
++      bond_mc_list_destroy(bond);
++      bond_mc_list_copy(bond_dev->mc_list, bond, GFP_ATOMIC);
++
++      write_unlock_bh(&bond->lock);
+ }
+-/* Destroy the bonding directory under /proc/net, if empty.
+- * Caller must hold rtnl_lock.
++/*
++ * Change the MTU of all of a master's slaves to match the master
+  */
+-static void bond_destroy_proc_dir(void)
++static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
+ {
+-      struct proc_dir_entry *de;
++      struct bonding *bond = bond_dev->priv;
++      struct slave *slave, *stop_at;
++      int res = 0;
++      int i;
+-      if (!bond_proc_dir) {
+-              return;
+-      }
++      dprintk("bond=%p, name=%s, new_mtu=%d\n", bond,
++              (bond_dev ? bond_dev->name : "None"), new_mtu);
+-      /* verify that the /proc dir is empty */
+-      for (de = bond_proc_dir->subdir; de; de = de->next) {
+-              /* ignore . and .. */
+-              if (*(de->name) != '.') {
+-                      break;
++      /* Can't hold bond->lock with bh disabled here since
++       * some base drivers panic. On the other hand we can't
++       * hold bond->lock without bh disabled because we'll
++       * deadlock. The only solution is to rely on the fact
++       * that we're under rtnl_lock here, and the slaves
++       * list won't change. This doesn't solve the problem
++       * of setting the slave's MTU while it is
++       * transmitting, but the assumption is that the base
++       * driver can handle that.
++       *
++       * TODO: figure out a way to safely iterate the slaves
++       * list, but without holding a lock around the actual
++       * call to the base driver.
++       */
++
++      bond_for_each_slave(bond, slave, i) {
++              dprintk("s %p s->p %p c_m %p\n", slave,
++                      slave->prev, slave->dev->change_mtu);
++              if (slave->dev->change_mtu) {
++                      res = slave->dev->change_mtu(slave->dev, new_mtu);
++              } else {
++                      slave->dev->mtu = new_mtu;
++                      res = 0;
++              }
++
++              if (res) {
++                      /* If we failed to set the slave's mtu to the new value
++                       * we must abort the operation even in ACTIVE_BACKUP
++                       * mode, because if we allow the backup slaves to have
++                       * different mtu values than the active slave we'll
++                       * need to change their mtu when doing a failover. That
++                       * means changing their mtu from timer context, which
++                       * is probably not a good idea.
++                       */
++                      dprintk("err %d %s\n", res, slave->dev->name);
++                      goto unwind;
+               }
+       }
+-      if (de) {
+-              if (bond_proc_dir->owner == THIS_MODULE) {
+-                      bond_proc_dir->owner = NULL;
++      bond_dev->mtu = new_mtu;
++
++      return 0;
++
++unwind:
++      /* unwind from head to the slave that failed */
++      stop_at = slave;
++      bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
++              int tmp_res;
++
++              if (slave->dev->change_mtu) {
++                      tmp_res = slave->dev->change_mtu(slave->dev, bond_dev->mtu);
++                      if (tmp_res) {
++                              dprintk("unwind err %d dev %s\n", tmp_res,
++                                      slave->dev->name);
++                      }
++              } else {
++                      slave->dev->mtu = bond_dev->mtu;
+               }
+-      } else {
+-              remove_proc_entry(DRV_NAME, proc_net);
+-              bond_proc_dir = NULL;
+       }
++
++      return res;
+ }
+-#endif /* CONFIG_PROC_FS */
+ /*
+  * Change HW address
+@@ -3638,353 +3426,366 @@ static void bond_destroy_proc_dir(void)
+  * downing the master releases all slaves.  We can make bonds full of
+  * bonding devices to test this, however.
+  */
+-static inline int
+-bond_set_mac_address(struct net_device *dev, void *addr)
++static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
+ {
+-      struct bonding *bond = dev->priv;
++      struct bonding *bond = bond_dev->priv;
+       struct sockaddr *sa = addr, tmp_sa;
+-      struct slave *slave;
+-      int error;
++      struct slave *slave, *stop_at;
++      int res = 0;
++      int i;
+-      dprintk(KERN_INFO "bond_set_mac_address %p %s\n", dev,
+-             dev->name);
++      dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None"));
+       if (!is_valid_ether_addr(sa->sa_data)) {
+               return -EADDRNOTAVAIL;
+       }
+-      for (slave = bond->prev; slave != (struct slave *)bond;
+-           slave = slave->prev) {
+-              dprintk(KERN_INFO "bond_set_mac: slave %p %s\n", slave,
+-                      slave->dev->name);
++      /* Can't hold bond->lock with bh disabled here since
++       * some base drivers panic. On the other hand we can't
++       * hold bond->lock without bh disabled because we'll
++       * deadlock. The only solution is to rely on the fact
++       * that we're under rtnl_lock here, and the slaves
++       * list won't change. This doesn't solve the problem
++       * of setting the slave's hw address while it is
++       * transmitting, but the assumption is that the base
++       * driver can handle that.
++       *
++       * TODO: figure out a way to safely iterate the slaves
++       * list, but without holding a lock around the actual
++       * call to the base driver.
++       */
++
++      bond_for_each_slave(bond, slave, i) {
++              dprintk("slave %p %s\n", slave, slave->dev->name);
++
+               if (slave->dev->set_mac_address == NULL) {
+-                      error = -EOPNOTSUPP;
+-                      dprintk(KERN_INFO "bond_set_mac EOPNOTSUPP %s\n",
+-                              slave->dev->name);
++                      res = -EOPNOTSUPP;
++                      dprintk("EOPNOTSUPP %s\n", slave->dev->name);
+                       goto unwind;
+               }
+-              error = slave->dev->set_mac_address(slave->dev, addr);
+-              if (error) {
+-                      /* TODO: consider downing the slave 
++              res = slave->dev->set_mac_address(slave->dev, addr);
++              if (res) {
++                      /* TODO: consider downing the slave
+                        * and retry ?
+                        * User should expect communications
+                        * breakage anyway until ARP finish
+                        * updating, so...
+                        */
+-                      dprintk(KERN_INFO "bond_set_mac err %d %s\n",
+-                              error, slave->dev->name);
++                      dprintk("err %d %s\n", res, slave->dev->name);
+                       goto unwind;
+               }
+       }
+       /* success */
+-      memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
++      memcpy(bond_dev->dev_addr, sa->sa_data, bond_dev->addr_len);
+       return 0;
+ unwind:
+-      memcpy(tmp_sa.sa_data, dev->dev_addr, dev->addr_len);
+-      tmp_sa.sa_family = dev->type;
++      memcpy(tmp_sa.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
++      tmp_sa.sa_family = bond_dev->type;
+-      for (slave = slave->next; slave != bond->next;
+-           slave = slave->next) {
+-              int tmp_error;
+-
+-              tmp_error = slave->dev->set_mac_address(slave->dev, &tmp_sa);
+-              if (tmp_error) {
+-                      dprintk(KERN_INFO "bond_set_mac_address: "
+-                              "unwind err %d dev %s\n",
+-                              tmp_error, slave->dev->name);
++      /* unwind from head to the slave that failed */
++      stop_at = slave;
++      bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
++              int tmp_res;
++
++              tmp_res = slave->dev->set_mac_address(slave->dev, &tmp_sa);
++              if (tmp_res) {
++                      dprintk("unwind err %d dev %s\n", tmp_res,
++                              slave->dev->name);
+               }
+       }
+-      return error;
++      return res;
+ }
+-/*
+- * Change the MTU of all of a master's slaves to match the master
+- */
+-static inline int
+-bond_change_mtu(struct net_device *dev, int newmtu)
++static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
+ {
+-      bonding_t *bond = dev->priv;
+-      slave_t *slave;
+-      int error;
+-
+-      dprintk(KERN_INFO "CM: b %p nm %d\n", bond, newmtu);
+-      for (slave = bond->prev; slave != (slave_t *)bond;
+-           slave = slave->prev) {
+-              dprintk(KERN_INFO "CM: s %p s->p %p c_m %p\n", slave,
+-                      slave->prev, slave->dev->change_mtu);
+-              if (slave->dev->change_mtu) {
+-                      error = slave->dev->change_mtu(slave->dev, newmtu);
+-              } else {
+-                      slave->dev->mtu = newmtu;
+-                      error = 0;
+-              }
++      struct bonding *bond = bond_dev->priv;
++      struct slave *slave, *start_at;
++      int i;
+-              if (error) {
+-                      /* If we failed to set the slave's mtu to the new value
+-                       * we must abort the operation even in ACTIVE_BACKUP
+-                       * mode, because if we allow the backup slaves to have
+-                       * different mtu values than the active slave we'll
+-                       * need to change their mtu when doing a failover. That
+-                       * means changing their mtu from timer context, which
+-                       * is probably not a good idea.
+-                       */
+-                      dprintk(KERN_INFO "bond_change_mtu err %d %s\n",
+-                             error, slave->dev->name);
+-                      goto unwind;
++      read_lock(&bond->lock);
++
++      if (!BOND_IS_OK(bond)) {
++              goto free_out;
++      }
++
++      read_lock(&bond->curr_slave_lock);
++      slave = start_at = bond->curr_active_slave;
++      read_unlock(&bond->curr_slave_lock);
++
++      if (!slave) {
++              goto free_out;
++      }
++
++      bond_for_each_slave_from(bond, slave, i, start_at) {
++              if (IS_UP(slave->dev) &&
++                  (slave->link == BOND_LINK_UP) &&
++                  (slave->state == BOND_STATE_ACTIVE)) {
++                      skb->dev = slave->dev;
++                      skb->priority = 1;
++                      dev_queue_xmit(skb);
++
++                      write_lock(&bond->curr_slave_lock);
++                      bond->curr_active_slave = slave->next;
++                      write_unlock(&bond->curr_slave_lock);
++
++                      goto out;
+               }
+       }
+-      dev->mtu = newmtu;
++out:
++      read_unlock(&bond->lock);
+       return 0;
++free_out:
++      /* no suitable interface, frame not sent */
++      dev_kfree_skb(skb);
++      goto out;
++}
+-unwind:
+-      for (slave = slave->next; slave != bond->next;
+-           slave = slave->next) {
++/*
++ * in active-backup mode, we know that bond->curr_active_slave is always valid if
++ * the bond has a usable interface.
++ */
++static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_dev)
++{
++      struct bonding *bond = bond_dev->priv;
+-              if (slave->dev->change_mtu) {
+-                      slave->dev->change_mtu(slave->dev, dev->mtu);
+-              } else {
+-                      slave->dev->mtu = dev->mtu;
+-              }
++      /* if we are sending arp packets, try to at least
++         identify our own ip address */
++      if (arp_interval && !my_ip &&
++              (skb->protocol == __constant_htons(ETH_P_ARP))) {
++              char *the_ip = (char *)skb->data +
++                              sizeof(struct ethhdr) +
++                              sizeof(struct arphdr) +
++                              ETH_ALEN;
++              memcpy(&my_ip, the_ip, 4);
+       }
+-      return error;
++      read_lock(&bond->lock);
++      read_lock(&bond->curr_slave_lock);
++
++      if (!BOND_IS_OK(bond)) {
++              goto free_out;
++      }
++
++      if (bond->curr_active_slave) { /* one usable interface */
++              skb->dev = bond->curr_active_slave->dev;
++              skb->priority = 1;
++              dev_queue_xmit(skb);
++              goto out;
++      } else {
++              goto free_out;
++      }
++out:
++      read_unlock(&bond->curr_slave_lock);
++      read_unlock(&bond->lock);
++      return 0;
++
++free_out:
++      /* no suitable interface, frame not sent */
++      dev_kfree_skb(skb);
++      goto out;
+ }
+ /*
+- * Change device name
++ * in XOR mode, we determine the output device by performing xor on
++ * the source and destination hw adresses.  If this device is not
++ * enabled, find the next slave following this xor slave.
+  */
+-static inline int bond_event_changename(struct bonding *bond)
++static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
+ {
+-#ifdef CONFIG_PROC_FS
+-      bond_destroy_proc_info(bond);
+-      bond_create_proc_info(bond);
+-#endif
+-
+-      return NOTIFY_DONE;
+-}
++      struct bonding *bond = bond_dev->priv;
++      struct ethhdr *data = (struct ethhdr *)skb->data;
++      struct slave *slave, *start_at;
++      int slave_no;
++      int i;
+-static int bond_master_netdev_event(unsigned long event, struct net_device *event_dev)
+-{
+-      struct bonding *bond, *event_bond = NULL;
++      read_lock(&bond->lock);
+-      list_for_each_entry(bond, &bond_dev_list, bond_list) {
+-              if (bond == event_dev->priv) {
+-                      event_bond = bond;
+-                      break;
+-              }
++      if (!BOND_IS_OK(bond)) {
++              goto free_out;
+       }
+-      if (event_bond == NULL) {
+-              return NOTIFY_DONE;
+-      }
++      slave_no = (data->h_dest[5]^bond_dev->dev_addr[5]) % bond->slave_cnt;
+-      switch (event) {
+-      case NETDEV_CHANGENAME:
+-              return bond_event_changename(event_bond);
+-      case NETDEV_UNREGISTER:
+-              /*
+-               * TODO: remove a bond from the list?
+-               */
+-              break;
+-      default:
+-              break;
++      bond_for_each_slave(bond, slave, i) {
++              slave_no--;
++              if (slave_no < 0) {
++                      break;
++              }
+       }
+-      return NOTIFY_DONE;
+-}
++      start_at = slave;
+-static int bond_slave_netdev_event(unsigned long event, struct net_device *event_dev)
+-{
+-      struct net_device *master = event_dev->master;
++      bond_for_each_slave_from(bond, slave, i, start_at) {
++              if (IS_UP(slave->dev) &&
++                  (slave->link == BOND_LINK_UP) &&
++                  (slave->state == BOND_STATE_ACTIVE)) {
++                      skb->dev = slave->dev;
++                      skb->priority = 1;
++                      dev_queue_xmit(skb);
+-      switch (event) {
+-      case NETDEV_UNREGISTER:
+-              if (master != NULL) {
+-                      bond_release(master, event_dev);
++                      goto out;
+               }
+-              break;
+-      case NETDEV_CHANGE:
+-              /*
+-               * TODO: is this what we get if somebody
+-               * sets up a hierarchical bond, then rmmod's
+-               * one of the slave bonding devices?
+-               */
+-              break;
+-      case NETDEV_DOWN:
+-              /*
+-               * ... Or is it this?
+-               */
+-              break;
+-      case NETDEV_CHANGEMTU:
+-              /*
+-               * TODO: Should slaves be allowed to
+-               * independently alter their MTU?  For
+-               * an active-backup bond, slaves need
+-               * not be the same type of device, so
+-               * MTUs may vary.  For other modes,
+-               * slaves arguably should have the
+-               * same MTUs. To do this, we'd need to
+-               * take over the slave's change_mtu
+-               * function for the duration of their
+-               * servitude.
+-               */
+-              break;
+-      case NETDEV_CHANGENAME:
+-              /*
+-               * TODO: handle changing the primary's name
+-               */
+-              break;
+-      default:
+-              break;
+       }
+-      return NOTIFY_DONE;
++out:
++      read_unlock(&bond->lock);
++      return 0;
++
++free_out:
++      /* no suitable interface, frame not sent */
++      dev_kfree_skb(skb);
++      goto out;
+ }
+ /*
+- * bond_netdev_event: handle netdev notifier chain events.
+- *
+- * This function receives events for the netdev chain.  The caller (an
+- * ioctl handler calling notifier_call_chain) holds the necessary
+- * locks for us to safely manipulate the slave devices (RTNL lock,
+- * dev_probe_lock).
++ * in broadcast mode, we send everything to all usable interfaces.
+  */
+-static int bond_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
++static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
+ {
+-      struct net_device *event_dev = (struct net_device *)ptr;
+-      unsigned short flags;
+-      int res = NOTIFY_DONE;
++      struct bonding *bond = bond_dev->priv;
++      struct slave *slave, *start_at;
++      struct net_device *tx_dev = NULL;
++      int i;
+-      dprintk(KERN_INFO "bond_netdev_event n_b %p ev %lx ptr %p\n",
+-              this, event, ptr);
++      read_lock(&bond->lock);
+-      flags = event_dev->flags & (IFF_MASTER | IFF_SLAVE);
+-      switch (flags) {
+-      case IFF_MASTER:
+-              res = bond_master_netdev_event(event, event_dev);
+-              break;
+-      case IFF_SLAVE:
+-              res = bond_slave_netdev_event(event, event_dev);
+-              break;
+-      default:
+-              /* A master that is also a slave ? */
+-              break;
++      if (!BOND_IS_OK(bond)) {
++              goto free_out;
+       }
+-      return res;
+-}
++      read_lock(&bond->curr_slave_lock);
++      start_at = bond->curr_active_slave;
++      read_unlock(&bond->curr_slave_lock);
++
++      if (!start_at) {
++              goto free_out;
++      }
++
++      bond_for_each_slave_from(bond, slave, i, start_at) {
++              if (IS_UP(slave->dev) &&
++                  (slave->link == BOND_LINK_UP) &&
++                  (slave->state == BOND_STATE_ACTIVE)) {
++                      if (tx_dev) {
++                              struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
++                              if (!skb2) {
++                                      printk(KERN_ERR DRV_NAME
++                                             ": Error: bond_xmit_broadcast(): "
++                                             "skb_clone() failed\n");
++                                      continue;
++                              }
+-static struct notifier_block bond_netdev_notifier = {
+-      .notifier_call = bond_netdev_event,
+-};
++                              skb2->dev = tx_dev;
++                              skb2->priority = 1;
++                              dev_queue_xmit(skb2);
++                      }
++                      tx_dev = slave->dev;
++              }
++      }
+-/* De-initialize device specific data.
+- * Caller must hold rtnl_lock.
+- */
+-static inline void bond_deinit(struct net_device *dev)
+-{
+-      struct bonding *bond = dev->priv;
++      if (tx_dev) {
++              skb->dev = tx_dev;
++              skb->priority = 1;
++              dev_queue_xmit(skb);
++      } else {
++              goto free_out;
++      }
+-      list_del(&bond->bond_list);
++out:
++      /* frame sent to all suitable interfaces */
++      read_unlock(&bond->lock);
++      return 0;
+-#ifdef CONFIG_PROC_FS
+-      bond_destroy_proc_info(bond);
+-#endif
++free_out:
++      /* no suitable interface, frame not sent */
++      dev_kfree_skb(skb);
++      goto out;
+ }
+-/* Unregister and free all bond devices.
+- * Caller must hold rtnl_lock.
+- */
+-static void bond_free_all(void)
++#ifdef CONFIG_NET_FASTROUTE
++static int bond_accept_fastpath(struct net_device *bond_dev, struct dst_entry *dst)
+ {
+-      struct bonding *bond, *nxt;
+-
+-      list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
+-              struct net_device *dev = bond->device;
+-
+-              unregister_netdevice(dev);
+-              bond_deinit(dev);
+-              free_netdev(dev);
+-      }
+-
+-#ifdef CONFIG_PROC_FS
+-      bond_destroy_proc_dir();
+-#endif
++      return -1;
+ }
++#endif
++
++/*------------------------- Device initialization ---------------------------*/
+ /*
+  * Does not allocate but creates a /proc entry.
+  * Allowed to fail.
+  */
+-static int __init bond_init(struct net_device *dev)
++static int __init bond_init(struct net_device *bond_dev)
+ {
+-      struct bonding *bond;
++      struct bonding *bond = bond_dev->priv;
+       int count;
+-#ifdef BONDING_DEBUG
+-      printk (KERN_INFO "Begin bond_init for %s\n", dev->name);
+-#endif
+-      bond = dev->priv;
++      dprintk("Begin bond_init for %s\n", bond_dev->name);
+       /* initialize rwlocks */
+       rwlock_init(&bond->lock);
+-      rwlock_init(&bond->ptrlock);
++      rwlock_init(&bond->curr_slave_lock);
+       /* Initialize pointers */
+-      bond->next = bond->prev = (slave_t *)bond;
+-      bond->current_slave = NULL;
++      bond->first_slave = NULL;
++      bond->curr_active_slave = NULL;
+       bond->current_arp_slave = NULL;
+-      bond->device = dev;
++      bond->primary_slave = NULL;
++      bond->dev = bond_dev;
+-      /* Initialize the device structure. */
+-      dev->set_mac_address = bond_set_mac_address;
++      /* Initialize the device entry points */
++      bond_dev->open = bond_open;
++      bond_dev->stop = bond_close;
++      bond_dev->get_stats = bond_get_stats;
++      bond_dev->do_ioctl = bond_do_ioctl;
++      bond_dev->set_multicast_list = bond_set_multicast_list;
++      bond_dev->change_mtu = bond_change_mtu;
++      bond_dev->set_mac_address = bond_set_mac_address;
+       switch (bond_mode) {
+-      case BOND_MODE_ACTIVEBACKUP:
+-              dev->hard_start_xmit = bond_xmit_activebackup;
+-              break;
+       case BOND_MODE_ROUNDROBIN:
+-              dev->hard_start_xmit = bond_xmit_roundrobin;
++              bond_dev->hard_start_xmit = bond_xmit_roundrobin;
++              break;
++      case BOND_MODE_ACTIVEBACKUP:
++              bond_dev->hard_start_xmit = bond_xmit_activebackup;
+               break;
+       case BOND_MODE_XOR:
+-              dev->hard_start_xmit = bond_xmit_xor;
++              bond_dev->hard_start_xmit = bond_xmit_xor;
+               break;
+       case BOND_MODE_BROADCAST:
+-              dev->hard_start_xmit = bond_xmit_broadcast;
++              bond_dev->hard_start_xmit = bond_xmit_broadcast;
+               break;
+       case BOND_MODE_8023AD:
+-              dev->hard_start_xmit = bond_3ad_xmit_xor;
++              bond_dev->hard_start_xmit = bond_3ad_xmit_xor; /* extern */
+               break;
+       case BOND_MODE_TLB:
+       case BOND_MODE_ALB:
+-              dev->hard_start_xmit = bond_alb_xmit;
+-              dev->set_mac_address = bond_alb_set_mac_address;
++              bond_dev->hard_start_xmit = bond_alb_xmit; /* extern */
++              bond_dev->set_mac_address = bond_alb_set_mac_address; /* extern */
+               break;
+       default:
+-              printk(KERN_ERR "Unknown bonding mode %d\n", bond_mode);
++              printk(KERN_ERR DRV_NAME
++                     ": Error: Unknown bonding mode %d\n",
++                     bond_mode);
+               return -EINVAL;
+       }
+-      dev->get_stats = bond_get_stats;
+-      dev->open = bond_open;
+-      dev->stop = bond_close;
+-      dev->set_multicast_list = set_multicast_list;
+-      dev->do_ioctl = bond_ioctl;
+-      dev->change_mtu = bond_change_mtu;
+-      dev->tx_queue_len = 0;
+-      dev->flags |= IFF_MASTER|IFF_MULTICAST;
++      bond_dev->destructor = free_netdev;
+ #ifdef CONFIG_NET_FASTROUTE
+-      dev->accept_fastpath = bond_accept_fastpath;
++      bond_dev->accept_fastpath = bond_accept_fastpath;
+ #endif
+-      printk(KERN_INFO "%s registered with", dev->name);
+-      if (miimon > 0) {
++      /* Initialize the device options */
++      bond_dev->tx_queue_len = 0;
++      bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
++
++      printk(KERN_INFO DRV_NAME ": %s registered with", bond_dev->name);
++      if (miimon) {
+               printk(" MII link monitoring set to %d ms", miimon);
+               updelay /= miimon;
+               downdelay /= miimon;
+@@ -3993,19 +3794,20 @@ static int __init bond_init(struct net_d
+       }
+       printk(", in %s mode.\n", bond_mode_name());
+-      printk(KERN_INFO "%s registered with", dev->name);
++      printk(KERN_INFO DRV_NAME ": %s registered with", bond_dev->name);
+       if (arp_interval > 0) {
+-              printk(" ARP monitoring set to %d ms with %d target(s):", 
+-                      arp_interval, arp_ip_count);
+-              for (count=0 ; count<arp_ip_count ; count++)
+-                        printk (" %s", arp_ip_target[count]);
++              printk(" ARP monitoring set to %d ms with %d target(s):",
++                     arp_interval, arp_ip_count);
++              for (count=0 ; count<arp_ip_count ; count++) {
++                      printk(" %s", arp_ip_target[count]);
++              }
+               printk("\n");
+       } else {
+               printk("out ARP monitoring\n");
+       }
+- 
++
+ #ifdef CONFIG_PROC_FS
+-      bond_create_proc_info(bond);
++      bond_create_proc_entry(bond);
+ #endif
+       list_add_tail(&bond->bond_list, &bond_dev_list);
+@@ -4013,28 +3815,54 @@ static int __init bond_init(struct net_d
+       return 0;
+ }
+-/*
+-static int __init bond_probe(struct net_device *dev)
++/* De-initialize device specific data.
++ * Caller must hold rtnl_lock.
++ */
++static inline void bond_deinit(struct net_device *bond_dev)
+ {
+-      bond_init(dev);
+-      return 0;
++      struct bonding *bond = bond_dev->priv;
++
++      list_del(&bond->bond_list);
++
++#ifdef CONFIG_PROC_FS
++      bond_remove_proc_entry(bond);
++#endif
+ }
++
++/* Unregister and free all bond devices.
++ * Caller must hold rtnl_lock.
+  */
++static void bond_free_all(void)
++{
++      struct bonding *bond, *nxt;
++
++      list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
++              struct net_device *bond_dev = bond->dev;
++
++              unregister_netdevice(bond_dev);
++              bond_deinit(bond_dev);
++      }
++
++#ifdef CONFIG_PROC_FS
++      bond_destroy_proc_dir();
++#endif
++}
++
++/*------------------------- Module initialization ---------------------------*/
+ /*
+  * Convert string input module parms.  Accept either the
+  * number of the mode or its string name.
+  */
+-static inline int
+-bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
++static inline int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
+ {
+       int i;
+-      for (i = 0; tbl[i].modename != NULL; i++) {
++      for (i = 0; tbl[i].modename; i++) {
+               if ((isdigit(*mode_arg) &&
+-                  tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
+-                  (0 == strncmp(mode_arg, tbl[i].modename,
+-                                strlen(tbl[i].modename)))) {
++                   tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
++                  (strncmp(mode_arg, tbl[i].modename,
++                           strlen(tbl[i].modename)) == 0)) {
+                       return tbl[i].mode;
+               }
+       }
+@@ -4042,88 +3870,64 @@ bond_parse_parm(char *mode_arg, struct b
+       return -1;
+ }
+-
+-static int __init bonding_init(void)
++static int bond_check_params(void)
+ {
+-      int no;
+-      int err;
+-
+-      printk(KERN_INFO "%s", version);
+-
+       /*
+        * Convert string parameters.
+        */
+       if (mode) {
+               bond_mode = bond_parse_parm(mode, bond_mode_tbl);
+               if (bond_mode == -1) {
+-                      printk(KERN_WARNING
+-                             "bonding_init(): Invalid bonding mode \"%s\"\n",
++                      printk(KERN_ERR DRV_NAME
++                             ": Error: Invalid bonding mode \"%s\"\n",
+                              mode == NULL ? "NULL" : mode);
+                       return -EINVAL;
+               }
+       }
+-      if (USES_PRIMARY(bond_mode)) {
+-              multicast_mode = BOND_MULTICAST_ACTIVE;
+-      } else {
+-              multicast_mode = BOND_MULTICAST_ALL;
+-      }
+-
+-      if (multicast) {
+-              multicast_mode = bond_parse_parm(multicast, bond_mc_tbl);
+-              if (multicast_mode == -1) {
+-                      printk(KERN_WARNING 
+-                     "bonding_init(): Invalid multicast mode \"%s\"\n",
+-                             multicast == NULL ? "NULL" : multicast);
+-                      return -EINVAL;
+-              }
+-      }
+-
+       if (lacp_rate) {
+               if (bond_mode != BOND_MODE_8023AD) {
+-                      printk(KERN_WARNING
+-                             "lacp_rate param is irrelevant in mode %s\n",
++                      printk(KERN_INFO DRV_NAME
++                             ": lacp_rate param is irrelevant in mode %s\n",
+                              bond_mode_name());
+               } else {
+                       lacp_fast = bond_parse_parm(lacp_rate, bond_lacp_tbl);
+                       if (lacp_fast == -1) {
+-                              printk(KERN_WARNING
+-                                     "bonding_init(): Invalid lacp rate "
+-                                     "\"%s\"\n",
++                              printk(KERN_ERR DRV_NAME
++                                     ": Error: Invalid lacp rate \"%s\"\n",
+                                      lacp_rate == NULL ? "NULL" : lacp_rate);
+-
+                               return -EINVAL;
+                       }
+               }
+       }
+       if (max_bonds < 1 || max_bonds > INT_MAX) {
+-              printk(KERN_WARNING 
+-                     "bonding_init(): max_bonds (%d) not in range %d-%d, "
+-                     "so it was reset to BOND_DEFAULT_MAX_BONDS (%d)",
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning: max_bonds (%d) not in range %d-%d, so it "
++                     "was reset to BOND_DEFAULT_MAX_BONDS (%d)",
+                      max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS);
+               max_bonds = BOND_DEFAULT_MAX_BONDS;
+       }
+       if (miimon < 0) {
+-              printk(KERN_WARNING 
+-                     "bonding_init(): miimon module parameter (%d), "
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning: miimon module parameter (%d), "
+                      "not in range 0-%d, so it was reset to %d\n",
+                      miimon, INT_MAX, BOND_LINK_MON_INTERV);
+               miimon = BOND_LINK_MON_INTERV;
+       }
+       if (updelay < 0) {
+-              printk(KERN_WARNING 
+-                     "bonding_init(): updelay module parameter (%d), "
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning: updelay module parameter (%d), "
+                      "not in range 0-%d, so it was reset to 0\n",
+                      updelay, INT_MAX);
+               updelay = 0;
+       }
+       if (downdelay < 0) {
+-              printk(KERN_WARNING 
+-                     "bonding_init(): downdelay module parameter (%d), "
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning: downdelay module parameter (%d), "
+                      "not in range 0-%d, so it was reset to 0\n",
+                      downdelay, INT_MAX);
+               downdelay = 0;
+@@ -4131,82 +3935,69 @@ static int __init bonding_init(void)
+       /* reset values for 802.3ad */
+       if (bond_mode == BOND_MODE_8023AD) {
+-              if (arp_interval != 0) {
+-                      printk(KERN_WARNING "bonding_init(): ARP monitoring"
+-                             "can't be used simultaneously with 802.3ad, "
+-                             "disabling ARP monitoring\n");
++              if (arp_interval) {
++                      printk(KERN_WARNING DRV_NAME
++                             ": Warning: ARP monitoring can't be used "
++                             "simultaneously with 802.3ad, disabling ARP "
++                             "monitoring\n");
+                       arp_interval = 0;
+               }
+-              if (miimon == 0) {
+-                      printk(KERN_ERR
+-                             "bonding_init(): miimon must be specified, "
+-                             "otherwise bonding will not detect link failure, "
+-                             "speed and duplex which are essential "
+-                             "for 802.3ad operation\n");
+-                      printk(KERN_ERR "Forcing miimon to 100msec\n");
++              if (miimon) {
++                      printk(KERN_WARNING DRV_NAME
++                             ": Warning: miimon must be specified, "
++                             "otherwise bonding will not detect link "
++                             "failure, speed and duplex which are "
++                             "essential for 802.3ad operation\n");
++                      printk(KERN_WARNING "Forcing miimon to 100msec\n");
+                       miimon = 100;
+               }
+-
+-              if (multicast_mode != BOND_MULTICAST_ALL) {
+-                      printk(KERN_ERR
+-                             "bonding_init(): Multicast mode must "
+-                             "be set to ALL for 802.3ad\n");
+-                      printk(KERN_ERR "Forcing Multicast mode to ALL\n");
+-                      multicast_mode = BOND_MULTICAST_ALL;
+-              }
+       }
+       /* reset values for TLB/ALB */
+       if ((bond_mode == BOND_MODE_TLB) ||
+           (bond_mode == BOND_MODE_ALB)) {
+-              if (miimon == 0) {
+-                      printk(KERN_ERR
+-                             "bonding_init(): miimon must be specified, "
+-                             "otherwise bonding will not detect link failure "
+-                             "and link speed which are essential "
++              if (!miimon) {
++                      printk(KERN_WARNING DRV_NAME
++                             ": Warning: miimon must be specified, "
++                             "otherwise bonding will not detect link "
++                             "failure and link speed which are essential "
+                              "for TLB/ALB load balancing\n");
+-                      printk(KERN_ERR "Forcing miimon to 100msec\n");
++                      printk(KERN_WARNING "Forcing miimon to 100msec\n");
+                       miimon = 100;
+               }
+-
+-              if (multicast_mode != BOND_MULTICAST_ACTIVE) {
+-                      printk(KERN_ERR
+-                             "bonding_init(): Multicast mode must "
+-                             "be set to ACTIVE for TLB/ALB\n");
+-                      printk(KERN_ERR "Forcing Multicast mode to ACTIVE\n");
+-                      multicast_mode = BOND_MULTICAST_ACTIVE;
+-              }
+       }
+       if (bond_mode == BOND_MODE_ALB) {
+-              printk(KERN_INFO
+-                     "In ALB mode you might experience client disconnections"
+-                     " upon reconnection of a link if the bonding module"
+-                     " updelay parameter (%d msec) is incompatible with the"
+-                     " forwarding delay time of the switch\n", updelay);
++              printk(KERN_NOTICE DRV_NAME
++                     ": In ALB mode you might experience client "
++                     "disconnections upon reconnection of a link if the "
++                     "bonding module updelay parameter (%d msec) is "
++                     "incompatible with the forwarding delay time of the "
++                     "switch\n",
++                     updelay);
+       }
+-      if (miimon == 0) {
+-              if ((updelay != 0) || (downdelay != 0)) {
++      if (!miimon) {
++              if (updelay || downdelay) {
+                       /* just warn the user the up/down delay will have
+                        * no effect since miimon is zero...
+                        */
+-                      printk(KERN_WARNING 
+-                             "bonding_init(): miimon module parameter not "
+-                             "set and updelay (%d) or downdelay (%d) module "
++                      printk(KERN_WARNING DRV_NAME
++                             ": Warning: miimon module parameter not set "
++                             "and updelay (%d) or downdelay (%d) module "
+                              "parameter is set; updelay and downdelay have "
+                              "no effect unless miimon is set\n",
+-                             updelay, downdelay);
++                             updelay, downdelay);
+               }
+       } else {
+               /* don't allow arp monitoring */
+-              if (arp_interval != 0) {
+-                      printk(KERN_WARNING 
+-                             "bonding_init(): miimon (%d) and arp_interval "
+-                             "(%d) can't be used simultaneously, "
+-                             "disabling ARP monitoring\n",
+-                             miimon, arp_interval);
++              if (arp_interval) {
++                      printk(KERN_WARNING DRV_NAME
++                             ": Warning: miimon (%d) and arp_interval (%d) "
++                             "can't be used simultaneously, disabling ARP "
++                             "monitoring\n",
++                             miimon, arp_interval);
+                       arp_interval = 0;
+               }
+@@ -4214,103 +4005,114 @@ static int __init bonding_init(void)
+                       /* updelay will be rounded in bond_init() when it
+                        * is divided by miimon, we just inform user here
+                        */
+-                      printk(KERN_WARNING 
+-                             "bonding_init(): updelay (%d) is not a multiple "
++                      printk(KERN_WARNING DRV_NAME
++                             ": Warning: updelay (%d) is not a multiple "
+                              "of miimon (%d), updelay rounded to %d ms\n",
+-                             updelay, miimon, (updelay / miimon) * miimon);
++                             updelay, miimon, (updelay / miimon) * miimon);
+               }
+               if ((downdelay % miimon) != 0) {
+                       /* downdelay will be rounded in bond_init() when it
+                        * is divided by miimon, we just inform user here
+                        */
+-                      printk(KERN_WARNING 
+-                             "bonding_init(): downdelay (%d) is not a "
+-                             "multiple of miimon (%d), downdelay rounded "
+-                             "to %d ms\n",
+-                             downdelay, miimon, 
++                      printk(KERN_WARNING DRV_NAME
++                             ": Warning: downdelay (%d) is not a multiple "
++                             "of miimon (%d), downdelay rounded to %d ms\n",
++                             downdelay, miimon,
+                              (downdelay / miimon) * miimon);
+               }
+       }
+       if (arp_interval < 0) {
+-              printk(KERN_WARNING 
+-                     "bonding_init(): arp_interval module parameter (%d), "
+-                     "not in range 0-%d, so it was reset to %d\n",
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning: arp_interval module parameter (%d) "
++                     ", not in range 0-%d, so it was reset to %d\n",
+                      arp_interval, INT_MAX, BOND_LINK_ARP_INTERV);
+               arp_interval = BOND_LINK_ARP_INTERV;
+       }
+-        for (arp_ip_count=0 ;
+-             (arp_ip_count < MAX_ARP_IP_TARGETS) && arp_ip_target[arp_ip_count];
+-              arp_ip_count++ ) {
++      for (arp_ip_count = 0;
++           (arp_ip_count < MAX_ARP_IP_TARGETS) && arp_ip_target[arp_ip_count];
++           arp_ip_count++) {
+               /* not complete check, but should be good enough to
+                  catch mistakes */
+-              if (!isdigit(arp_ip_target[arp_ip_count][0])) { 
+-                        printk(KERN_WARNING
+-                               "bonding_init(): bad arp_ip_target module "
+-                               "parameter (%s), ARP monitoring will not be "
+-                               "performed\n",
+-                               arp_ip_target[arp_ip_count]);
+-                        arp_interval = 0;
+-              } else { 
+-                      u32 ip = in_aton(arp_ip_target[arp_ip_count]); 
++              if (!isdigit(arp_ip_target[arp_ip_count][0])) {
++                      printk(KERN_WARNING DRV_NAME
++                             ": Warning: bad arp_ip_target module parameter "
++                             "(%s), ARP monitoring will not be performed\n",
++                             arp_ip_target[arp_ip_count]);
++                      arp_interval = 0;
++              } else {
++                      u32 ip = in_aton(arp_ip_target[arp_ip_count]);
+                       arp_target[arp_ip_count] = ip;
+               }
+-        }
+-
++      }
+-      if ( (arp_interval > 0) && (arp_ip_count==0)) {
++      if (arp_interval && !arp_ip_count) {
+               /* don't allow arping if no arp_ip_target given... */
+-              printk(KERN_WARNING 
+-                     "bonding_init(): arp_interval module parameter "
+-                     "(%d) specified without providing an arp_ip_target "
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning: arp_interval module parameter (%d) "
++                     "specified without providing an arp_ip_target "
+                      "parameter, arp_interval was reset to 0\n",
+                      arp_interval);
+               arp_interval = 0;
+       }
+-      if ((miimon == 0) && (arp_interval == 0)) {
++      if (!miimon && !arp_interval) {
+               /* miimon and arp_interval not set, we need one so things
+                * work as expected, see bonding.txt for details
+                */
+-              printk(KERN_ERR 
+-                     "bonding_init(): either miimon or "
+-                     "arp_interval and arp_ip_target module parameters "
+-                     "must be specified, otherwise bonding will not detect "
+-                     "link failures! see bonding.txt for details.\n");
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning: either miimon or arp_interval and "
++                     "arp_ip_target module parameters must be specified, "
++                     "otherwise bonding will not detect link failures! see "
++                     "bonding.txt for details.\n");
+       }
+-      if ((primary != NULL) && !USES_PRIMARY(bond_mode)) {
++      if (primary && !USES_PRIMARY(bond_mode)) {
+               /* currently, using a primary only makes sense
+                * in active backup, TLB or ALB modes
+                */
+-              printk(KERN_WARNING 
+-                     "bonding_init(): %s primary device specified but has "
+-                     "no effect in %s mode\n",
++              printk(KERN_WARNING DRV_NAME
++                     ": Warning: %s primary device specified but has no "
++                     "effect in %s mode\n",
+                      primary, bond_mode_name());
+               primary = NULL;
+       }
++      return 0;
++}
++
++static int __init bonding_init(void)
++{
++      int i;
++      int res;
++
++      printk(KERN_INFO "%s", version);
++
++      res = bond_check_params();
++      if (res) {
++              return res;
++      }
++
+       rtnl_lock();
+ #ifdef CONFIG_PROC_FS
+       bond_create_proc_dir();
+ #endif
+-      err = 0;
+-      for (no = 0; no < max_bonds; no++) {
+-              struct net_device *dev;
+-
+-              dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
+-              if (!dev) {
+-                      err = -ENOMEM;
++      for (i = 0; i < max_bonds; i++) {
++              struct net_device *bond_dev;
++
++              bond_dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
++              if (!bond_dev) {
++                      res = -ENOMEM;
+                       goto out_err;
+               }
+-              err = dev_alloc_name(dev, "bond%d");
+-              if (err < 0) {
+-                      free_netdev(dev);
++              res = dev_alloc_name(bond_dev, "bond%d");
++              if (res < 0) {
++                      free_netdev(bond_dev);
+                       goto out_err;
+               }
+@@ -4318,18 +4120,18 @@ static int __init bonding_init(void)
+                * /proc files), but before register_netdevice(), because we
+                * need to set function pointers.
+                */
+-              err = bond_init(dev);
+-              if (err < 0) {
+-                      free_netdev(dev);
++              res = bond_init(bond_dev);
++              if (res < 0) {
++                      free_netdev(bond_dev);
+                       goto out_err;
+               }
+-              SET_MODULE_OWNER(dev);
++              SET_MODULE_OWNER(bond_dev);
+-              err = register_netdevice(dev);
+-              if (err < 0) {
+-                      bond_deinit(dev);
+-                      free_netdev(dev);
++              res = register_netdevice(bond_dev);
++              if (res < 0) {
++                      bond_deinit(bond_dev);
++                      free_netdev(bond_dev);
+                       goto out_err;
+               }
+       }
+@@ -4345,7 +4147,7 @@ out_err:
+       rtnl_unlock();
+-      return err;
++      return res;
+ }
+ static void __exit bonding_exit(void)
+@@ -4361,6 +4163,8 @@ module_init(bonding_init);
+ module_exit(bonding_exit);
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION);
++MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others");
++MODULE_SUPPORTED_DEVICE("most ethernet devices");
+ /*
+  * Local variables:
+@@ -4369,3 +4173,4 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION ", v"
+  *  tab-width: 8
+  * End:
+  */
++
+--- linux-2.6.0/drivers/net/cs89x0.c   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/cs89x0.c    2003-12-28 23:23:06.000000000 -0800
+@@ -47,7 +47,7 @@
+                     : <klee@crystal.cirrus.com>)
+                     : Don't call netif_wake_queue() in net_send_packet()
+                     : Fixed an out-of-mem bug in dma_rx()
+-                    : Updated Documentation/cs89x0.txt
++                    : Updated Documentation/networking/cs89x0.txt
+   Andrew Morton     : andrewm@uow.edu.au / Kernel 2.3.99-pre1
+                     : Use skb_reserve to longword align IP header (two places)
+@@ -212,9 +212,7 @@ struct net_local {
+ /* Index to functions, as function prototypes. */
+-extern int cs89x0_probe(struct net_device *dev);
+-
+-static int cs89x0_probe1(struct net_device *dev, int ioaddr);
++static int cs89x0_probe1(struct net_device *dev, int ioaddr, int modular);
+ static int net_open(struct net_device *dev);
+ static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
+ static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+@@ -274,27 +272,51 @@ __setup("cs89x0_media=", media_fn);
+    Return 0 on success.
+    */
+-int __init cs89x0_probe(struct net_device *dev)
++struct net_device * __init cs89x0_probe(int unit)
+ {
+-      int i;
+-      int base_addr = dev ? dev->base_addr : 0;
+-
+-      SET_MODULE_OWNER(dev);
++      struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
++      unsigned *port;
++      int err = 0;
++      int irq;
++      int io;
++
++      if (!dev)
++              return ERR_PTR(-ENODEV);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++      io = dev->base_addr;
++      irq = dev->irq;
+       if (net_debug)
+-              printk("cs89x0:cs89x0_probe(0x%x)\n", base_addr);
++              printk("cs89x0:cs89x0_probe(0x%x)\n", io);
+-      if (base_addr > 0x1ff)          /* Check a single specified location. */
+-              return cs89x0_probe1(dev, base_addr);
+-      else if (base_addr != 0)        /* Don't probe at all. */
+-              return -ENXIO;
+-
+-      for (i = 0; netcard_portlist[i]; i++) {
+-              if (cs89x0_probe1(dev, netcard_portlist[i]) == 0)
+-                      return 0;
++      if (io > 0x1ff) {       /* Check a single specified location. */
++              err = cs89x0_probe1(dev, io, 0);
++      } else if (io != 0) {   /* Don't probe at all. */
++              err = -ENXIO;
++      } else {
++              for (port = netcard_portlist; *port; port++) {
++                      if (cs89x0_probe1(dev, *port, 0) == 0)
++                              break;
++                      dev->irq = irq;
++              }
++              if (!*port)
++                      err = -ENODEV;
+       }
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      outw(PP_ChipID, dev->base_addr + ADD_PORT);
++      release_region(dev->base_addr, NETCARD_IO_EXTENT);
++out:
++      free_netdev(dev);
+       printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected.  Be sure to disable PnP with SETUP\n");
+-      return -ENODEV;
++      return ERR_PTR(err);
+ }
+ static int
+@@ -375,39 +397,34 @@ get_eeprom_cksum(int off, int len, int *
+  */
+ static int __init
+-cs89x0_probe1(struct net_device *dev, int ioaddr)
++cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
+ {
+-      struct net_local *lp;
++      struct net_local *lp = (struct net_local *)dev->priv;
+       static unsigned version_printed;
+       int i;
+       unsigned rev_type = 0;
+       int eeprom_buff[CHKSUM_LEN];
+       int retval;
++      SET_MODULE_OWNER(dev);
+       /* Initialize the device structure. */
+-      if (dev->priv == NULL) {
+-              dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-              if (dev->priv == 0) {
+-                      retval = -ENOMEM;
+-                      goto out;
+-              }
+-              lp = (struct net_local *)dev->priv;
++      if (!modular) {
+               memset(lp, 0, sizeof(*lp));
+               spin_lock_init(&lp->lock);
+-#if !defined(MODULE) && (ALLOW_DMA != 0)
++#ifndef MODULE
++#if ALLOW_DMA
+               if (g_cs89x0_dma) {
+                       lp->use_dma = 1;
+                       lp->dma = g_cs89x0_dma;
+                       lp->dmasize = 16;       /* Could make this an option... */
+               }
+ #endif
+-#ifndef MODULE
+               lp->force = g_cs89x0_media__force;
+ #endif
+         }
+-      lp = (struct net_local *)dev->priv;
+       /* Grab the region so we can find another board if autoIRQ fails. */
++      /* WTF is going on here? */
+       if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, dev->name)) {
+               printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n",
+                               dev->name, ioaddr, NETCARD_IO_EXTENT);
+@@ -696,9 +713,6 @@ printk("PP_addr=0x%x\n", inw(ioaddr + AD
+       dev->set_multicast_list = set_multicast_list;
+       dev->set_mac_address    = set_mac_address;
+-      /* Fill in the fields of the device structure with ethernet values. */
+-      ether_setup(dev);
+-
+       printk("\n");
+       if (net_debug)
+               printk("cs89x0_probe1() successful\n");
+@@ -706,9 +720,6 @@ printk("PP_addr=0x%x\n", inw(ioaddr + AD
+ out2:
+       release_region(ioaddr & ~3, NETCARD_IO_EXTENT);
+ out1:
+-      kfree(dev->priv);
+-      dev->priv = 0;
+-out:
+       return retval;
+ }
+@@ -1655,7 +1666,7 @@ static int set_mac_address(struct net_de
+ #ifdef MODULE
+-static struct net_device dev_cs89x0;
++static struct net_device *dev_cs89x0;
+ /*
+  * Support the 'debug' module parm even if we're compiled for non-debug to 
+@@ -1733,6 +1744,7 @@ MODULE_LICENSE("GPL");
+ int
+ init_module(void)
+ {
++      struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+       struct net_local *lp;
+       int ret = 0;
+@@ -1741,18 +1753,12 @@ init_module(void)
+ #else
+       debug = 0;
+ #endif
+-
+-      dev_cs89x0.irq = irq;
+-      dev_cs89x0.base_addr = io;
+-
+-        dev_cs89x0.init = cs89x0_probe;
+-        dev_cs89x0.priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-      if (dev_cs89x0.priv == 0) {
+-              printk(KERN_ERR "cs89x0.c: Out of memory.\n");
++      if (!dev)
+               return -ENOMEM;
+-      }
+-      memset(dev_cs89x0.priv, 0, sizeof(struct net_local));
+-      lp = (struct net_local *)dev_cs89x0.priv;
++
++      dev->irq = irq;
++      dev->base_addr = io;
++      lp = dev->priv;
+ #if ALLOW_DMA
+       if (use_dma) {
+@@ -1782,7 +1788,10 @@ init_module(void)
+                 printk(KERN_ERR "cs89x0.c: Append io=0xNNN\n");
+                 ret = -EPERM;
+               goto out;
+-        }
++        } else if (io <= 0x1ff) {
++              ret = -ENXIO;
++              goto out;
++      }
+ #if ALLOW_DMA
+       if (use_dma && dmasize != 16 && dmasize != 64) {
+@@ -1791,30 +1800,31 @@ init_module(void)
+               goto out;
+       }
+ #endif
++      ret = cs89x0_probe1(dev, io, 1);
++      if (ret)
++              goto out;
+-        if (register_netdev(&dev_cs89x0) != 0) {
++        if (register_netdev(dev) != 0) {
+                 printk(KERN_ERR "cs89x0.c: No card found at 0x%x\n", io);
+                 ret = -ENXIO;
++              outw(PP_ChipID, dev->base_addr + ADD_PORT);
++              release_region(dev->base_addr, NETCARD_IO_EXTENT);
+               goto out;
+         }
++      dev_cs89x0 = dev;
++      return 0;
+ out:
+-      if (ret)
+-              kfree(dev_cs89x0.priv);
++      free_netdev(dev);
+       return ret;
+ }
+ void
+ cleanup_module(void)
+ {
+-        if (dev_cs89x0.priv != NULL) {
+-                /* Free up the private structure, or leak memory :-)  */
+-                unregister_netdev(&dev_cs89x0);
+-              outw(PP_ChipID, dev_cs89x0.base_addr + ADD_PORT);
+-                kfree(dev_cs89x0.priv);
+-                dev_cs89x0.priv = NULL;       /* gets re-allocated by cs89x0_probe1 */
+-                /* If we don't do this, we can't re-insmod it later. */
+-                release_region(dev_cs89x0.base_addr, NETCARD_IO_EXTENT);
+-        }
++      unregister_netdev(dev_cs89x0);
++      outw(PP_ChipID, dev_cs89x0->base_addr + ADD_PORT);
++      release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
++      free_netdev(dev_cs89x0);
+ }
+ #endif /* MODULE */
\f
+--- linux-2.6.0/drivers/net/de600.c    2003-06-14 12:18:35.000000000 -0700
++++ 25/drivers/net/de600.c     2003-12-28 23:21:01.000000000 -0800
+@@ -99,7 +99,7 @@ static volatile int          tx_fifo_in;
+ static volatile int           tx_fifo_out;
+ static volatile int           free_tx_pages = TX_PAGES;
+ static int                    was_down;
+-static spinlock_t             de600_lock;
++static spinlock_t             de600_lock = SPIN_LOCK_UNLOCKED;
+ static inline u8 de600_read_status(struct net_device *dev)
+ {
+@@ -398,20 +398,31 @@ static void de600_rx_intr(struct net_dev
+        */
+ }
+-int __init de600_probe(struct net_device *dev)
++static struct net_device * __init de600_probe(void)
+ {
+       int     i;
+-      static struct net_device_stats de600_netstats;
+-      /*dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);*/
++      struct net_device *dev;
++      int err;
++
++      dev = alloc_etherdev(sizeof(struct net_device_stats));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+       SET_MODULE_OWNER(dev);
++      if (!request_region(DE600_IO, 3, "de600")) {
++              printk(KERN_WARNING "DE600: port 0x%x busy\n", DE600_IO);
++              err = -EBUSY;
++              goto out;
++      }
++
+       printk(KERN_INFO "%s: D-Link DE-600 pocket adapter", dev->name);
+       /* Alpha testers must have the version number to report bugs. */
+       if (de600_debug > 1)
+               printk(version);
+       /* probe for adapter */
++      err = -ENODEV;
+       rx_page = 0;
+       select_nic();
+       (void)de600_read_status(dev);
+@@ -419,7 +430,7 @@ int __init de600_probe(struct net_device
+       de600_put_command(STOP_RESET);
+       if (de600_read_status(dev) & 0xf0) {
+               printk(": not at I/O %#3x.\n", DATA_PORT);
+-              return -ENODEV;
++              goto out1;
+       }
+       /*
+@@ -444,12 +455,7 @@ int __init de600_probe(struct net_device
+               dev->dev_addr[3] |= 0x70;
+       } else {
+               printk(" not identified in the printer port\n");
+-              return -ENODEV;
+-      }
+-
+-      if (!request_region(DE600_IO, 3, "de600")) {
+-              printk(KERN_WARNING "DE600: port 0x%x busy\n", DE600_IO);
+-              return -EBUSY;
++              goto out1;
+       }
+       printk(", Ethernet Address: %02X", dev->dev_addr[0]);
+@@ -457,22 +463,27 @@ int __init de600_probe(struct net_device
+               printk(":%02X",dev->dev_addr[i]);
+       printk("\n");
+-      /* Initialize the device structure. */
+-      dev->priv = &de600_netstats;
+-
+-      memset(dev->priv, 0, sizeof(struct net_device_stats));
+       dev->get_stats = get_stats;
+       dev->open = de600_open;
+       dev->stop = de600_close;
+       dev->hard_start_xmit = &de600_start_xmit;
+-      ether_setup(dev);
+-
+       dev->flags&=~IFF_MULTICAST;
+       select_prn();
+-      return 0;
++
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++
++      return dev;
++
++out1:
++      release_region(DE600_IO, 3);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ static int adapter_init(struct net_device *dev)
+@@ -527,21 +538,21 @@ static int adapter_init(struct net_devic
+       return 0; /* OK */
+ }
+-static struct net_device de600_dev;
++static struct net_device *de600_dev;
+ static int __init de600_init(void)
+ {
+-      spin_lock_init(&de600_lock);
+-      de600_dev.init = de600_probe;
+-      if (register_netdev(&de600_dev) != 0)
+-              return -EIO;
++      de600_dev = de600_probe();
++      if (IS_ERR(de600_dev))
++              return PTR_ERR(de600_dev);
+       return 0;
+ }
+ static void __exit de600_exit(void)
+ {
+-      unregister_netdev(&de600_dev);
++      unregister_netdev(de600_dev);
+       release_region(DE600_IO, 3);
++      free_netdev(de600_dev);
+ }
+ module_init(de600_init);
+--- linux-2.6.0/drivers/net/de600.h    2003-06-14 12:18:23.000000000 -0700
++++ 25/drivers/net/de600.h     2003-12-28 23:21:01.000000000 -0800
+@@ -131,7 +131,6 @@ static void        de600_rx_intr(struct net_dev
+ /* Initialization */
+ static void   trigger_interrupt(struct net_device *dev);
+-int           de600_probe(struct net_device *dev);
+ static int    adapter_init(struct net_device *dev);
+ /*
+--- linux-2.6.0/drivers/net/de620.c    2003-06-14 12:18:22.000000000 -0700
++++ 25/drivers/net/de620.c     2003-12-28 23:21:01.000000000 -0800
+@@ -226,7 +226,6 @@ static int de620_rx_intr(struct net_devi
+ /* Initialization */
+ static int    adapter_init(struct net_device *);
+-int           de620_probe(struct net_device *);
+ static int    read_eeprom(struct net_device *);
+@@ -814,11 +813,16 @@ static int adapter_init(struct net_devic
+  *
+  * Check if there is a DE-620 connected
+  */
+-int __init de620_probe(struct net_device *dev)
++struct net_device * __init de620_probe(int unit)
+ {
+-      static struct net_device_stats de620_netstats;
+-      int i;
+       byte checkbyte = 0xa5;
++      struct net_device *dev;
++      int err = -ENOMEM;
++      int i;
++
++      dev = alloc_etherdev(sizeof(struct net_device_stats));
++      if (!dev)
++              goto out;
+       SET_MODULE_OWNER(dev);
+@@ -831,11 +835,23 @@ int __init de620_probe(struct net_device
+       dev->base_addr = io;
+       dev->irq       = irq;
++      /* allow overriding parameters on command line */
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
++      
+       if (de620_debug)
+               printk(version);
+       printk(KERN_INFO "D-Link DE-620 pocket adapter");
++      if (!request_region(dev->base_addr, 3, "de620")) {
++              printk(" io 0x%3lX, which is busy.\n", dev->base_addr);
++              err = -EBUSY;
++              goto out1;
++      }
++
+       /* Initially, configure basic nibble mode, so we can read the EEPROM */
+       NIC_Cmd = DEF_NIC_CMD;
+       de620_set_register(dev, W_EIP, EIPRegister);
+@@ -846,12 +862,8 @@ int __init de620_probe(struct net_device
+       if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) {
+               printk(" not identified in the printer port\n");
+-              return -ENODEV;
+-      }
+-
+-      if (!request_region(dev->base_addr, 3, "de620")) {
+-              printk(KERN_ERR "io 0x%3lX, which is busy.\n", dev->base_addr);
+-              return -EBUSY;
++              err = -ENODEV;
++              goto out2;
+       }
+       /* else, got it! */
+@@ -870,10 +882,6 @@ int __init de620_probe(struct net_device
+       else
+               printk(" UTP)\n");
+-      /* Initialize the device structure. */
+-      dev->priv = &de620_netstats;
+-
+-      memset(dev->priv, 0, sizeof(struct net_device_stats));
+       dev->get_stats          = get_stats;
+       dev->open               = de620_open;
+       dev->stop               = de620_close;
+@@ -884,8 +892,6 @@ int __init de620_probe(struct net_device
+       
+       /* base_addr and irq are already set, see above! */
+-      ether_setup(dev);
+-
+       /* dump eeprom */
+       if (de620_debug) {
+               printk("\nEEPROM contents:\n");
+@@ -899,7 +905,17 @@ int __init de620_probe(struct net_device
+               printk("SCR = 0x%02x\n", nic_data.SCR);
+       }
+-      return 0;
++      err = register_netdev(dev);
++      if (err)
++              goto out2;
++      return dev;
++
++out2:
++      release_region(dev->base_addr, 3);
++out1:
++      free_netdev(dev);
++out:
++      return ERR_PTR(err);
+ }
\f
+ /**********************************
+@@ -994,20 +1010,21 @@ static int __init read_eeprom(struct net
+  *
+  */
+ #ifdef MODULE
+-static struct net_device de620_dev;
++static struct net_device *de620_dev;
+ int init_module(void)
+ {
+-      de620_dev.init = de620_probe;
+-      if (register_netdev(&de620_dev) != 0)
+-              return -EIO;
++      de620_dev = de620_probe(-1);
++      if (IS_ERR(de620_dev))
++              return PTR_ERR(de620_dev);
+       return 0;
+ }
+ void cleanup_module(void)
+ {
+-      unregister_netdev(&de620_dev);
+-      release_region(de620_dev.base_addr, 3);
++      unregister_netdev(de620_dev);
++      release_region(de620_dev->base_addr, 3);
++      free_netdev(de620_dev);
+ }
+ #endif /* MODULE */
+ MODULE_LICENSE("GPL");
+--- linux-2.6.0/drivers/net/declance.c 2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/declance.c  2003-12-28 23:21:01.000000000 -0800
+@@ -1039,13 +1039,13 @@ static int __init dec_lance_init(const i
+       if (dec_lance_debug && version_printed++ == 0)
+               printk(version);
+-      dev = init_etherdev(NULL, sizeof(struct lance_private));
++      dev = alloc_etherdev(sizeof(struct lance_private));
+       if (!dev)
+               return -ENOMEM;
+       SET_MODULE_OWNER(dev);
+       /*
+-       * init_etherdev ensures the data structures used by the LANCE
++       * alloc_etherdev ensures the data structures used by the LANCE
+        * are aligned.
+        */
+       lp = (struct lance_private *) dev->priv;
+@@ -1188,9 +1188,6 @@ static int __init dec_lance_init(const i
+               }
+       }
+-      lp->next = root_lance_dev;
+-      root_lance_dev = dev;
+-
+       /* Copy the ethernet address to the device structure, later to the
+        * lance initialization block so the lance gets it every time it's
+        * (re)initialized.
+@@ -1239,11 +1236,14 @@ static int __init dec_lance_init(const i
+       init_timer(&lp->multicast_timer);
+       lp->multicast_timer.data = (unsigned long) dev;
+       lp->multicast_timer.function = &lance_set_multicast_retry;
+-
++      ret = register_netdev(dev);
++      if (ret)
++              goto err_out;
++      lp->next = root_lance_dev;
++      root_lance_dev = dev;
+       return 0;
+ err_out:
+-      unregister_netdev(dev);
+       free_netdev(dev);
+       return ret;
+ }
+@@ -1288,13 +1288,12 @@ static void __exit dec_lance_cleanup(voi
+       while (root_lance_dev) {
+               struct net_device *dev = root_lance_dev;
+               struct lance_private *lp = (struct lance_private *)dev->priv;
+-
++              unregister_netdev(dev);
+ #ifdef CONFIG_TC
+               if (lp->slot >= 0)
+                       release_tc_card(lp->slot);
+ #endif
+               root_lance_dev = lp->next;
+-              unregister_netdev(dev);
+               free_netdev(dev);
+       }
+ }
+--- linux-2.6.0/drivers/net/defxx.c    2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/defxx.c     2003-12-28 23:21:01.000000000 -0800
+@@ -491,7 +491,7 @@ err_out_kfree:
+ err_out_region:
+       release_region(ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN);
+ err_out:
+-      kfree(dev);
++      free_netdev(dev);
+       return err;
+ }
+--- linux-2.6.0/drivers/net/depca.c    2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/depca.c     2003-12-28 23:21:01.000000000 -0800
+@@ -681,8 +681,7 @@ static int __init depca_hw_init (struct 
+       lp->sh_mem = ioremap(mem_start, mem_len);
+       if (lp->sh_mem == NULL) {
+               printk(KERN_ERR "depca: cannot remap ISA memory, aborting\n");
+-              release_mem_region (mem_start, mem_len);
+-              goto out_priv;
++              goto out1;
+       }
+       lp->mem_start = mem_start;
+@@ -771,7 +770,7 @@ static int __init depca_hw_init (struct 
+               status = -ENXIO;
+               if (!irqnum) {
+                       printk(" and failed to detect IRQ line.\n");
+-                      goto out_priv;
++                      goto out2;
+               } else {
+                       for (dev->irq = 0, i = 0; (depca_irq[i]) && (!dev->irq); i++)
+                               if (irqnum == depca_irq[i]) {
+@@ -781,7 +780,7 @@ static int __init depca_hw_init (struct 
+                       if (!dev->irq) {
+                               printk(" but incorrect IRQ line detected.\n");
+-                              return -ENXIO;
++                              goto out2;
+                       }
+               }
+       } else {
+@@ -807,11 +806,14 @@ static int __init depca_hw_init (struct 
+       device->driver_data = dev;
+       SET_NETDEV_DEV (dev, device);
+       
+-      register_netdev (dev);
+-      return 0;
+-
+- out_priv:
+-      
++      status = register_netdev(dev);
++      if (status == 0)
++              return 0;
++out2:
++      iounmap(lp->sh_mem);
++out1:
++      release_mem_region (mem_start, mem_len);
++out_priv:
+       return status;
+ }
\f
+--- linux-2.6.0/drivers/net/dummy.c    2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/dummy.c     2003-12-28 23:21:01.000000000 -0800
+@@ -96,7 +96,7 @@ static int __init dummy_init_module(void
+               return -ENOMEM;
+       if ((err = register_netdev(dev_dummy))) {
+-              kfree(dev_dummy);
++              free_netdev(dev_dummy);
+               dev_dummy = NULL;
+       }
+       return err;
+--- linux-2.6.0/drivers/net/e1000/e1000_ethtool.c      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/e1000/e1000_ethtool.c       2003-12-28 23:21:01.000000000 -0800
+@@ -39,6 +39,10 @@ extern int e1000_up(struct e1000_adapter
+ extern void e1000_down(struct e1000_adapter *adapter);
+ extern void e1000_reset(struct e1000_adapter *adapter);
+ extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
++extern int e1000_setup_rx_resources(struct e1000_adapter *adapter);
++extern int e1000_setup_tx_resources(struct e1000_adapter *adapter);
++extern void e1000_free_rx_resources(struct e1000_adapter *adapter);
++extern void e1000_free_tx_resources(struct e1000_adapter *adapter);
+ struct e1000_stats {
+       char stat_string[ETH_GSTRING_LEN];
+@@ -440,6 +444,71 @@ seeprom_error:
+       return ret_val;
+ }
++static int
++e1000_ethtool_gring(struct e1000_adapter *adapter,
++                    struct ethtool_ringparam *ring)
++{
++      e1000_mac_type mac_type = adapter->hw.mac_type;
++      struct e1000_desc_ring *txdr = &adapter->tx_ring;
++      struct e1000_desc_ring *rxdr = &adapter->rx_ring;
++
++      ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD :
++              E1000_MAX_82544_RXD;
++      ring->tx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_TXD :
++              E1000_MAX_82544_TXD;
++      ring->rx_mini_max_pending = 0;
++      ring->rx_jumbo_max_pending = 0;
++      ring->rx_pending = rxdr->count;
++      ring->tx_pending = txdr->count;
++      ring->rx_mini_pending = 0;
++      ring->rx_jumbo_pending = 0;
++
++      return 0;
++}
++static int 
++e1000_ethtool_sring(struct e1000_adapter *adapter,
++                    struct ethtool_ringparam *ring)
++{
++      int err;
++      e1000_mac_type mac_type = adapter->hw.mac_type;
++      struct e1000_desc_ring *txdr = &adapter->tx_ring;
++      struct e1000_desc_ring *rxdr = &adapter->rx_ring;
++
++      if(netif_running(adapter->netdev)) {
++              e1000_down(adapter);
++              e1000_free_rx_resources(adapter);
++              e1000_free_tx_resources(adapter);
++      }
++
++      rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
++      rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
++              E1000_MAX_RXD : E1000_MAX_82544_RXD));
++      E1000_ROUNDUP(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE); 
++
++      txdr->count = max(ring->tx_pending,(uint32_t)E1000_MIN_TXD);
++      txdr->count = min(txdr->count,(uint32_t)(mac_type < e1000_82544 ?
++              E1000_MAX_TXD : E1000_MAX_82544_TXD));
++      E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE); 
++
++      if(netif_running(adapter->netdev)) {
++              if((err = e1000_setup_rx_resources(adapter)))
++                      goto err_setup_rx;
++              if((err = e1000_setup_tx_resources(adapter)))
++                      goto err_setup_tx;
++              if((err = e1000_up(adapter)))
++                      goto err_up;
++      }
++
++      return 0;
++err_up:
++      e1000_free_tx_resources(adapter);
++err_setup_tx:
++      e1000_free_rx_resources(adapter);
++err_setup_rx:
++      e1000_reset(adapter);
++      return err;
++}
++
+ #define REG_PATTERN_TEST(R, M, W)                                              \
+ {                                                                              \
+       uint32_t pat, value;                                                   \
+@@ -579,8 +648,8 @@ e1000_intr_test(struct e1000_adapter *ad
+       *data = 0;
+       /* Hook up test interrupt handler just for this test */
+-      if(request_irq
+-         (netdev->irq, &e1000_test_intr, SA_SHIRQ, netdev->name, netdev)) {
++      if(request_irq(adapter->pdev->irq, &e1000_test_intr, SA_SHIRQ,
++         netdev->name, netdev)) {
+               *data = 1;
+               return -1;
+       }
+@@ -664,7 +733,7 @@ e1000_intr_test(struct e1000_adapter *ad
+       msec_delay(10);
+       /* Unhook test interrupt handler */
+-      free_irq(netdev->irq, netdev);
++      free_irq(adapter->pdev->irq, netdev);
+       return *data;
+ }
+@@ -770,9 +839,9 @@ e1000_setup_desc_rings(struct e1000_adap
+                                      PCI_DMA_TODEVICE);
+               tx_desc->buffer_addr = cpu_to_le64(txdr->buffer_info[i].dma);
+               tx_desc->lower.data = cpu_to_le32(skb->len);
+-              tx_desc->lower.data |= E1000_TXD_CMD_EOP;
+-              tx_desc->lower.data |= E1000_TXD_CMD_IFCS;
+-              tx_desc->lower.data |= E1000_TXD_CMD_RPS;
++              tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP |
++                                                 E1000_TXD_CMD_IFCS |
++                                                 E1000_TXD_CMD_RPS);
+               tx_desc->upper.data = 0;
+       }
+@@ -1502,6 +1571,19 @@ err_geeprom_ioctl:
+               addr += offsetof(struct ethtool_eeprom, data);
+               return e1000_ethtool_seeprom(adapter, &eeprom, addr);
+       }
++      case ETHTOOL_GRINGPARAM: {
++              struct ethtool_ringparam ering = {ETHTOOL_GRINGPARAM};
++              e1000_ethtool_gring(adapter, &ering);
++              if(copy_to_user(addr, &ering, sizeof(ering)))
++                      return -EFAULT;
++              return 0;
++      }
++      case ETHTOOL_SRINGPARAM: {
++              struct ethtool_ringparam ering;
++              if(copy_from_user(&ering, addr, sizeof(ering)))
++                      return -EFAULT;
++              return e1000_ethtool_sring(adapter, &ering);
++      }
+       case ETHTOOL_GPAUSEPARAM: {
+               struct ethtool_pauseparam epause = {ETHTOOL_GPAUSEPARAM};
+               e1000_ethtool_gpause(adapter, &epause);
+--- linux-2.6.0/drivers/net/e1000/e1000.h      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/e1000/e1000.h       2003-12-28 23:21:01.000000000 -0800
+@@ -92,6 +92,16 @@ struct e1000_adapter;
+ #define E1000_MAX_INTR 10
++/* How many descriptors for TX and RX ? */
++#define E1000_DEFAULT_TXD                  256
++#define E1000_MAX_TXD                      256
++#define E1000_MIN_TXD                       80
++#define E1000_MAX_82544_TXD               4096
++#define E1000_DEFAULT_RXD                  256
++#define E1000_MAX_RXD                      256
++#define E1000_MIN_RXD                       80
++#define E1000_MAX_82544_RXD               4096
++
+ /* Supported Rx Buffer Sizes */
+ #define E1000_RXBUFFER_2048  2048
+ #define E1000_RXBUFFER_4096  4096
+--- linux-2.6.0/drivers/net/e1000/e1000_hw.c   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/e1000/e1000_hw.c    2003-12-28 23:21:01.000000000 -0800
+@@ -1485,8 +1485,8 @@ e1000_phy_force_speed_duplex(struct e100
+             if(mii_status_reg & MII_SR_LINK_STATUS) break;
+             msec_delay(100);
+         }
+-        if(i == 0) { /* We didn't get link */
+-            /* Reset the DSP and wait again for link. */
++        if((i == 0) && (hw->phy_type == e1000_phy_m88)) {
++            /* We didn't get link.  Reset the DSP and wait again for link. */
+             if((ret_val = e1000_phy_reset_dsp(hw))) {
+                 DEBUGOUT("Error Resetting PHY DSP\n");
+                 return ret_val;
+@@ -2081,6 +2081,25 @@ e1000_check_for_link(struct e1000_hw *hw
+         DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\r\n");
+         E1000_WRITE_REG(hw, TXCW, hw->txcw);
+         E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
++
++        hw->serdes_link_down = FALSE;
++    }
++    /* If we force link for non-auto-negotiation switch, check link status
++     * based on MAC synchronization for internal serdes media type.
++     */
++    else if((hw->media_type == e1000_media_type_internal_serdes) &&
++            !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
++        /* SYNCH bit and IV bit are sticky. */
++        udelay(10);
++        if(E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) {
++            if(!(rxcw & E1000_RXCW_IV)) {
++                hw->serdes_link_down = FALSE;
++                DEBUGOUT("SERDES: Link is up.\n");
++            }
++        } else {
++            hw->serdes_link_down = TRUE;
++            DEBUGOUT("SERDES: Link is down.\n");
++        }
+     }
+     return E1000_SUCCESS;
+ }
+@@ -2481,8 +2500,8 @@ e1000_write_phy_reg_ex(struct e1000_hw *
+         E1000_WRITE_REG(hw, MDIC, mdic);
+         /* Poll the ready bit to see if the MDI read completed */
+-        for(i = 0; i < 64; i++) {
+-            udelay(50);
++        for(i = 0; i < 640; i++) {
++            udelay(5);
+             mdic = E1000_READ_REG(hw, MDIC);
+             if(mdic & E1000_MDIC_READY) break;
+         }
+@@ -3498,10 +3517,12 @@ e1000_write_eeprom(struct e1000_hw *hw,
+     if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+         return -E1000_ERR_EEPROM;
+-    if(eeprom->type == e1000_eeprom_microwire)
++    if(eeprom->type == e1000_eeprom_microwire) {
+         status = e1000_write_eeprom_microwire(hw, offset, words, data);
+-    else
++    } else {
+         status = e1000_write_eeprom_spi(hw, offset, words, data);
++        msec_delay(10);
++    }
+     /* Done with writing */
+     e1000_release_eeprom(hw);
+@@ -3719,12 +3740,9 @@ e1000_read_mac_addr(struct e1000_hw * hw
+         hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
+     }
+     if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
+-       (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
+-        if(hw->perm_mac_addr[5] & 0x01)
+-            hw->perm_mac_addr[5] &= ~(0x01);
+-        else
+-            hw->perm_mac_addr[5] |= 0x01;
+-    }
++       (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
++            hw->perm_mac_addr[5] ^= 0x01;
++
+     for(i = 0; i < NODE_ADDRESS_SIZE; i++)
+         hw->mac_addr[i] = hw->perm_mac_addr[i];
+     return E1000_SUCCESS;
+@@ -3743,22 +3761,13 @@ void
+ e1000_init_rx_addrs(struct e1000_hw *hw)
+ {
+     uint32_t i;
+-    uint32_t addr_low;
+-    uint32_t addr_high;
+     DEBUGFUNC("e1000_init_rx_addrs");
+     /* Setup the receive address. */
+     DEBUGOUT("Programming MAC Address into RAR[0]\n");
+-    addr_low = (hw->mac_addr[0] |
+-                (hw->mac_addr[1] << 8) |
+-                (hw->mac_addr[2] << 16) | (hw->mac_addr[3] << 24));
+-
+-    addr_high = (hw->mac_addr[4] |
+-                 (hw->mac_addr[5] << 8) | E1000_RAH_AV);
+-    E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low);
+-    E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high);
++    e1000_rar_set(hw, hw->mac_addr, 0);
+     /* Zero out the other 15 receive addresses. */
+     DEBUGOUT("Clearing RAR[1-15]\n");
+@@ -3785,11 +3794,11 @@ void
+ e1000_mc_addr_list_update(struct e1000_hw *hw,
+                           uint8_t *mc_addr_list,
+                           uint32_t mc_addr_count,
+-                          uint32_t pad)
++                          uint32_t pad,
++                        uint32_t rar_used_count)
+ {
+     uint32_t hash_value;
+     uint32_t i;
+-    uint32_t rar_used_count = 1; /* RAR[0] is used for our MAC address */
+     DEBUGFUNC("e1000_mc_addr_list_update");
+@@ -4523,8 +4532,8 @@ uint32_t
+ e1000_read_reg_io(struct e1000_hw *hw,
+                   uint32_t offset)
+ {
+-    uint32_t io_addr = hw->io_base;
+-    uint32_t io_data = hw->io_base + 4;
++    unsigned long io_addr = hw->io_base;
++    unsigned long io_data = hw->io_base + 4;
+     e1000_io_write(hw, io_addr, offset);
+     return e1000_io_read(hw, io_data);
+@@ -4543,8 +4552,8 @@ e1000_write_reg_io(struct e1000_hw *hw,
+                    uint32_t offset,
+                    uint32_t value)
+ {
+-    uint32_t io_addr = hw->io_base;
+-    uint32_t io_data = hw->io_base + 4;
++    unsigned long io_addr = hw->io_base;
++    unsigned long io_data = hw->io_base + 4;
+     e1000_io_write(hw, io_addr, offset);
+     e1000_io_write(hw, io_data, value);
+--- linux-2.6.0/drivers/net/e1000/e1000_hw.h   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/e1000/e1000_hw.h    2003-12-28 23:21:01.000000000 -0800
+@@ -291,7 +291,7 @@ int32_t e1000_read_mac_addr(struct e1000
+ /* Filters (multicast, vlan, receive) */
+ void e1000_init_rx_addrs(struct e1000_hw *hw);
+-void e1000_mc_addr_list_update(struct e1000_hw *hw, uint8_t * mc_addr_list, uint32_t mc_addr_count, uint32_t pad);
++void e1000_mc_addr_list_update(struct e1000_hw *hw, uint8_t * mc_addr_list, uint32_t mc_addr_count, uint32_t pad, uint32_t rar_used_count);
+ uint32_t e1000_hash_mc_addr(struct e1000_hw *hw, uint8_t * mc_addr);
+ void e1000_mta_set(struct e1000_hw *hw, uint32_t hash_value);
+ void e1000_rar_set(struct e1000_hw *hw, uint8_t * mc_addr, uint32_t rar_index);
+@@ -317,9 +317,9 @@ void e1000_pci_clear_mwi(struct e1000_hw
+ void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
+ void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
+ /* Port I/O is only supported on 82544 and newer */
+-uint32_t e1000_io_read(struct e1000_hw *hw, uint32_t port);
++uint32_t e1000_io_read(struct e1000_hw *hw, unsigned long port);
+ uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
+-void e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value);
++void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
+ void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
+ int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
+ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
+@@ -978,7 +978,7 @@ struct e1000_hw {
+     e1000_ms_type master_slave;
+     e1000_ms_type original_master_slave;
+     e1000_ffe_config ffe_config_state;
+-    uint32_t io_base;
++    unsigned long io_base;
+     uint32_t phy_id;
+     uint32_t phy_revision;
+     uint32_t phy_addr;
+@@ -1021,6 +1021,7 @@ struct e1000_hw {
+     boolean_t speed_downgraded;
+     e1000_dsp_config dsp_config_state;
+     boolean_t get_link_status;
++    boolean_t serdes_link_down;
+     boolean_t tbi_compatibility_en;
+     boolean_t tbi_compatibility_on;
+     boolean_t phy_reset_disable;
+--- linux-2.6.0/drivers/net/e1000/e1000_main.c 2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/e1000/e1000_main.c  2003-12-28 23:21:01.000000000 -0800
+@@ -30,10 +30,19 @@
+ /* Change Log
+  *
+- * 5.2.20     9/30/03
++ * 5.2.26     11/13/03
++ *   o Fixed endianess bug causing ethtool loopback diags to fail on ppc.
++ *   o Use pdev->irq rather than netdev->irq in preparation for MSI support.
++ *   o Report driver message on user override of InterruptThrottleRate
++ *     module parameter.
++ *   o Change I/O address storage from uint32_t to unsigned long.
++ *   o Added ethtool RINGPARAM support.
++ *
++ * 5.2.22     10/15/03
+  *   o Bug fix: SERDES devices might be connected to a back-plane
+  *     switch that doesn't support auto-neg, so add the capability
+- *     to force 1000/Full.
++ *     to force 1000/Full.  Also, since forcing 1000/Full, sample
++ *     RxSynchronize bit to detect link state.
+  *   o Bug fix: Flow control settings for hi/lo watermark didn't
+  *     consider changes in the Rx FIFO size, which could occur with
+  *     Jumbo Frames or with the reduced FIFO in 82547.
+@@ -42,29 +51,18 @@
+  *   o Bug fix: hang under heavy Tx stress when running out of Tx
+  *     descriptors; wasn't clearing context descriptor when backing
+  *     out of send because of no-resource condition.
++ *   o Bug fix: check netif_running in dev->poll so we don't have to
++ *     hang in dev->close until all polls are finished.  [Robert
++ *     Ollson (robert.olsson@data.slu.se)].
++ *   o Revert TxDescriptor ring size back to 256 since change to 1024
++ *     wasn't accepted into the kernel.
+  *
+  * 5.2.16     8/8/03
+- *   o Added support for new controllers: 82545GM, 82546GB, 82541/7_B1
+- *   o Bug fix: reset h/w before first EEPROM read because we don't know
+- *     who may have been messing with the device before we got there.
+- *     [Dave Johnson (ddj -a-t- cascv.brown.edu)]
+- *   o Bug fix: read the correct work from EEPROM to detect programmed
+- *     WoL settings.
+- *   o Bug fix: TSO would hang if space left in FIFO was being miscalculated
+- *     when mss dropped without a correspoding drop in the DMA buffer size.
+- *   o ASF for Fiber nics isn't supported.
+- *   o Bug fix: Workaround added for potential hang with 82544 running in
+- *     PCI-X if send buffer terminates within an evenly-aligned dword.
+- *   o Feature: Add support for ethtool flow control setting.
+- *   o Feature: Add support for ethtool TSO setting.
+- *   o Feature: Increase default Tx Descriptor count to 1024 for >= 82544.
+- *   
+- * 5.1.13     5/28/03
+  */
+ char e1000_driver_name[] = "e1000";
+ char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
+-char e1000_driver_version[] = "5.2.20-k1";
++char e1000_driver_version[] = "5.2.26-k1";
+ char e1000_copyright[] = "Copyright (c) 1999-2003 Intel Corporation.";
+ /* e1000_pci_tbl - PCI Device ID Table
+@@ -113,12 +111,16 @@ static struct pci_device_id e1000_pci_tb
+ MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
+-/* Local Function Prototypes */
+-
+ int e1000_up(struct e1000_adapter *adapter);
+ void e1000_down(struct e1000_adapter *adapter);
+ void e1000_reset(struct e1000_adapter *adapter);
+ int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
++int e1000_setup_tx_resources(struct e1000_adapter *adapter);
++int e1000_setup_rx_resources(struct e1000_adapter *adapter);
++void e1000_free_tx_resources(struct e1000_adapter *adapter);
++void e1000_free_rx_resources(struct e1000_adapter *adapter);
++
++/* Local Function Prototypes */
+ static int e1000_init_module(void);
+ static void e1000_exit_module(void);
+@@ -127,15 +129,11 @@ static void __devexit e1000_remove(struc
+ static int e1000_sw_init(struct e1000_adapter *adapter);
+ static int e1000_open(struct net_device *netdev);
+ static int e1000_close(struct net_device *netdev);
+-static int e1000_setup_tx_resources(struct e1000_adapter *adapter);
+-static int e1000_setup_rx_resources(struct e1000_adapter *adapter);
+ static void e1000_configure_tx(struct e1000_adapter *adapter);
+ static void e1000_configure_rx(struct e1000_adapter *adapter);
+ static void e1000_setup_rctl(struct e1000_adapter *adapter);
+ static void e1000_clean_tx_ring(struct e1000_adapter *adapter);
+ static void e1000_clean_rx_ring(struct e1000_adapter *adapter);
+-static void e1000_free_tx_resources(struct e1000_adapter *adapter);
+-static void e1000_free_rx_resources(struct e1000_adapter *adapter);
+ static void e1000_set_multi(struct net_device *netdev);
+ static void e1000_update_phy_info(unsigned long data);
+ static void e1000_watchdog(unsigned long data);
+@@ -268,7 +266,7 @@ e1000_up(struct e1000_adapter *adapter)
+       e1000_configure_rx(adapter);
+       e1000_alloc_rx_buffers(adapter);
+-      if((err = request_irq(netdev->irq, &e1000_intr,
++      if((err = request_irq(adapter->pdev->irq, &e1000_intr,
+                             SA_SHIRQ | SA_SAMPLE_RANDOM,
+                             netdev->name, netdev)))
+               return err;
+@@ -285,7 +283,7 @@ e1000_down(struct e1000_adapter *adapter
+       struct net_device *netdev = adapter->netdev;
+       e1000_irq_disable(adapter);
+-      free_irq(netdev->irq, netdev);
++      free_irq(adapter->pdev->irq, netdev);
+       del_timer_sync(&adapter->tx_fifo_stall_timer);
+       del_timer_sync(&adapter->watchdog_timer);
+       del_timer_sync(&adapter->phy_info_timer);
+@@ -435,7 +433,6 @@ e1000_probe(struct pci_dev *pdev,
+       netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
+       netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
+-      netdev->irq = pdev->irq;
+       netdev->mem_start = mmio_start;
+       netdev->mem_end = mmio_start + mmio_len;
+       netdev->base_addr = adapter->hw.io_base;
+@@ -749,7 +746,7 @@ e1000_close(struct net_device *netdev)
+  * Return 0 on success, negative on failure
+  **/
+-static int
++int
+ e1000_setup_tx_resources(struct e1000_adapter *adapter)
+ {
+       struct e1000_desc_ring *txdr = &adapter->tx_ring;
+@@ -866,7 +863,7 @@ e1000_configure_tx(struct e1000_adapter 
+  * Returns 0 on success, negative on failure
+  **/
+-static int
++int
+ e1000_setup_rx_resources(struct e1000_adapter *adapter)
+ {
+       struct e1000_desc_ring *rxdr = &adapter->rx_ring;
+@@ -1005,7 +1002,7 @@ e1000_configure_rx(struct e1000_adapter 
+  * Free all transmit software resources
+  **/
+-static void
++void
+ e1000_free_tx_resources(struct e1000_adapter *adapter)
+ {
+       struct pci_dev *pdev = adapter->pdev;
+@@ -1073,7 +1070,7 @@ e1000_clean_tx_ring(struct e1000_adapter
+  * Free all receive software resources
+  **/
+-static void
++void
+ e1000_free_rx_resources(struct e1000_adapter *adapter)
+ {
+       struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+@@ -1281,41 +1278,6 @@ e1000_set_multi(struct net_device *netde
+               e1000_leave_82542_rst(adapter);
+ }
+-static void
+-e1000_tx_flush(struct e1000_adapter *adapter)
+-{
+-      uint32_t ctrl, tctl, txcw, icr;
+-
+-      e1000_irq_disable(adapter);
+-
+-      if(adapter->hw.mac_type < e1000_82543) {
+-              /* Transmit Unit Reset */
+-              tctl = E1000_READ_REG(&adapter->hw, TCTL);
+-              E1000_WRITE_REG(&adapter->hw, TCTL, tctl | E1000_TCTL_RST);
+-              E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
+-              e1000_clean_tx_ring(adapter);
+-              e1000_configure_tx(adapter);
+-      } else {
+-              txcw = E1000_READ_REG(&adapter->hw, TXCW);
+-              E1000_WRITE_REG(&adapter->hw, TXCW, txcw & ~E1000_TXCW_ANE);
+-
+-              ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+-              E1000_WRITE_REG(&adapter->hw, CTRL, ctrl | E1000_CTRL_SLU |
+-                              E1000_CTRL_ILOS);
+-
+-              mdelay(10);
+-
+-              e1000_clean_tx_irq(adapter);
+-              E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+-              E1000_WRITE_REG(&adapter->hw, TXCW, txcw);
+-
+-              /* clear the link status change interrupts this caused */
+-              icr = E1000_READ_REG(&adapter->hw, ICR);
+-      }
+-
+-      e1000_irq_enable(adapter);
+-}
+-
+ /* need to wait a few seconds after link up to get diagnostic information from the phy */
+ static void
+@@ -1379,10 +1341,17 @@ e1000_watchdog(unsigned long data)
+       struct net_device *netdev = adapter->netdev;
+       struct e1000_desc_ring *txdr = &adapter->tx_ring;
+       unsigned int i;
++      uint32_t link;
+       e1000_check_for_link(&adapter->hw);
+-      if(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU) {
++      if((adapter->hw.media_type == e1000_media_type_internal_serdes) &&
++         !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE))
++              link = !adapter->hw.serdes_link_down;
++      else
++              link = E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU;
++
++      if(link) {
+               if(!netif_carrier_ok(netdev)) {
+                       e1000_get_speed_and_duplex(&adapter->hw,
+                                                  &adapter->link_speed,
+@@ -1419,10 +1388,11 @@ e1000_watchdog(unsigned long data)
+       if(!netif_carrier_ok(netdev)) {
+               if(E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
+-                      unsigned long flags;
+-                      spin_lock_irqsave(&netdev->xmit_lock, flags);
+-                      e1000_tx_flush(adapter);
+-                      spin_unlock_irqrestore(&netdev->xmit_lock, flags);
++                      /* We've lost link, so the controller stops DMA,
++                       * but we've got queued Tx work that's never going
++                       * to get done, so reset controller to flush Tx.
++                       * (Do the reset outside of interrupt context). */
++                      schedule_work(&adapter->tx_timeout_task);
+               }
+       }
+@@ -2064,7 +2034,7 @@ e1000_irq_disable(struct e1000_adapter *
+       atomic_inc(&adapter->irq_sem);
+       E1000_WRITE_REG(&adapter->hw, IMC, ~0);
+       E1000_WRITE_FLUSH(&adapter->hw);
+-      synchronize_irq(adapter->netdev->irq);
++      synchronize_irq(adapter->pdev->irq);
+ }
+ /**
+@@ -2093,6 +2063,7 @@ e1000_intr(int irq, void *data, struct p
+ {
+       struct net_device *netdev = data;
+       struct e1000_adapter *adapter = netdev->priv;
++      struct e1000_hw *hw = &adapter->hw;
+       uint32_t icr = E1000_READ_REG(&adapter->hw, ICR);
+ #ifndef CONFIG_E1000_NAPI
+       unsigned int i;
+@@ -2102,7 +2073,7 @@ e1000_intr(int irq, void *data, struct p
+               return IRQ_NONE;  /* Not our interrupt */
+       if(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+-              adapter->hw.get_link_status = 1;
++              hw->get_link_status = 1;
+               mod_timer(&adapter->watchdog_timer, jiffies);
+       }
+@@ -2114,14 +2085,30 @@ e1000_intr(int irq, void *data, struct p
+               */
+               atomic_inc(&adapter->irq_sem);
+-              E1000_WRITE_REG(&adapter->hw, IMC, ~0);
++              E1000_WRITE_REG(hw, IMC, ~0);
+               __netif_rx_schedule(netdev);
+       }
+ #else
++        /* Writing IMC and IMS is needed for 82547.
++         Due to Hub Link bus being occupied, an interrupt 
++         de-assertion message is not able to be sent. 
++         When an interrupt assertion message is generated later,
++         two messages are re-ordered and sent out.
++         That causes APIC to think 82547 is in de-assertion
++         state, while 82547 is in assertion state, resulting 
++         in dead lock. Writing IMC forces 82547 into 
++         de-assertion state.
++        */
++      if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
++              e1000_irq_disable(adapter);
++
+       for(i = 0; i < E1000_MAX_INTR; i++)
+               if(!e1000_clean_rx_irq(adapter) &
+                  !e1000_clean_tx_irq(adapter))
+                       break;
++
++      if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
++              e1000_irq_enable(adapter);
+ #endif
+       return IRQ_HANDLED;
+@@ -2146,7 +2133,7 @@ e1000_clean(struct net_device *netdev, i
+       *budget -= work_done;
+       netdev->quota -= work_done;
+       
+-      if(work_done < work_to_do) {
++      if(work_done < work_to_do || !netif_running(netdev)) {
+               netif_rx_complete(netdev);
+               e1000_irq_enable(adapter);
+       }
+@@ -2642,13 +2629,13 @@ e1000_write_pci_cfg(struct e1000_hw *hw,
+ }
+ uint32_t
+-e1000_io_read(struct e1000_hw *hw, uint32_t port)
++e1000_io_read(struct e1000_hw *hw, unsigned long port)
+ {
+       return inl(port);
+ }
+ void
+-e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value)
++e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value)
+ {
+       outl(value, port);
+ }
+--- linux-2.6.0/drivers/net/e1000/e1000_param.c        2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/e1000/e1000_param.c 2003-12-28 23:21:01.000000000 -0800
+@@ -196,16 +196,6 @@ E1000_PARAM(InterruptThrottleRate, "Inte
+ #define AUTONEG_ADV_MASK     0x2F
+ #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
+-#define DEFAULT_TXD                  256
+-#define MAX_TXD                      256
+-#define MIN_TXD                       80
+-#define MAX_82544_TXD               4096
+-
+-#define DEFAULT_RXD                  256
+-#define MAX_RXD                      256
+-#define MIN_RXD                       80
+-#define MAX_82544_RXD               4096
+-
+ #define DEFAULT_RDTR                   0
+ #define MAX_RXDELAY               0xFFFF
+ #define MIN_RXDELAY                    0
+@@ -320,14 +310,15 @@ e1000_check_options(struct e1000_adapter
+               struct e1000_option opt = {
+                       .type = range_option,
+                       .name = "Transmit Descriptors",
+-                      .err  = "using default of " __MODULE_STRING(DEFAULT_TXD),
+-                      .def  = DEFAULT_TXD,
+-                      .arg  = { .r = { .min = MIN_TXD }}
++                      .err  = "using default of "
++                              __MODULE_STRING(E1000_DEFAULT_TXD),
++                      .def  = E1000_DEFAULT_TXD,
++                      .arg  = { .r = { .min = E1000_MIN_TXD }}
+               };
+               struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+               e1000_mac_type mac_type = adapter->hw.mac_type;
+               opt.arg.r.max = mac_type < e1000_82544 ?
+-                      MAX_TXD : MAX_82544_TXD;
++                      E1000_MAX_TXD : E1000_MAX_82544_TXD;
+               tx_ring->count = TxDescriptors[bd];
+               e1000_validate_option(&tx_ring->count, &opt);
+@@ -337,13 +328,15 @@ e1000_check_options(struct e1000_adapter
+               struct e1000_option opt = {
+                       .type = range_option,
+                       .name = "Receive Descriptors",
+-                      .err  = "using default of " __MODULE_STRING(DEFAULT_RXD),
+-                      .def  = DEFAULT_RXD,
+-                      .arg  = { .r = { .min = MIN_RXD }}
++                      .err  = "using default of "
++                              __MODULE_STRING(E1000_DEFAULT_RXD),
++                      .def  = E1000_DEFAULT_RXD,
++                      .arg  = { .r = { .min = E1000_MIN_RXD }}
+               };
+               struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+               e1000_mac_type mac_type = adapter->hw.mac_type;
+-              opt.arg.r.max = mac_type < e1000_82544 ? MAX_RXD : MAX_82544_RXD;
++              opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD :
++                      E1000_MAX_82544_RXD;
+               rx_ring->count = RxDescriptors[bd];
+               e1000_validate_option(&rx_ring->count, &opt);
+@@ -446,13 +439,19 @@ e1000_check_options(struct e1000_adapter
+               };
+               adapter->itr = InterruptThrottleRate[bd];
+-              if(adapter->itr == 0) {
+-                      printk(KERN_INFO "%s turned off\n", opt.name);
+-              } else if(adapter->itr == 1 || adapter->itr == -1) {
+-                      /* Dynamic mode */
++              switch(adapter->itr) {
++              case -1:
+                       adapter->itr = 1;
+-              } else {
++                      break;
++              case 0:
++                      printk(KERN_INFO "%s turned off\n", opt.name);
++                      break;
++              case 1:
++                      printk(KERN_INFO "%s set to dynamic mode\n", opt.name);
++                      break;
++              default:
+                       e1000_validate_option(&adapter->itr, &opt);
++                      break;
+               }
+       }
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/net/e100.c      2003-12-28 23:21:01.000000000 -0800
+@@ -0,0 +1,2308 @@
++/*******************************************************************************
++
++  
++  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
++  
++  This program is free software; you can redistribute it and/or modify it 
++  under the terms of the GNU General Public License as published by the Free 
++  Software Foundation; either version 2 of the License, or (at your option) 
++  any later version.
++  
++  This program is distributed in the hope that it will be useful, but WITHOUT 
++  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
++  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
++  more details.
++  
++  You should have received a copy of the GNU General Public License along with
++  this program; if not, write to the Free Software Foundation, Inc., 59 
++  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++  
++  The full GNU General Public License is included in this distribution in the
++  file called LICENSE.
++  
++  Contact Information:
++  Linux NICS <linux.nics@intel.com>
++  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
++
++*******************************************************************************/
++
++/*
++ *    e100.c: Intel(R) PRO/100 ethernet driver 
++ *
++ *    (Re)written 2003 by scott.feldman@intel.com.  Based loosely on
++ *    original e100 driver, but better described as a munging of
++ *    e100, e1000, eepro100, tg3, 8139cp, and other drivers.
++ *
++ *    References:
++ *            Intel 8255x 10/100 Mbps Ethernet Controller Family,
++ *            Open Source Software Developers Manual,
++ *            http://sourceforge.net/projects/e1000
++ *
++ *
++ *                          Theory of Operation
++ *
++ *    I.   General
++ *
++ *    The driver supports Intel(R) 10/100 Mbps PCI Fast Ethernet
++ *    controller family, which includes the 82557, 82558, 82559, 82550,
++ *    82551, and 82562 devices.  82558 and greater controllers
++ *    integrate the Intel 82555 PHY.  The controllers are used in
++ *    server and client network interface cards, as well as in
++ *    LAN-On-Motherboard (LOM), CardBus, MiniPCI, and ICHx
++ *    configurations.  8255x supports a 32-bit linear addressing
++ *    mode and operates at 33Mhz PCI clock rate.
++ *
++ *    II.  Driver Operation
++ *
++ *    Memory-mapped mode is used exclusively to access the device's
++ *    shared-memory structure, the Control/Status Registers (CSR). All
++ *    setup, configuration, and control of the device, including queuing
++ *    of Tx, Rx, and configuration commands is through the CSR.
++ *    cmd_lock serializes accesses to the CSR command register.  cb_lock
++ *    protects the shared Command Block List (CBL).
++ *
++ *    8255x is highly MII-compliant and all access to the PHY go
++ *    through the Management Data Interface (MDI).  Consequently, the
++ *    driver leverages the mii.c library shared with other MII-compliant
++ *    devices.
++ *    
++ *    Big- and Little-Endian byte order as well as 32- and 64-bit 
++ *    archs are supported.  Weak-ordered memory and non-cache-coherent
++ *    archs are supported.
++ *    
++ *    III. Transmit
++ *
++ *    A Tx skb is mapped and hangs off of a TCB.  TCBs are linked
++ *    together in a fixed-size ring (CBL) thus forming the flexible mode
++ *    memory structure.  A TCB marked with the suspend-bit indicates
++ *    the end of the ring.  The last TCB processed suspends the
++ *    controller, and the controller can be restarted by issue a CU
++ *    resume command to continue from the suspend point, or a CU start
++ *    command to start at a given position in the ring.
++ *
++ *    Non-Tx commands (config, multicast setup, etc) are linked
++ *    into the CBL ring along with Tx commands.  The common structure
++ *    used for both Tx and non-Tx commands is the Command Block (CB).
++ *    
++ *    cb_to_use is the next CB to use for queuing a command; cb_to_clean
++ *    is the next CB to check for completion; cb_to_send is the first
++ *    CB to start on in case of a previous failure to resume.  CB clean
++ *    up happens in interrupt context in response to a CU interrupt, or
++ *    in dev->poll in the case where NAPI is enabled.  cbs_avail keeps
++ *    track of number of free CB resources available.
++ *
++ *    Hardware padding of short packets to minimum packet size is
++ *    enabled.  82557 pads with 7Eh, while the later controllers pad
++ *    with 00h.
++ *
++ *    IV.  Recieve
++ *
++ *    The Receive Frame Area (RFA) comprises a ring of Receive Frame
++ *    Descriptors (RFD) + data buffer, thus forming the simplified mode
++ *    memory structure.  Rx skbs are allocated to contain both the RFD
++ *    and the data buffer, but the RFD is pulled off before the skb is
++ *    indicated.  The data buffer is aligned such that encapsulated 
++ *    protocol headers are u32-aligned.  Since the RFD is part of the
++ *    mapped shared memory, and completion status is contained within
++ *    the RFD, the RFD must be dma_sync'ed to maintain a consistent
++ *    view from software and hardware.
++ *
++ *    Under typical operation, the  receive unit (RU) is start once,
++ *    and the controller happily fills RFDs as frames arrive.  If 
++ *    replacement RFDs cannot be allocated, or the RU goes non-active,
++ *    the RU must be restarted.  Frame arrival generates an interrupt,
++ *    and Rx indication and re-allocation happen in the same context,
++ *    therefore no locking is required.  If NAPI is enabled, this work
++ *    happens in dev->poll.  A software-generated interrupt is gen-
++ *    erated from the watchdog to recover from a failed allocation
++ *    senario where all Rx resources have been indicated and none re-
++ *    placed.
++ *
++ *    V.   Miscellaneous
++ *
++ *    VLAN offloading of tagging, stripping and filtering is not
++ *    supported, but driver will accommodate the extra 4-byte VLAN tag
++ *    for processing by upper layers.  Tx/Rx Checksum offloading is not
++ *    supported.  Tx Scatter/Gather is not supported.  Jumbo Frames is
++ *    not supported (hardware limitation).
++ *
++ *    NAPI support is enabled with CONFIG_E100_NAPI.
++ *
++ *    MagicPacket(tm) WoL support is enabled/disabled via ethtool.
++ *
++ *    Thanks to JC (jchapman@katalix.com) for helping with 
++ *    testing/troubleshooting the development driver.
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/pci.h>
++#include <linux/list.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/mii.h>
++#include <linux/if_vlan.h>
++#include <linux/skbuff.h>
++#include <linux/ethtool.h>
++#include <linux/string.h>
++#include <asm/unaligned.h>
++
++
++#define DRV_NAME              "e100"
++#define DRV_VERSION           "3.0.11_dev"
++#define DRV_DESCRIPTION               "Intel(R) PRO/100 Network Driver"
++#define DRV_COPYRIGHT         "Copyright(c) 1999-2003 Intel Corporation"
++#define PFX                   DRV_NAME ": "
++
++#define E100_WATCHDOG_PERIOD  2 * HZ
++#define E100_NAPI_WEIGHT      16
++
++MODULE_DESCRIPTION(DRV_DESCRIPTION);
++MODULE_AUTHOR(DRV_COPYRIGHT);
++MODULE_LICENSE("GPL");
++
++static int debug = 3;
++module_param(debug, int, 0);
++MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
++#define DPRINTK(nlevel, klevel, fmt, args...) \
++      (void)((NETIF_MSG_##nlevel & nic->msg_enable) && \
++      printk(KERN_##klevel PFX "%s: %s: " fmt, nic->netdev->name, \
++              __FUNCTION__ , ## args))
++
++#define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\
++      PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \
++      PCI_CLASS_NETWORK_ETHERNET << 8, 0xFFFF00, ich }
++static struct pci_device_id e100_id_table[] = {
++      INTEL_8255X_ETHERNET_DEVICE(0x1029, 0),
++      INTEL_8255X_ETHERNET_DEVICE(0x1030, 0),
++      INTEL_8255X_ETHERNET_DEVICE(0x1031, 3),
++      INTEL_8255X_ETHERNET_DEVICE(0x1032, 3),
++      INTEL_8255X_ETHERNET_DEVICE(0x1033, 3),
++      INTEL_8255X_ETHERNET_DEVICE(0x1034, 3),
++      INTEL_8255X_ETHERNET_DEVICE(0x1038, 3),
++      INTEL_8255X_ETHERNET_DEVICE(0x1039, 4),
++      INTEL_8255X_ETHERNET_DEVICE(0x103A, 4),
++      INTEL_8255X_ETHERNET_DEVICE(0x103B, 4),
++      INTEL_8255X_ETHERNET_DEVICE(0x103C, 4),
++      INTEL_8255X_ETHERNET_DEVICE(0x103D, 4),
++      INTEL_8255X_ETHERNET_DEVICE(0x103E, 4),
++      INTEL_8255X_ETHERNET_DEVICE(0x1050, 5),
++      INTEL_8255X_ETHERNET_DEVICE(0x1051, 5),
++      INTEL_8255X_ETHERNET_DEVICE(0x1052, 5),
++      INTEL_8255X_ETHERNET_DEVICE(0x1053, 5),
++      INTEL_8255X_ETHERNET_DEVICE(0x1054, 5),
++      INTEL_8255X_ETHERNET_DEVICE(0x1055, 5),
++      INTEL_8255X_ETHERNET_DEVICE(0x1064, 6),
++      INTEL_8255X_ETHERNET_DEVICE(0x1065, 6),
++      INTEL_8255X_ETHERNET_DEVICE(0x1066, 6),
++      INTEL_8255X_ETHERNET_DEVICE(0x1067, 6),
++      INTEL_8255X_ETHERNET_DEVICE(0x1068, 6),
++      INTEL_8255X_ETHERNET_DEVICE(0x1069, 6),
++      INTEL_8255X_ETHERNET_DEVICE(0x106A, 6),
++      INTEL_8255X_ETHERNET_DEVICE(0x106B, 6),
++      INTEL_8255X_ETHERNET_DEVICE(0x1059, 0),
++      INTEL_8255X_ETHERNET_DEVICE(0x1209, 0),
++      INTEL_8255X_ETHERNET_DEVICE(0x1229, 0),
++      INTEL_8255X_ETHERNET_DEVICE(0x2449, 2),
++      INTEL_8255X_ETHERNET_DEVICE(0x2459, 2),
++      INTEL_8255X_ETHERNET_DEVICE(0x245D, 2),
++      { 0, }
++};
++MODULE_DEVICE_TABLE(pci, e100_id_table);
++
++enum mac {
++      mac_82557_D100_A  = 0,
++      mac_82557_D100_B  = 1,
++      mac_82557_D100_C  = 2,
++      mac_82558_D101_A4 = 4,
++      mac_82558_D101_B0 = 5,
++      mac_82559_D101M   = 8,
++      mac_82559_D101S   = 9,
++      mac_82550_D102    = 12,
++      mac_82550_D102_C  = 13,
++      mac_82551_E       = 14,
++      mac_82551_F       = 15,
++      mac_82551_10      = 16,
++      mac_unknown       = 0xFF,
++};
++
++enum phy {
++      phy_100a     = 0x000003E0,
++      phy_100c     = 0x035002A8, 
++      phy_82555_tx = 0x015002A8,
++      phy_nsc_tx   = 0x5C002000, 
++      phy_82562_et = 0x033002A8,
++      phy_82562_em = 0x032002A8,
++      phy_82562_eh = 0x017002A8,
++      phy_unknown  = 0xFFFFFFFF,
++};
++
++/* CSR (Control/Status Registers) */
++struct csr {
++      struct {
++              u8 status;
++              u8 stat_ack;
++              u8 cmd_lo;
++              u8 cmd_hi;
++              u32 gen_ptr;
++      } scb;
++      u32 port;
++      u16 flash_ctrl;
++      u8 eeprom_ctrl_lo;
++      u8 eeprom_ctrl_hi;
++      u32 mdi_ctrl;
++      u32 rx_dma_count;
++};
++
++enum scb_status {
++      rus_idle         = 0x00,
++      rus_suspended    = 0x04,
++      rus_no_resources = 0x08,
++      rus_ready        = 0x10,
++      rus_mask         = 0x3C,
++      cus_idle         = 0x00,
++      cus_suspended    = 0x40,
++      cus_active       = 0x80,
++              cus_mask         = 0xC0,
++};
++
++enum scb_stat_ack {
++      stat_ack_sw_gen      = 0x04,
++      stat_ack_rnr         = 0x10,
++      stat_ack_cu_idle     = 0x20,
++      stat_ack_frame_rx    = 0x40,
++      stat_ack_cu_cmd_done = 0x80,
++      stat_ack_rx = (stat_ack_sw_gen | stat_ack_rnr | stat_ack_frame_rx),
++      stat_ack_tx = (stat_ack_cu_idle | stat_ack_cu_cmd_done),
++};
++
++enum scb_cmd_hi {
++      irq_mask_none = 0x00,
++      irq_mask_all  = 0x01,
++      irq_sw_gen    = 0x02,
++};
++
++enum scb_cmd_lo {
++      ruc_start      = 0x01,
++      ruc_load_base  = 0x06,
++      cuc_start      = 0x10,
++      cuc_resume     = 0x20,
++      cuc_dump_addr  = 0x40,
++      cuc_dump_stats = 0x50,
++      cuc_load_base  = 0x60,
++      cuc_dump_reset = 0x70,
++};
++
++enum port {
++      software_reset  = 0x0000,
++      selftest        = 0x0001,
++      selective_reset = 0x0002,
++};
++
++enum eeprom_ctrl_lo {
++      eesk = 0x01,
++      eecs = 0x02,
++      eedi = 0x04,
++      eedo = 0x08,
++};
++
++enum mdi_ctrl {
++      mdi_write = 0x04000000,
++      mdi_read  = 0x08000000,
++      mdi_ready = 0x10000000,
++};
++
++enum eeprom_op {
++      op_write = 0x05,
++      op_read  = 0x06,
++      op_ewds  = 0x10,
++      op_ewen  = 0x13,
++};
++
++enum eeprom_offsets {
++      eeprom_id         = 0x0A,
++      eeprom_config_asf = 0x0D,
++      eeprom_smbus_addr = 0x90,
++};
++
++enum eeprom_id {
++      eeprom_id_wol = 0x0020,
++};
++
++enum eeprom_config_asf {
++      eeprom_asf = 0x8000,
++      eeprom_gcl = 0x4000,
++};
++
++enum cb_status {
++      cb_complete = 0x8000,
++      cb_ok       = 0x2000,
++};
++
++enum cb_command {
++      cb_iaaddr = 0x0001,
++      cb_config = 0x0002,
++      cb_multi  = 0x0003,
++      cb_tx     = 0x0004,
++      cb_dump   = 0x0006,
++      cb_tx_sf  = 0x0008,
++      cb_cid    = 0x1f00,
++      cb_i      = 0x2000,
++      cb_s      = 0x4000,
++      cb_el     = 0x8000,
++};
++
++struct rfd {
++      u16 status;
++      u16 command;
++      u32 link;
++      u32 rbd;
++      u16 actual_size;
++      u16 size;
++};
++
++struct rx_list {
++      struct list_head list;
++      struct sk_buff *skb;
++      dma_addr_t dma_addr;
++      unsigned int length;
++};
++
++#if defined(__BIG_ENDIAN_BITFIELD)
++#define X(a,b)        b,a
++#else
++#define X(a,b)        a,b
++#endif
++struct config {
++/*0*/ u8 X(byte_count:6, pad0:2);
++/*1*/ u8 X(X(rx_fifo_limit:4, tx_fifo_limit:3), pad1:1);
++/*2*/ u8 adaptive_ifs;
++/*3*/ u8 X(X(X(X(mwi_enable:1, type_enable:1), read_align_enable:1),
++         term_write_cache_line:1), pad3:4);
++/*4*/ u8 X(rx_dma_max_count:7, pad4:1);
++/*5*/ u8 X(tx_dma_max_count:7, dma_max_count_enable:1);
++/*6*/ u8 X(X(X(X(X(X(X(late_scb_update:1, direct_rx_dma:1),
++         tno_intr:1), cna_intr:1), standard_tcb:1), standard_stat_counter:1),
++         rx_discard_overruns:1), rx_save_bad_frames:1);
++/*7*/ u8 X(X(X(X(X(rx_discard_short_frames:1, tx_underrun_retry:2),
++         pad7:2), rx_extended_rfd:1), tx_two_frames_in_fifo:1),
++         tx_dynamic_tbd:1);
++/*8*/ u8 X(X(mii_mode:1, pad8:6), csma_disabled:1);
++/*9*/ u8 X(X(X(X(X(rx_tcpudp_checksum:1, pad9:3), vlan_arp_tco:1),
++         link_status_wake:1), arp_wake:1), mcmatch_wake:1);
++/*10*/        u8 X(X(X(pad10:3, no_source_addr_insertion:1), preamble_length:2),
++         loopback:2);
++/*11*/        u8 X(linear_priority:3, pad11:5);
++/*12*/        u8 X(X(linear_priority_mode:1, pad12:3), ifs:4);
++/*13*/        u8 ip_addr_lo;
++/*14*/        u8 ip_addr_hi;
++/*15*/        u8 X(X(X(X(X(X(X(promiscuous_mode:1, broadcast_disabled:1),
++         wait_after_win:1), pad15_1:1), ignore_ul_bit:1), crc_16_bit:1),
++         pad15_2:1), crs_or_cdt:1);
++/*16*/        u8 fc_delay_lo;
++/*17*/        u8 fc_delay_hi;
++/*18*/        u8 X(X(X(X(X(rx_stripping:1, tx_padding:1), rx_crc_transfer:1),
++         rx_long_ok:1), fc_priority_threshold:3), pad18:1);
++/*19*/        u8 X(X(X(X(X(X(X(addr_wake:1, magic_packet_disable:1),
++         fc_disable:1), fc_restop:1), fc_restart:1), fc_reject:1),
++         full_duplex_force:1), full_duplex_pin:1);
++/*20*/        u8 X(X(X(pad20_1:5, fc_priority_location:1), multi_ia:1), pad20_2:1);
++/*21*/        u8 X(X(pad21_1:3, multicast_all:1), pad21_2:4);
++/*22*/        u8 X(X(rx_d102_mode:1, rx_vlan_drop:1), pad22:6);
++      u8 pad_d102[9];
++};
++
++#define E100_MAX_MULTICAST_ADDRS      64
++struct multi {
++      u16 count;
++      u8 addr[E100_MAX_MULTICAST_ADDRS * ETH_ALEN + 2/*pad*/];
++};
++
++/* Important: keep total struct u32-aligned */
++struct cb {
++      u16 status;
++      u16 command;
++      u32 link;
++      union {
++              u8 iaaddr[ETH_ALEN];
++              struct config config;
++              struct multi multi;
++              struct {
++                      u32 tbd_array;
++                      u16 tcb_byte_count;
++                      u8 threshold;
++                      u8 tbd_count;
++                      struct {
++                              u32 buf_addr;
++                              u16 size;
++                              u16 eol;
++                      } tbd;
++              } tcb;
++              u32 dump_buffer_addr;
++      } u;
++      struct cb *next, *prev;
++      dma_addr_t dma_addr;
++      struct sk_buff *skb;
++};
++
++enum loopback {
++      lb_none = 0, lb_mac = 1, lb_phy = 3,
++};
++
++struct stats {
++      u32 tx_good_frames, tx_max_collisions, tx_late_collisions,
++              tx_underruns, tx_lost_crs, tx_deferred, tx_single_collisions,
++              tx_multiple_collisions, tx_total_collisions;
++      u32 rx_good_frames, rx_crc_errors, rx_alignment_errors,
++              rx_resource_errors, rx_overrun_errors, rx_cdt_errors,
++              rx_short_frame_errors;
++      u32 fc_xmt_pause, fc_rcv_pause, fc_rcv_unsupported;
++      u16 xmt_tco_frames, rcv_tco_frames;
++      u32 complete;
++};
++
++struct mem {
++      struct {
++              u32 signature;
++              u32 result;
++      } selftest;
++      struct stats stats;
++      u8 dump_buf[596];
++};
++
++struct param_range {
++      u32 min;
++      u32 max;
++      u32 count;
++};
++
++struct params {
++      struct param_range rfds;
++      struct param_range cbs;
++};
++
++struct nic {
++      /* Begin: frequently used values: keep adjacent for cache effect */
++      u32 msg_enable                          ____cacheline_aligned;
++      struct net_device *netdev;
++      struct pci_dev *pdev;
++      
++      struct list_head rx_list_head           ____cacheline_aligned;
++      struct rx_list *rx_list;
++      struct rfd blank_rfd;
++      
++      spinlock_t cb_lock                      ____cacheline_aligned;
++      spinlock_t cmd_lock;
++      struct csr *csr;
++      enum scb_cmd_lo cuc_cmd;
++      unsigned int cbs_avail;
++      struct cb *cbs;
++      struct cb *cb_to_use;
++      struct cb *cb_to_send;
++      struct cb *cb_to_clean;
++      u16 tx_command;
++      /* End: frequently used values: keep adjacent for cache effect */
++
++      enum {
++              ich           = (1 << 0),
++              promiscuous   = (1 << 1),
++              multicast_all = (1 << 2),
++              wol_magic     = (1 << 3),
++      } flags                                 ____cacheline_aligned;
++      
++      enum mac mac;
++      enum phy phy;
++      struct params params;
++      struct net_device_stats net_stats;
++      struct timer_list watchdog;
++      struct timer_list blink_timer;
++      struct mii_if_info mii;
++      enum loopback loopback;
++
++      struct mem *mem;
++      dma_addr_t dma_addr;
++
++      dma_addr_t cbs_dma_addr;
++      u8 adaptive_ifs;
++      u8 tx_threshold;
++      u32 tx_frames;
++      u32 tx_collisions;
++      u32 tx_deferred;
++      u32 tx_single_collisions;
++      u32 tx_multiple_collisions;
++      u32 tx_fc_pause;
++      u32 tx_tco_frames;
++
++      u32 rx_fc_pause;
++      u32 rx_fc_unsupported;
++      u32 rx_tco_frames;
++      
++      u8 rev_id;
++      u16 leds;
++      u16 eeprom_wc;
++      u16 eeprom[256];
++      u32 pm_state[16];
++};
++
++static void e100_get_defaults(struct nic *nic)
++{
++      struct param_range rfds = { .min = 64, .max = 256, .count = 64 };
++      struct param_range cbs  = { .min = 64, .max = 256, .count = 64 };
++
++      pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
++      /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
++      nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->rev_id;
++      if(nic->mac == mac_unknown)
++              nic->mac = mac_82557_D100_A;
++
++      nic->params.rfds = rfds; 
++      nic->params.cbs = cbs; 
++      
++      /* Quadwords to DMA into FIFO before starting frame transmit */
++      nic->tx_threshold = 0xE0;
++
++      nic->tx_command = cpu_to_le16(cb_tx | cb_i | cb_tx_sf |
++              ((nic->mac >= mac_82558_D101_A4) ? cb_cid : 0));
++
++      /* Template for a freshly allocated RFD */
++      nic->blank_rfd.status = 0;
++      nic->blank_rfd.command = cpu_to_le16(cb_el);
++      nic->blank_rfd.link = 0;
++      nic->blank_rfd.rbd = 0xFFFFFFFF;
++      nic->blank_rfd.actual_size = 0;
++      nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
++}
++
++static inline void e100_write_flush(struct nic *nic)
++{
++      /* Flush previous PCI writes through intermediate bridges
++       * by doing a benign read */
++      (void)readb(&nic->csr->scb.status);
++}
++
++static inline void e100_enable_irq(struct nic *nic)
++{
++      writeb(irq_mask_none, &nic->csr->scb.cmd_hi);
++      e100_write_flush(nic);
++}
++
++static inline void e100_disable_irq(struct nic *nic)
++{
++      writeb(irq_mask_all, &nic->csr->scb.cmd_hi);
++      e100_write_flush(nic);
++}
++
++static void e100_hw_reset(struct nic *nic)
++{
++      /* Put CU and RU into idle with a selective reset to get
++       * device off of PCI bus */
++      writel(selective_reset, &nic->csr->port);
++      e100_write_flush(nic); udelay(20);
++      
++      /* Now fully reset device */
++      writel(software_reset, &nic->csr->port);
++      e100_write_flush(nic); udelay(20);
++      
++      /* TCO workaround - 82559 and greater */
++      if(nic->mac >= mac_82559_D101M) {
++              /* Issue a redundant CU load base without setting 
++               * general pointer, and without waiting for scb to
++               * clear.  This gets us into post-driver.  Finally,
++               * wait 20 msec for reset to take effect. */
++              writeb(cuc_load_base, &nic->csr->scb.cmd_lo);
++              mdelay(20);
++      }
++
++      /* Mask off our interrupt line - it's unmasked after reset */
++      e100_disable_irq(nic);
++}
++
++static int e100_self_test(struct nic *nic)
++{
++      u32 dma_addr = nic->dma_addr + offsetof(struct mem, selftest);
++
++      /* Passing the self-test is a pretty good indication
++       * that the device can DMA to/from host memory */
++
++      nic->mem->selftest.signature = 0;
++      nic->mem->selftest.result = 0xFFFFFFFF;
++
++      writel(selftest | dma_addr, &nic->csr->port);
++      e100_write_flush(nic);
++      /* Wait 10 msec for self-test to complete */
++      set_current_state(TASK_UNINTERRUPTIBLE);
++      schedule_timeout(HZ / 100 + 1);
++
++      /* Interrupts are enabled after self-test */
++      e100_disable_irq(nic);
++
++      /* Check results of self-test */
++      if(nic->mem->selftest.result != 0) {
++              DPRINTK(HW, ERR, "Self-test failed: result=0x%08X\n",
++                      nic->mem->selftest.result);
++              return -ETIMEDOUT;
++      }
++      if(nic->mem->selftest.signature == 0) {
++              DPRINTK(HW, ERR, "Self-test failed: timed out\n");
++              return -ETIMEDOUT;
++      }
++
++      return 0;
++}
++
++static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, u16 data)
++{
++      u32 cmd_addr_data[3];
++      u8 ctrl;
++      int i, j;
++
++      /* Three cmds: write/erase enable, write data, write/erase disable */
++      cmd_addr_data[0] = op_ewen << (addr_len - 2);
++      cmd_addr_data[1] = (((op_write << addr_len) | addr) << 16) | data;
++      cmd_addr_data[2] = op_ewds << (addr_len - 2);
++
++      /* Bit-bang cmds to write word to eeprom */
++      for(j = 0; j < 3; j++) {
++
++              /* Chip select */
++              writeb(eecs | eesk, &nic->csr->eeprom_ctrl_lo);
++              e100_write_flush(nic); udelay(4);
++
++              for(i = 31; i >= 0; i--) {
++                      ctrl = (cmd_addr_data[j] & (1 << i)) ?
++                              eecs | eedi : eecs;
++                      writeb(ctrl, &nic->csr->eeprom_ctrl_lo);
++                      e100_write_flush(nic); udelay(4);
++                      writeb(ctrl | eesk, &nic->csr->eeprom_ctrl_lo);
++                      e100_write_flush(nic); udelay(4);
++              }
++              /* Wait 10 msec for cmd to complete */
++              set_current_state(TASK_UNINTERRUPTIBLE);
++              schedule_timeout(HZ / 100 + 1);
++
++              /* Chip deselect */
++              writeb(0, &nic->csr->eeprom_ctrl_lo);
++              e100_write_flush(nic); udelay(4);
++      }
++
++};
++
++/* General technique stolen from the eepro100 driver - very clever */
++static u16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr)
++{
++      u32 cmd_addr_data;
++      u16 data = 0;
++      u8 ctrl;
++      int i;
++
++      cmd_addr_data = ((op_read << *addr_len) | addr) << 16;
++
++      /* Chip select */
++      writeb(eecs | eesk, &nic->csr->eeprom_ctrl_lo);
++      e100_write_flush(nic); udelay(4);
++
++      /* Bit-bang to read word from eeprom */
++      for(i = 31; i >= 0; i--) {
++              ctrl = (cmd_addr_data & (1 << i)) ? eecs | eedi : eecs;
++              writeb(ctrl, &nic->csr->eeprom_ctrl_lo);
++              e100_write_flush(nic); udelay(4);
++              writeb(ctrl | eesk, &nic->csr->eeprom_ctrl_lo);
++              e100_write_flush(nic); udelay(4);
++              /* Eeprom drives a dummy zero to EEDO after receiving
++               * complete address.  Use this to adjust addr_len. */
++              ctrl = readb(&nic->csr->eeprom_ctrl_lo);
++              if(!(ctrl & eedo) && i > 16) {
++                      *addr_len -= (i - 16);
++                      i = 17;
++              }
++              data = (data << 1) | (ctrl & eedo ? 1 : 0);
++      }
++
++      /* Chip deselect */
++      writeb(0, &nic->csr->eeprom_ctrl_lo);
++      e100_write_flush(nic); udelay(4);
++
++      return data;
++};
++
++/* Load entire EEPROM image into driver cache and validate checksum */
++static int e100_eeprom_load(struct nic *nic)
++{
++      u16 addr, addr_len = 8, checksum = 0;
++
++      /* Try reading with an 8-bit addr len to discover actual addr len */
++      e100_eeprom_read(nic, &addr_len, 0);
++      nic->eeprom_wc = 1 << addr_len;
++      
++      for(addr = 0; addr < nic->eeprom_wc; addr++) {
++              nic->eeprom[addr] = e100_eeprom_read(nic, &addr_len, addr);
++              if(addr < nic->eeprom_wc - 1)
++                      checksum += nic->eeprom[addr];
++      }
++
++      /* The checksum, stored in the last word, is calculated such that
++       * the sum of words should be 0xBABA */
++      checksum = 0xBABA - checksum;
++      if(checksum != nic->eeprom[nic->eeprom_wc - 1]) {
++              DPRINTK(PROBE, ERR, "EEPROM corrupted\n");
++              return -EAGAIN;
++      }
++      
++      return 0;
++}
++
++/* Save (portion of) driver EEPROM cache to device and update checksum */
++static int e100_eeprom_save(struct nic *nic, u16 start, u16 count)
++{
++      u16 addr, addr_len = 8, checksum = 0;
++
++      /* Try reading with an 8-bit addr len to discover actual addr len */
++      e100_eeprom_read(nic, &addr_len, 0);
++      nic->eeprom_wc = 1 << addr_len;
++      
++      if(start + count >= nic->eeprom_wc)
++              return -EINVAL;
++      
++      for(addr = start; addr < start + count; addr++)
++              e100_eeprom_write(nic, addr_len, addr, nic->eeprom[addr]);
++
++      /* The checksum, stored in the last word, is calculated such that
++       * the sum of words should be 0xBABA */
++      for(addr = 0; addr < nic->eeprom_wc - 1; addr++)
++              checksum += nic->eeprom[addr];
++      nic->eeprom[nic->eeprom_wc - 1] = 0xBABA - checksum;
++      e100_eeprom_write(nic, addr_len, nic->eeprom_wc - 1, 0xBABA - checksum);
++
++      return 0;
++}
++
++#define E100_WAIT_SCB_TIMEOUT 40
++static inline int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr)
++{
++      unsigned long flags;
++      unsigned int i;
++      int err = 0;
++
++      spin_lock_irqsave(&nic->cmd_lock, flags);
++
++      /* Previous command is accepted when SCB clears */
++      for(i = 0; i < E100_WAIT_SCB_TIMEOUT; i++) {
++              if(likely(!readb(&nic->csr->scb.cmd_lo)))
++                      break;
++              cpu_relax();
++              if(unlikely(i > (E100_WAIT_SCB_TIMEOUT >> 1)))
++                      udelay(5);
++      }
++      if(unlikely(i == E100_WAIT_SCB_TIMEOUT)) {
++              err = -EAGAIN;
++              goto err_unlock;
++      }
++
++      if(unlikely(cmd != cuc_resume))
++              writel(dma_addr, &nic->csr->scb.gen_ptr);
++      writeb(cmd, &nic->csr->scb.cmd_lo);
++
++err_unlock:
++      spin_unlock_irqrestore(&nic->cmd_lock, flags);
++
++      return err;
++}
++
++static inline int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
++      void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *))
++{
++      struct cb *cb;
++      unsigned long flags;
++      int err = 0;
++
++      spin_lock_irqsave(&nic->cb_lock, flags);
++
++      if(unlikely(!nic->cbs_avail)) {
++              err = -ENOMEM;
++              goto err_unlock;
++      }
++
++      cb = nic->cb_to_use;
++      nic->cb_to_use = cb->next;
++      nic->cbs_avail--;
++      cb->skb = skb;
++
++      if(unlikely(!nic->cbs_avail))
++              err = -ENOSPC;
++
++      cb_prepare(nic, cb, skb);
++      
++      /* Order is important otherwise we'll be in a race with h/w:
++       * set S-bit in current first, then clear S-bit in previous. */
++      cb->command |= cpu_to_le16(cb_s);
++      cb->prev->command &= cpu_to_le16(~cb_s);
++
++      while(nic->cb_to_send != nic->cb_to_use) {
++              if(unlikely((err = e100_exec_cmd(nic, nic->cuc_cmd,
++                      nic->cb_to_send->dma_addr)))) {
++                      /* Ok, here's where things get sticky.  It's
++                       * possible that we can't schedule the command
++                       * because the controller is too busy, so
++                       * let's just queue the command and try again
++                       * when another command is scheduled. */
++                      break;
++              } else {
++                      nic->cuc_cmd = cuc_resume;
++                      nic->cb_to_send = nic->cb_to_send->next;
++              }
++      }
++
++err_unlock:
++      spin_unlock_irqrestore(&nic->cb_lock, flags);
++
++      return err;
++}
++
++static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
++{
++      u32 data_out = 0;
++      unsigned int i;
++
++      writel((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl);
++
++      for(i = 0; i < 100; i++) {
++              udelay(20);
++              if((data_out = readl(&nic->csr->mdi_ctrl)) & mdi_ready)
++                      break;
++      }
++      
++      DPRINTK(HW, DEBUG,
++              "%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n",
++              dir == mdi_read ? "READ" : "WRITE", addr, reg, data, data_out);
++      return (u16)data_out;
++}
++
++static int mdio_read(struct net_device *netdev, int addr, int reg)
++{
++      return mdio_ctrl(netdev->priv, addr, mdi_read, reg, 0);
++}
++
++static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
++{
++      mdio_ctrl(netdev->priv, addr, mdi_write, reg, data);
++}
++
++static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
++{
++      struct config *config = &cb->u.config;
++      u8 *c = (u8 *)config;
++
++      cb->command = cpu_to_le16(cb_config);
++                              
++      memset(config, 0, sizeof(struct config));
++      
++      config->byte_count = 0x16;              /* bytes in this struct */
++      config->rx_fifo_limit = 0x8;            /* bytes in FIFO before DMA */
++      config->direct_rx_dma = 0x1;            /* reserved */
++      config->standard_tcb = 0x1;             /* 1=standard, 0=extended */
++      config->standard_stat_counter = 0x1;    /* 1=standard, 0=extended */
++      config->rx_discard_short_frames = 0x1;  /* 1=discard, 0=pass */
++      config->tx_underrun_retry = 0x3;        /* # of underrun retries */
++      config->mii_mode = 0x1;                 /* 1=MII mode, 0=503 mode */
++      config->pad10 = 0x6;
++      config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */
++      config->preamble_length = 0x2;          /* 0=1, 1=3, 2=7, 3=15 bytes */
++      config->ifs = 0x6;                      /* x16 = inter frame spacing */
++      config->ip_addr_hi = 0xF2;              /* ARP IP filter - not used */
++      config->pad15_1 = 0x1;
++      config->pad15_2 = 0x1;
++      config->crs_or_cdt = 0x0;               /* 0=CRS only, 1=CRS or CDT */
++      config->fc_delay_hi = 0x40;             /* time delay for fc frame */
++      config->tx_padding = 0x1;               /* 1=pad short frames */
++      config->fc_priority_threshold = 0x7;    /* 7=priority fc disabled */
++      config->pad18 = 0x1;
++      config->full_duplex_pin = 0x1;          /* 1=examine FDX# pin */
++      config->pad20_1 = 0x1F;
++      config->fc_priority_location = 0x1;     /* 1=byte#31, 0=byte#19 */
++      config->pad21_1 = 0x5;
++
++      config->adaptive_ifs = nic->adaptive_ifs;
++      config->loopback = nic->loopback;
++
++      if(nic->mii.force_media && nic->mii.full_duplex)
++              config->full_duplex_force = 0x1;        /* 1=force, 0=auto */
++              
++      if(nic->flags & promiscuous || nic->loopback) {
++              config->rx_save_bad_frames = 0x1;       /* 1=save, 0=discard */
++              config->rx_discard_short_frames = 0x0;  /* 1=discard, 0=save */
++              config->promiscuous_mode = 0x1;         /* 1=on, 0=off */
++      }
++
++      if(nic->flags & multicast_all)
++              config->multicast_all = 0x1;            /* 1=accept, 0=no */
++      
++      if(!(nic->flags & wol_magic))
++              config->magic_packet_disable = 0x1;     /* 1=off, 0=on */
++
++      if(nic->mac >= mac_82558_D101_A4) {
++              config->fc_disable = 0x1;       /* 1=Tx fc off, 0=Tx fc on */
++              config->mwi_enable = 0x1;       /* 1=enable, 0=disable */
++              config->standard_tcb = 0x0;     /* 1=standard, 0=extended */
++              config->rx_long_ok = 0x1;       /* 1=VLANs ok, 0=standard */
++              if(nic->mac >= mac_82559_D101M)
++                      config->tno_intr = 0x1;         /* TCO stats enable */
++              else
++                      config->standard_stat_counter = 0x0;
++      }
++      
++      DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
++              c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
++      DPRINTK(HW, DEBUG, "[08-15]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
++              c[8], c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
++      DPRINTK(HW, DEBUG, "[16-23]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
++              c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
++}
++
++static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
++      struct sk_buff *skb)
++{
++      cb->command = cpu_to_le16(cb_iaaddr);
++      memcpy(cb->u.iaaddr, nic->netdev->dev_addr, ETH_ALEN);
++}
++
++static void e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb)
++{
++      cb->command = cpu_to_le16(cb_dump);
++      cb->u.dump_buffer_addr = cpu_to_le32(nic->dma_addr +
++              offsetof(struct mem, dump_buf));
++}
++
++#define NCONFIG_AUTO_SWITCH   0x0080
++#define MII_NSC_CONG          MII_RESV1
++#define NSC_CONG_ENABLE               0x0100
++#define NSC_CONG_TXREADY      0x0400
++#define ADVERTISE_FC_SUPPORTED        0x0400
++static int e100_phy_init(struct nic *nic)
++{
++      struct net_device *netdev = nic->netdev;
++      u32 addr;
++      u16 bmcr, stat, id_lo, id_hi, cong;
++
++      nic->mii.phy_id = 0;
++      nic->mii.advertising = 0;
++      nic->mii.phy_id_mask = 0x1F;
++      nic->mii.reg_num_mask = 0x1F;
++      nic->mii.dev = netdev;
++      nic->mii.full_duplex = 0;
++      nic->mii.force_media = 0;
++      nic->mii.mdio_read = mdio_read;
++      nic->mii.mdio_write = mdio_write;
++      
++      /* Discover phy addr by searching addrs in order {1,0,2,..., 31} */
++      for(addr = 0; addr < 32; addr++) {
++              nic->mii.phy_id = (addr == 0) ? 1 : (addr == 1) ? 0 : addr;
++              bmcr = mdio_read(netdev, nic->mii.phy_id, MII_BMCR);
++              stat = mdio_read(netdev, nic->mii.phy_id, MII_BMSR);
++              stat = mdio_read(netdev, nic->mii.phy_id, MII_BMSR);
++              if(!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0))))
++                      break;
++      }
++      DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
++      if(addr == 32)
++              return -EAGAIN;
++      
++      /* Selected the phy and isolate the rest */
++      for(addr = 0; addr < 32; addr++) {
++              if(addr != nic->mii.phy_id) {
++                      mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
++              } else {
++                      bmcr = mdio_read(netdev, addr, MII_BMCR);
++                      mdio_write(netdev, addr, MII_BMCR,
++                              bmcr & ~BMCR_ISOLATE);
++              }
++      }
++      
++      /* Get phy ID */
++      id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1);
++      id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2);
++      nic->phy = (u32)id_hi << 16 | (u32)id_lo;
++      DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy);
++              
++      /* Handle National tx phy */
++      if(nic->phy == phy_nsc_tx) {
++              /* Disable congestion control */
++              cong = mdio_read(netdev, nic->mii.phy_id, MII_NSC_CONG);
++              cong |= NSC_CONG_TXREADY;
++              cong &= ~NSC_CONG_ENABLE;
++              mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong);
++      }
++      
++      /* enable MDI/MDI-X auto-switching */
++      if(nic->mac >= mac_82550_D102)
++              mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG,
++                      NCONFIG_AUTO_SWITCH);
++
++      return 0;
++}
++
++static int e100_hw_init(struct nic *nic)
++{
++      int err;
++      
++      e100_hw_reset(nic);
++
++      DPRINTK(HW, ERR, "e100_hw_init\n");
++      if(!in_interrupt() && (err = e100_self_test(nic)))
++              return err;
++
++      if((err = e100_phy_init(nic)))
++              return err;
++      if((err = e100_exec_cmd(nic, cuc_load_base, 0)))
++              return err;
++      if((err = e100_exec_cmd(nic, ruc_load_base, 0)))
++              return err;
++      if((err = e100_exec_cb(nic, NULL, e100_configure)))
++              return err;
++      if((err = e100_exec_cb(nic, NULL, e100_setup_iaaddr)))
++              return err;
++      if((err = e100_exec_cmd(nic, cuc_dump_addr, 
++              nic->dma_addr + offsetof(struct mem, stats))))
++              return err;
++      if((err = e100_exec_cmd(nic, cuc_dump_reset, 0)))
++              return err;
++
++      e100_disable_irq(nic);
++
++      return 0;
++}
++
++static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb)
++{
++      struct net_device *netdev = nic->netdev;
++      struct dev_mc_list *list = netdev->mc_list;
++      u16 i, count = min(netdev->mc_count, E100_MAX_MULTICAST_ADDRS);
++
++      cb->command = cpu_to_le16(cb_multi);
++      cb->u.multi.count = cpu_to_le16(count * ETH_ALEN);
++      for(i = 0; list && i < count; i++, list = list->next)
++              memcpy(&cb->u.multi.addr[i*ETH_ALEN], &list->dmi_addr,
++                      ETH_ALEN);
++}
++
++static void e100_set_multicast_list(struct net_device *netdev)
++{
++      struct nic *nic = netdev->priv;
++
++      DPRINTK(HW, DEBUG, "mc_count=%d, flags=0x%04X\n",
++              netdev->mc_count, netdev->flags);
++
++      if(netdev->flags & IFF_PROMISC)
++              nic->flags |= promiscuous;
++      else
++              nic->flags &= ~promiscuous;
++
++      if(netdev->flags & IFF_ALLMULTI ||
++              netdev->mc_count > E100_MAX_MULTICAST_ADDRS)
++              nic->flags |= multicast_all;
++      else
++              nic->flags &= ~multicast_all;
++
++      e100_exec_cb(nic, NULL, e100_configure);
++      e100_exec_cb(nic, NULL, e100_multi);
++}
++
++static void e100_update_stats(struct nic *nic)
++{
++      struct net_device_stats *ns = &nic->net_stats;
++      struct stats *s = &nic->mem->stats;
++      u32 *complete = (nic->mac < mac_82558_D101_A4) ? &s->fc_xmt_pause :
++              (nic->mac < mac_82559_D101M) ? (u32 *)&s->xmt_tco_frames :
++              &s->complete;
++
++      /* Device's stats reporting may take several microseconds to
++       * complete, so where always waiting for results of the 
++       * previous command. */
++
++      if(*complete == le32_to_cpu(0x0000A007)) {
++              *complete = 0;
++              nic->tx_frames = le32_to_cpu(s->tx_good_frames);
++              nic->tx_collisions = le32_to_cpu(s->tx_total_collisions);
++              ns->tx_aborted_errors += le32_to_cpu(s->tx_max_collisions);
++              ns->tx_window_errors += le32_to_cpu(s->tx_late_collisions);
++              ns->tx_carrier_errors += le32_to_cpu(s->tx_lost_crs);
++              ns->tx_fifo_errors += le32_to_cpu(s->tx_underruns);
++              ns->collisions += nic->tx_collisions;
++              ns->tx_errors += le32_to_cpu(s->tx_max_collisions) +
++                      le32_to_cpu(s->tx_lost_crs);
++              ns->rx_dropped += le32_to_cpu(s->rx_resource_errors);
++              ns->rx_length_errors += le32_to_cpu(s->rx_short_frame_errors);
++              ns->rx_over_errors += le32_to_cpu(s->rx_resource_errors);
++              ns->rx_crc_errors += le32_to_cpu(s->rx_crc_errors);
++              ns->rx_frame_errors += le32_to_cpu(s->rx_alignment_errors);
++              ns->rx_fifo_errors += le32_to_cpu(s->rx_overrun_errors);
++              ns->rx_errors += le32_to_cpu(s->rx_crc_errors) +
++                      le32_to_cpu(s->rx_alignment_errors) +
++                      le32_to_cpu(s->rx_short_frame_errors) +
++                      le32_to_cpu(s->rx_cdt_errors);
++              nic->tx_deferred += le32_to_cpu(s->tx_deferred);
++              nic->tx_single_collisions +=
++                      le32_to_cpu(s->tx_single_collisions);
++              nic->tx_multiple_collisions +=
++                      le32_to_cpu(s->tx_multiple_collisions);
++              if(nic->mac >= mac_82558_D101_A4) {
++                      nic->tx_fc_pause += le32_to_cpu(s->fc_xmt_pause);
++                      nic->rx_fc_pause += le32_to_cpu(s->fc_rcv_pause);
++                      nic->rx_fc_unsupported +=
++                              le32_to_cpu(s->fc_rcv_unsupported);
++                      if(nic->mac >= mac_82559_D101M) {
++                              nic->tx_tco_frames +=
++                                      le16_to_cpu(s->xmt_tco_frames);
++                              nic->rx_tco_frames +=
++                                      le16_to_cpu(s->rcv_tco_frames);
++                      }
++              }
++      }
++
++      e100_exec_cmd(nic, cuc_dump_reset, 0);
++}
++
++static void e100_adjust_adaptive_ifs(struct nic *nic, int speed, int duplex)
++{
++      /* Adjust inter-frame-spacing (IFS) between two transmits if
++       * we're getting collisions on a half-duplex connection. */
++
++      if(duplex == DUPLEX_HALF) {
++              u32 prev = nic->adaptive_ifs;
++              u32 min_frames = (speed == SPEED_100) ? 1000 : 100;
++
++              if((nic->tx_frames / 32 < nic->tx_collisions) &&
++                 (nic->tx_frames > min_frames)) {
++                      if(nic->adaptive_ifs < 60)
++                              nic->adaptive_ifs += 5;
++              } else if (nic->tx_frames < min_frames) {
++                      if(nic->adaptive_ifs >= 5)
++                              nic->adaptive_ifs -= 5;
++              }
++              if(nic->adaptive_ifs != prev)
++                      e100_exec_cb(nic, NULL, e100_configure);
++      }
++}
++
++static void e100_watchdog(unsigned long data)
++{
++      struct nic *nic = (struct nic *)data;
++      struct ethtool_cmd cmd;
++
++      DPRINTK(TIMER, DEBUG, "right now = %ld\n", jiffies);
++
++      /* mii library handles link maintenance tasks */
++
++      mii_ethtool_gset(&nic->mii, &cmd);
++
++      if(mii_link_ok(&nic->mii) && !netif_carrier_ok(nic->netdev)) {
++              DPRINTK(LINK, INFO, "link up, %sMbps, %s-duplex\n",
++                      cmd.speed == SPEED_100 ? "100" : "10",
++                      cmd.duplex == DUPLEX_FULL ? "full" : "half");
++      } else if(!mii_link_ok(&nic->mii) && netif_carrier_ok(nic->netdev)) {
++              DPRINTK(LINK, INFO, "link down\n");
++      }
++      
++      mii_check_link(&nic->mii);
++      
++      /* Software generated interrupt to recover from (rare) Rx 
++       * allocation failure */
++      writeb(irq_sw_gen, &nic->csr->scb.cmd_hi);
++      e100_write_flush(nic);
++
++      e100_update_stats(nic);
++      e100_adjust_adaptive_ifs(nic, cmd.speed, cmd.duplex);
++
++      if(nic->mac <= mac_82557_D100_C)
++              /* Issue a multicast command to workaround a 557 lock up */
++              e100_set_multicast_list(nic->netdev);
++
++      mod_timer(&nic->watchdog, jiffies + E100_WATCHDOG_PERIOD);
++}
++
++static inline void e100_xmit_prepare(struct nic *nic, struct cb *cb,
++      struct sk_buff *skb)
++{
++      cb->command = nic->tx_command;
++      cb->u.tcb.tbd_array = cb->dma_addr + offsetof(struct cb, u.tcb.tbd);
++      cb->u.tcb.tcb_byte_count = 0;
++      cb->u.tcb.threshold = nic->tx_threshold;
++      cb->u.tcb.tbd_count = 1;
++      cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev,
++              skb->data, skb->len, PCI_DMA_TODEVICE));
++      cb->u.tcb.tbd.size = cpu_to_le16(skb->len);
++}
++
++static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
++{
++      struct nic *nic = netdev->priv;
++      int err = e100_exec_cb(nic, skb, e100_xmit_prepare);
++
++      switch(err) {
++      case -ENOSPC:
++              /* We queued the skb, but now we're out of space. */
++              netif_stop_queue(netdev);
++              break;
++      case -ENOMEM:
++              /* This is a hard error - log it. */
++              DPRINTK(TX_ERR, DEBUG, "Out of Tx resources, returning skb\n");
++              netif_stop_queue(netdev);
++              return 1;
++      }
++
++      netdev->trans_start = jiffies;
++      return 0;
++}
++
++static inline int e100_tx_clean(struct nic *nic)
++{
++      struct cb *cb;
++      int tx_cleaned = 0;
++
++      spin_lock(&nic->cb_lock);
++
++      DPRINTK(TX_DONE, DEBUG, "cb->status = 0x%04X\n",
++              nic->cb_to_clean->status);
++
++      /* Clean CBs marked complete */
++      for(cb = nic->cb_to_clean;
++          cb->status & cpu_to_le16(cb_complete);
++          cb = nic->cb_to_clean = cb->next) {
++              if(likely(cb->skb != NULL)) {
++                      nic->net_stats.tx_packets++;
++                      nic->net_stats.tx_bytes += cb->skb->len;
++
++                      pci_unmap_single(nic->pdev,
++                              le32_to_cpu(cb->u.tcb.tbd.buf_addr),
++                              le16_to_cpu(cb->u.tcb.tbd.size),
++                              PCI_DMA_TODEVICE);
++                      dev_kfree_skb_any(cb->skb);
++                      tx_cleaned = 1;
++              }
++              cb->status = 0;
++              nic->cbs_avail++;
++      }
++      
++      spin_unlock(&nic->cb_lock);
++
++      /* Recover from running out of Tx resources in xmit_frame */
++      if(unlikely(tx_cleaned && netif_queue_stopped(nic->netdev)))
++              netif_wake_queue(nic->netdev);
++
++      return tx_cleaned;
++}
++
++static void e100_clean_cbs(struct nic *nic, int free_mem)
++{
++      if(nic->cbs) {
++              while(nic->cb_to_clean != nic->cb_to_use) {
++                      struct cb *cb = nic->cb_to_clean;
++                      if(cb->skb) {
++                              pci_unmap_single(nic->pdev,
++                                      le32_to_cpu(cb->u.tcb.tbd.buf_addr),
++                                      le16_to_cpu(cb->u.tcb.tbd.size),
++                                      PCI_DMA_TODEVICE);
++                              dev_kfree_skb(cb->skb);
++                      }
++                      nic->cb_to_clean = nic->cb_to_clean->next;
++              }
++              nic->cbs_avail = nic->params.cbs.count;
++              if(free_mem) {
++                      pci_free_consistent(nic->pdev, 
++                              sizeof(struct cb) * nic->params.cbs.count, 
++                              nic->cbs, nic->cbs_dma_addr);
++                      nic->cbs = NULL;
++                      nic->cbs_avail = 0;
++              }
++      }
++      nic->cuc_cmd = cuc_start;
++      nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean =
++              nic->cbs;
++}
++
++static int e100_alloc_cbs(struct nic *nic)
++{
++      struct cb *cb;
++      unsigned int i, count = nic->params.cbs.count;
++      
++      nic->cuc_cmd = cuc_start;
++      nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL;
++      nic->cbs_avail = 0;
++      
++      nic->cbs = pci_alloc_consistent(nic->pdev, 
++              sizeof(struct cb) * count, &nic->cbs_dma_addr);
++      if(!nic->cbs)
++              return -ENOMEM;
++
++      for(cb = nic->cbs, i = 0; i < count; cb++, i++) {
++              cb->next = (i + 1 < count) ? cb + 1 : nic->cbs;
++              cb->prev = (i == 0) ? nic->cbs + count - 1 : cb - 1;    
++              
++              cb->dma_addr = nic->cbs_dma_addr + i * sizeof(struct cb);
++              cb->link = cpu_to_le32(nic->cbs_dma_addr +
++                      ((i+1) % count) * sizeof(struct cb));
++      }
++      
++      nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs;
++      nic->cbs_avail = count;
++
++      return 0;
++}
++
++static inline void e100_start_receiver(struct nic *nic)
++{
++      /* (Re)start RU if suspended or idle and RFA is fully allocated */
++      struct rx_list *curr =
++              list_entry(nic->rx_list_head.next, struct rx_list, list);
++      if(curr->skb) {
++              u8 status = readb(&nic->csr->scb.status);
++              if(unlikely((status & rus_mask) != rus_ready))
++                      e100_exec_cmd(nic, ruc_start, curr->dma_addr);
++      }
++}
++
++static inline int e100_rx_alloc_skb(struct nic *nic, struct rx_list *curr)
++{
++      unsigned int rx_offset = 2; /* u32 align protocol headers */
++
++      curr->dma_addr = 0;
++      curr->length = sizeof(struct rfd) + VLAN_ETH_FRAME_LEN;
++
++      if(!(curr->skb = dev_alloc_skb(curr->length + rx_offset)))
++              return -ENOMEM;
++
++      skb_reserve(curr->skb, rx_offset);
++      curr->skb->dev = nic->netdev;
++      curr->dma_addr = pci_map_single(nic->pdev, curr->skb->data,
++              curr->length, PCI_DMA_FROMDEVICE);
++
++      return 0;
++}
++
++static inline void e100_rx_rfa_add_tail(struct nic *nic, struct rx_list *curr)
++{
++      memcpy(curr->skb->data, &nic->blank_rfd, sizeof(struct rfd));
++      pci_dma_sync_single(nic->pdev, curr->dma_addr, 
++              sizeof(struct rfd), PCI_DMA_TODEVICE);
++
++      if(likely(curr->list.prev != &nic->rx_list_head)) {
++              struct rx_list *prev = (struct rx_list *)curr->list.prev;
++              if(likely(prev->skb != NULL)) {
++                      struct rfd *prev_rfd = (struct rfd *)prev->skb->data;
++                      put_unaligned(cpu_to_le32(curr->dma_addr),
++                              (u32 *)&prev_rfd->link);
++                      prev_rfd->command = 0;
++                      pci_dma_sync_single(nic->pdev, prev->dma_addr, 
++                              sizeof(struct rfd), PCI_DMA_TODEVICE);
++              }
++      }
++}
++
++static inline int e100_rx_indicate(struct nic *nic, struct rx_list *curr,
++      unsigned int *work_done, unsigned int work_to_do)
++{
++      struct sk_buff *skb = curr->skb;
++      struct rfd *rfd = (struct rfd *)skb->data;
++      u16 rfd_status, actual_size;
++
++      if(unlikely(work_done && *work_done >= work_to_do))
++              return -EAGAIN;
++
++      /* Need to sync before taking a peek at cb_complete bit */
++      pci_dma_sync_single(nic->pdev, curr->dma_addr,
++              sizeof(struct rfd), PCI_DMA_FROMDEVICE);
++      rfd_status = le16_to_cpu(rfd->status);
++
++      DPRINTK(RX_STATUS, DEBUG, "status=0x%04X\n", rfd_status);
++
++      /* If data isn't ready, nothing to indicate */
++      if(unlikely(!(rfd_status & cb_complete)))
++                      return -EAGAIN;
++
++      /* Get actual data size */
++      actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF;
++      if(unlikely(actual_size > curr->length - sizeof(struct rfd)))
++              actual_size = curr->length - sizeof(struct rfd);
++
++      /* Get data */
++      pci_dma_sync_single(nic->pdev, curr->dma_addr,
++              sizeof(struct rfd) + actual_size,
++              PCI_DMA_FROMDEVICE);
++      pci_unmap_single(nic->pdev, curr->dma_addr,
++              curr->length, PCI_DMA_FROMDEVICE);
++
++      /* Pull off the RFD and put the actual data (minus eth hdr) */
++      skb_reserve(skb, sizeof(struct rfd));
++      skb_put(skb, actual_size);
++      skb->protocol = eth_type_trans(skb, nic->netdev);
++
++      if(unlikely(!(rfd_status & cb_ok)) ||
++         actual_size > nic->netdev->mtu + VLAN_ETH_HLEN) {
++              /* Don't indicate if errors */
++              dev_kfree_skb_any(skb);
++      } else {
++              nic->net_stats.rx_packets++;
++              nic->net_stats.rx_bytes += actual_size;
++              nic->netdev->last_rx = jiffies;
++#ifdef CONFIG_E100_NAPI
++              netif_receive_skb(skb);
++#else
++              netif_rx(skb);
++#endif
++              if(work_done)
++                      (*work_done)++;
++      }
++
++      curr->length = 0;
++      curr->dma_addr = 0;
++      curr->skb = NULL;
++      
++      return 0;
++}
++
++static inline void e100_rx_clean(struct nic *nic, unsigned int *work_done,
++      unsigned int work_to_do)
++{
++      struct list_head *list, *tmp;
++      struct rx_list *curr;
++
++      /* Indicate newly arrived packets */
++      list_for_each(list, &nic->rx_list_head) {
++              curr = list_entry(list, struct rx_list, list);
++              if(likely(curr->skb != NULL))
++                      if(e100_rx_indicate(nic, curr, work_done, work_to_do))
++                              break;
++      }
++
++      /* Alloc new skbs to refill list */
++      list_for_each_safe(list, tmp, &nic->rx_list_head) {
++              curr = list_entry(list, struct rx_list, list);
++              if(unlikely(curr->skb != NULL))
++                      break; /* List is full, done */
++              if(unlikely(e100_rx_alloc_skb(nic, curr)))
++                      break; /* Better luck next time (see watchdog) */
++              list_del(&curr->list);
++              list_add_tail(&curr->list, &nic->rx_list_head);
++              e100_rx_rfa_add_tail(nic, curr);
++      }
++
++      e100_start_receiver(nic);
++}
++
++static void e100_rx_clean_list(struct nic *nic)
++{
++      struct list_head *list;
++      
++      if(!nic->rx_list)
++              return;
++
++      list_for_each(list, &nic->rx_list_head) {
++              struct rx_list *curr = list_entry(list, 
++                      struct rx_list, list);
++              if(curr->skb) {
++                      pci_unmap_single(nic->pdev, curr->dma_addr,
++                              curr->length, PCI_DMA_FROMDEVICE);
++                      dev_kfree_skb(curr->skb);
++              }
++      }
++
++      kfree(nic->rx_list);
++      nic->rx_list = NULL;
++}
++
++static int e100_rx_alloc_list(struct nic *nic)
++{
++      struct rx_list *curr;
++      unsigned int i, count = nic->params.rfds.count;
++      
++      INIT_LIST_HEAD(&nic->rx_list_head);
++
++      if(!(nic->rx_list = kmalloc(sizeof(struct rx_list)*count, GFP_ATOMIC)))
++              return -ENOMEM;
++
++      for(curr = nic->rx_list, i = 0; i < count; curr++, i++) {
++              if(e100_rx_alloc_skb(nic, curr)) {
++                      e100_rx_clean_list(nic);
++                      return -ENOMEM;
++              }
++              list_add_tail(&curr->list, &nic->rx_list_head);
++              e100_rx_rfa_add_tail(nic, curr);
++      }
++      
++      return 0;
++}
++
++static irqreturn_t e100_intr(int irq, void *dev_id, struct pt_regs *regs)
++{
++      struct net_device *netdev = dev_id;
++      struct nic *nic = netdev->priv;
++      u8 stat_ack = readb(&nic->csr->scb.stat_ack);
++
++      DPRINTK(INTR, DEBUG, "stat_ack = 0x%02X\n", stat_ack);
++
++      if(stat_ack == 0x00 ||  /* Not our interrupt */
++         stat_ack == 0xFF)    /* Hardware is ejected (cardbus, hotswap)  */
++              return IRQ_NONE;
++
++      /* Ack interrupts */
++      writeb(stat_ack, &nic->csr->scb.stat_ack);
++      e100_write_flush(nic);
++
++#ifdef CONFIG_E100_NAPI
++      e100_disable_irq(nic);
++      netif_rx_schedule(netdev);
++#else
++      if(stat_ack & stat_ack_rx)
++              e100_rx_clean(nic, NULL, 0);
++      if(stat_ack & stat_ack_tx)
++              e100_tx_clean(nic);
++#endif
++
++      return IRQ_HANDLED;
++}
++
++#ifdef CONFIG_E100_NAPI
++static int e100_poll(struct net_device *netdev, int *budget)
++{
++      struct nic *nic = netdev->priv;
++      unsigned int work_to_do = min(netdev->quota, *budget);
++      unsigned int work_done = 0;
++      int tx_cleaned;
++
++      e100_rx_clean(nic, &work_done, work_to_do);
++      tx_cleaned = e100_tx_clean(nic);
++
++      /* If no Rx and Tx cleanup work was done, exit polling mode. */
++      if((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) {
++              netif_rx_complete(netdev);
++              e100_enable_irq(nic);
++              return 0;
++      }
++
++      *budget -= work_done;
++      netdev->quota -= work_done;
++
++      return 1;
++}
++#endif
++
++static struct net_device_stats *e100_get_stats(struct net_device *netdev)
++{
++      struct nic *nic = netdev->priv;
++      return &nic->net_stats;
++}
++
++static int e100_set_mac_address(struct net_device *netdev, void *p)
++{
++      struct nic *nic = netdev->priv;
++      struct sockaddr *addr = p;
++
++      if (!is_valid_ether_addr(addr->sa_data))
++              return -EADDRNOTAVAIL;
++
++      memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
++      e100_exec_cb(nic, NULL, e100_setup_iaaddr);
++
++      return 0;
++}
++
++static int e100_change_mtu(struct net_device *netdev, int new_mtu)
++{
++      if(new_mtu < ETH_ZLEN || new_mtu > ETH_DATA_LEN)
++              return -EINVAL;
++      netdev->mtu = new_mtu;
++      return 0;
++}
++
++static int e100_asf(struct nic *nic)
++{
++      /* ASF can be enabled from eeprom */
++      return((nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1055) &&
++         (nic->eeprom[eeprom_config_asf] & eeprom_asf) &&
++         !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) &&
++         ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE));
++}
++      
++static int e100_up(struct nic *nic)
++{
++      int err;
++
++      if((err = e100_rx_alloc_list(nic)))
++              return err;
++      if((err = e100_alloc_cbs(nic)))
++              goto err_rx_clean_list;
++      if((err = e100_hw_init(nic)))
++              goto err_clean_cbs;
++      e100_set_multicast_list(nic->netdev);
++      e100_start_receiver(nic);
++      netif_start_queue(nic->netdev);
++      mod_timer(&nic->watchdog, jiffies);
++      if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
++              nic->netdev->name, nic->netdev)))
++              goto err_no_irq;
++      e100_enable_irq(nic);
++      return 0;
++
++err_no_irq:
++      del_timer_sync(&nic->watchdog);
++      netif_stop_queue(nic->netdev);
++err_clean_cbs:
++      e100_clean_cbs(nic, 1);
++err_rx_clean_list:
++      e100_rx_clean_list(nic);
++      return err;
++}
++
++static void e100_down(struct nic *nic)
++{
++      e100_disable_irq(nic);
++      free_irq(nic->pdev->irq, nic->netdev);
++      del_timer_sync(&nic->watchdog);
++      netif_carrier_off(nic->netdev);
++      netif_stop_queue(nic->netdev);
++      e100_clean_cbs(nic, 1);
++      e100_rx_clean_list(nic);
++}
++
++static void e100_tx_timeout(struct net_device *netdev)
++{
++      struct nic *nic = netdev->priv;
++
++      DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n",
++              readb(&nic->csr->scb.status));
++      e100_down(netdev->priv);
++      e100_up(netdev->priv);
++}
++
++static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
++{
++      int err;
++      struct sk_buff *skb;
++      struct rx_list *rx;
++
++      /* Use driver resources to perform internal MAC or PHY
++       * loopback test.  A single packet is prepared and transmitted
++       * in loopback mode, and the test passes if the received
++       * packet compares byte-for-byte to the transmitted packet. */
++
++      if((err = e100_rx_alloc_list(nic)))
++              return err;
++      if((err = e100_alloc_cbs(nic)))
++              goto err_clean_rx;
++
++      /* ICH PHY loopback is broken so do MAC loopback instead */
++      if(nic->flags & ich && loopback_mode == lb_phy)
++              loopback_mode = lb_mac;
++
++      nic->loopback = loopback_mode;
++      if((err = e100_hw_init(nic)))
++              goto err_loopback_none;
++
++      if(loopback_mode == lb_phy)
++              mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
++                      BMCR_LOOPBACK);
++
++      e100_start_receiver(nic);
++      
++      if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) {
++              err = -ENOMEM;
++              goto err_loopback_none;
++      }
++      skb_put(skb, ETH_DATA_LEN);
++      memset(skb->data, 0xFF, ETH_DATA_LEN);
++      e100_xmit_frame(skb, nic->netdev);
++
++      set_current_state(TASK_UNINTERRUPTIBLE);
++      schedule_timeout(HZ / 100 + 1);
++
++      rx = list_entry(nic->rx_list_head.next, struct rx_list, list);
++      if(memcmp(rx->skb->data + sizeof(struct rfd), skb->data, ETH_DATA_LEN))
++                      err = -EAGAIN;
++
++err_loopback_none:
++      mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 0);
++      nic->loopback = lb_none;
++      e100_hw_init(nic);
++      e100_clean_cbs(nic, 1);
++err_clean_rx:
++      e100_rx_clean_list(nic);
++      return err;
++}
++
++#define MII_LED_CONTROL       0x1B
++static void e100_blink_led(unsigned long data)
++{
++      struct nic *nic = (struct nic *)data;
++      enum led_state {
++              led_on     = 0x01,
++              led_off    = 0x04,
++              led_on_559 = 0x05,
++              led_on_557 = 0x07,
++      };
++
++      nic->leds = (nic->leds & led_on) ? led_off :
++              (nic->mac < mac_82559_D101M) ? led_on_557 : led_on_559;
++      mdio_write(nic->netdev, nic->mii.phy_id, MII_LED_CONTROL, nic->leds);
++      mod_timer(&nic->blink_timer, jiffies + HZ / 4);
++}
++
++static int e100_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
++{
++      struct nic *nic = netdev->priv;
++      return mii_ethtool_gset(&nic->mii, cmd);
++}
++  
++static int e100_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
++{
++      struct nic *nic = netdev->priv;
++      return mii_ethtool_sset(&nic->mii, cmd);
++}
++  
++static void e100_get_drvinfo(struct net_device *netdev,
++      struct ethtool_drvinfo *info)
++{
++      struct nic *nic = netdev->priv;
++      strcpy(info->driver, DRV_NAME);
++      strcpy(info->version, DRV_VERSION);
++      strcpy(info->fw_version, "N/A");
++      strcpy(info->bus_info, pci_name(nic->pdev));
++}
++  
++static int e100_get_regs_len(struct net_device *netdev)
++{
++      struct nic *nic = netdev->priv;
++#define E100_PHY_REGS         0x1C
++#define E100_REGS_LEN         1 + E100_PHY_REGS + \
++      sizeof(nic->mem->dump_buf) / sizeof(u32)
++      return E100_REGS_LEN * sizeof(u32);
++}
++
++static void e100_get_regs(struct net_device *netdev,
++      struct ethtool_regs *regs, void *p)
++{
++      struct nic *nic = netdev->priv;
++      u32 *buff = p;
++      int i;
++
++      regs->version = (1 << 24) | nic->rev_id;
++      buff[0] = readb(&nic->csr->scb.cmd_hi) << 24 |
++              readb(&nic->csr->scb.cmd_lo) << 16 |
++              readw(&nic->csr->scb.status);
++      for(i = E100_PHY_REGS; i >= 0; i--)
++              buff[1 + E100_PHY_REGS - i] =
++                      mdio_read(netdev, nic->mii.phy_id, i);
++      memset(nic->mem->dump_buf, 0, sizeof(nic->mem->dump_buf));
++      e100_exec_cb(nic, NULL, e100_dump);
++      set_current_state(TASK_UNINTERRUPTIBLE);
++      schedule_timeout(HZ / 100 + 1);
++      memcpy(&buff[2 + E100_PHY_REGS], nic->mem->dump_buf,
++              sizeof(nic->mem->dump_buf));
++}
++
++static void e100_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
++{
++      struct nic *nic = netdev->priv;
++      wol->supported = (nic->mac >= mac_82558_D101_A4) ?  WAKE_MAGIC : 0;
++      wol->wolopts = (nic->flags & wol_magic) ? WAKE_MAGIC : 0;
++}
++  
++static int e100_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
++{
++      struct nic *nic = netdev->priv;
++  
++      if(wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
++              return -EOPNOTSUPP;
++
++      if(wol->wolopts)
++              nic->flags |= wol_magic;
++      else
++              nic->flags &= ~wol_magic;
++
++      pci_enable_wake(nic->pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
++      e100_exec_cb(nic, NULL, e100_configure);
++  
++      return 0;
++}
++  
++static u32 e100_get_msglevel(struct net_device *netdev)
++{
++      struct nic *nic = netdev->priv;
++      return nic->msg_enable;
++}
++  
++static void e100_set_msglevel(struct net_device *netdev, u32 value)
++{
++      struct nic *nic = netdev->priv;
++      nic->msg_enable = value;
++}
++  
++static int e100_nway_reset(struct net_device *netdev)
++{
++      struct nic *nic = netdev->priv;
++      return mii_nway_restart(&nic->mii);
++}
++
++static u32 e100_get_link(struct net_device *netdev)
++{
++      struct nic *nic = netdev->priv;
++      return mii_link_ok(&nic->mii);
++}
++  
++static int e100_get_eeprom_len(struct net_device *netdev)
++{
++      struct nic *nic = netdev->priv;
++      return nic->eeprom_wc << 1;
++}
++
++#define E100_EEPROM_MAGIC     0x1234
++static int e100_get_eeprom(struct net_device *netdev,
++      struct ethtool_eeprom *eeprom, u8 *bytes)
++{
++      struct nic *nic = netdev->priv;
++      
++      eeprom->magic = E100_EEPROM_MAGIC;
++      memcpy(bytes, &((u8 *)nic->eeprom)[eeprom->offset], eeprom->len);
++
++      return 0;
++}
++
++static int e100_set_eeprom(struct net_device *netdev,
++      struct ethtool_eeprom *eeprom, u8 *bytes)
++{
++      struct nic *nic = netdev->priv;
++      
++      if(eeprom->magic != E100_EEPROM_MAGIC)
++              return -EINVAL;
++      memcpy(&((u8 *)nic->eeprom)[eeprom->offset], bytes, eeprom->len);
++
++      return e100_eeprom_save(nic, eeprom->offset >> 1,
++              (eeprom->len >> 1) + 1);
++}
++
++static void e100_get_ringparam(struct net_device *netdev,
++      struct ethtool_ringparam *ring)
++{
++      struct nic *nic = netdev->priv;
++      struct param_range *rfds = &nic->params.rfds;
++      struct param_range *cbs = &nic->params.cbs;
++  
++      ring->rx_max_pending = rfds->max;
++      ring->tx_max_pending = cbs->max;
++      ring->rx_mini_max_pending = 0;
++      ring->rx_jumbo_max_pending = 0;
++      ring->rx_pending = rfds->count;
++      ring->tx_pending = cbs->count;
++      ring->rx_mini_pending = 0;
++      ring->rx_jumbo_pending = 0;
++}
++  
++static int e100_set_ringparam(struct net_device *netdev,
++      struct ethtool_ringparam *ring)
++{
++      struct nic *nic = netdev->priv;
++      struct param_range *rfds = &nic->params.rfds;
++      struct param_range *cbs = &nic->params.cbs;
++  
++      if(netif_running(netdev))
++              e100_down(nic);
++      rfds->count = max(ring->rx_pending, rfds->min);
++      rfds->count = min(rfds->count, rfds->max);
++      cbs->count = max(ring->tx_pending, cbs->min);
++      cbs->count = min(cbs->count, cbs->max);
++      if(netif_running(netdev))
++              e100_up(nic);
++              
++      return 0;
++}
++  
++static char e100_gstrings_test[][ETH_GSTRING_LEN] = {
++      "Link test     (on/offline)",
++      "Eeprom test   (on/offline)",
++      "Self test        (offline)",
++      "Mac loopback     (offline)",
++      "Phy loopback     (offline)",
++};
++#define E100_TEST_LEN sizeof(e100_gstrings_test) / ETH_GSTRING_LEN
++
++static int e100_diag_test_count(struct net_device *netdev)
++{
++      return E100_TEST_LEN;
++}
++
++static void e100_diag_test(struct net_device *netdev,
++      struct ethtool_test *test, u64 *data)
++{
++      struct nic *nic = netdev->priv;
++      int i;
++
++      memset(data, 0, E100_TEST_LEN * sizeof(u64));
++      data[0] = !mii_link_ok(&nic->mii);
++      data[1] = e100_eeprom_load(nic);
++      if(test->flags & ETH_TEST_FL_OFFLINE) {
++              if(netif_running(netdev))
++                      e100_down(nic);
++              data[2] = e100_self_test(nic);
++              data[3] = e100_loopback_test(nic, lb_mac);
++              data[4] = e100_loopback_test(nic, lb_phy);
++              if(netif_running(netdev))
++                      e100_up(nic);
++      }
++      for(i = 0; i < E100_TEST_LEN; i++)
++              test->flags |= data[i] ? ETH_TEST_FL_FAILED : 0;
++}
++
++static int e100_phys_id(struct net_device *netdev, u32 data)
++{
++      struct nic *nic = netdev->priv;
++
++      if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
++              data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
++      mod_timer(&nic->blink_timer, jiffies);
++      set_current_state(TASK_INTERRUPTIBLE);
++      schedule_timeout(data * HZ);
++      del_timer_sync(&nic->blink_timer);
++      mdio_write(netdev, nic->mii.phy_id, MII_LED_CONTROL, 0);
++
++      return 0;
++}
++
++static char e100_gstrings_stats[][ETH_GSTRING_LEN] = {
++      "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
++      "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
++      "rx_length_errors", "rx_over_errors", "rx_crc_errors",
++      "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
++      "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
++      "tx_heartbeat_errors", "tx_window_errors",
++      /* device-specific stats */
++      "tx_deferred", "tx_single_collisions", "tx_multi_collisions", 
++      "tx_flow_control_pause", "rx_flow_control_pause",
++      "rx_flow_control_unsupported", "tx_tco_packets", "rx_tco_packets",
++};
++#define E100_NET_STATS_LEN    21
++#define E100_STATS_LEN        sizeof(e100_gstrings_stats) / ETH_GSTRING_LEN
++
++static int e100_get_stats_count(struct net_device *netdev)
++{
++      return E100_STATS_LEN;
++}
++
++static void e100_get_ethtool_stats(struct net_device *netdev,
++      struct ethtool_stats *stats, u64 *data)
++{
++      struct nic *nic = netdev->priv;
++      int i;
++
++      for(i = 0; i < E100_NET_STATS_LEN; i++)
++              data[i] = ((unsigned long *)&nic->net_stats)[i];
++
++      data[i++] = nic->tx_deferred;
++      data[i++] = nic->tx_single_collisions;
++      data[i++] = nic->tx_multiple_collisions;
++      data[i++] = nic->tx_fc_pause;
++      data[i++] = nic->rx_fc_pause;
++      data[i++] = nic->rx_fc_unsupported;
++      data[i++] = nic->tx_tco_frames;
++      data[i++] = nic->rx_tco_frames;
++}
++
++static void e100_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
++{
++      switch(stringset) {
++      case ETH_SS_TEST:
++              memcpy(data, *e100_gstrings_test, sizeof(e100_gstrings_test));
++              break;
++      case ETH_SS_STATS:
++              memcpy(data, *e100_gstrings_stats, sizeof(e100_gstrings_stats));
++              break;
++      }
++}
++
++static struct ethtool_ops e100_ethtool_ops = {
++      .get_settings           = e100_get_settings,
++      .set_settings           = e100_set_settings,
++      .get_drvinfo            = e100_get_drvinfo,
++      .get_regs_len           = e100_get_regs_len,
++      .get_regs               = e100_get_regs,
++      .get_wol                = e100_get_wol,
++      .set_wol                = e100_set_wol,
++      .get_msglevel           = e100_get_msglevel,
++      .set_msglevel           = e100_set_msglevel,
++      .nway_reset             = e100_nway_reset,
++      .get_link               = e100_get_link,
++      .get_eeprom_len         = e100_get_eeprom_len,
++      .get_eeprom             = e100_get_eeprom,
++      .set_eeprom             = e100_set_eeprom,
++      .get_ringparam          = e100_get_ringparam,
++      .set_ringparam          = e100_set_ringparam,
++      .self_test_count        = e100_diag_test_count,
++      .self_test              = e100_diag_test,
++      .get_strings            = e100_get_strings,
++      .phys_id                = e100_phys_id,
++      .get_stats_count        = e100_get_stats_count,
++      .get_ethtool_stats      = e100_get_ethtool_stats,
++};
++
++static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
++{
++      struct nic *nic = netdev->priv;
++      struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr->ifr_data;
++
++      return generic_mii_ioctl(&nic->mii, mii, cmd, NULL);
++}
++
++static int e100_alloc(struct nic *nic)
++{
++      nic->mem = pci_alloc_consistent(nic->pdev, sizeof(struct mem),
++              &nic->dma_addr);
++      return nic->mem ? 0 : -ENOMEM;
++}
++
++static void e100_free(struct nic *nic)
++{
++      if(nic->mem) {
++              pci_free_consistent(nic->pdev, sizeof(struct mem),
++                      nic->mem, nic->dma_addr);
++              nic->mem = NULL;
++      }
++}
++
++static int e100_open(struct net_device *netdev)
++{
++      struct nic *nic = netdev->priv;
++      int err = 0;
++
++      netif_carrier_off(netdev);
++      if((err = e100_up(nic)))
++              DPRINTK(IFUP, ERR, "Cannot open interface, aborting.\n");
++      return err;
++}
++
++static int e100_close(struct net_device *netdev)
++{
++      e100_down(netdev->priv);
++      return 0;
++}
++
++static int __devinit e100_probe(struct pci_dev *pdev, 
++      const struct pci_device_id *ent)
++{
++      struct net_device *netdev;
++      struct nic *nic;
++      int err;
++      
++      if(!(netdev = alloc_etherdev(sizeof(struct nic)))) {
++              if(((1 << debug) - 1) & NETIF_MSG_PROBE)
++                      printk(KERN_ERR PFX "Etherdev alloc failed, abort.\n");
++              return -ENOMEM;
++      }
++
++      netdev->open = e100_open;
++      netdev->stop = e100_close;
++      netdev->hard_start_xmit = e100_xmit_frame;
++      netdev->get_stats = e100_get_stats;
++      netdev->set_multicast_list = e100_set_multicast_list;
++      netdev->set_mac_address = e100_set_mac_address;
++      netdev->change_mtu = e100_change_mtu;
++      netdev->do_ioctl = e100_do_ioctl;
++      SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
++      netdev->tx_timeout = e100_tx_timeout;
++      netdev->watchdog_timeo = E100_WATCHDOG_PERIOD;
++#ifdef CONFIG_E100_NAPI
++      netdev->poll = e100_poll;
++      netdev->weight = E100_NAPI_WEIGHT;
++#endif
++
++      nic = netdev->priv;
++      nic->netdev = netdev;
++      nic->pdev = pdev;
++      nic->msg_enable = (1 << debug) - 1;
++      pci_set_drvdata(pdev, netdev);
++
++      if((err = pci_enable_device(pdev))) {
++              DPRINTK(PROBE, ERR, "Cannot enable PCI device, aborting.\n");
++              goto err_out_free_dev;
++      }
++
++      if(!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
++              DPRINTK(PROBE, ERR, "Cannot find proper PCI device "
++                      "base address, aborting.\n");
++              err = -ENODEV;
++              goto err_out_disable_pdev;
++      }
++
++      if((err = pci_request_regions(pdev, DRV_NAME))) {
++              DPRINTK(PROBE, ERR, "Cannot obtain PCI resources, aborting.\n");
++              goto err_out_disable_pdev;
++      }
++
++      pci_set_master(pdev);
++
++      if((err = pci_set_dma_mask(pdev, 0xFFFFFFFFULL))) {
++              DPRINTK(PROBE, ERR, "No usable DMA configuration, aborting.\n");
++              goto err_out_free_res;
++      }
++
++      SET_MODULE_OWNER(netdev);
++      SET_NETDEV_DEV(netdev, &pdev->dev);
++
++      nic->csr = ioremap(pci_resource_start(pdev, 0), sizeof(struct csr));
++      if(!nic->csr) {
++              DPRINTK(PROBE, ERR, "Cannot map device registers, aborting.\n");
++              err = -ENOMEM;
++              goto err_out_free_res;
++      }
++
++      if(ent->driver_data)
++              nic->flags |= ich;
++      else
++              nic->flags &= ~ich;
++
++      spin_lock_init(&nic->cb_lock);
++      spin_lock_init(&nic->cmd_lock);
++
++      init_timer(&nic->watchdog);
++      nic->watchdog.function = e100_watchdog;
++      nic->watchdog.data = (unsigned long)nic;
++      init_timer(&nic->blink_timer);
++      nic->blink_timer.function = e100_blink_led;
++      nic->blink_timer.data = (unsigned long)nic;
++
++      if((err = e100_alloc(nic))) {
++              DPRINTK(PROBE, ERR, "Cannot alloc driver memory, aborting.\n");
++              goto err_out_iounmap;
++      }
++
++      e100_get_defaults(nic);
++      e100_hw_reset(nic);
++      e100_phy_init(nic);
++
++      if((err = e100_eeprom_load(nic)))
++              goto err_out_free;
++      ((u16 *)netdev->dev_addr)[0] = le16_to_cpu(nic->eeprom[0]);
++      ((u16 *)netdev->dev_addr)[1] = le16_to_cpu(nic->eeprom[1]);
++      ((u16 *)netdev->dev_addr)[2] = le16_to_cpu(nic->eeprom[2]);
++      if(!is_valid_ether_addr(netdev->dev_addr)) {
++              DPRINTK(PROBE, ERR, "Invalid MAC address from "
++                      "EEPROM, aborting.\n");
++              err = -EAGAIN;
++              goto err_out_free;
++      }
++
++      /* Wol magic packet can be enabled from eeprom */
++      if((nic->mac >= mac_82558_D101_A4) &&
++         (nic->eeprom[eeprom_id] & eeprom_id_wol))
++              nic->flags |= wol_magic;
++
++      pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
++
++      if((err = register_netdev(netdev))) {
++              DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n");
++              goto err_out_free;
++      }
++
++      DPRINTK(PROBE, INFO, "addr 0x%lx, irq %d, "
++              "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n",
++              pci_resource_start(pdev, 0), pdev->irq,
++              netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
++              netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
++
++      return 0;
++
++err_out_free:
++      e100_free(nic);
++err_out_iounmap:
++      iounmap(nic->csr);
++err_out_free_res:
++      pci_release_regions(pdev);
++err_out_disable_pdev:
++      pci_disable_device(pdev);
++err_out_free_dev:
++      pci_set_drvdata(pdev, NULL);
++      free_netdev(netdev);
++      return err;
++}
++
++static void __devexit e100_remove(struct pci_dev *pdev)
++{
++      struct net_device *netdev = pci_get_drvdata(pdev);
++
++      if(netdev) {
++              struct nic *nic = netdev->priv;
++              unregister_netdev(netdev);
++              e100_free(nic);
++              iounmap(nic->csr);
++              free_netdev(netdev);
++              pci_release_regions(pdev);
++              pci_disable_device(pdev);
++              pci_set_drvdata(pdev, NULL);
++      }
++}
++
++#ifdef CONFIG_PM                      
++static int e100_suspend(struct pci_dev *pdev, u32 state)
++{
++      struct net_device *netdev = pci_get_drvdata(pdev);
++      struct nic *nic = netdev->priv;
++
++      if(netif_running(netdev))
++              e100_down(nic);
++      e100_hw_reset(nic);
++      netif_device_detach(netdev);
++
++      pci_save_state(pdev, nic->pm_state);
++      pci_enable_wake(pdev, state, nic->flags & (wol_magic | e100_asf(nic)));
++      pci_disable_device(pdev);
++      pci_set_power_state(pdev, state);
++
++      return 0;
++}
++
++static int e100_resume(struct pci_dev *pdev)
++{
++      struct net_device *netdev = pci_get_drvdata(pdev);
++      struct nic *nic = netdev->priv;
++
++      pci_set_power_state(pdev, 0);
++      pci_restore_state(pdev, nic->pm_state);
++      e100_hw_init(nic);
++
++      netif_device_attach(netdev);
++      if(netif_running(netdev))
++              e100_up(nic);
++      
++      return 0;
++}
++#endif
++
++static struct pci_driver e100_driver = {
++      .name =         DRV_NAME,
++      .id_table =     e100_id_table,
++      .probe =        e100_probe,
++      .remove =       __devexit_p(e100_remove),
++#ifdef CONFIG_PM                      
++      .suspend =      e100_suspend,
++      .resume =       e100_resume,
++#endif
++};
++
++static int __init e100_init_module(void)
++{
++      if(((1 << debug) - 1) & NETIF_MSG_DRV) {
++              printk(KERN_INFO PFX "%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
++              printk(KERN_INFO PFX "%s\n", DRV_COPYRIGHT);
++      }
++        return pci_module_init(&e100_driver);
++}
++
++static void __exit e100_cleanup_module(void)
++{
++      pci_unregister_driver(&e100_driver);
++}
++
++module_init(e100_init_module);
++module_exit(e100_cleanup_module);
+--- linux-2.6.0/drivers/net/e100/e100_config.c 2003-09-27 18:57:45.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,639 +0,0 @@
+-/*******************************************************************************
+-
+-  
+-  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+-  
+-  This program is free software; you can redistribute it and/or modify it 
+-  under the terms of the GNU General Public License as published by the Free 
+-  Software Foundation; either version 2 of the License, or (at your option) 
+-  any later version.
+-  
+-  This program is distributed in the hope that it will be useful, but WITHOUT 
+-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+-  more details.
+-  
+-  You should have received a copy of the GNU General Public License along with
+-  this program; if not, write to the Free Software Foundation, Inc., 59 
+-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+-  
+-  The full GNU General Public License is included in this distribution in the
+-  file called LICENSE.
+-  
+-  Contact Information:
+-  Linux NICS <linux.nics@intel.com>
+-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+-*******************************************************************************/
+-
+-/**********************************************************************
+-*                                                                     *
+-* INTEL CORPORATION                                                   *
+-*                                                                     *
+-* This software is supplied under the terms of the license included   *
+-* above.  All use of this driver must be in accordance with the terms *
+-* of that license.                                                    *
+-*                                                                     *
+-* Module Name:  e100_config.c                                         *
+-*                                                                     *
+-* Abstract:     Functions for configuring the network adapter.        *
+-*                                                                     *
+-* Environment:  This file is intended to be specific to the Linux     *
+-*               operating system.                                     *
+-*                                                                     *
+-**********************************************************************/
+-#include "e100_config.h"
+-
+-static void e100_config_long_rx(struct e100_private *bdp, unsigned char enable);
+-
+-static const u8 def_config[] = {
+-      CB_CFIG_BYTE_COUNT,
+-      0x08, 0x00, 0x00, 0x00, 0x00, 0x32, 0x07, 0x01,
+-      0x00, 0x2e, 0x00, 0x60, 0x00, 0xf2, 0xc8, 0x00,
+-      0x40, 0xf2, 0x80, 0x3f, 0x05
+-};
+-
+-/**
+- * e100_config_init_82557 - config the 82557 adapter
+- * @bdp: atapter's private data struct
+- *
+- * This routine will initialize the 82557 configure block.
+- * All other init functions will only set values that are
+- * different from the 82557 default.
+- */
+-void __devinit
+-e100_config_init_82557(struct e100_private *bdp)
+-{
+-      /* initialize config block */
+-      memcpy(bdp->config, def_config, sizeof (def_config));
+-      bdp->config[0] = CB_CFIG_BYTE_COUNT;    /* just in case */
+-
+-      e100_config_ifs(bdp);
+-
+-      /*
+-       * Enable extended statistical counters (82558 and up) and TCO counters
+-       * (82559 and up) and set the statistical counters' mode in bdp 
+-       *  
+-       *  stat. mode      |    TCO stat. bit (2)  |  Extended stat. bit (5)
+-       * ------------------------------------------------------------------
+-       *  Basic (557)     |       0               |         1
+-       * ------------------------------------------------------------------
+-       *  Extended (558)  |       0               |         0
+-       * ------------------------------------------------------------------
+-       *  TCO (559)       |       1               |         1
+-       * ------------------------------------------------------------------
+-       *  Reserved        |       1               |         0
+-       * ------------------------------------------------------------------
+-       */
+-      bdp->config[6] &= ~CB_CFIG_TCO_STAT;
+-      bdp->config[6] |= CB_CFIG_EXT_STAT_DIS;
+-      bdp->stat_mode = E100_BASIC_STATS;
+-
+-      /* Setup for MII or 503 operation.  The CRS+CDT bit should only be set */
+-      /* when operating in 503 mode. */
+-      if (bdp->phy_addr == 32) {
+-              bdp->config[8] &= ~CB_CFIG_503_MII;
+-              bdp->config[15] |= CB_CFIG_CRS_OR_CDT;
+-      } else {
+-              bdp->config[8] |= CB_CFIG_503_MII;
+-              bdp->config[15] &= ~CB_CFIG_CRS_OR_CDT;
+-      }
+-
+-      e100_config_fc(bdp);
+-      e100_config_force_dplx(bdp);
+-      e100_config_promisc(bdp, false);
+-      e100_config_mulcast_enbl(bdp, false);
+-}
+-
+-static void __devinit
+-e100_config_init_82558(struct e100_private *bdp)
+-{
+-      /* MWI enable. This should be turned on only if the adapter is a 82558/9
+-       * and if the PCI command reg. has enabled the MWI bit. */
+-      bdp->config[3] |= CB_CFIG_MWI_EN;
+-
+-      bdp->config[6] &= ~CB_CFIG_EXT_TCB_DIS;
+-
+-      if (bdp->rev_id >= D101MA_REV_ID) {
+-              /* this is 82559 and up - enable TCO counters */
+-              bdp->config[6] |= CB_CFIG_TCO_STAT;
+-              bdp->config[6] |= CB_CFIG_EXT_STAT_DIS;
+-              bdp->stat_mode = E100_TCO_STATS;
+-
+-              if ((bdp->rev_id < D102_REV_ID) &&
+-                  (bdp->params.b_params & PRM_XSUMRX) &&
+-                  (bdp->pdev->device != 0x1209)) {
+-
+-                      bdp->flags |= DF_CSUM_OFFLOAD;
+-                      bdp->config[9] |= 1;
+-              }
+-      } else {
+-              /* this is 82558 */
+-              bdp->config[6] &= ~CB_CFIG_TCO_STAT;
+-              bdp->config[6] &= ~CB_CFIG_EXT_STAT_DIS;
+-              bdp->stat_mode = E100_EXTENDED_STATS;
+-      }
+-
+-      e100_config_long_rx(bdp, true);
+-}
+-
+-static void __devinit
+-e100_config_init_82550(struct e100_private *bdp)
+-{
+-      /* The D102 chip allows for 32 config bytes.  This value is
+-       * supposed to be in Byte 0.  Just add the extra bytes to
+-       * what was already setup in the block. */
+-      bdp->config[0] += CB_CFIG_D102_BYTE_COUNT;
+-
+-      /* now we need to enable the extended RFD.  When this is
+-       * enabled, the immediated receive data buffer starts at offset
+-       * 32 from the RFD base address, instead of at offset 16. */
+-      bdp->config[7] |= CB_CFIG_EXTENDED_RFD;
+-
+-      /* put the chip into D102 receive mode.  This is necessary
+-       * for any parsing and offloading features. */
+-      bdp->config[22] = CB_CFIG_RECEIVE_GAMLA_MODE;
+-
+-      /* set the flag if checksum offloading was enabled */
+-      if (bdp->params.b_params & PRM_XSUMRX) {
+-              bdp->flags |= DF_CSUM_OFFLOAD;
+-      }
+-}
+-
+-/* Initialize the adapter's configure block */
+-void __devinit
+-e100_config_init(struct e100_private *bdp)
+-{
+-      e100_config_init_82557(bdp);
+-
+-      if (bdp->flags & IS_BACHELOR)
+-              e100_config_init_82558(bdp);
+-
+-      if (bdp->rev_id >= D102_REV_ID)
+-              e100_config_init_82550(bdp);
+-}
+-
+-/**
+- * e100_force_config - force a configure command
+- * @bdp: atapter's private data struct
+- *
+- * This routine will force a configure command to the adapter.
+- * The command will be executed in polled mode as interrupts
+- * are _disabled_ at this time.
+- *
+- * Returns:
+- *      true: if the configure command was successfully issued and completed
+- *      false: otherwise
+- */
+-unsigned char
+-e100_force_config(struct e100_private *bdp)
+-{
+-      spin_lock_bh(&(bdp->config_lock));
+-
+-      bdp->config[0] = CB_CFIG_BYTE_COUNT;
+-      if (bdp->rev_id >= D102_REV_ID) {
+-              /* The D102 chip allows for 32 config bytes.  This value is
+-                 supposed to be in Byte 0.  Just add the extra bytes to
+-                 what was already setup in the block. */
+-              bdp->config[0] += CB_CFIG_D102_BYTE_COUNT;
+-      }
+-
+-      spin_unlock_bh(&(bdp->config_lock));
+-
+-      // although we call config outside the lock, there is no
+-      // race condition because config byte count has maximum value
+-      return e100_config(bdp);
+-}
+-
+-/**
+- * e100_config - issue a configure command
+- * @bdp: atapter's private data struct
+- *
+- * This routine will issue a configure command to the 82557.
+- * This command will be executed in polled mode as interrupts
+- * are _disabled_ at this time.
+- *
+- * Returns:
+- *      true: if the configure command was successfully issued and completed
+- *      false: otherwise
+- */
+-unsigned char
+-e100_config(struct e100_private *bdp)
+-{
+-      cb_header_t *pntcb_hdr;
+-      unsigned char res = true;
+-      nxmit_cb_entry_t *cmd;
+-
+-      if (bdp->config[0] == 0) {
+-              goto exit;
+-      }
+-
+-      if ((cmd = e100_alloc_non_tx_cmd(bdp)) == NULL) {
+-              res = false;
+-              goto exit;
+-      }
+-
+-      pntcb_hdr = (cb_header_t *) cmd->non_tx_cmd;
+-      pntcb_hdr->cb_cmd = __constant_cpu_to_le16(CB_CONFIGURE);
+-
+-      spin_lock_bh(&bdp->config_lock);
+-
+-      if (bdp->config[0] < CB_CFIG_MIN_PARAMS) {
+-              bdp->config[0] = CB_CFIG_MIN_PARAMS;
+-      }
+-
+-      /* Copy the device's config block to the device's memory */
+-      memcpy(cmd->non_tx_cmd->ntcb.config.cfg_byte, bdp->config,
+-             bdp->config[0]);
+-      /* reset number of bytes to config next time */
+-      bdp->config[0] = 0;
+-
+-      spin_unlock_bh(&bdp->config_lock);
+-
+-      res = e100_exec_non_cu_cmd(bdp, cmd);
+-
+-exit:
+-      if (netif_running(bdp->device))
+-              netif_wake_queue(bdp->device);
+-      return res;
+-}
+-
+-/**
+- * e100_config_fc - config flow-control state
+- * @bdp: adapter's private data struct
+- *
+- * This routine will enable or disable flow control support in the adapter's
+- * config block. Flow control will be enable only if requested using the command
+- * line option, and if the link is flow-contorl capable (both us and the link
+- * partner). But, if link partner is capable of autoneg, but not capable of
+- * flow control, received PAUSE       frames are still honored.
+- */
+-void
+-e100_config_fc(struct e100_private *bdp)
+-{
+-      unsigned char enable = false;
+-      /* 82557 doesn't support fc. Don't touch this option */
+-      if (!(bdp->flags & IS_BACHELOR))
+-              return;
+-
+-      /* Enable fc if requested and if the link supports it */
+-      if ((bdp->params.b_params & PRM_FC) && (bdp->flags & 
+-              (DF_LINK_FC_CAP | DF_LINK_FC_TX_ONLY))) {
+-              enable = true;
+-      }
+-
+-      spin_lock_bh(&(bdp->config_lock));
+-
+-      if (enable) {
+-              if (bdp->flags & DF_LINK_FC_TX_ONLY) {
+-                      /* If link partner is capable of autoneg, but  */
+-                      /* not capable of flow control, Received PAUSE */
+-                      /* frames are still honored, i.e.,             */
+-                      /* transmitted frames would be paused by       */
+-                      /* incoming PAUSE frames                       */
+-                      bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
+-                      bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
+-                      bdp->config[19] &= ~(CB_CFIG_FC_RESTOP | CB_CFIG_FC_RESTART);
+-                      bdp->config[19] |= CB_CFIG_FC_REJECT;
+-                      bdp->config[19] &= ~CB_CFIG_TX_FC_DIS;
+-              } else {
+-                      bdp->config[16] = DFLT_FC_DELAY_LSB;
+-                      bdp->config[17] = DFLT_FC_DELAY_MSB;
+-                      bdp->config[19] |= CB_CFIG_FC_OPTS;
+-                      bdp->config[19] &= ~CB_CFIG_TX_FC_DIS;
+-              }
+-      } else {
+-              bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
+-              bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
+-              bdp->config[19] &= ~CB_CFIG_FC_OPTS;
+-              bdp->config[19] |= CB_CFIG_TX_FC_DIS;
+-      }
+-      E100_CONFIG(bdp, 19);
+-      spin_unlock_bh(&(bdp->config_lock));
+-
+-      return;
+-}
+-
+-/**
+- * e100_config_promisc - configure promiscuous mode
+- * @bdp: atapter's private data struct
+- * @enable: should we enable this option or not
+- *
+- * This routine will enable or disable promiscuous mode
+- * in the adapter's config block.
+- */
+-void
+-e100_config_promisc(struct e100_private *bdp, unsigned char enable)
+-{
+-      spin_lock_bh(&(bdp->config_lock));
+-
+-      /* if in promiscuous mode, save bad frames */
+-      if (enable) {
+-
+-              if (!(bdp->config[6] & CB_CFIG_SAVE_BAD_FRAMES)) {
+-                      bdp->config[6] |= CB_CFIG_SAVE_BAD_FRAMES;
+-                      E100_CONFIG(bdp, 6);
+-              }
+-
+-              if (bdp->config[7] & (u8) BIT_0) {
+-                      bdp->config[7] &= (u8) (~BIT_0);
+-                      E100_CONFIG(bdp, 7);
+-              }
+-
+-              if (!(bdp->config[15] & CB_CFIG_PROMISCUOUS)) {
+-                      bdp->config[15] |= CB_CFIG_PROMISCUOUS;
+-                      E100_CONFIG(bdp, 15);
+-              }
+-
+-      } else {                /* not in promiscuous mode */
+-
+-              if (bdp->config[6] & CB_CFIG_SAVE_BAD_FRAMES) {
+-                      bdp->config[6] &= ~CB_CFIG_SAVE_BAD_FRAMES;
+-                      E100_CONFIG(bdp, 6);
+-              }
+-
+-              if (!(bdp->config[7] & (u8) BIT_0)) {
+-                      bdp->config[7] |= (u8) (BIT_0);
+-                      E100_CONFIG(bdp, 7);
+-              }
+-
+-              if (bdp->config[15] & CB_CFIG_PROMISCUOUS) {
+-                      bdp->config[15] &= ~CB_CFIG_PROMISCUOUS;
+-                      E100_CONFIG(bdp, 15);
+-              }
+-      }
+-
+-      spin_unlock_bh(&(bdp->config_lock));
+-}
+-
+-/**
+- * e100_config_mulcast_enbl - configure allmulti mode
+- * @bdp: atapter's private data struct
+- * @enable: should we enable this option or not
+- *
+- * This routine will enable or disable reception of all multicast packets
+- * in the adapter's config block.
+- */
+-void
+-e100_config_mulcast_enbl(struct e100_private *bdp, unsigned char enable)
+-{
+-      spin_lock_bh(&(bdp->config_lock));
+-
+-      /* this flag is used to enable receiving all multicast packet */
+-      if (enable) {
+-              if (!(bdp->config[21] & CB_CFIG_MULTICAST_ALL)) {
+-                      bdp->config[21] |= CB_CFIG_MULTICAST_ALL;
+-                      E100_CONFIG(bdp, 21);
+-              }
+-
+-      } else {
+-              if (bdp->config[21] & CB_CFIG_MULTICAST_ALL) {
+-                      bdp->config[21] &= ~CB_CFIG_MULTICAST_ALL;
+-                      E100_CONFIG(bdp, 21);
+-              }
+-      }
+-
+-      spin_unlock_bh(&(bdp->config_lock));
+-}
+-
+-/**
+- * e100_config_ifs - configure the IFS parameter
+- * @bdp: atapter's private data struct
+- *
+- * This routine will configure the adaptive IFS value
+- * in the adapter's config block. IFS values are only
+- * relevant in half duplex, so set to 0 in full duplex.
+- */
+-void
+-e100_config_ifs(struct e100_private *bdp)
+-{
+-      u8 value = 0;
+-
+-      spin_lock_bh(&(bdp->config_lock));
+-
+-      /* IFS value is only needed to be specified at half-duplex mode */
+-      if (bdp->cur_dplx_mode == HALF_DUPLEX) {
+-              value = (u8) bdp->ifs_value;
+-      }
+-
+-      if (bdp->config[2] != value) {
+-              bdp->config[2] = value;
+-              E100_CONFIG(bdp, 2);
+-      }
+-
+-      spin_unlock_bh(&(bdp->config_lock));
+-}
+-
+-/**
+- * e100_config_force_dplx - configure the forced full duplex mode
+- * @bdp: atapter's private data struct
+- *
+- * This routine will enable or disable force full duplex
+- * in the adapter's config block. If the PHY is 503, and
+- * the duplex is full, consider the adapter forced.
+- */
+-void
+-e100_config_force_dplx(struct e100_private *bdp)
+-{
+-      spin_lock_bh(&(bdp->config_lock));
+-
+-      /* We must force full duplex on if we are using PHY 0, and we are */
+-      /* supposed to run in FDX mode. We do this because the e100 has only */
+-      /* one FDX# input pin, and that pin will be connected to PHY 1. */
+-      /* Changed the 'if' condition below to fix performance problem * at 10
+-       * full. The Phy was getting forced to full duplex while the MAC * was
+-       * not, because the cur_dplx_mode was not being set to 2 by SetupPhy. *
+-       * This is how the condition was, initially. * This has been changed so
+-       * that the MAC gets forced to full duplex * simply if the user has
+-       * forced full duplex. * * if (( bdp->phy_addr == 0 ) && (
+-       * bdp->cur_dplx_mode == 2 )) */
+-      /* The rest of the fix is in the PhyDetect code. */
+-      if ((bdp->params.e100_speed_duplex == E100_SPEED_10_FULL) ||
+-          (bdp->params.e100_speed_duplex == E100_SPEED_100_FULL) ||
+-          ((bdp->phy_addr == 32) && (bdp->cur_dplx_mode == FULL_DUPLEX))) {
+-              if (!(bdp->config[19] & (u8) CB_CFIG_FORCE_FDX)) {
+-                      bdp->config[19] |= (u8) CB_CFIG_FORCE_FDX;
+-                      E100_CONFIG(bdp, 19);
+-              }
+-
+-      } else {
+-              if (bdp->config[19] & (u8) CB_CFIG_FORCE_FDX) {
+-                      bdp->config[19] &= (u8) (~CB_CFIG_FORCE_FDX);
+-                      E100_CONFIG(bdp, 19);
+-              }
+-      }
+-
+-      spin_unlock_bh(&(bdp->config_lock));
+-}
+-
+-/**
+- * e100_config_long_rx
+- * @bdp: atapter's private data struct
+- * @enable: should we enable this option or not
+- *
+- * This routine will enable or disable reception of larger packets.
+- * This is needed by VLAN implementations.
+- */
+-static void
+-e100_config_long_rx(struct e100_private *bdp, unsigned char enable)
+-{
+-      if (enable) {
+-              if (!(bdp->config[18] & CB_CFIG_LONG_RX_OK)) {
+-                      bdp->config[18] |= CB_CFIG_LONG_RX_OK;
+-                      E100_CONFIG(bdp, 18);
+-              }
+-
+-      } else {
+-              if ((bdp->config[18] & CB_CFIG_LONG_RX_OK)) {
+-                      bdp->config[18] &= ~CB_CFIG_LONG_RX_OK;
+-                      E100_CONFIG(bdp, 18);
+-              }
+-      }
+-}
+-
+-/**
+- * e100_config_wol
+- * @bdp: atapter's private data struct
+- *
+- * This sets configuration options for PHY and Magic Packet WoL 
+- */
+-void
+-e100_config_wol(struct e100_private *bdp)
+-{
+-      spin_lock_bh(&(bdp->config_lock));
+-
+-      if (bdp->wolopts & WAKE_PHY) {
+-              bdp->config[9] |= CB_LINK_STATUS_WOL;
+-      }
+-      else {
+-              /* Disable PHY WoL */
+-              bdp->config[9] &= ~CB_LINK_STATUS_WOL;
+-      }
+-
+-      if (bdp->wolopts & WAKE_MAGIC) {
+-              bdp->config[19] &= ~CB_DISABLE_MAGPAK_WAKE;
+-      }
+-      else {
+-              /* Disable Magic Packet WoL */
+-              bdp->config[19] |= CB_DISABLE_MAGPAK_WAKE;
+-      }
+-
+-      E100_CONFIG(bdp, 19);
+-      spin_unlock_bh(&(bdp->config_lock));
+-}
+-
+-void
+-e100_config_vlan_drop(struct e100_private *bdp, unsigned char enable)
+-{
+-      spin_lock_bh(&(bdp->config_lock));
+-      if (enable) {
+-              if (!(bdp->config[22] & CB_CFIG_VLAN_DROP_ENABLE)) {
+-                      bdp->config[22] |= CB_CFIG_VLAN_DROP_ENABLE;
+-                      E100_CONFIG(bdp, 22);
+-              }
+-
+-      } else {
+-              if ((bdp->config[22] & CB_CFIG_VLAN_DROP_ENABLE)) {
+-                      bdp->config[22] &= ~CB_CFIG_VLAN_DROP_ENABLE;
+-                      E100_CONFIG(bdp, 22);
+-              }
+-      }
+-      spin_unlock_bh(&(bdp->config_lock));
+-}
+-
+-/**
+- * e100_config_loopback_mode
+- * @bdp: atapter's private data struct
+- * @mode: loopback mode(phy/mac/none)
+- *
+- */
+-unsigned char
+-e100_config_loopback_mode(struct e100_private *bdp, u8 mode)
+-{
+-      unsigned char bc_changed = false;
+-      u8 config_byte;
+-
+-      spin_lock_bh(&(bdp->config_lock));
+-
+-      switch (mode) {
+-      case NO_LOOPBACK:
+-              config_byte = CB_CFIG_LOOPBACK_NORMAL;
+-              break;
+-      case MAC_LOOPBACK:
+-              config_byte = CB_CFIG_LOOPBACK_INTERNAL;
+-              break;
+-      case PHY_LOOPBACK:
+-              config_byte = CB_CFIG_LOOPBACK_EXTERNAL;
+-              break;
+-      default:
+-              printk(KERN_NOTICE "e100: e100_config_loopback_mode: "
+-                     "Invalid argument 'mode': %d\n", mode);
+-              goto exit;
+-      }
+-
+-      if ((bdp->config[10] & CB_CFIG_LOOPBACK_MODE) != config_byte) {
+-
+-              bdp->config[10] &= (~CB_CFIG_LOOPBACK_MODE);
+-              bdp->config[10] |= config_byte;
+-              E100_CONFIG(bdp, 10);
+-              bc_changed = true;
+-      }
+-
+-exit:
+-      spin_unlock_bh(&(bdp->config_lock));
+-      return bc_changed;
+-}
+-unsigned char
+-e100_config_tcb_ext_enable(struct e100_private *bdp, unsigned char enable)
+-{
+-        unsigned char bc_changed = false;
+- 
+-        spin_lock_bh(&(bdp->config_lock));
+- 
+-        if (enable) {
+-                if (bdp->config[6] & CB_CFIG_EXT_TCB_DIS) {
+- 
+-                        bdp->config[6] &= (~CB_CFIG_EXT_TCB_DIS);
+-                        E100_CONFIG(bdp, 6);
+-                        bc_changed = true;
+-                }
+- 
+-        } else {
+-                if (!(bdp->config[6] & CB_CFIG_EXT_TCB_DIS)) {
+- 
+-                        bdp->config[6] |= CB_CFIG_EXT_TCB_DIS;
+-                        E100_CONFIG(bdp, 6);
+-                        bc_changed = true;
+-                }
+-        }
+-        spin_unlock_bh(&(bdp->config_lock));
+- 
+-        return bc_changed;
+-}
+-unsigned char
+-e100_config_dynamic_tbd(struct e100_private *bdp, unsigned char enable)
+-{
+-        unsigned char bc_changed = false;
+- 
+-        spin_lock_bh(&(bdp->config_lock));
+- 
+-        if (enable) {
+-                if (!(bdp->config[7] & CB_CFIG_DYNTBD_EN)) {
+- 
+-                        bdp->config[7] |= CB_CFIG_DYNTBD_EN;
+-                        E100_CONFIG(bdp, 7);
+-                        bc_changed = true;
+-                }
+- 
+-        } else {
+-                if (bdp->config[7] & CB_CFIG_DYNTBD_EN) {
+- 
+-                        bdp->config[7] &= (~CB_CFIG_DYNTBD_EN);
+-                        E100_CONFIG(bdp, 7);
+-                        bc_changed = true;
+-                }
+-        }
+-        spin_unlock_bh(&(bdp->config_lock));
+- 
+-        return bc_changed;
+-}
+-
+--- linux-2.6.0/drivers/net/e100/e100_config.h 2003-09-27 18:57:45.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,168 +0,0 @@
+-/*******************************************************************************
+-
+-  
+-  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+-  
+-  This program is free software; you can redistribute it and/or modify it 
+-  under the terms of the GNU General Public License as published by the Free 
+-  Software Foundation; either version 2 of the License, or (at your option) 
+-  any later version.
+-  
+-  This program is distributed in the hope that it will be useful, but WITHOUT 
+-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+-  more details.
+-  
+-  You should have received a copy of the GNU General Public License along with
+-  this program; if not, write to the Free Software Foundation, Inc., 59 
+-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+-  
+-  The full GNU General Public License is included in this distribution in the
+-  file called LICENSE.
+-  
+-  Contact Information:
+-  Linux NICS <linux.nics@intel.com>
+-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+-*******************************************************************************/
+-
+-#ifndef _E100_CONFIG_INC_
+-#define _E100_CONFIG_INC_
+-
+-#include "e100.h"
+-
+-#define E100_CONFIG(bdp, X) ((bdp)->config[0] = max_t(u8, (bdp)->config[0], (X)+1))
+-
+-#define CB_CFIG_MIN_PARAMS         8
+-
+-/* byte 0 bit definitions*/
+-#define CB_CFIG_BYTE_COUNT_MASK     BIT_0_5   /* Byte count occupies bit 5-0 */
+-
+-/* byte 1 bit definitions*/
+-#define CB_CFIG_RXFIFO_LIMIT_MASK   BIT_0_4   /* RxFifo limit mask */
+-#define CB_CFIG_TXFIFO_LIMIT_MASK   BIT_4_7   /* TxFifo limit mask */
+-
+-/* byte 2 bit definitions -- ADAPTIVE_IFS*/
+-
+-/* word 3 bit definitions -- RESERVED*/
+-/* Changed for 82558 enhancements */
+-/* byte 3 bit definitions */
+-#define CB_CFIG_MWI_EN      BIT_0     /* Enable MWI on PCI bus */
+-#define CB_CFIG_TYPE_EN     BIT_1     /* Type Enable */
+-#define CB_CFIG_READAL_EN   BIT_2     /* Enable Read Align */
+-#define CB_CFIG_TERMCL_EN   BIT_3     /* Cache line write  */
+-
+-/* byte 4 bit definitions*/
+-#define CB_CFIG_RX_MIN_DMA_MASK     BIT_0_6   /* Rx minimum DMA count mask */
+-
+-/* byte 5 bit definitions*/
+-#define CB_CFIG_TX_MIN_DMA_MASK BIT_0_6       /* Tx minimum DMA count mask */
+-#define CB_CFIG_DMBC_EN         BIT_7 /* Enable Tx/Rx min. DMA counts */
+-
+-/* Changed for 82558 enhancements */
+-/* byte 6 bit definitions*/
+-#define CB_CFIG_LATE_SCB           BIT_0      /* Update SCB After New Tx Start */
+-#define CB_CFIG_DIRECT_DMA_DIS     BIT_1      /* Direct DMA mode */
+-#define CB_CFIG_TNO_INT            BIT_2      /* Tx Not OK Interrupt */
+-#define CB_CFIG_TCO_STAT           BIT_2      /* TCO statistics in 559 and above */
+-#define CB_CFIG_CI_INT             BIT_3      /* Command Complete Interrupt */
+-#define CB_CFIG_EXT_TCB_DIS        BIT_4      /* Extended TCB */
+-#define CB_CFIG_EXT_STAT_DIS       BIT_5      /* Extended Stats */
+-#define CB_CFIG_SAVE_BAD_FRAMES    BIT_7      /* Save Bad Frames Enabled */
+-
+-/* byte 7 bit definitions*/
+-#define CB_CFIG_DISC_SHORT_FRAMES   BIT_0     /* Discard Short Frames */
+-#define CB_CFIG_DYNTBD_EN           BIT_7     /* Enable dynamic TBD */
+-/* Enable extended RFD's on D102 */
+-#define CB_CFIG_EXTENDED_RFD        BIT_5
+-
+-/* byte 8 bit definitions*/
+-#define CB_CFIG_503_MII             BIT_0     /* 503 vs. MII mode */
+-
+-/* byte 9 bit definitions -- pre-defined all zeros*/
+-#define CB_LINK_STATUS_WOL    BIT_5
+-
+-/* byte 10 bit definitions*/
+-#define CB_CFIG_NO_SRCADR       BIT_3 /* No Source Address Insertion */
+-#define CB_CFIG_PREAMBLE_LEN    BIT_4_5       /* Preamble Length */
+-#define CB_CFIG_LOOPBACK_MODE   BIT_6_7       /* Loopback Mode */
+-#define CB_CFIG_LOOPBACK_NORMAL 0
+-#define CB_CFIG_LOOPBACK_INTERNAL BIT_6
+-#define CB_CFIG_LOOPBACK_EXTERNAL BIT_6_7
+-
+-/* byte 11 bit definitions*/
+-#define CB_CFIG_LINEAR_PRIORITY     BIT_0_2   /* Linear Priority */
+-
+-/* byte 12 bit definitions*/
+-#define CB_CFIG_LINEAR_PRI_MODE     BIT_0     /* Linear Priority mode */
+-#define CB_CFIG_IFS_MASK            BIT_4_7   /* Interframe Spacing mask */
+-
+-/* byte 13 bit definitions -- pre-defined all zeros*/
+-
+-/* byte 14 bit definitions -- pre-defined 0xf2*/
+-
+-/* byte 15 bit definitions*/
+-#define CB_CFIG_PROMISCUOUS         BIT_0     /* Promiscuous Mode Enable */
+-#define CB_CFIG_BROADCAST_DIS       BIT_1     /* Broadcast Mode Disable */
+-#define CB_CFIG_CRS_OR_CDT          BIT_7     /* CRS Or CDT */
+-
+-/* byte 16 bit definitions -- pre-defined all zeros*/
+-#define DFLT_FC_DELAY_LSB  0x1f       /* Delay for outgoing Pause frames */
+-#define DFLT_NO_FC_DELAY_LSB  0x00    /* no flow control default value */
+-
+-/* byte 17 bit definitions -- pre-defined 0x40*/
+-#define DFLT_FC_DELAY_MSB  0x01       /* Delay for outgoing Pause frames */
+-#define DFLT_NO_FC_DELAY_MSB  0x40    /* no flow control default value */
+-
+-/* byte 18 bit definitions*/
+-#define CB_CFIG_STRIPPING           BIT_0     /* Padding Disabled */
+-#define CB_CFIG_PADDING             BIT_1     /* Padding Disabled */
+-#define CB_CFIG_CRC_IN_MEM          BIT_2     /* Transfer CRC To Memory */
+-
+-/* byte 19 bit definitions*/
+-#define CB_CFIG_TX_ADDR_WAKE        BIT_0     /* Address Wakeup */
+-#define CB_DISABLE_MAGPAK_WAKE      BIT_1     /* Magic Packet Wakeup disable */
+-/* Changed TX_FC_EN to TX_FC_DIS because 0 enables, 1 disables. Jul 8, 1999 */
+-#define CB_CFIG_TX_FC_DIS           BIT_2     /* Tx Flow Control Disable */
+-#define CB_CFIG_FC_RESTOP           BIT_3     /* Rx Flow Control Restop */
+-#define CB_CFIG_FC_RESTART          BIT_4     /* Rx Flow Control Restart */
+-#define CB_CFIG_FC_REJECT           BIT_5     /* Rx Flow Control Restart */
+-#define CB_CFIG_FC_OPTS (CB_CFIG_FC_RESTOP | CB_CFIG_FC_RESTART | CB_CFIG_FC_REJECT)
+-
+-/* end 82558/9 specifics */
+-
+-#define CB_CFIG_FORCE_FDX           BIT_6     /* Force Full Duplex */
+-#define CB_CFIG_FDX_ENABLE          BIT_7     /* Full Duplex Enabled */
+-
+-/* byte 20 bit definitions*/
+-#define CB_CFIG_MULTI_IA            BIT_6     /* Multiple IA Addr */
+-
+-/* byte 21 bit definitions*/
+-#define CB_CFIG_MULTICAST_ALL       BIT_3     /* Multicast All */
+-
+-/* byte 22 bit defines */
+-#define CB_CFIG_RECEIVE_GAMLA_MODE  BIT_0     /* D102 receive mode */
+-#define CB_CFIG_VLAN_DROP_ENABLE    BIT_1     /* vlan stripping */
+-
+-#define CB_CFIG_LONG_RX_OK        BIT_3
+-
+-#define NO_LOOPBACK   0       
+-#define MAC_LOOPBACK  0x01
+-#define PHY_LOOPBACK  0x02
+-
+-/* function prototypes */
+-extern void e100_config_init(struct e100_private *bdp);
+-extern void e100_config_init_82557(struct e100_private *bdp);
+-extern unsigned char e100_force_config(struct e100_private *bdp);
+-extern unsigned char e100_config(struct e100_private *bdp);
+-extern void e100_config_fc(struct e100_private *bdp);
+-extern void e100_config_promisc(struct e100_private *bdp, unsigned char enable);
+-extern void e100_config_brdcast_dsbl(struct e100_private *bdp);
+-extern void e100_config_mulcast_enbl(struct e100_private *bdp,
+-                                   unsigned char enable);
+-extern void e100_config_ifs(struct e100_private *bdp);
+-extern void e100_config_force_dplx(struct e100_private *bdp);
+-extern u8 e100_config_loopback_mode(struct e100_private *bdp, u8 mode);
+-extern u8 e100_config_dynamic_tbd(struct e100_private *bdp, u8 enable);
+-extern u8 e100_config_tcb_ext_enable(struct e100_private *bdp, u8 enable);
+-extern void e100_config_vlan_drop(struct e100_private *bdp, unsigned char enable);
+-#endif /* _E100_CONFIG_INC_ */
+--- linux-2.6.0/drivers/net/e100/e100_eeprom.c 2003-06-14 12:18:07.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,565 +0,0 @@
+-/*******************************************************************************
+-
+-  
+-  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+-  
+-  This program is free software; you can redistribute it and/or modify it 
+-  under the terms of the GNU General Public License as published by the Free 
+-  Software Foundation; either version 2 of the License, or (at your option) 
+-  any later version.
+-  
+-  This program is distributed in the hope that it will be useful, but WITHOUT 
+-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+-  more details.
+-  
+-  You should have received a copy of the GNU General Public License along with
+-  this program; if not, write to the Free Software Foundation, Inc., 59 
+-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+-  
+-  The full GNU General Public License is included in this distribution in the
+-  file called LICENSE.
+-  
+-  Contact Information:
+-  Linux NICS <linux.nics@intel.com>
+-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+-*******************************************************************************/
+-
+-/**********************************************************************
+-*                                                                     *
+-* INTEL CORPORATION                                                   *
+-*                                                                     *
+-* This software is supplied under the terms of the license included   *
+-* above.  All use of this driver must be in accordance with the terms *
+-* of that license.                                                    *
+-*                                                                     *
+-* Module Name:  e100_eeprom.c                                         *
+-*                                                                     *
+-* Abstract:     This module contains routines to read and write to a  *
+-*               serial EEPROM                                         *
+-*                                                                     *
+-* Environment:  This file is intended to be specific to the Linux     *
+-*               operating system.                                     *
+-*                                                                     *
+-**********************************************************************/
+-#include "e100.h"
+-
+-#define CSR_EEPROM_CONTROL_FIELD(bdp) ((bdp)->scb->scb_eprm_cntrl)
+-
+-#define CSR_GENERAL_CONTROL2_FIELD(bdp) \
+-                 ((bdp)->scb->scb_ext.d102_scb.scb_gen_ctrl2)
+-
+-#define EEPROM_STALL_TIME     4
+-#define EEPROM_CHECKSUM               ((u16) 0xBABA)
+-#define EEPROM_MAX_WORD_SIZE  256
+-
+-void e100_eeprom_cleanup(struct e100_private *adapter);
+-u16 e100_eeprom_calculate_chksum(struct e100_private *adapter);
+-static void e100_eeprom_write_word(struct e100_private *adapter, u16 reg,
+-                                 u16 data);
+-void e100_eeprom_write_block(struct e100_private *adapter, u16 start, u16 *data,
+-                           u16 size);
+-u16 e100_eeprom_size(struct e100_private *adapter);
+-u16 e100_eeprom_read(struct e100_private *adapter, u16 reg);
+-
+-static void shift_out_bits(struct e100_private *adapter, u16 data, u16 count);
+-static u16 shift_in_bits(struct e100_private *adapter);
+-static void raise_clock(struct e100_private *adapter, u16 *x);
+-static void lower_clock(struct e100_private *adapter, u16 *x);
+-static u16 eeprom_wait_cmd_done(struct e100_private *adapter);
+-static void eeprom_stand_by(struct e100_private *adapter);
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   eeprom_set_semaphore
+-//
+-// Description: This function set (write 1) Gamla EEPROM semaphore bit (bit 23 word 0x1C in the CSR).
+-//
+-// Arguments:
+-//      Adapter                 - Adapter context
+-//
+-// Returns:  true if success
+-//           else return false 
+-//
+-//----------------------------------------------------------------------------------------
+-
+-inline u8
+-eeprom_set_semaphore(struct e100_private *adapter)
+-{
+-      u16 data = 0;
+-      unsigned long expiration_time = jiffies + HZ / 100 + 1;
+-
+-      do {
+-              // Get current value of General Control 2
+-              data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
+-
+-              // Set bit 23 word 0x1C in the CSR.
+-              data |= SCB_GCR2_EEPROM_ACCESS_SEMAPHORE;
+-              writeb(data, &CSR_GENERAL_CONTROL2_FIELD(adapter));
+-
+-              // Check to see if this bit set or not.
+-              data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
+-
+-              if (data & SCB_GCR2_EEPROM_ACCESS_SEMAPHORE) {
+-                      return true;
+-              }
+-
+-              if (time_before(jiffies, expiration_time))
+-                      yield();
+-              else
+-                      return false;
+-
+-      } while (true);
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   eeprom_reset_semaphore
+-//
+-// Description: This function reset (write 0) Gamla EEPROM semaphore bit 
+-//              (bit 23 word 0x1C in the CSR).
+-//
+-// Arguments:  struct e100_private * adapter - Adapter context
+-//----------------------------------------------------------------------------------------
+-
+-inline void
+-eeprom_reset_semaphore(struct e100_private *adapter)
+-{
+-      u16 data = 0;
+-
+-      data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
+-      data &= ~(SCB_GCR2_EEPROM_ACCESS_SEMAPHORE);
+-      writeb(data, &CSR_GENERAL_CONTROL2_FIELD(adapter));
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   e100_eeprom_size
+-//
+-// Description: This routine determines the size of the EEPROM.  This value should be
+-//              checked for validity - ie. is it too big or too small.  The size returned
+-//              is then passed to the read/write functions.
+-//
+-// Returns:
+-//      Size of the eeprom, or zero if an error occurred
+-//----------------------------------------------------------------------------------------
+-u16
+-e100_eeprom_size(struct e100_private *adapter)
+-{
+-      u16 x, size = 1;        // must be one to accumulate a product
+-
+-      // if we've already stored this data, read from memory
+-      if (adapter->eeprom_size) {
+-              return adapter->eeprom_size;
+-      }
+-      // otherwise, read from the eeprom
+-      // Set EEPROM semaphore.
+-      if (adapter->rev_id >= D102_REV_ID) {
+-              if (!eeprom_set_semaphore(adapter))
+-                      return 0;
+-      }
+-      // enable the eeprom by setting EECS.
+-      x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
+-      x &= ~(EEDI | EEDO | EESK);
+-      x |= EECS;
+-      writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-
+-      // write the read opcode
+-      shift_out_bits(adapter, EEPROM_READ_OPCODE, 3);
+-
+-      // experiment to discover the size of the eeprom.  request register zero
+-      // and wait for the eeprom to tell us it has accepted the entire address.
+-      x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
+-      do {
+-              size *= 2;      // each bit of address doubles eeprom size
+-              x |= EEDO;      // set bit to detect "dummy zero"
+-              x &= ~EEDI;     // address consists of all zeros
+-
+-              writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-              readw(&(adapter->scb->scb_status));
+-              udelay(EEPROM_STALL_TIME);
+-              raise_clock(adapter, &x);
+-              lower_clock(adapter, &x);
+-
+-              // check for "dummy zero"
+-              x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
+-              if (size > EEPROM_MAX_WORD_SIZE) {
+-                      size = 0;
+-                      break;
+-              }
+-      } while (x & EEDO);
+-
+-      // read in the value requested
+-      (void) shift_in_bits(adapter);
+-      e100_eeprom_cleanup(adapter);
+-
+-      // Clear EEPROM Semaphore.
+-      if (adapter->rev_id >= D102_REV_ID) {
+-              eeprom_reset_semaphore(adapter);
+-      }
+-
+-      return size;
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   eeprom_address_size
+-//
+-// Description: determines the number of bits in an address for the eeprom acceptable
+-//              values are 64, 128, and 256
+-// Arguments: size of the eeprom
+-// Returns: bits in an address for that size eeprom
+-//----------------------------------------------------------------------------------------
+-
+-static inline int
+-eeprom_address_size(u16 size)
+-{
+-      int isize = size;
+-      
+-      return (ffs(isize) - 1);
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   e100_eeprom_read
+-//
+-// Description: This routine serially reads one word out of the EEPROM.
+-//
+-// Arguments:
+-//      adapter - our adapter context
+-//      reg - EEPROM word to read.
+-//
+-// Returns:
+-//      Contents of EEPROM word (reg).
+-//----------------------------------------------------------------------------------------
+-
+-u16
+-e100_eeprom_read(struct e100_private *adapter, u16 reg)
+-{
+-      u16 x, data, bits;
+-
+-      // Set EEPROM semaphore.
+-      if (adapter->rev_id >= D102_REV_ID) {
+-              if (!eeprom_set_semaphore(adapter))
+-                      return 0;
+-      }
+-      // eeprom size is initialized to zero
+-      if (!adapter->eeprom_size)
+-              adapter->eeprom_size = e100_eeprom_size(adapter);
+-
+-      bits = eeprom_address_size(adapter->eeprom_size);
+-
+-      // select EEPROM, reset bits, set EECS
+-      x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
+-
+-      x &= ~(EEDI | EEDO | EESK);
+-      x |= EECS;
+-      writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-
+-      // write the read opcode and register number in that order
+-      // The opcode is 3bits in length, reg is 'bits' bits long
+-      shift_out_bits(adapter, EEPROM_READ_OPCODE, 3);
+-      shift_out_bits(adapter, reg, bits);
+-
+-      // Now read the data (16 bits) in from the selected EEPROM word
+-      data = shift_in_bits(adapter);
+-
+-      e100_eeprom_cleanup(adapter);
+-
+-      // Clear EEPROM Semaphore.
+-      if (adapter->rev_id >= D102_REV_ID) {
+-              eeprom_reset_semaphore(adapter);
+-      }
+-
+-      return data;
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   shift_out_bits
+-//
+-// Description: This routine shifts data bits out to the EEPROM.
+-//
+-// Arguments:
+-//      data - data to send to the EEPROM.
+-//      count - number of data bits to shift out.
+-//
+-// Returns: (none)
+-//----------------------------------------------------------------------------------------
+-
+-static void
+-shift_out_bits(struct e100_private *adapter, u16 data, u16 count)
+-{
+-      u16 x, mask;
+-
+-      mask = 1 << (count - 1);
+-      x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
+-      x &= ~(EEDO | EEDI);
+-
+-      do {
+-              x &= ~EEDI;
+-              if (data & mask)
+-                      x |= EEDI;
+-
+-              writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-              readw(&(adapter->scb->scb_status)); /* flush command to card */
+-              udelay(EEPROM_STALL_TIME);
+-              raise_clock(adapter, &x);
+-              lower_clock(adapter, &x);
+-              mask = mask >> 1;
+-      } while (mask);
+-
+-      x &= ~EEDI;
+-      writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   raise_clock
+-//
+-// Description: This routine raises the EEPROM's clock input (EESK)
+-//
+-// Arguments:
+-//      x - Ptr to the EEPROM control register's current value
+-//
+-// Returns: (none)
+-//----------------------------------------------------------------------------------------
+-
+-void
+-raise_clock(struct e100_private *adapter, u16 *x)
+-{
+-      *x = *x | EESK;
+-      writew(*x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-      readw(&(adapter->scb->scb_status)); /* flush command to card */
+-      udelay(EEPROM_STALL_TIME);
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   lower_clock
+-//
+-// Description: This routine lower's the EEPROM's clock input (EESK)
+-//
+-// Arguments:
+-//      x - Ptr to the EEPROM control register's current value
+-//
+-// Returns: (none)
+-//----------------------------------------------------------------------------------------
+-
+-void
+-lower_clock(struct e100_private *adapter, u16 *x)
+-{
+-      *x = *x & ~EESK;
+-      writew(*x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-      readw(&(adapter->scb->scb_status)); /* flush command to card */
+-      udelay(EEPROM_STALL_TIME);
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   shift_in_bits
+-//
+-// Description: This routine shifts data bits in from the EEPROM.
+-//
+-// Arguments:
+-//
+-// Returns:
+-//      The contents of that particular EEPROM word
+-//----------------------------------------------------------------------------------------
+-
+-static u16
+-shift_in_bits(struct e100_private *adapter)
+-{
+-      u16 x, d, i;
+-
+-      x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
+-      x &= ~(EEDO | EEDI);
+-      d = 0;
+-
+-      for (i = 0; i < 16; i++) {
+-              d <<= 1;
+-              raise_clock(adapter, &x);
+-
+-              x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
+-
+-              x &= ~EEDI;
+-              if (x & EEDO)
+-                      d |= 1;
+-
+-              lower_clock(adapter, &x);
+-      }
+-
+-      return d;
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   e100_eeprom_cleanup
+-//
+-// Description: This routine returns the EEPROM to an idle state
+-//----------------------------------------------------------------------------------------
+-
+-void
+-e100_eeprom_cleanup(struct e100_private *adapter)
+-{
+-      u16 x;
+-
+-      x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
+-
+-      x &= ~(EECS | EEDI);
+-      writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-
+-      raise_clock(adapter, &x);
+-      lower_clock(adapter, &x);
+-}
+-
+-//**********************************************************************************
+-// Procedure:   e100_eeprom_update_chksum
+-//
+-// Description: Calculates the checksum and writes it to the EEProm. 
+-//              It calculates the checksum accroding to the formula: 
+-//                              Checksum = 0xBABA - (sum of first 63 words).
+-//
+-//-----------------------------------------------------------------------------------
+-u16
+-e100_eeprom_calculate_chksum(struct e100_private *adapter)
+-{
+-      u16 idx, xsum_index, checksum = 0;
+-
+-      // eeprom size is initialized to zero
+-      if (!adapter->eeprom_size)
+-              adapter->eeprom_size = e100_eeprom_size(adapter);
+-
+-      xsum_index = adapter->eeprom_size - 1;
+-      for (idx = 0; idx < xsum_index; idx++)
+-              checksum += e100_eeprom_read(adapter, idx);
+-
+-      checksum = EEPROM_CHECKSUM - checksum;
+-      return checksum;
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   e100_eeprom_write_word
+-//
+-// Description: This routine writes a word to a specific EEPROM location without.
+-//              taking EEPROM semaphore and updating checksum. 
+-//              Use e100_eeprom_write_block for the EEPROM update
+-// Arguments: reg - The EEPROM word that we are going to write to.
+-//            data - The data (word) that we are going to write to the EEPROM.
+-//----------------------------------------------------------------------------------------
+-static void
+-e100_eeprom_write_word(struct e100_private *adapter, u16 reg, u16 data)
+-{
+-      u16 x;
+-      u16 bits;
+-
+-      bits = eeprom_address_size(adapter->eeprom_size);
+-
+-      /* select EEPROM, mask off ASIC and reset bits, set EECS */
+-      x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
+-      x &= ~(EEDI | EEDO | EESK);
+-      writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-      readw(&(adapter->scb->scb_status)); /* flush command to card */
+-      udelay(EEPROM_STALL_TIME);
+-      x |= EECS;
+-      writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-
+-      shift_out_bits(adapter, EEPROM_EWEN_OPCODE, 5);
+-      shift_out_bits(adapter, reg, (u16) (bits - 2));
+-      if (!eeprom_wait_cmd_done(adapter))
+-              return;
+-
+-      /* write the new word to the EEPROM & send the write opcode the EEPORM */
+-      shift_out_bits(adapter, EEPROM_WRITE_OPCODE, 3);
+-
+-      /* select which word in the EEPROM that we are writing to */
+-      shift_out_bits(adapter, reg, bits);
+-
+-      /* write the data to the selected EEPROM word */
+-      shift_out_bits(adapter, data, 16);
+-      if (!eeprom_wait_cmd_done(adapter))
+-              return;
+-
+-      shift_out_bits(adapter, EEPROM_EWDS_OPCODE, 5);
+-      shift_out_bits(adapter, reg, (u16) (bits - 2));
+-      if (!eeprom_wait_cmd_done(adapter))
+-              return;
+-
+-      e100_eeprom_cleanup(adapter);
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   e100_eeprom_write_block
+-//
+-// Description: This routine writes a block of words starting from specified EEPROM 
+-//              location and updates checksum
+-// Arguments: reg - The EEPROM word that we are going to write to.
+-//            data - The data (word) that we are going to write to the EEPROM.
+-//----------------------------------------------------------------------------------------
+-void
+-e100_eeprom_write_block(struct e100_private *adapter, u16 start, u16 *data,
+-                      u16 size)
+-{
+-      u16 checksum;
+-      u16 i;
+-
+-      if (!adapter->eeprom_size)
+-              adapter->eeprom_size = e100_eeprom_size(adapter);
+-
+-      // Set EEPROM semaphore.
+-      if (adapter->rev_id >= D102_REV_ID) {
+-              if (!eeprom_set_semaphore(adapter))
+-                      return;
+-      }
+-
+-      for (i = 0; i < size; i++) {
+-              e100_eeprom_write_word(adapter, start + i, data[i]);
+-      }
+-      //Update checksum
+-      checksum = e100_eeprom_calculate_chksum(adapter);
+-      e100_eeprom_write_word(adapter, (adapter->eeprom_size - 1), checksum);
+-
+-      // Clear EEPROM Semaphore.
+-      if (adapter->rev_id >= D102_REV_ID) {
+-              eeprom_reset_semaphore(adapter);
+-      }
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   eeprom_wait_cmd_done
+-//
+-// Description: This routine waits for the the EEPROM to finish its command.  
+-//                              Specifically, it waits for EEDO (data out) to go high.
+-// Returns:     true - If the command finished
+-//              false - If the command never finished (EEDO stayed low)
+-//----------------------------------------------------------------------------------------
+-static u16
+-eeprom_wait_cmd_done(struct e100_private *adapter)
+-{
+-      u16 x;
+-      unsigned long expiration_time = jiffies + HZ / 100 + 1;
+-
+-      eeprom_stand_by(adapter);
+-
+-      do {
+-              rmb();
+-              x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
+-              if (x & EEDO)
+-                      return true;
+-              if (time_before(jiffies, expiration_time))
+-                      yield();
+-              else
+-                      return false;
+-      } while (true);
+-}
+-
+-//----------------------------------------------------------------------------------------
+-// Procedure:   eeprom_stand_by
+-//
+-// Description: This routine lowers the EEPROM chip select (EECS) for a few microseconds.
+-//----------------------------------------------------------------------------------------
+-static void
+-eeprom_stand_by(struct e100_private *adapter)
+-{
+-      u16 x;
+-
+-      x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
+-      x &= ~(EECS | EESK);
+-      writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-      readw(&(adapter->scb->scb_status)); /* flush command to card */
+-      udelay(EEPROM_STALL_TIME);
+-      x |= EECS;
+-      writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+-      readw(&(adapter->scb->scb_status)); /* flush command to card */
+-      udelay(EEPROM_STALL_TIME);
+-}
+--- linux-2.6.0/drivers/net/e100/e100.h        2003-09-27 18:57:45.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,999 +0,0 @@
+-/*******************************************************************************
+-
+-  
+-  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+-  
+-  This program is free software; you can redistribute it and/or modify it 
+-  under the terms of the GNU General Public License as published by the Free 
+-  Software Foundation; either version 2 of the License, or (at your option) 
+-  any later version.
+-  
+-  This program is distributed in the hope that it will be useful, but WITHOUT 
+-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+-  more details.
+-  
+-  You should have received a copy of the GNU General Public License along with
+-  this program; if not, write to the Free Software Foundation, Inc., 59 
+-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+-  
+-  The full GNU General Public License is included in this distribution in the
+-  file called LICENSE.
+-  
+-  Contact Information:
+-  Linux NICS <linux.nics@intel.com>
+-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+-*******************************************************************************/
+-
+-#ifndef _E100_INC_
+-#define _E100_INC_
+-
+-#include <linux/module.h>
+-#include <linux/types.h>
+-#include <linux/init.h>
+-#include <linux/mm.h>
+-#include <linux/errno.h>
+-#include <linux/ioport.h>
+-#include <linux/pci.h>
+-#include <linux/kernel.h>
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-#include <linux/skbuff.h>
+-#include <linux/delay.h>
+-#include <linux/timer.h>
+-#include <linux/slab.h>
+-#include <linux/interrupt.h>
+-#include <linux/string.h>
+-#include <linux/wait.h>
+-#include <linux/reboot.h>
+-#include <asm/io.h>
+-#include <asm/unaligned.h>
+-#include <asm/processor.h>
+-#include <linux/ethtool.h>
+-#include <linux/inetdevice.h>
+-#include <linux/bitops.h>
+-
+-#include <linux/if.h>
+-#include <asm/uaccess.h>
+-#include <linux/ip.h>
+-#include <linux/if_vlan.h>
+-#include <linux/mii.h>
+-
+-#define E100_CABLE_UNKNOWN    0
+-#define E100_CABLE_OK         1               
+-#define E100_CABLE_OPEN_NEAR  2       /* Open Circuit Near End  */
+-#define E100_CABLE_OPEN_FAR   3       /* Open Circuit Far End   */
+-#define E100_CABLE_SHORT_NEAR 4       /* Short Circuit Near End */
+-#define E100_CABLE_SHORT_FAR  5       /* Short Circuit Far End  */
+-
+-#define E100_REGS_LEN 2
+-/*
+- *  Configure parameters for buffers per controller.
+- *  If the machine this is being used on is a faster machine (i.e. > 150MHz)
+- *  and running on a 10MBS network then more queueing of data occurs. This
+- *  may indicate the some of the numbers below should be adjusted.  Here are
+- *  some typical numbers:
+- *                             MAX_TCB 64
+- *                             MAX_RFD 64
+- *  The default numbers give work well on most systems tests so no real
+- *  adjustments really need to take place.  Also, if the machine is connected
+- *  to a 100MBS network the numbers described above can be lowered from the
+- *  defaults as considerably less data will be queued.
+- */
+-
+-#define TX_FRAME_CNT   8      /* consecutive transmit frames per interrupt */
+-/* TX_FRAME_CNT must be less than MAX_TCB    */
+-
+-#define E100_DEFAULT_TCB   64
+-#define E100_MIN_TCB       2*TX_FRAME_CNT + 3 /* make room for at least 2 interrupts */
+-#define E100_MAX_TCB       1024
+-
+-#define E100_DEFAULT_RFD   64
+-#define E100_MIN_RFD       8
+-#define E100_MAX_RFD       1024
+-
+-#define E100_DEFAULT_XSUM         true
+-#define E100_DEFAULT_BER          ZLOCK_MAX_ERRORS
+-#define E100_DEFAULT_SPEED_DUPLEX 0
+-#define E100_DEFAULT_FC           0
+-#define E100_DEFAULT_IFS          true
+-#define E100_DEFAULT_UCODE        true
+-
+-#define TX_THRSHLD     8
+-
+-/* IFS parameters */
+-#define MIN_NUMBER_OF_TRANSMITS_100 1000
+-#define MIN_NUMBER_OF_TRANSMITS_10  100
+-
+-#define E100_MAX_NIC 16
+-
+-#define E100_MAX_SCB_WAIT     100     /* Max udelays in wait_scb */
+-#define E100_MAX_CU_IDLE_WAIT 50      /* Max udelays in wait_cus_idle */
+-
+-/* HWI feature related constant */
+-#define HWI_REGISTER_GRANULARITY        80    /* register granularity = 80 Cm */
+-#define HWI_NEAR_END_BOUNDARY           1000  /* Near end is defined as < 10 meters */
+-
+-/* CPUSAVER_BUNDLE_MAX: Sets the maximum number of frames that will be bundled.
+- * In some situations, such as the TCP windowing algorithm, it may be
+- * better to limit the growth of the bundle size than let it go as
+- * high as it can, because that could cause too much added latency.
+- * The default is six, because this is the number of packets in the
+- * default TCP window size.  A value of 1 would make CPUSaver indicate
+- * an interrupt for every frame received.  If you do not want to put
+- * a limit on the bundle size, set this value to xFFFF.
+- */
+-#define E100_DEFAULT_CPUSAVER_BUNDLE_MAX      6
+-#define E100_DEFAULT_CPUSAVER_INTERRUPT_DELAY 0x600
+-#define E100_DEFAULT_BUNDLE_SMALL_FR          false
+-
+-/* end of configurables */
+-
+-/* ====================================================================== */
+-/*                                hw                                      */
+-/* ====================================================================== */
+-
+-/* timeout for command completion */
+-#define E100_CMD_WAIT   100   /* iterations */
+-
+-struct driver_stats {
+-      struct net_device_stats net_stats;
+-
+-      unsigned long tx_late_col;
+-      unsigned long tx_ok_defrd;
+-      unsigned long tx_one_retry;
+-      unsigned long tx_mt_one_retry;
+-      unsigned long rcv_cdt_frames;
+-      unsigned long xmt_fc_pkts;
+-      unsigned long rcv_fc_pkts;
+-      unsigned long rcv_fc_unsupported;
+-      unsigned long xmt_tco_pkts;
+-      unsigned long rcv_tco_pkts;
+-      unsigned long rx_intr_pkts;
+-};
+-
+-/* TODO: kill me when we can do C99 */
+-#define false         (0)
+-#define true          (1)
+-
+-/* Changed for 82558 and 82559 enhancements */
+-/* defines for 82558/9 flow control CSR values */
+-#define DFLT_FC_THLD       0x00       /* Rx FIFO threshold of 0.5KB free  */
+-#define DFLT_FC_CMD        0x00       /* FC Command in CSR */
+-
+-/* ====================================================================== */
+-/*                              equates                                   */
+-/* ====================================================================== */
+-
+-/*
+- * These are general purpose defines 
+- */
+-
+-/* Bit Mask definitions */
+-#define BIT_0       0x0001
+-#define BIT_1       0x0002
+-#define BIT_2       0x0004
+-#define BIT_3       0x0008
+-#define BIT_4       0x0010
+-#define BIT_5       0x0020
+-#define BIT_6       0x0040
+-#define BIT_7       0x0080
+-#define BIT_8       0x0100
+-#define BIT_9       0x0200
+-#define BIT_10      0x0400
+-#define BIT_11      0x0800
+-#define BIT_12      0x1000
+-#define BIT_13      0x2000
+-#define BIT_14      0x4000
+-#define BIT_15      0x8000
+-#define BIT_28      0x10000000
+-
+-#define BIT_0_2     0x0007
+-#define BIT_0_3     0x000F
+-#define BIT_0_4     0x001F
+-#define BIT_0_5     0x003F
+-#define BIT_0_6     0x007F
+-#define BIT_0_7     0x00FF
+-#define BIT_0_8     0x01FF
+-#define BIT_0_13    0x3FFF
+-#define BIT_0_15    0xFFFF
+-#define BIT_1_2     0x0006
+-#define BIT_1_3     0x000E
+-#define BIT_2_5     0x003C
+-#define BIT_3_4     0x0018
+-#define BIT_4_5     0x0030
+-#define BIT_4_6     0x0070
+-#define BIT_4_7     0x00F0
+-#define BIT_5_7     0x00E0
+-#define BIT_5_12    0x1FE0
+-#define BIT_5_15    0xFFE0
+-#define BIT_6_7     0x00c0
+-#define BIT_7_11    0x0F80
+-#define BIT_8_10    0x0700
+-#define BIT_9_13    0x3E00
+-#define BIT_12_15   0xF000
+-#define BIT_8_15    0xFF00
+-
+-#define BIT_16_20   0x001F0000
+-#define BIT_21_25   0x03E00000
+-#define BIT_26_27   0x0C000000
+-
+-/* Transmit Threshold related constants */
+-#define DEFAULT_TX_PER_UNDERRUN         20000
+-
+-#define MAX_MULTICAST_ADDRS             64
+-#define MAX_FILTER                      16
+-
+-#define FULL_DUPLEX      2
+-#define HALF_DUPLEX      1
+-
+-/*
+- * These defines are specific to the 82557 
+- */
+-
+-/* E100 PORT functions -- lower 4 bits */
+-#define PORT_SOFTWARE_RESET         0
+-#define PORT_SELFTEST               1
+-#define PORT_SELECTIVE_RESET        2
+-#define PORT_DUMP                   3
+-
+-/* SCB Status Word bit definitions */
+-/* Interrupt status/ack fields */
+-/* ER and FCP interrupts for 82558 masks  */
+-#define SCB_STATUS_ACK_MASK        BIT_8_15   /* Status Mask */
+-#define SCB_STATUS_ACK_CX          BIT_15     /* CU Completed Action Cmd */
+-#define SCB_STATUS_ACK_FR          BIT_14     /* RU Received A Frame */
+-#define SCB_STATUS_ACK_CNA         BIT_13     /* CU Became Inactive (IDLE) */
+-#define SCB_STATUS_ACK_RNR         BIT_12     /* RU Became Not Ready */
+-#define SCB_STATUS_ACK_MDI         BIT_11     /* MDI read or write done */
+-#define SCB_STATUS_ACK_SWI         BIT_10     /* S/W generated interrupt */
+-#define SCB_STATUS_ACK_ER          BIT_9      /* Early Receive */
+-#define SCB_STATUS_ACK_FCP         BIT_8      /* Flow Control Pause */
+-
+-/*- CUS Fields */
+-#define SCB_CUS_MASK            (BIT_6 | BIT_7)       /* CUS 2-bit Mask */
+-#define SCB_CUS_IDLE            0     /* CU Idle */
+-#define SCB_CUS_SUSPEND         BIT_6 /* CU Suspended */
+-#define SCB_CUS_ACTIVE          BIT_7 /* CU Active */
+-
+-/*- RUS Fields */
+-#define SCB_RUS_IDLE            0     /* RU Idle */
+-#define SCB_RUS_MASK            BIT_2_5       /* RUS 3-bit Mask */
+-#define SCB_RUS_SUSPEND         BIT_2 /* RU Suspended */
+-#define SCB_RUS_NO_RESOURCES    BIT_3 /* RU Out Of Resources */
+-#define SCB_RUS_READY           BIT_4 /* RU Ready */
+-#define SCB_RUS_SUSP_NO_RBDS    (BIT_2 | BIT_5)       /* RU No More RBDs */
+-#define SCB_RUS_NO_RBDS         (BIT_3 | BIT_5)       /* RU No More RBDs */
+-#define SCB_RUS_READY_NO_RBDS   (BIT_4 | BIT_5)       /* RU Ready, No RBDs */
+-
+-/* SCB Command Word bit definitions */
+-/*- CUC fields */
+-/* Changing mask to 4 bits */
+-#define SCB_CUC_MASK            BIT_4_7       /* CUC 4-bit Mask */
+-#define SCB_CUC_NOOP            0
+-#define SCB_CUC_START           BIT_4 /* CU Start */
+-#define SCB_CUC_RESUME          BIT_5 /* CU Resume */
+-#define SCB_CUC_UNKNOWN         BIT_7 /* CU unknown command */
+-/* Changed for 82558 enhancements */
+-#define SCB_CUC_STATIC_RESUME   (BIT_5 | BIT_7)       /* 82558/9 Static Resume */
+-#define SCB_CUC_DUMP_ADDR       BIT_6 /* CU Dump Counters Address */
+-#define SCB_CUC_DUMP_STAT       (BIT_4 | BIT_6)       /* CU Dump stat. counters */
+-#define SCB_CUC_LOAD_BASE       (BIT_5 | BIT_6)       /* Load the CU base */
+-/* Below was defined as BIT_4_7 */
+-#define SCB_CUC_DUMP_RST_STAT   BIT_4_6       /* CU Dump & reset statistics cntrs */
+-
+-/*- RUC fields */
+-#define SCB_RUC_MASK            BIT_0_2       /* RUC 3-bit Mask */
+-#define SCB_RUC_START           BIT_0 /* RU Start */
+-#define SCB_RUC_RESUME          BIT_1 /* RU Resume */
+-#define SCB_RUC_ABORT           BIT_2 /* RU Abort */
+-#define SCB_RUC_LOAD_HDS        (BIT_0 | BIT_2)       /* Load RFD Header Data Size */
+-#define SCB_RUC_LOAD_BASE       (BIT_1 | BIT_2)       /* Load the RU base */
+-#define SCB_RUC_RBD_RESUME      BIT_0_2       /* RBD resume */
+-
+-/* Interrupt fields (assuming byte addressing) */
+-#define SCB_INT_MASK            BIT_0 /* Mask interrupts */
+-#define SCB_SOFT_INT            BIT_1 /* Generate a S/W interrupt */
+-/*  Specific Interrupt Mask Bits (upper byte of SCB Command word) */
+-#define SCB_FCP_INT_MASK        BIT_2 /* Flow Control Pause */
+-#define SCB_ER_INT_MASK         BIT_3 /* Early Receive */
+-#define SCB_RNR_INT_MASK        BIT_4 /* RU Not Ready */
+-#define SCB_CNA_INT_MASK        BIT_5 /* CU Not Active */
+-#define SCB_FR_INT_MASK         BIT_6 /* Frame Received */
+-#define SCB_CX_INT_MASK         BIT_7 /* CU eXecution w/ I-bit done */
+-#define SCB_BACHELOR_INT_MASK   BIT_2_7       /* 82558 interrupt mask bits */
+-
+-#define SCB_GCR2_EEPROM_ACCESS_SEMAPHORE BIT_7
+-
+-/* EEPROM bit definitions */
+-/*- EEPROM control register bits */
+-#define EEPROM_FLAG_ASF  0x8000
+-#define EEPROM_FLAG_GCL  0x4000
+-
+-#define EN_TRNF          0x10 /* Enable turnoff */
+-#define EEDO             0x08 /* EEPROM data out */
+-#define EEDI             0x04 /* EEPROM data in (set for writing data) */
+-#define EECS             0x02 /* EEPROM chip select (1=hi, 0=lo) */
+-#define EESK             0x01 /* EEPROM shift clock (1=hi, 0=lo) */
+-
+-/*- EEPROM opcodes */
+-#define EEPROM_READ_OPCODE          06
+-#define EEPROM_WRITE_OPCODE         05
+-#define EEPROM_ERASE_OPCODE         07
+-#define EEPROM_EWEN_OPCODE          19        /* Erase/write enable */
+-#define EEPROM_EWDS_OPCODE          16        /* Erase/write disable */
+-
+-/*- EEPROM data locations */
+-#define EEPROM_NODE_ADDRESS_BYTE_0      0
+-#define EEPROM_COMPATIBILITY_WORD       3
+-#define EEPROM_PWA_NO                   8
+-#define EEPROM_ID_WORD                        0x0A
+-#define EEPROM_CONFIG_ASF             0x0D
+-#define EEPROM_SMBUS_ADDR             0x90
+-
+-#define EEPROM_SUM                      0xbaba
+-
+-// Zero Locking Algorithm definitions:
+-#define ZLOCK_ZERO_MASK               0x00F0
+-#define ZLOCK_MAX_READS               50      
+-#define ZLOCK_SET_ZERO                0x2010
+-#define ZLOCK_MAX_SLEEP               300 * HZ        
+-#define ZLOCK_MAX_ERRORS      300
+-
+-/* E100 Action Commands */
+-#define CB_IA_ADDRESS           1
+-#define CB_CONFIGURE            2
+-#define CB_MULTICAST            3
+-#define CB_TRANSMIT             4
+-#define CB_LOAD_MICROCODE       5
+-#define CB_LOAD_FILTER                8
+-#define CB_MAX_NONTX_CMD        9
+-#define CB_IPCB_TRANSMIT        9
+-
+-/* Pre-defined Filter Bits */
+-#define CB_FILTER_EL            0x80000000
+-#define CB_FILTER_FIX           0x40000000
+-#define CB_FILTER_ARP           0x08000000
+-#define CB_FILTER_IA_MATCH      0x02000000
+-
+-/* Command Block (CB) Field Definitions */
+-/*- CB Command Word */
+-#define CB_EL_BIT           BIT_15    /* CB EL Bit */
+-#define CB_S_BIT            BIT_14    /* CB Suspend Bit */
+-#define CB_I_BIT            BIT_13    /* CB Interrupt Bit */
+-#define CB_TX_SF_BIT        BIT_3     /* TX CB Flexible Mode */
+-#define CB_CMD_MASK         BIT_0_3   /* CB 4-bit CMD Mask */
+-#define CB_CID_DEFAULT      (0x1f << 8)       /* CB 5-bit CID (max value) */
+-
+-/*- CB Status Word */
+-#define CB_STATUS_MASK          BIT_12_15     /* CB Status Mask (4-bits) */
+-#define CB_STATUS_COMPLETE      BIT_15        /* CB Complete Bit */
+-#define CB_STATUS_OK            BIT_13        /* CB OK Bit */
+-#define CB_STATUS_VLAN          BIT_12 /* CB Valn detected Bit */
+-#define CB_STATUS_FAIL          BIT_11        /* CB Fail (F) Bit */
+-
+-/*misc command bits */
+-#define CB_TX_EOF_BIT           BIT_15        /* TX CB/TBD EOF Bit */
+-
+-/* Config params */
+-#define CB_CFIG_BYTE_COUNT          22        /* 22 config bytes */
+-#define CB_CFIG_D102_BYTE_COUNT    10
+-
+-/* Receive Frame Descriptor Fields */
+-
+-/*- RFD Status Bits */
+-#define RFD_RECEIVE_COLLISION   BIT_0 /* Collision detected on Receive */
+-#define RFD_IA_MATCH            BIT_1 /* Indv Address Match Bit */
+-#define RFD_RX_ERR              BIT_4 /* RX_ERR pin on Phy was set */
+-#define RFD_FRAME_TOO_SHORT     BIT_7 /* Receive Frame Short */
+-#define RFD_DMA_OVERRUN         BIT_8 /* Receive DMA Overrun */
+-#define RFD_NO_RESOURCES        BIT_9 /* No Buffer Space */
+-#define RFD_ALIGNMENT_ERROR     BIT_10        /* Alignment Error */
+-#define RFD_CRC_ERROR           BIT_11        /* CRC Error */
+-#define RFD_STATUS_OK           BIT_13        /* RFD OK Bit */
+-#define RFD_STATUS_COMPLETE     BIT_15        /* RFD Complete Bit */
+-
+-/*- RFD Command Bits*/
+-#define RFD_EL_BIT      BIT_15        /* RFD EL Bit */
+-#define RFD_S_BIT       BIT_14        /* RFD Suspend Bit */
+-#define RFD_H_BIT       BIT_4 /* Header RFD Bit */
+-#define RFD_SF_BIT      BIT_3 /* RFD Flexible Mode */
+-
+-/*- RFD misc bits*/
+-#define RFD_EOF_BIT         BIT_15    /* RFD End-Of-Frame Bit */
+-#define RFD_F_BIT           BIT_14    /* RFD Buffer Fetch Bit */
+-#define RFD_ACT_COUNT_MASK  BIT_0_13  /* RFD Actual Count Mask */
+-
+-/* Receive Buffer Descriptor Fields*/
+-#define RBD_EOF_BIT             BIT_15        /* RBD End-Of-Frame Bit */
+-#define RBD_F_BIT               BIT_14        /* RBD Buffer Fetch Bit */
+-#define RBD_ACT_COUNT_MASK      BIT_0_13      /* RBD Actual Count Mask */
+-
+-#define SIZE_FIELD_MASK     BIT_0_13  /* Size of the associated buffer */
+-#define RBD_EL_BIT          BIT_15    /* RBD EL Bit */
+-
+-/* Self Test Results*/
+-#define CB_SELFTEST_FAIL_BIT        BIT_12
+-#define CB_SELFTEST_DIAG_BIT        BIT_5
+-#define CB_SELFTEST_REGISTER_BIT    BIT_3
+-#define CB_SELFTEST_ROM_BIT         BIT_2
+-
+-#define CB_SELFTEST_ERROR_MASK ( \
+-                CB_SELFTEST_FAIL_BIT | CB_SELFTEST_DIAG_BIT | \
+-                CB_SELFTEST_REGISTER_BIT | CB_SELFTEST_ROM_BIT)
+-
+-/* adapter vendor & device ids */
+-#define PCI_OHIO_BOARD   0x10f0       /* subdevice ID, Ohio dual port nic */
+-
+-/* Values for PCI_REV_ID_REGISTER values */
+-#define D101A4_REV_ID      4  /* 82558 A4 stepping */
+-#define D101B0_REV_ID      5  /* 82558 B0 stepping */
+-#define D101MA_REV_ID      8  /* 82559 A0 stepping */
+-#define D101S_REV_ID      9   /* 82559S A-step */
+-#define D102_REV_ID      12
+-#define D102C_REV_ID     13   /* 82550 step C */
+-#define D102E_REV_ID     15
+-
+-/* ############Start of 82555 specific defines################## */
+-
+-#define PHY_82555_LED_SWITCH_CONTROL          0x1b    /* 82555 led switch control register */
+-
+-/* 82555 led switch control reg. opcodes */
+-#define PHY_82555_LED_NORMAL_CONTROL    0     // control back to the 8255X
+-#define PHY_82555_LED_DRIVER_CONTROL    BIT_2 // the driver is in control
+-#define PHY_82555_LED_OFF               BIT_2 // activity LED is off
+-#define PHY_82555_LED_ON_559           (BIT_0 | BIT_2)        // activity LED is on for 559 and later
+-#define PHY_82555_LED_ON_PRE_559       (BIT_0 | BIT_1 | BIT_2)        // activity LED is on for 558 and before
+-
+-// Describe the state of the phy led.
+-// needed for the function : 'e100_blink_timer'
+-enum led_state_e {
+-      LED_OFF = 0,
+-      LED_ON,
+-};
+-
+-/* ############End of 82555 specific defines##################### */
+-
+-#define RFD_PARSE_BIT                 BIT_3
+-#define RFD_TCP_PACKET                        0x00
+-#define RFD_UDP_PACKET                        0x01
+-#define TCPUDP_CHECKSUM_BIT_VALID     BIT_4
+-#define TCPUDP_CHECKSUM_VALID         BIT_5
+-#define CHECKSUM_PROTOCOL_MASK                0x03
+-
+-#define VLAN_SIZE   4
+-#define CHKSUM_SIZE 2
+-#define RFD_DATA_SIZE (ETH_FRAME_LEN + CHKSUM_SIZE + VLAN_SIZE)
+-
+-/* Bits for bdp->flags */
+-#define DF_LINK_FC_CAP     0x00000001 /* Link is flow control capable */
+-#define DF_CSUM_OFFLOAD    0x00000002
+-#define DF_UCODE_LOADED    0x00000004
+-#define USE_IPCB           0x00000008 /* set if using ipcb for transmits */
+-#define IS_BACHELOR        0x00000010 /* set if 82558 or newer board */
+-#define IS_ICH             0x00000020
+-#define DF_SPEED_FORCED    0x00000040 /* set if speed is forced */
+-#define LED_IS_ON        0x00000080   /* LED is turned ON by the driver */
+-#define DF_LINK_FC_TX_ONLY 0x00000100 /* Received PAUSE frames are honored*/
+-
+-typedef struct net_device_stats net_dev_stats_t;
+-
+-/* needed macros */
+-/* These macros use the bdp pointer. If you use them it better be defined */
+-#define PREV_TCB_USED(X)  ((X).tail ? (X).tail - 1 : bdp->params.TxDescriptors - 1)
+-#define NEXT_TCB_TOUSE(X) ((((X) + 1) >= bdp->params.TxDescriptors) ? 0 : (X) + 1)
+-#define TCB_TO_USE(X)     ((X).tail)
+-#define TCBS_AVAIL(X)     (NEXT_TCB_TOUSE( NEXT_TCB_TOUSE((X).tail)) != (X).head)
+-
+-#define RFD_POINTER(skb,bdp)      ((rfd_t *) (((unsigned char *)((skb)->data))-((bdp)->rfd_size)))
+-#define SKB_RFD_STATUS(skb,bdp)   ((RFD_POINTER((skb),(bdp)))->rfd_header.cb_status)
+-
+-/* ====================================================================== */
+-/*                              82557                                     */
+-/* ====================================================================== */
+-
+-/* Changed for 82558 enhancement */
+-typedef struct _d101_scb_ext_t {
+-      u32 scb_rx_dma_cnt;     /* Rx DMA byte count */
+-      u8 scb_early_rx_int;    /* Early Rx DMA byte count */
+-      u8 scb_fc_thld; /* Flow Control threshold */
+-      u8 scb_fc_xon_xoff;     /* Flow Control XON/XOFF values */
+-      u8 scb_pmdr;    /* Power Mgmt. Driver Reg */
+-} d101_scb_ext __attribute__ ((__packed__));
+-
+-/* Changed for 82559 enhancement */
+-typedef struct _d101m_scb_ext_t {
+-      u32 scb_rx_dma_cnt;     /* Rx DMA byte count */
+-      u8 scb_early_rx_int;    /* Early Rx DMA byte count */
+-      u8 scb_fc_thld; /* Flow Control threshold */
+-      u8 scb_fc_xon_xoff;     /* Flow Control XON/XOFF values */
+-      u8 scb_pmdr;    /* Power Mgmt. Driver Reg */
+-      u8 scb_gen_ctrl;        /* General Control */
+-      u8 scb_gen_stat;        /* General Status */
+-      u16 scb_reserved;       /* Reserved */
+-      u32 scb_function_event; /* Cardbus Function Event */
+-      u32 scb_function_event_mask;    /* Cardbus Function Mask */
+-      u32 scb_function_present_state; /* Cardbus Function state */
+-      u32 scb_force_event;    /* Cardbus Force Event */
+-} d101m_scb_ext __attribute__ ((__packed__));
+-
+-/* Changed for 82550 enhancement */
+-typedef struct _d102_scb_ext_t {
+-      u32 scb_rx_dma_cnt;     /* Rx DMA byte count */
+-      u8 scb_early_rx_int;    /* Early Rx DMA byte count */
+-      u8 scb_fc_thld; /* Flow Control threshold */
+-      u8 scb_fc_xon_xoff;     /* Flow Control XON/XOFF values */
+-      u8 scb_pmdr;    /* Power Mgmt. Driver Reg */
+-      u8 scb_gen_ctrl;        /* General Control */
+-      u8 scb_gen_stat;        /* General Status */
+-      u8 scb_gen_ctrl2;
+-      u8 scb_reserved;        /* Reserved */
+-      u32 scb_scheduling_reg;
+-      u32 scb_reserved2;
+-      u32 scb_function_event; /* Cardbus Function Event */
+-      u32 scb_function_event_mask;    /* Cardbus Function Mask */
+-      u32 scb_function_present_state; /* Cardbus Function state */
+-      u32 scb_force_event;    /* Cardbus Force Event */
+-} d102_scb_ext __attribute__ ((__packed__));
+-
+-/*
+- * 82557 status control block. this will be memory mapped & will hang of the
+- * the bdp, which hangs of the bdp. This is the brain of it.
+- */
+-typedef struct _scb_t {
+-      u16 scb_status; /* SCB Status register */
+-      u8 scb_cmd_low; /* SCB Command register (low byte) */
+-      u8 scb_cmd_hi;  /* SCB Command register (high byte) */
+-      u32 scb_gen_ptr;        /* SCB General pointer */
+-      u32 scb_port;   /* PORT register */
+-      u16 scb_flsh_cntrl;     /* Flash Control register */
+-      u16 scb_eprm_cntrl;     /* EEPROM control register */
+-      u32 scb_mdi_cntrl;      /* MDI Control Register */
+-      /* Changed for 82558 enhancement */
+-      union {
+-              u32 scb_rx_dma_cnt;     /* Rx DMA byte count */
+-              d101_scb_ext d101_scb;  /* 82558/9 specific fields */
+-              d101m_scb_ext d101m_scb;        /* 82559 specific fields */
+-              d102_scb_ext d102_scb;
+-      } scb_ext;
+-} scb_t __attribute__ ((__packed__));
+-
+-/* Self test
+- * This is used to dump results of the self test 
+- */
+-typedef struct _self_test_t {
+-      u32 st_sign;    /* Self Test Signature */
+-      u32 st_result;  /* Self Test Results */
+-} self_test_t __attribute__ ((__packed__));
+-
+-/* 
+- *  Statistical Counters 
+- */
+-/* 82557 counters */
+-typedef struct _basic_cntr_t {
+-      u32 xmt_gd_frames;      /* Good frames transmitted */
+-      u32 xmt_max_coll;       /* Fatal frames -- had max collisions */
+-      u32 xmt_late_coll;      /* Fatal frames -- had a late coll. */
+-      u32 xmt_uruns;  /* Xmit underruns (fatal or re-transmit) */
+-      u32 xmt_lost_crs;       /* Frames transmitted without CRS */
+-      u32 xmt_deferred;       /* Deferred transmits */
+-      u32 xmt_sngl_coll;      /* Transmits that had 1 and only 1 coll. */
+-      u32 xmt_mlt_coll;       /* Transmits that had multiple coll. */
+-      u32 xmt_ttl_coll;       /* Transmits that had 1+ collisions. */
+-      u32 rcv_gd_frames;      /* Good frames received */
+-      u32 rcv_crc_errs;       /* Aligned frames that had a CRC error */
+-      u32 rcv_algn_errs;      /* Receives that had alignment errors */
+-      u32 rcv_rsrc_err;       /* Good frame dropped cuz no resources */
+-      u32 rcv_oruns;  /* Overrun errors - bus was busy */
+-      u32 rcv_err_coll;       /* Received frms. that encountered coll. */
+-      u32 rcv_shrt_frames;    /* Received frames that were to short */
+-} basic_cntr_t;
+-
+-/* 82558 extended statistic counters */
+-typedef struct _ext_cntr_t {
+-      u32 xmt_fc_frames;
+-      u32 rcv_fc_frames;
+-      u32 rcv_fc_unsupported;
+-} ext_cntr_t;
+-
+-/* 82559 TCO statistic counters */
+-typedef struct _tco_cntr_t {
+-      u16 xmt_tco_frames;
+-      u16 rcv_tco_frames;
+-} tco_cntr_t;
+-
+-/* Structures to access thet physical dump area */
+-/* Use one of these types, according to the statisitcal counters mode,
+-   to cast the pointer to the physical dump area and access the cmd_complete
+-   DWORD. */
+-
+-/* 557-mode : only basic counters + cmd_complete */
+-typedef struct _err_cntr_557_t {
+-      basic_cntr_t basic_stats;
+-      u32 cmd_complete;
+-} err_cntr_557_t;
+-
+-/* 558-mode : basic + extended counters + cmd_complete */
+-typedef struct _err_cntr_558_t {
+-      basic_cntr_t basic_stats;
+-      ext_cntr_t extended_stats;
+-      u32 cmd_complete;
+-} err_cntr_558_t;
+-
+-/* 559-mode : basic + extended + TCO counters + cmd_complete */
+-typedef struct _err_cntr_559_t {
+-      basic_cntr_t basic_stats;
+-      ext_cntr_t extended_stats;
+-      tco_cntr_t tco_stats;
+-      u32 cmd_complete;
+-} err_cntr_559_t;
+-
+-/* This typedef defines the struct needed to hold the largest number of counters */
+-typedef err_cntr_559_t max_counters_t;
+-
+-/* Different statistical-counters mode the controller may be in */
+-typedef enum _stat_mode_t {
+-      E100_BASIC_STATS = 0,   /* 82557 stats : 16 counters / 16 dw */
+-      E100_EXTENDED_STATS,    /* 82558 stats : 19 counters / 19 dw */
+-      E100_TCO_STATS          /* 82559 stats : 21 counters / 20 dw */
+-} stat_mode_t;
+-
+-/* dump statistical counters complete codes */
+-#define DUMP_STAT_COMPLETED   0xA005
+-#define DUMP_RST_STAT_COMPLETED       0xA007
+-
+-/* Command Block (CB) Generic Header Structure*/
+-typedef struct _cb_header_t {
+-      u16 cb_status;  /* Command Block Status */
+-      u16 cb_cmd;     /* Command Block Command */
+-      u32 cb_lnk_ptr; /* Link To Next CB */
+-} cb_header_t __attribute__ ((__packed__));
+-
+-//* Individual Address Command Block (IA_CB)*/
+-typedef struct _ia_cb_t {
+-      cb_header_t ia_cb_hdr;
+-      u8 ia_addr[ETH_ALEN];
+-} ia_cb_t __attribute__ ((__packed__));
+-
+-/* Configure Command Block (CONFIG_CB)*/
+-typedef struct _config_cb_t {
+-      cb_header_t cfg_cbhdr;
+-      u8 cfg_byte[CB_CFIG_BYTE_COUNT + CB_CFIG_D102_BYTE_COUNT];
+-} config_cb_t __attribute__ ((__packed__));
+-
+-/* MultiCast Command Block (MULTICAST_CB)*/
+-typedef struct _multicast_cb_t {
+-      cb_header_t mc_cbhdr;
+-      u16 mc_count;   /* Number of multicast addresses */
+-      u8 mc_addr[(ETH_ALEN * MAX_MULTICAST_ADDRS)];
+-} mltcst_cb_t __attribute__ ((__packed__));
+-
+-#define UCODE_MAX_DWORDS      134
+-/* Load Microcode Command Block (LOAD_UCODE_CB)*/
+-typedef struct _load_ucode_cb_t {
+-      cb_header_t load_ucode_cbhdr;
+-      u32 ucode_dword[UCODE_MAX_DWORDS];
+-} load_ucode_cb_t __attribute__ ((__packed__));
+-
+-/* Load Programmable Filter Data*/
+-typedef struct _filter_cb_t {
+-      cb_header_t filter_cb_hdr;
+-      u32 filter_data[MAX_FILTER];
+-} filter_cb_t __attribute__ ((__packed__));
+-
+-/* NON_TRANSMIT_CB -- Generic Non-Transmit Command Block 
+- */
+-typedef struct _nxmit_cb_t {
+-      union {
+-              config_cb_t config;
+-              ia_cb_t setup;
+-              load_ucode_cb_t load_ucode;
+-              mltcst_cb_t multicast;
+-              filter_cb_t filter;
+-      } ntcb;
+-} nxmit_cb_t __attribute__ ((__packed__));
+-
+-/*Block for queuing for postponed execution of the non-transmit commands*/
+-typedef struct _nxmit_cb_entry_t {
+-      struct list_head list_elem;
+-      nxmit_cb_t *non_tx_cmd;
+-      dma_addr_t dma_addr;
+-      unsigned long expiration_time;
+-} nxmit_cb_entry_t;
+-
+-/* States for postponed non tx commands execution */
+-typedef enum _non_tx_cmd_state_t {
+-      E100_NON_TX_IDLE = 0,   /* No queued NON-TX commands */
+-      E100_WAIT_TX_FINISH,    /* Wait for completion of the TX activities */
+-      E100_WAIT_NON_TX_FINISH /* Wait for completion of the non TX command */
+-} non_tx_cmd_state_t;
+-
+-/* some defines for the ipcb */
+-#define IPCB_IP_CHECKSUM_ENABLE       BIT_4
+-#define IPCB_TCPUDP_CHECKSUM_ENABLE   BIT_5
+-#define IPCB_TCP_PACKET               BIT_6
+-#define IPCB_LARGESEND_ENABLE                 BIT_7
+-#define IPCB_HARDWAREPARSING_ENABLE   BIT_0
+-#define IPCB_INSERTVLAN_ENABLE                BIT_1
+-#define IPCB_IP_ACTIVATION_DEFAULT      IPCB_HARDWAREPARSING_ENABLE
+-
+-/* Transmit Buffer Descriptor (TBD)*/
+-typedef struct _tbd_t {
+-      u32 tbd_buf_addr;       /* Physical Transmit Buffer Address */
+-      u16 tbd_buf_cnt;        /* Actual Count Of Bytes */
+-      u16 padd;
+-} tbd_t __attribute__ ((__packed__));
+-
+-/* d102 specific fields */
+-typedef struct _tcb_ipcb_t {
+-      u16 schedule_low;
+-      u8 ip_schedule;
+-      u8 ip_activation_high;
+-      u16 vlan;
+-      u8 ip_header_offset;
+-      u8 tcp_header_offset;
+-      union {
+-              u32 sec_rec_phys_addr;
+-              u32 tbd_zero_address;
+-      } tbd_sec_addr;
+-      union {
+-              u16 sec_rec_size;
+-              u16 tbd_zero_size;
+-      } tbd_sec_size;
+-      u16 total_tcp_payload;
+-} tcb_ipcb_t __attribute__ ((__packed__));
+-
+-#define E100_TBD_ARRAY_SIZE (2+MAX_SKB_FRAGS)
+-
+-/* Transmit Command Block (TCB)*/
+-struct _tcb_t {
+-      cb_header_t tcb_hdr;
+-      u32 tcb_tbd_ptr;        /* TBD address */
+-      u16 tcb_cnt;    /* Data Bytes In TCB past header */
+-      u8 tcb_thrshld; /* TX Threshold for FIFO Extender */
+-      u8 tcb_tbd_num;
+-
+-      union {
+-              tcb_ipcb_t ipcb;        /* d102 ipcb fields */
+-              tbd_t tbd_array[E100_TBD_ARRAY_SIZE];
+-      } tcbu;
+-
+-      /* From here onward we can dump anything we want as long as the
+-       * size of the total structure is a multiple of a paragraph
+-       * boundary ( i.e. -16 bit aligned ).
+-       */
+-      tbd_t *tbd_ptr;
+-
+-      u32 tcb_tbd_dflt_ptr;   /* TBD address for non-segmented packet */
+-      u32 tcb_tbd_expand_ptr; /* TBD address for segmented packet */
+-
+-      struct sk_buff *tcb_skb;        /* the associated socket buffer */
+-      dma_addr_t tcb_phys;    /* phys addr of the TCB */
+-} __attribute__ ((__packed__));
+-
+-#define _TCB_T_
+-typedef struct _tcb_t tcb_t;
+-
+-/* Receive Frame Descriptor (RFD) - will be using the simple model*/
+-struct _rfd_t {
+-      /* 8255x */
+-      cb_header_t rfd_header;
+-      u32 rfd_rbd_ptr;        /* Receive Buffer Descriptor Addr */
+-      u16 rfd_act_cnt;        /* Number Of Bytes Received */
+-      u16 rfd_sz;     /* Number Of Bytes In RFD */
+-      /* D102 aka Gamla */
+-      u16 vlanid;
+-      u8 rcvparserstatus;
+-      u8 reserved;
+-      u16 securitystatus;
+-      u8 checksumstatus;
+-      u8 zerocopystatus;
+-      u8 pad[8];      /* data should be 16 byte aligned */
+-      u8 data[RFD_DATA_SIZE];
+-
+-} __attribute__ ((__packed__));
+-
+-#define _RFD_T_
+-typedef struct _rfd_t rfd_t;
+-
+-/* Receive Buffer Descriptor (RBD)*/
+-typedef struct _rbd_t {
+-      u16 rbd_act_cnt;        /* Number Of Bytes Received */
+-      u16 rbd_filler;
+-      u32 rbd_lnk_addr;       /* Link To Next RBD */
+-      u32 rbd_rcb_addr;       /* Receive Buffer Address */
+-      u16 rbd_sz;     /* Receive Buffer Size */
+-      u16 rbd_filler1;
+-} rbd_t __attribute__ ((__packed__));
+-
+-/*
+- * This structure is used to maintain a FIFO access to a resource that is 
+- * maintained as a circular queue. The resource to be maintained is pointed
+- * to by the "data" field in the structure below. In this driver the TCBs', 
+- * TBDs' & RFDs' are maintained  as a circular queue & are managed thru this
+- * structure.
+- */
+-typedef struct _buf_pool_t {
+-      unsigned int head;      /* index to first used resource */
+-      unsigned int tail;      /* index to last used resource */
+-      void *data;             /* points to resource pool */
+-} buf_pool_t;
+-
+-/*Rx skb holding structure*/
+-struct rx_list_elem {
+-      struct list_head list_elem;
+-      dma_addr_t dma_addr;
+-      struct sk_buff *skb;
+-};
+-
+-enum next_cu_cmd_e { RESUME_NO_WAIT = 0, RESUME_WAIT, START_WAIT };
+-enum zlock_state_e { ZLOCK_INITIAL, ZLOCK_READING, ZLOCK_SLEEPING };
+-enum tx_queue_stop_type { LONG_STOP = 0, SHORT_STOP };
+-
+-/* 64 bit aligned size */
+-#define E100_SIZE_64A(X) ((sizeof(X) + 7) & ~0x7)
+-
+-typedef struct _bd_dma_able_t {
+-      char selftest[E100_SIZE_64A(self_test_t)];
+-      char stats_counters[E100_SIZE_64A(max_counters_t)];
+-} bd_dma_able_t;
+-
+-/* bit masks for bool parameters */
+-#define PRM_XSUMRX       0x00000001
+-#define PRM_UCODE        0x00000002
+-#define PRM_FC           0x00000004
+-#define PRM_IFS          0x00000008
+-#define PRM_BUNDLE_SMALL 0x00000010
+-
+-struct cfg_params {
+-      int e100_speed_duplex;
+-      int RxDescriptors;
+-      int TxDescriptors;
+-      int IntDelay;
+-      int BundleMax;
+-      int ber;
+-      u32 b_params;
+-};
+-struct ethtool_lpbk_data{
+-        dma_addr_t dma_handle;
+-        tcb_t *tcb;
+-        rfd_t *rfd;
+-
+-};
+-
+-struct e100_private {
+-      struct vlan_group *vlgrp;
+-      u32 flags;              /* board management flags */
+-      u32 tx_per_underrun;    /* number of good tx frames per underrun */
+-      unsigned int tx_count;  /* count of tx frames, so we can request an interrupt */
+-      u8 tx_thld;             /* stores transmit threshold */
+-      u16 eeprom_size;
+-      u32 pwa_no;             /* PWA: xxxxxx-0xx */
+-      u8 perm_node_address[ETH_ALEN];
+-      struct list_head active_rx_list;        /* list of rx buffers */
+-      struct list_head rx_struct_pool;        /* pool of rx buffer struct headers */
+-      u16 rfd_size;                   /* size of the adapter's RFD struct */
+-      int skb_req;                    /* number of skbs neede by the adapter */
+-      u8 intr_mask;                   /* mask for interrupt status */
+-
+-      void *dma_able;                 /* dma allocated structs */
+-      dma_addr_t dma_able_phys;
+-      self_test_t *selftest;          /* pointer to self test area */
+-      dma_addr_t selftest_phys;       /* phys addr of selftest */
+-      max_counters_t *stats_counters; /* pointer to stats table */
+-      dma_addr_t stat_cnt_phys;       /* phys addr of stat counter area */
+-
+-      stat_mode_t stat_mode;  /* statistics mode: extended, TCO, basic */
+-      scb_t *scb;             /* memory mapped ptr to 82557 scb */
+-
+-      tcb_t *last_tcb;        /* pointer to last tcb sent */
+-      buf_pool_t tcb_pool;    /* adapter's TCB array */
+-      dma_addr_t tcb_phys;    /* phys addr of start of TCBs */
+-
+-      u16 cur_line_speed;
+-      u16 cur_dplx_mode;
+-
+-      struct net_device *device;
+-      struct pci_dev *pdev;
+-      struct driver_stats drv_stats;
+-
+-      u8 rev_id;              /* adapter PCI revision ID */
+-
+-      unsigned int phy_addr;  /* address of PHY component */
+-      unsigned int PhyId;     /* ID of PHY component */
+-      unsigned int PhyState;  /* state for the fix squelch algorithm */
+-      unsigned int PhyDelay;  /* delay for the fix squelch algorithm */
+-
+-      /* Lock defintions for the driver */
+-      spinlock_t bd_lock;             /* board lock */
+-      spinlock_t bd_non_tx_lock;      /* Non transmit command lock  */
+-      spinlock_t config_lock;         /* config block lock */
+-      spinlock_t mdi_access_lock;     /* mdi lock */
+-
+-      struct timer_list watchdog_timer;       /* watchdog timer id */
+-
+-      /* non-tx commands parameters */
+-      struct timer_list nontx_timer_id;       /* non-tx timer id */
+-      struct list_head non_tx_cmd_list;
+-      non_tx_cmd_state_t non_tx_command_state;
+-      nxmit_cb_entry_t *same_cmd_entry[CB_MAX_NONTX_CMD];
+-
+-      enum next_cu_cmd_e next_cu_cmd;
+-
+-      /* Zero Locking Algorithm data members */
+-      enum zlock_state_e zlock_state;
+-      u8 zlock_read_data[16]; /* number of times each value 0-15 was read */
+-      u16 zlock_read_cnt;     /* counts number of reads */
+-      ulong zlock_sleep_cnt;  /* keeps track of "sleep" time */
+-
+-      u8 config[CB_CFIG_BYTE_COUNT + CB_CFIG_D102_BYTE_COUNT];
+-
+-      /* IFS params */
+-      u8 ifs_state;
+-      u8 ifs_value;
+-
+-      struct cfg_params params;       /* adapter's command line parameters */
+-
+-      u32 speed_duplex_caps;  /* adapter's speed/duplex capabilities */
+-
+-      /* WOL params for ethtool */
+-      u32 wolsupported;
+-      u32 wolopts;
+-      u16 ip_lbytes;
+-      struct ethtool_lpbk_data loopback;
+-      struct timer_list blink_timer;  /* led blink timer id */
+-
+-#ifdef CONFIG_PM
+-      u32 pci_state[16];
+-#endif
+-#ifdef E100_CU_DEBUG  
+-      u8 last_cmd;
+-      u8 last_sub_cmd;
+-#endif        
+-};
+-
+-#define E100_AUTONEG        0
+-#define E100_SPEED_10_HALF  1
+-#define E100_SPEED_10_FULL  2
+-#define E100_SPEED_100_HALF 3
+-#define E100_SPEED_100_FULL 4
+-
+-/********* function prototypes *************/
+-extern int e100_open(struct net_device *);
+-extern int e100_close(struct net_device *);
+-extern void e100_isolate_driver(struct e100_private *bdp);
+-extern unsigned char e100_hw_init(struct e100_private *);
+-extern void e100_sw_reset(struct e100_private *bdp, u32 reset_cmd);
+-extern u8 e100_start_cu(struct e100_private *bdp, tcb_t *tcb);
+-extern void e100_free_non_tx_cmd(struct e100_private *bdp,
+-                               nxmit_cb_entry_t *non_tx_cmd);
+-extern nxmit_cb_entry_t *e100_alloc_non_tx_cmd(struct e100_private *bdp);
+-extern unsigned char e100_exec_non_cu_cmd(struct e100_private *bdp,
+-                                        nxmit_cb_entry_t *cmd);
+-extern unsigned char e100_selftest(struct e100_private *bdp, u32 *st_timeout,
+-                                 u32 *st_result);
+-extern unsigned char e100_get_link_state(struct e100_private *bdp);
+-extern unsigned char e100_wait_scb(struct e100_private *bdp);
+-
+-extern void e100_deisolate_driver(struct e100_private *bdp, u8 full_reset);
+-extern unsigned char e100_configure_device(struct e100_private *bdp);
+-#ifdef E100_CU_DEBUG
+-extern unsigned char e100_cu_unknown_state(struct e100_private *bdp);
+-#endif
+-
+-#define ROM_TEST_FAIL         0x01
+-#define REGISTER_TEST_FAIL    0x02
+-#define SELF_TEST_FAIL                0x04
+-#define TEST_TIMEOUT          0x08
+-
+-enum test_offsets {
+-      test_link,
+-      test_eeprom,
+-      test_self_test,
+-      test_loopback_mac,
+-      test_loopback_phy,
+-      cable_diag,
+-      max_test_res,  /* must be last */
+-};
+-
+-#endif
+--- linux-2.6.0/drivers/net/e100/e100_main.c   2003-11-09 16:45:05.000000000 -0800
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,4343 +0,0 @@
+-/*******************************************************************************
+-
+-  
+-  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+-  
+-  This program is free software; you can redistribute it and/or modify it 
+-  under the terms of the GNU General Public License as published by the Free 
+-  Software Foundation; either version 2 of the License, or (at your option) 
+-  any later version.
+-  
+-  This program is distributed in the hope that it will be useful, but WITHOUT 
+-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+-  more details.
+-  
+-  You should have received a copy of the GNU General Public License along with
+-  this program; if not, write to the Free Software Foundation, Inc., 59 
+-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+-  
+-  The full GNU General Public License is included in this distribution in the
+-  file called LICENSE.
+-  
+-  Contact Information:
+-  Linux NICS <linux.nics@intel.com>
+-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+-*******************************************************************************/
+-
+-/**********************************************************************
+-*                                                                     *
+-* INTEL CORPORATION                                                   *
+-*                                                                     *
+-* This software is supplied under the terms of the license included   *
+-* above.  All use of this driver must be in accordance with the terms *
+-* of that license.                                                    *
+-*                                                                     *
+-* Module Name:  e100_main.c                                           *
+-*                                                                     *
+-* Abstract:     Functions for the driver entry points like load,      *
+-*               unload, open and close. All board specific calls made *
+-*               by the network interface section of the driver.       *
+-*                                                                     *
+-* Environment:  This file is intended to be specific to the Linux     *
+-*               operating system.                                     *
+-*                                                                     *
+-**********************************************************************/
+-
+-/* Change Log
+- * 
+- * 2.3.30       09/21/03
+- * o Bug fix (Bugzilla 97908): Loading e100 was causing crash on Itanium2
+- *   with HP chipset
+- * o Bug fix (Bugzilla 101583): e100 can't pass traffic with ipv6
+- * o Bug fix (Bugzilla 101360): PRO/10+ can't pass traffic
+- * 
+- * 2.3.27       08/08/03
+- * o Bug fix: read skb->len after freeing skb
+- *   [Andrew Morton] akpm@zip.com.au
+- * o Bug fix: 82557 (with National PHY) timeout during init
+- *   [Adam Kropelin] akropel1@rochester.rr.com
+- * o Feature add: allow to change Wake On LAN when EEPROM disabled
+- * 
+- * 2.3.13       05/08/03
+- */
+- 
+-#include <linux/config.h>
+-#include <net/checksum.h>
+-#include <linux/tcp.h>
+-#include <linux/udp.h>
+-#include "e100.h"
+-#include "e100_ucode.h"
+-#include "e100_config.h"
+-#include "e100_phy.h"
+-
+-extern void e100_force_speed_duplex_to_phy(struct e100_private *bdp);
+-
+-static char e100_gstrings_stats[][ETH_GSTRING_LEN] = {
+-      "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
+-      "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
+-      "rx_length_errors", "rx_over_errors", "rx_crc_errors",
+-      "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
+-      "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
+-      "tx_heartbeat_errors", "tx_window_errors",
+-};
+-#define E100_STATS_LEN        sizeof(e100_gstrings_stats) / ETH_GSTRING_LEN
+-
+-static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *);
+-static void e100_get_speed_duplex_caps(struct e100_private *);
+-static int e100_ethtool_get_settings(struct net_device *, struct ifreq *);
+-static int e100_ethtool_set_settings(struct net_device *, struct ifreq *);
+-
+-static int e100_ethtool_get_drvinfo(struct net_device *, struct ifreq *);
+-static int e100_ethtool_eeprom(struct net_device *, struct ifreq *);
+-
+-#define E100_EEPROM_MAGIC 0x1234
+-static int e100_ethtool_glink(struct net_device *, struct ifreq *);
+-static int e100_ethtool_gregs(struct net_device *, struct ifreq *);
+-static int e100_ethtool_nway_rst(struct net_device *, struct ifreq *);
+-static int e100_ethtool_wol(struct net_device *, struct ifreq *);
+-#ifdef CONFIG_PM
+-static unsigned char e100_setup_filter(struct e100_private *bdp);
+-static void e100_do_wol(struct pci_dev *pcid, struct e100_private *bdp);
+-#endif
+-static u16 e100_get_ip_lbytes(struct net_device *dev);
+-extern void e100_config_wol(struct e100_private *bdp);
+-extern u32 e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags);
+-static int e100_ethtool_test(struct net_device *, struct ifreq *);
+-static int e100_ethtool_gstrings(struct net_device *, struct ifreq *);
+-static char test_strings[][ETH_GSTRING_LEN] = {
+-      "Link test     (on/offline)",
+-      "Eeprom test   (on/offline)",
+-      "Self test        (offline)",
+-      "Mac loopback     (offline)",
+-      "Phy loopback     (offline)",
+-      "Cable diagnostic (offline)"
+-};
+-
+-static int e100_ethtool_led_blink(struct net_device *, struct ifreq *);
+-
+-static int e100_mii_ioctl(struct net_device *, struct ifreq *, int);
+-
+-static unsigned char e100_delayed_exec_non_cu_cmd(struct e100_private *,
+-                                                nxmit_cb_entry_t *);
+-static void e100_free_nontx_list(struct e100_private *);
+-static void e100_non_tx_background(unsigned long);
+-static inline void e100_tx_skb_free(struct e100_private *bdp, tcb_t *tcb);
+-/* Global Data structures and variables */
+-char e100_copyright[] __devinitdata = "Copyright (c) 2003 Intel Corporation";
+-char e100_driver_version[]="2.3.30-k1";
+-const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver";
+-char e100_short_driver_name[] = "e100";
+-static int e100nics = 0;
+-static void e100_vlan_rx_register(struct net_device *netdev, struct vlan_group
+-              *grp);
+-static void e100_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
+-static void e100_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
+-
+-#ifdef CONFIG_PM
+-static int e100_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
+-static int e100_suspend(struct pci_dev *pcid, u32 state);
+-static int e100_resume(struct pci_dev *pcid);
+-static unsigned char e100_asf_enabled(struct e100_private *bdp);
+-struct notifier_block e100_notifier_reboot = {
+-        .notifier_call  = e100_notify_reboot,
+-        .next           = NULL,
+-        .priority       = 0
+-};
+-#endif
+-
+-/*********************************************************************/
+-/*! This is a GCC extension to ANSI C.
+- *  See the item "Labeled Elements in Initializers" in the section
+- *  "Extensions to the C Language Family" of the GCC documentation.
+- *********************************************************************/
+-#define E100_PARAM_INIT { [0 ... E100_MAX_NIC] = -1 }
+-
+-/* All parameters are treated the same, as an integer array of values.
+- * This macro just reduces the need to repeat the same declaration code
+- * over and over (plus this helps to avoid typo bugs).
+- */
+-#define E100_PARAM(X, S)                                        \
+-        static const int X[E100_MAX_NIC + 1] = E100_PARAM_INIT; \
+-        MODULE_PARM(X, "1-" __MODULE_STRING(E100_MAX_NIC) "i"); \
+-        MODULE_PARM_DESC(X, S);
+-
+-/* ====================================================================== */
+-static u8 e100_D101M_checksum(struct e100_private *, struct sk_buff *);
+-static u8 e100_D102_check_checksum(rfd_t *);
+-static int e100_ioctl(struct net_device *, struct ifreq *, int);
+-static int e100_change_mtu(struct net_device *, int);
+-static int e100_xmit_frame(struct sk_buff *, struct net_device *);
+-static unsigned char e100_init(struct e100_private *);
+-static int e100_set_mac(struct net_device *, void *);
+-struct net_device_stats *e100_get_stats(struct net_device *);
+-
+-static irqreturn_t e100intr(int, void *, struct pt_regs *);
+-static void e100_print_brd_conf(struct e100_private *);
+-static void e100_set_multi(struct net_device *);
+-
+-static u8 e100_pci_setup(struct pci_dev *, struct e100_private *);
+-static u8 e100_sw_init(struct e100_private *);
+-static void e100_tco_workaround(struct e100_private *);
+-static unsigned char e100_alloc_space(struct e100_private *);
+-static void e100_dealloc_space(struct e100_private *);
+-static int e100_alloc_tcb_pool(struct e100_private *);
+-static void e100_setup_tcb_pool(tcb_t *, unsigned int, struct e100_private *);
+-static void e100_free_tcb_pool(struct e100_private *);
+-static int e100_alloc_rfd_pool(struct e100_private *);
+-static void e100_free_rfd_pool(struct e100_private *);
+-
+-static void e100_rd_eaddr(struct e100_private *);
+-static void e100_rd_pwa_no(struct e100_private *);
+-extern u16 e100_eeprom_read(struct e100_private *, u16);
+-extern void e100_eeprom_write_block(struct e100_private *, u16, u16 *, u16);
+-extern u16 e100_eeprom_size(struct e100_private *);
+-u16 e100_eeprom_calculate_chksum(struct e100_private *adapter);
+-
+-static unsigned char e100_clr_cntrs(struct e100_private *);
+-static unsigned char e100_load_microcode(struct e100_private *);
+-static unsigned char e100_setup_iaaddr(struct e100_private *, u8 *);
+-static unsigned char e100_update_stats(struct e100_private *bdp);
+-
+-static void e100_start_ru(struct e100_private *);
+-static void e100_dump_stats_cntrs(struct e100_private *);
+-
+-static void e100_check_options(int board, struct e100_private *bdp);
+-static void e100_set_int_option(int *, int, int, int, int, char *);
+-static void e100_set_bool_option(struct e100_private *bdp, int, u32, int,
+-                               char *);
+-unsigned char e100_wait_exec_cmplx(struct e100_private *, u32, u8, u8);
+-void e100_exec_cmplx(struct e100_private *, u32, u8);
+-
+-/**
+- * e100_get_rx_struct - retrieve cell to hold skb buff from the pool
+- * @bdp: atapter's private data struct
+- *
+- * Returns the new cell to hold sk_buff or %NULL.
+- */
+-static inline struct rx_list_elem *
+-e100_get_rx_struct(struct e100_private *bdp)
+-{
+-      struct rx_list_elem *rx_struct = NULL;
+-
+-      if (!list_empty(&(bdp->rx_struct_pool))) {
+-              rx_struct = list_entry(bdp->rx_struct_pool.next,
+-                                     struct rx_list_elem, list_elem);
+-              list_del(&(rx_struct->list_elem));
+-      }
+-
+-      return rx_struct;
+-}
+-
+-/**
+- * e100_alloc_skb - allocate an skb for the adapter
+- * @bdp: atapter's private data struct
+- *
+- * Allocates skb with enough room for rfd, and data, and reserve non-data space.
+- * Returns the new cell with sk_buff or %NULL.
+- */
+-static inline struct rx_list_elem *
+-e100_alloc_skb(struct e100_private *bdp)
+-{
+-      struct sk_buff *new_skb;
+-      u32 skb_size = sizeof (rfd_t);
+-      struct rx_list_elem *rx_struct;
+-
+-      new_skb = (struct sk_buff *) dev_alloc_skb(skb_size);
+-      if (new_skb) {
+-              /* The IP data should be 
+-                 DWORD aligned. since the ethernet header is 14 bytes long, 
+-                 we need to reserve 2 extra bytes so that the TCP/IP headers
+-                 will be DWORD aligned. */
+-              skb_reserve(new_skb, 2);
+-              if ((rx_struct = e100_get_rx_struct(bdp)) == NULL)
+-                      goto err;
+-              rx_struct->skb = new_skb;
+-              rx_struct->dma_addr = pci_map_single(bdp->pdev, new_skb->data,
+-                                                   sizeof (rfd_t),
+-                                                   PCI_DMA_FROMDEVICE);
+-              if (!rx_struct->dma_addr)
+-                      goto err;
+-              skb_reserve(new_skb, bdp->rfd_size);
+-              return rx_struct;
+-      } else {
+-              return NULL;
+-      }
+-
+-err:
+-      dev_kfree_skb_irq(new_skb);
+-      return NULL;
+-}
+-
+-/**
+- * e100_add_skb_to_end - add an skb to the end of our rfd list
+- * @bdp: atapter's private data struct
+- * @rx_struct: rx_list_elem with the new skb
+- *
+- * Adds a newly allocated skb to the end of our rfd list.
+- */
+-inline void
+-e100_add_skb_to_end(struct e100_private *bdp, struct rx_list_elem *rx_struct)
+-{
+-      rfd_t *rfdn;            /* The new rfd */
+-      rfd_t *rfd;             /* The old rfd */
+-      struct rx_list_elem *rx_struct_last;
+-
+-      (rx_struct->skb)->dev = bdp->device;
+-      rfdn = RFD_POINTER(rx_struct->skb, bdp);
+-      rfdn->rfd_header.cb_status = 0;
+-      rfdn->rfd_header.cb_cmd = __constant_cpu_to_le16(RFD_EL_BIT);
+-      rfdn->rfd_act_cnt = 0;
+-      rfdn->rfd_sz = __constant_cpu_to_le16(RFD_DATA_SIZE);
+-
+-      pci_dma_sync_single(bdp->pdev, rx_struct->dma_addr, bdp->rfd_size,
+-                          PCI_DMA_TODEVICE);
+-
+-      if (!list_empty(&(bdp->active_rx_list))) {
+-              rx_struct_last = list_entry(bdp->active_rx_list.prev,
+-                                          struct rx_list_elem, list_elem);
+-              rfd = RFD_POINTER(rx_struct_last->skb, bdp);
+-              pci_dma_sync_single(bdp->pdev, rx_struct_last->dma_addr,
+-                                  4, PCI_DMA_FROMDEVICE);
+-              put_unaligned(cpu_to_le32(rx_struct->dma_addr),
+-                            ((u32 *) (&(rfd->rfd_header.cb_lnk_ptr))));
+-
+-              pci_dma_sync_single(bdp->pdev, rx_struct_last->dma_addr,
+-                                  8, PCI_DMA_TODEVICE);
+-              rfd->rfd_header.cb_cmd &=
+-                      __constant_cpu_to_le16((u16) ~RFD_EL_BIT);
+-
+-              pci_dma_sync_single(bdp->pdev, rx_struct_last->dma_addr,
+-                                  4, PCI_DMA_TODEVICE);
+-      }
+-
+-      list_add_tail(&(rx_struct->list_elem), &(bdp->active_rx_list));
+-}
+-
+-static inline void
+-e100_alloc_skbs(struct e100_private *bdp)
+-{
+-      for (; bdp->skb_req > 0; bdp->skb_req--) {
+-              struct rx_list_elem *rx_struct;
+-
+-              if ((rx_struct = e100_alloc_skb(bdp)) == NULL)
+-                      return;
+-
+-              e100_add_skb_to_end(bdp, rx_struct);
+-      }
+-}
+-
+-void e100_tx_srv(struct e100_private *);
+-u32 e100_rx_srv(struct e100_private *);
+-
+-void e100_watchdog(struct net_device *);
+-void e100_refresh_txthld(struct e100_private *);
+-void e100_manage_adaptive_ifs(struct e100_private *);
+-void e100_clear_pools(struct e100_private *);
+-static void e100_clear_structs(struct net_device *);
+-static inline tcb_t *e100_prepare_xmit_buff(struct e100_private *,
+-                                          struct sk_buff *);
+-static void e100_set_multi_exec(struct net_device *dev);
+-
+-MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
+-MODULE_DESCRIPTION("Intel(R) PRO/100 Network Driver");
+-MODULE_LICENSE("GPL");
+-
+-E100_PARAM(TxDescriptors, "Number of transmit descriptors");
+-E100_PARAM(RxDescriptors, "Number of receive descriptors");
+-E100_PARAM(XsumRX, "Disable or enable Receive Checksum offload");
+-E100_PARAM(e100_speed_duplex, "Speed and Duplex settings");
+-E100_PARAM(ucode, "Disable or enable microcode loading");
+-E100_PARAM(ber, "Value for the BER correction algorithm");
+-E100_PARAM(flow_control, "Disable or enable Ethernet PAUSE frames processing");
+-E100_PARAM(IntDelay, "Value for CPU saver's interrupt delay");
+-E100_PARAM(BundleSmallFr, "Disable or enable interrupt bundling of small frames");
+-E100_PARAM(BundleMax, "Maximum number for CPU saver's packet bundling");
+-E100_PARAM(IFS, "Disable or enable the adaptive IFS algorithm");
+-
+-/**
+- * e100_exec_cmd - issue a comand
+- * @bdp: atapter's private data struct
+- * @scb_cmd_low: the command that is to be issued
+- *
+- * This general routine will issue a command to the e100.
+- */
+-static inline void
+-e100_exec_cmd(struct e100_private *bdp, u8 cmd_low)
+-{
+-      writeb(cmd_low, &(bdp->scb->scb_cmd_low));
+-      readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */
+-}
+-
+-/**
+- * e100_wait_scb - wait for SCB to clear
+- * @bdp: atapter's private data struct
+- *
+- * This routine checks to see if the e100 has accepted a command.
+- * It does so by checking the command field in the SCB, which will
+- * be zeroed by the e100 upon accepting a command.  The loop waits
+- * for up to 1 millisecond for command acceptance.
+- *
+- * Returns:
+- *      true if the SCB cleared within 1 millisecond.
+- *      false if it didn't clear within 1 millisecond
+- */
+-unsigned char
+-e100_wait_scb(struct e100_private *bdp)
+-{
+-      int i;
+-
+-      /* loop on the scb for a few times */
+-      for (i = 0; i < 100; i++) {
+-              if (!readb(&bdp->scb->scb_cmd_low))
+-                      return true;
+-              cpu_relax();
+-      }
+-
+-      /* it didn't work. do it the slow way using udelay()s */
+-      for (i = 0; i < E100_MAX_SCB_WAIT; i++) {
+-              if (!readb(&bdp->scb->scb_cmd_low))
+-                      return true;
+-              cpu_relax();
+-              udelay(1);
+-      }
+-
+-      return false;
+-}
+-
+-/**
+- * e100_wait_exec_simple - issue a command
+- * @bdp: atapter's private data struct
+- * @scb_cmd_low: the command that is to be issued
+- *
+- * This general routine will issue a command to the e100 after waiting for
+- * the previous command to finish.
+- *
+- * Returns:
+- *      true if the command was issued to the chip successfully
+- *      false if the command was not issued to the chip
+- */
+-inline unsigned char
+-e100_wait_exec_simple(struct e100_private *bdp, u8 scb_cmd_low)
+-{
+-      if (!e100_wait_scb(bdp)) {
+-              printk(KERN_DEBUG "e100: %s: e100_wait_exec_simple: failed\n",
+-                     bdp->device->name);
+-#ifdef E100_CU_DEBUG          
+-              printk(KERN_ERR "e100: %s: Last command (%x/%x) "
+-                      "timeout\n", bdp->device->name, 
+-                      bdp->last_cmd, bdp->last_sub_cmd);
+-              printk(KERN_ERR "e100: %s: Current simple command (%x) "
+-                      "can't be executed\n", 
+-                      bdp->device->name, scb_cmd_low);
+-#endif                
+-              return false;
+-      }
+-      e100_exec_cmd(bdp, scb_cmd_low);
+-#ifdef E100_CU_DEBUG  
+-      bdp->last_cmd = scb_cmd_low;
+-      bdp->last_sub_cmd = 0;
+-#endif        
+-      return true;
+-}
+-
+-void
+-e100_exec_cmplx(struct e100_private *bdp, u32 phys_addr, u8 cmd)
+-{
+-      writel(phys_addr, &(bdp->scb->scb_gen_ptr));
+-      readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */
+-      e100_exec_cmd(bdp, cmd);
+-}
+-
+-unsigned char
+-e100_wait_exec_cmplx(struct e100_private *bdp, u32 phys_addr, u8 cmd, u8 sub_cmd)
+-{
+-      if (!e100_wait_scb(bdp)) {
+-#ifdef E100_CU_DEBUG          
+-              printk(KERN_ERR "e100: %s: Last command (%x/%x) "
+-                      "timeout\n", bdp->device->name, 
+-                      bdp->last_cmd, bdp->last_sub_cmd);
+-              printk(KERN_ERR "e100: %s: Current complex command "
+-                      "(%x/%x) can't be executed\n", 
+-                      bdp->device->name, cmd, sub_cmd);
+-#endif                
+-              return false;
+-      }
+-      e100_exec_cmplx(bdp, phys_addr, cmd);
+-#ifdef E100_CU_DEBUG  
+-      bdp->last_cmd = cmd;
+-      bdp->last_sub_cmd = sub_cmd;
+-#endif        
+-      return true;
+-}
+-
+-inline u8
+-e100_wait_cus_idle(struct e100_private *bdp)
+-{
+-      int i;
+-
+-      /* loop on the scb for a few times */
+-      for (i = 0; i < 100; i++) {
+-              if (((readw(&(bdp->scb->scb_status)) & SCB_CUS_MASK) !=
+-                   SCB_CUS_ACTIVE)) {
+-                      return true;
+-              }
+-              cpu_relax();
+-      }
+-
+-      for (i = 0; i < E100_MAX_CU_IDLE_WAIT; i++) {
+-              if (((readw(&(bdp->scb->scb_status)) & SCB_CUS_MASK) !=
+-                   SCB_CUS_ACTIVE)) {
+-                      return true;
+-              }
+-              cpu_relax();
+-              udelay(1);
+-      }
+-
+-      return false;
+-}
+-
+-/**
+- * e100_disable_clear_intr - disable and clear/ack interrupts
+- * @bdp: atapter's private data struct
+- *
+- * This routine disables interrupts at the hardware, by setting
+- * the M (mask) bit in the adapter's CSR SCB command word.
+- * It also clear/ack interrupts.
+- */
+-static inline void
+-e100_disable_clear_intr(struct e100_private *bdp)
+-{
+-      u16 intr_status;
+-      /* Disable interrupts on our PCI board by setting the mask bit */
+-      writeb(SCB_INT_MASK, &bdp->scb->scb_cmd_hi);
+-      intr_status = readw(&bdp->scb->scb_status);
+-      /* ack and clear intrs */
+-      writew(intr_status, &bdp->scb->scb_status);
+-      readw(&bdp->scb->scb_status);
+-}
+-
+-/**
+- * e100_set_intr_mask - set interrupts
+- * @bdp: atapter's private data struct
+- *
+- * This routine sets interrupts at the hardware, by resetting
+- * the M (mask) bit in the adapter's CSR SCB command word
+- */
+-static inline void
+-e100_set_intr_mask(struct e100_private *bdp)
+-{
+-      writeb(bdp->intr_mask, &bdp->scb->scb_cmd_hi);
+-      readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */
+-}
+-
+-static inline void
+-e100_trigger_SWI(struct e100_private *bdp)
+-{
+-      /* Trigger interrupt on our PCI board by asserting SWI bit */
+-      writeb(SCB_SOFT_INT, &bdp->scb->scb_cmd_hi);
+-      readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */
+-}
+-
+-static int __devinit
+-e100_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
+-{
+-      static int first_time = true;
+-      struct net_device *dev = NULL;
+-      struct e100_private *bdp = NULL;
+-      int rc = 0;
+-      u16 cal_checksum, read_checksum;
+-
+-      dev = alloc_etherdev(sizeof (struct e100_private));
+-      if (dev == NULL) {
+-              printk(KERN_ERR "e100: Not able to alloc etherdev struct\n");
+-              rc = -ENODEV;
+-              goto out;
+-      }
+-
+-      SET_MODULE_OWNER(dev);
+-
+-      if (first_time) {
+-              first_time = false;
+-              printk(KERN_NOTICE "%s - version %s\n",
+-                     e100_full_driver_name, e100_driver_version);
+-              printk(KERN_NOTICE "%s\n", e100_copyright);
+-              printk(KERN_NOTICE "\n");
+-      }
+-
+-      bdp = dev->priv;
+-      bdp->pdev = pcid;
+-      bdp->device = dev;
+-
+-      pci_set_drvdata(pcid, dev);
+-      SET_NETDEV_DEV(dev, &pcid->dev);
+-
+-      bdp->flags = 0;
+-      bdp->ifs_state = 0;
+-      bdp->ifs_value = 0;
+-      bdp->scb = 0;
+-
+-      init_timer(&bdp->nontx_timer_id);
+-      bdp->nontx_timer_id.data = (unsigned long) bdp;
+-      bdp->nontx_timer_id.function = (void *) &e100_non_tx_background;
+-      INIT_LIST_HEAD(&(bdp->non_tx_cmd_list));
+-      bdp->non_tx_command_state = E100_NON_TX_IDLE;
+-
+-      init_timer(&bdp->watchdog_timer);
+-      bdp->watchdog_timer.data = (unsigned long) dev;
+-      bdp->watchdog_timer.function = (void *) &e100_watchdog;
+-
+-      if ((rc = e100_pci_setup(pcid, bdp)) != 0) {
+-              goto err_dev;
+-      }
+-
+-      if ((rc = e100_alloc_space(bdp)) != 0) {
+-              goto err_pci;
+-      }
+-
+-      if (((bdp->pdev->device > 0x1030)
+-             && (bdp->pdev->device < 0x103F))
+-          || ((bdp->pdev->device >= 0x1050)
+-             && (bdp->pdev->device <= 0x1057))
+-          || (bdp->pdev->device == 0x2449)
+-          || (bdp->pdev->device == 0x2459)
+-          || (bdp->pdev->device == 0x245D)) {
+-              bdp->rev_id = D101MA_REV_ID;    /* workaround for ICH3 */
+-              bdp->flags |= IS_ICH;
+-      }
+-
+-      if (bdp->rev_id == 0xff)
+-              bdp->rev_id = 1;
+-
+-      if ((u8) bdp->rev_id >= D101A4_REV_ID)
+-              bdp->flags |= IS_BACHELOR;
+-
+-      if ((u8) bdp->rev_id >= D102_REV_ID) {
+-              bdp->flags |= USE_IPCB;
+-              bdp->rfd_size = 32;
+-      } else {
+-              bdp->rfd_size = 16;
+-      }
+-
+-      dev->vlan_rx_register = e100_vlan_rx_register;
+-      dev->vlan_rx_add_vid = e100_vlan_rx_add_vid;
+-      dev->vlan_rx_kill_vid = e100_vlan_rx_kill_vid;
+-      dev->irq = pcid->irq;
+-      dev->open = &e100_open;
+-      dev->hard_start_xmit = &e100_xmit_frame;
+-      dev->stop = &e100_close;
+-      dev->change_mtu = &e100_change_mtu;
+-      dev->get_stats = &e100_get_stats;
+-      dev->set_multicast_list = &e100_set_multi;
+-      dev->set_mac_address = &e100_set_mac;
+-      dev->do_ioctl = &e100_ioctl;
+-
+-      if (bdp->flags & USE_IPCB)
+-      dev->features = NETIF_F_SG | NETIF_F_IP_CSUM |
+-                      NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+-              
+-      if ((rc = register_netdev(dev)) != 0) {
+-              goto err_dealloc;
+-      }
+-
+-      e100_check_options(e100nics, bdp);
+-
+-      if (!e100_init(bdp)) {
+-              printk(KERN_ERR "e100: Failed to initialize, instance #%d\n",
+-                     e100nics);
+-              rc = -ENODEV;
+-              goto err_unregister_netdev;
+-      }
+-
+-      /* Check if checksum is valid */
+-      cal_checksum = e100_eeprom_calculate_chksum(bdp);
+-      read_checksum = e100_eeprom_read(bdp, (bdp->eeprom_size - 1));
+-      if (cal_checksum != read_checksum) {
+-                printk(KERN_ERR "e100: Corrupted EEPROM on instance #%d\n",
+-                     e100nics);
+-                rc = -ENODEV;
+-                goto err_unregister_netdev;
+-      }
+-      
+-      e100nics++;
+-
+-      e100_get_speed_duplex_caps(bdp);
+-
+-      printk(KERN_NOTICE
+-             "e100: %s: %s\n", 
+-             bdp->device->name, "Intel(R) PRO/100 Network Connection");
+-      e100_print_brd_conf(bdp);
+-
+-      bdp->wolsupported = 0;
+-      bdp->wolopts = 0;
+-      if (bdp->rev_id >= D101A4_REV_ID)
+-              bdp->wolsupported = WAKE_PHY | WAKE_MAGIC;
+-      if (bdp->rev_id >= D101MA_REV_ID)
+-              bdp->wolsupported |= WAKE_UCAST | WAKE_ARP;
+-      
+-      /* Check if WoL is enabled on EEPROM */
+-      if (e100_eeprom_read(bdp, EEPROM_ID_WORD) & BIT_5) {
+-              /* Magic Packet WoL is enabled on device by default */
+-              /* if EEPROM WoL bit is TRUE                        */
+-              bdp->wolopts = WAKE_MAGIC;
+-      }
+-
+-      printk(KERN_NOTICE "\n");
+-
+-      goto out;
+-
+-err_unregister_netdev:
+-      unregister_netdev(dev);
+-err_dealloc:
+-      e100_dealloc_space(bdp);
+-err_pci:
+-      iounmap(bdp->scb);
+-      pci_release_regions(pcid);
+-      pci_disable_device(pcid);
+-err_dev:
+-      pci_set_drvdata(pcid, NULL);
+-      kfree(dev);
+-out:
+-      return rc;
+-}
+-
+-/**
+- * e100_clear_structs - free resources
+- * @dev: adapter's net_device struct
+- *
+- * Free all device specific structs, unmap i/o address, etc.
+- */
+-static void __devexit
+-e100_clear_structs(struct net_device *dev)
+-{
+-      struct e100_private *bdp = dev->priv;
+-
+-      iounmap(bdp->scb);
+-      pci_release_regions(bdp->pdev);
+-      pci_disable_device(bdp->pdev);
+-
+-      e100_dealloc_space(bdp);
+-      pci_set_drvdata(bdp->pdev, NULL);
+-      free_netdev(dev);
+-}
+-
+-static void __devexit
+-e100_remove1(struct pci_dev *pcid)
+-{
+-      struct net_device *dev;
+-      struct e100_private *bdp;
+-
+-      if (!(dev = (struct net_device *) pci_get_drvdata(pcid)))
+-              return;
+-
+-      bdp = dev->priv;
+-
+-      unregister_netdev(dev);
+-
+-      e100_sw_reset(bdp, PORT_SELECTIVE_RESET);
+-
+-      if (bdp->non_tx_command_state != E100_NON_TX_IDLE) {
+-              del_timer_sync(&bdp->nontx_timer_id);
+-              e100_free_nontx_list(bdp);
+-              bdp->non_tx_command_state = E100_NON_TX_IDLE;
+-      }
+-
+-      e100_clear_structs(dev);
+-
+-      --e100nics;
+-}
+-
+-static struct pci_device_id e100_id_table[] = {
+-      {0x8086, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },       
+-      {0x8086, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, 
+-      {0x8086, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, 
+-      {0x8086, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, 
+-      {0x8086, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x1055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0x8086, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+-      {0,} /* This has to be the last entry*/
+-};
+-MODULE_DEVICE_TABLE(pci, e100_id_table);
+-
+-static struct pci_driver e100_driver = {
+-      .name         = "e100",
+-      .id_table     = e100_id_table,
+-      .probe        = e100_found1,
+-      .remove       = __devexit_p(e100_remove1),
+-#ifdef CONFIG_PM
+-      .suspend      = e100_suspend,
+-      .resume       = e100_resume,
+-#endif
+-};
+-
+-static int __init
+-e100_init_module(void)
+-{
+-      int ret;
+-        ret = pci_module_init(&e100_driver);
+-
+-      if(ret >= 0) {
+-#ifdef CONFIG_PM
+-              register_reboot_notifier(&e100_notifier_reboot);
+-#endif 
+-      }
+-
+-      return ret;
+-}
+-
+-static void __exit
+-e100_cleanup_module(void)
+-{
+-#ifdef CONFIG_PM      
+-      unregister_reboot_notifier(&e100_notifier_reboot);
+-#endif 
+-
+-      pci_unregister_driver(&e100_driver);
+-}
+-
+-module_init(e100_init_module);
+-module_exit(e100_cleanup_module);
+-
+-/**
+- * e100_check_options - check command line options
+- * @board: board number
+- * @bdp: atapter's private data struct
+- *
+- * This routine does range checking on command-line options
+- */
+-void __devinit
+-e100_check_options(int board, struct e100_private *bdp)
+-{
+-      if (board >= E100_MAX_NIC) {
+-              printk(KERN_NOTICE 
+-                     "e100: No configuration available for board #%d\n",
+-                     board);
+-              printk(KERN_NOTICE "e100: Using defaults for all values\n");
+-              board = E100_MAX_NIC;
+-      }
+-
+-      e100_set_int_option(&(bdp->params.TxDescriptors), TxDescriptors[board],
+-                          E100_MIN_TCB, E100_MAX_TCB, E100_DEFAULT_TCB,
+-                          "TxDescriptor count");
+-
+-      e100_set_int_option(&(bdp->params.RxDescriptors), RxDescriptors[board],
+-                          E100_MIN_RFD, E100_MAX_RFD, E100_DEFAULT_RFD,
+-                          "RxDescriptor count");
+-
+-      e100_set_int_option(&(bdp->params.e100_speed_duplex),
+-                          e100_speed_duplex[board], 0, 4,
+-                          E100_DEFAULT_SPEED_DUPLEX, "speed/duplex mode");
+-
+-      e100_set_int_option(&(bdp->params.ber), ber[board], 0, ZLOCK_MAX_ERRORS,
+-                          E100_DEFAULT_BER, "Bit Error Rate count");
+-
+-      e100_set_bool_option(bdp, XsumRX[board], PRM_XSUMRX, E100_DEFAULT_XSUM,
+-                           "XsumRX value");
+-
+-      /* Default ucode value depended on controller revision */
+-      if (bdp->rev_id >= D101MA_REV_ID) {
+-              e100_set_bool_option(bdp, ucode[board], PRM_UCODE,
+-                                   E100_DEFAULT_UCODE, "ucode value");
+-      } else {
+-              e100_set_bool_option(bdp, ucode[board], PRM_UCODE, false,
+-                                   "ucode value");
+-      }
+-
+-      e100_set_bool_option(bdp, flow_control[board], PRM_FC, E100_DEFAULT_FC,
+-                           "flow control value");
+-
+-      e100_set_bool_option(bdp, IFS[board], PRM_IFS, E100_DEFAULT_IFS,
+-                           "IFS value");
+-
+-      e100_set_bool_option(bdp, BundleSmallFr[board], PRM_BUNDLE_SMALL,
+-                           E100_DEFAULT_BUNDLE_SMALL_FR,
+-                           "CPU saver bundle small frames value");
+-
+-      e100_set_int_option(&(bdp->params.IntDelay), IntDelay[board], 0x0,
+-                          0xFFFF, E100_DEFAULT_CPUSAVER_INTERRUPT_DELAY,
+-                          "CPU saver interrupt delay value");
+-
+-      e100_set_int_option(&(bdp->params.BundleMax), BundleMax[board], 0x1,
+-                          0xFFFF, E100_DEFAULT_CPUSAVER_BUNDLE_MAX,
+-                          "CPU saver bundle max value");
+-
+-}
+-
+-/**
+- * e100_set_int_option - check and set an integer option
+- * @option: a pointer to the relevant option field
+- * @val: the value specified
+- * @min: the minimum valid value
+- * @max: the maximum valid value
+- * @default_val: the default value
+- * @name: the name of the option
+- *
+- * This routine does range checking on a command-line option.
+- * If the option's value is '-1' use the specified default.
+- * Otherwise, if the value is invalid, change it to the default.
+- */
+-void __devinit
+-e100_set_int_option(int *option, int val, int min, int max, int default_val,
+-                  char *name)
+-{
+-      if (val == -1) {        /* no value specified. use default */
+-              *option = default_val;
+-
+-      } else if ((val < min) || (val > max)) {
+-              printk(KERN_NOTICE
+-                     "e100: Invalid %s specified (%i). "
+-                     "Valid range is %i-%i\n",
+-                     name, val, min, max);
+-              printk(KERN_NOTICE "e100: Using default %s of %i\n", name,
+-                     default_val);
+-              *option = default_val;
+-      } else {
+-              printk(KERN_INFO "e100: Using specified %s of %i\n", name, val);
+-              *option = val;
+-      }
+-}
+-
+-/**
+- * e100_set_bool_option - check and set a boolean option
+- * @bdp: atapter's private data struct
+- * @val: the value specified
+- * @mask: the mask for the relevant option
+- * @default_val: the default value
+- * @name: the name of the option
+- *
+- * This routine checks a boolean command-line option.
+- * If the option's value is '-1' use the specified default.
+- * Otherwise, if the value is invalid (not 0 or 1), 
+- * change it to the default.
+- */
+-void __devinit
+-e100_set_bool_option(struct e100_private *bdp, int val, u32 mask,
+-                   int default_val, char *name)
+-{
+-      if (val == -1) {
+-              if (default_val)
+-                      bdp->params.b_params |= mask;
+-
+-      } else if ((val != true) && (val != false)) {
+-              printk(KERN_NOTICE
+-                     "e100: Invalid %s specified (%i). "
+-                     "Valid values are %i/%i\n",
+-                     name, val, false, true);
+-              printk(KERN_NOTICE "e100: Using default %s of %i\n", name,
+-                     default_val);
+-
+-              if (default_val)
+-                      bdp->params.b_params |= mask;
+-      } else {
+-              printk(KERN_INFO "e100: Using specified %s of %i\n", name, val);
+-              if (val)
+-                      bdp->params.b_params |= mask;
+-      }
+-}
+-
+-int
+-e100_open(struct net_device *dev)
+-{
+-      struct e100_private *bdp;
+-      int rc = 0;
+-
+-      bdp = dev->priv;
+-
+-      /* setup the tcb pool */
+-      if (!e100_alloc_tcb_pool(bdp)) {
+-              rc = -ENOMEM;
+-              goto err_exit;
+-      }
+-      bdp->last_tcb = NULL;
+-
+-      bdp->tcb_pool.head = 0;
+-      bdp->tcb_pool.tail = 1; 
+-
+-      e100_setup_tcb_pool((tcb_t *) bdp->tcb_pool.data,
+-                          bdp->params.TxDescriptors, bdp);
+-
+-      if (!e100_alloc_rfd_pool(bdp)) {
+-              rc = -ENOMEM;
+-              goto err_exit;
+-      }
+-
+-      if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE, 0)) {
+-              rc = -EAGAIN;
+-              goto err_exit;
+-      }
+-
+-      if (!e100_wait_exec_cmplx(bdp, 0, SCB_RUC_LOAD_BASE, 0)) {
+-              rc = -EAGAIN;
+-              goto err_exit;
+-      }
+-
+-      mod_timer(&(bdp->watchdog_timer), jiffies + (2 * HZ));
+-
+-      if (dev->flags & IFF_UP)
+-              /* Otherwise process may sleep forever */
+-              netif_wake_queue(dev);
+-      else
+-              netif_start_queue(dev);
+-
+-      e100_start_ru(bdp);
+-      if ((rc = request_irq(dev->irq, &e100intr, SA_SHIRQ,
+-                            dev->name, dev)) != 0) {
+-              del_timer_sync(&bdp->watchdog_timer);
+-              goto err_exit;
+-      }
+-      bdp->intr_mask = 0;
+-      e100_set_intr_mask(bdp);
+-
+-      e100_force_config(bdp);
+-
+-      goto exit;
+-
+-err_exit:
+-      e100_clear_pools(bdp);
+-exit:
+-      return rc;
+-}
+-
+-int
+-e100_close(struct net_device *dev)
+-{
+-      struct e100_private *bdp = dev->priv;
+-
+-      e100_disable_clear_intr(bdp);
+-      free_irq(dev->irq, dev);
+-      bdp->intr_mask = SCB_INT_MASK;
+-      e100_isolate_driver(bdp);
+-
+-      netif_carrier_off(bdp->device);
+-      bdp->cur_line_speed = 0;
+-      bdp->cur_dplx_mode = 0;
+-      e100_clear_pools(bdp);
+-
+-      return 0;
+-}
+-
+-static int
+-e100_change_mtu(struct net_device *dev, int new_mtu)
+-{
+-      if ((new_mtu < 68) || (new_mtu > (ETH_DATA_LEN + VLAN_SIZE)))
+-              return -EINVAL;
+-
+-      dev->mtu = new_mtu;
+-      return 0;
+-}
+-
+-static int
+-e100_xmit_frame(struct sk_buff *skb, struct net_device *dev)
+-{
+-      int rc = 0;
+-      int notify_stop = false;
+-      struct e100_private *bdp = dev->priv;
+-
+-      if (!spin_trylock(&bdp->bd_non_tx_lock)) {
+-              notify_stop = true;
+-              rc = 1;
+-              goto exit2;
+-      }
+-
+-      /* tcb list may be empty temporarily during releasing resources */
+-      if (!TCBS_AVAIL(bdp->tcb_pool) || (bdp->tcb_phys == 0) ||
+-          (bdp->non_tx_command_state != E100_NON_TX_IDLE)) {
+-              notify_stop = true;
+-              rc = 1;
+-              goto exit1;
+-      }
+-
+-      bdp->drv_stats.net_stats.tx_bytes += skb->len;
+-
+-      e100_prepare_xmit_buff(bdp, skb);
+-
+-      dev->trans_start = jiffies;
+-
+-exit1:
+-      spin_unlock(&bdp->bd_non_tx_lock);
+-exit2:
+-      if (notify_stop) {
+-              netif_stop_queue(dev);
+-      }
+-
+-      return rc;
+-}
+-
+-/**
+- * e100_get_stats - get driver statistics
+- * @dev: adapter's net_device struct
+- *
+- * This routine is called when the OS wants the adapter's stats returned.
+- * It returns the address of the net_device_stats stucture for the device.
+- * If the statistics are currently being updated, then they might be incorrect
+- * for a short while. However, since this cannot actually cause damage, no
+- * locking is used.
+- */
+-struct net_device_stats *
+-e100_get_stats(struct net_device *dev)
+-{
+-      struct e100_private *bdp = dev->priv;
+-
+-      bdp->drv_stats.net_stats.tx_errors =
+-              bdp->drv_stats.net_stats.tx_carrier_errors +
+-              bdp->drv_stats.net_stats.tx_aborted_errors;
+-
+-      bdp->drv_stats.net_stats.rx_errors =
+-              bdp->drv_stats.net_stats.rx_crc_errors +
+-              bdp->drv_stats.net_stats.rx_frame_errors +
+-              bdp->drv_stats.net_stats.rx_length_errors +
+-              bdp->drv_stats.rcv_cdt_frames;
+-
+-      return &(bdp->drv_stats.net_stats);
+-}
+-
+-/**
+- * e100_set_mac - set the MAC address
+- * @dev: adapter's net_device struct
+- * @addr: the new address
+- *
+- * This routine sets the ethernet address of the board
+- * Returns:
+- * 0  - if successful
+- * -1 - otherwise
+- */
+-static int
+-e100_set_mac(struct net_device *dev, void *addr)
+-{
+-      struct e100_private *bdp;
+-      int rc = -1;
+-      struct sockaddr *p_sockaddr = (struct sockaddr *) addr;
+-
+-      if (!is_valid_ether_addr(p_sockaddr->sa_data))
+-              return -EADDRNOTAVAIL;
+-      bdp = dev->priv;
+-
+-      if (e100_setup_iaaddr(bdp, (u8 *) (p_sockaddr->sa_data))) {
+-              memcpy(&(dev->dev_addr[0]), p_sockaddr->sa_data, ETH_ALEN);
+-              rc = 0;
+-      }
+-
+-      return rc;
+-}
+-
+-static void
+-e100_set_multi_exec(struct net_device *dev)
+-{
+-      struct e100_private *bdp = dev->priv;
+-      mltcst_cb_t *mcast_buff;
+-      cb_header_t *cb_hdr;
+-      struct dev_mc_list *mc_list;
+-      unsigned int i;
+-      nxmit_cb_entry_t *cmd = e100_alloc_non_tx_cmd(bdp);
+-
+-      if (cmd != NULL) {
+-              mcast_buff = &((cmd->non_tx_cmd)->ntcb.multicast);
+-              cb_hdr = &((cmd->non_tx_cmd)->ntcb.multicast.mc_cbhdr);
+-      } else {
+-              return;
+-      }
+-
+-      /* initialize the multi cast command */
+-      cb_hdr->cb_cmd = __constant_cpu_to_le16(CB_MULTICAST);
+-
+-      /* now fill in the rest of the multicast command */
+-      *(u16 *) (&(mcast_buff->mc_count)) = cpu_to_le16(dev->mc_count * 6);
+-      for (i = 0, mc_list = dev->mc_list;
+-           (i < dev->mc_count) && (i < MAX_MULTICAST_ADDRS);
+-           i++, mc_list = mc_list->next) {
+-              /* copy into the command */
+-              memcpy(&(mcast_buff->mc_addr[i * ETH_ALEN]),
+-                     (u8 *) &(mc_list->dmi_addr), ETH_ALEN);
+-      }
+-
+-      if (!e100_exec_non_cu_cmd(bdp, cmd)) {
+-              printk(KERN_WARNING "e100: %s: Multicast setup failed\n", 
+-                     dev->name);
+-      }
+-}
+-
+-/**
+- * e100_set_multi - set multicast status
+- * @dev: adapter's net_device struct
+- *
+- * This routine is called to add or remove multicast addresses, and/or to
+- * change the adapter's promiscuous state.
+- */
+-static void
+-e100_set_multi(struct net_device *dev)
+-{
+-      struct e100_private *bdp = dev->priv;
+-      unsigned char promisc_enbl;
+-      unsigned char mulcast_enbl;
+-
+-      promisc_enbl = ((dev->flags & IFF_PROMISC) == IFF_PROMISC);
+-      mulcast_enbl = ((dev->flags & IFF_ALLMULTI) ||
+-                      (dev->mc_count > MAX_MULTICAST_ADDRS));
+-
+-      e100_config_promisc(bdp, promisc_enbl);
+-      e100_config_mulcast_enbl(bdp, mulcast_enbl);
+-
+-      /* reconfigure the chip if something has changed in its config space */
+-      e100_config(bdp);
+-
+-      if (promisc_enbl || mulcast_enbl) {
+-              return; /* no need for Multicast Cmd */
+-      }
+-
+-      /* get the multicast CB */
+-      e100_set_multi_exec(dev);
+-}
+-
+-static int
+-e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+-{
+-
+-      switch (cmd) {
+-
+-      case SIOCETHTOOL:
+-              return e100_do_ethtool_ioctl(dev, ifr);
+-              break;
+-
+-      case SIOCGMIIPHY:       /* Get address of MII PHY in use. */
+-      case SIOCGMIIREG:       /* Read MII PHY register. */
+-      case SIOCSMIIREG:       /* Write to MII PHY register. */
+-              return e100_mii_ioctl(dev, ifr, cmd);
+-              break;
+-
+-      default:
+-              return -EOPNOTSUPP;
+-      }
+-      return 0;
+-
+-}
+-
+-/**
+- * e100init - initialize the adapter
+- * @bdp: atapter's private data struct
+- *
+- * This routine is called when this driver is loaded. This is the initialization
+- * routine which allocates memory, configures the adapter and determines the
+- * system resources.
+- *
+- * Returns:
+- *      true: if successful
+- *      false: otherwise
+- */
+-static unsigned char __devinit
+-e100_init(struct e100_private *bdp)
+-{
+-      u32 st_timeout = 0;
+-      u32 st_result = 0;
+-      e100_sw_init(bdp);
+-
+-      if (!e100_selftest(bdp, &st_timeout, &st_result)) {
+-              if (st_timeout) {
+-                      printk(KERN_ERR "e100: selftest timeout\n");
+-              } else {
+-                      printk(KERN_ERR "e100: selftest failed. Results: %x\n",
+-                                      st_result);
+-              }
+-              return false;
+-      }
+-      else
+-              printk(KERN_DEBUG "e100: selftest OK.\n");
+-
+-      /* read the MAC address from the eprom */
+-      e100_rd_eaddr(bdp);
+-      if (!is_valid_ether_addr(bdp->device->dev_addr)) {
+-              printk(KERN_ERR "e100: Invalid Ethernet address\n");
+-              return false;
+-      }
+-      /* read NIC's part number */
+-      e100_rd_pwa_no(bdp);
+-
+-      if (!e100_hw_init(bdp))
+-              return false;
+-      /* Interrupts are enabled after device reset */
+-      e100_disable_clear_intr(bdp);
+-
+-      return true;
+-}
+-
+-/**
+- * e100_sw_init - initialize software structs
+- * @bdp: atapter's private data struct
+- * 
+- * This routine initializes all software structures. Sets up the
+- * circular structures for the RFD's & TCB's. Allocates the per board
+- * structure for storing adapter information. The CSR is also memory 
+- * mapped in this routine.
+- *
+- * Returns :
+- *      true: if S/W was successfully initialized
+- *      false: otherwise
+- */
+-static unsigned char __devinit
+-e100_sw_init(struct e100_private *bdp)
+-{
+-      bdp->next_cu_cmd = START_WAIT;  // init the next cu state
+-
+-      /* 
+-       * Set the value for # of good xmits per underrun. the value assigned
+-       * here is an intelligent  suggested default. Nothing magical about it.
+-       */
+-      bdp->tx_per_underrun = DEFAULT_TX_PER_UNDERRUN;
+-
+-      /* get the default transmit threshold value */
+-      bdp->tx_thld = TX_THRSHLD;
+-
+-      /* get the EPROM size */
+-      bdp->eeprom_size = e100_eeprom_size(bdp);
+-
+-      /* Initialize our spinlocks */
+-      spin_lock_init(&(bdp->bd_lock));
+-      spin_lock_init(&(bdp->bd_non_tx_lock));
+-      spin_lock_init(&(bdp->config_lock));
+-      spin_lock_init(&(bdp->mdi_access_lock));
+-      /* Initialize configuration data */
+-      e100_config_init(bdp);
+-
+-      return 1;
+-}
+-
+-static void __devinit
+-e100_tco_workaround(struct e100_private *bdp)
+-{
+-      int i;
+-
+-      /* Do software reset */
+-      e100_sw_reset(bdp, PORT_SOFTWARE_RESET);
+-
+-      /* Do a dummy LOAD CU BASE command. */
+-      /* This gets us out of pre-driver to post-driver. */
+-      e100_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE);
+-
+-      /* Wait 20 msec for reset to take effect */
+-      set_current_state(TASK_UNINTERRUPTIBLE);
+-      schedule_timeout(HZ / 50 + 1);
+-
+-      /* disable interrupts since they are enabled */
+-      /* after device reset                        */
+-      e100_disable_clear_intr(bdp);
+-
+-      /* Wait for command to be cleared up to 1 sec */
+-      for (i=0; i<100; i++) {
+-              if (!readb(&bdp->scb->scb_cmd_low))
+-                      break;
+-              set_current_state(TASK_UNINTERRUPTIBLE);
+-              schedule_timeout(HZ / 100 + 1);
+-      }
+-
+-      /* Wait for TCO request bit in PMDR register to be clear */
+-      for (i=0; i<50; i++) {
+-              if (!(readb(&bdp->scb->scb_ext.d101m_scb.scb_pmdr) & BIT_1))
+-                      break;
+-              set_current_state(TASK_UNINTERRUPTIBLE);
+-              schedule_timeout(HZ / 100 + 1);
+-      }
+-}
+-
+-/**
+- * e100_hw_init - initialized tthe hardware
+- * @bdp: atapter's private data struct
+- *
+- * This routine performs a reset on the adapter, and configures the adapter.
+- * This includes configuring the 82557 LAN controller, validating and setting
+- * the node address, detecting and configuring the Phy chip on the adapter,
+- * and initializing all of the on chip counters.
+- *
+- * Returns:
+- *      true - If the adapter was initialized
+- *      false - If the adapter failed initialization
+- */
+-unsigned char
+-e100_hw_init(struct e100_private *bdp)
+-{
+-      if (!e100_phy_init(bdp))
+-              goto err;
+-
+-      e100_sw_reset(bdp, PORT_SELECTIVE_RESET);
+-
+-      /* Only 82559 or above needs TCO workaround */
+-      if (bdp->rev_id >= D101MA_REV_ID)
+-              e100_tco_workaround(bdp);
+-
+-      /* Load the CU BASE (set to 0, because we use linear mode) */
+-      if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE, 0))
+-              goto err;
+-
+-      if (!e100_wait_exec_cmplx(bdp, 0, SCB_RUC_LOAD_BASE, 0))
+-              goto err;
+-
+-      /* Load interrupt microcode  */
+-      if (e100_load_microcode(bdp)) {
+-              bdp->flags |= DF_UCODE_LOADED;
+-      }
+-
+-      if ((u8) bdp->rev_id < D101A4_REV_ID)
+-              e100_config_init_82557(bdp);
+-              
+-      if (!e100_config(bdp))
+-              goto err;
+-
+-      if (!e100_setup_iaaddr(bdp, bdp->device->dev_addr))
+-              goto err;
+-
+-      /* Clear the internal counters */
+-      if (!e100_clr_cntrs(bdp))
+-              goto err;
+-
+-      /* Change for 82558 enhancement */
+-      /* If 82558/9 and if the user has enabled flow control, set up the
+-       * Flow Control Reg. in the CSR */
+-      if ((bdp->flags & IS_BACHELOR)
+-          && (bdp->params.b_params & PRM_FC)) {
+-              writeb(DFLT_FC_THLD, &bdp->scb->scb_ext.d101_scb.scb_fc_thld);
+-              writeb(DFLT_FC_CMD,
+-                     &bdp->scb->scb_ext.d101_scb.scb_fc_xon_xoff);
+-      }
+-
+-      return true;
+-err:
+-      printk(KERN_ERR "e100: hw init failed\n");
+-      return false;
+-}
+-
+-/**
+- * e100_setup_tcb_pool - setup TCB circular list
+- * @head: Pointer to head of the allocated TCBs
+- * @qlen: Number of elements in the queue
+- * @bdp: atapter's private data struct
+- * 
+- * This routine arranges the contigiously allocated TCB's in a circular list.
+- * Also does the one time initialization of the TCBs.
+- */
+-static void
+-e100_setup_tcb_pool(tcb_t *head, unsigned int qlen, struct e100_private *bdp)
+-{
+-      int ele_no;
+-      tcb_t *pcurr_tcb;       /* point to current tcb */
+-      u32 next_phys;          /* the next phys addr */
+-      u16 txcommand = CB_S_BIT | CB_TX_SF_BIT;
+-
+-      bdp->tx_count = 0;
+-      if (bdp->flags & USE_IPCB) {
+-              txcommand |= CB_IPCB_TRANSMIT | CB_CID_DEFAULT;
+-      } else if (bdp->flags & IS_BACHELOR) {
+-              txcommand |= CB_TRANSMIT | CB_CID_DEFAULT;
+-      } else {
+-              txcommand |= CB_TRANSMIT;
+-      }
+-
+-      for (ele_no = 0, next_phys = bdp->tcb_phys, pcurr_tcb = head;
+-           ele_no < qlen; ele_no++, pcurr_tcb++) {
+-
+-              /* set the phys addr for this TCB, next_phys has not incr. yet */
+-              pcurr_tcb->tcb_phys = next_phys;
+-              next_phys += sizeof (tcb_t);
+-
+-              /* set the link to next tcb */
+-              if (ele_no == (qlen - 1))
+-                      pcurr_tcb->tcb_hdr.cb_lnk_ptr =
+-                              cpu_to_le32(bdp->tcb_phys);
+-              else
+-                      pcurr_tcb->tcb_hdr.cb_lnk_ptr = cpu_to_le32(next_phys);
+-
+-              pcurr_tcb->tcb_hdr.cb_status = 0;
+-              pcurr_tcb->tcb_hdr.cb_cmd = cpu_to_le16(txcommand);
+-              pcurr_tcb->tcb_cnt = 0; 
+-              pcurr_tcb->tcb_thrshld = bdp->tx_thld;  
+-              if (ele_no < 2) {
+-                      pcurr_tcb->tcb_hdr.cb_status =
+-                              cpu_to_le16(CB_STATUS_COMPLETE);
+-              }
+-              pcurr_tcb->tcb_tbd_num = 1;
+-
+-              if (bdp->flags & IS_BACHELOR) {
+-                      pcurr_tcb->tcb_tbd_ptr =
+-                              __constant_cpu_to_le32(0xFFFFFFFF);
+-              } else {
+-                      pcurr_tcb->tcb_tbd_ptr =
+-                              cpu_to_le32(pcurr_tcb->tcb_phys + 0x10);
+-              }
+-
+-              if (bdp->flags & IS_BACHELOR) {
+-                      pcurr_tcb->tcb_tbd_expand_ptr =
+-                              cpu_to_le32(pcurr_tcb->tcb_phys + 0x20);
+-              } else {
+-                      pcurr_tcb->tcb_tbd_expand_ptr =
+-                              cpu_to_le32(pcurr_tcb->tcb_phys + 0x10);
+-              }
+-              pcurr_tcb->tcb_tbd_dflt_ptr = pcurr_tcb->tcb_tbd_ptr;
+-
+-              if (bdp->flags & USE_IPCB) {
+-                      pcurr_tcb->tbd_ptr = &(pcurr_tcb->tcbu.tbd_array[1]);
+-                      pcurr_tcb->tcbu.ipcb.ip_activation_high =
+-                              IPCB_IP_ACTIVATION_DEFAULT;
+-                      pcurr_tcb->tcbu.ipcb.vlan = 0;
+-              } else {
+-                      pcurr_tcb->tbd_ptr = &(pcurr_tcb->tcbu.tbd_array[0]);
+-              }
+-
+-              pcurr_tcb->tcb_skb = NULL;
+-      }
+-
+-      wmb();
+-}
+-
+-/***************************************************************************/
+-/***************************************************************************/
+-/*       Memory Management Routines                                        */
+-/***************************************************************************/
+-
+-/**
+- * e100_alloc_space - allocate private driver data
+- * @bdp: atapter's private data struct
+- *
+- * This routine allocates memory for the driver. Memory allocated is for the
+- * selftest and statistics structures.
+- *
+- * Returns:
+- *      0: if the operation was successful
+- *      %-ENOMEM: if memory allocation failed
+- */
+-unsigned char __devinit
+-e100_alloc_space(struct e100_private *bdp)
+-{
+-      unsigned long off;
+-
+-      /* allocate all the dma-able structures in one call:
+-       * selftest results, adapter stats, and non-tx cb commands */
+-      if (!(bdp->dma_able =
+-            pci_alloc_consistent(bdp->pdev, sizeof (bd_dma_able_t),
+-                                 &(bdp->dma_able_phys)))) {
+-              goto err;
+-      }
+-
+-      /* now assign the various pointers into the struct we've just allocated */
+-      off = offsetof(bd_dma_able_t, selftest);
+-
+-      bdp->selftest = (self_test_t *) (bdp->dma_able + off);
+-      bdp->selftest_phys = bdp->dma_able_phys + off;
+-
+-      off = offsetof(bd_dma_able_t, stats_counters);
+-
+-      bdp->stats_counters = (max_counters_t *) (bdp->dma_able + off);
+-      bdp->stat_cnt_phys = bdp->dma_able_phys + off;
+-
+-      return 0;
+-
+-err:
+-      printk(KERN_ERR
+-             "e100: Failed to allocate memory\n");
+-      return -ENOMEM;
+-}
+-
+-/**
+- * e100_alloc_tcb_pool - allocate TCB circular list
+- * @bdp: atapter's private data struct
+- *
+- * This routine allocates memory for the circular list of transmit descriptors.
+- *
+- * Returns:
+- *       0: if allocation has failed.
+- *       1: Otherwise. 
+- */
+-int
+-e100_alloc_tcb_pool(struct e100_private *bdp)
+-{
+-      int stcb = sizeof (tcb_t) * bdp->params.TxDescriptors;
+-
+-      /* allocate space for the TCBs */
+-      if (!(bdp->tcb_pool.data =
+-            pci_alloc_consistent(bdp->pdev, stcb, &bdp->tcb_phys)))
+-              return 0;
+-
+-      memset(bdp->tcb_pool.data, 0x00, stcb);
+-
+-      return 1;
+-}
+-
+-void
+-e100_free_tcb_pool(struct e100_private *bdp)
+-{
+-      tcb_t *tcb;
+-      int i;
+-      /* Return tx skbs */ 
+-      for (i = 0; i < bdp->params.TxDescriptors; i++) {
+-              tcb = bdp->tcb_pool.data;
+-              tcb += bdp->tcb_pool.head;
+-              e100_tx_skb_free(bdp, tcb);
+-              if (NEXT_TCB_TOUSE(bdp->tcb_pool.head) == bdp->tcb_pool.tail)
+-                      break;
+-              bdp->tcb_pool.head = NEXT_TCB_TOUSE(bdp->tcb_pool.head);
+-      }
+-      pci_free_consistent(bdp->pdev,
+-                          sizeof (tcb_t) * bdp->params.TxDescriptors,
+-                          bdp->tcb_pool.data, bdp->tcb_phys);
+-      bdp->tcb_pool.head = 0;
+-      bdp->tcb_pool.tail = 1; 
+-      bdp->tcb_phys = 0;
+-}
+-
+-static void
+-e100_dealloc_space(struct e100_private *bdp)
+-{
+-      if (bdp->dma_able) {
+-              pci_free_consistent(bdp->pdev, sizeof (bd_dma_able_t),
+-                                  bdp->dma_able, bdp->dma_able_phys);
+-      }
+-
+-      bdp->selftest_phys = 0;
+-      bdp->stat_cnt_phys = 0;
+-      bdp->dma_able_phys = 0;
+-      bdp->dma_able = 0;
+-}
+-
+-static void
+-e100_free_rfd_pool(struct e100_private *bdp)
+-{
+-      struct rx_list_elem *rx_struct;
+-
+-      while (!list_empty(&(bdp->active_rx_list))) {
+-
+-              rx_struct = list_entry(bdp->active_rx_list.next,
+-                                     struct rx_list_elem, list_elem);
+-              list_del(&(rx_struct->list_elem));
+-              pci_unmap_single(bdp->pdev, rx_struct->dma_addr,
+-                               sizeof (rfd_t), PCI_DMA_TODEVICE);
+-              dev_kfree_skb(rx_struct->skb);
+-              kfree(rx_struct);
+-      }
+-
+-      while (!list_empty(&(bdp->rx_struct_pool))) {
+-              rx_struct = list_entry(bdp->rx_struct_pool.next,
+-                                     struct rx_list_elem, list_elem);
+-              list_del(&(rx_struct->list_elem));
+-              kfree(rx_struct);
+-      }
+-}
+-
+-/**
+- * e100_alloc_rfd_pool - allocate RFDs
+- * @bdp: atapter's private data struct
+- *
+- * Allocates initial pool of skb which holds both rfd and data,
+- * and return a pointer to the head of the list
+- */
+-static int
+-e100_alloc_rfd_pool(struct e100_private *bdp)
+-{
+-      struct rx_list_elem *rx_struct;
+-      int i;
+-
+-      INIT_LIST_HEAD(&(bdp->active_rx_list));
+-      INIT_LIST_HEAD(&(bdp->rx_struct_pool));
+-      bdp->skb_req = bdp->params.RxDescriptors;
+-      for (i = 0; i < bdp->skb_req; i++) {
+-              rx_struct = kmalloc(sizeof (struct rx_list_elem), GFP_ATOMIC);
+-              list_add(&(rx_struct->list_elem), &(bdp->rx_struct_pool));
+-      }
+-      e100_alloc_skbs(bdp);
+-      return !list_empty(&(bdp->active_rx_list));
+-
+-}
+-
+-void
+-e100_clear_pools(struct e100_private *bdp)
+-{
+-      bdp->last_tcb = NULL;
+-      e100_free_rfd_pool(bdp);
+-      e100_free_tcb_pool(bdp);
+-}
+-
+-/*****************************************************************************/
+-/*****************************************************************************/
+-/*      Run Time Functions                                                   */
+-/*****************************************************************************/
+-
+-/**
+- * e100_watchdog
+- * @dev: adapter's net_device struct
+- *
+- * This routine runs every 2 seconds and updates our statitics and link state,
+- * and refreshs txthld value.
+- */
+-void
+-e100_watchdog(struct net_device *dev)
+-{
+-      struct e100_private *bdp = dev->priv;
+-
+-#ifdef E100_CU_DEBUG
+-      if (e100_cu_unknown_state(bdp)) {
+-              printk(KERN_ERR "e100: %s: CU unknown state in e100_watchdog\n",
+-                      dev->name);
+-      }
+-#endif        
+-      if (!netif_running(dev)) {
+-              return;
+-      }
+-
+-      /* check if link state has changed */
+-      if (e100_phy_check(bdp)) {
+-              if (netif_carrier_ok(dev)) {
+-                      printk(KERN_ERR
+-                             "e100: %s NIC Link is Up %d Mbps %s duplex\n",
+-                             bdp->device->name, bdp->cur_line_speed,
+-                             (bdp->cur_dplx_mode == HALF_DUPLEX) ?
+-                             "Half" : "Full");
+-
+-                      e100_config_fc(bdp);
+-                      e100_config(bdp);  
+-
+-              } else {
+-                      printk(KERN_ERR "e100: %s NIC Link is Down\n",
+-                             bdp->device->name);
+-              }
+-      }
+-
+-      // toggle the tx queue according to link status
+-      // this also resolves a race condition between tx & non-cu cmd flows
+-      if (netif_carrier_ok(dev)) {
+-              if (netif_running(dev))
+-                      netif_wake_queue(dev);
+-      } else {
+-              if (netif_running(dev))
+-                      netif_stop_queue(dev);
+-              /* When changing to non-autoneg, device may lose  */
+-              /* link with some switches. e100 will try to      */
+-              /* revover link by sending command to PHY layer   */
+-              if (bdp->params.e100_speed_duplex != E100_AUTONEG)
+-                      e100_force_speed_duplex_to_phy(bdp);
+-      }
+-
+-      rmb();
+-
+-      if (e100_update_stats(bdp)) {
+-
+-              /* Check if a change in the IFS parameter is needed,
+-                 and configure the device accordingly */
+-              if (bdp->params.b_params & PRM_IFS)
+-                      e100_manage_adaptive_ifs(bdp);
+-
+-              /* Now adjust our dynamic tx threshold value */
+-              e100_refresh_txthld(bdp);
+-
+-              /* Now if we are on a 557 and we havn't received any frames then we
+-               * should issue a multicast command to reset the RU */
+-              if (bdp->rev_id < D101A4_REV_ID) {
+-                      if (!(bdp->stats_counters->basic_stats.rcv_gd_frames)) {
+-                              e100_set_multi(dev);
+-                      }
+-              }
+-      }
+-      /* Issue command to dump statistics from device.        */
+-      /* Check for command completion on next watchdog timer. */
+-      e100_dump_stats_cntrs(bdp);
+-
+-      wmb();
+-
+-      /* relaunch watchdog timer in 2 sec */
+-      mod_timer(&(bdp->watchdog_timer), jiffies + (2 * HZ));
+-
+-      if (list_empty(&bdp->active_rx_list))
+-              e100_trigger_SWI(bdp);
+-}
+-
+-/**
+- * e100_manage_adaptive_ifs
+- * @bdp: atapter's private data struct
+- *
+- * This routine manages the adaptive Inter-Frame Spacing algorithm
+- * using a state machine.
+- */
+-void
+-e100_manage_adaptive_ifs(struct e100_private *bdp)
+-{
+-      static u16 state_table[9][4] = {        // rows are states
+-              {2, 0, 0, 0},   // state0   // column0: next state if increasing
+-              {2, 0, 5, 30},  // state1   // column1: next state if decreasing
+-              {5, 1, 5, 30},  // state2   // column2: IFS value for 100 mbit
+-              {5, 3, 0, 0},   // state3   // column3: IFS value for 10 mbit
+-              {5, 3, 10, 60}, // state4
+-              {8, 4, 10, 60}, // state5
+-              {8, 6, 0, 0},   // state6
+-              {8, 6, 20, 60}, // state7
+-              {8, 7, 20, 60}  // state8
+-      };
+-
+-      u32 transmits =
+-              le32_to_cpu(bdp->stats_counters->basic_stats.xmt_gd_frames);
+-      u32 collisions =
+-              le32_to_cpu(bdp->stats_counters->basic_stats.xmt_ttl_coll);
+-      u32 state = bdp->ifs_state;
+-      u32 old_value = bdp->ifs_value;
+-      int next_col;
+-      u32 min_transmits;
+-
+-      if (bdp->cur_dplx_mode == FULL_DUPLEX) {
+-              bdp->ifs_state = 0;
+-              bdp->ifs_value = 0;
+-
+-      } else {                /* Half Duplex */
+-              /* Set speed specific parameters */
+-              if (bdp->cur_line_speed == 100) {
+-                      next_col = 2;
+-                      min_transmits = MIN_NUMBER_OF_TRANSMITS_100;
+-
+-              } else {        /* 10 Mbps */
+-                      next_col = 3;
+-                      min_transmits = MIN_NUMBER_OF_TRANSMITS_10;
+-              }
+-
+-              if ((transmits / 32 < collisions)
+-                  && (transmits > min_transmits)) {
+-                      state = state_table[state][0];  /* increment */
+-
+-              } else if (transmits < min_transmits) {
+-                      state = state_table[state][1];  /* decrement */
+-              }
+-
+-              bdp->ifs_value = state_table[state][next_col];
+-              bdp->ifs_state = state;
+-      }
+-
+-      /* If the IFS value has changed, configure the device */
+-      if (bdp->ifs_value != old_value) {
+-              e100_config_ifs(bdp);
+-              e100_config(bdp);
+-      }
+-}
+-
+-/**
+- * e100intr - interrupt handler
+- * @irq: the IRQ number
+- * @dev_inst: the net_device struct
+- * @regs: registers (unused)
+- *
+- * This routine is the ISR for the e100 board. It services
+- * the RX & TX queues & starts the RU if it has stopped due
+- * to no resources.
+- */
+-irqreturn_t
+-e100intr(int irq, void *dev_inst, struct pt_regs *regs)
+-{
+-      struct net_device *dev;
+-      struct e100_private *bdp;
+-      u16 intr_status;
+-
+-      dev = dev_inst;
+-      bdp = dev->priv;
+-
+-      intr_status = readw(&bdp->scb->scb_status);
+-      /* If not my interrupt, just return */
+-      if (!(intr_status & SCB_STATUS_ACK_MASK) || (intr_status == 0xffff)) {
+-              return IRQ_NONE;
+-      }
+-
+-      /* disable and ack intr */
+-      e100_disable_clear_intr(bdp);
+-
+-      /* the device is closed, don't continue or else bad things may happen. */
+-      if (!netif_running(dev)) {
+-              e100_set_intr_mask(bdp);
+-              return IRQ_NONE;
+-      }
+-
+-      /* SWI intr (triggered by watchdog) is signal to allocate new skb buffers */
+-      if (intr_status & SCB_STATUS_ACK_SWI) {
+-              e100_alloc_skbs(bdp);
+-      }
+-
+-      /* do recv work if any */
+-      if (intr_status &
+-          (SCB_STATUS_ACK_FR | SCB_STATUS_ACK_RNR | SCB_STATUS_ACK_SWI)) 
+-              bdp->drv_stats.rx_intr_pkts += e100_rx_srv(bdp);
+-
+-      /* clean up after tx'ed packets */
+-      if (intr_status & (SCB_STATUS_ACK_CNA | SCB_STATUS_ACK_CX))
+-              e100_tx_srv(bdp);
+-
+-      e100_set_intr_mask(bdp);
+-      return IRQ_HANDLED;
+-}
+-
+-/**
+- * e100_tx_skb_free - free TX skbs resources
+- * @bdp: atapter's private data struct
+- * @tcb: associated tcb of the freed skb
+- *
+- * This routine frees resources of TX skbs.
+- */
+-static inline void
+-e100_tx_skb_free(struct e100_private *bdp, tcb_t *tcb)
+-{
+-      if (tcb->tcb_skb) {
+-              int i;
+-              tbd_t *tbd_arr = tcb->tbd_ptr;
+-              int frags = skb_shinfo(tcb->tcb_skb)->nr_frags;
+-
+-              for (i = 0; i <= frags; i++, tbd_arr++) {
+-                      pci_unmap_single(bdp->pdev,
+-                                       le32_to_cpu(tbd_arr->tbd_buf_addr),
+-                                       le16_to_cpu(tbd_arr->tbd_buf_cnt),
+-                                       PCI_DMA_TODEVICE);
+-              }
+-              dev_kfree_skb_irq(tcb->tcb_skb);
+-              tcb->tcb_skb = NULL;
+-      }
+-}
+-
+-/**
+- * e100_tx_srv - service TX queues
+- * @bdp: atapter's private data struct
+- *
+- * This routine services the TX queues. It reclaims the TCB's & TBD's & other
+- * resources used during the transmit of this buffer. It is called from the ISR.
+- * We don't need a tx_lock since we always access buffers which were already
+- * prepared.
+- */
+-void
+-e100_tx_srv(struct e100_private *bdp)
+-{
+-      tcb_t *tcb;
+-      int i;
+-
+-      /* go over at most TxDescriptors buffers */
+-      for (i = 0; i < bdp->params.TxDescriptors; i++) {
+-              tcb = bdp->tcb_pool.data;
+-              tcb += bdp->tcb_pool.head;
+-
+-              rmb();
+-
+-              /* if the buffer at 'head' is not complete, break */
+-              if (!(tcb->tcb_hdr.cb_status &
+-                    __constant_cpu_to_le16(CB_STATUS_COMPLETE)))
+-                      break;
+-
+-              /* service next buffer, clear the out of resource condition */
+-              e100_tx_skb_free(bdp, tcb);
+-
+-              if (netif_running(bdp->device))
+-                      netif_wake_queue(bdp->device);
+-
+-              /* if we've caught up with 'tail', break */
+-              if (NEXT_TCB_TOUSE(bdp->tcb_pool.head) == bdp->tcb_pool.tail) {
+-                      break;
+-              }
+-
+-              bdp->tcb_pool.head = NEXT_TCB_TOUSE(bdp->tcb_pool.head);
+-      }
+-}
+-
+-/**
+- * e100_rx_srv - service RX queue
+- * @bdp: atapter's private data struct
+- * @max_number_of_rfds: max number of RFDs to process
+- * @rx_congestion: flag pointer, to inform the calling function of congestion.
+- *
+- * This routine processes the RX interrupt & services the RX queues.
+- * For each successful RFD, it allocates a new msg block, links that
+- * into the RFD list, and sends the old msg upstream.
+- * The new RFD is then put at the end of the free list of RFD's.
+- * It returns the number of serviced RFDs.
+- */
+-u32
+-e100_rx_srv(struct e100_private *bdp)
+-{
+-      rfd_t *rfd;             /* new rfd, received rfd */
+-      int i;
+-      u16 rfd_status;
+-      struct sk_buff *skb;
+-      struct net_device *dev;
+-      unsigned int data_sz;
+-      struct rx_list_elem *rx_struct;
+-      u32 rfd_cnt = 0;
+-
+-      dev = bdp->device;
+-
+-      /* current design of rx is as following:
+-       * 1. socket buffer (skb) used to pass network packet to upper layer
+-       * 2. all HW host memory structures (like RFDs, RBDs and data buffers)
+-       *    are placed in a skb's data room
+-       * 3. when rx process is complete, we change skb internal pointers to exclude
+-       *    from data area all unrelated things (RFD, RDB) and to leave
+-       *    just rx'ed packet netto
+-       * 4. for each skb passed to upper layer, new one is allocated instead.
+-       * 5. if no skb left, in 2 sec another atempt to allocate skbs will be made
+-       *    (watchdog trigger SWI intr and isr should allocate new skbs)
+-       */
+-      for (i = 0; i < bdp->params.RxDescriptors; i++) {
+-              if (list_empty(&(bdp->active_rx_list))) {
+-                      break;
+-              }
+-
+-              rx_struct = list_entry(bdp->active_rx_list.next,
+-                                     struct rx_list_elem, list_elem);
+-              skb = rx_struct->skb;
+-
+-              rfd = RFD_POINTER(skb, bdp);    /* locate RFD within skb */
+-
+-              // sync only the RFD header
+-              pci_dma_sync_single(bdp->pdev, rx_struct->dma_addr,
+-                                  bdp->rfd_size, PCI_DMA_FROMDEVICE);
+-              rfd_status = le16_to_cpu(rfd->rfd_header.cb_status);    /* get RFD's status */
+-              if (!(rfd_status & RFD_STATUS_COMPLETE))        /* does not contains data yet - exit */
+-                      break;
+-
+-              /* to allow manipulation with current skb we need to unlink it */
+-              list_del(&(rx_struct->list_elem));
+-
+-              /* do not free & unmap badly received packet.
+-               * move it to the end of skb list for reuse */
+-              if (!(rfd_status & RFD_STATUS_OK)) {
+-                      e100_add_skb_to_end(bdp, rx_struct);
+-                      continue;
+-              }
+-
+-              data_sz = min_t(u16, (le16_to_cpu(rfd->rfd_act_cnt) & 0x3fff),
+-                              (sizeof (rfd_t) - bdp->rfd_size));
+-
+-              /* now sync all the data */
+-              pci_dma_sync_single(bdp->pdev, rx_struct->dma_addr,
+-                                  (data_sz + bdp->rfd_size),
+-                                  PCI_DMA_FROMDEVICE);
+-
+-              pci_unmap_single(bdp->pdev, rx_struct->dma_addr,
+-                               sizeof (rfd_t), PCI_DMA_FROMDEVICE);
+-
+-              list_add(&(rx_struct->list_elem), &(bdp->rx_struct_pool));
+-
+-              /* end of dma access to rfd */
+-              bdp->skb_req++; /* incr number of requested skbs */
+-              e100_alloc_skbs(bdp);   /* and get them */
+-
+-              /* set packet size, excluding checksum (2 last bytes) if it is present */
+-              if ((bdp->flags & DF_CSUM_OFFLOAD)
+-                  && (bdp->rev_id < D102_REV_ID))
+-                      skb_put(skb, (int) data_sz - 2);
+-              else
+-                      skb_put(skb, (int) data_sz);
+-
+-              /* set the protocol */
+-              skb->protocol = eth_type_trans(skb, dev);
+-
+-              /* set the checksum info */
+-              if (bdp->flags & DF_CSUM_OFFLOAD) {
+-                      if (bdp->rev_id >= D102_REV_ID) {
+-                              skb->ip_summed = e100_D102_check_checksum(rfd);
+-                      } else {
+-                              skb->ip_summed = e100_D101M_checksum(bdp, skb);
+-                      }
+-              } else {
+-                      skb->ip_summed = CHECKSUM_NONE;
+-              }
+-
+-              bdp->drv_stats.net_stats.rx_bytes += skb->len;
+-
+-              if(bdp->vlgrp && (rfd_status & CB_STATUS_VLAN)) {
+-                      vlan_hwaccel_rx(skb, bdp->vlgrp, be16_to_cpu(rfd->vlanid));
+-              } else {
+-                      netif_rx(skb);
+-              }
+-              dev->last_rx = jiffies;
+-              
+-              rfd_cnt++;
+-      }                       /* end of rfd loop */
+-
+-      /* restart the RU if it has stopped */
+-      if ((readw(&bdp->scb->scb_status) & SCB_RUS_MASK) != SCB_RUS_READY) {
+-              e100_start_ru(bdp);
+-      }
+-
+-      return rfd_cnt;
+-}
+-
+-void
+-e100_refresh_txthld(struct e100_private *bdp)
+-{
+-      basic_cntr_t *pstat = &(bdp->stats_counters->basic_stats);
+-
+-      /* as long as tx_per_underrun is not 0, we can go about dynamically *
+-       * adjusting the xmit threshold. we stop doing that & resort to defaults
+-       * * once the adjustments become meaningless. the value is adjusted by *
+-       * dumping the error counters & checking the # of xmit underrun errors *
+-       * we've had. */
+-      if (bdp->tx_per_underrun) {
+-              /* We are going to last values dumped from the dump statistics
+-               * command */
+-              if (le32_to_cpu(pstat->xmt_gd_frames)) {
+-                      if (le32_to_cpu(pstat->xmt_uruns)) {
+-                              /* 
+-                               * if we have had more than one underrun per "DEFAULT #
+-                               * OF XMITS ALLOWED PER UNDERRUN" good xmits, raise the
+-                               * THRESHOLD.
+-                               */
+-                              if ((le32_to_cpu(pstat->xmt_gd_frames) /
+-                                   le32_to_cpu(pstat->xmt_uruns)) <
+-                                  bdp->tx_per_underrun) {
+-                                      bdp->tx_thld += 3;
+-                              }
+-                      }
+-
+-                      /* 
+-                       * if we've had less than one underrun per the DEFAULT number of
+-                       * of good xmits allowed, lower the THOLD but not less than 0 
+-                       */
+-                      if (le32_to_cpu(pstat->xmt_gd_frames) >
+-                          bdp->tx_per_underrun) {
+-                              bdp->tx_thld--;
+-
+-                              if (bdp->tx_thld < 6)
+-                                      bdp->tx_thld = 6;
+-
+-                      }
+-              }
+-
+-              /* end good xmits */
+-              /* 
+-               * * if our adjustments are becoming unresonable, stop adjusting &
+-               * resort * to defaults & pray. A THOLD value > 190 means that the
+-               * adapter will * wait for 190*8=1520 bytes in TX FIFO before it
+-               * starts xmit. Since * MTU is 1514, it doesn't make any sense for
+-               * further increase. */
+-              if (bdp->tx_thld >= 190) {
+-                      bdp->tx_per_underrun = 0;
+-                      bdp->tx_thld = 189;
+-              }
+-      }                       /* end underrun check */
+-}
+-
+-/**
+- * e100_prepare_xmit_buff - prepare a buffer for transmission
+- * @bdp: atapter's private data struct
+- * @skb: skb to send
+- *
+- * This routine prepare a buffer for transmission. It checks
+- * the message length for the appropiate size. It picks up a
+- * free tcb from the TCB pool and sets up the corresponding
+- * TBD's. If the number of fragments are more than the number
+- * of TBD/TCB it copies all the fragments in a coalesce buffer.
+- * It returns a pointer to the prepared TCB.
+- */
+-static inline tcb_t *
+-e100_prepare_xmit_buff(struct e100_private *bdp, struct sk_buff *skb)
+-{
+-      tcb_t *tcb, *prev_tcb;
+-
+-      tcb = bdp->tcb_pool.data;
+-      tcb += TCB_TO_USE(bdp->tcb_pool);
+-
+-      if (bdp->flags & USE_IPCB) {
+-              tcb->tcbu.ipcb.ip_activation_high = IPCB_IP_ACTIVATION_DEFAULT;
+-              tcb->tcbu.ipcb.ip_schedule &= ~IPCB_TCP_PACKET;
+-              tcb->tcbu.ipcb.ip_schedule &= ~IPCB_TCPUDP_CHECKSUM_ENABLE;
+-      }
+-
+-      if(bdp->vlgrp && vlan_tx_tag_present(skb)) {
+-              (tcb->tcbu).ipcb.ip_activation_high |= IPCB_INSERTVLAN_ENABLE;
+-              (tcb->tcbu).ipcb.vlan = cpu_to_be16(vlan_tx_tag_get(skb));
+-      }
+-      
+-      tcb->tcb_hdr.cb_status = 0;
+-      tcb->tcb_thrshld = bdp->tx_thld;
+-      tcb->tcb_hdr.cb_cmd |= __constant_cpu_to_le16(CB_S_BIT);
+-
+-      /* Set I (Interrupt) bit on every (TX_FRAME_CNT)th packet */
+-      if (!(++bdp->tx_count % TX_FRAME_CNT))
+-              tcb->tcb_hdr.cb_cmd |= __constant_cpu_to_le16(CB_I_BIT);
+-      else
+-              /* Clear I bit on other packets */
+-              tcb->tcb_hdr.cb_cmd &= ~__constant_cpu_to_le16(CB_I_BIT);
+-
+-      tcb->tcb_skb = skb;
+-
+-      if (skb->ip_summed == CHECKSUM_HW) {
+-              const struct iphdr *ip = skb->nh.iph;
+-
+-              if ((ip->protocol == IPPROTO_TCP) ||
+-                  (ip->protocol == IPPROTO_UDP)) {
+-
+-                      tcb->tcbu.ipcb.ip_activation_high |=
+-                              IPCB_HARDWAREPARSING_ENABLE;
+-                      tcb->tcbu.ipcb.ip_schedule |=
+-                              IPCB_TCPUDP_CHECKSUM_ENABLE;
+-
+-                      if (ip->protocol == IPPROTO_TCP)
+-                              tcb->tcbu.ipcb.ip_schedule |= IPCB_TCP_PACKET;
+-              }
+-      }
+-
+-      if (!skb_shinfo(skb)->nr_frags) {
+-              (tcb->tbd_ptr)->tbd_buf_addr =
+-                      cpu_to_le32(pci_map_single(bdp->pdev, skb->data,
+-                                                 skb->len, PCI_DMA_TODEVICE));
+-              (tcb->tbd_ptr)->tbd_buf_cnt = cpu_to_le16(skb->len);
+-              tcb->tcb_tbd_num = 1;
+-              tcb->tcb_tbd_ptr = tcb->tcb_tbd_dflt_ptr;
+-      } else {
+-              int i;
+-              void *addr;
+-              tbd_t *tbd_arr_ptr = &(tcb->tbd_ptr[1]);
+-              skb_frag_t *frag = &skb_shinfo(skb)->frags[0];
+-
+-              (tcb->tbd_ptr)->tbd_buf_addr =
+-                      cpu_to_le32(pci_map_single(bdp->pdev, skb->data,
+-                                                 skb_headlen(skb),
+-                                                 PCI_DMA_TODEVICE));
+-              (tcb->tbd_ptr)->tbd_buf_cnt =
+-                      cpu_to_le16(skb_headlen(skb));
+-
+-              for (i = 0; i < skb_shinfo(skb)->nr_frags;
+-                   i++, tbd_arr_ptr++, frag++) {
+-
+-                      addr = ((void *) page_address(frag->page) +
+-                              frag->page_offset);
+-
+-                      tbd_arr_ptr->tbd_buf_addr =
+-                              cpu_to_le32(pci_map_single(bdp->pdev,
+-                                                         addr, frag->size,
+-                                                         PCI_DMA_TODEVICE));
+-                      tbd_arr_ptr->tbd_buf_cnt = cpu_to_le16(frag->size);
+-              }
+-              tcb->tcb_tbd_num = skb_shinfo(skb)->nr_frags + 1;
+-              tcb->tcb_tbd_ptr = tcb->tcb_tbd_expand_ptr;
+-      }
+-
+-      /* clear the S-BIT on the previous tcb */
+-      prev_tcb = bdp->tcb_pool.data;
+-      prev_tcb += PREV_TCB_USED(bdp->tcb_pool);
+-      prev_tcb->tcb_hdr.cb_cmd &= __constant_cpu_to_le16((u16) ~CB_S_BIT);
+-
+-      bdp->tcb_pool.tail = NEXT_TCB_TOUSE(bdp->tcb_pool.tail);
+-
+-      wmb();
+-
+-      e100_start_cu(bdp, tcb);
+-
+-      return tcb;
+-}
+-
+-/* Changed for 82558 enhancement */
+-/**
+- * e100_start_cu - start the adapter's CU
+- * @bdp: atapter's private data struct
+- * @tcb: TCB to be transmitted
+- *
+- * This routine issues a CU Start or CU Resume command to the 82558/9.
+- * This routine was added because the prepare_ext_xmit_buff takes advantage
+- * of the 82558/9's Dynamic TBD chaining feature and has to start the CU as
+- * soon as the first TBD is ready. 
+- *
+- * e100_start_cu must be called while holding the tx_lock ! 
+- */
+-u8
+-e100_start_cu(struct e100_private *bdp, tcb_t *tcb)
+-{
+-      unsigned long lock_flag;
+-      u8 ret = true;
+-
+-      spin_lock_irqsave(&(bdp->bd_lock), lock_flag);
+-      switch (bdp->next_cu_cmd) {
+-      case RESUME_NO_WAIT:
+-              /*last cu command was a CU_RESMUE if this is a 558 or newer we don't need to
+-               * wait for command word to clear, we reach here only if we are bachlor
+-               */
+-              e100_exec_cmd(bdp, SCB_CUC_RESUME);
+-              break;
+-
+-      case RESUME_WAIT:
+-              if ((bdp->flags & IS_ICH) &&
+-                  (bdp->cur_line_speed == 10) &&
+-                  (bdp->cur_dplx_mode == HALF_DUPLEX)) {
+-                      e100_wait_exec_simple(bdp, SCB_CUC_NOOP);
+-                      udelay(1);
+-              }
+-              if ((e100_wait_exec_simple(bdp, SCB_CUC_RESUME)) &&
+-                  (bdp->flags & IS_BACHELOR) && (!(bdp->flags & IS_ICH))) {
+-                      bdp->next_cu_cmd = RESUME_NO_WAIT;
+-              }
+-              break;
+-
+-      case START_WAIT:
+-              // The last command was a non_tx CU command
+-              if (!e100_wait_cus_idle(bdp))
+-                      printk(KERN_DEBUG
+-                             "e100: %s: cu_start: timeout waiting for cu\n",
+-                             bdp->device->name);
+-              if (!e100_wait_exec_cmplx(bdp, (u32) (tcb->tcb_phys),
+-                                        SCB_CUC_START, CB_TRANSMIT)) {
+-                      printk(KERN_DEBUG
+-                             "e100: %s: cu_start: timeout waiting for scb\n",
+-                             bdp->device->name);
+-                      e100_exec_cmplx(bdp, (u32) (tcb->tcb_phys),
+-                                      SCB_CUC_START);
+-                      ret = false;
+-              }
+-
+-              bdp->next_cu_cmd = RESUME_WAIT;
+-
+-              break;
+-      }
+-
+-      /* save the last tcb */
+-      bdp->last_tcb = tcb;
+-
+-      spin_unlock_irqrestore(&(bdp->bd_lock), lock_flag);
+-      return ret;
+-}
+-
+-/* ====================================================================== */
+-/* hw                                                                     */
+-/* ====================================================================== */
+-
+-/**
+- * e100_selftest - perform H/W self test
+- * @bdp: atapter's private data struct
+- * @st_timeout: address to return timeout value, if fails
+- * @st_result: address to return selftest result, if fails
+- *
+- * This routine will issue PORT Self-test command to test the e100.
+- * The self-test will fail if the adapter's master-enable bit is not
+- * set in the PCI Command Register, or if the adapter is not seated
+- * in a PCI master-enabled slot. we also disable interrupts when the
+- * command is completed.
+- *
+- * Returns:
+- *      true: if adapter passes self_test
+- *      false: otherwise
+- */
+-unsigned char
+-e100_selftest(struct e100_private *bdp, u32 *st_timeout, u32 *st_result)
+-{
+-      u32 selftest_cmd;
+-
+-      /* initialize the nic state before running test */
+-      e100_sw_reset(bdp, PORT_SOFTWARE_RESET);
+-      /* Setup the address of the self_test area */
+-      selftest_cmd = bdp->selftest_phys;
+-
+-      /* Setup SELF TEST Command Code in D3 - D0 */
+-      selftest_cmd |= PORT_SELFTEST;
+-
+-      /* Initialize the self-test signature and results DWORDS */
+-      bdp->selftest->st_sign = 0;
+-      bdp->selftest->st_result = 0xffffffff;
+-
+-      /* Do the port command */
+-      writel(selftest_cmd, &bdp->scb->scb_port);
+-      readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */
+-
+-      /* Wait at least 10 milliseconds for the self-test to complete */
+-      set_current_state(TASK_UNINTERRUPTIBLE);
+-      schedule_timeout(HZ / 100 + 1);
+-
+-      /* disable interrupts since they are enabled */
+-      /* after device reset during selftest        */
+-      e100_disable_clear_intr(bdp);
+-
+-      /* if The First Self Test DWORD Still Zero, We've timed out. If the
+-       * second DWORD is not zero then we have an error. */
+-      if ((bdp->selftest->st_sign == 0) || (bdp->selftest->st_result != 0)) {
+-
+-              if (st_timeout)
+-                      *st_timeout = !(le32_to_cpu(bdp->selftest->st_sign));
+-
+-              if (st_result)
+-                      *st_result = le32_to_cpu(bdp->selftest->st_result);
+-
+-              return false;
+-      }
+-
+-      return true;
+-}
+-
+-/**
+- * e100_setup_iaaddr - issue IA setup sommand
+- * @bdp: atapter's private data struct
+- * @eaddr: new ethernet address
+- *
+- * This routine will issue the IA setup command. This command
+- * will notify the 82557 (e100) of what its individual (node)
+- * address is. This command will be executed in polled mode.
+- *
+- * Returns:
+- *      true: if the IA setup command was successfully issued and completed
+- *      false: otherwise
+- */
+-unsigned char
+-e100_setup_iaaddr(struct e100_private *bdp, u8 *eaddr)
+-{
+-      unsigned int i;
+-      cb_header_t *ntcb_hdr;
+-      unsigned char res;
+-      nxmit_cb_entry_t *cmd;
+-
+-      if ((cmd = e100_alloc_non_tx_cmd(bdp)) == NULL) {
+-              res = false;
+-              goto exit;
+-      }
+-
+-      ntcb_hdr = (cb_header_t *) cmd->non_tx_cmd;
+-      ntcb_hdr->cb_cmd = __constant_cpu_to_le16(CB_IA_ADDRESS);
+-
+-      for (i = 0; i < ETH_ALEN; i++) {
+-              (cmd->non_tx_cmd)->ntcb.setup.ia_addr[i] = eaddr[i];
+-      }
+-
+-      res = e100_exec_non_cu_cmd(bdp, cmd);
+-      if (!res)
+-              printk(KERN_WARNING "e100: %s: IA setup failed\n", 
+-                     bdp->device->name);
+-
+-exit:
+-      return res;
+-}
+-
+-/**
+- * e100_start_ru - start the RU if needed
+- * @bdp: atapter's private data struct
+- *
+- * This routine checks the status of the 82557's receive unit(RU),
+- * and starts the RU if it was not already active.  However,
+- * before restarting the RU, the driver gives the RU the buffers
+- * it freed up during the servicing of the ISR. If there are
+- * no free buffers to give to the RU, (i.e. we have reached a
+- * no resource condition) the RU will not be started till the
+- * next ISR.
+- */
+-void
+-e100_start_ru(struct e100_private *bdp)
+-{
+-      struct rx_list_elem *rx_struct = NULL;
+-      int buffer_found = 0;
+-      struct list_head *entry_ptr;
+-
+-      list_for_each(entry_ptr, &(bdp->active_rx_list)) {
+-              rx_struct =
+-                      list_entry(entry_ptr, struct rx_list_elem, list_elem);
+-              pci_dma_sync_single(bdp->pdev, rx_struct->dma_addr,
+-                                  bdp->rfd_size, PCI_DMA_FROMDEVICE);
+-              if (!((SKB_RFD_STATUS(rx_struct->skb, bdp) &
+-                     __constant_cpu_to_le16(RFD_STATUS_COMPLETE)))) {
+-                      buffer_found = 1;
+-                      break;
+-              }
+-      }
+-
+-      /* No available buffers */
+-      if (!buffer_found) {
+-              return;
+-      }
+-
+-      spin_lock(&bdp->bd_lock);
+-
+-      if (!e100_wait_exec_cmplx(bdp, rx_struct->dma_addr, SCB_RUC_START, 0)) {
+-              printk(KERN_DEBUG
+-                     "e100: %s: start_ru: wait_scb failed\n", 
+-                     bdp->device->name);
+-              e100_exec_cmplx(bdp, rx_struct->dma_addr, SCB_RUC_START);
+-      }
+-      if (bdp->next_cu_cmd == RESUME_NO_WAIT) {
+-              bdp->next_cu_cmd = RESUME_WAIT;
+-      }
+-      spin_unlock(&bdp->bd_lock);
+-}
+-
+-/**
+- * e100_cmd_complete_location
+- * @bdp: atapter's private data struct
+- *
+- * This routine returns a pointer to the location of the command-complete
+- * DWord in the dump statistical counters area, according to the statistical
+- * counters mode (557 - basic, 558 - extended, or 559 - TCO mode).
+- * See e100_config_init() for the setting of the statistical counters mode.
+- */
+-static u32 *
+-e100_cmd_complete_location(struct e100_private *bdp)
+-{
+-      u32 *cmd_complete;
+-      max_counters_t *stats = bdp->stats_counters;
+-
+-      switch (bdp->stat_mode) {
+-      case E100_EXTENDED_STATS:
+-              cmd_complete =
+-                      (u32 *) &(((err_cntr_558_t *) (stats))->cmd_complete);
+-              break;
+-
+-      case E100_TCO_STATS:
+-              cmd_complete =
+-                      (u32 *) &(((err_cntr_559_t *) (stats))->cmd_complete);
+-              break;
+-
+-      case E100_BASIC_STATS:
+-      default:                
+-              cmd_complete =
+-                      (u32 *) &(((err_cntr_557_t *) (stats))->cmd_complete);
+-              break;
+-      }
+-
+-      return cmd_complete;
+-}
+-
+-/**
+- * e100_clr_cntrs - clear statistics counters
+- * @bdp: atapter's private data struct
+- *
+- * This routine will clear the adapter error statistic counters.
+- *
+- * Returns:
+- *      true: if successfully cleared stat counters
+- *      false: otherwise
+- */
+-static unsigned char __devinit
+-e100_clr_cntrs(struct e100_private *bdp)
+-{
+-      volatile u32 *pcmd_complete;
+-
+-      /* clear the dump counter complete word */
+-      pcmd_complete = e100_cmd_complete_location(bdp);
+-      *pcmd_complete = 0;
+-      wmb();
+-
+-      if (!e100_wait_exec_cmplx(bdp, bdp->stat_cnt_phys, SCB_CUC_DUMP_ADDR, 0))
+-              return false;
+-
+-      /* wait 10 microseconds for the command to complete */
+-      udelay(10);
+-
+-      if (!e100_wait_exec_simple(bdp, SCB_CUC_DUMP_RST_STAT))
+-              return false;
+-
+-      if (bdp->next_cu_cmd == RESUME_NO_WAIT) {
+-              bdp->next_cu_cmd = RESUME_WAIT;
+-      }
+-
+-      return true;
+-}
+-
+-static unsigned char
+-e100_update_stats(struct e100_private *bdp)
+-{
+-      u32 *pcmd_complete;
+-      basic_cntr_t *pstat = &(bdp->stats_counters->basic_stats);
+-
+-      // check if last dump command completed
+-      pcmd_complete = e100_cmd_complete_location(bdp);
+-      if (*pcmd_complete != le32_to_cpu(DUMP_RST_STAT_COMPLETED) &&
+-          *pcmd_complete != le32_to_cpu(DUMP_STAT_COMPLETED)) {
+-              *pcmd_complete = 0;
+-              return false;
+-      }
+-
+-      /* increment the statistics */
+-      bdp->drv_stats.net_stats.rx_packets +=
+-              le32_to_cpu(pstat->rcv_gd_frames);
+-      bdp->drv_stats.net_stats.tx_packets +=
+-              le32_to_cpu(pstat->xmt_gd_frames);
+-      bdp->drv_stats.net_stats.rx_dropped += le32_to_cpu(pstat->rcv_rsrc_err);
+-      bdp->drv_stats.net_stats.collisions += le32_to_cpu(pstat->xmt_ttl_coll);
+-      bdp->drv_stats.net_stats.rx_length_errors +=
+-              le32_to_cpu(pstat->rcv_shrt_frames);
+-      bdp->drv_stats.net_stats.rx_over_errors +=
+-              le32_to_cpu(pstat->rcv_rsrc_err);
+-      bdp->drv_stats.net_stats.rx_crc_errors +=
+-              le32_to_cpu(pstat->rcv_crc_errs);
+-      bdp->drv_stats.net_stats.rx_frame_errors +=
+-              le32_to_cpu(pstat->rcv_algn_errs);
+-      bdp->drv_stats.net_stats.rx_fifo_errors +=
+-              le32_to_cpu(pstat->rcv_oruns);
+-      bdp->drv_stats.net_stats.tx_aborted_errors +=
+-              le32_to_cpu(pstat->xmt_max_coll);
+-      bdp->drv_stats.net_stats.tx_carrier_errors +=
+-              le32_to_cpu(pstat->xmt_lost_crs);
+-      bdp->drv_stats.net_stats.tx_fifo_errors +=
+-              le32_to_cpu(pstat->xmt_uruns);
+-
+-      bdp->drv_stats.tx_late_col += le32_to_cpu(pstat->xmt_late_coll);
+-      bdp->drv_stats.tx_ok_defrd += le32_to_cpu(pstat->xmt_deferred);
+-      bdp->drv_stats.tx_one_retry += le32_to_cpu(pstat->xmt_sngl_coll);
+-      bdp->drv_stats.tx_mt_one_retry += le32_to_cpu(pstat->xmt_mlt_coll);
+-      bdp->drv_stats.rcv_cdt_frames += le32_to_cpu(pstat->rcv_err_coll);
+-
+-      if (bdp->stat_mode != E100_BASIC_STATS) {
+-              ext_cntr_t *pex_stat = &bdp->stats_counters->extended_stats;
+-
+-              bdp->drv_stats.xmt_fc_pkts +=
+-                      le32_to_cpu(pex_stat->xmt_fc_frames);
+-              bdp->drv_stats.rcv_fc_pkts +=
+-                      le32_to_cpu(pex_stat->rcv_fc_frames);
+-              bdp->drv_stats.rcv_fc_unsupported +=
+-                      le32_to_cpu(pex_stat->rcv_fc_unsupported);
+-      }
+-
+-      if (bdp->stat_mode == E100_TCO_STATS) {
+-              tco_cntr_t *ptco_stat = &bdp->stats_counters->tco_stats;
+-
+-              bdp->drv_stats.xmt_tco_pkts +=
+-                      le16_to_cpu(ptco_stat->xmt_tco_frames);
+-              bdp->drv_stats.rcv_tco_pkts +=
+-                      le16_to_cpu(ptco_stat->rcv_tco_frames);
+-      }
+-
+-      *pcmd_complete = 0;
+-      return true;
+-}
+-
+-/**
+- * e100_dump_stat_cntrs
+- * @bdp: atapter's private data struct
+- *
+- * This routine will dump the board statistical counters without waiting
+- * for stat_dump to complete. Any access to this stats should verify the completion
+- * of the command
+- */
+-void
+-e100_dump_stats_cntrs(struct e100_private *bdp)
+-{
+-      unsigned long lock_flag_bd;
+-
+-      spin_lock_irqsave(&(bdp->bd_lock), lock_flag_bd);
+-
+-      /* dump h/w stats counters */
+-      if (e100_wait_exec_simple(bdp, SCB_CUC_DUMP_RST_STAT)) {
+-              if (bdp->next_cu_cmd == RESUME_NO_WAIT) {
+-                      bdp->next_cu_cmd = RESUME_WAIT;
+-              }
+-      }
+-
+-      spin_unlock_irqrestore(&(bdp->bd_lock), lock_flag_bd);
+-}
+-
+-/**
+- * e100_exec_non_cu_cmd
+- * @bdp: atapter's private data struct
+- * @command: the non-cu command to execute
+- *
+- * This routine will submit a command block to be executed,
+- */
+-unsigned char
+-e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
+-{
+-      cb_header_t *ntcb_hdr;
+-      unsigned long lock_flag;
+-      unsigned long expiration_time;
+-      unsigned char rc = true;
+-      u8 sub_cmd;
+-
+-      ntcb_hdr = (cb_header_t *) command->non_tx_cmd; /* get hdr of non tcb cmd */
+-      sub_cmd = cpu_to_le16(ntcb_hdr->cb_cmd);
+-
+-      /* Set the Command Block to be the last command block */
+-      ntcb_hdr->cb_cmd |= __constant_cpu_to_le16(CB_EL_BIT);
+-      ntcb_hdr->cb_status = 0;
+-      ntcb_hdr->cb_lnk_ptr = 0;
+-
+-      wmb();
+-      if (in_interrupt())
+-              return e100_delayed_exec_non_cu_cmd(bdp, command);
+-
+-      if (netif_running(bdp->device) && netif_carrier_ok(bdp->device))
+-              return e100_delayed_exec_non_cu_cmd(bdp, command);
+-
+-      spin_lock_bh(&(bdp->bd_non_tx_lock));
+-
+-      if (bdp->non_tx_command_state != E100_NON_TX_IDLE) {
+-              goto delayed_exec;
+-      }
+-
+-      if (bdp->last_tcb) {
+-              rmb();
+-              if ((bdp->last_tcb->tcb_hdr.cb_status &
+-                   __constant_cpu_to_le16(CB_STATUS_COMPLETE)) == 0)
+-                      goto delayed_exec;
+-      }
+-
+-      if ((readw(&bdp->scb->scb_status) & SCB_CUS_MASK) == SCB_CUS_ACTIVE) {
+-              goto delayed_exec;
+-      }
+-
+-      spin_lock_irqsave(&bdp->bd_lock, lock_flag);
+-
+-      if (!e100_wait_exec_cmplx(bdp, command->dma_addr, SCB_CUC_START, sub_cmd)) {
+-              spin_unlock_irqrestore(&(bdp->bd_lock), lock_flag);
+-              rc = false;
+-              goto exit;
+-      }
+-
+-      bdp->next_cu_cmd = START_WAIT;
+-      spin_unlock_irqrestore(&(bdp->bd_lock), lock_flag);
+-
+-      /* now wait for completion of non-cu CB up to 20 msec */
+-      expiration_time = jiffies + HZ / 50 + 1;
+-      rmb();
+-      while (!(ntcb_hdr->cb_status &
+-                   __constant_cpu_to_le16(CB_STATUS_COMPLETE))) {
+-
+-              if (time_before(jiffies, expiration_time)) {
+-                      spin_unlock_bh(&(bdp->bd_non_tx_lock));
+-                      yield();
+-                      spin_lock_bh(&(bdp->bd_non_tx_lock));
+-              } else {
+-#ifdef E100_CU_DEBUG                  
+-                      printk(KERN_ERR "e100: %s: non-TX command (%x) "
+-                              "timeout\n", bdp->device->name, sub_cmd);
+-#endif                        
+-                      rc = false;
+-                      goto exit;
+-              }
+-              rmb();
+-      }
+-
+-exit:
+-      e100_free_non_tx_cmd(bdp, command);
+-
+-      if (netif_running(bdp->device))
+-              netif_wake_queue(bdp->device);
+-
+-      spin_unlock_bh(&(bdp->bd_non_tx_lock));
+-      return rc;
+-
+-delayed_exec:
+-      spin_unlock_bh(&(bdp->bd_non_tx_lock));
+-      return e100_delayed_exec_non_cu_cmd(bdp, command);
+-}
+-
+-/**
+- * e100_sw_reset
+- * @bdp: atapter's private data struct
+- * @reset_cmd: s/w reset or selective reset
+- *
+- * This routine will issue a software reset to the adapter. It 
+- * will also disable interrupts, as the are enabled after reset.
+- */
+-void
+-e100_sw_reset(struct e100_private *bdp, u32 reset_cmd)
+-{
+-      /* Do  a selective reset first to avoid a potential PCI hang */
+-      writel(PORT_SELECTIVE_RESET, &bdp->scb->scb_port);
+-      readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */
+-
+-      /* wait for the reset to take effect */
+-      udelay(20);
+-      if (reset_cmd == PORT_SOFTWARE_RESET) {
+-              writel(PORT_SOFTWARE_RESET, &bdp->scb->scb_port);
+-
+-              /* wait 20 micro seconds for the reset to take effect */
+-              udelay(20);
+-      }
+-
+-      /* Mask off our interrupt line -- it is unmasked after reset */
+-      e100_disable_clear_intr(bdp);
+-#ifdef E100_CU_DEBUG  
+-      bdp->last_cmd = 0;
+-      bdp->last_sub_cmd = 0;
+-#endif        
+-}
+-
+-/**
+- * e100_load_microcode - Download microsocde to controller.
+- * @bdp: atapter's private data struct
+- *
+- * This routine downloads microcode on to the controller. This
+- * microcode is available for the 82558/9, 82550. Currently the
+- * microcode handles interrupt bundling and TCO workaround.
+- *
+- * Returns:
+- *      true: if successfull
+- *      false: otherwise
+- */
+-static unsigned char
+-e100_load_microcode(struct e100_private *bdp)
+-{
+-      static struct {
+-              u8 rev_id;
+-              u32 ucode[UCODE_MAX_DWORDS + 1];
+-              int timer_dword;
+-              int bundle_dword;
+-              int min_size_dword;
+-      } ucode_opts[] = {
+-              { D101A4_REV_ID,
+-                D101_A_RCVBUNDLE_UCODE,
+-                D101_CPUSAVER_TIMER_DWORD,
+-                D101_CPUSAVER_BUNDLE_DWORD,
+-                D101_CPUSAVER_MIN_SIZE_DWORD },
+-              { D101B0_REV_ID,
+-                D101_B0_RCVBUNDLE_UCODE,
+-                D101_CPUSAVER_TIMER_DWORD,
+-                D101_CPUSAVER_BUNDLE_DWORD,
+-                D101_CPUSAVER_MIN_SIZE_DWORD },
+-              { D101MA_REV_ID,
+-                D101M_B_RCVBUNDLE_UCODE,
+-                D101M_CPUSAVER_TIMER_DWORD,
+-                D101M_CPUSAVER_BUNDLE_DWORD,
+-                D101M_CPUSAVER_MIN_SIZE_DWORD },
+-              { D101S_REV_ID,
+-                D101S_RCVBUNDLE_UCODE,
+-                D101S_CPUSAVER_TIMER_DWORD,
+-                D101S_CPUSAVER_BUNDLE_DWORD,
+-                D101S_CPUSAVER_MIN_SIZE_DWORD },
+-              { D102_REV_ID,
+-                D102_B_RCVBUNDLE_UCODE,
+-                D102_B_CPUSAVER_TIMER_DWORD,
+-                D102_B_CPUSAVER_BUNDLE_DWORD,
+-                D102_B_CPUSAVER_MIN_SIZE_DWORD },
+-              { D102C_REV_ID,
+-                D102_C_RCVBUNDLE_UCODE,
+-                D102_C_CPUSAVER_TIMER_DWORD,
+-                D102_C_CPUSAVER_BUNDLE_DWORD,
+-                D102_C_CPUSAVER_MIN_SIZE_DWORD },
+-              { D102E_REV_ID,
+-                D102_E_RCVBUNDLE_UCODE,
+-                D102_E_CPUSAVER_TIMER_DWORD,
+-                D102_E_CPUSAVER_BUNDLE_DWORD,
+-                D102_E_CPUSAVER_MIN_SIZE_DWORD },
+-              { 0, {0}, 0, 0, 0}
+-      }, *opts;
+-
+-      opts = ucode_opts;
+-
+-      /* User turned ucode loading off */
+-      if (!(bdp->params.b_params & PRM_UCODE))
+-              return false;
+-
+-      /* These controllers do not need ucode */
+-      if (bdp->flags & IS_ICH)
+-              return false;
+-
+-      /* Search for ucode match against h/w rev_id */
+-      while (opts->rev_id) {
+-              if (bdp->rev_id == opts->rev_id) {
+-                      int i;
+-                      u32 *ucode_dword;
+-                      load_ucode_cb_t *ucode_cmd_ptr;
+-                      nxmit_cb_entry_t *cmd = e100_alloc_non_tx_cmd(bdp);
+-
+-                      if (cmd != NULL) {
+-                              ucode_cmd_ptr =
+-                                      (load_ucode_cb_t *) cmd->non_tx_cmd;
+-                              ucode_dword = ucode_cmd_ptr->ucode_dword;
+-                      } else {
+-                              return false;
+-                      }
+-
+-                      memcpy(ucode_dword, opts->ucode, sizeof (opts->ucode));
+-
+-                      /* Insert user-tunable settings */
+-                      ucode_dword[opts->timer_dword] &= 0xFFFF0000;
+-                      ucode_dword[opts->timer_dword] |=
+-                              (u16) bdp->params.IntDelay;
+-                      ucode_dword[opts->bundle_dword] &= 0xFFFF0000;
+-                      ucode_dword[opts->bundle_dword] |=
+-                              (u16) bdp->params.BundleMax;
+-                      ucode_dword[opts->min_size_dword] &= 0xFFFF0000;
+-                      ucode_dword[opts->min_size_dword] |=
+-                              (bdp->params.b_params & PRM_BUNDLE_SMALL) ?
+-                              0xFFFF : 0xFF80;
+-
+-                      for (i = 0; i < UCODE_MAX_DWORDS; i++)
+-                              cpu_to_le32s(&(ucode_dword[i]));
+-
+-                      ucode_cmd_ptr->load_ucode_cbhdr.cb_cmd =
+-                              __constant_cpu_to_le16(CB_LOAD_MICROCODE);
+-
+-                      return e100_exec_non_cu_cmd(bdp, cmd);
+-              }
+-              opts++;
+-      }
+-
+-      return false;
+-}
+-
+-/***************************************************************************/
+-/***************************************************************************/
+-/*       EEPROM  Functions                                                 */
+-/***************************************************************************/
+-
+-/* Read PWA (printed wired assembly) number */
+-void __devinit
+-e100_rd_pwa_no(struct e100_private *bdp)
+-{
+-      bdp->pwa_no = e100_eeprom_read(bdp, EEPROM_PWA_NO);
+-      bdp->pwa_no <<= 16;
+-      bdp->pwa_no |= e100_eeprom_read(bdp, EEPROM_PWA_NO + 1);
+-}
+-
+-/* Read the permanent ethernet address from the eprom. */
+-void __devinit
+-e100_rd_eaddr(struct e100_private *bdp)
+-{
+-      int i;
+-      u16 eeprom_word;
+-
+-      for (i = 0; i < 6; i += 2) {
+-              eeprom_word =
+-                      e100_eeprom_read(bdp,
+-                                       EEPROM_NODE_ADDRESS_BYTE_0 + (i / 2));
+-
+-              bdp->device->dev_addr[i] =
+-                      bdp->perm_node_address[i] = (u8) eeprom_word;
+-              bdp->device->dev_addr[i + 1] =
+-                      bdp->perm_node_address[i + 1] = (u8) (eeprom_word >> 8);
+-      }
+-}
+-
+-/* Check the D102 RFD flags to see if the checksum passed */
+-static unsigned char
+-e100_D102_check_checksum(rfd_t *rfd)
+-{
+-      if (((le16_to_cpu(rfd->rfd_header.cb_status)) & RFD_PARSE_BIT)
+-          && (((rfd->rcvparserstatus & CHECKSUM_PROTOCOL_MASK) ==
+-               RFD_TCP_PACKET)
+-              || ((rfd->rcvparserstatus & CHECKSUM_PROTOCOL_MASK) ==
+-                  RFD_UDP_PACKET))
+-          && (rfd->checksumstatus & TCPUDP_CHECKSUM_BIT_VALID)
+-          && (rfd->checksumstatus & TCPUDP_CHECKSUM_VALID)) {
+-              return CHECKSUM_UNNECESSARY;
+-      }
+-      return CHECKSUM_NONE;
+-}
+-
+-/**
+- * e100_D101M_checksum
+- * @bdp: atapter's private data struct
+- * @skb: skb received
+- *
+- * Sets the skb->csum value from D101 csum found at the end of the Rx frame. The
+- * D101M sums all words in frame excluding the ethernet II header (14 bytes) so
+- * in case the packet is ethernet II and the protocol is IP, all is need is to
+- * assign this value to skb->csum.
+- */
+-static unsigned char
+-e100_D101M_checksum(struct e100_private *bdp, struct sk_buff *skb)
+-{
+-      unsigned short proto = (skb->protocol);
+-
+-      if (proto == __constant_htons(ETH_P_IP)) {
+-
+-              skb->csum = get_unaligned((u16 *) (skb->tail));
+-              return CHECKSUM_HW;
+-      }
+-      return CHECKSUM_NONE;
+-}
+-
+-/***************************************************************************/
+-/***************************************************************************/
+-/***************************************************************************/
+-/***************************************************************************/
+-/*       Auxilary Functions                                                */
+-/***************************************************************************/
+-
+-/* Print the board's configuration */
+-void __devinit
+-e100_print_brd_conf(struct e100_private *bdp)
+-{
+-      /* Print the string if checksum Offloading was enabled */
+-      if (bdp->flags & DF_CSUM_OFFLOAD)
+-              printk(KERN_NOTICE "  Hardware receive checksums enabled\n");
+-      else {
+-              if (bdp->rev_id >= D101MA_REV_ID) 
+-                      printk(KERN_NOTICE "  Hardware receive checksums disabled\n");
+-      }
+-
+-      if ((bdp->flags & DF_UCODE_LOADED))
+-              printk(KERN_NOTICE "  cpu cycle saver enabled\n");
+-}
+-
+-/**
+- * e100_pci_setup - setup the adapter's PCI information
+- * @pcid: adapter's pci_dev struct
+- * @bdp: atapter's private data struct
+- *
+- * This routine sets up all PCI information for the adapter. It enables the bus
+- * master bit (some BIOS don't do this), requests memory ans I/O regions, and
+- * calls ioremap() on the adapter's memory region.
+- *
+- * Returns:
+- *      true: if successfull
+- *      false: otherwise
+- */
+-static unsigned char __devinit
+-e100_pci_setup(struct pci_dev *pcid, struct e100_private *bdp)
+-{
+-      struct net_device *dev = bdp->device;
+-      int rc = 0;
+-
+-      if ((rc = pci_enable_device(pcid)) != 0) {
+-              goto err;
+-      }
+-
+-      /* dev and ven ID have already been checked so it is our device */
+-      pci_read_config_byte(pcid, PCI_REVISION_ID, (u8 *) &(bdp->rev_id));
+-
+-      /* address #0 is a memory region */
+-      dev->mem_start = pci_resource_start(pcid, 0);
+-      dev->mem_end = dev->mem_start + sizeof (scb_t);
+-
+-      /* address #1 is a IO region */
+-      dev->base_addr = pci_resource_start(pcid, 1);
+-
+-      if ((rc = pci_request_regions(pcid, e100_short_driver_name)) != 0) {
+-              goto err_disable;
+-      }
+-
+-      pci_enable_wake(pcid, 0, 0);
+-
+-      /* if Bus Mastering is off, turn it on! */
+-      pci_set_master(pcid);
+-
+-      /* address #0 is a memory mapping */
+-      bdp->scb = (scb_t *) ioremap_nocache(dev->mem_start, sizeof (scb_t));
+-
+-      if (!bdp->scb) {
+-              printk(KERN_ERR "e100: %s: Failed to map PCI address 0x%lX\n",
+-                     dev->name, pci_resource_start(pcid, 0));
+-              rc = -ENOMEM;
+-              goto err_region;
+-      }
+-
+-      return 0;
+-
+-err_region:
+-      pci_release_regions(pcid);
+-err_disable:
+-      pci_disable_device(pcid);
+-err:
+-      return rc;
+-}
+-
+-void
+-e100_isolate_driver(struct e100_private *bdp)
+-{
+-
+-      /* Check if interface is up                              */
+-      /* NOTE: Can't use netif_running(bdp->device) because    */
+-      /* dev_close clears __LINK_STATE_START before calling    */
+-      /* e100_close (aka dev->stop)                            */
+-      if (bdp->device->flags & IFF_UP) {
+-              e100_disable_clear_intr(bdp);
+-              del_timer_sync(&bdp->watchdog_timer);
+-              netif_carrier_off(bdp->device);
+-              netif_stop_queue(bdp->device); 
+-              bdp->last_tcb = NULL;
+-      } 
+-      e100_sw_reset(bdp, PORT_SELECTIVE_RESET);
+-}
+-
+-static void
+-e100_tcb_add_C_bit(struct e100_private *bdp)
+-{
+-      tcb_t *tcb = (tcb_t *) bdp->tcb_pool.data;
+-      int i;
+-
+-      for (i = 0; i < bdp->params.TxDescriptors; i++, tcb++) {
+-              tcb->tcb_hdr.cb_status |= cpu_to_le16(CB_STATUS_COMPLETE);
+-      }
+-}
+-
+-/* 
+- * Procedure:   e100_configure_device
+- *
+- * Description: This routine will configure device
+- *
+- * Arguments:
+- *      bdp - Ptr to this card's e100_bdconfig structure
+- *
+- * Returns:
+- *        true upon success
+- *        false upon failure
+- */
+-unsigned char
+-e100_configure_device(struct e100_private *bdp)
+-{
+-      /*load CU & RU base */
+-      if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE, 0))
+-              return false;
+-
+-      if (e100_load_microcode(bdp))
+-              bdp->flags |= DF_UCODE_LOADED;
+-
+-      if (!e100_wait_exec_cmplx(bdp, 0, SCB_RUC_LOAD_BASE, 0))
+-              return false;
+-
+-      /* Issue the load dump counters address command */
+-      if (!e100_wait_exec_cmplx(bdp, bdp->stat_cnt_phys, SCB_CUC_DUMP_ADDR, 0))
+-              return false;
+-
+-      if (!e100_setup_iaaddr(bdp, bdp->device->dev_addr)) {
+-              printk(KERN_ERR "e100: e100_configure_device: "
+-                      "setup iaaddr failed\n");
+-              return false;
+-      }
+-
+-      e100_set_multi_exec(bdp->device);
+-
+-      /* Change for 82558 enhancement                                */
+-      /* If 82558/9 and if the user has enabled flow control, set up */
+-      /* flow Control Reg. in the CSR                                */
+-      if ((bdp->flags & IS_BACHELOR)
+-          && (bdp->params.b_params & PRM_FC)) {
+-              writeb(DFLT_FC_THLD,
+-                      &bdp->scb->scb_ext.d101_scb.scb_fc_thld);
+-              writeb(DFLT_FC_CMD,
+-                      &bdp->scb->scb_ext.d101_scb.scb_fc_xon_xoff);
+-      }
+-
+-      e100_force_config(bdp);
+-
+-      return true;
+-}
+-
+-void
+-e100_deisolate_driver(struct e100_private *bdp, u8 full_reset)
+-{
+-      u32 cmd = full_reset ? PORT_SOFTWARE_RESET : PORT_SELECTIVE_RESET;
+-      e100_sw_reset(bdp, cmd);
+-      if (cmd == PORT_SOFTWARE_RESET) {
+-              if (!e100_configure_device(bdp))
+-                      printk(KERN_ERR "e100: e100_deisolate_driver:" 
+-                              " device configuration failed\n");
+-      } 
+-
+-      if (netif_running(bdp->device)) {
+-
+-              bdp->next_cu_cmd = START_WAIT;
+-              bdp->last_tcb = NULL;
+-
+-              e100_start_ru(bdp);
+-
+-              /* relaunch watchdog timer in 2 sec */
+-              mod_timer(&(bdp->watchdog_timer), jiffies + (2 * HZ));
+-
+-              // we must clear tcbs since we may have lost Tx intrrupt
+-              // or have unsent frames on the tcb chain
+-              e100_tcb_add_C_bit(bdp);
+-              e100_tx_srv(bdp);
+-              netif_wake_queue(bdp->device);
+-              e100_set_intr_mask(bdp);
+-      }
+-}
+-
+-static int
+-e100_do_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct ethtool_cmd ecmd;
+-      int rc = -EOPNOTSUPP;
+-
+-      if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd.cmd)))
+-              return -EFAULT;
+-
+-      switch (ecmd.cmd) {
+-      case ETHTOOL_GSET:
+-              rc = e100_ethtool_get_settings(dev, ifr);
+-              break;
+-      case ETHTOOL_SSET:
+-              rc = e100_ethtool_set_settings(dev, ifr);
+-              break;
+-      case ETHTOOL_GDRVINFO:
+-              rc = e100_ethtool_get_drvinfo(dev, ifr);
+-              break;
+-      case ETHTOOL_GREGS:
+-              rc = e100_ethtool_gregs(dev, ifr);
+-              break;
+-      case ETHTOOL_NWAY_RST:
+-              rc = e100_ethtool_nway_rst(dev, ifr);
+-              break;
+-      case ETHTOOL_GLINK:
+-              rc = e100_ethtool_glink(dev, ifr);
+-              break;
+-      case ETHTOOL_GEEPROM:
+-      case ETHTOOL_SEEPROM:
+-              rc = e100_ethtool_eeprom(dev, ifr);
+-              break;
+-      case ETHTOOL_GSTATS: {
+-              struct {
+-                      struct ethtool_stats cmd;
+-                      uint64_t data[E100_STATS_LEN];
+-              } stats = { {ETHTOOL_GSTATS, E100_STATS_LEN} };
+-              struct e100_private *bdp = dev->priv;
+-              void *addr = ifr->ifr_data;
+-              int i;
+-
+-              for(i = 0; i < E100_STATS_LEN; i++)
+-                      stats.data[i] =
+-                              ((unsigned long *)&bdp->drv_stats.net_stats)[i];
+-              if(copy_to_user(addr, &stats, sizeof(stats)))
+-                      return -EFAULT;
+-              return 0;
+-      }
+-      case ETHTOOL_GWOL:
+-      case ETHTOOL_SWOL:
+-              rc = e100_ethtool_wol(dev, ifr);
+-              break;
+-      case ETHTOOL_TEST:
+-              rc = e100_ethtool_test(dev, ifr);
+-              break;
+-      case ETHTOOL_GSTRINGS:
+-              rc = e100_ethtool_gstrings(dev,ifr);
+-              break;
+-      case ETHTOOL_PHYS_ID:
+-              rc = e100_ethtool_led_blink(dev,ifr);
+-              break;
+-#ifdef        ETHTOOL_GRINGPARAM
+-      case ETHTOOL_GRINGPARAM: {
+-              struct ethtool_ringparam ering;
+-              struct e100_private *bdp = dev->priv;
+-              memset((void *) &ering, 0, sizeof(ering));
+-              ering.rx_max_pending = E100_MAX_RFD;
+-              ering.tx_max_pending = E100_MAX_TCB;
+-              ering.rx_pending = bdp->params.RxDescriptors;
+-              ering.tx_pending = bdp->params.TxDescriptors;
+-              rc = copy_to_user(ifr->ifr_data, &ering, sizeof(ering))
+-                      ? -EFAULT : 0;
+-              return rc;
+-      }
+-#endif
+-#ifdef        ETHTOOL_SRINGPARAM
+-      case ETHTOOL_SRINGPARAM: {
+-              struct ethtool_ringparam ering;
+-              struct e100_private *bdp = dev->priv;
+-              if (copy_from_user(&ering, ifr->ifr_data, sizeof(ering)))
+-                      return -EFAULT;
+-              if (ering.rx_pending > E100_MAX_RFD 
+-                  || ering.rx_pending < E100_MIN_RFD)
+-                      return -EINVAL;
+-              if (ering.tx_pending > E100_MAX_TCB 
+-                  || ering.tx_pending < E100_MIN_TCB)
+-                      return -EINVAL;
+-              if (netif_running(dev)) {
+-                      spin_lock_bh(&dev->xmit_lock);
+-                      e100_close(dev);
+-                      spin_unlock_bh(&dev->xmit_lock);
+-                      /* Use new values to open interface */
+-                      bdp->params.RxDescriptors = ering.rx_pending;
+-                      bdp->params.TxDescriptors = ering.tx_pending;
+-                      e100_hw_init(bdp);
+-                      e100_open(dev);
+-              }
+-              else {
+-                      bdp->params.RxDescriptors = ering.rx_pending;
+-                      bdp->params.TxDescriptors = ering.tx_pending;
+-              }
+-              return 0;
+-      }
+-#endif
+-#ifdef        ETHTOOL_GPAUSEPARAM
+-      case ETHTOOL_GPAUSEPARAM: {
+-              struct ethtool_pauseparam epause;
+-              struct e100_private *bdp = dev->priv;
+-              memset((void *) &epause, 0, sizeof(epause));
+-              if ((bdp->flags & IS_BACHELOR)
+-                  && (bdp->params.b_params & PRM_FC)) {
+-                      epause.autoneg = 1;
+-                      if (bdp->flags && DF_LINK_FC_CAP) {
+-                              epause.rx_pause = 1;
+-                              epause.tx_pause = 1;
+-                      }
+-                      if (bdp->flags && DF_LINK_FC_TX_ONLY)
+-                              epause.tx_pause = 1;
+-              }
+-              rc = copy_to_user(ifr->ifr_data, &epause, sizeof(epause))
+-                      ? -EFAULT : 0;
+-              return rc;
+-      }
+-#endif
+-#ifdef        ETHTOOL_SPAUSEPARAM
+-      case ETHTOOL_SPAUSEPARAM: {
+-              struct ethtool_pauseparam epause;
+-              struct e100_private *bdp = dev->priv;
+-              if (!(bdp->flags & IS_BACHELOR))
+-                      return -EINVAL;
+-              if (copy_from_user(&epause, ifr->ifr_data, sizeof(epause)))
+-                      return -EFAULT;
+-              if (epause.autoneg == 1)
+-                      bdp->params.b_params |= PRM_FC;
+-              else
+-                      bdp->params.b_params &= ~PRM_FC;
+-              if (netif_running(dev)) {
+-                      spin_lock_bh(&dev->xmit_lock);
+-                      e100_close(dev);
+-                      spin_unlock_bh(&dev->xmit_lock);
+-                      e100_hw_init(bdp);
+-                      e100_open(dev);
+-              }
+-              return 0;
+-      }
+-#endif
+-#ifdef        ETHTOOL_GRXCSUM
+-      case ETHTOOL_GRXCSUM:
+-      case ETHTOOL_GTXCSUM:
+-      case ETHTOOL_GSG:
+-      {       struct ethtool_value eval;
+-              struct e100_private *bdp = dev->priv;
+-              memset((void *) &eval, 0, sizeof(eval));
+-              if ((ecmd.cmd == ETHTOOL_GRXCSUM) 
+-                  && (bdp->params.b_params & PRM_XSUMRX))
+-                      eval.data = 1;
+-              else
+-                      eval.data = 0;
+-              rc = copy_to_user(ifr->ifr_data, &eval, sizeof(eval))
+-                      ? -EFAULT : 0;
+-              return rc;
+-      }
+-#endif
+-#ifdef        ETHTOOL_SRXCSUM
+-      case ETHTOOL_SRXCSUM:
+-      case ETHTOOL_STXCSUM:
+-      case ETHTOOL_SSG:
+-      {       struct ethtool_value eval;
+-              struct e100_private *bdp = dev->priv;
+-              if (copy_from_user(&eval, ifr->ifr_data, sizeof(eval)))
+-                      return -EFAULT;
+-              if (ecmd.cmd == ETHTOOL_SRXCSUM) {
+-                      if (eval.data == 1) { 
+-                              if (bdp->rev_id >= D101MA_REV_ID)
+-                                      bdp->params.b_params |= PRM_XSUMRX;
+-                              else
+-                                      return -EINVAL;
+-                      } else {
+-                              if (bdp->rev_id >= D101MA_REV_ID)
+-                                      bdp->params.b_params &= ~PRM_XSUMRX;
+-                              else
+-                                      return 0;
+-                      }
+-              } else {
+-                      if (eval.data == 1)
+-                              return -EINVAL;
+-                      else
+-                              return 0;
+-              }
+-              if (netif_running(dev)) {
+-                      spin_lock_bh(&dev->xmit_lock);
+-                      e100_close(dev);
+-                      spin_unlock_bh(&dev->xmit_lock);
+-                      e100_hw_init(bdp);
+-                      e100_open(dev);
+-              }
+-              return 0;
+-      }
+-#endif
+-      default:
+-              break;
+-      }                       //switch
+-      return rc;
+-}
+-
+-static int
+-e100_ethtool_get_settings(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct e100_private *bdp;
+-      struct ethtool_cmd ecmd;
+-      u16 advert = 0;
+-
+-      memset((void *) &ecmd, 0, sizeof (ecmd));
+-
+-      bdp = dev->priv;
+-
+-      ecmd.supported = bdp->speed_duplex_caps;
+-
+-      ecmd.port =
+-              (bdp->speed_duplex_caps & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
+-      ecmd.transceiver = XCVR_INTERNAL;
+-      ecmd.phy_address = bdp->phy_addr;
+-
+-      if (netif_carrier_ok(bdp->device)) {
+-              ecmd.speed = bdp->cur_line_speed;
+-              ecmd.duplex =
+-                      (bdp->cur_dplx_mode == HALF_DUPLEX) ? DUPLEX_HALF : DUPLEX_FULL;
+-      }
+-      else {
+-              ecmd.speed = -1;
+-              ecmd.duplex = -1;
+-      }
+-
+-      ecmd.advertising = ADVERTISED_TP;
+-
+-      if (bdp->params.e100_speed_duplex == E100_AUTONEG) {
+-              ecmd.autoneg = AUTONEG_ENABLE;
+-              ecmd.advertising |= ADVERTISED_Autoneg;
+-      } else {
+-              ecmd.autoneg = AUTONEG_DISABLE;
+-      }
+-
+-      if (bdp->speed_duplex_caps & SUPPORTED_MII) {
+-              e100_mdi_read(bdp, MII_ADVERTISE, bdp->phy_addr, &advert);
+-
+-              if (advert & ADVERTISE_10HALF)
+-                      ecmd.advertising |= ADVERTISED_10baseT_Half;
+-              if (advert & ADVERTISE_10FULL)
+-                      ecmd.advertising |= ADVERTISED_10baseT_Full;
+-              if (advert & ADVERTISE_100HALF)
+-                      ecmd.advertising |= ADVERTISED_100baseT_Half;
+-              if (advert & ADVERTISE_100FULL)
+-                      ecmd.advertising |= ADVERTISED_100baseT_Full;
+-      } else {
+-              ecmd.autoneg = AUTONEG_DISABLE;
+-              ecmd.advertising &= ~ADVERTISED_Autoneg;
+-      }
+-
+-      if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
+-              return -EFAULT;
+-
+-      return 0;
+-}
+-
+-static int
+-e100_ethtool_set_settings(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct e100_private *bdp;
+-      int e100_new_speed_duplex;
+-      int ethtool_new_speed_duplex;
+-      struct ethtool_cmd ecmd;
+-
+-      bdp = dev->priv;
+-      if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd))) {
+-              return -EFAULT;
+-      }
+-
+-      if ((ecmd.autoneg == AUTONEG_ENABLE)
+-          && (bdp->speed_duplex_caps & SUPPORTED_Autoneg)) {
+-              bdp->params.e100_speed_duplex = E100_AUTONEG;
+-              if (netif_running(dev)) {
+-                      spin_lock_bh(&dev->xmit_lock);
+-                      e100_close(dev);
+-                      spin_unlock_bh(&dev->xmit_lock);
+-                      e100_hw_init(bdp);
+-                      e100_open(dev);
+-              }
+-      } else {
+-              if (ecmd.speed == SPEED_10) {
+-                      if (ecmd.duplex == DUPLEX_HALF) {
+-                              e100_new_speed_duplex =
+-                                      E100_SPEED_10_HALF;
+-                              ethtool_new_speed_duplex =
+-                                      SUPPORTED_10baseT_Half;
+-                      } else { 
+-                              e100_new_speed_duplex =
+-                                      E100_SPEED_10_FULL;
+-                              ethtool_new_speed_duplex =
+-                                      SUPPORTED_10baseT_Full;
+-                      } 
+-              } else { 
+-                      if (ecmd.duplex == DUPLEX_HALF) {
+-                              e100_new_speed_duplex =
+-                                      E100_SPEED_100_HALF;
+-                              ethtool_new_speed_duplex =
+-                                      SUPPORTED_100baseT_Half;
+-                      } else { 
+-                              e100_new_speed_duplex =
+-                                      E100_SPEED_100_FULL;
+-                              ethtool_new_speed_duplex =
+-                                      SUPPORTED_100baseT_Full;
+-                      } 
+-              }
+-
+-              if (bdp->speed_duplex_caps & ethtool_new_speed_duplex) {
+-                      bdp->params.e100_speed_duplex =
+-                              e100_new_speed_duplex;
+-                      if (netif_running(dev)) {
+-                              spin_lock_bh(&dev->xmit_lock);
+-                              e100_close(dev);
+-                              spin_unlock_bh(&dev->xmit_lock);
+-                              e100_hw_init(bdp);
+-                              e100_open(dev);
+-                      }
+-              } else {
+-                      return -EOPNOTSUPP;
+-              } 
+-      }
+-
+-      return 0;
+-}
+-
+-static int
+-e100_ethtool_glink(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct e100_private *bdp;
+-      struct ethtool_value info;
+-
+-      memset((void *) &info, 0, sizeof (info));
+-
+-      bdp = dev->priv;
+-      info.cmd = ETHTOOL_GLINK;
+-
+-      /* Consider both PHY link and netif_running */
+-      info.data = e100_update_link_state(bdp);
+-
+-      if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
+-              return -EFAULT;
+-
+-      return 0;
+-}
+-
+-static int
+-e100_ethtool_test(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct ethtool_test *info;
+-      int rc = -EFAULT;
+-
+-      info = kmalloc(sizeof(*info) + max_test_res * sizeof(u64),
+-                     GFP_ATOMIC);
+-
+-      if (!info)
+-              return -ENOMEM;
+-
+-      memset((void *) info, 0, sizeof(*info) +
+-                               max_test_res * sizeof(u64));
+-
+-      if (copy_from_user(info, ifr->ifr_data, sizeof(*info)))
+-              goto exit;
+-
+-      info->flags = e100_run_diag(dev, info->data, info->flags);
+-
+-      if (!copy_to_user(ifr->ifr_data, info,
+-                       sizeof(*info) + max_test_res * sizeof(u64)))
+-              rc = 0;
+-exit:
+-      kfree(info);
+-      return rc;
+-}
+-
+-static int
+-e100_ethtool_gregs(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct e100_private *bdp;
+-      u32 regs_buff[E100_REGS_LEN];
+-      struct ethtool_regs regs = {ETHTOOL_GREGS};
+-      void *addr = ifr->ifr_data;
+-      u16 mdi_reg;
+-
+-      bdp = dev->priv;
+-
+-      if(copy_from_user(&regs, addr, sizeof(regs)))
+-              return -EFAULT;
+-
+-      regs.version = (1 << 24) | bdp->rev_id;
+-      regs_buff[0] = readb(&(bdp->scb->scb_cmd_hi)) << 24 |
+-              readb(&(bdp->scb->scb_cmd_low)) << 16 |
+-              readw(&(bdp->scb->scb_status));
+-      e100_mdi_read(bdp, MII_NCONFIG, bdp->phy_addr, &mdi_reg);
+-      regs_buff[1] = mdi_reg;
+-
+-      if(copy_to_user(addr, &regs, sizeof(regs)))
+-              return -EFAULT;
+-
+-      addr += offsetof(struct ethtool_regs, data);
+-      if(copy_to_user(addr, regs_buff, regs.len))
+-              return -EFAULT;
+-
+-      return 0;
+-}
+-
+-static int
+-e100_ethtool_nway_rst(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct e100_private *bdp;
+-
+-      bdp = dev->priv;
+-
+-      if ((bdp->speed_duplex_caps & SUPPORTED_Autoneg) &&
+-          (bdp->params.e100_speed_duplex == E100_AUTONEG)) {
+-              if (netif_running(dev)) {
+-                      spin_lock_bh(&dev->xmit_lock);
+-                      e100_close(dev);
+-                      spin_unlock_bh(&dev->xmit_lock);
+-                      e100_hw_init(bdp);
+-                      e100_open(dev);
+-              }
+-      } else {
+-              return -EFAULT;
+-      }
+-      return 0;
+-}
+-
+-static int
+-e100_ethtool_get_drvinfo(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct e100_private *bdp;
+-      struct ethtool_drvinfo info;
+-
+-      memset((void *) &info, 0, sizeof (info));
+-
+-      bdp = dev->priv;
+-
+-      strncpy(info.driver, e100_short_driver_name, sizeof (info.driver) - 1);
+-      strncpy(info.version, e100_driver_version, sizeof (info.version) - 1);
+-      strncpy(info.fw_version, "N/A",
+-              sizeof (info.fw_version) - 1);
+-      strncpy(info.bus_info, pci_name(bdp->pdev),
+-              sizeof (info.bus_info) - 1);
+-      info.n_stats = E100_STATS_LEN;
+-      info.regdump_len  = E100_REGS_LEN * sizeof(u32);
+-      info.eedump_len = (bdp->eeprom_size << 1);      
+-      info.testinfo_len = max_test_res;
+-      if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
+-              return -EFAULT;
+-
+-      return 0;
+-}
+-
+-static int
+-e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct e100_private *bdp;
+-      struct ethtool_eeprom ecmd;
+-      u16 eeprom_data[256];
+-      u16 *usr_eeprom_ptr;
+-      u16 first_word, last_word;
+-      int i, max_len;
+-      void *ptr;
+-      u8 *eeprom_data_bytes = (u8 *)eeprom_data;
+-
+-      bdp = dev->priv;
+-
+-      if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd)))
+-              return -EFAULT;
+-
+-      usr_eeprom_ptr =
+-              (u16 *) (ifr->ifr_data + offsetof(struct ethtool_eeprom, data));
+-
+-        max_len = bdp->eeprom_size * 2;
+-        
+-        if (ecmd.offset > ecmd.offset + ecmd.len)
+-              return -EINVAL;
+-              
+-      if ((ecmd.offset + ecmd.len) > max_len)
+-              ecmd.len = (max_len - ecmd.offset);
+-
+-      first_word = ecmd.offset >> 1;
+-      last_word = (ecmd.offset + ecmd.len - 1) >> 1;
+-              
+-      if (first_word >= bdp->eeprom_size)
+-              return -EFAULT;
+-
+-      if (ecmd.cmd == ETHTOOL_GEEPROM) {
+-              for(i = 0; i <= (last_word - first_word); i++)
+-                      eeprom_data[i] = e100_eeprom_read(bdp, first_word + i);
+-
+-              ecmd.magic = E100_EEPROM_MAGIC;
+-
+-              if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
+-                      return -EFAULT;
+-
+-              if(ecmd.offset & 1)
+-                      eeprom_data_bytes++;
+-              if (copy_to_user(usr_eeprom_ptr, eeprom_data_bytes, ecmd.len))
+-                      return -EFAULT;
+-      } else {
+-              if (ecmd.magic != E100_EEPROM_MAGIC)
+-                      return -EFAULT;
+-
+-              ptr = (void *)eeprom_data;
+-              if(ecmd.offset & 1) {
+-                      /* need modification of first changed EEPROM word */
+-                      /* only the second byte of the word is being modified */
+-                      eeprom_data[0] = e100_eeprom_read(bdp, first_word);
+-                      ptr++;
+-              }
+-              if((ecmd.offset + ecmd.len) & 1) {
+-                      /* need modification of last changed EEPROM word */
+-                      /* only the first byte of the word is being modified */
+-                      eeprom_data[last_word - first_word] = 
+-                              e100_eeprom_read(bdp, last_word);
+-              }
+-              if(copy_from_user(ptr, usr_eeprom_ptr, ecmd.len))
+-                      return -EFAULT;
+-
+-              e100_eeprom_write_block(bdp, first_word, eeprom_data,
+-                                      last_word - first_word + 1);
+-
+-              if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
+-                      return -EFAULT;
+-      }
+-      return 0;
+-}
+-
+-#define E100_BLINK_INTERVAL   (HZ/4)
+-/**
+- * e100_led_control
+- * @bdp: atapter's private data struct
+- * @led_mdi_op: led operation
+- *
+- * Software control over adapter's led. The possible operations are:
+- * TURN LED OFF, TURN LED ON and RETURN LED CONTROL TO HARDWARE.
+- */
+-static void
+-e100_led_control(struct e100_private *bdp, u16 led_mdi_op)
+-{
+-      e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
+-                     bdp->phy_addr, led_mdi_op);
+-
+-}
+-/**
+- * e100_led_blink_callback
+- * @data: pointer to atapter's private data struct
+- *
+- * Blink timer callback function. Toggles ON/OFF led status bit and calls
+- * led hardware access function. 
+- */
+-static void
+-e100_led_blink_callback(unsigned long data)
+-{
+-      struct e100_private *bdp = (struct e100_private *) data;
+-
+-      if(bdp->flags & LED_IS_ON) {
+-              bdp->flags &= ~LED_IS_ON;
+-              e100_led_control(bdp, PHY_82555_LED_OFF);
+-      } else {
+-              bdp->flags |= LED_IS_ON;
+-              if (bdp->rev_id >= D101MA_REV_ID)
+-                      e100_led_control(bdp, PHY_82555_LED_ON_559);
+-              else
+-                      e100_led_control(bdp, PHY_82555_LED_ON_PRE_559);
+-      }
+-
+-      mod_timer(&bdp->blink_timer, jiffies + E100_BLINK_INTERVAL);
+-}
+-/**
+- * e100_ethtool_led_blink
+- * @dev: pointer to atapter's net_device struct
+- * @ifr: pointer to ioctl request structure
+- *
+- * Blink led ioctl handler. Initialtes blink timer and sleeps until
+- * blink period expires. Than it kills timer and returns. The led control
+- * is returned back to hardware when blink timer is killed.
+- */
+-static int
+-e100_ethtool_led_blink(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct e100_private *bdp;
+-      struct ethtool_value ecmd;
+-
+-      bdp = dev->priv;
+-
+-      if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd)))
+-              return -EFAULT;
+-
+-      if(!bdp->blink_timer.function) {
+-              init_timer(&bdp->blink_timer);
+-              bdp->blink_timer.function = e100_led_blink_callback;
+-              bdp->blink_timer.data = (unsigned long) bdp;
+-      }
+-
+-      mod_timer(&bdp->blink_timer, jiffies);
+-
+-      set_current_state(TASK_INTERRUPTIBLE);
+-
+-      if ((!ecmd.data) || (ecmd.data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)))
+-              ecmd.data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
+-
+-      schedule_timeout(ecmd.data * HZ);
+-
+-      del_timer_sync(&bdp->blink_timer);
+-
+-      e100_led_control(bdp, PHY_82555_LED_NORMAL_CONTROL);
+-
+-      return 0;
+-}
+-
+-static inline int __devinit
+-e100_10BaseT_adapter(struct e100_private *bdp)
+-{
+-      return ((bdp->pdev->device == 0x1229) &&
+-              (bdp->pdev->subsystem_vendor == 0x8086) &&
+-              (bdp->pdev->subsystem_device == 0x0003));
+-}
+-
+-static void __devinit
+-e100_get_speed_duplex_caps(struct e100_private *bdp)
+-{
+-      u16 status;
+-
+-      e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &status);
+-
+-      bdp->speed_duplex_caps = 0;
+-
+-      bdp->speed_duplex_caps |=
+-              (status & BMSR_ANEGCAPABLE) ? SUPPORTED_Autoneg : 0;
+-
+-      bdp->speed_duplex_caps |=
+-              (status & BMSR_10HALF) ? SUPPORTED_10baseT_Half : 0;
+-
+-      bdp->speed_duplex_caps |=
+-              (status & BMSR_10FULL) ? SUPPORTED_10baseT_Full : 0;
+-
+-      bdp->speed_duplex_caps |=
+-              (status & BMSR_100HALF) ? SUPPORTED_100baseT_Half : 0;
+-
+-      bdp->speed_duplex_caps |=
+-              (status & BMSR_100FULL) ? SUPPORTED_100baseT_Full : 0;
+-
+-      if (IS_NC3133(bdp))
+-              bdp->speed_duplex_caps =
+-                      (SUPPORTED_FIBRE | SUPPORTED_100baseT_Full);
+-      else
+-              bdp->speed_duplex_caps |= SUPPORTED_TP;
+-
+-      if ((status == 0xFFFF) && e100_10BaseT_adapter(bdp)) {
+-              bdp->speed_duplex_caps =
+-                      (SUPPORTED_10baseT_Half | SUPPORTED_TP);
+-      } else {
+-              bdp->speed_duplex_caps |= SUPPORTED_MII;
+-      }
+-
+-}
+-
+-#ifdef CONFIG_PM
+-static unsigned char
+-e100_setup_filter(struct e100_private *bdp)
+-{
+-      cb_header_t *ntcb_hdr;
+-      unsigned char res = false;
+-      nxmit_cb_entry_t *cmd;
+-
+-      if ((cmd = e100_alloc_non_tx_cmd(bdp)) == NULL) {
+-              goto exit;
+-      }
+-
+-      ntcb_hdr = (cb_header_t *) cmd->non_tx_cmd;
+-      ntcb_hdr->cb_cmd = __constant_cpu_to_le16(CB_LOAD_FILTER);
+-
+-      /* Set EL and FIX bit */
+-      (cmd->non_tx_cmd)->ntcb.filter.filter_data[0] =
+-              __constant_cpu_to_le32(CB_FILTER_EL | CB_FILTER_FIX);
+-
+-      if (bdp->wolopts & WAKE_UCAST) {
+-              (cmd->non_tx_cmd)->ntcb.filter.filter_data[0] |=
+-                      __constant_cpu_to_le32(CB_FILTER_IA_MATCH);
+-      }
+-
+-      if (bdp->wolopts & WAKE_ARP) {
+-              /* Setup ARP bit and lower IP parts */
+-              /* bdp->ip_lbytes contains 2 lower bytes of IP address in network byte order */
+-              (cmd->non_tx_cmd)->ntcb.filter.filter_data[0] |=
+-                      cpu_to_le32(CB_FILTER_ARP | bdp->ip_lbytes);
+-      }
+-
+-      res = e100_exec_non_cu_cmd(bdp, cmd);
+-      if (!res)
+-              printk(KERN_WARNING "e100: %s: Filter setup failed\n",
+-                     bdp->device->name);
+-
+-exit:
+-      return res;
+-
+-}
+-
+-static void
+-e100_do_wol(struct pci_dev *pcid, struct e100_private *bdp)
+-{
+-      e100_config_wol(bdp);
+-
+-      if (e100_config(bdp)) {
+-              if (bdp->wolopts & (WAKE_UCAST | WAKE_ARP))
+-                      if (!e100_setup_filter(bdp))
+-                              printk(KERN_ERR
+-                                     "e100: WOL options failed\n");
+-      } else {
+-              printk(KERN_ERR "e100: config WOL failed\n");
+-      }
+-}
+-#endif
+-
+-static u16
+-e100_get_ip_lbytes(struct net_device *dev)
+-{
+-      struct in_ifaddr *ifa;
+-      struct in_device *in_dev;
+-      u32 res = 0;
+-
+-      in_dev = (struct in_device *) dev->ip_ptr;
+-      /* Check if any in_device bound to interface */
+-      if (in_dev) {
+-              /* Check if any IP address is bound to interface */
+-              if ((ifa = in_dev->ifa_list) != NULL) {
+-                      res = __constant_ntohl(ifa->ifa_address);
+-                      res = __constant_htons(res & 0x0000ffff);
+-              }
+-      }
+-      return res;
+-}
+-
+-static int
+-e100_ethtool_wol(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct e100_private *bdp;
+-      struct ethtool_wolinfo wolinfo;
+-      int res = 0;
+-
+-      bdp = dev->priv;
+-
+-      if (copy_from_user(&wolinfo, ifr->ifr_data, sizeof (wolinfo))) {
+-              return -EFAULT;
+-      }
+-
+-      switch (wolinfo.cmd) {
+-      case ETHTOOL_GWOL:
+-              wolinfo.supported = bdp->wolsupported;
+-              wolinfo.wolopts = bdp->wolopts;
+-              if (copy_to_user(ifr->ifr_data, &wolinfo, sizeof (wolinfo)))
+-                      res = -EFAULT;
+-              break;
+-      case ETHTOOL_SWOL:
+-              /* If ALL requests are supported or request is DISABLE wol */
+-              if (((wolinfo.wolopts & bdp->wolsupported) == wolinfo.wolopts)
+-                  || (wolinfo.wolopts == 0)) {
+-                      bdp->wolopts = wolinfo.wolopts;
+-              } else {
+-                      res = -EOPNOTSUPP;
+-              }
+-              if (wolinfo.wolopts & WAKE_ARP)
+-                      bdp->ip_lbytes = e100_get_ip_lbytes(dev);
+-              break;
+-      default:
+-              break;
+-      }
+-      return res;
+-}
+-
+-static int e100_ethtool_gstrings(struct net_device *dev, struct ifreq *ifr)
+-{
+-      struct ethtool_gstrings info;
+-      char *strings = NULL;
+-      char *usr_strings;
+-      int i;
+-
+-      memset((void *) &info, 0, sizeof(info));
+-
+-      usr_strings = (u8 *) (ifr->ifr_data + 
+-                            offsetof(struct ethtool_gstrings, data));
+-
+-      if (copy_from_user(&info, ifr->ifr_data, sizeof (info)))
+-              return -EFAULT;
+-
+-      switch (info.string_set) {
+-      case ETH_SS_TEST: {
+-              int ret = 0;
+-              if (info.len > max_test_res)
+-                      info.len = max_test_res;
+-              strings = kmalloc(info.len * ETH_GSTRING_LEN, GFP_ATOMIC);
+-              if (!strings)
+-                      return -ENOMEM;
+-              memset(strings, 0, info.len * ETH_GSTRING_LEN);
+-
+-              for (i = 0; i < info.len; i++) {
+-                      sprintf(strings + i * ETH_GSTRING_LEN, "%s",
+-                              test_strings[i]);
+-              }
+-              if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
+-                      ret = -EFAULT;
+-              if (copy_to_user(usr_strings, strings, info.len * ETH_GSTRING_LEN))
+-                      ret = -EFAULT;
+-              kfree(strings);
+-              return ret;
+-      }
+-      case ETH_SS_STATS: {
+-              char *strings = NULL;
+-              void *addr = ifr->ifr_data;
+-              info.len = E100_STATS_LEN;
+-              strings = *e100_gstrings_stats;
+-              if(copy_to_user(ifr->ifr_data, &info, sizeof(info)))
+-                      return -EFAULT;
+-              addr += offsetof(struct ethtool_gstrings, data);
+-              if(copy_to_user(addr, strings,
+-                 info.len * ETH_GSTRING_LEN))
+-                      return -EFAULT;
+-              return 0;
+-      }
+-      default:
+-              return -EOPNOTSUPP;
+-      }
+-}
+-
+-static int
+-e100_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+-{
+-      struct e100_private *bdp;
+-      struct mii_ioctl_data *data_ptr =
+-              (struct mii_ioctl_data *) &(ifr->ifr_data);
+-
+-      bdp = dev->priv;
+-
+-      switch (cmd) {
+-      case SIOCGMIIPHY:
+-              data_ptr->phy_id = bdp->phy_addr & 0x1f;
+-              break;
+-
+-      case SIOCGMIIREG:
+-              if (!capable(CAP_NET_ADMIN))
+-                      return -EPERM;
+-              e100_mdi_read(bdp, data_ptr->reg_num & 0x1f, bdp->phy_addr,
+-                            &(data_ptr->val_out));
+-              break;
+-
+-      case SIOCSMIIREG:
+-              if (!capable(CAP_NET_ADMIN))
+-                      return -EPERM;
+-              /* If reg = 0 && change speed/duplex */
+-              if (data_ptr->reg_num == 0 && 
+-                      (data_ptr->val_in == (BMCR_ANENABLE | BMCR_ANRESTART) /* restart cmd */
+-                      || data_ptr->val_in == (BMCR_RESET) /* reset cmd */ 
+-                      || data_ptr->val_in & (BMCR_SPEED100 | BMCR_FULLDPLX) 
+-                      || data_ptr->val_in == 0)) {
+-                              if (data_ptr->val_in == (BMCR_ANENABLE | BMCR_ANRESTART)
+-                                      || data_ptr->val_in == (BMCR_RESET))
+-                                      bdp->params.e100_speed_duplex = E100_AUTONEG;
+-                              else if (data_ptr->val_in == (BMCR_SPEED100 | BMCR_FULLDPLX))
+-                                      bdp->params.e100_speed_duplex = E100_SPEED_100_FULL;
+-                              else if (data_ptr->val_in == (BMCR_SPEED100))
+-                                      bdp->params.e100_speed_duplex = E100_SPEED_100_HALF;
+-                              else if (data_ptr->val_in == (BMCR_FULLDPLX))
+-                                      bdp->params.e100_speed_duplex = E100_SPEED_10_FULL;
+-                              else
+-                                      bdp->params.e100_speed_duplex = E100_SPEED_10_HALF;
+-                              if (netif_running(dev)) {
+-                                      spin_lock_bh(&dev->xmit_lock);
+-                                      e100_close(dev);
+-                                      spin_unlock_bh(&dev->xmit_lock);
+-                                      e100_hw_init(bdp);
+-                                      e100_open(dev);
+-                              }
+-              }
+-              else 
+-                      /* Only allows changing speed/duplex */
+-                      return -EINVAL;
+-              
+-              break;
+-
+-      default:
+-              return -EOPNOTSUPP;
+-      }
+-      return 0;
+-}
+-
+-nxmit_cb_entry_t *
+-e100_alloc_non_tx_cmd(struct e100_private *bdp)
+-{
+-      nxmit_cb_entry_t *non_tx_cmd_elem;
+-
+-      if (!(non_tx_cmd_elem = (nxmit_cb_entry_t *)
+-            kmalloc(sizeof (nxmit_cb_entry_t), GFP_ATOMIC))) {
+-              return NULL;
+-      }
+-      non_tx_cmd_elem->non_tx_cmd =
+-              pci_alloc_consistent(bdp->pdev, sizeof (nxmit_cb_t),
+-                                   &(non_tx_cmd_elem->dma_addr));
+-      if (non_tx_cmd_elem->non_tx_cmd == NULL) {
+-              kfree(non_tx_cmd_elem);
+-              return NULL;
+-      }
+-      return non_tx_cmd_elem;
+-}
+-
+-void
+-e100_free_non_tx_cmd(struct e100_private *bdp,
+-                   nxmit_cb_entry_t *non_tx_cmd_elem)
+-{
+-      pci_free_consistent(bdp->pdev, sizeof (nxmit_cb_t),
+-                          non_tx_cmd_elem->non_tx_cmd,
+-                          non_tx_cmd_elem->dma_addr);
+-      kfree(non_tx_cmd_elem);
+-}
+-
+-static void
+-e100_free_nontx_list(struct e100_private *bdp)
+-{
+-      nxmit_cb_entry_t *command;
+-      int i;
+-
+-      while (!list_empty(&bdp->non_tx_cmd_list)) {
+-              command = list_entry(bdp->non_tx_cmd_list.next,
+-                                   nxmit_cb_entry_t, list_elem);
+-              list_del(&(command->list_elem));
+-              e100_free_non_tx_cmd(bdp, command);
+-      }
+-
+-      for (i = 0; i < CB_MAX_NONTX_CMD; i++) {
+-              bdp->same_cmd_entry[i] = NULL;
+-      }
+-}
+-
+-static unsigned char
+-e100_delayed_exec_non_cu_cmd(struct e100_private *bdp,
+-                           nxmit_cb_entry_t *command)
+-{
+-      nxmit_cb_entry_t *same_command;
+-      cb_header_t *ntcb_hdr;
+-      u16 cmd;
+-
+-      ntcb_hdr = (cb_header_t *) command->non_tx_cmd;
+-
+-      cmd = CB_CMD_MASK & le16_to_cpu(ntcb_hdr->cb_cmd);
+-
+-      spin_lock_bh(&(bdp->bd_non_tx_lock));
+-
+-      same_command = bdp->same_cmd_entry[cmd];
+-
+-      if (same_command != NULL) {
+-              memcpy((void *) (same_command->non_tx_cmd),
+-                     (void *) (command->non_tx_cmd), sizeof (nxmit_cb_t));
+-              e100_free_non_tx_cmd(bdp, command);
+-      } else {
+-              list_add_tail(&(command->list_elem), &(bdp->non_tx_cmd_list));
+-              bdp->same_cmd_entry[cmd] = command;
+-      }
+-
+-      if (bdp->non_tx_command_state == E100_NON_TX_IDLE) {
+-              bdp->non_tx_command_state = E100_WAIT_TX_FINISH;
+-              mod_timer(&(bdp->nontx_timer_id), jiffies + 1);
+-      }
+-
+-      spin_unlock_bh(&(bdp->bd_non_tx_lock));
+-      return true;
+-}
+-
+-static void
+-e100_non_tx_background(unsigned long ptr)
+-{
+-      struct e100_private *bdp = (struct e100_private *) ptr;
+-      nxmit_cb_entry_t *active_command;
+-      int restart = true;
+-      cb_header_t *non_tx_cmd;
+-      u8 sub_cmd;
+-
+-      spin_lock_bh(&(bdp->bd_non_tx_lock));
+-
+-      switch (bdp->non_tx_command_state) {
+-      case E100_WAIT_TX_FINISH:
+-              if (bdp->last_tcb != NULL) {
+-                      rmb();
+-                      if ((bdp->last_tcb->tcb_hdr.cb_status &
+-                           __constant_cpu_to_le16(CB_STATUS_COMPLETE)) == 0)
+-                              goto exit;
+-              }
+-              if ((readw(&bdp->scb->scb_status) & SCB_CUS_MASK) ==
+-                  SCB_CUS_ACTIVE) {
+-                      goto exit;
+-              }
+-              break;
+-
+-      case E100_WAIT_NON_TX_FINISH:
+-              active_command = list_entry(bdp->non_tx_cmd_list.next,
+-                                          nxmit_cb_entry_t, list_elem);
+-              rmb();
+-
+-              if (((((cb_header_t *) (active_command->non_tx_cmd))->cb_status
+-                    & __constant_cpu_to_le16(CB_STATUS_COMPLETE)) == 0)
+-                  && time_before(jiffies, active_command->expiration_time)) {
+-                      goto exit;
+-              } else {
+-                      non_tx_cmd = (cb_header_t *) active_command->non_tx_cmd;
+-                      sub_cmd = CB_CMD_MASK & le16_to_cpu(non_tx_cmd->cb_cmd);
+-#ifdef E100_CU_DEBUG                  
+-                      if (!(non_tx_cmd->cb_status 
+-                          & __constant_cpu_to_le16(CB_STATUS_COMPLETE)))
+-                              printk(KERN_ERR "e100: %s: Queued "
+-                                      "command (%x) timeout\n", 
+-                                      bdp->device->name, sub_cmd);
+-#endif                        
+-                      list_del(&(active_command->list_elem));
+-                      e100_free_non_tx_cmd(bdp, active_command);
+-              }
+-              break;
+-
+-      default:
+-              break;
+-      }                       //switch
+-
+-      if (list_empty(&bdp->non_tx_cmd_list)) {
+-              bdp->non_tx_command_state = E100_NON_TX_IDLE;
+-              spin_lock_irq(&(bdp->bd_lock));
+-              bdp->next_cu_cmd = START_WAIT;
+-              spin_unlock_irq(&(bdp->bd_lock));
+-              restart = false;
+-              goto exit;
+-      } else {
+-              u16 cmd_type;
+-
+-              bdp->non_tx_command_state = E100_WAIT_NON_TX_FINISH;
+-              active_command = list_entry(bdp->non_tx_cmd_list.next,
+-                                          nxmit_cb_entry_t, list_elem);
+-              sub_cmd = ((cb_header_t *) active_command->non_tx_cmd)->cb_cmd;
+-              spin_lock_irq(&(bdp->bd_lock));
+-              e100_wait_exec_cmplx(bdp, active_command->dma_addr,
+-                                   SCB_CUC_START, sub_cmd);
+-              spin_unlock_irq(&(bdp->bd_lock));
+-              active_command->expiration_time = jiffies + HZ;
+-              cmd_type = CB_CMD_MASK &
+-                      le16_to_cpu(((cb_header_t *)
+-                                   (active_command->non_tx_cmd))->cb_cmd);
+-              bdp->same_cmd_entry[cmd_type] = NULL;
+-      }
+-
+-exit:
+-      if (restart) {
+-              mod_timer(&(bdp->nontx_timer_id), jiffies + 1);
+-      } else {
+-              if (netif_running(bdp->device))
+-                      netif_wake_queue(bdp->device);
+-      }
+-      spin_unlock_bh(&(bdp->bd_non_tx_lock));
+-}
+-
+-static void
+-e100_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
+-{
+-      struct e100_private *bdp = netdev->priv;
+-
+-      e100_disable_clear_intr(bdp);
+-      bdp->vlgrp = grp;
+-
+-      if(grp) {
+-              /* enable VLAN tag insert/strip */
+-              e100_config_vlan_drop(bdp, true);
+-
+-      } else {
+-              /* disable VLAN tag insert/strip */
+-              e100_config_vlan_drop(bdp, false);
+-      }
+-
+-      e100_config(bdp);
+-      e100_set_intr_mask(bdp);
+-}
+-
+-static void
+-e100_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+-{
+-      /* We don't do Vlan filtering */
+-      return;
+-}
+-
+-static void
+-e100_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+-{
+-      struct e100_private *bdp = netdev->priv;
+-
+-      if(bdp->vlgrp)
+-              bdp->vlgrp->vlan_devices[vid] = NULL;
+-      /* We don't do Vlan filtering */
+-      return;
+-}
+-
+-#ifdef CONFIG_PM
+-static int
+-e100_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
+-{
+-        struct pci_dev *pdev = NULL;
+-      
+-        switch(event) {
+-        case SYS_DOWN:
+-        case SYS_HALT:
+-        case SYS_POWER_OFF:
+-              while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+-                        if(pci_dev_driver(pdev) == &e100_driver) {
+-                              /* If net_device struct is allocated? */
+-                                if (pci_get_drvdata(pdev))
+-                                      e100_suspend(pdev, 3);
+-
+-                      }
+-              }
+-        }
+-        return NOTIFY_DONE;
+-}
+-
+-static int
+-e100_suspend(struct pci_dev *pcid, u32 state)
+-{
+-      struct net_device *netdev = pci_get_drvdata(pcid);
+-      struct e100_private *bdp = netdev->priv;
+-
+-      e100_isolate_driver(bdp);
+-      pci_save_state(pcid, bdp->pci_state);
+-
+-      /* Enable or disable WoL */
+-      e100_do_wol(pcid, bdp);
+-      
+-      /* If wol is enabled */
+-      if (bdp->wolopts || e100_asf_enabled(bdp)) {
+-              pci_enable_wake(pcid, 3, 1);    /* Enable PME for power state D3 */
+-              pci_set_power_state(pcid, 3);   /* Set power state to D3.        */
+-      } else {
+-              /* Disable bus mastering */
+-              pci_disable_device(pcid);
+-              pci_set_power_state(pcid, state);
+-      }
+-      return 0;
+-}
+-
+-static int
+-e100_resume(struct pci_dev *pcid)
+-{
+-      struct net_device *netdev = pci_get_drvdata(pcid);
+-      struct e100_private *bdp = netdev->priv;
+-
+-      pci_set_power_state(pcid, 0);
+-      pci_enable_wake(pcid, 0, 0);    /* Clear PME status and disable PME */
+-      pci_restore_state(pcid, bdp->pci_state);
+-
+-      /* Also do device full reset because device was in D3 state */
+-      e100_deisolate_driver(bdp, true);
+-
+-      return 0;
+-}
+-
+-/**
+- * e100_asf_enabled - checks if ASF is configured on the current adaper
+- *                    by reading registers 0xD and 0x90 in the EEPROM 
+- * @bdp: atapter's private data struct
+- *
+- * Returns: true if ASF is enabled
+- */
+-static unsigned char
+-e100_asf_enabled(struct e100_private *bdp)
+-{
+-      u16 asf_reg;
+-      u16 smbus_addr_reg;
+-      if ((bdp->pdev->device >= 0x1050) && (bdp->pdev->device <= 0x1055)) {
+-              asf_reg = e100_eeprom_read(bdp, EEPROM_CONFIG_ASF);
+-              if ((asf_reg & EEPROM_FLAG_ASF)
+-                  && !(asf_reg & EEPROM_FLAG_GCL)) {
+-                      smbus_addr_reg = 
+-                              e100_eeprom_read(bdp, EEPROM_SMBUS_ADDR);
+-                      if ((smbus_addr_reg & 0xFF) != 0xFE) 
+-                              return true;
+-              }
+-      }
+-      return false;
+-}
+-#endif /* CONFIG_PM */
+-
+-#ifdef E100_CU_DEBUG
+-unsigned char
+-e100_cu_unknown_state(struct e100_private *bdp)
+-{
+-      u8 scb_cmd_low;
+-      u16 scb_status;
+-      scb_cmd_low = bdp->scb->scb_cmd_low;
+-      scb_status = le16_to_cpu(bdp->scb->scb_status);
+-      /* If CU is active and executing unknown cmd */
+-      if (scb_status & SCB_CUS_ACTIVE && scb_cmd_low & SCB_CUC_UNKNOWN)
+-              return true;
+-      else
+-              return false;
+-}
+-#endif
+-
+--- linux-2.6.0/drivers/net/e100/e100_phy.c    2003-07-13 21:44:34.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,1163 +0,0 @@
+-/*******************************************************************************
+-
+-  
+-  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+-  
+-  This program is free software; you can redistribute it and/or modify it 
+-  under the terms of the GNU General Public License as published by the Free 
+-  Software Foundation; either version 2 of the License, or (at your option) 
+-  any later version.
+-  
+-  This program is distributed in the hope that it will be useful, but WITHOUT 
+-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+-  more details.
+-  
+-  You should have received a copy of the GNU General Public License along with
+-  this program; if not, write to the Free Software Foundation, Inc., 59 
+-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+-  
+-  The full GNU General Public License is included in this distribution in the
+-  file called LICENSE.
+-  
+-  Contact Information:
+-  Linux NICS <linux.nics@intel.com>
+-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+-*******************************************************************************/
+-
+-#include "e100_phy.h"
+-
+-void e100_handle_zlock(struct e100_private *bdp);
+-
+-/* 
+- * Procedure: e100_mdi_write
+- *
+- * Description: This routine will write a value to the specified MII register
+- *            of an external MDI compliant device (e.g. PHY 100).  The
+- *            command will execute in polled mode.
+- *
+- * Arguments:
+- *    bdp - Ptr to this card's e100_bdconfig structure
+- *    reg_addr - The MII register that we are writing to
+- *    phy_addr - The MDI address of the Phy component.
+- *    data - The value that we are writing to the MII register.
+- *
+- * Returns:
+- *    NOTHING
+- */
+-int
+-e100_mdi_write(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 data)
+-{
+-      int e100_retry;
+-      u32 temp_val;
+-      unsigned int mdi_cntrl;
+-
+-      spin_lock_bh(&bdp->mdi_access_lock);
+-      temp_val = (((u32) data) | (reg_addr << 16) |
+-                  (phy_addr << 21) | (MDI_WRITE << 26));
+-      writel(temp_val, &bdp->scb->scb_mdi_cntrl);
+-      readw(&bdp->scb->scb_status);
+-
+-      /* wait 20usec before checking status */
+-      udelay(20);
+-
+-      /* poll for the mdi write to complete */
+-      e100_retry = E100_CMD_WAIT;
+-      while ((!((mdi_cntrl = readl(&bdp->scb->scb_mdi_cntrl)) & MDI_PHY_READY)) && (e100_retry)) {
+-
+-              udelay(20);
+-              e100_retry--;
+-      }
+-      spin_unlock_bh(&bdp->mdi_access_lock);
+-      if (mdi_cntrl & MDI_PHY_READY) 
+-              return 0;
+-      else {
+-              printk(KERN_ERR "e100: MDI write timeout\n");
+-              return 1;
+-      }
+-}
+-
+-/* 
+- * Procedure: e100_mdi_read
+- *
+- * Description: This routine will read a value from the specified MII register
+- *            of an external MDI compliant device (e.g. PHY 100), and return
+- *            it to the calling routine.  The command will execute in polled
+- *            mode.
+- *
+- * Arguments:
+- *    bdp - Ptr to this card's e100_bdconfig structure
+- *    reg_addr - The MII register that we are reading from
+- *    phy_addr - The MDI address of the Phy component.
+- *
+- * Results:
+- *    data - The value that we read from the MII register.
+- *
+- * Returns:
+- *    NOTHING
+- */
+-int
+-e100_mdi_read(struct e100_private *bdp, u32 reg_addr, u32 phy_addr, u16 *data)
+-{
+-      int e100_retry;
+-      u32 temp_val;
+-      unsigned int mdi_cntrl;
+-
+-      spin_lock_bh(&bdp->mdi_access_lock);
+-      /* Issue the read command to the MDI control register. */
+-      temp_val = ((reg_addr << 16) | (phy_addr << 21) | (MDI_READ << 26));
+-      writel(temp_val, &bdp->scb->scb_mdi_cntrl);
+-      readw(&bdp->scb->scb_status);
+-
+-      /* wait 20usec before checking status */
+-      udelay(20);
+-
+-      /* poll for the mdi read to complete */
+-      e100_retry = E100_CMD_WAIT;
+-      while ((!((mdi_cntrl = readl(&bdp->scb->scb_mdi_cntrl)) & MDI_PHY_READY)) && (e100_retry)) {
+-
+-              udelay(20);
+-              e100_retry--;
+-      }
+-
+-      spin_unlock_bh(&bdp->mdi_access_lock);
+-      if (mdi_cntrl & MDI_PHY_READY) {
+-              /* return the lower word */
+-              *data = (u16) mdi_cntrl;
+-              return 0;
+-      }
+-      else {
+-              printk(KERN_ERR "e100: MDI read timeout\n");
+-              return 1;
+-      }
+-}
+-
+-static unsigned char __devinit
+-e100_phy_valid(struct e100_private *bdp, unsigned int phy_address)
+-{
+-      u16 ctrl_reg, stat_reg;
+-
+-      /* Read the MDI control register */
+-      e100_mdi_read(bdp, MII_BMCR, phy_address, &ctrl_reg);
+-
+-      /* Read the status register twice, bacause of sticky bits */
+-      e100_mdi_read(bdp, MII_BMSR, phy_address, &stat_reg);
+-      e100_mdi_read(bdp, MII_BMSR, phy_address, &stat_reg);
+-
+-      if ((ctrl_reg == 0xffff) || ((stat_reg == 0) && (ctrl_reg == 0)))
+-              return false;
+-
+-      return true;
+-}
+-
+-static void __devinit
+-e100_phy_address_detect(struct e100_private *bdp)
+-{
+-      unsigned int addr;
+-      unsigned char valid_phy_found = false;
+-
+-      if (IS_NC3133(bdp)) {
+-              bdp->phy_addr = 0;
+-              return;
+-      }
+-
+-      if (e100_phy_valid(bdp, PHY_DEFAULT_ADDRESS)) {
+-              bdp->phy_addr = PHY_DEFAULT_ADDRESS;
+-              valid_phy_found = true;
+-
+-      } else {
+-              for (addr = MIN_PHY_ADDR; addr <= MAX_PHY_ADDR; addr++) {
+-                      if (e100_phy_valid(bdp, addr)) {
+-                              bdp->phy_addr = addr;
+-                              valid_phy_found = true;
+-                              break;
+-                      }
+-              }
+-      }
+-
+-      if (!valid_phy_found) {
+-              bdp->phy_addr = PHY_ADDRESS_503;
+-      }
+-}
+-
+-static void __devinit
+-e100_phy_id_detect(struct e100_private *bdp)
+-{
+-      u16 low_id_reg, high_id_reg;
+-
+-      if (bdp->phy_addr == PHY_ADDRESS_503) {
+-              bdp->PhyId = PHY_503;
+-              return;
+-      }
+-      if (!(bdp->flags & IS_ICH)) {
+-              if (bdp->rev_id >= D102_REV_ID) {
+-                      bdp->PhyId = PHY_82562ET;
+-                      return;
+-              }
+-      }
+-
+-      /* Read phy id from the MII register */
+-      e100_mdi_read(bdp, MII_PHYSID1, bdp->phy_addr, &low_id_reg);
+-      e100_mdi_read(bdp, MII_PHYSID2, bdp->phy_addr, &high_id_reg);
+-
+-      bdp->PhyId = ((unsigned int) low_id_reg |
+-                    ((unsigned int) high_id_reg << 16));
+-}
+-
+-static void __devinit
+-e100_phy_isolate(struct e100_private *bdp)
+-{
+-      unsigned int phy_address;
+-      u16 ctrl_reg;
+-
+-      /* Go over all phy addresses. Deisolate the selected one, and isolate
+-       * all the rest */
+-      for (phy_address = 0; phy_address <= MAX_PHY_ADDR; phy_address++) {
+-              if (phy_address != bdp->phy_addr) {
+-                      e100_mdi_write(bdp, MII_BMCR, phy_address,
+-                                     BMCR_ISOLATE);
+-
+-              } else {
+-                      e100_mdi_read(bdp, MII_BMCR, bdp->phy_addr, &ctrl_reg);
+-                      ctrl_reg &= ~BMCR_ISOLATE;
+-                      e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, ctrl_reg);
+-              }
+-
+-              udelay(100);
+-      }
+-}
+-
+-static unsigned char __devinit
+-e100_phy_specific_setup(struct e100_private *bdp)
+-{
+-      u16 misc_reg;
+-
+-      if (bdp->phy_addr == PHY_ADDRESS_503) {
+-              switch (bdp->params.e100_speed_duplex) {
+-              case E100_AUTONEG:
+-                      /* The adapter can't autoneg. so set to 10/HALF */
+-                      printk(KERN_INFO
+-                             "e100: 503 serial component detected which "
+-                             "cannot autonegotiate\n");
+-                      printk(KERN_INFO
+-                             "e100: speed/duplex forced to "
+-                             "10Mbps / Half duplex\n");
+-                      bdp->params.e100_speed_duplex = E100_SPEED_10_HALF;
+-                      break;
+-
+-              case E100_SPEED_100_HALF:
+-              case E100_SPEED_100_FULL:
+-                      printk(KERN_ERR
+-                             "e100: 503 serial component detected "
+-                             "which does not support 100Mbps\n");
+-                      printk(KERN_ERR
+-                             "e100: Change the forced speed/duplex "
+-                             "to a supported setting\n");
+-                      return false;
+-              }
+-
+-              return true;
+-      }
+-
+-      if (IS_NC3133(bdp)) {
+-              u16 int_reg;
+-
+-              /* enable 100BASE fiber interface */
+-              e100_mdi_write(bdp, MDI_NC3133_CONFIG_REG, bdp->phy_addr,
+-                             MDI_NC3133_100FX_ENABLE);
+-
+-              if ((bdp->params.e100_speed_duplex != E100_AUTONEG) &&
+-                  (bdp->params.e100_speed_duplex != E100_SPEED_100_FULL)) {
+-                      /* just inform user about 100 full */
+-                      printk(KERN_ERR "e100: NC3133 NIC can only run "
+-                             "at 100Mbps full duplex\n");
+-              }
+-
+-              bdp->params.e100_speed_duplex = E100_SPEED_100_FULL;
+-
+-              /* enable interrupts */
+-              e100_mdi_read(bdp, MDI_NC3133_INT_ENABLE_REG,
+-                            bdp->phy_addr, &int_reg);
+-              int_reg |= MDI_NC3133_INT_ENABLE;
+-              e100_mdi_write(bdp, MDI_NC3133_INT_ENABLE_REG,
+-                             bdp->phy_addr, int_reg);
+-      }
+-
+-      /* Handle the National TX */
+-      if ((bdp->PhyId & PHY_MODEL_REV_ID_MASK) == PHY_NSC_TX) {
+-              e100_mdi_read(bdp, NSC_CONG_CONTROL_REG,
+-                            bdp->phy_addr, &misc_reg);
+-
+-              misc_reg |= NSC_TX_CONG_TXREADY;
+-
+-              /* disable the congestion control bit in the National Phy */
+-              misc_reg &= ~NSC_TX_CONG_ENABLE;
+-
+-              e100_mdi_write(bdp, NSC_CONG_CONTROL_REG,
+-                             bdp->phy_addr, misc_reg);
+-      }
+-
+-      return true;
+-}
+-
+-/* 
+- * Procedure: e100_phy_fix_squelch
+- *
+- * Description:
+- *    Help find link on certain rare scenarios.
+- *    NOTE: This routine must be called once per watchdog,
+- *          and *after* setting the current link state.
+- *
+- * Arguments:
+- *    bdp - Ptr to this card's e100_bdconfig structure
+- *
+- * Returns:
+- *    NOTHING
+- */
+-static void
+-e100_phy_fix_squelch(struct e100_private *bdp)
+-{
+-      if ((bdp->PhyId != PHY_82555_TX) || (bdp->flags & DF_SPEED_FORCED))
+-              return;
+-
+-      if (netif_carrier_ok(bdp->device)) {
+-              switch (bdp->PhyState) {
+-              case 0:
+-                      break;
+-              case 1:
+-                      e100_mdi_write(bdp, PHY_82555_SPECIAL_CONTROL,
+-                                     bdp->phy_addr, 0x0000);
+-                      break;
+-              case 2:
+-                      e100_mdi_write(bdp, PHY_82555_MDI_EQUALIZER_CSR,
+-                                     bdp->phy_addr, 0x3000);
+-                      break;
+-              }
+-              bdp->PhyState = 0;
+-              bdp->PhyDelay = 0;
+-
+-      } else if (!bdp->PhyDelay--) {
+-              switch (bdp->PhyState) {
+-              case 0:
+-                      e100_mdi_write(bdp, PHY_82555_SPECIAL_CONTROL,
+-                                     bdp->phy_addr, EXTENDED_SQUELCH_BIT);
+-                      bdp->PhyState = 1;
+-                      break;
+-              case 1:
+-                      e100_mdi_write(bdp, PHY_82555_SPECIAL_CONTROL,
+-                                     bdp->phy_addr, 0x0000);
+-                      e100_mdi_write(bdp, PHY_82555_MDI_EQUALIZER_CSR,
+-                                     bdp->phy_addr, 0x2010);
+-                      bdp->PhyState = 2;
+-                      break;
+-              case 2:
+-                      e100_mdi_write(bdp, PHY_82555_MDI_EQUALIZER_CSR,
+-                                     bdp->phy_addr, 0x3000);
+-                      bdp->PhyState = 0;
+-                      break;
+-              }
+-
+-              e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr,
+-                             BMCR_ANENABLE | BMCR_ANRESTART);
+-              bdp->PhyDelay = 3;
+-      }
+-}
+-
+-/* 
+- * Procedure: e100_fix_polarity
+- *
+- * Description:
+- *    Fix for 82555 auto-polarity toggle problem. With a short cable 
+- *    connecting an 82555 with an 840A link partner, if the medium is noisy,
+- *    the 82555 sometime thinks that the polarity might be wrong and so 
+- *    toggles polarity. This happens repeatedly and results in a high bit 
+- *    error rate.
+- *    NOTE: This happens only at 10 Mbps
+- *
+- * Arguments:
+- *    bdp - Ptr to this card's e100_bdconfig structure
+- *
+- * Returns:
+- *    NOTHING
+- */
+-static void __devinit
+-e100_fix_polarity(struct e100_private *bdp)
+-{
+-      u16 status;
+-      u16 errors;
+-      u16 misc_reg;
+-      int speed;
+-
+-      if ((bdp->PhyId != PHY_82555_TX) && (bdp->PhyId != PHY_82562ET) &&
+-          (bdp->PhyId != PHY_82562EM))
+-              return;
+-
+-      /* If the user wants auto-polarity disabled, do only that and nothing *
+-       * else. * e100_autopolarity == 0 means disable --- we do just the
+-       * disabling * e100_autopolarity == 1 means enable  --- we do nothing at
+-       * all * e100_autopolarity >= 2 means we do the workaround code. */
+-      /* Change for 82558 enhancement */
+-      switch (E100_AUTOPOLARITY) {
+-      case 0:
+-              e100_mdi_read(bdp, PHY_82555_SPECIAL_CONTROL,
+-                            bdp->phy_addr, &misc_reg);
+-              e100_mdi_write(bdp, PHY_82555_SPECIAL_CONTROL, bdp->phy_addr,
+-                             (u16) (misc_reg | DISABLE_AUTO_POLARITY));
+-              break;
+-
+-      case 1:
+-              e100_mdi_read(bdp, PHY_82555_SPECIAL_CONTROL,
+-                            bdp->phy_addr, &misc_reg);
+-              e100_mdi_write(bdp, PHY_82555_SPECIAL_CONTROL, bdp->phy_addr,
+-                             (u16) (misc_reg & ~DISABLE_AUTO_POLARITY));
+-              break;
+-
+-      case 2:
+-              /* we do this only if link is up */
+-              if (!netif_carrier_ok(bdp->device)) {
+-                      break;
+-              }
+-
+-              e100_mdi_read(bdp, PHY_82555_CSR, bdp->phy_addr, &status);
+-              speed = (status & PHY_82555_SPEED_BIT) ? 100 : 10;
+-
+-              /* we need to do this only if speed is 10 */
+-              if (speed != 10) {
+-                      break;
+-              }
+-
+-              /* see if we have any end of frame errors */
+-              e100_mdi_read(bdp, PHY_82555_EOF_COUNTER,
+-                            bdp->phy_addr, &errors);
+-
+-              /* if non-zero, wait for 100 ms before reading again */
+-              if (errors) {
+-                      udelay(200);
+-                      e100_mdi_read(bdp, PHY_82555_EOF_COUNTER,
+-                                    bdp->phy_addr, &errors);
+-
+-                      /* if non-zero again, we disable polarity */
+-                      if (errors) {
+-                              e100_mdi_read(bdp, PHY_82555_SPECIAL_CONTROL,
+-                                            bdp->phy_addr, &misc_reg);
+-                              e100_mdi_write(bdp, PHY_82555_SPECIAL_CONTROL,
+-                                             bdp->phy_addr,
+-                                             (u16) (misc_reg |
+-                                                    DISABLE_AUTO_POLARITY));
+-                      }
+-              }
+-
+-              if (!errors) {
+-                      /* it is safe to read the polarity now */
+-                      e100_mdi_read(bdp, PHY_82555_CSR,
+-                                    bdp->phy_addr, &status);
+-
+-                      /* if polarity is normal, disable polarity */
+-                      if (!(status & PHY_82555_POLARITY_BIT)) {
+-                              e100_mdi_read(bdp, PHY_82555_SPECIAL_CONTROL,
+-                                            bdp->phy_addr, &misc_reg);
+-                              e100_mdi_write(bdp, PHY_82555_SPECIAL_CONTROL,
+-                                             bdp->phy_addr,
+-                                             (u16) (misc_reg |
+-                                                    DISABLE_AUTO_POLARITY));
+-                      }
+-              }
+-              break;
+-
+-      default:
+-              break;
+-      }
+-}
+-
+-/* 
+- * Procedure: e100_find_speed_duplex
+- *
+- * Description: This routine will figure out what line speed and duplex mode
+- *            the PHY is currently using.
+- *
+- * Arguments:
+- *    bdp - Ptr to this card's e100_bdconfig structure
+- *
+- * Returns:
+- *    NOTHING
+- */
+-static void
+-e100_find_speed_duplex(struct e100_private *bdp)
+-{
+-      unsigned int PhyId;
+-      u16 stat_reg, misc_reg;
+-      u16 ad_reg, lp_ad_reg;
+-
+-      PhyId = bdp->PhyId & PHY_MODEL_REV_ID_MASK;
+-
+-      /* First we should check to see if we have link */
+-      /* If we don't have a link no reason to print a speed and duplex */
+-      if (!e100_update_link_state(bdp)) {
+-              bdp->cur_line_speed = 0;
+-              bdp->cur_dplx_mode = 0;
+-              return;
+-      }
+-
+-      /* On the 82559 and later controllers, speed/duplex is part of the *
+-       * SCB. So, we save an mdi_read and get these from the SCB. * */
+-      if (bdp->rev_id >= D101MA_REV_ID) {
+-              /* Read speed */
+-              if (readb(&bdp->scb->scb_ext.d101m_scb.scb_gen_stat) & BIT_1)
+-                      bdp->cur_line_speed = 100;
+-              else
+-                      bdp->cur_line_speed = 10;
+-
+-              /* Read duplex */
+-              if (readb(&bdp->scb->scb_ext.d101m_scb.scb_gen_stat) & BIT_2)
+-                      bdp->cur_dplx_mode = FULL_DUPLEX;
+-              else
+-                      bdp->cur_dplx_mode = HALF_DUPLEX;
+-
+-              return;
+-      }
+-
+-      /* If this is a Phy 100, then read bits 1 and 0 of extended register 0,
+-       * to get the current speed and duplex settings. */
+-      if ((PhyId == PHY_100_A) || (PhyId == PHY_100_C) ||
+-          (PhyId == PHY_82555_TX)) {
+-
+-              /* Read Phy 100 extended register 0 */
+-              e100_mdi_read(bdp, EXTENDED_REG_0, bdp->phy_addr, &misc_reg);
+-
+-              /* Get current speed setting */
+-              if (misc_reg & PHY_100_ER0_SPEED_INDIC)
+-                      bdp->cur_line_speed = 100;
+-              else
+-                      bdp->cur_line_speed = 10;
+-
+-              /* Get current duplex setting -- FDX enabled if bit is set */
+-              if (misc_reg & PHY_100_ER0_FDX_INDIC)
+-                      bdp->cur_dplx_mode = FULL_DUPLEX;
+-              else
+-                      bdp->cur_dplx_mode = HALF_DUPLEX;
+-
+-              return;
+-      }
+-
+-      /* See if link partner is capable of Auto-Negotiation (bit 0, reg 6) */
+-      e100_mdi_read(bdp, MII_EXPANSION, bdp->phy_addr, &misc_reg);
+-
+-      /* See if Auto-Negotiation was complete (bit 5, reg 1) */
+-      e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
+-
+-      /* If a True NWAY connection was made, then we can detect speed/dplx
+-       * by ANDing our adapter's advertised abilities with our link partner's
+-       * advertised ablilities, and then assuming that the highest common
+-       * denominator was chosed by NWAY. */
+-      if ((misc_reg & EXPANSION_NWAY) && (stat_reg & BMSR_ANEGCOMPLETE)) {
+-
+-              /* Read our advertisement register */
+-              e100_mdi_read(bdp, MII_ADVERTISE, bdp->phy_addr, &ad_reg);
+-
+-              /* Read our link partner's advertisement register */
+-              e100_mdi_read(bdp, MII_LPA, bdp->phy_addr, &lp_ad_reg);
+-
+-              /* AND the two advertisement registers together, and get rid
+-               * of any extraneous bits. */
+-              ad_reg &= (lp_ad_reg & NWAY_LP_ABILITY);
+-
+-              /* Get speed setting */
+-              if (ad_reg &
+-                  (ADVERTISE_100HALF | ADVERTISE_100FULL |
+-                   ADVERTISE_100BASE4))
+-
+-                      bdp->cur_line_speed = 100;
+-              else
+-                      bdp->cur_line_speed = 10;
+-
+-              /* Get duplex setting -- use priority resolution algorithm */
+-              if (ad_reg & ADVERTISE_100BASE4) {
+-                      bdp->cur_dplx_mode = HALF_DUPLEX;
+-              } else if (ad_reg & ADVERTISE_100FULL) {
+-                      bdp->cur_dplx_mode = FULL_DUPLEX;
+-              } else if (ad_reg & ADVERTISE_100HALF) {
+-                      bdp->cur_dplx_mode = HALF_DUPLEX;
+-              } else if (ad_reg & ADVERTISE_10FULL) {
+-                      bdp->cur_dplx_mode = FULL_DUPLEX;
+-              } else {
+-                      bdp->cur_dplx_mode = HALF_DUPLEX;
+-              }
+-
+-              return;
+-      }
+-
+-      /* If we are connected to a dumb (non-NWAY) repeater or hub, and the
+-       * line speed was determined automatically by parallel detection, then
+-       * we have no way of knowing exactly what speed the PHY is set to
+-       * unless that PHY has a propietary register which indicates speed in
+-       * this situation. The NSC TX PHY does have such a register. Also,
+-       * since NWAY didn't establish the connection, the duplex setting
+-       * should HALF duplex. */
+-      bdp->cur_dplx_mode = HALF_DUPLEX;
+-
+-      if (PhyId == PHY_NSC_TX) {
+-              /* Read register 25 to get the SPEED_10 bit */
+-              e100_mdi_read(bdp, NSC_SPEED_IND_REG, bdp->phy_addr, &misc_reg);
+-
+-              /* If bit 6 was set then we're at 10Mbps */
+-              if (misc_reg & NSC_TX_SPD_INDC_SPEED)
+-                      bdp->cur_line_speed = 10;
+-              else
+-                      bdp->cur_line_speed = 100;
+-
+-      } else {
+-              /* If we don't know the line speed, default to 10Mbps */
+-              bdp->cur_line_speed = 10;
+-      }
+-}
+-
+-/* 
+- * Procedure: e100_force_speed_duplex
+- *
+- * Description: This routine forces line speed and duplex mode of the
+- * adapter based on the values the user has set in e100.c.
+- *
+- * Arguments:  bdp - Pointer to the e100_private structure for the board
+- *
+- * Returns: void
+- *
+- */
+-void
+-e100_force_speed_duplex(struct e100_private *bdp)
+-{
+-      u16 control;
+-      unsigned long expires;
+-
+-      bdp->flags |= DF_SPEED_FORCED;
+-
+-      e100_mdi_read(bdp, MII_BMCR, bdp->phy_addr, &control);
+-      control &= ~BMCR_ANENABLE;
+-      control &= ~BMCR_LOOPBACK;
+-
+-      switch (bdp->params.e100_speed_duplex) {
+-      case E100_SPEED_10_HALF:
+-              control &= ~BMCR_SPEED100;
+-              control &= ~BMCR_FULLDPLX;
+-              bdp->cur_line_speed = 10;
+-              bdp->cur_dplx_mode = HALF_DUPLEX;
+-              break;
+-
+-      case E100_SPEED_10_FULL:
+-              control &= ~BMCR_SPEED100;
+-              control |= BMCR_FULLDPLX;
+-              bdp->cur_line_speed = 10;
+-              bdp->cur_dplx_mode = FULL_DUPLEX;
+-              break;
+-
+-      case E100_SPEED_100_HALF:
+-              control |= BMCR_SPEED100;
+-              control &= ~BMCR_FULLDPLX;
+-              bdp->cur_line_speed = 100;
+-              bdp->cur_dplx_mode = HALF_DUPLEX;
+-              break;
+-
+-      case E100_SPEED_100_FULL:
+-              control |= BMCR_SPEED100;
+-              control |= BMCR_FULLDPLX;
+-              bdp->cur_line_speed = 100;
+-              bdp->cur_dplx_mode = FULL_DUPLEX;
+-              break;
+-      }
+-
+-      e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, control);
+-
+-      /* loop must run at least once */
+-      expires = jiffies + 2 * HZ;
+-      do {
+-              if (e100_update_link_state(bdp) || 
+-                  time_after(jiffies, expires)) {
+-                      break;
+-              } else {
+-                      yield();
+-              }
+-
+-      } while (true);
+-}
+-
+-void
+-e100_force_speed_duplex_to_phy(struct e100_private *bdp)
+-{
+-      u16 control;
+-
+-      e100_mdi_read(bdp, MII_BMCR, bdp->phy_addr, &control);
+-      control &= ~BMCR_ANENABLE;
+-      control &= ~BMCR_LOOPBACK;
+-
+-      switch (bdp->params.e100_speed_duplex) {
+-      case E100_SPEED_10_HALF:
+-              control &= ~BMCR_SPEED100;
+-              control &= ~BMCR_FULLDPLX;
+-              break;
+-
+-      case E100_SPEED_10_FULL:
+-              control &= ~BMCR_SPEED100;
+-              control |= BMCR_FULLDPLX;
+-              break;
+-
+-      case E100_SPEED_100_HALF:
+-              control |= BMCR_SPEED100;
+-              control &= ~BMCR_FULLDPLX;
+-              break;
+-
+-      case E100_SPEED_100_FULL:
+-              control |= BMCR_SPEED100;
+-              control |= BMCR_FULLDPLX;
+-              break;
+-      }
+-
+-      /* Send speed/duplex command to PHY layer. */
+-      e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, control);
+-}
+-
+-/* 
+- * Procedure: e100_set_fc
+- *
+- * Description: Checks the link's capability for flow control.
+- * 
+- * Arguments:  bdp - Pointer to the e100_private structure for the board
+- *                
+- * Returns: void
+- *
+- */
+-static void
+-e100_set_fc(struct e100_private *bdp)
+-{
+-      u16 ad_reg;
+-      u16 lp_ad_reg;
+-      u16 exp_reg;
+-
+-      /* no flow control for 82557, forced links or half duplex */
+-      if (!netif_carrier_ok(bdp->device) || (bdp->flags & DF_SPEED_FORCED) ||
+-          (bdp->cur_dplx_mode == HALF_DUPLEX) ||
+-          !(bdp->flags & IS_BACHELOR)) {
+-
+-              bdp->flags &= ~DF_LINK_FC_CAP;
+-              return;
+-      }
+-
+-      /* See if link partner is capable of Auto-Negotiation (bit 0, reg 6) */
+-      e100_mdi_read(bdp, MII_EXPANSION, bdp->phy_addr, &exp_reg);
+-
+-      if (exp_reg & EXPANSION_NWAY) {
+-              /* Read our advertisement register */
+-              e100_mdi_read(bdp, MII_ADVERTISE, bdp->phy_addr, &ad_reg);
+-
+-              /* Read our link partner's advertisement register */
+-              e100_mdi_read(bdp, MII_LPA, bdp->phy_addr, &lp_ad_reg);
+-
+-              ad_reg &= lp_ad_reg;    /* AND the 2 ad registers */
+-
+-              if (ad_reg & NWAY_AD_FC_SUPPORTED)
+-                      bdp->flags |= DF_LINK_FC_CAP;
+-              else
+-                      /* If link partner is capable of autoneg, but  */
+-                      /* not capable of flow control, Received PAUSE */
+-                      /* frames are still honored, i.e.,             */
+-                      /* transmitted frames would be paused */
+-                      /* by incoming PAUSE frames           */
+-                      bdp->flags |= DF_LINK_FC_TX_ONLY;
+-
+-      } else {
+-              bdp->flags &= ~DF_LINK_FC_CAP;
+-      }
+-}
+-
+-/* 
+- * Procedure: e100_phy_check
+- * 
+- * Arguments:  bdp - Pointer to the e100_private structure for the board
+- *
+- * Returns: true if link state was changed
+- *       false otherwise
+- *
+- */
+-unsigned char
+-e100_phy_check(struct e100_private *bdp)
+-{
+-      unsigned char old_link;
+-      unsigned char changed = false;
+-
+-      old_link = netif_carrier_ok(bdp->device) ? 1 : 0;
+-      e100_find_speed_duplex(bdp);
+-
+-      if (!old_link && netif_carrier_ok(bdp->device)) {
+-              e100_set_fc(bdp);
+-              changed = true;
+-      }
+-
+-      if (old_link && !netif_carrier_ok(bdp->device)) {
+-              /* reset the zero lock state */
+-              bdp->zlock_state = ZLOCK_INITIAL;
+-
+-              // set auto lock for phy auto-negotiation on link up
+-              if ((bdp->PhyId & PHY_MODEL_REV_ID_MASK) == PHY_82555_TX)
+-                      e100_mdi_write(bdp, PHY_82555_MDI_EQUALIZER_CSR,
+-                                     bdp->phy_addr, 0);
+-              changed = true;
+-      }
+-
+-      e100_phy_fix_squelch(bdp);
+-      e100_handle_zlock(bdp);
+-
+-      return changed;
+-}
+-
+-/* 
+- * Procedure: e100_auto_neg
+- *
+- * Description: This routine will start autonegotiation and wait
+- *                 for it to complete
+- *
+- * Arguments:
+- *    bdp             - pointer to this card's e100_bdconfig structure
+- *    force_restart   - defines if autoneg should be restarted even if it
+- *                    has been completed before
+- * Returns:
+- *    NOTHING
+- */
+-static void
+-e100_auto_neg(struct e100_private *bdp, unsigned char force_restart)
+-{
+-      u16 stat_reg;
+-      unsigned long expires;
+-
+-      bdp->flags &= ~DF_SPEED_FORCED;
+-
+-      e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
+-      e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
+-
+-      /* if we are capable of performing autoneg then we restart if needed */
+-      if ((stat_reg != 0xFFFF) && (stat_reg & BMSR_ANEGCAPABLE)) {
+-
+-              if ((!force_restart) &&
+-                  (stat_reg & BMSR_ANEGCOMPLETE)) {
+-                      goto exit;
+-              }
+-
+-              e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr,
+-                             BMCR_ANENABLE | BMCR_ANRESTART);
+-
+-              /* wait for autoneg to complete (up to 3 seconds) */
+-              expires = jiffies + HZ * 3;
+-              do {
+-                      /* now re-read the value. Sticky so read twice */
+-                      e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
+-                      e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
+-
+-                      if ((stat_reg & BMSR_ANEGCOMPLETE) ||
+-                          time_after(jiffies, expires) ) {
+-                              goto exit;
+-                      } else {
+-                              yield();
+-                      }
+-              } while (true);
+-      }
+-
+-exit:
+-      e100_find_speed_duplex(bdp);
+-}
+-
+-void
+-e100_phy_set_speed_duplex(struct e100_private *bdp, unsigned char force_restart)
+-{
+-      if (bdp->params.e100_speed_duplex == E100_AUTONEG) {
+-              if (bdp->rev_id >= D102_REV_ID) 
+-                      /* Enable MDI/MDI-X auto switching */
+-                      e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
+-                                     MDI_MDIX_AUTO_SWITCH_ENABLE);
+-              e100_auto_neg(bdp, force_restart);
+-
+-      } else {
+-              if (bdp->rev_id >= D102_REV_ID) 
+-                      /* Disable MDI/MDI-X auto switching */
+-                      e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
+-                                     MDI_MDIX_RESET_ALL_MASK);
+-              e100_force_speed_duplex(bdp);
+-      }
+-
+-      e100_set_fc(bdp);
+-}
+-
+-void
+-e100_phy_autoneg(struct e100_private *bdp)
+-{
+-      u16 ctrl_reg;
+-
+-      ctrl_reg = BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET;
+-
+-      e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, ctrl_reg);
+-
+-      udelay(100);
+-}
+-
+-void
+-e100_phy_set_loopback(struct e100_private *bdp)
+-{
+-      u16 ctrl_reg;
+-      ctrl_reg = BMCR_LOOPBACK;
+-      e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, ctrl_reg);
+-              udelay(100);
+-}
+-      
+-void
+-e100_phy_reset(struct e100_private *bdp)
+-{
+-      u16 ctrl_reg;
+-      ctrl_reg = BMCR_RESET;
+-      e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, ctrl_reg);
+-      /* ieee 802.3 : The reset process shall be completed       */
+-      /* within 0.5 seconds from the settting of PHY reset bit.  */
+-      set_current_state(TASK_UNINTERRUPTIBLE);
+-      schedule_timeout(HZ / 2);
+-}
+-
+-unsigned char __devinit
+-e100_phy_init(struct e100_private *bdp)
+-{
+-      e100_phy_reset(bdp);
+-      e100_phy_address_detect(bdp);
+-      e100_phy_isolate(bdp);
+-      e100_phy_id_detect(bdp);
+-
+-      if (!e100_phy_specific_setup(bdp))
+-              return false;
+-
+-      bdp->PhyState = 0;
+-      bdp->PhyDelay = 0;
+-      bdp->zlock_state = ZLOCK_INITIAL;
+-
+-      e100_phy_set_speed_duplex(bdp, false);
+-      e100_fix_polarity(bdp);
+-
+-      return true;
+-}
+-
+-/* 
+- * Procedure: e100_get_link_state
+- * 
+- * Description: This routine checks the link status of the adapter
+- *
+- * Arguments:  bdp - Pointer to the e100_private structure for the board
+- *                
+- *
+- * Returns: true - If a link is found
+- *            false - If there is no link
+- *
+- */
+-unsigned char
+-e100_get_link_state(struct e100_private *bdp)
+-{
+-      unsigned char link = false;
+-      u16 status;
+-
+-      /* Check link status */
+-      /* If the controller is a 82559 or later one, link status is available
+-       * from the CSR. This avoids the mdi_read. */
+-      if (bdp->rev_id >= D101MA_REV_ID) {
+-              if (readb(&bdp->scb->scb_ext.d101m_scb.scb_gen_stat) & BIT_0) {
+-                      link = true;
+-              } else {
+-                      link = false;
+-              }
+-
+-      } else {
+-              /* Read the status register twice because of sticky bits */
+-              e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &status);
+-              e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &status);
+-
+-              if (status & BMSR_LSTATUS) {
+-                      link = true;
+-              } else {
+-                      link = false;
+-              }
+-      }
+-
+-      return link;
+-}
+-
+-/* 
+- * Procedure: e100_update_link_state
+- * 
+- * Description: This routine updates the link status of the adapter,
+- *            also considering netif_running
+- *
+- * Arguments:  bdp - Pointer to the e100_private structure for the board
+- *                
+- *
+- * Returns: true - If a link is found
+- *            false - If there is no link
+- *
+- */
+-unsigned char
+-e100_update_link_state(struct e100_private *bdp)
+-{
+-      unsigned char link;
+-
+-      /* Logical AND PHY link & netif_running */
+-      link = e100_get_link_state(bdp) && netif_running(bdp->device);
+-
+-      if (link) {
+-              if (!netif_carrier_ok(bdp->device))
+-                      netif_carrier_on(bdp->device);
+-      } else {
+-              if (netif_carrier_ok(bdp->device))
+-                      netif_carrier_off(bdp->device);
+-      }
+-
+-      return link;
+-}
+-
+-/**************************************************************************\
+- **
+- ** PROC NAME:     e100_handle_zlock
+- **    This function manages a state machine that controls
+- **    the driver's zero locking algorithm.
+- **    This function is called by e100_watchdog() every ~2 second.
+- ** States:
+- **    The current link handling state is stored in 
+- **    bdp->zlock_state, and is one of:
+- **    ZLOCK_INITIAL, ZLOCK_READING, ZLOCK_SLEEPING
+- **    Detailed description of the states and the transitions
+- **    between states is found below.
+- **    Note that any time the link is down / there is a reset
+- **    state will be changed outside this function to ZLOCK_INITIAL
+- ** Algorithm:
+- **    1. If link is up & 100 Mbps continue else stay in #1:
+- **    2. Set 'auto lock'
+- **    3. Read & Store 100 times 'Zero' locked in 1 sec interval
+- **    4. If max zero read >= 0xB continue else goto 1
+- **    5. Set most popular 'Zero' read in #3
+- **    6. Sleep 5 minutes
+- **    7. Read number of errors, if it is > 300 goto 2 else goto 6
+- ** Data Structures (in DRIVER_DATA):
+- **    zlock_state           - current state of the algorithm
+- **    zlock_read_cnt        - counts number of reads (up to 100)
+- **    zlock_read_data[i]    - counts number of times 'Zero' read was i, 0 <= i <= 15
+- **    zlock_sleep_cnt       - keeps track of "sleep" time (up to 300 secs = 5 minutes)
+- **                                
+- ** Parameters:    DRIVER_DATA    *bdp
+- **
+- **                bdp  - Pointer to HSM's adapter data space
+- **
+- ** Return Value:  NONE
+- **
+- ** See Also:      e100_watchdog()
+- **
+- \**************************************************************************/
+-void
+-e100_handle_zlock(struct e100_private *bdp)
+-{
+-      u16 pos;
+-      u16 eq_reg;
+-      u16 err_cnt;
+-      u8 mpz;                 /* Most Popular Zero */
+-
+-      switch (bdp->zlock_state) {
+-      case ZLOCK_INITIAL:
+-
+-              if (((u8) bdp->rev_id <= D102_REV_ID) ||
+-                  !(bdp->cur_line_speed == 100) ||
+-                  !netif_carrier_ok(bdp->device)) {
+-                      break;
+-              }
+-
+-              /* initialize hw and sw and start reading */
+-              e100_mdi_write(bdp, PHY_82555_MDI_EQUALIZER_CSR,
+-                             bdp->phy_addr, 0);
+-              /* reset read counters: */
+-              bdp->zlock_read_cnt = 0;
+-              for (pos = 0; pos < 16; pos++)
+-                      bdp->zlock_read_data[pos] = 0;
+-              /* start reading in the next call back: */
+-              bdp->zlock_state = ZLOCK_READING;
+-
+-              /* FALL THROUGH !! */
+-
+-      case ZLOCK_READING:
+-              /* state: reading (100 times) zero locked in 1 sec interval
+-               * prev states: ZLOCK_INITIAL
+-               * next states: ZLOCK_INITIAL, ZLOCK_SLEEPING */
+-
+-              e100_mdi_read(bdp, PHY_82555_MDI_EQUALIZER_CSR,
+-                            bdp->phy_addr, &eq_reg);
+-              pos = (eq_reg & ZLOCK_ZERO_MASK) >> 4;
+-              bdp->zlock_read_data[pos]++;
+-              bdp->zlock_read_cnt++;
+-
+-              if (bdp->zlock_read_cnt == ZLOCK_MAX_READS) {
+-                      /* check if we read a 'Zero' value of 0xB or greater */
+-                      if ((bdp->zlock_read_data[0xB]) ||
+-                          (bdp->zlock_read_data[0xC]) ||
+-                          (bdp->zlock_read_data[0xD]) ||
+-                          (bdp->zlock_read_data[0xE]) ||
+-                          (bdp->zlock_read_data[0xF])) {
+-
+-                              /* we've read 'Zero' value of 0xB or greater,
+-                               * find most popular 'Zero' value and lock it */
+-                              mpz = 0;
+-                              /* this loop finds the most popular 'Zero': */
+-                              for (pos = 1; pos < 16; pos++) {
+-                                      if (bdp->zlock_read_data[pos] >
+-                                          bdp->zlock_read_data[mpz])
+-
+-                                              mpz = pos;
+-                              }
+-                              /* now lock the most popular 'Zero': */
+-                              eq_reg = (ZLOCK_SET_ZERO | mpz);
+-                              e100_mdi_write(bdp,
+-                                             PHY_82555_MDI_EQUALIZER_CSR,
+-                                             bdp->phy_addr, eq_reg);
+-
+-                              /* sleep for 5 minutes: */
+-                              bdp->zlock_sleep_cnt = jiffies;
+-                              bdp->zlock_state = ZLOCK_SLEEPING;
+-                              /* we will be reading the # of errors after 5
+-                               * minutes, so we need to reset the error
+-                               * counters - these registers are self clearing
+-                               * on read, so read them */
+-                              e100_mdi_read(bdp, PHY_82555_SYMBOL_ERR,
+-                                            bdp->phy_addr, &err_cnt);
+-
+-                      } else {
+-                              /* we did not read a 'Zero' value of 0xB or
+-                               * above. go back to the start */
+-                              bdp->zlock_state = ZLOCK_INITIAL;
+-                      }
+-
+-              }
+-              break;
+-
+-      case ZLOCK_SLEEPING:
+-              /* state: sleeping for 5 minutes
+-               * prev states: ZLOCK_READING
+-               * next states: ZLOCK_READING, ZLOCK_SLEEPING */
+-
+-              /* if 5 minutes have passed: */
+-              if ((jiffies - bdp->zlock_sleep_cnt) >= ZLOCK_MAX_SLEEP) {
+-                      /* read and sum up the number of errors:  */
+-                      e100_mdi_read(bdp, PHY_82555_SYMBOL_ERR,
+-                                    bdp->phy_addr, &err_cnt);
+-                      /* if we've more than 300 errors (this number was
+-                       * calculated according to the spec max allowed errors
+-                       * (80 errors per 1 million frames) for 5 minutes in
+-                       * 100 Mbps (or the user specified max BER number) */
+-                      if (err_cnt > bdp->params.ber) {
+-                              /* start again in the next callback: */
+-                              bdp->zlock_state = ZLOCK_INITIAL;
+-                      } else {
+-                              /* we don't have more errors than allowed,
+-                               * sleep for 5 minutes */
+-                              bdp->zlock_sleep_cnt = jiffies;
+-                      }
+-              }
+-              break;
+-
+-      default:
+-              break;
+-      }
+-}
+--- linux-2.6.0/drivers/net/e100/e100_phy.h    2003-06-14 12:17:59.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,158 +0,0 @@
+-/*******************************************************************************
+-
+-  
+-  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+-  
+-  This program is free software; you can redistribute it and/or modify it 
+-  under the terms of the GNU General Public License as published by the Free 
+-  Software Foundation; either version 2 of the License, or (at your option) 
+-  any later version.
+-  
+-  This program is distributed in the hope that it will be useful, but WITHOUT 
+-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+-  more details.
+-  
+-  You should have received a copy of the GNU General Public License along with
+-  this program; if not, write to the Free Software Foundation, Inc., 59 
+-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+-  
+-  The full GNU General Public License is included in this distribution in the
+-  file called LICENSE.
+-  
+-  Contact Information:
+-  Linux NICS <linux.nics@intel.com>
+-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+-*******************************************************************************/
+-
+-#ifndef _E100_PHY_INC_
+-#define _E100_PHY_INC_
+-
+-#include "e100.h"
+-
+-/*
+- * Auto-polarity enable/disable
+- * e100_autopolarity = 0 => disable auto-polarity
+- * e100_autopolarity = 1 => enable auto-polarity
+- * e100_autopolarity = 2 => let software determine
+- */
+-#define E100_AUTOPOLARITY 2
+-
+-#define IS_NC3133(bdp) (((bdp)->pdev->subsystem_vendor == 0x0E11) && \
+-                        ((bdp)->pdev->subsystem_device == 0xB0E1))
+-
+-#define PHY_503                 0
+-#define PHY_100_A               0x000003E0
+-#define PHY_100_C               0x035002A8
+-#define PHY_NSC_TX              0x5c002000
+-#define PHY_82562ET             0x033002A8
+-#define PHY_82562EM             0x032002A8
+-#define PHY_82562EH             0x017002A8
+-#define PHY_82555_TX            0x015002a8    /* added this for 82555 */
+-#define PHY_OTHER               0xFFFF
+-#define MAX_PHY_ADDR            31
+-#define MIN_PHY_ADDR            0
+-
+-#define PHY_MODEL_REV_ID_MASK   0xFFF0FFFF
+-
+-#define PHY_DEFAULT_ADDRESS 1
+-#define PHY_ADDRESS_503 32
+-
+-/* MDI Control register bit definitions */
+-#define MDI_PHY_READY     BIT_28      /* PHY is ready for next MDI cycle */
+-
+-#define MDI_NC3133_CONFIG_REG           0x19
+-#define MDI_NC3133_100FX_ENABLE         BIT_2
+-#define MDI_NC3133_INT_ENABLE_REG       0x17
+-#define MDI_NC3133_INT_ENABLE           BIT_1
+-
+-/* MDI Control register opcode definitions */
+-#define MDI_WRITE 1           /* Phy Write */
+-#define MDI_READ  2           /* Phy read */
+-
+-/* MDI register set*/
+-#define AUTO_NEG_NEXT_PAGE_REG            0x07        /* Auto-negotiation next page xmit */
+-#define EXTENDED_REG_0                    0x10        /* Extended reg 0 (Phy 100 modes) */
+-#define EXTENDED_REG_1                    0x14        /* Extended reg 1 (Phy 100 error indications) */
+-#define NSC_CONG_CONTROL_REG      0x17        /* National (TX) congestion control */
+-#define NSC_SPEED_IND_REG         0x19        /* National (TX) speed indication */
+-
+-#define HWI_CONTROL_REG             0x1D      /* HWI Control register */
+-/* MDI/MDI-X Control Register bit definitions */
+-#define MDI_MDIX_RES_TIMER          BIT_0_3   /* minimum slot time for resolution timer */
+-#define MDI_MDIX_CONFIG_IS_OK       BIT_4     /* 1 = resolution algorithm completes OK */
+-#define MDI_MDIX_STATUS             BIT_5     /* 1 = MDIX (croos over), 0 = MDI (straight through) */
+-#define MDI_MDIX_SWITCH             BIT_6     /* 1 = Forces to MDIX, 0 = Forces to MDI */
+-#define MDI_MDIX_AUTO_SWITCH_ENABLE BIT_7     /* 1 = MDI/MDI-X feature enabled */
+-#define MDI_MDIX_CONCT_CONFIG       BIT_8     /* Sets the MDI/MDI-X connectivity configuration (test prupose only) */
+-#define MDI_MDIX_CONCT_TEST_ENABLE  BIT_9     /* 1 = Enables connectivity testing */
+-#define MDI_MDIX_RESET_ALL_MASK     0x0000
+-
+-/* HWI Control Register bit definitions */
+-#define HWI_TEST_DISTANCE           BIT_0_8   /* distance to cable problem */
+-#define HWI_TEST_HIGHZ_PROBLEM      BIT_9     /* 1 = Open Circuit */
+-#define HWI_TEST_LOWZ_PROBLEM       BIT_10    /* 1 = Short Circuit */
+-#define HWI_TEST_RESERVED           (BIT_11 | BIT_12) /* reserved */
+-#define HWI_TEST_EXECUTE            BIT_13    /* 1 = Execute the HWI test on the PHY */
+-#define HWI_TEST_ABILITY            BIT_14    /* 1 = test passed */
+-#define HWI_TEST_ENABLE             BIT_15    /* 1 = Enables the HWI feature */
+-#define HWI_RESET_ALL_MASK          0x0000
+-
+-/* ############Start of 82555 specific defines################## */
+-
+-/* Intel 82555 specific registers */
+-#define PHY_82555_CSR             0x10        /* 82555 CSR */
+-#define PHY_82555_SPECIAL_CONTROL   0x11      /* 82555 special control register */
+-
+-#define PHY_82555_RCV_ERR         0x15        /* 82555 100BaseTx Receive Error
+-                                               * Frame Counter */
+-#define PHY_82555_SYMBOL_ERR      0x16        /* 82555 RCV Symbol Error Counter */
+-#define PHY_82555_PREM_EOF_ERR            0x17        /* 82555 100BaseTx RCV Premature End
+-                                               * of Frame Error Counter */
+-#define PHY_82555_EOF_COUNTER     0x18        /* 82555 end of frame error counter */
+-#define PHY_82555_MDI_EQUALIZER_CSR 0x1a      /* 82555 specific equalizer reg. */
+-
+-/* 82555 CSR bits */
+-#define PHY_82555_SPEED_BIT    BIT_1
+-#define PHY_82555_POLARITY_BIT BIT_8
+-
+-/* 82555 equalizer reg. opcodes */
+-#define ENABLE_ZERO_FORCING  0x2010   /* write to ASD conf. reg. 0 */
+-#define DISABLE_ZERO_FORCING 0x2000   /* write to ASD conf. reg. 0 */
+-
+-/* 82555 special control reg. opcodes */
+-#define DISABLE_AUTO_POLARITY 0x0010
+-#define EXTENDED_SQUELCH_BIT  BIT_2
+-
+-/* ############End of 82555 specific defines##################### */
+-
+-/* Auto-Negotiation advertisement register bit definitions*/
+-#define NWAY_AD_FC_SUPPORTED    0x0400        /* Flow Control supported */
+-
+-/* Auto-Negotiation link partner ability register bit definitions*/
+-#define NWAY_LP_ABILITY               0x07e0  /* technologies supported */
+-
+-/* PHY 100 Extended Register 0 bit definitions*/
+-#define PHY_100_ER0_FDX_INDIC BIT_0   /* 1 = FDX, 0 = half duplex */
+-#define PHY_100_ER0_SPEED_INDIC BIT_1 /* 1 = 100Mbps, 0= 10Mbps */
+-
+-/* National Semiconductor TX phy congestion control register bit definitions*/
+-#define NSC_TX_CONG_TXREADY  BIT_10   /* Makes TxReady an input */
+-#define NSC_TX_CONG_ENABLE   BIT_8    /* Enables congestion control */
+-
+-/* National Semiconductor TX phy speed indication register bit definitions*/
+-#define NSC_TX_SPD_INDC_SPEED BIT_6   /* 0 = 100Mbps, 1=10Mbps */
+-
+-/************* function prototypes ************/
+-extern unsigned char e100_phy_init(struct e100_private *bdp);
+-extern unsigned char e100_update_link_state(struct e100_private *bdp);
+-extern unsigned char e100_phy_check(struct e100_private *bdp);
+-extern void e100_phy_set_speed_duplex(struct e100_private *bdp,
+-                                    unsigned char force_restart);
+-extern void e100_phy_autoneg(struct e100_private *bdp);
+-extern void e100_phy_reset(struct e100_private *bdp);
+-extern void e100_phy_set_loopback(struct e100_private *bdp);
+-extern int e100_mdi_write(struct e100_private *, u32, u32, u16);
+-extern int e100_mdi_read(struct e100_private *, u32, u32, u16 *);
+-
+-#endif
+--- linux-2.6.0/drivers/net/e100/e100_test.c   2003-06-14 12:18:08.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,500 +0,0 @@
+-/*******************************************************************************
+-
+-  
+-  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+-  
+-  This program is free software; you can redistribute it and/or modify it 
+-  under the terms of the GNU General Public License as published by the Free 
+-  Software Foundation; either version 2 of the License, or (at your option) 
+-  any later version.
+-  
+-  This program is distributed in the hope that it will be useful, but WITHOUT 
+-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+-  more details.
+-  
+-  You should have received a copy of the GNU General Public License along with
+-  this program; if not, write to the Free Software Foundation, Inc., 59 
+-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+-  
+-  The full GNU General Public License is included in this distribution in the
+-  file called LICENSE.
+-  
+-  Contact Information:
+-  Linux NICS <linux.nics@intel.com>
+-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+-*******************************************************************************/
+-
+-#include "e100_phy.h"
+-#include "e100_config.h"
+-
+-extern u16 e100_eeprom_read(struct e100_private *, u16);
+-extern int e100_wait_exec_cmplx(struct e100_private *, u32,u8, u8);
+-extern void e100_phy_reset(struct e100_private *bdp);
+-extern void e100_phy_autoneg(struct e100_private *bdp);
+-extern void e100_phy_set_loopback(struct e100_private *bdp);
+-extern void e100_force_speed_duplex(struct e100_private *bdp);
+-
+-static u8 e100_diag_selftest(struct net_device *);
+-static u8 e100_diag_eeprom(struct net_device *);
+-static u8 e100_diag_loopback(struct net_device *);
+-
+-static u8 e100_diag_one_loopback (struct net_device *, u8);
+-static u8 e100_diag_rcv_loopback_pkt(struct e100_private *);
+-static void e100_diag_config_loopback(struct e100_private *, u8, u8, u8 *,u8 *);
+-static u8 e100_diag_loopback_alloc(struct e100_private *);
+-static void e100_diag_loopback_cu_ru_exec(struct e100_private *);
+-static u8 e100_diag_check_pkt(u8 *);
+-static void e100_diag_loopback_free(struct e100_private *);
+-static int e100_cable_diag(struct e100_private *bdp);
+-
+-#define LB_PACKET_SIZE 1500
+-
+-/**
+- * e100_run_diag - main test execution handler - checks mask of requests and calls the diag routines  
+- * @dev: atapter's net device data struct
+- * @test_info: array with test request mask also used to store test results
+- *
+- * RETURNS: updated flags field of struct ethtool_test
+- */
+-u32
+-e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags)
+-{
+-      struct e100_private* bdp = dev->priv;
+-      u8 test_result = 0;
+-
+-      if (!e100_get_link_state(bdp)) {
+-              test_result = ETH_TEST_FL_FAILED;
+-              test_info[test_link] = true;
+-      }
+-      if (!e100_diag_eeprom(dev)) {
+-              test_result = ETH_TEST_FL_FAILED;
+-              test_info[test_eeprom] = true;
+-      }
+-      if (flags & ETH_TEST_FL_OFFLINE) {
+-              u8 fail_mask;
+-              if (netif_running(dev)) {
+-                      spin_lock_bh(&dev->xmit_lock);
+-                      e100_close(dev);
+-                      spin_unlock_bh(&dev->xmit_lock);
+-              }
+-              if (e100_diag_selftest(dev)) {
+-                      test_result = ETH_TEST_FL_FAILED;
+-                      test_info[test_self_test] = true;
+-              }
+-
+-              fail_mask = e100_diag_loopback(dev);
+-              if (fail_mask) {
+-                      test_result = ETH_TEST_FL_FAILED;
+-                      if (fail_mask & PHY_LOOPBACK)
+-                              test_info[test_loopback_phy] = true;
+-                      if (fail_mask & MAC_LOOPBACK)
+-                              test_info[test_loopback_mac] = true;
+-              }
+-
+-              test_info[cable_diag] = e100_cable_diag(bdp);
+-              /* Need hw init regardless of netif_running */
+-              e100_hw_init(bdp);
+-              if (netif_running(dev)) {
+-                      e100_open(dev);
+-              }
+-      }
+-      else {
+-              test_info[test_self_test] = false;
+-              test_info[test_loopback_phy] = false;
+-              test_info[test_loopback_mac] = false;
+-              test_info[cable_diag] = false;
+-      }
+-
+-      return flags | test_result;
+-}
+-
+-/**
+- * e100_diag_selftest - run hardware selftest 
+- * @dev: atapter's net device data struct
+- */
+-static u8
+-e100_diag_selftest(struct net_device *dev)
+-{
+-      struct e100_private *bdp = dev->priv;
+-      u32 st_timeout, st_result;
+-      u8 retval = 0;
+-
+-      if (!e100_selftest(bdp, &st_timeout, &st_result)) {
+-              if (!st_timeout) {
+-                      if (st_result & CB_SELFTEST_REGISTER_BIT)
+-                              retval |= REGISTER_TEST_FAIL;
+-                      if (st_result & CB_SELFTEST_DIAG_BIT)
+-                              retval |= SELF_TEST_FAIL;
+-                      if (st_result & CB_SELFTEST_ROM_BIT)
+-                              retval |= ROM_TEST_FAIL;
+-              } else {
+-                      retval = TEST_TIMEOUT;
+-              }
+-      }
+-
+-      return retval;
+-}
+-
+-/**
+- * e100_diag_eeprom - validate eeprom checksum correctness
+- * @dev: atapter's net device data struct
+- *
+- */
+-static u8
+-e100_diag_eeprom (struct net_device *dev)
+-{
+-      struct e100_private *bdp = dev->priv;
+-      u16 i, eeprom_sum, eeprom_actual_csm;
+-
+-      for (i = 0, eeprom_sum = 0; i < (bdp->eeprom_size - 1); i++) {
+-              eeprom_sum += e100_eeprom_read(bdp, i);
+-      }
+-
+-      eeprom_actual_csm = e100_eeprom_read(bdp, bdp->eeprom_size - 1);
+-
+-      if (eeprom_actual_csm == (u16)(EEPROM_SUM - eeprom_sum)) {
+-              return true;
+-      }
+-
+-      return false;
+-}
+-
+-/**
+- * e100_diag_loopback - performs loopback test  
+- * @dev: atapter's net device data struct
+- */
+-static u8
+-e100_diag_loopback (struct net_device *dev)
+-{
+-      u8 rc = 0;
+-
+-      printk(KERN_DEBUG "%s: PHY loopback test starts\n", dev->name);
+-      e100_hw_init(dev->priv);
+-      if (!e100_diag_one_loopback(dev, PHY_LOOPBACK)) {
+-              rc |= PHY_LOOPBACK;
+-      }
+-      printk(KERN_DEBUG "%s: PHY loopback test ends\n", dev->name);
+-
+-      printk(KERN_DEBUG "%s: MAC loopback test starts\n", dev->name);
+-      e100_hw_init(dev->priv);
+-      if (!e100_diag_one_loopback(dev, MAC_LOOPBACK)) {
+-              rc |= MAC_LOOPBACK;
+-      }
+-      printk(KERN_DEBUG "%s: MAC loopback test ends\n", dev->name);
+-
+-      return rc;
+-}
+-
+-/**
+- * e100_diag_loopback - performs loopback test  
+- * @dev: atapter's net device data struct
+- * @mode: lopback test type
+- */
+-static u8
+-e100_diag_one_loopback (struct net_device *dev, u8 mode)
+-{
+-        struct e100_private *bdp = dev->priv;
+-        u8 res = false;
+-      u8 saved_dynamic_tbd = false;
+-      u8 saved_extended_tcb = false;
+-
+-      if (!e100_diag_loopback_alloc(bdp))
+-              return false;
+-
+-      /* change the config block to standard tcb and the correct loopback */
+-        e100_diag_config_loopback(bdp, true, mode,
+-                                &saved_extended_tcb, &saved_dynamic_tbd);
+-
+-      e100_diag_loopback_cu_ru_exec(bdp);
+-
+-        if (e100_diag_rcv_loopback_pkt(bdp)) {
+-              res = true;
+-      }
+-
+-        e100_diag_loopback_free(bdp);
+-
+-        /* change the config block to previous tcb mode and the no loopback */
+-        e100_diag_config_loopback(bdp, false, mode,
+-                                &saved_extended_tcb, &saved_dynamic_tbd);
+-      return res;
+-}
+-
+-/**
+- * e100_diag_config_loopback - setup/clear loopback before/after lpbk test
+- * @bdp: atapter's private data struct
+- * @set_loopback: true if the function is called to set lb
+- * @loopback_mode: the loopback mode(MAC or PHY)
+- * @tcb_extended: true if need to set extended tcb mode after clean loopback
+- * @dynamic_tbd: true if needed to set dynamic tbd mode after clean loopback
+- *
+- */
+-void
+-e100_diag_config_loopback(struct e100_private* bdp,
+-                        u8 set_loopback,
+-                        u8 loopback_mode,
+-                        u8* tcb_extended,
+-                        u8* dynamic_tbd)
+-{
+-      /* if set_loopback == true - we want to clear tcb_extended/dynamic_tbd.
+-       * the previous values are saved in the params tcb_extended/dynamic_tbd
+-       * if set_loopback == false - we want to restore previous value.
+-       */
+-      if (set_loopback || (*tcb_extended))
+-                *tcb_extended = e100_config_tcb_ext_enable(bdp,*tcb_extended);
+-
+-      if (set_loopback || (*dynamic_tbd))
+-               *dynamic_tbd = e100_config_dynamic_tbd(bdp,*dynamic_tbd);
+-
+-      if (set_loopback) {
+-              /* ICH PHY loopback is broken */
+-              if (bdp->flags & IS_ICH && loopback_mode == PHY_LOOPBACK)
+-                      loopback_mode = MAC_LOOPBACK;
+-              /* Configure loopback on MAC */
+-              e100_config_loopback_mode(bdp,loopback_mode);
+-      } else {
+-              e100_config_loopback_mode(bdp,NO_LOOPBACK);
+-      }
+-
+-      e100_config(bdp);
+-
+-      if (loopback_mode == PHY_LOOPBACK) {
+-              if (set_loopback)
+-                        /* Set PHY loopback mode */
+-                        e100_phy_set_loopback(bdp);
+-              else
+-                      /* Reset PHY loopback mode */
+-                      e100_phy_reset(bdp);    
+-              /* Wait for PHY state change */
+-              set_current_state(TASK_UNINTERRUPTIBLE);
+-                schedule_timeout(HZ);
+-      } else { /* For MAC loopback wait 500 msec to take effect */
+-              set_current_state(TASK_UNINTERRUPTIBLE);
+-              schedule_timeout(HZ / 2);
+-      }
+-}
+-  
+-/**
+- * e100_diag_loopback_alloc - alloc & initate tcb and rfd for the loopback
+- * @bdp: atapter's private data struct
+- *
+- */
+-static u8
+-e100_diag_loopback_alloc(struct e100_private *bdp)
+-{
+-      dma_addr_t dma_handle;
+-      tcb_t *tcb;
+-      rfd_t *rfd;
+-      tbd_t *tbd;
+-
+-      /* tcb, tbd and transmit buffer are allocated */
+-      tcb = pci_alloc_consistent(bdp->pdev,
+-                                 (sizeof (tcb_t) + sizeof (tbd_t) +
+-                                  LB_PACKET_SIZE),
+-                                 &dma_handle);
+-        if (tcb == NULL)
+-              return false;
+-
+-      memset(tcb, 0x00, sizeof (tcb_t) + sizeof (tbd_t) + LB_PACKET_SIZE);
+-      tcb->tcb_phys = dma_handle;
+-      tcb->tcb_hdr.cb_status = 0;
+-      tcb->tcb_hdr.cb_cmd =
+-              cpu_to_le16(CB_EL_BIT | CB_TRANSMIT | CB_TX_SF_BIT);
+-      /* Next command is null */
+-      tcb->tcb_hdr.cb_lnk_ptr = cpu_to_le32(0xffffffff);
+-      tcb->tcb_cnt = 0;
+-      tcb->tcb_thrshld = bdp->tx_thld;
+-      tcb->tcb_tbd_num = 1;
+-      /* Set up tcb tbd pointer */
+-      tcb->tcb_tbd_ptr = cpu_to_le32(tcb->tcb_phys + sizeof (tcb_t));
+-      tbd = (tbd_t *) ((u8 *) tcb + sizeof (tcb_t));
+-      /* Set up tbd transmit buffer */
+-      tbd->tbd_buf_addr =
+-              cpu_to_le32(le32_to_cpu(tcb->tcb_tbd_ptr) + sizeof (tbd_t));
+-      tbd->tbd_buf_cnt = __constant_cpu_to_le16(1024);
+-      /* The value of first 512 bytes is FF */
+-      memset((void *) ((u8 *) tbd + sizeof (tbd_t)), 0xFF, 512);
+-      /* The value of second 512 bytes is BA */
+-      memset((void *) ((u8 *) tbd + sizeof (tbd_t) + 512), 0xBA, 512);
+-      wmb();
+-      rfd = pci_alloc_consistent(bdp->pdev, sizeof (rfd_t), &dma_handle);
+-
+-      if (rfd == NULL) {
+-              pci_free_consistent(bdp->pdev,
+-                                  sizeof (tcb_t) + sizeof (tbd_t) +
+-                                  LB_PACKET_SIZE, tcb, tcb->tcb_phys);
+-              return false;
+-      }
+-
+-      memset(rfd, 0x00, sizeof (rfd_t));
+-
+-      /* init all fields in rfd */
+-      rfd->rfd_header.cb_cmd = cpu_to_le16(RFD_EL_BIT);
+-      rfd->rfd_sz = cpu_to_le16(ETH_FRAME_LEN + CHKSUM_SIZE);
+-      /* dma_handle is physical address of rfd */
+-      bdp->loopback.dma_handle = dma_handle;
+-      bdp->loopback.tcb = tcb;
+-      bdp->loopback.rfd = rfd;
+-      wmb();
+-      return true;
+-}
+-
+-/**
+- * e100_diag_loopback_cu_ru_exec - activates cu and ru to send & receive the pkt
+- * @bdp: atapter's private data struct
+- *
+- */
+-static void
+-e100_diag_loopback_cu_ru_exec(struct e100_private *bdp)
+-{
+-      /*load CU & RU base */ 
+-      if(!e100_wait_exec_cmplx(bdp, bdp->loopback.dma_handle, SCB_RUC_START, 0))
+-              printk(KERN_ERR "e100: SCB_RUC_START failed!\n");
+-
+-      bdp->next_cu_cmd = START_WAIT;
+-      e100_start_cu(bdp, bdp->loopback.tcb);
+-      bdp->last_tcb = NULL;
+-      rmb();
+-}
+-/**
+- * e100_diag_check_pkt - checks if a given packet is a loopback packet
+- * @bdp: atapter's private data struct
+- *
+- * Returns true if OK false otherwise.
+- */
+-static u8
+-e100_diag_check_pkt(u8 *datap)
+-{
+-      int i;
+-      for (i = 0; i<512; i++) {
+-              if( !((*datap)==0xFF && (*(datap + 512) == 0xBA)) ) {
+-                      printk (KERN_ERR "e100: check loopback packet failed at: %x\n", i);
+-                      return false;
+-                      }
+-      }
+-      printk (KERN_DEBUG "e100: Check received loopback packet OK\n");
+-      return true;
+-}
+-
+-/**
+- * e100_diag_rcv_loopback_pkt - waits for receive and checks lpbk packet
+- * @bdp: atapter's private data struct
+- *
+- * Returns true if OK false otherwise.
+- */
+-static u8
+-e100_diag_rcv_loopback_pkt(struct e100_private* bdp) 
+-{    
+-      rfd_t *rfdp;
+-      u16 rfd_status;
+-      unsigned long expires = jiffies + HZ * 2;
+-
+-        rfdp =bdp->loopback.rfd;
+-
+-        rfd_status = le16_to_cpu(rfdp->rfd_header.cb_status);
+-
+-        while (!(rfd_status & RFD_STATUS_COMPLETE)) { 
+-              if (time_before(jiffies, expires)) {
+-                      yield();
+-                      rmb();
+-                      rfd_status = le16_to_cpu(rfdp->rfd_header.cb_status);
+-              } else {
+-                      break;
+-              }
+-        }
+-
+-        if (rfd_status & RFD_STATUS_COMPLETE) {
+-              printk(KERN_DEBUG "e100: Loopback packet received\n");
+-                return e100_diag_check_pkt(((u8 *)rfdp+bdp->rfd_size));
+-      }
+-      else {
+-              printk(KERN_ERR "e100: Loopback packet not received\n");
+-              return false;
+-      }
+-}
+-
+-/**
+- * e100_diag_loopback_free - free data allocated for loopback pkt send/receive
+- * @bdp: atapter's private data struct
+- *
+- */
+-static void
+-e100_diag_loopback_free (struct e100_private *bdp)
+-{
+-        pci_free_consistent(bdp->pdev,
+-                          sizeof(tcb_t) + sizeof(tbd_t) + LB_PACKET_SIZE,
+-                          bdp->loopback.tcb, bdp->loopback.tcb->tcb_phys);
+-
+-        pci_free_consistent(bdp->pdev, sizeof(rfd_t), bdp->loopback.rfd,
+-                          bdp->loopback.dma_handle);
+-}
+-
+-static int
+-e100_cable_diag(struct e100_private *bdp)
+-{     
+-      int saved_open_circut = 0xffff;
+-      int saved_short_circut = 0xffff;
+-      int saved_distance = 0xffff;
+-      int saved_same = 0;
+-      int cable_status = E100_CABLE_UNKNOWN;
+-      int i;
+-      
+-      /* If we have link, */  
+-      if (e100_get_link_state(bdp))
+-              return E100_CABLE_OK;
+-      
+-      if (bdp->rev_id < D102_REV_ID)
+-              return E100_CABLE_UNKNOWN;
+-
+-      /* Disable MDI/MDI-X auto switching */
+-        e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
+-              MDI_MDIX_RESET_ALL_MASK);
+-      /* Set to 100 Full as required by cable test */
+-      e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr,
+-              BMCR_SPEED100 | BMCR_FULLDPLX);
+-
+-      /* Test up to 100 times */
+-      for (i = 0; i < 100; i++) {
+-              u16 ctrl_reg;
+-              int distance, open_circut, short_circut, near_end;
+-
+-              /* Enable and execute cable test */
+-              e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,
+-                      (HWI_TEST_ENABLE | HWI_TEST_EXECUTE));
+-              /* Wait for cable test finished */
+-              set_current_state(TASK_UNINTERRUPTIBLE);
+-              schedule_timeout(HZ/100 + 1);
+-              /* Read results */
+-              e100_mdi_read(bdp, HWI_CONTROL_REG, bdp->phy_addr, &ctrl_reg);
+-              distance = ctrl_reg & HWI_TEST_DISTANCE;
+-              open_circut = ctrl_reg & HWI_TEST_HIGHZ_PROBLEM;
+-              short_circut = ctrl_reg & HWI_TEST_LOWZ_PROBLEM;
+-
+-              if ((distance == saved_distance) &&
+-                  (open_circut == saved_open_circut) &&
+-                  (short_circut == saved_short_circut)) 
+-                      saved_same++;
+-              else {
+-                      saved_same = 0;
+-                      saved_distance = distance;
+-                      saved_open_circut = open_circut;
+-                      saved_short_circut = short_circut;
+-              }
+-              /* If results are the same 3 times */
+-              if (saved_same == 3) {
+-                      near_end = ((distance * HWI_REGISTER_GRANULARITY) <
+-                             HWI_NEAR_END_BOUNDARY);
+-                      if (open_circut)
+-                              cable_status = (near_end) ? 
+-                                      E100_CABLE_OPEN_NEAR : E100_CABLE_OPEN_FAR;
+-                      if (short_circut)
+-                              cable_status = (near_end) ?
+-                                      E100_CABLE_SHORT_NEAR : E100_CABLE_SHORT_FAR;
+-                      break;
+-              }
+-      }
+-      /* Reset cable test */
+-        e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,                                          HWI_RESET_ALL_MASK);
+-      return cable_status;
+-}
+-
+--- linux-2.6.0/drivers/net/e100/e100_ucode.h  2003-06-14 12:18:34.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,365 +0,0 @@
+-/*******************************************************************************
+-
+-  
+-  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+-  
+-  This program is free software; you can redistribute it and/or modify it 
+-  under the terms of the GNU General Public License as published by the Free 
+-  Software Foundation; either version 2 of the License, or (at your option) 
+-  any later version.
+-  
+-  This program is distributed in the hope that it will be useful, but WITHOUT 
+-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+-  more details.
+-  
+-  You should have received a copy of the GNU General Public License along with
+-  this program; if not, write to the Free Software Foundation, Inc., 59 
+-  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+-  
+-  The full GNU General Public License is included in this distribution in the
+-  file called LICENSE.
+-  
+-  Contact Information:
+-  Linux NICS <linux.nics@intel.com>
+-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+-*******************************************************************************/
+-
+-#ifndef _E100_UCODE_H_
+-#define _E100_UCODE_H_
+-
+-/*
+-e100_ucode.h
+-
+-This file contains the loadable micro code arrays to implement receive 
+-bundling on the D101 A-step, D101 B-step, D101M (B-step only), D101S, 
+-D102 B-step, D102 B-step with TCO work around and D102 C-step.
+-
+-Each controller has its own specific micro code array.  The array for one 
+-controller is totally incompatible with any other controller, and if used 
+-will most likely cause the controller to lock up and stop responding to 
+-the driver.  Each micro code array has its own parameter offsets (described 
+-below), and they each have their own version number.
+-*/
+-
+-/*************************************************************************
+-*  CPUSaver parameters
+-*
+-*  All CPUSaver parameters are 16-bit literals that are part of a
+-*  "move immediate value" instruction.  By changing the value of
+-*  the literal in the instruction before the code is loaded, the
+-*  driver can change algorithm.
+-*
+-*  CPUSAVER_DWORD - This is the location of the instruction that loads
+-*    the dead-man timer with its inital value.  By writing a 16-bit
+-*    value to the low word of this instruction, the driver can change
+-*    the timer value.  The current default is either x600 or x800;
+-*    experiments show that the value probably should stay within the
+-*    range of x200 - x1000.
+-*
+-*  CPUSAVER_BUNDLE_MAX_DWORD - This is the location of the instruction
+-*    that sets the maximum number of frames that will be bundled.  In
+-*    some situations, such as the TCP windowing algorithm, it may be
+-*    better to limit the growth of the bundle size than let it go as
+-*    high as it can, because that could cause too much added latency.
+-*    The default is six, because this is the number of packets in the
+-*    default TCP window size.  A value of 1 would make CPUSaver indicate
+-*    an interrupt for every frame received.  If you do not want to put
+-*    a limit on the bundle size, set this value to xFFFF.
+-*
+-*  CPUSAVER_MIN_SIZE_DWORD - This is the location of the instruction
+-*    that contains a bit-mask describing the minimum size frame that
+-*    will be bundled.  The default masks the lower 7 bits, which means
+-*    that any frame less than 128 bytes in length will not be bundled,
+-*    but will instead immediately generate an interrupt.  This does
+-*    not affect the current bundle in any way.  Any frame that is 128
+-*    bytes or large will be bundled normally.  This feature is meant
+-*    to provide immediate indication of ACK frames in a TCP environment.
+-*    Customers were seeing poor performance when a machine with CPUSaver
+-*    enabled was sending but not receiving.  The delay introduced when
+-*    the ACKs were received was enough to reduce total throughput, because
+-*    the sender would sit idle until the ACK was finally seen.
+-*
+-*    The current default is 0xFF80, which masks out the lower 7 bits.
+-*    This means that any frame which is x7F (127) bytes or smaller
+-*    will cause an immediate interrupt.  Because this value must be a 
+-*    bit mask, there are only a few valid values that can be used.  To
+-*    turn this feature off, the driver can write the value xFFFF to the
+-*    lower word of this instruction (in the same way that the other
+-*    parameters are used).  Likewise, a value of 0xF800 (2047) would
+-*    cause an interrupt to be generated for every frame, because all
+-*    standard Ethernet frames are <= 2047 bytes in length.
+-*************************************************************************/
+-
+-#ifndef UCODE_MAX_DWORDS
+-#define UCODE_MAX_DWORDS      134
+-#endif
+-
+-/********************************************************/
+-/*  CPUSaver micro code for the D101A                   */
+-/********************************************************/
+-
+-/*  Version 2.0  */
+-
+-/*  This value is the same for both A and B step of 558.  */
+-
+-#define D101_CPUSAVER_TIMER_DWORD             72
+-#define D101_CPUSAVER_BUNDLE_DWORD            UCODE_MAX_DWORDS
+-#define D101_CPUSAVER_MIN_SIZE_DWORD          UCODE_MAX_DWORDS
+-
+-#define     D101_A_RCVBUNDLE_UCODE \
+-{\
+-0x03B301BB, 0x0046FFFF, 0xFFFFFFFF, 0x051DFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
+-0x000C0001, 0x00101212, 0x000C0008, 0x003801BC, \
+-0x00000000, 0x00124818, 0x000C1000, 0x00220809, \
+-0x00010200, 0x00124818, 0x000CFFFC, 0x003803B5, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x0010009C, 0x0024B81D, 0x00130836, 0x000C0001, \
+-0x0026081C, 0x0020C81B, 0x00130824, 0x00222819, \
+-0x00101213, 0x00041000, 0x003A03B3, 0x00010200, \
+-0x00101B13, 0x00238081, 0x00213049, 0x0038003B, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x0010009C, 0x0024B83E, 0x00130826, 0x000C0001, \
+-0x0026083B, 0x00010200, 0x00134824, 0x000C0001, \
+-0x00101213, 0x00041000, 0x0038051E, 0x00101313, \
+-0x00010400, 0x00380521, 0x00050600, 0x00100824, \
+-0x00101310, 0x00041000, 0x00080600, 0x00101B10, \
+-0x0038051E, 0x00000000, 0x00000000, 0x00000000  \
+-}
+-
+-/********************************************************/
+-/*  CPUSaver micro code for the D101B                   */
+-/********************************************************/
+-
+-/*  Version 2.0  */
+-
+-#define     D101_B0_RCVBUNDLE_UCODE \
+-{\
+-0x03B401BC, 0x0047FFFF, 0xFFFFFFFF, 0x051EFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
+-0x000C0001, 0x00101B92, 0x000C0008, 0x003801BD, \
+-0x00000000, 0x00124818, 0x000C1000, 0x00220809, \
+-0x00010200, 0x00124818, 0x000CFFFC, 0x003803B6, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x0010009C, 0x0024B81D, 0x0013082F, 0x000C0001, \
+-0x0026081C, 0x0020C81B, 0x00130837, 0x00222819, \
+-0x00101B93, 0x00041000, 0x003A03B4, 0x00010200, \
+-0x00101793, 0x00238082, 0x0021304A, 0x0038003C, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x0010009C, 0x0024B83E, 0x00130826, 0x000C0001, \
+-0x0026083B, 0x00010200, 0x00134837, 0x000C0001, \
+-0x00101B93, 0x00041000, 0x0038051F, 0x00101313, \
+-0x00010400, 0x00380522, 0x00050600, 0x00100837, \
+-0x00101310, 0x00041000, 0x00080600, 0x00101790, \
+-0x0038051F, 0x00000000, 0x00000000, 0x00000000  \
+-}
+-
+-/********************************************************/
+-/*  CPUSaver micro code for the D101M (B-step only)     */
+-/********************************************************/
+-
+-/*  Version 2.10.1  */
+-
+-/*  Parameter values for the D101M B-step  */
+-#define D101M_CPUSAVER_TIMER_DWORD            78
+-#define D101M_CPUSAVER_BUNDLE_DWORD           65
+-#define D101M_CPUSAVER_MIN_SIZE_DWORD         126
+-
+-#define D101M_B_RCVBUNDLE_UCODE \
+-{\
+-0x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \
+-0x000C0001, 0x00101312, 0x000C0008, 0x00380216, \
+-0x0010009C, 0x00204056, 0x002380CC, 0x00380056, \
+-0x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \
+-0x00380438, 0x00000000, 0x00140000, 0x00380555, \
+-0x00308000, 0x00100662, 0x00100561, 0x000E0408, \
+-0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
+-0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
+-0x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \
+-0x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \
+-0x003A0437, 0x00044010, 0x0038078A, 0x00000000, \
+-0x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \
+-0x00130824, 0x000C0001, 0x00101213, 0x00260C75, \
+-0x00041000, 0x00010004, 0x00130826, 0x000C0006, \
+-0x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
+-0x00101210, 0x00380C34, 0x00000000, 0x00000000, \
+-0x0021155B, 0x00100099, 0x00206559, 0x0010009C, \
+-0x00244559, 0x00130836, 0x000C0000, 0x00220C62, \
+-0x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \
+-0x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \
+-0x00214C0E, 0x00380555, 0x00010004, 0x00041000, \
+-0x00278C67, 0x00040800, 0x00018100, 0x003A0437, \
+-0x00130826, 0x000C0001, 0x00220559, 0x00101313, \
+-0x00380559, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00130831, 0x0010090B, 0x00124813, \
+-0x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \
+-0x003806A8, 0x00000000, 0x00000000, 0x00000000, \
+-}
+-
+-/********************************************************/
+-/*  CPUSaver micro code for the D101S                   */
+-/********************************************************/
+-
+-/*  Version 1.20.1  */
+-
+-/*  Parameter values for the D101S  */
+-#define D101S_CPUSAVER_TIMER_DWORD            78
+-#define D101S_CPUSAVER_BUNDLE_DWORD           67
+-#define D101S_CPUSAVER_MIN_SIZE_DWORD         128
+-
+-#define D101S_RCVBUNDLE_UCODE \
+-{\
+-0x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \
+-0x000C0001, 0x00101312, 0x000C0008, 0x00380243, \
+-0x0010009C, 0x00204056, 0x002380D0, 0x00380056, \
+-0x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \
+-0x0038047F, 0x00000000, 0x00140000, 0x003805A3, \
+-0x00308000, 0x00100610, 0x00100561, 0x000E0408, \
+-0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
+-0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
+-0x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \
+-0x00380F90, 0x00080000, 0x00103090, 0x00380F90, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \
+-0x003A047E, 0x00044010, 0x00380819, 0x00000000, \
+-0x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \
+-0x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \
+-0x00101213, 0x00260FF7, 0x00041000, 0x00010004, \
+-0x00130826, 0x000C0006, 0x00220700, 0x0013C926, \
+-0x00101313, 0x00380700, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
+-0x00101210, 0x00380FB6, 0x00000000, 0x00000000, \
+-0x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \
+-0x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \
+-0x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \
+-0x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \
+-0x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \
+-0x00010004, 0x00041000, 0x00278FE9, 0x00040800, \
+-0x00018100, 0x003A047E, 0x00130826, 0x000C0001, \
+-0x002205A7, 0x00101313, 0x003805A7, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00130831, \
+-0x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \
+-0x00041000, 0x00010004, 0x00380700  \
+-}
+-
+-/********************************************************/
+-/*  CPUSaver micro code for the D102 B-step             */
+-/********************************************************/
+-
+-/*  Version 2.0  */
+-/*  Parameter values for the D102 B-step  */
+-#define D102_B_CPUSAVER_TIMER_DWORD           82
+-#define D102_B_CPUSAVER_BUNDLE_DWORD          106
+-#define D102_B_CPUSAVER_MIN_SIZE_DWORD                70
+-
+-#define     D102_B_RCVBUNDLE_UCODE \
+-{\
+-0x006F0276, 0x0EF71FFF, 0x0ED30F86, 0x0D250ED9, 0x1FFF1FFF, 0x1FFF04D2, \
+-0x00300001, 0x0140D871, 0x00300008, 0x00E00277, \
+-0x01406C57, 0x00816073, 0x008700FA, 0x00E00070, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x01406CBA, 0x00807F9A, 0x00901F9A, 0x0024FFFF, \
+-0x014B6F6F, 0x0030FFFE, 0x01407172, 0x01496FBA, \
+-0x014B6F72, 0x00308000, 0x01406C52, 0x00912EFC, \
+-0x00E00EF8, 0x00000000, 0x00000000, 0x00000000, \
+-0x00906F8C, 0x00900F8C, 0x00E00F87, 0x00000000, \
+-0x00906ED8, 0x01406C55, 0x00E00ED4, 0x00000000, \
+-0x01406C51, 0x0080DFC2, 0x01406C52, 0x00815FC2, \
+-0x01406C57, 0x00917FCC, 0x00E01FDD, 0x00000000, \
+-0x00822D30, 0x01406C51, 0x0080CD26, 0x01406C52, \
+-0x00814D26, 0x01406C57, 0x00916D26, 0x014C6FD7, \
+-0x00300000, 0x00841FD2, 0x00300001, 0x0140D772, \
+-0x00E012B3, 0x014C6F91, 0x0150710B, 0x01496F72, \
+-0x0030FF80, 0x00940EDD, 0x00102000, 0x00038400, \
+-0x00E00EDA, 0x00000000, 0x00000000, 0x00000000, \
+-0x01406C57, 0x00917FE9, 0x00001000, 0x00E01FE9, \
+-0x00200600, 0x0140D76F, 0x00138400, 0x01406FD8, \
+-0x0140D96F, 0x00E01FDD, 0x00038400, 0x00102000, \
+-0x00971FD7, 0x00101000, 0x00050200, 0x00E804D2, \
+-0x014C6FD8, 0x00300001, 0x00840D26, 0x0140D872, \
+-0x00E00D26, 0x014C6FD9, 0x00300001, 0x0140D972, \
+-0x00941FBD, 0x00102000, 0x00038400, 0x014C6FD8, \
+-0x00300006, 0x00840EDA, 0x014F71D8, 0x0140D872, \
+-0x00E00EDA, 0x01496F50, 0x00E004D3, 0x00000000, \
+-}
+-
+-/********************************************************/
+-/*  Micro code for the D102 C-step                      */
+-/********************************************************/
+-
+-/*  Parameter values for the D102 C-step  */
+-#define D102_C_CPUSAVER_TIMER_DWORD           46
+-#define D102_C_CPUSAVER_BUNDLE_DWORD          74
+-#define D102_C_CPUSAVER_MIN_SIZE_DWORD                54
+-
+-#define     D102_C_RCVBUNDLE_UCODE \
+-{ \
+-0x00700279, 0x0E6604E2, 0x02BF0CAE, 0x1508150C, 0x15190E5B, 0x0E840F13, \
+-0x00E014D8, 0x00000000, 0x00000000, 0x00000000, \
+-0x00E014DC, 0x00000000, 0x00000000, 0x00000000, \
+-0x00E014F4, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00E014E0, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00E014E7, 0x00000000, 0x00000000, 0x00000000, \
+-0x00141000, 0x015D6F0D, 0x00E002C0, 0x00000000, \
+-0x00200600, 0x00E0150D, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x0030FF80, 0x00940E6A, 0x00038200, 0x00102000, \
+-0x00E00E67, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00906E65, 0x00800E60, 0x00E00E5D, 0x00000000, \
+-0x00300006, 0x00E0151A, 0x00000000, 0x00000000, \
+-0x00906F19, 0x00900F19, 0x00E00F14, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x01406CBA, 0x00807FDA, 0x00901FDA, 0x0024FFFF, \
+-0x014B6F6F, 0x0030FFFE, 0x01407172, 0x01496FBA, \
+-0x014B6F72, 0x00308000, 0x01406C52, 0x00912E89, \
+-0x00E00E85, 0x00000000, 0x00000000, 0x00000000  \
+-}
+-
+-/********************************************************/
+-/*  Micro code for the D102 E-step                      */
+-/********************************************************/
+-
+-/*  Parameter values for the D102 E-step  */
+-#define D102_E_CPUSAVER_TIMER_DWORD           42
+-#define D102_E_CPUSAVER_BUNDLE_DWORD          54
+-#define D102_E_CPUSAVER_MIN_SIZE_DWORD                46
+-
+-#define     D102_E_RCVBUNDLE_UCODE \
+-{\
+-0x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x1FFF1FFF, 0x1FFF1FFF, \
+-0x00E014B9, 0x00000000, 0x00000000, 0x00000000, \
+-0x00E014BD, 0x00000000, 0x00000000, 0x00000000, \
+-0x00E014D5, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00E014C1, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+-0x00E014C8, 0x00000000, 0x00000000, 0x00000000, \
+-0x00200600, 0x00E014EE, 0x00000000, 0x00000000, \
+-0x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \
+-0x00E00E43, 0x00000000, 0x00000000, 0x00000000, \
+-0x00300006, 0x00E014FB, 0x00000000, 0x00000000  \
+-}
+-
+-#endif /* _E100_UCODE_H_ */
+--- linux-2.6.0/drivers/net/e100/LICENSE       2003-06-14 12:18:24.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,339 +0,0 @@
+-
+-"This software program is licensed subject to the GNU General Public License 
+-(GPL). Version 2, June 1991, available at 
+-<http://www.fsf.org/copyleft/gpl.html>"
+-
+-GNU General Public License 
+-
+-Version 2, June 1991
+-
+-Copyright (C) 1989, 1991 Free Software Foundation, Inc.  
+-59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+-
+-Everyone is permitted to copy and distribute verbatim copies of this license
+-document, but changing it is not allowed.
+-
+-Preamble
+-
+-The licenses for most software are designed to take away your freedom to 
+-share and change it. By contrast, the GNU General Public License is intended
+-to guarantee your freedom to share and change free software--to make sure 
+-the software is free for all its users. This General Public License applies 
+-to most of the Free Software Foundation's software and to any other program 
+-whose authors commit to using it. (Some other Free Software Foundation 
+-software is covered by the GNU Library General Public License instead.) You 
+-can apply it to your programs, too.
+-
+-When we speak of free software, we are referring to freedom, not price. Our
+-General Public Licenses are designed to make sure that you have the freedom 
+-to distribute copies of free software (and charge for this service if you 
+-wish), that you receive source code or can get it if you want it, that you 
+-can change the software or use pieces of it in new free programs; and that 
+-you know you can do these things.
+-
+-To protect your rights, we need to make restrictions that forbid anyone to 
+-deny you these rights or to ask you to surrender the rights. These 
+-restrictions translate to certain responsibilities for you if you distribute
+-copies of the software, or if you modify it.
+-
+-For example, if you distribute copies of such a program, whether gratis or 
+-for a fee, you must give the recipients all the rights that you have. You 
+-must make sure that they, too, receive or can get the source code. And you 
+-must show them these terms so they know their rights.
+- 
+-We protect your rights with two steps: (1) copyright the software, and (2) 
+-offer you this license which gives you legal permission to copy, distribute 
+-and/or modify the software. 
+-
+-Also, for each author's protection and ours, we want to make certain that 
+-everyone understands that there is no warranty for this free software. If 
+-the software is modified by someone else and passed on, we want its 
+-recipients to know that what they have is not the original, so that any 
+-problems introduced by others will not reflect on the original authors' 
+-reputations. 
+-
+-Finally, any free program is threatened constantly by software patents. We 
+-wish to avoid the danger that redistributors of a free program will 
+-individually obtain patent licenses, in effect making the program 
+-proprietary. To prevent this, we have made it clear that any patent must be 
+-licensed for everyone's free use or not licensed at all. 
+-
+-The precise terms and conditions for copying, distribution and modification 
+-follow. 
+-
+-TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+-
+-0. This License applies to any program or other work which contains a notice
+-   placed by the copyright holder saying it may be distributed under the 
+-   terms of this General Public License. The "Program", below, refers to any
+-   such program or work, and a "work based on the Program" means either the 
+-   Program or any derivative work under copyright law: that is to say, a 
+-   work containing the Program or a portion of it, either verbatim or with 
+-   modifications and/or translated into another language. (Hereinafter, 
+-   translation is included without limitation in the term "modification".) 
+-   Each licensee is addressed as "you". 
+-
+-   Activities other than copying, distribution and modification are not 
+-   covered by this License; they are outside its scope. The act of running 
+-   the Program is not restricted, and the output from the Program is covered 
+-   only if its contents constitute a work based on the Program (independent 
+-   of having been made by running the Program). Whether that is true depends
+-   on what the Program does. 
+-
+-1. You may copy and distribute verbatim copies of the Program's source code 
+-   as you receive it, in any medium, provided that you conspicuously and 
+-   appropriately publish on each copy an appropriate copyright notice and 
+-   disclaimer of warranty; keep intact all the notices that refer to this 
+-   License and to the absence of any warranty; and give any other recipients 
+-   of the Program a copy of this License along with the Program. 
+-
+-   You may charge a fee for the physical act of transferring a copy, and you 
+-   may at your option offer warranty protection in exchange for a fee. 
+-
+-2. You may modify your copy or copies of the Program or any portion of it, 
+-   thus forming a work based on the Program, and copy and distribute such 
+-   modifications or work under the terms of Section 1 above, provided that 
+-   you also meet all of these conditions: 
+-
+-   * a) You must cause the modified files to carry prominent notices stating 
+-        that you changed the files and the date of any change. 
+-
+-   * b) You must cause any work that you distribute or publish, that in 
+-        whole or in part contains or is derived from the Program or any part 
+-        thereof, to be licensed as a whole at no charge to all third parties
+-        under the terms of this License. 
+-
+-   * c) If the modified program normally reads commands interactively when 
+-        run, you must cause it, when started running for such interactive 
+-        use in the most ordinary way, to print or display an announcement 
+-        including an appropriate copyright notice and a notice that there is
+-        no warranty (or else, saying that you provide a warranty) and that 
+-        users may redistribute the program under these conditions, and 
+-        telling the user how to view a copy of this License. (Exception: if 
+-        the Program itself is interactive but does not normally print such 
+-        an announcement, your work based on the Program is not required to 
+-        print an announcement.) 
+-
+-   These requirements apply to the modified work as a whole. If identifiable 
+-   sections of that work are not derived from the Program, and can be 
+-   reasonably considered independent and separate works in themselves, then 
+-   this License, and its terms, do not apply to those sections when you 
+-   distribute them as separate works. But when you distribute the same 
+-   sections as part of a whole which is a work based on the Program, the 
+-   distribution of the whole must be on the terms of this License, whose 
+-   permissions for other licensees extend to the entire whole, and thus to 
+-   each and every part regardless of who wrote it. 
+-
+-   Thus, it is not the intent of this section to claim rights or contest 
+-   your rights to work written entirely by you; rather, the intent is to 
+-   exercise the right to control the distribution of derivative or 
+-   collective works based on the Program. 
+-
+-   In addition, mere aggregation of another work not based on the Program 
+-   with the Program (or with a work based on the Program) on a volume of a 
+-   storage or distribution medium does not bring the other work under the 
+-   scope of this License. 
+-
+-3. You may copy and distribute the Program (or a work based on it, under 
+-   Section 2) in object code or executable form under the terms of Sections 
+-   1 and 2 above provided that you also do one of the following: 
+-
+-   * a) Accompany it with the complete corresponding machine-readable source 
+-        code, which must be distributed under the terms of Sections 1 and 2 
+-        above on a medium customarily used for software interchange; or, 
+-
+-   * b) Accompany it with a written offer, valid for at least three years, 
+-        to give any third party, for a charge no more than your cost of 
+-        physically performing source distribution, a complete machine-
+-        readable copy of the corresponding source code, to be distributed 
+-        under the terms of Sections 1 and 2 above on a medium customarily 
+-        used for software interchange; or, 
+-
+-   * c) Accompany it with the information you received as to the offer to 
+-        distribute corresponding source code. (This alternative is allowed 
+-        only for noncommercial distribution and only if you received the 
+-        program in object code or executable form with such an offer, in 
+-        accord with Subsection b above.) 
+-
+-   The source code for a work means the preferred form of the work for 
+-   making modifications to it. For an executable work, complete source code 
+-   means all the source code for all modules it contains, plus any 
+-   associated interface definition files, plus the scripts used to control 
+-   compilation and installation of the executable. However, as a special 
+-   exception, the source code distributed need not include anything that is 
+-   normally distributed (in either source or binary form) with the major 
+-   components (compiler, kernel, and so on) of the operating system on which
+-   the executable runs, unless that component itself accompanies the 
+-   executable. 
+-
+-   If distribution of executable or object code is made by offering access 
+-   to copy from a designated place, then offering equivalent access to copy 
+-   the source code from the same place counts as distribution of the source 
+-   code, even though third parties are not compelled to copy the source 
+-   along with the object code. 
+-
+-4. You may not copy, modify, sublicense, or distribute the Program except as
+-   expressly provided under this License. Any attempt otherwise to copy, 
+-   modify, sublicense or distribute the Program is void, and will 
+-   automatically terminate your rights under this License. However, parties 
+-   who have received copies, or rights, from you under this License will not
+-   have their licenses terminated so long as such parties remain in full 
+-   compliance. 
+-
+-5. You are not required to accept this License, since you have not signed 
+-   it. However, nothing else grants you permission to modify or distribute 
+-   the Program or its derivative works. These actions are prohibited by law 
+-   if you do not accept this License. Therefore, by modifying or 
+-   distributing the Program (or any work based on the Program), you 
+-   indicate your acceptance of this License to do so, and all its terms and
+-   conditions for copying, distributing or modifying the Program or works 
+-   based on it. 
+-
+-6. Each time you redistribute the Program (or any work based on the 
+-   Program), the recipient automatically receives a license from the 
+-   original licensor to copy, distribute or modify the Program subject to 
+-   these terms and conditions. You may not impose any further restrictions 
+-   on the recipients' exercise of the rights granted herein. You are not 
+-   responsible for enforcing compliance by third parties to this License. 
+-
+-7. If, as a consequence of a court judgment or allegation of patent 
+-   infringement or for any other reason (not limited to patent issues), 
+-   conditions are imposed on you (whether by court order, agreement or 
+-   otherwise) that contradict the conditions of this License, they do not 
+-   excuse you from the conditions of this License. If you cannot distribute 
+-   so as to satisfy simultaneously your obligations under this License and 
+-   any other pertinent obligations, then as a consequence you may not 
+-   distribute the Program at all. For example, if a patent license would 
+-   not permit royalty-free redistribution of the Program by all those who 
+-   receive copies directly or indirectly through you, then the only way you 
+-   could satisfy both it and this License would be to refrain entirely from 
+-   distribution of the Program. 
+-
+-   If any portion of this section is held invalid or unenforceable under any
+-   particular circumstance, the balance of the section is intended to apply
+-   and the section as a whole is intended to apply in other circumstances. 
+-
+-   It is not the purpose of this section to induce you to infringe any 
+-   patents or other property right claims or to contest validity of any 
+-   such claims; this section has the sole purpose of protecting the 
+-   integrity of the free software distribution system, which is implemented 
+-   by public license practices. Many people have made generous contributions
+-   to the wide range of software distributed through that system in 
+-   reliance on consistent application of that system; it is up to the 
+-   author/donor to decide if he or she is willing to distribute software 
+-   through any other system and a licensee cannot impose that choice. 
+-
+-   This section is intended to make thoroughly clear what is believed to be 
+-   a consequence of the rest of this License. 
+-
+-8. If the distribution and/or use of the Program is restricted in certain 
+-   countries either by patents or by copyrighted interfaces, the original 
+-   copyright holder who places the Program under this License may add an 
+-   explicit geographical distribution limitation excluding those countries, 
+-   so that distribution is permitted only in or among countries not thus 
+-   excluded. In such case, this License incorporates the limitation as if 
+-   written in the body of this License. 
+-
+-9. The Free Software Foundation may publish revised and/or new versions of 
+-   the General Public License from time to time. Such new versions will be 
+-   similar in spirit to the present version, but may differ in detail to 
+-   address new problems or concerns. 
+-
+-   Each version is given a distinguishing version number. If the Program 
+-   specifies a version number of this License which applies to it and "any 
+-   later version", you have the option of following the terms and 
+-   conditions either of that version or of any later version published by 
+-   the Free Software Foundation. If the Program does not specify a version 
+-   number of this License, you may choose any version ever published by the 
+-   Free Software Foundation. 
+-
+-10. If you wish to incorporate parts of the Program into other free programs
+-    whose distribution conditions are different, write to the author to ask 
+-    for permission. For software which is copyrighted by the Free Software 
+-    Foundation, write to the Free Software Foundation; we sometimes make 
+-    exceptions for this. Our decision will be guided by the two goals of 
+-    preserving the free status of all derivatives of our free software and 
+-    of promoting the sharing and reuse of software generally. 
+-
+-   NO WARRANTY
+-
+-11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 
+-    FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 
+-    OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 
+-    PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER 
+-    EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 
+-    ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH 
+-    YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL 
+-    NECESSARY SERVICING, REPAIR OR CORRECTION. 
+-
+-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 
+-    WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 
+-    REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR 
+-    DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL 
+-    DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM 
+-    (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED 
+-    INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF 
+-    THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR 
+-    OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
+-
+-END OF TERMS AND CONDITIONS
+-
+-How to Apply These Terms to Your New Programs
+-
+-If you develop a new program, and you want it to be of the greatest 
+-possible use to the public, the best way to achieve this is to make it free 
+-software which everyone can redistribute and change under these terms. 
+-
+-To do so, attach the following notices to the program. It is safest to 
+-attach them to the start of each source file to most effectively convey the
+-exclusion of warranty; and each file should have at least the "copyright" 
+-line and a pointer to where the full notice is found. 
+-
+-one line to give the program's name and an idea of what it does.
+-Copyright (C) yyyy  name of author
+-
+-This program is free software; you can redistribute it and/or modify it 
+-under the terms of the GNU General Public License as published by the Free 
+-Software Foundation; either version 2 of the License, or (at your option) 
+-any later version.
+-
+-This program is distributed in the hope that it will be useful, but WITHOUT 
+-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+-more details.
+-
+-You should have received a copy of the GNU General Public License along with
+-this program; if not, write to the Free Software Foundation, Inc., 59 
+-Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+-
+-Also add information on how to contact you by electronic and paper mail. 
+-
+-If the program is interactive, make it output a short notice like this when 
+-it starts in an interactive mode: 
+-
+-Gnomovision version 69, Copyright (C) year name of author Gnomovision comes 
+-with ABSOLUTELY NO WARRANTY; for details type 'show w'.  This is free 
+-software, and you are welcome to redistribute it under certain conditions; 
+-type 'show c' for details.
+-
+-The hypothetical commands 'show w' and 'show c' should show the appropriate 
+-parts of the General Public License. Of course, the commands you use may be 
+-called something other than 'show w' and 'show c'; they could even be 
+-mouse-clicks or menu items--whatever suits your program. 
+-
+-You should also get your employer (if you work as a programmer) or your 
+-school, if any, to sign a "copyright disclaimer" for the program, if 
+-necessary. Here is a sample; alter the names: 
+-
+-Yoyodyne, Inc., hereby disclaims all copyright interest in the program 
+-'Gnomovision' (which makes passes at compilers) written by James Hacker.
+-
+-signature of Ty Coon, 1 April 1989
+-Ty Coon, President of Vice
+-
+-This General Public License does not permit incorporating your program into 
+-proprietary programs. If your program is a subroutine library, you may 
+-consider it more useful to permit linking proprietary applications with the 
+-library. If this is what you want to do, use the GNU Library General Public 
+-License instead of this License.
+--- linux-2.6.0/drivers/net/e100/Makefile      2003-06-14 12:18:34.000000000 -0700
++++ /dev/null  2002-08-30 16:31:37.000000000 -0700
+@@ -1,8 +0,0 @@
+-#
+-# Makefile for the Intel's E100 ethernet driver
+-#
+-
+-obj-$(CONFIG_E100) += e100.o
+-
+-e100-objs := e100_main.o e100_config.o e100_phy.o \
+-           e100_eeprom.o e100_test.o
+--- linux-2.6.0/drivers/net/e2100.c    2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/e2100.c     2003-12-28 23:21:01.000000000 -0800
+@@ -95,7 +95,6 @@ static inline void mem_off(short port)
+ #define E21_BIG_RX_STOP_PG    0xF0    /* Last page +1 of RX ring */
+ #define E21_TX_START_PG               E21_RX_STOP_PG  /* First page of TX buffer */
+-int e2100_probe(struct net_device *dev);
+ static int e21_probe1(struct net_device *dev, int ioaddr);
+ static int e21_open(struct net_device *dev);
+@@ -117,10 +116,11 @@ static int e21_close(struct net_device *
+       station address).
+  */
+-int  __init e2100_probe(struct net_device *dev)
++static int  __init do_e2100_probe(struct net_device *dev)
+ {
+       int *port;
+       int base_addr = dev->base_addr;
++      int irq = dev->irq;
+       SET_MODULE_OWNER(dev);
+@@ -129,13 +129,46 @@ int  __init e2100_probe(struct net_devic
+       else if (base_addr != 0)        /* Don't probe at all. */
+               return -ENXIO;
+-      for (port = e21_probe_list; *port; port++)
++      for (port = e21_probe_list; *port; port++) {
++              dev->irq = irq;
+               if (e21_probe1(dev, *port) == 0)
+                       return 0;
++      }
+       return -ENODEV;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      /* NB: e21_close() handles free_irq */
++      release_region(dev->base_addr, E21_IO_EXTENT);
++}
++
++struct net_device * __init e2100_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_e2100_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ static int __init e21_probe1(struct net_device *dev, int ioaddr)
+ {
+       int i, status, retval;
+@@ -175,13 +208,6 @@ static int __init e21_probe1(struct net_
+       for (i = 0; i < 6; i++)
+               printk(" %02X", station_addr[i]);
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev)) {
+-              printk (" unable to get memory for dev->priv.\n");
+-              retval = -ENOMEM;
+-              goto out;
+-      }
+-
+       if (dev->irq < 2) {
+               int irqlist[] = {15,11,10,12,5,9,3,4}, i;
+               for (i = 0; i < 8; i++)
+@@ -191,8 +217,6 @@ static int __init e21_probe1(struct net_
+                       }
+               if (i >= 8) {
+                       printk(" unable to get IRQ %d.\n", dev->irq);
+-                      kfree(dev->priv);
+-                      dev->priv = NULL;
+                       retval = -EAGAIN;
+                       goto out;
+               }
+@@ -376,7 +400,7 @@ e21_close(struct net_device *dev)
\f
+ #ifdef MODULE
+ #define MAX_E21_CARDS 4       /* Max number of E21 cards per module */
+-static struct net_device dev_e21[MAX_E21_CARDS];
++static struct net_device *dev_e21[MAX_E21_CARDS];
+ static int io[MAX_E21_CARDS];
+ static int irq[MAX_E21_CARDS];
+ static int mem[MAX_E21_CARDS];
+@@ -398,29 +422,35 @@ ISA device autoprobes on a running machi
+ int
+ init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_e21[this_dev];
+-              dev->irq = irq[this_dev];
+-              dev->base_addr = io[this_dev];
+-              dev->mem_start = mem[this_dev];
+-              dev->mem_end = xcvr[this_dev];  /* low 4bits = xcvr sel. */
+-              dev->init = e2100_probe;
+               if (io[this_dev] == 0)  {
+                       if (this_dev != 0) break; /* only autoprobe 1st one */
+                       printk(KERN_NOTICE "e2100.c: Presently autoprobing (not recommended) for a single card.\n");
+               }
+-              if (register_netdev(dev) != 0) {
+-                      printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]);
+-                      if (found != 0) {       /* Got at least one. */
+-                              return 0;
++              dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
++              dev->irq = irq[this_dev];
++              dev->base_addr = io[this_dev];
++              dev->mem_start = mem[this_dev];
++              dev->mem_end = xcvr[this_dev];  /* low 4bits = xcvr sel. */
++              if (do_e2100_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_e21[found++] = dev;
++                              continue;
+                       }
+-                      return -ENXIO;
++                      cleanup_card(dev);
+               }
+-              found++;
++              free_netdev(dev);
++              printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]);
++              break;
+       }
+-      return 0;
++      if (found)
++              return 0;
++      return -ENXIO;
+ }
+ void
+@@ -429,13 +459,11 @@ cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_e21[this_dev];
+-              if (dev->priv != NULL) {
+-                      void *priv = dev->priv;
+-                      /* NB: e21_close() handles free_irq */
+-                      release_region(dev->base_addr, E21_IO_EXTENT);
++              struct net_device *dev = dev_e21[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(priv);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/eepro100.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/net/eepro100.c  2003-12-28 23:21:01.000000000 -0800
+@@ -542,6 +542,7 @@ static int speedo_start_xmit(struct sk_b
+ static void speedo_refill_rx_buffers(struct net_device *dev, int force);
+ static int speedo_rx(struct net_device *dev);
+ static void speedo_tx_buffer_gc(struct net_device *dev);
++static void poll_speedo (struct net_device *dev);
+ static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+ static int speedo_close(struct net_device *dev);
+ static struct net_device_stats *speedo_get_stats(struct net_device *dev);
+@@ -885,6 +886,9 @@ static int __devinit speedo_found1(struc
+       dev->get_stats = &speedo_get_stats;
+       dev->set_multicast_list = &set_rx_mode;
+       dev->do_ioctl = &speedo_ioctl;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++      dev->poll_controller = &poll_speedo;
++#endif
+       if (register_netdevice(dev))
+               goto err_free_unlock;
+@@ -1675,6 +1679,23 @@ static irqreturn_t speedo_interrupt(int 
+       return IRQ_RETVAL(handled);
+ }
++#ifdef CONFIG_NET_POLL_CONTROLLER
++/*
++ * Polling 'interrupt' - used by things like netconsole to send skbs
++ * without having to re-enable interrupts. It's not called while
++ * the interrupt routine is executing.
++ */
++
++static void poll_speedo (struct net_device *dev)
++{
++      /* disable_irq is not very nice, but with the funny lockless design
++         we have no other choice. */
++      disable_irq(dev->irq);
++      speedo_interrupt (dev->irq, dev, NULL);
++      enable_irq(dev->irq);
++}
++#endif
++
+ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
+ {
+       struct speedo_private *sp = (struct speedo_private *)dev->priv;
+--- linux-2.6.0/drivers/net/eepro.c    2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/eepro.c     2003-12-28 23:21:01.000000000 -0800
+@@ -302,9 +302,7 @@ struct eepro_local {
+ /* Index to functions, as function prototypes. */
+-extern int eepro_probe(struct net_device *dev);
+-
+-static int    eepro_probe1(struct net_device *dev, short ioaddr);
++static int    eepro_probe1(struct net_device *dev, int autoprobe);
+ static int    eepro_open(struct net_device *dev);
+ static int    eepro_send_packet(struct sk_buff *skb, struct net_device *dev);
+ static irqreturn_t eepro_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+@@ -527,10 +525,11 @@ buffer (transmit-buffer = 32K - receive-
+    If dev->base_addr == 2, allocate space for the device and return success
+    (detachable devices only).
+    */
+-int __init eepro_probe(struct net_device *dev)
++static int __init do_eepro_probe(struct net_device *dev)
+ {
+       int i;
+       int base_addr = dev->base_addr;
++      int irq = dev->irq;
+       SET_MODULE_OWNER(dev);
+@@ -563,24 +562,48 @@ int __init eepro_probe(struct net_device
+ #endif
+       if (base_addr > 0x1ff)          /* Check a single specified location. */
+-              return eepro_probe1(dev, base_addr);
++              return eepro_probe1(dev, 0);
+       else if (base_addr != 0)        /* Don't probe at all. */
+               return -ENXIO;
+-
+       for (i = 0; eepro_portlist[i]; i++) {
+-              int ioaddr = eepro_portlist[i];
+-
+-              if (check_region(ioaddr, EEPRO_IO_EXTENT))
+-                      continue;
+-              if (eepro_probe1(dev, ioaddr) == 0)
++              dev->base_addr = eepro_portlist[i];
++              dev->irq = irq;
++              if (eepro_probe1(dev, 1) == 0)
+                       return 0;
+       }
+       return -ENODEV;
+ }
++struct net_device * __init eepro_probe(int unit)
++{
++      struct net_device *dev = alloc_etherdev(sizeof(struct eepro_local));
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENODEV);
++
++      SET_MODULE_OWNER(dev);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_eepro_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      release_region(dev->base_addr, EEPRO_IO_EXTENT);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ static void __init printEEPROMInfo(short ioaddr, struct net_device *dev)
+ {
+       unsigned short Word;
+@@ -713,83 +736,75 @@ static void eepro_print_info (struct net
+    probes on the ISA bus.  A good device probe avoids doing writes, and
+    verifies that the correct device exists and functions.  */
+-static int __init eepro_probe1(struct net_device *dev, short ioaddr)
++static int __init eepro_probe1(struct net_device *dev, int autoprobe)
+ {
+       unsigned short station_addr[6], id, counter;
+-      int i, j, irqMask, retval = 0;
++      int i;
+       struct eepro_local *lp;
+       enum iftype { AUI=0, BNC=1, TPE=2 };
++      int ioaddr = dev->base_addr;
++
++      /* Grab the region so we can find another board if autoIRQ fails. */
++      if (!request_region(ioaddr, EEPRO_IO_EXTENT, dev->name)) { 
++              if (!autoprobe)
++                      printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n",
++                              ioaddr);
++              return -EBUSY;
++      }
+       /* Now, we are going to check for the signature of the
+          ID_REG (register 2 of bank 0) */
+-      id=inb(ioaddr + ID_REG);
++      id = inb(ioaddr + ID_REG);
+-      if (((id) & ID_REG_MASK) != ID_REG_SIG) {
+-              retval = -ENODEV;
++      if ((id & ID_REG_MASK) != ID_REG_SIG)
+               goto exit;
+-      }
+-              /* We seem to have the 82595 signature, let's
+-                 play with its counter (last 2 bits of
+-                 register 2 of bank 0) to be sure. */
++      /* We seem to have the 82595 signature, let's
++         play with its counter (last 2 bits of
++         register 2 of bank 0) to be sure. */
+-              counter = (id & R_ROBIN_BITS);
+-
+-      if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS)!=(counter + 0x40)) {
+-              retval = -ENODEV;
+-              goto exit;
+-      }
++      counter = id & R_ROBIN_BITS;
+-                      /* Initialize the device structure */
+-                      dev->priv = kmalloc(sizeof(struct eepro_local), GFP_KERNEL);
+-      if (!dev->priv) {
+-              retval = -ENOMEM;
++      if ((inb(ioaddr + ID_REG) & R_ROBIN_BITS) != (counter + 0x40))
+               goto exit;
+-      }
+-
+-                      memset(dev->priv, 0, sizeof(struct eepro_local));
+-
+-                      lp = (struct eepro_local *)dev->priv;
+-      /* default values */
+-      lp->eepro = 0;
++      lp = (struct eepro_local *)dev->priv;
++      memset(lp, 0, sizeof(struct eepro_local));
+       lp->xmt_bar = XMT_BAR_PRO;
+       lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
+       lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
+       lp->eeprom_reg = EEPROM_REG_PRO;
++      spin_lock_init(&lp->lock);
+-                      /* Now, get the ethernet hardware address from
+-                         the EEPROM */
+-                      station_addr[0] = read_eeprom(ioaddr, 2, dev);
+-
+-                      /* FIXME - find another way to know that we've found
+-                       * an Etherexpress 10
+-                       */
+-                      if (station_addr[0] == 0x0000 ||
+-                          station_addr[0] == 0xffff) {
+-                              lp->eepro = LAN595FX_10ISA;
++      /* Now, get the ethernet hardware address from
++         the EEPROM */
++      station_addr[0] = read_eeprom(ioaddr, 2, dev);
++
++      /* FIXME - find another way to know that we've found
++       * an Etherexpress 10
++       */
++      if (station_addr[0] == 0x0000 || station_addr[0] == 0xffff) {
++              lp->eepro = LAN595FX_10ISA;
+               lp->eeprom_reg = EEPROM_REG_10;
+               lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
+               lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
+               lp->xmt_bar = XMT_BAR_10;
+-                              station_addr[0] = read_eeprom(ioaddr, 2, dev);
+-                      }
+-                      station_addr[1] = read_eeprom(ioaddr, 3, dev);
+-                      station_addr[2] = read_eeprom(ioaddr, 4, dev);
++              station_addr[0] = read_eeprom(ioaddr, 2, dev);
++      }
++      station_addr[1] = read_eeprom(ioaddr, 3, dev);
++      station_addr[2] = read_eeprom(ioaddr, 4, dev);
+       if (!lp->eepro) {
+               if (read_eeprom(ioaddr,7,dev)== ee_FX_INT2IRQ)
+                       lp->eepro = 2;
+               else if (station_addr[2] == SA_ADDR1)
+                       lp->eepro = 1;
+-                      }
+-
+-                      /* Fill in the 'dev' fields. */
+-                      dev->base_addr = ioaddr;
++      }
++      /* Fill in the 'dev' fields. */
+       for (i=0; i < 6; i++)
+-                              dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];
++              dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];
+       /* RX buffer must be more than 3K and less than 29K */
+       if (dev->mem_end < 3072 || dev->mem_end > 29696)
+@@ -798,65 +813,49 @@ static int __init eepro_probe1(struct ne
+       /* calculate {xmt,rcv}_{lower,upper}_limit */
+       eepro_recalc(dev);
+-
+-                      if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE))
+-                              dev->if_port = BNC;
++      if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE))
++              dev->if_port = BNC;
+       else
+               dev->if_port = TPE;
+-      if ((dev->irq < 2) && (lp->eepro!=0)) {
+-                              i = read_eeprom(ioaddr, 1, dev);
+-                              irqMask = read_eeprom(ioaddr, 7, dev);
+-                              i &= 0x07; /* Mask off INT number */
+-
+-                              for (j=0; ((j<16) && (i>=0)); j++) {
+-                                      if ((irqMask & (1<<j))!=0) {
+-                                              if (i==0) {
+-                                                      dev->irq = j;
+-                                                      break; /* found bit corresponding to irq */
+-                                              }
+-                                              i--; /* count bits set in irqMask */
+-                                      }
+-                              }
+-                              if (dev->irq < 2) {
+-                      printk(KERN_ERR " Duh! invalid interrupt vector stored in EEPROM.\n");
+-                      retval = -ENODEV;
+-                      goto freeall;
+-                              } else
+-                      if (dev->irq==2) dev->irq = 9;
+-                      }
+-
+-                      /* Grab the region so we can find another board if autoIRQ fails. */
+-                      if (!request_region(ioaddr, EEPRO_IO_EXTENT, dev->name)) { 
+-                              printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n", ioaddr);
+-                              goto freeall;
+-                      }
+-                      ((struct eepro_local *)dev->priv)->lock = SPIN_LOCK_UNLOCKED;
+-
+-                      dev->open               = eepro_open;
+-                      dev->stop               = eepro_close;
+-                      dev->hard_start_xmit    = eepro_send_packet;
+-                      dev->get_stats          = eepro_get_stats;
+-                      dev->set_multicast_list = &set_multicast_list;
+-                      dev->tx_timeout         = eepro_tx_timeout;
+-                      dev->watchdog_timeo     = TX_TIMEOUT;
+-
+-                      /* Fill in the fields of the device structure with
+-                         ethernet generic values */
+-                      ether_setup(dev);
+-
++      if (dev->irq < 2 && lp->eepro != 0) {
++              /* Mask off INT number */
++              int count = read_eeprom(ioaddr, 1, dev) & 7;
++              unsigned irqMask = read_eeprom(ioaddr, 7, dev);
++ 
++              while (count--)
++                      irqMask &= irqMask - 1;
++ 
++              count = ffs(irqMask);
++ 
++              if (count)
++                      dev->irq = count - 1;
++ 
++              if (dev->irq < 2) {
++                      printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");
++                      goto exit;
++              } else if (dev->irq == 2) {
++                      dev->irq = 9;
++              }
++      }
++ 
++      dev->open               = eepro_open;
++      dev->stop               = eepro_close;
++      dev->hard_start_xmit    = eepro_send_packet;
++      dev->get_stats          = eepro_get_stats;
++      dev->set_multicast_list = &set_multicast_list;
++      dev->tx_timeout         = eepro_tx_timeout;
++      dev->watchdog_timeo     = TX_TIMEOUT;
++ 
+       /* print boot time info */
+       eepro_print_info(dev);
+       /* reset 82595 */
+-                      eepro_reset(ioaddr);
+-
++      eepro_reset(ioaddr);
++      return 0;
+ exit:
+-      return retval;
+-freeall:
+-      kfree(dev->priv);
+-      goto exit;
+-
++      release_region(dev->base_addr, EEPRO_IO_EXTENT);
++      return -ENODEV;
+ }
+ /* Open/initialize the board.  This is called (in the current kernel)
+@@ -1701,7 +1700,7 @@ eepro_transmit_interrupt(struct net_devi
+ #ifdef MODULE
+ #define MAX_EEPRO 8
+-static struct net_device dev_eepro[MAX_EEPRO];
++static struct net_device *dev_eepro[MAX_EEPRO];
+ static int io[MAX_EEPRO];
+ static int irq[MAX_EEPRO];
+@@ -1729,6 +1728,7 @@ MODULE_PARM_DESC(autodetect, "EtherExpre
+ int
+ init_module(void)
+ {
++      struct net_device *dev;
+       int i;
+       if (io[0] == 0 && autodetect == 0) {
+               printk(KERN_WARNING "eepro_init_module: Probe is very dangerous in ISA boards!\n");
+@@ -1743,17 +1743,24 @@ init_module(void)
+       }
+       for (i = 0; i < MAX_EEPRO; i++) {
+-              struct net_device *d = &dev_eepro[n_eepro];
+-              d->mem_end      = mem[i];
+-              d->base_addr    = io[i];
+-              d->irq          = irq[i];
+-              d->init         = eepro_probe;
+-
+-                      if (register_netdev(d) == 0)
+-                              n_eepro++;
+-                      else
+-                              break;
++              dev = alloc_etherdev(sizeof(struct eepro_local));
++              if (!dev)
++                      break;
++
++              dev->mem_end = mem[i];
++              dev->base_addr = io[i];
++              dev->irq = irq[i];
++
++              if (do_eepro_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_eepro[n_eepro++] = dev;
++                              continue;
++                      }
++                      release_region(dev->base_addr, EEPRO_IO_EXTENT);
+               }
++              free_netdev(dev);
++              break;
++      }
+       if (n_eepro)
+               printk(KERN_INFO "%s", version);
+@@ -1767,15 +1774,10 @@ cleanup_module(void)
+       int i;
+       for (i=0; i<n_eepro; i++) {
+-              struct net_device *d = &dev_eepro[i];
+-              unregister_netdev(d);
+-
+-              kfree(d->priv);
+-              d->priv=NULL;
+-
+-              /* If we don't do this, we can't re-insmod it later. */
+-              release_region(d->base_addr, EEPRO_IO_EXTENT);
+-
++              struct net_device *dev = dev_eepro[i];
++              unregister_netdev(dev);
++              release_region(dev->base_addr, EEPRO_IO_EXTENT);
++              free_netdev(dev);
+       }
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/eexpress.c 2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/eexpress.c  2003-12-28 23:21:01.000000000 -0800
+@@ -244,7 +244,6 @@ static char mca_irqmap[] = { 12, 9, 3, 4
+  * Prototypes for Linux interface
+  */
+-extern int express_probe(struct net_device *dev);
+ static int eexp_open(struct net_device *dev);
+ static int eexp_close(struct net_device *dev);
+ static void eexp_timeout(struct net_device *dev);
+@@ -334,11 +333,13 @@ static inline unsigned short int SHADOW(
+  * checks for presence of EtherExpress card
+  */
+-int __init express_probe(struct net_device *dev)
++static int __init do_express_probe(struct net_device *dev)
+ {
+       unsigned short *port;
+       static unsigned short ports[] = { 0x240,0x300,0x310,0x270,0x320,0x340,0 };
+       unsigned short ioaddr = dev->base_addr;
++      int dev_irq = dev->irq;
++      int err;
+       SET_MODULE_OWNER(dev);
+@@ -391,27 +392,58 @@ int __init express_probe(struct net_devi
+               }
+       }
+ #endif
+-      if (ioaddr&0xfe00)
+-              return eexp_hw_probe(dev,ioaddr);
+-      else if (ioaddr)
++      if (ioaddr&0xfe00) {
++              if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress"))
++                      return -EBUSY;
++              err = eexp_hw_probe(dev,ioaddr);
++              release_region(ioaddr, EEXP_IO_EXTENT);
++              return err;
++      } else if (ioaddr)
+               return -ENXIO;
+       for (port=&ports[0] ; *port ; port++ )
+       {
+               unsigned short sum = 0;
+               int i;
++              if (!request_region(*port, EEXP_IO_EXTENT, "EtherExpress"))
++                      continue;
+               for ( i=0 ; i<4 ; i++ )
+               {
+                       unsigned short t;
+                       t = inb(*port + ID_PORT);
+                       sum |= (t>>4) << ((t & 0x03)<<2);
+               }
+-              if (sum==0xbaba && !eexp_hw_probe(dev,*port))
++              if (sum==0xbaba && !eexp_hw_probe(dev,*port)) {
++                      release_region(*port, EEXP_IO_EXTENT);
+                       return 0;
++              }
++              release_region(*port, EEXP_IO_EXTENT);
++              dev->irq = dev_irq;
+       }
+       return -ENODEV;
+ }
++struct net_device * __init express_probe(int unit)
++{
++      struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_express_probe(dev);
++      if (!err) {
++              err = register_netdev(dev);
++              if (!err)
++                      return dev;
++      }
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ /*
+  * open and initialize the adapter, ready for use
+  */
+@@ -1058,7 +1090,7 @@ static int __init eexp_hw_probe(struct n
+       unsigned int memory_size;
+       int i;
+       unsigned short xsum = 0;
+-      struct net_local *lp;
++      struct net_local *lp = dev->priv;
+       printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr);
+@@ -1108,17 +1140,18 @@ static int __init eexp_hw_probe(struct n
+               buswidth = !((setupval & 0x400) >> 10);
+       }
+-      dev->priv = lp = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-      if (!dev->priv)
+-              return -ENOMEM;
+-
+-      memset(dev->priv, 0, sizeof(struct net_local));
++      memset(lp, 0, sizeof(struct net_local));
+       spin_lock_init(&lp->lock);
+       printk("(IRQ %d, %s connector, %d-bit bus", dev->irq, 
+              eexp_ifmap[dev->if_port], buswidth?8:16);
+  
++      if (!request_region(dev->base_addr + 0x300e, 1, "EtherExpress"))
++              return -EBUSY;
++
+       eexp_hw_set_interface(dev);
++ 
++      release_region(dev->base_addr + 0x300e, 1);
+   
+       /* Find out how much RAM we have on the card */
+       outw(0, dev->base_addr + WRITE_PTR);
+@@ -1156,7 +1189,6 @@ static int __init eexp_hw_probe(struct n
+               break;
+       default:
+               printk(") bad memory size (%dk).\n", memory_size);
+-              kfree(dev->priv);
+               return -ENODEV;
+               break;
+       }
+@@ -1171,7 +1203,6 @@ static int __init eexp_hw_probe(struct n
+       dev->set_multicast_list = &eexp_set_multicast;
+       dev->tx_timeout = eexp_timeout;
+       dev->watchdog_timeo = 2*HZ;
+-      ether_setup(dev);
+       return 0;
+ }
+@@ -1654,7 +1685,7 @@ eexp_set_multicast(struct net_device *de
+ #define EEXP_MAX_CARDS     4    /* max number of cards to support */
+-static struct net_device dev_eexp[EEXP_MAX_CARDS];
++static struct net_device *dev_eexp[EEXP_MAX_CARDS];
+ static int irq[EEXP_MAX_CARDS];
+ static int io[EEXP_MAX_CARDS];
+@@ -1671,25 +1702,30 @@ MODULE_LICENSE("GPL");
+  */
+ int init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_eexp[this_dev];
++              dev = alloc_etherdev(sizeof(struct net_local));
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+-              dev->init = express_probe;
+               if (io[this_dev] == 0) {
+-                      if (this_dev) break;
++                      if (this_dev)
++                              break;
+                       printk(KERN_NOTICE "eexpress.c: Module autoprobe not recommended, give io=xx.\n");
+               }
+-              if (register_netdev(dev) != 0) {
+-                      printk(KERN_WARNING "eexpress.c: Failed to register card at 0x%x.\n", io[this_dev]);
+-                      if (found != 0) return 0;
+-                      return -ENXIO;
++              if (do_express_probe(dev) == 0 && register_netdev(dev) == 0) {
++                      dev_eexp[this_dev] = dev;
++                      found++;
++                      continue;
+               }
+-              found++;
++              printk(KERN_WARNING "eexpress.c: Failed to register card at 0x%x.\n", io[this_dev]);
++              free_netdev(dev);
++              break;
+       }
+-      return 0;
++      if (found)
++              return 0;
++      return -ENXIO;
+ }
+ void cleanup_module(void)
+@@ -1697,11 +1733,10 @@ void cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_eexp[this_dev];
+-              if (dev->priv != NULL) {
++              struct net_device *dev = dev_eexp[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(dev->priv);
+-                      dev->priv = NULL;
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/eql.c      2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/eql.c       2003-12-28 23:21:01.000000000 -0800
+@@ -600,7 +600,7 @@ static int __init eql_init_module(void)
+       err = register_netdev(dev_eql);
+       if (err) 
+-              kfree(dev_eql);
++              free_netdev(dev_eql);
+       return err;
+ }
+--- linux-2.6.0/drivers/net/es3210.c   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/es3210.c    2003-12-28 23:21:01.000000000 -0800
+@@ -62,7 +62,6 @@ static const char version[] =
+ #include "8390.h"
+-int es_probe(struct net_device *dev);
+ static int es_probe1(struct net_device *dev, int ioaddr);
+ static int es_open(struct net_device *dev);
+@@ -125,9 +124,11 @@ static unsigned char hi_irq_map[] __init
+  *    PROM for a match against the Racal-Interlan assigned value.
+  */
+-int __init es_probe(struct net_device *dev)
++static int __init do_es_probe(struct net_device *dev)
+ {
+       unsigned short ioaddr = dev->base_addr;
++      int irq = dev->irq;
++      int mem_start = dev->mem_start;
+       SET_MODULE_OWNER(dev);
+@@ -144,13 +145,47 @@ int __init es_probe(struct net_device *d
+       }
+       /* EISA spec allows for up to 16 slots, but 8 is typical. */
+-      for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000)
++      for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
+               if (es_probe1(dev, ioaddr) == 0)
+                       return 0;
++              dev->irq = irq;
++              dev->mem_start = mem_start;
++      }
+       return -ENODEV;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, ES_IO_EXTENT);
++}
++
++struct net_device * __init es_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_es_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ static int __init es_probe1(struct net_device *dev, int ioaddr)
+ {
+       int i, retval;
+@@ -240,13 +275,6 @@ static int __init es_probe1(struct net_d
+       printk("mem %#lx-%#lx\n", dev->mem_start, dev->mem_end-1);
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev)) {
+-              printk (" unable to allocate memory for dev->priv.\n");
+-              retval = -ENOMEM;
+-              goto out1;
+-      }
+-
+ #if ES_DEBUG & ES_D_PROBE
+       if (inb(ioaddr + ES_CFG5))
+               printk("es3210: Warning - DMA channel enabled, but not used here.\n");
+@@ -376,7 +404,7 @@ static int es_close(struct net_device *d
+ #ifdef MODULE
+ #define MAX_ES_CARDS  4       /* Max number of ES3210 cards per module */
+ #define NAMELEN               8       /* # of chars for storing dev->name */
+-static struct net_device dev_es3210[MAX_ES_CARDS];
++static struct net_device *dev_es3210[MAX_ES_CARDS];
+ static int io[MAX_ES_CARDS];
+ static int irq[MAX_ES_CARDS];
+ static int mem[MAX_ES_CARDS];
+@@ -393,26 +421,32 @@ MODULE_LICENSE("GPL");
+ int
+ init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_es3210[this_dev];
++              if (io[this_dev] == 0 && this_dev != 0)
++                      break;
++              dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+-              dev->mem_start = mem[this_dev];         /* Currently ignored by driver */
+-              dev->init = es_probe;
+-              /* Default is to only install one card. */
+-              if (io[this_dev] == 0 && this_dev != 0) break;
+-              if (register_netdev(dev) != 0) {
+-                      printk(KERN_WARNING "es3210.c: No es3210 card found (i/o = 0x%x).\n", io[this_dev]);
+-                      if (found != 0) {       /* Got at least one. */
+-                              return 0;
++              dev->mem_start = mem[this_dev];
++              if (do_es_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_es3210[found++] = dev;
++                              continue;
+                       }
+-                      return -ENXIO;
++                      cleanup_card(dev);
+               }
+-              found++;
++              free_netdev(dev);
++              printk(KERN_WARNING "es3210.c: No es3210 card found (i/o = 0x%x).\n", io[this_dev]);
++              break;
+       }
+-      return 0;
++      if (found)
++              return 0;
++      return -ENXIO;
+ }
+ void
+@@ -421,13 +455,11 @@ cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_es3210[this_dev];
+-              if (dev->priv != NULL) {
+-                      void *priv = dev->priv;
+-                      free_irq(dev->irq, dev);
+-                      release_region(dev->base_addr, ES_IO_EXTENT);
++              struct net_device *dev = dev_es3210[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(priv);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/eth16i.c   2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/eth16i.c    2003-12-28 23:21:01.000000000 -0800
+@@ -369,7 +369,6 @@ static unsigned int eth32i_irqmap[] __in
+ #define NUM_OF_EISA_IRQS   8
+ static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
+-static unsigned int boot = 1;
+ /* Use 0 for production, 1 for verification, >2 for debug */
+ #ifndef ETH16I_DEBUG
+@@ -395,8 +394,6 @@ struct eth16i_local {
+ /* Function prototypes */
+-extern int     eth16i_probe(struct net_device *dev);
+-
+ static int     eth16i_probe1(struct net_device *dev, int ioaddr);
+ static int     eth16i_check_signature(int ioaddr);
+ static int     eth16i_probe_port(int ioaddr);
+@@ -418,7 +415,7 @@ static void    eth16i_timeout(struct net
+ static void    eth16i_skip_packet(struct net_device *dev);
+ static void    eth16i_multicast(struct net_device *dev); 
+ static void    eth16i_select_regbank(unsigned char regbank, int ioaddr);
+-static void    eth16i_initialize(struct net_device *dev);
++static void    eth16i_initialize(struct net_device *dev, int boot);
+ #if 0
+ static int     eth16i_set_irq(struct net_device *dev);
+@@ -432,7 +429,7 @@ static struct net_device_stats *eth16i_g
+ static char cardname[] __initdata = "ICL EtherTeam 16i/32";
+-int __init eth16i_probe(struct net_device *dev)
++static int __init do_eth16i_probe(struct net_device *dev)
+ {
+       int i;
+       int ioaddr;
+@@ -461,14 +458,38 @@ int __init eth16i_probe(struct net_devic
+       return -ENODEV;
+ }
++struct net_device * __init eth16i_probe(int unit)
++{
++      struct net_device *dev = alloc_etherdev(sizeof(struct eth16i_local));
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_eth16i_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, ETH16I_IO_EXTENT);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
+ {
+-      struct eth16i_local *lp;
++      struct eth16i_local *lp = dev->priv;
+       static unsigned version_printed;
+       int retval;
+-      boot = 1;  /* To inform initilization that we are in boot probe */
+-
+       /* Let's grab the region */
+       if (!request_region(ioaddr, ETH16I_IO_EXTENT, dev->name))
+               return -EBUSY;
+@@ -531,22 +552,13 @@ static int __init eth16i_probe1(struct n
+       eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
+       outb(0x38, ioaddr + TRANSCEIVER_MODE_REG); 
+-      eth16i_initialize(dev);   /* Initialize rest of the chip's registers */
++      eth16i_initialize(dev, 1); /* Initialize rest of the chip's registers */
+       /* Now let's same some energy by shutting down the chip ;) */
+       BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
+       /* Initialize the device structure */
+-      if(dev->priv == NULL) {
+-              dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL);
+-              if(dev->priv == NULL) {
+-                      free_irq(dev->irq, dev);
+-                      retval = -ENOMEM;
+-                      goto out;
+-              }
+-      }
+-
+-      memset(dev->priv, 0, sizeof(struct eth16i_local));
++      memset(lp, 0, sizeof(struct eth16i_local));
+       dev->open               = eth16i_open;
+       dev->stop               = eth16i_close;
+       dev->hard_start_xmit    = eth16i_tx;
+@@ -554,15 +566,7 @@ static int __init eth16i_probe1(struct n
+       dev->set_multicast_list = eth16i_multicast;
+       dev->tx_timeout         = eth16i_timeout;
+       dev->watchdog_timeo     = TX_TIMEOUT;
+-
+-      lp = (struct eth16i_local *)dev->priv;
+       spin_lock_init(&lp->lock);
+-
+-      /* Fill in the fields of the device structure with ethernet values. */
+-      ether_setup(dev);
+-
+-      boot = 0;
+-
+       return 0;
+ out:
+       release_region(ioaddr, ETH16I_IO_EXTENT);
+@@ -570,7 +574,7 @@ out:
+ }
+-static void eth16i_initialize(struct net_device *dev)
++static void eth16i_initialize(struct net_device *dev, int boot)
+ {
+       int ioaddr = dev->base_addr;
+       int i, node_w = 0;
+@@ -953,7 +957,7 @@ static int eth16i_open(struct net_device
+       outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
+       /* Initialize the chip */
+-      eth16i_initialize(dev);  
++      eth16i_initialize(dev, 0);  
+       /* Set the transmit buffer size */
+       lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
+@@ -1401,7 +1405,7 @@ static ushort eth16i_parse_mediatype(con
+ #define MAX_ETH16I_CARDS 4  /* Max number of Eth16i cards per module */
+-static struct net_device dev_eth16i[MAX_ETH16I_CARDS];
++static struct net_device *dev_eth16i[MAX_ETH16I_CARDS];
+ static int io[MAX_ETH16I_CARDS];
+ #if 0
+ static int irq[MAX_ETH16I_CARDS];
+@@ -1431,14 +1435,14 @@ MODULE_PARM_DESC(debug, "eth16i debug le
+ int init_module(void)
+ {
+       int this_dev, found = 0;
++      struct net_device *dev;
++
++      for (this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
++              dev = alloc_etherdev(sizeof(struct eth16i_local));
++              if (!dev)
++                      break;
+-      for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++)
+-      {
+-              struct net_device *dev = &dev_eth16i[this_dev];
+-      
+-              dev->irq = 0; /* irq[this_dev]; */
+               dev->base_addr = io[this_dev];
+-              dev->init = eth16i_probe;
+               if(debug != -1)
+                       eth16i_debug = debug;
+@@ -1448,44 +1452,43 @@ int init_module(void)
+               dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]);
+-              if(io[this_dev] == 0)
+-              {
+-                      if(this_dev != 0) break; /* Only autoprobe 1st one */
++              if(io[this_dev] == 0) {
++                      if(this_dev != 0) /* Only autoprobe 1st one */
++                              break;
+                       printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n");
+               }
+-              if(register_netdev(dev) != 0)
+-              {
+-                      printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n",
+-                             io[this_dev]);
+-          
+-                      if(found != 0) return 0;
+-                      return -ENXIO;
++              if (do_eth16i_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_eth16i[found++] = dev;
++                              continue;
++                      }
++                      free_irq(dev->irq, dev);
++                      release_region(dev->base_addr, ETH16I_IO_EXTENT);
+               }
+-
+-              found++;
++              printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n",
++                     io[this_dev]);
++              free_netdev(dev);
++              break;
+       }
+-      return 0;
++      if (found)
++              return 0;
++      return -ENXIO;
+ }
+       
+ void cleanup_module(void)
+ {
+       int this_dev;
+-      for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++)
+-      {
+-              struct net_device* dev = &dev_eth16i[this_dev];
++      for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
++              struct net_device *dev = dev_eth16i[this_dev];
+               
+-              if(dev->priv != NULL)
+-              {
++              if(dev->priv) {
+                       unregister_netdev(dev);
+-                      kfree(dev->priv);
+-                      dev->priv = NULL;
+-                      
+                       free_irq(dev->irq, dev);
+                       release_region(dev->base_addr, ETH16I_IO_EXTENT);
+-                      
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/ethertap.c 2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/ethertap.c  2003-12-28 23:21:01.000000000 -0800
+@@ -72,8 +72,7 @@ static int  __init ethertap_probe(int un
+       struct net_device *dev;
+       int err = -ENOMEM;
+-      dev = alloc_netdev(sizeof(struct net_local), "tap%d",
+-                         ether_setup);
++      dev = alloc_etherdev(sizeof(struct net_local));
+       if (!dev)
+               goto out;
+--- linux-2.6.0/drivers/net/ewrk3.c    2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ewrk3.c     2003-12-28 23:21:01.000000000 -0800
+@@ -324,25 +324,14 @@ static int Read_EEPROM(u_long iobase, u_
+ static int Write_EEPROM(short data, u_long iobase, u_char eaddr);
+ static u_char get_hw_addr(struct net_device *dev, u_char * eeprom_image, char chipType);
+-static void isa_probe(struct net_device *dev, u_long iobase);
+-static void eisa_probe(struct net_device *dev, u_long iobase);
+-static struct net_device *alloc_device(struct net_device *dev, u_long iobase);
+-static int ewrk3_dev_index(char *s);
+-static struct net_device *insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *));
++static int ewrk3_probe1(struct net_device *dev, u_long iobase, int irq);
++static int isa_probe(struct net_device *dev, u_long iobase);
++static int eisa_probe(struct net_device *dev, u_long iobase);
+-
+-#ifdef MODULE
+-static int autoprobed = 1, loading_module = 1;
+-
+-#else
+-static u_char irq[] =
+-{5, 0, 10, 3, 11, 9, 15, 12};
+-static int autoprobed, loading_module;
+-
+-#endif                                /* MODULE */
++static u_char irq[MAX_NUM_EWRK3S+1] = {5, 0, 10, 3, 11, 9, 15, 12};
+ static char name[EWRK3_STRLEN + 1];
+-static int num_ewrk3s, num_eth;
++static int num_ewrks3s;
+ /*
+    ** Miscellaneous defines...
+@@ -352,38 +341,50 @@ static int num_ewrk3s, num_eth;
+     mdelay(1);\
+ }
+-int __init ewrk3_probe(struct net_device *dev)
++struct net_device * __init ewrk3_probe(int unit)
+ {
+-      int tmp = num_ewrk3s, status = -ENODEV;
+-      u_long iobase = dev->base_addr;
++      struct net_device *dev = alloc_etherdev(sizeof(struct ewrk3_private));
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
+       SET_MODULE_OWNER(dev);
+-      if ((iobase == 0) && loading_module) {
+-              printk("Autoprobing is not supported when loading a module based driver.\n");
+-              status = -EIO;
+-      } else {                /* First probe for the Ethernet */
+-              /* Address PROM pattern */
+-              isa_probe(dev, iobase);
+-              eisa_probe(dev, iobase);
+-
+-              if ((tmp == num_ewrk3s) && (iobase != 0) && loading_module) {
+-                      printk("%s: ewrk3_probe() cannot find device at 0x%04lx.\n", dev->name,
+-                             iobase);
+-              }
+-              /*
+-                 ** Walk the device list to check that at least one device
+-                 ** initialised OK
+-               */
+-              for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
++      err = ewrk3_probe1(dev, dev->base_addr, dev->irq);
++      if (err) 
++              goto out;
++      return dev;
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++      
++}
+-              if (dev->priv)
+-                      status = 0;
+-              if (iobase == 0)
+-                      autoprobed = 1;
+-      }
++static int __init ewrk3_probe1(struct net_device *dev, u_long iobase, int irq)
++{
++      int err;
+-      return status;
++      dev->base_addr = iobase;
++      dev->irq = irq;
++
++      /* Address PROM pattern */
++      err = isa_probe(dev, iobase);
++      if (err != 0) 
++              err = eisa_probe(dev, iobase);
++
++      if (err)
++              return err;
++
++      err = register_netdev(dev);
++      if (err)
++              release_region(dev->base_addr, EWRK3_TOTAL_SIZE);
++
++      return err;
+ }
+ static int __init 
+@@ -396,8 +397,8 @@ ewrk3_hw_init(struct net_device *dev, u_
+       u_char eeprom_image[EEPROM_MAX], chksum, eisa_cr = 0;
+       /*
+-         ** Stop the EWRK3. Enable the DBR ROM. Disable interrupts and remote boot.
+-         ** This also disables the EISA_ENABLE bit in the EISA Control Register.
++      ** Stop the EWRK3. Enable the DBR ROM. Disable interrupts and remote boot.
++      ** This also disables the EISA_ENABLE bit in the EISA Control Register.
+        */
+       if (iobase > 0x400)
+               eisa_cr = inb(EISA_CR);
+@@ -409,232 +410,210 @@ ewrk3_hw_init(struct net_device *dev, u_
+       icr &= 0x70;
+       outb(icr, EWRK3_ICR);   /* Disable all the IRQs */
+-      if (nicsr == (CSR_TXD | CSR_RXD)) {
++      if (nicsr == (CSR_TXD | CSR_RXD))
++              return -ENXIO;
+-              /* Check that the EEPROM is alive and well and not living on Pluto... */
+-              for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) {
+-                      union {
+-                              short val;
+-                              char c[2];
+-                      } tmp;
+-
+-                      tmp.val = (short) Read_EEPROM(iobase, (i >> 1));
+-                      eeprom_image[i] = tmp.c[0];
+-                      eeprom_image[i + 1] = tmp.c[1];
+-                      chksum += eeprom_image[i] + eeprom_image[i + 1];
+-              }
+-
+-              if (chksum != 0) {      /* Bad EEPROM Data! */
+-                      printk("%s: Device has a bad on-board EEPROM.\n", dev->name);
+-                      status = -ENXIO;
+-              } else {
+-                      EthwrkSignature(name, eeprom_image);
+-                      if (*name != '\0') {    /* found a EWRK3 device */
+-                              dev->base_addr = iobase;
+-
+-                              if (iobase > 0x400) {
+-                                      outb(eisa_cr, EISA_CR);         /* Rewrite the EISA CR */
+-                              }
+-                              lemac = eeprom_image[EEPROM_CHIPVER];
+-                              cmr = inb(EWRK3_CMR);
+-
+-                              if (((lemac == LeMAC) && ((cmr & CMR_NO_EEPROM) != CMR_NO_EEPROM)) ||
+-                              ((lemac == LeMAC2) && !(cmr & CMR_HS))) {
+-                                      printk("%s: %s at %#4lx", dev->name, name, iobase);
+-                                      hard_strapped = 1;
+-                              } else if ((iobase & 0x0fff) == EWRK3_EISA_IO_PORTS) {
+-                                      /* EISA slot address */
+-                                      printk("%s: %s at %#4lx (EISA slot %ld)",
+-                                             dev->name, name, iobase, ((iobase >> 12) & 0x0f));
+-                              } else {        /* ISA port address */
+-                                      printk("%s: %s at %#4lx", dev->name, name, iobase);
+-                              }
+-
+-                              if (!status) {
+-                                      printk(", h/w address ");
+-                                      if (lemac != LeMAC2)
+-                                              DevicePresent(iobase);  /* need after EWRK3_INIT */
+-                                      status = get_hw_addr(dev, eeprom_image, lemac);
+-                                      for (i = 0; i < ETH_ALEN - 1; i++) {    /* get the ethernet addr. */
+-                                              printk("%2.2x:", dev->dev_addr[i]);
+-                                      }
+-                                      printk("%2.2x,\n", dev->dev_addr[i]);
+-                                      if (status) {
+-                                              printk("      which has an EEPROM CRC error.\n");
+-                                              status = -ENXIO;
+-                                      } else {
+-                                              if (lemac == LeMAC2) {  /* Special LeMAC2 CMR things */
+-                                                      cmr &= ~(CMR_RA | CMR_WB | CMR_LINK | CMR_POLARITY | CMR_0WS);
+-                                                      if (eeprom_image[EEPROM_MISC0] & READ_AHEAD)
+-                                                              cmr |= CMR_RA;
+-                                                      if (eeprom_image[EEPROM_MISC0] & WRITE_BEHIND)
+-                                                              cmr |= CMR_WB;
+-                                                      if (eeprom_image[EEPROM_NETMAN0] & NETMAN_POL)
+-                                                              cmr |= CMR_POLARITY;
+-                                                      if (eeprom_image[EEPROM_NETMAN0] & NETMAN_LINK)
+-                                                              cmr |= CMR_LINK;
+-                                                      if (eeprom_image[EEPROM_MISC0] & _0WS_ENA)
+-                                                              cmr |= CMR_0WS;
+-                                              }
+-                                              if (eeprom_image[EEPROM_SETUP] & SETUP_DRAM)
+-                                                      cmr |= CMR_DRAM;
+-                                              outb(cmr, EWRK3_CMR);
+-
+-                                              cr = inb(EWRK3_CR);     /* Set up the Control Register */
+-                                              cr |= eeprom_image[EEPROM_SETUP] & SETUP_APD;
+-                                              if (cr & SETUP_APD)
+-                                                      cr |= eeprom_image[EEPROM_SETUP] & SETUP_PS;
+-                                              cr |= eeprom_image[EEPROM_MISC0] & FAST_BUS;
+-                                              cr |= eeprom_image[EEPROM_MISC0] & ENA_16;
+-                                              outb(cr, EWRK3_CR);
++      /* Check that the EEPROM is alive and well and not living on Pluto... */
++      for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) {
++              union {
++                      short val;
++                      char c[2];
++              } tmp;
++
++              tmp.val = (short) Read_EEPROM(iobase, (i >> 1));
++              eeprom_image[i] = tmp.c[0];
++              eeprom_image[i + 1] = tmp.c[1];
++              chksum += eeprom_image[i] + eeprom_image[i + 1];
++      }
++
++      if (chksum != 0) {      /* Bad EEPROM Data! */
++              printk("%s: Device has a bad on-board EEPROM.\n", dev->name);
++              return -ENXIO;
++      }
++      
++      EthwrkSignature(name, eeprom_image);
++      if (*name == '\0') 
++              return -ENXIO;
++
++      dev->base_addr = iobase;
++                              
++      if (iobase > 0x400) {
++              outb(eisa_cr, EISA_CR);         /* Rewrite the EISA CR */
++      }
++      lemac = eeprom_image[EEPROM_CHIPVER];
++      cmr = inb(EWRK3_CMR);
++      
++      if (((lemac == LeMAC) && ((cmr & CMR_NO_EEPROM) != CMR_NO_EEPROM)) ||
++          ((lemac == LeMAC2) && !(cmr & CMR_HS))) {
++              printk("%s: %s at %#4lx", dev->name, name, iobase);
++              hard_strapped = 1;
++      } else if ((iobase & 0x0fff) == EWRK3_EISA_IO_PORTS) {
++              /* EISA slot address */
++              printk("%s: %s at %#4lx (EISA slot %ld)",
++                     dev->name, name, iobase, ((iobase >> 12) & 0x0f));
++      } else {        /* ISA port address */
++              printk("%s: %s at %#4lx", dev->name, name, iobase);
++      }
++
++      printk(", h/w address ");
++      if (lemac != LeMAC2)
++              DevicePresent(iobase);  /* need after EWRK3_INIT */
++      status = get_hw_addr(dev, eeprom_image, lemac);
++      for (i = 0; i < ETH_ALEN - 1; i++) {    /* get the ethernet addr. */
++              printk("%2.2x:", dev->dev_addr[i]);
++      }
++      printk("%2.2x,\n", dev->dev_addr[i]);
++      
++      if (status) {
++              printk("      which has an EEPROM CRC error.\n");
++              return -ENXIO;
++      }
++
++      if (lemac == LeMAC2) {  /* Special LeMAC2 CMR things */
++              cmr &= ~(CMR_RA | CMR_WB | CMR_LINK | CMR_POLARITY | CMR_0WS);
++              if (eeprom_image[EEPROM_MISC0] & READ_AHEAD)
++                      cmr |= CMR_RA;
++              if (eeprom_image[EEPROM_MISC0] & WRITE_BEHIND)
++                      cmr |= CMR_WB;
++              if (eeprom_image[EEPROM_NETMAN0] & NETMAN_POL)
++                      cmr |= CMR_POLARITY;
++              if (eeprom_image[EEPROM_NETMAN0] & NETMAN_LINK)
++                      cmr |= CMR_LINK;
++              if (eeprom_image[EEPROM_MISC0] & _0WS_ENA)
++                      cmr |= CMR_0WS;
++      }
++      if (eeprom_image[EEPROM_SETUP] & SETUP_DRAM)
++              cmr |= CMR_DRAM;
++      outb(cmr, EWRK3_CMR);
++      
++      cr = inb(EWRK3_CR);     /* Set up the Control Register */
++      cr |= eeprom_image[EEPROM_SETUP] & SETUP_APD;
++      if (cr & SETUP_APD)
++              cr |= eeprom_image[EEPROM_SETUP] & SETUP_PS;
++      cr |= eeprom_image[EEPROM_MISC0] & FAST_BUS;
++      cr |= eeprom_image[EEPROM_MISC0] & ENA_16;
++      outb(cr, EWRK3_CR);
+-                                              /*
+-                                                 ** Determine the base address and window length for the EWRK3
+-                                                 ** RAM from the memory base register.
+-                                               */
+-                                              mem_start = inb(EWRK3_MBR);
+-                                              shmem_length = 0;
+-                                              if (mem_start != 0) {
+-                                                      if ((mem_start >= 0x0a) && (mem_start <= 0x0f)) {
+-                                                              mem_start *= SHMEM_64K;
+-                                                              shmem_length = SHMEM_64K;
+-                                                      } else if ((mem_start >= 0x14) && (mem_start <= 0x1f)) {
+-                                                              mem_start *= SHMEM_32K;
+-                                                              shmem_length = SHMEM_32K;
+-                                                      } else if ((mem_start >= 0x40) && (mem_start <= 0xff)) {
+-                                                              mem_start = mem_start * SHMEM_2K + 0x80000;
+-                                                              shmem_length = SHMEM_2K;
+-                                                      } else {
+-                                                              status = -ENXIO;
+-                                                      }
+-                                              }
+-                                              /*
+-                                                 ** See the top of this source code for comments about
+-                                                 ** uncommenting this line.
+-                                               */
++      /*
++      ** Determine the base address and window length for the EWRK3
++      ** RAM from the memory base register.
++      */
++      mem_start = inb(EWRK3_MBR);
++      shmem_length = 0;
++      if (mem_start != 0) {
++              if ((mem_start >= 0x0a) && (mem_start <= 0x0f)) {
++                      mem_start *= SHMEM_64K;
++                      shmem_length = SHMEM_64K;
++              } else if ((mem_start >= 0x14) && (mem_start <= 0x1f)) {
++                      mem_start *= SHMEM_32K;
++                      shmem_length = SHMEM_32K;
++              } else if ((mem_start >= 0x40) && (mem_start <= 0xff)) {
++                      mem_start = mem_start * SHMEM_2K + 0x80000;
++                      shmem_length = SHMEM_2K;
++              } else {
++                      return -ENXIO;
++              }
++      }
++      /*
++      ** See the top of this source code for comments about
++      ** uncommenting this line.
++      */
+ /*          FORCE_2K_MODE; */
++      
++      if (hard_strapped) {
++              printk("      is hard strapped.\n");
++      } else if (mem_start) {
++              printk("      has a %dk RAM window", (int) (shmem_length >> 10));
++              printk(" at 0x%.5lx", mem_start);
++      } else {
++              printk("      is in I/O only mode");
++      }
+-                                              if (!status) {
+-                                                      if (hard_strapped) {
+-                                                              printk("      is hard strapped.\n");
+-                                                      } else if (mem_start) {
+-                                                              printk("      has a %dk RAM window", (int) (shmem_length >> 10));
+-                                                              printk(" at 0x%.5lx", mem_start);
+-                                                      } else {
+-                                                              printk("      is in I/O only mode");
+-                                                      }
+-
+-                                                      /* private area & initialise */
+-                                                      dev->priv = (void *) kmalloc(sizeof(struct ewrk3_private),
+-                                                           GFP_KERNEL);
+-                                                      if (dev->priv == NULL) {
+-                                                              return -ENOMEM;
+-                                                      }
+-                                                      lp = (struct ewrk3_private *) dev->priv;
+-                                                      memset(dev->priv, 0, sizeof(struct ewrk3_private));
+-                                                      lp->shmem_base = mem_start;
+-                                                      lp->shmem_length = shmem_length;
+-                                                      lp->lemac = lemac;
+-                                                      lp->hard_strapped = hard_strapped;
+-                                                      lp->led_mask = CR_LED;
+-                                                      spin_lock_init(&lp->hw_lock);
+-
+-                                                      lp->mPage = 64;
+-                                                      if (cmr & CMR_DRAM)
+-                                                              lp->mPage <<= 1;        /* 2 DRAMS on module */
+-
+-                                                      sprintf(lp->adapter_name, "%s (%s)", name, dev->name);
+-                                                      request_region(iobase, EWRK3_TOTAL_SIZE, lp->adapter_name);
+-
+-                                                      lp->irq_mask = ICR_TNEM | ICR_TXDM | ICR_RNEM | ICR_RXDM;
+-
+-                                                      if (!hard_strapped) {
+-                                                              /*
+-                                                                 ** Enable EWRK3 board interrupts for autoprobing
+-                                                               */
+-                                                              icr |= ICR_IE;  /* Enable interrupts */
+-                                                              outb(icr, EWRK3_ICR);
+-
+-                                                              /* The DMA channel may be passed in on this parameter. */
+-                                                              dev->dma = 0;
+-
+-                                                              /* To auto-IRQ we enable the initialization-done and DMA err,
+-                                                                 interrupts. For now we will always get a DMA error. */
+-                                                              if (dev->irq < 2) {
++      lp = (struct ewrk3_private *) dev->priv;
++      lp->shmem_base = mem_start;
++      lp->shmem_length = shmem_length;
++      lp->lemac = lemac;
++      lp->hard_strapped = hard_strapped;
++      lp->led_mask = CR_LED;
++      spin_lock_init(&lp->hw_lock);
++      
++      lp->mPage = 64;
++      if (cmr & CMR_DRAM)
++              lp->mPage <<= 1;        /* 2 DRAMS on module */
++      
++      sprintf(lp->adapter_name, "%s (%s)", name, dev->name);
++      
++      lp->irq_mask = ICR_TNEM | ICR_TXDM | ICR_RNEM | ICR_RXDM;
++      
++      if (!hard_strapped) {
++              /*
++              ** Enable EWRK3 board interrupts for autoprobing
++              */
++              icr |= ICR_IE;  /* Enable interrupts */
++              outb(icr, EWRK3_ICR);
++              
++              /* The DMA channel may be passed in on this parameter. */
++              dev->dma = 0;
++              
++              /* To auto-IRQ we enable the initialization-done and DMA err,
++                 interrupts. For now we will always get a DMA error. */
++              if (dev->irq < 2) {
+ #ifndef MODULE
+-                                                                      u_char irqnum;
+-                                                                      unsigned long irq_mask;
++                      u_char irqnum;
++                      unsigned long irq_mask;
+                       
+-                                                                      irq_mask = probe_irq_on();
+-
+-                                                                      /*
+-                                                                         ** Trigger a TNE interrupt.
+-                                                                       */
+-                                                                      icr |= ICR_TNEM;
+-                                                                      outb(1, EWRK3_TDQ);     /* Write to the TX done queue */
+-                                                                      outb(icr, EWRK3_ICR);   /* Unmask the TXD interrupt */
+-
+-                                                                      irqnum = irq[((icr & IRQ_SEL) >> 4)];
+-
+-                                                                      mdelay(20);
+-                                                                      dev->irq = probe_irq_off(irq_mask);
+-                                                                      if ((dev->irq) && (irqnum == dev->irq)) {
+-                                                                              printk(" and uses IRQ%d.\n", dev->irq);
+-                                                                      } else {
+-                                                                              if (!dev->irq) {
+-                                                                                      printk(" and failed to detect IRQ line.\n");
+-                                                                              } else if ((irqnum == 1) && (lemac == LeMAC2)) {
+-                                                                                      printk(" and an illegal IRQ line detected.\n");
+-                                                                              } else {
+-                                                                                      printk(", but incorrect IRQ line detected.\n");
+-                                                                              }
+-                                                                              status = -ENXIO;
+-                                                                      }
+-
+-                                                                      DISABLE_IRQs;   /* Mask all interrupts */
+-
+-#endif                                /* MODULE */
+-                                                              } else {
+-                                                                      printk(" and requires IRQ%d.\n", dev->irq);
+-                                                              }
+-                                                      }
+-                                                      if (status)
+-                                                              release_region(iobase, EWRK3_TOTAL_SIZE);
+-                                              } else {
+-                                                      status = -ENXIO;
+-                                              }
+-                                      }
+-                              }
++                      irq_mask = probe_irq_on();
++                      
++                      /*
++                      ** Trigger a TNE interrupt.
++                      */
++                      icr |= ICR_TNEM;
++                      outb(1, EWRK3_TDQ);     /* Write to the TX done queue */
++                      outb(icr, EWRK3_ICR);   /* Unmask the TXD interrupt */
++                      
++                      irqnum = irq[((icr & IRQ_SEL) >> 4)];
++                      
++                      mdelay(20);
++                      dev->irq = probe_irq_off(irq_mask);
++                      if ((dev->irq) && (irqnum == dev->irq)) {
++                              printk(" and uses IRQ%d.\n", dev->irq);
+                       } else {
+-                              status = -ENXIO;
+-                      }
+-              }
+-
+-              if (!status) {
+-                      if (ewrk3_debug > 1) {
+-                              printk(version);
++                              if (!dev->irq) {
++                                      printk(" and failed to detect IRQ line.\n");
++                              } else if ((irqnum == 1) && (lemac == LeMAC2)) {
++                                      printk(" and an illegal IRQ line detected.\n");
++                              } else {
++                                      printk(", but incorrect IRQ line detected.\n");
++                              }
++                              return -ENXIO;
+                       }
+-                      /* The EWRK3-specific entries in the device structure. */
+-                      dev->open = ewrk3_open;
+-                      dev->hard_start_xmit = ewrk3_queue_pkt;
+-                      dev->stop = ewrk3_close;
+-                      dev->get_stats = ewrk3_get_stats;
+-                      dev->set_multicast_list = set_multicast_list;
+-                      dev->do_ioctl = ewrk3_ioctl;
+-                      dev->tx_timeout = ewrk3_timeout;
+-                      dev->watchdog_timeo = QUEUE_PKT_TIMEOUT;
+-                      dev->mem_start = 0;
++                      DISABLE_IRQs;   /* Mask all interrupts */
+-                      /* Fill in the generic field of the device structure. */
+-                      ether_setup(dev);
++#endif                                /* MODULE */
++              } else {
++                      printk(" and requires IRQ%d.\n", dev->irq);
+               }
+-      } else {
+-              status = -ENXIO;
+       }
+-      return status;
++
++      if (ewrk3_debug > 1) {
++              printk(version);
++      }
++      /* The EWRK3-specific entries in the device structure. */
++      dev->open = ewrk3_open;
++      dev->hard_start_xmit = ewrk3_queue_pkt;
++      dev->stop = ewrk3_close;
++      dev->get_stats = ewrk3_get_stats;
++      dev->set_multicast_list = set_multicast_list;
++      dev->do_ioctl = ewrk3_ioctl;
++      dev->tx_timeout = ewrk3_timeout;
++      dev->watchdog_timeo = QUEUE_PKT_TIMEOUT;
++      
++      dev->mem_start = 0;
++
++      return 0;
+ }
\f
+@@ -1269,15 +1248,15 @@ static void SetMulticastFilter(struct ne
+ /*
+    ** ISA bus I/O device probe
+  */
+-static void __init isa_probe(struct net_device *dev, u_long ioaddr)
++static int __init isa_probe(struct net_device *dev, u_long ioaddr)
+ {
+-      int i = num_ewrk3s, maxSlots;
++      int i = num_ewrks3s, maxSlots;
++      int ret = -ENODEV;
++
+       u_long iobase;
+-      if (!ioaddr && autoprobed)
+-              return;         /* Been here before ! */
+       if (ioaddr >= 0x400)
+-              return;         /* Not ISA */
++              goto out;
+       if (ioaddr == 0) {      /* Autoprobing */
+               iobase = EWRK3_IO_BASE;         /* Get the first slot address */
+@@ -1287,38 +1266,37 @@ static void __init isa_probe(struct net_
+               maxSlots = i + 1;
+       }
+-      for (; (i < maxSlots) && (dev != NULL); iobase += EWRK3_IOP_INC, i++) {
+-              if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {
++      for (; (i < maxSlots) && (dev != NULL);
++           iobase += EWRK3_IOP_INC, i++)
++      {
++              if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name)) {
+                       if (DevicePresent(iobase) == 0) {
+-                              if ((dev = alloc_device(dev, iobase)) != NULL) {
+-                                      if (ewrk3_hw_init(dev, iobase) == 0) {
+-                                              num_ewrk3s++;
+-                                      }
+-                                      num_eth++;
+-                              }
++                              int irq = dev->irq;
++                              ret = ewrk3_hw_init(dev, iobase);
++                              if (!ret)
++                                      break;
++                              dev->irq = irq;
+                       }
+-              } else if (autoprobed) {
+-                      printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
++                      release_region(iobase, EWRK3_TOTAL_SIZE);
+               }
+       }
++ out:
+-      return;
++      return ret;
+ }
+ /*
+    ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
+    ** the motherboard.
+  */
+-static void __init eisa_probe(struct net_device *dev, u_long ioaddr)
++static int __init eisa_probe(struct net_device *dev, u_long ioaddr)
+ {
+       int i, maxSlots;
+       u_long iobase;
+-      char name[EWRK3_STRLEN];
++      int ret = -ENODEV;
+-      if (!ioaddr && autoprobed)
+-              return;         /* Been here before ! */
+       if (ioaddr < 0x1000)
+-              return;         /* Not EISA */
++              goto out;
+       if (ioaddr == 0) {      /* Autoprobing */
+               iobase = EISA_SLOT_INC;         /* Get the first slot address */
+@@ -1332,114 +1310,22 @@ static void __init eisa_probe(struct net
+       for (i = 1; (i < maxSlots) && (dev != NULL); i++, iobase += EISA_SLOT_INC) {
+               if (EISA_signature(name, EISA_ID) == 0) {
+-                      if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {
+-                              if (DevicePresent(iobase) == 0) {
+-                                      if ((dev = alloc_device(dev, iobase)) != NULL) {
+-                                              if (ewrk3_hw_init(dev, iobase) == 0) {
+-                                                      num_ewrk3s++;
+-                                              }
+-                                              num_eth++;
+-                                      }
+-                              }
+-                      } else if (autoprobed) {
+-                              printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
++                      if (request_region(iobase, EWRK3_TOTAL_SIZE, dev->name) &&
++                          DevicePresent(iobase) == 0) {
++                              int irq = dev->irq;
++                              ret = ewrk3_hw_init(dev, iobase);
++                              if (!ret)
++                                      break;
++                              dev->irq = irq;
+                       }
++                      release_region(iobase, EWRK3_TOTAL_SIZE);
+               }
+       }
+-      return;
++ out:
++      return ret;
+ }
+-/*
+-   ** Search the entire 'eth' device list for a fixed probe. If a match isn't
+-   ** found then check for an autoprobe or unused device location. If they
+-   ** are not available then insert a new device structure at the end of
+-   ** the current list.
+- */
+-static struct net_device * __init  alloc_device(struct net_device *dev, u_long iobase)
+-{
+-      struct net_device *adev = NULL;
+-      int fixed = 0, new_dev = 0;
+-
+-      num_eth = ewrk3_dev_index(dev->name);
+-      if (loading_module)
+-              return dev;
+-
+-      while (1) {
+-              if (((dev->base_addr == EWRK3_NDA) || (dev->base_addr == 0)) && !adev) {
+-                      adev = dev;
+-              } else if ((dev->priv == NULL) && (dev->base_addr == iobase)) {
+-                      fixed = 1;
+-              } else {
+-                      if (dev->next == NULL) {
+-                              new_dev = 1;
+-                      } else if (strncmp(dev->next->name, "eth", 3) != 0) {
+-                              new_dev = 1;
+-                      }
+-              }
+-              if ((dev->next == NULL) || new_dev || fixed)
+-                      break;
+-              dev = dev->next;
+-              num_eth++;
+-      }
+-      if (adev && !fixed) {
+-              dev = adev;
+-              num_eth = ewrk3_dev_index(dev->name);
+-              new_dev = 0;
+-      }
+-      if (((dev->next == NULL) &&
+-           ((dev->base_addr != EWRK3_NDA) && (dev->base_addr != 0)) && !fixed) ||
+-          new_dev) {
+-              num_eth++;      /* New device */
+-              dev = insert_device(dev, iobase, ewrk3_probe);
+-      }
+-      return dev;
+-}
+-
+-/*
+-   ** If at end of eth device list and can't use current entry, malloc
+-   ** one up. If memory could not be allocated, print an error message.
+- */
+-static struct net_device * __init
+-insert_device(struct net_device *dev, u_long iobase, int (*init) (struct net_device *))
+-{
+-      struct net_device *new;
+-
+-      new = (struct net_device *) kmalloc(sizeof(struct net_device) + 8, GFP_KERNEL);
+-      if (new == NULL) {
+-              printk("eth%d: Device not initialised, insufficient memory\n", num_eth);
+-              return NULL;
+-      } else {
+-              new->next = dev->next;
+-              dev->next = new;
+-              dev = dev->next;        /* point to the new device */
+-              if (num_eth > 9999) {
+-                      sprintf(dev->name, "eth????");  /* New device name */
+-              } else {
+-                      sprintf(dev->name, "eth%d", num_eth);   /* New device name */
+-              }
+-              dev->base_addr = iobase;        /* assign the io address */
+-              dev->init = init;       /* initialisation routine */
+-      }
+-
+-      return dev;
+-}
+-
+-static int __init 
+-ewrk3_dev_index(char *s)
+-{
+-      int i = 0, j = 0;
+-
+-      for (; *s; s++) {
+-              if (isdigit(*s)) {
+-                      j = 1;
+-                      i = (i * 10) + (*s - '0');
+-              } else if (j)
+-                      break;
+-      }
+-
+-      return i;
+-}
+ /*
+    ** Read the EWRK3 EEPROM using this routine
+@@ -2074,8 +1960,7 @@ static int ewrk3_ioctl(struct net_device
+ #ifdef MODULE
+ static struct net_device *ewrk3_devs[MAX_NUM_EWRK3S];
+ static int ndevs;
+-static int io[MAX_NUM_EWRK3S+1] = { 0x300, 0, };      /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
+-static int irq[MAX_NUM_EWRK3S+1] = { 5, 0, };         /* or use the insmod io= irq= options           */
++static int io[MAX_NUM_EWRK3S+1] = { 0x300, 0, };
+ /* '21' below should really be 'MAX_NUM_EWRK3S' */
+ MODULE_PARM(io, "0-21i");
+@@ -2083,50 +1968,39 @@ MODULE_PARM(irq, "0-21i");
+ MODULE_PARM_DESC(io, "EtherWORKS 3 I/O base address(es)");
+ MODULE_PARM_DESC(irq, "EtherWORKS 3 IRQ number(s)");
+-static void ewrk3_exit_module(void)
++static __exit void ewrk3_exit_module(void)
+ {
+       int i;
+       for( i=0; i<ndevs; i++ ) {
+               unregister_netdev(ewrk3_devs[i]);
+-              if (ewrk3_devs[i]->priv) {
+-                      kfree(ewrk3_devs[i]->priv);
+-                      ewrk3_devs[i]->priv = NULL;
+-              }
+-              ewrk3_devs[i]->irq = 0;
+-
+               release_region(ewrk3_devs[i]->base_addr, EWRK3_TOTAL_SIZE);
+               free_netdev(ewrk3_devs[i]);
+               ewrk3_devs[i] = NULL;
+       }
+ }
+-static int ewrk3_init_module(void)
++static __init int ewrk3_init_module(void)
+ {
+       int i=0;
+       while( io[i] && irq[i] ) {
+-              ewrk3_devs[ndevs] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+-              if (!ewrk3_devs[ndevs])
+-                      goto error; 
+-              memset(ewrk3_devs[ndevs], 0, sizeof(struct net_device));
+-              ewrk3_devs[ndevs]->base_addr = io[i];
+-              ewrk3_devs[ndevs]->irq = irq[i];
+-              ewrk3_devs[ndevs]->init = ewrk3_probe;
+-
+-              if (register_netdev(ewrk3_devs[ndevs]) == 0)
+-                      ndevs++;
+-              else
+-                      kfree(ewrk3_devs[ndevs]);
++              struct net_device *dev
++                      = alloc_etherdev(sizeof(struct ewrk3_private));
++
++              if (!dev)
++                      break;
++              if (ewrk3_probe1(dev, io[i], irq[i]) != 0) {
++                      free_netdev(dev);
++                      break;
++              }
++
++              ewrk3_devs[ndevs++] = dev;
+               i++;
+       }
+       return ndevs ? 0 : -EIO;
+-
+-error:
+-      ewrk3_exit_module();
+-      return -ENOMEM;
+ }
+--- linux-2.6.0/drivers/net/fc/iph5526.c       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/fc/iph5526.c        2003-12-28 23:21:01.000000000 -0800
+@@ -259,6 +259,7 @@ static int __init iph5526_probe_pci(stru
+ static int __init fcdev_init(struct net_device *dev)
+ {
++      SET_MODULE_OWNER(dev);
+       dev->open = iph5526_open;
+       dev->stop = iph5526_close;
+       dev->hard_start_xmit = iph5526_send_packet;
+@@ -2896,14 +2897,12 @@ static void update_EDB_indx(struct fc_in
+ static int iph5526_open(struct net_device *dev)
+ {
+       netif_start_queue(dev);
+-      MOD_INC_USE_COUNT;
+       return 0;
+ }
+ static int iph5526_close(struct net_device *dev)
+ {
+       netif_stop_queue(dev);
+-      MOD_DEC_USE_COUNT;
+       return 0;
+ }
+--- linux-2.6.0/drivers/net/fc/iph5526_scsi.h  2003-06-14 12:18:22.000000000 -0700
++++ 25/drivers/net/fc/iph5526_scsi.h   2003-12-28 23:21:01.000000000 -0800
+@@ -25,7 +25,7 @@ int iph5526_queuecommand(Scsi_Cmnd *Cmnd
+ int iph5526_release(struct Scsi_Host *host);
+ int iph5526_abort(Scsi_Cmnd *Cmnd);
+ const char *iph5526_info(struct Scsi_Host *host);
+-int iph5526_biosparam(Disk * disk, struct block_device *n, int ip[]);
++int iph5526_biosparam(struct Scsi_Disk * disk, struct block_device *n, int ip[]);
+ #endif
+--- linux-2.6.0/drivers/net/fmv18x.c   2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/fmv18x.c    2003-12-28 23:21:01.000000000 -0800
+@@ -57,7 +57,7 @@ static const char version[] =
+ #include <asm/io.h>
+ #include <asm/dma.h>
+-static int fmv18x_probe_list[] __initdata = {
++static unsigned fmv18x_probe_list[] __initdata = {
+       0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
+ };
+@@ -109,8 +109,6 @@ struct net_local {
+ /* Index to functions, as function prototypes. */
+-extern int fmv18x_probe(struct net_device *dev);
+-
+ static int fmv18x_probe1(struct net_device *dev, short ioaddr);
+ static int net_open(struct net_device *dev);
+ static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
+@@ -129,23 +127,50 @@ static void set_multicast_list(struct ne
+    (detachable devices only).
+    */
+-int __init fmv18x_probe(struct net_device *dev)
++static int io = 0x220;
++static int irq;
++
++struct net_device * __init fmv18x_probe(int unit)
+ {
+-      int i;
+-      int base_addr = dev->base_addr;
++      struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
++      unsigned *port;
++      int err = 0;
++
++      if (!dev)
++              return ERR_PTR(-ENODEV);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++              io = dev->base_addr;
++              irq = dev->irq;
++      }
+       SET_MODULE_OWNER(dev);
+-      if (base_addr > 0x1ff)          /* Check a single specified location. */
+-              return fmv18x_probe1(dev, base_addr);
+-      else if (base_addr != 0)        /* Don't probe at all. */
+-              return -ENXIO;
+-
+-      for (i = 0; fmv18x_probe_list[i]; i++)
+-              if (fmv18x_probe1(dev, fmv18x_probe_list[i]) == 0)
+-                      return 0;
+-
+-      return -ENODEV;
++      if (io > 0x1ff) {       /* Check a single specified location. */
++              err = fmv18x_probe1(dev, io);
++      } else if (io != 0) {   /* Don't probe at all. */
++              err = -ENXIO;
++      } else {
++              for (port = fmv18x_probe_list; *port; port++)
++                      if (fmv18x_probe1(dev, *port) == 0)
++                              break;
++              if (!*port)
++                      err = -ENODEV;
++      }
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, FMV18X_IO_EXTENT);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /* The Fujitsu datasheet suggests that the NIC be probed for by checking its
+@@ -160,7 +185,7 @@ static int __init fmv18x_probe1(struct n
+ {
+       char irqmap[4] = {3, 7, 10, 15};
+       char irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
+-      unsigned int i, irq, retval;
++      unsigned int i, retval;
+       struct net_local *lp;
+       /* Resetting the chip doesn't reset the ISA interface, so don't bother.
+@@ -170,6 +195,9 @@ static int __init fmv18x_probe1(struct n
+       if (!request_region(ioaddr, FMV18X_IO_EXTENT, dev->name))
+               return -EBUSY;
++      dev->irq = irq;
++      dev->base_addr = ioaddr;
++
+       /* Check I/O address configuration and Fujitsu vendor code */
+       if (inb(ioaddr+FJ_MACADDR  ) != 0x00
+       ||  inb(ioaddr+FJ_MACADDR+1) != 0x00
+@@ -181,9 +209,8 @@ static int __init fmv18x_probe1(struct n
+       /* Check PnP mode for FMV-183/184/183A/184A. */
+       /* This PnP routine is very poor. IO and IRQ should be known. */
+       if (inb(ioaddr + FJ_STATUS1) & 0x20) {
+-              irq = dev->irq;
+               for (i = 0; i < 8; i++) {
+-                      if (irq == irqmap_pnp[i])
++                      if (dev->irq == irqmap_pnp[i])
+                               break;
+               }
+               if (i == 8) {
+@@ -193,22 +220,19 @@ static int __init fmv18x_probe1(struct n
+       } else {
+               if (fmv18x_probe_list[inb(ioaddr + FJ_CONFIG0) & 0x07] != ioaddr)
+                       return -ENODEV;
+-              irq = irqmap[(inb(ioaddr + FJ_CONFIG0)>>6) & 0x03];
++              dev->irq = irqmap[(inb(ioaddr + FJ_CONFIG0)>>6) & 0x03];
+       }
+       /* Snarf the interrupt vector now. */
+-      retval = request_irq(irq, &net_interrupt, 0, dev->name, dev);
++      retval = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);
+       if (retval) {
+               printk ("FMV-18x found at %#3x, but it's unusable due to a conflict on"
+-                              "IRQ %d.\n", ioaddr, irq);
++                              "IRQ %d.\n", ioaddr, dev->irq);
+               goto out;
+       }
+       printk("%s: FMV-18x found at %#3x, IRQ %d, address ", dev->name,
+-                 ioaddr, irq);
+-
+-      dev->base_addr = ioaddr;
+-      dev->irq = irq;
++                 ioaddr, dev->irq);
+       for(i = 0; i < 6; i++) {
+               unsigned char val = inb(ioaddr + FJ_MACADDR + i);
+@@ -279,14 +303,10 @@ static int __init fmv18x_probe1(struct n
+       dev->watchdog_timeo     = HZ/10;
+       dev->get_stats          = net_get_stats;
+       dev->set_multicast_list = set_multicast_list;
+-
+-      /* Fill in the fields of 'dev' with ethernet-generic values. */
+-
+-      ether_setup(dev);
+       return 0;
+ out_irq:
+-      free_irq(irq, dev);
++      free_irq(dev->irq, dev);
+ out:
+       release_region(ioaddr, FMV18X_IO_EXTENT);
+       return retval;
+@@ -413,9 +433,7 @@ static int net_send_packet(struct sk_buf
+               lp->tx_queue_len = 0;
+               dev->trans_start = jiffies;
+               lp->tx_started = 1;
+-      } else if (lp->tx_queue_len < 4096 - 1502)
+-              /* Yes, there is room for one more packet. */
+-      else
++      } else if (lp->tx_queue_len >= 4096 - 1502) /* No room for a packet */
+               netif_stop_queue(dev);
+       dev_kfree_skb(skb);
+@@ -628,9 +646,7 @@ static void set_multicast_list(struct ne
+ }
+ #ifdef MODULE
+-static struct net_device dev_fmv18x;
+-static int io = 0x220;
+-static int irq;
++static struct net_device *dev_fmv18x;
+ MODULE_PARM(io, "i");
+ MODULE_PARM(irq, "i");
+@@ -644,26 +660,19 @@ int init_module(void)
+ {
+       if (io == 0)
+               printk("fmv18x: You should not use auto-probing with insmod!\n");
+-      dev_fmv18x.base_addr    = io;
+-      dev_fmv18x.irq          = irq;
+-      dev_fmv18x.init         = fmv18x_probe;
+-      if (register_netdev(&dev_fmv18x) != 0) {
+-              printk("fmv18x: register_netdev() returned non-zero.\n");
+-              return -EIO;
+-      }
++      dev_fmv18x = fmv18x_probe(-1);
++      if (IS_ERR(dev_fmv18x))
++              return PTR_ERR(dev_fmv18x);
+       return 0;
+ }
+ void
+ cleanup_module(void)
+ {
+-      unregister_netdev(&dev_fmv18x);
+-      kfree(dev_fmv18x.priv);
+-      dev_fmv18x.priv = NULL;
+-
+-      /* If we don't do this, we can't re-insmod it later. */
+-      free_irq(dev_fmv18x.irq, &dev_fmv18x);
+-      release_region(dev_fmv18x.base_addr, FMV18X_IO_EXTENT);
++      unregister_netdev(dev_fmv18x);
++      free_irq(dev_fmv18x->irq, dev_fmv18x);
++      release_region(dev_fmv18x->base_addr, FMV18X_IO_EXTENT);
++      free_netdev(dev_fmv18x);
+ }
+ #endif /* MODULE */
\f
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/net/forcedeth.c 2003-12-28 23:21:01.000000000 -0800
+@@ -0,0 +1,1495 @@
++/*
++ * forcedeth: Ethernet driver for NVIDIA nForce media access controllers.
++ *
++ * Note: This driver is a cleanroom reimplementation based on reverse
++ *      engineered documentation written by Carl-Daniel Hailfinger
++ *      and Andrew de Quincey. It's neither supported nor endorsed
++ *      by NVIDIA Corp. Use at your own risk.
++ *
++ * NVIDIA, nForce and other NVIDIA marks are trademarks or registered
++ * trademarks of NVIDIA Corporation in the United States and other
++ * countries.
++ *
++ * Copyright (C) 2003 Manfred Spraul
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ * Changelog:
++ *    0.01: 05 Oct 2003: First release that compiles without warnings.
++ *    0.02: 05 Oct 2003: Fix bug for drain_tx: do not try to free NULL skbs.
++ *                       Check all PCI BARs for the register window.
++ *                       udelay added to mii_rw.
++ *    0.03: 06 Oct 2003: Initialize dev->irq.
++ *    0.04: 07 Oct 2003: Initialize np->lock, reduce handled irqs, add printks.
++ *    0.05: 09 Oct 2003: printk removed again, irq status print tx_timeout.
++ *    0.06: 10 Oct 2003: MAC Address read updated, pff flag generation updated,
++ *                       irq mask updated
++ *    0.07: 14 Oct 2003: Further irq mask updates.
++ *    0.08: 20 Oct 2003: rx_desc.Length initialization added, alloc_rx refill
++ *                       added into irq handler, NULL check for drain_ring.
++ *    0.09: 20 Oct 2003: Basic link speed irq implementation. Only handle the
++ *                       requested interrupt sources.
++ *    0.10: 20 Oct 2003: First cleanup for release.
++ *    0.11: 21 Oct 2003: hexdump for tx added, rx buffer sizes increased.
++ *                       MAC Address init fix, set_multicast cleanup.
++ *    0.12: 23 Oct 2003: Cleanups for release.
++ *    0.13: 25 Oct 2003: Limit for concurrent tx packets increased to 10.
++ *                       Set link speed correctly. start rx before starting
++ *                       tx (start_rx sets the link speed).
++ *    0.14: 25 Oct 2003: Nic dependant irq mask.
++ *    0.15: 08 Nov 2003: fix smp deadlock with set_multicast_list during
++ *                       open.
++ *    0.16: 15 Nov 2003: include file cleanup for ppc64, rx buffer size
++ *                       increased to 1628 bytes.
++ *    0.17: 16 Nov 2003: undo rx buffer size increase. Substract 1 from
++ *                       the tx length.
++ *    0.18: 17 Nov 2003: fix oops due to late initialization of dev_stats
++ *    0.19: 29 Nov 2003: Handle RxNoBuf, detect & handle invalid mac
++ *                       addresses, really stop rx if already running
++ *                       in start_rx, clean up a bit.
++ *                            (C) Carl-Daniel Hailfinger
++ *
++ * Known bugs:
++ * The irq handling is wrong - no tx done interrupts are generated.
++ * This means recovery from netif_stop_queue only happens in the hw timer
++ * interrupt (1/2 second on nForce2, 1/100 second on nForce3), or if an
++ * rx packet arrives by chance.
++ */
++#define FORCEDETH_VERSION             "0.19"
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/pci.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/delay.h>
++#include <linux/spinlock.h>
++#include <linux/ethtool.h>
++#include <linux/timer.h>
++#include <linux/skbuff.h>
++#include <linux/mii.h>
++#include <linux/random.h>
++#include <linux/init.h>
++
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/system.h>
++
++#if 0
++#define dprintk                       printk
++#else
++#define dprintk(x...)         do { } while (0)
++#endif
++
++
++/*
++ * Hardware access:
++ */
++
++#define DEV_NEED_LASTPACKET1  0x0001
++#define DEV_IRQMASK_1         0x0002
++#define DEV_IRQMASK_2         0x0004
++
++enum {
++      NvRegIrqStatus = 0x000,
++#define NVREG_IRQSTAT_MIIEVENT        0x040
++#define NVREG_IRQSTAT_MASK            0x1ff
++      NvRegIrqMask = 0x004,
++#define NVREG_IRQ_RX                  0x0002
++#define NVREG_IRQ_RX_NOBUF            0x0004
++#define NVREG_IRQ_TX_ERR              0x0008
++#define NVREG_IRQ_TX2                 0x0010
++#define NVREG_IRQ_TIMER                       0x0020
++#define NVREG_IRQ_LINK                        0x0040
++#define NVREG_IRQ_TX1                 0x0100
++#define NVREG_IRQMASK_WANTED_1                0x005f
++#define NVREG_IRQMASK_WANTED_2                0x0147
++#define NVREG_IRQ_UNKNOWN             (~(NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1))
++
++      NvRegUnknownSetupReg6 = 0x008,
++#define NVREG_UNKSETUP6_VAL           3
++
++      NvRegPollingInterval = 0x00c,
++      NvRegMisc1 = 0x080,
++#define NVREG_MISC1_HD                0x02
++#define NVREG_MISC1_FORCE     0x3b0f3c
++
++      NvRegTransmitterControl = 0x084,
++#define NVREG_XMITCTL_START   0x01
++      NvRegTransmitterStatus = 0x088,
++#define NVREG_XMITSTAT_BUSY   0x01
++
++      NvRegPacketFilterFlags = 0x8c,
++#define NVREG_PFF_ALWAYS      0x7F0008
++#define NVREG_PFF_PROMISC     0x80
++#define NVREG_PFF_MYADDR      0x20
++
++      NvRegOffloadConfig = 0x90,
++#define NVREG_OFFLOAD_HOMEPHY 0x601
++#define NVREG_OFFLOAD_NORMAL  0x5ee
++      NvRegReceiverControl = 0x094,
++#define NVREG_RCVCTL_START    0x01
++      NvRegReceiverStatus = 0x98,
++#define NVREG_RCVSTAT_BUSY    0x01
++
++      NvRegRandomSeed = 0x9c,
++#define NVREG_RNDSEED_MASK    0x00ff
++#define NVREG_RNDSEED_FORCE   0x7f00
++
++      NvRegUnknownSetupReg1 = 0xA0,
++#define NVREG_UNKSETUP1_VAL   0x16070f
++      NvRegUnknownSetupReg2 = 0xA4,
++#define NVREG_UNKSETUP2_VAL   0x16
++      NvRegMacAddrA = 0xA8,
++      NvRegMacAddrB = 0xAC,
++      NvRegMulticastAddrA = 0xB0,
++#define NVREG_MCASTADDRA_FORCE        0x01
++      NvRegMulticastAddrB = 0xB4,
++      NvRegMulticastMaskA = 0xB8,
++      NvRegMulticastMaskB = 0xBC,
++
++      NvRegTxRingPhysAddr = 0x100,
++      NvRegRxRingPhysAddr = 0x104,
++      NvRegRingSizes = 0x108,
++#define NVREG_RINGSZ_TXSHIFT 0
++#define NVREG_RINGSZ_RXSHIFT 16
++      NvRegUnknownTransmitterReg = 0x10c,
++      NvRegLinkSpeed = 0x110,
++#define NVREG_LINKSPEED_FORCE 0x10000
++#define NVREG_LINKSPEED_10    10
++#define NVREG_LINKSPEED_100   100
++#define NVREG_LINKSPEED_1000  1000
++      NvRegUnknownSetupReg5 = 0x130,
++#define NVREG_UNKSETUP5_BIT31 (1<<31)
++      NvRegUnknownSetupReg3 = 0x134,
++#define NVREG_UNKSETUP3_VAL1  0x200010
++      NvRegTxRxControl = 0x144,
++#define NVREG_TXRXCTL_KICK    0x0001
++#define NVREG_TXRXCTL_BIT1    0x0002
++#define NVREG_TXRXCTL_BIT2    0x0004
++#define NVREG_TXRXCTL_IDLE    0x0008
++#define NVREG_TXRXCTL_RESET   0x0010
++      NvRegMIIStatus = 0x180,
++#define NVREG_MIISTAT_ERROR           0x0001
++#define NVREG_MIISTAT_LINKCHANGE      0x0008
++#define NVREG_MIISTAT_MASK            0x000f
++#define NVREG_MIISTAT_MASK2           0x000f
++      NvRegUnknownSetupReg4 = 0x184,
++#define NVREG_UNKSETUP4_VAL   8
++
++      NvRegAdapterControl = 0x188,
++#define NVREG_ADAPTCTL_START  0x02
++#define NVREG_ADAPTCTL_LINKUP 0x04
++#define NVREG_ADAPTCTL_PHYVALID       0x4000
++#define NVREG_ADAPTCTL_RUNNING        0x100000
++#define NVREG_ADAPTCTL_PHYSHIFT       24
++      NvRegMIISpeed = 0x18c,
++#define NVREG_MIISPEED_BIT8   (1<<8)
++#define NVREG_MIIDELAY        5
++      NvRegMIIControl = 0x190,
++#define NVREG_MIICTL_INUSE    0x10000
++#define NVREG_MIICTL_WRITE    0x08000
++#define NVREG_MIICTL_ADDRSHIFT        5
++      NvRegMIIData = 0x194,
++      NvRegWakeUpFlags = 0x200,
++#define NVREG_WAKEUPFLAGS_VAL         0x7770
++#define NVREG_WAKEUPFLAGS_BUSYSHIFT   24
++#define NVREG_WAKEUPFLAGS_ENABLESHIFT 16
++#define NVREG_WAKEUPFLAGS_D3SHIFT     12
++#define NVREG_WAKEUPFLAGS_D2SHIFT     8
++#define NVREG_WAKEUPFLAGS_D1SHIFT     4
++#define NVREG_WAKEUPFLAGS_D0SHIFT     0
++#define NVREG_WAKEUPFLAGS_ACCEPT_MAGPAT               0x01
++#define NVREG_WAKEUPFLAGS_ACCEPT_WAKEUPPAT    0x02
++#define NVREG_WAKEUPFLAGS_ACCEPT_LINKCHANGE   0x04
++
++      NvRegPatternCRC = 0x204,
++      NvRegPatternMask = 0x208,
++      NvRegPowerCap = 0x268,
++#define NVREG_POWERCAP_D3SUPP (1<<30)
++#define NVREG_POWERCAP_D2SUPP (1<<26)
++#define NVREG_POWERCAP_D1SUPP (1<<25)
++      NvRegPowerState = 0x26c,
++#define NVREG_POWERSTATE_POWEREDUP    0x8000
++#define NVREG_POWERSTATE_VALID                0x0100
++#define NVREG_POWERSTATE_MASK         0x0003
++#define NVREG_POWERSTATE_D0           0x0000
++#define NVREG_POWERSTATE_D1           0x0001
++#define NVREG_POWERSTATE_D2           0x0002
++#define NVREG_POWERSTATE_D3           0x0003
++};
++
++struct ring_desc {
++      u32 PacketBuffer;
++      u16 Length;
++      u16 Flags;
++};
++
++#define NV_TX_LASTPACKET      (1<<0)
++#define NV_TX_RETRYERROR      (1<<3)
++#define NV_TX_LASTPACKET1     (1<<8)
++#define NV_TX_DEFERRED                (1<<10)
++#define NV_TX_CARRIERLOST     (1<<11)
++#define NV_TX_LATECOLLISION   (1<<12)
++#define NV_TX_UNDERFLOW               (1<<13)
++#define NV_TX_ERROR           (1<<14)
++#define NV_TX_VALID           (1<<15)
++
++#define NV_RX_DESCRIPTORVALID (1<<0)
++#define NV_RX_MISSEDFRAME     (1<<1)
++#define NV_RX_SUBSTRACT1      (1<<3)
++#define NV_RX_ERROR1          (1<<7)
++#define NV_RX_ERROR2          (1<<8)
++#define NV_RX_ERROR3          (1<<9)
++#define NV_RX_ERROR4          (1<<10)
++#define NV_RX_CRCERR          (1<<11)
++#define NV_RX_OVERFLOW                (1<<12)
++#define NV_RX_FRAMINGERR      (1<<13)
++#define NV_RX_ERROR           (1<<14)
++#define NV_RX_AVAIL           (1<<15)
++
++/* Miscelaneous hardware related defines: */
++#define NV_PCI_REGSZ          0x270
++
++/* various timeout delays: all in usec */
++#define NV_TXRX_RESET_DELAY   4
++#define NV_TXSTOP_DELAY1      10
++#define NV_TXSTOP_DELAY1MAX   500000
++#define NV_TXSTOP_DELAY2      100
++#define NV_RXSTOP_DELAY1      10
++#define NV_RXSTOP_DELAY1MAX   500000
++#define NV_RXSTOP_DELAY2      100
++#define NV_SETUP5_DELAY               5
++#define NV_SETUP5_DELAYMAX    50000
++#define NV_POWERUP_DELAY      5
++#define NV_POWERUP_DELAYMAX   5000
++#define NV_MIIBUSY_DELAY      50
++#define NV_MIIPHY_DELAY       10
++#define NV_MIIPHY_DELAYMAX    10000
++
++#define NV_WAKEUPPATTERNS     5
++#define NV_WAKEUPMASKENTRIES  4
++
++/* General driver defaults */
++#define NV_WATCHDOG_TIMEO     (2*HZ)
++#define DEFAULT_MTU           1500    /* also maximum supported, at least for now */
++
++#define RX_RING               128
++#define TX_RING               16
++/* limited to 1 packet until we understand NV_TX_LASTPACKET */
++#define TX_LIMIT_STOP 10
++#define TX_LIMIT_START        5
++
++/* rx/tx mac addr + type + vlan + align + slack*/
++#define RX_NIC_BUFSIZE                (DEFAULT_MTU + 64)
++/* even more slack */
++#define RX_ALLOC_BUFSIZE      (DEFAULT_MTU + 128)
++
++#define OOM_REFILL    (1+HZ/20)
++#define POLL_WAIT     (1+HZ/100)
++
++/*
++ * SMP locking:
++ * All hardware access under dev->priv->lock, except the performance
++ * critical parts:
++ * - rx is (pseudo-) lockless: it relies on the single-threading provided
++ *    by the arch code for interrupts.
++ * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission
++ *    needs dev->priv->lock :-(
++ * - set_multicast_list: preparation lockless, relies on dev->xmit_lock.
++ */
++
++/* in dev: base, irq */
++struct fe_priv {
++      spinlock_t lock;
++
++      /* General data:
++       * Locking: spin_lock(&np->lock); */
++      struct net_device_stats stats;
++      int in_shutdown;
++      u32 linkspeed;
++      int duplex;
++      int phyaddr;
++
++      /* General data: RO fields */
++      dma_addr_t ring_addr;
++      struct pci_dev *pci_dev;
++      u32 orig_mac[2];
++      u32 irqmask;
++
++      /* rx specific fields.
++       * Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
++       */
++      struct ring_desc *rx_ring;
++      unsigned int cur_rx, refill_rx;
++      struct sk_buff *rx_skbuff[RX_RING];
++      dma_addr_t rx_dma[RX_RING];
++      unsigned int rx_buf_sz;
++      struct timer_list oom_kick;
++      struct timer_list nic_poll;
++
++      /*
++       * tx specific fields.
++       */
++      struct ring_desc *tx_ring;
++      unsigned int next_tx, nic_tx;
++      struct sk_buff *tx_skbuff[TX_RING];
++      dma_addr_t tx_dma[TX_RING];
++      u16 tx_flags;
++};
++
++/*
++ * Maximum number of loops until we assume that a bit in the irq mask
++ * is stuck. Overridable with module param.
++ */
++static int max_interrupt_work = 5;
++
++static inline struct fe_priv *get_nvpriv(struct net_device *dev)
++{
++      return (struct fe_priv *) dev->priv;
++}
++
++static inline u8 *get_hwbase(struct net_device *dev)
++{
++      return (u8 *) dev->base_addr;
++}
++
++static inline void pci_push(u8 * base)
++{
++      /* force out pending posted writes */
++      readl(base);
++}
++
++static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target,
++                              int delay, int delaymax, const char *msg)
++{
++      u8 *base = get_hwbase(dev);
++
++      pci_push(base);
++      do {
++              udelay(delay);
++              delaymax -= delay;
++              if (delaymax < 0) {
++                      if (msg)
++                              printk(msg);
++                      return 1;
++              }
++      } while ((readl(base + offset) & mask) != target);
++      return 0;
++}
++
++#define MII_READ      (-1)
++/* mii_rw: read/write a register on the PHY.
++ *
++ * Caller must guarantee serialization
++ */
++static int mii_rw(struct net_device *dev, int addr, int miireg, int value)
++{
++      u8 *base = get_hwbase(dev);
++      int was_running;
++      u32 reg;
++      int retval;
++
++      writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
++      was_running = 0;
++      reg = readl(base + NvRegAdapterControl);
++      if (reg & NVREG_ADAPTCTL_RUNNING) {
++              was_running = 1;
++              writel(reg & ~NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl);
++      }
++      reg = readl(base + NvRegMIIControl);
++      if (reg & NVREG_MIICTL_INUSE) {
++              writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl);
++              udelay(NV_MIIBUSY_DELAY);
++      }
++
++      reg = NVREG_MIICTL_INUSE | (addr << NVREG_MIICTL_ADDRSHIFT) | miireg;
++      if (value != MII_READ) {
++              writel(value, base + NvRegMIIData);
++              reg |= NVREG_MIICTL_WRITE;
++      }
++      writel(reg, base + NvRegMIIControl);
++
++      if (reg_delay(dev, NvRegMIIControl, NVREG_MIICTL_INUSE, 0,
++                      NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL)) {
++              dprintk(KERN_DEBUG "%s: mii_rw of reg %d at PHY %d timed out.\n",
++                              dev->name, miireg, addr);
++              retval = -1;
++      } else if (value != MII_READ) {
++              /* it was a write operation - fewer failures are detectable */
++              dprintk(KERN_DEBUG "%s: mii_rw wrote 0x%x to reg %d at PHY %d\n",
++                              dev->name, value, miireg, addr);
++              retval = 0;
++      } else if (readl(base + NvRegMIIStatus) & NVREG_MIISTAT_ERROR) {
++              dprintk(KERN_DEBUG "%s: mii_rw of reg %d at PHY %d failed.\n",
++                              dev->name, miireg, addr);
++              retval = -1;
++      } else {
++              /* FIXME: why is that required? */
++              udelay(50);
++              retval = readl(base + NvRegMIIData);
++              dprintk(KERN_DEBUG "%s: mii_rw read from reg %d at PHY %d: 0x%x.\n",
++                              dev->name, miireg, addr, retval);
++      }
++      if (was_running) {
++              reg = readl(base + NvRegAdapterControl);
++              writel(reg | NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl);
++      }
++      return retval;
++}
++
++static void start_rx(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++      u8 *base = get_hwbase(dev);
++
++      dprintk(KERN_DEBUG "%s: start_rx\n", dev->name);
++      /* Already running? Stop it. */
++      if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) {
++              writel(0, base + NvRegReceiverControl);
++              pci_push(base);
++      }
++      writel(np->linkspeed, base + NvRegLinkSpeed);
++      pci_push(base);
++      writel(NVREG_RCVCTL_START, base + NvRegReceiverControl);
++      pci_push(base);
++}
++
++static void stop_rx(struct net_device *dev)
++{
++      u8 *base = get_hwbase(dev);
++
++      dprintk(KERN_DEBUG "%s: stop_rx\n", dev->name);
++      writel(0, base + NvRegReceiverControl);
++      reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0,
++                     NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX,
++                     KERN_INFO "stop_rx: ReceiverStatus remained busy");
++
++      udelay(NV_RXSTOP_DELAY2);
++      writel(0, base + NvRegLinkSpeed);
++}
++
++static void start_tx(struct net_device *dev)
++{
++      u8 *base = get_hwbase(dev);
++
++      dprintk(KERN_DEBUG "%s: start_tx\n", dev->name);
++      writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl);
++      pci_push(base);
++}
++
++static void stop_tx(struct net_device *dev)
++{
++      u8 *base = get_hwbase(dev);
++
++      dprintk(KERN_DEBUG "%s: stop_tx\n", dev->name);
++      writel(0, base + NvRegTransmitterControl);
++      reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0,
++                     NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX,
++                     KERN_INFO "stop_tx: TransmitterStatus remained busy");
++
++      udelay(NV_TXSTOP_DELAY2);
++      writel(0, base + NvRegUnknownTransmitterReg);
++}
++
++static void txrx_reset(struct net_device *dev)
++{
++      u8 *base = get_hwbase(dev);
++
++      dprintk(KERN_DEBUG "%s: txrx_reset\n", dev->name);
++      writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET, base + NvRegTxRxControl);
++      pci_push(base);
++      udelay(NV_TXRX_RESET_DELAY);
++      writel(NVREG_TXRXCTL_BIT2, base + NvRegTxRxControl);
++      pci_push(base);
++}
++
++/*
++ * get_stats: dev->get_stats function
++ * Get latest stats value from the nic.
++ * Called with read_lock(&dev_base_lock) held for read -
++ * only synchronized against unregister_netdevice.
++ */
++static struct net_device_stats *get_stats(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++
++      /* It seems that the nic always generates interrupts and doesn't
++       * accumulate errors internally. Thus the current values in np->stats
++       * are already up to date.
++       */
++      return &np->stats;
++}
++
++
++/*
++ * nic_ioctl: dev->do_ioctl function
++ * Called with rtnl_lock held.
++ */
++static int nic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
++{
++      return -EOPNOTSUPP;
++}
++
++/*
++ * alloc_rx: fill rx ring entries.
++ * Return 1 if the allocations for the skbs failed and the
++ * rx engine is without Available descriptors
++ */
++static int alloc_rx(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++      unsigned int refill_rx = np->refill_rx;
++
++      while (np->cur_rx != refill_rx) {
++              int nr = refill_rx % RX_RING;
++              struct sk_buff *skb;
++
++              if (np->rx_skbuff[nr] == NULL) {
++
++                      skb = dev_alloc_skb(RX_ALLOC_BUFSIZE);
++                      if (!skb)
++                              break;
++
++                      skb->dev = dev;
++                      np->rx_skbuff[nr] = skb;
++              } else {
++                      skb = np->rx_skbuff[nr];
++              }
++              np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len,
++                                              PCI_DMA_FROMDEVICE);
++              np->rx_ring[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]);
++              np->rx_ring[nr].Length = cpu_to_le16(RX_NIC_BUFSIZE);
++              wmb();
++              np->rx_ring[nr].Flags = cpu_to_le16(NV_RX_AVAIL);
++              dprintk(KERN_DEBUG "%s: alloc_rx: Packet  %d marked as Available\n",
++                                      dev->name, refill_rx);
++              refill_rx++;
++      }
++      np->refill_rx = refill_rx;
++      if (np->cur_rx - refill_rx == RX_RING)
++              return 1;
++      return 0;
++}
++
++static void do_rx_refill(unsigned long data)
++{
++      struct net_device *dev = (struct net_device *) data;
++      struct fe_priv *np = get_nvpriv(dev);
++
++      disable_irq(dev->irq);
++      if (alloc_rx(dev)) {
++              spin_lock(&np->lock);
++              if (!np->in_shutdown)
++                      mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
++              spin_unlock(&np->lock);
++      }
++      enable_irq(dev->irq);
++}
++
++static int init_ring(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++      int i;
++
++      np->next_tx = np->nic_tx = 0;
++      for (i = 0; i < TX_RING; i++) {
++              np->tx_ring[i].Flags = 0;
++      }
++
++      np->cur_rx = RX_RING;
++      np->refill_rx = 0;
++      for (i = 0; i < RX_RING; i++) {
++              np->rx_ring[i].Flags = 0;
++      }
++      return alloc_rx(dev);
++}
++
++static void drain_tx(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++      int i;
++      for (i = 0; i < TX_RING; i++) {
++              np->tx_ring[i].Flags = 0;
++              if (np->tx_skbuff[i]) {
++                      pci_unmap_single(np->pci_dev, np->tx_dma[i],
++                                              np->tx_skbuff[i]->len,
++                                              PCI_DMA_TODEVICE);
++                      dev_kfree_skb(np->tx_skbuff[i]);
++                      np->tx_skbuff[i] = NULL;
++                      np->stats.tx_dropped++;
++              }
++      }
++}
++
++static void drain_rx(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++      int i;
++      for (i = 0; i < RX_RING; i++) {
++              np->rx_ring[i].Flags = 0;
++              wmb();
++              if (np->rx_skbuff[i]) {
++                      pci_unmap_single(np->pci_dev, np->rx_dma[i],
++                                              np->rx_skbuff[i]->len,
++                                              PCI_DMA_FROMDEVICE);
++                      dev_kfree_skb(np->rx_skbuff[i]);
++                      np->rx_skbuff[i] = NULL;
++              }
++      }
++}
++
++static void drain_ring(struct net_device *dev)
++{
++      drain_tx(dev);
++      drain_rx(dev);
++}
++
++/*
++ * start_xmit: dev->hard_start_xmit function
++ * Called with dev->xmit_lock held.
++ */
++static int start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++      int nr = np->next_tx % TX_RING;
++
++      np->tx_skbuff[nr] = skb;
++      np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len,
++                                      PCI_DMA_TODEVICE);
++
++      np->tx_ring[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
++      np->tx_ring[nr].Length = cpu_to_le16(skb->len-1);
++
++      spin_lock_irq(&np->lock);
++      wmb();
++      np->tx_ring[nr].Flags = np->tx_flags;
++      dprintk(KERN_DEBUG "%s: start_xmit: packet packet %d queued for transmission.\n",
++                              dev->name, np->next_tx);
++      {
++              int j;
++              for (j=0; j<64; j++) {
++                      if ((j%16) == 0)
++                              dprintk("\n%03x:", j);
++                      dprintk(" %02x", ((unsigned char*)skb->data)[j]);
++              }
++              dprintk("\n");
++      }
++
++      np->next_tx++;
++
++      dev->trans_start = jiffies;
++      if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP)
++              netif_stop_queue(dev);
++      spin_unlock_irq(&np->lock);
++      writel(NVREG_TXRXCTL_KICK, get_hwbase(dev) + NvRegTxRxControl);
++      return 0;
++}
++
++/*
++ * tx_done: check for completed packets, release the skbs.
++ *
++ * Caller must own np->lock.
++ */
++static void tx_done(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++
++      while (np->nic_tx < np->next_tx) {
++              struct ring_desc *prd;
++              int i = np->nic_tx % TX_RING;
++
++              prd = &np->tx_ring[i];
++
++              dprintk(KERN_DEBUG "%s: tx_done: looking at packet %d, Flags 0x%x.\n",
++                                      dev->name, np->nic_tx, prd->Flags);
++              if (prd->Flags & cpu_to_le16(NV_TX_VALID))
++                      break;
++              if (prd->Flags & cpu_to_le16(NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
++                                              NV_TX_UNDERFLOW|NV_TX_ERROR)) {
++                      if (prd->Flags & cpu_to_le16(NV_TX_UNDERFLOW))
++                              np->stats.tx_fifo_errors++;
++                      if (prd->Flags & cpu_to_le16(NV_TX_CARRIERLOST))
++                              np->stats.tx_carrier_errors++;
++                      np->stats.tx_errors++;
++              } else {
++                      np->stats.tx_packets++;
++                      np->stats.tx_bytes += np->tx_skbuff[i]->len;
++              }
++              pci_unmap_single(np->pci_dev, np->tx_dma[i],
++                                      np->tx_skbuff[i]->len,
++                                      PCI_DMA_TODEVICE);
++              dev_kfree_skb_irq(np->tx_skbuff[i]);
++              np->tx_skbuff[i] = NULL;
++              np->nic_tx++;
++      }
++      if (np->next_tx - np->nic_tx < TX_LIMIT_START)
++              netif_wake_queue(dev);
++}
++
++/*
++ * tx_timeout: dev->tx_timeout function
++ * Called with dev->xmit_lock held.
++ */
++static void tx_timeout(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++      u8 *base = get_hwbase(dev);
++
++      dprintk(KERN_DEBUG "%s: Got tx_timeout. irq: %08x\n", dev->name,
++                      readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK);
++
++      spin_lock_irq(&np->lock);
++
++      /* 1) stop tx engine */
++      stop_tx(dev);
++
++      /* 2) check that the packets were not sent already: */
++      tx_done(dev);
++
++      /* 3) if there are dead entries: clear everything */
++      if (np->next_tx != np->nic_tx) {
++              printk(KERN_DEBUG "%s: tx_timeout: dead entries!\n", dev->name);
++              drain_tx(dev);
++              np->next_tx = np->nic_tx = 0;
++              writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr);
++              netif_wake_queue(dev);
++      }
++
++      /* 4) restart tx engine */
++      start_tx(dev);
++      spin_unlock_irq(&np->lock);
++}
++
++static void rx_process(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++
++      for (;;) {
++              struct ring_desc *prd;
++              struct sk_buff *skb;
++              int len;
++              int i;
++              if (np->cur_rx - np->refill_rx >= RX_RING)
++                      break;  /* we scanned the whole ring - do not continue */
++
++              i = np->cur_rx % RX_RING;
++              prd = &np->rx_ring[i];
++              dprintk(KERN_DEBUG "%s: rx_process: looking at packet %d, Flags 0x%x.\n",
++                                      dev->name, np->cur_rx, prd->Flags);
++
++              if (prd->Flags & cpu_to_le16(NV_RX_AVAIL))
++                      break;  /* still owned by hardware, */
++
++              /*
++               * the packet is for us - immediately tear down the pci mapping, and
++               * prefetch the first cacheline of the packet.
++               */
++              pci_unmap_single(np->pci_dev, np->rx_dma[i],
++                              np->rx_skbuff[i]->len,
++                              PCI_DMA_FROMDEVICE);
++              prefetch(np->rx_skbuff[i]->data);
++
++              {
++                      int j;
++                      dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",prd->Flags);
++                      for (j=0; j<64; j++) {
++                              if ((j%16) == 0)
++                                      dprintk("\n%03x:", j);
++                              dprintk(" %02x", ((unsigned char*)np->rx_skbuff[i]->data)[j]);
++                      }
++                      dprintk("\n");
++              }
++              /* look at what we actually got: */
++              if (!(prd->Flags & cpu_to_le16(NV_RX_DESCRIPTORVALID)))
++                      goto next_pkt;
++
++
++              len = le16_to_cpu(prd->Length);
++
++              if (prd->Flags & cpu_to_le16(NV_RX_MISSEDFRAME)) {
++                      np->stats.rx_missed_errors++;
++                      np->stats.rx_errors++;
++                      goto next_pkt;
++              }
++              if (prd->Flags & cpu_to_le16(NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) {
++                      np->stats.rx_errors++;
++                      goto next_pkt;
++              }
++              if (prd->Flags & cpu_to_le16(NV_RX_CRCERR)) {
++                      np->stats.rx_crc_errors++;
++                      np->stats.rx_errors++;
++                      goto next_pkt;
++              }
++              if (prd->Flags & cpu_to_le16(NV_RX_OVERFLOW)) {
++                      np->stats.rx_over_errors++;
++                      np->stats.rx_errors++;
++                      goto next_pkt;
++              }
++              if (prd->Flags & cpu_to_le16(NV_RX_ERROR)) {
++                      /* framing errors are soft errors, the rest is fatal. */
++                      if (prd->Flags & cpu_to_le16(NV_RX_FRAMINGERR)) {
++                              if (prd->Flags & cpu_to_le16(NV_RX_SUBSTRACT1)) {
++                                      len--;
++                              }
++                      } else {
++                              np->stats.rx_errors++;
++                              goto next_pkt;
++                      }
++              }
++              /* got a valid packet - forward it to the network core */
++              skb = np->rx_skbuff[i];
++              np->rx_skbuff[i] = NULL;
++
++              skb_put(skb, len);
++              skb->protocol = eth_type_trans(skb, dev);
++              dprintk(KERN_DEBUG "%s: rx_process: packet %d with %d bytes, proto %d accepted.\n",
++                                      dev->name, np->cur_rx, len, skb->protocol);
++              netif_rx(skb);
++              dev->last_rx = jiffies;
++              np->stats.rx_packets++;
++              np->stats.rx_bytes += len;
++next_pkt:
++              np->cur_rx++;
++      }
++}
++
++/*
++ * change_mtu: dev->change_mtu function
++ * Called with dev_base_lock held for read.
++ */
++static int change_mtu(struct net_device *dev, int new_mtu)
++{
++      if (new_mtu > DEFAULT_MTU)
++              return -EINVAL;
++      dev->mtu = new_mtu;
++      return 0;
++}
++
++/*
++ * change_mtu: dev->change_mtu function
++ * Called with dev->xmit_lock held.
++ */
++static void set_multicast(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++      u8 *base = get_hwbase(dev);
++      u32 addr[2];
++      u32 mask[2];
++      u32 pff;
++
++      memset(addr, 0, sizeof(addr));
++      memset(mask, 0, sizeof(mask));
++
++      if (dev->flags & IFF_PROMISC) {
++              printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
++              pff = NVREG_PFF_PROMISC;
++      } else {
++              pff = NVREG_PFF_MYADDR;
++
++              if (dev->flags & IFF_ALLMULTI || dev->mc_list) {
++                      u32 alwaysOff[2];
++                      u32 alwaysOn[2];
++
++                      alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0xffffffff;
++                      if (dev->flags & IFF_ALLMULTI) {
++                              alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0;
++                      } else {
++                              struct dev_mc_list *walk;
++
++                              walk = dev->mc_list;
++                              while (walk != NULL) {
++                                      u32 a, b;
++                                      a = le32_to_cpu(*(u32 *) walk->dmi_addr);
++                                      b = le16_to_cpu(*(u16 *) (&walk->dmi_addr[4]));
++                                      alwaysOn[0] &= a;
++                                      alwaysOff[0] &= ~a;
++                                      alwaysOn[1] &= b;
++                                      alwaysOff[1] &= ~b;
++                                      walk = walk->next;
++                              }
++                      }
++                      addr[0] = alwaysOn[0];
++                      addr[1] = alwaysOn[1];
++                      mask[0] = alwaysOn[0] | alwaysOff[0];
++                      mask[1] = alwaysOn[1] | alwaysOff[1];
++              }
++      }
++      addr[0] |= NVREG_MCASTADDRA_FORCE;
++      pff |= NVREG_PFF_ALWAYS;
++      spin_lock_irq(&np->lock);
++      stop_rx(dev);
++      writel(addr[0], base + NvRegMulticastAddrA);
++      writel(addr[1], base + NvRegMulticastAddrB);
++      writel(mask[0], base + NvRegMulticastMaskA);
++      writel(mask[1], base + NvRegMulticastMaskB);
++      writel(pff, base + NvRegPacketFilterFlags);
++      start_rx(dev);
++      spin_unlock_irq(&np->lock);
++}
++
++static int update_linkspeed(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++      int adv, lpa, newls, newdup;
++
++      adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
++      lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ);
++      dprintk(KERN_DEBUG "%s: update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n",
++                              dev->name, adv, lpa);
++
++      /* FIXME: handle parallel detection properly, handle gigabit ethernet */
++      lpa = lpa & adv;
++      if (lpa  & LPA_100FULL) {
++              newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100;
++              newdup = 1;
++      } else if (lpa & LPA_100HALF) {
++              newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100;
++              newdup = 0;
++      } else if (lpa & LPA_10FULL) {
++              newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
++              newdup = 1;
++      } else if (lpa & LPA_10HALF) {
++              newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
++              newdup = 0;
++      } else {
++              dprintk(KERN_DEBUG "%s: bad ability %04x - falling back to 10HD.\n", dev->name, lpa);
++              newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
++              newdup = 0;
++      }
++      if (np->duplex != newdup || np->linkspeed != newls) {
++              np->duplex = newdup;
++              np->linkspeed = newls;
++              return 1;
++      }
++      return 0;
++}
++
++static void link_irq(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++      u8 *base = get_hwbase(dev);
++      u32 miistat;
++      int miival;
++
++      miistat = readl(base + NvRegMIIStatus);
++      writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
++      printk(KERN_DEBUG "%s: link change notification, status 0x%x.\n", dev->name, miistat);
++
++      miival = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
++      if (miival & BMSR_ANEGCOMPLETE) {
++              update_linkspeed(dev);
++
++              if (netif_carrier_ok(dev)) {
++                      stop_rx(dev);
++              } else {
++                      netif_carrier_on(dev);
++                      printk(KERN_INFO "%s: link up.\n", dev->name);
++              }
++              writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD),
++                                      base + NvRegMisc1);
++              start_rx(dev);
++      } else {
++              if (netif_carrier_ok(dev)) {
++                      netif_carrier_off(dev);
++                      printk(KERN_INFO "%s: link down.\n", dev->name);
++                      stop_rx(dev);
++              }
++              writel(np->linkspeed, base + NvRegLinkSpeed);
++              pci_push(base);
++      }
++}
++
++static irqreturn_t nic_irq(int foo, void *data, struct pt_regs *regs)
++{
++      struct net_device *dev = (struct net_device *) data;
++      struct fe_priv *np = get_nvpriv(dev);
++      u8 *base = get_hwbase(dev);
++      u32 events;
++      int i;
++
++      dprintk(KERN_DEBUG "%s: nic_irq\n", dev->name);
++
++      for (i=0; ; i++) {
++              events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
++              writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
++              pci_push(base);
++              dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
++              if (!(events & np->irqmask))
++                      break;
++
++              if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX2|NVREG_IRQ_TX_ERR)) {
++                      spin_lock(&np->lock);
++                      tx_done(dev);
++                      spin_unlock(&np->lock);
++              }
++
++              if (events & (NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) {
++                      rx_process(dev);
++                      if (alloc_rx(dev)) {
++                              spin_lock(&np->lock);
++                              if (!np->in_shutdown)
++                                      mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
++                              spin_unlock(&np->lock);
++                      }
++              }
++
++              if (events & NVREG_IRQ_LINK) {
++                      spin_lock(&np->lock);
++                      link_irq(dev);
++                      spin_unlock(&np->lock);
++              }
++              if (events & (NVREG_IRQ_TX_ERR)) {
++                      dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
++                                              dev->name, events);
++              }
++              if (events & (NVREG_IRQ_UNKNOWN)) {
++                      printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n",
++                                              dev->name, events);
++              }
++              if (i > max_interrupt_work) {
++                      spin_lock(&np->lock);
++                      /* disable interrupts on the nic */
++                      writel(0, base + NvRegIrqMask);
++                      pci_push(base);
++
++                      if (!np->in_shutdown)
++                              mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
++                      printk(KERN_DEBUG "%s: too many iterations (%d) in nic_irq.\n", dev->name, i);
++                      spin_unlock(&np->lock);
++                      break;
++              }
++
++      }
++      dprintk(KERN_DEBUG "%s: nic_irq completed\n", dev->name);
++
++      return IRQ_RETVAL(i);
++}
++
++static void do_nic_poll(unsigned long data)
++{
++      struct net_device *dev = (struct net_device *) data;
++      struct fe_priv *np = get_nvpriv(dev);
++      u8 *base = get_hwbase(dev);
++
++      disable_irq(dev->irq);
++      /*
++       * reenable interrupts on the nic, we have to do this before calling
++       * nic_irq because that may decide to do otherwise
++       */
++      writel(np->irqmask, base + NvRegIrqMask);
++      pci_push(base);
++      nic_irq((int) 0, (void *) data, (struct pt_regs *) NULL);
++      enable_irq(dev->irq);
++}
++
++static int open(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++      u8 *base = get_hwbase(dev);
++      int ret, oom, i;
++
++      dprintk(KERN_DEBUG "forcedeth: open\n");
++
++      /* 1) erase previous misconfiguration */
++      /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */
++      writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
++      writel(0, base + NvRegMulticastAddrB);
++      writel(0, base + NvRegMulticastMaskA);
++      writel(0, base + NvRegMulticastMaskB);
++      writel(0, base + NvRegPacketFilterFlags);
++      writel(0, base + NvRegAdapterControl);
++      writel(0, base + NvRegLinkSpeed);
++      writel(0, base + NvRegUnknownTransmitterReg);
++      txrx_reset(dev);
++      writel(0, base + NvRegUnknownSetupReg6);
++
++      /* 2) initialize descriptor rings */
++      np->in_shutdown = 0;
++      oom = init_ring(dev);
++
++      /* 3) set mac address */
++      {
++              u32 mac[2];
++
++              mac[0] = (dev->dev_addr[0] <<  0) + (dev->dev_addr[1] <<  8) +
++                              (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24);
++              mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8);
++
++              writel(mac[0], base + NvRegMacAddrA);
++              writel(mac[1], base + NvRegMacAddrB);
++      }
++
++      /* 4) continue setup */
++      np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
++      np->duplex = 0;
++      writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
++      writel(0, base + NvRegTxRxControl);
++      pci_push(base);
++      writel(NVREG_TXRXCTL_BIT1, base + NvRegTxRxControl);
++      reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31,
++                      NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX,
++                      KERN_INFO "open: SetupReg5, Bit 31 remained off\n");
++      writel(0, base + NvRegUnknownSetupReg4);
++
++      /* 5) Find a suitable PHY */
++      writel(NVREG_MIISPEED_BIT8|NVREG_MIIDELAY, base + NvRegMIISpeed);
++      for (i = 1; i < 32; i++) {
++              int id1, id2;
++
++              id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ);
++              if (id1 < 0)
++                      continue;
++              id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ);
++              if (id2 < 0)
++                      continue;
++              dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n",
++                              dev->name, id1, id2, i);
++              np->phyaddr = i;
++
++              update_linkspeed(dev);
++
++              break;
++      }
++      if (i == 32) {
++              printk(KERN_INFO "%s: open: failing due to lack of suitable PHY.\n",
++                              dev->name);
++              ret = -EINVAL;
++              goto out_drain;
++      }
++
++      /* 6) continue setup */
++      writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD),
++                              base + NvRegMisc1);
++      writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus);
++      writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags);
++      writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig);
++
++      writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus);
++      get_random_bytes(&i, sizeof(i));
++      writel(NVREG_RNDSEED_FORCE | (i&NVREG_RNDSEED_MASK), base + NvRegRandomSeed);
++      writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1);
++      writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2);
++      writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);
++      writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID,
++                      base + NvRegAdapterControl);
++      writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4);
++      writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags);
++
++      /* 7) start packet processing */
++      writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr);
++      writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr);
++      writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT),
++                      base + NvRegRingSizes);
++
++      i = readl(base + NvRegPowerState);
++      if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0) {
++              writel(NVREG_POWERSTATE_POWEREDUP|i, base + NvRegPowerState);
++      }
++      pci_push(base);
++      udelay(10);
++      writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState);
++      writel(NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl);
++
++
++      writel(0, base + NvRegIrqMask);
++      pci_push(base);
++      writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
++      pci_push(base);
++      writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
++      writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
++      pci_push(base);
++
++      ret = request_irq(dev->irq, &nic_irq, SA_SHIRQ, dev->name, dev);
++      if (ret)
++              goto out_drain;
++
++      writel(np->irqmask, base + NvRegIrqMask);
++
++      spin_lock_irq(&np->lock);
++      writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
++      writel(0, base + NvRegMulticastAddrB);
++      writel(0, base + NvRegMulticastMaskA);
++      writel(0, base + NvRegMulticastMaskB);
++      writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags);
++      start_rx(dev);
++      start_tx(dev);
++      netif_start_queue(dev);
++      if (oom)
++              mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
++      if (!(mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ) & BMSR_ANEGCOMPLETE)) {
++              printk("%s: no link during initialization.\n", dev->name);
++              netif_carrier_off(dev);
++      }
++
++      spin_unlock_irq(&np->lock);
++
++      return 0;
++out_drain:
++      drain_ring(dev);
++      return ret;
++}
++
++static int close(struct net_device *dev)
++{
++      struct fe_priv *np = get_nvpriv(dev);
++
++      spin_lock_irq(&np->lock);
++      np->in_shutdown = 1;
++      spin_unlock_irq(&np->lock);
++      synchronize_irq(dev->irq);
++
++      del_timer_sync(&np->oom_kick);
++      del_timer_sync(&np->nic_poll);
++
++      netif_stop_queue(dev);
++      spin_lock_irq(&np->lock);
++      stop_tx(dev);
++      stop_rx(dev);
++      spin_unlock_irq(&np->lock);
++
++      free_irq(dev->irq, dev);
++
++      drain_ring(dev);
++
++      /* FIXME: power down nic */
++
++      return 0;
++}
++
++static int __devinit probe_nic(struct pci_dev *pci_dev, const struct pci_device_id *id)
++{
++      struct net_device *dev;
++      struct fe_priv *np;
++      unsigned long addr;
++      u8 *base;
++      int err, i;
++
++      dev = alloc_etherdev(sizeof(struct fe_priv));
++      np = get_nvpriv(dev);
++      err = -ENOMEM;
++      if (!dev)
++              goto out;
++
++      np->pci_dev = pci_dev;
++      spin_lock_init(&np->lock);
++      SET_MODULE_OWNER(dev);
++      SET_NETDEV_DEV(dev, &pci_dev->dev);
++
++      init_timer(&np->oom_kick);
++      np->oom_kick.data = (unsigned long) dev;
++      np->oom_kick.function = &do_rx_refill;  /* timer handler */
++      init_timer(&np->nic_poll);
++      np->nic_poll.data = (unsigned long) dev;
++      np->nic_poll.function = &do_nic_poll;   /* timer handler */
++
++      err = pci_enable_device(pci_dev);
++      if (err) {
++              printk(KERN_INFO "forcedeth: pci_enable_dev failed: %d\n", err);
++              goto out_free;
++      }
++
++      pci_set_master(pci_dev);
++
++      err = pci_request_regions(pci_dev, dev->name);
++      if (err < 0)
++              goto out_disable;
++
++      err = -EINVAL;
++      addr = 0;
++      for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
++              dprintk(KERN_DEBUG "forcedeth: resource %d start %p len %ld flags 0x%08lx.\n",
++                              i, (void*)pci_resource_start(pci_dev, i),
++                              pci_resource_len(pci_dev, i),
++                              pci_resource_flags(pci_dev, i));
++              if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM &&
++                              pci_resource_len(pci_dev, i) >= NV_PCI_REGSZ) {
++                      addr = pci_resource_start(pci_dev, i);
++                      break;
++              }
++      }
++      if (i == DEVICE_COUNT_RESOURCE) {
++              printk(KERN_INFO "forcedeth: Couldn't find register window.\n");
++              goto out_relreg;
++      }
++
++      err = -ENOMEM;
++      dev->base_addr = (unsigned long) ioremap(addr, NV_PCI_REGSZ);
++      if (!dev->base_addr)
++              goto out_disable;
++      dev->irq = pci_dev->irq;
++      np->rx_ring = pci_alloc_consistent(pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING),
++                                              &np->ring_addr);
++      if (!np->rx_ring)
++              goto out_unmap;
++      np->tx_ring = &np->rx_ring[RX_RING];
++
++      dev->open = open;
++      dev->stop = close;
++      dev->hard_start_xmit = start_xmit;
++      dev->get_stats = get_stats;
++      dev->change_mtu = change_mtu;
++      dev->set_multicast_list = set_multicast;
++      dev->do_ioctl = nic_ioctl;
++      dev->tx_timeout = tx_timeout;
++      dev->watchdog_timeo = NV_WATCHDOG_TIMEO;
++
++      pci_set_drvdata(pci_dev, dev);
++
++      err = register_netdev(dev);
++      if (err) {
++              printk(KERN_INFO "forcedeth: unable to register netdev: %d\n", err);
++              goto out_freering;
++      }
++
++      printk(KERN_INFO "%s: forcedeth.c: subsystem: %05x:%04x\n",
++                      dev->name, pci_dev->subsystem_vendor, pci_dev->subsystem_device);
++
++
++      /* read the mac address */
++      base = get_hwbase(dev);
++      np->orig_mac[0] = readl(base + NvRegMacAddrA);
++      np->orig_mac[1] = readl(base + NvRegMacAddrB);
++
++      dev->dev_addr[0] = (np->orig_mac[1] >>  8) & 0xff;
++      dev->dev_addr[1] = (np->orig_mac[1] >>  0) & 0xff;
++      dev->dev_addr[2] = (np->orig_mac[0] >> 24) & 0xff;
++      dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
++      dev->dev_addr[4] = (np->orig_mac[0] >>  8) & 0xff;
++      dev->dev_addr[5] = (np->orig_mac[0] >>  0) & 0xff;
++
++      if (!is_valid_ether_addr(dev->dev_addr)) {
++              /*
++               * Bad mac address. At least one bios sets the mac address
++               * to 01:23:45:67:89:ab
++               */
++              printk(KERN_ERR "%s: Invalid Mac address detected: %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
++                      dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
++                      dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
++              printk(KERN_ERR "Please complain to your hardware vendor. Switching to a random MAC.\n");
++              dev->dev_addr[0] = 0x00;
++              dev->dev_addr[1] = 0x00;
++              dev->dev_addr[2] = 0x6c;
++              get_random_bytes(&dev->dev_addr[3], 3);
++      }
++
++      dprintk(KERN_DEBUG "%s: MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
++                      dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
++                      dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
++
++      np->tx_flags = cpu_to_le16(NV_TX_LASTPACKET|NV_TX_LASTPACKET1|NV_TX_VALID);
++      if (id->driver_data & DEV_NEED_LASTPACKET1)
++              np->tx_flags |= cpu_to_le16(NV_TX_LASTPACKET1);
++      if (id->driver_data & DEV_IRQMASK_1)
++              np->irqmask = NVREG_IRQMASK_WANTED_1;
++      if (id->driver_data & DEV_IRQMASK_2)
++              np->irqmask = NVREG_IRQMASK_WANTED_2;
++
++      return 0;
++
++out_freering:
++      pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING),
++                              np->rx_ring, np->ring_addr);
++out_unmap:
++      iounmap(get_hwbase(dev));
++out_relreg:
++      pci_release_regions(pci_dev);
++out_disable:
++      pci_disable_device(pci_dev);
++out_free:
++      kfree(dev);
++      pci_set_drvdata(pci_dev, NULL);
++out:
++      return err;
++}
++
++static void __devexit remove_nic(struct pci_dev *pci_dev)
++{
++      struct net_device *dev = pci_get_drvdata(pci_dev);
++      struct fe_priv *np = get_nvpriv(dev);
++      u8 *base = get_hwbase(dev);
++
++      unregister_netdev(dev);
++
++      /* special op: write back the misordered MAC address - otherwise
++       * the next probe_nic would see a wrong address.
++       */
++      writel(np->orig_mac[0], base + NvRegMacAddrA);
++      writel(np->orig_mac[1], base + NvRegMacAddrB);
++
++      /* free all structures */
++      pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), np->rx_ring, np->ring_addr);
++      iounmap(get_hwbase(dev));
++      pci_release_regions(pci_dev);
++      pci_disable_device(pci_dev);
++      kfree(dev);
++      pci_set_drvdata(pci_dev, NULL);
++}
++
++static struct pci_device_id pci_tbl[] = {
++      {       /* nForce Ethernet Controller */
++              .vendor = PCI_VENDOR_ID_NVIDIA,
++              .device = 0x1C3,
++              .subvendor = PCI_ANY_ID,
++              .subdevice = PCI_ANY_ID,
++              .driver_data = DEV_IRQMASK_1,
++      },
++      {       /* nForce2 Ethernet Controller */
++              .vendor = PCI_VENDOR_ID_NVIDIA,
++              .device = 0x0066,
++              .subvendor = PCI_ANY_ID,
++              .subdevice = PCI_ANY_ID,
++              .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2,
++      },
++      {       /* nForce3 Ethernet Controller */
++              .vendor = PCI_VENDOR_ID_NVIDIA,
++              .device = 0x00D6,
++              .subvendor = PCI_ANY_ID,
++              .subdevice = PCI_ANY_ID,
++              .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2,
++      },
++      {0,},
++};
++
++static struct pci_driver driver = {
++      .name = "forcedeth",
++      .id_table = pci_tbl,
++      .probe = probe_nic,
++      .remove = __devexit_p(remove_nic),
++};
++
++
++static int __init init_nic(void)
++{
++      printk(KERN_INFO "forcedeth.c: Reverse Engineered nForce ethernet driver. Version %s.\n", FORCEDETH_VERSION);
++      return pci_module_init(&driver);
++}
++
++static void __exit exit_nic(void)
++{
++      pci_unregister_driver(&driver);
++}
++
++MODULE_PARM(max_interrupt_work, "i");
++MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt");
++ 
++MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
++MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
++MODULE_LICENSE("GPL");
++
++MODULE_DEVICE_TABLE(pci, pci_tbl);
++
++module_init(init_nic);
++module_exit(exit_nic);
+--- linux-2.6.0/drivers/net/gt96100eth.c       2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/gt96100eth.c        2003-12-28 23:21:01.000000000 -0800
+@@ -729,10 +729,12 @@ gt96100_probe1(int port_num)
+               return -EBUSY;
+       }
+-      dev = init_etherdev(0, sizeof(struct gt96100_private));
++      dev = alloc_etherdev(sizeof(struct gt96100_private));
++      if (!dev)
++              goto out;
+       gtif->dev = dev;
+       
+-      /* private struct aligned and zeroed by init_etherdev */
++      /* private struct aligned and zeroed by alloc_etherdev */
+       /* Fill in the 'dev' fields. */
+       dev->base_addr = gtif->iobase;
+       dev->irq = gtif->irq;
+@@ -740,7 +742,7 @@ gt96100_probe1(int port_num)
+       if ((retval = parse_mac_addr(dev, gtif->mac_str))) {
+               err("%s: MAC address parse failed\n", __FUNCTION__);
+               retval = -EINVAL;
+-              goto free_region;
++              goto out1;
+       }
+       gp = dev->priv;
+@@ -768,7 +770,7 @@ gt96100_probe1(int port_num)
+                                      &gp->rx_ring_dma);
+               if (gp->rx_ring == NULL) {
+                       retval = -ENOMEM;
+-                      goto free_region;
++                      goto out1;
+               }
+       
+               gp->tx_ring = (gt96100_td_t *)(gp->rx_ring + RX_RING_SIZE);
+@@ -781,11 +783,8 @@ gt96100_probe1(int port_num)
+               gp->rx_buff = dmaalloc(PKT_BUF_SZ*RX_RING_SIZE,
+                                      &gp->rx_buff_dma);
+               if (gp->rx_buff == NULL) {
+-                      dmafree(sizeof(gt96100_rd_t) * RX_RING_SIZE
+-                              + sizeof(gt96100_td_t) * TX_RING_SIZE,
+-                              gp->rx_ring);
+                       retval = -ENOMEM;
+-                      goto free_region;
++                      goto out2;
+               }
+       }
+     
+@@ -797,12 +796,8 @@ gt96100_probe1(int port_num)
+               gp->hash_table = (char*)dmaalloc(RX_HASH_TABLE_SIZE,
+                                                &gp->hash_table_dma);
+               if (gp->hash_table == NULL) {
+-                      dmafree(sizeof(gt96100_rd_t) * RX_RING_SIZE
+-                              + sizeof(gt96100_td_t) * TX_RING_SIZE,
+-                              gp->rx_ring);
+-                      dmafree(PKT_BUF_SZ*RX_RING_SIZE, gp->rx_buff);
+                       retval = -ENOMEM;
+-                      goto free_region;
++                      goto out3;
+               }
+       }
+     
+@@ -819,14 +814,23 @@ gt96100_probe1(int port_num)
+       dev->tx_timeout = gt96100_tx_timeout;
+       dev->watchdog_timeo = GT96100ETH_TX_TIMEOUT;
+-      /* Fill in the fields of the device structure with ethernet values. */
+-      ether_setup(dev);
++      retval = register_netdev(dev);
++      if (retval)
++              goto out4;
+       return 0;
+- free_region:
+-      release_region(gtif->iobase, GT96100_ETH_IO_SIZE);
+-      unregister_netdev(dev);
++out4:
++      dmafree(RX_HASH_TABLE_SIZE, gp->hash_table_dma);
++out3:
++      dmafree(PKT_BUF_SZ*RX_RING_SIZE, gp->rx_buff);
++out2:
++      dmafree(sizeof(gt96100_rd_t) * RX_RING_SIZE
++              + sizeof(gt96100_td_t) * TX_RING_SIZE,
++              gp->rx_ring);
++out1:
+       free_netdev (dev);
++out:
++      release_region(gtif->iobase, GT96100_ETH_IO_SIZE);
+       err("%s failed.  Returns %d\n", __FUNCTION__, retval);
+       return retval;
+ }
+@@ -1573,9 +1577,14 @@ static void gt96100_cleanup_module(void)
+               if (gtif->dev != NULL) {
+                       struct gt96100_private *gp =
+                               (struct gt96100_private *)gtif->dev->priv;
+-                      release_region(gtif->iobase, gp->io_size);
+                       unregister_netdev(gtif->dev);
+-                      free_netdev (gtif->dev);
++                      dmafree(RX_HASH_TABLE_SIZE, gp->hash_table_dma);
++                      dmafree(PKT_BUF_SZ*RX_RING_SIZE, gp->rx_buff);
++                      dmafree(sizeof(gt96100_rd_t) * RX_RING_SIZE
++                              + sizeof(gt96100_td_t) * TX_RING_SIZE,
++                              gp->rx_ring);
++                      free_netdev(gtif->dev);
++                      release_region(gtif->iobase, gp->io_size);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/hamradio/baycom_epp.c      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/hamradio/baycom_epp.c       2003-12-28 23:21:01.000000000 -0800
+@@ -1275,7 +1275,7 @@ static int baycom_ioctl(struct net_devic
+  * If dev->base_addr == 2, allocate space for the device and return success
+  * (detachable devices only).
+  */
+-static int baycom_probe(struct net_device *dev)
++static void baycom_probe(struct net_device *dev)
+ {
+       static char ax25_bcast[AX25_ADDR_LEN] = {
+               'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1
+@@ -1288,9 +1288,6 @@ static int baycom_probe(struct net_devic
+       };
+       struct baycom_state *bc;
+-      if (!dev)
+-              return -ENXIO;
+-      baycom_paranoia_check(dev, "baycom_probe", -ENXIO);
+       /*
+        * not a real probe! only initialize data structures
+        */
+@@ -1332,8 +1329,6 @@ static int baycom_probe(struct net_devic
+       /* New style flags */
+       dev->flags = 0;
+-
+-      return 0;
+ }
+ /* --------------------------------------------------------------------- */
+@@ -1368,7 +1363,7 @@ static void __init baycom_epp_dev_setup(
+       /*
+        * initialize part of the device struct
+        */
+-      dev->init = baycom_probe;
++      baycom_probe(dev);
+ }
+ static int __init init_baycomepp(void)
+@@ -1401,7 +1396,7 @@ static int __init init_baycomepp(void)
+               if (register_netdev(dev)) {
+                       printk(KERN_WARNING "%s: cannot register net device %s\n", bc_drvname, dev->name);
+-                      kfree(dev);
++                      free_netdev(dev);
+                       break;
+               }
+               if (set_hw && baycom_setmode(dev->priv, mode[i]))
+--- linux-2.6.0/drivers/net/hamradio/bpqether.c        2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/hamradio/bpqether.c 2003-12-28 23:21:01.000000000 -0800
+@@ -547,7 +547,7 @@ static int bpq_new_device(struct net_dev
+  error:
+       dev_put(edev);
+-      kfree(ndev);
++      free_netdev(ndev);
+       return err;
+       
+ }
+--- linux-2.6.0/drivers/net/hamradio/dmascc.c  2003-06-14 12:18:08.000000000 -0700
++++ 25/drivers/net/hamradio/dmascc.c   2003-12-28 23:21:01.000000000 -0800
+@@ -242,7 +242,7 @@ struct scc_priv {
+ struct scc_info {
+   int irq_used;
+   int twin_serial_cfg;
+-  struct net_device dev[2];
++  struct net_device *dev[2];
+   struct scc_priv priv[2];
+   struct scc_info *next;
+   spinlock_t register_lock;   /* Per device register lock */
+@@ -310,18 +310,19 @@ static void __exit dmascc_exit(void) {
+     info = first;
+     /* Unregister devices */
+-    for (i = 0; i < 2; i++) {
+-      if (info->dev[i].name)
+-      unregister_netdev(&info->dev[i]);
+-    }
++    for (i = 0; i < 2; i++)
++      unregister_netdev(info->dev[i]);
+     /* Reset board */
+     if (info->priv[0].type == TYPE_TWIN)
+-      outb(0, info->dev[0].base_addr + TWIN_SERIAL_CFG);
++      outb(0, info->dev[0]->base_addr + TWIN_SERIAL_CFG);
+     write_scc(&info->priv[0], R9, FHWRES);
+-    release_region(info->dev[0].base_addr,
++    release_region(info->dev[0]->base_addr,
+                  hw[info->priv[0].type].io_size);
++    for (i = 0; i < 2; i++)
++      free_netdev(info->dev[i]);
++
+     /* Free memory */
+     first = info->next;
+     kfree(info);
+@@ -443,156 +444,193 @@ static int __init dmascc_init(void) {
+ module_init(dmascc_init);
+ module_exit(dmascc_exit);
++static void dev_setup(struct net_device *dev)
++{
++      dev->type = ARPHRD_AX25;
++      dev->hard_header_len = 73;
++      dev->mtu = 1500;
++      dev->addr_len = 7;
++      dev->tx_queue_len = 64;
++      memcpy(dev->broadcast, ax25_broadcast, 7);
++      memcpy(dev->dev_addr, ax25_test, 7);
++}
++
++static int __init setup_adapter(int card_base, int type, int n)
++{
++      int i, irq, chip;
++      struct scc_info *info;
++      struct net_device *dev;
++      struct scc_priv *priv;
++      unsigned long time;
++      unsigned int irqs;
++      int tmr_base = card_base + hw[type].tmr_offset;
++      int scc_base = card_base + hw[type].scc_offset;
++      char *chipnames[] = CHIPNAMES;
++
++      /* Allocate memory */
++      info = kmalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA);
++      if (!info) {
++              printk(KERN_ERR "dmascc: "
++                      "could not allocate memory for %s at %#3x\n",
++                      hw[type].name, card_base);
++              goto out;
++      }
+-int __init setup_adapter(int card_base, int type, int n) {
+-  int i, irq, chip;
+-  struct scc_info *info;
+-  struct net_device *dev;
+-  struct scc_priv *priv;
+-  unsigned long time;
+-  unsigned int irqs;
+-  int tmr_base = card_base + hw[type].tmr_offset;
+-  int scc_base = card_base + hw[type].scc_offset;
+-  char *chipnames[] = CHIPNAMES;
+-
+-  /* Allocate memory */
+-  info = kmalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA);
+-  if (!info) {
+-    printk(KERN_ERR "dmascc: could not allocate memory for %s at %#3x\n",
+-         hw[type].name, card_base);
+-    return -1;
+-  }
+-
+-  /* Initialize what is necessary for write_scc and write_scc_data */
+-  memset(info, 0, sizeof(struct scc_info));
+-  spin_lock_init(&info->register_lock);
+-  
+-  priv = &info->priv[0];
+-  priv->type = type;
+-  priv->card_base = card_base;
+-  priv->scc_cmd = scc_base + SCCA_CMD;
+-  priv->scc_data = scc_base + SCCA_DATA;
+-  priv->register_lock = &info->register_lock;
+-
+-  /* Reset SCC */
+-  write_scc(priv, R9, FHWRES | MIE | NV);
+-
+-  /* Determine type of chip by enabling SDLC/HDLC enhancements */
+-  write_scc(priv, R15, SHDLCE);
+-  if (!read_scc(priv, R15)) {
+-    /* WR7' not present. This is an ordinary Z8530 SCC. */
+-    chip = Z8530;
+-  } else {
+-    /* Put one character in TX FIFO */
+-    write_scc_data(priv, 0, 0);
+-    if (read_scc(priv, R0) & Tx_BUF_EMP) {
+-      /* TX FIFO not full. This is a Z85230 ESCC with a 4-byte FIFO. */
+-      chip = Z85230;
+-    } else {
+-      /* TX FIFO full. This is a Z85C30 SCC with a 1-byte FIFO. */
+-      chip = Z85C30;
+-    }
+-  }
+-  write_scc(priv, R15, 0);
++      /* Initialize what is necessary for write_scc and write_scc_data */
++      memset(info, 0, sizeof(struct scc_info));
+-  /* Start IRQ auto-detection */
+-  irqs = probe_irq_on();
++      info->dev[0] = alloc_netdev(0, "", dev_setup);
++      if (!info->dev[0]) {
++              printk(KERN_ERR "dmascc: "
++                      "could not allocate memory for %s at %#3x\n",
++                      hw[type].name, card_base);
++              goto out1;
++      }
+-  /* Enable interrupts */
+-  if (type == TYPE_TWIN) {
+-    outb(0, card_base + TWIN_DMA_CFG);
+-    inb(card_base + TWIN_CLR_TMR1);
+-    inb(card_base + TWIN_CLR_TMR2);
+-    outb((info->twin_serial_cfg = TWIN_EI), card_base + TWIN_SERIAL_CFG);
+-  } else {
+-    write_scc(priv, R15, CTSIE);
+-    write_scc(priv, R0, RES_EXT_INT);
+-    write_scc(priv, R1, EXT_INT_ENAB);
+-  }
+-
+-  /* Start timer */
+-  outb(1, tmr_base + TMR_CNT1);
+-  outb(0, tmr_base + TMR_CNT1);
+-
+-  /* Wait and detect IRQ */
+-  time = jiffies; while (jiffies - time < 2 + HZ / TMR_0_HZ);
+-  irq = probe_irq_off(irqs);
+-
+-  /* Clear pending interrupt, disable interrupts */
+-  if (type == TYPE_TWIN) {
+-    inb(card_base + TWIN_CLR_TMR1);
+-  } else {
+-    write_scc(priv, R1, 0);
+-    write_scc(priv, R15, 0);
+-    write_scc(priv, R0, RES_EXT_INT);
+-  }
++      info->dev[1] = alloc_netdev(0, "", dev_setup);
++      if (!info->dev[1]) {
++              printk(KERN_ERR "dmascc: "
++                      "could not allocate memory for %s at %#3x\n",
++                      hw[type].name, card_base);
++              goto out2;
++      }
++      spin_lock_init(&info->register_lock);
+-  if (irq <= 0) {
+-    printk(KERN_ERR "dmascc: could not find irq of %s at %#3x (irq=%d)\n",
+-         hw[type].name, card_base, irq);
+-    kfree(info);
+-    return -1;
+-  }
++      priv = &info->priv[0];
++      priv->type = type;
++      priv->card_base = card_base;
++      priv->scc_cmd = scc_base + SCCA_CMD;
++      priv->scc_data = scc_base + SCCA_DATA;
++      priv->register_lock = &info->register_lock;
++
++      /* Reset SCC */
++      write_scc(priv, R9, FHWRES | MIE | NV);
++
++      /* Determine type of chip by enabling SDLC/HDLC enhancements */
++      write_scc(priv, R15, SHDLCE);
++      if (!read_scc(priv, R15)) {
++              /* WR7' not present. This is an ordinary Z8530 SCC. */
++              chip = Z8530;
++      } else {
++              /* Put one character in TX FIFO */
++              write_scc_data(priv, 0, 0);
++              if (read_scc(priv, R0) & Tx_BUF_EMP) {
++                      /* TX FIFO not full. This is a Z85230 ESCC with a 4-byte FIFO. */
++                      chip = Z85230;
++              } else {
++                      /* TX FIFO full. This is a Z85C30 SCC with a 1-byte FIFO. */
++                      chip = Z85C30;
++              }
++      }
++      write_scc(priv, R15, 0);
+-  /* Set up data structures */
+-  for (i = 0; i < 2; i++) {
+-    dev = &info->dev[i];
+-    priv = &info->priv[i];
+-    priv->type = type;
+-    priv->chip = chip;
+-    priv->dev = dev;
+-    priv->info = info;
+-    priv->channel = i;
+-    spin_lock_init(&priv->ring_lock);
+-    priv->register_lock = &info->register_lock;
+-    priv->card_base = card_base;
+-    priv->scc_cmd = scc_base + (i ? SCCB_CMD : SCCA_CMD);
+-    priv->scc_data = scc_base + (i ? SCCB_DATA : SCCA_DATA);
+-    priv->tmr_cnt = tmr_base + (i ? TMR_CNT2 : TMR_CNT1);
+-    priv->tmr_ctrl = tmr_base + TMR_CTRL;
+-    priv->tmr_mode = i ? 0xb0 : 0x70;
+-    priv->param.pclk_hz = hw[type].pclk_hz;
+-    priv->param.brg_tc = -1;
+-    priv->param.clocks = TCTRxCP | RCRTxCP;
+-    priv->param.persist = 256;
+-    priv->param.dma = -1;
+-    INIT_WORK(&priv->rx_work, rx_bh, priv);
+-    dev->priv = priv;
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+-    if (sizeof(dev->name) == sizeof(char *)) dev->name = priv->name;
+-#endif
+-    sprintf(dev->name, "dmascc%i", 2*n+i);
+-    SET_MODULE_OWNER(dev);
+-    dev->base_addr = card_base;
+-    dev->irq = irq;
+-    dev->open = scc_open;
+-    dev->stop = scc_close;
+-    dev->do_ioctl = scc_ioctl;
+-    dev->hard_start_xmit = scc_send_packet;
+-    dev->get_stats = scc_get_stats;
+-    dev->hard_header = ax25_encapsulate;
+-    dev->rebuild_header = ax25_rebuild_header;
+-    dev->set_mac_address = scc_set_mac_address;
+-    dev->type = ARPHRD_AX25;
+-    dev->hard_header_len = 73;
+-    dev->mtu = 1500;
+-    dev->addr_len = 7;
+-    dev->tx_queue_len = 64;
+-    memcpy(dev->broadcast, ax25_broadcast, 7);
+-    memcpy(dev->dev_addr, ax25_test, 7);
+-    rtnl_lock();
+-    if (register_netdevice(dev)) {
+-      printk(KERN_ERR "dmascc: could not register %s\n", dev->name);
+-    }
+-    rtnl_unlock();
+-  }
++      /* Start IRQ auto-detection */
++      irqs = probe_irq_on();
++      /* Enable interrupts */
++      if (type == TYPE_TWIN) {
++              outb(0, card_base + TWIN_DMA_CFG);
++              inb(card_base + TWIN_CLR_TMR1);
++              inb(card_base + TWIN_CLR_TMR2);
++              info->twin_serial_cfg = TWIN_EI;
++              outb(info->twin_serial_cfg, card_base + TWIN_SERIAL_CFG);
++      } else {
++              write_scc(priv, R15, CTSIE);
++              write_scc(priv, R0, RES_EXT_INT);
++              write_scc(priv, R1, EXT_INT_ENAB);
++      }
+-  info->next = first;
+-  first = info;
+-  printk(KERN_INFO "dmascc: found %s (%s) at %#3x, irq %d\n", hw[type].name,
+-       chipnames[chip], card_base, irq);
+-  return 0;
++      /* Start timer */
++      outb(1, tmr_base + TMR_CNT1);
++      outb(0, tmr_base + TMR_CNT1);
++
++      /* Wait and detect IRQ */
++      time = jiffies; while (jiffies - time < 2 + HZ / TMR_0_HZ);
++      irq = probe_irq_off(irqs);
++
++      /* Clear pending interrupt, disable interrupts */
++      if (type == TYPE_TWIN) {
++              inb(card_base + TWIN_CLR_TMR1);
++      } else {
++              write_scc(priv, R1, 0);
++              write_scc(priv, R15, 0);
++              write_scc(priv, R0, RES_EXT_INT);
++      }
++
++      if (irq <= 0) {
++              printk(KERN_ERR "dmascc: could not find irq of %s at %#3x (irq=%d)\n",
++                      hw[type].name, card_base, irq);
++              goto out3;
++      }
++
++      /* Set up data structures */
++      for (i = 0; i < 2; i++) {
++              dev = info->dev[i];
++              priv = &info->priv[i];
++              priv->type = type;
++              priv->chip = chip;
++              priv->dev = dev;
++              priv->info = info;
++              priv->channel = i;
++              spin_lock_init(&priv->ring_lock);
++              priv->register_lock = &info->register_lock;
++              priv->card_base = card_base;
++              priv->scc_cmd = scc_base + (i ? SCCB_CMD : SCCA_CMD);
++              priv->scc_data = scc_base + (i ? SCCB_DATA : SCCA_DATA);
++              priv->tmr_cnt = tmr_base + (i ? TMR_CNT2 : TMR_CNT1);
++              priv->tmr_ctrl = tmr_base + TMR_CTRL;
++              priv->tmr_mode = i ? 0xb0 : 0x70;
++              priv->param.pclk_hz = hw[type].pclk_hz;
++              priv->param.brg_tc = -1;
++              priv->param.clocks = TCTRxCP | RCRTxCP;
++              priv->param.persist = 256;
++              priv->param.dma = -1;
++              INIT_WORK(&priv->rx_work, rx_bh, priv);
++              dev->priv = priv;
++              sprintf(dev->name, "dmascc%i", 2*n+i);
++              SET_MODULE_OWNER(dev);
++              dev->base_addr = card_base;
++              dev->irq = irq;
++              dev->open = scc_open;
++              dev->stop = scc_close;
++              dev->do_ioctl = scc_ioctl;
++              dev->hard_start_xmit = scc_send_packet;
++              dev->get_stats = scc_get_stats;
++              dev->hard_header = ax25_encapsulate;
++              dev->rebuild_header = ax25_rebuild_header;
++              dev->set_mac_address = scc_set_mac_address;
++      }
++      if (register_netdev(info->dev[0])) {
++              printk(KERN_ERR "dmascc: could not register %s\n",
++                              info->dev[0]->name);
++              goto out3;
++      }
++      if (register_netdev(info->dev[1])) {
++              printk(KERN_ERR "dmascc: could not register %s\n",
++                              info->dev[1]->name);
++              goto out4;
++      }
++
++
++      info->next = first;
++      first = info;
++      printk(KERN_INFO "dmascc: found %s (%s) at %#3x, irq %d\n", hw[type].name,
++      chipnames[chip], card_base, irq);
++      return 0;
++
++out4:
++      unregister_netdev(info->dev[0]);
++out3:
++      if (info->priv[0].type == TYPE_TWIN)
++              outb(0, info->dev[0]->base_addr + TWIN_SERIAL_CFG);
++      write_scc(&info->priv[0], R9, FHWRES);
++      free_netdev(info->dev[1]);
++out2:
++      free_netdev(info->dev[0]);
++out1:
++      kfree(info);
++out:
++      return -1;
+ }
+--- linux-2.6.0/drivers/net/hamradio/hdlcdrv.c 2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/hamradio/hdlcdrv.c  2003-12-28 23:21:01.000000000 -0800
+@@ -832,7 +832,7 @@ struct net_device *hdlcdrv_register(cons
+       if (err < 0) {
+               printk(KERN_WARNING "hdlcdrv: cannot register net "
+                      "device %s\n", dev->name);
+-              kfree(dev);
++              free_netdev(dev);
+               dev = ERR_PTR(err);
+       }
+       return dev;
+--- linux-2.6.0/drivers/net/hamradio/scc.c     2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/hamradio/scc.c      2003-12-28 23:22:33.000000000 -0800
+@@ -1196,11 +1196,7 @@ static void t_tail(unsigned long channel
+       if (scc->stat.tx_state == TXS_TIMEOUT)          /* we had a timeout? */
+       {
+               scc->stat.tx_state = TXS_WAIT;
+-
+-              if (scc->kiss.mintime != TIMER_OFF)     /* try it again */
+-                      scc_start_tx_timer(scc, t_dwait, scc->kiss.mintime*100);
+-              else
+-                      scc_start_tx_timer(scc, t_dwait, 0);
++              scc_start_tx_timer(scc, t_dwait, scc->kiss.mintime*100);
+               return;
+       }
+       
+@@ -1274,8 +1270,7 @@ static void t_idle(unsigned long channel
+       del_timer(&scc->tx_wdog);
+       scc_key_trx(scc, TX_OFF);
+-
+-      if (scc->kiss.mintime != TIMER_OFF)
++      if(scc->kiss.mintime)
+               scc_start_tx_timer(scc, t_dwait, scc->kiss.mintime*100);
+       scc->stat.tx_state = TXS_WAIT;
+ }
+--- linux-2.6.0/drivers/net/hamradio/yam.c     2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/hamradio/yam.c      2003-12-28 23:21:01.000000000 -0800
+@@ -1192,7 +1192,7 @@ static void __exit yam_cleanup_driver(vo
+               struct net_device *dev = yam_devs[i];
+               if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(dev);
++                      free_netdev(dev);
+               }
+       }
+--- linux-2.6.0/drivers/net/hp100.c    2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/hp100.c     2003-12-28 23:21:01.000000000 -0800
+@@ -118,8 +118,6 @@
+ #include <asm/bitops.h>
+ #include <asm/io.h>
+-typedef struct net_device_stats hp100_stats_t;
+-
+ #include "hp100.h"
+ /*
+@@ -130,23 +128,8 @@ typedef struct net_device_stats hp100_st
+ #define HP100_BUS_EISA    1
+ #define HP100_BUS_PCI     2
+-#ifndef PCI_DEVICE_ID_HP_J2585B
+-#define PCI_DEVICE_ID_HP_J2585B 0x1031
+-#endif
+-#ifndef PCI_VENDOR_ID_COMPEX
+-#define PCI_VENDOR_ID_COMPEX 0x11f6
+-#endif
+-#ifndef PCI_DEVICE_ID_COMPEX_ENET100VG4
+-#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112
+-#endif
+-#ifndef PCI_VENDOR_ID_COMPEX2
+-#define PCI_VENDOR_ID_COMPEX2 0x101a
+-#endif
+-#ifndef PCI_DEVICE_ID_COMPEX2_100VG
+-#define PCI_DEVICE_ID_COMPEX2_100VG 0x0005
+-#endif
+-
+ #define HP100_REGION_SIZE     0x20    /* for ioports */
++#define HP100_SIG_LEN         8       /* same as EISA_SIG_LEN */
+ #define HP100_MAX_PACKET_SIZE (1536+4)
+ #define HP100_MIN_PACKET_SIZE 60
+@@ -165,20 +148,9 @@ typedef struct net_device_stats hp100_st
+  *  structures
+  */
+-struct hp100_eisa_id {
+-      u_int id;
+-      const char *name;
+-      u_char bus;
+-};
+-
+-struct hp100_pci_id {
+-      u_short vendor;
+-      u_short device;
+-};
+-
+ struct hp100_private {
+-      struct hp100_eisa_id *id;
+       spinlock_t lock;
++      char id[HP100_SIG_LEN];
+       u_short chip;
+       u_short soft_model;
+       u_int memory_size;
+@@ -196,7 +168,7 @@ struct hp100_private {
+       u_char mac1_mode;
+       u_char mac2_mode;
+       u_char hash_bytes[8];
+-      hp100_stats_t stats;
++      struct net_device_stats stats;
+       /* Rings for busmaster mode: */
+       hp100_ring_t *rxrhead;  /* Head (oldest) index into rxring */
+@@ -216,83 +188,36 @@ struct hp100_private {
+ /*
+  *  variables
+  */
+-
+-static struct hp100_eisa_id hp100_eisa_ids[] = {
+-
+-      /* 10/100 EISA card with revision A Cascade chip */
+-      {0x80F1F022, "HP J2577 rev A", HP100_BUS_EISA},
+-
+-      /* 10/100 ISA card with revision A Cascade chip */
+-      {0x50F1F022, "HP J2573 rev A", HP100_BUS_ISA},
+-
+-      /* 10 only EISA card with Cascade chip */
+-      {0x2019F022, "HP 27248B", HP100_BUS_EISA},
+-
+-      /* 10/100 EISA card with Cascade chip */
+-      {0x4019F022, "HP J2577", HP100_BUS_EISA},
+-
+-      /* 10/100 ISA card with Cascade chip */
+-      {0x5019F022, "HP J2573", HP100_BUS_ISA},
+-
+-      /* 10/100 EISA card with AT&T chip */
+-      {0x9019f022, "HP J2577", HP100_BUS_EISA },
+-
+-      /* 10/100 PCI card - old J2585A */
+-      {0x1030103c, "HP J2585A", HP100_BUS_PCI},
+-
+-      /* 10/100 PCI card - new J2585B - master capable */
+-      {0x1041103c, "HP J2585B", HP100_BUS_PCI},
+-
+-      /* 10 Mbit Combo Adapter */
+-      {0x1042103c, "HP J2970", HP100_BUS_PCI},
+-
+-      /* 10 Mbit 10baseT Adapter */
+-      {0x1040103c, "HP J2973", HP100_BUS_PCI},
+-
+-      /* 10/100 EISA card from Compex */
+-      {0x0103180e, "ReadyLink ENET100-VG4", HP100_BUS_EISA},
+-
+-      /* 10/100 EISA card from Compex - FreedomLine (sq5bpf) */
+-      /* Note: plhbrod@mbox.vol.cz reported that same ID have ISA */
+-      /*       version of adapter, too... */
+-      {0x0104180e, "FreedomLine 100/VG", HP100_BUS_EISA},
+-
+-      /* 10/100 PCI card from Compex - FreedomLine
+-       *
+-       * I think this card doesn't like aic7178 scsi controller, but
+-       * I haven't tested this much. It works fine on diskless machines.
+-       *                            Jacek Lipkowski <sq5bpf@acid.ch.pw.edu.pl>
+-       */
+-      {0x021211f6, "FreedomLine 100/VG", HP100_BUS_PCI},
+-
+-      /* 10/100 PCI card from Compex (J2585A compatible) */
+-      {0x011211f6, "ReadyLink ENET100-VG4", HP100_BUS_PCI},
+-      
+-      /* 10/100 PCI card from KTI */
+-      {0x40008e2e, "KTI DP-200", HP100_BUS_PCI }
++static const char *hp100_isa_tbl[] = {
++      "HWPF150", /* HP J2573 rev A */
++      "HWP1950", /* HP J2573 */
+ };
+-#define HP100_EISA_IDS_SIZE   (sizeof(hp100_eisa_ids)/sizeof(struct hp100_eisa_id))
+-
+-#ifdef CONFIG_PCI
+-static struct hp100_pci_id hp100_pci_ids[] = {
+-      {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A},
+-      {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B},
+-      {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4},
+-      {PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG}
++#ifdef CONFIG_EISA
++static struct eisa_device_id hp100_eisa_tbl[] = {
++      { "HWPF180" }, /* HP J2577 rev A */
++      { "HWP1920" }, /* HP 27248B */
++      { "HWP1940" }, /* HP J2577 */
++      { "HWP1990" }, /* HP J2577 */
++      { "CPX0301" }, /* ReadyLink ENET100-VG4 */
++      { "CPX0401" }, /* FreedomLine 100/VG */
+ };
++MODULE_DEVICE_TABLE(eisa, hp100_eisa_tbl);
+ #endif
+-#define HP100_PCI_IDS_SIZE    (sizeof(hp100_pci_ids)/sizeof(struct hp100_pci_id))
+-
++#ifdef CONFIG_PCI
+ static struct pci_device_id hp100_pci_tbl[] = {
+       {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID,},
+       {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID,},
++      {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2970A, PCI_ANY_ID, PCI_ANY_ID,},
++      {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2973A, PCI_ANY_ID, PCI_ANY_ID,},
+       {PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4, PCI_ANY_ID, PCI_ANY_ID,},
+       {PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG, PCI_ANY_ID, PCI_ANY_ID,},
++/*    {PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_DP200, PCI_ANY_ID, PCI_ANY_ID }, */
+       {}                      /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(pci, hp100_pci_tbl);
++#endif
+ static int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO;
+ static int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX;
+@@ -316,7 +241,7 @@ static int hp100_start_xmit(struct sk_bu
+ static int hp100_start_xmit_bm(struct sk_buff *skb,
+                              struct net_device *dev);
+ static void hp100_rx(struct net_device *dev);
+-static hp100_stats_t *hp100_get_stats(struct net_device *dev);
++static struct net_device_stats *hp100_get_stats(struct net_device *dev);
+ static void hp100_misc_interrupt(struct net_device *dev);
+ static void hp100_update_stats(struct net_device *dev);
+ static void hp100_clear_stats(struct hp100_private *lp, int ioaddr);
+@@ -370,196 +295,180 @@ static void wait(void)
+  *  since this could cause problems when the card is not installed.
+  */
+-int __init hp100_probe(struct net_device *dev)
++/*
++ * Read board id and convert to string.
++ * Effectively same code as decode_eisa_sig
++ */
++static __init const char *hp100_read_id(int ioaddr)
+ {
+-      int base_addr = dev ? dev->base_addr : 0;
+-      int ioaddr = 0;
+-      int pci_start_index = 0;
++      int i;
++      static char str[HP100_SIG_LEN];
++      unsigned char sig[4], sum;
++        unsigned short rev;
+-#ifdef HP100_DEBUG_B
+-      hp100_outw(0x4200, TRACE);
+-      printk("hp100: %s: probe\n", dev->name);
+-#endif
++      hp100_page(ID_MAC_ADDR);
++      sum = 0;
++      for (i = 0; i < 4; i++) {
++              sig[i] = hp100_inb(BOARD_ID + i);
++              sum += sig[i];
++      }
+-      if (base_addr > 0xff) { /* Check a single specified location. */
+-              if (check_region(base_addr, HP100_REGION_SIZE))
+-                      return -EINVAL;
+-              if (base_addr < 0x400)
+-                      return hp100_probe1(dev, base_addr, HP100_BUS_ISA,
+-                                          NULL);
+-              if (EISA_bus && base_addr >= 0x1c38 && ((base_addr - 0x1c38) & 0x3ff) == 0)
+-                      return hp100_probe1(dev, base_addr, HP100_BUS_EISA, NULL);
+-#ifdef CONFIG_PCI
+-              printk("hp100: %s: You must specify card # in i/o address parameter for PCI bus...", dev->name);
+-#else
+-              return -ENODEV;
+-#endif
+-      } else
+-#ifdef CONFIG_PCI
+-              if (base_addr > 0 && base_addr < 8 + 1)
+-                      pci_start_index = 0x100 | (base_addr - 1);
+-        else
+-#endif
+-              if (base_addr != 0)
+-                      return -ENXIO;
++      sum += hp100_inb(BOARD_ID + i);
++      if (sum != 0xff)
++              return NULL;    /* bad checksum */
+-      /* First: scan PCI bus(es) */
++        str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
++        str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
++        str[2] = (sig[1] & 0x1f) + ('A' - 1);
++        rev = (sig[2] << 8) | sig[3];
++        sprintf(str + 3, "%04X", rev);
+-#ifdef CONFIG_PCI
+-      {
+-              int pci_index;
+-              struct pci_dev *pci_dev = NULL;
+-              int pci_id_index;
+-              u_short pci_command;
+-
+-#ifdef HP100_DEBUG_PCI
+-              printk("hp100: %s: PCI BIOS is present, checking for devices..\n", dev->name);
+-#endif
+-              pci_index = 0;
+-              for (pci_id_index = 0; pci_id_index < HP100_PCI_IDS_SIZE;
+-                   pci_id_index++) {
+-                      while ((pci_dev = pci_find_device(hp100_pci_ids[pci_id_index].vendor,
+-                                                        hp100_pci_ids[pci_id_index].device,
+-                                                        pci_dev)) != NULL) {
+-                              if (pci_index < (pci_start_index & 7)) {
+-                                      pci_index++;
+-                                      continue;
+-                              }
+-                              if (pci_enable_device(pci_dev))
+-                                      continue;
+-                              /* found... */
+-                              ioaddr = pci_resource_start(pci_dev, 0);
+-                              if (check_region(ioaddr, HP100_REGION_SIZE))
+-                                      continue;
+-                              pci_read_config_word(pci_dev, PCI_COMMAND, &pci_command);
+-                              if (!(pci_command & PCI_COMMAND_IO)) {
+-#ifdef HP100_DEBUG
+-                                      printk("hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name);
+-#endif
+-                                      pci_command |= PCI_COMMAND_IO;
+-                                      pci_write_config_word(pci_dev, PCI_COMMAND, pci_command);
+-                              }
+-                              if (!(pci_command & PCI_COMMAND_MASTER)) {
+-#ifdef HP100_DEBUG
+-                                      printk("hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name);
+-#endif
+-                                      pci_command |= PCI_COMMAND_MASTER;
+-                                      pci_write_config_word(pci_dev, PCI_COMMAND, pci_command);
+-                              }
+-#ifdef HP100_DEBUG
+-                              printk("hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr);
+-#endif
+-                              if (hp100_probe1(dev, ioaddr, HP100_BUS_PCI, pci_dev) == 0)
+-                                      return 0;
+-                      }
+-              }
+-      }
+-      if (pci_start_index > 0)
+-              return -ENODEV;
+-#endif /* CONFIG_PCI */
++      return str;
++}
+-      /* Second: Probe all EISA possible port regions (if EISA bus present) */
+-      for (ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400) {
+-              if (check_region(ioaddr, HP100_REGION_SIZE))
+-                      continue;
+-              if (hp100_probe1(dev, ioaddr, HP100_BUS_EISA, NULL) == 0)
+-                      return 0;
+-      }
++static __init int hp100_isa_probe1(struct net_device *dev, int addr)
++{
++      const char *sig;
++      int i;
++
++      if (!request_region(addr, HP100_REGION_SIZE, "hp100"))
++              goto err;
++
++      sig = hp100_read_id(addr);
++      release_region(addr, HP100_REGION_SIZE);
++
++      if (sig == NULL)
++              goto err;
++
++      for (i = 0; i < ARRAY_SIZE(hp100_isa_tbl); i++) {
++              if (!strcmp(hp100_isa_tbl[i], sig)) 
++                      break;
+-      /* Third: Probe all ISA possible port regions */
+-      for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) {
+-              if (check_region(ioaddr, HP100_REGION_SIZE))
+-                      continue;
+-              if (hp100_probe1(dev, ioaddr, HP100_BUS_ISA, NULL) == 0)
+-                      return 0;
+       }
++      if (i < ARRAY_SIZE(hp100_isa_tbl))
++              return hp100_probe1(dev, addr, HP100_BUS_ISA, NULL);
++ err:
+       return -ENODEV;
++
++}
++/*
++ * Probe for ISA board.
++ * EISA and PCI are handled by device infrastructure.
++ */
++
++static int  __init hp100_isa_probe(struct net_device *dev, int addr)
++{
++      int err = -ENODEV;
++
++      /* Probe for a specific ISA address */          
++      if (addr > 0xff && addr < 0x400)
++              err = hp100_isa_probe1(dev, addr);
++
++      else if (addr != 0) 
++              err = -ENXIO;
++
++      else {
++              /* Probe all ISA possible port regions */
++              for (addr = 0x100; addr < 0x400; addr += 0x20) {
++                      err = hp100_isa_probe1(dev, addr);
++                      if (!err)
++                              break;
++              }
++      }
++      return err;
++}
++
++
++struct net_device * __init hp100_probe(int unit)
++{
++      struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENODEV);
++
++      SET_MODULE_OWNER(dev);
++
++#ifdef HP100_DEBUG_B
++      hp100_outw(0x4200, TRACE);
++      printk("hp100: %s: probe\n", dev->name);
++#endif
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
++
++      err = hp100_isa_probe(dev, dev->base_addr);
++      if (err)
++              goto out;
++
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++ out1:
++      release_region(dev->base_addr, HP100_REGION_SIZE);
++ out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
+                              u_char bus, struct pci_dev *pci_dev)
+ {
+       int i;
+-
+-      u_char uc, uc_1;
+-      u_int eisa_id;
++      int err = -ENODEV;
++      const char *eid;
+       u_int chip;
++      u_char uc;
+       u_int memory_size = 0, virt_memory_size = 0;
+       u_short local_mode, lsw;
+       short mem_mapped;
+       unsigned long mem_ptr_phys;
+       void **mem_ptr_virt;
+       struct hp100_private *lp;
+-      struct hp100_eisa_id *eid;
+ #ifdef HP100_DEBUG_B
+       hp100_outw(0x4201, TRACE);
+       printk("hp100: %s: probe1\n", dev->name);
+ #endif
+-      if (dev == NULL) {
+-#ifdef HP100_DEBUG
+-              printk("hp100_probe1: %s: dev == NULL ?\n", dev->name);
+-#endif
+-              return -EIO;
+-      }
++      /* memory region for programmed i/o */
++      if (!request_region(ioaddr, HP100_REGION_SIZE, "hp100"))
++              goto out1;
+-      if (hp100_inw(HW_ID) != HP100_HW_ID_CASCADE) {
+-              return -ENODEV;
+-      } else {
+-              chip = hp100_inw(PAGING) & HP100_CHIPID_MASK;
++      if (hp100_inw(HW_ID) != HP100_HW_ID_CASCADE) 
++              goto out2;
++
++      chip = hp100_inw(PAGING) & HP100_CHIPID_MASK;
+ #ifdef HP100_DEBUG
+-              if (chip == HP100_CHIPID_SHASTA)
+-                      printk("hp100: %s: Shasta Chip detected. (This is a pre 802.12 chip)\n", dev->name);
+-              else if (chip == HP100_CHIPID_RAINIER)
+-                      printk("hp100: %s: Rainier Chip detected. (This is a pre 802.12 chip)\n", dev->name);
+-              else if (chip == HP100_CHIPID_LASSEN)
+-                      printk("hp100: %s: Lassen Chip detected.\n", dev->name);
+-              else
+-                      printk("hp100: %s: Warning: Unknown CASCADE chip (id=0x%.4x).\n", dev->name, chip);
++      if (chip == HP100_CHIPID_SHASTA)
++              printk("hp100: %s: Shasta Chip detected. (This is a pre 802.12 chip)\n", dev->name);
++      else if (chip == HP100_CHIPID_RAINIER)
++              printk("hp100: %s: Rainier Chip detected. (This is a pre 802.12 chip)\n", dev->name);
++      else if (chip == HP100_CHIPID_LASSEN)
++              printk("hp100: %s: Lassen Chip detected.\n", dev->name);
++      else
++              printk("hp100: %s: Warning: Unknown CASCADE chip (id=0x%.4x).\n", dev->name, chip);
+ #endif
+-      }
+       dev->base_addr = ioaddr;
+-      hp100_page(ID_MAC_ADDR);
+-      for (i = uc = eisa_id = 0; i < 4; i++) {
+-              eisa_id >>= 8;
+-              uc_1 = hp100_inb(BOARD_ID + i);
+-              eisa_id |= uc_1 << 24;
+-              uc += uc_1;
+-      }
+-      uc += hp100_inb(BOARD_ID + 4);
+-
+-      if (uc != 0xff) {       /* bad checksum? */
+-              printk("hp100_probe: %s: bad EISA ID checksum at base port 0x%x\n", dev->name, ioaddr);
+-              return -ENODEV;
+-      }
+-
+-      for (i = 0; i < HP100_EISA_IDS_SIZE; i++)
+-              if (hp100_eisa_ids[i].id == eisa_id)
+-                      break;
+-      if (i >= HP100_EISA_IDS_SIZE) {
+-              for (i = 0; i < HP100_EISA_IDS_SIZE; i++)
+-                      if ((hp100_eisa_ids[i].id & 0xf0ffffff) == (eisa_id & 0xf0ffffff))
+-                              break;
+-              if (i >= HP100_EISA_IDS_SIZE) {
+-                      printk ("hp100_probe: %s: card at port 0x%x isn't known (id = 0x%x)\n", dev->name, ioaddr, eisa_id);
+-                      return -ENODEV;
+-              }
+-      }
+-      eid = &hp100_eisa_ids[i];
+-      if ((eid->id & 0x0f000000) < (eisa_id & 0x0f000000)) {
+-              printk("hp100_probe: %s: newer version of card %s at port 0x%x - unsupported\n", dev->name, eid->name, ioaddr);
+-              return -ENODEV;
++      eid = hp100_read_id(ioaddr);
++      if (eid == NULL) {      /* bad checksum? */
++              printk(KERN_WARNING "hp100_probe: bad ID checksum at base port 0x%x\n", ioaddr);
++              goto out2;
+       }
++      hp100_page(ID_MAC_ADDR);
+       for (i = uc = 0; i < 7; i++)
+               uc += hp100_inb(LAN_ADDR + i);
+       if (uc != 0xff) {
+-              printk("hp100_probe: %s: bad lan address checksum (card %s at port 0x%x)\n", dev->name, eid->name, ioaddr);
+-              return -EIO;
++              printk(KERN_WARNING "hp100_probe: bad lan address checksum at port 0x%x)\n", ioaddr);
++              err = -EIO;
++              goto out2;
+       }
+       /* Make sure, that all registers are correctly updated... */
+@@ -607,17 +516,17 @@ static int __init hp100_probe1(struct ne
+               hp100_outw(HP100_MEM_EN | HP100_RESET_LB, OPTION_LSW);
+               hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW);
+               hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_RESET_HB, OPTION_LSW);
+-              printk("hp100: %s: IO mapped mode forced.\n", dev->name);
++              printk("hp100: IO mapped mode forced.\n");
+       } else if (local_mode == 2) {
+               hp100_outw(HP100_MEM_EN | HP100_SET_LB, OPTION_LSW);
+               hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW);
+               hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_RESET_HB, OPTION_LSW);
+-              printk("hp100: %s: Shared memory mode requested.\n", dev->name);
++              printk("hp100: Shared memory mode requested.\n");
+       } else if (local_mode == 4) {
+               if (chip == HP100_CHIPID_LASSEN) {
+                       hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_SET_HB, OPTION_LSW);
+                       hp100_outw(HP100_IO_EN | HP100_MEM_EN | HP100_RESET_LB, OPTION_LSW);
+-                      printk("hp100: %s: Busmaster mode requested.\n", dev->name);
++                      printk("hp100: Busmaster mode requested.\n");
+               }
+               local_mode = 1;
+       }
+@@ -643,7 +552,7 @@ static int __init hp100_probe1(struct ne
+                               /* Gracefully fallback to shared memory */
+                               goto busmasterfail;
+                       }
+-                      printk("hp100: %s: Busmaster mode enabled.\n", dev->name);
++                      printk("hp100: Busmaster mode enabled.\n");
+                       hp100_outw(HP100_MEM_EN | HP100_IO_EN | HP100_RESET_LB, OPTION_LSW);
+               } else {
+               busmasterfail:
+@@ -675,7 +584,7 @@ static int __init hp100_probe1(struct ne
+               mem_ptr_phys &= ~0x1fff;        /* 8k alignment */
+               if (bus == HP100_BUS_ISA && (mem_ptr_phys & ~0xfffff) != 0) {
+-                      printk("hp100: %s: Can only use programmed i/o mode.\n", dev->name);
++                      printk("hp100: Can only use programmed i/o mode.\n");
+                       mem_ptr_phys = 0;
+                       mem_mapped = 0;
+                       local_mode = 3; /* Use programmed i/o */
+@@ -699,7 +608,7 @@ static int __init hp100_probe1(struct ne
+                       }
+                       if (mem_ptr_virt == NULL) {     /* all ioremap tries failed */
+-                              printk("hp100: %s: Failed to ioremap the PCI card memory. Will have to use i/o mapped mode.\n", dev->name);
++                              printk("hp100: Failed to ioremap the PCI card memory. Will have to use i/o mapped mode.\n");
+                               local_mode = 3;
+                               virt_memory_size = 0;
+                       }
+@@ -710,17 +619,14 @@ static int __init hp100_probe1(struct ne
+               mem_mapped = 0;
+               mem_ptr_phys = 0;
+               mem_ptr_virt = NULL;
+-              printk("hp100: %s: Using (slow) programmed i/o mode.\n", dev->name);
++              printk("hp100: Using (slow) programmed i/o mode.\n");
+       }
+       /* Initialise the "private" data structure for this card. */
+-      if ((dev->priv = kmalloc(sizeof(struct hp100_private), GFP_KERNEL)) == NULL)
+-              return -ENOMEM;
+-
+       lp = (struct hp100_private *) dev->priv;
+-      memset(lp, 0, sizeof(struct hp100_private));
++
+       spin_lock_init(&lp->lock);
+-      lp->id = eid;
++      strlcpy(lp->id, eid, HP100_SIG_LEN);
+       lp->chip = chip;
+       lp->mode = local_mode;
+       lp->bus = bus;
+@@ -741,9 +647,6 @@ static int __init hp100_probe1(struct ne
+       lp->virt_memory_size = virt_memory_size;
+       lp->rx_ratio = hp100_rx_ratio;  /* can be conf'd with insmod */
+-      /* memory region for programmed i/o */
+-      request_region(dev->base_addr, HP100_REGION_SIZE, eid->name);
+-
+       dev->open = hp100_open;
+       dev->stop = hp100_close;
+@@ -776,10 +679,6 @@ static int __init hp100_probe1(struct ne
+       /* Reset statistics (counters) */
+       hp100_clear_stats(lp, ioaddr);
+-      SET_MODULE_OWNER(dev);
+-      SET_NETDEV_DEV(dev, &pci_dev->dev);
+-      ether_setup(dev);
+-
+       /* If busmaster mode is wanted, a dma-capable memory area is needed for
+        * the rx and tx PDLs 
+        * PCI cards can access the whole PC memory. Therefore GFP_DMA is not
+@@ -795,8 +694,10 @@ static int __init hp100_probe1(struct ne
+               /* Conversion to new PCI API :
+                * Pages are always aligned and zeroed, no need to it ourself.
+                * Doc says should be OK for EISA bus as well - Jean II */
+-              if ((lp->page_vaddr_algn = pci_alloc_consistent(lp->pci_dev, MAX_RINGSIZE, &page_baddr)) == NULL)
+-                      return -ENOMEM;
++              if ((lp->page_vaddr_algn = pci_alloc_consistent(lp->pci_dev, MAX_RINGSIZE, &page_baddr)) == NULL) {
++                      err = -ENOMEM;
++                      goto out2;
++              }
+               lp->whatever_offset = ((u_long) page_baddr) - ((u_long) lp->page_vaddr_algn);
+ #ifdef HP100_DEBUG_BM
+@@ -818,7 +719,7 @@ static int __init hp100_probe1(struct ne
+       lp->lan_type = hp100_sense_lan(dev);
+       /* Print out a message what about what we think we have probed. */
+-      printk("hp100: %s: %s at 0x%x, IRQ %d, ", dev->name, lp->id->name, ioaddr, dev->irq);
++      printk("hp100: at 0x%x, IRQ %d, ", ioaddr, dev->irq);
+       switch (bus) {
+       case HP100_BUS_EISA:
+               printk("EISA");
+@@ -833,7 +734,7 @@ static int __init hp100_probe1(struct ne
+       printk(" bus, %dk SRAM (rx/tx %d%%).\n", lp->memory_size >> 10, lp->rx_ratio);
+       if (lp->mode == 2) {    /* memory mapped */
+-              printk("hp100: %s: Memory area at 0x%lx-0x%lx", dev->name, mem_ptr_phys,
++              printk("hp100: Memory area at 0x%lx-0x%lx", mem_ptr_phys,
+                               (mem_ptr_phys + (mem_ptr_phys > 0x100000 ? (u_long) lp->memory_size : 16 * 1024)) - 1);
+               if (mem_ptr_virt)
+                       printk(" (virtual base %p)", mem_ptr_virt);
+@@ -843,7 +744,8 @@ static int __init hp100_probe1(struct ne
+               dev->mem_start = mem_ptr_phys;
+               dev->mem_end = mem_ptr_phys + lp->memory_size;
+       }
+-      printk("hp100: %s: ", dev->name);
++
++      printk("hp100: ");
+       if (lp->lan_type != HP100_LAN_ERR)
+               printk("Adapter is attached to ");
+       switch (lp->lan_type) {
+@@ -861,6 +763,10 @@ static int __init hp100_probe1(struct ne
+       }
+       return 0;
++out2:
++      release_region(ioaddr, HP100_REGION_SIZE);
++out1:
++      return -ENODEV;
+ }
+ /* This procedure puts the card into a stable init state */
+@@ -950,6 +856,7 @@ static void hp100_hwinit(struct net_devi
+       /* Finally try to log in the Hub if there may be a VG connection. */
+       if ((lp->lan_type == HP100_LAN_100) || (lp->lan_type == HP100_LAN_ERR))
+               hp100_login_to_vg_hub(dev, 0);  /* relogin */
++
+ }
\f
+@@ -1152,7 +1059,7 @@ static int hp100_open(struct net_device 
+       if (request_irq(dev->irq, hp100_interrupt,
+                       lp->bus == HP100_BUS_PCI || lp->bus ==
+                       HP100_BUS_EISA ? SA_SHIRQ : SA_INTERRUPT,
+-                      lp->id->name, dev)) {
++                      "hp100", dev)) {
+               printk("hp100: %s: unable to get IRQ %d\n", dev->name, dev->irq);
+               return -EAGAIN;
+       }
+@@ -2054,7 +1961,7 @@ static void hp100_rx_bm(struct net_devic
+ /*
+  *  statistics
+  */
+-static hp100_stats_t *hp100_get_stats(struct net_device *dev)
++static struct net_device_stats *hp100_get_stats(struct net_device *dev)
+ {
+       unsigned long flags;
+       int ioaddr = dev->base_addr;
+@@ -2558,10 +2465,14 @@ static int hp100_sense_lan(struct net_de
+               return HP100_LAN_COAX;
+       }
+-      if ((lp->id->id == 0x02019F022) ||
+-          (lp->id->id == 0x01042103c) || (lp->id->id == 0x01040103c))
+-              return HP100_LAN_ERR;   /* Those cards don't have a 100 Mbit connector */
+-
++      /* Those cards don't have a 100 Mbit connector */
++      if ( !strcmp(lp->id, "HWP1920")  ||
++           (lp->pci_dev && 
++            lp->pci_dev->vendor == PCI_VENDOR_ID && 
++            (lp->pci_dev->device == PCI_DEVICE_ID_HP_J2970A ||
++             lp->pci_dev->device == PCI_DEVICE_ID_HP_J2973A)))
++              return HP100_LAN_ERR;
++      
+       if (val_VG & HP100_LINK_CABLE_ST)       /* Can hear the HUBs tone. */
+               return HP100_LAN_100;
+       return HP100_LAN_ERR;
+@@ -2915,122 +2826,248 @@ void hp100_RegisterDump(struct net_devic
+ #endif
++static void cleanup_dev(struct net_device *d)
++{
++      struct hp100_private *p = (struct hp100_private *) d->priv;
++
++      unregister_netdev(d);
++      release_region(d->base_addr, HP100_REGION_SIZE);
++
++      if (p->mode == 1)       /* busmaster */
++              pci_free_consistent(p->pci_dev, MAX_RINGSIZE + 0x0f, 
++                                  p->page_vaddr_algn, 
++                                  virt_to_whatever(d, p->page_vaddr_algn));
++      if (p->mem_ptr_virt)
++              iounmap(p->mem_ptr_virt);
++
++      free_netdev(d);
++}
++
++#ifdef CONFIG_EISA
++static int __init hp100_eisa_probe (struct device *gendev)
++{
++      struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
++      struct eisa_device *edev = to_eisa_device(gendev);
++      int err;
++
++      if (!dev)
++              return -ENOMEM;
++
++      SET_MODULE_OWNER(dev);
++      SET_NETDEV_DEV(dev, &edev->dev);
++
++      err = hp100_probe1(dev, edev->base_addr, HP100_BUS_EISA, NULL);
++      if (err)
++              goto out1;
++
++      err = register_netdev(dev);
++      if (err)
++              goto out2;
++      
++#ifdef HP100_DEBUG
++      printk("hp100: %s: EISA adapter found at 0x%x\n", dev->name, 
++             dev->base_addr);
++#endif
++      gendev->driver_data = dev;
++      return 0;
++ out2:
++      release_region(dev->base_addr, HP100_REGION_SIZE);
++ out1:
++      free_netdev(dev);
++      return err;
++}
++
++static int __devexit hp100_eisa_remove (struct device *gendev)
++{
++      struct net_device *dev = gendev->driver_data;
++      cleanup_dev(dev);
++      return 0;
++}
++
++static struct eisa_driver hp100_eisa_driver = {
++        .id_table = hp100_eisa_tbl,
++        .driver   = {
++                .name    = "hp100",
++                .probe   = hp100_eisa_probe,
++                .remove  = __devexit_p (hp100_eisa_remove),
++        }
++};
++#endif
++
++#ifdef CONFIG_PCI
++static int __devinit hp100_pci_probe (struct pci_dev *pdev,
++                                   const struct pci_device_id *ent)
++{
++      struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
++      int ioaddr = pci_resource_start(pdev, 0);
++      u_short pci_command;
++      int err;
++      
++      if (!dev)
++              return -ENOMEM;
++
++      SET_MODULE_OWNER(dev);
++      SET_NETDEV_DEV(dev, &pdev->dev);
++
++      pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
++      if (!(pci_command & PCI_COMMAND_IO)) {
++#ifdef HP100_DEBUG
++              printk("hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name);
++#endif
++              pci_command |= PCI_COMMAND_IO;
++              pci_write_config_word(pdev, PCI_COMMAND, pci_command);
++      }
++
++      if (!(pci_command & PCI_COMMAND_MASTER)) {
++#ifdef HP100_DEBUG
++              printk("hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name);
++#endif
++              pci_command |= PCI_COMMAND_MASTER;
++              pci_write_config_word(pdev, PCI_COMMAND, pci_command);
++      }
++      
++
++      err = hp100_probe1(dev, ioaddr, HP100_BUS_PCI, pdev);
++      if (err) 
++              goto out1;
++      err = register_netdev(dev);
++      if (err)
++              goto out2;
++      
++#ifdef HP100_DEBUG
++      printk("hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr);
++#endif
++      pci_set_drvdata(pdev, dev);
++      return 0;
++ out2:
++      release_region(dev->base_addr, HP100_REGION_SIZE);
++ out1:
++      free_netdev(dev);
++      return err;
++}
++
++static void __devexit hp100_pci_remove (struct pci_dev *pdev)
++{
++      struct net_device *dev = pci_get_drvdata(pdev);
++
++      cleanup_dev(dev);
++}
++
++
++static struct pci_driver hp100_pci_driver = {
++      .name           = "hp100",
++      .id_table       = hp100_pci_tbl,
++      .probe          = hp100_pci_probe,
++      .remove         = __devexit_p(hp100_pci_remove),
++};
++#endif
++
+ /*
+  *  module section
+  */
+-#ifdef MODULE
+-
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, "
+               "Siegfried \"Frieder\" Loeffler (dg1sek) <floeff@mathematik.uni-stuttgart.de>");
+ MODULE_DESCRIPTION("HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters");
+ /*
+- * Note: if you have more than five 100vg cards in your pc, feel free to
+- * increase this value 
+- */
+-
+-#define HP100_DEVICES 5
+-
+-/*
+- * Note: to register three eisa or pci devices, use:
++ * Note: to register three isa devices, use:
+  * option hp100 hp100_port=0,0,0
+  *        to register one card at io 0x280 as eth239, use:
+- * option hp100 hp100_port=0x280 hp100_name=eth239
++ * option hp100 hp100_port=0x280
+  */
+-
++#if defined(MODULE) && defined(CONFIG_ISA)
++#define HP100_DEVICES 5
+ /* Parameters set by insmod */
+ static int hp100_port[HP100_DEVICES] = { 0, [1 ... (HP100_DEVICES-1)] = -1 };
+ MODULE_PARM(hp100_port, "1-" __MODULE_STRING(HP100_DEVICES) "i");
+-/* Allocate HP100_DEVICES strings of length IFNAMSIZ, one string for each device */
+-static char hp100_name[HP100_DEVICES][IFNAMSIZ] = { "", "", "", "", "" };
+-/* Allow insmod to write those HP100_DEVICES strings individually */
+-MODULE_PARM(hp100_name, "1-" __MODULE_STRING(HP100_DEVICES) "c" __MODULE_STRING(IFNAMSIZ));
+-
+ /* List of devices */
+ static struct net_device *hp100_devlist[HP100_DEVICES];
+-static void release_dev(int i)
++static int __init hp100_isa_init(void)
+ {
+-      struct net_device *d = hp100_devlist[i];
+-      struct hp100_private *p = (struct hp100_private *) d->priv;
++      struct net_device *dev;
++      int i, err, cards = 0;
+-      unregister_netdev(d);
+-      release_region(d->base_addr, HP100_REGION_SIZE);
++      /* Don't autoprobe ISA bus */
++      if (hp100_port[0] == 0)
++              return -ENODEV;
+-      if (p->mode == 1)       /* busmaster */
+-              pci_free_consistent(p->pci_dev, MAX_RINGSIZE + 0x0f, p->page_vaddr_algn, virt_to_whatever(d, p->page_vaddr_algn));
+-      if (p->mem_ptr_virt)
+-              iounmap(p->mem_ptr_virt);
+-      kfree(d->priv);
+-      d->priv = NULL;
+-      free_netdev(d);
+-      hp100_devlist[i] = NULL;
++      /* Loop on all possible base addresses */
++      for (i = 0; i < HP100_DEVICES && hp100_port[i] != -1; ++i) {
++              dev = alloc_etherdev(sizeof(struct hp100_private));
++              if (!dev) {
++                      printk(KERN_WARNING "hp100: no memory for network device\n");
++                      while (cards > 0)
++                              cleanup_dev(hp100_devlist[--cards]);
++
++                      return -ENOMEM;
++              }
++              SET_MODULE_OWNER(dev);
++
++              err = hp100_isa_probe(dev, hp100_port[i]);
++              if (!err) {
++                      err = register_netdev(dev);
++                      if (!err) 
++                              hp100_devlist[cards++] = dev;
++                      else
++                              release_region(dev->base_addr, HP100_REGION_SIZE);
++              }
++
++              if (err)
++                      free_netdev(dev);
++      }
++
++      return cards > 0 ? 0 : -ENODEV;
+ }
+-static int __init hp100_module_init(void)
++static void __exit hp100_isa_cleanup(void) 
+ {
+-      int i, cards;
++      int i;
+-#ifndef CONFIG_PCI
+-      if (hp100_port == 0 && !EISA_bus)
+-              printk("hp100: You should not use auto-probing with insmod!\n");
++      for (i = 0; i < HP100_DEVICES; i++) {
++              struct net_device *dev = hp100_devlist[i];
++              if (dev)
++                      cleanup_dev(dev);
++      }
++}
++#else
++#define hp100_isa_init()      (0)
++#define hp100_isa_cleanup()   do { } while(0)
+ #endif
+-      /* Loop on all possible base addresses */
+-      i = -1;
+-      cards = 0;
+-      while ((hp100_port[++i] != -1) && (i < HP100_DEVICES)) {
+-              /* Create device and set basics args */
+-              hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+-              if (!hp100_devlist[i])
+-                      goto fail;
+-              memset(hp100_devlist[i], 0x00, sizeof(struct net_device));
+-#if LINUX_VERSION_CODE >= 0x020362    /* 2.3.99-pre7 */
+-              memcpy(hp100_devlist[i]->name, hp100_name[i], IFNAMSIZ);        /* Copy name */
+-#else
+-              hp100_devlist[i]->name = hp100_name[i];
+-#endif                                /* LINUX_VERSION_CODE >= 0x020362 */
+-              hp100_devlist[i]->base_addr = hp100_port[i];
+-              hp100_devlist[i]->init = &hp100_probe;
+-
+-              /* Try to create the device */
+-              if (register_netdev(hp100_devlist[i]) != 0) {
+-                      /* DeAllocate everything */
+-                      /* Note: if dev->priv is mallocated, there is no way to fail */
+-                      kfree(hp100_devlist[i]);
+-                      hp100_devlist[i] = (struct net_device *) NULL;
+-              } else
+-                      cards++;
+-      }                       /* Loop over all devices */
++static int __init hp100_module_init(void)
++{
++      int err;
+-      return cards > 0 ? 0 : -ENODEV;
+-      fail:
+-      while (cards && --i)
+-              if (hp100_devlist[i]) {
+-                      release_dev(i);
+-                      --cards;
+-              }
+-      return -ENOMEM;
++      err = hp100_isa_init();
++
++#ifdef CONFIG_EISA
++      err |= eisa_driver_register(&hp100_eisa_driver);
++#endif
++#ifdef CONFIG_PCI
++      err |= pci_module_init(&hp100_pci_driver);
++#endif
++      return err;
+ }
++
+ static void __exit hp100_module_exit(void)
+ {
+-      int i;
+-
+-      /* TODO: Check if all skb's are released/freed. */
+-      for (i = 0; i < HP100_DEVICES; i++)
+-              if (hp100_devlist[i] != (struct net_device *) NULL)
+-                      release_dev(i);
++      hp100_isa_cleanup();
++#ifdef CONFIG_EISA
++      eisa_driver_unregister (&hp100_eisa_driver);
++#endif
++#ifdef CONFIG_PCI
++      pci_unregister_driver (&hp100_pci_driver);
++#endif
+ }
+ module_init(hp100_module_init)
+ module_exit(hp100_module_exit)
+-#endif                                /* MODULE */
+-
+ /*
+  * Local variables:
+--- linux-2.6.0/drivers/net/hp.c       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/hp.c        2003-12-28 23:21:01.000000000 -0800
+@@ -55,7 +55,6 @@ static unsigned int hppclan_portlist[] _
+ #define HP_8BSTOP_PG  0x80    /* Last page +1 of RX ring */
+ #define HP_16BSTOP_PG 0xFF    /* Same, for 16 bit cards. */
+-int hp_probe(struct net_device *dev);
+ static int hp_probe1(struct net_device *dev, int ioaddr);
+ static int hp_open(struct net_device *dev);
+@@ -79,10 +78,11 @@ static char irqmap[16] __initdata= { 0, 
+       Also initialize the card and fill in STATION_ADDR with the station
+       address. */
+-int __init hp_probe(struct net_device *dev)
++static int __init do_hp_probe(struct net_device *dev)
+ {
+       int i;
+       int base_addr = dev->base_addr;
++      int irq = dev->irq;
+       SET_MODULE_OWNER(dev);
+@@ -91,13 +91,46 @@ int __init hp_probe(struct net_device *d
+       else if (base_addr != 0)        /* Don't probe at all. */
+               return -ENXIO;
+-      for (i = 0; hppclan_portlist[i]; i++)
++      for (i = 0; hppclan_portlist[i]; i++) {
+               if (hp_probe1(dev, hppclan_portlist[i]) == 0)
+                       return 0;
++              dev->irq = irq;
++      }
+       return -ENODEV;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
++}
++
++struct net_device * __init hp_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_hp_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ static int __init hp_probe1(struct net_device *dev, int ioaddr)
+ {
+       int i, retval, board_id, wordmode;
+@@ -131,13 +164,6 @@ static int __init hp_probe1(struct net_d
+       if (ei_debug  &&  version_printed++ == 0)
+               printk(version);
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev)) {
+-              printk (" unable to get memory for dev->priv.\n");
+-              retval = -ENOMEM;
+-              goto out;
+-      }
+-
+       printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);
+       for(i = 0; i < ETHER_ADDR_LEN; i++)
+@@ -166,14 +192,14 @@ static int __init hp_probe1(struct net_d
+               if (*irqp == 0) {
+                       printk(" no free IRQ lines.\n");
+                       retval = -EBUSY;
+-                      goto out1;
++                      goto out;
+               }
+       } else {
+               if (dev->irq == 2)
+                       dev->irq = 9;
+               if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
+                       printk (" unable to get IRQ %d.\n", dev->irq);
+-                      goto out1;
++                      goto out;
+               }
+       }
+@@ -195,9 +221,6 @@ static int __init hp_probe1(struct net_d
+       hp_init_card(dev);
+       return 0;
+-out1:
+-      kfree(dev->priv);
+-      dev->priv = NULL;
+ out:
+       release_region(ioaddr, HP_IO_EXTENT);
+       return retval;
+@@ -372,7 +395,7 @@ hp_init_card(struct net_device *dev)
+ #ifdef MODULE
+ #define MAX_HP_CARDS  4       /* Max number of HP cards per module */
+-static struct net_device dev_hp[MAX_HP_CARDS];
++static struct net_device *dev_hp[MAX_HP_CARDS];
+ static int io[MAX_HP_CARDS];
+ static int irq[MAX_HP_CARDS];
+@@ -388,27 +411,33 @@ ISA device autoprobes on a running machi
+ int
+ init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_hp[this_dev];
+-              dev->irq = irq[this_dev];
+-              dev->base_addr = io[this_dev];
+-              dev->init = hp_probe;
+               if (io[this_dev] == 0)  {
+                       if (this_dev != 0) break; /* only autoprobe 1st one */
+                       printk(KERN_NOTICE "hp.c: Presently autoprobing (not recommended) for a single card.\n");
+               }
+-              if (register_netdev(dev) != 0) {
+-                      printk(KERN_WARNING "hp.c: No HP card found (i/o = 0x%x).\n", io[this_dev]);
+-                      if (found != 0) {       /* Got at least one. */
+-                              return 0;
++              dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
++              dev->irq = irq[this_dev];
++              dev->base_addr = io[this_dev];
++              if (do_hp_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_hp[found++] = dev;
++                              continue;
+                       }
+-                      return -ENXIO;
++                      cleanup_card(dev);
+               }
+-              found++;
++              free_netdev(dev);
++              printk(KERN_WARNING "hp.c: No HP card found (i/o = 0x%x).\n", io[this_dev]);
++              break;
+       }
+-      return 0;
++      if (found)
++              return 0;
++      return -ENXIO;
+ }
+ void
+@@ -417,14 +446,11 @@ cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_hp[this_dev];
+-              if (dev->priv != NULL) {
+-                      int ioaddr = dev->base_addr - NIC_OFFSET;
+-                      void *priv = dev->priv;
+-                      free_irq(dev->irq, dev);
+-                      release_region(ioaddr, HP_IO_EXTENT);
++              struct net_device *dev = dev_hp[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(priv);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/hplance.c  2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/hplance.c   2003-12-28 23:21:01.000000000 -0800
+@@ -50,8 +50,7 @@ struct hplance_private {
+  * plus board-specific init, open and close actions. 
+  * Oh, and we need to tell the generic code how to read and write LANCE registers...
+  */
+-int hplance_probe(struct net_device *dev);
+-static int hplance_init(struct net_device *dev, int scode);
++static void hplance_init(struct net_device *dev, int scode);
+ static int hplance_open(struct net_device *dev);
+ static int hplance_close(struct net_device *dev);
+ static void hplance_writerap(void *priv, unsigned short value);
+@@ -62,57 +61,61 @@ static unsigned short hplance_readrdp(vo
+ static struct hplance_private *root_hplance_dev;
+ #endif
++static void cleanup_card(struct net_device *dev)
++{
++        struct hplance_private *lp = dev->priv;
++      dio_unconfig_board(lp->scode);
++}
++
+ /* Find all the HP Lance boards and initialise them... */
+-int __init hplance_probe(struct net_device *dev)
++struct net_device * __init hplance_probe(int unit)
+ {
+-        int cards = 0, called = 0;
++      struct net_device *dev;
++
++        if (!MACH_IS_HP300)
++                return ERR_PTR(-ENODEV);
++
++      dev = alloc_etherdev(sizeof(struct hplance_private));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
+-        if (!MACH_IS_HP300 || called)
+-                return(ENODEV);
+-        called++;
++      SET_MODULE_OWNER(dev);
+         
+         /* Isn't DIO nice? */
+         for(;;)
+         {
+-                int v, scode = dio_find(DIO_ID_LAN);
++                int scode = dio_find(DIO_ID_LAN);
+                                 
+                 if (!scode)
+                         break;
+                 
+-                if(cards)
+-                        dev = NULL;      /* don't trash previous device, make a new one */
+-                cards++;
+-                
+-                v = hplance_init(dev, scode);
+-                if (v)                            /* error, abort immediately */
+-                        return v;
++              dio_config_board(scode);
++                hplance_init(dev, scode);
++              if (!register_netdev(dev)) {
++                      struct hplance_private *lp = dev->priv;
++                      lp->next_module = root_hplance_dev;
++                      root_hplance_dev = lp;
++                      return dev;
++              }
++              cleanup_card(dev);
+         }
+-        /* OK, return success, or ENODEV if we didn't find any cards */
+-        if (!cards)
+-                return -ENODEV;
+-        return 0;
++      free_netdev(dev);
++      return ERR_PTR(-ENODEV);
+ }
+ /* Initialise a single lance board at the given select code */
+-static int __init hplance_init(struct net_device *dev, int scode)
++static void __init hplance_init(struct net_device *dev, int scode)
+ {
+         const char *name = dio_scodetoname(scode);
+         void *va = dio_scodetoviraddr(scode);
+         struct hplance_private *lp;
+         int i;
+         
+-#ifdef MODULE
+-      dev = init_etherdev(0, sizeof(struct hplance_private));
+-      if (!dev)
+-              return -ENOMEM;
+-#else
+-      dev->priv = kmalloc(sizeof(struct hplance_private), GFP_KERNEL);
+-      if (dev->priv == NULL)
+-              return -ENOMEM;
+-      memset(dev->priv, 0, sizeof(struct hplance_private));
+-#endif
+-      SET_MODULE_OWNER(dev);
+-
+         printk("%s: %s; select code %d, addr", dev->name, name, scode);
+         /* reset the board */
+@@ -154,17 +157,7 @@ static int __init hplance_init(struct ne
+         lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
+         lp->scode = scode;
+       lp->base = va;
+-        ether_setup(dev);
+       printk(", irq %d\n", lp->lance.irq);
+-
+-#ifdef MODULE
+-        dev->ifindex = dev_new_index();
+-        lp->next_module = root_hplance_dev;
+-        root_hplance_dev = lp;
+-#endif /* MODULE */
+-
+-        dio_config_board(scode);                  /* tell bus scanning code this one's taken */
+-        return 0;
+ }
+ /* This is disgusting. We have to check the DIO status register for ack every
+@@ -227,8 +220,10 @@ static int hplance_close(struct net_devi
+ MODULE_LICENSE("GPL");
+ int init_module(void)
+ {
+-        root_lance_dev = NULL;
+-        return hplance_probe(NULL);
++      int found = 0;
++      while (!IS_ERR(hplance_probe(-1)))
++              found++;
++      return found ? 0 : -ENODEV;
+ }
+ void cleanup_module(void)
+@@ -237,8 +232,8 @@ void cleanup_module(void)
+         struct hplance_private *lp;
+         while (root_hplance_dev) {
+                 lp = root_hplance_dev->next_module;
+-                dio_unconfig_board(lp->scode);
+                 unregister_netdev(root_lance_dev->dev);
++                cleanup_card(root_lance_dev->dev);
+                 free_netdev(root_lance_dev->dev);
+                 root_lance_dev = lp;
+         }
+--- linux-2.6.0/drivers/net/hp-plus.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/hp-plus.c   2003-12-28 23:21:01.000000000 -0800
+@@ -92,7 +92,6 @@ enum HP_Option {
+       EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20,
+       MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, };
+-int hp_plus_probe(struct net_device *dev);
+ static int hpp_probe1(struct net_device *dev, int ioaddr);
+ static void hpp_reset_8390(struct net_device *dev);
+@@ -115,10 +114,11 @@ static void hpp_io_get_8390_hdr(struct n
+ /*    Probe a list of addresses for an HP LAN+ adaptor.
+       This routine is almost boilerplate. */
+-int __init hp_plus_probe(struct net_device *dev)
++static int __init do_hpp_probe(struct net_device *dev)
+ {
+       int i;
+       int base_addr = dev->base_addr;
++      int irq = dev->irq;
+       SET_MODULE_OWNER(dev);
+@@ -127,13 +127,46 @@ int __init hp_plus_probe(struct net_devi
+       else if (base_addr != 0)        /* Don't probe at all. */
+               return -ENXIO;
+-      for (i = 0; hpplus_portlist[i]; i++)
++      for (i = 0; hpplus_portlist[i]; i++) {
+               if (hpp_probe1(dev, hpplus_portlist[i]) == 0)
+                       return 0;
++              dev->irq = irq;
++      }
+       return -ENODEV;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      /* NB: hpp_close() handles free_irq */
++      release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
++}
++
++struct net_device * __init hp_plus_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_hpp_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ /* Do the interesting part of the probe at a single address. */
+ static int __init hpp_probe1(struct net_device *dev, int ioaddr)
+ {
+@@ -179,13 +212,6 @@ static int __init hpp_probe1(struct net_
+               printk(" ID %4.4x", inw(ioaddr + 12));
+       }
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev)) {
+-              printk ("hp-plus.c: unable to allocate memory for dev->priv.\n");
+-              retval = -ENOMEM;
+-              goto out;
+-       }
+-
+       /* Read the IRQ line. */
+       outw(HW_Page, ioaddr + HP_PAGING);
+       {
+@@ -400,7 +426,7 @@ hpp_mem_block_output(struct net_device *
\f
+ #ifdef MODULE
+ #define MAX_HPP_CARDS 4       /* Max number of HPP cards per module */
+-static struct net_device dev_hpp[MAX_HPP_CARDS];
++static struct net_device *dev_hpp[MAX_HPP_CARDS];
+ static int io[MAX_HPP_CARDS];
+ static int irq[MAX_HPP_CARDS];
+@@ -416,27 +442,33 @@ ISA device autoprobes on a running machi
+ int
+ init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_hpp[this_dev];
+-              dev->irq = irq[this_dev];
+-              dev->base_addr = io[this_dev];
+-              dev->init = hp_plus_probe;
+               if (io[this_dev] == 0)  {
+                       if (this_dev != 0) break; /* only autoprobe 1st one */
+                       printk(KERN_NOTICE "hp-plus.c: Presently autoprobing (not recommended) for a single card.\n");
+               }
+-              if (register_netdev(dev) != 0) {
+-                      printk(KERN_WARNING "hp-plus.c: No HP-Plus card found (i/o = 0x%x).\n", io[this_dev]);
+-                      if (found != 0) {       /* Got at least one. */
+-                              return 0;
++              dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
++              dev->irq = irq[this_dev];
++              dev->base_addr = io[this_dev];
++              if (do_hpp_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_hpp[found++] = dev;
++                              continue;
+                       }
+-                      return -ENXIO;
++                      cleanup_card(dev);
+               }
+-              found++;
++              free_netdev(dev);
++              printk(KERN_WARNING "hp-plus.c: No HP-Plus card found (i/o = 0x%x).\n", io[this_dev]);
++              break;
+       }
+-      return 0;
++      if (found)
++              return 0;
++      return -ENXIO;
+ }
+ void
+@@ -445,14 +477,11 @@ cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_hpp[this_dev];
+-              if (dev->priv != NULL) {
+-                      int ioaddr = dev->base_addr - NIC_OFFSET;
+-                      void *priv = dev->priv;
+-                      /* NB: hpp_close() handles free_irq */
+-                      release_region(ioaddr, HP_IO_EXTENT);
++              struct net_device *dev = dev_hpp[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(priv);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/hydra.c    2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/hydra.c     2003-12-28 23:21:01.000000000 -0800
+@@ -89,13 +89,14 @@ static int __init hydra_init(unsigned lo
+     const char name[] = "NE2000";
+     int start_page, stop_page;
+     int j;
++    int err;
+     static u32 hydra_offsets[16] = {
+       0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
+       0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
+     };
+-    dev = init_etherdev(NULL, 0);
++    dev = alloc_ei_netdev();
+     if (!dev)
+       return -ENOMEM;
+     SET_MODULE_OWNER(dev);
+@@ -113,13 +114,9 @@ static int __init hydra_init(unsigned lo
+     /* Install the Interrupt handler */
+     if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, "Hydra Ethernet",
+-                  dev))
++                  dev)) {
++      free_netdev(dev);
+       return -EAGAIN;
+-
+-    /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-    if (ethdev_init(dev)) {
+-      printk("Unable to get memory for dev->priv.\n");
+-      return -ENOMEM;
+     }
+     printk("%s: hydra at 0x%08lx, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n", dev->name, ZTWO_PADDR(board),
+@@ -146,7 +143,13 @@ static int __init hydra_init(unsigned lo
+     root_hydra_dev = dev;
+ #endif
+     NS8390_init(dev, 0);
+-    return 0;
++    err = register_netdev(dev);
++    if (!err)
++      return 0;
++
++    free_irq(IRQ_AMIGA_PORTS, dev);
++    free_netdev(dev);
++    return err;
+ }
+ static int hydra_open(struct net_device *dev)
+--- linux-2.6.0/drivers/net/ibmlana.c  2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/ibmlana.c   2003-12-28 23:21:01.000000000 -0800
+@@ -906,7 +906,7 @@ static void ibmlana_set_multicast_list(s
+ static int startslot;         /* counts through slots when probing multiple devices */
+-int ibmlana_probe(struct net_device *dev)
++static int ibmlana_probe(struct net_device *dev)
+ {
+       int force_detect = 0;
+       int slot, z;
+@@ -924,34 +924,21 @@ int ibmlana_probe(struct net_device *dev
+       if (dev->mem_start == 1)
+               force_detect = 1;
+-      /* search through slots */
+-      if (dev != NULL) {
+-              base = dev->mem_start;
+-              irq = dev->irq;
+-      }
+-      slot = mca_find_adapter(IBM_LANA_ID, startslot);
++      base = dev->mem_start;
++      irq = dev->irq;
+-      while (slot != -1) {
++      for (slot = startslot; (slot = mca_find_adapter(IBM_LANA_ID, slot)) != -1; slot++) {
+               /* deduce card addresses */
+               getaddrs(slot, &base, &memlen, &iobase, &irq, &medium);
+               /* slot already in use ? */
+-              if (mca_is_adapter_used(slot)) {
+-                      slot = mca_find_adapter(IBM_LANA_ID, slot + 1);
++              if (mca_is_adapter_used(slot))
+                       continue;
+-              }
+               /* were we looking for something different ? */
+-              if (dev->irq != 0 || dev->mem_start != 0) {
+-                      if (dev->irq != 0 && dev->irq != irq) {
+-                              slot = mca_find_adapter(IBM_LANA_ID, slot + 1);
+-                              continue;
+-                      }
+-                      if (dev->mem_start != 0 && dev->mem_start != base) 
+-                      {
+-                              slot = mca_find_adapter(IBM_LANA_ID, slot + 1);
+-                              continue;
+-                      }
+-              }
++              if (dev->irq && dev->irq != irq)
++                      continue;
++              if (dev->mem_start && dev->mem_start != base)
++                      continue;
+               /* found something that matches */
+               break;
+       }
+@@ -977,16 +964,11 @@ int ibmlana_probe(struct net_device *dev
+       mca_mark_as_used(slot);
+       /* allocate structure */
+-      priv = dev->priv = (ibmlana_priv *) kmalloc(sizeof(ibmlana_priv), GFP_KERNEL);
+-      if (!priv) {
+-              release_region(iobase, IBM_LANA_IORANGE);
+-              return -ENOMEM;
+-      }
++      priv = dev->priv;
+       priv->slot = slot;
+       priv->realirq = irq;
+       priv->medium = medium;
+       spin_lock_init(&priv->lock);
+-      memset(&priv->stat, 0, sizeof(struct net_device_stats));
+       /* set base + irq for this device (irq not allocated so far) */
+@@ -1006,10 +988,6 @@ int ibmlana_probe(struct net_device *dev
+       dev->set_multicast_list = ibmlana_set_multicast_list;
+       dev->flags |= IFF_MULTICAST;
+-      /* generic setup */
+-
+-      ether_setup(dev);
+-
+       /* copy out MAC address */
+       for (z = 0; z < sizeof(dev->dev_addr); z++)
+@@ -1044,7 +1022,7 @@ int ibmlana_probe(struct net_device *dev
+ #define DEVMAX 5
+-static struct net_device moddevs[DEVMAX];
++static struct net_device *moddevs[DEVMAX];
+ static int irq;
+ static int io;
+@@ -1056,41 +1034,47 @@ MODULE_LICENSE("GPL");
+ int init_module(void)
+ {
+-      int z, res;
++      int z;
+       startslot = 0;
+       for (z = 0; z < DEVMAX; z++) {
+-              moddevs[z].init = ibmlana_probe;
+-              moddevs[z].irq = irq;
+-              moddevs[z].base_addr = io;
+-              res = register_netdev(moddevs + z);
+-              if (res != 0)
+-                      return (z > 0) ? 0 : -EIO;
++              struct net_device *dev = alloc_etherdev(sizeof(ibmlana_priv));
++              if (!dev)
++                      break;
++              dev->irq = irq;
++              dev->base_addr = io;
++              if (ibmlana_probe(dev)) {
++                      free_netdev(dev);
++                      break;
++              }
++              if (register_netdev(dev)) {
++                      ibmlana_priv *priv = dev->priv;
++                      release_region(dev->base_addr, IBM_LANA_IORANGE);
++                      mca_mark_as_unused(priv->slot);
++                      mca_set_adapter_name(priv->slot, "");
++                      mca_set_adapter_procfn(priv->slot, NULL, NULL);
++                      free_netdev(dev);
++                      break;
++              }
++              moddevs[z] = dev;
+       }
+-      return 0;
++      return (z > 0) ? 0 : -EIO;
+ }
+ void cleanup_module(void)
+ {
+-      struct net_device *dev;
+-      ibmlana_priv *priv;
+       int z;
+-
+       for (z = 0; z < DEVMAX; z++) {
+-              dev = moddevs + z;
+-              if (dev->priv != NULL) {
+-                      priv = (ibmlana_priv *) dev->priv;
++              struct net_device *dev = moddevs[z];
++              if (dev) {
++                      ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
++                      unregister_netdev(dev);
+                       /*DeinitBoard(dev); */
+-                      if (dev->irq != 0)
+-                              free_irq(dev->irq, dev);
+-                      dev->irq = 0;
+                       release_region(dev->base_addr, IBM_LANA_IORANGE);
+-                      unregister_netdev(dev);
+                       mca_mark_as_unused(priv->slot);
+                       mca_set_adapter_name(priv->slot, "");
+                       mca_set_adapter_procfn(priv->slot, NULL, NULL);
+-                      kfree(dev->priv);
+-                      dev->priv = NULL;
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/ibmlana.h  2003-06-14 12:18:31.000000000 -0700
++++ 25/drivers/net/ibmlana.h   2003-12-28 23:21:01.000000000 -0800
+@@ -275,7 +275,4 @@ typedef struct {
+ #endif                                /* _IBM_LANA_DRIVER_ */
+-extern int ibmlana_probe(struct net_device *);
+-
+-
+ #endif        /* _IBM_LANA_INCLUDE_ */
+--- linux-2.6.0/drivers/net/irda/ali-ircc.c    2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/irda/ali-ircc.c     2003-12-28 23:23:01.000000000 -0800
+@@ -8,6 +8,8 @@
+  * Created at:    2000/10/16 03:46PM
+  * Modified at:   2001/1/3 02:55PM
+  * Modified by:   Benjamin Kong <benjamin_kong@ali.com.tw>
++ * Modified at:   2003/11/6 and support for ALi south-bridge chipsets M1563
++ * Modified by:   Clear Zhang <clear_zhang@ali.com.tw>
+  * 
+  *     Copyright (c) 2000 Benjamin Kong <benjamin_kong@ali.com.tw>
+  *     All Rights Reserved
+@@ -68,6 +70,7 @@ static ali_chip_t chips[] =
+ {
+       { "M1543", { 0x3f0, 0x370 }, 0x51, 0x23, 0x20, 0x43, ali_ircc_probe_53, ali_ircc_init_43 },
+       { "M1535", { 0x3f0, 0x370 }, 0x51, 0x23, 0x20, 0x53, ali_ircc_probe_53, ali_ircc_init_53 },
++      { "M1563", { 0x3f0, 0x370 }, 0x51, 0x23, 0x20, 0x63, ali_ircc_probe_53, ali_ircc_init_53 },
+       { NULL }
+ };
+@@ -1331,7 +1334,7 @@ static int ali_ircc_net_open(struct net_
+       }
+       
+       /* Turn on interrups */
+-      outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER);
++      outb(UART_IER_RDI , iobase+UART_IER);
+       /* Ready to play! */
+       netif_start_queue(dev); //benjamin by irport
+--- linux-2.6.0/drivers/net/ixgb/ixgb_main.c   2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/ixgb/ixgb_main.c    2003-12-28 23:21:01.000000000 -0800
+@@ -446,7 +446,7 @@ ixgb_probe(struct pci_dev *pdev, const s
+       iounmap(adapter->hw.hw_addr);
+       err_ioremap:
+       pci_release_regions(pdev);
+-      kfree(netdev);
++      free_netdev(netdev);
+       err_alloc_etherdev:
+       return -ENOMEM;
+ }
+--- linux-2.6.0/drivers/net/jazzsonic.c        2003-06-14 12:18:06.000000000 -0700
++++ 25/drivers/net/jazzsonic.c 2003-12-28 23:21:01.000000000 -0800
+@@ -80,7 +80,6 @@ static unsigned short known_revisions[] 
+ /* Index to functions, as function prototypes. */
+-extern int sonic_probe(struct net_device *dev);
+ static int sonic_probe1(struct net_device *dev, unsigned int base_addr,
+                         unsigned int irq);
+@@ -89,29 +88,57 @@ static int sonic_probe1(struct net_devic
+  * Probe for a SONIC ethernet controller on a Mips Jazz board.
+  * Actually probing is superfluous but we're paranoid.
+  */
+-int __init sonic_probe(struct net_device *dev)
++struct net_device * __init sonic_probe(int unit)
+ {
+-      unsigned int base_addr = dev ? dev->base_addr : 0;
++      struct net_device *dev;
++      struct sonic_local *lp;
++      unsigned int base_addr;
++      int err = 0;
+       int i;
+       /*
+        * Don't probe if we're not running on a Jazz board.
+        */
+       if (mips_machgroup != MACH_GROUP_JAZZ)
+-              return -ENODEV;
+-      if (base_addr >= KSEG0) /* Check a single specified location. */
+-              return sonic_probe1(dev, base_addr, dev->irq);
+-      else if (base_addr != 0)        /* Don't probe at all. */
+-              return -ENXIO;
+-
+-      for (i = 0; sonic_portlist[i].port; i++) {
+-              int base_addr = sonic_portlist[i].port;
+-              if (check_region(base_addr, 0x100))
+-                      continue;
+-              if (sonic_probe1(dev, base_addr, sonic_portlist[i].irq) == 0)
+-                      return 0;
++              return ERR_PTR(-ENODEV);
++
++      dev = alloc_etherdev(0);
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++      base_addr = dev->base_addr;
++
++      if (base_addr >= KSEG0) { /* Check a single specified location. */
++              err = sonic_probe1(dev, base_addr, dev->irq);
++      } else if (base_addr != 0) { /* Don't probe at all. */
++              err = -ENXIO;
++      } else {
++              for (i = 0; sonic_portlist[i].port; i++) {
++                      int io = sonic_portlist[i].port;
++                      if (sonic_probe1(dev, io, sonic_portlist[i].irq) == 0)
++                              break;
++              }
++              if (!sonic_portlist[i].port)
++                      err = -ENODEV;
+       }
+-      return -ENODEV;
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      lp = dev->priv;
++      vdma_free(lp->rba_laddr);
++      kfree(lp->rba);
++      vdma_free(lp->cda_laddr);
++      kfree(lp);
++      release_region(dev->base_addr, 0x100);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
+@@ -121,8 +148,11 @@ static int __init sonic_probe1(struct ne
+       unsigned int silicon_revision;
+       unsigned int val;
+       struct sonic_local *lp;
++      int err = -ENODEV;
+       int i;
++      if (!request_region(base_addr, 0x100, dev->name))
++              return -EBUSY;
+       /*
+        * get the Silicon Revision ID. If this is one of the known
+        * one assume that we found a SONIC ethernet controller at
+@@ -140,12 +170,9 @@ static int __init sonic_probe1(struct ne
+       if (known_revisions[i] == 0xffff) {
+               printk("SONIC ethernet controller not found (0x%4x)\n",
+                      silicon_revision);
+-              return -ENODEV;
++              goto out;
+       }
+     
+-      if (!request_region(base_addr, 0x100, dev->name))
+-              return -EBUSY;
+-
+       if (sonic_debug  &&  version_printed++ == 0)
+               printk(version);
+@@ -175,6 +202,8 @@ static int __init sonic_probe1(struct ne
+       }
+       printk(" IRQ %d\n", irq);
++
++      err = -ENOMEM;
+     
+       /* Initialize the device structure. */
+       if (dev->priv == NULL) {
+@@ -196,7 +225,7 @@ static int __init sonic_probe1(struct ne
+               if (lp == NULL) {
+                       printk("%s: couldn't allocate memory for descriptors\n",
+                              dev->name);
+-                      return -ENOMEM;
++                      goto out;
+               }
+               memset(lp, 0, sizeof(struct sonic_local));
+@@ -206,7 +235,7 @@ static int __init sonic_probe1(struct ne
+               if (lp->cda_laddr == ~0UL) {
+                       printk("%s: couldn't get DMA page entry for "
+                              "descriptors\n", dev->name);
+-                      return -ENOMEM;
++                      goto out1;
+               }
+               lp->tda_laddr = lp->cda_laddr + sizeof (lp->cda);
+@@ -219,7 +248,7 @@ static int __init sonic_probe1(struct ne
+               if (!lp->rba) {
+                       printk("%s: couldn't allocate receive buffers\n",
+                              dev->name);
+-                      return -ENOMEM;
++                      goto out2;
+               }
+               /* get virtual dma address */
+@@ -228,7 +257,7 @@ static int __init sonic_probe1(struct ne
+               if (lp->rba_laddr == ~0UL) {
+                       printk("%s: couldn't get DMA page entry for receive "
+                              "buffers\n",dev->name);
+-                      return -ENOMEM;
++                      goto out3;
+               }
+               /* now convert pointer to KSEG1 pointer */
+@@ -252,9 +281,16 @@ static int __init sonic_probe1(struct ne
+       SONIC_WRITE(SONIC_FAET,0xffff);
+       SONIC_WRITE(SONIC_MPT,0xffff);
+-      /* Fill in the fields of the device structure with ethernet values. */
+-      ether_setup(dev);
+       return 0;
++out3:
++      kfree(lp->rba);
++out2:
++      vdma_free(lp->cda_laddr);
++out1:
++      kfree(lp);
++out:
++      release_region(base_addr, 0x100);
++      return err;
+ }
+ /*
+--- linux-2.6.0/drivers/net/Kconfig    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/net/Kconfig     2003-12-28 23:21:01.000000000 -0800
+@@ -657,7 +657,7 @@ config ELMC
+ config ELMC_II
+       tristate "3c527 \"EtherLink/MC 32\" support (EXPERIMENTAL)"
+-      depends on NET_VENDOR_3COM && MCA && EXPERIMENTAL && BROKEN_ON_SMP
++      depends on NET_VENDOR_3COM && MCA && MCA_LEGACY
+       help
+         If you have a network (Ethernet) card of this type, say Y and read
+         the Ethernet-HOWTO, available from
+@@ -1283,6 +1283,19 @@ config B44
+         <file:Documentation/networking/net-modules.txt>.  The module will be
+         called b44.
++config FORCEDETH
++      tristate "Reverse Engineered nForce Ethernet support (EXPERIMENTAL)"
++      depends on NET_PCI && PCI && EXPERIMENTAL
++      help
++        If you have a network (Ethernet) controller of this type, say Y and
++        read the Ethernet-HOWTO, available from
++        <http://www.tldp.org/docs.html#howto>.
++
++        To compile this driver as a module, choose M here and read
++        <file:Documentation/networking/net-modules.txt>.  The module will be
++        called forcedeth.
++
++
+ config CS89x0
+       tristate "CS89x0 support"
+       depends on NET_PCI && ISA
+@@ -1341,8 +1354,9 @@ config EEPRO100_PIO
+         say N.
+ config E100
+-      tristate "EtherExpressPro/100 support (e100, Alternate Intel driver)"
++      tristate "Intel(R) PRO/100+ support"
+       depends on NET_PCI && PCI
++      select MII
+       ---help---
+         This driver supports Intel(R) PRO/100 family of adapters, which 
+         includes:
+@@ -1415,6 +1429,10 @@ config E100
+         <file:Documentation/networking/net-modules.txt>.  The module
+         will be called e100.
++config E100_NAPI
++      bool "Use Rx Polling (NAPI)"
++      depends on E100
++
+ config LNE390
+       tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)"
+       depends on NET_PCI && EISA && EXPERIMENTAL
+@@ -1564,6 +1582,24 @@ config 8139_OLD_RX_RESET
+         experience problems, you can enable this option to restore the
+         old RX-reset behavior.  If unsure, say N.
++config 8139_RXBUF_IDX
++      int "Receive ring size (0 => 8K, 1 => 16K, 2 => 32K, 3 => 64K)"
++      depends on 8139TOO
++      range 0 3
++      default 1 if EMBEDDED || SH_DREAMCAST
++      default 2
++      help
++         The 8139too driver has a fixed area of memory for receiving data.
++         The default value is adequate for most systems. The 64KB 
++         ring size has hardware issues that may cause problems.
++         Values:
++              0  => 8 KB 
++              1  => 16 KB embedded systems
++              2  => 32 KB default for most systems
++              3  => 64 KB 
++         If unsure, use the default 2.
++
++
+ config SIS900
+       tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
+       depends on NET_PCI && PCI
+@@ -1957,9 +1993,11 @@ config SK98LIN
+           - EG1032 v2 Instant Gigabit Network Adapter
+           - EG1064 v2 Instant Gigabit Network Adapter
+           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
++          - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
+           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
+           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
+           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
++          - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
+           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
+           - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
+           - Marvell RDK-8001 Adapter
+@@ -2005,8 +2043,10 @@ config SK98LIN
+         Questions concerning this driver may be addressed to:
+             linux@syskonnect.de
+         
+-        To compile this driver as a module, choose M here: the module
+-        will be called sk98lin.  This is recommended.
++        If you want to compile this driver as a module ( = code which can be
++        inserted in and removed from the running kernel whenever you want),
++        say M here and read Documentation/modules.txt. This is recommended.
++        The module will be called sk98lin. This is recommended.
+ config TIGON3
+       tristate "Broadcom Tigon3 support"
+@@ -2441,6 +2481,13 @@ config SHAPER
+         To compile this driver as a module, choose M here: the module
+         will be called shaper.  If unsure, say N.
++config NETCONSOLE
++      tristate "Network console logging support (EXPERIMENTAL)"
++      depends on NETDEVICES && EXPERIMENTAL
++      ---help---
++      If you want to log kernel messages over the network, enable this.
++      See Documentation/networking/netconsole.txt for details.
++
+ source "drivers/net/wan/Kconfig"
+ source "drivers/net/pcmcia/Kconfig"
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/net/kgdb_eth.c  2003-12-28 23:21:09.000000000 -0800
+@@ -0,0 +1,131 @@
++/*
++ * Network interface GDB stub
++ *
++ * Written by San Mehat (nettwerk@biodome.org)
++ * Based upon 'gdbserial' by David Grothe (dave@gcom.com)
++ * and Scott Foehner (sfoehner@engr.sgi.com)
++ *
++ * Twiddled for 2.6 by Robert Walsh <rjwalsh@durables.org>
++ * and wangdi <wangdi@clusterfs.com>.
++ *
++ * Refactored for netpoll API by Matt Mackall <mpm@selenic.com>
++ *
++ */
++
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/config.h>
++#include <linux/string.h>
++#include <linux/netpoll.h>
++
++#include <asm/system.h>
++#include <asm/kgdb.h>
++#include <asm/io.h>
++#include <asm/bitops.h>
++#include <asm/system.h>
++#include <asm/irq.h>
++#include <asm/atomic.h>
++
++#define IN_BUF_SIZE 512 /* power of 2, please */
++#define OUT_BUF_SIZE 256
++
++static char in_buf[IN_BUF_SIZE], out_buf[OUT_BUF_SIZE];
++static int in_head, in_tail, out_count;
++static atomic_t in_count;
++int kgdboe = 0; /* Default to tty mode */
++
++extern void set_debug_traps(void);
++extern void breakpoint(void);
++static void rx_hook(struct netpoll *np, int port, char *msg, int len);
++
++static struct netpoll np = {
++      .name = "kgdboe",
++      .dev_name = "eth0",
++      .rx_hook = rx_hook,
++      .local_port = 6443,
++      .remote_port = 6442,
++      .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
++};
++
++int eth_getDebugChar(void)
++{
++      int chr;
++
++      while (atomic_read(&in_count) == 0)
++              netpoll_poll(&np);
++
++      chr = in_buf[in_tail++];
++      in_tail &= (IN_BUF_SIZE - 1);
++      atomic_dec(&in_count);
++      return chr;
++}
++
++void eth_flushDebugChar(void)
++{
++      if(out_count && np.dev) {
++              netpoll_send_udp(&np, out_buf, out_count);
++              out_count = 0;
++      }
++}
++
++void eth_putDebugChar(int chr)
++{
++      out_buf[out_count++] = chr;
++      if(out_count == OUT_BUF_SIZE)
++              eth_flushDebugChar();
++}
++
++static void rx_hook(struct netpoll *np, int port, char *msg, int len)
++{
++      int i;
++
++      np->remote_port = port;
++
++      /* Is this gdb trying to attach? */
++      if (!netpoll_trap() && len == 8 && !strncmp(msg, "$Hc-1#09", 8))
++              kgdb_schedule_breakpoint();
++
++      for (i = 0; i < len; i++) {
++              if (msg[i] == 3)
++                      kgdb_schedule_breakpoint();
++
++              if (atomic_read(&in_count) >= IN_BUF_SIZE) {
++                      /* buffer overflow, clear it */
++                      in_head = in_tail = 0;
++                      atomic_set(&in_count, 0);
++                      break;
++              }
++              in_buf[in_head++] = msg[i];
++              in_head &= (IN_BUF_SIZE - 1);
++              atomic_inc(&in_count);
++      }
++}
++
++static int option_setup(char *opt)
++{
++      return netpoll_parse_options(&np, opt);
++}
++
++__setup("kgdboe=", option_setup);
++
++static int init_kgdboe(void)
++{
++#ifdef CONFIG_SMP
++      if (num_online_cpus() > CONFIG_NO_KGDB_CPUS) {
++              printk("kgdb: too manu cpus. Cannot enable debugger with more than %d cpus\n", CONFIG_NO_KGDB_CPUS);
++              return -1;
++      }
++#endif
++
++      set_debug_traps();
++
++      if(!np.remote_ip || netpoll_setup(&np))
++              return 1;
++
++      kgdboe = 1;
++      printk(KERN_INFO "kgdb: debugging over ethernet enabled\n");
++
++      return 0;
++}
++
++module_init(init_kgdboe);
+--- linux-2.6.0/drivers/net/lance.c    2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/lance.c     2003-12-28 23:21:01.000000000 -0800
+@@ -59,8 +59,8 @@ static const char version[] = "lance.c:v
+ #include <asm/dma.h>
+ static unsigned int lance_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0};
+-int lance_probe(struct net_device *dev);
+ static int lance_probe1(struct net_device *dev, int ioaddr, int irq, int options);
++static int __init do_lance_probe(struct net_device *dev);
+ #ifdef LANCE_DEBUG
+ static int lance_debug = LANCE_DEBUG;
+@@ -274,7 +274,6 @@ enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_
+ static unsigned char lance_need_isa_bounce_buffers = 1;
+ static int lance_open(struct net_device *dev);
+-static int lance_open_fail(struct net_device *dev);
+ static void lance_init_ring(struct net_device *dev, int mode);
+ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
+ static int lance_rx(struct net_device *dev);
+@@ -286,10 +285,21 @@ static void lance_tx_timeout (struct net
\f
++static void cleanup_card(struct net_device *dev)
++{
++      struct lance_private *lp = dev->priv;
++      if (dev->dma != 4)
++              free_dma(dev->dma);
++      release_region(dev->base_addr, LANCE_TOTAL_SIZE);
++      kfree(lp->tx_bounce_buffs);
++      kfree((void*)lp->rx_buffs);
++      kfree(lp);
++}
++
+ #ifdef MODULE
+ #define MAX_CARDS             8       /* Max number of interfaces (cards) per module */
+-static struct net_device dev_lance[MAX_CARDS];
++static struct net_device *dev_lance[MAX_CARDS];
+ static int io[MAX_CARDS];
+ static int dma[MAX_CARDS];
+ static int irq[MAX_CARDS];
+@@ -305,28 +315,35 @@ MODULE_PARM_DESC(lance_debug, "LANCE/PCn
+ int init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_lance[this_dev];
+-              dev->irq = irq[this_dev];
+-              dev->base_addr = io[this_dev];
+-              dev->dma = dma[this_dev];
+-              dev->init = lance_probe;
+               if (io[this_dev] == 0)  {
+-                      if (this_dev != 0) break; /* only complain once */
++                      if (this_dev != 0) /* only complain once */
++                              break;
+                       printk(KERN_NOTICE "lance.c: Module autoprobing not allowed. Append \"io=0xNNN\" value(s).\n");
+                       return -EPERM;
+               }
+-              if (register_netdev(dev) != 0) {
+-                      printk(KERN_WARNING "lance.c: No PCnet/LANCE card found (i/o = 0x%x).\n", io[this_dev]);
+-                      if (found != 0) return 0;       /* Got at least one. */
+-                      return -ENXIO;
++              dev = alloc_etherdev(0);
++              if (!dev)
++                      break;
++              dev->irq = irq[this_dev];
++              dev->base_addr = io[this_dev];
++              dev->dma = dma[this_dev];
++              if (do_lance_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_lance[found++] = dev;
++                              continue;
++                      }
++                      cleanup_card(dev);
+               }
+-              found++;
++              free_netdev(dev);
++              break;
+       }
+-
+-      return 0;
++      if (found != 0)
++              return 0;
++      return -ENXIO;
+ }
+ void cleanup_module(void)
+@@ -334,13 +351,11 @@ void cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_lance[this_dev];
+-              if (dev->priv != NULL) {
++              struct net_device *dev = dev_lance[this_dev];
++              if (dev) {
+                       unregister_netdev(dev); 
+-                      free_dma(dev->dma);
+-                      release_region(dev->base_addr, LANCE_TOTAL_SIZE);
+-                      kfree(dev->priv);
+-                      dev->priv = NULL;
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+@@ -352,7 +367,7 @@ MODULE_LICENSE("GPL");
+    board probes now that kmalloc() can allocate ISA DMA-able regions.
+    This also allows the LANCE driver to be used as a module.
+    */
+-int __init lance_probe(struct net_device *dev)
++static int __init do_lance_probe(struct net_device *dev)
+ {
+       int *port, result;
+@@ -387,6 +402,31 @@ int __init lance_probe(struct net_device
+       return -ENODEV;
+ }
++struct net_device * __init lance_probe(int unit)
++{
++      struct net_device *dev = alloc_etherdev(0);
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENODEV);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_lance_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options)
+ {
+       struct lance_private *lp;
+@@ -398,6 +438,7 @@ static int __init lance_probe1(struct ne
+       int hp_builtin = 0;                     /* HP on-board ethernet. */
+       static int did_version;                 /* Already printed version info. */
+       unsigned long flags;
++      int err = -ENOMEM;
+       /* First we look for special cases.
+          Check for HP's on-board ethernet by looking for 'HP' in the BIOS.
+@@ -432,7 +473,7 @@ static int __init lance_probe1(struct ne
+       outw(88, ioaddr+LANCE_ADDR);
+       if (inw(ioaddr+LANCE_ADDR) != 88) {
+               lance_version = 0;
+-      } else {                                                        /* Good, it's a newer chip. */
++      } else {                        /* Good, it's a newer chip. */
+               int chip_version = inw(ioaddr+LANCE_DATA);
+               outw(89, ioaddr+LANCE_ADDR);
+               chip_version |= inw(ioaddr+LANCE_DATA) << 16;
+@@ -447,13 +488,9 @@ static int __init lance_probe1(struct ne
+               }
+       }
+-      /* We can't use init_etherdev() to allocate dev->priv because it must
++      /* We can't allocate dev->priv from alloc_etherdev() because it must
+          a ISA DMA-able region. */
+-      dev = init_etherdev(dev, 0);
+-      if (!dev)
+-              return -ENOMEM;
+       SET_MODULE_OWNER(dev);
+-      dev->open = lance_open_fail;
+       chipname = chip_table[lance_version].name;
+       printk("%s: %s at %#3x,", dev->name, chipname, ioaddr);
+@@ -465,8 +502,7 @@ static int __init lance_probe1(struct ne
+       dev->base_addr = ioaddr;
+       /* Make certain the data structures used by the LANCE are aligned and DMAble. */
+               
+-      lp = (struct lance_private *)(((unsigned long)kmalloc(sizeof(*lp)+7,
+-                                         GFP_DMA | GFP_KERNEL)+7) & ~7);
++      lp = kmalloc(sizeof(*lp), GFP_DMA | GFP_KERNEL);
+       if(lp==NULL)
+               return -ENODEV;
+       if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp);
+@@ -486,7 +522,7 @@ static int __init lance_probe1(struct ne
+               lp->tx_bounce_buffs = NULL;
+       lp->chip_version = lance_version;
+-      lp->devlock = SPIN_LOCK_UNLOCKED;
++      spin_lock_init(&lp->devlock);
+       lp->init_block.mode = 0x0003;           /* Disable Rx and Tx. */
+       for (i = 0; i < 6; i++)
+@@ -540,6 +576,7 @@ static int __init lance_probe1(struct ne
+               dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
+                       (inb(DMA2_STAT_REG) & 0xf0);
+       }
++      err = -ENODEV;
+       if (dev->irq >= 2)
+               printk(" assigned IRQ %d", dev->irq);
+       else if (lance_version != 0)  { /* 7990 boards need DMA detection first. */
+@@ -559,7 +596,7 @@ static int __init lance_probe1(struct ne
+                       printk(", probed IRQ %d", dev->irq);
+               else {
+                       printk(", failed to detect IRQ line.\n");
+-                      return -ENODEV;
++                      goto out_tx;
+               }
+               /* Check for the initialization done bit, 0x0100, which means
+@@ -573,7 +610,7 @@ static int __init lance_probe1(struct ne
+       } else if (dev->dma) {
+               if (request_dma(dev->dma, chipname)) {
+                       printk("DMA %d allocation failed.\n", dev->dma);
+-                      return -ENODEV;
++                      goto out_tx;
+               } else
+                       printk(", assigned DMA %d.\n", dev->dma);
+       } else {                        /* OK, we have to auto-DMA. */
+@@ -613,7 +650,7 @@ static int __init lance_probe1(struct ne
+               }
+               if (i == 4) {                   /* Failure: bail. */
+                       printk("DMA detection failed.\n");
+-                      return -ENODEV;
++                      goto out_tx;
+               }
+       }
+@@ -629,7 +666,7 @@ static int __init lance_probe1(struct ne
+               dev->irq = probe_irq_off(irq_mask);
+               if (dev->irq == 0) {
+                       printk("  Failed to detect the 7990 IRQ line.\n");
+-                      return -ENODEV;
++                      goto out_dma;
+               }
+               printk("  Auto-IRQ detected IRQ%d.\n", dev->irq);
+       }
+@@ -655,18 +692,18 @@ static int __init lance_probe1(struct ne
+       dev->watchdog_timeo = TX_TIMEOUT;
+       return 0;
+-out_rx:       kfree((void*)lp->rx_buffs);
+-out_lp:       kfree(lp);
+-      return -ENOMEM;
+-}
+-
+-static int
+-lance_open_fail(struct net_device *dev)
+-{
+-      return -ENODEV;
++out_dma:
++      if (dev->dma != 4)
++              free_dma(dev->dma);
++out_tx:
++      kfree(lp->tx_bounce_buffs);
++out_rx:
++      kfree((void*)lp->rx_buffs);
++out_lp:
++      kfree(lp);
++      return err;
+ }
+-
\f
+ static int
+ lance_open(struct net_device *dev)
+--- linux-2.6.0/drivers/net/lasi_82596.c       2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/lasi_82596.c        2003-12-28 23:21:01.000000000 -0800
+@@ -1149,12 +1149,11 @@ static void print_eth(unsigned char *add
+ #define LAN_PROM_ADDR 0xF0810000
+-static int __devinit i82596_probe(struct net_device *dev)
++static int __devinit i82596_probe(struct net_device *dev,
++                                struct device *gen_dev)
+ {
+       int i;
+       struct i596_private *lp;
+-      /* we're going to overwrite dev->priv, so pull the device out */
+-      struct device *gen_dev = dev->priv;
+       char eth_addr[6];
+       dma_addr_t dma_addr;
+@@ -1204,7 +1203,6 @@ static int __devinit i82596_probe(struct
+               return -ENOMEM;
+       }
+-      ether_setup(dev);
+       DEB(DEB_PROBE,printk("%s: 82596 at %#3lx,", dev->name, dev->base_addr));
+       for (i = 0; i < 6; i++)
+@@ -1537,12 +1535,19 @@ lan_init_chip(struct parisc_device *dev)
+       netdevice->base_addr = dev->hpa;
+       netdevice->irq = dev->irq;
+-      netdevice->init = i82596_probe;
+-      netdevice->priv = &dev->dev;
++
++      retval = i82596_probe(netdevice, &dev->dev);
++      if (retval) {
++              free_netdev(netdevice);
++              return -ENODEV;
++      }
+       retval = register_netdev(netdevice);
+       if (retval) {
++              struct i596_private *lp = netdevice->priv;
+               printk(KERN_WARNING __FILE__ ": register_netdevice ret'd %d\n", retval);
++              dma_free_noncoherent(lp->dev, sizeof(struct i596_private), 
++                                  (void *)netdevice->mem_start, lp->dma_addr);
+               free_netdev(netdevice);
+               return -ENODEV;
+       };
+--- linux-2.6.0/drivers/net/lne390.c   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/lne390.c    2003-12-28 23:21:01.000000000 -0800
+@@ -49,7 +49,6 @@ static const char *version =
+ #include "8390.h"
+-int lne390_probe(struct net_device *dev);
+ static int lne390_probe1(struct net_device *dev, int ioaddr);
+ static int lne390_open(struct net_device *dev);
+@@ -103,9 +102,11 @@ static unsigned int shmem_mapB[] __initd
+  *    PROM for a match against the value assigned to Mylex.
+  */
+-int __init lne390_probe(struct net_device *dev)
++static int __init do_lne390_probe(struct net_device *dev)
+ {
+       unsigned short ioaddr = dev->base_addr;
++      int irq = dev->irq;
++      int mem_start = dev->mem_start;
+       int ret;
+       SET_MODULE_OWNER(dev);
+@@ -135,11 +136,46 @@ int __init lne390_probe(struct net_devic
+               if (lne390_probe1(dev, ioaddr) == 0)
+                       return 0;
+               release_region(ioaddr, LNE390_IO_EXTENT);
++              dev->irq = irq;
++              dev->mem_start = mem_start;
+       }
+       return -ENODEV;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, LNE390_IO_EXTENT);
++      if (ei_status.reg0)
++              iounmap((void *)dev->mem_start);
++}
++
++struct net_device * __init lne390_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_lne390_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
+ {
+       int i, revision, ret;
+@@ -174,11 +210,6 @@ static int __init lne390_probe1(struct n
+               return -ENODEV;
+       }
+ #endif
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev)) {
+-              printk ("lne390.c: unable to allocate memory for dev->priv!\n");
+-              return -ENOMEM;
+-      }
+       printk("lne390.c: LNE390%X in EISA slot %d, address", 0xa+revision, ioaddr/0x1000);
+       for(i = 0; i < ETHER_ADDR_LEN; i++)
+@@ -199,8 +230,6 @@ static int __init lne390_probe1(struct n
+       if ((ret = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
+               printk (" unable to get IRQ %d.\n", dev->irq);
+-              kfree(dev->priv);
+-              dev->priv = NULL;
+               return ret;
+       }
+@@ -274,8 +303,6 @@ static int __init lne390_probe1(struct n
+       return 0;
+ cleanup:
+       free_irq(dev->irq, dev);
+-      kfree(dev->priv);
+-      dev->priv = NULL;
+       return ret;
+ }
+@@ -373,7 +400,7 @@ static int lne390_close(struct net_devic
+ #ifdef MODULE
+ #define MAX_LNE_CARDS 4       /* Max number of LNE390 cards per module */
+-static struct net_device dev_lne[MAX_LNE_CARDS];
++static struct net_device *dev_lne[MAX_LNE_CARDS];
+ static int io[MAX_LNE_CARDS];
+ static int irq[MAX_LNE_CARDS];
+ static int mem[MAX_LNE_CARDS];
+@@ -389,26 +416,32 @@ MODULE_LICENSE("GPL");
+ int init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_lne[this_dev];
++              if (io[this_dev] == 0 && this_dev != 0)
++                      break;
++              dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
+               dev->irq = irq[this_dev];
+               dev->base_addr = io[this_dev];
+               dev->mem_start = mem[this_dev];
+-              dev->init = lne390_probe;
+-              /* Default is to only install one card. */
+-              if (io[this_dev] == 0 && this_dev != 0) break;
+-              if (register_netdev(dev) != 0) {
+-                      printk(KERN_WARNING "lne390.c: No LNE390 card found (i/o = 0x%x).\n", io[this_dev]);
+-                      if (found != 0) {       /* Got at least one. */
+-                              return 0;
++              if (do_lne390_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_lne[found++] = dev;
++                              continue;
+                       }
+-                      return -ENXIO;
++                      cleanup_card(dev);
+               }
+-              found++;
+-      }
+-      return 0;
++              free_netdev(dev);
++              printk(KERN_WARNING "lne390.c: No LNE390 card found (i/o = 0x%x).\n", io[this_dev]);
++              break;
++      }
++      if (found)
++              return 0;
++      return -ENXIO;
+ }
+ void cleanup_module(void)
+@@ -416,15 +449,11 @@ void cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_lne[this_dev];
+-              if (dev->priv != NULL) {
+-                      void *priv = dev->priv;
+-                      free_irq(dev->irq, dev);
+-                      release_region(dev->base_addr, LNE390_IO_EXTENT);
+-                      if (ei_status.reg0)
+-                              iounmap((void *)dev->mem_start);
++              struct net_device *dev = dev_lne[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(priv);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/lp486e.c   2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/lp486e.c    2003-12-28 23:21:01.000000000 -0800
+@@ -1314,18 +1314,23 @@ static int io = IOADDR;
+ static int irq = IRQ;
+ static int __init lp486e_init_module(void) {
+-      struct net_device *dev;
+-
+-      dev = alloc_etherdev(sizeof(struct i596_private));
++      int err;
++      struct net_device *dev = alloc_etherdev(sizeof(struct i596_private));
+       if (!dev)
+               return -ENOMEM;
+       dev->irq = irq;
+       dev->base_addr = io;
+-      dev->init = lp486e_probe;
+-      if (register_netdev(dev) != 0) {
++      err = lp486e_probe(dev);
++      if (err) {
++              free_netdev(dev);
++              return err;
++      }
++      err = register_netdev(dev);
++      if (err) {
++              release_region(dev->base_addr, LP486E_TOTAL_SIZE);
+               free_netdev(dev);
+-              return -EIO;
++              return err;
+       }
+       dev_lp486e = dev;
+       full_duplex = 0;
+--- linux-2.6.0/drivers/net/mac8390.c  2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/mac8390.c   2003-12-28 23:21:01.000000000 -0800
+@@ -124,11 +124,10 @@ static int useresources[] = {
+ static char version[] __initdata =
+       "mac8390.c: v0.4 2001-05-15 David Huggins-Daines <dhd@debian.org> and others\n";
+               
+-extern int mac8390_probe(struct net_device * dev);
+ extern enum mac8390_type mac8390_ident(struct nubus_dev * dev);
+ extern int mac8390_memsize(unsigned long membase);
+ extern int mac8390_memtest(struct net_device * dev);
+-extern int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
++static int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
+                          enum mac8390_type type);
+ static int mac8390_open(struct net_device * dev);
+@@ -223,43 +222,43 @@ int __init mac8390_memsize(unsigned long
+       return i * 0x1000;
+ }
+-static int probed __initdata = 0;
+-
+-int __init mac8390_probe(struct net_device * dev)
++struct net_device * __init mac8390_probe(int unit)
+ {
++      struct net_device *dev;
+       volatile unsigned short *i;
+-      int boards_found = 0;
+       int version_disp = 0;
+       struct nubus_dev * ndev = NULL;
++      int err = -ENODEV;
+       
+       struct nubus_dir dir;
+       struct nubus_dirent ent;
+       int offset;
++      static unsigned int slots;
+       enum mac8390_type cardtype;
+-      if (probed)
+-              return -ENODEV;
+-      probed++;
+-
+       /* probably should check for Nubus instead */
+       if (!MACH_IS_MAC)
+-              return -ENODEV;
++              return ERR_PTR(-ENODEV);
++
++      dev = alloc_ei_netdev();
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (unit >= 0)
++              sprintf(dev->name, "eth%d", unit);
++
++      SET_MODULE_OWNER(dev);
+       while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, ndev))) {
+-              
+-              dev = NULL;
+-              
+-              if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE)
++              /* Have we seen it already? */
++              if (slots & (1<<ndev->board->slot))
+                       continue;
++              slots |= 1<<ndev->board->slot;
+-              dev = init_etherdev(dev, 0);
+-              if (dev == NULL) {
+-                      printk(KERN_ERR "Unable to allocate etherdev"
+-                                      "structure!\n");
+-                      return -ENOMEM;
+-              }
++              if ((cardtype = mac8390_ident(ndev)) == MAC8390_NONE)
++                      continue;
+               if (version_disp == 0) {
+                       version_disp = 1;
+@@ -358,21 +357,25 @@ int __init mac8390_probe(struct net_devi
+                                       printk(KERN_ERR "Card type %s is"
+                                                       " unsupported, sorry\n",
+                                              cardname[cardtype]);
+-                                      return -ENODEV;
++                                      continue;
+                       }
+               }
+               /* Do the nasty 8390 stuff */
+-              if (mac8390_initdev(dev, ndev, cardtype))
+-                      continue;
+-              boards_found++;
++              if (!mac8390_initdev(dev, ndev, cardtype))
++                      break;
+       }
+-      /* We're outta here */
+-      if (boards_found > 0)
+-              return 0;
+-      else
+-              return -ENODEV;
++      if (!ndev)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out;
++      return dev;
++
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ #ifdef MODULE
+@@ -380,26 +383,39 @@ MODULE_AUTHOR("David Huggins-Daines <dhd
+ MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver");
+ MODULE_LICENSE("GPL");
++/* overkill, of course */
++static struct net_device *dev_mac8390[15];
+ int init_module(void)
+ {
+-      if (mac8390_probe(NULL)) {
++      int i;
++      for (i = 0; i < 15; i++) {
++              struct net_device *dev = mac8390_probe(-1);
++              if (IS_ERR(dev))
++                      break;
++              dev_mac890[i] = dev;
++      }
++      if (!i) {
+               printk(KERN_NOTICE "mac8390.c: No useable cards found, driver NOT installed.\n");
+               return -ENODEV;
+       }
+-      lock_8390_module();
+       return 0;
+ }
+ void cleanup_module(void)
+ {
+-      /* FIXME: should probably keep track of net_device structs
+-           somewhere and unregister them here? */
+-      unlock_8390_module();
++      int i;
++      for (i = 0; i < 15; i++) {
++              struct net_device *dev = dev_mac890[i];
++              if (dev) {
++                      unregister_netdev(dev);
++                      free_netdev(dev);
++              }
++      }
+ }
+ #endif /* MODULE */
+-int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
++static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
+                           enum mac8390_type type)
+ {
+       static u32 fwrd4_offsets[16]={
+@@ -423,12 +439,6 @@ int __init mac8390_initdev(struct net_de
+       int access_bitmode;
+       
+-      /* 8390 specific init for dev - allocates dev->priv */
+-      if (ethdev_init(dev)) {
+-              printk(KERN_ERR "%s: Unable to allocate memory for dev->priv!\n", dev->name);
+-              return -ENOMEM;
+-      }
+-
+       /* Now fill in our stuff */
+       dev->open = &mac8390_open;
+       dev->stop = &mac8390_close;
+@@ -529,7 +539,6 @@ static int mac8390_open(struct net_devic
+               printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
+               return -EAGAIN;
+       }       
+-      MOD_INC_USE_COUNT;
+       return 0;
+ }
+@@ -537,7 +546,6 @@ static int mac8390_close(struct net_devi
+ {
+       free_irq(dev->irq, dev);
+       ei_close(dev);
+-      MOD_DEC_USE_COUNT;
+       return 0;
+ }
+--- linux-2.6.0/drivers/net/mac89x0.c  2003-06-14 12:18:21.000000000 -0700
++++ 25/drivers/net/mac89x0.c   2003-12-28 23:21:01.000000000 -0800
+@@ -123,7 +123,6 @@ struct net_local {
+ /* Index to functions, as function prototypes. */
+-extern int mac89x0_probe(struct net_device *dev);
+ #if 0
+ extern void reset_chip(struct net_device *dev);
+ #endif
+@@ -170,8 +169,9 @@ writereg(struct net_device *dev, int por
+ /* Probe for the CS8900 card in slot E.  We won't bother looking
+    anywhere else until we have a really good reason to do so. */
+-int __init mac89x0_probe(struct net_device *dev)
++struct net_device * __init mac89x0_probe(int unit)
+ {
++      struct net_device *dev;
+       static int once_is_enough;
+       struct net_local *lp;
+       static unsigned version_printed;
+@@ -179,18 +179,28 @@ int __init mac89x0_probe(struct net_devi
+       unsigned rev_type = 0;
+       unsigned long ioaddr;
+       unsigned short sig;
++      int err = -ENODEV;
++
++      dev = alloc_etherdev(sizeof(struct net_local));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
+       SET_MODULE_OWNER(dev);
+       if (once_is_enough)
+-              return -ENODEV;
++              goto out;
+       once_is_enough = 1;
+       /* We might have to parameterize this later */
+       slot = 0xE;
+       /* Get out now if there's a real NuBus card in slot E */
+       if (nubus_find_slot(slot, NULL) != NULL)
+-              return -ENODEV; 
++              goto out;
+       /* The pseudo-ISA bits always live at offset 0x300 (gee,
+            wonder why...) */
+@@ -206,21 +216,15 @@ int __init mac89x0_probe(struct net_devi
+               local_irq_restore(flags);
+               if (!card_present)
+-                      return -ENODEV;
++                      goto out;
+       }
+       nubus_writew(0, ioaddr + ADD_PORT);
+       sig = nubus_readw(ioaddr + DATA_PORT);
+       if (sig != swab16(CHIP_EISA_ID_SIG))
+-              return -ENODEV;
++              goto out;
+       /* Initialize the net_device structure. */
+-      if (dev->priv == NULL) {
+-              dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-              if (!dev->priv)
+-                      return -ENOMEM;
+-                memset(dev->priv, 0, sizeof(struct net_local));
+-        }
+       lp = (struct net_local *)dev->priv;
+       /* Fill in the 'dev' fields. */
+@@ -258,9 +262,7 @@ int __init mac89x0_probe(struct net_devi
+       /* Try to read the MAC address */
+       if ((readreg(dev, PP_SelfST) & (EEPROM_PRESENT | EEPROM_OK)) == 0) {
+               printk("\nmac89x0: No EEPROM, giving up now.\n");
+-              kfree(dev->priv);
+-              dev->priv = NULL;
+-              return -ENODEV;
++              goto out1;
+         } else {
+                 for (i = 0; i < ETH_ALEN; i += 2) {
+                       /* Big-endian (why??!) */
+@@ -277,6 +279,7 @@ int __init mac89x0_probe(struct net_devi
+       for (i = 0; i < ETH_ALEN; i++)
+               printk("%2.2x%s", dev->dev_addr[i],
+                      ((i < ETH_ALEN-1) ? ":" : ""));
++      printk("\n");
+       dev->open               = net_open;
+       dev->stop               = net_close;
+@@ -285,11 +288,15 @@ int __init mac89x0_probe(struct net_devi
+       dev->set_multicast_list = &set_multicast_list;
+       dev->set_mac_address = &set_mac_address;
+-      /* Fill in the fields of the net_device structure with ethernet values. */
+-      ether_setup(dev);
+-
+-      printk("\n");
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
+       return 0;
++out1:
++      nubus_writew(0, dev->base_addr + ADD_PORT);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ #if 0
+@@ -619,7 +626,7 @@ static int set_mac_address(struct net_de
+ #ifdef MODULE
+-static struct net_device dev_cs89x0;
++static struct net_device *dev_cs89x0;
+ static int debug;
+ MODULE_PARM(debug, "i");
+@@ -630,36 +637,20 @@ int
+ init_module(void)
+ {
+       net_debug = debug;
+-        dev_cs89x0.init = mac89x0_probe;
+-        dev_cs89x0.priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-      if (!dev_cs89x0.priv)
+-              return -ENOMEM;
+-      memset(dev_cs89x0.priv, 0, sizeof(struct net_local));
+-
+-        if (register_netdev(&dev_cs89x0) != 0) {
++        dev_cs89x0 = mac89x0_probe(-1);
++      if (IS_ERR(dev_cs89x0)) {
+                 printk(KERN_WARNING "mac89x0.c: No card found\n");
+-              kfree(dev_cs89x0.priv);
+-                return -ENXIO;
+-        }
++              return PTR_ERR(dev_cs89x0);
++      }
+       return 0;
+ }
+ void
+ cleanup_module(void)
+ {
+-
+-#endif
+-#ifdef MODULE
+-      nubus_writew(0, dev_cs89x0.base_addr + ADD_PORT);
+-#endif
+-#ifdef MODULE
+-
+-        if (dev_cs89x0.priv != NULL) {
+-                /* Free up the private structure, or leak memory :-)  */
+-                unregister_netdev(&dev_cs89x0);
+-                kfree(dev_cs89x0.priv);
+-                dev_cs89x0.priv = NULL;       /* gets re-allocated by cs89x0_probe1 */
+-        }
++      unregister_netdev(dev_cs89x0);
++      nubus_writew(0, dev_cs89x0->base_addr + ADD_PORT);
++      free_netdev(dev_cs89x0);
+ }
+ #endif /* MODULE */
\f
+--- linux-2.6.0/drivers/net/mace.c     2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/mace.c      2003-12-28 23:21:01.000000000 -0800
+@@ -142,6 +142,10 @@ static void __init mace_probe1(struct de
+               }
+       }
++      /*
++       * lazy allocation - it's a driver-wide thing and it will live until
++       * the unload, but we don't allocate it until it's needed
++       */
+       if (dummy_buf == NULL) {
+               dummy_buf = kmalloc(RX_BUFLEN+2, GFP_KERNEL);
+               if (dummy_buf == NULL) {
+@@ -150,7 +154,7 @@ static void __init mace_probe1(struct de
+               }
+       }
+-      dev = init_etherdev(0, PRIV_BYTES);
++      dev = alloc_etherdev(PRIV_BYTES);
+       if (!dev)
+               return;
+       SET_MODULE_OWNER(dev);
+@@ -160,16 +164,16 @@ static void __init mace_probe1(struct de
+       
+       if (!request_OF_resource(mace, 0, " (mace)")) {
+               printk(KERN_ERR "MACE: can't request IO resource !\n");
+-              goto err_out;
++              goto out1;
+       }
+       if (!request_OF_resource(mace, 1, " (mace tx dma)")) {
+               printk(KERN_ERR "MACE: can't request TX DMA resource !\n");
+-              goto err_out;
++              goto out2;
+       }
+       if (!request_OF_resource(mace, 2, " (mace tx dma)")) {
+               printk(KERN_ERR "MACE: can't request RX DMA resource !\n");
+-              goto err_out;
++              goto out3;
+       }
+       dev->base_addr = mace->addrs[0].address;
+@@ -229,30 +233,42 @@ static void __init mace_probe1(struct de
+       dev->set_multicast_list = mace_set_multicast;
+       dev->set_mac_address = mace_set_address;
+-      ether_setup(dev);
+-
+       mace_reset(dev);
+-      if (request_irq(dev->irq, mace_interrupt, 0, "MACE", dev))
++      if (request_irq(dev->irq, mace_interrupt, 0, "MACE", dev)) {
+               printk(KERN_ERR "MACE: can't get irq %d\n", dev->irq);
++              goto out4;
++      }
+       if (request_irq(mace->intrs[1].line, mace_txdma_intr, 0, "MACE-txdma",
+-                      dev))
++                      dev)) {
+               printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[1].line);
++              goto out5;
++      }
+       if (request_irq(mace->intrs[2].line, mace_rxdma_intr, 0, "MACE-rxdma",
+-                      dev))
++                      dev)) {
+               printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[2].line);
++              goto out6;
++      }
++      if (register_netdev(dev) != 0)
++              goto out7;
+       mp->next_mace = mace_devs;
+       mace_devs = dev;
+       return;
+       
+-err_out:
+-      unregister_netdev(dev);
+-      if (mp->of_node) {
+-              release_OF_resource(mp->of_node, 0);
+-              release_OF_resource(mp->of_node, 1);
+-              release_OF_resource(mp->of_node, 2);
+-      }
++out7:
++      free_irq(mp->rx_dma_intr, dev);
++out6:
++      free_irq(mp->tx_dma_intr, dev);
++out5:
++      free_irq(dev->irq, dev);
++out4:
++      release_OF_resource(mp->of_node, 2);
++out3:
++      release_OF_resource(mp->of_node, 1);
++out2:
++      release_OF_resource(mp->of_node, 0);
++out1:
+       free_netdev(dev);
+ }
+@@ -975,7 +991,7 @@ static void __exit mace_cleanup (void)
+               release_OF_resource(mp->of_node, 1);
+               release_OF_resource(mp->of_node, 2);
+-              kfree(dev);
++              free_netdev(dev);
+     }
+     if (dummy_buf != NULL) {
+               kfree(dummy_buf);
+--- linux-2.6.0/drivers/net/macmace.c  2003-06-14 12:18:07.000000000 -0700
++++ 25/drivers/net/macmace.c   2003-12-28 23:21:01.000000000 -0800
+@@ -180,7 +180,7 @@ static void mace_dma_off(struct net_devi
+  * model of Macintrash has a MACE (AV macintoshes)
+  */
+  
+-int mace_probe(struct net_device *unused)
++struct net_device *mace_probe(int unit)
+ {
+       int j;
+       struct mace_data *mp;
+@@ -188,13 +188,19 @@ int mace_probe(struct net_device *unused
+       struct net_device *dev;
+       unsigned char checksum = 0;
+       static int found = 0;
++      int err;
+       
+-      if (found || macintosh_config->ether_type != MAC_ETHER_MACE) return -ENODEV;
++      if (found || macintosh_config->ether_type != MAC_ETHER_MACE)
++              return ERR_PTR(-ENODEV);
+       found = 1;      /* prevent 'finding' one on every device probe */
+-      dev = init_etherdev(0, PRIV_BYTES);
+-      if (!dev) return -ENOMEM;
++      dev = alloc_etherdev(PRIV_BYTES);
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (unit >= 0)
++              sprintf(dev->name, "eth%d", unit);
+       mp = (struct mace_data *) dev->priv;
+       dev->base_addr = (u32)MACE_BASE;
+@@ -221,7 +227,10 @@ int mace_probe(struct net_device *unused
+               checksum ^= bitrev(addr[j<<4]);
+       }
+       
+-      if (checksum != 0xFF) return -ENODEV;
++      if (checksum != 0xFF) {
++              free_netdev(dev);
++              return ERR_PTR(-ENODEV);
++      }
+       memset(&mp->stats, 0, sizeof(mp->stats));
+@@ -234,13 +243,16 @@ int mace_probe(struct net_device *unused
+       dev->set_multicast_list = mace_set_multicast;
+       dev->set_mac_address    = mace_set_address;
+-      ether_setup(dev);
+-
+       printk(KERN_INFO "%s: 68K MACE, hardware address %.2X", dev->name, dev->dev_addr[0]);
+       for (j = 1 ; j < 6 ; j++) printk(":%.2X", dev->dev_addr[j]);
+       printk("\n");
+-      return 0;
++      err = register_netdev(dev);
++      if (!err)
++              return dev;
++
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /*
+--- linux-2.6.0/drivers/net/macsonic.c 2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/net/macsonic.c  2003-12-28 23:21:01.000000000 -0800
+@@ -74,7 +74,6 @@ static int sonic_version_printed;
+ static int reg_offset;
+-extern int macsonic_probe(struct net_device* dev);
+ extern int mac_onboard_sonic_probe(struct net_device* dev);
+ extern int mac_nubus_sonic_probe(struct net_device* dev);
+@@ -110,14 +109,38 @@ enum macsonic_type {
+ #define SONIC_READ_PROM(addr) nubus_readb(prom_addr+addr)
+-int __init macsonic_probe(struct net_device* dev)
++struct net_device * __init macsonic_probe(int unit)
+ {
+-      int rv;
++      struct net_device *dev = alloc_etherdev(0);
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (unit >= 0)
++              sprintf(dev->name, "eth%d", unit);
++
++      SET_MODULE_OWNER(dev);
+       /* This will catch fatal stuff like -ENOMEM as well as success */
+-      if ((rv = mac_onboard_sonic_probe(dev)) != -ENODEV)
+-              return rv;
+-      return mac_nubus_sonic_probe(dev);
++      err = mac_onboard_sonic_probe(dev);
++      if (err == 0)
++              goto found;
++      if (err != -ENODEV)
++              goto out;
++      err = mac_nubus_sonic_probe(dev);
++      if (err)
++              goto out;
++found:
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      kfree(dev->priv);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /*
+@@ -195,6 +218,7 @@ int __init macsonic_init(struct net_devi
+       if ((lp->rba = (char *)
+            kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) {
+               printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name);
++              dev->priv = NULL;
+               kfree(lp);
+               return -ENOMEM;
+       }
+@@ -229,8 +253,6 @@ int __init macsonic_init(struct net_devi
+       sonic_write(dev, SONIC_FAET, 0xffff);
+       sonic_write(dev, SONIC_MPT, 0xffff);
+-      /* Fill in the fields of the device structure with ethernet values. */
+-      ether_setup(dev);
+       return 0;
+ }
+@@ -344,30 +366,6 @@ int __init mac_onboard_sonic_probe(struc
+       printk("yes\n");        
+-      if (dev) {
+-              dev = init_etherdev(dev, sizeof(struct sonic_local));
+-              if (!dev)
+-                      return -ENOMEM;
+-              /* methinks this will always be true but better safe than sorry */
+-              if (dev->priv == NULL) {
+-                      dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL);
+-                      if (!dev->priv)
+-                              return -ENOMEM;
+-              }
+-      } else {
+-              dev = init_etherdev(NULL, sizeof(struct sonic_local));
+-      }
+-
+-      if (dev == NULL)
+-              return -ENOMEM;
+-
+-      if(dev->priv) {
+-              printk("%s: warning! sonic entering with priv already allocated!\n",
+-                     dev->name);
+-              printk("%s: discarding, will attempt to reallocate\n", dev->name);
+-              dev->priv = NULL;
+-      }
+-
+       /* Danger!  My arms are flailing wildly!  You *must* set this
+            before using sonic_read() */
+@@ -497,7 +495,6 @@ int __init mac_nubus_sonic_probe(struct 
+ {
+       static int slots;
+       struct nubus_dev* ndev = NULL;
+-      struct sonic_local* lp;
+       unsigned long base_addr, prom_addr;
+       u16 sonic_dcr;
+       int id;
+@@ -567,25 +564,6 @@ int __init mac_nubus_sonic_probe(struct 
+               return -ENODEV;
+       }
+-      if (dev) {
+-              dev = init_etherdev(dev, sizeof(struct sonic_local));
+-              if (!dev)
+-                      return -ENOMEM;
+-              /* methinks this will always be true but better safe than sorry */
+-              if (dev->priv == NULL) {
+-                      dev->priv = kmalloc(sizeof(struct sonic_local), GFP_KERNEL);
+-                      if (!dev->priv) /* FIXME: kfree dev if necessary */
+-                              return -ENOMEM;
+-              }
+-      } else {
+-              dev = init_etherdev(NULL, sizeof(struct sonic_local));
+-      }
+-
+-      if (dev == NULL)
+-              return -ENOMEM;
+-
+-      lp = (struct sonic_local*) dev->priv;
+-      memset(lp, 0, sizeof(struct sonic_local));
+       /* Danger!  My arms are flailing wildly!  You *must* set this
+            before using sonic_read() */
+       dev->base_addr = base_addr;
+@@ -631,8 +609,7 @@ int __init mac_nubus_sonic_probe(struct 
+ }
+ #ifdef MODULE
+-static char namespace[16] = "";
+-static struct net_device dev_macsonic;
++static struct net_device *dev_macsonic;
+ MODULE_PARM(sonic_debug, "i");
+ MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
+@@ -641,24 +618,20 @@ MODULE_LICENSE("GPL");
+ int
+ init_module(void)
+ {
+-        dev_macsonic.name = namespace;
+-        dev_macsonic.init = macsonic_probe;
+-
+-        if (register_netdev(&dev_macsonic) != 0) {
++        dev_macsonic = macsonic_probe(-1);
++      if (IS_ERR(dev_macsonic)) {
+                 printk(KERN_WARNING "macsonic.c: No card found\n");
+-                return -ENXIO;
+-        }
++              return PTR_ERR(dev_macsonic);
++      }
+       return 0;
+ }
+ void
+ cleanup_module(void)
+ {
+-        if (dev_macsonic.priv != NULL) {
+-                unregister_netdev(&dev_macsonic);
+-                kfree(dev_macsonic.priv);
+-                dev_macsonic.priv = NULL;
+-        }
++      unregister_netdev(dev_macsonic);
++      kfree(dev_macsonic->priv);
++      free_netdev(dev_macsonic);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/Makefile   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/net/Makefile    2003-12-28 23:21:09.000000000 -0800
+@@ -8,7 +8,6 @@ ifeq ($(CONFIG_ISDN_PPP),y)
+   obj-$(CONFIG_ISDN) += slhc.o
+ endif
+-obj-$(CONFIG_E100) += e100/
+ obj-$(CONFIG_E1000) += e1000/
+ obj-$(CONFIG_IXGB) += ixgb/
+ obj-$(CONFIG_BONDING) += bonding/
+@@ -39,6 +38,7 @@ obj-$(CONFIG_TYPHOON) += typhoon.o
+ obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
+ obj-$(CONFIG_PCNET32) += pcnet32.o
+ obj-$(CONFIG_EEPRO100) += eepro100.o
++obj-$(CONFIG_E100) += e100.o
+ obj-$(CONFIG_TLAN) += tlan.o
+ obj-$(CONFIG_EPIC100) += epic100.o
+ obj-$(CONFIG_SIS190) += sis190.o
+@@ -95,6 +95,7 @@ obj-$(CONFIG_LNE390) += lne390.o 8390.o
+ obj-$(CONFIG_NE3210) += ne3210.o 8390.o
+ obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o
+ obj-$(CONFIG_B44) += b44.o
++obj-$(CONFIG_FORCEDETH) += forcedeth.o
+ obj-$(CONFIG_PPP) += ppp_generic.o slhc.o
+ obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
+@@ -111,7 +112,6 @@ endif
+ obj-$(CONFIG_DUMMY) += dummy.o
+ obj-$(CONFIG_DE600) += de600.o
+ obj-$(CONFIG_DE620) += de620.o
+-obj-$(CONFIG_AT1500) += lance.o
+ obj-$(CONFIG_LANCE) += lance.o
+ obj-$(CONFIG_SUN3_82586) += sun3_82586.o
+ obj-$(CONFIG_SUN3LANCE) += sun3lance.o
+@@ -188,3 +188,6 @@ obj-$(CONFIG_NET_TULIP) += tulip/
+ obj-$(CONFIG_HAMRADIO) += hamradio/
+ obj-$(CONFIG_IRDA) += irda/
++# Must come after all NICs that might use them
++obj-$(CONFIG_NETCONSOLE) += netconsole.o
++obj-$(CONFIG_KGDB) += kgdb_eth.o
+--- linux-2.6.0/drivers/net/meth.c     2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/meth.c      2003-12-28 23:21:01.000000000 -0800
+@@ -95,7 +95,6 @@ typedef struct meth_private {
+     spinlock_t meth_lock;
+ } meth_private;
+-extern struct net_device meth_devs[];
+ void meth_tx_timeout (struct net_device *dev);
+ void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs);
+         
+@@ -762,17 +761,16 @@ struct net_device_stats *meth_stats(stru
+ /*
+  * The init function (sometimes called probe).
+- * It is invoked by register_netdev()
+  */
+-int meth_init(struct net_device *dev)
++static struct net_device *meth_init(struct net_device *dev)
+ {
++      struct net_device *dev;
+       meth_private *priv;
+       int ret;
+-      /* 
+-       * Then, assign other fields in dev, using ether_setup() and some
+-       * hand assignments
+-       */
+-      ether_setup(dev); /* assign some of the fields */
++
++      dev = alloc_etherdev(sizeof(struct meth_private));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+       dev->open            = meth_open;
+       dev->stop            = meth_release;
+@@ -787,16 +785,8 @@ int meth_init(struct net_device *dev)
+       dev->irq                 = MACE_ETHERNET_IRQ;
+       SET_MODULE_OWNER(dev);
+-      /*
+-       * Then, allocate the priv field. This encloses the statistics
+-       * and a few private fields.
+-       */
+-      priv = kmalloc(sizeof(struct meth_private), GFP_KERNEL);
+-      if (priv == NULL)
+-              return -ENOMEM;
+-      dev->priv=priv;
+-      memset(priv, 0, sizeof(struct meth_private));
+-      spin_lock_init(&((struct meth_private *) dev->priv)->meth_lock);
++      priv = dev->priv;
++      spin_lock_init(&priv->meth_lock);
+       /*
+        * Make the usual checks: check_region(), probe irq, ...  -ENODEV
+        * should be returned if no device found.  No resource should be
+@@ -807,28 +797,41 @@ int meth_init(struct net_device *dev)
+       priv->phy_addr = -1; /* No phy is known yet... */
+       /* Initialize the hardware */
+-      if((ret=meth_reset(dev)) < 0)
+-              return ret;
++      ret = meth_reset(dev);
++      if (ret < 0)
++              goto out;
+       /* Allocate the ring buffers */
+-      if((ret=meth_init_tx_ring(priv))<0||(ret=meth_init_rx_ring(priv))<0){
+-              meth_free_tx_ring(priv);
+-              meth_free_rx_ring(priv);
+-              return ret;
+-      }
++      ret = meth_init_tx_ring(priv);
++      if (ret < 0)
++              goto out;
++
++      ret = meth_init_rx_ring(priv);
++      if (ret < 0)
++              goto out1;
++
++      ret = register_netdev(dev);
++      if (ret)
++              goto out2;
+       printk("SGI O2 Fast Ethernet rev. %ld\n", priv->regs->mac_ctrl >> 29);
+-    return 0;
++      return ret;
++
++out2:
++      meth_free_rx_ring(priv);
++out1:
++      meth_free_tx_ring(priv);
++out:
++      free_netdev(dev);
++      return ERR_PTR(ret);
+ }
+ /*
+  * The devices
+  */
+-struct net_device meth_devs[1] = {
+-    { init: meth_init, }  /* init, nothing more */
+-};
++struct net_device *meth_dev;
+ /*
+  * Finally, the module stuff
+@@ -836,23 +839,19 @@ struct net_device meth_devs[1] = {
+ int meth_init_module(void)
+ {
+-      int result, device_present = 0;
+-
+-      strcpy(meth_devs[0].name, "eth%d");
+-
+-      if ( (result = register_netdev(meth_devs)) )
+-              printk("meth: error %i registering device \"%s\"\n",
+-                     result, meth_devs->name);
+-      else device_present++;
+-      
+-      return device_present ? 0 : -ENODEV;
++      meth_dev = meth_init();
++      if (IS_ERR(meth_dev))
++              return PTR_ERR(meth_dev);
++      return 0;
+ }
+ void meth_cleanup(void)
+ {
+-    kfree(meth_devs->priv);
+-    unregister_netdev(meth_devs);
+-    return;
++      meth_private *priv = meth_dev->priv;
++      unregister_netdev(meth_dev);
++      meth_free_rx_ring(priv);
++      meth_free_tx_ring(priv);
++      free_netdev(meth_dev);
+ }
+ module_init(meth_init_module);
+--- linux-2.6.0/drivers/net/mvme147.c  2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/mvme147.c   2003-12-28 23:21:01.000000000 -0800
+@@ -41,7 +41,7 @@
+ struct m147lance_private {
+       struct lance_private lance;
+       void *base;
+-      void *ram;
++      unsigned long ram;
+ };
+ /* function prototypes... This is easy because all the grot is in the
+@@ -49,7 +49,6 @@ struct m147lance_private {
+  * plus board-specific init, open and close actions.
+  * Oh, and we need to tell the generic code how to read and write LANCE registers...
+  */
+-int mvme147lance_probe(struct net_device *dev);
+ static int m147lance_open(struct net_device *dev);
+ static int m147lance_close(struct net_device *dev);
+ static void m147lance_writerap(struct m147lance_private *lp, unsigned short value);
+@@ -60,29 +59,29 @@ typedef void (*writerap_t)(void *, unsig
+ typedef void (*writerdp_t)(void *, unsigned short);
+ typedef unsigned short (*readrdp_t)(void *);
+-#ifdef MODULE
+-static struct m147lance_private *root_m147lance_dev;
+-#endif
+-
+ /* Initialise the one and only on-board 7990 */
+-int __init mvme147lance_probe(struct net_device *dev)
++struct net_device * __init mvme147lance_probe(int unit)
+ {
++      struct net_device *dev;
+       static int called;
+       static const char name[] = "MVME147 LANCE";
+       struct m147lance_private *lp;
+       u_long *addr;
+       u_long address;
++      int err;
+       if (!MACH_IS_MVME147 || called)
+-              return -ENODEV;
++              return ERR_PTR(-ENODEV);
+       called++;
+-      SET_MODULE_OWNER(dev);
++      dev = alloc_etherdev(sizeof(struct m147lance_private));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+-      dev->priv = kmalloc(sizeof(struct m147lance_private), GFP_KERNEL);
+-      if (dev->priv == NULL)
+-              return -ENOMEM;
+-      memset(dev->priv, 0, sizeof(struct m147lance_private));
++      if (unit >= 0)
++              sprintf(dev->name, "eth%d", unit);
++
++      SET_MODULE_OWNER(dev);
+       /* Fill the dev fields */
+       dev->base_addr = (unsigned long)MVME147_LANCE_BASE;
+@@ -114,11 +113,12 @@ int __init mvme147lance_probe(struct net
+               dev->dev_addr[5]);
+       lp = (struct m147lance_private *)dev->priv;
+-      lp->ram = (void *)__get_dma_pages(GFP_ATOMIC, 3);       /* 16K */
++      lp->ram = __get_dma_pages(GFP_ATOMIC, 3);       /* 16K */
+       if (!lp->ram)
+       {
+               printk("%s: No memory for LANCE buffers\n", dev->name);
+-              return -ENODEV;
++              free_netdev(dev);
++              return ERR_PTR(-ENOMEM);
+       }
+       lp->lance.name = (char*)name;                   /* discards const, shut up gcc */
+@@ -134,15 +134,15 @@ int __init mvme147lance_probe(struct net
+       lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
+       lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
+       lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
+-      ether_setup(dev);
+-#ifdef MODULE
+-      dev->ifindex = dev_new_index();
+-      lp->next_module = root_m147lance_dev;
+-      root_m147lance_dev = lp;
+-#endif /* MODULE */
++      err = register_netdev(dev);
++      if (err) {
++              free_pages(lp->ram, 3);
++              free_netdev(dev);
++              return ERR_PTR(err);
++      }
+-      return 0;
++      return dev;
+ }
+ static void m147lance_writerap(struct m147lance_private *lp, unsigned short value)
+@@ -185,23 +185,21 @@ static int m147lance_close(struct net_de
+ #ifdef MODULE
+ MODULE_LICENSE("GPL");
++static struct net_device *dev_mvme147_lance;
+ int init_module(void)
+ {
+-      root_lance_dev = NULL;
+-      return mvme147lance_probe(NULL);
++      dev_mvme147_lance = mvme147lance_probe(-1);
++      if (IS_ERR(dev_mvme147_lance))
++              return PTR_ERR(dev_mvme147_lance);
++      return 0;
+ }
+ void cleanup_module(void)
+ {
+-      /* Walk the chain of devices, unregistering them */
+-      struct m147lance_private *lp;
+-      while (root_m147lance_dev) {
+-              lp = root_m147lance_dev->next_module;
+-              unregister_netdev(root_lance_dev->dev);
+-              free_pages(lp->ram, 3);
+-              free_netdev(root_lance_dev->dev);
+-              root_lance_dev = lp;
+-      }
++      struct m147lance_private *lp = dev_mvme147_lance->priv;
++      unregister_netdev(dev_mvme147_lance);
++      free_pages(lp->ram, 3);
++      free_netdev(dev_mvme147_lance);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/natsemi.c  2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/natsemi.c   2003-12-28 23:21:01.000000000 -0800
+@@ -765,19 +765,13 @@ static int __devinit natsemi_probe1 (str
+       SET_NETDEV_DEV(dev, &pdev->dev);
+       i = pci_request_regions(pdev, dev->name);
+-      if (i) {
+-              free_netdev(dev);
+-              return i;
+-      }
++      if (i)
++              goto err_pci_request_regions;
+-      {
+-              void *mmio = ioremap (ioaddr, iosize);
+-              if (!mmio) {
+-                      pci_release_regions(pdev);
+-                      free_netdev(dev);
+-                      return -ENOMEM;
+-              }
+-              ioaddr = (unsigned long) mmio;
++      ioaddr = (unsigned long) ioremap (ioaddr, iosize);
++      if (!ioaddr) {
++              i = -ENOMEM;
++              goto err_ioremap;
+       }
+       /* Work around the dropped serial bit. */
+@@ -835,13 +829,9 @@ static int __devinit natsemi_probe1 (str
+               dev->mtu = mtu;
+       i = register_netdev(dev);
+-      if (i) {
+-              pci_release_regions(pdev);
+-              unregister_netdev(dev);
+-              free_netdev(dev);
+-              pci_set_drvdata(pdev, NULL);
+-              return i;
+-      }
++      if (i)
++              goto err_register_netdev;
++
+       netif_carrier_off(dev);
+       if (netif_msg_drv(np)) {
+@@ -878,6 +868,17 @@ static int __devinit natsemi_probe1 (str
+       return 0;
++
++ err_register_netdev:
++      iounmap ((void *) dev->base_addr);
++
++ err_ioremap:
++      pci_release_regions(pdev);
++      pci_set_drvdata(pdev, NULL);
++
++ err_pci_request_regions:
++      free_netdev(dev);
++      return i;
+ }
+--- linux-2.6.0/drivers/net/ne2.c      2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/ne2.c       2003-12-28 23:21:01.000000000 -0800
+@@ -242,7 +242,7 @@ static unsigned int __init dlink_get_eep
+  * Note that at boot, this probe only picks up one card at a time.
+  */
+-int __init ne2_probe(struct net_device *dev)
++static int __init do_ne2_probe(struct net_device *dev)
+ {
+       static int current_mca_slot = -1;
+       int i;
+@@ -262,16 +262,52 @@ int __init ne2_probe(struct net_device *
+                       mca_find_unused_adapter(ne2_adapters[i].id, 0);
+               if((current_mca_slot != MCA_NOTFOUND) && !adapter_found) {
++                      int res;
+                       mca_set_adapter_name(current_mca_slot, 
+                                       ne2_adapters[i].name);
+                       mca_mark_as_used(current_mca_slot);
+                       
+-                      return ne2_probe1(dev, current_mca_slot);
++                      res = ne2_probe1(dev, current_mca_slot);
++                      if (res)
++                              mca_mark_as_unused(current_mca_slot);
++                      return res;
+               }
+       }
+       return -ENODEV;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      mca_mark_as_unused(ei_status.priv);
++      mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, NE_IO_EXTENT);
++}
++
++struct net_device * __init ne2_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_ne2_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
+ static int ne2_procinfo(char *buf, int slot, struct net_device *dev)
+ {
+@@ -443,14 +479,6 @@ static int __init ne2_probe1(struct net_
+       dev->base_addr = base_addr;
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev)) {
+-              printk (" unable to get memory for dev->priv.\n");
+-              free_irq(dev->irq, dev);
+-              retval = -ENOMEM;
+-              goto out;
+-      }
+-
+       for(i = 0; i < ETHER_ADDR_LEN; i++) {
+               printk(" %2.2x", SA_prom[i]);
+               dev->dev_addr[i] = SA_prom[i];
+@@ -735,7 +763,7 @@ retry:
+ #ifdef MODULE
+ #define MAX_NE_CARDS  4       /* Max number of NE cards per module */
+-static struct net_device dev_ne[MAX_NE_CARDS];
++static struct net_device *dev_ne[MAX_NE_CARDS];
+ static int io[MAX_NE_CARDS];
+ static int irq[MAX_NE_CARDS];
+ static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */
+@@ -754,23 +782,30 @@ MODULE_PARM_DESC(bad, "(ignored)");
+ int init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ne[this_dev];
++              dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
+               dev->irq = irq[this_dev];
+               dev->mem_end = bad[this_dev];
+               dev->base_addr = io[this_dev];
+-              dev->init = ne2_probe;
+-              if (register_netdev(dev) != 0) {
+-                      if (found != 0) return 0;   /* Got at least one. */
+-
+-                      printk(KERN_WARNING "ne2.c: No NE/2 card found.\n");
+-                      return -ENXIO;
++              if (do_ne2_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_ne[found++] = dev;
++                              continue;
++                      }
++                      cleanup_card(dev);
+               }
+-              found++;
++              free_netdev(dev);
++              break;
+       }
+-      return 0;
++      if (found)
++              return 0;
++      printk(KERN_WARNING "ne2.c: No NE/2 card found\n");
++      return -ENXIO;
+ }
+ void cleanup_module(void)
+@@ -778,14 +813,11 @@ void cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ne[this_dev];
+-              if (dev->priv != NULL) {
+-                      mca_mark_as_unused(ei_status.priv);
+-                      mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
+-                      kfree(dev->priv);
+-                      free_irq(dev->irq, dev);
+-                      release_region(dev->base_addr, NE_IO_EXTENT);
++              struct net_device *dev = dev_ne[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/ne2k_cbus.c        2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ne2k_cbus.c 2003-12-28 23:21:01.000000000 -0800
+@@ -78,7 +78,6 @@ bad_clone_list[] __initdata = {
+ #include "ne2k_cbus.h"
+-int ne_probe(struct net_device *dev);
+ static int ne_probe1(struct net_device *dev, int ioaddr);
+ static int ne_open(struct net_device *dev);
+ static int ne_close(struct net_device *dev);
+@@ -113,9 +112,10 @@ static void ne_block_output(struct net_d
+       E2010    starts at 0x100 and ends at 0x4000.
+       E2010-x starts at 0x100 and ends at 0xffff.  */
+-int __init ne_probe(struct net_device *dev)
++static int __init do_ne_probe(struct net_device *dev)
+ {
+       unsigned int base_addr = dev->base_addr;
++      int irq = dev->irq;
+       SET_MODULE_OWNER(dev);
+@@ -135,7 +135,7 @@ int __init ne_probe(struct net_device *d
+               if (ei_debug > 2)
+                       printk(KERN_DEBUG "ne_probe(): call ne_probe_cbus(base_addr=0x%x)\n", base_addr);
+-              result = ne_probe_cbus(dev, hw, base_addr);
++              result = ne_probe_cbus(dev, hw, base_addr, irq);
+               if (result != 0)
+                       ne2k_cbus_destroy(dev);
+@@ -156,13 +156,13 @@ int __init ne_probe(struct net_device *d
+               if (hw && hw->hwtype) {
+                       const unsigned short *plist;
+                       for (plist = hw->portlist; *plist; plist++)
+-                              if (ne_probe_cbus(dev, hw, *plist) == 0)
++                              if (ne_probe_cbus(dev, hw, *plist, irq) == 0)
+                                       return 0;
+               } else {
+                       for (hw = &ne2k_cbus_hwinfo_list[0]; hw->hwtype; hw++) {
+                               const unsigned short *plist;
+                               for (plist = hw->portlist; *plist; plist++)
+-                                      if (ne_probe_cbus(dev, hw, *plist) == 0)
++                                      if (ne_probe_cbus(dev, hw, *plist, irq) == 0)
+                                               return 0;
+                       }
+               }
+@@ -174,7 +174,45 @@ int __init ne_probe(struct net_device *d
+       return -ENODEV;
+ }
+-static int __init ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr)
++static void cleanup_card(struct net_device *dev)
++{
++      const struct ne2k_cbus_region *rlist;
++      const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK));
++
++      free_irq(dev->irq, dev);
++      for (rlist = hw->regionlist; rlist->range; rlist++) {
++              release_region(dev->base_addr + rlist->start,
++                              rlist->range);
++      }
++      ne2k_cbus_destroy(dev);
++}
++
++struct net_device * __init ne_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_ne_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
++static int __init ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr, int irq)
+ {
+       if (ei_debug > 2)
+               printk(KERN_DEBUG "ne_probe_cbus(): entered. (called from %p)\n",
+@@ -182,6 +220,7 @@ static int __init ne_probe_cbus(struct n
+       if (hw && hw->hwtype) {
+               ne2k_cbus_set_hwtype(dev, hw, ioaddr);
++              dev->irq = irq;
+               return ne_probe1(dev, ioaddr);
+       } else {
+               /* auto detect */
+@@ -189,6 +228,7 @@ static int __init ne_probe_cbus(struct n
+               printk(KERN_DEBUG "ne_probe_cbus(): try to determine hardware types.\n");
+               for (hw = &ne2k_cbus_hwinfo_list[0]; hw->hwtype; hw++) {
+                       ne2k_cbus_set_hwtype(dev, hw, ioaddr);
++                      dev->irq = irq;
+                       if (ne_probe1(dev, ioaddr) == 0)
+                               return 0;
+               }
+@@ -301,11 +341,12 @@ static int __init ne_probe1(struct net_d
+               if (ei_debug > 2)
+                       printk(" [CNET98EL-specific initialize...");
+               outb_p(E8390_NODMA | E8390_STOP, ioaddr + E8390_CMD); /* 0x20|0x1 */
++              ret = -ENODEV;
+               i = inb(ioaddr);
+               if ((i & ~0x2) != (0x20 | 0x01))
+-                      return -ENODEV;
++                      goto err_out;
+               if ((inb(ioaddr + 0x7) & 0x80) != 0x80)
+-                      return -ENODEV;
++                      goto err_out;
+               outb_p(E8390_RXOFF, ioaddr + EN0_RXCR); /* out(ioaddr+0xc, 0x20) */
+               /* outb_p(ENDCFG_WTS|ENDCFG_FT1|ENDCFG_LS, ioaddr+EN0_DCFG); */
+               outb_p(ENDCFG_WTS | 0x48, ioaddr + EN0_DCFG); /* 0x49 */
+@@ -330,7 +371,7 @@ static int __init ne_probe1(struct net_d
+                       if (ei_debug > 2)
+                               printk("] ");
+                       printk("memory failure at %x\n", i);
+-                      return -ENODEV;
++                      goto err_out;
+               }
+               if (ei_debug > 2)
+                       printk(" good...");
+@@ -338,7 +379,7 @@ static int __init ne_probe1(struct net_d
+                       if (ei_debug > 2)
+                               printk("] ");
+                       printk("IRQ must be specified for C-NET(98)E/L. probe failed.\n");
+-                      return -ENODEV;
++                      goto err_out;
+               }
+               outb((dev->irq > 5) ? (dev->irq & 4):(dev->irq >> 1), ioaddr + (0x2 | 0x400));
+               outb(0x7e, ioaddr + (0x4 | 0x400));
+@@ -457,14 +498,6 @@ static int __init ne_probe1(struct net_d
+               goto err_out;
+       }
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev))
+-      {
+-              printk (" unable to get memory for dev->priv.\n");
+-              ret = -ENOMEM;
+-              goto err_out;
+-      }
+-
+       /* Snarf the interrupt now.  There's no point in waiting since we cannot
+          share and the board will usually be enabled. */
+       ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);
+@@ -779,7 +812,7 @@ retry:
\f
+ #ifdef MODULE
+ #define MAX_NE_CARDS  4       /* Max number of NE cards per module */
+-static struct net_device dev_ne[MAX_NE_CARDS];
++static struct net_device *dev_ne[MAX_NE_CARDS];
+ static int io[MAX_NE_CARDS];
+ static int irq[MAX_NE_CARDS];
+ static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */
+@@ -806,26 +839,32 @@ int init_module(void)
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ne[this_dev];
++              struct net_device *dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
+               dev->irq = irq[this_dev];
+               dev->mem_end = bad[this_dev];
+               dev->base_addr = io[this_dev];
+               dev->mem_start = hwtype[this_dev];
+-              dev->init = ne_probe;
+-              if (register_netdev(dev) == 0) {
+-                      found++;
+-                      continue;
+-              }
+-              if (found != 0) {       /* Got at least one. */
+-                      return 0;
++              if (do_ne_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_ne[found++] = dev;
++                              continue;
++                      }
++                      cleanup_card(dev);
+               }
++              free_netdev(dev);
++              if (found)
++                      break;
+               if (io[this_dev] != 0)
+                       printk(KERN_WARNING "ne2k_cbus: No NE*000 card found at i/o = %#x\n", io[this_dev]);
+               else
+-                      printk(KERN_NOTICE "ne2k_cbus: You must supply \"io=0xNNN\" value(s) for C-Bus cards.\n");
++                      printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n");
+               return -ENXIO;
+       }
+-      return 0;
++      if (found)
++              return 0;
++      return -ENODEV;
+ }
+ void cleanup_module(void)
+@@ -833,18 +872,11 @@ void cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ne[this_dev];
+-              if (dev->priv != NULL) {
+-                      const struct ne2k_cbus_region *rlist;
+-                      const struct ne2k_cbus_hwinfo *hw = ne2k_cbus_get_hwinfo((int)(dev->mem_start & NE2K_CBUS_HARDWARE_TYPE_MASK));
+-
+-                      free_irq(dev->irq, dev);
+-                      for (rlist = hw->regionlist; rlist->range; rlist++) {
+-                              release_region(dev->base_addr + rlist->start,
+-                                              rlist->range);
+-                      }
++              struct net_device *dev = dev_ne[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      ne2k_cbus_destroy(dev);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/ne2k_cbus.h        2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/net/ne2k_cbus.h 2003-12-28 23:21:01.000000000 -0800
+@@ -477,5 +477,5 @@ static void __init ne2k_cbus_writemem(st
+ }
+ #endif
+-static int ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr);
++static int ne_probe_cbus(struct net_device *dev, const struct ne2k_cbus_hwinfo *hw, int ioaddr, int irq);
+ /* End of ne2k_cbus.h */
+--- linux-2.6.0/drivers/net/ne2k-pci.c 2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ne2k-pci.c  2003-12-28 23:21:01.000000000 -0800
+@@ -115,6 +115,7 @@ enum ne2k_pci_chipsets {
+       CH_Winbond_W89C940F,
+       CH_Holtek_HT80232,
+       CH_Holtek_HT80229,
++      CH_Winbond_89C940_8c4a,
+ };
+@@ -132,6 +133,7 @@ static struct {
+       {"Winbond W89C940F", 0},
+       {"Holtek HT80232", ONLY_16BIT_IO | HOLTEK_FDX},
+       {"Holtek HT80229", ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60 },
++      {"Winbond W89C940(misprogrammed)", 0},
+       {0,}
+ };
+@@ -147,6 +149,7 @@ static struct pci_device_id ne2k_pci_tbl
+       { 0x1050, 0x5a5a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_W89C940F },
+       { 0x12c3, 0x0058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80232 },
+       { 0x12c3, 0x5598, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80229 },
++      { 0x8c4a, 0x1980, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940_8c4a },
+       { 0, }
+ };
+ MODULE_DEVICE_TABLE(pci, ne2k_pci_tbl);
+--- linux-2.6.0/drivers/net/ne3210.c   2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/ne3210.c    2003-12-28 23:21:01.000000000 -0800
+@@ -111,12 +111,6 @@ static int __init ne3210_eisa_probe (str
+       device->driver_data = dev;
+       ioaddr = edev->base_addr;
+-      if (ethdev_init (dev)) {
+-              printk ("ne3210.c: unable to allocate memory for dev->priv!\n");
+-              retval = -ENOMEM;
+-              goto out;
+-      }
+-
+       if (!request_region(ioaddr, NE3210_IO_EXTENT, dev->name)) {
+               retval = -EBUSY;
+               goto out;
+@@ -357,24 +351,6 @@ static struct eisa_driver ne3210_eisa_dr
+       },
+ };
+-#ifdef MODULE
+-#if 0
+-#define MAX_NE3210_CARDS      4       /* Max number of NE3210 cards per module */
+-static struct net_device dev_ne3210[MAX_NE3210_CARDS];
+-static int io[MAX_NE3210_CARDS];
+-static int irq[MAX_NE3210_CARDS];
+-static int mem[MAX_NE3210_CARDS];
+-
+-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
+-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
+-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
+-MODULE_PARM_DESC(io, "I/O base address(es)");
+-MODULE_PARM_DESC(irq, "IRQ number(s)");
+-MODULE_PARM_DESC(mem, "memory base address(es)");
+-#endif
+-#endif /* MODULE */
+-
+-
+ MODULE_DESCRIPTION("NE3210 EISA Ethernet driver");
+ MODULE_LICENSE("GPL");
+--- linux-2.6.0/drivers/net/ne.c       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ne.c        2003-12-28 23:21:01.000000000 -0800
+@@ -126,7 +126,6 @@ bad_clone_list[] __initdata = {
+ #define NESM_START_PG 0x40    /* First page of TX buffer */
+ #define NESM_STOP_PG  0x80    /* Last page +1 of RX ring */
+-int ne_probe(struct net_device *dev);
+ static int ne_probe1(struct net_device *dev, int ioaddr);
+ static int ne_probe_isapnp(struct net_device *dev);
+@@ -163,9 +162,10 @@ static void ne_block_output(struct net_d
+       E2010    starts at 0x100 and ends at 0x4000.
+       E2010-x starts at 0x100 and ends at 0xffff.  */
+-int __init ne_probe(struct net_device *dev)
++static int __init do_ne_probe(struct net_device *dev)
+ {
+       unsigned int base_addr = dev->base_addr;
++      int irq = dev->irq;
+       SET_MODULE_OWNER(dev);
+@@ -183,6 +183,7 @@ int __init ne_probe(struct net_device *d
+       /* Last resort. The semi-risky ISA auto-probe. */
+       for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) {
+               int ioaddr = netcard_portlist[base_addr];
++              dev->irq = irq;
+               if (ne_probe1(dev, ioaddr) == 0)
+                       return 0;
+       }
+@@ -191,6 +192,40 @@ int __init ne_probe(struct net_device *d
+       return -ENODEV;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
++      if (idev)
++              pnp_device_detach(idev);
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, NE_IO_EXTENT);
++}
++
++struct net_device * __init ne_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_ne_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ static int __init ne_probe_isapnp(struct net_device *dev)
+ {
+       int i;
+@@ -425,20 +460,12 @@ static int __init ne_probe1(struct net_d
+               goto err_out;
+       }
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev))
+-      {
+-              printk (" unable to get memory for dev->priv.\n");
+-              ret = -ENOMEM;
+-              goto err_out;
+-      }
+-
+       /* Snarf the interrupt now.  There's no point in waiting since we cannot
+          share and the board will usually be enabled. */
+       ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);
+       if (ret) {
+               printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret);
+-              goto err_out_kfree;
++              goto err_out;
+       }
+       dev->base_addr = ioaddr;
+@@ -472,9 +499,6 @@ static int __init ne_probe1(struct net_d
+       NS8390_init(dev, 0);
+       return 0;
+-err_out_kfree:
+-      kfree(dev->priv);
+-      dev->priv = NULL;
+ err_out:
+       release_region(ioaddr, NE_IO_EXTENT);
+       return ret;
+@@ -734,7 +758,7 @@ retry:
\f
+ #ifdef MODULE
+ #define MAX_NE_CARDS  4       /* Max number of NE cards per module */
+-static struct net_device dev_ne[MAX_NE_CARDS];
++static struct net_device *dev_ne[MAX_NE_CARDS];
+ static int io[MAX_NE_CARDS];
+ static int irq[MAX_NE_CARDS];
+ static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */
+@@ -758,25 +782,31 @@ int init_module(void)
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ne[this_dev];
++              struct net_device *dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
+               dev->irq = irq[this_dev];
+               dev->mem_end = bad[this_dev];
+               dev->base_addr = io[this_dev];
+-              dev->init = ne_probe;
+-              if (register_netdev(dev) == 0) {
+-                      found++;
+-                      continue;
+-              }
+-              if (found != 0) {       /* Got at least one. */
+-                      return 0;
++              if (do_ne_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_ne[found++] = dev;
++                              continue;
++                      }
++                      cleanup_card(dev);
+               }
++              free_netdev(dev);
++              if (found)
++                      break;
+               if (io[this_dev] != 0)
+                       printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]);
+               else
+                       printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n");
+               return -ENXIO;
+       }
+-      return 0;
++      if (found)
++              return 0;
++      return -ENODEV;
+ }
+ void cleanup_module(void)
+@@ -784,16 +814,11 @@ void cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ne[this_dev];
+-              if (dev->priv != NULL) {
+-                      void *priv = dev->priv;
+-                      struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+-                      if (idev)
+-                              pnp_device_detach(idev);
+-                      free_irq(dev->irq, dev);
+-                      release_region(dev->base_addr, NE_IO_EXTENT);
++              struct net_device *dev = dev_ne[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(priv);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/net/netconsole.c        2003-12-28 23:21:01.000000000 -0800
+@@ -0,0 +1,120 @@
++/*
++ *  linux/drivers/net/netconsole.c
++ *
++ *  Copyright (C) 2001  Ingo Molnar <mingo@redhat.com>
++ *
++ *  This file contains the implementation of an IRQ-safe, crash-safe
++ *  kernel console implementation that outputs kernel messages to the
++ *  network.
++ *
++ * Modification history:
++ *
++ * 2001-09-17    started by Ingo Molnar.
++ * 2003-08-11    2.6 port by Matt Mackall
++ *               simplified options
++ *               generic card hooks
++ *               works non-modular
++ * 2003-09-07    rewritten with netpoll api
++ */
++
++/****************************************************************
++ *      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; if not, write to the Free Software
++ *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ ****************************************************************/
++
++#include <linux/mm.h>
++#include <linux/tty.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/console.h>
++#include <linux/tty_driver.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/string.h>
++#include <linux/sysrq.h>
++#include <linux/smp.h>
++#include <linux/netpoll.h>
++
++MODULE_AUTHOR("Maintainer: Matt Mackall <mpm@selenic.com>");
++MODULE_DESCRIPTION("Console driver for network interfaces");
++MODULE_LICENSE("GPL");
++
++static char config[256];
++module_param_string(netconsole, config, 256, 0);
++MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n");
++
++static struct netpoll np = {
++      .name = "netconsole",
++      .dev_name = "eth0",
++      .local_port = 6665,
++      .remote_port = 6666,
++      .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
++};
++
++#define MAX_PRINT_CHUNK 1000
++
++static void write_msg(struct console *con, const char *msg, unsigned int len)
++{
++      int frag, left;
++      unsigned long flags;
++
++      if (!np.dev)
++              return;
++
++      local_irq_save(flags);
++
++      for(left = len; left; ) {
++              frag = min(left, MAX_PRINT_CHUNK);
++              netpoll_send_udp(&np, msg, frag);
++              msg += frag;
++              left -= frag;
++      }
++
++      local_irq_restore(flags);
++}
++
++static struct console netconsole = {
++      .flags = CON_ENABLED | CON_PRINTBUFFER,
++      .write = write_msg
++};
++
++static int option_setup(char *opt)
++{
++      return netpoll_parse_options(&np, opt);
++}
++
++__setup("netconsole=", option_setup);
++
++static int init_netconsole(void)
++{
++      if(strlen(config) && option_setup(config))
++              return 1;
++
++      if(!np.remote_ip || netpoll_setup(&np))
++              return 1;
++
++      register_console(&netconsole);
++      printk(KERN_INFO "netconsole: network logging started\n");
++      return 0;
++}
++
++static void cleanup_netconsole(void)
++{
++      unregister_console(&netconsole);
++      netpoll_cleanup(&np);
++}
++
++module_init(init_netconsole);
++module_exit(cleanup_netconsole);
+--- linux-2.6.0/drivers/net/net_init.c 2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/net_init.c  2003-12-28 23:21:01.000000000 -0800
+@@ -73,23 +73,28 @@
+ struct net_device *alloc_netdev(int sizeof_priv, const char *mask,
+                                      void (*setup)(struct net_device *))
+ {
++      void *p;
+       struct net_device *dev;
+       int alloc_size;
+-      /* ensure 32-byte alignment of the private area */
+-      alloc_size = sizeof (*dev) + sizeof_priv + 31;
++      /* ensure 32-byte alignment of both the device and private area */
+-      dev = (struct net_device *) kmalloc (alloc_size, GFP_KERNEL);
+-      if (dev == NULL)
+-      {
+-              printk(KERN_ERR "alloc_dev: Unable to allocate device memory.\n");
++      alloc_size = (sizeof(struct net_device) + 31) & ~31;
++      alloc_size += sizeof_priv + 31;
++
++      p = kmalloc (alloc_size, GFP_KERNEL);
++      if (!p) {
++              printk(KERN_ERR "alloc_dev: Unable to allocate device.\n");
+               return NULL;
+       }
+-      memset(dev, 0, alloc_size);
++      memset(p, 0, alloc_size);
++
++      dev = (struct net_device *)(((long)p + 31) & ~31);
++      dev->padded = (char *)dev - (char *)p;
+       if (sizeof_priv)
+-              dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
++              dev->priv = netdev_priv(dev);
+       setup(dev);
+       strcpy(dev->name, mask);
+--- linux-2.6.0/drivers/net/ni5010.c   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ni5010.c    2003-12-28 23:21:01.000000000 -0800
+@@ -82,7 +82,7 @@ static unsigned int bufsize_rcv;
+ #ifndef FULL_IODETECT
+ /* A zero-terminated list of I/O addresses to be probed. */
+-static unsigned int ni5010_portlist[] __initdata =
++static unsigned int ports[] __initdata =
+       { 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0 };
+ #endif
+@@ -95,13 +95,11 @@ static unsigned int ni5010_portlist[] __
+ struct ni5010_local {
+       struct net_device_stats stats;
+       int o_pkt_size;
+-      int i_pkt_size;
+       spinlock_t lock;
+ };
+ /* Index to functions, as function prototypes. */
+-extern int    ni5010_probe(struct net_device *dev);
+ static int    ni5010_probe1(struct net_device *dev, int ioaddr);
+ static int    ni5010_open(struct net_device *dev);
+ static int    ni5010_send_packet(struct sk_buff *skb, struct net_device *dev);
+@@ -120,38 +118,58 @@ static void      chipset_init(struct net_dev
+ static void   dump_packet(void *buf, int len);
+ static void   ni5010_show_registers(struct net_device *dev);
++static int io;
++static int irq;
+-int __init ni5010_probe(struct net_device *dev)
++struct net_device * __init ni5010_probe(int unit)
+ {
++      struct net_device *dev = alloc_etherdev(sizeof(struct ni5010_local));
+       int *port;
+-      int base_addr = dev->base_addr;
++      int err = 0;
+-        PRINTK2((KERN_DEBUG "%s: Entering ni5010_probe\n", dev->name));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+-      SET_MODULE_OWNER(dev);
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++              io = dev->base_addr;
++              irq = dev->irq;
++      }
+-      if (base_addr > 0x1ff)          /* Check a single specified location. */
+-              return ni5010_probe1(dev, base_addr);
+-      else if (base_addr != 0)        /* Don't probe at all. */
+-              return -ENXIO;
++      PRINTK2((KERN_DEBUG "%s: Entering ni5010_probe\n", dev->name));
++      SET_MODULE_OWNER(dev);
++
++      if (io > 0x1ff) {       /* Check a single specified location. */
++              err = ni5010_probe1(dev, io);
++      } else if (io != 0) {   /* Don't probe at all. */
++              err = -ENXIO;
++      } else {
+ #ifdef FULL_IODETECT
+-              for (int ioaddr=0x200; ioaddr<0x400; ioaddr+=0x20) {
+-                      if (check_region(ioaddr, NI5010_IO_EXTENT))
+-                              continue;
+-                      if (ni5010_probe1(dev, ioaddr) == 0)
+-                              return 0;
+-              }
++              for (io=0x200; io<0x400 && ni5010_probe1(dev, io) ; io+=0x20)
++                      ;
++              if (io == 0x400)
++                      err = -ENODEV;
++
+ #else
+-              for (port = ni5010_portlist; *port; port++) {
+-                      int ioaddr = *port;
+-                      if (check_region(ioaddr, NI5010_IO_EXTENT))
+-                              continue;
+-                      if (ni5010_probe1(dev, ioaddr) == 0)
+-                              return 0;
+-              }
++              for (port = ports; *port && ni5010_probe1(dev, *port); port++)
++                      ;
++              if (!*port)
++                      err = -ENODEV;
+ #endif        /* FULL_IODETECT */
+-      return -ENODEV;
++      }
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      release_region(dev->base_addr, NI5010_IO_EXTENT);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ static inline int rd_port(int ioaddr)
+@@ -188,9 +206,17 @@ static void __init trigger_irq(int ioadd
+ static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
+ {
+       static unsigned version_printed;
++      struct ni5010_local *lp;
+       int i;
+       unsigned int data = 0;
+       int boguscount = 40;
++      int err = -ENODEV;
++
++      dev->base_addr = ioaddr;
++      dev->irq = irq;
++
++      if (!request_region(ioaddr, NI5010_IO_EXTENT, boardname))
++              return -EBUSY;
+       /*
+        * This is no "official" probe method, I've rather tested which
+@@ -205,36 +231,40 @@ static int __init ni5010_probe1(struct n
+        *
+        *   - Andreas
+        */
+-      
++
+       PRINTK2((KERN_DEBUG "%s: entering ni5010_probe1(%#3x)\n", 
+               dev->name, ioaddr));
+-      if (inb(ioaddr+0) == 0xff) return -ENODEV;
++      if (inb(ioaddr+0) == 0xff)
++              goto out;
+       while ( (rd_port(ioaddr) & rd_port(ioaddr) & rd_port(ioaddr) &
+                rd_port(ioaddr) & rd_port(ioaddr) & rd_port(ioaddr)) != 0xff)
+       {
+-              if (boguscount-- == 0) return -ENODEV;
++              if (boguscount-- == 0)
++                      goto out;
+       }
+       PRINTK2((KERN_DEBUG "%s: I/O #1 passed!\n", dev->name));
+       for (i=0; i<32; i++)
+               if ( (data = rd_port(ioaddr)) != 0xff) break;
+-      if (data==0xff) return -ENODEV;
++      if (data==0xff)
++              goto out;
+       PRINTK2((KERN_DEBUG "%s: I/O #2 passed!\n", dev->name));
+-      if (            (data == SA_ADDR0) &&
+-           (rd_port(ioaddr) == SA_ADDR1) &&
+-           (rd_port(ioaddr) == SA_ADDR2) ) {
+-              for (i=0; i<4; i++) rd_port(ioaddr);
+-              if ( (rd_port(ioaddr) != NI5010_MAGICVAL1) ||
+-                   (rd_port(ioaddr) != NI5010_MAGICVAL2) ) {
+-                      return -ENODEV;
+-              }
+-      } else return -ENODEV;
+-      
++      if ((data != SA_ADDR0) || (rd_port(ioaddr) != SA_ADDR1) ||
++          (rd_port(ioaddr) != SA_ADDR2))
++              goto out;
++
++      for (i=0; i<4; i++)
++              rd_port(ioaddr);
++
++      if ( (rd_port(ioaddr) != NI5010_MAGICVAL1) ||
++           (rd_port(ioaddr) != NI5010_MAGICVAL2) )
++              goto out;
++
+       PRINTK2((KERN_DEBUG "%s: I/O #3 passed!\n", dev->name));
+       if (NI5010_DEBUG && version_printed++ == 0)
+@@ -267,8 +297,9 @@ static int __init ni5010_probe1(struct n
+               PRINTK2((KERN_DEBUG "%s: I/O #6 passed!\n", dev->name));
+               if (dev->irq == 0) {
++                      err = -EAGAIN;
+                       printk(KERN_WARNING "%s: no IRQ found!\n", dev->name);
+-                      return -EAGAIN;
++                      goto out;
+               }
+               PRINTK2((KERN_DEBUG "%s: I/O #7 passed!\n", dev->name));
+       } else if (dev->irq == 2) {
+@@ -278,19 +309,9 @@ static int __init ni5010_probe1(struct n
+       PRINTK2((KERN_DEBUG "%s: I/O #9 passed!\n", dev->name));
+       /* DMA is not supported (yet?), so no use detecting it */
++      lp = (struct ni5010_local*)dev->priv;
+-      if (dev->priv == NULL) {
+-              struct ni5010_local* lp;
+-
+-              dev->priv = kmalloc(sizeof(struct ni5010_local), GFP_KERNEL|GFP_DMA);
+-              if (dev->priv == NULL) {
+-                      printk(KERN_WARNING "%s: Failed to allocate private memory\n", dev->name);
+-                      return -ENOMEM;
+-              }
+-
+-              lp = (struct ni5010_local*)dev->priv;
+-              spin_lock_init(&lp->lock);
+-      }
++      spin_lock_init(&lp->lock);
+       PRINTK2((KERN_DEBUG "%s: I/O #10 passed!\n", dev->name));
+@@ -315,9 +336,6 @@ static int __init ni5010_probe1(struct n
+       }
+         printk("// bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
+       memset(dev->priv, 0, sizeof(struct ni5010_local));
+-
+-      /* Grab the region so we can find another board if autoIRQ fails. */
+-      request_region(ioaddr, NI5010_IO_EXTENT, boardname);
+       
+       dev->open               = ni5010_open;
+       dev->stop               = ni5010_close;
+@@ -327,9 +345,6 @@ static int __init ni5010_probe1(struct n
+       dev->tx_timeout         = ni5010_timeout;
+       dev->watchdog_timeo     = HZ/20;
+-      /* Fill in the fields of the device structure with ethernet values. */
+-      ether_setup(dev);
+-      
+       dev->flags &= ~IFF_MULTICAST;   /* Multicast doesn't work */
+       /* Shut up the ni5010 */
+@@ -345,6 +360,9 @@ static int __init ni5010_probe1(struct n
+       printk(KERN_INFO "Join the NI5010 driver development team!\n");
+       printk(KERN_INFO "Mail to a.mohr@mailto.de or jvbest@wi.leidenuniv.nl\n");
+       return 0;
++out:
++      release_region(dev->base_addr, NI5010_IO_EXTENT);
++      return err;
+ }
+ /* 
+@@ -513,6 +531,7 @@ static void ni5010_rx(struct net_device 
+       int ioaddr = dev->base_addr;
+       unsigned char rcv_stat;
+       struct sk_buff *skb;
++      int i_pkt_size;
+       
+       PRINTK2((KERN_DEBUG "%s: entering ni5010_rx()\n", dev->name)); 
+       
+@@ -532,17 +551,17 @@ static void ni5010_rx(struct net_device 
+       
+         outb(0xff, EDLC_RCLR);  /* Clear the interrupt */
+-      lp->i_pkt_size = inw(IE_RCNT);
+-      if (lp->i_pkt_size > ETH_FRAME_LEN || lp->i_pkt_size < 10 ) {
++      i_pkt_size = inw(IE_RCNT);
++      if (i_pkt_size > ETH_FRAME_LEN || i_pkt_size < 10 ) {
+               PRINTK((KERN_DEBUG "%s: Packet size error, packet size = %#4.4x\n", 
+-                      dev->name, lp->i_pkt_size));
++                      dev->name, i_pkt_size));
+               lp->stats.rx_errors++;
+               lp->stats.rx_length_errors++;
+               return;
+       }
+       /* Malloc up new buffer. */
+-      skb = dev_alloc_skb(lp->i_pkt_size + 3);
++      skb = dev_alloc_skb(i_pkt_size + 3);
+       if (skb == NULL) {
+               printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
+               lp->stats.rx_dropped++;
+@@ -555,7 +574,7 @@ static void ni5010_rx(struct net_device 
+       /* Read packet into buffer */
+         outb(MM_MUX, IE_MMODE); /* Rcv buffer to system bus */
+       outw(0, IE_GP); /* Seek to beginning of packet */
+-      insb(IE_RBUF, skb_put(skb, lp->i_pkt_size), lp->i_pkt_size); 
++      insb(IE_RBUF, skb_put(skb, i_pkt_size), i_pkt_size); 
+       
+       if (NI5010_DEBUG >= 4) 
+               dump_packet(skb->data, skb->len); 
+@@ -564,10 +583,10 @@ static void ni5010_rx(struct net_device 
+       netif_rx(skb);
+       dev->last_rx = jiffies;
+       lp->stats.rx_packets++;
+-      lp->stats.rx_bytes += lp->i_pkt_size;
++      lp->stats.rx_bytes += i_pkt_size;
+       PRINTK2((KERN_DEBUG "%s: Received packet, size=%#4.4x\n", 
+-              dev->name, lp->i_pkt_size));
++              dev->name, i_pkt_size));
+       
+ }
+@@ -697,10 +716,10 @@ static void hardware_send_packet(struct 
+       
+       if (NI5010_DEBUG > 3) dump_packet(buf, length);
+-        buf_offs = NI5010_BUFSIZE - length - pad;
+-        lp->o_pkt_size = length + pad;
++      buf_offs = NI5010_BUFSIZE - length - pad;
+       spin_lock_irqsave(&lp->lock, flags);
++      lp->o_pkt_size = length + pad;
+       outb(0, EDLC_RMASK);    /* Mask all receive interrupts */
+       outb(0, IE_MMODE);      /* Put Xmit buffer on system bus */
+@@ -745,9 +764,7 @@ static void ni5010_show_registers(struct
+ }
+ #ifdef MODULE
+-static struct net_device dev_ni5010;
+-static int io;
+-static int irq;
++static struct net_device *dev_ni5010;
+ MODULE_PARM(io, "i");
+ MODULE_PARM(irq, "i");
+@@ -756,8 +773,6 @@ MODULE_PARM_DESC(irq, "ni5010 IRQ number
+ int init_module(void)
+ {
+-      int result;
+-      
+       PRINTK2((KERN_DEBUG "%s: entering init_module\n", boardname));
+       /*
+       if(io <= 0 || irq == 0){
+@@ -771,29 +786,18 @@ int init_module(void)
+       }
+       PRINTK2((KERN_DEBUG "%s: init_module irq=%#2x, io=%#3x\n", boardname, irq, io));
+-        dev_ni5010.irq=irq;
+-        dev_ni5010.base_addr=io;
+-      dev_ni5010.init=ni5010_probe;
+-        if ((result = register_netdev(&dev_ni5010)) != 0) {
+-              PRINTK((KERN_WARNING "%s: register_netdev returned %d.\n", 
+-                      boardname, result));
+-                return -EIO;
+-        }
++      dev_ni5010 = ni5010_probe(-1);
++      if (IS_ERR(dev_ni5010))
++              return PTR_ERR(dev_ni5010);
+         return 0;
+ }
+-void
+-cleanup_module(void)
++void cleanup_module(void)
+ {
+       PRINTK2((KERN_DEBUG "%s: entering cleanup_module\n", boardname));
+-
+-        unregister_netdev(&dev_ni5010);
+-
+-      release_region(dev_ni5010.base_addr, NI5010_IO_EXTENT);
+-      if (dev_ni5010.priv != NULL){
+-              kfree(dev_ni5010.priv);
+-              dev_ni5010.priv = NULL;
+-      }
++      unregister_netdev(dev_ni5010);
++      release_region(dev_ni5010->base_addr, NI5010_IO_EXTENT);
++      free_netdev(dev_ni5010);
+ }
+ #endif /* MODULE */
+ MODULE_LICENSE("GPL");
+--- linux-2.6.0/drivers/net/ni52.c     2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ni52.c      2003-12-28 23:21:01.000000000 -0800
+@@ -354,50 +354,76 @@ static void alloc586(struct net_device *
+       memset((char *)p->scb,0,sizeof(struct scb_struct));
+ }
++/* set: io,irq,memstart,memend or set it when calling insmod */
++static int irq=9;
++static int io=0x300;
++static long memstart; /* e.g 0xd0000 */
++static long memend;   /* e.g 0xd4000 */
++
+ /**********************************************
+  * probe the ni5210-card
+  */
+-int __init ni52_probe(struct net_device *dev)
++struct net_device * __init ni52_probe(int unit)
+ {
+-#ifndef MODULE
+-      int *port;
++      struct net_device *dev = alloc_etherdev(sizeof(struct priv));
+       static int ports[] = {0x300, 0x280, 0x360 , 0x320 , 0x340, 0};
+-#endif
+-      int base_addr = dev->base_addr;
+-
+-      SET_MODULE_OWNER(dev);
++      int *port;
++      int err = 0;
+-      if (base_addr > 0x1ff)          /* Check a single specified location. */
+-              return ni52_probe1(dev, base_addr);
+-      else if (base_addr > 0)         /* Don't probe at all. */
+-              return -ENXIO;
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+-#ifdef MODULE
+-      printk("%s: no autoprobing allowed for modules.\n",dev->name);
+-#else
+-      for (port = ports; *port; port++) {
+-              int ioaddr = *port;
+-              dev->base_addr = ioaddr;
+-              if (ni52_probe1(dev, ioaddr) == 0)
+-                      return 0;
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++              io = dev->base_addr;
++              irq = dev->irq;
++              memstart = dev->mem_start;
++              memend = dev->mem_end;
+       }
+-#ifdef FULL_IO_PROBE
+-      for(dev->base_addr=0x200; dev->base_addr<0x400; dev->base_addr+=8)
+-              if (ni52_probe1(dev, dev->base_addr) == 0)
+-                      return 0;
+-#endif
++      SET_MODULE_OWNER(dev);
++      if (io > 0x1ff) {       /* Check a single specified location. */
++              err = ni52_probe1(dev, io);
++      } else if (io > 0) {            /* Don't probe at all. */
++              err = -ENXIO;
++      } else {
++              for (port = ports; *port && ni52_probe1(dev, *port) ; port++)
++                      ;
++              if (*port)
++                      goto got_it;
++#ifdef FULL_IO_PROBE
++              for (io = 0x200; io < 0x400 && ni52_probe1(dev, io); io += 8)
++                      ;
++              if (io < 0x400)
++                      goto got_it;
+ #endif
+-
+-      dev->base_addr = base_addr;
+-      return -ENODEV;
++              err = -ENODEV;
++      }
++      if (err)
++              goto out;
++got_it:
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      release_region(dev->base_addr, NI52_TOTAL_SIZE);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ static int __init ni52_probe1(struct net_device *dev,int ioaddr)
+ {
+       int i, size, retval;
++      dev->base_addr = ioaddr;
++      dev->irq = irq;
++      dev->mem_start = memstart;
++      dev->mem_end = memend;
++
+       if (!request_region(ioaddr, NI52_TOTAL_SIZE, dev->name))
+               return -EBUSY;
+@@ -416,7 +442,7 @@ static int __init ni52_probe1(struct net
+               goto out;
+       }
+-      printk("%s: NI5210 found at %#3lx, ",dev->name,dev->base_addr);
++      printk(KERN_INFO "%s: NI5210 found at %#3lx, ",dev->name,dev->base_addr);
+       /*
+        * check (or search) IO-Memory, 8K and 16K
+@@ -469,13 +495,6 @@ static int __init ni52_probe1(struct net
+       dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
+ #endif
+-      dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
+-      if(dev->priv == NULL) {
+-              printk("%s: Ooops .. can't allocate private driver memory.\n",dev->name);
+-              retval = -ENOMEM;
+-              goto out;
+-      }
+-                                                                                                                                      /* warning: we don't free it on errors */
+       memset((char *) dev->priv,0,sizeof(struct priv));
+       ((struct priv *) (dev->priv))->memtop = isa_bus_to_virt(dev->mem_start) + size;
+@@ -503,8 +522,6 @@ static int __init ni52_probe1(struct net
+               if(!dev->irq)
+               {
+                       printk("?autoirq, Failed to detect IRQ line!\n");
+-                      kfree(dev->priv);
+-                      dev->priv = NULL;
+                       retval = -EAGAIN;
+                       goto out;
+               }
+@@ -526,8 +543,6 @@ static int __init ni52_probe1(struct net
+       dev->if_port            = 0;
+-      ether_setup(dev);
+-
+       return 0;
+ out:
+       release_region(ioaddr, NI52_TOTAL_SIZE);
+@@ -1295,13 +1310,7 @@ static void set_multicast_list(struct ne
+ }
+ #ifdef MODULE
+-static struct net_device dev_ni52;
+-
+-/* set: io,irq,memstart,memend or set it when calling insmod */
+-static int irq=9;
+-static int io=0x300;
+-static long memstart; /* e.g 0xd0000 */
+-static long memend;   /* e.g 0xd4000 */
++static struct net_device *dev_ni52;
+ MODULE_PARM(io, "i");
+ MODULE_PARM(irq, "i");
+@@ -1318,22 +1327,17 @@ int init_module(void)
+               printk("ni52: Autoprobing not allowed for modules.\nni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n");
+               return -ENODEV;
+       }
+-      dev_ni52.init = ni52_probe;
+-      dev_ni52.irq = irq;
+-      dev_ni52.base_addr = io;
+-      dev_ni52.mem_end = memend;
+-      dev_ni52.mem_start = memstart;
+-      if (register_netdev(&dev_ni52) != 0)
+-              return -EIO;
++      dev_ni52 = ni52_probe(-1);
++      if (IS_ERR(dev_ni52))
++              return PTR_ERR(dev_ni52);
+       return 0;
+ }
+ void cleanup_module(void)
+ {
+-      release_region(dev_ni52.base_addr, NI52_TOTAL_SIZE);
+-      unregister_netdev(&dev_ni52);
+-      kfree(dev_ni52.priv);
+-      dev_ni52.priv = NULL;
++      unregister_netdev(dev_ni52);
++      release_region(dev_ni52->base_addr, NI52_TOTAL_SIZE);
++      free_netdev(dev_ni52);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/ni65.c     2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ni65.c      2003-12-28 23:21:01.000000000 -0800
+@@ -343,29 +343,64 @@ static int ni65_close(struct net_device 
+       return 0;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      struct priv *p = (struct priv *) dev->priv;
++      disable_dma(dev->dma);
++      free_dma(dev->dma);
++      release_region(dev->base_addr, cards[p->cardno].total_size);
++      ni65_free_buffer(p);
++}
++
++/* set: io,irq,dma or set it when calling insmod */
++static int irq;
++static int io;
++static int dma;
++
+ /*
+  * Probe The Card (not the lance-chip)
+  */
+-#ifdef MODULE
+-static
+-#endif
+-int __init ni65_probe(struct net_device *dev)
++struct net_device * __init ni65_probe(int unit)
+ {
+-      int *port;
++      struct net_device *dev = alloc_etherdev(0);
+       static int ports[] = {0x360,0x300,0x320,0x340, 0};
++      int *port;
++      int err = 0;
+-      if (dev->base_addr > 0x1ff)          /* Check a single specified location. */
+-               return ni65_probe1(dev, dev->base_addr);
+-      else if (dev->base_addr > 0)         /* Don't probe at all. */
+-               return -ENXIO;
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+-      for (port = ports; *port; port++)
+-      {
+-              if (ni65_probe1(dev, *port) == 0)
+-                       return 0;
+-      }
+-
+-      return -ENODEV;
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++              irq = dev->irq;
++              dma = dev->dma;
++      } else {
++              dev->base_addr = io;
++      }
++
++      if (dev->base_addr > 0x1ff) { /* Check a single specified location. */
++              err = ni65_probe1(dev, dev->base_addr);
++      } else if (dev->base_addr > 0) { /* Don't probe at all. */
++              err = -ENXIO;
++      } else {
++              for (port = ports; *port && ni65_probe1(dev, *port); port++)
++                      ;
++              if (!*port)
++                      err = -ENODEV;
++      }
++      if (err)
++              goto out;
++
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /*
+@@ -377,6 +412,9 @@ static int __init ni65_probe1(struct net
+       struct priv *p;
+       unsigned long flags;
++      dev->irq = irq;
++      dev->dma = dma;
++
+       for(i=0;i<NUM_CARDS;i++) {
+               if(!request_region(ioaddr, cards[i].total_size, cards[i].cardname))
+                       continue;
+@@ -521,9 +559,6 @@ static int __init ni65_probe1(struct net
+       dev->watchdog_timeo     = HZ/2;
+       dev->get_stats          = ni65_get_stats;
+       dev->set_multicast_list = set_multicast_list;
+-
+-      ether_setup(dev);
+-
+       return 0; /* everything is OK */
+ }
+@@ -1213,12 +1248,7 @@ static void set_multicast_list(struct ne
+ }
+ #ifdef MODULE
+-static struct net_device dev_ni65 = { .base_addr = 0x360, .irq = 9, .init = ni65_probe };
+-
+-/* set: io,irq,dma or set it when calling insmod */
+-static int irq;
+-static int io;
+-static int dma;
++static struct net_device *dev_ni65;
+ MODULE_PARM(irq, "i");
+ MODULE_PARM(io, "i");
+@@ -1229,26 +1259,15 @@ MODULE_PARM_DESC(dma, "ni6510 ISA DMA ch
+ int init_module(void)
+ {
+-      dev_ni65.irq = irq;
+-      dev_ni65.dma = dma;
+-      dev_ni65.base_addr = io;
+-      if (register_netdev(&dev_ni65) != 0)
+-              return -EIO;
+-      return 0;
++      dev_ni65 = ni65_probe(-1);
++      return IS_ERR(dev_ni65) ? PTR_ERR(dev_ni65) : 0;
+ }
+ void cleanup_module(void)
+ {
+-      struct priv *p;
+-      p = (struct priv *) dev_ni65.priv;
+-      if(!p)
+-              BUG();
+-      disable_dma(dev_ni65.dma);
+-      free_dma(dev_ni65.dma);
+-      unregister_netdev(&dev_ni65);
+-      release_region(dev_ni65.base_addr,cards[p->cardno].total_size);
+-      ni65_free_buffer(p);
+-      dev_ni65.priv = NULL;
++      unregister_netdev(dev_ni65);
++      cleanup_card(dev_ni65);
++      free_netdev(dev_ni65);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/ns83820.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ns83820.c   2003-12-28 23:21:01.000000000 -0800
+@@ -374,19 +374,6 @@ static int lnksts = 0;            /* CFG_LNKSTS bi
+ #define LINK_DOWN             0x02
+ #define LINK_UP                       0x04
+-#define __kick_rx(dev)        writel(CR_RXE, dev->base + CR)
+-
+-#define kick_rx(dev) do { \
+-      dprintk("kick_rx: maybe kicking\n"); \
+-      if (test_and_clear_bit(0, &dev->rx_info.idle)) { \
+-              dprintk("actually kicking\n"); \
+-              writel(dev->rx_info.phy_descs + (4 * DESC_SIZE * dev->rx_info.next_rx), dev->base + RXDP); \
+-              if (dev->rx_info.next_rx == dev->rx_info.next_empty) \
+-                      printk(KERN_DEBUG "%s: uh-oh: next_rx == next_empty???\n", dev->net_dev.name);\
+-              __kick_rx(dev); \
+-      } \
+-} while(0)
+-
+ #ifdef USE_64BIT_ADDR
+ #define HW_ADDR_LEN   8
+ #define desc_addr_set(desc, addr)                             \
+@@ -438,7 +425,6 @@ struct rx_info {
+ struct ns83820 {
+-      struct net_device       net_dev;        /* must be first */
+       struct net_device_stats stats;
+       u8                      *base;
+@@ -478,6 +464,29 @@ struct ns83820 {
+       struct timer_list       tx_watchdog;
+ };
++static inline struct ns83820 *PRIV(struct net_device *dev)
++{
++      return netdev_priv(dev);
++}
++
++#define __kick_rx(dev)        writel(CR_RXE, dev->base + CR)
++
++static inline void kick_rx(struct net_device *ndev)
++{
++      struct ns83820 *dev = PRIV(ndev);
++      dprintk("kick_rx: maybe kicking\n");
++      if (test_and_clear_bit(0, &dev->rx_info.idle)) {
++              dprintk("actually kicking\n");
++              writel(dev->rx_info.phy_descs +
++                      (4 * DESC_SIZE * dev->rx_info.next_rx),
++                     dev->base + RXDP);
++              if (dev->rx_info.next_rx == dev->rx_info.next_empty)
++                      printk(KERN_DEBUG "%s: uh-oh: next_rx == next_empty???\n",
++                              ndev->name);
++              __kick_rx(dev);
++      }
++}
++
+ //free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC
+ #define start_tx_okay(dev)    \
+       (((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > MIN_TX_DESC_FREE)
+@@ -546,15 +555,16 @@ static inline int ns83820_add_rx_skb(str
+       return 0;
+ }
+-static inline int rx_refill(struct ns83820 *dev, int gfp)
++static inline int rx_refill(struct net_device *ndev, int gfp)
+ {
++      struct ns83820 *dev = PRIV(ndev);
+       unsigned i;
+       unsigned long flags = 0;
+       if (unlikely(nr_rx_empty(dev) <= 2))
+               return 0;
+-      dprintk("rx_refill(%p)\n", dev);
++      dprintk("rx_refill(%p)\n", ndev);
+       if (gfp == GFP_ATOMIC)
+               spin_lock_irqsave(&dev->rx_info.lock, flags);
+       for (i=0; i<NR_RX_DESC; i++) {
+@@ -570,7 +580,7 @@ static inline int rx_refill(struct ns838
+               res &= 0xf;
+               skb_reserve(skb, res);
+-              skb->dev = &dev->net_dev;
++              skb->dev = ndev;
+               if (gfp != GFP_ATOMIC)
+                       spin_lock_irqsave(&dev->rx_info.lock, flags);
+               res = ns83820_add_rx_skb(dev, skb);
+@@ -587,20 +597,21 @@ static inline int rx_refill(struct ns838
+       return i ? 0 : -ENOMEM;
+ }
+-static void FASTCALL(rx_refill_atomic(struct ns83820 *dev));
+-static void rx_refill_atomic(struct ns83820 *dev)
++static void FASTCALL(rx_refill_atomic(struct net_device *ndev));
++static void rx_refill_atomic(struct net_device *ndev)
+ {
+-      rx_refill(dev, GFP_ATOMIC);
++      rx_refill(ndev, GFP_ATOMIC);
+ }
+ /* REFILL */
+ static inline void queue_refill(void *_dev)
+ {
+-      struct ns83820 *dev = _dev;
++      struct net_device *ndev = _dev;
++      struct ns83820 *dev = PRIV(ndev);
+-      rx_refill(dev, GFP_KERNEL);
++      rx_refill(ndev, GFP_KERNEL);
+       if (dev->rx_info.up)
+-              kick_rx(dev);
++              kick_rx(ndev);
+ }
+ static inline void clear_rx_desc(struct ns83820 *dev, unsigned i)
+@@ -608,9 +619,10 @@ static inline void clear_rx_desc(struct 
+       build_rx_desc(dev, dev->rx_info.descs + (DESC_SIZE * i), 0, 0, CMDSTS_OWN, 0);
+ }
+-static void FASTCALL(phy_intr(struct ns83820 *dev));
+-static void phy_intr(struct ns83820 *dev)
++static void FASTCALL(phy_intr(struct net_device *ndev));
++static void phy_intr(struct net_device *ndev)
+ {
++      struct ns83820 *dev = PRIV(ndev);
+       static char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" };
+       u32 cfg, new_cfg;
+       u32 tbisr, tanar, tanlpar;
+@@ -688,27 +700,28 @@ static void phy_intr(struct ns83820 *dev
+       if (newlinkstate & LINK_UP
+           && dev->linkstate != newlinkstate) {
+-              netif_start_queue(&dev->net_dev);
+-              netif_wake_queue(&dev->net_dev);
++              netif_start_queue(ndev);
++              netif_wake_queue(ndev);
+               printk(KERN_INFO "%s: link now %s mbps, %s duplex and up.\n",
+-                      dev->net_dev.name,
++                      ndev->name,
+                       speeds[speed],
+                       fullduplex ? "full" : "half");
+       } else if (newlinkstate & LINK_DOWN
+                  && dev->linkstate != newlinkstate) {
+-              netif_stop_queue(&dev->net_dev);
+-              printk(KERN_INFO "%s: link now down.\n", dev->net_dev.name);
++              netif_stop_queue(ndev);
++              printk(KERN_INFO "%s: link now down.\n", ndev->name);
+       }
+       dev->linkstate = newlinkstate;
+ }
+-static int ns83820_setup_rx(struct ns83820 *dev)
++static int ns83820_setup_rx(struct net_device *ndev)
+ {
++      struct ns83820 *dev = PRIV(ndev);
+       unsigned i;
+       int ret;
+-      dprintk("ns83820_setup_rx(%p)\n", dev);
++      dprintk("ns83820_setup_rx(%p)\n", ndev);
+       dev->rx_info.idle = 1;
+       dev->rx_info.next_rx = 0;
+@@ -721,7 +734,7 @@ static int ns83820_setup_rx(struct ns838
+       writel(0, dev->base + RXDP_HI);
+       writel(dev->rx_info.phy_descs, dev->base + RXDP);
+-      ret = rx_refill(dev, GFP_KERNEL);
++      ret = rx_refill(ndev, GFP_KERNEL);
+       if (!ret) {
+               dprintk("starting receiver\n");
+               /* prevent the interrupt handler from stomping on us */
+@@ -734,7 +747,7 @@ static int ns83820_setup_rx(struct ns838
+               dev->rx_info.up = 1;
+-              phy_intr(dev);
++              phy_intr(ndev);
+               /* Okay, let it rip */
+               spin_lock_irq(&dev->misc_lock);
+@@ -753,7 +766,7 @@ static int ns83820_setup_rx(struct ns838
+               writel(1, dev->base + IER);
+               spin_unlock_irq(&dev->misc_lock);
+-              kick_rx(dev);
++              kick_rx(ndev);
+               spin_unlock_irq(&dev->rx_info.lock);
+       }
+@@ -793,37 +806,39 @@ static void ns83820_cleanup_rx(struct ns
+       }
+ }
+-static void FASTCALL(ns83820_rx_kick(struct ns83820 *dev));
+-static void ns83820_rx_kick(struct ns83820 *dev)
++static void FASTCALL(ns83820_rx_kick(struct net_device *ndev));
++static void ns83820_rx_kick(struct net_device *ndev)
+ {
++      struct ns83820 *dev = PRIV(ndev);
+       /*if (nr_rx_empty(dev) >= NR_RX_DESC/4)*/ {
+               if (dev->rx_info.up) {
+-                      rx_refill_atomic(dev);
+-                      kick_rx(dev);
++                      rx_refill_atomic(ndev);
++                      kick_rx(ndev);
+               }
+       }
+       if (dev->rx_info.up && nr_rx_empty(dev) > NR_RX_DESC*3/4)
+               schedule_work(&dev->tq_refill);
+       else
+-              kick_rx(dev);
++              kick_rx(ndev);
+       if (dev->rx_info.idle)
+-              printk(KERN_DEBUG "%s: BAD\n", dev->net_dev.name);
++              printk(KERN_DEBUG "%s: BAD\n", ndev->name);
+ }
+ /* rx_irq
+  *    
+  */
+-static void FASTCALL(rx_irq(struct ns83820 *dev));
+-static void rx_irq(struct ns83820 *dev)
++static void FASTCALL(rx_irq(struct net_device *ndev));
++static void rx_irq(struct net_device *ndev)
+ {
++      struct ns83820 *dev = PRIV(ndev);
+       struct rx_info *info = &dev->rx_info;
+       unsigned next_rx;
+       u32 cmdsts, *desc;
+       unsigned long flags;
+       int nr = 0;
+-      dprintk("rx_irq(%p)\n", dev);
++      dprintk("rx_irq(%p)\n", ndev);
+       dprintk("rxdp: %08x, descs: %08lx next_rx[%d]: %p next_empty[%d]: %p\n",
+               readl(dev->base + RXDP),
+               (long)(dev->rx_info.phy_descs),
+@@ -873,7 +888,7 @@ static void rx_irq(struct ns83820 *dev)
+                       } else {
+                               skb->ip_summed = CHECKSUM_NONE;
+                       }
+-                      skb->protocol = eth_type_trans(skb, &dev->net_dev);
++                      skb->protocol = eth_type_trans(skb, ndev);
+                       if (NET_RX_DROP == netif_rx(skb)) {
+ netdev_mangle_me_harder_failed:
+                               dev->stats.rx_dropped ++;
+@@ -899,8 +914,9 @@ out:
+ static void rx_action(unsigned long _dev)
+ {
+-      struct ns83820 *dev = (void *)_dev;
+-      rx_irq(dev);
++      struct net_device *ndev = (void *)_dev;
++      struct ns83820 *dev = PRIV(ndev);
++      rx_irq(ndev);
+       writel(ihr, dev->base + IHR);
+       spin_lock_irq(&dev->misc_lock);
+@@ -908,8 +924,8 @@ static void rx_action(unsigned long _dev
+       writel(dev->IMR_cache, dev->base + IMR);
+       spin_unlock_irq(&dev->misc_lock);
+-      rx_irq(dev);
+-      ns83820_rx_kick(dev);
++      rx_irq(ndev);
++      ns83820_rx_kick(ndev);
+ }
+ /* Packet Transmit code
+@@ -924,13 +940,14 @@ static inline void kick_tx(struct ns8382
+ /* No spinlock needed on the transmit irq path as the interrupt handler is
+  * serialized.
+  */
+-static void do_tx_done(struct ns83820 *dev)
++static void do_tx_done(struct net_device *ndev)
+ {
++      struct ns83820 *dev = PRIV(ndev);
+       u32 cmdsts, tx_done_idx, *desc;
+       spin_lock_irq(&dev->tx_lock);
+-      dprintk("do_tx_done(%p)\n", dev);
++      dprintk("do_tx_done(%p)\n", ndev);
+       tx_done_idx = dev->tx_done_idx;
+       desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
+@@ -980,10 +997,10 @@ static void do_tx_done(struct ns83820 *d
+       /* Allow network stack to resume queueing packets after we've
+        * finished transmitting at least 1/4 of the packets in the queue.
+        */
+-      if (netif_queue_stopped(&dev->net_dev) && start_tx_okay(dev)) {
+-              dprintk("start_queue(%p)\n", dev);
+-              netif_start_queue(&dev->net_dev);
+-              netif_wake_queue(&dev->net_dev);
++      if (netif_queue_stopped(ndev) && start_tx_okay(dev)) {
++              dprintk("start_queue(%p)\n", ndev);
++              netif_start_queue(ndev);
++              netif_wake_queue(ndev);
+       }
+       spin_unlock_irq(&dev->tx_lock);
+ }
+@@ -1015,9 +1032,9 @@ static void ns83820_cleanup_tx(struct ns
+  * while trying to track down a bug in either the zero copy code or
+  * the tx fifo (hence the MAX_FRAG_LEN).
+  */
+-static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *_dev)
++static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ {
+-      struct ns83820 *dev = (struct ns83820 *)_dev;
++      struct ns83820 *dev = PRIV(ndev);
+       u32 free_idx, cmdsts, extsts;
+       int nr_free, nr_frags;
+       unsigned tx_done_idx, last_idx;
+@@ -1033,10 +1050,10 @@ static int ns83820_hard_start_xmit(struc
+       nr_frags =  skb_shinfo(skb)->nr_frags;
+ again:
+       if (unlikely(dev->CFG_cache & CFG_LNKSTS)) {
+-              netif_stop_queue(&dev->net_dev);
++              netif_stop_queue(ndev);
+               if (unlikely(dev->CFG_cache & CFG_LNKSTS))
+                       return 1;
+-              netif_start_queue(&dev->net_dev);
++              netif_start_queue(ndev);
+       }
+       last_idx = free_idx = dev->tx_free_idx;
+@@ -1044,13 +1061,13 @@ again:
+       nr_free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC;
+       nr_free -= 1;
+       if (nr_free <= nr_frags) {
+-              dprintk("stop_queue - not enough(%p)\n", dev);
+-              netif_stop_queue(&dev->net_dev);
++              dprintk("stop_queue - not enough(%p)\n", ndev);
++              netif_stop_queue(ndev);
+               /* Check again: we may have raced with a tx done irq */
+               if (dev->tx_done_idx != tx_done_idx) {
+-                      dprintk("restart queue(%p)\n", dev);
+-                      netif_start_queue(&dev->net_dev);
++                      dprintk("restart queue(%p)\n", ndev);
++                      netif_start_queue(ndev);
+                       goto again;
+               }
+               return 1;
+@@ -1063,8 +1080,8 @@ again:
+       nr_free -= nr_frags;
+       if (nr_free < MIN_TX_DESC_FREE) {
+-              dprintk("stop_queue - last entry(%p)\n", dev);
+-              netif_stop_queue(&dev->net_dev);
++              dprintk("stop_queue - last entry(%p)\n", ndev);
++              netif_stop_queue(ndev);
+               stopped = 1;
+       }
+@@ -1136,10 +1153,10 @@ again:
+       /* Check again: we may have raced with a tx done irq */
+       if (stopped && (dev->tx_done_idx != tx_done_idx) && start_tx_okay(dev))
+-              netif_start_queue(&dev->net_dev);
++              netif_start_queue(ndev);
+       /* set the transmit start time to catch transmit timeouts */
+-      dev->net_dev.trans_start = jiffies;
++      ndev->trans_start = jiffies;
+       return 0;
+ }
+@@ -1161,9 +1178,9 @@ static void ns83820_update_stats(struct 
+       dev->stats.tx_carrier_errors    += readl(base + 0x88) & 0xff;
+ }
+-static struct net_device_stats *ns83820_get_stats(struct net_device *_dev)
++static struct net_device_stats *ns83820_get_stats(struct net_device *ndev)
+ {
+-      struct ns83820 *dev = (void *)_dev;
++      struct ns83820 *dev = PRIV(ndev);
+       /* somewhat overkill */
+       spin_lock_irq(&dev->misc_lock);
+@@ -1213,9 +1230,9 @@ static int ns83820_ethtool_ioctl (struct
+       return -EOPNOTSUPP;
+ }
+-static int ns83820_ioctl(struct net_device *_dev, struct ifreq *rq, int cmd)
++static int ns83820_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
+ {
+-      struct ns83820 *dev = (struct ns83820 *)_dev;
++      struct ns83820 *dev = PRIV(ndev);
+       switch(cmd) {
+       case SIOCETHTOOL:
+@@ -1233,23 +1250,25 @@ static void ns83820_mib_isr(struct ns838
+       spin_unlock(&dev->misc_lock);
+ }
+-static void ns83820_do_isr(struct ns83820 *dev, u32 isr);
++static void ns83820_do_isr(struct net_device *ndev, u32 isr);
+ static irqreturn_t ns83820_irq(int foo, void *data, struct pt_regs *regs)
+ {
+-      struct ns83820 *dev = data;
++      struct net_device *ndev = data;
++      struct ns83820 *dev = PRIV(ndev);
+       u32 isr;
+-      dprintk("ns83820_irq(%p)\n", dev);
++      dprintk("ns83820_irq(%p)\n", ndev);
+       dev->ihr = 0;
+       isr = readl(dev->base + ISR);
+       dprintk("irq: %08x\n", isr);
+-      ns83820_do_isr(dev, isr);
++      ns83820_do_isr(ndev, isr);
+       return IRQ_HANDLED;
+ }
+-static void ns83820_do_isr(struct ns83820 *dev, u32 isr)
++static void ns83820_do_isr(struct net_device *ndev, u32 isr)
+ {
++      struct ns83820 *dev = PRIV(ndev);
+ #ifdef DEBUG
+       if (isr & ~(ISR_PHY | ISR_RXDESC | ISR_RXEARLY | ISR_RXOK | ISR_RXERR | ISR_TXIDLE | ISR_TXOK | ISR_TXDESC))
+               Dprintk("odd isr? 0x%08x\n", isr);
+@@ -1258,7 +1277,7 @@ static void ns83820_do_isr(struct ns8382
+       if (ISR_RXIDLE & isr) {
+               dev->rx_info.idle = 1;
+               Dprintk("oh dear, we are idle\n");
+-              ns83820_rx_kick(dev);
++              ns83820_rx_kick(ndev);
+       }
+       if ((ISR_RXDESC | ISR_RXOK) & isr) {
+@@ -1270,12 +1289,12 @@ static void ns83820_do_isr(struct ns8382
+               spin_unlock_irq(&dev->misc_lock);
+               tasklet_schedule(&dev->rx_tasklet);
+-              //rx_irq(dev);
++              //rx_irq(ndev);
+               //writel(4, dev->base + IHR);
+       }
+       if ((ISR_RXIDLE | ISR_RXORN | ISR_RXDESC | ISR_RXOK | ISR_RXERR) & isr)
+-              ns83820_rx_kick(dev);
++              ns83820_rx_kick(ndev);
+       if (unlikely(ISR_RXSOVR & isr)) {
+               //printk("overrun: rxsovr\n");
+@@ -1297,7 +1316,7 @@ static void ns83820_do_isr(struct ns8382
+               txdp -= dev->tx_phy_descs;
+               dev->tx_idx = txdp / (DESC_SIZE * 4);
+               if (dev->tx_idx >= NR_TX_DESC) {
+-                      printk(KERN_ALERT "%s: BUG -- txdp out of range\n", dev->net_dev.name);
++                      printk(KERN_ALERT "%s: BUG -- txdp out of range\n", ndev->name);
+                       dev->tx_idx = 0;
+               }
+               /* The may have been a race between a pci originated read
+@@ -1313,7 +1332,7 @@ static void ns83820_do_isr(struct ns8382
+        * work has accumulated
+        */
+       if ((ISR_TXDESC | ISR_TXIDLE | ISR_TXOK | ISR_TXERR) & isr) {
+-              do_tx_done(dev);
++              do_tx_done(ndev);
+               /* Disable TxOk if there are no outstanding tx packets.
+                */
+@@ -1345,7 +1364,7 @@ static void ns83820_do_isr(struct ns8382
+       /* PHY: Link up/down/negotiation state change */
+       if (unlikely(ISR_PHY & isr))
+-              phy_intr(dev);
++              phy_intr(ndev);
+ #if 0 /* Still working on the interrupt mitigation strategy */
+       if (dev->ihr)
+@@ -1363,9 +1382,9 @@ static void ns83820_do_reset(struct ns83
+       Dprintk("okay!\n");
+ }
+-static int ns83820_stop(struct net_device *_dev)
++static int ns83820_stop(struct net_device *ndev)
+ {
+-      struct ns83820 *dev = (struct ns83820 *)_dev;
++      struct ns83820 *dev = PRIV(ndev);
+       /* FIXME: protect against interrupt handler? */
+       del_timer_sync(&dev->tx_watchdog);
+@@ -1392,10 +1411,9 @@ static int ns83820_stop(struct net_devic
+       return 0;
+ }
+-static void ns83820_do_isr(struct ns83820 *dev, u32 isr);
+-static void ns83820_tx_timeout(struct net_device *_dev)
++static void ns83820_tx_timeout(struct net_device *ndev)
+ {
+-      struct ns83820 *dev = (struct ns83820 *)_dev;
++      struct ns83820 *dev = PRIV(ndev);
+         u32 tx_done_idx, *desc;
+       unsigned long flags;
+@@ -1405,7 +1423,7 @@ static void ns83820_tx_timeout(struct ne
+       desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
+       printk(KERN_INFO "%s: tx_timeout: tx_done_idx=%d free_idx=%d cmdsts=%08x\n",
+-              dev->net_dev.name,
++              ndev->name,
+               tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS]));
+ #if defined(DEBUG)
+@@ -1413,17 +1431,17 @@ static void ns83820_tx_timeout(struct ne
+               u32 isr;
+               isr = readl(dev->base + ISR);
+               printk("irq: %08x imr: %08x\n", isr, dev->IMR_cache);
+-              ns83820_do_isr(dev, isr);
++              ns83820_do_isr(ndev, isr);
+       }
+ #endif
+-      do_tx_done(dev);
++      do_tx_done(ndev);
+       tx_done_idx = dev->tx_done_idx;
+       desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
+       printk(KERN_INFO "%s: after: tx_done_idx=%d free_idx=%d cmdsts=%08x\n",
+-              dev->net_dev.name,
++              ndev->name,
+               tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS]));
+       local_irq_restore(flags);
+@@ -1431,7 +1449,8 @@ static void ns83820_tx_timeout(struct ne
+ static void ns83820_tx_watch(unsigned long data)
+ {
+-      struct ns83820 *dev = (void *)data;
++      struct net_device *ndev = (void *)data;
++      struct ns83820 *dev = PRIV(ndev);
+ #if defined(DEBUG)
+       printk("ns83820_tx_watch: %u %u %d\n",
+@@ -1439,21 +1458,21 @@ static void ns83820_tx_watch(unsigned lo
+               );
+ #endif
+-      if (time_after(jiffies, dev->net_dev.trans_start + 1*HZ) &&
++      if (time_after(jiffies, ndev->trans_start + 1*HZ) &&
+           dev->tx_done_idx != dev->tx_free_idx) {
+               printk(KERN_DEBUG "%s: ns83820_tx_watch: %u %u %d\n",
+-                      dev->net_dev.name,
++                      ndev->name,
+                       dev->tx_done_idx, dev->tx_free_idx,
+                       atomic_read(&dev->nr_tx_skbs));
+-              ns83820_tx_timeout(&dev->net_dev);
++              ns83820_tx_timeout(ndev);
+       }
+       mod_timer(&dev->tx_watchdog, jiffies + 2*HZ);
+ }
+-static int ns83820_open(struct net_device *_dev)
++static int ns83820_open(struct net_device *ndev)
+ {
+-      struct ns83820 *dev = (struct ns83820 *)_dev;
++      struct ns83820 *dev = PRIV(ndev);
+       unsigned i;
+       u32 desc;
+       int ret;
+@@ -1462,7 +1481,7 @@ static int ns83820_open(struct net_devic
+       writel(0, dev->base + PQCR);
+-      ret = ns83820_setup_rx(dev);
++      ret = ns83820_setup_rx(ndev);
+       if (ret)
+               goto failed;
+@@ -1481,16 +1500,16 @@ static int ns83820_open(struct net_devic
+       writel(desc, dev->base + TXDP);
+       init_timer(&dev->tx_watchdog);
+-      dev->tx_watchdog.data = (unsigned long)dev;
++      dev->tx_watchdog.data = (unsigned long)ndev;
+       dev->tx_watchdog.function = ns83820_tx_watch;
+       mod_timer(&dev->tx_watchdog, jiffies + 2*HZ);
+-      netif_start_queue(&dev->net_dev);       /* FIXME: wait for phy to come up */
++      netif_start_queue(ndev);        /* FIXME: wait for phy to come up */
+       return 0;
+ failed:
+-      ns83820_stop(_dev);
++      ns83820_stop(ndev);
+       return ret;
+ }
+@@ -1513,28 +1532,28 @@ static void ns83820_getmac(struct ns8382
+       }
+ }
+-static int ns83820_change_mtu(struct net_device *_dev, int new_mtu)
++static int ns83820_change_mtu(struct net_device *ndev, int new_mtu)
+ {
+       if (new_mtu > RX_BUF_SIZE)
+               return -EINVAL;
+-      _dev->mtu = new_mtu;
++      ndev->mtu = new_mtu;
+       return 0;
+ }
+-static void ns83820_set_multicast(struct net_device *_dev)
++static void ns83820_set_multicast(struct net_device *ndev)
+ {
+-      struct ns83820 *dev = (void *)_dev;
++      struct ns83820 *dev = PRIV(ndev);
+       u8 *rfcr = dev->base + RFCR;
+       u32 and_mask = 0xffffffff;
+       u32 or_mask = 0;
+       u32 val;
+-      if (dev->net_dev.flags & IFF_PROMISC)
++      if (ndev->flags & IFF_PROMISC)
+               or_mask |= RFCR_AAU | RFCR_AAM;
+       else
+               and_mask &= ~(RFCR_AAU | RFCR_AAM);
+-      if (dev->net_dev.flags & IFF_ALLMULTI)
++      if (ndev->flags & IFF_ALLMULTI)
+               or_mask |= RFCR_AAM;
+       else
+               and_mask &= ~RFCR_AAM;
+@@ -1547,14 +1566,15 @@ static void ns83820_set_multicast(struct
+       spin_unlock_irq(&dev->misc_lock);
+ }
+-static void ns83820_run_bist(struct ns83820 *dev, const char *name, u32 enable, u32 done, u32 fail)
++static void ns83820_run_bist(struct net_device *ndev, const char *name, u32 enable, u32 done, u32 fail)
+ {
++      struct ns83820 *dev = PRIV(ndev);
+       int timed_out = 0;
+       long start;
+       u32 status;
+       int loops = 0;
+-      dprintk("%s: start %s\n", dev->net_dev.name, name);
++      dprintk("%s: start %s\n", ndev->name, name);
+       start = jiffies;
+@@ -1578,12 +1598,12 @@ static void ns83820_run_bist(struct ns83
+       if (status & fail)
+               printk(KERN_INFO "%s: %s failed! (0x%08x & 0x%08x)\n",
+-                      dev->net_dev.name, name, status, fail);
++                      ndev->name, name, status, fail);
+       else if (timed_out)
+               printk(KERN_INFO "%s: run_bist %s timed out! (%08x)\n",
+-                      dev->net_dev.name, name, status);
++                      ndev->name, name, status);
+-      dprintk("%s: done %s in %d loops\n", dev->net_dev.name, name, loops);
++      dprintk("%s: done %s in %d loops\n", ndev->name, name, loops);
+ }
+ #ifdef PHY_CODE_IS_FINISHED
+@@ -1706,8 +1726,9 @@ static unsigned ns83820_mii_write_reg(st
+       return data;
+ }
+-static void ns83820_probe_phy(struct ns83820 *dev)
++static void ns83820_probe_phy(struct net_device *ndev)
+ {
++      struct ns83820 *dev = PRIV(ndev);
+       static int first;
+       int i;
+ #define MII_PHYIDR1   0x02
+@@ -1734,11 +1755,11 @@ static void ns83820_probe_phy(struct ns8
+               b = ns83820_mii_read_reg(dev, i, MII_PHYIDR2);
+               //printk("%s: phy %d: 0x%04x 0x%04x\n",
+-              //      dev->net_dev.name, i, a, b);
++              //      ndev->name, i, a, b);
+               for (j=0; j<0x16; j+=4) {
+                       dprintk("%s: [0x%02x] %04x %04x %04x %04x\n",
+-                              dev->net_dev.name, j,
++                              ndev->name, j,
+                               ns83820_mii_read_reg(dev, i, 0 + j),
+                               ns83820_mii_read_reg(dev, i, 1 + j),
+                               ns83820_mii_read_reg(dev, i, 2 + j),
+@@ -1763,6 +1784,7 @@ static void ns83820_probe_phy(struct ns8
+ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_device_id *id)
+ {
++      struct net_device *ndev;
+       struct ns83820 *dev;
+       long addr;
+       int err;
+@@ -1778,7 +1800,8 @@ static int __devinit ns83820_init_one(st
+               return -ENODEV;
+       }
+-      dev = (struct ns83820 *)alloc_etherdev((sizeof *dev) - (sizeof dev->net_dev));
++      ndev = alloc_etherdev(sizeof(struct ns83820));
++      dev = PRIV(ndev);
+       err = -ENOMEM;
+       if (!dev)
+               goto out;
+@@ -1790,12 +1813,11 @@ static int __devinit ns83820_init_one(st
+       dev->ee.cache = &dev->MEAR_cache;
+       dev->ee.lock = &dev->misc_lock;
+-      SET_MODULE_OWNER(dev->net_dev);
+-      SET_NETDEV_DEV(&dev->net_dev, &pci_dev->dev);
+-      dev->net_dev.priv = dev;
++      SET_MODULE_OWNER(ndev);
++      SET_NETDEV_DEV(ndev, &pci_dev->dev);
+-      INIT_WORK(&dev->tq_refill, queue_refill, dev);
+-      tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)dev);
++      INIT_WORK(&dev->tq_refill, queue_refill, ndev);
++      tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)ndev);
+       err = pci_enable_device(pci_dev);
+       if (err) {
+@@ -1829,55 +1851,63 @@ static int __devinit ns83820_init_one(st
+               0);
+       err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ,
+-                        dev->net_dev.name, dev);
++                        ndev->name, ndev);
+       if (err) {
+               printk(KERN_INFO "ns83820: unable to register irq %d\n",
+                       pci_dev->irq);
+               goto out_disable;
+       }
+-      err = register_netdev(&dev->net_dev);
+-      if (err) {
+-              printk(KERN_INFO "ns83820: unable to register netdev: %d\n", err);
++      /*
++       * FIXME: we are holding rtnl_lock() over obscenely long area only
++       * because some of the setup code uses dev->name.  It's Wrong(tm) -
++       * we should be using driver-specific names for all that stuff.
++       * For now that will do, but we really need to come back and kill
++       * most of the dev_alloc_name() users later.
++       */
++      rtnl_lock();
++      err = dev_alloc_name(ndev, ndev->name);
++      if (err < 0) {
++              printk(KERN_INFO "ns83820: unable to get netdev name: %d\n", err);
+               goto out_free_irq;
+       }
+       printk("%s: ns83820.c: 0x22c: %08x, subsystem: %04x:%04x\n",
+-              dev->net_dev.name, le32_to_cpu(readl(dev->base + 0x22c)),
++              ndev->name, le32_to_cpu(readl(dev->base + 0x22c)),
+               pci_dev->subsystem_vendor, pci_dev->subsystem_device);
+-      dev->net_dev.open = ns83820_open;
+-      dev->net_dev.stop = ns83820_stop;
+-      dev->net_dev.hard_start_xmit = ns83820_hard_start_xmit;
+-      dev->net_dev.get_stats = ns83820_get_stats;
+-      dev->net_dev.change_mtu = ns83820_change_mtu;
+-      dev->net_dev.set_multicast_list = ns83820_set_multicast;
+-      dev->net_dev.do_ioctl = ns83820_ioctl;
+-      dev->net_dev.tx_timeout = ns83820_tx_timeout;
+-      dev->net_dev.watchdog_timeo = 5 * HZ;
++      ndev->open = ns83820_open;
++      ndev->stop = ns83820_stop;
++      ndev->hard_start_xmit = ns83820_hard_start_xmit;
++      ndev->get_stats = ns83820_get_stats;
++      ndev->change_mtu = ns83820_change_mtu;
++      ndev->set_multicast_list = ns83820_set_multicast;
++      ndev->do_ioctl = ns83820_ioctl;
++      ndev->tx_timeout = ns83820_tx_timeout;
++      ndev->watchdog_timeo = 5 * HZ;
+-      pci_set_drvdata(pci_dev, dev);
++      pci_set_drvdata(pci_dev, ndev);
+       ns83820_do_reset(dev, CR_RST);
+       /* Must reset the ram bist before running it */
+       writel(PTSCR_RBIST_RST, dev->base + PTSCR);
+-      ns83820_run_bist(dev, "sram bist",   PTSCR_RBIST_EN,
++      ns83820_run_bist(ndev, "sram bist",   PTSCR_RBIST_EN,
+                        PTSCR_RBIST_DONE, PTSCR_RBIST_FAIL);
+-      ns83820_run_bist(dev, "eeprom bist", PTSCR_EEBIST_EN, 0,
++      ns83820_run_bist(ndev, "eeprom bist", PTSCR_EEBIST_EN, 0,
+                        PTSCR_EEBIST_FAIL);
+-      ns83820_run_bist(dev, "eeprom load", PTSCR_EELOAD_EN, 0, 0);
++      ns83820_run_bist(ndev, "eeprom load", PTSCR_EELOAD_EN, 0, 0);
+       /* I love config registers */
+       dev->CFG_cache = readl(dev->base + CFG);
+       if ((dev->CFG_cache & CFG_PCI64_DET)) {
+               printk(KERN_INFO "%s: detected 64 bit PCI data bus.\n",
+-                      dev->net_dev.name);
++                      ndev->name);
+               /*dev->CFG_cache |= CFG_DATA64_EN;*/
+               if (!(dev->CFG_cache & CFG_DATA64_EN))
+                       printk(KERN_INFO "%s: EEPROM did not enable 64 bit bus.  Disabled.\n",
+-                              dev->net_dev.name);
++                              ndev->name);
+       } else
+               dev->CFG_cache &= ~(CFG_DATA64_EN);
+@@ -1905,7 +1935,7 @@ static int __devinit ns83820_init_one(st
+       /* setup optical transceiver if we have one */
+       if (dev->CFG_cache & CFG_TBI_EN) {
+               printk(KERN_INFO "%s: enabling optical transceiver\n",
+-                      dev->net_dev.name);
++                      ndev->name);
+               writel(readl(dev->base + GPIOR) | 0x3e8, dev->base + GPIOR);
+               /* setup auto negotiation feature advertisement */
+@@ -1926,7 +1956,7 @@ static int __devinit ns83820_init_one(st
+       dprintk("CFG: %08x\n", dev->CFG_cache);
+       if (reset_phy) {
+-              printk(KERN_INFO "%s: resetting phy\n", dev->net_dev.name);
++              printk(KERN_INFO "%s: resetting phy\n", ndev->name);
+               writel(dev->CFG_cache | CFG_PHY_RST, dev->base + CFG);
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout((HZ+99)/100);
+@@ -1996,37 +2026,49 @@ static int __devinit ns83820_init_one(st
+       /* Disable Wake On Lan */
+       writel(0, dev->base + WCSR);
+-      ns83820_getmac(dev, dev->net_dev.dev_addr);
++      ns83820_getmac(dev, ndev->dev_addr);
+       /* Yes, we support dumb IP checksum on transmit */
+-      dev->net_dev.features |= NETIF_F_SG;
+-      dev->net_dev.features |= NETIF_F_IP_CSUM;
++      ndev->features |= NETIF_F_SG;
++      ndev->features |= NETIF_F_IP_CSUM;
+       if (using_dac) {
+               printk(KERN_INFO "%s: using 64 bit addressing.\n",
+-                      dev->net_dev.name);
+-              dev->net_dev.features |= NETIF_F_HIGHDMA;
++                      ndev->name);
++              ndev->features |= NETIF_F_HIGHDMA;
+       }
+       printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %02x:%02x:%02x:%02x:%02x:%02x io=0x%08lx irq=%d f=%s\n",
+-              dev->net_dev.name,
++              ndev->name,
+               (unsigned)readl(dev->base + SRR) >> 8,
+               (unsigned)readl(dev->base + SRR) & 0xff,
+-              dev->net_dev.dev_addr[0], dev->net_dev.dev_addr[1],
+-              dev->net_dev.dev_addr[2], dev->net_dev.dev_addr[3],
+-              dev->net_dev.dev_addr[4], dev->net_dev.dev_addr[5],
++              ndev->dev_addr[0], ndev->dev_addr[1],
++              ndev->dev_addr[2], ndev->dev_addr[3],
++              ndev->dev_addr[4], ndev->dev_addr[5],
+               addr, pci_dev->irq,
+-              (dev->net_dev.features & NETIF_F_HIGHDMA) ? "h,sg" : "sg"
++              (ndev->features & NETIF_F_HIGHDMA) ? "h,sg" : "sg"
+               );
+ #ifdef PHY_CODE_IS_FINISHED
+-      ns83820_probe_phy(dev);
++      ns83820_probe_phy(ndev);
+ #endif
++      err = register_netdevice(ndev);
++      if (err) {
++              printk(KERN_INFO "ns83820: unable to register netdev: %d\n", err);
++              goto out_cleanup;
++      }
++      rtnl_unlock();
++
+       return 0;
++out_cleanup:
++      writel(0, dev->base + IMR);     /* paranoia */
++      writel(0, dev->base + IER);
++      readl(dev->base + IER);
+ out_free_irq:
+-      free_irq(pci_dev->irq, dev);
++      rtnl_unlock();
++      free_irq(pci_dev->irq, ndev);
+ out_disable:
+       if (dev->base)
+               iounmap(dev->base);
+@@ -2034,7 +2076,7 @@ out_disable:
+       pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_RX_DESC, dev->rx_info.descs, dev->rx_info.phy_descs);
+       pci_disable_device(pci_dev);
+ out_free:
+-      kfree(dev);
++      free_netdev(ndev);
+       pci_set_drvdata(pci_dev, NULL);
+ out:
+       return err;
+@@ -2042,24 +2084,25 @@ out:
+ static void __devexit ns83820_remove_one(struct pci_dev *pci_dev)
+ {
+-      struct ns83820  *dev = pci_get_drvdata(pci_dev);
++      struct net_device *ndev = pci_get_drvdata(pci_dev);
++      struct ns83820 *dev = PRIV(ndev); /* ok even if NULL */
+-      if (!dev)                       /* paranoia */
++      if (!ndev)                      /* paranoia */
+               return;
+       writel(0, dev->base + IMR);     /* paranoia */
+       writel(0, dev->base + IER);
+       readl(dev->base + IER);
+-      unregister_netdev(&dev->net_dev);
+-      free_irq(dev->pci_dev->irq, dev);
++      unregister_netdev(ndev);
++      free_irq(dev->pci_dev->irq, ndev);
+       iounmap(dev->base);
+       pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_TX_DESC,
+                       dev->tx_descs, dev->tx_phy_descs);
+       pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_RX_DESC,
+                       dev->rx_info.descs, dev->rx_info.phy_descs);
+       pci_disable_device(dev->pci_dev);
+-      free_netdev(&dev->net_dev);
++      free_netdev(ndev);
+       pci_set_drvdata(pci_dev, NULL);
+ }
+--- linux-2.6.0/drivers/net/oaknet.c   2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/oaknet.c    2003-12-28 23:21:01.000000000 -0800
+@@ -94,8 +94,8 @@ static int __init oaknet_init(void)
+ {
+       register int i;
+       int reg0, regd;
+-      int ret;
+-      struct net_device tmp, *dev = NULL;
++      int ret = -ENOMEM;
++      struct net_device *dev;
+ #if 0
+       unsigned long ioaddr = OAKNET_IO_BASE; 
+ #else
+@@ -105,17 +105,14 @@ static int __init oaknet_init(void)
+       if (!ioaddr)
+               return -ENOMEM;
+-      /*
+-       * This MUST happen here because of the nic_* macros
+-       * which have an implicit dependency on dev->base_addr.
+-       */
+-      tmp.base_addr = ioaddr;
+-      dev = &tmp;
++      dev = alloc_ei_netdev();
++      if (!dev)
++              goto out_unmap;
+       ret = -EBUSY;
+       if (!request_region(OAKNET_IO_BASE, OAKNET_IO_SIZE, name))
+-              goto out_unmap;
++              goto out_dev;
+       /* Quick register check to see if the device is really there. */
+@@ -144,17 +141,7 @@ static int __init oaknet_init(void)
+               goto out_region;
+       }
+-      /*
+-       * We're not using the old-style probing API, so we have to allocate
+-       * our own device structure.
+-       */
+-
+-      dev = init_etherdev(NULL, 0);
+-      ret = -ENOMEM;
+-      if (!dev)
+-              goto out_region;
+       SET_MODULE_OWNER(dev);
+-      oaknet_devs = dev;
+       /*
+        * This controller is on an embedded board, so the base address
+@@ -164,14 +151,6 @@ static int __init oaknet_init(void)
+       dev->base_addr = ioaddr;
+       dev->irq = OAKNET_INT;
+-      /* Allocate 8390-specific device-private area and fields. */
+-
+-      ret = -ENOMEM;
+-      if (ethdev_init(dev)) {
+-              printk(" unable to get memory for dev->priv.\n");
+-              goto out_dev;
+-      }
+-
+       /*
+        * Disable all chip interrupts for now and ACK all pending
+        * interrupts.
+@@ -186,7 +165,7 @@ static int __init oaknet_init(void)
+       if (request_irq(dev->irq, ei_interrupt, 0, name, dev)) {
+               printk("%s: unable to request interrupt %d.\n",
+                      dev->name, dev->irq);
+-              goto out_priv;
++              goto out_region;
+       }
+       /* Tell the world about what and where we've found. */
+@@ -215,15 +194,19 @@ static int __init oaknet_init(void)
+       dev->stop = oaknet_close;
+       NS8390_init(dev, FALSE);
++      ret = register_netdev(dev);
++      if (ret)
++              goto out_irq;
++      
++      oaknet_devs = dev;
++      return 0;
+-      return (0);
+-out_priv:
+-      kfree(dev->priv);
+-out_dev:
+-      unregister_netdev(dev);
+-      kfree(dev);
++out_irq;
++      free_irq(dev->irq, dev);
+ out_region:
+       release_region(OAKNET_IO_BASE, OAKNET_IO_SIZE);
++out_dev:
++      free_netdev(dev);
+ out_unmap:
+       iounmap(ioaddr);
+       return ret;
+@@ -662,38 +645,18 @@ oaknet_dma_error(struct net_device *dev,
+ }
+ /*
+- * Oak Ethernet module load interface.
+- */
+-static int __init oaknet_init_module (void)
+-{
+-      if (oaknet_devs != NULL)
+-              return (-EBUSY);
+-
+-      return (oaknet_init());
+-}
+-
+-/*
+  * Oak Ethernet module unload interface.
+  */
+ static void __exit oaknet_cleanup_module (void)
+ {
+-      if (oaknet_devs == NULL)
+-              return;
+-
+-      if (oaknet_devs->priv != NULL) {
+-              int ioaddr = oaknet_devs->base_addr;
+-              void *priv = oaknet_devs->priv;
+-              free_irq(oaknet_devs->irq, oaknet_devs);
+-              release_region(ioaddr, OAKNET_IO_SIZE);
+-              iounmap(ioaddr);
+-              unregister_netdev(oaknet_dev);
+-              free_netdev(priv);
+-      }
+-
+       /* Convert to loop once driver supports multiple devices. */
+-      kfree(oaknet_devs);
++      unregister_netdev(oaknet_dev);
++      free_irq(oaknet_devs->irq, oaknet_devs);
++      release_region(oaknet_devs->base_addr, OAKNET_IO_SIZE);
++      iounmap(ioaddr);
++      free_netdev(oaknet_devs);
+ }
+-module_init(oaknet_init_module);
++module_init(oaknet_init);
+ module_exit(oaknet_cleanup_module);
+ MODULE_LICENSE("GPL");
+--- linux-2.6.0/drivers/net/pci-skeleton.c     2003-12-17 21:20:02.000000000 -0800
++++ 25/drivers/net/pci-skeleton.c      2003-12-28 23:21:01.000000000 -0800
+@@ -730,7 +730,7 @@ err_out_free_res:
+ #endif
+       pci_release_regions (pdev);
+ err_out:
+-      kfree (dev);
++      free_netdev (dev);
+       DPRINTK ("EXIT, returning %d\n", rc);
+       return rc;
+ }
+--- linux-2.6.0/drivers/net/pcmcia/3c574_cs.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/pcmcia/3c574_cs.c   2003-12-28 23:22:53.000000000 -0800
+@@ -330,7 +330,7 @@ static dev_link_t *tc574_attach(void)
+       client_reg.event_handler = &tc574_event;
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != 0) {
+               cs_error(link->handle, RegisterClient, ret);
+               tc574_detach(link);
+@@ -362,23 +362,17 @@ static void tc574_detach(dev_link_t *lin
+       if (*linkp == NULL)
+       return;
+-      if (link->state & DEV_CONFIG) {
++      if (link->state & DEV_CONFIG)
+               tc574_release(link);
+-              if (link->state & DEV_STALE_CONFIG)
+-                      return;
+-      }
+       if (link->handle)
+-              CardServices(DeregisterClient, link->handle);
++              pcmcia_deregister_client(link->handle);
+       /* Unlink device structure, free bits */
+       *linkp = link->next;
+-      if (link->dev) {
++      if (link->dev)
+               unregister_netdev(dev);
+-              free_netdev(dev);
+-      } else 
+-              kfree(dev);
+-
++      free_netdev(dev);
+ } /* tc574_detach */
+ /*
+@@ -387,8 +381,8 @@ static void tc574_detach(dev_link_t *lin
+       ethernet device available to the system.
+ */
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void tc574_config(dev_link_t *link)
+ {
+@@ -409,12 +403,12 @@ static void tc574_config(dev_link_t *lin
+       tuple.Attributes = 0;
+       tuple.DesiredTuple = CISTPL_CONFIG;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       tuple.TupleData = (cisdata_t *)buf;
+       tuple.TupleDataMax = 64;
+       tuple.TupleOffset = 0;
+-      CS_CHECK(GetTupleData, handle, &tuple);
+-      CS_CHECK(ParseTuple, handle, &tuple, &parse);
++      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++      CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+       link->conf.ConfigBase = parse.config.base;
+       link->conf.Present = parse.config.rmask[0];
+@@ -424,15 +418,15 @@ static void tc574_config(dev_link_t *lin
+       link->io.IOAddrLines = 16;
+       for (i = j = 0; j < 0x400; j += 0x20) {
+               link->io.BasePort1 = j ^ 0x300;
+-              i = CardServices(RequestIO, link->handle, &link->io);
++              i = pcmcia_request_io(link->handle, &link->io);
+               if (i == CS_SUCCESS) break;
+       }
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestIO, i);
+               goto failed;
+       }
+-      CS_CHECK(RequestIRQ, link->handle, &link->irq);
+-      CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++      CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
++      CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+       dev->irq = link->irq.AssignedIRQ;
+       dev->base_addr = link->io.BasePort1;
+@@ -451,8 +445,8 @@ static void tc574_config(dev_link_t *lin
+          the hardware address.  The future products may include a modem chip
+          and put the address in the CIS. */
+       tuple.DesiredTuple = 0x88;
+-      if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) {
+-              CardServices(GetTupleData, handle, &tuple);
++      if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) {
++              pcmcia_get_tuple_data(handle, &tuple);
+               for (i = 0; i < 3; i++)
+                       phys_addr[i] = htons(buf[i]);
+       } else {
+@@ -466,9 +460,9 @@ static void tc574_config(dev_link_t *lin
+               }
+       }
+       tuple.DesiredTuple = CISTPL_VERS_1;
+-      if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS &&
+-              CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS &&
+-              CardServices(ParseTuple, handle, &tuple, &parse) == CS_SUCCESS) {
++      if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS &&
++              pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS &&
++              pcmcia_parse_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
+               cardname = parse.version_1.str + parse.version_1.ofs[1];
+       } else
+               cardname = "3Com 3c574";
+@@ -557,21 +551,11 @@ static void tc574_release(dev_link_t *li
+ {
+       DEBUG(0, "3c574_release(0x%p)\n", link);
+-      if (link->open) {
+-              DEBUG(1, "3c574_cs: release postponed, '%s' still open\n",
+-                        link->dev->dev_name);
+-              link->state |= DEV_STALE_CONFIG;
+-              return;
+-      }
+-
+-      CardServices(ReleaseConfiguration, link->handle);
+-      CardServices(ReleaseIO, link->handle, &link->io);
+-      CardServices(ReleaseIRQ, link->handle, &link->irq);
++      pcmcia_release_configuration(link->handle);
++      pcmcia_release_io(link->handle, &link->io);
++      pcmcia_release_irq(link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+-
+-      if (link->state & DEV_STALE_CONFIG)
+-              tc574_detach(link);
+ }
+ /*
+@@ -608,7 +592,7 @@ static int tc574_event(event_t event, in
+               if (link->state & DEV_CONFIG) {
+                       if (link->open)
+                               netif_device_detach(dev);
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               }
+               break;
+       case CS_EVENT_PM_RESUME:
+@@ -616,7 +600,7 @@ static int tc574_event(event_t event, in
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (link->state & DEV_CONFIG) {
+-                      CardServices(RequestConfiguration, link->handle, &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+                       if (link->open) {
+                               tc574_reset(dev);
+                               netif_device_attach(dev);
+@@ -1092,8 +1076,12 @@ static struct net_device_stats *el3_get_
+ {
+       struct el3_private *lp = (struct el3_private *)dev->priv;
+-      if (netif_device_present(dev))
++      if (netif_device_present(dev)) {
++              unsigned long flags;
++              spin_lock_irqsave(&lp->window_lock, flags);
+               update_stats(dev);
++              spin_unlock_irqrestore(&lp->window_lock, flags);
++      }
+       return &lp->stats;
+ }
+@@ -1105,7 +1093,6 @@ static void update_stats(struct net_devi
+ {
+       struct el3_private *lp = (struct el3_private *)dev->priv;
+       ioaddr_t ioaddr = dev->base_addr;
+-      unsigned long flags;
+       u8 rx, tx, up;
+       DEBUG(2, "%s: updating the statistics.\n", dev->name);
+@@ -1113,8 +1100,6 @@ static void update_stats(struct net_devi
+       if (inw(ioaddr+EL3_STATUS) == 0xffff) /* No card. */
+               return;
+               
+-      spin_lock_irqsave(&lp->window_lock, flags);
+-
+       /* Unlike the 3c509 we need not turn off stats updates while reading. */
+       /* Switch to the stats window, and read everything. */
+       EL3WINDOW(6);
+@@ -1139,7 +1124,6 @@ static void update_stats(struct net_devi
+       lp->stats.tx_bytes                      += tx + ((up & 0xf0) << 12);
+       EL3WINDOW(1);
+-      spin_unlock_irqrestore(&lp->window_lock, flags);
+ }
+ static int el3_rx(struct net_device *dev, int worklimit)
+@@ -1281,6 +1265,8 @@ static int el3_close(struct net_device *
+       DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
+       
+       if (DEV_OK(link)) {
++              unsigned long flags;
++
+               /* Turn off statistics ASAP.  We update lp->stats below. */
+               outw(StatsDisable, ioaddr + EL3_CMD);
+               
+@@ -1290,15 +1276,15 @@ static int el3_close(struct net_device *
+               
+               /* Note: Switching to window 0 may disable the IRQ. */
+               EL3WINDOW(0);
+-              
++              spin_lock_irqsave(&lp->window_lock, flags);
+               update_stats(dev);
++              spin_unlock_irqrestore(&lp->window_lock, flags);
+       }
+       link->open--;
+       netif_stop_queue(dev);
+       del_timer_sync(&lp->media);
+-      if (link->state & DEV_STALE_CONFIG)
+-              tc574_release(link);
++
+       return 0;
+ }
+--- linux-2.6.0/drivers/net/pcmcia/3c589_cs.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/pcmcia/3c589_cs.c   2003-12-28 23:22:53.000000000 -0800
+@@ -244,7 +244,7 @@ static dev_link_t *tc589_attach(void)
+     client_reg.event_handler = &tc589_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != 0) {
+       cs_error(link->handle, RegisterClient, ret);
+       tc589_detach(link);
+@@ -276,23 +276,17 @@ static void tc589_detach(dev_link_t *lin
+     if (*linkp == NULL)
+       return;
+-    if (link->state & DEV_CONFIG) {
++    if (link->state & DEV_CONFIG)
+       tc589_release(link);
+-      if (link->state & DEV_STALE_CONFIG)
+-          return;
+-    }
+     
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     
+     /* Unlink device structure, free bits */
+     *linkp = link->next;
+-    if (link->dev) {
++    if (link->dev)
+       unregister_netdev(dev);
+-      free_netdev(dev);
+-    } else
+-        kfree(dev);
+-    
++    free_netdev(dev);
+ } /* tc589_detach */
+ /*======================================================================
+@@ -303,8 +297,8 @@ static void tc589_detach(dev_link_t *lin
+     
+ ======================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void tc589_config(dev_link_t *link)
+ {
+@@ -323,20 +317,20 @@ static void tc589_config(dev_link_t *lin
+     phys_addr = (u16 *)dev->dev_addr;
+     tuple.Attributes = 0;
+     tuple.DesiredTuple = CISTPL_CONFIG;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     tuple.TupleData = (cisdata_t *)buf;
+     tuple.TupleDataMax = sizeof(buf);
+     tuple.TupleOffset = 0;
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     link->conf.Present = parse.config.rmask[0];
+     
+     /* Is this a 3c562? */
+     tuple.DesiredTuple = CISTPL_MANFID;
+     tuple.Attributes = TUPLE_RETURN_COMMON;
+-    if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) &&
+-      (CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS)) {
++    if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) &&
++      (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) {
+       if (le16_to_cpu(buf[0]) != MANFID_3COM)
+           printk(KERN_INFO "3c589_cs: hmmm, is this really a "
+                  "3Com card??\n");
+@@ -351,15 +345,15 @@ static void tc589_config(dev_link_t *lin
+     for (i = j = 0; j < 0x400; j += 0x10) {
+       if (multi && (j & 0x80)) continue;
+       link->io.BasePort1 = j ^ 0x300;
+-      i = CardServices(RequestIO, link->handle, &link->io);
++      i = pcmcia_request_io(link->handle, &link->io);
+       if (i == CS_SUCCESS) break;
+     }
+     if (i != CS_SUCCESS) {
+       cs_error(link->handle, RequestIO, i);
+       goto failed;
+     }
+-    CS_CHECK(RequestIRQ, link->handle, &link->irq);
+-    CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+       
+     dev->irq = link->irq.AssignedIRQ;
+     dev->base_addr = link->io.BasePort1;
+@@ -374,8 +368,8 @@ static void tc589_config(dev_link_t *lin
+     /* The 3c589 has an extra EEPROM for configuration info, including
+        the hardware address.  The 3c562 puts the address in the CIS. */
+     tuple.DesiredTuple = 0x88;
+-    if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) {
+-      CardServices(GetTupleData, handle, &tuple);
++    if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) {
++      pcmcia_get_tuple_data(handle, &tuple);
+       for (i = 0; i < 3; i++)
+           phys_addr[i] = htons(buf[i]);
+     } else {
+@@ -433,21 +427,11 @@ static void tc589_release(dev_link_t *li
+ {
+     DEBUG(0, "3c589_release(0x%p)\n", link);
+     
+-    if (link->open) {
+-      DEBUG(1, "3c589_cs: release postponed, '%s' still open\n",
+-            link->dev->dev_name);
+-      link->state |= DEV_STALE_CONFIG;
+-      return;
+-    }
+-    
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     
+     link->state &= ~DEV_CONFIG;
+-
+-    if (link->state & DEV_STALE_CONFIG)
+-          tc589_detach(link);
+ }
+ /*======================================================================
+@@ -486,7 +470,7 @@ static int tc589_event(event_t event, in
+       if (link->state & DEV_CONFIG) {
+           if (link->open)
+               netif_device_detach(dev);
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       }
+       break;
+     case CS_EVENT_PM_RESUME:
+@@ -494,7 +478,7 @@ static int tc589_event(event_t event, in
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG) {
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+           if (link->open) {
+               tc589_reset(dev);
+               netif_device_attach(dev);
+@@ -1076,8 +1060,6 @@ static int el3_close(struct net_device *
+     link->open--;
+     netif_stop_queue(dev);
+     del_timer_sync(&lp->media);
+-    if (link->state & DEV_STALE_CONFIG)
+-           tc589_release(link);
+     
+     return 0;
+ }
+--- linux-2.6.0/drivers/net/pcmcia/axnet_cs.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/pcmcia/axnet_cs.c   2003-12-28 23:22:53.000000000 -0800
+@@ -119,7 +119,7 @@ static void axnet_detach(dev_link_t *);
+ static dev_info_t dev_info = "axnet_cs";
+ static dev_link_t *dev_list;
+-static int axdev_init(struct net_device *dev);
++static void axdev_setup(struct net_device *dev);
+ static void AX88190_init(struct net_device *dev, int startp);
+ static int ax_open(struct net_device *dev);
+ static int ax_close(struct net_device *dev);
+@@ -128,7 +128,6 @@ static irqreturn_t ax_interrupt(int irq,
+ /*====================================================================*/
+ typedef struct axnet_dev_t {
+-    struct net_device dev;    /* so &dev == &axnet_dev_t */
+     dev_link_t                link;
+     dev_node_t                node;
+     caddr_t           base;
+@@ -140,16 +139,10 @@ typedef struct axnet_dev_t {
+     int                       flags;
+ } axnet_dev_t;
+-/*======================================================================
+-
+-    We never need to do anything when a axnet device is "initialized"
+-    by the net software, because we only register already-found cards.
+-
+-======================================================================*/
+-
+-static int axnet_init(struct net_device *dev)
++static inline axnet_dev_t *PRIV(struct net_device *dev)
+ {
+-    return 0;
++      void *p = (char *)netdev_priv(dev) + sizeof(struct ei_device);
++      return p;
+ }
+ /*======================================================================
+@@ -170,12 +163,15 @@ static dev_link_t *axnet_attach(void)
+     DEBUG(0, "axnet_attach()\n");
+-    /* Create new ethernet device */
+-    info = kmalloc(sizeof(*info), GFP_KERNEL);
+-    if (!info) return NULL;
+-    memset(info, 0, sizeof(*info));
+-    link = &info->link; dev = &info->dev;
+-    link->priv = info;
++    dev = alloc_netdev(sizeof(struct ei_device) + sizeof(axnet_dev_t),
++                      "eth%d", axdev_setup);
++
++    if (!dev)
++      return NULL;
++
++    info = PRIV(dev);
++    link = &info->link;
++    link->priv = dev;
+     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+     link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
+     if (irq_list[0] == -1)
+@@ -186,8 +182,6 @@ static dev_link_t *axnet_attach(void)
+     link->conf.Attributes = CONF_ENABLE_IRQ;
+     link->conf.IntType = INT_MEMORY_AND_IO;
+-    axdev_init(dev);
+-    dev->init = &axnet_init;
+     dev->open = &axnet_open;
+     dev->stop = &axnet_close;
+     dev->do_ioctl = &axnet_ioctl;
+@@ -205,7 +199,7 @@ static dev_link_t *axnet_attach(void)
+     client_reg.event_handler = &axnet_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != CS_SUCCESS) {
+       cs_error(link->handle, RegisterClient, ret);
+       axnet_detach(link);
+@@ -226,7 +220,7 @@ static dev_link_t *axnet_attach(void)
+ static void axnet_detach(dev_link_t *link)
+ {
+-    axnet_dev_t *info = link->priv;
++    struct net_device *dev = link->priv;
+     dev_link_t **linkp;
+     DEBUG(0, "axnet_detach(0x%p)\n", link);
+@@ -237,23 +231,17 @@ static void axnet_detach(dev_link_t *lin
+     if (*linkp == NULL)
+       return;
+-    if (link->state & DEV_CONFIG) {
++    if (link->state & DEV_CONFIG)
+       axnet_release(link);
+-      if (link->state & DEV_STALE_CONFIG)
+-          return;
+-    }
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     /* Unlink device structure, free bits */
+     *linkp = link->next;
+-    if (link->dev) {
+-      unregister_netdev(&info->dev);
+-      free_netdev(&info->dev);
+-    } else
+-      kfree(info);
+-
++    if (link->dev)
++      unregister_netdev(dev);
++    free_netdev(dev);
+ } /* axnet_detach */
+ /*======================================================================
+@@ -313,11 +301,8 @@ static int get_prom(dev_link_t *link)
+ ======================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static int try_io_port(dev_link_t *link)
+ {
+@@ -340,20 +325,20 @@ static int try_io_port(dev_link_t *link)
+       for (j = 0; j < 0x400; j += 0x20) {
+           link->io.BasePort1 = j ^ 0x300;
+           link->io.BasePort2 = (j ^ 0x300) + 0x10;
+-          ret = CardServices(RequestIO, link->handle, &link->io);
++          ret = pcmcia_request_io(link->handle, &link->io);
+           if (ret == CS_SUCCESS) return ret;
+       }
+       return ret;
+     } else {
+-      return CardServices(RequestIO, link->handle, &link->io);
++      return pcmcia_request_io(link->handle, &link->io);
+     }
+ }
+ static void axnet_config(dev_link_t *link)
+ {
+     client_handle_t handle = link->handle;
+-    axnet_dev_t *info = link->priv;
+-    struct net_device *dev = &info->dev;
++    struct net_device *dev = link->priv;
++    axnet_dev_t *info = PRIV(dev);
+     tuple_t tuple;
+     cisparse_t parse;
+     int i, j, last_ret, last_fn;
+@@ -367,9 +352,9 @@ static void axnet_config(dev_link_t *lin
+     tuple.TupleDataMax = sizeof(buf);
+     tuple.TupleOffset = 0;
+     tuple.DesiredTuple = CISTPL_CONFIG;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     /* don't trust the CIS on this; Linksys got it wrong */
+     link->conf.Present = 0x63;
+@@ -378,19 +363,19 @@ static void axnet_config(dev_link_t *lin
+     link->state |= DEV_CONFIG;
+     /* Look up current Vcc */
+-    CS_CHECK(GetConfigurationInfo, handle, &conf);
++    CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
+     link->conf.Vcc = conf.Vcc;
+     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+     tuple.Attributes = 0;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     while (last_ret == CS_SUCCESS) {
+       cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+       cistpl_io_t *io = &(parse.cftable_entry.io);
+       
+-      CFG_CHECK(GetTupleData, handle, &tuple);
+-      CFG_CHECK(ParseTuple, handle, &tuple, &parse);
+-      if ((cfg->index == 0) || (cfg->io.nwin == 0))
++      if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++              pcmcia_parse_tuple(handle, &tuple, &parse) != 0 ||
++              cfg->index == 0 || cfg->io.nwin == 0)
+           goto next_entry;
+       
+       link->conf.ConfigIndex = 0x05;
+@@ -411,32 +396,27 @@ static void axnet_config(dev_link_t *lin
+           if (last_ret == CS_SUCCESS) break;
+       }
+     next_entry:
+-      last_ret = CardServices(GetNextTuple, handle, &tuple);
++      last_ret = pcmcia_get_next_tuple(handle, &tuple);
+     }
+     if (last_ret != CS_SUCCESS) {
+       cs_error(handle, RequestIO, last_ret);
+       goto failed;
+     }
+-    CS_CHECK(RequestIRQ, handle, &link->irq);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
+     
+     if (link->io.NumPorts2 == 8) {
+       link->conf.Attributes |= CONF_ENABLE_SPKR;
+       link->conf.Status = CCSR_AUDIO_ENA;
+     }
+     
+-    CS_CHECK(RequestConfiguration, handle, &link->conf);
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
+     dev->irq = link->irq.AssignedIRQ;
+     dev->base_addr = link->io.BasePort1;
+-    if (register_netdev(dev) != 0) {
+-      printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
+-      goto failed;
+-    }
+     if (!get_prom(link)) {
+       printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n");
+       printk(KERN_NOTICE "axnet_cs: use pcnet_cs instead.\n");
+-      unregister_netdev(dev);
+       goto failed;
+     }
+@@ -451,7 +431,6 @@ static void axnet_config(dev_link_t *lin
+     ei_status.block_output = &block_output;
+     strcpy(info->node.dev_name, dev->name);
+-    link->dev = &info->node;
+     if (inb(dev->base_addr + AXNET_TEST) != 0)
+       info->flags |= IS_AX88790;
+@@ -476,7 +455,7 @@ static void axnet_config(dev_link_t *lin
+        Bit 2 of CCSR is active low. */ 
+     if (i == 32) {
+       conf_reg_t reg = { 0, CS_WRITE, CISREG_CCSR, 0x04 };
+-      CardServices(AccessConfigurationRegister, link->handle, &reg);
++      pcmcia_access_configuration_register(link->handle, &reg);
+       for (i = 0; i < 32; i++) {
+           j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
+           if ((j != 0) && (j != 0xffff)) break;
+@@ -490,6 +469,12 @@ static void axnet_config(dev_link_t *lin
+       printk(KERN_NOTICE "  No MII transceivers found!\n");
+     }
++    if (register_netdev(dev) != 0) {
++      printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
++      goto failed;
++    }
++
++    link->dev = &info->node;
+     link->state &= ~DEV_CONFIG_PENDING;
+     return;
+@@ -513,21 +498,11 @@ static void axnet_release(dev_link_t *li
+ {
+     DEBUG(0, "axnet_release(0x%p)\n", link);
+-    if (link->open) {
+-      DEBUG(1, "axnet_cs: release postponed, '%s' still open\n",
+-            ((axnet_dev_t *)(link->priv))->node.dev_name);
+-      link->state |= DEV_STALE_CONFIG;
+-      return;
+-    }
+-
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     link->state &= ~DEV_CONFIG;
+-
+-    if (link->state & DEV_STALE_CONFIG)
+-          axnet_detach(link);
+ }
+ /*======================================================================
+@@ -543,7 +518,7 @@ static int axnet_event(event_t event, in
+                      event_callback_args_t *args)
+ {
+     dev_link_t *link = args->client_data;
+-    axnet_dev_t *info = link->priv;
++    struct net_device *dev = link->priv;
+     DEBUG(2, "axnet_event(0x%06x)\n", event);
+@@ -551,7 +526,7 @@ static int axnet_event(event_t event, in
+     case CS_EVENT_CARD_REMOVAL:
+       link->state &= ~DEV_PRESENT;
+       if (link->state & DEV_CONFIG) {
+-          netif_device_detach(&info->dev);
++          netif_device_detach(dev);
+           axnet_release(link);
+       }
+       break;
+@@ -565,7 +540,7 @@ static int axnet_event(event_t event, in
+     case CS_EVENT_RESET_PHYSICAL:
+       if (link->state & DEV_CONFIG) {
+           if (link->open)
+-              netif_device_detach(&info->dev);
++              netif_device_detach(dev);
+           CardServices(ReleaseConfiguration, link->handle);
+       }
+       break;
+@@ -574,11 +549,11 @@ static int axnet_event(event_t event, in
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG) {
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+           if (link->open) {
+-              axnet_reset_8390(&info->dev);
+-              AX88190_init(&info->dev, 1);
+-              netif_device_attach(&info->dev);
++              axnet_reset_8390(dev);
++              AX88190_init(dev, 1);
++              netif_device_attach(dev);
+           }
+       }
+       break;
+@@ -648,7 +623,7 @@ static void mdio_write(ioaddr_t addr, in
+ static int axnet_open(struct net_device *dev)
+ {
+-    axnet_dev_t *info = (axnet_dev_t *)dev;
++    axnet_dev_t *info = PRIV(dev);
+     dev_link_t *link = &info->link;
+     
+     DEBUG(2, "axnet_open('%s')\n", dev->name);
+@@ -663,7 +638,7 @@ static int axnet_open(struct net_device 
+     info->link_status = 0x00;
+     init_timer(&info->watchdog);
+     info->watchdog.function = &ei_watchdog;
+-    info->watchdog.data = (u_long)info;
++    info->watchdog.data = (u_long)dev;
+     info->watchdog.expires = jiffies + HZ;
+     add_timer(&info->watchdog);
+@@ -674,7 +649,7 @@ static int axnet_open(struct net_device 
+ static int axnet_close(struct net_device *dev)
+ {
+-    axnet_dev_t *info = (axnet_dev_t *)dev;
++    axnet_dev_t *info = PRIV(dev);
+     dev_link_t *link = &info->link;
+     DEBUG(2, "axnet_close('%s')\n", dev->name);
+@@ -685,8 +660,6 @@ static int axnet_close(struct net_device
+     link->open--;
+     netif_stop_queue(dev);
+     del_timer_sync(&info->watchdog);
+-    if (link->state & DEV_STALE_CONFIG)
+-      axnet_release(link);
+     return 0;
+ } /* axnet_close */
+@@ -726,15 +699,15 @@ static void axnet_reset_8390(struct net_
+ static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
+ {
+-    axnet_dev_t *info = dev_id;
+-    info->stale = 0;
++    struct net_device *dev = dev_id;
++    PRIV(dev)->stale = 0;
+     return ax_interrupt(irq, dev_id, regs);
+ }
+ static void ei_watchdog(u_long arg)
+ {
+-    axnet_dev_t *info = (axnet_dev_t *)(arg);
+-    struct net_device *dev = &info->dev;
++    struct net_device *dev = (struct net_device *)(arg);
++    axnet_dev_t *info = PRIV(dev);
+     ioaddr_t nic_base = dev->base_addr;
+     ioaddr_t mii_addr = nic_base + AXNET_MII_EEP;
+     u_short link;
+@@ -804,7 +777,7 @@ static struct ethtool_ops netdev_ethtool
+ static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ {
+-    axnet_dev_t *info = (axnet_dev_t *)dev;
++    axnet_dev_t *info = PRIV(dev);
+     u16 *data = (u16 *)&rq->ifr_data;
+     ioaddr_t mii_addr = dev->base_addr + AXNET_MII_EEP;
+     switch (cmd) {
+@@ -1053,14 +1026,7 @@ static void do_set_multicast_list(struct
+ static int ax_open(struct net_device *dev)
+ {
+       unsigned long flags;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
+-
+-      /* This can't happen unless somebody forgot to call axdev_init(). */
+-      if (ei_local == NULL) 
+-      {
+-              printk(KERN_EMERG "%s: ax_open passed a non-existent device!\n", dev->name);
+-              return -ENXIO;
+-      }
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ #ifdef HAVE_TX_TIMEOUT
+       /* The card I/O part of the driver (e.g. 3c503) can hook a Tx timeout
+@@ -1086,7 +1052,7 @@ static int ax_open(struct net_device *de
+       return 0;
+ }
+-#define dev_lock(dev) (((struct ei_device *)(dev)->priv)->page_lock)
++#define dev_lock(dev) (((struct ei_device *)netdev_priv(dev))->page_lock)
+ /**
+  * ax_close - shut down network device
+@@ -1120,7 +1086,7 @@ int ax_close(struct net_device *dev)
+ void ei_tx_timeout(struct net_device *dev)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       int txsr, isr, tickssofar = jiffies - dev->trans_start;
+       unsigned long flags;
+@@ -1166,7 +1132,7 @@ void ei_tx_timeout(struct net_device *de
+ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       int length, send_length, output_page;
+       unsigned long flags;
+       u8 packet[ETH_ZLEN];
+@@ -1312,7 +1278,7 @@ static irqreturn_t ax_interrupt(int irq,
+       }
+     
+       e8390_base = dev->base_addr;
+-      ei_local = (struct ei_device *) dev->priv;
++      ei_local = (struct ei_device *) netdev_priv(dev);
+       /*
+        *      Protect the irq test too.
+@@ -1424,7 +1390,7 @@ static irqreturn_t ax_interrupt(int irq,
+ static void ei_tx_err(struct net_device *dev)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       unsigned char txsr = inb_p(e8390_base+EN0_TSR);
+       unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
+@@ -1465,7 +1431,7 @@ static void ei_tx_err(struct net_device 
+ static void ei_tx_intr(struct net_device *dev)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       int status = inb(e8390_base + EN0_TSR);
+     
+       /*
+@@ -1546,7 +1512,7 @@ static void ei_tx_intr(struct net_device
+ static void ei_receive(struct net_device *dev)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       unsigned char rxing_page, this_frame, next_frame;
+       unsigned short current_offset;
+       int rx_pkt_count = 0;
+@@ -1666,7 +1632,7 @@ static void ei_rx_overrun(struct net_dev
+       axnet_dev_t *info = (axnet_dev_t *)dev;
+       long e8390_base = dev->base_addr;
+       unsigned char was_txing, must_resend = 0;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+     
+       /*
+        * Record whether a Tx was in progress and then issue the
+@@ -1733,7 +1699,7 @@ static void ei_rx_overrun(struct net_dev
+ static struct net_device_stats *get_stats(struct net_device *dev)
+ {
+       long ioaddr = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       unsigned long flags;
+     
+       /* If the card is stopped, just return the present stats. */
+@@ -1786,39 +1752,30 @@ static void set_multicast_list(struct ne
+ }     
+ /**
+- * axdev_init - init rest of 8390 device struct
++ * axdev_setup - init rest of 8390 device struct
+  * @dev: network device structure to init
+  *
+  * Initialize the rest of the 8390 device structure.  Do NOT __init
+  * this, as it is used by 8390 based modular drivers too.
+  */
+-static int axdev_init(struct net_device *dev)
++static void axdev_setup(struct net_device *dev)
+ {
++      struct ei_device *ei_local;
+       if (ei_debug > 1)
+               printk(version_8390);
+     
+       SET_MODULE_OWNER(dev);
+-      if (dev->priv == NULL) 
+-      {
+-              struct ei_device *ei_local;
+               
+-              dev->priv = kmalloc(sizeof(struct ei_device), GFP_KERNEL);
+-              if (dev->priv == NULL)
+-                      return -ENOMEM;
+-              memset(dev->priv, 0, sizeof(struct ei_device));
+-              ei_local = (struct ei_device *)dev->priv;
+-              spin_lock_init(&ei_local->page_lock);
+-      }
++      ei_local = (struct ei_device *)netdev_priv(dev);
++      spin_lock_init(&ei_local->page_lock);
+     
+       dev->hard_start_xmit = &ei_start_xmit;
+       dev->get_stats  = get_stats;
+       dev->set_multicast_list = &set_multicast_list;
+       ether_setup(dev);
+-        
+-      return 0;
+ }
+ /* This page of functions should be 8390 generic */
+@@ -1834,9 +1791,9 @@ static int axdev_init(struct net_device 
+ static void AX88190_init(struct net_device *dev, int startp)
+ {
+-      axnet_dev_t *info = (axnet_dev_t *)dev;
++      axnet_dev_t *info = PRIV(dev);
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+       int i;
+       int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48;
+     
+@@ -1905,7 +1862,7 @@ static void NS8390_trigger_send(struct n
+                                                               int start_page)
+ {
+       long e8390_base = dev->base_addr;
+-      struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) dev->priv;
++      struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev);
+     
+       if (inb_p(e8390_base) & E8390_TRANS) 
+       {
+--- linux-2.6.0/drivers/net/pcmcia/com20020_cs.c       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/pcmcia/com20020_cs.c        2003-12-28 23:22:53.000000000 -0800
+@@ -145,20 +145,6 @@ typedef struct com20020_dev_t {
+     dev_node_t          node;
+ } com20020_dev_t;
+-static void com20020_setup(struct net_device *dev)
+-{
+-      struct arcnet_local *lp = dev->priv;
+-
+-      lp->timeout = timeout;
+-      lp->backplane = backplane;
+-      lp->clockp = clockp;
+-      lp->clockm = clockm & 3;
+-      lp->hw.owner = THIS_MODULE;
+-
+-      /* fill in our module parameters as defaults */
+-      dev->dev_addr[0] = node;
+-}
+-
+ /*======================================================================
+     com20020_attach() creates an "instance" of the driver, allocating
+@@ -187,14 +173,21 @@ static dev_link_t *com20020_attach(void)
+     if (!info)
+       goto fail_alloc_info;
+-    dev = alloc_netdev(sizeof(struct arcnet_local), "arc%d",
+-                     com20020_setup);
++    dev = alloc_arcdev("");
+     if (!dev)
+       goto fail_alloc_dev;
+     memset(info, 0, sizeof(struct com20020_dev_t));
+     memset(link, 0, sizeof(struct dev_link_t));
+     lp = dev->priv;
++    lp->timeout = timeout;
++    lp->backplane = backplane;
++    lp->clockp = clockp;
++    lp->clockm = clockm & 3;
++    lp->hw.owner = THIS_MODULE;
++
++    /* fill in our module parameters as defaults */
++    dev->dev_addr[0] = node;
+     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+     link->io.NumPorts1 = 16;
+@@ -227,7 +220,7 @@ static dev_link_t *com20020_attach(void)
+     client_reg.event_handler = &com20020_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != 0) {
+         cs_error(link->handle, RegisterClient, ret);
+         com20020_detach(link);
+@@ -270,14 +263,11 @@ static void com20020_detach(dev_link_t *
+     dev = info->dev;
+-    if (link->state & DEV_CONFIG) {
++    if (link->state & DEV_CONFIG)
+         com20020_release(link);
+-        if (link->state & DEV_STALE_CONFIG)
+-            return;
+-    }
+     if (link->handle)
+-        CardServices(DeregisterClient, link->handle);
++        pcmcia_deregister_client(link->handle);
+     /* Unlink device structure, free bits */
+     DEBUG(1,"unlinking...\n");
+@@ -293,6 +283,8 @@ static void com20020_detach(dev_link_t *
+               if (netif_running(dev))
+                   dev->stop(dev);
++
++              unregister_netdev(dev);
+           
+               /*
+                * this is necessary because we register our IRQ separately
+@@ -300,10 +292,7 @@ static void com20020_detach(dev_link_t *
+                */
+               if (dev->irq)
+                   free_irq(dev->irq, dev);
+-              
+               /* ...but I/O ports are done automatically by card services */
+-              
+-              unregister_netdev(dev);
+           }
+           
+           DEBUG(1,"kfree...\n");
+@@ -325,8 +314,8 @@ static void com20020_detach(dev_link_t *
+ ======================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void com20020_config(dev_link_t *link)
+ {
+@@ -353,9 +342,9 @@ static void com20020_config(dev_link_t *
+     tuple.TupleDataMax = 64;
+     tuple.TupleOffset = 0;
+     tuple.DesiredTuple = CISTPL_CONFIG;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     /* Configure card */
+@@ -368,13 +357,13 @@ static void com20020_config(dev_link_t *
+       for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
+       {
+           link->io.BasePort1 = ioaddr;
+-          i = CardServices(RequestIO, link->handle, &link->io);
++          i = pcmcia_request_io(link->handle, &link->io);
+           if (i == CS_SUCCESS)
+               break;
+       }
+     }
+     else
+-      i = CardServices(RequestIO, link->handle, &link->io);
++      i = pcmcia_request_io(link->handle, &link->io);
+     
+     if (i != CS_SUCCESS)
+     {
+@@ -388,7 +377,7 @@ static void com20020_config(dev_link_t *
+     DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n",
+          link->irq.AssignedIRQ,
+          link->irq.IRQInfo1, link->irq.IRQInfo2);
+-    i = CardServices(RequestIRQ, link->handle, &link->irq);
++    i = pcmcia_request_irq(link->handle, &link->irq);
+     if (i != CS_SUCCESS)
+     {
+       DEBUG(1,"arcnet: requestIRQ failed totally!\n");
+@@ -397,7 +386,7 @@ static void com20020_config(dev_link_t *
+     dev->irq = link->irq.AssignedIRQ;
+-    CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+     if (com20020_check(dev))
+     {
+@@ -447,21 +436,11 @@ static void com20020_release(dev_link_t 
+     DEBUG(0, "com20020_release(0x%p)\n", link);
+-    if (link->open) {
+-      DEBUG(1,"postpone...\n");
+-      DEBUG(1, "com20020_cs: release postponed, device stll open\n");
+-        link->state |= DEV_STALE_CONFIG;
+-        return;
+-    }
+-
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
+-
+-    if (link->state & DEV_STALE_CONFIG)
+-          com20020_detach(link);
+ }
+ /*======================================================================
+@@ -502,7 +481,7 @@ static int com20020_event(event_t event,
+             if (link->open) {
+                 netif_device_detach(dev);
+             }
+-            CardServices(ReleaseConfiguration, link->handle);
++            pcmcia_release_configuration(link->handle);
+         }
+         break;
+     case CS_EVENT_PM_RESUME:
+@@ -510,7 +489,7 @@ static int com20020_event(event_t event,
+         /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+         if (link->state & DEV_CONFIG) {
+-            CardServices(RequestConfiguration, link->handle, &link->conf);
++            pcmcia_request_configuration(link->handle, &link->conf);
+             if (link->open) {
+               int ioaddr = dev->base_addr;
+               struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
+--- linux-2.6.0/drivers/net/pcmcia/fmvj18x_cs.c        2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/pcmcia/fmvj18x_cs.c 2003-12-28 23:22:53.000000000 -0800
+@@ -307,7 +307,7 @@ static dev_link_t *fmvj18x_attach(void)
+     client_reg.event_handler = &fmvj18x_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != 0) {
+       cs_error(link->handle, RegisterClient, ret);
+       fmvj18x_detach(link);
+@@ -332,30 +332,24 @@ static void fmvj18x_detach(dev_link_t *l
+     if (*linkp == NULL)
+       return;
+-    if (link->state & DEV_CONFIG) {
++    if (link->state & DEV_CONFIG)
+       fmvj18x_release(link);
+-      if (link->state & DEV_STALE_CONFIG)
+-          return;
+-    }
+     /* Break the link with Card Services */
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     
+     /* Unlink device structure, free pieces */
+     *linkp = link->next;
+-    if (link->dev) {
++    if (link->dev)
+       unregister_netdev(dev);
+-      free_netdev(dev);
+-    } else
+-      kfree(dev);
+-    
++    free_netdev(dev);
+ } /* fmvj18x_detach */
+ /*====================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static int mfc_try_io_port(dev_link_t *link)
+ {
+@@ -369,7 +363,7 @@ static int mfc_try_io_port(dev_link_t *l
+           link->io.NumPorts2 = 0;
+           printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n");
+       }
+-      ret = CardServices(RequestIO, link->handle, &link->io);
++      ret = pcmcia_request_io(link->handle, &link->io);
+       if (ret == CS_SUCCESS) return ret;
+     }
+     return ret;
+@@ -385,7 +379,7 @@ static int ungermann_try_io_port(dev_lin
+     */
+     for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) {
+       link->io.BasePort1 = ioaddr;
+-      ret = CardServices(RequestIO, link->handle, &link->io);
++      ret = pcmcia_request_io(link->handle, &link->io);
+       if (ret == CS_SUCCESS) {
+           /* calculate ConfigIndex value */
+           link->conf.ConfigIndex = 
+@@ -417,12 +411,12 @@ static void fmvj18x_config(dev_link_t *l
+        registers.
+     */
+     tuple.DesiredTuple = CISTPL_CONFIG;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     tuple.TupleData = (u_char *)buf;
+     tuple.TupleDataMax = 64;
+     tuple.TupleOffset = 0;
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     
+     /* Configure card */
+     link->state |= DEV_CONFIG;
+@@ -432,16 +426,16 @@ static void fmvj18x_config(dev_link_t *l
+     tuple.DesiredTuple = CISTPL_FUNCE;
+     tuple.TupleOffset = 0;
+-    if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) {
++    if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) {
+       /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
+       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
+-      CS_CHECK(GetTupleData, handle, &tuple);
+-      CS_CHECK(ParseTuple, handle, &tuple, &parse);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++      CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+       link->conf.ConfigIndex = parse.cftable_entry.index;
+       tuple.DesiredTuple = CISTPL_MANFID;
+-      if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS)
+-          CS_CHECK(GetTupleData, handle, &tuple);
++      if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS)
++          CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+       else
+           buf[0] = 0xffff;
+       switch (le16_to_cpu(buf[0])) {
+@@ -449,7 +443,7 @@ static void fmvj18x_config(dev_link_t *l
+           cardtype = TDK;
+           if (le16_to_cpu(buf[1]) == PRODID_TDK_CF010) {
+               cs_status_t status;
+-              CardServices(GetStatus, handle, &status);
++              pcmcia_get_status(handle, &status);
+               if (status.CardState & CS_EVENT_3VCARD)
+                   link->conf.Vcc = 33; /* inserted in 3.3V slot */
+           } else if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410) {
+@@ -478,8 +472,8 @@ static void fmvj18x_config(dev_link_t *l
+     } else {
+       /* old type card */
+       tuple.DesiredTuple = CISTPL_MANFID;
+-      if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS)
+-          CS_CHECK(GetTupleData, handle, &tuple);
++      if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS)
++          CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+       else
+           buf[0] = 0xffff;
+       switch (le16_to_cpu(buf[0])) {
+@@ -510,10 +504,10 @@ static void fmvj18x_config(dev_link_t *l
+       ret = ungermann_try_io_port(link);
+       if (ret != CS_SUCCESS) goto cs_failed;
+     } else { 
+-      CS_CHECK(RequestIO, link->handle, &link->io);
++      CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
+     }
+-    CS_CHECK(RequestIRQ, link->handle, &link->irq);
+-    CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+     dev->irq = link->irq.AssignedIRQ;
+     dev->base_addr = link->io.BasePort1;
+     if (register_netdev(dev) != 0) {
+@@ -546,17 +540,17 @@ static void fmvj18x_config(dev_link_t *l
+     case CONTEC:
+       tuple.DesiredTuple = CISTPL_FUNCE;
+       tuple.TupleOffset = 0;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       tuple.TupleOffset = 0;
+-      CS_CHECK(GetTupleData, handle, &tuple);
++      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+       if (cardtype == MBH10304) {
+           /* MBH10304's CIS_FUNCE is corrupted */
+           node_id = &(tuple.TupleData[5]);
+           card_name = "FMV-J182";
+       } else {
+           while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
+-              CS_CHECK(GetNextTuple, handle, &tuple) ;
+-              CS_CHECK(GetTupleData, handle, &tuple) ;
++              CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
++              CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+           }
+           node_id = &(tuple.TupleData[2]);
+           if( cardtype == TDK ) {
+@@ -633,8 +627,7 @@ static int fmvj18x_get_hwinfo(dev_link_t
+     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
+     req.Base = 0; req.Size = 0;
+     req.AccessSpeed = 0;
+-    link->win = (window_handle_t)link->handle;
+-    i = CardServices(RequestWindow, &link->win, &req);
++    i = pcmcia_request_window(&link->handle, &req, &link->win);
+     if (i != CS_SUCCESS) {
+       cs_error(link->handle, RequestWindow, i);
+       return -1;
+@@ -643,7 +636,7 @@ static int fmvj18x_get_hwinfo(dev_link_t
+     base = ioremap(req.Base, req.Size);
+     mem.Page = 0;
+     mem.CardOffset = 0;
+-    CardServices(MapMemPage, link->win, &mem);
++    pcmcia_map_mem_page(link->win, &mem);
+     /*
+      *  MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
+@@ -668,7 +661,7 @@ static int fmvj18x_get_hwinfo(dev_link_t
+     }
+     iounmap(base);
+-    j = CardServices(ReleaseWindow, link->win);
++    j = pcmcia_release_window(link->win);
+     if (j != CS_SUCCESS)
+       cs_error(link->handle, ReleaseWindow, j);
+     return (i != 0x200) ? 0 : -1;
+@@ -689,8 +682,7 @@ static int fmvj18x_setup_mfc(dev_link_t 
+     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
+     req.Base = 0; req.Size = 0;
+     req.AccessSpeed = 0;
+-    link->win = (window_handle_t)link->handle;
+-    i = CardServices(RequestWindow, &link->win, &req);
++    i = pcmcia_request_window(&link->handle, &req, &link->win);
+     if (i != CS_SUCCESS) {
+       cs_error(link->handle, RequestWindow, i);
+       return -1;
+@@ -699,7 +691,7 @@ static int fmvj18x_setup_mfc(dev_link_t 
+     base = ioremap(req.Base, req.Size);
+     mem.Page = 0;
+     mem.CardOffset = 0;
+-    CardServices(MapMemPage, link->win, &mem);
++    pcmcia_map_mem_page(link->win, &mem);
+     ioaddr = dev->base_addr;
+     writeb(0x47, base+0x800); /* Config Option Register of LAN */
+@@ -712,7 +704,7 @@ static int fmvj18x_setup_mfc(dev_link_t 
+     writeb(0x8, base+0x822);  /* Config and Status Register */
+     iounmap(base);
+-    j = CardServices(ReleaseWindow, link->win);
++    j = pcmcia_release_window(link->win);
+     if (j != CS_SUCCESS)
+       cs_error(link->handle, ReleaseWindow, j);
+     return 0;
+@@ -725,27 +717,13 @@ static void fmvj18x_release(dev_link_t *
+     DEBUG(0, "fmvj18x_release(0x%p)\n", link);
+-    /*
+-       If the device is currently in use, we won't release until it
+-       is actually closed.
+-    */
+-    if (link->open) {
+-      DEBUG(1, "fmvj18x_cs: release postponed, '%s' "
+-            "still open\n", link->dev->dev_name);
+-      link->state |= DEV_STALE_CONFIG;
+-      return;
+-    }
+-
+     /* Don't bother checking to see if these succeed or not */
+-    CardServices(ReleaseWindow, link->win);
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_window(link->win);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     
+     link->state &= ~DEV_CONFIG;
+-
+-    if (link->state & DEV_STALE_CONFIG)
+-          fmvj18x_detach(link);
+ }
+ /*====================================================================*/
+@@ -777,7 +755,7 @@ static int fmvj18x_event(event_t event, 
+       if (link->state & DEV_CONFIG) {
+           if (link->open)
+               netif_device_detach(dev);
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       }
+       break;
+     case CS_EVENT_PM_RESUME:
+@@ -785,7 +763,7 @@ static int fmvj18x_event(event_t event, 
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG) {
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+           if (link->open) {
+               fjn_reset(dev);
+               netif_device_attach(dev);
+@@ -1253,8 +1231,6 @@ static int fjn_close(struct net_device *
+       outb(INTR_OFF, ioaddr + LAN_CTRL);
+     link->open--;
+-    if (link->state & DEV_STALE_CONFIG)
+-          fmvj18x_release(link);
+     return 0;
+ } /* fjn_close */
+--- linux-2.6.0/drivers/net/pcmcia/ibmtr_cs.c  2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/pcmcia/ibmtr_cs.c   2003-12-28 23:22:53.000000000 -0800
+@@ -125,8 +125,7 @@ static void ibmtr_detach(dev_link_t *);
+ static dev_link_t *dev_list;
+-extern int ibmtr_probe(struct net_device *dev);
+-extern int trdev_init(struct net_device *dev);
++extern int ibmtr_probe_card(struct net_device *dev);
+ extern irqreturn_t tok_interrupt (int irq, void *dev_id, struct pt_regs *regs);
+ /*====================================================================*/
+@@ -199,7 +198,6 @@ static dev_link_t *ibmtr_attach(void)
+     link->irq.Instance = info->dev = dev;
+     
+-    dev->init = &ibmtr_probe;
+     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+     /* Register with Card Services */
+@@ -214,7 +212,7 @@ static dev_link_t *ibmtr_attach(void)
+     client_reg.event_handler = &ibmtr_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != 0) {
+         cs_error(link->handle, RegisterClient, ret);
+       goto out_detach;
+@@ -253,22 +251,22 @@ static void ibmtr_detach(dev_link_t *lin
+         return;
+     dev = info->dev;
++
++    if (link->dev)
++      unregister_netdev(dev);
++
+     {
+       struct tok_info *ti = (struct tok_info *)dev->priv;
+       del_timer_sync(&(ti->tr_timer));
+     }
+-    if (link->state & DEV_CONFIG) {
++    if (link->state & DEV_CONFIG)
+         ibmtr_release(link);
+-        if (link->state & DEV_STALE_CONFIG)
+-            return;
+-    }
+     if (link->handle)
+-        CardServices(DeregisterClient, link->handle);
++        pcmcia_deregister_client(link->handle);
+     /* Unlink device structure, free bits */
+     *linkp = link->next;
+-    unregister_netdev(dev);
+     free_netdev(dev);
+     kfree(info); 
+ } /* ibmtr_detach */
+@@ -281,8 +279,8 @@ static void ibmtr_detach(dev_link_t *lin
+ ======================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void ibmtr_config(dev_link_t *link)
+ {
+@@ -304,9 +302,9 @@ static void ibmtr_config(dev_link_t *lin
+     tuple.TupleDataMax = 64;
+     tuple.TupleOffset = 0;
+     tuple.DesiredTuple = CISTPL_CONFIG;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     /* Configure card */
+@@ -318,18 +316,18 @@ static void ibmtr_config(dev_link_t *lin
+     /* Try PRIMARY card at 0xA20-0xA23 */
+     link->io.BasePort1 = 0xA20;
+-    i = CardServices(RequestIO, link->handle, &link->io);
++    i = pcmcia_request_io(link->handle, &link->io);
+     if (i == CS_SUCCESS) {
+       memcpy(info->node.dev_name, "tr0\0", 4);
+     } else {
+       /* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */
+       link->io.BasePort1 = 0xA24;
+-      CS_CHECK(RequestIO, link->handle, &link->io);
++      CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
+       memcpy(info->node.dev_name, "tr1\0", 4);
+     }
+     dev->base_addr = link->io.BasePort1;
+-    CS_CHECK(RequestIRQ, link->handle, &link->irq);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+     dev->irq = link->irq.AssignedIRQ;
+     ti->irq = link->irq.AssignedIRQ;
+     ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
+@@ -340,12 +338,11 @@ static void ibmtr_config(dev_link_t *lin
+     req.Base = 0; 
+     req.Size = 0x2000;
+     req.AccessSpeed = 250;
+-    link->win = (window_handle_t)link->handle;
+-    CS_CHECK(RequestWindow, &link->win, &req);
++    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
+     mem.CardOffset = mmiobase;
+     mem.Page = 0;
+-    CS_CHECK(MapMemPage, link->win, &mem);
++    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+     ti->mmio = ioremap(req.Base, req.Size);
+     /* Allocate the SRAM memory window */
+@@ -354,24 +351,23 @@ static void ibmtr_config(dev_link_t *lin
+     req.Base = 0;
+     req.Size = sramsize * 1024;
+     req.AccessSpeed = 250;
+-    info->sram_win_handle = (window_handle_t)link->handle;
+-    CS_CHECK(RequestWindow, &info->sram_win_handle, &req);
++    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &info->sram_win_handle));
+     mem.CardOffset = srambase;
+     mem.Page = 0;
+-    CS_CHECK(MapMemPage, info->sram_win_handle, &mem);
++    CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
+     ti->sram_base = mem.CardOffset >> 12;
+     ti->sram_virt = (u_long)ioremap(req.Base, req.Size);
+-    CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+     /*  Set up the Token-Ring Controller Configuration Register and
+         turn on the card.  Check the "Local Area Network Credit Card
+         Adapters Technical Reference"  SC30-3585 for this info.  */
+     ibmtr_hw_setup(dev, mmiobase);
+-    i = register_netdev(dev);
++    i = ibmtr_probe_card(dev);
+     
+     if (i != 0) {
+       printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
+@@ -412,27 +408,17 @@ static void ibmtr_release(dev_link_t *li
+     DEBUG(0, "ibmtr_release(0x%p)\n", link);
+-    if (link->open) {
+-      DEBUG(1, "ibmtr_cs: release postponed, '%s' "
+-            "still open\n", info->node.dev_name);
+-        link->state |= DEV_STALE_CONFIG;
+-        return;
+-    }
+-
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     if (link->win) {
+       struct tok_info *ti = dev->priv;
+       iounmap((void *)ti->mmio);
+-      CardServices(ReleaseWindow, link->win);
+-      CardServices(ReleaseWindow, info->sram_win_handle);
++      pcmcia_release_window(link->win);
++      pcmcia_release_window(info->sram_win_handle);
+     }
+     link->state &= ~DEV_CONFIG;
+-
+-    if (link->state & DEV_STALE_CONFIG)
+-          ibmtr_detach(link);
+ }
+ /*======================================================================
+@@ -474,7 +460,7 @@ static int ibmtr_event(event_t event, in
+         if (link->state & DEV_CONFIG) {
+             if (link->open)
+               netif_device_detach(dev);
+-            CardServices(ReleaseConfiguration, link->handle);
++            pcmcia_release_configuration(link->handle);
+         }
+         break;
+     case CS_EVENT_PM_RESUME:
+@@ -482,9 +468,9 @@ static int ibmtr_event(event_t event, in
+         /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+         if (link->state & DEV_CONFIG) {
+-            CardServices(RequestConfiguration, link->handle, &link->conf);
++            pcmcia_request_configuration(link->handle, &link->conf);
+             if (link->open) {
+-              (dev->init)(dev);
++              ibmtr_probe(dev);       /* really? */
+               netif_device_attach(dev);
+             }
+         }
+--- linux-2.6.0/drivers/net/pcmcia/nmclan_cs.c 2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/pcmcia/nmclan_cs.c  2003-12-28 23:22:53.000000000 -0800
+@@ -520,7 +520,7 @@ static dev_link_t *nmclan_attach(void)
+     client_reg.event_handler = &nmclan_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != 0) {
+       cs_error(link->handle, RegisterClient, ret);
+       nmclan_detach(link);
+@@ -551,23 +551,17 @@ static void nmclan_detach(dev_link_t *li
+     if (*linkp == NULL)
+       return;
+-    if (link->state & DEV_CONFIG) {
++    if (link->state & DEV_CONFIG)
+       nmclan_release(link);
+-      if (link->state & DEV_STALE_CONFIG)
+-          return;
+-    }
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     /* Unlink device structure, free bits */
+     *linkp = link->next;
+-    if (link->dev) {
++    if (link->dev)
+       unregister_netdev(dev);
+-      free_netdev(dev);
+-    } else
+-      kfree(dev);
+-
++    free_netdev(dev);
+ } /* nmclan_detach */
+ /* ----------------------------------------------------------------------------
+@@ -706,8 +700,8 @@ nmclan_config
+       ethernet device available to the system.
+ ---------------------------------------------------------------------------- */
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void nmclan_config(dev_link_t *link)
+ {
+@@ -727,17 +721,17 @@ static void nmclan_config(dev_link_t *li
+   tuple.TupleDataMax = 64;
+   tuple.TupleOffset = 0;
+   tuple.DesiredTuple = CISTPL_CONFIG;
+-  CS_CHECK(GetFirstTuple, handle, &tuple);
+-  CS_CHECK(GetTupleData, handle, &tuple);
+-  CS_CHECK(ParseTuple, handle, &tuple, &parse);
++  CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++  CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++  CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+   link->conf.ConfigBase = parse.config.base;
+   /* Configure card */
+   link->state |= DEV_CONFIG;
+-  CS_CHECK(RequestIO, handle, &link->io);
+-  CS_CHECK(RequestIRQ, handle, &link->irq);
+-  CS_CHECK(RequestConfiguration, handle, &link->conf);
++  CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io));
++  CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
++  CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
+   dev->irq = link->irq.AssignedIRQ;
+   dev->base_addr = link->io.BasePort1;
+   i = register_netdev(dev);
+@@ -753,8 +747,8 @@ static void nmclan_config(dev_link_t *li
+   tuple.TupleData = buf;
+   tuple.TupleDataMax = 64;
+   tuple.TupleOffset = 0;
+-  CS_CHECK(GetFirstTuple, handle, &tuple);
+-  CS_CHECK(GetTupleData, handle, &tuple);
++  CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++  CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+   memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
+   /* Verify configuration by reading the MACE ID. */
+@@ -812,21 +806,11 @@ static void nmclan_release(dev_link_t *l
+   DEBUG(0, "nmclan_release(0x%p)\n", link);
+-  if (link->open) {
+-    DEBUG(1, "nmclan_cs: release postponed, '%s' "
+-        "still open\n", link->dev->dev_name);
+-    link->state |= DEV_STALE_CONFIG;
+-    return;
+-  }
+-
+-  CardServices(ReleaseConfiguration, link->handle);
+-  CardServices(ReleaseIO, link->handle, &link->io);
+-  CardServices(ReleaseIRQ, link->handle, &link->irq);
++  pcmcia_release_configuration(link->handle);
++  pcmcia_release_io(link->handle, &link->io);
++  pcmcia_release_irq(link->handle, &link->irq);
+   link->state &= ~DEV_CONFIG;
+-
+-  if (link->state & DEV_STALE_CONFIG)
+-        nmclan_detach(link);
+ }
+ /* ----------------------------------------------------------------------------
+@@ -863,7 +847,7 @@ static int nmclan_event(event_t event, i
+       if (link->state & DEV_CONFIG) {
+       if (link->open)
+         netif_device_detach(dev);
+-      CardServices(ReleaseConfiguration, link->handle);
++      pcmcia_release_configuration(link->handle);
+       }
+       break;
+     case CS_EVENT_PM_RESUME:
+@@ -871,7 +855,7 @@ static int nmclan_event(event_t event, i
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG) {
+-      CardServices(RequestConfiguration, link->handle, &link->conf);
++      pcmcia_request_configuration(link->handle, &link->conf);
+       if (link->open) {
+         nmclan_reset(dev);
+         netif_device_attach(dev);
+@@ -903,7 +887,7 @@ static void nmclan_reset(struct net_devi
+   reg.Action = CS_READ;
+   reg.Offset = CISREG_COR;
+   reg.Value = 0;
+-  CardServices(AccessConfigurationRegister, link->handle, &reg);
++  pcmcia_access_configuration_register(link->handle, &reg);
+   OrigCorValue = reg.Value;
+   /* Reset Xilinx */
+@@ -912,12 +896,12 @@ static void nmclan_reset(struct net_devi
+   DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
+       OrigCorValue);
+   reg.Value = COR_SOFT_RESET;
+-  CardServices(AccessConfigurationRegister, link->handle, &reg);
++  pcmcia_access_configuration_register(link->handle, &reg);
+   /* Need to wait for 20 ms for PCMCIA to finish reset. */
+   /* Restore original COR configuration index */
+   reg.Value = COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK);
+-  CardServices(AccessConfigurationRegister, link->handle, &reg);
++  pcmcia_access_configuration_register(link->handle, &reg);
+   /* Xilinx is now completely reset along with the MACE chip. */
+   lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
+@@ -993,8 +977,6 @@ static int mace_close(struct net_device 
+   link->open--;
+   netif_stop_queue(dev);
+-  if (link->state & DEV_STALE_CONFIG)
+-        nmclan_release(link);
+   return 0;
+ } /* mace_close */
+@@ -1046,7 +1028,7 @@ static void mace_tx_timeout(struct net_d
+   printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name);
+ #if RESET_ON_TIMEOUT
+   printk("resetting card\n");
+-  CardServices(ResetCard, link->handle);
++  pcmcia_reset_card(link->handle, NULL);
+ #else /* #if RESET_ON_TIMEOUT */
+   printk("NOT resetting card\n");
+ #endif /* #if RESET_ON_TIMEOUT */
+--- linux-2.6.0/drivers/net/pcmcia/pcnet_cs.c  2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/pcmcia/pcnet_cs.c   2003-12-28 23:22:53.000000000 -0800
+@@ -11,7 +11,7 @@
+     Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net
+-    pcnet_cs.c 1.149 2002/06/29 06:27:37
++    pcnet_cs.c 1.153 2003/11/09 18:53:09
+     
+     The network driver code is based on Donald Becker's NE2000 code:
+@@ -74,7 +74,7 @@ static int pc_debug = PCMCIA_DEBUG;
+ MODULE_PARM(pc_debug, "i");
+ #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+ static char *version =
+-"pcnet_cs.c 1.149 2002/06/29 06:27:37 (David Hinds)";
++"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)";
+ #else
+ #define DEBUG(n, args...)
+ #endif
+@@ -224,7 +224,6 @@ static hw_info_t dl10019_info = { 0, 0, 
+ static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII };
+ typedef struct pcnet_dev_t {
+-    struct net_device dev;    /* so &dev == &pcnet_dev_t */
+     dev_link_t                link;
+     dev_node_t                node;
+     u_int             flags;
+@@ -237,16 +236,10 @@ typedef struct pcnet_dev_t {
+     u_long            mii_reset;
+ } pcnet_dev_t;
+-/*======================================================================
+-
+-    We never need to do anything when a pcnet device is "initialized"
+-    by the net software, because we only register already-found cards.
+-
+-======================================================================*/
+-
+-static int pcnet_init(struct net_device *dev)
++static inline pcnet_dev_t *PRIV(struct net_device *dev)
+ {
+-    return 0;
++      char *p = netdev_priv(dev);
++      return (pcnet_dev_t *)(p + sizeof(struct ei_device));
+ }
+ /*======================================================================
+@@ -268,11 +261,11 @@ static dev_link_t *pcnet_attach(void)
+     DEBUG(0, "pcnet_attach()\n");
+     /* Create new ethernet device */
+-    info = kmalloc(sizeof(*info), GFP_KERNEL);
+-    if (!info) return NULL;
+-    memset(info, 0, sizeof(*info));
+-    link = &info->link; dev = &info->dev;
+-    link->priv = info;
++    dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
++    if (!dev) return NULL;
++    info = PRIV(dev);
++    link = &info->link;
++    link->priv = dev;
+     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+     link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
+@@ -284,9 +277,7 @@ static dev_link_t *pcnet_attach(void)
+     link->conf.Attributes = CONF_ENABLE_IRQ;
+     link->conf.IntType = INT_MEMORY_AND_IO;
+-    ethdev_init(dev);
+     SET_MODULE_OWNER(dev);
+-    dev->init = &pcnet_init;
+     dev->open = &pcnet_open;
+     dev->stop = &pcnet_close;
+     dev->set_config = &set_config;
+@@ -303,7 +294,7 @@ static dev_link_t *pcnet_attach(void)
+     client_reg.event_handler = &pcnet_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != CS_SUCCESS) {
+       cs_error(link->handle, RegisterClient, ret);
+       pcnet_detach(link);
+@@ -324,7 +315,7 @@ static dev_link_t *pcnet_attach(void)
+ static void pcnet_detach(dev_link_t *link)
+ {
+-    pcnet_dev_t *info = link->priv;
++    struct net_device *dev = link->priv;
+     dev_link_t **linkp;
+     DEBUG(0, "pcnet_detach(0x%p)\n", link);
+@@ -335,23 +326,17 @@ static void pcnet_detach(dev_link_t *lin
+     if (*linkp == NULL)
+       return;
+-    if (link->state & DEV_CONFIG) {
++    if (link->state & DEV_CONFIG)
+       pcnet_release(link);
+-      if (link->state & DEV_STALE_CONFIG)
+-          return;
+-    }
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     /* Unlink device structure, free bits */
+     *linkp = link->next;
+-    if (link->dev) {
+-      unregister_netdev(&info->dev);
+-      free_netdev(&info->dev);
+-    } else
+-       kfree(info);
+-
++    if (link->dev)
++      unregister_netdev(dev);
++    free_netdev(dev);
+ } /* pcnet_detach */
+ /*======================================================================
+@@ -373,8 +358,7 @@ static hw_info_t *get_hwinfo(dev_link_t 
+     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
+     req.Base = 0; req.Size = 0;
+     req.AccessSpeed = 0;
+-    link->win = (window_handle_t)link->handle;
+-    i = CardServices(RequestWindow, &link->win, &req);
++    i = pcmcia_request_window(&link->handle, &req, &link->win);
+     if (i != CS_SUCCESS) {
+       cs_error(link->handle, RequestWindow, i);
+       return NULL;
+@@ -384,7 +368,7 @@ static hw_info_t *get_hwinfo(dev_link_t 
+     mem.Page = 0;
+     for (i = 0; i < NR_INFO; i++) {
+       mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
+-      CardServices(MapMemPage, link->win, &mem);
++      pcmcia_map_mem_page(link->win, &mem);
+       base = &virt[hw_info[i].offset & (req.Size-1)];
+       if ((readb(base+0) == hw_info[i].a0) &&
+           (readb(base+2) == hw_info[i].a1) &&
+@@ -397,7 +381,7 @@ static hw_info_t *get_hwinfo(dev_link_t 
+     }
+     
+     iounmap(virt);
+-    j = CardServices(ReleaseWindow, link->win);
++    j = pcmcia_release_window(link->win);
+     if (j != CS_SUCCESS)
+       cs_error(link->handle, ReleaseWindow, j);
+     return (i < NR_INFO) ? hw_info+i : NULL;
+@@ -544,11 +528,8 @@ static hw_info_t *get_hwired(dev_link_t 
+ ======================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static int try_io_port(dev_link_t *link)
+ {
+@@ -571,20 +552,20 @@ static int try_io_port(dev_link_t *link)
+       for (j = 0; j < 0x400; j += 0x20) {
+           link->io.BasePort1 = j ^ 0x300;
+           link->io.BasePort2 = (j ^ 0x300) + 0x10;
+-          ret = CardServices(RequestIO, link->handle, &link->io);
++          ret = pcmcia_request_io(link->handle, &link->io);
+           if (ret == CS_SUCCESS) return ret;
+       }
+       return ret;
+     } else {
+-      return CardServices(RequestIO, link->handle, &link->io);
++      return pcmcia_request_io(link->handle, &link->io);
+     }
+ }
+ static void pcnet_config(dev_link_t *link)
+ {
+     client_handle_t handle = link->handle;
+-    pcnet_dev_t *info = link->priv;
+-    struct net_device *dev = &info->dev;
++    struct net_device *dev = link->priv;
++    pcnet_dev_t *info = PRIV(dev);
+     tuple_t tuple;
+     cisparse_t parse;
+     int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
+@@ -600,9 +581,9 @@ static void pcnet_config(dev_link_t *lin
+     tuple.TupleDataMax = sizeof(buf);
+     tuple.TupleOffset = 0;
+     tuple.DesiredTuple = CISTPL_CONFIG;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     link->conf.Present = parse.config.rmask[0];
+@@ -610,28 +591,28 @@ static void pcnet_config(dev_link_t *lin
+     link->state |= DEV_CONFIG;
+     /* Look up current Vcc */
+-    CS_CHECK(GetConfigurationInfo, handle, &conf);
++    CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
+     link->conf.Vcc = conf.Vcc;
+     tuple.DesiredTuple = CISTPL_MANFID;
+     tuple.Attributes = TUPLE_RETURN_COMMON;
+-    if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) &&
+-      (CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS)) {
++    if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) &&
++      (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) {
+       manfid = le16_to_cpu(buf[0]);
+       prodid = le16_to_cpu(buf[1]);
+     }
+     
+     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+     tuple.Attributes = 0;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     while (last_ret == CS_SUCCESS) {
+       cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+       cistpl_io_t *io = &(parse.cftable_entry.io);
+       
+-      CFG_CHECK(GetTupleData, handle, &tuple);
+-      CFG_CHECK(ParseTuple, handle, &tuple, &parse);
+-      if ((cfg->index == 0) || (cfg->io.nwin == 0))
+-          goto next_entry;
++      if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++                      pcmcia_parse_tuple(handle, &tuple, &parse) != 0 ||
++                      cfg->index == 0 || cfg->io.nwin == 0)
++              goto next_entry;
+       
+       link->conf.ConfigIndex = cfg->index;
+       /* For multifunction cards, by convention, we configure the
+@@ -653,14 +634,14 @@ static void pcnet_config(dev_link_t *lin
+           if (last_ret == CS_SUCCESS) break;
+       }
+     next_entry:
+-      last_ret = CardServices(GetNextTuple, handle, &tuple);
++      last_ret = pcmcia_get_next_tuple(handle, &tuple);
+     }
+     if (last_ret != CS_SUCCESS) {
+       cs_error(handle, RequestIO, last_ret);
+       goto failed;
+     }
+-    CS_CHECK(RequestIRQ, handle, &link->irq);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
+     
+     if (link->io.NumPorts2 == 8) {
+       link->conf.Attributes |= CONF_ENABLE_SPKR;
+@@ -670,7 +651,7 @@ static void pcnet_config(dev_link_t *lin
+       (prodid == PRODID_IBM_HOME_AND_AWAY))
+       link->conf.ConfigIndex |= 0x10;
+     
+-    CS_CHECK(RequestConfiguration, handle, &link->conf);
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
+     dev->irq = link->irq.AssignedIRQ;
+     dev->base_addr = link->io.BasePort1;
+     if (info->flags & HAS_MISC_REG) {
+@@ -786,29 +767,19 @@ failed:
+ static void pcnet_release(dev_link_t *link)
+ {
+-    pcnet_dev_t *info = link->priv;
++    pcnet_dev_t *info = PRIV(link->priv);
+     DEBUG(0, "pcnet_release(0x%p)\n", link);
+-    if (link->open) {
+-      DEBUG(1, "pcnet_cs: release postponed, '%s' still open\n",
+-            info->node.dev_name);
+-      link->state |= DEV_STALE_CONFIG;
+-      return;
+-    }
+-
+     if (info->flags & USE_SHMEM) {
+       iounmap(info->base);
+-      CardServices(ReleaseWindow, link->win);
++      pcmcia_release_window(link->win);
+     }
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     link->state &= ~DEV_CONFIG;
+-
+-    if (link->state & DEV_STALE_CONFIG)
+-          pcnet_detach(link);
+ }
+ /*======================================================================
+@@ -824,7 +795,7 @@ static int pcnet_event(event_t event, in
+                      event_callback_args_t *args)
+ {
+     dev_link_t *link = args->client_data;
+-    pcnet_dev_t *info = link->priv;
++    struct net_device *dev = link->priv;
+     DEBUG(2, "pcnet_event(0x%06x)\n", event);
+@@ -832,7 +803,7 @@ static int pcnet_event(event_t event, in
+     case CS_EVENT_CARD_REMOVAL:
+       link->state &= ~DEV_PRESENT;
+       if (link->state & DEV_CONFIG) {
+-          netif_device_detach(&info->dev);
++          netif_device_detach(dev);
+           pcnet_release(link);
+       }
+       break;
+@@ -846,8 +817,8 @@ static int pcnet_event(event_t event, in
+     case CS_EVENT_RESET_PHYSICAL:
+       if (link->state & DEV_CONFIG) {
+           if (link->open)
+-              netif_device_detach(&info->dev);
+-          CardServices(ReleaseConfiguration, link->handle);
++              netif_device_detach(dev);
++          pcmcia_release_configuration(link->handle);
+       }
+       break;
+     case CS_EVENT_PM_RESUME:
+@@ -855,11 +826,11 @@ static int pcnet_event(event_t event, in
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG) {
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+           if (link->open) {
+-              pcnet_reset_8390(&info->dev);
+-              NS8390_init(&info->dev, 1);
+-              netif_device_attach(&info->dev);
++              pcnet_reset_8390(dev);
++              NS8390_init(dev, 1);
++              netif_device_attach(dev);
+           }
+       }
+       break;
+@@ -871,13 +842,15 @@ static int pcnet_event(event_t event, in
+     MII interface support for DL10019 and DL10022 based cards
+-    On the DL10019, the MII IO direction bit is 0x10; on  the DL10022
++    On the DL10019, the MII IO direction bit is 0x10; on the DL10022
+     it is 0x20.  Setting both bits seems to work on both card types.
+ ======================================================================*/
+ #define DLINK_GPIO            0x1c
+ #define DLINK_DIAG            0x1d
++#define DLINK_EEPROM          0x1e
++
+ #define MDIO_SHIFT_CLK                0x80
+ #define MDIO_DATA_OUT         0x40
+ #define MDIO_DIR_WRITE                0x30
+@@ -940,12 +913,104 @@ static void mdio_reset(ioaddr_t addr, in
+     outb_p(0x00, addr);
+ }
++/*======================================================================
++
++    EEPROM access routines for DL10019 and DL10022 based cards
++
++======================================================================*/
++
++#define EE_EEP                0x40
++#define EE_ASIC               0x10
++#define EE_CS         0x08
++#define EE_CK         0x04
++#define EE_DO         0x02
++#define EE_DI         0x01
++#define EE_ADOT               0x01    /* DataOut for ASIC */
++#define EE_READ_CMD   0x06
++
++#define DL19FDUPLX    0x0400  /* DL10019 Full duplex mode */
++
++static int read_eeprom(ioaddr_t ioaddr, int location)
++{
++    int i, retval = 0;
++    ioaddr_t ee_addr = ioaddr + DLINK_EEPROM;
++    int read_cmd = location | (EE_READ_CMD << 8);
++
++    outb(0, ee_addr);
++    outb(EE_EEP|EE_CS, ee_addr);
++
++    /* Shift the read command bits out. */
++    for (i = 10; i >= 0; i--) {
++      short dataval = (read_cmd & (1 << i)) ? EE_DO : 0;
++      outb_p(EE_EEP|EE_CS|dataval, ee_addr);
++      outb_p(EE_EEP|EE_CS|dataval|EE_CK, ee_addr);
++    }
++    outb(EE_EEP|EE_CS, ee_addr);
++
++    for (i = 16; i > 0; i--) {
++      outb_p(EE_EEP|EE_CS | EE_CK, ee_addr);
++      retval = (retval << 1) | ((inb(ee_addr) & EE_DI) ? 1 : 0);
++      outb_p(EE_EEP|EE_CS, ee_addr);
++    }
++
++    /* Terminate the EEPROM access. */
++    outb(0, ee_addr);
++    return retval;
++}
++
++/*
++    The internal ASIC registers can be changed by EEPROM READ access
++    with EE_ASIC bit set.
++    In ASIC mode, EE_ADOT is used to output the data to the ASIC.
++*/
++
++static void write_asic(ioaddr_t ioaddr, int location, short asic_data)
++{
++      int i;
++      ioaddr_t ee_addr = ioaddr + DLINK_EEPROM;
++      short dataval;
++      int read_cmd = location | (EE_READ_CMD << 8);
++
++      asic_data |= read_eeprom(ioaddr, location);
++
++      outb(0, ee_addr);
++      outb(EE_ASIC|EE_CS|EE_DI, ee_addr);
++
++      read_cmd = read_cmd >> 1;
++
++      /* Shift the read command bits out. */
++      for (i = 9; i >= 0; i--) {
++              dataval = (read_cmd & (1 << i)) ? EE_DO : 0;
++              outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr);
++              outb_p(EE_ASIC|EE_CS|EE_DI|dataval|EE_CK, ee_addr);
++              outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr);
++      }
++      // sync
++      outb(EE_ASIC|EE_CS, ee_addr);
++      outb(EE_ASIC|EE_CS|EE_CK, ee_addr);
++      outb(EE_ASIC|EE_CS, ee_addr);
++
++      for (i = 15; i >= 0; i--) {
++              dataval = (asic_data & (1 << i)) ? EE_ADOT : 0;
++              outb_p(EE_ASIC|EE_CS|dataval, ee_addr);
++              outb_p(EE_ASIC|EE_CS|dataval|EE_CK, ee_addr);
++              outb_p(EE_ASIC|EE_CS|dataval, ee_addr);
++      }
++
++      /* Terminate the ASIC access. */
++      outb(EE_ASIC|EE_DI, ee_addr);
++      outb(EE_ASIC|EE_DI| EE_CK, ee_addr);
++      outb(EE_ASIC|EE_DI, ee_addr);
++
++      outb(0, ee_addr);
++}
++
+ /*====================================================================*/
+ static void set_misc_reg(struct net_device *dev)
+ {
+     ioaddr_t nic_base = dev->base_addr;
+-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
++    pcnet_dev_t *info = PRIV(dev);
+     u_char tmp;
+     
+     if (info->flags & HAS_MISC_REG) {
+@@ -975,7 +1040,7 @@ static void set_misc_reg(struct net_devi
+ static void mii_phy_probe(struct net_device *dev)
+ {
+-    pcnet_dev_t *info = (pcnet_dev_t *)dev;   
++    pcnet_dev_t *info = PRIV(dev);
+     ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO;
+     int i;
+     u_int tmp, phyid;
+@@ -999,7 +1064,7 @@ static void mii_phy_probe(struct net_dev
+ static int pcnet_open(struct net_device *dev)
+ {
+-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
++    pcnet_dev_t *info = PRIV(dev);
+     dev_link_t *link = &info->link;
+     
+     DEBUG(2, "pcnet_open('%s')\n", dev->name);
+@@ -1016,7 +1081,7 @@ static int pcnet_open(struct net_device 
+     info->link_status = 0x00;
+     init_timer(&info->watchdog);
+     info->watchdog.function = &ei_watchdog;
+-    info->watchdog.data = (u_long)info;
++    info->watchdog.data = (u_long)dev;
+     info->watchdog.expires = jiffies + HZ;
+     add_timer(&info->watchdog);
+@@ -1027,7 +1092,7 @@ static int pcnet_open(struct net_device 
+ static int pcnet_close(struct net_device *dev)
+ {
+-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
++    pcnet_dev_t *info = PRIV(dev);
+     dev_link_t *link = &info->link;
+     DEBUG(2, "pcnet_close('%s')\n", dev->name);
+@@ -1038,8 +1103,6 @@ static int pcnet_close(struct net_device
+     link->open--;
+     netif_stop_queue(dev);
+     del_timer_sync(&info->watchdog);
+-    if (link->state & DEV_STALE_CONFIG)
+-          pcnet_release(link);
+     return 0;
+ } /* pcnet_close */
+@@ -1080,7 +1143,7 @@ static void pcnet_reset_8390(struct net_
+ static int set_config(struct net_device *dev, struct ifmap *map)
+ {
+-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
++    pcnet_dev_t *info = PRIV(dev);
+     if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
+       if (!(info->flags & HAS_MISC_REG))
+           return -EOPNOTSUPP;
+@@ -1098,7 +1161,8 @@ static int set_config(struct net_device 
+ static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
+ {
+-    pcnet_dev_t *info = dev_id;
++    struct net_device *dev = dev_id;
++    pcnet_dev_t *info = PRIV(dev);
+     info->stale = 0;
+     ei_interrupt(irq, dev_id, regs);
+     /* FIXME! Was it really ours? */
+@@ -1107,8 +1171,8 @@ static irqreturn_t ei_irq_wrapper(int ir
+ static void ei_watchdog(u_long arg)
+ {
+-    pcnet_dev_t *info = (pcnet_dev_t *)(arg);
+-    struct net_device *dev = &info->dev;
++    struct net_device *dev = (struct net_device *)arg;
++    pcnet_dev_t *info = PRIV(dev);
+     ioaddr_t nic_base = dev->base_addr;
+     ioaddr_t mii_addr = nic_base + DLINK_GPIO;
+     u_short link;
+@@ -1154,6 +1218,9 @@ static void ei_watchdog(u_long arg)
+       if (link && (info->flags & IS_DL10022)) {
+           /* Disable collision detection on full duplex links */
+           outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG);
++      } else if (link && (info->flags & IS_DL10019)) {
++          /* Disable collision detection on full duplex links */
++          write_asic(dev->base_addr, 4, (p & 0x140) ? DL19FDUPLX : 0);
+       }
+       if (link) {
+           if (info->phy_id == info->eth_phy) {
+@@ -1208,7 +1275,7 @@ static struct ethtool_ops netdev_ethtool
+ static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ {
+-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
++    pcnet_dev_t *info = PRIV(dev);
+     u16 *data = (u16 *)&rq->ifr_data;
+     ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO;
+     switch (cmd) {
+@@ -1319,7 +1386,7 @@ static void dma_block_output(struct net_
+                            const u_char *buf, const int start_page)
+ {
+     ioaddr_t nic_base = dev->base_addr;
+-    pcnet_dev_t *info = (pcnet_dev_t *)dev;
++    pcnet_dev_t *info = PRIV(dev);
+ #ifdef PCMCIA_DEBUG
+     int retries = 0;
+ #endif
+@@ -1505,7 +1572,7 @@ static int setup_shmem_window(dev_link_t
+                             int stop_pg, int cm_offset)
+ {
+     struct net_device *dev = link->priv;
+-    pcnet_dev_t *info = link->priv;
++    pcnet_dev_t *info = PRIV(dev);
+     win_req_t req;
+     memreq_t mem;
+     int i, window_size, offset, last_ret, last_fn;
+@@ -1523,14 +1590,13 @@ static int setup_shmem_window(dev_link_t
+     req.Attributes |= WIN_USE_WAIT;
+     req.Base = 0; req.Size = window_size;
+     req.AccessSpeed = mem_speed;
+-    link->win = (window_handle_t)link->handle;
+-    CS_CHECK(RequestWindow, &link->win, &req);
++    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
+     mem.CardOffset = (start_pg << 8) + cm_offset;
+     offset = mem.CardOffset % window_size;
+     mem.CardOffset -= offset;
+     mem.Page = 0;
+-    CS_CHECK(MapMemPage, link->win, &mem);
++    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+     /* Try scribbling on the buffer */
+     info->base = ioremap(req.Base, window_size);
+@@ -1542,7 +1608,7 @@ static int setup_shmem_window(dev_link_t
+     pcnet_reset_8390(dev);
+     if (i != (TX_PAGES<<8)) {
+       iounmap(info->base);
+-      CardServices(ReleaseWindow, link->win);
++      pcmcia_release_window(link->win);
+       info->base = NULL; link->win = NULL;
+       goto failed;
+     }
+--- linux-2.6.0/drivers/net/pcmcia/smc91c92_cs.c       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/pcmcia/smc91c92_cs.c        2003-12-28 23:22:53.000000000 -0800
+@@ -379,7 +379,7 @@ static dev_link_t *smc91c92_attach(void)
+     client_reg.event_handler = &smc91c92_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != 0) {
+       cs_error(link->handle, RegisterClient, ret);
+       smc91c92_detach(link);
+@@ -411,23 +411,17 @@ static void smc91c92_detach(dev_link_t *
+     if (*linkp == NULL)
+       return;
+-    if (link->state & DEV_CONFIG) {
++    if (link->state & DEV_CONFIG)
+       smc91c92_release(link);
+-      if (link->state & DEV_STALE_CONFIG)
+-          return;
+-    }
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     /* Unlink device structure, free bits */
+     *linkp = link->next;
+-    if (link->dev) {
++    if (link->dev)
+       unregister_netdev(dev);
+-      free_netdev(dev);
+-    } else
+-      kfree(dev);
+-
++    free_netdev(dev);
+ } /* smc91c92_detach */
+ /*====================================================================*/
+@@ -453,19 +447,27 @@ static int cvt_ascii_address(struct net_
+ /*====================================================================*/
+-static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple,
+-                   cisparse_t *parse)
++static int first_tuple(client_handle_t handle, tuple_t *tuple,
++              cisparse_t *parse)
+ {
+-    int i;
+-    i = CardServices(fn, handle, tuple);
+-    if (i != CS_SUCCESS) return i;
+-    i = CardServices(GetTupleData, handle, tuple);
+-    if (i != CS_SUCCESS) return i;
+-    return CardServices(ParseTuple, handle, tuple, parse);
++      int i;
++
++      if ((i = pcmcia_get_first_tuple(handle, tuple)) != CS_SUCCESS ||
++                      (i = pcmcia_get_tuple_data(handle, tuple)) != CS_SUCCESS)
++              return i;
++      return pcmcia_parse_tuple(handle, tuple, parse);
+ }
+-#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+-#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
++static int next_tuple(client_handle_t handle, tuple_t *tuple,
++              cisparse_t *parse)
++{
++      int i;
++
++      if ((i = pcmcia_get_next_tuple(handle, tuple)) != CS_SUCCESS ||
++                      (i = pcmcia_get_tuple_data(handle, tuple)) != CS_SUCCESS)
++              return i;
++      return pcmcia_parse_tuple(handle, tuple, parse);
++}
+ /*======================================================================
+@@ -534,7 +536,7 @@ static int mhz_mfc_config(dev_link_t *li
+       for (k = 0; k < 0x400; k += 0x10) {
+           if (k & 0x80) continue;
+           link->io.BasePort1 = k ^ 0x300;
+-          i = CardServices(RequestIO, link->handle, &link->io);
++          i = pcmcia_request_io(link->handle, &link->io);
+           if (i == CS_SUCCESS) break;
+       }
+       if (i == CS_SUCCESS) break;
+@@ -548,15 +550,14 @@ static int mhz_mfc_config(dev_link_t *li
+     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
+     req.Base = req.Size = 0;
+     req.AccessSpeed = 0;
+-    link->win = (window_handle_t)link->handle;
+-    i = CardServices(RequestWindow, &link->win, &req);
++    i = pcmcia_request_window(&link->handle, &req, &link->win);
+     if (i != CS_SUCCESS)
+       return i;
+     smc->base = ioremap(req.Base, req.Size);
+     mem.CardOffset = mem.Page = 0;
+     if (smc->manfid == MANFID_MOTOROLA)
+       mem.CardOffset = link->conf.ConfigBase;
+-    i = CardServices(MapMemPage, link->win, &mem);
++    i = pcmcia_map_mem_page(link->win, &mem);
+     if ((i == CS_SUCCESS)
+       && (smc->manfid == MANFID_MEGAHERTZ)
+@@ -594,9 +595,9 @@ static int mhz_setup(dev_link_t *link)
+     /* Another possibility: for the EM3288, in a special tuple */
+     tuple.DesiredTuple = 0x81;
+-    if (CardServices(GetFirstTuple, handle, &tuple) != CS_SUCCESS)
++    if (pcmcia_get_first_tuple(handle, &tuple) != CS_SUCCESS)
+       return -1;
+-    if (CardServices(GetTupleData, handle, &tuple) != CS_SUCCESS)
++    if (pcmcia_get_tuple_data(handle, &tuple) != CS_SUCCESS)
+       return -1;
+     buf[12] = '\0';
+     if (cvt_ascii_address(dev, buf) == 0)
+@@ -690,7 +691,7 @@ static int smc_config(dev_link_t *link)
+           link->conf.ConfigIndex = cf->index;
+           link->io.BasePort1 = cf->io.win[0].base;
+           link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
+-          i = CardServices(RequestIO, link->handle, &link->io);
++          i = pcmcia_request_io(link->handle, &link->io);
+           if (i == CS_SUCCESS) break;
+       }
+       i = next_tuple(link->handle, &tuple, &parse);
+@@ -763,14 +764,14 @@ static int osi_config(dev_link_t *link)
+     for (i = j = 0; j < 4; j++) {
+       link->io.BasePort2 = com[j];
+-      i = CardServices(RequestIO, link->handle, &link->io);
++      i = pcmcia_request_io(link->handle, &link->io);
+       if (i == CS_SUCCESS) break;
+     }
+     if (i != CS_SUCCESS) {
+       /* Fallback: turn off hard decode */
+       link->conf.ConfigIndex = 0x03;
+       link->io.NumPorts2 = 0;
+-      i = CardServices(RequestIO, link->handle, &link->io);
++      i = pcmcia_request_io(link->handle, &link->io);
+     }
+     dev->base_addr = link->io.BasePort1 + 0x10;
+     return i;
+@@ -791,12 +792,12 @@ static int osi_setup(dev_link_t *link, u
+     /* Read the station address from tuple 0x90, subtuple 0x04 */
+     tuple.DesiredTuple = 0x90;
+-    i = CardServices(GetFirstTuple, handle, &tuple);
++    i = pcmcia_get_first_tuple(handle, &tuple);
+     while (i == CS_SUCCESS) {
+-      i = CardServices(GetTupleData, handle, &tuple);
++      i = pcmcia_get_tuple_data(handle, &tuple);
+       if ((i != CS_SUCCESS) || (buf[0] == 0x04))
+           break;
+-      i = CardServices(GetNextTuple, handle, &tuple);
++      i = pcmcia_get_next_tuple(handle, &tuple);
+     }
+     if (i != CS_SUCCESS)
+       return -1;
+@@ -869,9 +870,9 @@ static int check_sig(dev_link_t *link)
+       printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
+       args.client_data = link;
+       smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args);
+-      CardServices(ReleaseIO, link->handle, &link->io);
++      pcmcia_release_io(link->handle, &link->io);
+       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+-      CardServices(RequestIO, link->handle, &link->io);
++      pcmcia_request_io(link->handle, &link->io);
+       smc91c92_event(CS_EVENT_CARD_RESET, 0, &args);
+       return check_sig(link);
+     }
+@@ -936,9 +937,9 @@ static void smc91c92_config(dev_link_t *
+     }
+     CS_EXIT_TEST(i, RequestIO, config_failed);
+-    i = CardServices(RequestIRQ, link->handle, &link->irq);
++    i = pcmcia_request_irq(link->handle, &link->irq);
+     CS_EXIT_TEST(i, RequestIRQ, config_failed);
+-    i = CardServices(RequestConfiguration, link->handle, &link->conf);
++    i = pcmcia_request_configuration(link->handle, &link->conf);
+     CS_EXIT_TEST(i, RequestConfiguration, config_failed);
+     if (smc->manfid == MANFID_MOTOROLA)
+@@ -1063,27 +1064,17 @@ static void smc91c92_release(dev_link_t 
+     DEBUG(0, "smc91c92_release(0x%p)\n", link);
+-    if (link->open) {
+-      DEBUG(1, "smc91c92_cs: release postponed, '%s' still open\n",
+-            link->dev->dev_name);
+-      link->state |= DEV_STALE_CONFIG;
+-      return;
+-    }
+-
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     if (link->win) {
+       struct net_device *dev = link->priv;
+       struct smc_private *smc = dev->priv;
+       iounmap(smc->base);
+-      CardServices(ReleaseWindow, link->win);
++      pcmcia_release_window(link->win);
+     }
+     link->state &= ~DEV_CONFIG;
+-
+-    if (link->state & DEV_STALE_CONFIG)
+-          smc91c92_detach(link);
+ }
+ /*======================================================================
+@@ -1124,7 +1115,7 @@ static int smc91c92_event(event_t event,
+       if (link->state & DEV_CONFIG) {
+           if (link->open)
+               netif_device_detach(dev);
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       }
+       break;
+     case CS_EVENT_PM_RESUME:
+@@ -1135,7 +1126,7 @@ static int smc91c92_event(event_t event,
+           if ((smc->manfid == MANFID_MEGAHERTZ) &&
+               (smc->cardid == PRODID_MEGAHERTZ_EM3288))
+               mhz_3288_power(link);
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+           if (smc->manfid == MANFID_MOTOROLA)
+               mot_config(link);
+           if ((smc->manfid == MANFID_OSITECH) &&
+@@ -1309,8 +1300,6 @@ static int smc_close(struct net_device *
+     link->open--;
+     del_timer_sync(&smc->media);
+-    if (link->state & DEV_STALE_CONFIG)
+-          smc91c92_release(link);
+     return 0;
+ } /* smc_close */
+--- linux-2.6.0/drivers/net/pcmcia/xirc2ps_cs.c        2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/pcmcia/xirc2ps_cs.c 2003-12-28 23:22:53.000000000 -0800
+@@ -391,28 +391,27 @@ static int do_stop(struct net_device *de
+ /*=============== Helper functions =========================*/
+ static int
+-get_tuple_data(int fn, client_handle_t handle, tuple_t *tuple)
++first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
+ {
+-    int err;
++      int err;
+-    if ((err=CardServices(fn, handle, tuple)))
++      if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
++                      (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
++              err = pcmcia_parse_tuple(handle, tuple, parse);
+       return err;
+-    return CardServices(GetTupleData, handle, tuple);
+ }
+ static int
+-get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
++next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
+ {
+-    int err;
++      int err;
+-    if ((err=get_tuple_data(fn, handle, tuple)))
++      if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
++                      (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
++              err = pcmcia_parse_tuple(handle, tuple, parse);
+       return err;
+-    return CardServices(ParseTuple, handle, tuple, parse);
+ }
+-#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+-#define next_tuple(a, b, c)  get_tuple(GetNextTuple, a, b, c)
+-
+ #define SelectPage(pgnr)   outb((pgnr), ioaddr + XIRCREG_PR)
+ #define GetByte(reg)     ((unsigned)inb(ioaddr + (reg)))
+ #define GetWord(reg)     ((unsigned)inw(ioaddr + (reg)))
+@@ -636,7 +635,7 @@ xirc2ps_attach(void)
+     client_reg.event_handler = &xirc2ps_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    if ((err = CardServices(RegisterClient, &link->handle, &client_reg))) {
++    if ((err = pcmcia_register_client(&link->handle, &client_reg))) {
+       cs_error(link->handle, RegisterClient, err);
+       xirc2ps_detach(link);
+       return NULL;
+@@ -680,16 +679,13 @@ xirc2ps_detach(dev_link_t * link)
+     /* Break the link with Card Services */
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     /* Unlink device structure, free it */
+     *linkp = link->next;
+-    if (link->dev) {
++    if (link->dev)
+       unregister_netdev(dev);
+-      free_netdev(dev);
+-    } else
+-      kfree(dev);
+-
++    free_netdev(dev);
+ } /* xirc2ps_detach */
+ /****************
+@@ -887,7 +883,8 @@ xirc2ps_config(dev_link_t * link)
+     }
+     if (err) { /* not found: try to get the node-id from tuple 0x89 */
+       tuple.DesiredTuple = 0x89;  /* data layout looks like tuple 0x22 */
+-      if (!(err = get_tuple_data(GetFirstTuple, handle, &tuple))) {
++      if ((err = pcmcia_get_first_tuple(handle, &tuple)) == 0 &&
++              (err = pcmcia_get_tuple_data(handle, &tuple)) == 0) {
+           if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)
+               memcpy(&parse, buf, 8);
+           else
+@@ -953,8 +950,7 @@ xirc2ps_config(dev_link_t * link)
+                       link->conf.ConfigIndex = cf->index ;
+                       link->io.BasePort2 = cf->io.win[0].base;
+                       link->io.BasePort1 = ioaddr;
+-                      if (!(err=CardServices(RequestIO, link->handle,
+-                                                              &link->io)))
++                      if (!(err=pcmcia_request_io(link->handle, &link->io)))
+                           goto port_found;
+                   }
+               }
+@@ -976,8 +972,7 @@ xirc2ps_config(dev_link_t * link)
+                       link->io.BasePort1 = link->io.BasePort2
+                                   + (pass ? (cf->index & 0x20 ? -24:8)
+                                           : (cf->index & 0x20 ?   8:-24));
+-                      if (!(err=CardServices(RequestIO, link->handle,
+-                                                              &link->io)))
++                      if (!(err=pcmcia_request_io(link->handle, &link->io)))
+                           goto port_found;
+                   }
+               }
+@@ -992,11 +987,11 @@ xirc2ps_config(dev_link_t * link)
+       link->io.NumPorts1 = 16;
+       for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
+           link->io.BasePort1 = ioaddr;
+-          if (!(err=CardServices(RequestIO, link->handle, &link->io)))
++          if (!(err=pcmcia_request_io(link->handle, &link->io)))
+               goto port_found;
+       }
+       link->io.BasePort1 = 0; /* let CS decide */
+-      if ((err=CardServices(RequestIO, link->handle, &link->io))) {
++      if ((err=pcmcia_request_io(link->handle, &link->io))) {
+           cs_error(link->handle, RequestIO, err);
+           goto config_error;
+       }
+@@ -1009,7 +1004,7 @@ xirc2ps_config(dev_link_t * link)
+      * Now allocate an interrupt line.        Note that this does not
+      * actually assign a handler to the interrupt.
+      */
+-    if ((err=CardServices(RequestIRQ, link->handle, &link->irq))) {
++    if ((err=pcmcia_request_irq(link->handle, &link->irq))) {
+       cs_error(link->handle, RequestIRQ, err);
+       goto config_error;
+     }
+@@ -1018,8 +1013,7 @@ xirc2ps_config(dev_link_t * link)
+      * This actually configures the PCMCIA socket -- setting up
+      * the I/O windows and the interrupt mapping.
+      */
+-    if ((err=CardServices(RequestConfiguration,
+-                        link->handle, &link->conf))) {
++    if ((err=pcmcia_request_configuration(link->handle, &link->conf))) {
+       cs_error(link->handle, RequestConfiguration, err);
+       goto config_error;
+     }
+@@ -1037,16 +1031,14 @@ xirc2ps_config(dev_link_t * link)
+       reg.Action = CS_WRITE;
+       reg.Offset = CISREG_IOBASE_0;
+       reg.Value = link->io.BasePort2 & 0xff;
+-      if ((err = CardServices(AccessConfigurationRegister, link->handle,
+-                              &reg))) {
++      if ((err = pcmcia_access_configuration_register(link->handle, &reg))) {
+           cs_error(link->handle, AccessConfigurationRegister, err);
+           goto config_error;
+       }
+       reg.Action = CS_WRITE;
+       reg.Offset = CISREG_IOBASE_1;
+       reg.Value = (link->io.BasePort2 >> 8) & 0xff;
+-      if ((err = CardServices(AccessConfigurationRegister, link->handle,
+-                              &reg))) {
++      if ((err = pcmcia_access_configuration_register(link->handle, &reg))) {
+           cs_error(link->handle, AccessConfigurationRegister, err);
+           goto config_error;
+       }
+@@ -1058,15 +1050,14 @@ xirc2ps_config(dev_link_t * link)
+       req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
+       req.Base = req.Size = 0;
+       req.AccessSpeed = 0;
+-      link->win = (window_handle_t)link->handle;
+-      if ((err = CardServices(RequestWindow, &link->win, &req))) {
++      if ((err = pcmcia_request_window(&link->handle, &req, &link->win))) {
+           cs_error(link->handle, RequestWindow, err);
+           goto config_error;
+       }
+       local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;
+       mem.CardOffset = 0x0;
+       mem.Page = 0;
+-      if ((err = CardServices(MapMemPage, link->win, &mem))) {
++      if ((err = pcmcia_map_mem_page(link->win, &mem))) {
+           cs_error(link->handle, MapMemPage, err);
+           goto config_error;
+       }
+@@ -1171,11 +1162,11 @@ xirc2ps_release(dev_link_t *link)
+       local_info_t *local = dev->priv;
+       if (local->dingo)
+           iounmap(local->dingo_ccr - 0x0800);
+-      CardServices(ReleaseWindow, link->win);
++      pcmcia_release_window(link->win);
+     }
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     link->state &= ~DEV_CONFIG;
+ } /* xirc2ps_release */
+@@ -1227,7 +1218,7 @@ xirc2ps_event(event_t event, int priorit
+               netif_device_detach(dev);
+               do_powerdown(dev);
+           }
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       }
+       break;
+     case CS_EVENT_PM_RESUME:
+@@ -1235,7 +1226,7 @@ xirc2ps_event(event_t event, int priorit
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG) {
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+           if (link->open) {
+               do_reset(dev,1);
+               netif_device_attach(dev);
+--- linux-2.6.0/drivers/net/pcnet32.c  2003-12-17 21:20:02.000000000 -0800
++++ 25/drivers/net/pcnet32.c   2003-12-28 23:21:01.000000000 -0800
+@@ -456,6 +456,14 @@ static struct pcnet32_access pcnet32_dwi
+     .reset    = pcnet32_dwio_reset
+ };
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void pcnet32_poll_controller(struct net_device *dev)
++{ 
++      disable_irq(dev->irq);
++      pcnet32_interrupt(0, dev, NULL);
++      enable_irq(dev->irq);
++} 
++#endif
+ /* only probes for non-PCI devices, the rest are handled by 
+@@ -805,12 +813,16 @@ pcnet32_probe1(unsigned long ioaddr, uns
+     dev->do_ioctl = &pcnet32_ioctl;
+     dev->tx_timeout = pcnet32_tx_timeout;
+     dev->watchdog_timeo = (5*HZ);
++#ifdef CONFIG_NET_POLL_CONTROLLER
++    dev->poll_controller = pcnet32_poll_controller;
++#endif    
++
++    /* Fill in the generic fields of the device structure. */
++    if (register_netdev(dev))
++      goto err_free_consistent;
+     lp->next = pcnet32_dev;
+     pcnet32_dev = dev;
+-
+-    /* Fill in the generic fields of the device structure. */
+-    register_netdev(dev);
+     printk(KERN_INFO "%s: registered as %s\n",dev->name, lp->name);
+     cards_found++;
+     return 0;
+--- linux-2.6.0/drivers/net/plip.c     2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/plip.c      2003-12-28 23:21:01.000000000 -0800
+@@ -277,19 +277,11 @@ inline static unsigned char read_status 
+    then calls us here.
+    */
+-static int
++static void
+ plip_init_netdev(struct net_device *dev)
+ {
+       struct net_local *nl = dev->priv;
+-      printk(KERN_INFO "%s", version);
+-      if (dev->irq != -1)
+-              printk(KERN_INFO "%s: Parallel port at %#3lx, using IRQ %d.\n",
+-                     dev->name, dev->base_addr, dev->irq);
+-      else
+-              printk(KERN_INFO "%s: Parallel port at %#3lx, not using IRQ.\n",
+-                     dev->name, dev->base_addr);
+-
+       /* Then, override parts of it */
+       dev->hard_start_xmit     = plip_tx_packet;
+       dev->open                = plip_open;
+@@ -323,8 +315,6 @@ plip_init_netdev(struct net_device *dev)
+               INIT_WORK(&nl->timer, (void (*)(void *))plip_timer_bh, dev);
+       spin_lock_init(&nl->lock);
+-
+-      return 0;
+ }
\f
+ /* Bottom half handler for the delayed request.
+@@ -1282,14 +1272,13 @@ static void plip_attach (struct parport 
+               }
+               sprintf(name, "plip%d", unit);
+-              dev = alloc_netdev(sizeof(struct net_local), name, 
+-                                 ether_setup);
++              dev = alloc_etherdev(sizeof(struct net_local));
+               if (!dev) {
+                       printk(KERN_ERR "plip: memory squeeze\n");
+                       return;
+               }
+               
+-              dev->init = plip_init_netdev;
++              strcpy(dev->name, name);
+               SET_MODULE_OWNER(dev);
+               dev->irq = port->irq;
+@@ -1306,17 +1295,35 @@ static void plip_attach (struct parport 
+               if (!nl->pardev) {
+                       printk(KERN_ERR "%s: parport_register failed\n", name);
+-                      kfree(dev);
++                      goto err_free_dev;
+                       return;
+               }
++              plip_init_netdev(dev);
++
+               if (register_netdev(dev)) {
+                       printk(KERN_ERR "%s: network register failed\n", name);
+-                      kfree(dev);
+-              } else {
+-                      dev_plip[unit++] = dev;
++                      goto err_parport_unregister;
+               }
++
++              printk(KERN_INFO "%s", version);
++              if (dev->irq != -1)
++                      printk(KERN_INFO "%s: Parallel port at %#3lx, "
++                                       "using IRQ %d.\n",
++                                       dev->name, dev->base_addr, dev->irq);
++              else
++                      printk(KERN_INFO "%s: Parallel port at %#3lx, "
++                                       "not using IRQ.\n",
++                                       dev->name, dev->base_addr);
++              dev_plip[unit++] = dev;
+       }
++      return;
++
++err_parport_unregister:
++      parport_unregister_device(nl->pardev);
++err_free_dev:
++      free_netdev(dev);
++      return;
+ }
+ /* plip_detach() is called (by the parport code) when a port is
+--- linux-2.6.0/drivers/net/ppp_async.c        2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/ppp_async.c 2003-12-28 23:22:46.000000000 -0800
+@@ -16,8 +16,6 @@
+  * Part of the code in this driver was inspired by the old async-only
+  * PPP driver, written by Michael Callahan and Al Longyear, and
+  * subsequently hacked by Paul Mackerras.
+- *
+- * ==FILEVERSION 20020125==
+  */
+ #include <linux/module.h>
+@@ -61,6 +59,9 @@ struct asyncppp {
+       struct sk_buff  *rpkt;
+       int             lcp_fcs;
++      struct sk_buff_head rqueue;
++
++      struct tasklet_struct tsk;
+       atomic_t        refcnt;
+       struct semaphore dead_sem;
+@@ -74,8 +75,9 @@ struct asyncppp {
+ #define XMIT_BUSY     2
+ /* State bits */
+-#define SC_TOSS               0x20000000
+-#define SC_ESCAPE     0x40000000
++#define SC_TOSS               1
++#define SC_ESCAPE     2
++#define SC_PREV_ERROR 4
+ /* Bits in rbits */
+ #define SC_RCV_BITS   (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
+@@ -97,6 +99,8 @@ static void ppp_async_input(struct async
+                           char *flags, int count);
+ static int ppp_async_ioctl(struct ppp_channel *chan, unsigned int cmd,
+                          unsigned long arg);
++static void ppp_async_process(unsigned long arg);
++
+ static void async_lcp_peek(struct asyncppp *ap, unsigned char *data,
+                          int len, int inbound);
+@@ -165,6 +169,9 @@ ppp_asynctty_open(struct tty_struct *tty
+       ap->olim = ap->obuf;
+       ap->lcp_fcs = -1;
++      skb_queue_head_init(&ap->rqueue);
++      tasklet_init(&ap->tsk, ppp_async_process, (unsigned long) ap);
++
+       atomic_set(&ap->refcnt, 1);
+       init_MUTEX_LOCKED(&ap->dead_sem);
+@@ -214,10 +221,12 @@ ppp_asynctty_close(struct tty_struct *tt
+        */
+       if (!atomic_dec_and_test(&ap->refcnt))
+               down(&ap->dead_sem);
++      tasklet_kill(&ap->tsk);
+       ppp_unregister_channel(&ap->chan);
+       if (ap->rpkt != 0)
+               kfree_skb(ap->rpkt);
++      skb_queue_purge(&ap->rqueue);
+       if (ap->tpkt != 0)
+               kfree_skb(ap->tpkt);
+       kfree(ap);
+@@ -316,17 +325,24 @@ ppp_asynctty_room(struct tty_struct *tty
+       return 65535;
+ }
++/*
++ * This can now be called from hard interrupt level as well
++ * as soft interrupt level or mainline.
++ */
+ static void
+ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
+-                char *flags, int count)
++                char *cflags, int count)
+ {
+       struct asyncppp *ap = ap_get(tty);
++      unsigned long flags;
+       if (ap == 0)
+               return;
+-      spin_lock_bh(&ap->recv_lock);
+-      ppp_async_input(ap, buf, flags, count);
+-      spin_unlock_bh(&ap->recv_lock);
++      spin_lock_irqsave(&ap->recv_lock, flags);
++      ppp_async_input(ap, buf, cflags, count);
++      spin_unlock_irqrestore(&ap->recv_lock, flags);
++      if (skb_queue_len(&ap->rqueue))
++              tasklet_schedule(&ap->tsk);
+       ap_put(ap);
+       if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
+           && tty->driver->unthrottle)
+@@ -341,8 +357,8 @@ ppp_asynctty_wakeup(struct tty_struct *t
+       clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+       if (ap == 0)
+               return;
+-      if (ppp_async_push(ap))
+-              ppp_output_wakeup(&ap->chan);
++      set_bit(XMIT_WAKEUP, &ap->xmit_flags);
++      tasklet_schedule(&ap->tsk);
+       ap_put(ap);
+ }
+@@ -396,9 +412,9 @@ ppp_async_ioctl(struct ppp_channel *chan
+               if (get_user(val, (int *) arg))
+                       break;
+               ap->flags = val & ~SC_RCV_BITS;
+-              spin_lock_bh(&ap->recv_lock);
++              spin_lock_irq(&ap->recv_lock);
+               ap->rbits = val & SC_RCV_BITS;
+-              spin_unlock_bh(&ap->recv_lock);
++              spin_unlock_irq(&ap->recv_lock);
+               err = 0;
+               break;
+@@ -460,6 +476,28 @@ ppp_async_ioctl(struct ppp_channel *chan
+ }
+ /*
++ * This is called at softirq level to deliver received packets
++ * to the ppp_generic code, and to tell the ppp_generic code
++ * if we can accept more output now.
++ */
++static void ppp_async_process(unsigned long arg)
++{
++      struct asyncppp *ap = (struct asyncppp *) arg;
++      struct sk_buff *skb;
++
++      /* process received packets */
++      while ((skb = skb_dequeue(&ap->rqueue)) != NULL) {
++              if (skb->cb[0])
++                      ppp_input_error(&ap->chan, 0);
++              ppp_input(&ap->chan, skb);
++      }
++
++      /* try to push more stuff out */
++      if (test_bit(XMIT_WAKEUP, &ap->xmit_flags) && ppp_async_push(ap))
++              ppp_output_wakeup(&ap->chan);
++}
++
++/*
+  * Procedures for encapsulation and framing.
+  */
+@@ -641,7 +679,6 @@ ppp_async_push(struct asyncppp *ap)
+       struct tty_struct *tty = ap->tty;
+       int tty_stuffed = 0;
+-      set_bit(XMIT_WAKEUP, &ap->xmit_flags);
+       /*
+        * We can get called recursively here if the tty write
+        * function calls our wakeup function.  This can happen
+@@ -752,22 +789,19 @@ scan_ordinary(struct asyncppp *ap, const
+ }
+ /* called when a flag is seen - do end-of-packet processing */
+-static inline void
++static void
+ process_input_packet(struct asyncppp *ap)
+ {
+       struct sk_buff *skb;
+       unsigned char *p;
+       unsigned int len, fcs, proto;
+-      int code = 0;
+       skb = ap->rpkt;
+-      ap->rpkt = 0;
+-      if ((ap->state & (SC_TOSS | SC_ESCAPE)) || skb == 0) {
+-              ap->state &= ~(SC_TOSS | SC_ESCAPE);
+-              if (skb != 0)
+-                      kfree_skb(skb);
+-              return;
+-      }
++      if (ap->state & (SC_TOSS | SC_ESCAPE))
++              goto err;
++
++      if (skb == NULL)
++              return;         /* 0-length packet */
+       /* check the FCS */
+       p = skb->data;
+@@ -801,20 +835,18 @@ process_input_packet(struct asyncppp *ap
+                       async_lcp_peek(ap, p, skb->len, 1);
+       }
+-      /* all OK, give it to the generic layer */
+-      ppp_input(&ap->chan, skb);
++      /* queue the frame to be processed */
++      skb->cb[0] = ap->state;
++      skb_queue_tail(&ap->rqueue, skb);
++      ap->rpkt = 0;
++      ap->state = 0;
+       return;
+  err:
+-      kfree_skb(skb);
+-      ppp_input_error(&ap->chan, code);
+-}
+-
+-static inline void
+-input_error(struct asyncppp *ap, int code)
+-{
+-      ap->state |= SC_TOSS;
+-      ppp_input_error(&ap->chan, code);
++      /* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */
++      ap->state = SC_PREV_ERROR;
++      if (skb)
++              skb_trim(skb, 0);
+ }
+ /* called when the tty driver has data for us. */
+@@ -856,7 +888,7 @@ ppp_async_input(struct asyncppp *ap, con
+               }
+               if (f != 0) {
+                       /* start tossing */
+-                      input_error(ap, f);
++                      ap->state |= SC_TOSS;
+               } else if (n > 0 && (ap->state & SC_TOSS) == 0) {
+                       /* stuff the chars in the skb */
+@@ -872,7 +904,7 @@ ppp_async_input(struct asyncppp *ap, con
+                       }
+                       if (n > skb_tailroom(skb)) {
+                               /* packet overflowed MRU */
+-                              input_error(ap, 1);
++                              ap->state |= SC_TOSS;
+                       } else {
+                               sp = skb_put(skb, n);
+                               memcpy(sp, buf, n);
+@@ -909,7 +941,7 @@ ppp_async_input(struct asyncppp *ap, con
+  nomem:
+       printk(KERN_ERR "PPPasync: no memory (input pkt)\n");
+-      input_error(ap, 0);
++      ap->state |= SC_TOSS;
+ }
+ /*
+--- linux-2.6.0/drivers/net/ppp_generic.c      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/ppp_generic.c       2003-12-28 23:21:01.000000000 -0800
+@@ -917,19 +917,14 @@ ppp_net_ioctl(struct net_device *dev, st
+       return err;
+ }
+-static int
+-ppp_net_init(struct net_device *dev)
++static void ppp_setup(struct net_device *dev)
+ {
+       dev->hard_header_len = PPP_HDRLEN;
+       dev->mtu = PPP_MTU;
+-      dev->hard_start_xmit = ppp_start_xmit;
+-      dev->get_stats = ppp_net_stats;
+-      dev->do_ioctl = ppp_net_ioctl;
+       dev->addr_len = 0;
+       dev->tx_queue_len = 3;
+       dev->type = ARPHRD_PPP;
+       dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
+-      return 0;
+ }
+ /*
+@@ -2272,23 +2267,13 @@ ppp_create_interface(int unit, int *retp
+       int i;
+       ppp = kmalloc(sizeof(struct ppp), GFP_KERNEL);
+-      if (ppp == 0)
+-              goto err;
+-      dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+-      if (dev == 0)
+-              goto err;
++      if (!ppp)
++              goto out;
++      dev = alloc_netdev(0, "", ppp_setup);
++      if (!dev)
++              goto out1;
+       memset(ppp, 0, sizeof(struct ppp));
+-      memset(dev, 0, sizeof(struct net_device));
+-      ret = -EEXIST;
+-      down(&all_ppp_sem);
+-      if (unit < 0)
+-              unit = cardmap_find_first_free(all_ppp_units);
+-      else if (cardmap_get(all_ppp_units, unit) != NULL)
+-              goto err_unlock;        /* unit already exists */
+-
+-      /* Initialize the new ppp unit */
+-      ppp->file.index = unit;
+       ppp->mru = PPP_MRU;
+       init_ppp_file(&ppp->file, INTERFACE);
+       ppp->file.hdrlen = PPP_HDRLEN - 2;      /* don't count proto bytes */
+@@ -2301,20 +2286,29 @@ ppp_create_interface(int unit, int *retp
+       ppp->minseq = -1;
+       skb_queue_head_init(&ppp->mrq);
+ #endif /* CONFIG_PPP_MULTILINK */
+-
+       ppp->dev = dev;
+-      dev->init = ppp_net_init;
+-      sprintf(dev->name, "ppp%d", unit);
+       dev->priv = ppp;
+-      dev->destructor = free_netdev;
+-      rtnl_lock();
+-      ret = register_netdevice(dev);
+-      rtnl_unlock();
++      dev->hard_start_xmit = ppp_start_xmit;
++      dev->get_stats = ppp_net_stats;
++      dev->do_ioctl = ppp_net_ioctl;
++
++      ret = -EEXIST;
++      down(&all_ppp_sem);
++      if (unit < 0)
++              unit = cardmap_find_first_free(all_ppp_units);
++      else if (cardmap_get(all_ppp_units, unit) != NULL)
++              goto out2;      /* unit already exists */
++
++      /* Initialize the new ppp unit */
++      ppp->file.index = unit;
++      sprintf(dev->name, "ppp%d", unit);
++
++      ret = register_netdev(dev);
+       if (ret != 0) {
+               printk(KERN_ERR "PPP: couldn't register device %s (%d)\n",
+                      dev->name, ret);
+-              goto err_unlock;
++              goto out2;
+       }
+       atomic_inc(&ppp_unit_count);
+@@ -2323,14 +2317,13 @@ ppp_create_interface(int unit, int *retp
+       *retp = 0;
+       return ppp;
+- err_unlock:
++out2:
+       up(&all_ppp_sem);
+- err:
++      free_netdev(dev);
++out1:
++      kfree(ppp);
++out:
+       *retp = ret;
+-      if (ppp)
+-              kfree(ppp);
+-      if (dev)
+-              kfree(dev);
+       return NULL;
+ }
+@@ -2361,8 +2354,10 @@ static void ppp_shutdown_interface(struc
+       ppp->dev = 0;
+       ppp_unlock(ppp);
+       /* This will call dev_close() for us. */
+-      if (dev)
++      if (dev) {
+               unregister_netdev(dev);
++              free_netdev(dev);
++      }
+       cardmap_set(&all_ppp_units, ppp->file.index, NULL);
+       ppp->file.dead = 1;
+       ppp->owner = NULL;
+--- linux-2.6.0/drivers/net/pppoe.c    2003-11-26 13:53:35.000000000 -0800
++++ 25/drivers/net/pppoe.c     2003-12-28 23:22:25.000000000 -0800
+@@ -1151,3 +1151,4 @@ module_exit(pppoe_exit);
+ MODULE_AUTHOR("Michal Ostrowski <mostrows@speakeasy.net>");
+ MODULE_DESCRIPTION("PPP over Ethernet driver");
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS_NETPROTO(PF_PPPOX);
+--- linux-2.6.0/drivers/net/r8169.c    2003-12-17 21:20:02.000000000 -0800
++++ 25/drivers/net/r8169.c     2003-12-28 23:21:01.000000000 -0800
+@@ -56,9 +56,11 @@ VERSION 1.2 <2002/11/30>
+               printk( "Assertion failed! %s,%s,%s,line=%d\n", \
+               #expr,__FILE__,__FUNCTION__,__LINE__);          \
+         }
++#define dprintk(fmt, args...) do { printk(PFX fmt, ## args) } while (0)
+ #else
+ #define assert(expr) do {} while (0)
+-#endif
++#define dprintk(fmt, args...) do {} while (0)
++#endif /* RTL8169_DEBUG */
+ /* media options */
+ #define MAX_UNITS 8
+@@ -89,9 +91,12 @@ static int multicast_filter_limit = 32;
+ #define NUM_TX_DESC   64      /* Number of Tx descriptor registers */
+ #define NUM_RX_DESC   64      /* Number of Rx descriptor registers */
+ #define RX_BUF_SIZE   1536    /* Rx Buffer size */
++#define R8169_TX_RING_BYTES   (NUM_TX_DESC * sizeof(struct TxDesc))
++#define R8169_RX_RING_BYTES   (NUM_RX_DESC * sizeof(struct RxDesc))
+ #define RTL_MIN_IO_SIZE 0x80
+-#define TX_TIMEOUT  (6*HZ)
++#define RTL8169_TX_TIMEOUT    (6*HZ)
++#define RTL8169_PHY_TIMEOUT   (HZ) 
+ /* write/read MMIO register */
+ #define RTL_W8(reg, val8)     writeb ((val8), ioaddr + (reg))
+@@ -101,11 +106,35 @@ static int multicast_filter_limit = 32;
+ #define RTL_R16(reg)          readw (ioaddr + (reg))
+ #define RTL_R32(reg)          ((unsigned long) readl (ioaddr + (reg)))
+-static struct {
++enum mac_version {
++      RTL_GIGA_MAC_VER_B = 0x00,
++      /* RTL_GIGA_MAC_VER_C = 0x03, */
++      RTL_GIGA_MAC_VER_D = 0x01,
++      RTL_GIGA_MAC_VER_E = 0x02
++};
++
++enum phy_version {
++      RTL_GIGA_PHY_VER_C = 0x03, /* PHY Reg 0x03 bit0-3 == 0x0000 */
++      RTL_GIGA_PHY_VER_D = 0x04, /* PHY Reg 0x03 bit0-3 == 0x0000 */
++      RTL_GIGA_PHY_VER_E = 0x05, /* PHY Reg 0x03 bit0-3 == 0x0000 */
++      RTL_GIGA_PHY_VER_F = 0x06, /* PHY Reg 0x03 bit0-3 == 0x0001 */
++      RTL_GIGA_PHY_VER_G = 0x07, /* PHY Reg 0x03 bit0-3 == 0x0002 */
++};
++
++
++#define _R(NAME,MAC,MASK) \
++      { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
++
++const static struct {
+       const char *name;
+-} board_info[] __devinitdata = {
+-      {
+-"RealTek RTL8169 Gigabit Ethernet"},};
++      u8 mac_version;
++      u32 RxConfigMask;       /* Clears the bits supported by this chip */
++} rtl_chip_info[] __devinitdata = {
++      _R("RTL8169",           RTL_GIGA_MAC_VER_B, 0xff7e1880),
++      _R("RTL8169s/8110s",    RTL_GIGA_MAC_VER_D, 0xff7e1880),
++      _R("RTL8169s/8110s",    RTL_GIGA_MAC_VER_E, 0xff7e1880)
++};
++#undef _R
+ static struct pci_device_id rtl8169_pci_tbl[] = {
+       {0x10ec, 0x8169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+@@ -114,6 +143,8 @@ static struct pci_device_id rtl8169_pci_
+ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
++static int rx_copybreak = 200;
++
+ enum RTL8169_registers {
+       MAC0 = 0,               /* Ethernet hardware address. */
+       MAR0 = 8,               /* Multicast filter. */
+@@ -242,14 +273,6 @@ enum RTL8169_register_content {
+       TBILinkOK = 0x02000000,
+ };
+-const static struct {
+-      const char *name;
+-      u8 version;             /* depend on RTL8169 docs */
+-      u32 RxConfigMask;       /* should clear the bits supported by this chip */
+-} rtl_chip_info[] = {
+-      {
+-"RTL-8169", 0x00, 0xff7e1880,},};
+-
+ enum _DescStatusBit {
+       OWNbit = 0x80000000,
+       EORbit = 0x40000000,
+@@ -257,6 +280,8 @@ enum _DescStatusBit {
+       LSbit = 0x10000000,
+ };
++#define RsvdMask      0x3fffc000
++
+ struct TxDesc {
+       u32 status;
+       u32 vlan_tag;
+@@ -277,28 +302,33 @@ struct rtl8169_private {
+       struct net_device_stats stats;  /* statistics of net device */
+       spinlock_t lock;        /* spin lock flag */
+       int chipset;
+-      unsigned long cur_rx;   /* Index into the Rx descriptor buffer of next Rx pkt. */
+-      unsigned long cur_tx;   /* Index into the Tx descriptor buffer of next Rx pkt. */
+-      unsigned long dirty_tx;
+-      unsigned char *TxDescArrays;    /* Index of Tx Descriptor buffer */
+-      unsigned char *RxDescArrays;    /* Index of Rx Descriptor buffer */
++      int mac_version;
++      int phy_version;
++      u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
++      u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
++      u32 dirty_rx;
++      u32 dirty_tx;
+       struct TxDesc *TxDescArray;     /* Index of 256-alignment Tx Descriptor buffer */
+       struct RxDesc *RxDescArray;     /* Index of 256-alignment Rx Descriptor buffer */
+-      unsigned char *RxBufferRings;   /* Index of Rx Buffer  */
+-      unsigned char *RxBufferRing[NUM_RX_DESC];       /* Index of Rx Buffer array */
++      dma_addr_t TxPhyAddr;
++      dma_addr_t RxPhyAddr;
++      struct sk_buff *Rx_skbuff[NUM_RX_DESC]; /* Rx data buffers */
+       struct sk_buff *Tx_skbuff[NUM_TX_DESC]; /* Index of Transmit data buffer */
++      struct timer_list timer;
++      unsigned long phy_link_down_cnt;
+ };
+ MODULE_AUTHOR("Realtek");
+ MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
+ MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "i");
++MODULE_PARM(rx_copybreak, "i");
+ MODULE_LICENSE("GPL");
+ static int rtl8169_open(struct net_device *dev);
+ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev);
+ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance,
+                             struct pt_regs *regs);
+-static void rtl8169_init_ring(struct net_device *dev);
++static int rtl8169_init_ring(struct net_device *dev);
+ static void rtl8169_hw_start(struct net_device *dev);
+ static int rtl8169_close(struct net_device *dev);
+ static void rtl8169_set_rx_mode(struct net_device *dev);
+@@ -306,11 +336,15 @@ static void rtl8169_tx_timeout(struct ne
+ static struct net_device_stats *rtl8169_get_stats(struct net_device *netdev);
+ static const u16 rtl8169_intr_mask =
+-    SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr | TxOK |
+-    RxErr | RxOK;
++    RxUnderrun | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK;
+ static const unsigned int rtl8169_rx_config =
+     (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
++#define PHY_Cap_10_Half_Or_Less PHY_Cap_10_Half
++#define PHY_Cap_10_Full_Or_Less PHY_Cap_10_Full | PHY_Cap_10_Half_Or_Less
++#define PHY_Cap_100_Half_Or_Less PHY_Cap_100_Half | PHY_Cap_10_Full_Or_Less
++#define PHY_Cap_100_Full_Or_Less PHY_Cap_100_Full | PHY_Cap_100_Half_Or_Less
++
+ void
+ mdio_write(void *ioaddr, int RegAddr, int value)
+ {
+@@ -342,13 +376,258 @@ mdio_read(void *ioaddr, int RegAddr)
+               if (RTL_R32(PHYAR) & 0x80000000) {
+                       value = (int) (RTL_R32(PHYAR) & 0xFFFF);
+                       break;
+-              } else {
+-                      udelay(100);
+               }
++              udelay(100);
+       }
+       return value;
+ }
++static void rtl8169_write_gmii_reg_bit(void *ioaddr, int reg, int bitnum,
++                                     int bitval)
++{
++      int val;
++
++      val = mdio_read(ioaddr, reg);
++      val = (bitval == 1) ?
++              val | (bitval << bitnum) :  val & ~(0x0001 << bitnum);
++      mdio_write(ioaddr, reg, val & 0xffff); 
++}
++
++static void rtl8169_get_mac_version(struct rtl8169_private *tp, void *ioaddr)
++{
++      const struct {
++              u32 mask;
++              int mac_version;
++      } mac_info[] = {
++              { 0x1 << 26,    RTL_GIGA_MAC_VER_E },
++              { 0x1 << 23,    RTL_GIGA_MAC_VER_D }, 
++              { 0x00000000,   RTL_GIGA_MAC_VER_B } /* Catch-all */
++      }, *p = mac_info;
++      u32 reg;
++
++      reg = RTL_R32(TxConfig) & 0x7c800000;
++      while ((reg & p->mask) != p->mask)
++              p++;
++      tp->mac_version = p->mac_version;
++}
++
++static void rtl8169_print_mac_version(struct rtl8169_private *tp)
++{
++      struct {
++              int version;
++              char *msg;
++      } mac_print[] = {
++              { RTL_GIGA_MAC_VER_E, "RTL_GIGA_MAC_VER_E" },
++              { RTL_GIGA_MAC_VER_D, "RTL_GIGA_MAC_VER_D" },
++              { RTL_GIGA_MAC_VER_B, "RTL_GIGA_MAC_VER_B" },
++              { 0, NULL }
++      }, *p;
++
++      for (p = mac_print; p->msg; p++) {
++              if (tp->mac_version == p->version) {
++                      dprintk("mac_version == %s (%04d)\n", p->msg,
++                                p->version);
++                      return;
++              }
++      }
++      dprintk("mac_version == Unknown\n");
++}
++
++static void rtl8169_get_phy_version(struct rtl8169_private *tp, void *ioaddr)
++{
++      const struct {
++              u16 mask;
++              u16 set;
++              int phy_version;
++      } phy_info[] = {
++              { 0x000f, 0x0002, RTL_GIGA_PHY_VER_G },
++              { 0x000f, 0x0001, RTL_GIGA_PHY_VER_F },
++              { 0x000f, 0x0000, RTL_GIGA_PHY_VER_E },
++              { 0x0000, 0x0000, RTL_GIGA_PHY_VER_D } /* Catch-all */
++      }, *p = phy_info;
++      u16 reg;
++
++      reg = mdio_read(ioaddr, 3) & 0xffff;
++      while ((reg & p->mask) != p->set)
++              p++;
++      tp->phy_version = p->phy_version;
++}
++
++static void rtl8169_print_phy_version(struct rtl8169_private *tp)
++{
++      struct {
++              int version;
++              char *msg;
++              u32 reg;
++      } phy_print[] = {
++              { RTL_GIGA_PHY_VER_G, "RTL_GIGA_PHY_VER_G", 0x0002 },
++              { RTL_GIGA_PHY_VER_F, "RTL_GIGA_PHY_VER_F", 0x0001 },
++              { RTL_GIGA_PHY_VER_E, "RTL_GIGA_PHY_VER_E", 0x0000 },
++              { RTL_GIGA_PHY_VER_D, "RTL_GIGA_PHY_VER_D", 0x0000 },
++              { 0, NULL, 0x0000 }
++      }, *p;
++
++      for (p = phy_print; p->msg; p++) {
++              if (tp->phy_version == p->version) {
++                      dprintk("phy_version == %s (%04x)\n", p->msg, p->reg);
++                      return;
++              }
++      }
++      dprintk("phy_version == Unknown\n");
++}
++
++static void rtl8169_hw_phy_config(struct net_device *dev)
++{
++      struct rtl8169_private *tp = dev->priv;
++      void *ioaddr = tp->mmio_addr;
++      struct {
++              u16 regs[5]; /* Beware of bit-sign propagation */
++      } phy_magic[5] = { {
++              { 0x0000,       //w 4 15 12 0
++                0x00a1,       //w 3 15 0 00a1
++                0x0008,       //w 2 15 0 0008
++                0x1020,       //w 1 15 0 1020
++                0x1000 } },{  //w 0 15 0 1000
++              { 0x7000,       //w 4 15 12 7
++                0xff41,       //w 3 15 0 ff41
++                0xde60,       //w 2 15 0 de60
++                0x0140,       //w 1 15 0 0140
++                0x0077 } },{  //w 0 15 0 0077
++              { 0xa000,       //w 4 15 12 a
++                0xdf01,       //w 3 15 0 df01
++                0xdf20,       //w 2 15 0 df20
++                0xff95,       //w 1 15 0 ff95
++                0xfa00 } },{  //w 0 15 0 fa00
++              { 0xb000,       //w 4 15 12 b
++                0xff41,       //w 3 15 0 ff41
++                0xde20,       //w 2 15 0 de20
++                0x0140,       //w 1 15 0 0140
++                0x00bb } },{  //w 0 15 0 00bb
++              { 0xf000,       //w 4 15 12 f
++                0xdf01,       //w 3 15 0 df01
++                0xdf20,       //w 2 15 0 df20
++                0xff95,       //w 1 15 0 ff95
++                0xbf00 }      //w 0 15 0 bf00
++              }
++      }, *p = phy_magic;
++      int i;
++
++      rtl8169_print_mac_version(tp);
++      rtl8169_print_phy_version(tp);
++
++      if (tp->mac_version <= RTL_GIGA_MAC_VER_B)
++              return;
++      if (tp->phy_version >= RTL_GIGA_PHY_VER_F) 
++              return;
++
++      dprintk("MAC version != 0 && PHY version == 0 or 1\n");
++      dprintk("Do final_reg2.cfg\n");
++
++      /* Shazam ! */
++
++      // phy config for RTL8169s mac_version C chip
++      mdio_write(ioaddr, 31, 0x0001);                 //w 31 2 0 1
++      mdio_write(ioaddr, 21, 0x1000);                 //w 21 15 0 1000
++      mdio_write(ioaddr, 24, 0x65c7);                 //w 24 15 0 65c7
++      rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0);   //w 4 11 11 0
++
++      for (i = ARRAY_SIZE(phy_magic); i > 0; i++, p++) {
++              int val, pos = 4;
++
++              val = (mdio_read(ioaddr, pos) & 0x0fff) | (p->regs[0] & 0xffff);
++              mdio_write(ioaddr, pos, val);
++              while (--pos >= 0)
++                      mdio_write(ioaddr, pos, p->regs[4 - pos] & 0xffff);
++              rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 1); //w 4 11 11 1
++              rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0
++      }
++      mdio_write(ioaddr, 31, 0x0000); //w 31 2 0 0
++}
++
++static void rtl8169_hw_phy_reset(struct net_device *dev)
++{
++      struct rtl8169_private *tp = dev->priv;
++      void *ioaddr = tp->mmio_addr;
++      int i, val;
++
++      printk(KERN_WARNING PFX "%s: Reset RTL8169s PHY\n", dev->name);
++
++      val = (mdio_read(ioaddr, 0) | 0x8000) & 0xffff;
++      mdio_write(ioaddr, 0, val);
++
++      for (i = 50; i >= 0; i--) {
++              if (!(mdio_read(ioaddr, 0) & 0x8000))
++                      break;
++              udelay(100); /* Gross */
++      }
++
++      if (i < 0) {
++              printk(KERN_WARNING PFX "%s: no PHY Reset ack. Giving up.\n",
++                     dev->name);
++      }
++}
++
++static void rtl8169_phy_timer(unsigned long __opaque)
++{
++      struct net_device *dev = (struct net_device *)__opaque;
++      struct rtl8169_private *tp = dev->priv;
++      struct timer_list *timer = &tp->timer;
++      void *ioaddr = tp->mmio_addr;
++
++      assert(tp->mac_version > RTL_GIGA_MAC_VER_B);
++      assert(tp->phy_version < RTL_GIGA_PHY_VER_G);
++
++      if (RTL_R8(PHYstatus) & LinkStatus)
++              tp->phy_link_down_cnt = 0;
++      else {
++              tp->phy_link_down_cnt++;
++              if (tp->phy_link_down_cnt >= 12) {
++                      int reg;
++
++                      // If link on 1000, perform phy reset.
++                      reg = mdio_read(ioaddr, PHY_1000_CTRL_REG);
++                      if (reg & PHY_Cap_1000_Full) 
++                              rtl8169_hw_phy_reset(dev);
++
++                      tp->phy_link_down_cnt = 0;
++              }
++      }
++
++      mod_timer(timer, RTL8169_PHY_TIMEOUT);
++}
++
++static inline void rtl8169_delete_timer(struct net_device *dev)
++{
++      struct rtl8169_private *tp = dev->priv;
++      struct timer_list *timer = &tp->timer;
++
++      if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
++          (tp->phy_version >= RTL_GIGA_PHY_VER_G))
++              return;
++
++      del_timer_sync(timer);
++
++      tp->phy_link_down_cnt = 0;
++}
++
++static inline void rtl8169_request_timer(struct net_device *dev)
++{
++      struct rtl8169_private *tp = dev->priv;
++      struct timer_list *timer = &tp->timer;
++
++      if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
++          (tp->phy_version >= RTL_GIGA_PHY_VER_G))
++              return;
++
++      tp->phy_link_down_cnt = 0;
++
++      init_timer(timer);
++      timer->expires = jiffies + RTL8169_PHY_TIMEOUT;
++      timer->data = (unsigned long)(dev);
++      timer->function = rtl8169_phy_timer;
++      add_timer(timer);
++}
++
+ static int __devinit
+ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
+                  void **ioaddr_out)
+@@ -356,9 +635,9 @@ rtl8169_init_board(struct pci_dev *pdev,
+       void *ioaddr = NULL;
+       struct net_device *dev;
+       struct rtl8169_private *tp;
+-      int rc, i;
+       unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
+-      u32 tmp;
++      int rc, i, acpi_idle_state = 0, pm_cap;
++
+       assert(pdev != NULL);
+       assert(ioaddr_out != NULL);
+@@ -379,8 +658,22 @@ rtl8169_init_board(struct pci_dev *pdev,
+       // enable device (incl. PCI PM wakeup and hotplug setup)
+       rc = pci_enable_device(pdev);
+-      if (rc)
++      if (rc) {
++              printk(KERN_ERR PFX "%s: unable to enable device\n", pdev->slot_name);
+               goto err_out;
++      }
++
++      /* save power state before pci_enable_device overwrites it */
++      pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
++      if (pm_cap) {
++              u16 pwr_command;
++
++              pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
++              acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
++      } else {
++              printk(KERN_ERR PFX "Cannot find PowerManagement capability, aborting.\n");
++              goto err_out_free_res;
++      }
+       mmio_start = pci_resource_start(pdev, 1);
+       mmio_end = pci_resource_end(pdev, 1);
+@@ -402,8 +695,10 @@ rtl8169_init_board(struct pci_dev *pdev,
+       }
+       rc = pci_request_regions(pdev, dev->name);
+-      if (rc)
++      if (rc) {
++              printk(KERN_ERR PFX "%s: Could not request regions.\n", pdev->slot_name);
+               goto err_out_disable;
++      }
+       // enable PCI bus-mastering
+       pci_set_master(pdev);
+@@ -420,30 +715,32 @@ rtl8169_init_board(struct pci_dev *pdev,
+       RTL_W8(ChipCmd, CmdReset);
+       // Check that the chip has finished the reset.
+-      for (i = 1000; i > 0; i--)
++      for (i = 1000; i > 0; i--) {
+               if ((RTL_R8(ChipCmd) & CmdReset) == 0)
+                       break;
+-              else
+-                      udelay(10);
++              udelay(10);
++      }
+-      // identify chip attached to board
+-      tmp = RTL_R32(TxConfig);
+-      tmp = ((tmp & 0x7c000000) + ((tmp & 0x00800000) << 2)) >> 24;
+-
+-      for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--)
+-              if (tmp == rtl_chip_info[i].version) {
+-                      tp->chipset = i;
+-                      goto match;
+-              }
+-      //if unknown chip, assume array element #0, original RTL-8169 in this case
+-      printk(KERN_DEBUG PFX
+-             "PCI device %s: unknown chip version, assuming RTL-8169\n",
+-             pci_name(pdev));
+-      printk(KERN_DEBUG PFX "PCI device %s: TxConfig = 0x%lx\n",
+-             pci_name(pdev), (unsigned long) RTL_R32(TxConfig));
+-      tp->chipset = 0;
++      // Identify chip attached to board
++      rtl8169_get_mac_version(tp, ioaddr);
++      rtl8169_get_phy_version(tp, ioaddr);
++
++      rtl8169_print_mac_version(tp);
++      rtl8169_print_phy_version(tp);
++
++      for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) {
++              if (tp->mac_version == rtl_chip_info[i].mac_version)
++                      break;
++      }
++      if (i < 0) {
++              /* Unknown chip: assume array element #0, original RTL-8169 */
++              printk(KERN_DEBUG PFX
++                     "PCI device %s: unknown chip version, assuming %s\n",
++                     pci_name(pdev), rtl_chip_info[0].name);
++              i++;
++      }
++      tp->chipset = i;
+-match:
+       *ioaddr_out = ioaddr;
+       *dev_out = dev;
+       return 0;
+@@ -499,7 +796,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
+       dev->stop = rtl8169_close;
+       dev->tx_timeout = rtl8169_tx_timeout;
+       dev->set_multicast_list = rtl8169_set_rx_mode;
+-      dev->watchdog_timeo = TX_TIMEOUT;
++      dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
+       dev->irq = pdev->irq;
+       dev->base_addr = (unsigned long) ioaddr;
+ //      dev->do_ioctl           = mii_ioctl;
+@@ -528,12 +825,29 @@ rtl8169_init_one(struct pci_dev *pdev, c
+              "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
+              "IRQ %d\n",
+              dev->name,
+-             board_info[ent->driver_data].name,
++             rtl_chip_info[ent->driver_data].name,
+              dev->base_addr,
+              dev->dev_addr[0], dev->dev_addr[1],
+              dev->dev_addr[2], dev->dev_addr[3],
+              dev->dev_addr[4], dev->dev_addr[5], dev->irq);
++      rtl8169_hw_phy_config(dev);
++
++      dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
++      RTL_W8(0x82, 0x01);
++
++      if (tp->mac_version < RTL_GIGA_MAC_VER_E) {
++              dprintk("Set PCI Latency=0x40\n");
++              pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
++      }
++
++      if (tp->mac_version == RTL_GIGA_MAC_VER_D) {
++              dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
++              RTL_W8(0x82, 0x01);
++              dprintk("Set PHY Reg 0x0bh = 0x00h\n");
++              mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
++      }
++
+       // if TBI is not endbled
+       if (!(RTL_R8(PHYstatus) & TBI_Enable)) {
+               int val = mdio_read(ioaddr, PHY_AUTO_NEGO_REG);
+@@ -546,23 +860,23 @@ rtl8169_init_one(struct pci_dev *pdev, c
+                       Cap10_100 = 0, Cap1000 = 0;
+                       switch (option) {
+                       case _10_Half:
+-                              Cap10_100 = PHY_Cap_10_Half;
++                              Cap10_100 = PHY_Cap_10_Half_Or_Less;
+                               Cap1000 = PHY_Cap_Null;
+                               break;
+                       case _10_Full:
+-                              Cap10_100 = PHY_Cap_10_Full;
++                              Cap10_100 = PHY_Cap_10_Full_Or_Less;
+                               Cap1000 = PHY_Cap_Null;
+                               break;
+                       case _100_Half:
+-                              Cap10_100 = PHY_Cap_100_Half;
++                              Cap10_100 = PHY_Cap_100_Half_Or_Less;
+                               Cap1000 = PHY_Cap_Null;
+                               break;
+                       case _100_Full:
+-                              Cap10_100 = PHY_Cap_100_Full;
++                              Cap10_100 = PHY_Cap_100_Full_Or_Less;
+                               Cap1000 = PHY_Cap_Null;
+                               break;
+                       case _1000_Full:
+-                              Cap10_100 = PHY_Cap_Null;
++                              Cap10_100 = PHY_Cap_100_Full_Or_Less;
+                               Cap1000 = PHY_Cap_1000_Full;
+                               break;
+                       default:
+@@ -576,9 +890,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
+                       // enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
+                       mdio_write(ioaddr, PHY_AUTO_NEGO_REG,
+-                                 PHY_Cap_10_Half | PHY_Cap_10_Full |
+-                                 PHY_Cap_100_Half | PHY_Cap_100_Full | (val &
+-                                                                        0x1F));
++                                 PHY_Cap_100_Full_Or_Less | (val & 0x1f));
+                       // enable 1000 Full Mode
+                       mdio_write(ioaddr, PHY_1000_CTRL_REG,
+@@ -647,56 +959,96 @@ rtl8169_remove_one(struct pci_dev *pdev)
+       pci_set_drvdata(pdev, NULL);
+ }
++#ifdef CONFIG_PM
++
++static int rtl8169_suspend(struct pci_dev *pdev, u32 state)
++{
++      struct net_device *dev = pci_get_drvdata(pdev);
++      struct rtl8169_private *tp = dev->priv;
++      void *ioaddr = tp->mmio_addr;
++      unsigned long flags;
++
++      if (!netif_running(dev))
++              return 0;
++      
++      netif_device_detach(dev);
++      netif_stop_queue(dev);
++      spin_lock_irqsave(&tp->lock, flags);
++
++      /* Disable interrupts, stop Rx and Tx */
++      RTL_W16(IntrMask, 0);
++      RTL_W8(ChipCmd, 0);
++              
++      /* Update the error counts. */
++      tp->stats.rx_missed_errors += RTL_R32(RxMissed);
++      RTL_W32(RxMissed, 0);
++      spin_unlock_irqrestore(&tp->lock, flags);
++      
++      return 0;
++}
++
++static int rtl8169_resume(struct pci_dev *pdev)
++{
++      struct net_device *dev = pci_get_drvdata(pdev);
++
++      if (!netif_running(dev))
++          return 0;
++
++      netif_device_attach(dev);
++      rtl8169_hw_start(dev);
++
++      return 0;
++}
++                                                                                
++#endif /* CONFIG_PM */
++
+ static int
+ rtl8169_open(struct net_device *dev)
+ {
+       struct rtl8169_private *tp = dev->priv;
++      struct pci_dev *pdev = tp->pci_dev;
+       int retval;
+-      u8 diff;
+-      u32 TxPhyAddr, RxPhyAddr;
+       retval =
+           request_irq(dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev);
+-      if (retval) {
+-              return retval;
+-      }
++      if (retval < 0)
++              goto out;
+-      tp->TxDescArrays =
+-          kmalloc(NUM_TX_DESC * sizeof (struct TxDesc) + 256, GFP_KERNEL);
+-      // Tx Desscriptor needs 256 bytes alignment;
+-      TxPhyAddr = virt_to_bus(tp->TxDescArrays);
+-      diff = 256 - (TxPhyAddr - ((TxPhyAddr >> 8) << 8));
+-      TxPhyAddr += diff;
+-      tp->TxDescArray = (struct TxDesc *) (tp->TxDescArrays + diff);
+-
+-      tp->RxDescArrays =
+-          kmalloc(NUM_RX_DESC * sizeof (struct RxDesc) + 256, GFP_KERNEL);
+-      // Rx Desscriptor needs 256 bytes alignment;
+-      RxPhyAddr = virt_to_bus(tp->RxDescArrays);
+-      diff = 256 - (RxPhyAddr - ((RxPhyAddr >> 8) << 8));
+-      RxPhyAddr += diff;
+-      tp->RxDescArray = (struct RxDesc *) (tp->RxDescArrays + diff);
++      retval = -ENOMEM;
+-      if (tp->TxDescArrays == NULL || tp->RxDescArrays == NULL) {
+-              printk(KERN_INFO
+-                     "Allocate RxDescArray or TxDescArray failed\n");
+-              free_irq(dev->irq, dev);
+-              if (tp->TxDescArrays)
+-                      kfree(tp->TxDescArrays);
+-              if (tp->RxDescArrays)
+-                      kfree(tp->RxDescArrays);
+-              return -ENOMEM;
+-      }
+-      tp->RxBufferRings = kmalloc(RX_BUF_SIZE * NUM_RX_DESC, GFP_KERNEL);
+-      if (tp->RxBufferRings == NULL) {
+-              printk(KERN_INFO "Allocate RxBufferRing failed\n");
+-      }
++      /*
++       * Rx and Tx desscriptors needs 256 bytes alignment.
++       * pci_alloc_consistent provides more.
++       */
++      tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES,
++                                             &tp->TxPhyAddr);
++      if (!tp->TxDescArray)
++              goto err_free_irq;
++
++      tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES,
++                                             &tp->RxPhyAddr);
++      if (!tp->RxDescArray)
++              goto err_free_tx;
++
++      retval = rtl8169_init_ring(dev);
++      if (retval < 0)
++              goto err_free_rx;
+-      rtl8169_init_ring(dev);
+       rtl8169_hw_start(dev);
+-      return 0;
+-
++      rtl8169_request_timer(dev);
++out:
++      return retval;
++
++err_free_rx:
++      pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
++                          tp->RxPhyAddr);
++err_free_tx:
++      pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
++                          tp->TxPhyAddr);
++err_free_irq:
++      free_irq(dev->irq, dev);
++      goto out;
+ }
+ static void
+@@ -733,11 +1085,17 @@ rtl8169_hw_start(struct net_device *dev)
+       RTL_W32(TxConfig,
+               (TX_DMA_BURST << TxDMAShift) | (InterFrameGap <<
+                                               TxInterFrameGapShift));
++      RTL_W16(CPlusCmd, RTL_R16(CPlusCmd));
++
++      if (tp->mac_version == RTL_GIGA_MAC_VER_D) {
++              dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14 MUST be 1\n");
++              RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) | (1 << 14) | (1 << 3));
++      }
+       tp->cur_rx = 0;
+-      RTL_W32(TxDescStartAddr, virt_to_bus(tp->TxDescArray));
+-      RTL_W32(RxDescStartAddr, virt_to_bus(tp->RxDescArray));
++      RTL_W32(TxDescStartAddr, tp->TxPhyAddr);
++      RTL_W32(RxDescStartAddr, tp->RxPhyAddr);
+       RTL_W8(Cfg9346, Cfg9346_Lock);
+       udelay(10);
+@@ -755,31 +1113,131 @@ rtl8169_hw_start(struct net_device *dev)
+ }
+-static void
+-rtl8169_init_ring(struct net_device *dev)
++static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc)
++{
++      desc->buf_addr = 0xdeadbeef;
++      desc->status &= ~cpu_to_le32(OWNbit | RsvdMask);
++}
++
++static void rtl8169_free_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
++                              struct RxDesc *desc)
++{
++      pci_unmap_single(pdev, le32_to_cpu(desc->buf_addr), RX_BUF_SIZE,
++                       PCI_DMA_FROMDEVICE);
++      dev_kfree_skb(*sk_buff);
++      *sk_buff = NULL;
++      rtl8169_make_unusable_by_asic(desc);
++}
++
++static inline void rtl8169_return_to_asic(struct RxDesc *desc)
++{
++      desc->status |= cpu_to_le32(OWNbit + RX_BUF_SIZE);
++}
++
++static inline void rtl8169_give_to_asic(struct RxDesc *desc, dma_addr_t mapping)
++{
++      desc->buf_addr = cpu_to_le32(mapping);
++      desc->status |= cpu_to_le32(OWNbit + RX_BUF_SIZE);
++}
++
++static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct net_device *dev,
++                              struct sk_buff **sk_buff, struct RxDesc *desc)
++{
++      struct sk_buff *skb;
++      dma_addr_t mapping;
++      int ret = 0;
++
++      skb = dev_alloc_skb(RX_BUF_SIZE);
++      if (!skb)
++              goto err_out;
++
++      skb->dev = dev;
++      skb_reserve(skb, 2);
++      *sk_buff = skb;
++
++      mapping = pci_map_single(pdev, skb->tail, RX_BUF_SIZE,
++                               PCI_DMA_FROMDEVICE);
++
++      rtl8169_give_to_asic(desc, mapping);
++
++out:
++      return ret;
++
++err_out:
++      ret = -ENOMEM;
++      rtl8169_make_unusable_by_asic(desc);
++      goto out;
++}
++
++static void rtl8169_rx_clear(struct rtl8169_private *tp)
+ {
+-      struct rtl8169_private *tp = dev->priv;
+       int i;
+-      tp->cur_rx = 0;
+-      tp->cur_tx = 0;
+-      tp->dirty_tx = 0;
++      for (i = 0; i < NUM_RX_DESC; i++) {
++              if (tp->Rx_skbuff[i]) {
++                      rtl8169_free_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
++                                          tp->RxDescArray + i);
++              }
++      }
++}
++
++static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev,
++                         u32 start, u32 end)
++{
++      u32 cur;
++      
++      for (cur = start; end - start > 0; cur++) {
++              int ret, i = cur % NUM_RX_DESC;
++
++              if (tp->Rx_skbuff[i])
++                      continue;
++                      
++              ret = rtl8169_alloc_rx_skb(tp->pci_dev, dev, tp->Rx_skbuff + i,
++                                         tp->RxDescArray + i);
++              if (ret < 0)
++                      break;
++      }
++      return cur - start;
++}
++
++static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc)
++{
++      desc->status |= cpu_to_le32(EORbit);
++}
++
++static int rtl8169_init_ring(struct net_device *dev)
++{
++      struct rtl8169_private *tp = dev->priv;
++
++      tp->cur_rx = tp->dirty_rx = 0;
++      tp->cur_tx = tp->dirty_tx = 0;
+       memset(tp->TxDescArray, 0x0, NUM_TX_DESC * sizeof (struct TxDesc));
+       memset(tp->RxDescArray, 0x0, NUM_RX_DESC * sizeof (struct RxDesc));
+-      for (i = 0; i < NUM_TX_DESC; i++) {
+-              tp->Tx_skbuff[i] = NULL;
+-      }
+-      for (i = 0; i < NUM_RX_DESC; i++) {
+-              if (i == (NUM_RX_DESC - 1))
+-                      tp->RxDescArray[i].status =
+-                          (OWNbit | EORbit) + RX_BUF_SIZE;
+-              else
+-                      tp->RxDescArray[i].status = OWNbit + RX_BUF_SIZE;
++      memset(tp->Tx_skbuff, 0x0, NUM_TX_DESC * sizeof(struct sk_buff *));
++      memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
+-              tp->RxBufferRing[i] = &(tp->RxBufferRings[i * RX_BUF_SIZE]);
+-              tp->RxDescArray[i].buf_addr = virt_to_bus(tp->RxBufferRing[i]);
+-      }
++      if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC)
++              goto err_out;
++
++      rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1);
++
++      return 0;
++
++err_out:
++      rtl8169_rx_clear(tp);
++      return -ENOMEM;
++}
++
++static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
++                               struct TxDesc *desc)
++{
++      u32 len = sk_buff[0]->len;
++
++      pci_unmap_single(pdev, le32_to_cpu(desc->buf_addr),
++                       len < ETH_ZLEN ? ETH_ZLEN : len, PCI_DMA_TODEVICE);
++      desc->buf_addr = 0x00;
++      *sk_buff = NULL;
+ }
+ static void
+@@ -789,9 +1247,12 @@ rtl8169_tx_clear(struct rtl8169_private 
+       tp->cur_tx = 0;
+       for (i = 0; i < NUM_TX_DESC; i++) {
+-              if (tp->Tx_skbuff[i] != NULL) {
+-                      dev_kfree_skb(tp->Tx_skbuff[i]);
+-                      tp->Tx_skbuff[i] = NULL;
++              struct sk_buff *skb = tp->Tx_skbuff[i];
++
++              if (skb) {
++                      rtl8169_unmap_tx_skb(tp->pci_dev, tp->Tx_skbuff + i,
++                                           tp->TxDescArray + i);
++                      dev_kfree_skb(skb);
+                       tp->stats.tx_dropped++;
+               }
+       }
+@@ -829,41 +1290,51 @@ rtl8169_start_xmit(struct sk_buff *skb, 
+       struct rtl8169_private *tp = dev->priv;
+       void *ioaddr = tp->mmio_addr;
+       int entry = tp->cur_tx % NUM_TX_DESC;
++      u32 len = skb->len;
+-      if (skb->len < ETH_ZLEN) {
++      if (unlikely(skb->len < ETH_ZLEN)) {
+               skb = skb_padto(skb, ETH_ZLEN);
+-              if (skb == NULL)
+-                      return 0;
++              if (!skb)
++                      goto err_update_stats;
++              len = ETH_ZLEN;
+       }
+       
+       spin_lock_irq(&tp->lock);
+-      if ((tp->TxDescArray[entry].status & OWNbit) == 0) {
++      if (!(le32_to_cpu(tp->TxDescArray[entry].status) & OWNbit)) {
++              dma_addr_t mapping;
++
++              mapping = pci_map_single(tp->pci_dev, skb->data, len,
++                                       PCI_DMA_TODEVICE);
++
+               tp->Tx_skbuff[entry] = skb;
+-              tp->TxDescArray[entry].buf_addr = virt_to_bus(skb->data);
+-              if (entry != (NUM_TX_DESC - 1))
+-                      tp->TxDescArray[entry].status =
+-                          (OWNbit | FSbit | LSbit) | ((skb->len > ETH_ZLEN) ?
+-                                                      skb->len : ETH_ZLEN);
+-              else
+-                      tp->TxDescArray[entry].status =
+-                          (OWNbit | EORbit | FSbit | LSbit) |
+-                          ((skb->len > ETH_ZLEN) ? skb->len : ETH_ZLEN);
++              tp->TxDescArray[entry].buf_addr = cpu_to_le32(mapping);
++              tp->TxDescArray[entry].status = cpu_to_le32(OWNbit | FSbit |
++                      LSbit | len | (EORbit * !((entry + 1) % NUM_TX_DESC)));
++                      
+               RTL_W8(TxPoll, 0x40);   //set polling bit
+               dev->trans_start = jiffies;
+               tp->cur_tx++;
+-      }
++      } else
++              goto err_drop;
+-      spin_unlock_irq(&tp->lock);
+       if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx) {
+               netif_stop_queue(dev);
+       }
++out:
++      spin_unlock_irq(&tp->lock);
+       return 0;
++
++err_drop:
++      dev_kfree_skb(skb);
++err_update_stats:
++      tp->stats.tx_dropped++;
++      goto out;
+ }
+ static void
+@@ -881,11 +1352,17 @@ rtl8169_tx_interrupt(struct net_device *
+       tx_left = tp->cur_tx - dirty_tx;
+       while (tx_left > 0) {
+-              if ((tp->TxDescArray[entry].status & OWNbit) == 0) {
+-                      dev_kfree_skb_irq(tp->
+-                                        Tx_skbuff[dirty_tx % NUM_TX_DESC]);
+-                      tp->Tx_skbuff[dirty_tx % NUM_TX_DESC] = NULL;
++              if (!(le32_to_cpu(tp->TxDescArray[entry].status) & OWNbit)) {
++                      int cur = dirty_tx % NUM_TX_DESC;
++                      struct sk_buff *skb = tp->Tx_skbuff[cur];
++
++                      /* FIXME: is it really accurate for TxErr ? */
++                      tp->stats.tx_bytes += skb->len >= ETH_ZLEN ?
++                                            skb->len : ETH_ZLEN;
+                       tp->stats.tx_packets++;
++                      rtl8169_unmap_tx_skb(tp->pci_dev, tp->Tx_skbuff + cur,
++                                           tp->TxDescArray + cur);
++                      dev_kfree_skb_irq(skb);
+                       dirty_tx++;
+                       tx_left--;
+                       entry++;
+@@ -899,70 +1376,95 @@ rtl8169_tx_interrupt(struct net_device *
+       }
+ }
++static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
++                                    struct RxDesc *desc,
++                                    struct net_device *dev)
++{
++      int ret = -1;
++
++      if (pkt_size < rx_copybreak) {
++              struct sk_buff *skb;
++
++              skb = dev_alloc_skb(pkt_size + 2);
++              if (skb) {
++                      skb->dev = dev;
++                      skb_reserve(skb, 2);
++                      eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0);
++                      *sk_buff = skb;
++                      rtl8169_return_to_asic(desc);
++                      ret = 0;
++              }
++      }
++      return ret;
++}
++
+ static void
+ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
+                    void *ioaddr)
+ {
+-      int cur_rx;
+-      struct sk_buff *skb;
+-      int pkt_size = 0;
++      int cur_rx, delta;
+       assert(dev != NULL);
+       assert(tp != NULL);
+       assert(ioaddr != NULL);
+-      cur_rx = tp->cur_rx;
++      cur_rx = tp->cur_rx % RX_BUF_SIZE;
+-      while ((tp->RxDescArray[cur_rx].status & OWNbit) == 0) {
++      while (!(le32_to_cpu(tp->RxDescArray[cur_rx].status) & OWNbit)) {
++              u32 status = le32_to_cpu(tp->RxDescArray[cur_rx].status);
+-              if (tp->RxDescArray[cur_rx].status & RxRES) {
++              if (status & RxRES) {
+                       printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name);
+                       tp->stats.rx_errors++;
+-                      if (tp->RxDescArray[cur_rx].status & (RxRWT | RxRUNT))
++                      if (status & (RxRWT | RxRUNT))
+                               tp->stats.rx_length_errors++;
+-                      if (tp->RxDescArray[cur_rx].status & RxCRC)
++                      if (status & RxCRC)
+                               tp->stats.rx_crc_errors++;
+               } else {
+-                      pkt_size =
+-                          (int) (tp->RxDescArray[cur_rx].
+-                                 status & 0x00001FFF) - 4;
+-                      skb = dev_alloc_skb(pkt_size + 2);
+-                      if (skb != NULL) {
+-                              skb->dev = dev;
+-                              skb_reserve(skb, 2);    // 16 byte align the IP fields. //
+-                              eth_copy_and_sum(skb, tp->RxBufferRing[cur_rx],
+-                                               pkt_size, 0);
+-                              skb_put(skb, pkt_size);
+-                              skb->protocol = eth_type_trans(skb, dev);
+-                              netif_rx(skb);
+-
+-                              if (cur_rx == (NUM_RX_DESC - 1))
+-                                      tp->RxDescArray[cur_rx].status =
+-                                          (OWNbit | EORbit) + RX_BUF_SIZE;
+-                              else
+-                                      tp->RxDescArray[cur_rx].status =
+-                                          OWNbit + RX_BUF_SIZE;
+-
+-                              tp->RxDescArray[cur_rx].buf_addr =
+-                                  virt_to_bus(tp->RxBufferRing[cur_rx]);
+-                              dev->last_rx = jiffies;
+-                              tp->stats.rx_bytes += pkt_size;
+-                              tp->stats.rx_packets++;
+-                      } else {
+-                              printk(KERN_WARNING
+-                                     "%s: Memory squeeze, deferring packet.\n",
+-                                     dev->name);
+-                              /* We should check that some rx space is free.
+-                                 If not, free one and mark stats->rx_dropped++. */
+-                              tp->stats.rx_dropped++;
++                      struct RxDesc *desc = tp->RxDescArray + cur_rx;
++                      struct sk_buff *skb = tp->Rx_skbuff[cur_rx];
++                      int pkt_size = (status & 0x00001FFF) - 4;
++
++                      pci_dma_sync_single(tp->pci_dev,
++                                          le32_to_cpu(desc->buf_addr),
++                                          RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
++
++                      if (rtl8169_try_rx_copy(&skb, pkt_size, desc, dev)) {
++                              pci_unmap_single(tp->pci_dev,
++                                               le32_to_cpu(desc->buf_addr),
++                                               RX_BUF_SIZE,
++                                               PCI_DMA_FROMDEVICE);
++                              tp->Rx_skbuff[cur_rx] = NULL;
+                       }
+-              }
+-
+-              cur_rx = (cur_rx + 1) % NUM_RX_DESC;
+-
+-      }
+-      tp->cur_rx = cur_rx;
++                      skb_put(skb, pkt_size);
++                      skb->protocol = eth_type_trans(skb, dev);
++                      netif_rx(skb);
++
++                      dev->last_rx = jiffies;
++                      tp->stats.rx_bytes += pkt_size;
++                      tp->stats.rx_packets++;
++              }
++              
++              tp->cur_rx++; 
++              cur_rx = tp->cur_rx % NUM_RX_DESC;
++      }
++
++      delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
++      if (delta > 0)
++              tp->dirty_rx += delta;
++      else if (delta < 0)
++              printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name);
++
++      /*
++       * FIXME: until there is periodic timer to try and refill the ring,
++       * a temporary shortage may definitely kill the Rx process.
++       * - disable the asic to try and avoid an overflow and kick it again
++       *   after refill ?
++       * - how do others driver handle this condition (Uh oh...).
++       */
++      if (tp->dirty_rx + NUM_RX_DESC == tp->cur_rx)
++              printk(KERN_EMERG "%s: Rx buffers exhausted\n", dev->name);
+ }
+ /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */
+@@ -991,9 +1493,7 @@ rtl8169_interrupt(int irq, void *dev_ins
+               RTL_W16(IntrStatus,
+                       (status & RxFIFOOver) ? (status | RxOverflow) : status);
+-              if ((status &
+-                   (SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver
+-                    | TxErr | TxOK | RxErr | RxOK)) == 0)
++              if (!(status & rtl8169_intr_mask))
+                       break;
+               // Rx interrupt 
+@@ -1023,11 +1523,13 @@ static int
+ rtl8169_close(struct net_device *dev)
+ {
+       struct rtl8169_private *tp = dev->priv;
++      struct pci_dev *pdev = tp->pci_dev;
+       void *ioaddr = tp->mmio_addr;
+-      int i;
+       netif_stop_queue(dev);
++      rtl8169_delete_timer(dev);
++
+       spin_lock_irq(&tp->lock);
+       /* Stop the chip's Tx and Rx DMA processes. */
+@@ -1046,16 +1548,15 @@ rtl8169_close(struct net_device *dev)
+       free_irq(dev->irq, dev);
+       rtl8169_tx_clear(tp);
+-      kfree(tp->TxDescArrays);
+-      kfree(tp->RxDescArrays);
+-      tp->TxDescArrays = NULL;
+-      tp->RxDescArrays = NULL;
++
++      rtl8169_rx_clear(tp);
++
++      pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
++                          tp->RxPhyAddr);
++      pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
++                          tp->TxPhyAddr);
+       tp->TxDescArray = NULL;
+       tp->RxDescArray = NULL;
+-      kfree(tp->RxBufferRings);
+-      for (i = 0; i < NUM_RX_DESC; i++) {
+-              tp->RxBufferRing[i] = NULL;
+-      }
+       return 0;
+ }
+@@ -1109,11 +1610,26 @@ rtl8169_set_rx_mode(struct net_device *d
+       spin_unlock_irqrestore(&tp->lock, flags);
+ }
++/**
++ *  rtl8169_get_stats - Get rtl8169 read/write statistics
++ *  @dev: The Ethernet Device to get statistics for
++ *
++ *  Get TX/RX statistics for rtl8169
++ */
+ struct net_device_stats *
+ rtl8169_get_stats(struct net_device *dev)
+ {
+       struct rtl8169_private *tp = dev->priv;
++      void *ioaddr = tp->mmio_addr;
++      unsigned long flags;
++      if (netif_running(dev)) {
++              spin_lock_irqsave(&tp->lock, flags);
++              tp->stats.rx_missed_errors += RTL_R32(RxMissed);
++              RTL_W32(RxMissed, 0);
++              spin_unlock_irqrestore(&tp->lock, flags);
++      }
++              
+       return &tp->stats;
+ }
+@@ -1122,8 +1638,10 @@ static struct pci_driver rtl8169_pci_dri
+       .id_table       = rtl8169_pci_tbl,
+       .probe          = rtl8169_init_one,
+       .remove         = __devexit_p(rtl8169_remove_one),
+-      .suspend        = NULL,
+-      .resume         = NULL,
++#ifdef CONFIG_PM
++      .suspend        = rtl8169_suspend,
++      .resume         = rtl8169_resume,
++#endif
+ };
+ static int __init
+--- linux-2.6.0/drivers/net/saa9730.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/saa9730.c   2003-12-28 23:21:01.000000000 -0800
+@@ -996,11 +996,11 @@ static void __devexit saa9730_remove_one
+         struct net_device *dev = pci_get_drvdata(pdev);
+         if (dev) {
+-              
++                unregister_netdev(dev);
++
+               if (dev->priv)
+                       kfree(dev->priv);
+-                unregister_netdev(dev);
+                 free_netdev(dev);
+                 pci_release_regions(pdev);
+                 pci_disable_device(pdev);
+@@ -1015,17 +1015,10 @@ static int lan_saa9730_init(struct net_d
+       unsigned char ethernet_addr[6];
+       int ret = 0;
+-      dev = init_etherdev(dev, 0);
+-
+-      if (!dev) 
+-              return -ENOMEM;
+-      
+       dev->open = lan_saa9730_open_fail;
+-      if (get_ethernet_addr(ethernet_addr)) {
+-              ret = -ENODEV;
+-              goto out;
+-      }
++      if (get_ethernet_addr(ethernet_addr))
++              return -ENODEV;
+       
+       memcpy(dev->dev_addr, ethernet_addr, 6);
+       dev->base_addr = ioaddr;
+@@ -1040,10 +1033,8 @@ static int lan_saa9730_init(struct net_d
+                                                     GFP_DMA | GFP_KERNEL)
+                                             + 7) & ~7);
+-      if (!lp) {
+-              ret = -ENOMEM;
+-                goto out;
+-        }
++      if (!lp)
++              return -ENOMEM;
+       dev->priv = lp;
+       memset(lp, 0, sizeof(*lp));
+@@ -1057,6 +1048,7 @@ static int lan_saa9730_init(struct net_d
+                                                        SAA9730_EVM_REGS_ADDR);
+       /* Allocate LAN RX/TX frame buffer space. */
++      /* FIXME: a leak */
+       if ((ret = lan_saa9730_allocate_buffers(lp)))
+               goto out;
+@@ -1095,63 +1087,70 @@ static int lan_saa9730_init(struct net_d
+       dev->watchdog_timeo = (HZ >> 1);
+       dev->dma = 0;
+       
++      ret = register_netdev(dev);
++      if (ret)
++              goto out;
+       return 0;
+  out:
+-      if (dev) {
+-              if (dev->priv)
+-                      kfree(dev->priv);
+-              unregister_netdevice(dev);
+-              free_netdev(dev);
+-      }
+-              
++      if (dev->priv)
++              kfree(dev->priv);
++      free_netdev(dev);
+       return ret;
+ }
+ static int __devinit saa9730_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+-      struct net_device *dev = NULL;
++      struct net_device *dev;
+       unsigned int pci_ioaddr;
+       int err;
+       if (lan_saa9730_debug > 1)
+               printk("saa9730.c: PCI bios is present, checking for devices...\n");
++      err = -ENOMEM;
++      dev = alloc_etherdev(0);
++      if (!dev)
++              goto out;
++
++      SET_MODULE_OWNER(dev);
++
+       err = pci_enable_device(pdev);
+         if (err) {
+                 printk(KERN_ERR "Cannot enable PCI device, aborting.\n");
+-                goto out;
++                goto out1;
+         }
+       err = pci_request_regions(pdev, DRV_MODULE_NAME);
+       if (err) {
+               printk(KERN_ERR "Cannot obtain PCI resources, aborting.\n");
+-              goto out_disable_pdev;
++              goto out2;
+       }
+       pci_irq_line = pdev->irq;
+       /* LAN base address in located at BAR 1. */
+-      
++
+       pci_ioaddr = pci_resource_start(pdev, 1);
+       pci_set_master(pdev);
+-      
++
+       printk("Found SAA9730 (PCI) at %#x, irq %d.\n",
+              pci_ioaddr, pci_irq_line);
+       err = lan_saa9730_init(dev, pci_ioaddr, pci_irq_line);
+       if (err) {
+               printk("Lan init failed");
+-              goto out_disable_pdev;
++              goto out2;
+       }
+-      
++
+       pci_set_drvdata(pdev, dev);
+       return 0;
+       
+- out_disable_pdev:
++out2:
+       pci_disable_device(pdev);
+- out:
+-      pci_set_drvdata(pdev, NULL);
++out1:
++      free_netdev(dev);
++out:
+       return err;
+ }
+--- linux-2.6.0/drivers/net/sb1250-mac.c       2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/sb1250-mac.c        2003-12-28 23:21:01.000000000 -0800
+@@ -2372,6 +2372,7 @@ static int sbmac_init(struct net_device 
+       unsigned char *eaddr;
+       uint64_t ea_reg;
+       int i;
++      int err;
+       
+       sc = (struct sbmac_softc *)dev->priv;
+       
+@@ -2430,7 +2431,6 @@ static int sbmac_init(struct net_device 
+       
+       spin_lock_init(&(sc->sbm_lock));
+       
+-      ether_setup(dev);
+       dev->open               = sbmac_open;
+       dev->hard_start_xmit    = sbmac_start_tx;
+       dev->stop               = sbmac_close;
+@@ -2444,8 +2444,11 @@ static int sbmac_init(struct net_device 
+       /* This is needed for PASS2 for Rx H/W checksum feature */
+       sbmac_set_iphdr_offset(sc);
+-      
+-      return 0;
++
++      err = register_netdev(dev);
++      if (err)
++              sbmac_uninitctx(sc);
++      return err;
+ }
+@@ -2811,13 +2814,12 @@ sbmac_setup_hwaddr(int chan,char *addr)
+ }
+ #endif
+-static struct net_device *dev_sbmac[MAX_UNITS] = {0,0,0};
++static struct net_device *dev_sbmac[MAX_UNITS];
+ static int __init
+ sbmac_init_module(void)
+ {
+       int idx;
+-      int macidx = 0;
+       struct net_device *dev;
+       sbmac_port_t port;
+       int chip_max_units;
+@@ -2884,26 +2886,24 @@ sbmac_init_module(void)
+                * Okay, cool.  Initialize this MAC.
+                */
+-              dev = init_etherdev(NULL,sizeof(struct sbmac_softc));
++              dev = alloc_etherdev(sizeof(struct sbmac_softc));
+               if (!dev) 
+-                return -ENOMEM;       /* return ENOMEM */
++                      return -ENOMEM; /* return ENOMEM */
+               printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port);
+               dev->irq = K_INT_MAC_0 + idx;
+               dev->base_addr = port;
+               dev->mem_end = 0;
+-              /*dev->init = sbmac_init;*/
+-              sbmac_init(dev, macidx);
+-
+-              dev_sbmac[macidx] = dev;
+-              macidx++;
++              if (sbmac_init(dev, idx)) {
++                      port = A_MAC_CHANNEL_BASE(idx);
++                      SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR),
++                                      sbmac_orig_hwaddr[idx] );
++                      free_netdev(dev);
++                      continue;
++              }
++              dev_sbmac[idx++] = dev;
+       }
+-
+-      /*
+-       * Should we care, 'macidx' is the total number of enabled MACs.
+-       */
+-      
+       return 0;
+ }
+@@ -2916,21 +2916,12 @@ sbmac_cleanup_module(void)
+       sbmac_port_t port;
+       for (idx = 0; idx < MAX_UNITS; idx++) {
+               dev = dev_sbmac[idx];
+-              if (dev == NULL)
+-                      continue;
+-              if (dev->priv != NULL) {
+-                      struct sbmac_softc *sc = (struct sbmac_softc *) dev->priv;
+-                      
++              if (!dev) {
++                      struct sbmac_softc *sc = dev->priv;
+                       unregister_netdev(dev);
+-                      
+                       sbmac_uninitctx(sc);
+-                      
++                      free_netdev(dev);
+               }
+-
+-              port = A_MAC_CHANNEL_BASE(idx);
+-              SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR), sbmac_orig_hwaddr[idx] );
+-              free_netdev(dev);
+-              dev_sbmac[idx] = NULL;
+       }
+ }
+--- linux-2.6.0/drivers/net/seeq8005.c 2003-09-08 13:58:57.000000000 -0700
++++ 25/drivers/net/seeq8005.c  2003-12-28 23:21:01.000000000 -0800
+@@ -78,8 +78,6 @@ struct net_local {
+ /* Index to functions, as function prototypes. */
+-extern int seeq8005_probe(struct net_device *dev);
+-
+ static int seeq8005_probe1(struct net_device *dev, int ioaddr);
+ static int seeq8005_open(struct net_device *dev);
+ static void seeq8005_timeout(struct net_device *dev);
+@@ -102,22 +100,48 @@ static inline void wait_for_buffer(struc
+    If dev->base_addr == 1, always return failure.
+    */
+-int __init 
+-seeq8005_probe(struct net_device *dev)
+-{
+-      int i;
+-      int base_addr = dev ? dev->base_addr : 0;
+-
+-      if (base_addr > 0x1ff)          /* Check a single specified location. */
+-              return seeq8005_probe1(dev, base_addr);
+-      else if (base_addr != 0)        /* Don't probe at all. */
+-              return -ENXIO;
+-
+-      for (i = 0; seeq8005_portlist[i]; i++)
+-              if (seeq8005_probe1(dev, seeq8005_portlist[i]) == 0)
+-                      return 0;
++static int io = 0x320;
++static int irq = 10;
+-      return -ENODEV;
++struct net_device * __init seeq8005_probe(int unit)
++{
++      struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
++      unsigned *port;
++      int err = 0;
++
++      if (!dev)
++              return ERR_PTR(-ENODEV);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++              io = dev->base_addr;
++              irq = dev->irq;
++      }
++
++      if (io > 0x1ff) {       /* Check a single specified location. */
++              err = seeq8005_probe1(dev, io);
++      } else if (io != 0) {   /* Don't probe at all. */
++              err = -ENXIO;
++      } else {
++              for (port = seeq8005_portlist; *port; port++) {
++                      if (seeq8005_probe1(dev, *port) == 0)
++                              break;
++              }
++              if (!*port)
++                      err = -ENODEV;
++      }
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      release_region(dev->base_addr, SEEQ8005_IO_EXTENT);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /* This is the real probe routine.  Linux has a history of friendly device
+@@ -274,6 +298,7 @@ static int __init seeq8005_probe1(struct
+       /* Fill in the 'dev' fields. */
+       dev->base_addr = ioaddr;
++      dev->irq = irq;
+       /* Retrieve and print the ethernet address. */
+       for (i = 0; i < 6; i++)
+@@ -307,13 +332,6 @@ static int __init seeq8005_probe1(struct
+                }
+       }
+ #endif
+-
+-      /* Initialize the device structure. */
+-      dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+-      if (dev->priv == NULL)
+-              return -ENOMEM;
+-      memset(dev->priv, 0, sizeof(struct net_local));
+-
+       dev->open               = seeq8005_open;
+       dev->stop               = seeq8005_close;
+       dev->hard_start_xmit    = seeq8005_send_packet;
+@@ -321,10 +339,6 @@ static int __init seeq8005_probe1(struct
+       dev->watchdog_timeo     = HZ/20;
+       dev->get_stats          = seeq8005_get_stats;
+       dev->set_multicast_list = set_multicast_list;
+-
+-      /* Fill in the fields of the device structure with ethernet values. */
+-      ether_setup(dev);
+-      
+       dev->flags &= ~IFF_MULTICAST;
+       return 0;
+@@ -721,9 +735,7 @@ inline void wait_for_buffer(struct net_d
+       
+ #ifdef MODULE
+-static struct net_device dev_seeq = { .init = seeq8005_probe };
+-static int io = 0x320;
+-static int irq = 10;
++static struct net_device *dev_seeq;
+ MODULE_LICENSE("GPL");
+ MODULE_PARM(io, "i");
+ MODULE_PARM(irq, "i");
+@@ -732,28 +744,17 @@ MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ num
+ int init_module(void)
+ {
+-      dev_seeq.irq=irq;
+-      dev_seeq.base_addr=io;
+-      if (register_netdev(&dev_seeq) != 0)
+-              return -EIO;
++      dev_seeq = seeq8005_probe(-1);
++      if (IS_ERR(dev_seeq))
++              return PTR_ERR(dev_seeq);
+       return 0;
+ }
+ void cleanup_module(void)
+ {
+-      unregister_netdev(&dev_seeq);
+-
+-      /*
+-       *      Free up the private structure, or leak memory :-)
+-       */
+-
+-      kfree(dev_seeq.priv);
+-      dev_seeq.priv = NULL;   /* gets re-allocated by el1_probe1 */
+-
+-      /*
+-       *      If we don't do this, we can't re-insmod it later.
+-       */
+-      release_region(dev_seeq.base_addr, SEEQ8005_IO_EXTENT);
++      unregister_netdev(dev_seeq);
++      release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT);
++      free_netdev(dev_seeq);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/sgiseeq.c  2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/sgiseeq.c   2003-12-28 23:21:01.000000000 -0800
+@@ -600,6 +600,7 @@ int sgiseeq_init(struct hpc3_regs* regs,
+ {
+       struct net_device *dev;
+       struct sgiseeq_private *sp;
++      int err = -ENOMEM;
+       int i;
+       
+       sp = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL);
+@@ -609,19 +610,17 @@ int sgiseeq_init(struct hpc3_regs* regs,
+               return -ENOMEM;
+       }
+-      dev = init_etherdev(NULL, 0);
++      dev = alloc_etherdev(0);
+       if (!dev) {
+               printk (KERN_ERR
+                       "Seeq8003: Could not allocate memory for device.\n");
+-              free_page((unsigned long) sp);
+-              return -ENOMEM;
++              goto out;
+       }
+       if (request_irq(irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) {
+-              printk(KERN_ERR "Seeq8003: Can't get irq %d\n", dev->irq);
+-              free_page((unsigned long) sp);
+-              unregister_netdev(dev);
+-              return -EAGAIN;
++              printk(KERN_ERR "Seeq8003: Can't get irq %d\n", irq);
++              err = -EAGAIN;
++              goto out1;
+       }
+       printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name);
+@@ -637,6 +636,8 @@ int sgiseeq_init(struct hpc3_regs* regs,
+       }
+       printk("\n");
++      SET_MODULE_OWNER(dev);
++
+       dev->priv = sp;
+ #ifdef DEBUG
+       gpriv = sp;
+@@ -677,12 +678,22 @@ int sgiseeq_init(struct hpc3_regs* regs,
+       dev->set_multicast_list   = sgiseeq_set_multicast;
+       dev->irq                  = irq;
+       dev->dma                  = 0;
+-      ether_setup(dev);
++
++      err = register_netdev(dev);
++      if (err)
++              goto out2;
+       sp->next_module = root_sgiseeq_dev;
+       root_sgiseeq_dev = dev;
+       return 0;
++out2:
++      free_irq(dev->irq, dev);
++out1:
++      free_netdev(dev);
++out:
++      free_page((unsigned long) sp);
++      return err;
+ }
+ static int __init sgiseeq_probe(void)
+@@ -701,9 +712,9 @@ static void __exit sgiseeq_exit(void)
+       while (dev) {
+               sp = (struct sgiseeq_private *) dev->priv;
+               next = sp->next_module;
++              unregister_netdev(dev);
+               free_irq(dev->irq, dev);
+               free_page((unsigned long) sp);
+-              unregister_netdev(dev);
+               free_netdev(dev);
+               dev = next;
+       }
+--- linux-2.6.0/drivers/net/shaper.c   2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/shaper.c    2003-12-28 23:21:01.000000000 -0800
+@@ -718,8 +718,10 @@ static int __init shaper_init(void)
+               if (!dev) 
+                       break;
+-              if (register_netdev(dev))
++              if (register_netdev(dev)) {
++                      free_netdev(dev);
+                       break;
++              }
+               devs[i] = dev;
+               shapers_registered++;
+@@ -737,9 +739,12 @@ static void __exit shaper_exit (void)
+ {
+       int i;
+-      for (i = 0; i < shapers_registered; i++)
+-              if (devs[i])
++      for (i = 0; i < shapers_registered; i++) {
++              if (devs[i]) {
+                       unregister_netdev(devs[i]);
++                      free_netdev(devs[i]);
++              }
++      }
+       kfree(devs);
+       devs = NULL;
+--- linux-2.6.0/drivers/net/sis900.c   2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/sis900.c    2003-12-28 23:22:01.000000000 -0800
+@@ -18,10 +18,11 @@
+    preliminary Rev. 1.0 Jan. 18, 1998
+    http://www.sis.com.tw/support/databook.htm
++   Rev 1.08.07 Nov.  2 2003 Daniele Venzano <webvenza@libero.it> add suspend/resume support
+    Rev 1.08.06 Sep. 24 2002 Mufasa Yang bug fix for Tx timeout & add SiS963 support
+-   Rev 1.08.05 Jun. 6 2002 Mufasa Yang bug fix for read_eeprom & Tx descriptor over-boundary 
++   Rev 1.08.05 Jun.  6 2002 Mufasa Yang bug fix for read_eeprom & Tx descriptor over-boundary
+    Rev 1.08.04 Apr. 25 2002 Mufasa Yang <mufasa@sis.com.tw> added SiS962 support
+-   Rev 1.08.03 Feb. 1 2002 Matt Domsch <Matt_Domsch@dell.com> update to use library crc32 function
++   Rev 1.08.03 Feb.  1 2002 Matt Domsch <Matt_Domsch@dell.com> update to use library crc32 function
+    Rev 1.08.02 Nov. 30 2001 Hui-Fen Hsu workaround for EDB & bug fix for dhcp problem
+    Rev 1.08.01 Aug. 25 2001 Hui-Fen Hsu update for 630ET & workaround for ICS1893 PHY
+    Rev 1.08.00 Jun. 11 2001 Hui-Fen Hsu workaround for RTL8201 PHY and some bug fix
+@@ -72,7 +73,7 @@
+ #include "sis900.h"
+ #define SIS900_MODULE_NAME "sis900"
+-#define SIS900_DRV_VERSION "v1.08.06 9/24/2002"
++#define SIS900_DRV_VERSION "v1.08.07 11/02/2003"
+ static char version[] __devinitdata =
+ KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
+@@ -169,6 +170,7 @@ struct sis900_private {
+       unsigned int tx_full;                   /* The Tx queue is full.    */
+       u8 host_bridge_rev;
++      u32 pci_state[16];
+ };
+ MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>, Ollie Lho <ollie@sis.com.tw>");
+@@ -305,7 +307,7 @@ static int __devinit sis635_get_mac_addr
+               *( ((u16 *)net_dev->dev_addr) + i) = inw(ioaddr + rfdr);
+       }
+-      /* enable packet filitering */
++      /* enable packet filtering */
+       outl(rfcrSave | RFEN, rfcr + ioaddr);
+       return 1;
+@@ -994,7 +996,7 @@ sis900_init_rxfilter (struct net_device 
+               }
+       }
+-      /* enable packet filitering */
++      /* enable packet filtering */
+       outl(rfcrSave | RFEN, rfcr + ioaddr);
+ }
+@@ -1466,7 +1468,7 @@ static void sis900_tx_timeout(struct net
+  *    @net_dev: the net device to transmit with
+  *
+  *    Set the transmit buffer descriptor, 
+- *    and write TxENA to enable transimt state machine.
++ *    and write TxENA to enable transmit state machine.
+  *    tell upper layer if the buffer is full
+  */
+@@ -2184,11 +2186,72 @@ static void __devexit sis900_remove(stru
+       pci_set_drvdata(pci_dev, NULL);
+ }
++#ifdef CONFIG_PM
++
++static int sis900_suspend(struct pci_dev *pci_dev, u32 state)
++{
++      struct net_device *net_dev = pci_get_drvdata(pci_dev);
++      struct sis900_private *sis_priv = net_dev->priv;
++      long ioaddr = net_dev->base_addr;
++
++      if(!netif_running(net_dev))
++              return 0;
++
++      netif_stop_queue(net_dev);
++
++      /* Stop the chip's Tx and Rx Status Machine */
++      outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
++
++      pci_set_power_state(pci_dev, 3);
++      pci_save_state(pci_dev, sis_priv->pci_state);
++
++      return 0;
++}
++
++static int sis900_resume(struct pci_dev *pci_dev)
++{
++      struct net_device *net_dev = pci_get_drvdata(pci_dev);
++      struct sis900_private *sis_priv = net_dev->priv;
++      long ioaddr = net_dev->base_addr;
++
++      if(!netif_running(net_dev))
++              return 0;
++      pci_restore_state(pci_dev, sis_priv->pci_state);
++      pci_set_power_state(pci_dev, 0);
++
++      sis900_init_rxfilter(net_dev);
++
++      sis900_init_tx_ring(net_dev);
++      sis900_init_rx_ring(net_dev);
++
++      set_rx_mode(net_dev);
++
++      netif_device_attach(net_dev);
++      netif_start_queue(net_dev);
++
++      /* Workaround for EDB */
++      sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
++
++      /* Enable all known interrupts by setting the interrupt mask. */
++      outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
++      outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
++      outl(IE, ioaddr + ier);
++
++      sis900_check_mode(net_dev, sis_priv->mii);
++
++      return 0;
++}
++#endif /* CONFIG_PM */
++
+ static struct pci_driver sis900_pci_driver = {
+       .name           = SIS900_MODULE_NAME,
+       .id_table       = sis900_pci_tbl,
+       .probe          = sis900_probe,
+       .remove         = __devexit_p(sis900_remove),
++#ifdef CONFIG_PM
++      .suspend        = sis900_suspend,
++      .resume         = sis900_resume,
++#endif /* CONFIG_PM */
+ };
+ static int __init sis900_init_module(void)
+--- linux-2.6.0/drivers/net/sk98lin/h/skcsum.h 2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/net/sk98lin/h/skcsum.h  2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skcsum.h
+  * Project:   GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
+- * Version:   $Revision: 1.9 $
+- * Date:      $Date: 2001/02/06 11:21:39 $
++ * Version:   $Revision: 1.10 $
++ * Date:      $Date: 2003/08/20 13:59:57 $
+  * Purpose:   Store/verify Internet checksum in send/receive packets.
+  *
+  ******************************************************************************/
+@@ -26,6 +26,10 @@
+  * History:
+  *
+  *    $Log: skcsum.h,v $
++ *    Revision 1.10  2003/08/20 13:59:57  mschmid
++ *    Changed notation of #ifndef SkCsCalculateChecksum to
++ *    #ifndef SK_CS_CALCULATE_CHECKSUM
++ *    
+  *    Revision 1.9  2001/02/06 11:21:39  rassmann
+  *    Editorial changes.
+  *    
+@@ -226,11 +230,11 @@ typedef struct s_CsPacketInfo {
+ /* function prototypes ********************************************************/
+-#ifndef SkCsCalculateChecksum
++#ifndef SK_CS_CALCULATE_CHECKSUM
+ extern unsigned SkCsCalculateChecksum(
+       void            *pData,
+       unsigned        Length);
+-#endif
++#endif /* SK_CS_CALCULATE_CHECKSUM */
+ extern int SkCsEvent(
+       SK_AC           *pAc,
+--- linux-2.6.0/drivers/net/sk98lin/h/skdrv1st.h       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/sk98lin/h/skdrv1st.h        2003-12-28 23:21:01.000000000 -0800
+@@ -2,15 +2,16 @@
+  *
+  * Name:      skdrv1st.h
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.1 $
+- * Date:      $Date: 2003/07/21 07:22:43 $
++ * Version:   $Revision: 1.4 $
++ * Date:      $Date: 2003/11/12 14:28:14 $
+  * Purpose:   First header file for driver and all other modules
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2003 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect GmbH.
++ *    (C)Copyright 2002-2003 Marvell.
+  *
+  *    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
+@@ -26,6 +27,15 @@
+  * History:
+  *
+  *    $Log: skdrv1st.h,v $
++ *    Revision 1.4  2003/11/12 14:28:14  rroesler
++ *    Fix: use dedicated ip_fast_csum() on X86_64 systems
++ *    
++ *    Revision 1.3  2003/10/07 08:16:52  mlindner
++ *    Fix: Copyright changes
++ *    
++ *    Revision 1.2  2003/09/29 12:05:59  mlindner
++ *    Fix: Added define SK_CS_CALCULSTE_CHECKSUM
++ *    
+  *    Revision 1.1  2003/07/21 07:22:43  rroesler
+  *    Fix: Re-Enter after CVS crash
+  *    
+@@ -110,6 +120,9 @@
+ #ifndef __INC_SKDRV1ST_H
+ #define __INC_SKDRV1ST_H
++/* Check kernel version */
++#include <linux/version.h>
++
+ typedef struct s_AC   SK_AC;
+ /* Set card versions */
+@@ -124,17 +137,15 @@ typedef struct s_AC      SK_AC;
+ #define SK_PNMI_READ_U32(p,v)         memcpy((char*)&(v),(char*)(p),4)
+ #define SK_PNMI_READ_U64(p,v)         memcpy((char*)&(v),(char*)(p),8)
+-#define SkCsCalculateChecksum(p,l)    ((~ip_compute_csum(p, l)) & 0xffff)
+-
+ #define SK_ADDR_EQUAL(a1,a2)          (!memcmp(a1,a2,6))
+-
+ #if !defined(__OPTIMIZE__)  ||  !defined(__KERNEL__)
+ #warning  You must compile this file with the correct options!
+ #warning  See the last lines of the source file.
+ #error You must compile this driver with "-O".
+ #endif
++#include <linux/version.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+@@ -154,6 +165,13 @@ typedef struct s_AC       SK_AC;
+ #include <asm/uaccess.h>
+ #include <net/checksum.h>
++#define SK_CS_CALCULATE_CHECKSUM
++#ifndef CONFIG_X86_64
++#define SkCsCalculateChecksum(p,l)    ((~ip_compute_csum(p, l)) & 0xffff)
++#else
++#define SkCsCalculateChecksum(p,l)    ((~ip_fast_csum(p, l)) & 0xffff)
++#endif
++
+ #include      "h/sktypes.h"
+ #include      "h/skerror.h"
+ #include      "h/skdebug.h"
+--- linux-2.6.0/drivers/net/sk98lin/h/skdrv2nd.h       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/sk98lin/h/skdrv2nd.h        2003-12-28 23:21:01.000000000 -0800
+@@ -2,15 +2,16 @@
+  *
+  * Name:      skdrv2nd.h
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.3 $
+- * Date:      $Date: 2003/08/12 16:51:18 $
++ * Version:   $Revision: 1.10 $
++ * Date:      $Date: 2003/12/11 16:04:45 $
+  * Purpose:   Second header file for driver and all other modules
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2003 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect GmbH.
++ *    (C)Copyright 2002-2003 Marvell.
+  *
+  *    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
+@@ -26,6 +27,27 @@
+  * History:
+  *
+  *    $Log: skdrv2nd.h,v $
++ *    Revision 1.10  2003/12/11 16:04:45  mlindner
++ *    Add: New pnmi data backup structure
++ *    
++ *    Revision 1.9  2003/11/10 09:31:37  rroesler
++ *    Add: pnmiBackup structure for DIAG backup restore
++ *    
++ *    Revision 1.8  2003/10/22 14:18:32  rroesler
++ *    Fix: DIAG handling for DualNet cards
++ *    
++ *    Revision 1.7  2003/10/07 09:34:59  mlindner
++ *    Add: New defines for lower and upper range values (interrupt moderation)
++ *    
++ *    Revision 1.6  2003/10/07 08:16:51  mlindner
++ *    Fix: Copyright changes
++ *    
++ *    Revision 1.5  2003/09/01 13:10:39  rroesler
++ *    Add: Prototypes for DIAG Attach/Detach functions
++ *    
++ *    Revision 1.4  2003/09/01 12:33:38  rroesler
++ *    Add: Defines for optimized DIAG interaction
++ *    
+  *    Revision 1.3  2003/08/12 16:51:18  mlindner
+  *    Fix: UDP and TCP Proto checks
+  *    Fix: UDP header offset
+@@ -206,6 +228,11 @@ extern int                SkPciWriteCfgWord(SK_AC*, in
+ extern int            SkPciWriteCfgByte(SK_AC*, int, SK_U8);
+ extern int            SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
++#ifdef SK_DIAG_SUPPORT
++extern int            SkDrvEnterDiagMode(SK_AC *pAc);
++extern int            SkDrvLeaveDiagMode(SK_AC *pAc);
++#endif
++
+ struct s_DrvRlmtMbuf {
+       SK_MBUF         *pNext;         /* Pointer to next RLMT Mbuf. */
+       SK_U8           *pData;         /* Data buffer (virtually contig.). */
+@@ -247,6 +274,7 @@ struct s_DrvRlmtMbuf {
+ #define               SK_IOCTL_SETMIB         (SK_IOCTL_BASE + 1)
+ #define               SK_IOCTL_PRESETMIB      (SK_IOCTL_BASE + 2)
+ #define               SK_IOCTL_GEN            (SK_IOCTL_BASE + 3)
++#define               SK_IOCTL_DIAG           (SK_IOCTL_BASE + 4)
+ typedef struct s_IOCTL        SK_GE_IOCTL;
+@@ -462,6 +490,9 @@ struct s_RxPort {
+ #define C_INTS_PER_SEC_DEFAULT      2000 
+ #define C_INT_MOD_ENABLE_PERCENTAGE   50 /* if higher 50% enable */
+ #define C_INT_MOD_DISABLE_PERCENTAGE  50 /* if lower 50% disable */
++#define C_INT_MOD_IPS_LOWER_RANGE     30
++#define C_INT_MOD_IPS_UPPER_RANGE     40000
++
+ typedef struct s_DynIrqModInfo  DIM_INFO;
+ struct s_DynIrqModInfo {
+@@ -493,6 +524,11 @@ typedef struct s_PerStrm  PER_STRM;
+ #define SK_ALLOC_IRQ  0x00000001
++#ifdef SK_DIAG_SUPPORT
++#define       DIAG_ACTIVE             1
++#define       DIAG_NOTACTIVE          0
++#endif
++
+ /****************************************************************************
+  * Per board structure / Adapter Context structure:
+  *    Allocated within attach(9e) and freed within detach(9e).
+@@ -563,9 +599,18 @@ struct s_AC  {
+       int             PortUp;
+       int             PortDown;
+       int             ChipsetType;    /*  Chipset family type 
+-                                                       *  0 == Genesis family support
+-                                                       *  1 == Yukon family support
+-                                                       */
++                                       *  0 == Genesis family support
++                                       *  1 == Yukon family support
++                                       */
++#ifdef SK_DIAG_SUPPORT
++      SK_U32          DiagModeActive;         /* is diag active?      */
++      SK_BOOL         DiagFlowCtrl;           /* for control purposes */
++      SK_PNMI_STRUCT_DATA PnmiBackup;         /* backup structure for all Pnmi-Data */
++      SK_BOOL         WasIfUp[SK_MAX_MACS];   /* for OpenClose while 
++                                               * DIAG is busy with NIC 
++                                               */
++#endif
++
+ };
+--- linux-2.6.0/drivers/net/sk98lin/h/skgehw.h 2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/h/skgehw.h  2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgehw.h
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.53 $
+- * Date:      $Date: 2003/07/04 12:39:01 $
++ * Version:   $Revision: 1.56 $
++ * Date:      $Date: 2003/09/23 09:01:00 $
+  * Purpose:   Defines and Macros for the Gigabit Ethernet Adapter Product Family
+  *
+  ******************************************************************************/
+@@ -26,6 +26,17 @@
+  *
+  * History:
+  * $Log: skgehw.h,v $
++ * Revision 1.56  2003/09/23 09:01:00  malthoff
++ * Minor change: Define I2C device size constants as long.
++ *
++ * Revision 1.55  2003/09/16 14:03:34  rschmidt
++ * Added define for YUKON-Lite Rev. A1,A2 Chip Revision
++ * Moved defines for PHY power down modes to skgeinit.h
++ * Editorial changes
++ *
++ * Revision 1.54  2003/09/16 07:37:58  mschmid
++ * Added defines for Marvell PHY low power modes
++ *
+  * Revision 1.53  2003/07/04 12:39:01  rschmidt
+  * Added SK_FAR to pointers in XM_IN32() and GM_IN32() macros (for PXE)
+  * Editorial changes
+@@ -84,7 +95,7 @@
+  * Editorial changes
+  *
+  * Revision 1.39  2002/06/10 09:37:07  rschmidt
+- * Added macros for the ADDR-Modul
++ * Added macros for the ADDR-Module
+  *
+  * Revision 1.38  2002/06/05 08:15:19  rschmidt
+  * Added defines for WOL Registers
+@@ -628,12 +639,12 @@ extern "C" {
+ #define B2_FAR                        0x0120  /* 32 bit       Flash-Prom Addr Reg/Cnt */
+ #define B2_FDP                        0x0124  /*  8 bit       Flash-Prom Data Port */
+       /* 0x0125 - 0x0127:     reserved */
+-#define B2_LD_CRTL            0x0128  /*  8 bit       EPROM loader control register */
++#define B2_LD_CTRL            0x0128  /*  8 bit       EPROM loader control register */
+ #define B2_LD_TEST            0x0129  /*  8 bit       EPROM loader test register */
+       /* 0x012a - 0x012f:     reserved */
+ #define B2_TI_INI             0x0130  /* 32 bit       Timer Init Value */
+ #define B2_TI_VAL             0x0134  /* 32 bit       Timer Value */
+-#define B2_TI_CRTL            0x0138  /*  8 bit       Timer Control */
++#define B2_TI_CTRL            0x0138  /*  8 bit       Timer Control */
+ #define B2_TI_TEST            0x0139  /*  8 Bit       Timer Test */
+       /* 0x013a - 0x013f:     reserved */
+ #define B2_IRQM_INI           0x0140  /* 32 bit       IRQ Moderation Timer Init Reg.*/
+@@ -1021,7 +1032,7 @@ extern "C" {
+                                                               /* Bit 7:       reserved */
+ #define RAP_RAP                       0x3f    /* Bit 6..0:    0 = block 0,..,6f = block 6f */
+-/*    B0_CTST         16 bit  Control/Status register */
++/*    B0_CTST                 16 bit  Control/Status register */
+                                                               /* Bit 15..14:  reserved */
+ #define CS_CLK_RUN_HOT        BIT_13S         /* CLK_RUN hot m. (YUKON-Lite only) */
+ #define CS_CLK_RUN_RST        BIT_12S         /* CLK_RUN reset  (YUKON-Lite only) */
+@@ -1038,7 +1049,7 @@ extern "C" {
+ #define CS_RST_CLR            BIT_1S          /* Clear Software reset */
+ #define CS_RST_SET            BIT_0S          /* Set   Software reset */
+-/*    B0_LED           8 Bit  LED register */
++/*    B0_LED                   8 Bit  LED register */
+                                                               /* Bit  7.. 2:  reserved */
+ #define LED_STAT_ON           BIT_1S          /* Status LED on        */
+ #define LED_STAT_OFF  BIT_0S          /* Status LED off       */
+@@ -1053,9 +1064,9 @@ extern "C" {
+ #define PC_VCC_ON             BIT_1       /* Switch VCC On  */
+ #define PC_VCC_OFF            BIT_0       /* Switch VCC Off */
+-/*    B0_ISRC         32 bit  Interrupt Source Register */
+-/*    B0_IMSK         32 bit  Interrupt Mask Register */
+-/*    B0_SP_ISRC      32 bit  Special Interrupt Source Reg */
++/*    B0_ISRC                 32 bit  Interrupt Source Register */
++/*    B0_IMSK                 32 bit  Interrupt Mask Register */
++/*    B0_SP_ISRC              32 bit  Special Interrupt Source Reg */
+ /*    B2_IRQM_MSK     32 bit  IRQ Moderation Mask */
+ #define IS_ALL_MSK            0xbfffffffUL    /* All Interrupt bits */
+ #define IS_HW_ERR             BIT_31          /* Interrupt HW Error */
+@@ -1099,9 +1110,9 @@ extern "C" {
+ #define IS_XA2_C              BIT_0           /* Q_XA2 Encoding Error */
+-/*    B0_HWE_ISRC     32 bit  HW Error Interrupt Src Reg */
+-/*    B0_HWE_IMSK     32 bit  HW Error Interrupt Mask Reg */
+-/*    B2_IRQM_HWE_MSK 32 bit  IRQ Moderation HW Error Mask */
++/*    B0_HWE_ISRC             32 bit  HW Error Interrupt Src Reg */
++/*    B0_HWE_IMSK             32 bit  HW Error Interrupt Mask Reg */
++/*    B2_IRQM_HWE_MSK 32 bit  IRQ Moderation HW Error Mask */
+ #define IS_ERR_MSK            0x00000fffL     /*              All Error bits */
+                                                               /* Bit 31..14:  reserved */
+ #define IS_IRQ_TIST_OV        BIT_13  /* Time Stamp Timer Overflow (YUKON only) */
+@@ -1119,29 +1130,32 @@ extern "C" {
+ #define IS_R1_PAR_ERR BIT_1   /* Queue R1 Parity Error */
+ #define IS_R2_PAR_ERR BIT_0   /* Queue R2 Parity Error */
+-/*    B2_CONN_TYP      8 bit  Connector type */
+-/*    B2_PMD_TYP       8 bit  PMD type */
++/*    B2_CONN_TYP              8 bit  Connector type */
++/*    B2_PMD_TYP               8 bit  PMD type */
+ /*    Values of connector and PMD type comply to SysKonnect internal std */
+-/*    B2_MAC_CFG       8 bit  MAC Configuration / Chip Revision */
++/*    B2_MAC_CFG               8 bit  MAC Configuration / Chip Revision */
+ #define CFG_CHIP_R_MSK        (0xf<<4)        /* Bit 7.. 4: Chip Revision */
+                                                                       /* Bit 3.. 2:   reserved */
+ #define CFG_DIS_M2_CLK        BIT_1S          /* Disable Clock for 2nd MAC */
+ #define CFG_SNG_MAC           BIT_0S          /* MAC Config: 0=2 MACs / 1=1 MAC*/
+-/*    B2_CHIP_ID       8 bit  Chip Identification Number */
++/*    B2_CHIP_ID               8 bit  Chip Identification Number */
+ #define CHIP_ID_GENESIS               0x0a    /* Chip ID for GENESIS */
+ #define CHIP_ID_YUKON         0xb0    /* Chip ID for YUKON */
+-#define CHIP_ID_YUKON_LITE    0xb1    /* Chip ID for YUKON-Lite (Rev. A1) */
++#define CHIP_ID_YUKON_LITE    0xb1    /* Chip ID for YUKON-Lite (Rev. A1-A3) */
+ #define CHIP_ID_YUKON_LP      0xb2    /* Chip ID for YUKON-LP */
+-/*    B2_FAR          32 bit  Flash-Prom Addr Reg/Cnt */
++#define CHIP_REV_YU_LITE_A1   3               /* Chip Rev. for YUKON-Lite A1,A2 */
++#define CHIP_REV_YU_LITE_A3   7               /* Chip Rev. for YUKON-Lite A3 */
++
++/*    B2_FAR                  32 bit  Flash-Prom Addr Reg/Cnt */
+ #define FAR_ADDR              0x1ffffL        /* Bit 16.. 0:  FPROM Address mask */
+-/*    B2_LD_CRTL       8 bit  EPROM loader control register */
++/*    B2_LD_CTRL               8 bit  EPROM loader control register */
+ /*    Bits are currently reserved */
+-/*    B2_LD_TEST       8 bit  EPROM loader test register */
++/*    B2_LD_TEST               8 bit  EPROM loader test register */
+                                                               /* Bit 7.. 4:   reserved */
+ #define LD_T_ON                       BIT_3S  /* Loader Test mode on */
+ #define LD_T_OFF              BIT_2S  /* Loader Test mode off */
+@@ -1151,16 +1165,16 @@ extern "C" {
+ /*
+  *    Timer Section
+  */
+-/*    B2_TI_CRTL       8 bit  Timer control */
++/*    B2_TI_CTRL               8 bit  Timer control */
+ /*    B2_IRQM_CTRL     8 bit  IRQ Moderation Timer Control */
+                                                               /* Bit 7.. 3:   reserved */
+ #define TIM_START             BIT_2S  /* Start Timer */
+ #define TIM_STOP              BIT_1S  /* Stop  Timer */
+ #define TIM_CLR_IRQ           BIT_0S  /* Clear Timer IRQ (!IRQM) */
+-/*    B2_TI_TEST       8 Bit  Timer Test */
++/*    B2_TI_TEST               8 Bit  Timer Test */
+ /*    B2_IRQM_TEST     8 bit  IRQ Moderation Timer Test */
+-/*    B28_DPT_TST      8 bit  Descriptor Poll Timer Test Reg */
++/*    B28_DPT_TST              8 bit  Descriptor Poll Timer Test Reg */
+                                                               /* Bit 7.. 3:   reserved */
+ #define TIM_T_ON              BIT_2S  /* Test mode on */
+ #define TIM_T_OFF             BIT_1S  /* Test mode off */
+@@ -1197,7 +1211,7 @@ extern "C" {
+ #define TST_FRC_APERR_1M64    BIT_1S  /* AddrPERR on 1. phase */
+ #define TST_FRC_APERR_2M64    BIT_0S  /* AddrPERR on 2. phase */
+-/*    B2_GP_IO        32 bit  General Purpose I/O Register */
++/*    B2_GP_IO                32 bit  General Purpose I/O Register */
+                                                       /* Bit 31..26:  reserved */
+ #define GP_DIR_9      BIT_25  /* IO_9 direct, 0=In/1=Out */
+ #define GP_DIR_8      BIT_24  /* IO_8 direct, 0=In/1=Out */
+@@ -1221,28 +1235,28 @@ extern "C" {
+ #define GP_IO_1               BIT_1   /* IO_1 pin */
+ #define GP_IO_0               BIT_0   /* IO_0 pin */
+-/*    B2_I2C_CTRL     32 bit  I2C HW Control Register */
++/*    B2_I2C_CTRL             32 bit  I2C HW Control Register */
+ #define I2C_FLAG              BIT_31          /* Start read/write if WR */
+ #define I2C_ADDR              (0x7fffL<<16)   /* Bit 30..16:  Addr to be RD/WR */
+ #define I2C_DEV_SEL           (0x7fL<<9)              /* Bit 15.. 9:  I2C Device Select */
+                                                               /* Bit  8.. 5:  reserved        */
+ #define I2C_BURST_LEN BIT_4           /* Burst Len, 1/4 bytes */
+-#define I2C_DEV_SIZE  (7L<<1)         /* Bit  3.. 1:  I2C Device Size */
+-#define I2C_025K_DEV  (0L<<1)         /*              0: 256 Bytes or smal. */
+-#define I2C_05K_DEV           (1L<<1)         /*              1: 512  Bytes   */
+-#define I2C_1K_DEV            (2L<<1)         /*              2: 1024 Bytes   */
+-#define I2C_2K_DEV            (3L<<1)         /*              3: 2048 Bytes   */
+-#define I2C_4K_DEV            (4L<<1)         /*              4: 4096 Bytes   */
+-#define I2C_8K_DEV            (5L<<1)         /*              5: 8192 Bytes   */
+-#define I2C_16K_DEV           (6L<<1)         /*              6: 16384 Bytes  */
+-#define I2C_32K_DEV           (7L<<1)         /*              7: 32768 Bytes  */
++#define I2C_DEV_SIZE  (7<<1)          /* Bit  3.. 1:  I2C Device Size */
++#define I2C_025K_DEV  (0<<1)          /*              0: 256 Bytes or smal. */
++#define I2C_05K_DEV           (1<<1)          /*              1: 512  Bytes   */
++#define I2C_1K_DEV            (2<<1)          /*              2: 1024 Bytes   */
++#define I2C_2K_DEV            (3<<1)          /*              3: 2048 Bytes   */
++#define I2C_4K_DEV            (4<<1)          /*              4: 4096 Bytes   */
++#define I2C_8K_DEV            (5<<1)          /*              5: 8192 Bytes   */
++#define I2C_16K_DEV           (6<<1)          /*              6: 16384 Bytes  */
++#define I2C_32K_DEV           (7<<1)          /*              7: 32768 Bytes  */
+ #define I2C_STOP              BIT_0           /* Interrupt I2C transfer */
+-/*    B2_I2C_IRQ      32 bit  I2C HW IRQ Register */
++/*    B2_I2C_IRQ              32 bit  I2C HW IRQ Register */
+                                                               /* Bit 31.. 1   reserved */
+ #define I2C_CLR_IRQ           BIT_0   /* Clear I2C IRQ */
+-/*    B2_I2C_SW       32 bit (8 bit access)   I2C HW SW Port Register */
++/*    B2_I2C_SW               32 bit (8 bit access)   I2C HW SW Port Register */
+                                                               /* Bit  7.. 3:  reserved */
+ #define I2C_DATA_DIR  BIT_2S          /* direction of I2C_DATA */
+ #define I2C_DATA              BIT_1S          /* I2C Data Port        */
+@@ -1254,27 +1268,27 @@ extern "C" {
+ #define I2C_SENS_ADDR LM80_ADDR       /* I2C Sensor Address, (Volt and Temp)*/
+-/*    B2_BSC_CTRL      8 bit  Blink Source Counter Control */
++/*    B2_BSC_CTRL              8 bit  Blink Source Counter Control */
+                                                       /* Bit  7.. 2:  reserved */
+ #define BSC_START     BIT_1S          /* Start Blink Source Counter */
+ #define BSC_STOP      BIT_0S          /* Stop  Blink Source Counter */
+-/*    B2_BSC_STAT      8 bit  Blink Source Counter Status */
++/*    B2_BSC_STAT              8 bit  Blink Source Counter Status */
+                                                       /* Bit  7.. 1:  reserved */
+ #define BSC_SRC               BIT_0S          /* Blink Source, 0=Off / 1=On */
+-/*    B2_BSC_TST      16 bit  Blink Source Counter Test Reg */
++/*    B2_BSC_TST              16 bit  Blink Source Counter Test Reg */
+ #define BSC_T_ON      BIT_2S          /* Test mode on */
+ #define BSC_T_OFF     BIT_1S          /* Test mode off */
+ #define BSC_T_STEP    BIT_0S          /* Test step */
+-/*    B3_RAM_ADDR     32 bit  RAM Address, to read or write */
++/*    B3_RAM_ADDR             32 bit  RAM Address, to read or write */
+                                       /* Bit 31..19:  reserved */
+ #define RAM_ADR_RAN   0x0007ffffL     /* Bit 18.. 0:  RAM Address Range */
+ /* RAM Interface Registers */
+-/*    B3_RI_CTRL      16 bit  RAM Iface Control Register */
++/*    B3_RI_CTRL              16 bit  RAM Iface Control Register */
+                                                               /* Bit 15..10:  reserved */
+ #define RI_CLR_RD_PERR        BIT_9S  /* Clear IRQ RAM Read Parity Err */
+ #define RI_CLR_WR_PERR        BIT_8S  /* Clear IRQ RAM Write Parity Err*/
+@@ -1282,7 +1296,7 @@ extern "C" {
+ #define RI_RST_CLR            BIT_1S  /* Clear RAM Interface Reset */
+ #define RI_RST_SET            BIT_0S  /* Set   RAM Interface Reset */
+-/*    B3_RI_TEST       8 bit  RAM Iface Test Register */
++/*    B3_RI_TEST               8 bit  RAM Iface Test Register */
+                                                               /* Bit 15.. 4:  reserved */
+ #define RI_T_EV                       BIT_3S  /* Timeout Event occured */
+ #define RI_T_ON                       BIT_2S  /* Timeout Timer Test On */
+@@ -1309,7 +1323,7 @@ extern "C" {
+ #define MA_DIS_REC_RX1        BIT_0S  /* Disable Recovery Timer RX1 */
+ /* Packet Arbiter Registers */
+-/*    B3_PA_CTRL      16 bit  Packet Arbiter Ctrl Register */
++/*    B3_PA_CTRL              16 bit  Packet Arbiter Ctrl Register */
+                                                               /* Bit 15..14:  reserved */
+ #define PA_CLR_TO_TX2 BIT_13S /* Clear IRQ Packet Timeout TX2 */
+ #define PA_CLR_TO_TX1 BIT_12S /* Clear IRQ Packet Timeout TX1 */
+@@ -1332,7 +1346,7 @@ extern "C" {
+ /* Rx/Tx Path related Arbiter Test Registers */
+ /*    B3_MA_TO_TEST   16 bit  MAC Arbiter Timeout Test Reg */
+ /*    B3_MA_RC_TEST   16 bit  MAC Arbiter Recovery Test Reg */
+-/*    B3_PA_TEST      16 bit  Packet Arbiter Test Register */
++/*    B3_PA_TEST              16 bit  Packet Arbiter Test Register */
+ /*                    Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
+ #define TX2_T_EV      BIT_15S         /* TX2 Timeout/Recv Event occured */
+ #define TX2_T_ON      BIT_14S         /* TX2 Timeout/Recv Timer Test On */
+@@ -1353,14 +1367,14 @@ extern "C" {
+ /* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
+-/*    TXA_ITI_INI     32 bit  Tx Arb Interval Timer Init Val */
+-/*    TXA_ITI_VAL     32 bit  Tx Arb Interval Timer Value */
+-/*    TXA_LIM_INI     32 bit  Tx Arb Limit Counter Init Val */
+-/*    TXA_LIM_VAL     32 bit  Tx Arb Limit Counter Value */
++/*    TXA_ITI_INI             32 bit  Tx Arb Interval Timer Init Val */
++/*    TXA_ITI_VAL             32 bit  Tx Arb Interval Timer Value */
++/*    TXA_LIM_INI             32 bit  Tx Arb Limit Counter Init Val */
++/*    TXA_LIM_VAL             32 bit  Tx Arb Limit Counter Value */
+                                                               /* Bit 31..24:  reserved */
+ #define TXA_MAX_VAL   0x00ffffffUL/* Bit 23.. 0:      Max TXA Timer/Cnt Val */
+-/*    TXA_CTRL         8 bit  Tx Arbiter Control Register */
++/*    TXA_CTRL                 8 bit  Tx Arbiter Control Register */
+ #define TXA_ENA_FSYNC BIT_7S  /* Enable  force of sync Tx queue */
+ #define TXA_DIS_FSYNC BIT_6S  /* Disable force of sync Tx queue */
+ #define TXA_ENA_ALLOC BIT_5S  /* Enable  alloc of free bandwidth */
+@@ -1370,7 +1384,7 @@ extern "C" {
+ #define TXA_ENA_ARB           BIT_1S  /* Enable  Tx Arbiter */
+ #define TXA_DIS_ARB           BIT_0S  /* Disable Tx Arbiter */
+-/*    TXA_TEST         8 bit  Tx Arbiter Test Register */
++/*    TXA_TEST                 8 bit  Tx Arbiter Test Register */
+                                                               /* Bit 7.. 6:   reserved */
+ #define TXA_INT_T_ON  BIT_5S  /* Tx Arb Interval Timer Test On */
+ #define TXA_INT_T_OFF BIT_4S  /* Tx Arb Interval Timer Test Off */
+@@ -1379,22 +1393,22 @@ extern "C" {
+ #define TXA_LIM_T_OFF BIT_1S  /* Tx Arb Limit Timer Test Off */
+ #define TXA_LIM_T_STEP        BIT_0S  /* Tx Arb Limit Timer Step */
+-/*    TXA_STAT         8 bit  Tx Arbiter Status Register */
++/*    TXA_STAT                 8 bit  Tx Arbiter Status Register */
+                                                               /* Bit 7.. 1:   reserved */
+ #define TXA_PRIO_XS           BIT_0S  /* sync queue has prio to send */
+-/*    Q_BC    32 bit  Current Byte Counter */
++/*    Q_BC                    32 bit  Current Byte Counter */
+                                                               /* Bit 31..16:  reserved */
+ #define BC_MAX                        0xffff  /* Bit 15.. 0:  Byte counter */
+ /* BMU Control Status Registers */
+-/*    B0_R1_CSR       32 bit  BMU Ctrl/Stat Rx Queue 1 */
+-/*    B0_R2_CSR       32 bit  BMU Ctrl/Stat Rx Queue 2 */
+-/*    B0_XA1_CSR      32 bit  BMU Ctrl/Stat Sync Tx Queue 1 */
+-/*    B0_XS1_CSR      32 bit  BMU Ctrl/Stat Async Tx Queue 1 */
+-/*    B0_XA2_CSR      32 bit  BMU Ctrl/Stat Sync Tx Queue 2 */
+-/*    B0_XS2_CSR      32 bit  BMU Ctrl/Stat Async Tx Queue 2 */
+-/*    Q_CSR           32 bit  BMU Control/Status Register */
++/*    B0_R1_CSR               32 bit  BMU Ctrl/Stat Rx Queue 1 */
++/*    B0_R2_CSR               32 bit  BMU Ctrl/Stat Rx Queue 2 */
++/*    B0_XA1_CSR              32 bit  BMU Ctrl/Stat Sync Tx Queue 1 */
++/*    B0_XS1_CSR              32 bit  BMU Ctrl/Stat Async Tx Queue 1 */
++/*    B0_XA2_CSR              32 bit  BMU Ctrl/Stat Sync Tx Queue 2 */
++/*    B0_XS2_CSR              32 bit  BMU Ctrl/Stat Async Tx Queue 2 */
++/*    Q_CSR                   32 bit  BMU Control/Status Register */
+                                                               /* Bit 31..25:  reserved */
+ #define CSR_SV_IDLE           BIT_24          /* BMU SM Idle */
+                                                               /* Bit 23..22:  reserved */
+@@ -1428,7 +1442,7 @@ extern "C" {
+                                               CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
+                                               CSR_TRANS_RUN)
+-/*    Q_F     32 bit  Flag Register */
++/*    Q_F                             32 bit  Flag Register */
+                                                                       /* Bit 31..28:  reserved */
+ #define F_ALM_FULL            BIT_27          /* Rx FIFO: almost full */
+ #define F_EMPTY                       BIT_27          /* Tx FIFO: empty flag */
+@@ -1439,17 +1453,17 @@ extern "C" {
+                                                                       /* Bit 15..11:  reserved */
+ #define F_WATER_MARK  0x0007ffL       /* Bit 10.. 0:  Watermark */
+-/*    Q_T1    32 bit  Test Register 1 */
++/*    Q_T1                    32 bit  Test Register 1 */
+ /*            Holds four State Machine control Bytes */
+-#define SM_CRTL_SV_MSK        (0xffL<<24)     /* Bit 31..24:  Control Supervisor SM */
+-#define SM_CRTL_RD_MSK        (0xffL<<16)     /* Bit 23..16:  Control Read Desc SM */
+-#define SM_CRTL_WR_MSK        (0xffL<<8)      /* Bit 15.. 8:  Control Write Desc SM */
+-#define SM_CRTL_TR_MSK        0xffL           /* Bit  7.. 0:  Control Transfer SM */
+-
+-/*    Q_T1_TR  8 bit  Test Register 1 Transfer SM */
+-/*    Q_T1_WR  8 bit  Test Register 1 Write Descriptor SM */
+-/*    Q_T1_RD  8 bit  Test Register 1 Read Descriptor SM */
+-/*    Q_T1_SV  8 bit  Test Register 1 Supervisor SM */
++#define SM_CTRL_SV_MSK        (0xffL<<24)     /* Bit 31..24:  Control Supervisor SM */
++#define SM_CTRL_RD_MSK        (0xffL<<16)     /* Bit 23..16:  Control Read Desc SM */
++#define SM_CTRL_WR_MSK        (0xffL<<8)      /* Bit 15.. 8:  Control Write Desc SM */
++#define SM_CTRL_TR_MSK        0xffL           /* Bit  7.. 0:  Control Transfer SM */
++
++/*    Q_T1_TR                  8 bit  Test Register 1 Transfer SM */
++/*    Q_T1_WR                  8 bit  Test Register 1 Write Descriptor SM */
++/*    Q_T1_RD                  8 bit  Test Register 1 Read Descriptor SM */
++/*    Q_T1_SV                  8 bit  Test Register 1 Supervisor SM */
+ /* The control status byte of each machine looks like ... */
+ #define SM_STATE              0xf0    /* Bit 7.. 4:   State which shall be loaded */
+@@ -1459,7 +1473,7 @@ extern "C" {
+ #define SM_STEP                       BIT_0S  /* Step the State Machine */
+ /* The encoding of the states is not supported by the Diagnostics Tool */
+-/*    Q_T2    32 bit  Test Register 2 */
++/*    Q_T2                    32 bit  Test Register 2 */
+                                                               /* Bit 31.. 8:  reserved */
+ #define T2_AC_T_ON            BIT_7   /* Address Counter Test Mode on */
+ #define T2_AC_T_OFF           BIT_6   /* Address Counter Test Mode off */
+@@ -1470,23 +1484,23 @@ extern "C" {
+ #define T2_STEP02             BIT_1   /* Inc AC/Dec BC by 2 */
+ #define T2_STEP01             BIT_0   /* Inc AC/Dec BC by 1 */
+-/*    Q_T3    32 bit  Test Register 3 */
++/*    Q_T3                    32 bit  Test Register 3 */
+                                                               /* Bit 31.. 7:  reserved */
+ #define T3_MUX_MSK            (7<<4)  /* Bit  6.. 4:  Mux Position */
+                                                               /* Bit  3:      reserved */
+ #define T3_VRAM_MSK           7               /* Bit  2.. 0:  Virtual RAM Buffer Address */
+ /* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
+-/*    RB_START        32 bit  RAM Buffer Start Address */
+-/*    RB_END          32 bit  RAM Buffer End Address */
+-/*    RB_WP           32 bit  RAM Buffer Write Pointer */
+-/*    RB_RP           32 bit  RAM Buffer Read Pointer */
+-/*    RB_RX_UTPP      32 bit  Rx Upper Threshold, Pause Pack */
+-/*    RB_RX_LTPP      32 bit  Rx Lower Threshold, Pause Pack */
+-/*    RB_RX_UTHP      32 bit  Rx Upper Threshold, High Prio */
+-/*    RB_RX_LTHP      32 bit  Rx Lower Threshold, High Prio */
+-/*    RB_PC           32 bit  RAM Buffer Packet Counter */
+-/*    RB_LEV          32 bit  RAM Buffer Level Register */
++/*    RB_START                32 bit  RAM Buffer Start Address */
++/*    RB_END                  32 bit  RAM Buffer End Address */
++/*    RB_WP                   32 bit  RAM Buffer Write Pointer */
++/*    RB_RP                   32 bit  RAM Buffer Read Pointer */
++/*    RB_RX_UTPP              32 bit  Rx Upper Threshold, Pause Pack */
++/*    RB_RX_LTPP              32 bit  Rx Lower Threshold, Pause Pack */
++/*    RB_RX_UTHP              32 bit  Rx Upper Threshold, High Prio */
++/*    RB_RX_LTHP              32 bit  Rx Lower Threshold, High Prio */
++/*    RB_PC                   32 bit  RAM Buffer Packet Counter */
++/*    RB_LEV                  32 bit  RAM Buffer Level Register */
+                               /* Bit 31..19:  reserved */
+ #define RB_MSK        0x0007ffff      /* Bit 18.. 0:  RAM Buffer Pointer Bits */
+@@ -1519,17 +1533,17 @@ extern "C" {
+ /* Receive and Transmit MAC FIFO Registers (GENESIS only) */
+-/*    RX_MFF_EA       32 bit  Receive MAC FIFO End Address */
+-/*    RX_MFF_WP       32 bit  Receive MAC FIFO Write Pointer */
+-/*    RX_MFF_RP       32 bit  Receive MAC FIFO Read Pointer */
+-/*    RX_MFF_PC       32 bit  Receive MAC FIFO Packet Counter */
+-/*    RX_MFF_LEV      32 bit  Receive MAC FIFO Level */
+-/*    TX_MFF_EA       32 bit  Transmit MAC FIFO End Address */
+-/*    TX_MFF_WP       32 bit  Transmit MAC FIFO Write Pointer */
+-/*    TX_MFF_WSP      32 bit  Transmit MAC FIFO WR Shadow Pointer */
+-/*    TX_MFF_RP       32 bit  Transmit MAC FIFO Read Pointer */
+-/*    TX_MFF_PC       32 bit  Transmit MAC FIFO Packet Cnt */
+-/*    TX_MFF_LEV      32 bit  Transmit MAC FIFO Level */
++/*    RX_MFF_EA               32 bit  Receive MAC FIFO End Address */
++/*    RX_MFF_WP               32 bit  Receive MAC FIFO Write Pointer */
++/*    RX_MFF_RP               32 bit  Receive MAC FIFO Read Pointer */
++/*    RX_MFF_PC               32 bit  Receive MAC FIFO Packet Counter */
++/*    RX_MFF_LEV              32 bit  Receive MAC FIFO Level */
++/*    TX_MFF_EA               32 bit  Transmit MAC FIFO End Address */
++/*    TX_MFF_WP               32 bit  Transmit MAC FIFO Write Pointer */
++/*    TX_MFF_WSP              32 bit  Transmit MAC FIFO WR Shadow Pointer */
++/*    TX_MFF_RP               32 bit  Transmit MAC FIFO Read Pointer */
++/*    TX_MFF_PC               32 bit  Transmit MAC FIFO Packet Cnt */
++/*    TX_MFF_LEV              32 bit  Transmit MAC FIFO Level */
+                                                               /* Bit 31.. 6:  reserved */
+ #define MFF_MSK                       0x007fL /* Bit  5.. 0:  MAC FIFO Address/Ptr Bits */
+@@ -1682,7 +1696,7 @@ extern "C" {
+ #define RX_GMF_FL_THR_DEF     0x0a    /* Rx GMAC FIFO Flush Threshold default */
+-/*    GMAC_TI_ST_CTRL           8 bit Time Stamp Timer Ctrl Reg (YUKON only) */
++/*    GMAC_TI_ST_CTRL  8 bit  Time Stamp Timer Ctrl Reg (YUKON only) */
+                                                               /* Bit 7.. 3:   reserved */
+ #define GMT_ST_START  BIT_2S          /* Start Time Stamp Timer */
+ #define GMT_ST_STOP           BIT_1S          /* Stop  Time Stamp Timer */
+@@ -1766,13 +1780,13 @@ extern "C" {
+ #define GMAC_DEF_MSK  (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
+                                               GM_IS_TX_FF_UR)
+-/*    GMAC_LINK_CTRL          16 bit  GMAC Link Control Reg (YUKON only) */
++/*    GMAC_LINK_CTRL  16 bit  GMAC Link Control Reg (YUKON only) */
+                                               /* Bits 15.. 2: reserved */
+ #define GMLC_RST_CLR  BIT_1S          /* Clear GMAC Link Reset */
+ #define GMLC_RST_SET  BIT_0S          /* Set   GMAC Link Reset */
+-/*    WOL_CTRL_STAT           16 bit  WOL Control/Status Reg */
++/*    WOL_CTRL_STAT   16 bit  WOL Control/Status Reg */
+ #define WOL_CTL_LINK_CHG_OCC                  BIT_15S
+ #define WOL_CTL_MAGIC_PKT_OCC                 BIT_14S
+ #define WOL_CTL_PATTERN_OCC                           BIT_13S
+@@ -1801,7 +1815,7 @@ extern "C" {
+       WOL_CTL_DIS_PATTERN_UNIT |              \
+       WOL_CTL_DIS_MAGIC_PKT_UNIT)
+-/*    WOL_MATCH_CTL            8 bit  WOL Match Control Reg */
++/*    WOL_MATCH_CTL    8 bit  WOL Match Control Reg */
+ #define WOL_CTL_PATT_ENA(x)                           (BIT_0 << (x))
+ #define SK_NUM_WOL_PATTERN            7
+--- linux-2.6.0/drivers/net/sk98lin/h/skgehwt.h        2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/h/skgehwt.h 2003-12-28 23:21:01.000000000 -0800
+@@ -1,9 +1,9 @@
+ /******************************************************************************
+  *
+  * Name:      skhwt.h
+- * Project:   Gigabit Ethernet Adapters, Schedule-Modul
+- * Version:   $Revision: 1.6 $
+- * Date:      $Date: 2003/05/13 17:57:48 $
++ * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
++ * Version:   $Revision: 1.7 $
++ * Date:      $Date: 2003/09/16 12:55:08 $
+  * Purpose:   Defines for the hardware timer functions
+  *
+  ******************************************************************************/
+@@ -27,6 +27,9 @@
+  * History:
+  *
+  *    $Log: skgehwt.h,v $
++ *    Revision 1.7  2003/09/16 12:55:08  rschmidt
++ *    Editorial changes
++ *    
+  *    Revision 1.6  2003/05/13 17:57:48  mkarl
+  *    Editorial changes.
+  *    
+@@ -34,7 +37,7 @@
+  *    Changed license header to GPL.
+  *    
+  *    Revision 1.4  1998/08/19 09:50:58  gklug
+- *    fix: remove struct keyword from c-code (see CCC) add typedefs
++ *    fix: remove struct keyword from C-code (see CCC) add typedefs
+  *    
+  *    Revision 1.3  1998/08/14 07:09:29  gklug
+  *    fix: chg pAc -> pAC
+@@ -44,10 +47,6 @@
+  *    
+  *    Revision 1.1  1998/08/07 09:32:58  gklug
+  *    first version
+- *    
+- *    
+- *    
+- *    
+  *
+  ******************************************************************************/
+@@ -64,14 +63,14 @@
+  * - use in Adapters context name pAC->Hwt
+  */
+ typedef       struct s_Hwt {
+-      SK_U32          TStart ;        /* HWT start */
+-      SK_U32          TStop ;         /* HWT stop */
+-      int             TActive ;       /* HWT: flag : active/inactive */
++      SK_U32          TStart; /* HWT start */
++      SK_U32          TStop;  /* HWT stop */
++      int             TActive;        /* HWT: flag : active/inactive */
+ } SK_HWT;
+ extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc);
+ extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time);
+ extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc);
+-extern SK_U32 SkHwtRead(SK_AC *pAC,SK_IOC Ioc);
++extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc);
+ extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc);
+ #endif        /* _SKGEHWT_H_ */
+--- linux-2.6.0/drivers/net/sk98lin/h/skgei2c.h        2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/h/skgei2c.h 2003-12-28 23:21:01.000000000 -0800
+@@ -1,16 +1,17 @@
+ /******************************************************************************
+  *
+  * Name:      skgei2c.h
+- * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.23 $
+- * Date:      $Date: 2002/12/19 14:34:27 $
+- * Purpose:   Special GEnesis defines for TWSI
++ * Project:   Gigabit Ethernet Adapters, TWSI-Module
++ * Version:   $Revision: 1.25 $
++ * Date:      $Date: 2003/10/20 09:06:05 $
++ * Purpose:   Special defines for TWSI
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2002 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect.
++ *    (C)Copyright 2002-2003 Marvell.
+  *
+  *    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
+@@ -26,6 +27,12 @@
+  * History:
+  *
+  *    $Log: skgei2c.h,v $
++ *    Revision 1.25  2003/10/20 09:06:05  rschmidt
++ *    Editorial changes.
++ *    
++ *    Revision 1.24  2003/09/23 09:31:15  malthoff
++ *    Parameter dev_size added to macro definition of SK_I2C_CTL.
++ *    
+  *    Revision 1.23  2002/12/19 14:34:27  rschmidt
+  *    Added cast in macros SK_I2C_SET_BIT() and SK_I2C_CLR_BIT()
+  *    Editorial changes (TWSI)
+@@ -107,8 +114,6 @@
+  *    Revision 1.1  1998/07/17 11:27:56  gklug
+  *    Created.
+  *
+- *
+- *
+  ******************************************************************************/
+ /*
+@@ -121,12 +126,13 @@
+ /*
+  * Macros to access the B2_I2C_CTRL
+  */
+-#define SK_I2C_CTL(IoC, flag, dev, reg, burst) \
++#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \
+       SK_OUT32(IoC, B2_I2C_CTRL,\
+               (flag ? 0x80000000UL : 0x0L) | \
+-              (((SK_U32) reg << 16) & I2C_ADDR) | \
+-              (((SK_U32) dev << 9) & I2C_DEV_SEL) | \
+-              (( burst << 4) & I2C_BURST_LEN))
++              (((SK_U32)reg << 16) & I2C_ADDR) | \
++              (((SK_U32)dev << 9) & I2C_DEV_SEL) | \
++              (dev_size & I2C_DEV_SIZE) | \
++              ((burst << 4) & I2C_BURST_LEN))
+ #define SK_I2C_STOP(IoC) {                            \
+       SK_U32  I2cCtrl;                                \
+@@ -166,42 +172,42 @@
+  */
+ #define       SK_LM80_VT_LSB          22      /* 22mV LSB resolution */
+ #define       SK_LM80_TEMP_LSB        10      /* 1 degree LSB resolution */
+-#define       SK_LM80_TEMPEXT_LSB     5       /* 0.5 degree LSB resolution for the
+-                                       * extension value
+-                                       */
+-#define SK_LM80_FAN_FAKTOR    ((22500L*60)/(1*2))
+-/* formula: counter = (22500*60)/(rpm * divisor * pulses/2)
++#define       SK_LM80_TEMPEXT_LSB      5      /* 0.5 degree LSB resolution for ext. val. */
++
++/*
++ * formula: counter = (22500*60)/(rpm * divisor * pulses/2)
+  * assuming: 6500rpm, 4 pulses, divisor 1
+  */
++#define SK_LM80_FAN_FAKTOR    ((22500L*60)/(1*2))
+ /*
+  * Define sensor management data
+- * Maximum is reached on copperfield with dual Broadcom.
++ * Maximum is reached on Genesis copper dual port and Yukon-64
+  * Board specific maximum is in pAC->I2c.MaxSens
+  */
+ #define       SK_MAX_SENSORS  8       /* maximal no. of installed sensors */
+ #define       SK_MIN_SENSORS  5       /* minimal no. of installed sensors */
+ /*
+- * To watch the statemachine (JS) use the timer in two ways instead of one as hitherto
++ * To watch the state machine (SM) use the timer in two ways
++ * instead of one as hitherto
+  */
+-#define       SK_TIMER_WATCH_STATEMACHINE     0       /* Watch the statemachine to finish in a specific time */
+-#define       SK_TIMER_NEW_GAUGING            1       /* Start a new gauging when timer expires */
+-
++#define       SK_TIMER_WATCH_SM               0       /* Watch the SM to finish in a spec. time */
++#define       SK_TIMER_NEW_GAUGING    1       /* Start a new gauging when timer expires */
+ /*
+- * Defines for the individual Thresholds
++ * Defines for the individual thresholds
+  */
+ /* Temperature sensor */
+-#define       SK_SEN_TEMP_HIGH_ERR    800     /* Temperature High Err  Threshold */
++#define       SK_SEN_TEMP_HIGH_ERR    800     /* Temperature High Err  Threshold */
+ #define       SK_SEN_TEMP_HIGH_WARN   700     /* Temperature High Warn Threshold */
+ #define       SK_SEN_TEMP_LOW_WARN    100     /* Temperature Low  Warn Threshold */
+-#define       SK_SEN_TEMP_LOW_ERR       0     /* Temperature Low  Err  Threshold */
++#define       SK_SEN_TEMP_LOW_ERR               0     /* Temperature Low  Err  Threshold */
+ /* VCC which should be 5 V */
+-#define       SK_SEN_PCI_5V_HIGH_ERR          5588    /* Voltage PCI High Err  Threshold */
+-#define       SK_SEN_PCI_5V_HIGH_WARN     5346        /* Voltage PCI High Warn Threshold */
++#define       SK_SEN_PCI_5V_HIGH_ERR          5588    /* Voltage PCI High Err  Threshold */
++#define       SK_SEN_PCI_5V_HIGH_WARN         5346    /* Voltage PCI High Warn Threshold */
+ #define       SK_SEN_PCI_5V_LOW_WARN          4664    /* Voltage PCI Low  Warn Threshold */
+ #define       SK_SEN_PCI_5V_LOW_ERR           4422    /* Voltage PCI Low  Err  Threshold */
+@@ -229,17 +235,16 @@
+ #define       SK_SEN_PCI_IO_3V3_HIGH_ERR      3850    /* + 15% V PCI-IO High Err Threshold */
+ #define       SK_SEN_PCI_IO_3V3_HIGH_WARN     3674    /* + 10% V PCI-IO High Warn Threshold */
+                                       /*              3300    mVolt */
+-#define       SK_SEN_PCI_IO_3V3_LOW_WARN  2926        /* - 10% V PCI-IO Low Warn Threshold */
+-#define       SK_SEN_PCI_IO_3V3_LOW_ERR   2772        /* - 15% V PCI-IO Low Err  Threshold */
+-
++#define       SK_SEN_PCI_IO_3V3_LOW_WARN      2926    /* - 10% V PCI-IO Low Warn Threshold */
++#define       SK_SEN_PCI_IO_3V3_LOW_ERR       2772    /* - 15% V PCI-IO Low Err  Threshold */
+ /*
+  * VDD voltage
+  */
+-#define       SK_SEN_VDD_HIGH_ERR         3630        /* Voltage ASIC High Err  Threshold */
+-#define       SK_SEN_VDD_HIGH_WARN    3476    /* Voltage ASIC High Warn Threshold */
+-#define       SK_SEN_VDD_LOW_WARN     3146    /* Voltage ASIC Low  Warn Threshold */
+-#define       SK_SEN_VDD_LOW_ERR      2970    /* Voltage ASIC Low  Err  Threshold */
++#define       SK_SEN_VDD_HIGH_ERR             3630    /* Voltage ASIC High Err  Threshold */
++#define       SK_SEN_VDD_HIGH_WARN    3476    /* Voltage ASIC High Warn Threshold */
++#define       SK_SEN_VDD_LOW_WARN             3146    /* Voltage ASIC Low  Warn Threshold */
++#define       SK_SEN_VDD_LOW_ERR              2970    /* Voltage ASIC Low  Err  Threshold */
+ /*
+  * PHY PLL 3V3 voltage
+@@ -255,8 +260,8 @@
+ #define       SK_SEN_VAUX_3V3_HIGH_ERR        3630    /* Voltage VAUX High Err Threshold */
+ #define       SK_SEN_VAUX_3V3_HIGH_WARN       3476    /* Voltage VAUX High Warn Threshold */
+ #define       SK_SEN_VAUX_3V3_LOW_WARN        3146    /* Voltage VAUX Low Warn Threshold */
+-#define       SK_SEN_VAUX_3V3_LOW_ERR     2970        /* Voltage VAUX Low Err Threshold */
+-#define       SK_SEN_VAUX_0V_WARN_ERR        0        /* if VAUX not present */
++#define       SK_SEN_VAUX_3V3_LOW_ERR         2970    /* Voltage VAUX Low Err Threshold */
++#define       SK_SEN_VAUX_0V_WARN_ERR            0    /* if VAUX not present */
+ #define       SK_SEN_VAUX_RANGE_LIMITER       1000    /* 1000 mV range delimiter */
+ /*
+@@ -270,7 +275,7 @@
+ /*
+  * ASIC Core 1V5 voltage (YUKON only)
+  */
+-#define       SK_SEN_CORE_1V5_HIGH_ERR    1650        /* Voltage ASIC Core High Err Threshold */
++#define       SK_SEN_CORE_1V5_HIGH_ERR        1650    /* Voltage ASIC Core High Err Threshold */
+ #define       SK_SEN_CORE_1V5_HIGH_WARN       1575    /* Voltage ASIC Core High Warn Threshold */
+ #define       SK_SEN_CORE_1V5_LOW_WARN        1425    /* Voltage ASIC Core Low Warn Threshold */
+ #define       SK_SEN_CORE_1V5_LOW_ERR         1350    /* Voltage ASIC Core Low Err Threshold */
+@@ -285,8 +290,8 @@
+  */
+ #define       SK_SEN_FAN_HIGH_ERR             20000   /* FAN Speed High Err Threshold */
+ #define       SK_SEN_FAN_HIGH_WARN    20000   /* FAN Speed High Warn Threshold */
+-#define       SK_SEN_FAN_LOW_WARN     5200    /* FAN Speed Low Warn Threshold */
+-#define       SK_SEN_FAN_LOW_ERR              4550    /* FAN Speed Low Err Threshold */
++#define       SK_SEN_FAN_LOW_WARN              5200   /* FAN Speed Low Warn Threshold */
++#define       SK_SEN_FAN_LOW_ERR               4550   /* FAN Speed Low Err Threshold */
+ /*
+  * Some Voltages need dynamic thresholds
+--- linux-2.6.0/drivers/net/sk98lin/h/skgeinit.h       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/sk98lin/h/skgeinit.h        2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgeinit.h
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.81 $
+- * Date:      $Date: 2003/07/04 12:30:38 $
++ * Version:   $Revision: 1.83 $
++ * Date:      $Date: 2003/09/16 14:07:37 $
+  * Purpose:   Structures and prototypes for the GE Init Module
+  *
+  ******************************************************************************/
+@@ -27,6 +27,23 @@
+  * History:
+  *
+  *    $Log: skgeinit.h,v $
++ *    Revision 1.83  2003/09/16 14:07:37  rschmidt
++ *    Moved defines for PHY power down modes from skgehw.h
++ *    Added prototypes for SkMacClearRst()
++ *    Editorial changes
++ *    
++ *    Revision 1.82  2003/09/16 07:18:36  mschmid
++ *    Added members to port structure for MAC control
++ *    - PMacColThres
++ *    - PMacJamLen
++ *    - PMacJamIpgVal
++ *    - PMacJamIpgData
++ *    - PMacIpgData
++ *    - PMacLimit4
++ *    Added PHY power state to port structure
++ *    - PPhyPowerState
++ *    Added function prototypes to enter and leave low power modes
++ *    
+  *    Revision 1.81  2003/07/04 12:30:38  rschmidt
+  *    Added SK_FAR to pointers in MAC statistic functions (for PXE)
+  *    Editorial changes
+@@ -594,6 +611,13 @@ extern "C" {
+ #define SK_PRT_INIT           2       /* the port is initialized */
+ #define SK_PRT_RUN            3       /* the port has an active link */
++/* PHY power down modes */
++#define PHY_PM_OPERATIONAL_MODE               0       /* PHY operational mode */
++#define PHY_PM_DEEP_SLEEP                     1       /* coma mode --> minimal power */
++#define PHY_PM_IEEE_POWER_DOWN                2       /* IEEE 22.2.4.1.5 compl. power down */
++#define PHY_PM_ENERGY_DETECT          3       /* energy detect */
++#define PHY_PM_ENERGY_DETECT_PLUS     4       /* energy detect plus */
++
+ /* Default receive frame limit for Workaround of XMAC Errata */
+ #define SK_DEF_RX_WA_LIM      SK_CONSTU64(100)
+@@ -685,6 +709,13 @@ typedef   struct s_GePort {
+       SK_U8   PCableLen;              /* Cable Length */
+       SK_U8   PMdiPairLen[4]; /* MDI[0..3] Pair Length */
+       SK_U8   PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */
++      SK_U8   PPhyPowerState; /* PHY current power state */
++      int             PMacColThres;   /* MAC Collision Threshold */
++      int             PMacJamLen;             /* MAC Jam length */
++      int             PMacJamIpgVal;  /* MAC Jam IPG */
++      int             PMacJamIpgData; /* MAC IPG Jam to Data */
++      int             PMacIpgData;    /* MAC Data IPG */
++      SK_BOOL PMacLimit4;             /* reset collision counter and backoff algorithm */
+ } SK_GEPORT;
+ /*
+@@ -865,6 +896,11 @@ extern void       SkMacHardRst(
+       SK_IOC  IoC,
+       int             Port);
++extern void   SkMacClearRst(
++      SK_AC   *pAC,
++      SK_IOC  IoC,
++      int             Port);
++
+ extern void   SkXmInitMac(
+       SK_AC   *pAC,
+       SK_IOC  IoC,
+@@ -1040,6 +1076,17 @@ extern int SkGmCableDiagStatus(
+       int             Port,
+       SK_BOOL StartTest);
++extern int SkGmEnterLowPowerMode(
++      SK_AC   *pAC,
++      SK_IOC  IoC,
++      int             Port,
++      SK_U8   Mode);
++
++extern int SkGmLeaveLowPowerMode(
++      SK_AC   *pAC,
++      SK_IOC  IoC,
++      int             Port);
++
+ #ifdef SK_DIAG
+ extern void   SkGePhyRead(
+       SK_AC   *pAC,
+@@ -1101,6 +1148,7 @@ extern int       SkGeInitAssignRamToQueues();
+ extern void SkMacRxTxDisable();
+ extern void   SkMacSoftRst();
+ extern void   SkMacHardRst();
++extern void   SkMacClearRst();
+ extern void SkMacInitPhy();
+ extern int  SkMacRxTxEnable();
+ extern void SkMacPromiscMode();
+@@ -1131,6 +1179,8 @@ extern int       SkGmResetCounter();
+ extern int    SkXmOverflowStatus();
+ extern int    SkGmOverflowStatus();
+ extern int    SkGmCableDiagStatus();
++extern int    SkGmEnterLowPowerMode();
++extern int    SkGmLeaveLowPowerMode();
+ #ifdef SK_DIAG
+ extern void   SkGePhyRead();
+--- linux-2.6.0/drivers/net/sk98lin/h/skgepnmi.h       2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/h/skgepnmi.h        2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgepnmi.h
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.61 $
+- * Date:      $Date: 2003/05/23 12:53:52 $
++ * Version:   $Revision: 1.62 $
++ * Date:      $Date: 2003/08/15 12:31:52 $
+  * Purpose:   Defines for Private Network Management Interface
+  *
+  ****************************************************************************/
+@@ -27,6 +27,18 @@
+  * History:
+  *
+  *    $Log: skgepnmi.h,v $
++ *    Revision 1.62  2003/08/15 12:31:52  tschilli
++ *    Added new OIDs:
++ *    OID_SKGE_DRIVER_RELDATE
++ *    OID_SKGE_DRIVER_FILENAME
++ *    OID_SKGE_CHIPID
++ *    OID_SKGE_RAMSIZE
++ *    OID_SKGE_VAUXAVAIL
++ *    OID_SKGE_PHY_TYPE
++ *    OID_SKGE_PHY_LP_MODE
++ *    
++ *    Added new define SK_DIAG_ATTACHED for OID_SKGE_DIAG_MODE handling.
++ *    
+  *    Revision 1.61  2003/05/23 12:53:52  tschilli
+  *    Generic PNMI IOCTL subcommands added.
+  *    Function prototype SkPnmiGenIoctl() added.
+@@ -568,15 +580,23 @@
+ #define OID_SKGE_ALL_DATA                             0xFF020190
+ /* Defines for VCT. */
+-#define OID_SKGE_VCT_GET                      0xFF020200
+-#define OID_SKGE_VCT_SET                      0xFF020201
+-#define OID_SKGE_VCT_STATUS                   0xFF020202
++#define OID_SKGE_VCT_GET                              0xFF020200
++#define OID_SKGE_VCT_SET                              0xFF020201
++#define OID_SKGE_VCT_STATUS                           0xFF020202
+ #ifdef SK_DIAG_SUPPORT
+ /* Defines for driver DIAG mode. */
+-#define OID_SKGE_DIAG_MODE                    0xFF020204
++#define OID_SKGE_DIAG_MODE                            0xFF020204
+ #endif /* SK_DIAG_SUPPORT */
++/* New OIDs */
++#define OID_SKGE_DRIVER_RELDATE                       0xFF020210
++#define OID_SKGE_DRIVER_FILENAME              0xFF020211
++#define OID_SKGE_CHIPID                                       0xFF020212
++#define OID_SKGE_RAMSIZE                              0xFF020213
++#define OID_SKGE_VAUXAVAIL                            0xFF020214
++#define OID_SKGE_PHY_TYPE                             0xFF020215
++#define OID_SKGE_PHY_LP_MODE                  0xFF020216
+ /* VCT struct to store a backup copy of VCT data after a port reset. */
+ typedef struct s_PnmiVct {
+@@ -613,6 +633,12 @@ typedef struct s_PnmiVct {
+ #define OID_SKGE_TRAP_RLMT_PORT_UP            523
+ #define OID_SKGE_TRAP_RLMT_SEGMENTATION       524
++#ifdef SK_DIAG_SUPPORT
++/* Defines for driver DIAG mode. */
++#define SK_DIAG_ATTACHED      2
++#define SK_DIAG_RUNNING               1
++#define SK_DIAG_IDLE          0
++#endif /* SK_DIAG_SUPPORT */
+ /*
+  * Generic PNMI IOCTL subcommand definitions.
+@@ -730,6 +756,14 @@ typedef struct s_PnmiVct {
+ #define SK_PNMI_ERR051MSG     "SkPnmiEvent: Port switch suspicious"
+ #define SK_PNMI_ERR052                (SK_ERRBASE_PNMI + 52)
+ #define SK_PNMI_ERR052MSG     ""
++#define SK_PNMI_ERR053                (SK_ERRBASE_PNMI + 53)
++#define SK_PNMI_ERR053MSG     "General: Driver release date not initialized"
++#define SK_PNMI_ERR054                (SK_ERRBASE_PNMI + 54)
++#define SK_PNMI_ERR054MSG     "General: Driver release date string too long"
++#define SK_PNMI_ERR055                (SK_ERRBASE_PNMI + 55)
++#define SK_PNMI_ERR055MSG     "General: Driver file name not initialized"
++#define SK_PNMI_ERR056                (SK_ERRBASE_PNMI + 56)
++#define SK_PNMI_ERR056MSG     "General: Driver file name string too long"
+ /*
+  * Management counter macros called by the driver
+@@ -740,6 +774,11 @@ typedef struct s_PnmiVct {
+ #define SK_PNMI_SET_DRIVER_VER(pAC,v) ((pAC)->Pnmi.pDriverVersion = \
+       (char *)(v))
++#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v)     ((pAC)->Pnmi.pDriverReleaseDate = \
++      (char *)(v))
++
++#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v)    ((pAC)->Pnmi.pDriverFileName = \
++      (char *)(v))
+ #define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \
+       { \
+@@ -916,6 +955,8 @@ typedef struct s_PnmiConf {
+       char                    ConfMacFactoryAddr[6];
+       SK_U8                   ConfPMD;
+       SK_U8                   ConfConnector;
++      SK_U32                  ConfPhyType;
++      SK_U32                  ConfPhyMode;
+       SK_U8                   ConfLinkCapability;
+       SK_U8                   ConfLinkMode;
+       SK_U8                   ConfLinkModeStatus;
+@@ -964,9 +1005,14 @@ typedef struct s_PnmiStrucData {
+       SK_U32                  DeviceType;
+       char                    DriverDescr[SK_PNMI_STRINGLEN1];
+       char                    DriverVersion[SK_PNMI_STRINGLEN2];
++      char                    DriverReleaseDate[SK_PNMI_STRINGLEN1];
++      char                    DriverFileName[SK_PNMI_STRINGLEN1];
+       char                    HwDescr[SK_PNMI_STRINGLEN1];
+       char                    HwVersion[SK_PNMI_STRINGLEN2];
+       SK_U16                  Chipset;
++      SK_U32                  ChipId;
++      SK_U8                   VauxAvail;
++      SK_U32                  RamSize;
+       SK_U32                  MtuSize;
+       SK_U32                  Action;
+       SK_U32                  TestResult;
+@@ -1090,6 +1136,8 @@ typedef struct s_PnmiData {
+       char                    *pDriverDescription;
+       char                    *pDriverVersion;
++      char                    *pDriverReleaseDate;
++      char                    *pDriverFileName;
+       int                             MacUpdatedFlag;
+       int                             RlmtUpdatedFlag;
+@@ -1119,6 +1167,9 @@ typedef struct s_PnmiData {
+       SK_U8           VctStatus[SK_MAX_MACS];
+       SK_PNMI_VCT     VctBackup[SK_MAX_MACS];
+       SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
++#ifdef SK_DIAG_SUPPORT
++      SK_U32                  DiagAttached;
++#endif /* SK_DIAG_SUPPORT */
+ } SK_PNMI;
+--- linux-2.6.0/drivers/net/sk98lin/h/ski2c.h  2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/h/ski2c.h   2003-12-28 23:21:01.000000000 -0800
+@@ -1,16 +1,17 @@
+ /******************************************************************************
+  *
+  * Name:      ski2c.h
+- * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.34 $
+- * Date:      $Date: 2003/01/28 09:11:21 $
++ * Project:   Gigabit Ethernet Adapters, TWSI-Module
++ * Version:   $Revision: 1.35 $
++ * Date:      $Date: 2003/10/20 09:06:30 $
+  * Purpose:   Defines to access Voltage and Temperature Sensor
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2003 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect.
++ *    (C)Copyright 2002-2003 Marvell.
+  *
+  *    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
+@@ -26,6 +27,10 @@
+  * History:
+  *
+  *    $Log: ski2c.h,v $
++ *    Revision 1.35  2003/10/20 09:06:30  rschmidt
++ *    Added prototypes for SkI2cRead() and SkI2cWrite().
++ *    Editorial changes.
++ *    
+  *    Revision 1.34  2003/01/28 09:11:21  rschmidt
+  *    Editorial changes
+  *    
+@@ -137,7 +142,6 @@
+  *    Revision 1.1  1998/06/19 14:30:10  malthoff
+  *    Created. Sources taken from ML Project.
+  *
+- *
+  ******************************************************************************/
+ /*
+@@ -252,7 +256,7 @@ struct     s_Sensor {
+       SK_I32  SenThreWarnLow;         /* Lower warning Threshold of the sensor */
+       int             SenErrFlag;                     /* Sensor indicated an error */
+       SK_BOOL SenInit;                        /* Is sensor initialized ? */
+-      SK_U64  SenErrCts;                      /* Error  trap counter */
++      SK_U64  SenErrCts;                      /* Error trap counter */
+       SK_U64  SenWarnCts;                     /* Warning trap counter */
+       SK_U64  SenBegErrTS;            /* Begin error timestamp */
+       SK_U64  SenBegWarnTS;           /* Begin warning timestamp */
+@@ -279,13 +283,17 @@ typedef  struct  s_I2c {
+ #endif /* !SK_DIAG */
+ } SK_I2C;
++extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
++extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size,
++                                         int Reg, int Burst);
+ extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
+-#ifndef SK_DIAG
++#ifdef SK_DIAG
++extern        SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg,
++                                               int Burst);
++#else /* !SK_DIAG */
+ extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
+-extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
+ extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
+ extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
+-
+-#endif
++#endif /* !SK_DIAG */
+ #endif /* n_SKI2C_H */
+--- linux-2.6.0/drivers/net/sk98lin/h/skqueue.h        2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/h/skqueue.h 2003-12-28 23:21:01.000000000 -0800
+@@ -1,9 +1,9 @@
+ /******************************************************************************
+  *
+  * Name:      skqueue.h
+- * Project:   Gigabit Ethernet Adapters, Schedule-Modul
+- * Version:   $Revision: 1.15 $
+- * Date:      $Date: 2003/05/13 17:54:57 $
++ * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
++ * Version:   $Revision: 1.16 $
++ * Date:      $Date: 2003/09/16 12:50:32 $
+  * Purpose:   Defines for the Event queue
+  *
+  ******************************************************************************/
+@@ -27,6 +27,9 @@
+  * History:
+  *
+  *    $Log: skqueue.h,v $
++ *    Revision 1.16  2003/09/16 12:50:32  rschmidt
++ *    Editorial changes
++ *    
+  *    Revision 1.15  2003/05/13 17:54:57  mkarl
+  *    Editorial changes.
+  *    
+@@ -47,7 +50,7 @@
+  *    add: typedef SK_QUEUE
+  *    
+  *    Revision 1.9  1998/08/19 09:50:59  gklug
+- *    fix: remove struct keyword from c-code (see CCC) add typedefs
++ *    fix: remove struct keyword from C-code (see CCC) add typedefs
+  *    
+  *    Revision 1.8  1998/08/18 07:00:01  gklug
+  *    fix: SK_PTR not defined use void * instead.
+@@ -74,8 +77,6 @@
+  *    Revision 1.1  1998/07/30 14:52:12  gklug
+  *    Initial version.
+  *    Defines Event Classes, Event structs and queue management variables.
+- *    
+- *    
+  *
+  ******************************************************************************/
+@@ -92,7 +93,7 @@
+  */
+ #define       SKGE_DRV        1       /* Driver Event Class */
+ #define       SKGE_RLMT       2       /* RLMT Event Class */
+-#define       SKGE_I2C        3       /* i2C Event Class */
++#define       SKGE_I2C        3       /* I2C Event Class */
+ #define       SKGE_PNMI       4       /* PNMI Event Class */
+ #define       SKGE_CSUM       5       /* Checksum Event Class */
+ #define       SKGE_HWAC       6       /* Hardware Access Event Class */
+@@ -121,25 +122,25 @@ typedef  union u_EvPara {
+  * Event Queue
+  *    skqueue.c
+  * events are class/value pairs
+- *    class   is addressee, e.g. RMT, PCM etc.
++ *    class   is addressee, e.g. RLMT, PNMI etc.
+  *    value   is command, e.g. line state change, ring op change etc.
+  */
+ typedef       struct s_EventElem {
+-      SK_U32          Class ;                 /* Event class */
+-      SK_U32          Event ;                 /* Event value */
+-      SK_EVPARA       Para ;                  /* Event parameter */
++      SK_U32          Class;                  /* Event class */
++      SK_U32          Event;                  /* Event value */
++      SK_EVPARA       Para;                   /* Event parameter */
+ } SK_EVENTELEM;
+ typedef       struct s_Queue {
+       SK_EVENTELEM    EvQueue[SK_MAX_EVENT];
+-      SK_EVENTELEM    *EvPut ;
+-      SK_EVENTELEM    *EvGet ;
++      SK_EVENTELEM    *EvPut;
++      SK_EVENTELEM    *EvGet;
+ } SK_QUEUE;
+ extern        void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level);
+ extern        void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event,
+       SK_EVPARA Para);
+-extern        int SkEventDispatcher(SK_AC *pAC,SK_IOC Ioc);
++extern        int SkEventDispatcher(SK_AC *pAC, SK_IOC Ioc);
+ /* Define Error Numbers and messages */
+--- linux-2.6.0/drivers/net/sk98lin/h/sktimer.h        2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/h/sktimer.h 2003-12-28 23:21:01.000000000 -0800
+@@ -1,9 +1,9 @@
+ /******************************************************************************
+  *
+  * Name:      sktimer.h
+- * Project:   Gigabit Ethernet Adapters, Schedule-Modul
+- * Version:   $Revision: 1.10 $
+- * Date:      $Date: 2003/05/13 17:56:44 $
++ * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
++ * Version:   $Revision: 1.11 $
++ * Date:      $Date: 2003/09/16 12:58:18 $
+  * Purpose:   Defines for the timer functions
+  *
+  ******************************************************************************/
+@@ -27,6 +27,9 @@
+  * History:
+  *
+  *    $Log: sktimer.h,v $
++ *    Revision 1.11  2003/09/16 12:58:18  rschmidt
++ *    Editorial changes
++ *    
+  *    Revision 1.10  2003/05/13 17:56:44  mkarl
+  *    Editorial changes.
+  *    
+@@ -40,7 +43,7 @@
+  *    fix: SK_TIMCTRL needs to be defined
+  *    
+  *    Revision 1.6  1998/08/19 09:51:00  gklug
+- *    fix: remove struct keyword from c-code (see CCC) add typedefs
++ *    fix: remove struct keyword from C-code (see CCC) add typedefs
+  *    
+  *    Revision 1.5  1998/08/17 13:43:21  gklug
+  *    chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
+@@ -78,25 +81,25 @@
+ typedef       struct s_Timer SK_TIMER;
+ struct s_Timer {
+-      SK_TIMER        *TmNext ;       /* linked list */
+-      SK_U32          TmClass ;       /* Timer Event class */
+-      SK_U32          TmEvent ;       /* Timer Event value */
+-      SK_EVPARA       TmPara ;        /* Timer Event parameter */
+-      SK_U32          TmDelta ;       /* delta time */
+-      int             TmActive ;      /* flag : active/inactive */
+-} ;
++      SK_TIMER        *TmNext;        /* linked list */
++      SK_U32          TmClass;        /* Timer Event class */
++      SK_U32          TmEvent;        /* Timer Event value */
++      SK_EVPARA       TmPara;         /* Timer Event parameter */
++      SK_U32          TmDelta;        /* delta time */
++      int                     TmActive;       /* flag: active/inactive */
++};
+ /*
+  * Timer control struct.
+  * - use in Adapters context name pAC->Tim
+  */
+ typedef       struct s_TimCtrl {
+-      SK_TIMER        *StQueue ;      /* Head of Timer queue */
+-} SK_TIMCTRL ;
++      SK_TIMER        *StQueue;       /* Head of Timer queue */
++} SK_TIMCTRL;
+-extern void SkTimerInit(SK_AC *pAC,SK_IOC Ioc, int Level);
+-extern void SkTimerStop(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer);
+-extern void SkTimerStart(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer,
+-      SK_U32 Time,SK_U32 Class,SK_U32 Event,SK_EVPARA Para);
+-extern void SkTimerDone(SK_AC *pAC,SK_IOC Ioc);
++extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level);
++extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer);
++extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer,
++      SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para);
++extern void SkTimerDone(SK_AC *pAC, SK_IOC Ioc);
+ #endif        /* _SKTIMER_H_ */
+--- linux-2.6.0/drivers/net/sk98lin/h/sktypes.h        2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/sk98lin/h/sktypes.h 2003-12-28 23:21:01.000000000 -0800
+@@ -2,15 +2,16 @@
+  *
+  * Name:      sktypes.h
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.1 $
+- * Date:      $Date: 2003/07/21 07:26:01 $
++ * Version:   $Revision: 1.2 $
++ * Date:      $Date: 2003/10/07 08:16:51 $
+  * Purpose:   Define data types for Linux
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2003 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect GmbH.
++ *    (C)Copyright 2002-2003 Marvell.
+  *
+  *    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
+@@ -26,6 +27,9 @@
+  * History:
+  *
+  *    $Log: sktypes.h,v $
++ *    Revision 1.2  2003/10/07 08:16:51  mlindner
++ *    Fix: Copyright changes
++ *    
+  *    Revision 1.1  2003/07/21 07:26:01  rroesler
+  *    Fix: Re-Enter after CVS crash
+  *    
+--- linux-2.6.0/drivers/net/sk98lin/h/skversion.h      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/sk98lin/h/skversion.h       2003-12-28 23:21:01.000000000 -0800
+@@ -2,15 +2,16 @@
+  *
+  * Name:      version.h
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.3 $
+- * Date:      $Date: 2003/08/25 13:34:48 $
++ * Version:   $Revision: 1.5 $
++ * Date:      $Date: 2003/10/07 08:16:51 $
+  * Purpose:   SK specific Error log support
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2003 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect GmbH.
++ *    (C)Copyright 2002-2003 Marvell.
+  *
+  *    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
+@@ -25,6 +26,12 @@
+  *
+  * History:
+  *    $Log: skversion.h,v $
++ *    Revision 1.5  2003/10/07 08:16:51  mlindner
++ *    Fix: Copyright changes
++ *    
++ *    Revision 1.4  2003/09/22 08:40:10  mlindner
++ *    Add: Added DRIVER_FILE_NAME and DRIVER_REL_DATE
++ *    
+  *    Revision 1.3  2003/08/25 13:34:48  mlindner
+  *    Fix: Lint changes
+  *    
+@@ -54,12 +61,14 @@
+ #ifdef        lint
+ static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
+ static const char SysKonnectBuildNumber[] =
+-      "@(#)SK-BUILD: 6.18 PL: 01"; 
++      "@(#)SK-BUILD: 6.21 PL: 01"; 
+ #endif        /* !defined(lint) */
+-#define BOOT_STRING   "sk98lin: Network Device Driver v6.18\n" \
++#define BOOT_STRING   "sk98lin: Network Device Driver v6.21\n" \
+                       "(C)Copyright 1999-2003 Marvell(R)."
+-#define VER_STRING    "6.18"
++#define VER_STRING    "6.21"
++#define DRIVER_FILE_NAME      "sk98lin"
++#define DRIVER_REL_DATE               "Dec-15-2003"
+--- linux-2.6.0/drivers/net/sk98lin/h/xmac_ii.h        2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/h/xmac_ii.h 2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      xmac_ii.h
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.48 $
+- * Date:      $Date: 2003/05/13 17:17:55 $
++ * Version:   $Revision: 1.52 $
++ * Date:      $Date: 2003/10/02 16:35:50 $
+  * Purpose:   Defines and Macros for Gigabit Ethernet Controller
+  *
+  ******************************************************************************/
+@@ -27,6 +27,22 @@
+  * History:
+  *
+  *    $Log: xmac_ii.h,v $
++ *    Revision 1.52  2003/10/02 16:35:50  rschmidt
++ *    Added defines for default values of GMAC parameters
++ *    Changed defines for setting GMAC parameters
++ *    Editorial changes
++ *    
++ *    Revision 1.51  2003/09/23 09:04:27  malthoff
++ *    Add bit definitions for PHY_MARV_EXT_P_STAT.
++ *    
++ *    Revision 1.50  2003/09/16 14:15:07  rschmidt
++ *    Added defines for Extended PHY Specific Control
++ *    Editorial changes
++ *    
++ *    Revision 1.49  2003/09/16 07:22:46  mschmid
++ *    Added defines for Marvell PHY energy detect modes
++ *    Added macros for MAC parameter setting in port structure
++ *    
+  *    Revision 1.48  2003/05/13 17:17:55  mkarl
+  *    Editorial changes.
+  *    
+@@ -676,7 +692,7 @@ extern "C" {
+ #define PHY_XMAC_AUNE_LP      0x05    /* 16 bit r/o   Link Partner Abi Reg */
+ #define PHY_XMAC_AUNE_EXP     0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
+ #define PHY_XMAC_NEPG         0x07    /* 16 bit r/w   Next Page Register */
+-#define PHY_XMAC_NEPG_LP      0x08    /* 16 bit r/o   Next Page Link P Reg */
++#define PHY_XMAC_NEPG_LP      0x08    /* 16 bit r/o   Next Page Link Partner */
+       /* 0x09 - 0x0e:         reserved */
+ #define PHY_XMAC_EXT_STAT     0x0f    /* 16 bit r/o   Ext Status Register */
+ #define PHY_XMAC_RES_ABI      0x10    /* 16 bit r/o   PHY Resolved Ability */
+@@ -693,7 +709,7 @@ extern "C" {
+ #define PHY_BCOM_AUNE_LP      0x05    /* 16 bit r/o   Link Part Ability Reg */
+ #define PHY_BCOM_AUNE_EXP     0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
+ #define PHY_BCOM_NEPG         0x07    /* 16 bit r/w   Next Page Register */
+-#define PHY_BCOM_NEPG_LP      0x08    /* 16 bit r/o   Next Page Link P Reg */
++#define PHY_BCOM_NEPG_LP      0x08    /* 16 bit r/o   Next Page Link Partner */
+       /* Broadcom-specific registers */
+ #define PHY_BCOM_1000T_CTRL   0x09    /* 16 bit r/w   1000Base-T Ctrl Reg */
+ #define PHY_BCOM_1000T_STAT   0x0a    /* 16 bit r/o   1000Base-T Status Reg */
+@@ -702,7 +718,7 @@ extern "C" {
+ #define PHY_BCOM_P_EXT_CTRL   0x10    /* 16 bit r/w   PHY Extended Ctrl Reg */
+ #define PHY_BCOM_P_EXT_STAT   0x11    /* 16 bit r/o   PHY Extended Stat Reg */
+ #define PHY_BCOM_RE_CTR               0x12    /* 16 bit r/w   Receive Error Counter */
+-#define PHY_BCOM_FC_CTR               0x13    /* 16 bit r/w   False Carr Sense Cnt */
++#define PHY_BCOM_FC_CTR               0x13    /* 16 bit r/w   False Carrier Sense Cnt */
+ #define PHY_BCOM_RNO_CTR      0x14    /* 16 bit r/w   Receiver NOT_OK Cnt */
+       /* 0x15 - 0x17:         reserved */
+ #define PHY_BCOM_AUX_CTRL     0x18    /* 16 bit r/w   Auxiliary Control Reg */
+@@ -724,7 +740,7 @@ extern "C" {
+ #define PHY_MARV_AUNE_LP      0x05    /* 16 bit r/o   Link Part Ability Reg */
+ #define PHY_MARV_AUNE_EXP     0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
+ #define PHY_MARV_NEPG         0x07    /* 16 bit r/w   Next Page Register */
+-#define PHY_MARV_NEPG_LP      0x08    /* 16 bit r/o   Next Page Link P Reg */
++#define PHY_MARV_NEPG_LP      0x08    /* 16 bit r/o   Next Page Link Partner */
+       /* Marvel-specific registers */
+ #define PHY_MARV_1000T_CTRL   0x09    /* 16 bit r/w   1000Base-T Ctrl Reg */
+ #define PHY_MARV_1000T_STAT   0x0a    /* 16 bit r/o   1000Base-T Status Reg */
+@@ -757,7 +773,7 @@ extern "C" {
+ #define PHY_LONE_AUNE_LP      0x05    /* 16 bit r/o   Link Part Ability Reg */
+ #define PHY_LONE_AUNE_EXP     0x06    /* 16 bit r/o   Auto-Neg. Expansion Reg */
+ #define PHY_LONE_NEPG         0x07    /* 16 bit r/w   Next Page Register */
+-#define PHY_LONE_NEPG_LP      0x08    /* 16 bit r/o   Next Page Link Partner*/
++#define PHY_LONE_NEPG_LP      0x08    /* 16 bit r/o   Next Page Link Partner */
+       /* Level One-specific registers */
+ #define PHY_LONE_1000T_CTRL   0x09    /* 16 bit r/w   1000Base-T Control Reg*/
+ #define PHY_LONE_1000T_STAT   0x0a    /* 16 bit r/o   1000Base-T Status Reg */
+@@ -804,12 +820,13 @@ extern "C" {
+ /*
+  * PHY bit definitions
+  * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
+- * Xmac/Broadcom/LevelOne/National-specific.
++ * XMAC/Broadcom/LevelOne/National/Marvell-specific.
+  * All other are general.
+  */
+ /*****  PHY_XMAC_CTRL 16 bit r/w      PHY Control Register *****/
+ /*****  PHY_BCOM_CTRL 16 bit r/w      PHY Control Register *****/
++/*****  PHY_MARV_CTRL 16 bit r/w      PHY Status Register *****/
+ /*****  PHY_LONE_CTRL 16 bit r/w      PHY Control Register *****/
+ #define PHY_CT_RESET  (1<<15) /* Bit 15: (sc) clear all PHY related regs */
+ #define PHY_CT_LOOP           (1<<14) /* Bit 14:      enable Loopback over PHY */
+@@ -909,27 +926,20 @@ extern "C" {
+ /*****  PHY_XMAC_AUNE_EXP     16 bit r/o      Auto-Negotiation Expansion Reg *****/
+                                                               /* Bit 15..4:   reserved */
+-#define PHY_AN_LP_NP  (1<<3)  /* Bit  3:      Link Partner can Next Page */
+-#define PHY_AN_LOC_NP (1<<2)  /* Bit  2:      Local PHY can Next Page */
+-#define PHY_AN_RX_PG  (1<<1)  /* Bit  1:      Page Received */
++#define PHY_ANE_LP_NP (1<<3)  /* Bit  3:      Link Partner can Next Page */
++#define PHY_ANE_LOC_NP        (1<<2)  /* Bit  2:      Local PHY can Next Page */
++#define PHY_ANE_RX_PG (1<<1)  /* Bit  1:      Page Received */
+                                                               /* Bit  0:      reserved */
+ /*****  PHY_BCOM_AUNE_EXP     16 bit r/o      Auto-Negotiation Expansion Reg *****/
+-                                                              /* Bit 15..5:   reserved */
+-#define PHY_B_AN_PDF  (1<<4)  /* Bit  4:      Parallel Detection Fault */
+-/*    PHY_AN_LP_NP            (see XMAC) Bit  3:      Link Partner can Next Page */
+-/*    PHY_AN_LOC_NP           (see XMAC) Bit  2:      Local PHY can Next Page */
+-/*    PHY_AN_RX_PG            (see XMAC) Bit  1:      Page Received */
+-#define PHY_B_AN_LP_CAP       (1<<0)  /* Bit  0:      Link Partner Auto-Neg. Cap. */  
+-
+ /*****  PHY_LONE_AUNE_EXP     16 bit r/o      Auto-Negotiation Expansion Reg *****/
+-#define PHY_L_AN_BP           (1<<5)  /* Bit  5:      Base Page Indication */
+-#define PHY_L_AN_PDF  (1<<4)  /* Bit  4:      Parallel Detection Fault */
+-/*    PHY_AN_LP_NP            (see XMAC) Bit  3:      Link Partner can Next Page */
+-/*    PHY_AN_LOC_NP           (see XMAC) Bit  2:      Local PHY can Next Page */
+-/*    PHY_AN_RX_PG            (see XMAC) Bit  1:      Page Received */
+-#define PHY_B_AN_LP_CAP       (1<<0)  /* Bit  0:      Link Partner Auto-Neg. Cap. */  
+-
++/*****  PHY_MARV_AUNE_EXP     16 bit r/o      Auto-Negotiation Expansion Reg *****/
++                                                              /* Bit 15..5:   reserved */
++#define PHY_ANE_PAR_DF        (1<<4)  /* Bit  4:      Parallel Detection Fault */
++/*    PHY_ANE_LP_NP           (see XMAC) Bit  3:      Link Partner can Next Page */
++/*    PHY_ANE_LOC_NP          (see XMAC) Bit  2:      Local PHY can Next Page */
++/*    PHY_ANE_RX_PG           (see XMAC) Bit  1:      Page Received */
++#define PHY_ANE_LP_CAP        (1<<0)  /* Bit  0:      Link Partner Auto-Neg. Cap. */  
+ /*****  PHY_XMAC_NEPG         16 bit r/w      Next Page Register *****/
+ /*****  PHY_BCOM_NEPG         16 bit r/w      Next Page Register *****/
+@@ -958,7 +968,7 @@ extern "C" {
+ #define PHY_X_RS_HD           (1<<6)  /* Bit  6:      Half Duplex Mode selected */
+ #define PHY_X_RS_FD           (1<<5)  /* Bit  5:      Full Duplex Mode selected */
+ #define PHY_X_RS_ABLMIS (1<<4)        /* Bit  4:      duplex or pause cap mismatch */
+-#define PHY_X_RS_PAUMIS (1<<3)        /* Bit  3:      pause capability missmatch */
++#define PHY_X_RS_PAUMIS (1<<3)        /* Bit  3:      pause capability mismatch */
+                                                               /* Bit  2..0:   reserved */
+ /*
+  * Remote Fault Bits (PHY_X_AN_RFB) encoding
+@@ -990,6 +1000,7 @@ extern "C" {
+                                                                       /* Bit  7..0:   reserved */
+ /*****  PHY_BCOM_1000T_STAT   16 bit r/o      1000Base-T Status Reg *****/
++/*****  PHY_MARV_1000T_STAT   16 bit r/o      1000Base-T Status Reg *****/
+ #define PHY_B_1000S_MSF               (1<<15) /* Bit 15:      Master/Slave Fault */
+ #define PHY_B_1000S_MSR               (1<<14) /* Bit 14:      Master/Slave Result */
+ #define PHY_B_1000S_LRS               (1<<13) /* Bit 13:      Local Receiver Status */
+@@ -1309,7 +1320,6 @@ extern "C" {
+                                                                       /* Bit  7..0:   reserved */
+ /*****  PHY_MARV_PHY_CTRL     16 bit r/w      PHY Specific Ctrl Reg *****/
+-
+ #define PHY_M_PC_TX_FFD_MSK   (3<<14) /* Bit 15..14:  Tx FIFO Depth Mask */
+ #define PHY_M_PC_RX_FFD_MSK   (3<<12) /* Bit 13..12:  Rx FIFO Depth Mask */
+ #define PHY_M_PC_ASS_CRS_TX   (1<<11) /* Bit 11:      Assert CRS on Transmit */
+@@ -1323,6 +1333,9 @@ extern "C" {
+ #define PHY_M_PC_POL_R_DIS    (1<<1)  /* Bit  1:      Polarity Reversal Disabled */
+ #define PHY_M_PC_DIS_JABBER   (1<<0)  /* Bit  0:      Disable Jabber */
++#define PHY_M_PC_EN_DET                       SHIFT8(2)       /* Energy Detect (Mode 1) */
++#define PHY_M_PC_EN_DET_PLUS  SHIFT8(3)       /* Energy Detect Plus (Mode 2) */
++
+ #define PHY_M_PC_MDI_XMODE(x) SHIFT5(x)       
+ #define PHY_M_PC_MAN_MDI      0       /* 00 = Manual MDI configuration */
+ #define PHY_M_PC_MAN_MDIX     1               /* 01 = Manual MDIX configuration */
+@@ -1373,6 +1386,7 @@ extern "C" {
+ #define PHY_M_EC_M_DSC_MSK    (3<<10) /* Bit 11..10:  Master downshift counter */
+ #define PHY_M_EC_S_DSC_MSK    (3<<8)  /* Bit  9.. 8:  Slave  downshift counter */
+ #define PHY_M_EC_MAC_S_MSK    (7<<4)  /* Bit  6.. 4:  Def. MAC interface speed */
++#define PHY_M_EC_FIB_AN_ENA   (1<<3)  /* Bit  3:      Fiber Auto-Neg. Enable */
+ #define PHY_M_EC_M_DSC(x)             SHIFT10(x)      /* 00=1x; 01=2x; 10=3x; 11=4x */
+ #define PHY_M_EC_S_DSC(x)             SHIFT8(x)       /* 00=dis; 01=1x; 10=2x; 11=3x */
+@@ -1434,6 +1448,18 @@ extern "C" {
+ #define PHY_M_EC2_FO_BOOST    (1<<3)  /* Bit  3:      Fiber Output Boost */
+ #define PHY_M_EC2_FO_AM_MSK   7               /* Bit  2.. 0:  Fiber Output Amplitude */
++/*****        PHY_MARV_EXT_P_STAT 16 bit r/w  Ext. PHY Specific Status *****/
++#define PHY_M_FC_AUTO_SEL     (1<<15) /* Bit 15:      Fiber/Copper Auto Sel. dis. */
++#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14:        Fiber/Copper Autoneg. reg acc */
++#define PHY_M_FC_RESULUTION (1<<13)   /* Bit 13:      Fiber/Copper Resulution */
++#define PHY_M_SER_IF_AN_BP  (1<<12) /* Bit 12:        Ser IF autoneg. bypass enable */
++#define PHY_M_SER_IF_BP_ST    (1<<11) /* Bit 11:      Ser IF autoneg. bypass status */
++#define PHY_M_IRQ_POLARITY    (1<<10) /* Bit 10:      IRQ polarity */
++                                                                      /* Bit 9..4: reserved */
++#define PHY_M_UNDOC1          (1<< 7) /* undocumented bit !! */
++#define PHY_M_MODE_MASK               (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */
++
++
+ /*****  PHY_MARV_CABLE_DIAG   16 bit r/o      Cable Diagnostic Reg *****/
+ #define PHY_M_CABD_ENA_TEST   (1<<15) /* Bit 15:      Enable Test */
+ #define PHY_M_CABD_STAT_MSK   (3<<13) /* Bit 14..13:  Status */
+@@ -1531,7 +1557,7 @@ extern "C" {
+ #define GM_RXF_SHT \
+                       (GM_MIB_CNT_BASE + 80)  /* Frames <64 Byte Received OK */
+ #define GM_RXE_FRAG \
+-                      (GM_MIB_CNT_BASE + 88)  /* Frames <64 Byte Receeived with FCS Err */
++                      (GM_MIB_CNT_BASE + 88)  /* Frames <64 Byte Received with FCS Err */
+ #define GM_RXF_64B \
+                       (GM_MIB_CNT_BASE + 96)  /* 64 Byte Rx Frame */
+ #define GM_RXF_127B \
+@@ -1606,7 +1632,6 @@ extern "C" {
+  */
+ /*    GM_GP_STAT      16 bit r/o      General Purpose Status Register */
+-
+ #define GM_GPSR_SPEED         (1<<15) /* Bit 15:      Port Speed (1 = 100 Mbps) */
+ #define GM_GPSR_DUPLEX                (1<<14) /* Bit 14:      Duplex Mode (1 = Full) */
+ #define GM_GPSR_FC_TX_DIS     (1<<13) /* Bit 13:      Tx Flow-Control Mode Disabled */
+@@ -1646,11 +1671,14 @@ extern "C" {
+                                                        GM_GPCR_AU_SPD_DIS)
+       
+ /*    GM_TX_CTRL                              16 bit r/w      Transmit Control Register */
+-
+ #define GM_TXCR_FORCE_JAM     (1<<15) /* Bit 15:      Force Jam / Flow-Control */
+ #define GM_TXCR_CRC_DIS               (1<<14) /* Bit 14:      Disable insertion of CRC */
+ #define GM_TXCR_PAD_DIS               (1<<13) /* Bit 13:      Disable padding of packets */
+-#define GM_TXCR_COL_THR               (4<<10) /* Bit 12..10:  Collision Threshold */
++#define GM_TXCR_COL_THR_MSK   (1<<10) /* Bit 12..10:  Collision Threshold */
++
++#define TX_COL_THR(x)         (SHIFT10(x) & GM_TXCR_COL_THR_MSK)
++
++#define TX_COL_DEF                    0x04
+       
+ /*    GM_RX_CTRL                              16 bit r/w      Receive Control Register */
+ #define GM_RXCR_UCF_ENA               (1<<15) /* Bit 15:      Enable Unicast filtering */
+@@ -1663,35 +1691,41 @@ extern "C" {
+ #define GM_TXPA_JAMIPG_MSK    (0x1f<<9)       /* Bit 13..9:   Jam IPG */
+ #define GM_TXPA_JAMDAT_MSK    (0x1f<<4)       /* Bit  8..4:   IPG Jam to Data */
+                                                               /* Bit  3..0:   reserved */
+-#define JAM_LEN_VAL(x)                SHIFT14(x)
+-#define JAM_IPG_VAL(x)                SHIFT9(x)
+-#define IPG_JAM_DATA(x)               SHIFT4(x)
++
++#define TX_JAM_LEN_VAL(x)     (SHIFT14(x) & GM_TXPA_JAMLEN_MSK)
++#define TX_JAM_IPG_VAL(x)     (SHIFT9(x) & GM_TXPA_JAMIPG_MSK)
++#define TX_IPG_JAM_DATA(x)    (SHIFT4(x) & GM_TXPA_JAMDAT_MSK)
++
++#define TX_JAM_LEN_DEF                0x03
++#define TX_JAM_IPG_DEF                0x0b
++#define TX_IPG_JAM_DEF                0x1c
+ /*    GM_SERIAL_MODE                  16 bit r/w      Serial Mode Register */
+-#define GM_SMOD_DATABL_MSK    (0x1f<<11)      /* Bit 15..11:  Data Blinder */
++#define GM_SMOD_DATABL_MSK    (0x1f<<11)      /* Bit 15..11:  Data Blinder (r/o) */
+ #define GM_SMOD_LIMIT_4               (1<<10) /* Bit 10:      4 consecutive Tx trials */
+ #define GM_SMOD_VLAN_ENA      (1<<9)  /* Bit  9:      Enable VLAN  (Max. Frame Len) */
+ #define GM_SMOD_JUMBO_ENA     (1<<8)  /* Bit  8:      Enable Jumbo (Max. Frame Len) */
+                                                               /* Bit  7..5:   reserved */
+ #define GM_SMOD_IPG_MSK               0x1f    /* Bit 4..0:    Inter-Packet Gap (IPG) */
+       
+-#define DATA_BLIND_VAL(x)     SHIFT11(x)
+-#define DATA_BLIND_FAST_ETH   0x1c
+-#define DATA_BLIND_GIGABIT    4
++#define DATA_BLIND_VAL(x)     (SHIFT11(x) & GM_SMOD_DATABL_MSK)
++#define DATA_BLIND_DEF                0x04
+-#define IPG_VAL_FAST_ETH      0x1e
+-#define IPG_VAL_GIGABIT               6
++#define IPG_DATA_VAL(x)               (x & GM_SMOD_IPG_MSK)
++#define IPG_DATA_DEF          0x1e
+ /*    GM_SMI_CTRL                             16 bit r/w      SMI Control Register */
+-
+-#define GM_SMI_CT_PHY_AD(x)   SHIFT11(x)
+-#define GM_SMI_CT_REG_AD(x)   SHIFT6(x)
++#define GM_SMI_CT_PHY_A_MSK   (0x1f<<11)      /* Bit 15..11:  PHY Device Address */
++#define GM_SMI_CT_REG_A_MSK   (0x1f<<6)       /* Bit 10.. 6:  PHY Register Address */
+ #define GM_SMI_CT_OP_RD               (1<<5)  /* Bit  5:      OpCode Read (0=Write)*/
+ #define GM_SMI_CT_RD_VAL      (1<<4)  /* Bit  4:      Read Valid (Read completed) */
+ #define GM_SMI_CT_BUSY                (1<<3)  /* Bit  3:      Busy (Operation in progress) */
+                                                               /* Bit   2..0:  reserved */
+       
+-/*    GM_PHY_ADDR                             16 bit r/w      GPHY Address Register */
++#define GM_SMI_CT_PHY_AD(x)   (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK)
++#define GM_SMI_CT_REG_AD(x)   (SHIFT6(x) & GM_SMI_CT_REG_A_MSK)
++
++      /*      GM_PHY_ADDR                             16 bit r/w      GPHY Address Register */
+                                                               /* Bit  15..6:  reserved */
+ #define GM_PAR_MIB_CLR                (1<<5)  /* Bit  5:      Set MIB Clear Counter Mode */
+ #define GM_PAR_MIB_TST                (1<<4)  /* Bit  4:      MIB Load Counter (Test Mode) */
+--- linux-2.6.0/drivers/net/sk98lin/Makefile   2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/Makefile    2003-12-28 23:21:01.000000000 -0800
+@@ -76,7 +76,7 @@ endif
+ # SK_DBGCAT_DRV_INT_SRC         0x04000000      interrupts sources
+ # SK_DBGCAT_DRV_EVENT           0x08000000      driver events
+-EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
++EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
+ clean:
+       rm -f core *.o *.a *.s
+--- linux-2.6.0/drivers/net/sk98lin/skcsum.c   2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/skcsum.c    2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skcsum.c
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.11 $
+- * Date:      $Date: 2003/03/11 14:05:55 $
++ * Version:   $Revision: 1.12 $
++ * Date:      $Date: 2003/08/20 13:55:53 $
+  * Purpose:   Store/verify Internet checksum in send/receive packets.
+  *
+  ******************************************************************************/
+@@ -26,6 +26,10 @@
+  * History:
+  *
+  *    $Log: skcsum.c,v $
++ *    Revision 1.12  2003/08/20 13:55:53  mschmid
++ *    Changed notation of #ifndef SkCsCalculateChecksum to
++ *    #ifndef SK_CS_CALCULATE_CHECKSUM
++ *    
+  *    Revision 1.11  2003/03/11 14:05:55  rschmidt
+  *    Replaced memset() by macro SK_MEMSET()
+  *    Editorial changes
+@@ -78,7 +82,7 @@
+ #ifndef lint
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skcsum.c,v 1.11 2003/03/11 14:05:55 rschmidt Exp $ (C) SysKonnect.";
++      "@(#) $Id: skcsum.c,v 1.12 2003/08/20 13:55:53 mschmid Exp $ (C) SysKonnect.";
+ #endif        /* !lint */
+ /******************************************************************************
+@@ -791,7 +795,7 @@ int                        NetNumber)
+       *pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE;
+ }     /* SkCsSetReceiveFlags */
+-#ifndef SkCsCalculateChecksum
++#ifndef SK_CS_CALCULATE_CHECKSUM
+ /******************************************************************************
+  *
+@@ -856,7 +860,7 @@ unsigned   Length)         /* Length of data. */
+       return ((unsigned) Checksum);
+ }     /* SkCsCalculateChecksum */
+-#endif /* SkCsCalculateChecksum */
++#endif /* SK_CS_CALCULATE_CHECKSUM */
+ /******************************************************************************
+  *
+--- linux-2.6.0/drivers/net/sk98lin/skdim.c    2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/sk98lin/skdim.c     2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skdim.c
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.2 $
+- * Date:      $Date: 2003/08/21 12:35:05 $
++ * Version:   $Revision: 1.5 $
++ * Date:      $Date: 2003/11/28 12:55:40 $
+  * Purpose:   All functions to maintain interrupt moderation
+  *
+  ******************************************************************************/
+@@ -11,6 +11,7 @@
+ /******************************************************************************
+  *
+  *    (C)Copyright 1998-2002 SysKonnect GmbH.
++ *    (C)Copyright 2002-2003 Marvell.
+  *
+  *    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
+@@ -26,6 +27,15 @@
+  * History:
+  *    
+  *    $Log: skdim.c,v $
++ *    Revision 1.5  2003/11/28 12:55:40  rroesler
++ *    Fix: support for new process timing interface added
++ *    
++ *    Revision 1.4  2003/10/10 10:58:56  mlindner
++ *    Fix: CPU detection under the kernel 2.6
++ *    
++ *    Revision 1.3  2003/10/07 08:17:08  mlindner
++ *    Fix: Copyright changes
++ *    
+  *    Revision 1.2  2003/08/21 12:35:05  mlindner
+  *    Fix: Corrected CPU detection and compile errors on single CPU machines
+  *    
+@@ -62,7 +72,7 @@
+ #ifndef       lint
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skdim.c,v 1.2 2003/08/21 12:35:05 mlindner Exp $ (C) SysKonnect.";
++      "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
+ #endif
+ #define __SKADDR_C
+@@ -327,7 +337,9 @@ GetCurrentSystemLoad(SK_AC *pAC) {
+       **
+       **      struct kernel_stat kstat
+       **
+-      ** is not marked as an exported symbol
++      ** is not marked as an exported symbol in the file
++      **
++      **      kernel/ksyms.c 
+       **
+       ** As a consequence, using this driver as KLM is not possible
+       ** and any access of the structure kernel_stat via the 
+--- linux-2.6.0/drivers/net/sk98lin/skge.c     2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/sk98lin/skge.c      2003-12-28 23:21:01.000000000 -0800
+@@ -1,35 +1,20 @@
+ /******************************************************************************
+  *
+- * Name:    skge.c
++ * Name:      skge.c
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.11 $
+- * Date:              $Date: 2003/08/26 16:05:19 $
++ * Version:   $Revision: 1.42 $
++ * Date:              $Date: 2003/12/12 10:05:43 $
+  * Purpose:   The main driver source module
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2003 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect GmbH.
++ *    (C)Copyright 2002-2003 Marvell.
+  *
+- *    Driver for SysKonnect Gigabit Ethernet Server Adapters:
+- *
+- *    SK-9871 (single link 1000Base-ZX)
+- *    SK-9872 (dual link   1000Base-ZX)
+- *    SK-9861 (single link 1000Base-SX, VF45 Volition Plug)
+- *    SK-9862 (dual link   1000Base-SX, VF45 Volition Plug)
+- *    SK-9841 (single link 1000Base-LX)
+- *    SK-9842 (dual link   1000Base-LX)
+- *    SK-9843 (single link 1000Base-SX)
+- *    SK-9844 (dual link   1000Base-SX)
+- *    SK-9821 (single link 1000Base-T)
+- *    SK-9822 (dual link   1000Base-T)
+- *    SK-9881 (single link 1000Base-SX V2 LC)
+- *    SK-9871 (single link 1000Base-ZX V2)
+- *    SK-9861 (single link 1000Base-SX V2, VF45 Volition Plug)
+- *    SK-9841 (single link 1000Base-LX V2)
+- *    SK-9843 (single link 1000Base-SX V2)
+- *    SK-9821 (single link 1000Base-T V2)
++ *    Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet 
++ *      Server Adapters.
+  *
+  *    Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
+  *    SysKonnects GEnesis Solaris driver
+@@ -56,6 +41,87 @@
+  * History:
+  *
+  *    $Log: skge.c,v $
++ *    Revision 1.42  2003/12/12 10:05:43  mlindner
++ *    Fix: Format of error message corrected
++ *    
++ *    Revision 1.41  2003/12/11 16:03:57  mlindner
++ *    Fix: Create backup from pnmi data structure
++ *    
++ *    Revision 1.40  2003/12/11 12:14:48  mlindner
++ *    Fix: Initalize Board before network configuration
++ *    Fix: Change device names to driver name
++ *    
++ *    Revision 1.39  2003/12/10 08:57:38  rroesler
++ *    Fix: Modifications regarding try_module_get() and capable()
++ *    
++ *    Revision 1.38  2003/12/01 17:16:50  mlindner
++ *    Fix: Remove useless register_netdev
++ *    
++ *    Revision 1.37  2003/12/01 17:11:30  mlindner
++ *    Fix: Register net device before SkGeBoardInit
++ *    
++ *    Revision 1.36  2003/11/28 13:04:27  rroesler
++ *    Fix: do not print interface status in case DIAG is used
++ *    
++ *    Revision 1.35  2003/11/17 14:41:06  mlindner
++ *    Fix: Endif command
++ *    
++ *    Revision 1.34  2003/11/17 13:29:05  mlindner
++ *    Fix: Editorial changes
++ *    
++ *    Revision 1.33  2003/11/14 14:56:54  rroesler
++ *    Fix: corrected compilation warnings kernel 2.2
++ *    
++ *    Revision 1.32  2003/11/13 14:18:47  rroesler
++ *    Fix: added latest changes regarding the use of the proc system
++ *    
++ *    Revision 1.31  2003/11/13 09:28:35  rroesler
++ *    Fix: removed kernel warning 'driver changed get_stats after register'
++ *    
++ *    Revision 1.30  2003/11/11 13:15:27  rroesler
++ *    Fix: use suitables kernel usage count macros when using the diag
++ *    
++ *    Revision 1.29  2003/11/10 09:38:26  rroesler
++ *    Fix: restore PNMI structure backup for DIAG actions
++ *    
++ *    Revision 1.28  2003/11/07 17:28:45  rroesler
++ *    Fix: Additions for the LeaveDiagMode
++ *    
++ *    Revision 1.27  2003/11/03 13:21:14  mlindner
++ *    Add: SkGeBuffPad function for padding to ensure the trailing bytes exist
++ *    
++ *    Revision 1.26  2003/10/30 09:20:40  mlindner
++ *    Fix: Control bit check
++ *    
++ *    Revision 1.25  2003/10/29 07:43:37  rroesler
++ *    Fix: Implemented full None values handling for parameter Moderation
++ *    
++ *    Revision 1.24  2003/10/22 14:18:12  rroesler
++ *    Fix: DIAG handling for DualNet cards
++ *    
++ *    Revision 1.23  2003/10/17 10:05:13  mlindner
++ *    Add: New blinkmode for Morvell cards
++ *    
++ *    Revision 1.22  2003/10/15 12:31:25  rroesler
++ *    Fix: Corrected bugreport #10954 (Linux System crash when using vlans)
++ *    
++ *    Revision 1.21  2003/10/07 12:32:28  mlindner
++ *    Fix: Editorial changes
++ *    
++ *    Revision 1.20  2003/10/07 12:22:40  mlindner
++ *    Fix: Compiler warnings
++ *    
++ *    Revision 1.19  2003/10/07 09:33:40  mlindner
++ *    Fix: No warnings for illegal values of Mod and IntsPerSec
++ *    Fix: Speed 100 in Half Duplex not allowed for Yukon
++ *    Fix: PrefPort=B not allowed on single NICs
++ *    
++ *    Revision 1.18  2003/10/07 08:17:08  mlindner
++ *    Fix: Copyright changes
++ *    
++ *    Revision 1.17  2003/09/29 12:06:59  mlindner
++ *    *** empty log message ***
++ *    
+  *    Revision 1.16  2003/09/23 11:07:35  mlindner
+  *    Fix: IO-control return race condition
+  *    Fix: Interrupt moderation value check
+@@ -68,6 +134,12 @@
+  *    Add: Yukon Plus changes (ChipID, PCI...)
+  *    Fix: TCP and UDP Checksum calculation
+  *    
++ *    Revision 1.13  2003/09/01 13:30:08  rroesler
++ *    Fix: Corrected missing defines
++ *    
++ *    Revision 1.12  2003/09/01 13:12:02  rroesler
++ *    Add: Code for improved DIAG Attach/Detach interface
++ *    
+  *    Revision 1.11  2003/08/26 16:05:19  mlindner
+  *    Fix: Compiler warnings (void *)
+  *    
+@@ -406,7 +478,6 @@
+  *    <linux/module.h>
+  *
+  *    "h/skdrv1st.h"
+- *            <linux/version.h>
+  *            <linux/types.h>
+  *            <linux/kernel.h>
+  *            <linux/string.h>
+@@ -568,6 +639,12 @@ static void       StartDrvCleanupTimer(SK_AC *
+ static void   StopDrvCleanupTimer(SK_AC *pAC);
+ static int    XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
++#ifdef SK_DIAG_SUPPORT
++static SK_U32   ParseDeviceNbrFromSlotName(const char *SlotName);
++static int      SkDrvInitAdapter(SK_AC *pAC, int devNbr);
++static int      SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
++#endif
++
+ /*******************************************************************************
+  *
+  * Extern Function Prototypes
+@@ -576,8 +653,8 @@ static int XmitFrameSG(SK_AC*, TX_PORT*,
+ #ifdef CONFIG_PROC_FS
+ static const char     SK_Root_Dir_entry[] = "sk98lin";
+-static struct         proc_dir_entry *pSkRootDir;
+-extern struct         file_operations sk_proc_fops;
++static struct         proc_dir_entry *pSkRootDir = NULL;
++extern struct file_operations sk_proc_fops;
+ #endif
+ extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);        
+@@ -595,12 +672,19 @@ static void      DumpLong(char*, int);
+ static const char *BootString = BOOT_STRING;
+ struct SK_NET_DEVICE *SkGeRootDev = NULL;
+ static int probed __initdata = 0;
++static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
+ /* local variables **********************************************************/
+ static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
+ static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
++#ifdef CONFIG_PROC_FS
++static struct proc_dir_entry  *pSkRootDir;
++#endif
++
++
++
+ /*****************************************************************************
+  *
+  *    skge_probe - find all SK-98xx adapters
+@@ -626,6 +710,7 @@ static int __init skge_probe (void)
+       SK_BOOL BootStringCount = SK_FALSE;
+       int                     retval;
+ #ifdef CONFIG_PROC_FS
++      int                     proc_root_initialized = 0;
+       struct proc_dir_entry   *pProcFile;
+ #endif
+@@ -700,6 +785,7 @@ static int __init skge_probe (void)
+               dev->stop =             &SkGeClose;
+               dev->hard_start_xmit =  &SkGeXmit;
+               dev->get_stats =        &SkGeStats;
++              dev->last_stats =       &SkGeStats;
+               dev->set_multicast_list = &SkGeSetRxMode;
+               dev->set_mac_address =  &SkGeSetMacAddr;
+               dev->do_ioctl =         &SkGeIoctl;
+@@ -718,15 +804,13 @@ static int __init skge_probe (void)
+ #endif
+               pAC->Index = boards_found;
++
+               if (SkGeBoardInit(dev, pAC)) {
+-                      FreeResources(dev);
+                       free_netdev(dev);
+                       continue;
+               }
+-              memcpy((caddr_t) &dev->dev_addr,
+-                      (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
+-
++              /* Register net device */
+               if (register_netdev(dev)) {
+                       printk(KERN_ERR "SKGE: Could not register device.\n");
+                       FreeResources(dev);
+@@ -734,6 +818,25 @@ static int __init skge_probe (void)
+                       continue;
+               }
++              /* Print adapter specific string from vpd */
++              ProductStr(pAC);
++              printk("%s: %s\n", dev->name, pAC->DeviceStr);
++
++              /* Print configuration settings */
++              printk("      PrefPort:%c  RlmtMode:%s\n",
++                      'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
++                      (pAC->RlmtMode==0)  ? "Check Link State" :
++                      ((pAC->RlmtMode==1) ? "Check Link State" :
++                      ((pAC->RlmtMode==3) ? "Check Local Port" :
++                      ((pAC->RlmtMode==7) ? "Check Segmentation" :
++                      ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
++
++              SkGeYellowLED(pAC, pAC->IoBase, 1);
++
++
++              memcpy((caddr_t) &dev->dev_addr,
++                      (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
++
+               /* First adapter... Create proc and print message */
+ #ifdef CONFIG_PROC_FS
+               if (!DeviceFound) {
+@@ -744,25 +847,27 @@ static int __init skge_probe (void)
+                       /*Create proc (directory)*/
+                       if(!pSkRootDir) {
+                               pSkRootDir = proc_mkdir(SK_Root_Dir_entry, proc_net);
+-                              if (!pSkRootDir) 
++                              if (!pSkRootDir) {
+                                       printk(KERN_WARNING "%s: Unable to create /proc/net/%s",
+-                                             dev->name, SK_Root_Dir_entry);
+-                              else
++                                              dev->name, SK_Root_Dir_entry);
++                              } else {
+                                       pSkRootDir->owner = THIS_MODULE;
++                              }
+                       }
+               }
+-              
++
+               /* Create proc file */
+-              if (pSkRootDir 
+-                  && (pProcFile = create_proc_entry(dev->name, S_IRUGO,
+-                                                    pSkRootDir))) {
++              if (pSkRootDir && 
++                      (pProcFile = create_proc_entry(dev->name, S_IRUGO,
++                              pSkRootDir))) {
+                       pProcFile->proc_fops = &sk_proc_fops;
+-                      pProcFile->data = dev;
++                      pProcFile->data      = dev;
+               }
++
+ #endif
+               pNet->PortNr = 0;
+-              pNet->NetNr = 0;
++              pNet->NetNr  = 0;
+               boards_found++;
+@@ -774,23 +879,24 @@ static int __init skge_probe (void)
+                               break;
+                       }
+-                      pAC->dev[1] = dev;
+-                      pNet = dev->priv;
+-                      pNet->PortNr = 1;
+-                      pNet->NetNr = 1;
+-                      pNet->pAC = pAC;
+-                      pNet->Mtu = 1500;
+-                      pNet->Up = 0;
+-
+-                      dev->open =             &SkGeOpen;
+-                      dev->stop =             &SkGeClose;
+-                      dev->hard_start_xmit =  &SkGeXmit;
+-                      dev->get_stats =        &SkGeStats;
++                      pAC->dev[1]   = dev;
++                      pNet          = dev->priv;
++                      pNet->PortNr  = 1;
++                      pNet->NetNr   = 1;
++                      pNet->pAC     = pAC;
++                      pNet->Mtu     = 1500;
++                      pNet->Up      = 0;
++
++                      dev->open               = &SkGeOpen;
++                      dev->stop               = &SkGeClose;
++                      dev->hard_start_xmit    = &SkGeXmit;
++                      dev->get_stats          = &SkGeStats;
++                      dev->last_stats         = &SkGeStats;
+                       dev->set_multicast_list = &SkGeSetRxMode;
+-                      dev->set_mac_address =  &SkGeSetMacAddr;
+-                      dev->do_ioctl =         &SkGeIoctl;
+-                      dev->change_mtu =       &SkGeChangeMtu;
+-                      dev->flags &=           ~IFF_RUNNING;
++                      dev->set_mac_address    = &SkGeSetMacAddr;
++                      dev->do_ioctl           = &SkGeIoctl;
++                      dev->change_mtu         = &SkGeChangeMtu;
++                      dev->flags             &= ~IFF_RUNNING;
+ #ifdef SK_ZEROCOPY
+ #ifdef USE_SK_TX_CHECKSUM
+@@ -802,34 +908,39 @@ static int __init skge_probe (void)
+ #endif
+                       if (register_netdev(dev)) {
+-                              printk(KERN_ERR "SKGE: Could not register "
+-                                     "second port.\n");
++                              printk(KERN_ERR "SKGE: Could not register device.\n");
+                               free_netdev(dev);
+                               pAC->dev[1] = pAC->dev[0];
+                       } else {
+ #ifdef CONFIG_PROC_FS
+                               if (pSkRootDir 
+                                   && (pProcFile = create_proc_entry(dev->name, 
+-                                                                    S_IRUGO,
+-                                                                    pSkRootDir))) {
++                                                              S_IRUGO, pSkRootDir))) {
+                                       pProcFile->proc_fops = &sk_proc_fops;
+-                                      pProcFile->data = dev;
++                                      pProcFile->data      = dev;
+                               }
+ #endif
+-                              memcpy((caddr_t) &dev->dev_addr,
+-                                     (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
++                      memcpy((caddr_t) &dev->dev_addr,
++                      (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6);
+       
+-                              printk("%s: %s\n", dev->name, pAC->DeviceStr);
+-                              printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
++                      printk("%s: %s\n", dev->name, pAC->DeviceStr);
++                      printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
+                       }
+               }
+-
+               /* Save the hardware revision */
+               pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
+                       (pAC->GIni.GIPciHwRev & 0x0F);
++              /* Set driver globals */
++              pAC->Pnmi.pDriverFileName    = DRIVER_FILE_NAME;
++              pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
++
++              SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
++              SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), 
++                              sizeof(SK_PNMI_STRUCT_DATA));
++
+               /*
+                * This is bollocks, but we need to tell the net-init
+                * code that it shall go for the next device.
+@@ -849,7 +960,6 @@ static int __init skge_probe (void)
+ } /* skge_probe */
+-
+ /*****************************************************************************
+  *
+  *    SkGeInitPCI - Init the PCI resources
+@@ -1143,7 +1253,7 @@ SK_EVPARA EvPara;
+               if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){
+                       unregister_netdev(pAC->dev[1]);
+-                      kfree(pAC->dev[1]);
++                      free_netdev(pAC->dev[1]);
+               }
+               FreeResources(SkGeRootDev);
+@@ -1161,8 +1271,7 @@ SK_EVPARA EvPara;
+ #ifdef CONFIG_PROC_FS
+       /* clear proc-dir */
+-      if (pSkRootDir) 
+-              remove_proc_entry(pSkRootDir->name, proc_net);
++      remove_proc_entry(pSkRootDir->name, proc_net);
+ #endif
+ } /* skge_cleanup_module */
+@@ -1224,7 +1333,7 @@ SK_BOOL  DualNet;
+       SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA);
+       SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA);
+       SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA);
+-      
++
+       pAC->BoardLevel = SK_INIT_DATA;
+       pAC->RxBufSize  = ETH_BUF_SIZE;
+@@ -1236,7 +1345,7 @@ SK_BOOL  DualNet;
+       /* level 1 init common modules here (HW init) */
+       spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+       if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
+-              printk("HWInit (1) failed.\n");
++              printk("sk98lin: HWInit (1) failed.\n");
+               spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+               return(-EAGAIN);
+       }
+@@ -1268,14 +1377,14 @@ SK_BOOL        DualNet;
+               Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
+                       pAC->Name, dev);
+       } else {
+-              printk(KERN_WARNING "%s: Illegal number of ports: %d\n",
+-                     dev->name, pAC->GIni.GIMacsFound);
++              printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
++                     pAC->GIni.GIMacsFound);
+               return -EAGAIN;
+       }
+       if (Ret) {
+-              printk(KERN_WARNING "%s: Requested IRQ %d is busy.\n",
+-                     dev->name, dev->irq);
++              printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
++                     dev->irq);
+               return -EAGAIN;
+       }
+       pAC->AllocFlag |= SK_ALLOC_IRQ;
+@@ -1303,25 +1412,10 @@ SK_BOOL        DualNet;
+               pAC->ActivePort,
+               DualNet)) {
+               BoardFreeMem(pAC);
+-              printk("SkGeInitAssignRamToQueues failed.\n");
++              printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
+               return(-EAGAIN);
+       }
+-      /* Print adapter specific string from vpd */
+-      ProductStr(pAC);
+-      printk("%s: %s\n", dev->name, pAC->DeviceStr);
+-
+-      /* Print configuration settings */
+-      printk("      PrefPort:%c  RlmtMode:%s\n",
+-              'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
+-              (pAC->RlmtMode==0)  ? "Check Link State" :
+-              ((pAC->RlmtMode==1) ? "Check Link State" :
+-              ((pAC->RlmtMode==3) ? "Check Local Port" :
+-              ((pAC->RlmtMode==7) ? "Check Segmentation" :
+-              ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
+-
+-      SkGeYellowLED(pAC, pAC->IoBase, 1);
+-
+       /*
+        * Register the device here
+        */
+@@ -1879,14 +1973,26 @@ struct SK_NET_DEVICE   *dev)
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
++#ifdef SK_DIAG_SUPPORT
++      if (pAC->DiagModeActive == DIAG_ACTIVE) {
++              if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
++                      return (-1);   /* still in use by diag; deny actions */
++              } 
++      }
++#endif
++
++      if (!try_module_get(THIS_MODULE)) {
++              return (-1);    /* increase of usage count not possible */
++      }
+       /* Set blink mode */
+-      if (pAC->PciDev->vendor == 0x1186)
++      if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
+               pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
+       if (pAC->BoardLevel == SK_INIT_DATA) {
+               /* level 1 init common modules here */
+               if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
++                      module_put(THIS_MODULE); /* decrease usage count */
+                       printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
+                       return (-1);
+               }
+@@ -1902,6 +2008,7 @@ struct SK_NET_DEVICE     *dev)
+       if (pAC->BoardLevel != SK_INIT_RUN) {
+               /* tschilling: Level 2 init modules here, check return value. */
+               if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) {
++                      module_put(THIS_MODULE); /* decrease usage count */
+                       printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
+                       return (-1);
+               }
+@@ -1953,7 +2060,6 @@ struct SK_NET_DEVICE     *dev)
+       pAC->MaxPorts++;
+       pNet->Up = 1;
+-      try_module_get(THIS_MODULE);
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeOpen suceeded\n"));
+@@ -1976,26 +2082,50 @@ struct SK_NET_DEVICE   *dev)
+ static int SkGeClose(
+ struct SK_NET_DEVICE  *dev)
+ {
+-      DEV_NET                 *pNet;
+-      SK_AC                   *pAC;
++      DEV_NET         *pNet;
++      DEV_NET         *newPtrNet;
++      SK_AC           *pAC;
+       unsigned long   Flags;          /* for spin lock */
+-      int                             i;
+-      int                             PortIdx;
+-      SK_EVPARA               EvPara;
++      int             i;
++      int             PortIdx;
++      SK_EVPARA       EvPara;
++
++      SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
++              ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
+-      netif_stop_queue(dev);
+       pNet = (DEV_NET*) dev->priv;
+       pAC = pNet->pAC;
++#ifdef SK_DIAG_SUPPORT
++      if (pAC->DiagModeActive == DIAG_ACTIVE) {
++              if (pAC->DiagFlowCtrl == SK_FALSE) {
++                      module_put(THIS_MODULE);
++                      /* 
++                      ** notify that the interface which has been closed
++                      ** by operator interaction must not be started up 
++                      ** again when the DIAG has finished. 
++                      */
++                      newPtrNet = (DEV_NET *) pAC->dev[0]->priv;
++                      if (newPtrNet == pNet) {
++                              pAC->WasIfUp[0] = SK_FALSE;
++                      } else {
++                              pAC->WasIfUp[1] = SK_FALSE;
++                      }
++                      return 0; /* return to system everything is fine... */
++              } else {
++                      pAC->DiagFlowCtrl = SK_FALSE;
++              }
++      }
++#endif
++
++      netif_stop_queue(dev);
++
+       if (pAC->RlmtNets == 1)
+               PortIdx = pAC->ActivePort;
+       else
+               PortIdx = pNet->NetNr;
+-      SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+-              ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
+-
+         StopDrvCleanupTimer(pAC);
+       /*
+@@ -2053,6 +2183,10 @@ struct SK_NET_DEVICE    *dev)
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeClose: done "));
++      SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
++      SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), 
++                      sizeof(SK_PNMI_STRUCT_DATA));
++
+       pAC->MaxPorts--;
+       pNet->Up = 0;
+@@ -2199,9 +2333,10 @@ struct sk_buff  *pMessage)      /* pointer to 
+       ** This is to resolve faulty padding by the HW with 0xaa bytes.
+       */
+       if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
+-          skb_put(pMessage, (C_LEN_ETHERNET_MINSIZE-BytesSend));
+-          SK_MEMSET( ((char *)(pMessage->data))+BytesSend,
+-                  0, C_LEN_ETHERNET_MINSIZE-BytesSend);
++              if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) {
++                      return 0;
++              }
++              pMessage->len = C_LEN_ETHERNET_MINSIZE;
+       }
+       /* 
+@@ -3318,6 +3453,16 @@ SK_EVPARA       EvPara;
+               return -EINVAL;
+       }
++#ifdef SK_DIAG_SUPPORT
++      if (pAC->DiagModeActive == DIAG_ACTIVE) {
++              if (pAC->DiagFlowCtrl == SK_FALSE) {
++                      return -1; /* still in use, deny any actions of MTU */
++              } else {
++                      pAC->DiagFlowCtrl = SK_FALSE;
++              }
++      }
++#endif
++
+       pNet->Mtu = NewMtu;
+       pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv;
+       if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
+@@ -3537,11 +3682,20 @@ unsigned long  Flags;                  /* for spin lock 
+       SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+               ("SkGeStats starts now...\n"));
+       pPnmiStruct = &pAC->PnmiStruct;
+-        memset(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
++
++#ifdef SK_DIAG_SUPPORT
++        if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
++                (pAC->BoardLevel == SK_INIT_RUN)) {
++#endif
++        SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
+         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+         Size = SK_PNMI_STRUCT_SIZE;
+               SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
+         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
++#ifdef SK_DIAG_SUPPORT
++      }
++#endif
++
+         pPnmiStat = &pPnmiStruct->Stat[0];
+         pPnmiConf = &pPnmiStruct->Conf[0];
+@@ -3604,7 +3758,7 @@ static int SkGeIoctl(struct SK_NET_DEVIC
+ DEV_NET               *pNet;
+ SK_AC         *pAC;
+ void          *pMemBuf;
+-
++struct pci_dev  *pdev = NULL;
+ SK_GE_IOCTL   Ioctl;
+ unsigned int  Err = 0;
+ int           Size = 0;
+@@ -3671,6 +3825,45 @@ int             HeaderLength = sizeof(SK_U32) + siz
+ fault_gen:
+               kfree(pMemBuf); /* cleanup everything */
+               break;
++#ifdef SK_DIAG_SUPPORT
++       case SK_IOCTL_DIAG:
++              if (!capable(CAP_NET_ADMIN)) return -EPERM;
++              if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
++                      Length = Ioctl.Len;
++              } else {
++                      Length = sizeof(pAC->PnmiStruct) + HeaderLength;
++              }
++              if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
++                      return -ENOMEM;
++              }
++              if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
++                      Err = -EFAULT;
++                      goto fault_diag;
++              }
++              pdev = pAC->PciDev;
++              Length = 3 * sizeof(SK_U32);  /* Error, Bus and Device */
++              /* 
++              ** While coding this new IOCTL interface, only a few lines of code
++              ** are to to be added. Therefore no dedicated function has been 
++              ** added. If more functionality is added, a separate function 
++              ** should be used...
++              */
++              * ((SK_U32 *)pMemBuf) = 0;
++              * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number;
++              * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pdev->slot_name);
++              if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
++                      Err = -EFAULT;
++                      goto fault_diag;
++              }
++              Ioctl.Len = Length;
++              if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
++                      Err = -EFAULT;
++                      goto fault_diag;
++              }
++fault_diag:
++              kfree(pMemBuf); /* cleanup everything */
++              break;
++#endif
+       default:
+               Err = -EOPNOTSUPP;
+       }
+@@ -3826,10 +4019,9 @@ int     Capabilities[3][3] =
+                               (strcmp(ConType[pAC->Index],"Auto")!=0) &&
+                               (strcmp(ConType[pAC->Index],"")!=0)) {
+                               /* Set the speed parameter back */
+-                                      printk("%s: Illegal value \"%s\" " 
++                                      printk("sk98lin: Illegal value \"%s\" " 
+                                                       "for ConType."
+                                                       " Using Auto.\n", 
+-                                                      pAC->dev[0]->name, 
+                                                       ConType[pAC->Index]);
+                                       sprintf(ConType[pAC->Index], "Auto");   
+@@ -3873,8 +4065,8 @@ int      Capabilities[3][3] =
+                       M_CurrPort.PLinkSpeed    = SK_LSPEED_10MBPS;
+                   }
+                 } else { 
+-                  printk("%s: Illegal value \"%s\" for ConType\n", 
+-                      pAC->dev[0]->name, ConType[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for ConType\n", 
++                      ConType[pAC->Index]);
+                   IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */
+               }
+         } else {
+@@ -3898,8 +4090,8 @@ int      Capabilities[3][3] =
+               } else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
+                   LinkSpeed = SK_LSPEED_1000MBPS;
+               } else {
+-                  printk("%s: Illegal value \"%s\" for Speed_A\n",
+-                      pAC->dev[0]->name, Speed_A[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for Speed_A\n",
++                      Speed_A[pAC->Index]);
+                   IsLinkSpeedDefined = SK_FALSE;
+               }
+       } else {
+@@ -3913,9 +4105,9 @@ int      Capabilities[3][3] =
+       if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
+               ((LinkSpeed != SK_LSPEED_AUTO) &&
+               (LinkSpeed != SK_LSPEED_1000MBPS))) {
+-              printk("%s: Illegal value for Speed_A. "
++              printk("sk98lin: Illegal value for Speed_A. "
+                       "Not a copper card or GE V2 card\n    Using "
+-                      "speed 1000\n", pAC->dev[0]->name);
++                      "speed 1000\n");
+               LinkSpeed = SK_LSPEED_1000MBPS;
+       }
+       
+@@ -3945,8 +4137,8 @@ int      Capabilities[3][3] =
+               } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
+                   AutoNeg = AN_SENS;
+               } else {
+-                  printk("%s: Illegal value \"%s\" for AutoNeg_A\n",
+-                      pAC->dev[0]->name, AutoNeg_A[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n",
++                      AutoNeg_A[pAC->Index]);
+               }
+       }
+@@ -3964,33 +4156,32 @@ int    Capabilities[3][3] =
+               } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
+                   DuplexCap = DC_HALF;
+               } else {
+-                  printk("%s: Illegal value \"%s\" for DupCap_A\n",
+-                      pAC->dev[0]->name, DupCap_A[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for DupCap_A\n",
++                      DupCap_A[pAC->Index]);
+               }
+       }
+-      
++
+       /* 
+       ** Check for illegal combinations 
+       */
+-      if ((LinkSpeed = SK_LSPEED_1000MBPS) &&
++      if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
+               ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
+               (DuplexCap == SK_LMODE_STAT_HALF)) &&
+               (pAC->ChipsetType)) {
+-                  printk("%s: Half Duplex not possible with Gigabit speed!\n"
+-                                      "    Using Full Duplex.\n",
+-                              pAC->dev[0]->name);
++                  printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
++                                      "    Using Full Duplex.\n");
+                               DuplexCap = DC_FULL;
+       }
+       if ( AutoSet && AutoNeg==AN_SENS && DupSet) {
+-              printk("%s, Port A: DuplexCapabilities"
+-                      " ignored using Sense mode\n", pAC->dev[0]->name);
++              printk("sk98lin, Port A: DuplexCapabilities"
++                      " ignored using Sense mode\n");
+       }
+       if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
+-              printk("%s, Port A: Illegal combination"
++              printk("sk98lin: Port A: Illegal combination"
+                       " of values AutoNeg. and DuplexCap.\n    Using "
+-                      "Full Duplex\n", pAC->dev[0]->name);
++                      "Full Duplex\n");
+               DuplexCap = DC_FULL;
+       }
+@@ -3999,10 +4190,9 @@ int     Capabilities[3][3] =
+       }
+       
+       if (!AutoSet && DupSet) {
+-              printk("%s, Port A: Duplex setting not"
++              printk("sk98lin: Port A: Duplex setting not"
+                       " possible in\n    default AutoNegotiation mode"
+-                      " (Sense).\n    Using AutoNegotiation On\n",
+-                      pAC->dev[0]->name);
++                      " (Sense).\n    Using AutoNegotiation On\n");
+               AutoNeg = AN_ON;
+       }
+       
+@@ -4029,8 +4219,8 @@ int      Capabilities[3][3] =
+               } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
+                   FlowCtrl = SK_FLOW_MODE_NONE;
+               } else {
+-                  printk("%s: Illegal value \"%s\" for FlowCtrl_A\n",
+-                        pAC->dev[0]->name, FlowCtrl_A[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n",
++                        FlowCtrl_A[pAC->Index]);
+                   IsFlowCtrlDefined = SK_FALSE;
+               }
+       } else {
+@@ -4039,9 +4229,9 @@ int      Capabilities[3][3] =
+       if (IsFlowCtrlDefined) {
+           if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
+-              printk("%s, Port A: FlowControl"
++              printk("sk98lin: Port A: FlowControl"
+                       " impossible without AutoNegotiation,"
+-                      " disabled\n", pAC->dev[0]->name);
++                      " disabled\n");
+               FlowCtrl = SK_FLOW_MODE_NONE;
+           }
+           pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl;
+@@ -4061,8 +4251,8 @@ int      Capabilities[3][3] =
+               } else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
+                   MSMode = SK_MS_MODE_SLAVE;
+               } else {
+-                  printk("%s: Illegal value \"%s\" for Role_A\n",
+-                      pAC->dev[0]->name, Role_A[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for Role_A\n",
++                      Role_A[pAC->Index]);
+                   IsRoleDefined = SK_FALSE;
+               }
+       } else {
+@@ -4097,8 +4287,8 @@ int      Capabilities[3][3] =
+               } else if (strcmp(Speed_B[pAC->Index],"1000")==0) {
+                   LinkSpeed = SK_LSPEED_1000MBPS;
+               } else {
+-                  printk("%s: Illegal value \"%s\" for Speed_B\n",
+-                      pAC->dev[1]->name, Speed_B[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for Speed_B\n",
++                      Speed_B[pAC->Index]);
+                   IsLinkSpeedDefined = SK_FALSE;
+               }
+       } else {
+@@ -4112,9 +4302,9 @@ int      Capabilities[3][3] =
+       if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
+               ((LinkSpeed != SK_LSPEED_AUTO) &&
+               (LinkSpeed != SK_LSPEED_1000MBPS))) {
+-              printk("%s: Illegal value for Speed_B. "
++              printk("sk98lin: Illegal value for Speed_B. "
+                       "Not a copper card or GE V2 card\n    Using "
+-                      "speed 1000\n", pAC->dev[1]->name);
++                      "speed 1000\n");
+               LinkSpeed = SK_LSPEED_1000MBPS;
+       }
+@@ -4144,8 +4334,8 @@ int      Capabilities[3][3] =
+               } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
+                   AutoNeg = AN_SENS;
+               } else {
+-                  printk("%s: Illegal value \"%s\" for AutoNeg_B\n",
+-                      pAC->dev[0]->name, AutoNeg_B[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n",
++                      AutoNeg_B[pAC->Index]);
+               }
+       }
+@@ -4163,8 +4353,8 @@ int      Capabilities[3][3] =
+               } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
+                   DuplexCap = DC_HALF;
+               } else {
+-                  printk("%s: Illegal value \"%s\" for DupCap_B\n",
+-                      pAC->dev[0]->name, DupCap_B[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for DupCap_B\n",
++                      DupCap_B[pAC->Index]);
+               }
+       }
+@@ -4172,25 +4362,24 @@ int    Capabilities[3][3] =
+       /* 
+       ** Check for illegal combinations 
+       */
+-      if ((LinkSpeed = SK_LSPEED_1000MBPS) &&
++      if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
+               ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
+               (DuplexCap == SK_LMODE_STAT_HALF)) &&
+               (pAC->ChipsetType)) {
+-                  printk("%s: Half Duplex not possible with Gigabit speed!\n"
+-                                      "    Using Full Duplex.\n",
+-                              pAC->dev[1]->name);
++                  printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
++                                      "    Using Full Duplex.\n");
+                               DuplexCap = DC_FULL;
+       }
+       if (AutoSet && AutoNeg==AN_SENS && DupSet) {
+-              printk("%s, Port B: DuplexCapabilities"
+-                      " ignored using Sense mode\n", pAC->dev[1]->name);
++              printk("sk98lin, Port B: DuplexCapabilities"
++                      " ignored using Sense mode\n");
+       }
+       if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
+-              printk("%s, Port B: Illegal combination"
++              printk("sk98lin: Port B: Illegal combination"
+                       " of values AutoNeg. and DuplexCap.\n    Using "
+-                      "Full Duplex\n", pAC->dev[1]->name);
++                      "Full Duplex\n");
+               DuplexCap = DC_FULL;
+       }
+@@ -4199,10 +4388,9 @@ int     Capabilities[3][3] =
+       }
+       
+       if (!AutoSet && DupSet) {
+-              printk("%s, Port B: Duplex setting not"
++              printk("sk98lin: Port B: Duplex setting not"
+                       " possible in\n    default AutoNegotiation mode"
+-                      " (Sense).\n    Using AutoNegotiation On\n",
+-                      pAC->dev[1]->name);
++                      " (Sense).\n    Using AutoNegotiation On\n");
+               AutoNeg = AN_ON;
+       }
+@@ -4229,8 +4417,8 @@ int      Capabilities[3][3] =
+               } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
+                   FlowCtrl = SK_FLOW_MODE_NONE;
+               } else {
+-                  printk("%s: Illegal value \"%s\" for FlowCtrl_B\n",
+-                      pAC->dev[0]->name, FlowCtrl_B[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n",
++                      FlowCtrl_B[pAC->Index]);
+                   IsFlowCtrlDefined = SK_FALSE;
+               }
+       } else {
+@@ -4239,9 +4427,9 @@ int      Capabilities[3][3] =
+       if (IsFlowCtrlDefined) {
+           if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
+-              printk("%s, Port B: FlowControl"
++              printk("sk98lin: Port B: FlowControl"
+                       " impossible without AutoNegotiation,"
+-                      " disabled\n", pAC->dev[1]->name);
++                      " disabled\n");
+               FlowCtrl = SK_FLOW_MODE_NONE;
+           }
+           pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl;
+@@ -4261,8 +4449,8 @@ int      Capabilities[3][3] =
+               } else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
+                   MSMode = SK_MS_MODE_SLAVE;
+               } else {
+-                  printk("%s: Illegal value \"%s\" for Role_B\n",
+-                      pAC->dev[1]->name, Role_B[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for Role_B\n",
++                      Role_B[pAC->Index]);
+                   IsRoleDefined = SK_FALSE;
+               }
+       } else {
+@@ -4280,28 +4468,37 @@ int    Capabilities[3][3] =
+       if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+               PrefPort[pAC->Index] != NULL) {
+               if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
+-                  pAC->ActivePort             =  0;
+-                  pAC->Rlmt.Net[0].Preference = -1; /* auto */
+-                  pAC->Rlmt.Net[0].PrefPort   =  0;
++                      pAC->ActivePort             =  0;
++                      pAC->Rlmt.Net[0].Preference = -1; /* auto */
++                      pAC->Rlmt.Net[0].PrefPort   =  0;
+               } else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
+-                  /*
+-                  ** do not set ActivePort here, thus a port
+-                  ** switch is issued after net up.
+-                  */
+-                  Port                        = 0;
+-                  pAC->Rlmt.Net[0].Preference = Port;
+-                  pAC->Rlmt.Net[0].PrefPort   = Port;
++                      /*
++                      ** do not set ActivePort here, thus a port
++                      ** switch is issued after net up.
++                      */
++                      Port                        = 0;
++                      pAC->Rlmt.Net[0].Preference = Port;
++                      pAC->Rlmt.Net[0].PrefPort   = Port;
+               } else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
+-                  /*
+-                  ** do not set ActivePort here, thus a port
+-                  ** switch is issued after net up.
+-                  */
+-                  Port                        = 1;
+-                  pAC->Rlmt.Net[0].Preference = Port;
+-                  pAC->Rlmt.Net[0].PrefPort   = Port;
++                      /*
++                      ** do not set ActivePort here, thus a port
++                      ** switch is issued after net up.
++                      */
++                      if (pAC->GIni.GIMacsFound == 1) {
++                              printk("sk98lin: Illegal value \"B\" for PrefPort.\n"
++                                      "      Port B not available on single port adapters.\n");
++
++                              pAC->ActivePort             =  0;
++                              pAC->Rlmt.Net[0].Preference = -1; /* auto */
++                              pAC->Rlmt.Net[0].PrefPort   =  0;
++                      } else {
++                              Port                        = 1;
++                              pAC->Rlmt.Net[0].Preference = Port;
++                              pAC->Rlmt.Net[0].PrefPort   = Port;
++                      }
+               } else {
+-                  printk("%s: Illegal value \"%s\" for PrefPort\n",
+-                      pAC->dev[0]->name, PrefPort[pAC->Index]);
++                  printk("sk98lin: Illegal value \"%s\" for PrefPort\n",
++                      PrefPort[pAC->Index]);
+               }
+       }
+@@ -4325,9 +4522,9 @@ int      Capabilities[3][3] =
+                       pAC->RlmtMode = SK_RLMT_CHECK_LINK;
+                       pAC->RlmtNets = 2;
+               } else {
+-                  printk("%s: Illegal value \"%s\" for"
++                  printk("sk98lin: Illegal value \"%s\" for"
+                       " RlmtMode, using default\n", 
+-                      pAC->dev[0]->name, RlmtMode[pAC->Index]);
++                      RlmtMode[pAC->Index]);
+                       pAC->RlmtMode = 0;
+               }
+       } else {
+@@ -4338,97 +4535,111 @@ int   Capabilities[3][3] =
+       ** Check the interrupt moderation parameters
+       */
+       if (Moderation[pAC->Index] != NULL) {
+-          if (strcmp(Moderation[pAC->Index], "Static") == 0) {
+-                pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
+-          } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) {
+-              pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC;
+-          } else {
+-              pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+-          }
++              if (strcmp(Moderation[pAC->Index], "") == 0) {
++                      pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
++              } else if (strcmp(Moderation[pAC->Index], "Static") == 0) {
++                      pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
++              } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) {
++                      pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC;
++              } else if (strcmp(Moderation[pAC->Index], "None") == 0) {
++                      pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
++              } else {
++                      printk("sk98lin: Illegal value \"%s\" for Moderation.\n"
++                              "      Disable interrupt moderation.\n",
++                              Moderation[pAC->Index]);
++                      pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
++              }
+       } else {
+-          pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
++              pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+       }
+       if (Stats[pAC->Index] != NULL) {
+-          if (strcmp(Stats[pAC->Index], "Yes") == 0) {
+-              pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
+-          } else {
+-              pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
+-          }
++              if (strcmp(Stats[pAC->Index], "Yes") == 0) {
++                      pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
++              } else {
++                      pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
++              }
+       } else {
+-          pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
++              pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
+       }
+-        if (ModerationMask[pAC->Index] != NULL) {
+-           if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
+-           } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
+-           } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
+-           } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
+-           } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
+-           } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+-           } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+-           } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
+-           } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
+-           } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-           } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-           } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-           } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-           } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-           } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+-           } else { /* some rubbish */
+-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
+-           }
+-        } else {  /* operator has stated nothing */
+-           pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+-        }
+-
+-        if (AutoSizing[pAC->Index] != NULL) {
+-           if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
+-               pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+-           } else {
+-               pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+-           }
+-        } else {  /* operator has stated nothing */
+-           pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+-        }
++      if (ModerationMask[pAC->Index] != NULL) {
++              if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
++              } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
++              } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
++              } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
++              } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
++              } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
++              } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
++              } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
++              } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
++              } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
++              } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
++              } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
++              } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
++              } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
++              } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
++              } else { /* some rubbish */
++                      pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
++              }
++      } else {  /* operator has stated nothing */
++              pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
++      }
++
++      if (AutoSizing[pAC->Index] != NULL) {
++              if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
++                      pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
++              } else {
++                      pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
++              }
++      } else {  /* operator has stated nothing */
++              pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
++      }
+-        if (IntsPerSec[pAC->Index] != 0) {
+-           if ((IntsPerSec[pAC->Index]< 30) || (IntsPerSec[pAC->Index]> 40000)) {
+-              pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
+-           } else {
+-              pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
+-           }
+-        } else {
+-           pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
+-        }
++      if (IntsPerSec[pAC->Index] != 0) {
++              if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || 
++                      (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) {
++                      printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n"
++                              "      Using default value of %i.\n", 
++                              IntsPerSec[pAC->Index],
++                              C_INT_MOD_IPS_LOWER_RANGE,
++                              C_INT_MOD_IPS_UPPER_RANGE,
++                              C_INTS_PER_SEC_DEFAULT);
++                      pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
++              } else {
++                      pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
++              }
++      } else {
++              pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
++      }
+-        /*
++      /*
+       ** Evaluate upper and lower moderation threshold
+       */
+-        pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
+-            pAC->DynIrqModInfo.MaxModIntsPerSec +
+-            (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
+-
+-        pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
+-            pAC->DynIrqModInfo.MaxModIntsPerSec -
+-            (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
++      pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
++              pAC->DynIrqModInfo.MaxModIntsPerSec +
++              (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
++
++      pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
++              pAC->DynIrqModInfo.MaxModIntsPerSec -
++              (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
+-        pAC->DynIrqModInfo.PrevTimeVal = jiffies;  /* initial value */
++      pAC->DynIrqModInfo.PrevTimeVal = jiffies;  /* initial value */
+ } /* GetConfiguration */
+@@ -4826,6 +5037,10 @@ SK_BOOL         DualNet;
+               FromPort = Param.Para32[0];
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("NET UP EVENT, Port: %d ", Param.Para32[0]));
++              /* Mac update */
++              SkAddrMcUpdate(pAC,IoC, FromPort);
++
++              if (DoPrintInterfaceChange) {
+               printk("%s: network connection up using"
+                       " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
+@@ -4841,8 +5056,6 @@ SK_BOOL          DualNet;
+                       printk("    speed:           unknown\n");
+               }
+-              /* Mac update */
+-              SkAddrMcUpdate(pAC,IoC, FromPort);
+               Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
+               if (Stat == SK_LMODE_STAT_AUTOHALF ||
+@@ -4920,6 +5133,9 @@ SK_BOOL          DualNet;
+                       printk("    rx-checksum:     disabled\n");
+ #endif
++              } else {
++                        DoPrintInterfaceChange = SK_TRUE;
++                }
+       
+               if ((Param.Para32[0] != pAC->ActivePort) &&
+                       (pAC->RlmtNets == 1)) {
+@@ -4937,7 +5153,12 @@ SK_BOOL         DualNet;
+               /* action list 7 */
+               SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+                       ("NET DOWN EVENT "));
+-              printk("%s: network connection down\n", pAC->dev[Param.Para32[1]]->name);
++              if (DoPrintInterfaceChange) {
++                      printk("%s: network connection down\n", 
++                              pAC->dev[Param.Para32[1]]->name);
++              } else {
++                      DoPrintInterfaceChange = SK_TRUE;
++              }
+               pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
+               break;
+       case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
+@@ -5122,6 +5343,231 @@ char   ClassStr[80];
+ } /* SkErrorLog */
++#ifdef SK_DIAG_SUPPORT
++
++/*****************************************************************************
++ *
++ *    SkDrvEnterDiagMode - handles DIAG attach request
++ *
++ * Description:
++ *    Notify the kernel to NOT access the card any longer due to DIAG
++ *    Deinitialize the Card
++ *
++ * Returns:
++ *    int
++ */
++int SkDrvEnterDiagMode(
++SK_AC   *pAc)   /* pointer to adapter context */
++{
++      SK_AC   *pAC  = NULL;
++      DEV_NET *pNet = NULL;
++
++      pNet = (DEV_NET *) pAc->dev[0]->priv;
++      pAC = pNet->pAC;
++
++      SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct), 
++                      sizeof(SK_PNMI_STRUCT_DATA));
++
++      pAC->DiagModeActive = DIAG_ACTIVE;
++      if (pAC->BoardLevel > SK_INIT_DATA) {
++              if (pNet->Up) {
++                      pAC->WasIfUp[0] = SK_TRUE;
++                      pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose      */
++                      DoPrintInterfaceChange = SK_FALSE;
++                      SkDrvDeInitAdapter(pAC, 0);  /* performs SkGeClose */
++              } else {
++                      pAC->WasIfUp[0] = SK_FALSE;
++              }
++              if (pNet != (DEV_NET *) pAc->dev[1]->priv) {
++                      pNet = (DEV_NET *) pAc->dev[1]->priv;
++                      if (pNet->Up) {
++                              pAC->WasIfUp[1] = SK_TRUE;
++                              pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
++                              DoPrintInterfaceChange = SK_FALSE;
++                              SkDrvDeInitAdapter(pAC, 1);  /* do SkGeClose  */
++                      } else {
++                              pAC->WasIfUp[1] = SK_FALSE;
++                      }
++              }
++              pAC->BoardLevel = SK_INIT_DATA;
++      }
++      return(0);
++}
++
++/*****************************************************************************
++ *
++ *    SkDrvLeaveDiagMode - handles DIAG detach request
++ *
++ * Description:
++ *    Notify the kernel to may access the card again after use by DIAG
++ *    Initialize the Card
++ *
++ * Returns:
++ *    int
++ */
++int SkDrvLeaveDiagMode(
++SK_AC   *pAc)   /* pointer to adapter control context */
++{ 
++      SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup), 
++                      sizeof(SK_PNMI_STRUCT_DATA));
++      pAc->DiagModeActive    = DIAG_NOTACTIVE;
++      pAc->Pnmi.DiagAttached = SK_DIAG_IDLE;
++        if (pAc->WasIfUp[0] == SK_TRUE) {
++                pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
++              DoPrintInterfaceChange = SK_FALSE;
++                SkDrvInitAdapter(pAc, 0);    /* first device  */
++        }
++        if (pAc->WasIfUp[1] == SK_TRUE) {
++                pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
++              DoPrintInterfaceChange = SK_FALSE;
++                SkDrvInitAdapter(pAc, 1);    /* second device */
++        }
++      return(0);
++}
++
++/*****************************************************************************
++ *
++ *    ParseDeviceNbrFromSlotName - Evaluate PCI device number
++ *
++ * Description:
++ *    This function parses the PCI slot name information string and will
++ *    retrieve the devcie number out of it. The slot_name maintianed by
++ *    linux is in the form of '02:0a.0', whereas the first two characters 
++ *    represent the bus number in hex (in the sample above this is 
++ *    pci bus 0x02) and the next two characters the device number (0x0a).
++ *
++ * Returns:
++ *    SK_U32: The device number from the PCI slot name
++ */ 
++
++static SK_U32 ParseDeviceNbrFromSlotName(
++const char *SlotName)   /* pointer to pci slot name eg. '02:0a.0' */
++{
++      char    *CurrCharPos    = (char *) SlotName;
++      int     FirstNibble     = -1;
++      int     SecondNibble    = -1;
++      SK_U32  Result          =  0;
++
++      while (*CurrCharPos != '\0') {
++              if (*CurrCharPos == ':') { 
++                      while (*CurrCharPos != '.') {
++                              CurrCharPos++;  
++                              if (    (*CurrCharPos >= '0') && 
++                                      (*CurrCharPos <= '9')) {
++                                      if (FirstNibble == -1) {
++                                              /* dec. value for '0' */
++                                              FirstNibble = *CurrCharPos - 48;
++                                      } else {
++                                              SecondNibble = *CurrCharPos - 48;
++                                      }  
++                              } else if (     (*CurrCharPos >= 'a') && 
++                                              (*CurrCharPos <= 'f')  ) {
++                                      if (FirstNibble == -1) {
++                                              FirstNibble = *CurrCharPos - 87; 
++                                      } else {
++                                              SecondNibble = *CurrCharPos - 87; 
++                                      }
++                              } else {
++                                      Result = 0;
++                              }
++                      }
++
++                      Result = FirstNibble;
++                      Result = Result << 4; /* first nibble is higher one */
++                      Result = Result | SecondNibble;
++              }
++              CurrCharPos++;   /* next character */
++      }
++      return (Result);
++}
++
++/****************************************************************************
++ *
++ *    SkDrvDeInitAdapter - deinitialize adapter (this function is only 
++ *                            called if Diag attaches to that card)
++ *
++ * Description:
++ *    Close initialized adapter.
++ *
++ * Returns:
++ *    0 - on success
++ *    error code - on error
++ */
++static int SkDrvDeInitAdapter(
++SK_AC   *pAC,         /* pointer to adapter context   */
++int      devNbr)      /* what device is to be handled */
++{
++      struct SK_NET_DEVICE *dev;
++
++      dev = pAC->dev[devNbr];
++
++      /*
++      ** Function SkGeClose() uses MOD_DEC_USE_COUNT (2.2/2.4)
++      ** or module_put() (2.6) to decrease the number of users for
++      ** a device, but if a device is to be put under control of 
++      ** the DIAG, that count is OK already and does not need to 
++      ** be adapted! Hence the opposite MOD_INC_USE_COUNT or 
++      ** try_module_get() needs to be used again to correct that.
++      */
++      if (!try_module_get(THIS_MODULE)) {
++              return (-1);
++      }
++
++      if (SkGeClose(dev) != 0) {
++              module_put(THIS_MODULE);
++              return (-1);
++      }
++      return (0);
++
++} /* SkDrvDeInitAdapter() */
++
++/****************************************************************************
++ *
++ *    SkDrvInitAdapter - Initialize adapter (this function is only 
++ *                            called if Diag deattaches from that card)
++ *
++ * Description:
++ *    Close initialized adapter.
++ *
++ * Returns:
++ *    0 - on success
++ *    error code - on error
++ */
++static int SkDrvInitAdapter(
++SK_AC   *pAC,         /* pointer to adapter context   */
++int      devNbr)      /* what device is to be handled */
++{
++      struct SK_NET_DEVICE *dev;
++
++      dev = pAC->dev[devNbr];
++
++      if (SkGeOpen(dev) != 0) {
++              return (-1);
++      } else {
++              /*
++              ** Function SkGeOpen() uses MOD_INC_USE_COUNT (2.2/2.4) 
++              ** or try_module_get() (2.6) to increase the number of 
++              ** users for a device, but if a device was just under 
++              ** control of the DIAG, that count is OK already and 
++              ** does not need to be adapted! Hence the opposite 
++              ** MOD_DEC_USE_COUNT or module_put() needs to be used 
++              ** again to correct that.
++              */
++              module_put(THIS_MODULE);
++      }
++
++      /*
++      ** Use correct MTU size and indicate to kernel TX queue can be started
++      */ 
++      if (SkGeChangeMtu(dev, dev->mtu) != 0) {
++              return (-1);
++      } 
++      return (0);
++
++} /* SkDrvInitAdapter */
++
++#endif
++
+ #ifdef DEBUG
+ /****************************************************************************/
+ /* "debug only" section *****************************************************/
+--- linux-2.6.0/drivers/net/sk98lin/skgehwt.c  2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/skgehwt.c   2003-12-28 23:21:01.000000000 -0800
+@@ -1,10 +1,10 @@
+ /******************************************************************************
+  *
+  * Name:      skgehwt.c
+- * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.14 $
+- * Date:      $Date: 2003/05/13 18:01:58 $
+- * Purpose:   Hardware Timer.
++ * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
++ * Version:   $Revision: 1.15 $
++ * Date:      $Date: 2003/09/16 13:41:23 $
++ * Purpose:   Hardware Timer
+  *
+  ******************************************************************************/
+@@ -27,6 +27,10 @@
+  * History:
+  *
+  *    $Log: skgehwt.c,v $
++ *    Revision 1.15  2003/09/16 13:41:23  rschmidt
++ *    Added (C) Marvell to SysKonnectFileId
++ *    Editorial changes
++ *    
+  *    Revision 1.14  2003/05/13 18:01:58  mkarl
+  *    Editorial changes.
+  *    
+@@ -69,19 +73,15 @@
+  *    
+  *    Revision 1.1  1998/08/05 11:28:36  gklug
+  *    first version: adapted from SMT/FDDI
+- *    
+- *    
+- *    
+  *
+  ******************************************************************************/
+-
+ /*
+-      Event queue and dispatcher
+-*/
++ *    Event queue and dispatcher
++ */
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.14 2003/05/13 18:01:58 mkarl Exp $" ;
++      "@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell.";
+ #endif
+ #include "h/skdrv1st.h"               /* Driver Specific Definitions */
+@@ -89,10 +89,7 @@ static const char SysKonnectFileId[] =
+ #ifdef __C2MAN__
+ /*
+-      Hardware Timer function queue management.
+-
+-      General Description:
+-
++ *   Hardware Timer function queue management.
+  */
+ intro()
+ {}
+@@ -117,9 +114,9 @@ SK_IOC     Ioc)    /* IoContext */
+ {
+       pAC->Hwt.TStart = 0 ;
+       pAC->Hwt.TStop  = 0 ;
+-      pAC->Hwt.TActive = SK_FALSE ;
++      pAC->Hwt.TActive = SK_FALSE;
+-      SkHwtStop(pAC,Ioc) ;
++      SkHwtStop(pAC, Ioc);
+ }
+ /*
+@@ -132,28 +129,29 @@ SK_AC    *pAC,   /* Adapters context */
+ SK_IOC        Ioc,    /* IoContext */
+ SK_U32        Time)   /* Time in units of 16us to load the timer with. */
+ {
+-      SK_U32  Cnt ;
++      SK_U32  Cnt;
+       if (Time > SK_HWT_MAX)
+-              Time = SK_HWT_MAX ;
++              Time = SK_HWT_MAX;
+-      pAC->Hwt.TStart = Time ;
+-      pAC->Hwt.TStop = 0L ;
++      pAC->Hwt.TStart = Time;
++      pAC->Hwt.TStop = 0L;
+-      Cnt = Time ;
++      Cnt = Time;
+       /*
+        * if time < 16 us
+        *      time = 16 us
+        */
+       if (!Cnt) {
+-              Cnt++ ;
++              Cnt++;
+       }
+-      SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC) ;
+-      SK_OUT16(Ioc, B2_TI_CRTL, TIM_START) ;  /* Start timer. */
++      SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC);
++      
++      SK_OUT16(Ioc, B2_TI_CTRL, TIM_START);   /* Start timer. */
+-      pAC->Hwt.TActive = SK_TRUE ;
++      pAC->Hwt.TActive = SK_TRUE;
+ }
+ /*
+@@ -164,10 +162,11 @@ void     SkHwtStop(
+ SK_AC *pAC,   /* Adapters context */
+ SK_IOC        Ioc)    /* IoContext */
+ {
+-      SK_OUT16(Ioc, B2_TI_CRTL, TIM_STOP) ;
+-      SK_OUT16(Ioc, B2_TI_CRTL, TIM_CLR_IRQ) ;
++      SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP);
++      
++      SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ);
+-      pAC->Hwt.TActive = SK_FALSE ;
++      pAC->Hwt.TActive = SK_FALSE;
+ }
+@@ -182,26 +181,31 @@ SK_U32   SkHwtRead(
+ SK_AC *pAC,   /* Adapters context */
+ SK_IOC        Ioc)    /* IoContext */
+ {
+-      SK_U32  TRead ;
+-      SK_U32  IStatus ;
++      SK_U32  TRead;
++      SK_U32  IStatus;
+       if (pAC->Hwt.TActive) {
+-              SkHwtStop(pAC,Ioc) ;
++              
++              SkHwtStop(pAC, Ioc);
+               SK_IN32(Ioc, B2_TI_VAL, &TRead);
+               TRead /= SK_HWT_FAC;
+               SK_IN32(Ioc, B0_ISRC, &IStatus);
+-              /* Check if timer expired (or wraparound). */
++              /* Check if timer expired (or wraped around) */
+               if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
+-                      SkHwtStop(pAC,Ioc) ;
+-                      pAC->Hwt.TStop = pAC->Hwt.TStart ;
+-              } else {
+-                      pAC->Hwt.TStop = pAC->Hwt.TStart - TRead ;
++                      
++                      SkHwtStop(pAC, Ioc);
++                      
++                      pAC->Hwt.TStop = pAC->Hwt.TStart;
++              }
++              else {
++                      
++                      pAC->Hwt.TStop = pAC->Hwt.TStart - TRead;
+               }
+       }
+-      return (pAC->Hwt.TStop) ;
++      return(pAC->Hwt.TStop);
+ }
+ /*
+@@ -211,9 +215,11 @@ void      SkHwtIsr(
+ SK_AC *pAC,   /* Adapters context */
+ SK_IOC        Ioc)    /* IoContext */
+ {
+-      SkHwtStop(pAC,Ioc);
++      SkHwtStop(pAC, Ioc);
++      
+       pAC->Hwt.TStop = pAC->Hwt.TStart;
+-      SkTimerDone(pAC,Ioc) ;
++      
++      SkTimerDone(pAC, Ioc);
+ }
+ /* End of file */
+--- linux-2.6.0/drivers/net/sk98lin/skgeinit.c 2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/skgeinit.c  2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgeinit.c
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.93 $
+- * Date:      $Date: 2003/05/28 15:44:43 $
++ * Version:   $Revision: 1.97 $
++ * Date:      $Date: 2003/10/02 16:45:31 $
+  * Purpose:   Contains functions to initialize the adapter
+  *
+  ******************************************************************************/
+@@ -27,6 +27,32 @@
+  * History:
+  *
+  *    $Log: skgeinit.c,v $
++ *    Revision 1.97  2003/10/02 16:45:31  rschmidt
++ *    Replaced default values of GMAC parameters with defines.
++ *    Removed hard reset of MACs in SkGeDeInit().
++ *    Added define SK_PHY_LP_MODE around power saving mode in SkGeDeInit().
++ *    Added check for VAUX available before switch power to VAUX.
++ *    
++ *    Revision 1.96  2003/09/18 14:02:41  rroesler
++ *    Add: Perform a hardreset of MACs in GeDeInit()
++ *    
++ *    Revision 1.95  2003/09/16 14:26:59  rschmidt
++ *    Added switch power to VCC (WA for VAUX problem) in SkGeInit1().
++ *    Fixed setting PHY to coma mode and D3 power state in SkGeDeInit().
++ *    Editorial changes.
++ *    
++ *    Revision 1.94  2003/09/16 07:17:10  mschmid
++ *    Added init for new members in port structure for MAC control
++ *    - PMacColThres
++ *    - PMacJamLen
++ *    - PMacJamIpgVal
++ *    - PMacJamIpgData
++ *    - PMacIpgData
++ *    - PMacLimit4
++ *    Added init for PHY power state in port structure
++ *    - PPhyPowerState
++ *    Added shutdown handling for Yukon Plus in SkGeDeInit()
++ *    
+  *    Revision 1.93  2003/05/28 15:44:43  rschmidt
+  *    Added check for chip Id on WOL WA for chip Rev. A.
+  *    Added setting of GILevel in SkGeDeInit().
+@@ -446,7 +472,7 @@
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skgeinit.c,v 1.93 2003/05/28 15:44:43 rschmidt Exp $ (C) Marvell.";
++      "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell.";
+ #endif
+ struct s_QOffTab {
+@@ -1013,8 +1039,6 @@ int              Port)           /* Port Index (MAC_1 + n) */
+        *      - enable the FIFO
+        */
+       
+-      Word = (SK_U16)GMF_RX_CTRL_DEF;
+-      
+ #ifdef GENESIS
+       if (pAC->GIni.GIGenesis) {
+               /* Configure Rx MAC FIFO */
+@@ -1039,6 +1063,8 @@ int              Port)           /* Port Index (MAC_1 + n) */
+               /* set Rx GMAC FIFO Flush Mask */
+               SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
+               
++              Word = (SK_U16)GMF_RX_CTRL_DEF;
++
+               /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
+               if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) {
+@@ -1809,6 +1835,13 @@ SK_IOC  IoC)            /* IO context */
+               pPrt->PAutoNegFail = SK_FALSE;
+               pPrt->PHWLinkUp = SK_FALSE;
+               pPrt->PLinkBroken = SK_TRUE; /* See WA code */
++              pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
++              pPrt->PMacColThres = TX_COL_DEF;
++              pPrt->PMacJamLen = TX_JAM_LEN_DEF;
++              pPrt->PMacJamIpgVal     = TX_JAM_IPG_DEF;
++              pPrt->PMacJamIpgData = TX_IPG_JAM_DEF;
++              pPrt->PMacIpgData = IPG_DATA_DEF;
++              pPrt->PMacLimit4 = SK_FALSE;
+       }
+       pAC->GIni.GIPortUsage = SK_RED_LINK;
+@@ -1963,7 +1996,7 @@ SK_IOC   IoC)            /* IO context */
+       /* restore CLK_RUN bits */
+       SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat &
+               (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)));
+-      
++
+       /* read Chip Identification Number */
+       SK_IN8(IoC, B2_CHIP_ID, &Byte);
+       pAC->GIni.GIChipId = Byte;
+@@ -2053,6 +2086,10 @@ SK_IOC  IoC)            /* IO context */
+                       }
+               }
++              /* switch power to VCC (WA for VAUX problem) */
++              SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
++                      PC_VAUX_OFF | PC_VCC_ON));
++
+               /* read the Interrupt source */
+               SK_IN32(IoC, B0_ISRC, &DWord);
+               
+@@ -2395,6 +2432,11 @@ SK_IOC  IoC)            /* IO context */
+       int     i;
+       SK_U16  Word;
++#ifdef SK_PHY_LP_MODE
++      SK_U8   Byte;
++      SK_U16  PmCtlSts;
++#endif /* SK_PHY_LP_MODE */
++
+ #if (!defined(SK_SLIM) && !defined(VCPU))
+       /* ensure I2C is ready */
+       SkI2cWaitIrq(pAC, IoC);
+@@ -2409,6 +2451,38 @@ SK_IOC  IoC)            /* IO context */
+               }
+       }
++#ifdef SK_PHY_LP_MODE
++    /*
++       * for power saving purposes within mobile environments
++       * we set the PHY to coma mode and switch to D3 power state.
++       */
++      if (pAC->GIni.GIYukonLite &&
++              pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
++
++              /* for all ports switch PHY to coma mode */
++              for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
++                      
++                      SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP);
++              }
++
++              if (pAC->GIni.GIVauxAvail) {
++                      /* switch power to VAUX */
++                      Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF;
++
++                      SK_OUT8(IoC, B0_POWER_CTRL, Byte);
++              }
++              
++              /* switch to D3 state */
++              SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts);
++
++              PmCtlSts |= PCI_PM_STATE_D3;
++
++              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
++
++              SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts);
++      }
++#endif /* SK_PHY_LP_MODE */
++
+       /* Reset all bits in the PCI STATUS register */
+       /*
+        * Note: PCI Cfg cycles cannot be used, because they are not
+--- linux-2.6.0/drivers/net/sk98lin/skgemib.c  2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/skgemib.c   2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgemib.c
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.9 $
+- * Date:      $Date: 2003/05/23 12:55:20 $
++ * Version:   $Revision: 1.11 $
++ * Date:      $Date: 2003/09/15 13:38:12 $
+  * Purpose:   Private Network Management Interface Management Database
+  *
+  ****************************************************************************/
+@@ -27,6 +27,19 @@
+  * History:
+  *
+  *    $Log: skgemib.c,v $
++ *    Revision 1.11  2003/09/15 13:38:12  tschilli
++ *    OID_SKGE_PHY_LP_MODE included only after using #define SK_PHY_LP_MODE.
++ *    
++ *    Revision 1.10  2003/08/15 12:28:59  tschilli
++ *    Added new OIDs:
++ *    OID_SKGE_DRIVER_RELDATE
++ *    OID_SKGE_DRIVER_FILENAME
++ *    OID_SKGE_CHIPID
++ *    OID_SKGE_RAMSIZE
++ *    OID_SKGE_VAUXAVAIL
++ *    OID_SKGE_PHY_TYPE
++ *    OID_SKGE_PHY_LP_MODE
++ *    
+  *    Revision 1.9  2003/05/23 12:55:20  tschilli
+  *    OID_SKGE_BOARDLEVEL added.
+  *    
+@@ -356,6 +369,16 @@ PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTa
+               0,
+               SK_PNMI_MAI_OFF(DriverVersion),
+               SK_PNMI_RO, General, 0},
++      {OID_SKGE_DRIVER_RELDATE,
++              1,
++              0,
++              SK_PNMI_MAI_OFF(DriverReleaseDate),
++              SK_PNMI_RO, General, 0},
++      {OID_SKGE_DRIVER_FILENAME,
++              1,
++              0,
++              SK_PNMI_MAI_OFF(DriverFileName),
++              SK_PNMI_RO, General, 0},
+       {OID_SKGE_HW_DESCR,
+               1,
+               0,
+@@ -371,6 +394,21 @@ PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTa
+               0,
+               SK_PNMI_MAI_OFF(Chipset),
+               SK_PNMI_RO, General, 0},
++      {OID_SKGE_CHIPID,
++              1,
++              0,
++              SK_PNMI_MAI_OFF(ChipId),
++              SK_PNMI_RO, General, 0},
++      {OID_SKGE_RAMSIZE,
++              1,
++              0,
++              SK_PNMI_MAI_OFF(RamSize),
++              SK_PNMI_RO, General, 0},
++      {OID_SKGE_VAUXAVAIL,
++              1,
++              0,
++              SK_PNMI_MAI_OFF(VauxAvail),
++              SK_PNMI_RO, General, 0},
+       {OID_SKGE_ACTION,
+               1,
+               0,
+@@ -876,6 +914,18 @@ PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTa
+               sizeof(SK_PNMI_CONF),
+               SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector),
+               SK_PNMI_RO, MacPrivateConf, 0},
++      {OID_SKGE_PHY_TYPE,
++              SK_PNMI_MAC_ENTRIES,
++              sizeof(SK_PNMI_CONF),
++              SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType),
++              SK_PNMI_RO, MacPrivateConf, 0},
++#ifdef SK_PHY_LP_MODE
++              {OID_SKGE_PHY_LP_MODE,
++              SK_PNMI_MAC_ENTRIES,
++              sizeof(SK_PNMI_CONF),
++              SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyMode),
++              SK_PNMI_RW, MacPrivateConf, 0},
++#endif        
+       {OID_SKGE_LINK_CAP,
+               SK_PNMI_MAC_ENTRIES,
+               sizeof(SK_PNMI_CONF),
+--- linux-2.6.0/drivers/net/sk98lin/skgepnmi.c 2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/skgepnmi.c  2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgepnmi.c
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.109 $
+- * Date:      $Date: 2003/07/17 14:15:24 $
++ * Version:   $Revision: 1.111 $
++ * Date:      $Date: 2003/09/15 13:35:35 $
+  * Purpose:   Private Network Management Interface
+  *
+  ****************************************************************************/
+@@ -27,6 +27,22 @@
+  * History:
+  *
+  *    $Log: skgepnmi.c,v $
++ *    Revision 1.111  2003/09/15 13:35:35  tschilli
++ *    Code for OID_SKGE_PHY_LP_MODE completed (using #define SK_PHY_LP_MODE).
++ *    SK_DIAG_ATTACHED handling for OID_SKGE_DIAG_MODE in DiagActions() changed.
++ *    
++ *    Revision 1.110  2003/08/15 12:28:04  tschilli
++ *    Added new OIDs:
++ *    OID_SKGE_DRIVER_RELDATE
++ *    OID_SKGE_DRIVER_FILENAME
++ *    OID_SKGE_CHIPID
++ *    OID_SKGE_RAMSIZE
++ *    OID_SKGE_VAUXAVAIL
++ *    OID_SKGE_PHY_TYPE
++ *    OID_SKGE_PHY_LP_MODE
++ *    
++ *    Added SK_DIAG_ATTACHED handling for OID_SKGE_DIAG_MODE in DiagActions().
++ *    
+  *    Revision 1.109  2003/07/17 14:15:24  tschilli
+  *    Bug in SkPnmiGenIoctl() fixed.
+  *    
+@@ -471,7 +487,7 @@
+ #ifndef _lint
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skgepnmi.c,v 1.109 2003/07/17 14:15:24 tschilli Exp $ (C) Marvell.";
++      "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
+ #endif /* !_lint */
+ #include "h/skdrv1st.h"
+@@ -4008,14 +4024,6 @@ SK_U32 NetIndex)        /* NetIndex (0..n), in 
+ #endif /* SK_NDIS_64BIT_CTR */
+               break;
+-      case OID_SKGE_BOARDLEVEL:
+-              if (*pLen < sizeof(SK_U32)) {
+-
+-                      *pLen = sizeof(SK_U32);
+-                      return (SK_PNMI_ERR_TOO_SHORT);
+-              }
+-              break;
+-
+       case OID_SKGE_PORT_NUMBER:
+       case OID_SKGE_DEVICE_TYPE:
+       case OID_SKGE_RESULT:
+@@ -4023,6 +4031,9 @@ SK_U32 NetIndex) /* NetIndex (0..n), in 
+       case OID_GEN_TRANSMIT_QUEUE_LENGTH:
+       case OID_SKGE_TRAP_NUMBER:
+       case OID_SKGE_MDB_VERSION:
++      case OID_SKGE_BOARDLEVEL:
++      case OID_SKGE_CHIPID:
++      case OID_SKGE_RAMSIZE:
+               if (*pLen < sizeof(SK_U32)) {
+                       *pLen = sizeof(SK_U32);
+@@ -4043,6 +4054,7 @@ SK_U32 NetIndex) /* NetIndex (0..n), in 
+       case OID_SKGE_BUS_WIDTH:
+       case OID_SKGE_SENSOR_NUMBER:
+       case OID_SKGE_CHKSM_NUMBER:
++      case OID_SKGE_VAUXAVAIL:
+               if (*pLen < sizeof(SK_U8)) {
+                       *pLen = sizeof(SK_U8);
+@@ -4234,6 +4246,66 @@ SK_U32 NetIndex)        /* NetIndex (0..n), in 
+               *pLen = Len;
+               break;
++      case OID_SKGE_DRIVER_RELDATE:
++              if (pAC->Pnmi.pDriverReleaseDate == NULL) {
++
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
++                              SK_PNMI_ERR053MSG);
++
++                      *pLen = 0;
++                      return (SK_PNMI_ERR_GENERAL);
++              }
++
++              Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
++              if (Len > SK_PNMI_STRINGLEN1) {
++
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
++                              SK_PNMI_ERR054MSG);
++
++                      *pLen = 0;
++                      return (SK_PNMI_ERR_GENERAL);
++              }
++
++              if (*pLen < Len) {
++
++                      *pLen = Len;
++                      return (SK_PNMI_ERR_TOO_SHORT);
++              }
++              *pBuf = (char)(Len - 1);
++              SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
++              *pLen = Len;
++              break;
++
++      case OID_SKGE_DRIVER_FILENAME:
++              if (pAC->Pnmi.pDriverFileName == NULL) {
++
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
++                              SK_PNMI_ERR055MSG);
++
++                      *pLen = 0;
++                      return (SK_PNMI_ERR_GENERAL);
++              }
++
++              Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
++              if (Len > SK_PNMI_STRINGLEN1) {
++
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
++                              SK_PNMI_ERR056MSG);
++
++                      *pLen = 0;
++                      return (SK_PNMI_ERR_GENERAL);
++              }
++
++              if (*pLen < Len) {
++
++                      *pLen = Len;
++                      return (SK_PNMI_ERR_TOO_SHORT);
++              }
++              *pBuf = (char)(Len - 1);
++              SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
++              *pLen = Len;
++              break;
++
+       case OID_SKGE_HW_DESCR:
+               /*
+                * The hardware description is located in the VPD. This
+@@ -4291,8 +4363,25 @@ SK_U32 NetIndex)        /* NetIndex (0..n), in 
+               *pLen = sizeof(SK_U16);
+               break;
++      case OID_SKGE_CHIPID:
++              Val32 = pAC->GIni.GIChipId;
++              SK_PNMI_STORE_U32(pBuf, Val32);
++              *pLen = sizeof(SK_U32);
++              break;
++
++      case OID_SKGE_RAMSIZE:
++              Val32 = pAC->GIni.GIRamSize;
++              SK_PNMI_STORE_U32(pBuf, Val32);
++              *pLen = sizeof(SK_U32);
++              break;
++
++      case OID_SKGE_VAUXAVAIL:
++              *pBuf = (char) pAC->GIni.GIVauxAvail;
++              *pLen = sizeof(char);
++              break;
++
+       case OID_SKGE_BUS_TYPE:
+-              *pBuf = (char)SK_PNMI_BUS_PCI;
++              *pBuf = (char) SK_PNMI_BUS_PCI;
+               *pLen = sizeof(char);
+               break;
+@@ -5435,6 +5524,9 @@ SK_U32 NetIndex) /* NetIndex (0..n), in 
+               case OID_SKGE_SPEED_CAP:
+               case OID_SKGE_SPEED_MODE:
+               case OID_SKGE_SPEED_STATUS:
++#ifdef SK_PHY_LP_MODE
++              case OID_SKGE_PHY_LP_MODE:
++#endif
+                       if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
+                               *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
+@@ -5443,6 +5535,7 @@ SK_U32 NetIndex) /* NetIndex (0..n), in 
+                       break;
+         case OID_SKGE_MTU:
++        case OID_SKGE_PHY_TYPE:
+                       if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
+                               *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
+@@ -5488,6 +5581,49 @@ SK_U32 NetIndex)        /* NetIndex (0..n), in 
+                               Offset += sizeof(char);
+                               break;
++                      case OID_SKGE_PHY_TYPE:
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                                      if (LogPortIndex == 0) {
++                                              continue;
++                                      }
++                                      else {
++                                              /* Get value for physical ports */
++                                              PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
++                                                      pAC, LogPortIndex);
++                                              Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
++                                              SK_PNMI_STORE_U32(pBufPtr, Val32);
++                                      }
++                              }
++                              else { /* DualNetMode */
++                                      
++                                      Val32 = pAC->GIni.GP[NetIndex].PhyType;
++                                      SK_PNMI_STORE_U32(pBufPtr, Val32);
++                              }
++                              Offset += sizeof(SK_U32);
++                              break;
++
++#ifdef SK_PHY_LP_MODE
++                      case OID_SKGE_PHY_LP_MODE:
++                              if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                                      if (LogPortIndex == 0) {
++                                              continue;
++                                      }
++                                      else {
++                                              /* Get value for physical ports */
++                                              PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
++                                              Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
++                                              *pBufPtr = Val8;
++                                      }
++                              }
++                              else { /* DualNetMode */
++                                      
++                                      Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
++                                      *pBufPtr = Val8;
++                              }
++                              Offset += sizeof(SK_U8);
++                              break;
++#endif
++
+                       case OID_SKGE_LINK_CAP:
+                               if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+                                       if (LogPortIndex == 0) {
+@@ -5804,6 +5940,16 @@ SK_U32 NetIndex)        /* NetIndex (0..n), in 
+               }
+               break;
++#ifdef SK_PHY_LP_MODE
++      case OID_SKGE_PHY_LP_MODE:
++              if (*pLen < Limit - LogPortIndex) {
++
++                      *pLen = Limit - LogPortIndex;
++                      return (SK_PNMI_ERR_TOO_SHORT);
++              }
++              break;
++#endif
++
+       case OID_SKGE_MTU:
+               if (*pLen < sizeof(SK_U32)) {
+@@ -6160,6 +6306,116 @@ SK_U32 NetIndex)       /* NetIndex (0..n), in 
+                       Offset += sizeof(SK_U32);
+                       break;
++              
++#ifdef SK_PHY_LP_MODE
++              case OID_SKGE_PHY_LP_MODE:
++                      /* The preset ends here */
++                      if (Action == SK_PNMI_PRESET) {
++
++                              return (SK_PNMI_ERR_OK);
++                      }
++
++                      if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
++                              if (LogPortIndex == 0) {
++                                      Offset = 0;
++                                      continue;
++                              }
++                              else {
++                                      /* Set value for physical ports */
++                                      PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
++
++                                      switch (*(pBuf + Offset)) {
++                                              case 0:
++                                                      /* If LowPowerMode is active, we can leave it. */
++                                                      if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
++
++                                                              Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
++                                                              
++                                                              if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3)     {
++                                                                      
++                                                                      SkDrvInitAdapter(pAC);
++                                                              }
++                                                              break;
++                                                      }
++                                                      else {
++                                                              *pLen = 0;
++                                                              return (SK_PNMI_ERR_GENERAL);
++                                                      }
++                                              case 1:
++                                              case 2:
++                                              case 3:
++                                              case 4:
++                                                      /* If no LowPowerMode is active, we can enter it. */
++                                                      if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
++
++                                                              if ((*(pBuf + Offset)) < 3)     {
++                                                              
++                                                                      SkDrvDeInitAdapter(pAC);
++                                                              }
++
++                                                              Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
++                                                              break;
++                                                      }
++                                                      else {
++                                                              *pLen = 0;
++                                                              return (SK_PNMI_ERR_GENERAL);
++                                                      }
++                                              default:
++                                                      *pLen = 0;
++                                                      return (SK_PNMI_ERR_BAD_VALUE);
++                                      }
++                              }
++                      }
++                      else { /* DualNetMode */
++                              
++                              switch (*(pBuf + Offset)) {
++                                      case 0:
++                                              /* If we are in a LowPowerMode, we can leave it. */
++                                              if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
++
++                                                      Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
++                                                      
++                                                      if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3)     {
++
++                                                              SkDrvInitAdapter(pAC);
++                                                      }
++                                                      break;
++                                              }
++                                              else {
++                                                      *pLen = 0;
++                                                      return (SK_PNMI_ERR_GENERAL);
++                                              }
++                                      
++                                      case 1:
++                                      case 2:
++                                      case 3:
++                                      case 4:
++                                              /* If we are not already in LowPowerMode, we can enter it. */
++                                              if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
++
++                                                      if ((*(pBuf + Offset)) < 3)     {
++
++                                                              SkDrvDeInitAdapter(pAC);
++                                                      }
++                                                      else {
++
++                                                              Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
++                                                      }
++                                                      break;
++                                              }
++                                              else {
++                                                      *pLen = 0;
++                                                      return (SK_PNMI_ERR_GENERAL);
++                                              }
++                                      
++                                      default:
++                                              *pLen = 0;
++                                              return (SK_PNMI_ERR_BAD_VALUE);
++                              }
++                      }
++                      Offset += sizeof(SK_U8);
++                      break;
++#endif
+               default:
+             SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
+@@ -6318,6 +6574,7 @@ char *pBuf)              /* Buffer used for the mana
+       unsigned int    PhysPortMax;
+       unsigned int    PhysPortIndex;
+       SK_U8           Val8;
++      SK_U32          Val32;
+       SK_BOOL         PortActiveFlag;
+       SK_GEPORT       *pPrt;
+@@ -6340,6 +6597,14 @@ char *pBuf)             /* Buffer used for the mana
+               switch (Id) {
++              case OID_SKGE_PHY_TYPE:
++                      /* Check if it is the first active port */
++                      if (*pBuf == 0) {
++                              Val32 = pPrt->PhyType;
++                              SK_PNMI_STORE_U32(pBuf, Val32);
++                              continue;
++                      }
++
+               case OID_SKGE_LINK_CAP:
+                       /*
+@@ -7974,6 +8239,7 @@ unsigned int TableIndex, /* Index to the
+ SK_U32 NetIndex)      /* NetIndex (0..n), in single net mode always zero */
+ {
++      SK_U32  DiagStatus;
+       SK_U32  RetCode = SK_PNMI_ERR_GENERAL;
+       /*
+@@ -8012,7 +8278,8 @@ SK_U32 NetIndex) /* NetIndex (0..n), in 
+               switch (Id) {
+               case OID_SKGE_DIAG_MODE:
+-                      SK_PNMI_STORE_U32(pBuf, pAC->DiagModeActive);
++                      DiagStatus = pAC->Pnmi.DiagAttached;
++                      SK_PNMI_STORE_U32(pBuf, DiagStatus);
+                       *pLen = sizeof(SK_U32); 
+                       RetCode = SK_PNMI_ERR_OK;
+                       break;
+@@ -8022,7 +8289,6 @@ SK_U32 NetIndex) /* NetIndex (0..n), in 
+                       RetCode = SK_PNMI_ERR_GENERAL;
+                       break;
+               }
+-
+               return (RetCode); 
+       }
+@@ -8039,23 +8305,84 @@ SK_U32 NetIndex)       /* NetIndex (0..n), in 
+                       /* Handle the SET. */
+                       switch (*pBuf) {
+-              
++
++                              /* Attach the DIAG to this adapter. */
++                              case SK_DIAG_ATTACHED:
++                                      /* Check if we come from running */
++                                      if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
++
++                                              RetCode = SkDrvLeaveDiagMode(pAC);
++
++                                      }
++                                      else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
++
++                                              RetCode = SK_PNMI_ERR_OK;
++                                      }       
++                                      
++                                      else {
++
++                                              RetCode = SK_PNMI_ERR_GENERAL;
++
++                                      }
++                                      
++                                      if (RetCode == SK_PNMI_ERR_OK) {
++
++                                              pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
++                                      }
++                                      break;
++
+                               /* Enter the DIAG mode in the driver. */
+-                              case 1:
+-                                      /* If DiagMode is not active, we can enter it. */
+-                                      if (!pAC->DiagModeActive) {
++                              case SK_DIAG_RUNNING:
++                                      RetCode = SK_PNMI_ERR_OK;
++                                      
++                                      /*
++                                       * If DiagAttached is set, we can tell the driver
++                                       * to enter the DIAG mode.
++                                       */
++                                      if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
++                                              /* If DiagMode is not active, we can enter it. */
++                                              if (!pAC->DiagModeActive) {
+-                                              RetCode = SkDrvEnterDiagMode(pAC);      
++                                                      RetCode = SkDrvEnterDiagMode(pAC); 
++                                              }
++                                              else {
++
++                                                      RetCode = SK_PNMI_ERR_GENERAL;
++                                              }
+                                       }
+                                       else {
+                                               RetCode = SK_PNMI_ERR_GENERAL;
+                                       }
++                                      
++                                      if (RetCode == SK_PNMI_ERR_OK) {
++
++                                              pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
++                                      }
+                                       break;
+-                              /* Leave the DIAG mode in the driver. */
+-                              case 0:
+-                                      RetCode = SkDrvLeaveDiagMode(pAC);      
++                              case SK_DIAG_IDLE:
++                                      /* Check if we come from running */
++                                      if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
++
++                                              RetCode = SkDrvLeaveDiagMode(pAC);
++
++                                      }
++                                      else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
++
++                                              RetCode = SK_PNMI_ERR_OK;
++                                      }       
++                                      
++                                      else {
++
++                                              RetCode = SK_PNMI_ERR_GENERAL;
++
++                                      }
++
++                                      if (RetCode == SK_PNMI_ERR_OK) {
++
++                                              pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
++                                      }
+                                       break;
+                               default:
+--- linux-2.6.0/drivers/net/sk98lin/skgesirq.c 2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/skgesirq.c  2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skgesirq.c
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.91 $
+- * Date:      $Date: 2003/07/04 12:46:22 $
++ * Version:   $Revision: 1.92 $
++ * Date:      $Date: 2003/09/16 14:37:07 $
+  * Purpose:   Special IRQ module
+  *
+  ******************************************************************************/
+@@ -27,6 +27,12 @@
+  * History:
+  *
+  *    $Log: skgesirq.c,v $
++ *    Revision 1.92  2003/09/16 14:37:07  rschmidt
++ *    Added debug messages in some SkGePortCheckUp...() routines.
++ *    Fixed compiler warnings for different types.
++ *    Avoided port check up in reset state (eg. coma mode).
++ *    Editorial changes.
++ *    
+  *    Revision 1.91  2003/07/04 12:46:22  rschmidt
+  *    Added debug messages in SkGePortCheckUpGmac().
+  *    Added error log message and new driver event SK_DRV_DOWNSHIFT_DET
+@@ -410,7 +416,7 @@
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skgesirq.c,v 1.91 2003/07/04 12:46:22 rschmidt Exp $ (C) Marvell.";
++      "@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell.";
+ #endif
+ #include "h/skdrv1st.h"               /* Driver Specific Definitions */
+@@ -490,7 +496,7 @@ int                Port)   /* Port Index (MAC_1 + n) */
+               ("AutoSensing: First mode %d on Port %d\n",
+               (int)SK_LMODE_AUTOFULL, Port));
+-      pPrt->PLinkMode = SK_LMODE_AUTOFULL;
++      pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
+       return;
+ }     /* SkHWInitDefSense */
+@@ -606,7 +612,7 @@ int                Port)           /* Port Index (MAC_1 + n) */
+       /* Reset Port stati */
+     pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
+     pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
+-      pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_INDETERMINATED;
++      pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED;
+       /* Re-init Phy especially when the AutoSense default is set now */
+       SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
+@@ -655,19 +661,19 @@ int              Port)   /* Port Index (MAC_1 + n) */
+               case SK_LSPEED_AUTO:
+                       /* default is 1000 Mbps */
+               case SK_LSPEED_1000MBPS:
+-                      pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
++                      pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
+                       break;
+               case SK_LSPEED_100MBPS:
+-                      pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS;
++                      pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
+                       break;
+               case SK_LSPEED_10MBPS:
+-                      pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS;
++                      pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
+                       break;
+               }
+               /* Set Link Mode Status */
+               if (pPrt->PLinkMode == SK_LMODE_FULL) {
+-                      pPrt->PLinkModeStatus = SK_LMODE_STAT_FULL;
++                      pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL;
+               }
+               else {
+             pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
+@@ -1598,8 +1604,7 @@ SK_BOOL  AutoNeg)        /* Is Auto-negotiation 
+                        * (clear Page Received bit if set)
+                        */
+                       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
+-                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                              ("AutoNeg done Port %d\n", Port));
++                      
+                       return(SK_HW_PS_LINK);
+               }
+               
+@@ -1870,7 +1875,7 @@ SK_BOOL  AutoNeg)        /* Is Auto-negotiation 
+       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
+       
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("AutoNeg: %d, PhyStat: 0x%04X\n", AutoNeg, PhyStat));
++              ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
+       SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
+@@ -1897,8 +1902,11 @@ SK_BOOL AutoNeg)        /* Is Auto-negotiation 
+       if (AutoNeg) {
+               if ((PhyStat & PHY_ST_AN_OVER) != 0) {
++                      
+                       SkHWLinkUp(pAC, IoC, Port);
++                      
+                       Done = SkMacAutoNegDone(pAC, IoC, Port);
++                      
+                       if (Done != SK_AND_OK) {
+ #ifdef DEBUG
+                               /* Get PHY parameters, for debugging only */
+@@ -1924,9 +1932,6 @@ SK_BOOL  AutoNeg)        /* Is Auto-negotiation 
+                                               (void *)NULL);
+                               }
+ #endif /* DEBUG */
+-                              
+-                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                                      ("AutoNeg done Port %d\n", Port));
+                               return(SK_HW_PS_LINK);
+                       }
+               }
+@@ -1989,9 +1994,22 @@ SK_BOOL AutoNeg)        /* Is Auto-negotiation 
+       SK_U16          PhySpecStat;/* PHY Specific Status */
+       SK_U16          ResAb;          /* Master/Slave resolution */
+       SK_EVPARA       Para;
++#ifdef DEBUG
++      SK_U16          Word;           /* I/O helper */
++#endif /* DEBUG */
+       pPrt = &pAC->GIni.GP[Port];
++      if (pPrt->PHWLinkUp) {
++              return(SK_HW_PS_NONE);
++      }
++
++      /* Read PHY Status */
++      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
++
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
++
+       /* Read PHY Interrupt Status */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc);
+@@ -2005,16 +2023,6 @@ SK_BOOL AutoNeg)        /* Is Auto-negotiation 
+                       ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc));
+       }
+-      if (pPrt->PHWLinkUp) {
+-              return(SK_HW_PS_NONE);
+-      }
+-
+-      /* Read PHY Status */
+-      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
+-
+-      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("AutoNeg: %d, PhyStat: 0x%04X\n", AutoNeg, PhyStat));
+-
+       SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
+       
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
+@@ -2034,7 +2042,20 @@ SK_BOOL AutoNeg)        /* Is Auto-negotiation 
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
+       
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("AutoNeg: %d, PhySpecStat: 0x%04X\n", AutoNeg, PhySpecStat));
++              ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat));
++
++#ifdef DEBUG
++      SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word);
++
++      if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 ||
++              (PhySpecStat & PHY_M_PS_PAGE_REC) != 0)  {
++              /* Read PHY Next Page Link Partner */
++              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word);
++
++              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++                      ("Page Received, NextPage: 0x%04X\n", Word));
++      }
++#endif /* DEBUG */
+       if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
+               return(SK_HW_PS_NONE);
+@@ -2069,8 +2090,6 @@ SK_BOOL  AutoNeg)        /* Is Auto-negotiation 
+                               return(SK_HW_PS_RESTART);
+                       }
+                       
+-                      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                              ("AutoNeg done Port %d\n", Port));
+                       return(SK_HW_PS_LINK);
+               }
+       }
+@@ -2179,8 +2198,6 @@ SK_BOOL  AutoNeg)        /* Is Auto-negotiation 
+                                * extra link down/ups
+                                */
+                               SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
+-                              SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                                      ("AutoNeg done Port %d\n", Port));
+                               return(SK_HW_PS_LINK);
+                       }
+               }
+@@ -2278,8 +2295,14 @@ SK_EVPARA       Para)           /* Event specific Param
+       switch (Event) {
+       case SK_HWEV_WATIM:
+-              /* Check whether port came up */
+-              PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);
++              if (pPrt->PState == SK_PRT_RESET) {
++              
++                      PortStat = SK_HW_PS_NONE;
++              }
++              else {
++                      /* Check whether port came up */
++                      PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);
++              }
+               switch (PortStat) {
+               case SK_HW_PS_RESTART:
+--- linux-2.6.0/drivers/net/sk98lin/ski2c.c    2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/ski2c.c     2003-12-28 23:21:01.000000000 -0800
+@@ -1,16 +1,17 @@
+ /******************************************************************************
+  *
+  * Name:      ski2c.c
+- * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.57 $
+- * Date:      $Date: 2003/01/28 09:17:38 $
++ * Project:   Gigabit Ethernet Adapters, TWSI-Module
++ * Version:   $Revision: 1.59 $
++ * Date:      $Date: 2003/10/20 09:07:25 $
+  * Purpose:   Functions to access Voltage and Temperature Sensor
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2003 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect.
++ *    (C)Copyright 2002-2003 Marvell.
+  *
+  *    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
+@@ -26,6 +27,14 @@
+  * History:
+  *
+  *    $Log: ski2c.c,v $
++ *    Revision 1.59  2003/10/20 09:07:25  rschmidt
++ *    Added cast SK_U32 in SkI2cWrite() to avoid compiler warning.
++ *    Editorial changes.
++ *    
++ *    Revision 1.58  2003/09/23 09:22:53  malthoff
++ *    Parameter I2cDevSize added in SkI2cRead and SkI2cWrite to
++ *    support larger devices on the TWSI bus.
++ *    
+  *    Revision 1.57  2003/01/28 09:17:38  rschmidt
+  *    Fixed handling for sensors on YUKON Fiber.
+  *    Editorial changes.
+@@ -224,15 +233,15 @@
+  *    Created. Sources taken from ML Projekt.
+  *    Sources have to be reworked for GE.
+  *
+- *
+  ******************************************************************************/
+-
+ /*
+  *    I2C Protocol
+  */
++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "$Id: ski2c.c,v 1.57 2003/01/28 09:17:38 rschmidt Exp $";
++      "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. ";
++#endif
+ #include "h/skdrv1st.h"               /* Driver Specific Definitions */
+ #include "h/lm80.h"
+@@ -312,7 +321,7 @@ intro()
+ {}
+ #endif
+-#ifdef        SK_DIAG
++#ifdef SK_DIAG
+ /*
+  * I2C Fast Mode timing values used by the LM80.
+  * If new devices are added to the I2C bus the timing values have to be checked.
+@@ -516,7 +525,6 @@ SK_IOC IoC)        /* I/O Context */
+ {
+       /*
+        * Received bit must be zero.
+-       *
+        */
+       SkI2cSndBit(IoC, 0);
+ }     /* SkI2cSndAck */
+@@ -590,7 +598,7 @@ int                Rw)             /* Read / Write Flag */
+       return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
+ }     /* SkI2cSndDev */
+-#endif        /* SK_DIAG */
++#endif /* SK_DIAG */
+ /*----------------- I2C CTRL Register Functions ----------*/
+@@ -620,7 +628,7 @@ int                Event)  /* complete event to wait fo
+                       SK_I2C_STOP(IoC);
+ #ifndef SK_DIAG
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
+-#endif        /* !SK_DIAG */
++#endif /* !SK_DIAG */
+                       return(1);
+               }
+               
+@@ -661,15 +669,19 @@ SK_IOC   IoC)    /* I/O Context */
+       }
+       StartTime = SkOsGetTime(pAC);
++      
+       do {
+               if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
++                      
+                       SK_I2C_STOP(IoC);
+ #ifndef SK_DIAG
+                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
+-#endif        /* !SK_DIAG */
++#endif /* !SK_DIAG */
+                       return;
+               }
++              
+               SK_IN32(IoC, B0_ISRC, &IrqSrc);
++
+       } while ((IrqSrc & IS_I2C_READY) == 0);
+       pSen->SenState = SK_SEN_IDLE;
+@@ -687,18 +699,19 @@ SK_AC    *pAC,           /* Adapter Context */
+ SK_IOC        IoC,            /* I/O Context */
+ SK_U32        I2cData,        /* I2C Data to write */
+ int           I2cDev,         /* I2C Device Address */
++int           I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
+ int           I2cReg,         /* I2C Device Register Address */
+ int           I2cBurst)       /* I2C Burst Flag */
+ {
+       SK_OUT32(IoC, B2_I2C_DATA, I2cData);
+-      SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst);
++      
++      SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
+       
+       return(SkI2cWait(pAC, IoC, I2C_WRITE));
+ }     /* SkI2cWrite*/
+ #ifdef        SK_DIAG
+-
+ /*
+  * reads a single byte or 4 bytes from the I2C device
+  *
+@@ -708,23 +721,24 @@ SK_U32 SkI2cRead(
+ SK_AC *pAC,           /* Adapter Context */
+ SK_IOC        IoC,            /* I/O Context */
+ int           I2cDev,         /* I2C Device Address */
++int           I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
+ int           I2cReg,         /* I2C Device Register Address */
+ int           I2cBurst)       /* I2C Burst Flag */
+ {
+       SK_U32  Data;
+       SK_OUT32(IoC, B2_I2C_DATA, 0);
+-      SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst);
++      SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
+       
+       if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
+               w_print("%s\n", SKERR_I2C_E002MSG);
+       }
+       
+       SK_IN32(IoC, B2_I2C_DATA, &Data);
++      
+       return(Data);
+ }     /* SkI2cRead */
+-
+-#endif        /* SK_DIAG */
++#endif /* SK_DIAG */
+ /*
+@@ -745,9 +759,10 @@ SK_SENSOR *pSen)  /* Sensor to be read */
+     if (pSen->SenRead != NULL) {
+         return((*pSen->SenRead)(pAC, IoC, pSen));
+     }
+-    else
++      else {
+         return(0); /* no success */
+-}     /* SkI2cReadSensor*/
++      }
++}     /* SkI2cReadSensor */
+ /*
+  * Do the Init state 0 initialization
+@@ -761,12 +776,12 @@ SK_AC    *pAC)   /* Adapter Context */
+       pAC->I2c.CurrSens = 0;
+       
+       /* Begin with timeout control for state machine */
+-      pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
++      pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
+       
+       /* Set sensor number to zero */
+       pAC->I2c.MaxSens = 0;
+-#ifndef       SK_DIAG
++#ifndef SK_DIAG
+       /* Initialize Number of Dummy Reads */
+       pAC->I2c.DummyReads = SK_MAX_SENSORS;
+ #endif
+@@ -840,19 +855,20 @@ SK_IOC   IoC)    /* I/O Context */
+     }
+       /* Check for 64 Bit Yukon without sensors */
+-      if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) {
++      if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) {
+         return(0);
+     }
+-      (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0);
++      (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
+       
+-      (void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0);
++      (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
+       
+-      (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0);
++      (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
+       
+-      (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0);
++      (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
+       
+-      (void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0);
++      (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
++              LM80_CFG, 0);
+       
+       /*
+        * MaxSens has to be updated here, because PhyType is not
+@@ -957,7 +973,7 @@ SK_IOC     IoC)    /* I/O Context */
+                               pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
+                       }
+                       else {
+-                              pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5";
++                              pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5";
+                               pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
+                               pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
+                               pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
+@@ -1015,9 +1031,9 @@ SK_IOC   IoC)    /* I/O Context */
+               pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
+       }
+-#ifndef       SK_DIAG
++#ifndef SK_DIAG
+       pAC->I2c.DummyReads = pAC->I2c.MaxSens;
+-#endif        /* !SK_DIAG */
++#endif /* !SK_DIAG */
+       
+       /* Clear I2C IRQ */
+       SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
+@@ -1208,15 +1224,13 @@ SK_SENSOR      *pSen)
+                       pSen->SenLastErrLogTS = CurrTime;
+                       if (pSen->SenType == SK_SEN_TEMP) {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011,
+-                                      SKERR_I2C_E011MSG);
+-                      } else if (pSen->SenType == SK_SEN_VOLT) {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012,
+-                                      SKERR_I2C_E012MSG);
+-                      } else
+-                      {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015,
+-                                      SKERR_I2C_E015MSG);
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
++                      }
++                      else if (pSen->SenType == SK_SEN_VOLT) {
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
++                      }
++                      else {
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
+                       }
+               }
+       }
+@@ -1235,8 +1249,7 @@ SK_SENSOR        *pSen)
+                       /* This state is the former one */
+                       /* So check first whether we have to send a trap */
+-                      if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD >
+-                          CurrTime) {
++                      if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
+                               /*
+                                * Do NOT send the Trap. The hold back time
+                                * has to run out first.
+@@ -1245,8 +1258,7 @@ SK_SENSOR        *pSen)
+                       }
+                       /* Check now whether we have to log an Error */
+-                      if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD >
+-                          CurrTime) {
++                      if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
+                               /*
+                                * Do NOT log the error. The hold back time
+                                * has to run out first.
+@@ -1277,15 +1289,13 @@ SK_SENSOR      *pSen)
+                       pSen->SenLastWarnLogTS = CurrTime;
+                       if (pSen->SenType == SK_SEN_TEMP) {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
+-                                      SKERR_I2C_E009MSG);
+-                      } else if (pSen->SenType == SK_SEN_VOLT) {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010,
+-                                      SKERR_I2C_E010MSG);
+-                      } else
+-                      {
+-                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014,
+-                                      SKERR_I2C_E014MSG);
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
++                      }
++                      else if (pSen->SenType == SK_SEN_VOLT) {
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
++                      }
++                      else {
++                              SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
+                       }
+               }
+       }
+@@ -1317,7 +1327,7 @@ SK_SENSOR        *pSen)
+               }
+       }
+       
+-#if 0
++#ifdef TEST_ONLY
+     /* Dynamic thresholds also for VAUX of LM80 sensor */
+       if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
+@@ -1359,7 +1369,7 @@ SK_SENSOR        *pSen)
+       if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
+               SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
+       }
+-}     /* SkI2cCheckSensor*/
++}     /* SkI2cCheckSensor */
+ /*
+@@ -1390,7 +1400,7 @@ SK_EVPARA        Para)   /* Event specific Parame
+               if (ReadComplete) {
+                       /* Check sensor against defined thresholds */
+-                      SkI2cCheckSensor (pAC, pSen);
++                      SkI2cCheckSensor(pAC, pSen);
+                       /* Increment Current sensor and set appropriate Timeout */
+                       pAC->I2c.CurrSens++;
+@@ -1414,7 +1424,7 @@ SK_EVPARA        Para)   /* Event specific Parame
+                       /* Start Timer */
+                       ParaLocal.Para64 = (SK_U64)0;
+-                      pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
++                      pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
+             SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
+                               SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
+@@ -1431,7 +1441,7 @@ SK_EVPARA        Para)   /* Event specific Parame
+                       if (ReadComplete) {
+                               /* Check sensor against defined thresholds */
+-                              SkI2cCheckSensor (pAC, pSen);
++                              SkI2cCheckSensor(pAC, pSen);
+                               /* Increment Current sensor and set appropriate Timeout */
+                               pAC->I2c.CurrSens++;
+@@ -1496,4 +1506,4 @@ SK_EVPARA        Para)   /* Event specific Parame
+       return(0);
+ }     /* SkI2cEvent*/
+-#endif        /* !SK_DIAG */
++#endif /* !SK_DIAG */
+--- linux-2.6.0/drivers/net/sk98lin/sklm80.c   2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/sklm80.c    2003-12-28 23:21:01.000000000 -0800
+@@ -1,16 +1,17 @@
+ /******************************************************************************
+  *
+  * Name:      sklm80.c
+- * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.20 $
+- * Date:      $Date: 2002/08/13 09:16:27 $
+- * Purpose:   Funktions to access Voltage and Temperature Sensor (LM80)
++ * Project:   Gigabit Ethernet Adapters, TWSI-Module
++ * Version:   $Revision: 1.22 $
++ * Date:      $Date: 2003/10/20 09:08:21 $
++ * Purpose:   Functions to access Voltage and Temperature Sensor (LM80)
+  *
+  ******************************************************************************/
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2002 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect.
++ *    (C)Copyright 2002-2003 Marvell.
+  *
+  *    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
+@@ -26,15 +27,21 @@
+  * History:
+  *
+  *    $Log: sklm80.c,v $
++ *    Revision 1.22  2003/10/20 09:08:21  rschmidt
++ *    Editorial changes.
++ *    
++ *    Revision 1.21  2003/09/23 09:29:04  malthoff
++ *    Parameter Dev_Size added to macro SK_I2C_CTL.
++ *    
+  *    Revision 1.20  2002/08/13 09:16:27  rschmidt
+  *    Changed return value for SkLm80ReadSensor() back to 'int'
+- *    Editorial changes
++ *    Editorial changes.
+  *    
+  *    Revision 1.19  2002/08/06 09:43:31  jschmalz
+- *    Extensions and changes for Yukon
++ *    Extensions and changes for Yukon.
+  *    
+  *    Revision 1.18  2002/08/02 12:26:57  rschmidt
+- *    Editorial changes
++ *    Editorial changes.
+  *    
+  *    Revision 1.17  1999/11/22 13:35:51  cgoos
+  *    Changed license header to GPL.
+@@ -93,16 +100,15 @@
+  *    Revision 1.1  1998/07/17 09:57:12  gklug
+  *    initial version
+  *
+- *
+- *
+  ******************************************************************************/
+-
+ /*
+       LM80 functions
+ */
++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "$Id: sklm80.c,v 1.20 2002/08/13 09:16:27 rschmidt Exp $" ;
++      "@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. ";
++#endif
+ #include "h/skdrv1st.h"               /* Driver Specific Definitions */
+ #include "h/lm80.h"
+@@ -202,7 +208,7 @@ SK_SENSOR  *pSen)  /* Sensor to be read */
+       switch (pSen->SenState) {
+       case SK_SEN_IDLE:
+               /* Send address to ADDR register */
+-              SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, pSen->SenReg, 0);
++              SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0);
+               pSen->SenState = SK_SEN_VALUE ;
+               BREAK_OR_WAIT(pAC, IoC, I2C_READ);
+@@ -250,7 +256,7 @@ SK_SENSOR  *pSen)  /* Sensor to be read */
+                       (pSen->SenValue % SK_LM80_TEMP_LSB);
+               /* Send address to ADDR register */
+-              SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, LM80_TEMP_CTRL, 0);
++              SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
+               pSen->SenState = SK_SEN_VALEXT ;
+               BREAK_OR_WAIT(pAC, IoC, I2C_READ);
+@@ -284,3 +290,4 @@ SK_SENSOR  *pSen)  /* Sensor to be read */
+       /* Not completed */
+       return(0);
+ }
++
+--- linux-2.6.0/drivers/net/sk98lin/skproc.c   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/sk98lin/skproc.c    2003-12-28 23:21:01.000000000 -0800
+@@ -1,16 +1,17 @@
+ /******************************************************************************
+  *
+- * Name:    skproc.c
++ * Name:      skproc.c
+  * Project:   GEnesis, PCI Gigabit Ethernet Adapter
+- * Version:   $Revision: 1.2 $
+- * Date:    $Date: 2003/08/12 16:45:29 $
++ * Version:   $Revision: 1.11 $
++ * Date:      $Date: 2003/12/11 16:03:57 $
+  * Purpose:   Funktions to display statictic data
+  *
+  ******************************************************************************/
+  
+ /******************************************************************************
+  *
+- *    (C)Copyright 1998-2003 SysKonnect GmbH.
++ *    (C)Copyright 1998-2002 SysKonnect GmbH.
++ *    (C)Copyright 2002-2003 Marvell.
+  *
+  *    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
+@@ -28,6 +29,33 @@
+  * History:
+  *
+  *    $Log: skproc.c,v $
++ *    Revision 1.11  2003/12/11 16:03:57  mlindner
++ *    Fix: Create backup from pnmi data structure
++ *    
++ *    Revision 1.10  2003/11/19 16:25:36  mlindner
++ *    Fix: Print output as 64-bit digit
++ *    
++ *    Revision 1.9  2003/11/17 13:29:05  mlindner
++ *    Fix: Editorial changes
++ *    
++ *    Revision 1.8  2003/11/13 14:18:48  rroesler
++ *    Fix: added latest changes regarding the use of the proc system
++ *    
++ *    Revision 1.7  2003/11/10 09:35:07  rroesler
++ *    Fix: diag backup restore of PNMI structure
++ *    
++ *    Revision 1.6  2003/11/07 17:31:39  rroesler
++ *    Add: security counter for the proc file system
++ *    
++ *    Revision 1.5  2003/10/07 08:17:08  mlindner
++ *    Fix: Copyright changes
++ *    
++ *    Revision 1.4  2003/09/01 15:29:24  mlindner
++ *    Fix: Editorial changes
++ *    
++ *    Revision 1.3  2003/08/29 12:30:58  mlindner
++ *    Add: Version entry in the proc file system
++ *    
+  *    Revision 1.2  2003/08/12 16:45:29  mlindner
+  *    Add: Removed SkNumber and SkDoDiv
+  *    Add: Counter output as (unsigned long long)
+@@ -94,223 +122,350 @@
+ #include "h/skdrv1st.h"
+ #include "h/skdrv2nd.h"
++#include "h/skversion.h"
+-#ifdef CONFIG_PROC_FS
++extern struct SK_NET_DEVICE *SkGeRootDev;
++static int sk_proc_print(void *writePtr, char *format, ...);
++static void sk_gen_browse(void *buffer);
++int len;
+-extern struct net_device      *SkGeRootDev;
++static int sk_seq_show(struct seq_file *seq, void *v);
++static int sk_proc_open(struct inode *inode, struct file *file);
++struct file_operations sk_proc_fops = {
++      .owner          = THIS_MODULE,
++      .open           = sk_proc_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = single_release,
++};
++struct net_device *currDev = NULL;
+-static int sk_seq_show(struct seq_file *seq, void *v)
++/*****************************************************************************
++ *
++ *    sk_gen_browse -generic  print "summaries" entry 
++ *
++ * Description:
++ *  This function fills the proc entry with statistic data about 
++ *  the ethernet device.
++ *  
++ * Returns: -
++ *    
++ */
++static void sk_gen_browse(void *buffer)
+ {
+-      struct net_device *dev = seq->private;
+-      DEV_NET         *pNet = dev->priv;
+-      SK_AC           *pAC = pNet->pAC;
+-      SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
+-      SK_PNMI_STAT    *pPnmiStat = &pPnmiStruct->Stat[0];
+-      int unit = !(pAC->dev[0] == dev);
+-      int i;
+-      char sens_msg[50];
+-
+-      seq_printf(seq,
+-                 "\nDetailed statistic for device %s\n",
+-                 dev->name);
+-      seq_printf(seq,
+-                 "=======================================\n");
+-      
+-      /* Board statistics */
+-      seq_printf(seq, 
+-                 "\nBoard statistics\n\n");
+-      seq_printf(seq,
+-                 "Active Port                    %c\n",
+-                 'A' + pAC->Rlmt.Net[unit].Port[pAC->Rlmt.
+-                                               Net[unit].PrefPort]->PortNumber);
+-      seq_printf(seq,
+-                 "Preferred Port                 %c\n",
+-                 'A' + pAC->Rlmt.Net[unit].Port[pAC->Rlmt.
+-                                               Net[unit].PrefPort]->PortNumber);
+-
+-      seq_printf(seq,
+-                 "Bus speed (MHz)                %d\n",
+-                 pPnmiStruct->BusSpeed);
+-
+-      seq_printf(seq,
+-                 "Bus width (Bit)                %d\n",
+-                 pPnmiStruct->BusWidth);
+-      seq_printf(seq,
+-                 "Hardware revision              v%d.%d\n",
+-                 (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
+-                 pAC->GIni.GIPciHwRev & 0x0F);
+-
+-      /* Print sensor informations */
+-      for (i=0; i < pAC->I2c.MaxSens; i ++) {
+-              /* Check type */
+-              switch (pAC->I2c.SenTable[i].SenType) {
+-              case 1:
+-                      strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+-                      strcat(sens_msg, " (C)");
+-                      seq_printf(seq,
+-                                 "%-25s      %d.%02d\n",
+-                                 sens_msg,
+-                                 pAC->I2c.SenTable[i].SenValue / 10,
+-                                 pAC->I2c.SenTable[i].SenValue % 10);
+-
+-                      strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+-                      strcat(sens_msg, " (F)");
+-                      seq_printf(seq,
+-                                 "%-25s      %d.%02d\n",
+-                                 sens_msg,
+-                                 ((((pAC->I2c.SenTable[i].SenValue)
+-                                    *10)*9)/5 + 3200)/100,
+-                                 ((((pAC->I2c.SenTable[i].SenValue)
+-                                    *10)*9)/5 + 3200) % 10);
+-                      break;
+-              case 2:
+-                      strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+-                      strcat(sens_msg, " (V)");
+-                      seq_printf(seq,
+-                                 "%-25s      %d.%03d\n",
+-                                 sens_msg,
+-                                 pAC->I2c.SenTable[i].SenValue / 1000,
+-                                 pAC->I2c.SenTable[i].SenValue % 1000);
+-                      break;
+-              case 3:
+-                      strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
+-                      strcat(sens_msg, " (rpm)");
+-                      seq_printf(seq,
+-                                 "%-25s      %d\n",
+-                                 sens_msg,
+-                                 pAC->I2c.SenTable[i].SenValue);
+-                      break;
+-              default:
+-                      break;
++      struct SK_NET_DEVICE    *SkgeProcDev = SkGeRootDev;
++      struct SK_NET_DEVICE    *next;
++      SK_PNMI_STRUCT_DATA     *pPnmiStruct;
++      SK_PNMI_STAT            *pPnmiStat;
++      unsigned long           Flags;  
++      unsigned int            Size;
++      DEV_NET                 *pNet;
++      SK_AC                   *pAC;
++      char                    sens_msg[50];
++      int                     MaxSecurityCount = 0;
++      int                     t;
++      int                     i;
++
++      while (SkgeProcDev) {
++              MaxSecurityCount++;
++              if (MaxSecurityCount > 100) {
++                      printk("Max limit for sk_proc_read security counter!\n");
++                      return;
+               }
+-      }
++              pNet = (DEV_NET*) SkgeProcDev->priv;
++              pAC = pNet->pAC;
++              next = pAC->Next;
++              pPnmiStruct = &pAC->PnmiStruct;
++              /* NetIndex in GetStruct is now required, zero is only dummy */
++
++              for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
++                      if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
++                              t--;
++
++                      spin_lock_irqsave(&pAC->SlowPathLock, Flags);
++                      Size = SK_PNMI_STRUCT_SIZE;
++#ifdef SK_DIAG_SUPPORT
++                      if (pAC->BoardLevel == SK_INIT_DATA) {
++                              SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
++                              if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
++                                      pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
++                              }
++                      } else {
++                              SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
++                      }
++#else
++                      SkPnmiGetStruct(pAC, pAC->IoBase, 
++                              pPnmiStruct, &Size, t-1);
++#endif
++                      spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
++      
++                      if (strcmp(pAC->dev[t-1]->name, currDev->name) == 0) {
++                              pPnmiStat = &pPnmiStruct->Stat[0];
++                              len = sk_proc_print(buffer, 
++                                      "\nDetailed statistic for device %s\n",
++                                      pAC->dev[t-1]->name);
++                              len += sk_proc_print(buffer,
++                                      "=======================================\n");
++      
++                              /* Board statistics */
++                              len += sk_proc_print(buffer, 
++                                      "\nBoard statistics\n\n");
++                              len += sk_proc_print(buffer,
++                                      "Active Port                    %c\n",
++                                      'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
++                                      Net[t-1].PrefPort]->PortNumber);
++                              len += sk_proc_print(buffer,
++                                      "Preferred Port                 %c\n",
++                                      'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
++                                      Net[t-1].PrefPort]->PortNumber);
++
++                              len += sk_proc_print(buffer,
++                                      "Bus speed (MHz)                %d\n",
++                                      pPnmiStruct->BusSpeed);
++
++                              len += sk_proc_print(buffer,
++                                      "Bus width (Bit)                %d\n",
++                                      pPnmiStruct->BusWidth);
++                              len += sk_proc_print(buffer,
++                                      "Driver version                 %s\n",
++                                      VER_STRING);
++                              len += sk_proc_print(buffer,
++                                      "Hardware revision              v%d.%d\n",
++                                      (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
++                                      pAC->GIni.GIPciHwRev & 0x0F);
++
++                              /* Print sensor informations */
++                              for (i=0; i < pAC->I2c.MaxSens; i ++) {
++                                      /* Check type */
++                                      switch (pAC->I2c.SenTable[i].SenType) {
++                                      case 1:
++                                              strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
++                                              strcat(sens_msg, " (C)");
++                                              len += sk_proc_print(buffer,
++                                                      "%-25s      %d.%02d\n",
++                                                      sens_msg,
++                                                      pAC->I2c.SenTable[i].SenValue / 10,
++                                                      pAC->I2c.SenTable[i].SenValue % 10);
++
++                                              strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
++                                              strcat(sens_msg, " (F)");
++                                              len += sk_proc_print(buffer,
++                                                      "%-25s      %d.%02d\n",
++                                                      sens_msg,
++                                                      ((((pAC->I2c.SenTable[i].SenValue)
++                                                      *10)*9)/5 + 3200)/100,
++                                                      ((((pAC->I2c.SenTable[i].SenValue)
++                                                      *10)*9)/5 + 3200) % 10);
++                                              break;
++                                      case 2:
++                                              strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
++                                              strcat(sens_msg, " (V)");
++                                              len += sk_proc_print(buffer,
++                                                      "%-25s      %d.%03d\n",
++                                                      sens_msg,
++                                                      pAC->I2c.SenTable[i].SenValue / 1000,
++                                                      pAC->I2c.SenTable[i].SenValue % 1000);
++                                              break;
++                                      case 3:
++                                              strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
++                                              strcat(sens_msg, " (rpm)");
++                                              len += sk_proc_print(buffer,
++                                                      "%-25s      %d\n",
++                                                      sens_msg,
++                                                      pAC->I2c.SenTable[i].SenValue);
++                                              break;
++                                      default:
++                                              break;
++                                      }
++                              }
+                               
+-      /*Receive statistics */
+-      seq_printf(seq, 
+-                 "\nReceive statistics\n\n");
+-
+-      seq_printf(seq,
+-                 "Received bytes                 %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
+-      seq_printf(seq,
+-                 "Received packets               %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxOkCts);
++                              /*Receive statistics */
++                              len += sk_proc_print(buffer, 
++                              "\nReceive statistics\n\n");
++
++                              len += sk_proc_print(buffer,
++                                      "Received bytes                 %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
++                              len += sk_proc_print(buffer,
++                                      "Received packets               %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxOkCts);
+ #if 0
+-      if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && 
+-          pAC->HWRevision < 12) {
+-              pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - 
+-                      pPnmiStat->StatRxShortsCts;
+-              pPnmiStat->StatRxShortsCts = 0;
+-      }
++                              if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && 
++                                      pAC->HWRevision < 12) {
++                                      pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - 
++                                              pPnmiStat->StatRxShortsCts;
++                                      pPnmiStat->StatRxShortsCts = 0;
++                              }
+ #endif
+-      if (pNet->Mtu > 1500) 
+-              pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
+-                      pPnmiStat->StatRxTooLongCts;
+-
+-      seq_printf(seq,
+-                 "Receive errors                 %Ld\n",
+-                 (unsigned long long) pPnmiStruct->InErrorsCts);
+-      seq_printf(seq,
+-                 "Receive dropped                %Ld\n",
+-                 (unsigned long long) pPnmiStruct->RxNoBufCts);
+-      seq_printf(seq,
+-                 "Received multicast             %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
+-      seq_printf(seq,
+-                 "Receive error types\n");
+-      seq_printf(seq,
+-                 "   length                      %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxRuntCts);
+-      seq_printf(seq,
+-                 "   buffer overflow             %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
+-      seq_printf(seq,
+-                 "   bad crc                     %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxFcsCts);
+-      seq_printf(seq,
+-                 "   framing                     %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxFramingCts);
+-      seq_printf(seq,
+-                 "   missed frames               %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxMissedCts);
+-
+-      if (pNet->Mtu > 1500)
+-              pPnmiStat->StatRxTooLongCts = 0;
+-
+-      seq_printf(seq,
+-                 "   too long                    %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxTooLongCts);                                   
+-      seq_printf(seq,
+-                 "   carrier extension           %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxCextCts);                              
+-      seq_printf(seq,
+-                 "   too short                   %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxShortsCts);                            
+-      seq_printf(seq,
+-                 "   symbol                      %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxSymbolCts);                            
+-      seq_printf(seq,
+-                 "   LLC MAC size                %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxIRLengthCts);                          
+-      seq_printf(seq,
+-                 "   carrier event               %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxCarrierCts);                           
+-      seq_printf(seq,
+-                 "   jabber                      %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatRxJabberCts);                            
+-
+-
+-      /*Transmit statistics */
+-      seq_printf(seq, 
+-                 "\nTransmit statistics\n\n");
++                              if (pNet->Mtu > 1500) 
++                                      pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
++                                              pPnmiStat->StatRxTooLongCts;
++
++                              len += sk_proc_print(buffer,
++                                      "Receive errors                 %Lu\n",
++                                      (unsigned long long) pPnmiStruct->InErrorsCts);
++                              len += sk_proc_print(buffer,
++                                      "Receive dropped                %Lu\n",
++                                      (unsigned long long) pPnmiStruct->RxNoBufCts);
++                              len += sk_proc_print(buffer,
++                                      "Received multicast             %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
++                              len += sk_proc_print(buffer,
++                                      "Receive error types\n");
++                              len += sk_proc_print(buffer,
++                                      "   length                      %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxRuntCts);
++                              len += sk_proc_print(buffer,
++                                      "   buffer overflow             %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
++                              len += sk_proc_print(buffer,
++                                      "   bad crc                     %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxFcsCts);
++                              len += sk_proc_print(buffer,
++                                      "   framing                     %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxFramingCts);
++                              len += sk_proc_print(buffer,
++                                      "   missed frames               %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxMissedCts);
++
++                              if (pNet->Mtu > 1500)
++                                      pPnmiStat->StatRxTooLongCts = 0;
++
++                              len += sk_proc_print(buffer,
++                                      "   too long                    %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxTooLongCts);                                      
++                              len += sk_proc_print(buffer,
++                                      "   carrier extension           %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxCextCts);                         
++                              len += sk_proc_print(buffer,
++                                      "   too short                   %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxShortsCts);                               
++                              len += sk_proc_print(buffer,
++                                      "   symbol                      %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxSymbolCts);                               
++                              len += sk_proc_print(buffer,
++                                      "   LLC MAC size                %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxIRLengthCts);                             
++                              len += sk_proc_print(buffer,
++                                      "   carrier event               %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxCarrierCts);                              
++                              len += sk_proc_print(buffer,
++                                      "   jabber                      %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatRxJabberCts);                               
++
++
++                              /*Transmit statistics */
++                              len += sk_proc_print(buffer, 
++                              "\nTransmit statistics\n\n");
+                               
+-      seq_printf(seq,
+-                 "Transmited bytes               %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
+-      seq_printf(seq,
+-                 "Transmited packets             %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatTxOkCts);
+-      seq_printf(seq,
+-                 "Transmit errors                %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
+-      seq_printf(seq,
+-                 "Transmit dropped               %Ld\n",
+-                 (unsigned long long) pPnmiStruct->TxNoBufCts);
+-      seq_printf(seq,
+-                 "Transmit collisions            %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
+-      seq_printf(seq,
+-                 "Transmit error types\n");
+-      seq_printf(seq,
+-                 "   excessive collision         %ld\n",
+-                 pAC->stats.tx_aborted_errors);
+-      seq_printf(seq,
+-                 "   carrier                     %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatTxCarrierCts);
+-      seq_printf(seq,
+-                 "   fifo underrun               %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
+-      seq_printf(seq,
+-                 "   heartbeat                   %Ld\n",
+-                 (unsigned long long) pPnmiStat->StatTxCarrierCts);
+-      seq_printf(seq,
+-                 "   window                      %ld\n",
+-                 pAC->stats.tx_window_errors);
++                              len += sk_proc_print(buffer,
++                                      "Transmited bytes               %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
++                              len += sk_proc_print(buffer,
++                                      "Transmited packets             %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatTxOkCts);
++                              len += sk_proc_print(buffer,
++                                      "Transmit errors                %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
++                              len += sk_proc_print(buffer,
++                                      "Transmit dropped               %Lu\n",
++                                      (unsigned long long) pPnmiStruct->TxNoBufCts);
++                              len += sk_proc_print(buffer,
++                                      "Transmit collisions            %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
++                              len += sk_proc_print(buffer,
++                                      "Transmit error types\n");
++                              len += sk_proc_print(buffer,
++                                      "   excessive collision         %ld\n",
++                                      pAC->stats.tx_aborted_errors);
++                              len += sk_proc_print(buffer,
++                                      "   carrier                     %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatTxCarrierCts);
++                              len += sk_proc_print(buffer,
++                                      "   fifo underrun               %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
++                              len += sk_proc_print(buffer,
++                                      "   heartbeat                   %Lu\n",
++                                      (unsigned long long) pPnmiStat->StatTxCarrierCts);
++                              len += sk_proc_print(buffer,
++                                      "   window                      %ld\n",
++                                      pAC->stats.tx_window_errors);
+                               
+-      return 0;
++                      } /* if (strcmp(pACname, currDeviceName) == 0) */
++              }
++              SkgeProcDev = next;
++      }
+ }
++/*****************************************************************************
++ *
++ *      sk_proc_print -generic line print  
++ *
++ * Description:
++ *  This function fills the proc entry with statistic data about 
++ *  the ethernet device.
++ *  
++ * Returns: number of bytes written
++ *      
++ */ 
++static int sk_proc_print(void *writePtr, char *format, ...)
++{   
++#define MAX_LEN_SINGLE_LINE 256
++      char     str[MAX_LEN_SINGLE_LINE];
++      va_list  a_start;
++      int      lenght = 0;
++
++      struct seq_file *seq = (struct seq_file *) writePtr;
++
++      SK_MEMSET(str, 0, MAX_LEN_SINGLE_LINE);
++
++      va_start(a_start, format);
++      vsprintf(str, format, a_start);
++      va_end(a_start);
++
++      lenght = strlen(str);
++      seq_printf(seq, str);
++      return lenght;
++}
++
++/*****************************************************************************
++ *
++ *      sk_seq_show - show proc information of a particular adapter
++ *
++ * Description:
++ *  This function fills the proc entry with statistic data about 
++ *  the ethernet device. It invokes the generic sk_gen_browse() to
++ *  print out all items one per one.
++ *  
++ * Returns: number of bytes written
++ *      
++ */
++static int sk_seq_show(struct seq_file *seq, void *v)
++{
++    void *castedBuffer = (void *) seq;
++    currDev = seq->private;
++    sk_gen_browse(castedBuffer);
++    return 0;
++}
++
++/*****************************************************************************
++ *
++ *      sk_proc_open - register the show function when proc is open'ed
++ *  
++ * Description:
++ *  This function is called whenever a sk98lin proc file is queried.
++ *  
++ * Returns: the return value of single_open()
++ *      
++ */
+ static int sk_proc_open(struct inode *inode, struct file *file)
+ {
+-      return single_open(file, sk_seq_show, PDE(inode)->data);
++    return single_open(file, sk_seq_show, PDE(inode)->data);
+ }
+-struct file_operations sk_proc_fops = {
+-      .owner = THIS_MODULE,
+-      .open  = sk_proc_open,
+-      .read  = seq_read,
+-      .llseek = seq_lseek,
+-      .release = single_release,
+-};
+-#endif
++/*******************************************************************************
++ *
++ * End of file
++ *
++ ******************************************************************************/
+--- linux-2.6.0/drivers/net/sk98lin/skqueue.c  2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/skqueue.c   2003-12-28 23:21:01.000000000 -0800
+@@ -1,9 +1,9 @@
+ /******************************************************************************
+  *
+  * Name:      skqueue.c
+- * Project:   Gigabit Ethernet Adapters, Schedule-Modul
+- * Version:   $Revision: 1.19 $
+- * Date:      $Date: 2003/05/13 18:00:07 $
++ * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
++ * Version:   $Revision: 1.20 $
++ * Date:      $Date: 2003/09/16 13:44:00 $
+  * Purpose:   Management of an event queue.
+  *
+  ******************************************************************************/
+@@ -27,6 +27,10 @@
+  * History:
+  *
+  *    $Log: skqueue.c,v $
++ *    Revision 1.20  2003/09/16 13:44:00  rschmidt
++ *    Added (C) Marvell to SysKonnectFileId
++ *    Editorial changes
++ *    
+  *    Revision 1.19  2003/05/13 18:00:07  mkarl
+  *    Removed calls to RLMT, TWSI, and PNMI for SLIM driver (SK_SLIM).
+  *    Editorial changes.
+@@ -85,18 +89,16 @@
+  *    
+  *    Revision 1.1  1998/07/30 15:14:01  gklug
+  *    Initial version. Adapted from SMT
+- *    
+- *    
+  *
+  ******************************************************************************/
+ /*
+-      Event queue and dispatcher
+-*/
++ *    Event queue and dispatcher
++ */
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "$Header: /usr56/projects/ge/schedule/skqueue.c,v 1.19 2003/05/13 18:00:07 mkarl Exp $" ;
++      "@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell.";
+ #endif
+ #include "h/skdrv1st.h"               /* Driver Specific Definitions */
+@@ -124,11 +126,11 @@ intro()
+ void  SkEventInit(
+ SK_AC *pAC,   /* Adapter context */
+ SK_IOC        Ioc,    /* IO context */
+-int   Level)  /* Init level */
++int           Level)  /* Init level */
+ {
+       switch (Level) {
+       case SK_INIT_DATA:
+-              pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue ;
++              pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue;
+               break;
+       default:
+               break;
+@@ -144,14 +146,15 @@ SK_U32           Class,  /* Event Class */
+ SK_U32                Event,  /* Event to be queued */
+ SK_EVPARA     Para)   /* Event parameter */
+ {
+-      pAC->Event.EvPut->Class = Class ;
+-      pAC->Event.EvPut->Event = Event ;
+-      pAC->Event.EvPut->Para = Para ;
++      pAC->Event.EvPut->Class = Class;
++      pAC->Event.EvPut->Event = Event;
++      pAC->Event.EvPut->Para = Para;
++      
+       if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
+-              pAC->Event.EvPut = pAC->Event.EvQueue ;
++              pAC->Event.EvPut = pAC->Event.EvQueue;
+       if (pAC->Event.EvPut == pAC->Event.EvGet) {
+-              SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG) ;
++              SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG);
+       }
+ }
+@@ -168,77 +171,79 @@ int      SkEventDispatcher(
+ SK_AC *pAC,   /* Adapters Context */
+ SK_IOC        Ioc)    /* Io context */
+ {
+-      SK_EVENTELEM    *pEv ;  /* pointer into queue */
+-      SK_U32                  Class ;
+-      int                     Rtv ;
+-
+-      pEv = pAC->Event.EvGet ;
+-      PRINTF("dispatch get %x put %x\n",pEv,pAC->Event.ev_put) ;
++      SK_EVENTELEM    *pEv;   /* pointer into queue */
++      SK_U32                  Class;
++      int                     Rtv;
++
++      pEv = pAC->Event.EvGet;
++      
++      PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put);
++      
+       while (pEv != pAC->Event.EvPut) {
+-              PRINTF("dispatch Class %d Event %d\n",pEv->Class,pEv->Event) ;
+-              switch(Class = pEv->Class) {
++              PRINTF("dispatch Class %d Event %d\n", pEv->Class, pEv->Event);
++
++              switch (Class = pEv->Class) {
+ #ifndef SK_USE_LAC_EV
+ #ifndef SK_SLIM
+-              case SKGE_RLMT :        /* RLMT Event */
+-                      Rtv = SkRlmtEvent(pAC,Ioc,pEv->Event,pEv->Para);
+-                      break ;
+-              case SKGE_I2C :         /* I2C Event */
+-                      Rtv = SkI2cEvent(pAC,Ioc,pEv->Event,pEv->Para);
+-                      break ;
+-              case SKGE_PNMI :
+-                      Rtv = SkPnmiEvent(pAC,Ioc,pEv->Event,pEv->Para);
+-                      break ;
++              case SKGE_RLMT:         /* RLMT Event */
++                      Rtv = SkRlmtEvent(pAC, Ioc, pEv->Event, pEv->Para);
++                      break;
++              case SKGE_I2C:          /* I2C Event */
++                      Rtv = SkI2cEvent(pAC, Ioc, pEv->Event, pEv->Para);
++                      break;
++              case SKGE_PNMI:         /* PNMI Event */
++                      Rtv = SkPnmiEvent(pAC, Ioc, pEv->Event, pEv->Para);
++                      break;
+ #endif        /* not SK_SLIM */
+ #endif        /* not SK_USE_LAC_EV */
+-              case SKGE_DRV :         /* Driver Event */
+-                      Rtv = SkDrvEvent(pAC,Ioc,pEv->Event,pEv->Para);
+-                      break ;
+-#ifndef SK_USE_SW_TIMER        
+-              case SKGE_HWAC :
+-                      Rtv = SkGeSirqEvent(pAC,Ioc,pEv->Event,pEv->Para);
+-                      break ;
++              case SKGE_DRV:          /* Driver Event */
++                      Rtv = SkDrvEvent(pAC, Ioc, pEv->Event, pEv->Para);
++                      break;
++#ifndef SK_USE_SW_TIMER
++              case SKGE_HWAC:
++                      Rtv = SkGeSirqEvent(pAC, Ioc, pEv->Event, pEv->Para);
++                      break;
+ #else /* !SK_USE_SW_TIMER */
+-        case SKGE_SWT : 
+-                      Rtv = SkSwtEvent(pAC,Ioc,pEv->Event,pEv->Para);
+-                      break ;
++        case SKGE_SWT :
++                      Rtv = SkSwtEvent(pAC, Ioc, pEv->Event, pEv->Para);
++                      break;
+ #endif /* !SK_USE_SW_TIMER */
+-#ifdef SK_USE_LAC_EV        
++#ifdef SK_USE_LAC_EV
+               case SKGE_LACP :
+-                      Rtv = SkLacpEvent(pAC,Ioc,pEv->Event,pEv->Para);
+-                      break ;
++                      Rtv = SkLacpEvent(pAC, Ioc, pEv->Event, pEv->Para);
++                      break;
+               case SKGE_RSF :
+-                      Rtv = SkRsfEvent(pAC,Ioc,pEv->Event,pEv->Para);
+-                      break ;
++                      Rtv = SkRsfEvent(pAC, Ioc, pEv->Event, pEv->Para);
++                      break;
+               case SKGE_MARKER :
+-                      Rtv = SkMarkerEvent(pAC,Ioc,pEv->Event,pEv->Para);
+-                      break ;
++                      Rtv = SkMarkerEvent(pAC, Ioc, pEv->Event, pEv->Para);
++                      break;
+               case SKGE_FD :
+-                      Rtv = SkFdEvent(pAC,Ioc,pEv->Event,pEv->Para);
+-                      break ;
++                      Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para);
++                      break;
+ #endif /* SK_USE_LAC_EV */
+ #ifdef        SK_USE_CSUM
+               case SKGE_CSUM :
+-                      Rtv = SkCsEvent(pAC,Ioc,pEv->Event,pEv->Para);
+-                      break ;
++                      Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para);
++                      break;
+ #endif        /* SK_USE_CSUM */
+               default :
+-                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002,
+-                              SKERR_Q_E002MSG) ;
++                      SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, SKERR_Q_E002MSG);
+                       Rtv = 0;
+               }
+               if (Rtv != 0) {
+-                      return(Rtv) ;
++                      return(Rtv);
+               }
+               if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT])
+-                      pEv = pAC->Event.EvQueue ;
++                      pEv = pAC->Event.EvQueue;
+               /* Renew get: it is used in queue_events to detect overruns */
+               pAC->Event.EvGet = pEv;
+       }
+-      return(0) ;
++      return(0);
+ }
+ /* End of file */
+--- linux-2.6.0/drivers/net/sk98lin/sktimer.c  2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/sktimer.c   2003-12-28 23:21:01.000000000 -0800
+@@ -1,9 +1,9 @@
+ /******************************************************************************
+  *
+  * Name:      sktimer.c
+- * Project:   Gigabit Ethernet Adapters, Schedule-Modul
+- * Version:   $Revision: 1.13 $
+- * Date:      $Date: 2003/05/13 18:01:01 $
++ * Project:   Gigabit Ethernet Adapters, Event Scheduler Module
++ * Version:   $Revision: 1.14 $
++ * Date:      $Date: 2003/09/16 13:46:51 $
+  * Purpose:   High level timer functions.
+  *
+  ******************************************************************************/
+@@ -27,6 +27,10 @@
+  * History:
+  *
+  *    $Log: sktimer.c,v $
++ *    Revision 1.14  2003/09/16 13:46:51  rschmidt
++ *    Added (C) Marvell to SysKonnectFileId
++ *    Editorial changes
++ *    
+  *    Revision 1.13  2003/05/13 18:01:01  mkarl
+  *    Editorial changes.
+  *    
+@@ -68,19 +72,16 @@
+  *    
+  *    Revision 1.1  1998/08/05 11:27:55  gklug
+  *    first version: adapted from SMT
+- *    
+- *    
+- *    
+  *
+  ******************************************************************************/
+ /*
+-      Event queue and dispatcher
+-*/
++ *    Event queue and dispatcher
++ */
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.13 2003/05/13 18:01:01 mkarl Exp $" ;
++      "@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell.";
+ #endif
+ #include "h/skdrv1st.h"               /* Driver Specific Definitions */
+@@ -110,14 +111,14 @@ static void timer_done(SK_AC *pAC,SK_IOC
+ void  SkTimerInit(
+ SK_AC *pAC,           /* Adapters context */
+ SK_IOC        Ioc,            /* IoContext */
+-int   Level)          /* Init Level */
++int           Level)          /* Init Level */
+ {
+       switch (Level) {
+       case SK_INIT_DATA:
+-              pAC->Tim.StQueue = 0 ;
++              pAC->Tim.StQueue = 0;
+               break;
+       case SK_INIT_IO:
+-              SkHwtInit(pAC,Ioc) ;
++              SkHwtInit(pAC, Ioc);
+               SkTimerDone(pAC, Ioc);
+               break;
+       default:
+@@ -134,31 +135,34 @@ SK_AC            *pAC,           /* Adapters context */
+ SK_IOC                Ioc,            /* IoContext */
+ SK_TIMER      *pTimer)        /* Timer Pointer to be started */
+ {
+-      SK_TIMER        **ppTimPrev ;
+-      SK_TIMER        *pTm ;
++      SK_TIMER        **ppTimPrev;
++      SK_TIMER        *pTm;
+       /*
+        * remove timer from queue
+        */
+-      pTimer->TmActive = SK_FALSE ;
++      pTimer->TmActive = SK_FALSE;
++      
+       if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
+-              SkHwtStop(pAC,Ioc) ;
++              SkHwtStop(pAC, Ioc);
+       }
+-      for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ;
++      
++      for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
+               ppTimPrev = &pTm->TmNext ) {
++              
+               if (pTm == pTimer) {
+                       /*
+                        * Timer found in queue
+                        * - dequeue it and
+                        * - correct delta of the next timer
+                        */
+-                      *ppTimPrev = pTm->TmNext ;
++                      *ppTimPrev = pTm->TmNext;
+                       if (pTm->TmNext) {
+                               /* correct delta of next timer in queue */
+-                              pTm->TmNext->TmDelta += pTm->TmDelta ;
++                              pTm->TmNext->TmDelta += pTm->TmDelta;
+                       }
+-                      return ;
++                      return;
+               }
+       }
+ }
+@@ -175,65 +179,67 @@ SK_U32           Class,          /* Event Class for this 
+ SK_U32                Event,          /* Event Value for this timer */
+ SK_EVPARA     Para)           /* Event Parameter for this timer */
+ {
+-      SK_TIMER        **ppTimPrev ;
+-      SK_TIMER        *pTm ;
+-      SK_U32          Delta ;
++      SK_TIMER        **ppTimPrev;
++      SK_TIMER        *pTm;
++      SK_U32          Delta;
+-      Time /= 16 ;            /* input is uS, clock ticks are 16uS */
++      Time /= 16;             /* input is uS, clock ticks are 16uS */
++      
+       if (!Time)
+-              Time = 1 ;
++              Time = 1;
+-      SkTimerStop(pAC,Ioc,pTimer) ;
++      SkTimerStop(pAC, Ioc, pTimer);
+-      pTimer->TmClass = Class ;
+-      pTimer->TmEvent = Event ;
+-      pTimer->TmPara = Para ;
+-      pTimer->TmActive = SK_TRUE ;
++      pTimer->TmClass = Class;
++      pTimer->TmEvent = Event;
++      pTimer->TmPara = Para;
++      pTimer->TmActive = SK_TRUE;
+       if (!pAC->Tim.StQueue) {
+               /* First Timer to be started */
+-              pAC->Tim.StQueue = pTimer ;
+-              pTimer->TmNext = 0 ;
+-              pTimer->TmDelta = Time ;
+-              SkHwtStart(pAC,Ioc,Time) ;
+-              return ;
++              pAC->Tim.StQueue = pTimer;
++              pTimer->TmNext = 0;
++              pTimer->TmDelta = Time;
++              
++              SkHwtStart(pAC, Ioc, Time);
++              
++              return;
+       }
+       /*
+        * timer correction
+        */
+-      timer_done(pAC,Ioc,0) ;
++      timer_done(pAC, Ioc, 0);
+       /*
+        * find position in queue
+        */
+-      Delta = 0 ;
+-      for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ;
++      Delta = 0;
++      for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
+               ppTimPrev = &pTm->TmNext ) {
++              
+               if (Delta + pTm->TmDelta > Time) {
+                       /* Position found */
+                       /* Here the timer needs to be inserted. */
+-                      break ;
++                      break;
+               }
+-              Delta += pTm->TmDelta ;
++              Delta += pTm->TmDelta;
+       }
+       /* insert in queue */
+-      *ppTimPrev = pTimer ;
+-      pTimer->TmNext = pTm ;
+-      pTimer->TmDelta = Time - Delta ;
++      *ppTimPrev = pTimer;
++      pTimer->TmNext = pTm;
++      pTimer->TmDelta = Time - Delta;
+       if (pTm) {
+               /* There is a next timer
+                * -> correct its Delta value.
+                */
+-              pTm->TmDelta -= pTimer->TmDelta ;
++              pTm->TmDelta -= pTimer->TmDelta;
+       }
+-      /*
+-       * start new with first
+-       */
+-      SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ;
++      /* restart with first */
++      SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
+ }
+@@ -241,55 +247,56 @@ void     SkTimerDone(
+ SK_AC *pAC,           /* Adapters context */
+ SK_IOC        Ioc)            /* IoContext */
+ {
+-      timer_done(pAC,Ioc,1) ;
++      timer_done(pAC, Ioc, 1);
+ }
+ static void   timer_done(
+ SK_AC *pAC,           /* Adapters context */
+ SK_IOC        Ioc,            /* IoContext */
+-int   Restart)        /* Do we need to restart the Hardware timer ? */
++int           Restart)        /* Do we need to restart the Hardware timer ? */
+ {
+-      SK_U32          Delta ;
+-      SK_TIMER        *pTm ;
+-      SK_TIMER        *pTComp ;       /* Timer completed now now */
+-      SK_TIMER        **ppLast ;      /* Next field of Last timer to be deq */
+-      int             Done = 0 ;
+-
+-      Delta = SkHwtRead(pAC,Ioc) ;
+-      ppLast = &pAC->Tim.StQueue ;
+-      pTm = pAC->Tim.StQueue ;
++      SK_U32          Delta;
++      SK_TIMER        *pTm;
++      SK_TIMER        *pTComp;        /* Timer completed now now */
++      SK_TIMER        **ppLast;       /* Next field of Last timer to be deq */
++      int             Done = 0;
++
++      Delta = SkHwtRead(pAC, Ioc);
++      
++      ppLast = &pAC->Tim.StQueue;
++      pTm = pAC->Tim.StQueue;
+       while (pTm && !Done) {
+               if (Delta >= pTm->TmDelta) {
+                       /* Timer ran out */
+-                      pTm->TmActive = SK_FALSE ;
+-                      Delta -= pTm->TmDelta ;
+-                      ppLast = &pTm->TmNext ;
+-                      pTm = pTm->TmNext ;
+-              } else {
++                      pTm->TmActive = SK_FALSE;
++                      Delta -= pTm->TmDelta;
++                      ppLast = &pTm->TmNext;
++                      pTm = pTm->TmNext;
++              }
++              else {
+                       /* We found the first timer that did not run out */
+-                      pTm->TmDelta -= Delta ;
+-                      Delta = 0 ;
+-                      Done = 1 ;
++                      pTm->TmDelta -= Delta;
++                      Delta = 0;
++                      Done = 1;
+               }
+       }
+-      *ppLast = 0 ;
++      *ppLast = 0;
+       /*
+        * pTm points to the first Timer that did not run out.
+        * StQueue points to the first Timer that run out.
+        */
+-      for ( pTComp = pAC->Tim.StQueue ; pTComp ; pTComp = pTComp->TmNext) {
+-              SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent,
+-                      pTComp->TmPara) ;
++      for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) {
++              SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara);
+       }
+       /* Set head of timer queue to the first timer that did not run out */
+-      pAC->Tim.StQueue = pTm ;
++      pAC->Tim.StQueue = pTm;
+       if (Restart && pAC->Tim.StQueue) {
+               /* Restart HW timer */
+-              SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ;
++              SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
+       }
+ }
+--- linux-2.6.0/drivers/net/sk98lin/skxmac2.c  2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/net/sk98lin/skxmac2.c   2003-12-28 23:21:01.000000000 -0800
+@@ -2,8 +2,8 @@
+  *
+  * Name:      skxmac2.c
+  * Project:   Gigabit Ethernet Adapters, Common Modules
+- * Version:   $Revision: 1.99 $
+- * Date:      $Date: 2003/07/11 12:19:33 $
++ * Version:   $Revision: 1.102 $
++ * Date:      $Date: 2003/10/02 16:53:58 $
+  * Purpose:   Contains functions to initialize the MACs and PHYs
+  *
+  ******************************************************************************/
+@@ -27,6 +27,23 @@
+  * History:
+  *
+  *    $Log: skxmac2.c,v $
++ *    Revision 1.102  2003/10/02 16:53:58  rschmidt
++ *    Changed setting of GMAC parameters with new macros.
++ *    Added define SLIM around SkGm...LowPowerMode().
++ *    Editorial changes.
++ *    
++ *    Revision 1.101  2003/09/16 14:49:07  rschmidt
++ *    Added routines SkGmClearRst(), SkXmClearRst, SkMacClearRst().
++ *    Added WA code for Yukon-Lite's COMA mode in SkGmHardRst().
++ *    Replaced PCI-Config R/W through internal access.
++ *    Fixed return from coma mode in SkGmLeaveLowPowerMode().
++ *    Fixed compiler warnings for different types.
++ *    Editorial changes.
++ *    
++ *    Revision 1.100  2003/09/16 07:09:11  mschmid
++ *    Added functions SkGmEnterLowPowerMode() and
++ *    SkGmLeaveLowPowerMode()
++ *    
+  *    Revision 1.99  2003/07/11 12:19:33  rschmidt
+  *    Reduced init values for Master & Slave downshift counters to
+  *    minimum values.
+@@ -164,7 +181,7 @@
+  *    Revision 1.74  2002/08/12 14:00:17  rschmidt
+  *    Replaced usage of Broadcom PHY Ids with defines.
+  *    Corrected error messages in SkGmMacStatistic().
+- *    Made SkMacPromiscMode() public for ADDR-Modul.
++ *    Made SkMacPromiscMode() public for ADDR-Module.
+  *    Editorial changes.
+  *    
+  *    Revision 1.73  2002/08/08 16:26:24  rschmidt
+@@ -475,7 +492,7 @@ typedef struct s_PhyHack {
+ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+ static const char SysKonnectFileId[] =
+-      "@(#) $Id: skxmac2.c,v 1.99 2003/07/11 12:19:33 rschmidt Exp $ (C) Marvell.";
++      "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";
+ #endif
+ #ifdef GENESIS
+@@ -1343,7 +1360,7 @@ int              Port)   /* Port Index (MAC_1 + n) */
+  * Description:
+  *    The XMAC of the specified 'Port' and all connected devices
+  *    (PHY and SERDES) will receive a reset signal on its *Reset pins.
+- *    External PHYs must be reset be clearing a bit in the GPIO register
++ *    External PHYs must be reset by clearing a bit in the GPIO register
+  *  (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns).
+  *
+  * ATTENTION:
+@@ -1386,23 +1403,62 @@ int            Port)   /* Port Index (MAC_1 + n) */
+       /* For external PHYs there must be special handling */
+       if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
+-              /* reset external PHY */
++              
+               SK_IN32(IoC, B2_GP_IO, &Reg);
++              
+               if (Port == 0) {
+-                      Reg |= GP_DIR_0; /* set to output */
+-                      Reg &= ~GP_IO_0;
++                      Reg |= GP_DIR_0;        /* set to output */
++                      Reg &= ~GP_IO_0;        /* set PHY reset (active low) */
+               }
+               else {
+-                      Reg |= GP_DIR_2; /* set to output */
+-                      Reg &= ~GP_IO_2;
++                      Reg |= GP_DIR_2;        /* set to output */
++                      Reg &= ~GP_IO_2;        /* set PHY reset (active low) */
+               }
++              /* reset external PHY */
+               SK_OUT32(IoC, B2_GP_IO, Reg);
+               /* short delay */
+               SK_IN32(IoC, B2_GP_IO, &Reg);
+       }
+-
+ }     /* SkXmHardRst */
++
++
++/******************************************************************************
++ *
++ *    SkXmClearRst() - Release the PHY & XMAC reset
++ *
++ * Description:
++ *
++ * Returns:
++ *    nothing
++ */
++static void SkXmClearRst(
++SK_AC *pAC,   /* adapter context */
++SK_IOC        IoC,    /* IO context */
++int           Port)   /* Port Index (MAC_1 + n) */
++{
++      SK_U32  DWord;
++      
++      /* clear HW reset */
++      SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
++
++      if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
++
++              SK_IN32(IoC, B2_GP_IO, &DWord);
++
++              if (Port == 0) {
++                      DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */
++              }
++              else {
++                      DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */
++              }
++              /* Clear PHY reset */
++              SK_OUT32(IoC, B2_GP_IO, DWord);
++
++              /* Enable GMII interface */
++              XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
++      }
++}     /* SkXmClearRst */
+ #endif /* GENESIS */
+@@ -1452,10 +1508,6 @@ int             Port)   /* Port Index (MAC_1 + n) */
+  *
+  * Description:
+  *
+- * ATTENTION:
+- *    It is absolutely necessary to reset the SW_RST Bit first
+- *    before calling this function.
+- *
+  * Returns:
+  *    nothing
+  */
+@@ -1464,6 +1516,20 @@ SK_AC   *pAC,   /* adapter context */
+ SK_IOC        IoC,    /* IO context */
+ int           Port)   /* Port Index (MAC_1 + n) */
+ {
++      SK_U32  DWord;
++      
++      /* WA code for COMA mode */
++      if (pAC->GIni.GIYukonLite &&
++              pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
++              
++              SK_IN32(IoC, B2_GP_IO, &DWord);
++
++              DWord |= (GP_DIR_9 | GP_IO_9);
++
++              /* set PHY reset */
++              SK_OUT32(IoC, B2_GP_IO, DWord);
++      }
++
+       /* set GPHY Control reset */
+       SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
+@@ -1471,6 +1537,73 @@ int             Port)   /* Port Index (MAC_1 + n) */
+       SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
+ }     /* SkGmHardRst */
++
++
++/******************************************************************************
++ *
++ *    SkGmClearRst() - Release the GPHY & GMAC reset
++ *
++ * Description:
++ *
++ * Returns:
++ *    nothing
++ */
++static void SkGmClearRst(
++SK_AC *pAC,   /* adapter context */
++SK_IOC        IoC,    /* IO context */
++int           Port)   /* Port Index (MAC_1 + n) */
++{
++      SK_U32  DWord;
++      
++#ifdef XXX
++              /* clear GMAC Control reset */
++              SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
++
++              /* set GMAC Control reset */
++              SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
++#endif /* XXX */
++
++      /* WA code for COMA mode */
++      if (pAC->GIni.GIYukonLite &&
++              pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
++              
++              SK_IN32(IoC, B2_GP_IO, &DWord);
++
++              DWord |= GP_DIR_9;              /* set to output */
++              DWord &= ~GP_IO_9;              /* clear PHY reset (active high) */
++
++              /* clear PHY reset */
++              SK_OUT32(IoC, B2_GP_IO, DWord);
++      }
++
++      /* set HWCFG_MODE */
++      DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
++              GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
++              (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
++              GPC_HWCFG_GMII_FIB);
++
++      /* set GPHY Control reset */
++      SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
++
++      /* release GPHY Control reset */
++      SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
++
++#ifdef VCPU
++      VCpuWait(9000);
++#endif /* VCPU */
++
++      /* clear GMAC Control reset */
++      SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
++
++#ifdef VCPU
++      VCpuWait(2000);
++      
++      SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord);
++                      
++      SK_IN32(IoC, B0_ISRC, &DWord);
++#endif /* VCPU */
++
++}     /* SkGmClearRst */
+ #endif /* YUKON */
+@@ -1553,6 +1686,38 @@ int             Port)   /* Port Index (MAC_1 + n) */
+ }     /* SkMacHardRst */
++/******************************************************************************
++ *
++ *    SkMacClearRst() - Clear the MAC reset
++ *
++ * Description:       calls a clear MAC reset routine dep. on board type
++ *
++ * Returns:
++ *    nothing
++ */
++void SkMacClearRst(
++SK_AC *pAC,   /* adapter context */
++SK_IOC        IoC,    /* IO context */
++int           Port)   /* Port Index (MAC_1 + n) */
++{
++      
++#ifdef GENESIS
++      if (pAC->GIni.GIGenesis) {
++              
++              SkXmClearRst(pAC, IoC, Port);
++      }
++#endif /* GENESIS */
++      
++#ifdef YUKON
++      if (pAC->GIni.GIYukon) {
++              
++              SkGmClearRst(pAC, IoC, Port);
++      }
++#endif /* YUKON */
++
++}     /* SkMacClearRst */
++
++
+ #ifdef GENESIS
+ /******************************************************************************
+  *
+@@ -1574,7 +1739,6 @@ SK_IOC   IoC,            /* IO context */
+ int           Port)           /* Port Index (MAC_1 + n) */
+ {
+       SK_GEPORT       *pPrt;
+-      SK_U32          Reg;
+       int                     i;
+       SK_U16          SWord;
+@@ -1594,32 +1758,10 @@ int            Port)           /* Port Index (MAC_1 + n) */
+       }
+       if (pPrt->PState == SK_PRT_RESET) {
+-              /*
+-               * clear HW reset
+-               * Note: The SW reset is self clearing, therefore there is
+-               *       nothing to do here.
+-               */
+-              SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
+-              /* Ensure that XMAC reset release is done (errata from LReinbold?) */
+-              SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
++              SkXmClearRst(pAC, IoC, Port);
+-              /* Clear PHY reset */
+               if (pPrt->PhyType != SK_PHY_XMAC) {
+-
+-                      SK_IN32(IoC, B2_GP_IO, &Reg);
+-                      
+-                      if (Port == 0) {
+-                              Reg |= (GP_DIR_0 | GP_IO_0); /* set to output */
+-                      }
+-                      else {
+-                              Reg |= (GP_DIR_2 | GP_IO_2); /* set to output */
+-                      }
+-                      SK_OUT32(IoC, B2_GP_IO, Reg);
+-
+-                      /* Enable GMII interface */
+-                      XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
+-
+                       /* read Id from external PHY (all have the same address) */
+                       SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);
+@@ -1831,43 +1973,11 @@ int            Port)           /* Port Index (MAC_1 + n) */
+       }
+       if (pPrt->PState == SK_PRT_RESET) {
+-              /* set GPHY Control reset */
+-              SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
+-
+-              /* set GMAC Control reset */
+-              SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
+-
+-#ifdef XXX
+-              /* clear GMAC Control reset */
+-              SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
+-
+-              /* set GMAC Control reset */
+-              SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
+-#endif /* XXX */
+-
+-              /* set HWCFG_MODE */
+-              DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
+-                      GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
+-                      (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
+-                      GPC_HWCFG_GMII_FIB);
+-
+-              /* set GPHY Control reset */
+-              SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
+-
+-              /* release GPHY Control reset */
+-              SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
+-
+-#ifdef VCPU
+-              VCpuWait(9000);
+-#endif /* VCPU */
+-
+-              /* clear GMAC Control reset */
+-              SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
+-
+-#ifdef VCPU
+-              VCpuWait(2000);
+-#endif /* VCPU */
++              
++              SkGmHardRst(pAC, IoC, Port);
++              SkGmClearRst(pAC, IoC, Port);
++              
+               /* Auto-negotiation ? */
+               if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+                       /* Auto-negotiation disabled */
+@@ -1906,6 +2016,7 @@ int              Port)           /* Port Index (MAC_1 + n) */
+                       SWord |= GM_GPCR_DUP_FULL;
+               }
++              /* flow-control settings */
+               switch (pPrt->PFlowCtrlMode) {
+               case SK_FLOW_MODE_NONE:
+                       /* set Pause Off */
+@@ -1940,7 +2051,7 @@ int              Port)           /* Port Index (MAC_1 + n) */
+       (void)SkGmResetCounter(pAC, IoC, Port);
+       /* setup Transmit Control Register */
+-      GM_OUT16(IoC, Port, GM_TX_CTRL, GM_TXCR_COL_THR);
++      GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres));
+       /* setup Receive Control Register */
+       GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
+@@ -1954,7 +2065,9 @@ int              Port)           /* Port Index (MAC_1 + n) */
+       GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
+ #endif /* VCPU */
+-    SWord = (SK_U16)(JAM_LEN_VAL(3) | JAM_IPG_VAL(11) | IPG_JAM_DATA(26));
++    SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
++                      TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
++                      TX_IPG_JAM_DATA(pPrt->PMacJamIpgData);
+       
+       GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
+@@ -1963,7 +2076,12 @@ int             Port)           /* Port Index (MAC_1 + n) */
+       GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
+ #endif /* VCPU */
+       
+-      SWord = GM_SMOD_VLAN_ENA | IPG_VAL_FAST_ETH;
++      SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData);
++
++      if (pPrt->PMacLimit4) {
++              /* reset of collision counter after 4 consecutive collisions */
++              SWord |= GM_SMOD_LIMIT_4;
++      }
+       if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
+               /* enable jumbo mode (Max. Frame Length = 9018) */
+@@ -2021,11 +2139,13 @@ int            Port)           /* Port Index (MAC_1 + n) */
+       GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
+       GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
++#if defined(SK_DIAG) || defined(DEBUG)
+       /* read General Purpose Status */
+       GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
+       
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("MAC Stat Reg=0x%04X\n", SWord));
++              ("MAC Stat Reg.=0x%04X\n", SWord));
++#endif /* SK_DIAG || DEBUG */
+ #ifdef SK_DIAG
+       c_print("MAC Stat Reg=0x%04X\n", SWord);
+@@ -2226,6 +2346,7 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+                               SKERR_HWI_E015MSG);
+               }
++              /* Set Flow-control capabilities */
+               switch (pPrt->PFlowCtrlMode) {
+               case SK_FLOW_MODE_NONE:
+                       Ctrl |= PHY_X_P_NO_PAUSE;
+@@ -2306,7 +2427,9 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyBcom: no auto-negotiation Port %d\n", Port));
+               /* Set DuplexMode in Config register */
+-              Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
++              if (pPrt->PLinkMode == SK_LMODE_FULL) {
++                      Ctrl1 |= PHY_CT_DUP_MD;
++              }
+               /* Determine Master/Slave manually if not already done */
+               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
+@@ -2346,6 +2469,7 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+                               SKERR_HWI_E015MSG);
+               }
++              /* Set Flow-control capabilities */
+               switch (pPrt->PFlowCtrlMode) {
+               case SK_FLOW_MODE_NONE:
+                       Ctrl3 |= PHY_B_P_NO_PAUSE;
+@@ -2375,12 +2499,12 @@ SK_BOOL        DoLoop)         /* Should a Phy LoopBac
+       /* Write 1000Base-T Control Register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
++              ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
+       
+       /* Write AutoNeg Advertisement Register */
+       SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
++              ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
+       
+       if (DoLoop) {
+               /* Set the Phy Loopback bit, too */
+@@ -2409,6 +2533,281 @@ SK_BOOL        DoLoop)         /* Should a Phy LoopBac
+ #ifdef YUKON
++#ifndef SK_SLIM
++/******************************************************************************
++ *
++ *    SkGmEnterLowPowerMode()
++ *
++ * Description:       
++ *    This function sets the Marvell Alaska PHY to the low power mode
++ *    given by parameter mode.
++ *    The following low power modes are available:
++ *            
++ *            - Coma Mode (Deep Sleep):
++ *                    Power consumption: ~15 - 30 mW
++ *                    The PHY cannot wake up on its own.
++ *
++ *            - IEEE 22.2.4.1.5 compatible power down mode
++ *                    Power consumption: ~240 mW
++ *                    The PHY cannot wake up on its own.
++ *
++ *            - energy detect mode
++ *                    Power consumption: ~160 mW
++ *                    The PHY can wake up on its own by detecting activity
++ *                    on the CAT 5 cable.
++ *
++ *            - energy detect plus mode
++ *                    Power consumption: ~150 mW
++ *                    The PHY can wake up on its own by detecting activity
++ *                    on the CAT 5 cable.
++ *                    Connected devices can be woken up by sending normal link
++ *                    pulses every one second.
++ *
++ * Note:
++ *
++ * Returns:
++ *            0: ok
++ *            1: error
++ */
++int SkGmEnterLowPowerMode(
++SK_AC *pAC,           /* adapter context */
++SK_IOC        IoC,            /* IO context */
++int           Port,           /* Port Index (e.g. MAC_1) */
++SK_U8 Mode)           /* low power mode */
++{
++      SK_U16  Word;
++      SK_U32  DWord;
++      SK_U8   LastMode;
++      int             Ret = 0;
++
++      if (pAC->GIni.GIYukonLite &&
++          pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
++
++              /* save current power mode */
++              LastMode = pAC->GIni.GP[Port].PPhyPowerState;
++              pAC->GIni.GP[Port].PPhyPowerState = Mode;
++
++              switch (Mode) {
++                      /* coma mode (deep sleep) */
++                      case PHY_PM_DEEP_SLEEP:
++                              /* setup General Purpose Control Register */
++                              GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS |
++                                      GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
++
++                              /* apply COMA mode workaround */
++                              SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f);
++                              SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3);
++
++                              SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
++
++                              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
++                              
++                              /* Set PHY to Coma Mode */
++                              SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA);
++                              
++                              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
++
++                      break;
++                      
++                      /* IEEE 22.2.4.1.5 compatible power down mode */
++                      case PHY_PM_IEEE_POWER_DOWN:
++                              /*
++                               * - disable MAC 125 MHz clock
++                               * - allow MAC power down
++                               */
++                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
++                              Word |= PHY_M_PC_DIS_125CLK;
++                              Word &= ~PHY_M_PC_MAC_POW_UP;
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++
++                              /*
++                               * register changes must be followed by a software
++                               * reset to take effect
++                               */
++                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
++                              Word |= PHY_CT_RESET;
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
++
++                              /* switch IEEE compatible power down mode on */
++                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
++                              Word |= PHY_CT_PDOWN;
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
++                      break;
++
++                      /* energy detect and energy detect plus mode */
++                      case PHY_PM_ENERGY_DETECT:
++                      case PHY_PM_ENERGY_DETECT_PLUS:
++                              /*
++                               * - disable MAC 125 MHz clock
++                               */
++                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
++                              Word |= PHY_M_PC_DIS_125CLK;
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++                              
++                              /* activate energy detect mode 1 */
++                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
++
++                              /* energy detect mode */
++                              if (Mode == PHY_PM_ENERGY_DETECT) {
++                                      Word |= PHY_M_PC_EN_DET;
++                              }
++                              /* energy detect plus mode */
++                              else {
++                                      Word |= PHY_M_PC_EN_DET_PLUS;
++                              }
++
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++
++                              /*
++                               * reinitialize the PHY to force a software reset
++                               * which is necessary after the register settings
++                               * for the energy detect modes.
++                               * Furthermore reinitialisation prevents that the
++                               * PHY is running out of a stable state.
++                               */
++                              SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
++                      break;
++
++                      /* don't change current power mode */
++                      default:
++                              pAC->GIni.GP[Port].PPhyPowerState = LastMode;
++                              Ret = 1;
++                      break;
++              }
++      }
++      /* low power modes are not supported by this chip */
++      else {
++              Ret = 1;
++      }
++
++      return(Ret);
++
++}     /* SkGmEnterLowPowerMode */
++
++/******************************************************************************
++ *
++ *    SkGmLeaveLowPowerMode()
++ *
++ * Description:       
++ *    Leave the current low power mode and switch to normal mode
++ *
++ * Note:
++ *
++ * Returns:
++ *            0:      ok
++ *            1:      error
++ */
++int SkGmLeaveLowPowerMode(
++SK_AC *pAC,           /* adapter context */
++SK_IOC        IoC,            /* IO context */
++int           Port)           /* Port Index (e.g. MAC_1) */
++{
++      SK_U32  DWord;
++      SK_U16  Word;
++      SK_U8   LastMode;
++      int             Ret = 0;
++
++      if (pAC->GIni.GIYukonLite &&
++              pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
++
++              /* save current power mode */
++              LastMode = pAC->GIni.GP[Port].PPhyPowerState;
++              pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
++
++              switch (LastMode) {
++                      /* coma mode (deep sleep) */
++                      case PHY_PM_DEEP_SLEEP:
++                              SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
++
++                              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
++                              
++                              /* Release PHY from Coma Mode */
++                              SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA);
++                              
++                              SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
++                              
++                              SK_IN32(IoC, B2_GP_IO, &DWord);
++
++                              /* set to output */
++                              DWord |= (GP_DIR_9 | GP_IO_9);
++
++                              /* set PHY reset */
++                              SK_OUT32(IoC, B2_GP_IO, DWord);
++
++                              DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
++
++                              /* clear PHY reset */
++                              SK_OUT32(IoC, B2_GP_IO, DWord);
++                      break;
++                      
++                      /* IEEE 22.2.4.1.5 compatible power down mode */
++                      case PHY_PM_IEEE_POWER_DOWN:
++                              /*
++                               * - enable MAC 125 MHz clock
++                               * - set MAC power up
++                               */
++                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
++                              Word &= ~PHY_M_PC_DIS_125CLK;
++                              Word |= PHY_M_PC_MAC_POW_UP;
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++
++                              /*
++                               * register changes must be followed by a software
++                               * reset to take effect
++                               */
++                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
++                              Word |= PHY_CT_RESET;
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
++
++                              /* switch IEEE compatible power down mode off */
++                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
++                              Word &= ~PHY_CT_PDOWN;
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
++                      break;
++
++                      /* energy detect and energy detect plus mode */
++                      case PHY_PM_ENERGY_DETECT:
++                      case PHY_PM_ENERGY_DETECT_PLUS:
++                              /*
++                               * - enable MAC 125 MHz clock
++                               */
++                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
++                              Word &= ~PHY_M_PC_DIS_125CLK;
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++                              
++                              /* disable energy detect mode */
++                              SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
++                              Word &= ~PHY_M_PC_EN_DET_MSK;
++                              SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
++
++                              /*
++                               * reinitialize the PHY to force a software reset
++                               * which is necessary after the register settings
++                               * for the energy detect modes.
++                               * Furthermore reinitialisation prevents that the
++                               * PHY is running out of a stable state.
++                               */
++                              SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
++                      break;
++
++                      /* don't change current power mode */
++                      default:
++                              pAC->GIni.GP[Port].PPhyPowerState = LastMode;
++                              Ret = 1;
++                      break;
++              }
++      }
++      /* low power modes are not supported by this chip */
++      else {
++              Ret = 1;
++      }
++
++      return(Ret);
++
++}     /* SkGmLeaveLowPowerMode */
++#endif /* !SK_SLIM */
++
++
+ /******************************************************************************
+  *
+  *    SkGmInitPhyMarv() - Initialize the Marvell Phy registers
+@@ -2457,7 +2856,6 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+       VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
+               Port, DoLoop);
+ #else /* VCPU */
+-      
+       if (DoLoop) {
+               /* Set 'MAC Power up'-bit, set Manual MDI configuration */
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
+@@ -2475,16 +2873,20 @@ SK_BOOL        DoLoop)         /* Should a Phy LoopBac
+       
+               SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-                      ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
++                      ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
+       }
+       /* Read PHY Control */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
++      if (!AutoNeg) {
++              /* Disable Auto-negotiation */
++              PhyCtrl &= ~PHY_CT_ANE;
++      }
++
+       PhyCtrl |= PHY_CT_RESET;
+       /* Assert software reset */
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
+-
+ #endif /* VCPU */
+       PhyCtrl = 0 /* PHY_CT_COL_TST */;
+@@ -2533,13 +2935,9 @@ SK_BOOL DoLoop)         /* Should a Phy LoopBac
+               if (!DoLoop) {
+                       PhyCtrl |= PHY_CT_RESET;
+               }
+-              /*
+-               * Do NOT enable Auto-negotiation here. This would hold
+-               * the link down because no IDLES are transmitted
+-               */
+       }
+       else {
+-              PhyCtrl |= PHY_CT_ANE;
++              /* Set Auto-negotiation advertisement */
+               
+               if (pAC->GIni.GICopperType) {
+                       /* Set Speed capabilities */
+@@ -2554,6 +2952,7 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+                               break;
+                       case SK_LSPEED_100MBPS:
+                               AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
++                                      /* advertise 10Base-T also */
+                                       PHY_M_AN_10_FD | PHY_M_AN_10_HD;
+                               break;
+                       case SK_LSPEED_10MBPS:
+@@ -2581,7 +2980,7 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+                                       SKERR_HWI_E015MSG);
+                       }
+                       
+-                      /* Set Auto-negotiation advertisement */
++                      /* Set Flow-control capabilities */
+                       switch (pPrt->PFlowCtrlMode) {
+                       case SK_FLOW_MODE_NONE:
+                               AutoNegAdv |= PHY_B_P_NO_PAUSE;
+@@ -2618,7 +3017,7 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+                                       SKERR_HWI_E015MSG);
+                       }
+                       
+-                      /* Set Auto-negotiation advertisement */
++                      /* Set Flow-control capabilities */
+                       switch (pPrt->PFlowCtrlMode) {
+                       case SK_FLOW_MODE_NONE:
+                               AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
+@@ -2640,7 +3039,7 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+               if (!DoLoop) {
+                       /* Restart Auto-negotiation */
+-                      PhyCtrl |= PHY_CT_RE_CFG;
++                      PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
+               }
+       }
+       
+@@ -2659,12 +3058,12 @@ SK_BOOL        DoLoop)         /* Should a Phy LoopBac
+       /* Write 1000Base-T Control Register */
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("1000B-T Ctrl=0x%04X\n", C1000BaseT));
++              ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
+       
+       /* Write AutoNeg Advertisement Register */
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("Auto-Neg.Ad.=0x%04X\n", AutoNegAdv));
++              ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
+ #endif /* VCPU */
+       
+       if (DoLoop) {
+@@ -2694,6 +3093,8 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+       /* Write to the PHY Control register */
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
+ #ifdef VCPU
+       VCpuWait(2000);
+@@ -2712,7 +3113,7 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
+       if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {
+-              /* only in forced 100Mbps mode */
++              /* only in forced 100 Mbps mode */
+               if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {
+                       SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,
+@@ -2741,7 +3142,7 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+       /* Read AutoNeg Advertisement Register */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
+       SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+-              ("Auto-Neg. Ad.=0x%04X\n", AutoNegAdv));
++              ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
+       
+       /* Read Ext. PHY Specific Control */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
+@@ -2818,13 +3219,15 @@ SK_BOOL        DoLoop)         /* Should a Phy LoopBac
+       /* Auto-negotiation ? */
+       if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
+               /*
+-               * level one spec say: "1000Mbps: manual mode not allowed"
++               * level one spec say: "1000 Mbps: manual mode not allowed"
+                * but lets see what happens...
+                */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("InitPhyLone: no auto-negotiation Port %d\n", Port));
+               /* Set DuplexMode in Config register */
+-              Ctrl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
++              if (pPrt->PLinkMode == SK_LMODE_FULL) {
++                      Ctrl1 |= PHY_CT_DUP_MD;
++              }
+               /* Determine Master/Slave manually if not already done */
+               if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
+@@ -2857,6 +3260,7 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+                               SKERR_HWI_E015MSG);
+               }
++              /* Set Flow-control capabilities */
+               switch (pPrt->PFlowCtrlMode) {
+               case SK_FLOW_MODE_NONE:
+                       Ctrl3 |= PHY_L_P_NO_PAUSE;
+@@ -2877,7 +3281,6 @@ SK_BOOL  DoLoop)         /* Should a Phy LoopBac
+               /* Restart Auto-negotiation */
+               Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
+-
+       }
+       
+       /* Write 1000Base-T Control Register */
+@@ -3019,10 +3422,10 @@ int            Port)           /* Port Index (MAC_1 + n) */
+       /* Check Duplex mismatch */
+       if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
+-              pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
++              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
+       }
+       else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
+-              pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
++              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
+       }
+       else {
+               /* Error */
+@@ -3055,7 +3458,7 @@ int              Port)           /* Port Index (MAC_1 + n) */
+               /* PAUSE mismatch -> no PAUSE */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+       }
+-      pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
++      pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
+       return(SK_AND_OK);
+ }     /* SkXmAutoNegDoneXmac */
+@@ -3110,10 +3513,10 @@ int            Port)           /* Port Index (MAC_1 + n) */
+       /* Check Duplex mismatch */
+       if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) {
+-              pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
++              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
+       }
+       else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) {
+-              pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
++              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
+       }
+       else {
+               /* Error */
+@@ -3156,7 +3559,7 @@ int              Port)           /* Port Index (MAC_1 + n) */
+               /* PAUSE mismatch -> no PAUSE */
+               pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+       }
+-      pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
++      pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
+       return(SK_AND_OK);
+ }     /* SkXmAutoNegDoneBcom */
+@@ -3192,6 +3595,8 @@ int              Port)           /* Port Index (MAC_1 + n) */
+       /* Get PHY parameters */
+       SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              ("Link P.Abil.=0x%04X\n", LPAb));
+       
+       if ((LPAb & PHY_M_AN_RF) != 0) {
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+@@ -3222,15 +3627,15 @@ int            Port)           /* Port Index (MAC_1 + n) */
+               SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+                       ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
+               pPrt->PAutoNegFail = SK_TRUE;
+-              pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
++              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
+               return(SK_AND_DUP_CAP);
+       }
+       
+       if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
+-              pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
++              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
+       }
+       else {
+-              pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
++              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
+       }
+       
+       /* Check PAUSE mismatch ??? */
+@@ -3255,13 +3660,13 @@ int            Port)           /* Port Index (MAC_1 + n) */
+       /* set used link speed */
+       switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
+       case (unsigned)PHY_M_PS_SPEED_1000:
+-              pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
++              pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
+               break;
+       case PHY_M_PS_SPEED_100:
+-              pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS;
++              pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
+               break;
+       default:
+-              pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS;
++              pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
+       }
+       return(SK_AND_OK);
+@@ -3312,10 +3717,10 @@ int            Port)           /* Port Index (MAC_1 + n) */
+       /* Check Duplex mismatch */
+       if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) {
+-              pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
++              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
+       }
+       else {
+-              pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
++              pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
+       }
+       
+       /* Check Master/Slave resolution */
+@@ -3338,6 +3743,7 @@ int              Port)           /* Port Index (MAC_1 + n) */
+       /* We are using IEEE 802.3z/D5.0 Table 37-4 */
+       /* we must manually resolve the abilities here */
+       pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
++      
+       switch (pPrt->PFlowCtrlMode) {
+       case SK_FLOW_MODE_NONE:
+               /* default */
+@@ -3457,6 +3863,9 @@ int              Port)           /* Port Index (MAC_1 + n) */
+               return(Rtv);
+       }
++      SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
++              ("AutoNeg done Port %d\n", Port));
++      
+       /* We checked everything and may now enable the link */
+       pPrt->PAutoNegFail = SK_FALSE;
+--- linux-2.6.0/drivers/net/skfp/skfddi.c      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/skfp/skfddi.c       2003-12-28 23:21:01.000000000 -0800
+@@ -39,12 +39,6 @@
+  *   are skfddi.c, h/types.h, h/osdef1st.h, h/targetos.h.
+  *   The others belong to the SysKonnect FDDI Hardware Module and
+  *   should better not be changed.
+- * NOTE:
+- *   Compiling this driver produces some warnings, but I did not fix
+- *   this, because the Hardware Module source is used for different
+- *   drivers, and fixing it for Linux might bring problems on other
+- *   projects. To keep the source common for all those drivers (and
+- *   thus simplify fixes to it), please do not clean it up!
+  *
+  * Modification History:
+  *              Date            Name    Description
+@@ -58,6 +52,7 @@
+  *            07-May-00       DM      64 bit fixes, new dma interface
+  *            31-Jul-03       DB      Audit copy_*_user in skfp_ioctl
+  *                                      Daniele Bellucci <bellucda@tiscali.it>
++ *            03-Dec-03       SH      Convert to PCI device model
+  *
+  * Compilation options (-Dxxx):
+  *              DRIVERDEBUG     print lots of messages to log file
+@@ -70,7 +65,7 @@
+ /* Version information string - should be updated prior to */
+ /* each new release!!! */
+-#define VERSION               "2.06"
++#define VERSION               "2.07"
+ static const char *boot_msg = 
+       "SysKonnect FDDI PCI Adapter driver v" VERSION " for\n"
+@@ -80,15 +75,11 @@ static const char *boot_msg = 
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/ptrace.h>
+ #include <linux/errno.h>
+ #include <linux/ioport.h>
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
+ #include <linux/pci.h>
+-#include <linux/delay.h>
+-#include <linux/ctype.h>      // isdigit
+ #include <linux/netdevice.h>
+ #include <linux/fddidevice.h>
+ #include <linux/skbuff.h>
+@@ -106,17 +97,7 @@ static const char *boot_msg = 
+ #include      "h/smtstate.h"
+-// Define global routines
+-int skfp_probe(struct net_device *dev);
+-
+-
+ // Define module-wide (static) routines
+-static struct net_device *alloc_device(struct net_device *dev, u_long iobase);
+-static struct net_device *insert_device(struct net_device *dev,
+-                                  int (*init) (struct net_device *));
+-static int fddi_dev_index(unsigned char *s);
+-static void init_dev(struct net_device *dev, u_long iobase);
+-static void link_modules(struct net_device *dev, struct net_device *tmp);
+ static int skfp_driver_init(struct net_device *dev);
+ static int skfp_open(struct net_device *dev);
+ static int skfp_close(struct net_device *dev);
+@@ -193,15 +174,6 @@ MODULE_AUTHOR("Mirko Lindner <mlindner@s
+ // Define module-wide (static) variables
+ static int num_boards;        /* total number of adapters configured */
+-static int num_fddi;
+-static int autoprobed;
+-
+-#ifdef MODULE
+-static struct net_device *unlink_modules(struct net_device *p);
+-static int loading_module = 1;
+-#else
+-static int loading_module;
+-#endif                                // MODULE
+ #ifdef DRIVERDEBUG
+ #define PRINTK(s, args...) printk(s, ## args)
+@@ -212,9 +184,9 @@ static int loading_module;
+ #define PRIV(dev) (&(((struct s_smc *)dev->priv)->os))
+ /*
+- * ==============
+- * = skfp_probe =
+- * ==============
++ * =================
++ * = skfp_init_one =
++ * =================
+  *   
+  * Overview:
+  *   Probes for supported FDDI PCI controllers
+@@ -223,30 +195,11 @@ static int loading_module;
+  *   Condition code
+  *       
+  * Arguments:
+- *   dev - pointer to device information
++ *   pdev - pointer to PCI device information
+  *
+  * Functional Description:
+- *   This routine is called by the OS for each FDDI device name (fddi0,
+- *   fddi1,...,fddi6, fddi7) specified in drivers/net/Space.c.
+- *   If loaded as a module, it will detect and initialize all 
+- *   adapters the first time it is called.
+- *
+- *   Let's say that skfp_probe() is getting called to initialize fddi0.
+- *   Furthermore, let's say there are three supported controllers in the
+- *   system.  Before skfp_probe() leaves, devices fddi0, fddi1, and fddi2
+- *   will be initialized and a global flag will be set to indicate that
+- *   skfp_probe() has already been called.
+- *
+- *   However...the OS doesn't know that we've already initialized
+- *   devices fddi1 and fddi2 so skfp_probe() gets called again and again
+- *   until it reaches the end of the device list for FDDI (presently,
+- *   fddi7).  It's important that the driver "pretend" to probe for
+- *   devices fddi1 and fddi2 and return success.  Devices fddi3
+- *   through fddi7 will return failure since they weren't initialized.
+- *
+- *   This algorithm seems to work for the time being.  As other FDDI
+- *   drivers are written for Linux, a more generic approach (perhaps
+- *   similar to the Ethernet card approach) may need to be implemented.
++ *   This is now called by PCI driver registration process
++ *   for each board found.
+  *   
+  * Return Codes:
+  *   0           - This device (fddi0, fddi1, etc) configured successfully
+@@ -259,374 +212,176 @@ static int loading_module;
+  *   initialized and the board resources are read and stored in
+  *   the device structure.
+  */
+-int skfp_probe(struct net_device *dev)
++static int skfp_init_one(struct pci_dev *pdev,
++                              const struct pci_device_id *ent)
+ {
+-      int i;                  /* used in for loops */
+-      struct pci_dev *pdev = NULL;    /* PCI device structure */
+-#ifndef MEM_MAPPED_IO
+-      u16 port;               /* temporary I/O (port) address */
+-      int port_len;           /* length of port address range (in bytes) */
+-#else
+-      unsigned long port;
+-#endif
+-      u16 command;    /* PCI Configuration space Command register val */
++      struct net_device *dev;
+       struct s_smc *smc;      /* board pointer */
+-      struct net_device *tmp = dev;
+-      u8 first_dev_used = 0;
+-      u16 SubSysId;
++      u32 port, len;
++      int err;
+-      PRINTK(KERN_INFO "entering skfp_probe\n");
+-
+-      /*
+-       * Verify whether we're going through skfp_probe() again
+-       *
+-       * If so, see if we're going through for a subsequent fddi device that
+-       * we've already initialized.  If we are, return success (0).  If not,
+-       * return failure (-ENODEV).
+-       */
+-
+-      if (autoprobed) {
+-              PRINTK(KERN_INFO "Already entered skfp_probe\n");
+-              if (dev != NULL) {
+-                      if ((strncmp(dev->name, "fddi", 4) == 0) &&
+-                          (dev->base_addr != 0)) {
+-                              return (0);
+-                      }
+-                      return (-ENODEV);
+-              }
+-      }
+-      autoprobed = 1;         /* set global flag */
++      PRINTK(KERN_INFO "entering skfp_init_one\n");
+-      printk("%s\n", boot_msg);
++      if (num_boards == 0) 
++              printk("%s\n", boot_msg);
+-      /* Scan for Syskonnect FDDI PCI controllers */
+-      for (i = 0; i < SKFP_MAX_NUM_BOARDS; i++) {     // scan for PCI cards
+-              PRINTK(KERN_INFO "Check device %d\n", i);
+-              if ((pdev=pci_find_device(PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP,
+-                      pdev)) == 0) {
+-                      break;
+-              }
+-              if (pci_enable_device(pdev))
+-                      continue;
++      err = pci_enable_device(pdev);
++      if (err)
++              goto err_out1;
+-#ifndef MEM_MAPPED_IO
+-              /* Verify that I/O enable bit is set (PCI slot is enabled) */
+-              pci_read_config_word(pdev, PCI_COMMAND, &command);
+-              if ((command & PCI_COMMAND_IO) == 0) {
+-                      PRINTK("I/O enable bit not set!");
+-                      PRINTK(" Verify that slot is enabled\n");
+-                      continue;
+-              }
+-              /* Turn off memory mapped space and enable mastering */
++#ifdef MEM_MAPPED_IO
++      if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
++              printk(KERN_ERR "skfp: region is not an MMIO resource\n");
++              err = -EIO;
++              goto err_out1;
++      }
++      port = pci_resource_start(pdev, 0);
++      len = pci_resource_len(pdev, 0);
+-              PRINTK(KERN_INFO "Command Reg: %04x\n", command);
+-              command |= PCI_COMMAND_MASTER;
+-              command &= ~PCI_COMMAND_MEMORY;
+-              pci_write_config_word(pdev, PCI_COMMAND, command);
+-
+-              /* Read I/O base address from PCI Configuration Space */
+-
+-              pci_read_config_word(pdev, PCI_BASE_ADDRESS_1, &port);
+-              port &= PCI_BASE_ADDRESS_IO_MASK; // clear I/O bit (bit 0)
+-
+-              /* Verify port address range is not already being used */
+-
+-              port_len = FP_IO_LEN;
+-              if (check_region(port, port_len) != 0) {
+-                      printk("I/O range allocated to adapter");
+-                      printk(" (0x%X-0x%X) is already being used!\n", port,
+-                             (port + port_len - 1));
+-                      continue;
+-              }
++      if (len < 0x4000) {
++              printk(KERN_ERR "skfp: Invalid PCI region size: %d\n", len);
++              err = -EIO;
++              goto err_out1;
++      }
+ #else
+-              /* Verify that MEM enable bit is set (PCI slot is enabled) */
+-              pci_read_config_word(pdev, PCI_COMMAND, &command);
+-              if ((command & PCI_COMMAND_MEMORY) == 0) {
+-                      PRINTK("MEMORY-I/O enable bit not set!");
+-                      PRINTK(" Verify that slot is enabled\n");
+-                      continue;
+-              }
+-
+-              /* Turn off IO mapped space and enable mastering */
+-
+-              PRINTK(KERN_INFO "Command Reg: %04x\n", command);
+-              command |= PCI_COMMAND_MASTER;
+-              command &= ~PCI_COMMAND_IO;
+-              pci_write_config_word(pdev, PCI_COMMAND, command);
+-
+-              port = pci_resource_start(pdev, 0);
+-
+-              port = (unsigned long)ioremap(port, 0x4000);
+-              if (!port){
+-                      printk("skfp:  Unable to map MEMORY register, "
+-                      "FDDI adapter will be disabled.\n");
+-                      break;
+-              }
+-#endif
+-
+-              if ((!loading_module) || first_dev_used) {
+-                      /* Allocate a device structure for this adapter */
+-                      tmp = alloc_device(dev, port);
+-              }
+-              first_dev_used = 1;     // only significant first time
+-
+-              pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &SubSysId);
+-
+-              if (tmp != NULL) {
+-                      if (loading_module)
+-                              link_modules(dev, tmp);
+-                      dev = tmp;
+-                      init_dev(dev, port);
+-                      dev->irq = pdev->irq;
+-
+-                      /* Initialize board structure with bus-specific info */
+-
+-                      smc = (struct s_smc *) dev->priv;
+-                      smc->os.dev = dev;
+-                      smc->os.bus_type = SK_BUS_TYPE_PCI;
+-                      smc->os.pdev = *pdev;
+-                      smc->os.QueueSkb = MAX_TX_QUEUE_LEN;
+-                      smc->os.MaxFrameSize = MAX_FRAME_SIZE;
+-                      smc->os.dev = dev;
+-                      smc->hw.slot = -1;
+-                      smc->os.ResetRequested = FALSE;
+-                      skb_queue_head_init(&smc->os.SendSkbQueue);
+-
+-                      if (skfp_driver_init(dev) == 0) {
+-                              // only increment global board 
+-                              // count on success
+-                              num_boards++;
+-                              request_region(dev->base_addr,
+-                                             FP_IO_LEN, dev->name);
+-                              if ((SubSysId & 0xff00) == 0x5500 ||
+-                                      (SubSysId & 0xff00) == 0x5800) {
+-                              printk("%s: SysKonnect FDDI PCI adapter"
+-                                     " found (SK-%04X)\n", dev->name,
+-                                      SubSysId);
+-                              } else {
+-                              printk("%s: FDDI PCI adapter found\n",
+-                                      dev->name);
+-                              }
+-                      } else {
+-                              kfree(dev);
+-                              i = SKFP_MAX_NUM_BOARDS;        // stop search
+-
+-                      }
+-
+-              }               // if (dev != NULL)
+-
+-      }                       // for SKFP_MAX_NUM_BOARDS
+-
+-      /*
+-       * If we're at this point we're going through skfp_probe() for the
+-       * first time. Return success (0) if we've initialized 1 or more
+-       * boards. Otherwise, return failure (-ENODEV).
+-       */
+-
+-      if (num_boards > 0)
+-              return (0);
+-      else {
+-              printk("no SysKonnect FDDI adapter found\n");
+-              return (-ENODEV);
++      if (!(pci_resource_flags(pdev, 1) & IO_RESOURCE_IO)) {
++              printk(KERN_ERR "skfp: region is not PIO resource\n");
++              err = -EIO;
++              goto err_out1;
+       }
+-}                             // skfp_probe
+-
+-
+-/************************
+- *
+- * Search the entire 'fddi' device list for a fixed probe. If a match isn't
+- * found then check for an autoprobe or unused device location. If they
+- * are not available then insert a new device structure at the end of
+- * the current list.
+- *
+- ************************/
+-static struct net_device *alloc_device(struct net_device *dev, u_long iobase)
+-{
+-      struct net_device *adev = NULL;
+-      int fixed = 0, new_dev = 0;
+-
+-      PRINTK(KERN_INFO "entering alloc_device\n");
+-      if (!dev)
+-              return dev;
+-      num_fddi = fddi_dev_index(dev->name);
+-      if (loading_module) {
+-              num_fddi++;
+-              dev = insert_device(dev, skfp_probe);
+-              return dev;
++      port = pci_resource_start(pdev, 1);
++      len = pci_resource_len(pdev, 1);
++      if (len < FP_IO_LEN) {
++              printk(KERN_ERR "skfp: Invalid PCI region size: %d\n",
++                     io_len);
++              err = -EIO;
++              goto err_out1;
+       }
+-      while (1) {
+-              if (((dev->base_addr == NO_ADDRESS) ||
+-                   (dev->base_addr == 0)) && !adev) {
+-                      adev = dev;
+-              } else if ((dev->priv == NULL) && (dev->base_addr == iobase)) {
+-                      fixed = 1;
+-              } else {
+-                      if (dev->next == NULL) {
+-                              new_dev = 1;
+-                      } else if (strncmp(dev->next->name, "fddi", 4) != 0) {
+-                              new_dev = 1;
+-                      }
+-              }
+-              if ((dev->next == NULL) || new_dev || fixed)
+-                      break;
+-              dev = dev->next;
+-              num_fddi++;
+-      }                       // while (1)
+-
+-      if (adev && !fixed) {
+-              dev = adev;
+-              num_fddi = fddi_dev_index(dev->name);
+-              new_dev = 0;
+-      }
+-      if (((dev->next == NULL) && ((dev->base_addr != NO_ADDRESS) &&
+-                                   (dev->base_addr != 0)) && !fixed) ||
+-          new_dev) {
+-              num_fddi++;     /* New device */
+-              dev = insert_device(dev, skfp_probe);
+-      }
+-      if (dev) {
+-              if (!dev->priv) {
+-                      /* Allocate space for private board structure */
+-                      dev->priv = (void *) kmalloc(sizeof(struct s_smc),
+-                                                   GFP_KERNEL);
+-                      if (dev->priv == NULL) {
+-                              printk("%s: Could not allocate memory for",
+-                                      dev->name);
+-                              printk(" private board structure!\n");
+-                              return (NULL);
+-                      }
+-                      /* clear structure */
+-                      memset(dev->priv, 0, sizeof(struct s_smc));
+-              }
++#endif
++      err = pci_request_regions(pdev, "skfddi");
++      if (err)
++              goto err_out1;
++
++      pci_set_master(pdev);
++
++      dev = alloc_fddidev(sizeof(struct s_smc));
++      if (!dev) {
++              printk(KERN_ERR "skfp: Unable to allocate fddi device, "
++                              "FDDI adapter will be disabled.\n");
++              err = -ENOMEM;
++              goto err_out2;
++      }
++
++#ifdef MEM_MAPPED_IO
++      dev->base_addr = (unsigned long) ioremap(port, len);
++      if (!dev->base_addr) {
++              printk(KERN_ERR "skfp:  Unable to map MEMORY register, "
++                              "FDDI adapter will be disabled.\n");
++              err = -EIO;
++              goto err_out3;
+       }
+-      return dev;
+-}                             // alloc_device
+-
+-
+-
+-/************************
+- *
+- * Initialize device structure
+- *
+- ************************/
+-static void init_dev(struct net_device *dev, u_long iobase)
+-{
+-      /* Initialize new device structure */
+-
+-      dev->mem_end = 0;       /* shared memory isn't used */
+-      dev->mem_start = 0;     /* shared memory isn't used */
+-      dev->base_addr = iobase;        /* save port (I/O) base address */
+-      dev->if_port = 0;       /* not applicable to FDDI adapters */
+-      dev->dma = 0;           /* Bus Master DMA doesn't require channel */
+-      dev->irq = 0;
+-
+-      netif_start_queue(dev);
++#else
++      dev->base_addr = port;
++#endif
++      dev->irq = pdev->irq;
+       dev->get_stats = &skfp_ctl_get_stats;
+       dev->open = &skfp_open;
+       dev->stop = &skfp_close;
+       dev->hard_start_xmit = &skfp_send_pkt;
+-      dev->hard_header = NULL;        /* set in fddi_setup() */
+-      dev->rebuild_header = NULL;     /* set in fddi_setup() */
+       dev->set_multicast_list = &skfp_ctl_set_multicast_list;
+       dev->set_mac_address = &skfp_ctl_set_mac_address;
+       dev->do_ioctl = &skfp_ioctl;
+-      dev->set_config = NULL; /* not supported for now &&& */
+       dev->header_cache_update = NULL;        /* not supported */
+-      dev->change_mtu = NULL; /* set in fddi_setup() */
+       SET_MODULE_OWNER(dev);
++      SET_NETDEV_DEV(dev, &pdev->dev);
+-      /* Initialize remaining device structure information */
+-      fddi_setup(dev);
+-}                             // init_device
+-
+-
+-/************************
+- *
+- * If at end of fddi device list and can't use current entry, malloc
+- * one up. If memory could not be allocated, print an error message.
+- *
+-************************/
+-static struct net_device *insert_device(struct net_device *dev,
+-                                  int (*init) (struct net_device *))
+-{
+-      struct net_device *new;
+-      int len;
+-
+-      PRINTK(KERN_INFO "entering insert_device\n");
+-      len = sizeof(struct net_device) + sizeof(struct s_smc);
+-      new = (struct net_device *) kmalloc(len, GFP_KERNEL);
+-      if (new == NULL) {
+-              printk("fddi%d: Device not initialised, insufficient memory\n",
+-                     num_fddi);
+-              return NULL;
+-      } else {
+-              memset((char *) new, 0, len);
+-              new->priv = (struct s_smc *) (new + 1);
+-              new->init = init;       /* initialisation routine */
+-              if (!loading_module) {
+-                      new->next = dev->next;
+-                      dev->next = new;
+-              }
+-              /* create new device name */
+-              if (num_fddi > 999) {
+-                      sprintf(new->name, "fddi????");
+-              } else {
+-                      sprintf(new->name, "fddi%d", num_fddi);
+-              }
+-      }
+-      return new;
+-}                             // insert_device
+-
+-
+-/************************
+- *
+- * Get the number of a "fddiX" string
+- *
+- ************************/
+-static int fddi_dev_index(unsigned char *s)
+-{
+-      int i = 0, j = 0;
+-
+-      for (; *s; s++) {
+-              if (isdigit(*s)) {
+-                      j = 1;
+-                      i = (i * 10) + (*s - '0');
+-              } else if (j)
+-                      break;
+-      }
+-      return i;
+-}                             // fddi_dev_index
++      /* Initialize board structure with bus-specific info */
++      smc = (struct s_smc *) dev->priv;
++      smc->os.dev = dev;
++      smc->os.bus_type = SK_BUS_TYPE_PCI;
++      smc->os.pdev = *pdev;
++      smc->os.QueueSkb = MAX_TX_QUEUE_LEN;
++      smc->os.MaxFrameSize = MAX_FRAME_SIZE;
++      smc->os.dev = dev;
++      smc->hw.slot = -1;
++      smc->os.ResetRequested = FALSE;
++      skb_queue_head_init(&smc->os.SendSkbQueue);
++
++      err = skfp_driver_init(dev);
++      if (err)
++              goto err_out4;
++
++      err = register_netdev(dev);
++      if (err)
++              goto err_out5;
++
++      ++num_boards;
++      pci_set_drvdata(pdev, dev);
++
++      if ((pdev->subsystem_device & 0xff00) == 0x5500 ||
++          (pdev->subsystem_device & 0xff00) == 0x5800) 
++              printk("%s: SysKonnect FDDI PCI adapter"
++                     " found (SK-%04X)\n", dev->name, 
++                     pdev->subsystem_device);
++      else
++              printk("%s: FDDI PCI adapter found\n", dev->name);
++      return 0;
++err_out5:
++      if (smc->os.SharedMemAddr) 
++              pci_free_consistent(pdev, smc->os.SharedMemSize,
++                                  smc->os.SharedMemAddr, 
++                                  smc->os.SharedMemDMA);
++      pci_free_consistent(pdev, MAX_FRAME_SIZE,
++                          smc->os.LocalRxBuffer, smc->os.LocalRxBufferDMA);
++err_out4:
++#ifdef MEM_MAPPED_IO
++      iounmap((void *) dev->base_addr);
++#endif
++err_out3:
++      free_netdev(dev);
++err_out2:
++      pci_release_regions(pdev);
++err_out1:
++      return err;
++}
+-/************************
+- *
+- * Used if loaded as module only. Link the device structures
+- * together. Needed to release them all at unload.
+- *
+-************************/
+-static void link_modules(struct net_device *dev, struct net_device *tmp)
++/*
++ * Called for each adapter board from pci_unregister_driver
++ */
++static void __devexit skfp_remove_one(struct pci_dev *pdev)
+ {
+-      struct net_device *p = dev;
++      struct net_device *p = pci_get_drvdata(pdev);
++      struct s_smc *lp = p->priv;
+-      if (p) {
+-              while (((struct s_smc *) (p->priv))->os.next_module) {
+-                      p = ((struct s_smc *) (p->priv))->os.next_module;
+-              }
++      unregister_netdev(p);
+-              if (dev != tmp) {
+-                      ((struct s_smc *) (p->priv))->os.next_module = tmp;
+-              } else {
+-                      ((struct s_smc *) (p->priv))->os.next_module = NULL;
+-              }
++      if (lp->os.SharedMemAddr) {
++              pci_free_consistent(&lp->os.pdev,
++                                  lp->os.SharedMemSize,
++                                  lp->os.SharedMemAddr,
++                                  lp->os.SharedMemDMA);
++              lp->os.SharedMemAddr = NULL;
++      }
++      if (lp->os.LocalRxBuffer) {
++              pci_free_consistent(&lp->os.pdev,
++                                  MAX_FRAME_SIZE,
++                                  lp->os.LocalRxBuffer,
++                                  lp->os.LocalRxBufferDMA);
++              lp->os.LocalRxBuffer = NULL;
+       }
+-      return;
+-}                             // link_modules
+-
++#ifdef MEM_MAPPED_IO
++      iounmap((void *) p->base_addr);
++#endif
++      pci_release_regions(pdev);
++      free_netdev(p);
++      pci_set_drvdata(pdev, NULL);
++}
+ /*
+  * ====================
+@@ -653,11 +408,11 @@ static void link_modules(struct net_devi
+  *    0 - initialization succeeded
+  *   -1 - initialization failed
+  */
+-static int skfp_driver_init(struct net_device *dev)
++static  int skfp_driver_init(struct net_device *dev)
+ {
+       struct s_smc *smc = (struct s_smc *) dev->priv;
+       skfddi_priv *bp = PRIV(dev);
+-      u8 val;                 /* used for I/O read/writes */
++      int err = -EIO;
+       PRINTK(KERN_INFO "entering skfp_driver_init\n");
+@@ -666,9 +421,7 @@ static int skfp_driver_init(struct net_d
+       smc->hw.iop = dev->base_addr;
+       // Get the interrupt level from the PCI Configuration Table
+-      val = dev->irq;
+-
+-      smc->hw.irq = val;
++      smc->hw.irq = dev->irq;
+       spin_lock_init(&bp->DriverLock);
+       
+@@ -738,7 +491,7 @@ fail:
+                                   bp->LocalRxBuffer, bp->LocalRxBufferDMA);
+               bp->LocalRxBuffer = NULL;
+       }
+-      return (-1);
++      return err;
+ }                             // skfp_driver_init
+@@ -766,14 +519,15 @@ fail:
+ static int skfp_open(struct net_device *dev)
+ {
+       struct s_smc *smc = (struct s_smc *) dev->priv;
++      int err;
+       PRINTK(KERN_INFO "entering skfp_open\n");
+       /* Register IRQ - support shared interrupts by passing device ptr */
+-      if (request_irq(dev->irq, (void *) skfp_interrupt, SA_SHIRQ,
+-                      dev->name, dev)) {
+-              printk("%s: Requested IRQ %d is busy\n", dev->name, dev->irq);
+-              return (-EAGAIN);
+-      }
++      err = request_irq(dev->irq, (void *) skfp_interrupt, SA_SHIRQ,
++                        dev->name, dev);
++      if (err)
++              return err;
++
+       /*
+        * Set current address to factory MAC address
+        *
+@@ -797,6 +551,7 @@ static int skfp_open(struct net_device *
+       /* Disable promiscuous filter settings */
+       mac_drv_rx_mode(smc, RX_DISABLE_PROMISC);
++      netif_start_queue(dev);
+       return (0);
+ }                             // skfp_open
+@@ -831,7 +586,6 @@ static int skfp_open(struct net_device *
+ static int skfp_close(struct net_device *dev)
+ {
+       struct s_smc *smc = (struct s_smc *) dev->priv;
+-      struct sk_buff *skb;
+       skfddi_priv *bp = PRIV(dev);
+       CLI_FBI();
+@@ -844,13 +598,8 @@ static int skfp_close(struct net_device 
+       /* Deregister (free) IRQ */
+       free_irq(dev->irq, dev);
+-      for (;;) {
+-              skb = skb_dequeue(&bp->SendSkbQueue);
+-              if (skb == NULL)
+-                      break;
+-              bp->QueueSkb++;
+-              dev_kfree_skb(skb);
+-      }
++      skb_queue_purge(&bp->SendSkbQueue);
++      bp->QueueSkb = MAX_TX_QUEUE_LEN;
+       return (0);
+ }                             // skfp_close
+@@ -1285,6 +1034,8 @@ static int skfp_ioctl(struct net_device 
+               break;
+       default:
+               printk("ioctl for %s: unknow cmd: %04x\n", dev->name, ioc.cmd);
++              status = -EOPNOTSUPP;
++
+       }                       // switch
+       return status;
+@@ -2538,63 +2289,21 @@ void drv_reset_indication(struct s_smc *
+ }                             // drv_reset_indication
+-
+-static struct net_device *mdev;
++static struct pci_driver skfddi_pci_driver = {
++      .name           = "skfddi",
++      .id_table       = skfddi_pci_tbl,
++      .probe          = skfp_init_one,
++      .remove         = __devexit_p(skfp_remove_one),
++};
+ static int __init skfd_init(void)
+ {
+-      struct net_device *p;
+-
+-      if ((mdev = insert_device(NULL, skfp_probe)) == NULL)
+-              return -ENOMEM;
+-
+-      for (p = mdev; p != NULL; p = ((struct s_smc *)p->priv)->os.next_module) {
+-              if (register_netdev(p) != 0) {
+-                      printk("skfddi init_module failed\n");
+-                      return -EIO;
+-              }
+-      }
+-
+-      return 0;
++      return pci_module_init(&skfddi_pci_driver);
+ }
+-static struct net_device *unlink_modules(struct net_device *p)
+-{
+-      struct net_device *next = NULL;
+-
+-      if (p->priv) {          /* Private areas allocated? */
+-              struct s_smc *lp = (struct s_smc *) p->priv;
+-
+-              next = lp->os.next_module;
+-
+-              if (lp->os.SharedMemAddr) {
+-                      pci_free_consistent(&lp->os.pdev,
+-                                          lp->os.SharedMemSize,
+-                                          lp->os.SharedMemAddr,
+-                                          lp->os.SharedMemDMA);
+-                      lp->os.SharedMemAddr = NULL;
+-              }
+-              if (lp->os.LocalRxBuffer) {
+-                      pci_free_consistent(&lp->os.pdev,
+-                                          MAX_FRAME_SIZE,
+-                                          lp->os.LocalRxBuffer,
+-                                          lp->os.LocalRxBufferDMA);
+-                      lp->os.LocalRxBuffer = NULL;
+-              }
+-              release_region(p->base_addr, 
+-                      (lp->os.bus_type == SK_BUS_TYPE_PCI ? FP_IO_LEN : 0));
+-      }
+-      unregister_netdev(p);
+-      printk("%s: unloaded\n", p->name);
+-      free_netdev(p);         /* Free the device structure */
+-
+-      return next;
+-}                             // unlink_modules
+-
+ static void __exit skfd_exit(void)
+ {
+-      while (mdev)
+-              mdev = unlink_modules(mdev);
++      pci_unregister_driver(&skfddi_pci_driver);
+ }
+ module_init(skfd_init);
+--- linux-2.6.0/drivers/net/sk_g16.c   2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/sk_g16.c    2003-12-28 23:21:01.000000000 -0800
+@@ -457,8 +457,6 @@ struct priv
+ /* static variables */
+ static SK_RAM *board;  /* pointer to our memory mapped board components */
+-static struct net_device *SK_dev;
+-unsigned long SK_ioaddr;
+ static spinlock_t SK_lock = SPIN_LOCK_UNLOCKED;
+ /* Macros */
+@@ -472,7 +470,6 @@ static spinlock_t SK_lock = SPIN_LOCK_UN
+  * See for short explanation of each function its definitions header.
+  */
+-int          SK_init(struct net_device *dev);
+ static int   SK_probe(struct net_device *dev, short ioaddr);
+ static void  SK_timeout(struct net_device *dev);
+@@ -530,84 +527,71 @@ void SK_print_ram(struct net_device *dev
+  *     YY/MM/DD  uid  Description
+ -*/
++static int io;        /* 0 == probe */
++
+ /* 
+  * Check for a network adaptor of this type, and return '0' if one exists.
+  * If dev->base_addr == 0, probe all likely locations.
+  * If dev->base_addr == 1, always return failure.
+  */
+-int __init SK_init(struct net_device *dev)
++struct net_device * __init SK_init(int unit)
+ {
+-      int ioaddr;                        /* I/O port address used for POS regs */
+       int *port, ports[] = SK_IO_PORTS;  /* SK_G16 supported ports */
+       static unsigned version_printed;
++      struct net_device *dev = alloc_etherdev(sizeof(struct priv));
++      int err = -ENODEV;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+-      /* get preconfigured base_addr from dev which is done in Space.c */
+-      int base_addr = dev->base_addr; 
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++              io = dev->base_addr;
++      }
+       if (version_printed++ == 0)
+               PRINTK(("%s: %s", SK_NAME, rcsid));
+-      if (base_addr > 0x0ff)        /* Check a single specified address */
+-      {
+-          int rc = -ENODEV;
+-
+-          ioaddr = base_addr;
+-
+-          /* Check if on specified address is a SK_G16 */
+-          if (!request_region(ioaddr, ETHERCARD_TOTAL_SIZE, "sk_g16"))
+-              return -EBUSY;
+-
+-          if ( (inb(SK_POS0) == SK_IDLOW) ||
+-               (inb(SK_POS1) == SK_IDHIGH) )  
+-          {
+-              rc = SK_probe(dev, ioaddr);
+-          }
++      if (io > 0xff) {        /* Check a single specified address */
++              err = -EBUSY;
++              /* Check if on specified address is a SK_G16 */
++              if (request_region(io, ETHERCARD_TOTAL_SIZE, "sk_g16")) {
++                      err = SK_probe(dev, io);
++                      if (!err)
++                              goto got_it;
++                      release_region(io, ETHERCARD_TOTAL_SIZE);
++              }
++      } else if (io > 0) {       /* Don't probe at all */
++              err = -ENXIO;
++      } else {
++              /* Autoprobe base_addr */
++              for (port = &ports[0]; *port; port++) {
++                      io = *port;
++
++                      /* Check if I/O Port region is used by another board */
++                      if (!request_region(io, ETHERCARD_TOTAL_SIZE, "sk_g16"))
++                              continue;       /* Try next Port address */
++
++                      /* Check if at ioaddr is a SK_G16 */
++                      if (SK_probe(dev, io) == 0)
++                              goto got_it;
+-          if (rc)
+-              release_region(ioaddr, ETHERCARD_TOTAL_SIZE);
+-          return rc;
++                      release_region(io, ETHERCARD_TOTAL_SIZE);
++              }
+       }
+-      else if (base_addr > 0)       /* Don't probe at all */
+-      {
+-              return -ENXIO;
++err_out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++
++got_it:
++      err = register_netdev(dev);
++      if (err) {
++              release_region(dev->base_addr, ETHERCARD_TOTAL_SIZE);
++              goto err_out;
+       }
+-
+-      /* Autoprobe base_addr */
+-
+-      for (port = &ports[0]; *port; port++) 
+-      {
+-          ioaddr = *port;           /* we need ioaddr for accessing POS regs */
+-
+-          /* Check if I/O Port region is used by another board */
+-
+-          if (!request_region(ioaddr, ETHERCARD_TOTAL_SIZE, "sk_g16"))
+-          {
+-              continue;             /* Try next Port address */
+-          }
+-
+-          /* Check if at ioaddr is a SK_G16 */
+-
+-          if ( !(inb(SK_POS0) == SK_IDLOW) ||
+-               !(inb(SK_POS1) == SK_IDHIGH) )
+-          {
+-              release_region(ioaddr, ETHERCARD_TOTAL_SIZE);
+-              continue;             /* Try next Port address */
+-          }
+-
+-          dev->base_addr = ioaddr;  /* Set I/O Port Address */
+-
+-          if (SK_probe(dev, ioaddr) == 0)  
+-          {
+-              return 0; /* Card found and initialized */
+-          }
+-
+-          release_region(ioaddr, ETHERCARD_TOTAL_SIZE);
+-      }
+-
+-      dev->base_addr = base_addr;   /* Write back original base_addr */
+-
+-      return -ENODEV;                /* Failed to find or init driver */
++      return dev;
+ } /* End of SK_init */
+@@ -620,54 +604,25 @@ MODULE_PARM_DESC(io, "0 to probe common 
+ #ifdef MODULE
+-static int io;        /* 0 == probe */
++
++static struct net_device *SK_dev;
+ static int __init SK_init_module (void)
+ {
+-      int rc;
+-      
+-      SK_dev = init_etherdev (NULL, 0);
+-      if (!SK_dev)
+-              return -ENOMEM;
+-      
+-      SK_dev->base_addr = io;
+-
+-      rc = SK_init (SK_dev);
+-      if (rc) {
+-              unregister_netdev (SK_dev);
+-              kfree (SK_dev);
+-              SK_dev = NULL;
+-      }
+-      
+-      return rc;
++      SK_dev = SK_init(-1);
++      return IS_ERR(SK_dev) ? PTR_ERR(SK_dev) : 0;
+ }
+-#endif /* MODULE */
+-
+ static void __exit SK_cleanup_module (void)
+ {
+-      if (SK_dev) {
+-              if (SK_dev->priv) {
+-                      kfree(SK_dev->priv);
+-                      SK_dev->priv = NULL;
+-              }
+-              unregister_netdev(SK_dev);
+-              free_netdev(SK_dev);
+-              SK_dev = NULL;
+-      }
+-      if (SK_ioaddr) {
+-              release_region(SK_ioaddr, ETHERCARD_TOTAL_SIZE);
+-              SK_ioaddr = 0;
+-      }
+-              
++      unregister_netdev(SK_dev);
++      release_region(SK_dev->base_addr, ETHERCARD_TOTAL_SIZE);
++      free_netdev(SK_dev);
+ }
+-
+-#ifdef MODULE
+ module_init(SK_init_module);
+-#endif
+ module_exit(SK_cleanup_module);
+-
++#endif
\f
+ /*-
+@@ -695,7 +650,11 @@ int __init SK_probe(struct net_device *d
+     int sk_addr_flag = 0;   /* SK ADDR correct? 1 - no, 0 - yes */
+     unsigned int rom_addr;  /* used to store RAM address used for POS_ADDR */
+-    struct priv *p;         /* SK_G16 private structure */
++    struct priv *p = dev->priv;         /* SK_G16 private structure */
++
++    if (inb(SK_POS0) != SK_IDLOW || inb(SK_POS1) != SK_IDHIGH)
++      return -ENODEV;
++    dev->base_addr = ioaddr;
+     if (SK_ADDR & 0x3fff || SK_ADDR < 0xa0000)
+     {
+@@ -837,12 +796,6 @@ int __init SK_probe(struct net_device *d
+           dev->dev_addr[4],
+           dev->dev_addr[5]);
+-    /* Allocate memory for private structure */
+-    p = dev->priv = (void *) kmalloc(sizeof(struct priv), GFP_KERNEL);
+-    if (p == NULL) {
+-         printk("%s: ERROR - no memory for driver data!\n", dev->name);
+-         return -ENOMEM;
+-    }
+     memset((char *) dev->priv, 0, sizeof(struct priv)); /* clear memory */
+     /* Assign our Device Driver functions */
+@@ -856,10 +809,6 @@ int __init SK_probe(struct net_device *d
+     dev->watchdog_timeo               = HZ/7;
+-    /* Set the generic fields of the device structure */
+-
+-    ether_setup(dev);
+-    
+     dev->flags &= ~IFF_MULTICAST;
+     /* Initialize private structure */
+@@ -884,12 +833,7 @@ int __init SK_probe(struct net_device *d
+     SK_print_pos(dev, "End of SK_probe");
+     SK_print_ram(dev);
+ #endif 
+-
+-    SK_dev = dev;
+-    SK_ioaddr = ioaddr;
+-
+     return 0;                            /* Initialization done */
+-
+ } /* End of SK_probe() */
\f
+@@ -1280,7 +1224,7 @@ static int SK_send_packet(struct sk_buff
+       memcpy_toio((tmdp->u.buffer & 0x00ffffff), skb->data, skb->len);
+       if (len != skb->len)
+-              memcpy_toio((tmdp->u.buffer & 0x00ffffff) + sb->len, pad, len-skb->len);
++              memcpy_toio((tmdp->u.buffer & 0x00ffffff) + skb->len, pad, len-skb->len);
+       writew(-len, &tmdp->blen);            /* set length to transmit */
+--- linux-2.6.0/drivers/net/sk_mca.c   2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/sk_mca.c    2003-12-28 23:21:01.000000000 -0800
+@@ -1022,18 +1022,39 @@ static void skmca_set_multicast_list(str
+ static int startslot;         /* counts through slots when probing multiple devices */
+-int __init skmca_probe(struct net_device *dev)
++static void cleanup_card(struct net_device *dev)
+ {
++      skmca_priv *priv = dev->priv;
++      DeinitBoard(dev);
++      if (dev->irq != 0)
++              free_irq(dev->irq, dev);
++      mca_mark_as_unused(priv->slot);
++      mca_set_adapter_procfn(priv->slot, NULL, NULL);
++}
++
++struct net_device * __init skmca_probe(int unit)
++{
++      struct net_device *dev;
+       int force_detect = 0;
+       int junior, slot, i;
+       int base = 0, irq = 0;
+       skmca_priv *priv;
+       skmca_medium medium;
++      int err;
+       /* can't work without an MCA bus ;-) */
+       if (MCA_bus == 0)
+-              return -ENODEV;
++              return ERR_PTR(-ENODEV);
++
++      dev = alloc_etherdev(sizeof(skmca_priv));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
+       SET_MODULE_OWNER(dev);
+@@ -1044,37 +1065,24 @@ int __init skmca_probe(struct net_device
+       /* search through slots */
+-      if (dev != NULL) {
+-              base = dev->mem_start;
+-              irq = dev->irq;
+-      }
+-      slot = dofind(&junior, startslot);
+-
+-      while (slot != -1) {
++      base = dev->mem_start;
++      irq = dev->base_addr;
++      for (slot = startslot; (slot = dofind(&junior, slot)) != -1; slot++) {
+               /* deduce card addresses */
+               getaddrs(slot, junior, &base, &irq, &medium);
+               /* slot already in use ? */
+-              if (mca_is_adapter_used(slot)) {
+-                      slot = dofind(&junior, slot + 1);
++              if (mca_is_adapter_used(slot))
+                       continue;
+-              }
+               /* were we looking for something different ? */
+-              if ((dev->irq != 0) || (dev->mem_start != 0)) {
+-                      if ((dev->irq != 0) && (dev->irq != irq)) {
+-                              slot = dofind(&junior, slot + 1);
+-                              continue;
+-                      }
+-                      if ((dev->mem_start != 0)
+-                          && (dev->mem_start != base)) {
+-                              slot = dofind(&junior, slot + 1);
+-                              continue;
+-                      }
+-              }
++              if (dev->irq && dev->irq != irq)
++                      continue;
++              if (dev->mem_start && dev->mem_start != base)
++                      continue;
+               /* found something that matches */
+@@ -1083,8 +1091,10 @@ int __init skmca_probe(struct net_device
+       /* nothing found ? */
+-      if (slot == -1)
+-              return ((base != 0) || (irq != 0)) ? ENXIO : ENODEV;
++      if (slot == -1) {
++              free_netdev(dev);
++              return (base || irq) ? ERR_PTR(-ENXIO) : ERR_PTR(-ENODEV);
++      }
+       /* make procfs entries */
+@@ -1102,17 +1112,14 @@ int __init skmca_probe(struct net_device
+              junior ? "Junior MC2" : "MC2+", slot + 1);
+       /* allocate structure */
+-      priv = dev->priv =
+-          (skmca_priv *) kmalloc(sizeof(skmca_priv), GFP_KERNEL);
+-      if (!priv)
+-              return -ENOMEM;
++      priv = dev->priv;
+       priv->slot = slot;
+       priv->macbase = base + 0x3fc0;
+       priv->ioregaddr = base + 0x3ff0;
+       priv->ctrladdr = base + 0x3ff2;
+       priv->cmdaddr = base + 0x3ff3;
+       priv->medium = medium;
+-      memset(&(priv->stat), 0, sizeof(struct net_device_stats));
++      memset(&priv->stat, 0, sizeof(struct net_device_stats));
+       spin_lock_init(&priv->lock);
+       /* set base + irq for this device (irq not allocated so far) */
+@@ -1146,9 +1153,6 @@ int __init skmca_probe(struct net_device
+       dev->set_multicast_list = skmca_set_multicast_list;
+       dev->flags |= IFF_MULTICAST;
+-      /* generic setup */
+-      ether_setup(dev);
+-
+       /* copy out MAC address */
+       for (i = 0; i < 6; i++)
+               dev->dev_addr[i] = SKMCA_READB(priv->macbase + (i << 1));
+@@ -1167,7 +1171,13 @@ int __init skmca_probe(struct net_device
+       startslot = slot + 1;
+-      return 0;
++      err = register_netdev(dev);
++      if (err) {
++              cleanup_card(dev);
++              free_netdev(dev);
++              dev = ERR_PTR(err);
++      }
++      return dev;
+ }
+ /* ------------------------------------------------------------------------
+@@ -1179,51 +1189,34 @@ MODULE_LICENSE("GPL");
+ #define DEVMAX 5
+-static struct net_device moddevs[DEVMAX] = {
+-      { .name = "    ", .init = skmca_probe },
+-      { .name = "    ", .init = skmca_probe },
+-      { .name = "    ", .init = skmca_probe },
+-      { .name = "    ", .init = skmca_probe },
+-      { .name = "    ", .init = skmca_probe }
+-};
+-
+-int irq;
+-int io;
++static struct net_device *moddevs[DEVMAX];
+ int init_module(void)
+ {
+-      int z, res;
++      int z;
+       startslot = 0;
+       for (z = 0; z < DEVMAX; z++) {
+-              strcpy(moddevs[z].name, "     ");
+-              res = register_netdev(moddevs + z);
+-              if (res != 0)
+-                      return (z > 0) ? 0 : -EIO;
++              struct net_device *dev = skmca_probe(-1);
++              if (IS_ERR(dev))
++                      break;
++              moddevs[z] = dev;
+       }
+-
++      if (!z)
++              return -EIO;
+       return 0;
+ }
+ void cleanup_module(void)
+ {
+-      struct net_device *dev;
+-      skmca_priv *priv;
+       int z;
+       for (z = 0; z < DEVMAX; z++) {
+-              dev = moddevs + z;
+-              if (dev->priv != NULL) {
+-                      priv = (skmca_priv *) dev->priv;
+-                      DeinitBoard(dev);
+-                      if (dev->irq != 0)
+-                              free_irq(dev->irq, dev);
+-                      dev->irq = 0;
++              struct net_device *dev = moddevs[z];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      mca_mark_as_unused(priv->slot);
+-                      mca_set_adapter_procfn(priv->slot, NULL, NULL);
+-                      kfree(dev->priv);
+-                      dev->priv = NULL;
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/sk_mca.h   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/sk_mca.h    2003-12-28 23:21:01.000000000 -0800
+@@ -178,7 +178,4 @@ typedef struct {           /* LANCE Rx descriptor
+ #endif                                /* _SK_MCA_DRIVER_ */
+-extern int skmca_probe(struct net_device *);
+-
+-
+ #endif        /* _SK_MCA_INCLUDE_ */
+--- linux-2.6.0/drivers/net/smc9194.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/smc9194.c   2003-12-28 23:21:01.000000000 -0800
+@@ -191,7 +191,7 @@ struct smc_local {
+  .
+  . NB:This shouldn't be static since it is referred to externally.
+ */
+-int smc_init(struct net_device *dev);
++struct net_device *smc_init(int unit);
+ /*
+  . The kernel calls this function when someone wants to use the device,
+@@ -672,7 +672,7 @@ static void smc_hardware_send_packet( st
+ /*-------------------------------------------------------------------------
+  |
+- | smc_init( struct net_device * dev )
++ | smc_init(int unit)
+  |   Input parameters:
+  |    dev->base_addr == 0, try to find all possible locations
+  |    dev->base_addr == 1, return failure code
+@@ -680,31 +680,56 @@ static void smc_hardware_send_packet( st
+  |    dev->base_addr == <anything else>   this is the address to check
+  |
+  |   Output:
+- |    0 --> there is a device
+- |    anything else, error
++ |    pointer to net_device or ERR_PTR(error)
+  |
+  ---------------------------------------------------------------------------
+ */
+-int __init smc_init(struct net_device *dev)
++static int io;
++static int irq;
++static int ifport;
++
++struct net_device * __init smc_init(int unit)
+ {
+-      int i;
+-      int base_addr = dev->base_addr;
++      struct net_device *dev = alloc_etherdev(sizeof(struct smc_local));
++      unsigned *port;
++      int err = 0;
++
++      if (!dev)
++              return ERR_PTR(-ENODEV);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++              io = dev->base_addr;
++              irq = dev->irq;
++      }
+       SET_MODULE_OWNER(dev);
+-      /*  try a specific location */
+-      if (base_addr > 0x1ff)
+-              return smc_probe(dev, base_addr);
+-      else if (base_addr != 0)
+-              return -ENXIO;
+-
+-      /* check every ethernet address */
+-      for (i = 0; smc_portlist[i]; i++)
+-              if (smc_probe(dev, smc_portlist[i]) == 0)
+-                      return 0;
+-
+-      /* couldn't find anything */
+-      return -ENODEV;
++      if (io > 0x1ff) {       /* Check a single specified location. */
++              err = smc_probe(dev, io);
++      } else if (io != 0) {   /* Don't probe at all. */
++              err = -ENXIO;
++      } else {
++              for (port = smc_portlist; *port; port++) {
++                      if (smc_probe(dev, *port) == 0)
++                              break;
++              }
++              if (!*port)
++                      err = -ENODEV;
++      }
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, SMC_IO_EXTENT);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /*----------------------------------------------------------------------
+@@ -821,6 +846,9 @@ static int __init smc_probe(struct net_d
+       if (!request_region(ioaddr, SMC_IO_EXTENT, dev->name))
+               return -EBUSY;
++      dev->irq = irq;
++      dev->if_port = ifport;
++
+       /* First, see if the high byte is 0x33 */
+       bank = inw( ioaddr + BANK_SELECT );
+       if ( (bank & 0xFF00) != 0x3300 ) {
+@@ -969,28 +997,14 @@ static int __init smc_probe(struct net_d
+               printk("%2.2x:", dev->dev_addr[i] );
+       printk("%2.2x \n", dev->dev_addr[5] );
+-
+-      /* Initialize the private structure. */
+-      if (dev->priv == NULL) {
+-              dev->priv = kmalloc(sizeof(struct smc_local), GFP_KERNEL);
+-              if (dev->priv == NULL) {
+-                      retval = -ENOMEM;
+-                      goto err_out;
+-              }
+-      }
+       /* set the private data to zero by default */
+       memset(dev->priv, 0, sizeof(struct smc_local));
+-      /* Fill in the fields of the device structure with ethernet values. */
+-      ether_setup(dev);
+-
+       /* Grab the IRQ */
+               retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
+               if (retval) {
+               printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
+                       dev->irq, retval);
+-              kfree(dev->priv);
+-              dev->priv = NULL;
+               goto err_out;
+               }
+@@ -1524,10 +1538,7 @@ static void smc_set_multicast_list(struc
+ #ifdef MODULE
+-static struct net_device devSMC9194;
+-static int io;
+-static int irq;
+-static int ifport;
++static struct net_device *devSMC9194;
+ MODULE_LICENSE("GPL");
+ MODULE_PARM(io, "i");
+@@ -1539,32 +1550,23 @@ MODULE_PARM_DESC(ifport, "SMC 99194 inte
+ int init_module(void)
+ {
+-      int result;
+-
+       if (io == 0)
+               printk(KERN_WARNING
+               CARDNAME": You shouldn't use auto-probing with insmod!\n" );
+       /* copy the parameters from insmod into the device structure */
+-      devSMC9194.base_addr = io;
+-      devSMC9194.irq       = irq;
+-      devSMC9194.if_port      = ifport;
+-      devSMC9194.init         = smc_init;
+-      if ((result = register_netdev(&devSMC9194)) != 0)
+-              return result;
+-
++      devSMC9194 = smc_init(-1);
++      if (IS_ERR(devSMC9194))
++              return PTR_ERR(devSMC9194);
+       return 0;
+ }
+ void cleanup_module(void)
+ {
+-      unregister_netdev(&devSMC9194);
+-
+-      free_irq(devSMC9194.irq, &devSMC9194);
+-      release_region(devSMC9194.base_addr, SMC_IO_EXTENT);
+-
+-      if (devSMC9194.priv)
+-              kfree(devSMC9194.priv);
++      unregister_netdev(devSMC9194);
++      free_irq(devSMC9194->irq, devSMC9194);
++      release_region(devSMC9194->base_addr, SMC_IO_EXTENT);
++      free_netdev(devSMC9194);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/smc-mca.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/smc-mca.c   2003-12-28 23:21:01.000000000 -0800
+@@ -202,22 +202,18 @@ int __init ultramca_probe(struct device 
+               return -ENXIO;
+         /* Adapter found. */
+-      dev  = alloc_etherdev(0);
++      dev  = alloc_ei_netdev();
+       if(!dev)
+               return -ENODEV;
+       SET_MODULE_OWNER(dev);
+       SET_NETDEV_DEV(dev, gen_dev);
+-
+-      rc = register_netdev(dev);
+-      if (rc)
+-              goto err_free_netdev;
+-
+-      printk(KERN_INFO "%s: %s found in slot %d\n",
+-             dev->name, smc_mca_adapter_names[adapter], slot + 1);
+-
+       mca_device_set_name(mca_dev, smc_mca_adapter_names[adapter]);
+       mca_device_set_claim(mca_dev, 1);
++
++      printk(KERN_INFO "smc_mca: %s found in slot %d\n",
++                     smc_mca_adapter_names[adapter], slot + 1);
++
+       ultra_found++;
+       dev->base_addr = ioaddr = mca_device_transform_ioport(mca_dev, tbase);
+@@ -266,18 +262,18 @@ int __init ultramca_probe(struct device 
+       /* sanity check, shouldn't happen */
+       if (dev->mem_start == 0) {
+               rc = -ENODEV;
+-              goto err_unregister_netdev;
++              goto err_unclaim;
+       }
+       if (!request_region(ioaddr, ULTRA_IO_EXTENT, dev->name)) {
+               rc = -ENODEV;
+-              goto err_unregister_netdev;
++              goto err_unclaim;
+       }
+       reg4 = inb(ioaddr + 4) & 0x7f;
+       outb(reg4, ioaddr + 4);
+-      printk(KERN_INFO "%s: Parameters: %#3x,", dev->name, ioaddr);
++      printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x,", slot + 1, ioaddr);
+       for (i = 0; i < 6; i++)
+               printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
+@@ -299,14 +295,6 @@ int __init ultramca_probe(struct device 
+       outb(reg4, ioaddr + 4);
+-      /* Allocate dev->priv and fill in 8390 specific dev fields.
+-       */
+-
+-      rc = ethdev_init(dev);
+-      if (rc) {
+-              printk (", no memory for dev->priv.\n");
+-              goto err_release_region;
+-      }
+       gen_dev->driver_data = dev;
+       /* The 8390 isn't at the base address, so fake the offset
+@@ -339,13 +327,16 @@ int __init ultramca_probe(struct device 
+       NS8390_init(dev, 0);
++      rc = register_netdev(dev);
++      if (rc)
++              goto err_release_region;
++
+       return 0;
+ err_release_region:
+       release_region(ioaddr, ULTRA_IO_EXTENT);
+-err_unregister_netdev:
+-      unregister_netdev(dev);
+-err_free_netdev:
++err_unclaim:
++      mca_device_set_claim(mca_dev, 0);
+       free_netdev(dev);
+       return rc;
+ }
+@@ -463,14 +454,14 @@ static int ultramca_remove(struct device
+       struct mca_device *mca_dev = to_mca_device(gen_dev);
+       struct net_device *dev = (struct net_device *)gen_dev->driver_data;
+-      if(dev && dev->priv) {
++      if (dev) {
+               /* NB: ultra_close_card() does free_irq */
+               int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
++              unregister_netdev(dev);
+               mca_device_set_claim(mca_dev, 0);
+               release_region(ioaddr, ULTRA_IO_EXTENT);
+-              unregister_netdev(dev);
+-              kfree(dev->priv);
++              free_netdev(dev);
+       }
+       return 0;
+ }
+--- linux-2.6.0/drivers/net/smc-ultra32.c      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/smc-ultra32.c       2003-12-28 23:21:01.000000000 -0800
+@@ -61,7 +61,6 @@ static const char *version = "smc-ultra3
+ #include "8390.h"
+-int ultra32_probe(struct net_device *dev);
+ static int ultra32_probe1(struct net_device *dev, int ioaddr);
+ static int ultra32_open(struct net_device *dev);
+ static void ultra32_reset_8390(struct net_device *dev);
+@@ -98,26 +97,59 @@ static int ultra32_close(struct net_devi
+ #define ULTRA32_CFG6  (-0x15) /* 0xc8b */
+ #define ULTRA32_CFG7  0x0d    /* 0xcad */
++static void cleanup_card(struct net_device *dev)
++{
++      int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET;
++      /* NB: ultra32_close_card() does free_irq */
++      release_region(ioaddr, ULTRA32_IO_EXTENT);
++}
+ /*    Probe for the Ultra32.  This looks like a 8013 with the station
+       address PROM at I/O ports <base>+8 to <base>+13, with a checksum
+       following.
+ */
+-int __init ultra32_probe(struct net_device *dev)
++struct net_device * __init ultra32_probe(int unit)
+ {
+-      int ioaddr;
+-
+-      if (!EISA_bus) return -ENODEV;
++      struct net_device *dev;
++      int base;
++      int irq;
++      int err = -ENODEV;
++
++      if (!EISA_bus)
++              return ERR_PTR(-ENODEV);
++
++      dev = alloc_ei_netdev();
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
+       SET_MODULE_OWNER(dev);
+-      /* EISA spec allows for up to 16 slots, but 8 is typical. */
+-      for (ioaddr = 0x1000 + ULTRA32_BASE; ioaddr < 0x9000; ioaddr += 0x1000)
+-              if (ultra32_probe1(dev, ioaddr) == 0)
+-                      return 0;
++      irq = dev->irq;
+-      return -ENODEV;
++      /* EISA spec allows for up to 16 slots, but 8 is typical. */
++      for (base = 0x1000 + ULTRA32_BASE; base < 0x9000; base += 0x1000) {
++              if (ultra32_probe1(dev, base) == 0)
++                      break;
++              dev->irq = irq;
++      }
++      if (base >= 0x9000)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
+@@ -210,13 +242,6 @@ static int __init ultra32_probe1(struct 
+               dev->irq = irq;
+       }
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev)) {
+-              printk (", no memory for dev->priv.\n");
+-                retval = -ENOMEM;
+-              goto out;
+-        }
+-
+       /* The 8390 isn't at the base address, so fake the offset */
+       dev->base_addr = ioaddr + ULTRA32_NIC_OFFSET;
+@@ -380,7 +405,7 @@ static void ultra32_block_output(struct 
\f
+ #ifdef MODULE
+ #define MAX_ULTRA32_CARDS   4 /* Max number of Ultra cards per module */
+-static struct net_device dev_ultra[MAX_ULTRA32_CARDS];
++static struct net_device *dev_ultra[MAX_ULTRA32_CARDS];
+ MODULE_DESCRIPTION("SMC Ultra32 EISA ethernet driver");
+ MODULE_LICENSE("GPL");
+@@ -390,18 +415,15 @@ int init_module(void)
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ultra[this_dev];
+-              dev->init = ultra32_probe;
+-              if (register_netdev(dev) != 0) {
+-                      if (found > 0) { /* Got at least one. */
+-                              return 0;
+-                      }
+-                      printk(KERN_WARNING "smc-ultra32.c: No SMC Ultra32 found.\n");
+-                      return -ENXIO;
+-              }
+-              found++;
++              struct net_device *dev = ultra32_probe(-1);
++              if (IS_ERR(dev))
++                      break;
++              dev_ultra[found++] = dev;
+       }
+-      return 0;
++      if (found)
++              return 0;
++      printk(KERN_WARNING "smc-ultra32.c: No SMC Ultra32 found.\n");
++      return -ENXIO;
+ }
+ void cleanup_module(void)
+@@ -409,14 +431,11 @@ void cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ultra[this_dev];
+-              if (dev->priv != NULL) {
+-                      int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET;
+-                      void *priv = dev->priv;
+-                      /* NB: ultra32_close_card() does free_irq */
+-                      release_region(ioaddr, ULTRA32_IO_EXTENT);
++              struct net_device *dev = dev_ultra[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(priv);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/smc-ultra.c        2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/smc-ultra.c 2003-12-28 23:21:01.000000000 -0800
+@@ -76,7 +76,6 @@ static const char version[] =
+ static unsigned int ultra_portlist[] __initdata =
+ {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0};
+-int ultra_probe(struct net_device *dev);
+ static int ultra_probe1(struct net_device *dev, int ioaddr);
+ #ifdef __ISAPNP__
+@@ -122,18 +121,30 @@ MODULE_DEVICE_TABLE(isapnp, ultra_device
+ #define ULTRA_IO_EXTENT 32
+ #define EN0_ERWCNT            0x08    /* Early receive warning count. */
\f
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void ultra_poll(struct net_device *dev)
++{
++      disable_irq(dev->irq);
++      ei_interrupt(dev->irq, dev, NULL);
++      enable_irq(dev->irq);
++}
++#endif
+ /*    Probe for the Ultra.  This looks like a 8013 with the station
+       address PROM at I/O ports <base>+8 to <base>+13, with a checksum
+       following.
+ */
+-int __init ultra_probe(struct net_device *dev)
++static int __init do_ultra_probe(struct net_device *dev)
+ {
+       int i;
+       int base_addr = dev->base_addr;
++      int irq = dev->irq;
+       SET_MODULE_OWNER(dev);
++#ifdef CONFIG_NET_POLL_CONTROLLER
++      dev->poll_controller = &ultra_poll;
++#endif
+       if (base_addr > 0x1ff)          /* Check a single specified location. */
+               return ultra_probe1(dev, base_addr);
+       else if (base_addr != 0)        /* Don't probe at all. */
+@@ -147,13 +158,51 @@ int __init ultra_probe(struct net_device
+       printk(KERN_NOTICE "smc-ultra.c: No ISAPnP cards found, trying standard ones...\n");
+ #endif
+-      for (i = 0; ultra_portlist[i]; i++)
++      for (i = 0; ultra_portlist[i]; i++) {
++              dev->irq = irq;
+               if (ultra_probe1(dev, ultra_portlist[i]) == 0)
+                       return 0;
++      }
+       return -ENODEV;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      /* NB: ultra_close_card() does free_irq */
++#ifdef __ISAPNP__
++      struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
++      if (idev)
++              pnp_device_detach(idev);
++#endif
++      release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT);
++}
++
++struct net_device * __init ultra_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_ultra_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
+ {
+       int i, retval;
+@@ -226,13 +275,6 @@ static int __init ultra_probe1(struct ne
+               eeprom_irq = 1;
+       }
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev)) {
+-              printk (", no memory for dev->priv.\n");
+-                retval = -ENOMEM;
+-              goto out;
+-        }
+-
+       /* The 8390 isn't at the base address, so fake the offset */
+       dev->base_addr = ioaddr+ULTRA_NIC_OFFSET;
+@@ -500,7 +542,7 @@ ultra_close_card(struct net_device *dev)
\f
+ #ifdef MODULE
+ #define MAX_ULTRA_CARDS       4       /* Max number of Ultra cards per module */
+-static struct net_device dev_ultra[MAX_ULTRA_CARDS];
++static struct net_device *dev_ultra[MAX_ULTRA_CARDS];
+ static int io[MAX_ULTRA_CARDS];
+ static int irq[MAX_ULTRA_CARDS];
+@@ -516,26 +558,33 @@ ISA device autoprobes on a running machi
+ int
+ init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ultra[this_dev];
+-              dev->irq = irq[this_dev];
+-              dev->base_addr = io[this_dev];
+-              dev->init = ultra_probe;
+               if (io[this_dev] == 0)  {
+                       if (this_dev != 0) break; /* only autoprobe 1st one */
+                       printk(KERN_NOTICE "smc-ultra.c: Presently autoprobing (not recommended) for a single card.\n");
+               }
+-              if (register_netdev(dev) != 0) {
+-                      printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
+-                      if (found != 0) return 0;       /* Got at least one. */
+-                      return -ENXIO;
++              dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
++              dev->irq = irq[this_dev];
++              dev->base_addr = io[this_dev];
++              if (do_ultra_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_ultra[found++] = dev;
++                              continue;
++                      }
++                      cleanup_card(dev);
+               }
+-              found++;
++              free_netdev(dev);
++              printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
++              break;
+       }
+-
+-      return 0;
++      if (found)
++              return 0;
++      return -ENXIO;
+ }
+ void
+@@ -544,20 +593,11 @@ cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_ultra[this_dev];
+-              if (dev->priv != NULL) {
+-                      /* NB: ultra_close_card() does free_irq */
+-                      int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
+-
+-#ifdef __ISAPNP__
+-                      struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+-                      if (idev)
+-                              pnp_device_detach(idev);
+-#endif
+-
++              struct net_device *dev = dev_ultra[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      release_region(ioaddr, ULTRA_IO_EXTENT);
+-                      kfree(dev->priv);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/Space.c    2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/Space.c     2003-12-28 23:21:06.000000000 -0800
+@@ -40,63 +40,62 @@
+    ethernet adaptor have the name "eth[0123...]".
+    */
+-extern int ne2_probe(struct net_device *dev);
+-extern int hp100_probe(struct net_device *dev);
+-extern int ultra_probe(struct net_device *dev);
+-extern int ultra32_probe(struct net_device *dev);
+-extern int wd_probe(struct net_device *dev);
+-extern int el2_probe(struct net_device *dev);
+-extern int ne_probe(struct net_device *dev);
+-extern int hp_probe(struct net_device *dev);
+-extern int hp_plus_probe(struct net_device *dev);
+-extern int express_probe(struct net_device *);
+-extern int eepro_probe(struct net_device *);
+-extern int at1500_probe(struct net_device *);
+-extern int at1700_probe(struct net_device *);
+-extern int fmv18x_probe(struct net_device *);
+-extern int eth16i_probe(struct net_device *);
+-extern int i82596_probe(struct net_device *);
+-extern int ewrk3_probe(struct net_device *);
+-extern int el1_probe(struct net_device *);
+-extern int wavelan_probe(struct net_device *);
+-extern int arlan_probe(struct net_device *);
+-extern int el16_probe(struct net_device *);
+-extern int elmc_probe(struct net_device *);
+-extern int skmca_probe(struct net_device *);
+-extern int elplus_probe(struct net_device *);
+-extern int ac3200_probe(struct net_device *);
+-extern int es_probe(struct net_device *);
+-extern int lne390_probe(struct net_device *);
+-extern int e2100_probe(struct net_device *);
+-extern int ni5010_probe(struct net_device *);
+-extern int ni52_probe(struct net_device *);
+-extern int ni65_probe(struct net_device *);
+-extern int sonic_probe(struct net_device *);
+-extern int SK_init(struct net_device *);
+-extern int seeq8005_probe(struct net_device *);
+-extern int smc_init( struct net_device * );
+-extern int atarilance_probe(struct net_device *);
+-extern int sun3lance_probe(struct net_device *);
+-extern int sun3_82586_probe(struct net_device *);
+-extern int apne_probe(struct net_device *);
+-extern int bionet_probe(struct net_device *);
+-extern int pamsnet_probe(struct net_device *);
+-extern int cs89x0_probe(struct net_device *dev);
+-extern int hplance_probe(struct net_device *dev);
+-extern int bagetlance_probe(struct net_device *);
+-extern int mvme147lance_probe(struct net_device *dev);
+-extern int tc515_probe(struct net_device *dev);
+-extern int lance_probe(struct net_device *dev);
+-extern int mace_probe(struct net_device *dev);
+-extern int macsonic_probe(struct net_device *dev);
+-extern int mac8390_probe(struct net_device *dev);
+-extern int mac89x0_probe(struct net_device *dev);
+-extern int mc32_probe(struct net_device *dev);
++extern struct net_device *ne2_probe(int unit);
++extern struct net_device *hp100_probe(int unit);
++extern struct net_device *ultra_probe(int unit);
++extern struct net_device *ultra32_probe(int unit);
++extern struct net_device *wd_probe(int unit);
++extern struct net_device *el2_probe(int unit);
++extern struct net_device *ne_probe(int unit);
++extern struct net_device *hp_probe(int unit);
++extern struct net_device *hp_plus_probe(int unit);
++extern struct net_device *express_probe(int unit);
++extern struct net_device *eepro_probe(int unit);
++extern struct net_device *at1700_probe(int unit);
++extern struct net_device *fmv18x_probe(int unit);
++extern struct net_device *eth16i_probe(int unit);
++extern struct net_device *i82596_probe(int unit);
++extern struct net_device *ewrk3_probe(int unit);
++extern struct net_device *el1_probe(int unit);
++extern struct net_device *wavelan_probe(int unit);
++extern struct net_device *arlan_probe(int unit);
++extern struct net_device *el16_probe(int unit);
++extern struct net_device *elmc_probe(int unit);
++extern struct net_device *skmca_probe(int unit);
++extern struct net_device *elplus_probe(int unit);
++extern struct net_device *ac3200_probe(int unit);
++extern struct net_device *es_probe(int unit);
++extern struct net_device *lne390_probe(int unit);
++extern struct net_device *e2100_probe(int unit);
++extern struct net_device *ni5010_probe(int unit);
++extern struct net_device *ni52_probe(int unit);
++extern struct net_device *ni65_probe(int unit);
++extern struct net_device *sonic_probe(int unit);
++extern struct net_device *SK_init(int unit);
++extern struct net_device *seeq8005_probe(int unit);
++extern struct net_device *smc_init(int unit);
++extern struct net_device *atarilance_probe(int unit);
++extern struct net_device *sun3lance_probe(int unit);
++extern struct net_device *sun3_82586_probe(int unit);
++extern struct net_device *apne_probe(int unit);
++extern struct net_device *bionet_probe(int unit);
++extern struct net_device *pamsnet_probe(int unit);
++extern struct net_device *cs89x0_probe(int unit);
++extern struct net_device *hplance_probe(int unit);
++extern struct net_device *bagetlance_probe(int unit);
++extern struct net_device *mvme147lance_probe(int unit);
++extern struct net_device *tc515_probe(int unit);
++extern struct net_device *lance_probe(int unit);
++extern struct net_device *mace_probe(int unit);
++extern struct net_device *macsonic_probe(int unit);
++extern struct net_device *mac8390_probe(int unit);
++extern struct net_device *mac89x0_probe(int unit);
++extern struct net_device *mc32_probe(int unit);
+ extern struct net_device *cops_probe(int unit);
+ extern struct net_device *ltpc_probe(void);
+   
+ /* Detachable devices ("pocket adaptors") */
+-extern int de620_probe(struct net_device *);
++extern struct net_device *de620_probe(int unit);
+ /* Fibre Channel adapters */
+ extern int iph5526_probe(struct net_device *dev);
+@@ -104,33 +103,22 @@ extern int iph5526_probe(struct net_devi
+ /* SBNI adapters */
+ extern int sbni_probe(int unit);
+-struct devprobe
+-{
+-      int (*probe)(struct net_device *dev);
++struct devprobe2 {
++      struct net_device *(*probe)(int unit);
+       int status;     /* non-zero if autoprobe has failed */
+ };
+-/*
+- * probe_list walks a list of probe functions and calls each so long
+- * as a non-zero ioaddr is given, or as long as it hasn't already failed 
+- * to find a card in the past (as recorded by "status") when asked to
+- * autoprobe (i.e. a probe that fails to find a card when autoprobing
+- * will not be asked to autoprobe again).  It exits when a card is found.
+- */
+-static int __init probe_list(struct net_device *dev, struct devprobe *plist)
++static int __init probe_list2(int unit, struct devprobe2 *p, int autoprobe)
+ {
+-      struct devprobe *p = plist;
+-      unsigned long base_addr = dev->base_addr;
+-
+-      while (p->probe != NULL) {
+-              if (base_addr && p->probe(dev) == 0)    /* probe given addr */
++      struct net_device *dev;
++      for (; p->probe; p++) {
++              if (autoprobe && p->status)
++                      continue;
++              dev = p->probe(unit);
++              if (!IS_ERR(dev))
+                       return 0;
+-              else if (p->status == 0) {              /* has autoprobe failed yet? */
+-                      p->status = p->probe(dev);      /* no, try autoprobe */
+-                      if (p->status == 0)
+-                              return 0;
+-              }
+-              p++;
++              if (autoprobe)
++                      p->status = PTR_ERR(dev);
+       }
+       return -ENODEV;
+ }
+@@ -141,7 +129,8 @@ static int __init probe_list(struct net_
+  * drivers that probe for EISA cards (in the ISA group).  These are the
+  * legacy EISA only driver probes, and also the legacy PCI probes
+  */
+-static struct devprobe eisa_probes[] __initdata = {
++
++static struct devprobe2 eisa_probes[] __initdata = {
+ #ifdef CONFIG_ULTRA32 
+       {ultra32_probe, 0},     
+ #endif
+@@ -157,8 +146,7 @@ static struct devprobe eisa_probes[] __i
+       {NULL, 0},
+ };
+-
+-static struct devprobe mca_probes[] __initdata = {
++static struct devprobe2 mca_probes[] __initdata = {
+ #ifdef CONFIG_NE2_MCA
+       {ne2_probe, 0},
+ #endif
+@@ -178,7 +166,7 @@ static struct devprobe mca_probes[] __in
+  * ISA probes that touch addresses < 0x400 (including those that also
+  * look for EISA/PCI/MCA cards in addition to ISA cards).
+  */
+-static struct devprobe isa_probes[] __initdata = {
++static struct devprobe2 isa_probes[] __initdata = {
+ #ifdef CONFIG_HP100           /* ISA, EISA & PCI */
+       {hp100_probe, 0},
+ #endif        
+@@ -215,9 +203,6 @@ static struct devprobe isa_probes[] __in
+ #ifdef CONFIG_SEEQ8005 
+       {seeq8005_probe, 0},
+ #endif
+-#ifdef CONFIG_AT1500
+-      {at1500_probe, 0},
+-#endif
+ #ifdef CONFIG_CS89x0
+       {cs89x0_probe, 0},
+ #endif
+@@ -272,14 +257,14 @@ static struct devprobe isa_probes[] __in
+       {NULL, 0},
+ };
+-static struct devprobe parport_probes[] __initdata = {
++static struct devprobe2 parport_probes[] __initdata = {
+ #ifdef CONFIG_DE620           /* D-Link DE-620 adapter */
+       {de620_probe, 0},
+ #endif
+       {NULL, 0},
+ };
+-static struct devprobe m68k_probes[] __initdata = {
++static struct devprobe2 m68k_probes[] __initdata = {
+ #ifdef CONFIG_ATARILANCE      /* Lance-based Atari ethernet boards */
+       {atarilance_probe, 0},
+ #endif
+@@ -319,7 +304,7 @@ static struct devprobe m68k_probes[] __i
+       {NULL, 0},
+ };
+-static struct devprobe mips_probes[] __initdata = {
++static struct devprobe2 mips_probes[] __initdata = {
+ #ifdef CONFIG_MIPS_JAZZ_SONIC
+       {sonic_probe, 0},
+ #endif
+@@ -334,83 +319,65 @@ static struct devprobe mips_probes[] __i
+  * per bus interface. This drives the legacy devices only for now.
+  */
+  
+-static int __init ethif_probe(int unit)
++static void __init ethif_probe2(int unit)
+ {
+-      struct net_device *dev;
+-      int err = -ENODEV;
++      unsigned long base_addr = netdev_boot_base("eth", unit);
+-      dev = alloc_etherdev(0);
+-      if (!dev)
+-              return -ENOMEM;
+-
+-      sprintf(dev->name, "eth%d", unit);
+-      netdev_boot_setup_check(dev);
+-
+-      /* 
+-       * Backwards compatibility - historically an I/O base of 1 was 
+-       * used to indicate not to probe for this ethN interface 
+-       */
+-      if (dev->base_addr == 1) {
+-              free_netdev(dev);
+-              return -ENXIO;
+-      }
+-
+-      /* 
+-       * The arch specific probes are 1st so that any on-board ethernet
+-       * will be probed before other ISA/EISA/MCA/PCI bus cards.
+-       */
+-      if (probe_list(dev, m68k_probes) == 0 ||
+-          probe_list(dev, mips_probes) == 0 ||
+-          probe_list(dev, eisa_probes) == 0 ||
+-          probe_list(dev, mca_probes) == 0 ||
+-          probe_list(dev, isa_probes) == 0 ||
+-          probe_list(dev, parport_probes) == 0) 
+-              err = register_netdev(dev);
+-
+-      if (err)
+-              free_netdev(dev);
+-      return err;
++      if (base_addr == 1)
++              return;
++      (void)( probe_list2(unit, m68k_probes, base_addr == 0) &&
++              probe_list2(unit, mips_probes, base_addr == 0) &&
++              probe_list2(unit, eisa_probes, base_addr == 0) &&
++              probe_list2(unit, mca_probes, base_addr == 0) &&
++              probe_list2(unit, isa_probes, base_addr == 0) &&
++              probe_list2(unit, parport_probes, base_addr == 0));
+ }
+ #ifdef CONFIG_TR
+ /* Token-ring device probe */
+-extern int ibmtr_probe(struct net_device *);
+-extern int sk_isa_probe(struct net_device *);
+-extern int proteon_probe(struct net_device *);
+-extern int smctr_probe(struct net_device *);
++extern int ibmtr_probe_card(struct net_device *);
++extern struct net_device *sk_isa_probe(int unit);
++extern struct net_device *proteon_probe(int unit);
++extern struct net_device *smctr_probe(int unit);
++
++static struct devprobe2 tr_probes2[] __initdata = {
++#ifdef CONFIG_SKISA
++      {sk_isa_probe, 0},
++#endif
++#ifdef CONFIG_PROTEON
++      {proteon_probe, 0},
++#endif
++#ifdef CONFIG_SMCTR
++      {smctr_probe, 0},
++#endif
++      {NULL, 0},
++};
+ static __init int trif_probe(int unit)
+ {
+-      struct net_device *dev;
+       int err = -ENODEV;
+-      
+-      dev = alloc_trdev(0);
++#ifdef CONFIG_IBMTR
++      struct net_device *dev = alloc_trdev(0);
+       if (!dev)
+               return -ENOMEM;
+       sprintf(dev->name, "tr%d", unit);
+       netdev_boot_setup_check(dev);
+-      if (
+-#ifdef CONFIG_IBMTR
+-          ibmtr_probe(dev) == 0  ||
+-#endif
+-#ifdef CONFIG_SKISA
+-          sk_isa_probe(dev) == 0 || 
+-#endif
+-#ifdef CONFIG_PROTEON
+-          proteon_probe(dev) == 0 ||
+-#endif
+-#ifdef CONFIG_SMCTR
+-          smctr_probe(dev) == 0 ||
+-#endif
+-          0 ) 
+-              err = register_netdev(dev);
+-              
++      err = ibmtr_probe_card(dev);
+       if (err)
+               free_netdev(dev);
++#endif
+       return err;
++}
++
++static void __init trif_probe2(int unit)
++{
++      unsigned long base_addr = netdev_boot_base("tr", unit);
++      if (base_addr == 1)
++              return;
++      probe_list2(unit, tr_probes2, base_addr == 0);
+ }
+ #endif
+@@ -437,10 +404,11 @@ static int __init net_olddevs_init(void)
+ #endif
+ #ifdef CONFIG_TR
+       for (num = 0; num < 8; ++num)
+-              trif_probe(num);
++              if (!trif_probe(num))
++                      trif_probe2(num);
+ #endif
+       for (num = 0; num < 8; ++num)
+-              ethif_probe(num);
++              ethif_probe2(num);
+ #ifdef CONFIG_COPS
+       cops_probe(0);
+--- linux-2.6.0/drivers/net/starfire.c 2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/starfire.c  2003-12-28 23:21:01.000000000 -0800
+@@ -139,7 +139,6 @@ TODO:      bugfixes (no bugs known as of righ
+ #include <linux/config.h>
+ #include <linux/version.h>
+ #include <linux/module.h>
+-#include <asm/io.h>
+ #include <linux/kernel.h>
+ #include <linux/pci.h>
+ #include <linux/netdevice.h>
+--- linux-2.6.0/drivers/net/stnic.c    2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/net/stnic.c     2003-12-28 23:21:01.000000000 -0800
+@@ -98,28 +98,20 @@ STNIC_WRITE (int reg, byte val)
+   STNIC_DELAY ();
+ }
\f
+-int __init stnic_probe(void)
++static int __init stnic_probe(void)
+ {
+   struct net_device *dev;
+-  int i;
++  int i, err;
+   /* If we are not running on a SolutionEngine, give up now */
+   if (! MACH_SE)
+     return -ENODEV;
+   /* New style probing API */
+-  dev = init_etherdev (NULL, 0);
++  dev = alloc_ei_netdev();
+   if (!dev)
+       return -ENOMEM;
+   SET_MODULE_OWNER(dev);
+-  stnic_dev = dev;
+-
+-  /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-  if (ethdev_init (dev))
+-    {
+-      printk (KERN_EMERG "Unable to get memory for dev->priv.\n");
+-      return -ENOMEM;
+-    }
+ #ifdef CONFIG_SH_STANDARD_BIOS 
+   sh_bios_get_node_addr (stnic_eadr);
+@@ -135,13 +127,11 @@ int __init stnic_probe(void)
+   /* Snarf the interrupt now.  There's no point in waiting since we cannot
+      share and the board will usually be enabled. */
+-  i = request_irq (dev->irq, ei_interrupt, 0, dev->name, dev);
+-  if (i)  {
++  err = request_irq (dev->irq, ei_interrupt, 0, dev->name, dev);
++  if (err)  {
+       printk (KERN_EMERG " unable to get IRQ %d.\n", dev->irq);
+-      unregister_netdev(dev);
+-      kfree(dev->priv);
+-      kfree(dev);
+-      return i;
++      free_netdev(dev);
++      return err;
+     }
+   ei_status.name = dev->name;
+@@ -162,6 +152,14 @@ int __init stnic_probe(void)
+   stnic_init (dev);
++  err = register_netdev(dev);
++  if (err) {
++    free_irq(dev->irq, dev);
++    free_netdev(dev);
++    return err;
++  }
++  stnic_dev = dev;
++
+   printk (KERN_INFO "NS ST-NIC 83902A\n");
+   return 0;
+@@ -305,15 +303,13 @@ stnic_init (struct net_device *dev)
+   return;
+ }
+-/* Hardware interrupt handler.  */
+-extern void ei_interrupt (int irq, void *dev_id, struct pt_regs *regs);
+-
+-void
+-do_stnic_intr (int irq, void *dev_id, struct pt_regs *regs)
++static void __exit stnic_cleanup(void)
+ {
+-  ei_interrupt (0, stnic_dev, regs);
++      unregister_netdev(stnic_dev);
++      free_irq(stnic_dev->irq, stnic_dev);
++      free_netdev(stnic_dev);
+ }
+ module_init(stnic_probe);
+-/* No cleanup routine. */
++module_exit(stnic_cleanup);
+ MODULE_LICENSE("GPL");
+--- linux-2.6.0/drivers/net/sun3_82586.c       2003-06-14 12:18:22.000000000 -0700
++++ 25/drivers/net/sun3_82586.c        2003-12-28 23:21:01.000000000 -0800
+@@ -55,6 +55,7 @@ static int fifo=0x8; /* don't change */
+ #define DEBUG       /* debug on */
+ #define SYSBUSVAL 0 /* 16 Bit */
++#define SUN3_82586_TOTAL_SIZE PAGE_SIZE
+ #define sun3_attn586()  {*(volatile unsigned char *)(dev->base_addr) |= IEOB_ATTEN; *(volatile unsigned char *)(dev->base_addr) &= ~IEOB_ATTEN;}
+ #define sun3_reset586() {*(volatile unsigned char *)(dev->base_addr) = 0; udelay(100); *(volatile unsigned char *)(dev->base_addr) = IEOB_NORSET;}
+@@ -277,10 +278,12 @@ static void alloc586(struct net_device *
+       memset((char *)p->scb,0,sizeof(struct scb_struct));
+ }
+-int __init sun3_82586_probe(struct net_device *dev)
++struct net_device * __init sun3_82586_probe(int unit)
+ {
++      struct net_device *dev;
+       unsigned long ioaddr;
+       static int found = 0;
++      int err = -ENOMEM;
+       
+       /* check that this machine has an onboard 82586 */
+       switch(idprom->id_machtype) {
+@@ -290,31 +293,51 @@ int __init sun3_82586_probe(struct net_d
+               break;
+       default:
+-              return(-ENODEV);
++              return ERR_PTR(-ENODEV);
+       }
+-      if(found)
+-              return -ENODEV;
++      if (found)
++              return ERR_PTR(-ENODEV);
+       
+-      ioaddr = (unsigned long)ioremap(IE_OBIO, PAGE_SIZE);
++      ioaddr = (unsigned long)ioremap(IE_OBIO, SUN3_82586_TOTAL_SIZE);
++      if (!ioaddr)
++              return ERR_PTR(-ENOMEM);
+       found = 1;
+       
++      dev = alloc_etherdev(sizeof(struct priv));
++      if (!dev)
++              goto out;
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++      }
+       SET_MODULE_OWNER(dev);
+       dev->irq = IE_IRQ;
+       dev->base_addr = ioaddr;
+-      if(sun3_82586_probe1(dev, ioaddr) == 0)
+-              return 0;
+-
+-      return -ENODEV;
++      err = sun3_82586_probe1(dev, ioaddr);
++      if (err)
++              goto out1;
++      err = register_netdev(dev);
++      if (err)
++              goto out2;
++      return dev;
++
++out2:
++      release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
++out1:
++      free_netdev(dev);
++out:
++      iounmap((void *)ioaddr);
++      return ERR_PTR(err);
+ }
+ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
+ {
+       int i, size, retval;
+-//    if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, dev->name))
+-//            return -EBUSY;
++      if (!request_region(ioaddr, SUN3_82586_TOTAL_SIZE, dev->name))
++              return -EBUSY;
+       /* copy in the ethernet address from the prom */
+       for(i = 0; i < 6 ; i++)
+@@ -341,16 +364,6 @@ static int __init sun3_82586_probe1(stru
+               goto out;
+       }
+-      dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
+-      if(dev->priv == NULL) {
+-              printk("%s: Ooops .. can't allocate private driver memory.\n",dev->name);
+-              retval = -ENOMEM;
+-              goto out;
+-      }
+-
+-      /* warning: we don't free it on errors */
+-      memset((char *) dev->priv,0,sizeof(struct priv));
+-
+       ((struct priv *) (dev->priv))->memtop = (char *)dvma_btov(dev->mem_start);
+       ((struct priv *) (dev->priv))->base = (unsigned long) dvma_btov(0);
+       alloc586(dev);
+@@ -374,11 +387,9 @@ static int __init sun3_82586_probe1(stru
+       dev->set_multicast_list = set_multicast_list;
+       dev->if_port            = 0;
+-
+-      ether_setup(dev);
+-
+       return 0;
+ out:
++      release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
+       return retval;
+ }
+@@ -1138,21 +1149,23 @@ static void set_multicast_list(struct ne
+ #ifdef MODULE
+ #error This code is not currently supported as a module
+-static struct net_device dev_sun3_82586;
++static struct net_device *dev_sun3_82586;
+ int init_module(void)
+ {
+-      dev_sun3_82586.init = sun3_82586_probe;
+-      if (register_netdev(&dev_sun3_82586) != 0)
+-              return -EIO;
++      dev_sun3_82586 = sun3_82586_probe(-1);
++      if (IS_ERR(dev_sun3_82586))
++              return PTR_ERR(dev_sun3_82586);
+       return 0;
+ }
+ void cleanup_module(void)
+ {
+-      unregister_netdev(&dev_sun3_82586);
+-      kfree(dev_sun3_82586.priv);
+-      dev_sun3_82586.priv = NULL;
++      unsigned long ioaddr = dev_sun3_82586->base_addr;
++      unregister_netdev(dev_sun3_82586);
++      release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
++      iounmap((void *)ioaddr);
++      free_netdev(dev_sun3_82586);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/sun3lance.c        2003-06-14 12:18:32.000000000 -0700
++++ 25/drivers/net/sun3lance.c 2003-12-28 23:21:01.000000000 -0800
+@@ -246,9 +246,11 @@ static void set_multicast_list( struct n
+ /************************* End of Prototypes **************************/
+-int __init sun3lance_probe( struct net_device *dev )
+-{     
++struct net_device * __init sun3lance_probe(int unit)
++{
++      struct net_device *dev;
+       static int found;
++      int err = -ENODEV;
+       /* check that this machine has an onboard lance */
+       switch(idprom->id_machtype) {
+@@ -259,18 +261,37 @@ int __init sun3lance_probe( struct net_d
+               break;
+       default:
+-              return(-ENODEV);
++              return ERR_PTR(-ENODEV);
+       }
+-      if(found)
+-              return(-ENODEV);
++      if (found)
++              return ERR_PTR(-ENODEV);
+-      if (lance_probe(dev)) {
+-                      found = 1;
+-                      return( 0 );
++      dev = alloc_etherdev(sizeof(struct lance_private));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
+       }
++      SET_MODULE_OWNER(dev);
++
++      if (!lance_probe(dev))
++              goto out;
+-      return( -ENODEV );
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      found = 1;
++      return dev;
++
++out1:
++#ifdef CONFIG_SUN3
++      iounmap((void *)dev->base_addr);
++#endif
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ static int __init lance_probe( struct net_device *dev)
+@@ -285,6 +306,8 @@ static int __init lance_probe( struct ne
+ #ifdef CONFIG_SUN3
+       ioaddr = (unsigned long)ioremap(LANCE_OBIO, PAGE_SIZE);
++      if (!ioaddr)
++              return 0;
+ #else
+       ioaddr = SUN3X_LANCE;
+ #endif
+@@ -303,17 +326,15 @@ static int __init lance_probe( struct ne
+               ioaddr_probe[0] = tmp1;
+               ioaddr_probe[1] = tmp2;
++#ifdef CONFIG_SUN3
++              iounmap((void *)ioaddr);
++#endif
+               return 0;
+       }
+-      init_etherdev( dev, sizeof(struct lance_private) );
+-      if (!dev->priv) {
+-              dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
+-              if (!dev->priv)
+-                      return 0;
+-      }
+       lp = (struct lance_private *)dev->priv;
++      /* XXX - leak? */
+       MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000);
+       lp->iobase = (volatile unsigned short *)ioaddr;
+@@ -921,32 +942,24 @@ static void set_multicast_list( struct n
+ #ifdef MODULE
+-static char devicename[9];
+-static struct net_device sun3lance_dev =
+-{
+-      devicename,     /* filled in by register_netdev() */
+-      0, 0, 0, 0,     /* memory */
+-      0, 0,           /* base, irq */
+-      0, 0, 0, NULL, sun3lance_probe,
+-};
++static struct net_device *sun3lance_dev;
+ int init_module(void)
+ {
+-      int err;
+-
+-      if ((err = register_netdev( &sun3lance_dev ))) {
+-              if (err == -EIO)  {
+-                      printk( "SUN3 Lance not detected.  Module not loaded.\n");
+-              }
+-              return( err );
+-      }
+-      return( 0 );
++      sun3lance_dev = sun3lance_probe(-1);
++      if (IS_ERR(sun3lance_dev))
++              return PTR_ERR(sun3lance_dev);
++      return 0;
+ }
+ void cleanup_module(void)
+ {
+-      unregister_netdev( &sun3lance_dev );
++      unregister_netdev(sun3lance_dev);
++#ifdef CONFIG_SUN3
++      iounmap((void *)sun3lance_dev->base_addr);
++#endif
++      free_netdev(sun3lance_dev);
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/tc35815.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/tc35815.c   2003-12-28 23:21:01.000000000 -0800
+@@ -463,7 +463,6 @@ static void        tc35815_set_multicast_list(s
+ static void   tc35815_chip_reset(struct net_device *dev);
+ static void   tc35815_chip_init(struct net_device *dev);
+ static void   tc35815_phy_chip_init(struct net_device *dev);
+-static int    tc35815_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
+ /* A list of all installed tc35815 devices. */
+ static struct net_device *root_tc35815_dev = NULL;
+@@ -482,78 +481,76 @@ int
+ tc35815_probe(struct pci_dev *pdev,
+               const struct pci_device_id *ent)
+ {
+-      static int called = 0;
+       int err = 0;
+       int ret;
++      unsigned long pci_memaddr;
++      unsigned int pci_irq_line;
+-      if (called)
+-              return -ENODEV;
+-      called++;
++      printk(KERN_INFO "tc35815_probe: found device %#08x.%#08x\n", ent->vendor, ent->device);
+-      if (pdev) {
+-              unsigned int pci_memaddr;
+-              unsigned int pci_irq_line;
++      err = pci_enable_device(pdev);
++      if (err)
++              return err;
+-              printk(KERN_INFO "tc35815_probe: found device %#08x.%#08x\n", ent->vendor, ent->device);
++        pci_memaddr = pci_resource_start (pdev, 1);
+-              pci_memaddr = pci_resource_start (pdev, 1);
++        printk(KERN_INFO "    pci_memaddr=%#08lx  resource_flags=%#08lx\n", pci_memaddr, pci_resource_flags (pdev, 0));
+-              printk(KERN_INFO "    pci_memaddr=%#08lx  resource_flags=%#08lx\n", pci_memaddr, pci_resource_flags (pdev, 0));
++      if (!pci_memaddr) {
++              printk(KERN_WARNING "no PCI MEM resources, aborting\n");
++              ret = -ENODEV;
++              goto err_out;
++      }
++      pci_irq_line = pdev->irq;
++      /* irq disabled. */
++      if (pci_irq_line == 0) {
++              printk(KERN_WARNING "no PCI irq, aborting\n");
++              ret = -ENODEV;
++              goto err_out;
++      }
+-              if (!pci_memaddr) {
+-                      printk(KERN_WARNING "no PCI MEM resources, aborting\n");
+-                      return -ENODEV;
+-              }
+-              pci_irq_line = pdev->irq;
+-              /* irq disabled. */
+-              if (pci_irq_line == 0) {
+-                      printk(KERN_WARNING "no PCI irq, aborting\n");
+-                      return -ENODEV;
+-              }
++      ret =  tc35815_probe1(pdev, pci_memaddr, pci_irq_line);
++      if (ret)
++              goto err_out;
+-              ret =  tc35815_probe1(pdev, pci_memaddr, pci_irq_line);
++      pci_set_master(pdev);
+-              if (!ret) {
+-                      if ((err = pci_enable_device(pdev)) < 0) {
+-                          printk(KERN_ERR "tc35815_probe: failed to enable device -- err=%d\n", err);
+-                          return err;
+-                      }
+-                      pci_set_master(pdev);
+-              }
++      return 0;
+-              return ret;
+-      }
+-      return -ENODEV;
++err_out:
++      pci_disable_device(pdev);
++      return ret;
+ }
+ static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr, unsigned int irq)
+ {
+       static unsigned version_printed = 0;
+-      int i;
++      int i, ret;
+       struct tc35815_local *lp;
+       struct tc35815_regs *tr;
+       struct net_device *dev;
+       /* Allocate a new 'dev' if needed. */
+-      dev = init_etherdev(NULL, sizeof(struct tc35815_local));
++      dev = alloc_etherdev(sizeof(struct tc35815_local));
+       if (dev == NULL)
+               return -ENOMEM;
+       /*
+-       * init_etherdev allocs and zeros dev->priv
++       * alloc_etherdev allocs and zeros dev->priv
+        */
+       lp = dev->priv;
+       if (tc35815_debug  &&  version_printed++ == 0)
+               printk(KERN_DEBUG "%s", version);
+-      printk(KERN_INFO "%s: %s found at %#x, irq %d\n",
+-             dev->name, cardname, base_addr, irq);
+-
+       /* Fill in the 'dev' fields. */
+       dev->irq = irq;
+       dev->base_addr = (unsigned long)ioremap(base_addr,
+                                               sizeof(struct tc35815_regs));
++      if (!dev->base_addr) {
++              ret = -ENOMEM;
++              goto err_out;
++      }
+       tr = (struct tc35815_regs*)dev->base_addr;
+       tc35815_chip_reset(dev);
+@@ -570,9 +567,6 @@ static int __devinit tc35815_probe1(stru
+               dev->dev_addr[i] = data & 0xff;
+               dev->dev_addr[i+1] = data >> 8;
+       }
+-      for (i = 0; i < 6; i++)
+-              printk(" %2.2x", dev->dev_addr[i]);
+-      printk("\n");
+       /* Initialize the device structure. */
+       lp->pdev = pdev;
+@@ -594,8 +588,6 @@ static int __devinit tc35815_probe1(stru
+       /* do auto negotiation */
+       tc35815_phy_chip_init(dev);
+-      printk(KERN_INFO "%s: linkspeed %dMbps, %s Duplex\n",
+-             dev->name, lp->linkspeed, lp->fullduplex ? "Full" : "Half");
+       dev->open               = tc35815_open;
+       dev->stop               = tc35815_close;
+@@ -604,20 +596,34 @@ static int __devinit tc35815_probe1(stru
+       dev->hard_start_xmit    = tc35815_send_packet;
+       dev->get_stats          = tc35815_get_stats;
+       dev->set_multicast_list = tc35815_set_multicast_list;
++      SET_MODULE_OWNER(dev);
+-#if 0 /* XXX called in init_etherdev */
+-      /* Fill in the fields of the device structure with ethernet values. */
+-      ether_setup(dev);
+-#endif
++      ret = register_netdev(dev);
++      if (ret)
++              goto err_out_iounmap;
++
++      printk(KERN_INFO "%s: %s found at %#x, irq %d, MAC",
++             dev->name, cardname, base_addr, irq);
++      for (i = 0; i < 6; i++)
++              printk(" %2.2x", dev->dev_addr[i]);
++      printk("\n");
++      printk(KERN_INFO "%s: linkspeed %dMbps, %s Duplex\n",
++             dev->name, lp->linkspeed, lp->fullduplex ? "Full" : "Half");
+       return 0;
++
++err_out_iounmap:
++      iounmap((void *) dev->base_addr);
++err_out:
++      free_netdev(dev);
++      return ret;
+ }
+ static int
+ tc35815_init_queues(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       int i;
+       unsigned long fd_addr;
+@@ -702,7 +708,7 @@ tc35815_init_queues(struct net_device *d
+ static void
+ tc35815_clear_queues(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       int i;
+       for (i = 0; i < TX_FD_NUM; i++) {
+@@ -719,7 +725,7 @@ tc35815_clear_queues(struct net_device *
+ static void
+ tc35815_free_queues(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       int i;
+       if (lp->tfd_base) {
+@@ -805,7 +811,7 @@ dump_frfd(struct FrFD *fd)
+ static void
+ panic_queues(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       int i;
+       printk("TxFD base %p, start %d, end %d\n",
+@@ -823,6 +829,7 @@ panic_queues(struct net_device *dev)
+       panic("%s: Illegal queue state.", dev->name);
+ }
++#if 0
+ static void print_buf(char *add, int length)
+ {
+       int i;
+@@ -839,6 +846,7 @@ static void print_buf(char *add, int len
+       }
+       printk("\n");
+ }
++#endif
+ static void print_eth(char *add)
+ {
+@@ -864,7 +872,7 @@ static void print_eth(char *add)
+ static int
+ tc35815_open(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       /*
+        * This is used if the interrupt line can turned off (shared).
+        * See 3c503.c for an example of selecting the IRQ at config-time.
+@@ -888,19 +896,17 @@ tc35815_open(struct net_device *dev)
+       lp->tbusy = 0;
+       netif_start_queue(dev);
+-      MOD_INC_USE_COUNT;
+-
+       return 0;
+ }
+ static void tc35815_tx_timeout(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       struct tc35815_regs *tr = (struct tc35815_regs *)dev->base_addr;
+-      int flags;
++      unsigned long flags;
+       spin_lock_irqsave(&lp->lock, flags);
+-      printk(KERN_WARNING "%s: transmit timed out, status %#x\n",
++      printk(KERN_WARNING "%s: transmit timed out, status %#lx\n",
+              dev->name, tc_readl(&tr->Tx_Stat));
+       /* Try to restart the adaptor. */
+       tc35815_chip_reset(dev);
+@@ -914,7 +920,7 @@ static void tc35815_tx_timeout(struct ne
+ static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       struct tc35815_regs *tr = (struct tc35815_regs *)dev->base_addr;
+       if (netif_queue_stopped(dev)) {
+@@ -925,7 +931,7 @@ static int tc35815_send_packet(struct sk
+               int tickssofar = jiffies - dev->trans_start;
+               if (tickssofar < 5)
+                       return 1;
+-              printk(KERN_WARNING "%s: transmit timed out, status %#x\n",
++              printk(KERN_WARNING "%s: transmit timed out, status %#lx\n",
+                      dev->name, tc_readl(&tr->Tx_Stat));
+               /* Try to restart the adaptor. */
+               tc35815_chip_reset(dev);
+@@ -947,7 +953,7 @@ static int tc35815_send_packet(struct sk
+               short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+               unsigned char *buf = skb->data;
+               struct TxFD *txfd = &lp->tfd_base[lp->tfd_start];
+-              int flags;
++              unsigned long flags;
+               lp->stats.tx_bytes += skb->len;
+@@ -1051,7 +1057,7 @@ static irqreturn_t tc35815_interrupt(int
+       }
+       tr = (struct tc35815_regs*)dev->base_addr;
+-      lp = (struct tc35815_local *)dev->priv;
++      lp = dev->priv;
+       do {
+               status = tc_readl(&tr->Int_Src);
+@@ -1107,7 +1113,7 @@ static irqreturn_t tc35815_interrupt(int
+ static void
+ tc35815_rx(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+       unsigned int fdctl;
+       int i;
+@@ -1157,7 +1163,9 @@ tc35815_rx(struct net_device *dev)
+                               offset += len;
+                               cur_bd++;
+                       }
+-      //              print_buf(data,pkt_len);
++#if 0
++                      print_buf(data,pkt_len);
++#endif
+                       if (tc35815_debug > 3)
+                               print_eth(data);
+                       skb->protocol = eth_type_trans(skb, dev);
+@@ -1247,7 +1255,7 @@ tc35815_rx(struct net_device *dev)
+ static void
+ tc35815_check_tx_stat(struct net_device *dev, int status)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       const char *msg = NULL;
+       /* count collisions */
+@@ -1304,7 +1312,7 @@ tc35815_check_tx_stat(struct net_device 
+ static void
+ tc35815_txdone(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+       struct TxFD *txfd;
+       unsigned int fdctl;
+@@ -1379,7 +1387,7 @@ tc35815_txdone(struct net_device *dev)
+ static int
+ tc35815_close(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       lp->tbusy = 1;
+       netif_stop_queue(dev);
+@@ -1391,8 +1399,6 @@ tc35815_close(struct net_device *dev)
+       tc35815_free_queues(dev);
+-      MOD_DEC_USE_COUNT;
+-
+       return 0;
+ }
+@@ -1402,7 +1408,7 @@ tc35815_close(struct net_device *dev)
+  */
+ static struct net_device_stats *tc35815_get_stats(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+       unsigned long flags;
+@@ -1456,7 +1462,7 @@ static void tc35815_set_cam_entry(struct
+               int i;
+               for (i = cam_index / 4; i < cam_index / 4 + 2; i++) {
+                       tc_writel(i * 4, &tr->CAM_Adr);
+-                      printk("CAM 0x%x: %08x",
++                      printk("CAM 0x%x: %08lx",
+                              i * 4, tc_readl(&tr->CAM_Data));
+               }
+       }
+@@ -1513,9 +1519,9 @@ tc35815_set_multicast_list(struct net_de
+ static unsigned long tc_phy_read(struct net_device *dev, struct tc35815_regs *tr, int phy, int phy_reg)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       unsigned long data;
+-      int flags;
++      unsigned long flags;
+       
+       spin_lock_irqsave(&lp->lock, flags);
+@@ -1529,8 +1535,8 @@ static unsigned long tc_phy_read(struct 
+ static void tc_phy_write(struct net_device *dev, unsigned long d, struct tc35815_regs *tr, int phy, int phy_reg)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+-      int flags;
++      struct tc35815_local *lp = dev->priv;
++      unsigned long flags;
+       spin_lock_irqsave(&lp->lock, flags);
+@@ -1543,7 +1549,7 @@ static void tc_phy_write(struct net_devi
+ static void tc35815_phy_chip_init(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+       static int first = 1;
+       unsigned short ctl;
+@@ -1648,9 +1654,9 @@ static void tc35815_chip_reset(struct ne
+ static void tc35815_chip_init(struct net_device *dev)
+ {
+-      struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
++      struct tc35815_local *lp = dev->priv;
+       struct tc35815_regs *tr = (struct tc35815_regs*)dev->base_addr;
+-      int flags;
++      unsigned long flags;
+       unsigned long txctl = TX_CTL_CMD;
+       tc35815_phy_chip_init(dev);
+@@ -1696,40 +1702,6 @@ static void tc35815_chip_init(struct net
+       spin_unlock_irqrestore(&lp->lock, flags);
+ }
+-static int tc35815_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
+-{
+-      int len = 0;
+-      off_t pos = 0;
+-      off_t begin = 0;
+-      struct net_device *dev;
+-
+-      len += sprintf(buffer, "TC35815 statistics:\n");
+-      for (dev = root_tc35815_dev; dev; dev = ((struct tc35815_local *)dev->priv)->next_module) {
+-              struct tc35815_local *lp = (struct tc35815_local *)dev->priv;
+-              len += sprintf(buffer + len,
+-                             "%s: tx_ints %d, rx_ints %d, max_tx_qlen %d\n",
+-                             dev->name,
+-                             lp->lstats.tx_ints,
+-                             lp->lstats.rx_ints,
+-                             lp->lstats.max_tx_qlen);
+-              pos = begin + len;
+-
+-              if (pos < offset) {
+-                      len = 0;
+-                      begin = pos;
+-              }
+-    
+-              if (pos > offset+length) break;
+-      }
+-
+-      *start = buffer + (offset - begin);
+-      len -= (offset - begin);
+-  
+-      if (len > length) len = length;
+-  
+-      return len;
+-}
+-
+ /* XXX */
+ void
+ tc35815_killall(void)
+--- linux-2.6.0/drivers/net/tg3.c      2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/tg3.c       2003-12-28 23:21:01.000000000 -0800
+@@ -56,8 +56,8 @@
+ #define DRV_MODULE_NAME               "tg3"
+ #define PFX DRV_MODULE_NAME   ": "
+-#define DRV_MODULE_VERSION    "2.3"
+-#define DRV_MODULE_RELDATE    "November 5, 2003"
++#define DRV_MODULE_VERSION    "2.4"
++#define DRV_MODULE_RELDATE    "December 2, 2003"
+ #define TG3_DEF_MAC_MODE      0
+ #define TG3_DEF_RX_MODE               0
+@@ -176,6 +176,10 @@ static struct pci_device_id tg3_pci_tbl[
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S_2,
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5705F,
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX,
+@@ -2475,6 +2479,13 @@ static irqreturn_t tg3_interrupt(int irq
+ static int tg3_init_hw(struct tg3 *);
+ static int tg3_halt(struct tg3 *);
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void tg3_poll_controller(struct net_device *dev)
++{
++      tg3_interrupt(dev->irq, dev, NULL);
++}
++#endif
++
+ static void tg3_reset_task(void *_data)
+ {
+       struct tg3 *tp = _data;
+@@ -2688,7 +2699,13 @@ static int tg3_start_xmit_4gbug(struct s
+                               mss |= (tsflags << 11);
+                       }
+               } else {
+-                      mss += tcp_opt_len;
++                      if (tcp_opt_len || skb->nh.iph->ihl > 5) {
++                              int tsflags;
++
++                              tsflags = ((skb->nh.iph->ihl - 5) +
++                                         (tcp_opt_len >> 2));
++                              base_flags |= tsflags << 12;
++                      }
+               }
+       }
+ #else
+@@ -2895,7 +2912,13 @@ static int tg3_start_xmit(struct sk_buff
+                               mss |= (tsflags << 11);
+                       }
+               } else {
+-                      mss += tcp_opt_len;
++                      if (tcp_opt_len || skb->nh.iph->ihl > 5) {
++                              int tsflags;
++
++                              tsflags = ((skb->nh.iph->ihl - 5) +
++                                         (tcp_opt_len >> 2));
++                              base_flags |= tsflags << 12;
++                      }
+               }
+       }
+ #else
+@@ -3860,180 +3883,181 @@ static int tg3_load_5701_a0_firmware_fix
+ #if TG3_TSO_SUPPORT != 0
+ #define TG3_TSO_FW_RELEASE_MAJOR      0x1
+-#define TG3_TSO_FW_RELASE_MINOR               0x3
++#define TG3_TSO_FW_RELASE_MINOR               0x4
+ #define TG3_TSO_FW_RELEASE_FIX                0x0
+ #define TG3_TSO_FW_START_ADDR         0x08000000
+ #define TG3_TSO_FW_TEXT_ADDR          0x08000000
+-#define TG3_TSO_FW_TEXT_LEN           0x1ac0
+-#define TG3_TSO_FW_RODATA_ADDR                0x08001650
++#define TG3_TSO_FW_TEXT_LEN           0x1a90
++#define TG3_TSO_FW_RODATA_ADDR                0x08001a900
+ #define TG3_TSO_FW_RODATA_LEN         0x60
+-#define TG3_TSO_FW_DATA_ADDR          0x080016a0
++#define TG3_TSO_FW_DATA_ADDR          0x08001b20
+ #define TG3_TSO_FW_DATA_LEN           0x20
+-#define TG3_TSO_FW_SBSS_ADDR          0x080016c0
++#define TG3_TSO_FW_SBSS_ADDR          0x08001b40
+ #define TG3_TSO_FW_SBSS_LEN           0x2c
+-#define TG3_TSO_FW_BSS_ADDR           0x080016e0
+-#define TG3_TSO_FW_BSS_LEN            0x890
++#define TG3_TSO_FW_BSS_ADDR           0x08001b70
++#define TG3_TSO_FW_BSS_LEN            0x894
+ static u32 tg3TsoFwText[] = {
+       0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c1d0800,
+       0x37bd4000, 0x03a0f021, 0x3c100800, 0x26100000, 0x0e000010, 0x00000000,
+       0x0000000d, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0x3c04fefe,
+-      0xafbf0018, 0x0e0005e0, 0x34840002, 0x0e000670, 0x00000000, 0x3c030800,
+-      0x90631b78, 0x24020002, 0x3c040800, 0x24841acc, 0x14620003, 0x24050001,
+-      0x3c040800, 0x24841ac0, 0x24060002, 0x00003821, 0xafa00010, 0x0e000684,
++      0xafbf0018, 0x0e0005d4, 0x34840002, 0x0e000664, 0x00000000, 0x3c030800,
++      0x90631b58, 0x24020002, 0x3c040800, 0x24841a9c, 0x14620003, 0x24050001,
++      0x3c040800, 0x24841a90, 0x24060003, 0x00003821, 0xafa00010, 0x0e000678,
+       0xafa00014, 0x8f625c50, 0x34420001, 0xaf625c50, 0x8f625c90, 0x34420001,
+       0xaf625c90, 0x2402ffff, 0x0e000034, 0xaf625404, 0x8fbf0018, 0x03e00008,
+-      0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf0018,
+-      0xafb10014, 0x0e000052, 0xafb00010, 0x24110001, 0x8f706820, 0x32020100,
+-      0x10400003, 0x00000000, 0x0e0000b2, 0x00000000, 0x8f706820, 0x32022000,
+-      0x10400004, 0x32020001, 0x0e0001e3, 0x24040001, 0x32020001, 0x10400003,
+-      0x00000000, 0x0e00009a, 0x00000000, 0x0a00003a, 0xaf715028, 0x8fbf0018,
+-      0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800,
+-      0x24841ae0, 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010,
+-      0x0e000684, 0xafa00014, 0x3c040800, 0x248423e8, 0xa4800000, 0x3c010800,
+-      0xa0201ba8, 0x3c010800, 0xac201bac, 0x3c010800, 0xac201bb0, 0x3c010800,
+-      0xac201bb4, 0x3c010800, 0xac201bbc, 0x3c010800, 0xac201bc8, 0x3c010800,
+-      0xac201bcc, 0x8f624434, 0x3c010800, 0xac221b98, 0x8f624438, 0x3c010800,
+-      0xac221b9c, 0x8f624410, 0xac80f7a8, 0x3c010800, 0xac201b94, 0x3c010800,
+-      0xac2023f0, 0x3c010800, 0xac2023d8, 0x3c010800, 0xac2023dc, 0x3c010800,
+-      0xac202410, 0x3c010800, 0xac221ba0, 0x8f620068, 0x24030007, 0x00021702,
+-      0x10430005, 0x00000000, 0x8f620068, 0x00021702, 0x14400004, 0x24020001,
+-      0x3c010800, 0x0a00008e, 0xac20241c, 0xac820034, 0x3c040800, 0x24841aec,
+-      0x3c050800, 0x8ca5241c, 0x00003021, 0x00003821, 0xafa00010, 0x0e000684,
+-      0xafa00014, 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0x3c040800,
+-      0x24841af8, 0x00002821, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010,
+-      0x0e000684, 0xafa00014, 0x0e000052, 0x00000000, 0x0e0000ab, 0x00002021,
+-      0x8fbf0018, 0x03e00008, 0x27bd0020, 0x24020001, 0x8f636820, 0x00821004,
+-      0x00021027, 0x00621824, 0x03e00008, 0xaf636820, 0x27bdffd0, 0xafbf002c,
+-      0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014,
+-      0xafb00010, 0x8f665c5c, 0x3c030800, 0x24631bcc, 0x8c620000, 0x14460005,
+-      0x3c0200ff, 0x3c020800, 0x90421ba8, 0x14400115, 0x3c0200ff, 0x3442fff8,
+-      0x00c28824, 0xac660000, 0x00111902, 0x306300ff, 0x30c20003, 0x000211c0,
+-      0x00623825, 0x00e02821, 0x00061602, 0x3c030800, 0x90631ba8, 0x3044000f,
+-      0x1460002b, 0x00804021, 0x24020001, 0x3c010800, 0xa0221ba8, 0x00071100,
+-      0x00821025, 0x3c010800, 0xac201bac, 0x3c010800, 0xac201bb0, 0x3c010800,
+-      0xac201bb4, 0x3c010800, 0xac201bbc, 0x3c010800, 0xac201bc8, 0x3c010800,
+-      0xac201bc0, 0x3c010800, 0xac201bc4, 0x3c010800, 0xa42223e8, 0x9623000c,
+-      0x30628000, 0x10400008, 0x30627fff, 0x2442003e, 0x3c010800, 0xa4221ba6,
+-      0x24020001, 0x3c010800, 0x0a0000f9, 0xac222404, 0x24620036, 0x3c010800,
+-      0xa4221ba6, 0x3c010800, 0xac202404, 0x3c010800, 0xac202400, 0x3c010800,
+-      0x0a000101, 0xac202408, 0x9622000c, 0x3c010800, 0xa42223fc, 0x3c040800,
+-      0x24841bac, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac311bd8,
+-      0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac261bdc, 0x8c820000,
+-      0x24a30001, 0x306701ff, 0x00021100, 0x3c010800, 0x00220821, 0xac271be0,
+-      0x8c820000, 0x00021100, 0x3c010800, 0x00220821, 0xac281be4, 0x96230008,
+-      0x3c020800, 0x8c421bbc, 0x00432821, 0x3c010800, 0xac251bbc, 0x9622000a,
+-      0x30420004, 0x14400018, 0x00071100, 0x8f630c14, 0x3063000f, 0x2c620002,
+-      0x1440000b, 0x3c02c000, 0x8f630c14, 0x3c020800, 0x8c421b50, 0x3063000f,
+-      0x24420001, 0x3c010800, 0xac221b50, 0x2c620002, 0x1040fff7, 0x3c02c000,
+-      0x00c21825, 0xaf635c5c, 0x8f625c50, 0x30420002, 0x10400014, 0x00000000,
+-      0x0a000133, 0x00000000, 0x3c030800, 0x8c631b90, 0x3c040800, 0x94841ba4,
+-      0x01021025, 0x3c010800, 0xa42223ea, 0x24020001, 0x3c010800, 0xac221bc8,
+-      0x24630001, 0x0085202a, 0x3c010800, 0x10800003, 0xac231b90, 0x3c010800,
+-      0xa4251ba4, 0x3c060800, 0x24c61bac, 0x8cc20000, 0x24420001, 0xacc20000,
+-      0x28420080, 0x14400005, 0x00000000, 0x0e00065e, 0x24040002, 0x0a0001d9,
+-      0x00000000, 0x3c020800, 0x8c421bc8, 0x1040007f, 0x24020001, 0x3c040800,
+-      0x90841ba8, 0x14820077, 0x24020003, 0x3c150800, 0x96b51ba6, 0x3c050800,
+-      0x8ca51bbc, 0x32a3ffff, 0x00a3102a, 0x14400073, 0x00000000, 0x14a30003,
+-      0x00000000, 0x3c010800, 0xac242400, 0x10600061, 0x00009021, 0x24d60004,
+-      0x0060a021, 0x24d30014, 0x8ec20000, 0x00028100, 0x3c110800, 0x02308821,
+-      0x0e00062d, 0x8e311bd8, 0x00403021, 0x10c00059, 0x00000000, 0x9628000a,
+-      0x31020040, 0x10400004, 0x2407180c, 0x8e22000c, 0x2407188c, 0xacc20018,
+-      0x31021000, 0x10400004, 0x34e32000, 0x00081040, 0x3042c000, 0x00623825,
+-      0x3c030800, 0x00701821, 0x8c631be0, 0x3c020800, 0x00501021, 0x8c421be4,
+-      0x00031d00, 0x00021400, 0x00621825, 0xacc30014, 0x8ec30004, 0x96220008,
+-      0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, 0x0282102a, 0x14400002,
+-      0x02b22823, 0x00802821, 0x8e620000, 0x30a4ffff, 0x00441021, 0xae620000,
+-      0x8e220000, 0xacc20000, 0x8e220004, 0x8e63fff4, 0x00431021, 0xacc20004,
+-      0xa4c5000e, 0x8e62fff4, 0x00441021, 0xae62fff4, 0x96230008, 0x0043102a,
+-      0x14400005, 0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001, 0xae62fff0,
+-      0xacc00008, 0x3242ffff, 0x14540008, 0x24020305, 0x31020080, 0x54400001,
+-      0x34e70010, 0x24020905, 0xa4c2000c, 0x0a0001bc, 0x34e70020, 0xa4c2000c,
+-      0x3c020800, 0x8c422400, 0x10400003, 0x3c024b65, 0x0a0001c4, 0x34427654,
+-      0x3c02b49a, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010, 0x0e0005aa,
+-      0x00c02021, 0x3242ffff, 0x0054102b, 0x1440ffa4, 0x00000000, 0x24020002,
+-      0x3c010800, 0x0a0001d9, 0xa0221ba8, 0x8ec2083c, 0x24420001, 0x0a0001d9,
+-      0xaec2083c, 0x14820003, 0x00000000, 0x0e0004b9, 0x00000000, 0x8fbf002c,
++      0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe0, 0xafbf001c,
++      0xafb20018, 0xafb10014, 0x0e00005b, 0xafb00010, 0x24120002, 0x24110001,
++      0x8f706820, 0x32020100, 0x10400003, 0x00000000, 0x0e0000bb, 0x00000000,
++      0x8f706820, 0x32022000, 0x10400004, 0x32020001, 0x0e0001ef, 0x24040001,
++      0x32020001, 0x10400003, 0x00000000, 0x0e0000a3, 0x00000000, 0x3c020800,
++      0x90421b88, 0x14520003, 0x00000000, 0x0e0004bf, 0x00000000, 0x0a00003c,
++      0xaf715028, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
++      0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ab0, 0x00002821, 0x00003021,
++      0x00003821, 0xafbf0018, 0xafa00010, 0x0e000678, 0xafa00014, 0x3c040800,
++      0x248423c8, 0xa4800000, 0x3c010800, 0xa0201b88, 0x3c010800, 0xac201b8c,
++      0x3c010800, 0xac201b90, 0x3c010800, 0xac201b94, 0x3c010800, 0xac201b9c,
++      0x3c010800, 0xac201ba8, 0x3c010800, 0xac201bac, 0x8f624434, 0x3c010800,
++      0xac221b78, 0x8f624438, 0x3c010800, 0xac221b7c, 0x8f624410, 0xac80f7a8,
++      0x3c010800, 0xac201b74, 0x3c010800, 0xac2023d0, 0x3c010800, 0xac2023b8,
++      0x3c010800, 0xac2023bc, 0x3c010800, 0xac2023f0, 0x3c010800, 0xac221b80,
++      0x8f620068, 0x24030007, 0x00021702, 0x10430005, 0x00000000, 0x8f620068,
++      0x00021702, 0x14400004, 0x24020001, 0x3c010800, 0x0a000097, 0xac2023fc,
++      0xac820034, 0x3c040800, 0x24841abc, 0x3c050800, 0x8ca523fc, 0x00003021,
++      0x00003821, 0xafa00010, 0x0e000678, 0xafa00014, 0x8fbf0018, 0x03e00008,
++      0x27bd0020, 0x27bdffe0, 0x3c040800, 0x24841ac8, 0x00002821, 0x00003021,
++      0x00003821, 0xafbf0018, 0xafa00010, 0x0e000678, 0xafa00014, 0x0e00005b,
++      0x00000000, 0x0e0000b4, 0x00002021, 0x8fbf0018, 0x03e00008, 0x27bd0020,
++      0x24020001, 0x8f636820, 0x00821004, 0x00021027, 0x00621824, 0x03e00008,
++      0xaf636820, 0x27bdffd0, 0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020,
++      0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x8f675c5c, 0x3c030800,
++      0x24631bac, 0x8c620000, 0x14470005, 0x3c0200ff, 0x3c020800, 0x90421b88,
++      0x14400118, 0x3c0200ff, 0x3442fff8, 0x00e28824, 0xac670000, 0x00111902,
++      0x306300ff, 0x30e20003, 0x000211c0, 0x00622825, 0x00a04021, 0x00071602,
++      0x3c030800, 0x90631b88, 0x3044000f, 0x14600036, 0x00804821, 0x24020001,
++      0x3c010800, 0xa0221b88, 0x00051100, 0x00821025, 0x3c010800, 0xac201b8c,
++      0x3c010800, 0xac201b90, 0x3c010800, 0xac201b94, 0x3c010800, 0xac201b9c,
++      0x3c010800, 0xac201ba8, 0x3c010800, 0xac201ba0, 0x3c010800, 0xac201ba4,
++      0x3c010800, 0xa42223c8, 0x9622000c, 0x30437fff, 0x3c010800, 0xa4222400,
++      0x30428000, 0x3c010800, 0xa4231bb6, 0x10400005, 0x24020001, 0x3c010800,
++      0xac2223e4, 0x0a000102, 0x2406003e, 0x24060036, 0x3c010800, 0xac2023e4,
++      0x9622000a, 0x3c030800, 0x94631bb6, 0x3c010800, 0xac2023e0, 0x3c010800,
++      0xac2023e8, 0x00021302, 0x00021080, 0x00c21021, 0x00621821, 0x3c010800,
++      0xa42223c0, 0x3c010800, 0x0a000115, 0xa4231b86, 0x9622000c, 0x3c010800,
++      0xa42223dc, 0x3c040800, 0x24841b8c, 0x8c820000, 0x00021100, 0x3c010800,
++      0x00220821, 0xac311bb8, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821,
++      0xac271bbc, 0x8c820000, 0x25030001, 0x306601ff, 0x00021100, 0x3c010800,
++      0x00220821, 0xac261bc0, 0x8c820000, 0x00021100, 0x3c010800, 0x00220821,
++      0xac291bc4, 0x96230008, 0x3c020800, 0x8c421b9c, 0x00432821, 0x3c010800,
++      0xac251b9c, 0x9622000a, 0x30420004, 0x14400018, 0x00061100, 0x8f630c14,
++      0x3063000f, 0x2c620002, 0x1440000b, 0x3c02c000, 0x8f630c14, 0x3c020800,
++      0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30, 0x2c620002,
++      0x1040fff7, 0x3c02c000, 0x00e21825, 0xaf635c5c, 0x8f625c50, 0x30420002,
++      0x10400014, 0x00000000, 0x0a000147, 0x00000000, 0x3c030800, 0x8c631b70,
++      0x3c040800, 0x94841b84, 0x01221025, 0x3c010800, 0xa42223ca, 0x24020001,
++      0x3c010800, 0xac221ba8, 0x24630001, 0x0085202a, 0x3c010800, 0x10800003,
++      0xac231b70, 0x3c010800, 0xa4251b84, 0x3c060800, 0x24c61b8c, 0x8cc20000,
++      0x24420001, 0xacc20000, 0x28420080, 0x14400005, 0x00000000, 0x0e000652,
++      0x24040002, 0x0a0001e5, 0x00000000, 0x3c020800, 0x8c421ba8, 0x10400077,
++      0x24020001, 0x3c050800, 0x90a51b88, 0x14a20071, 0x00000000, 0x3c150800,
++      0x96b51b86, 0x3c040800, 0x8c841b9c, 0x32a3ffff, 0x0083102a, 0x1440006b,
++      0x00000000, 0x14830003, 0x00000000, 0x3c010800, 0xac2523e0, 0x1060005b,
++      0x00009021, 0x24d60004, 0x0060a021, 0x24d30014, 0x8ec20000, 0x00028100,
++      0x3c110800, 0x02308821, 0x0e000621, 0x8e311bb8, 0x00402821, 0x10a00053,
++      0x00000000, 0x9628000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e22000c,
++      0x2407188c, 0xaca20018, 0x3c030800, 0x00701821, 0x8c631bc0, 0x3c020800,
++      0x00501021, 0x8c421bc4, 0x00031d00, 0x00021400, 0x00621825, 0xaca30014,
++      0x8ec30004, 0x96220008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021,
++      0x0282102a, 0x14400002, 0x02b23023, 0x00803021, 0x8e620000, 0x30c4ffff,
++      0x00441021, 0xae620000, 0x8e220000, 0xaca20000, 0x8e220004, 0x8e63fff4,
++      0x00431021, 0xaca20004, 0xa4a6000e, 0x8e62fff4, 0x00441021, 0xae62fff4,
++      0x96230008, 0x0043102a, 0x14400005, 0x02469021, 0x8e62fff0, 0xae60fff4,
++      0x24420001, 0xae62fff0, 0xaca00008, 0x3242ffff, 0x14540008, 0x24020305,
++      0x31020080, 0x54400001, 0x34e70010, 0x24020905, 0xa4a2000c, 0x0a0001ca,
++      0x34e70020, 0xa4a2000c, 0x3c020800, 0x8c4223e0, 0x10400003, 0x3c024b65,
++      0x0a0001d2, 0x34427654, 0x3c02b49a, 0x344289ab, 0xaca2001c, 0x30e2ffff,
++      0xaca20010, 0x0e00059f, 0x00a02021, 0x3242ffff, 0x0054102b, 0x1440ffaa,
++      0x00000000, 0x24020002, 0x3c010800, 0x0a0001e5, 0xa0221b88, 0x8ec2083c,
++      0x24420001, 0x0a0001e5, 0xaec2083c, 0x0e0004bf, 0x00000000, 0x8fbf002c,
+       0x8fb60028, 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014,
+       0x8fb00010, 0x03e00008, 0x27bd0030, 0x27bdffd0, 0xafbf0028, 0xafb30024,
+       0xafb20020, 0xafb1001c, 0xafb00018, 0x8f725c9c, 0x3c0200ff, 0x3442fff8,
+-      0x3c060800, 0x24c61bc4, 0x02428824, 0x9623000e, 0x8cc20000, 0x00431021,
+-      0xacc20000, 0x8e220010, 0x30420020, 0x14400011, 0x00809821, 0x0e000643,
++      0x3c060800, 0x24c61ba4, 0x02428824, 0x9623000e, 0x8cc20000, 0x00431021,
++      0xacc20000, 0x8e220010, 0x30420020, 0x14400011, 0x00809821, 0x0e000637,
+       0x02202021, 0x3c02c000, 0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002,
+       0x10400121, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1040011c,
+-      0x00000000, 0x0a000200, 0x00000000, 0x8e240008, 0x8e230014, 0x00041402,
++      0x00000000, 0x0a00020c, 0x00000000, 0x8e240008, 0x8e230014, 0x00041402,
+       0x000241c0, 0x00031502, 0x304201ff, 0x2442ffff, 0x3042007f, 0x00031942,
+       0x30637800, 0x00021100, 0x24424000, 0x00625021, 0x9542000a, 0x3084ffff,
+-      0x30420008, 0x104000b3, 0x000429c0, 0x3c020800, 0x8c422410, 0x1440002d,
+-      0x25050008, 0x95020014, 0x3c010800, 0xa42223e0, 0x8d070010, 0x00071402,
+-      0x3c010800, 0xa42223e2, 0x3c010800, 0xa42723e4, 0x9502000e, 0x30e3ffff,
+-      0x00431023, 0x3c010800, 0xac222418, 0x8f626800, 0x3c030010, 0x00431024,
+-      0x10400005, 0x00000000, 0x9503001a, 0x9502001c, 0x0a000235, 0x00431021,
+-      0x9502001a, 0x3c010800, 0xac22240c, 0x3c02c000, 0x02421825, 0x3c010800,
+-      0xac282410, 0x3c010800, 0xac322414, 0xaf635c9c, 0x8f625c90, 0x30420002,
++      0x30420008, 0x104000b3, 0x000429c0, 0x3c020800, 0x8c4223f0, 0x1440002d,
++      0x25050008, 0x95020014, 0x3c010800, 0xa42223c0, 0x8d070010, 0x00071402,
++      0x3c010800, 0xa42223c2, 0x3c010800, 0xa42723c4, 0x9502000e, 0x30e3ffff,
++      0x00431023, 0x3c010800, 0xac2223f8, 0x8f626800, 0x3c030010, 0x00431024,
++      0x10400005, 0x00000000, 0x9503001a, 0x9502001c, 0x0a000241, 0x00431021,
++      0x9502001a, 0x3c010800, 0xac2223ec, 0x3c02c000, 0x02421825, 0x3c010800,
++      0xac2823f0, 0x3c010800, 0xac3223f4, 0xaf635c9c, 0x8f625c90, 0x30420002,
+       0x104000df, 0x00000000, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x104000da,
+-      0x00000000, 0x0a000242, 0x00000000, 0x9502000e, 0x3c030800, 0x946323e4,
++      0x00000000, 0x0a00024e, 0x00000000, 0x9502000e, 0x3c030800, 0x946323c4,
+       0x00434823, 0x3123ffff, 0x2c620008, 0x1040001c, 0x00000000, 0x95020014,
+       0x24420028, 0x00a22821, 0x00031042, 0x1840000b, 0x00002021, 0x24c60848,
+       0x00403821, 0x94a30000, 0x8cc20000, 0x24840001, 0x00431021, 0xacc20000,
+       0x0087102a, 0x1440fff9, 0x24a50002, 0x31220001, 0x1040001f, 0x3c024000,
+-      0x3c040800, 0x2484240c, 0xa0a00001, 0x94a30000, 0x8c820000, 0x00431021,
+-      0x0a000281, 0xac820000, 0x8f626800, 0x3c030010, 0x00431024, 0x10400009,
+-      0x00000000, 0x9502001a, 0x3c030800, 0x8c63240c, 0x00431021, 0x3c010800,
+-      0xac22240c, 0x0a000282, 0x3c024000, 0x9502001a, 0x9504001c, 0x3c030800,
+-      0x8c63240c, 0x00441023, 0x00621821, 0x3c010800, 0xac23240c, 0x3c024000,
++      0x3c040800, 0x248423ec, 0xa0a00001, 0x94a30000, 0x8c820000, 0x00431021,
++      0x0a00028d, 0xac820000, 0x8f626800, 0x3c030010, 0x00431024, 0x10400009,
++      0x00000000, 0x9502001a, 0x3c030800, 0x8c6323ec, 0x00431021, 0x3c010800,
++      0xac2223ec, 0x0a00028e, 0x3c024000, 0x9502001a, 0x9504001c, 0x3c030800,
++      0x8c6323ec, 0x00441023, 0x00621821, 0x3c010800, 0xac2323ec, 0x3c024000,
+       0x02421825, 0xaf635c9c, 0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000,
+-      0x9542000a, 0x30420010, 0x10400095, 0x00000000, 0x3c060800, 0x24c62410,
+-      0x3c020800, 0x944223e4, 0x8cc50000, 0x3c040800, 0x8c842418, 0x24420030,
+-      0x00a22821, 0x94a20004, 0x3c030800, 0x8c63240c, 0x00441023, 0x00621821,
++      0x9542000a, 0x30420010, 0x10400095, 0x00000000, 0x3c060800, 0x24c623f0,
++      0x3c020800, 0x944223c4, 0x8cc50000, 0x3c040800, 0x8c8423f8, 0x24420030,
++      0x00a22821, 0x94a20004, 0x3c030800, 0x8c6323ec, 0x00441023, 0x00621821,
+       0x00603821, 0x00032402, 0x30e2ffff, 0x00823821, 0x00071402, 0x00e23821,
+-      0x00071027, 0x3c010800, 0xac23240c, 0xa4a20006, 0x3c030800, 0x8c632414,
++      0x00071027, 0x3c010800, 0xac2323ec, 0xa4a20006, 0x3c030800, 0x8c6323f4,
+       0x3c0200ff, 0x3442fff8, 0x00628824, 0x96220008, 0x24040001, 0x24034000,
+       0x000241c0, 0x00e01021, 0xa502001a, 0xa500001c, 0xacc00000, 0x3c010800,
+-      0xac241b70, 0xaf635cb8, 0x8f625cb0, 0x30420002, 0x10400003, 0x00000000,
+-      0x3c010800, 0xac201b70, 0x8e220008, 0xaf625cb8, 0x8f625cb0, 0x30420002,
+-      0x10400003, 0x00000000, 0x3c010800, 0xac201b70, 0x3c020800, 0x8c421b70,
+-      0x1040ffec, 0x00000000, 0x3c040800, 0x0e000643, 0x8c842414, 0x0a000320,
+-      0x00000000, 0x3c030800, 0x90631ba8, 0x24020002, 0x14620003, 0x3c034b65,
+-      0x0a0002d7, 0x00008021, 0x8e22001c, 0x34637654, 0x10430002, 0x24100002,
+-      0x24100001, 0x01002021, 0x0e000346, 0x02003021, 0x24020003, 0x3c010800,
+-      0xa0221ba8, 0x24020002, 0x1202000a, 0x24020001, 0x3c030800, 0x8c632400,
+-      0x10620006, 0x00000000, 0x3c020800, 0x944223e8, 0x00021400, 0x0a000315,
+-      0xae220014, 0x3c040800, 0x248423ea, 0x94820000, 0x00021400, 0xae220014,
+-      0x3c020800, 0x8c421bcc, 0x3c03c000, 0x3c010800, 0xa0201ba8, 0x00431025,
++      0xac241b50, 0xaf635cb8, 0x8f625cb0, 0x30420002, 0x10400003, 0x00000000,
++      0x3c010800, 0xac201b50, 0x8e220008, 0xaf625cb8, 0x8f625cb0, 0x30420002,
++      0x10400003, 0x00000000, 0x3c010800, 0xac201b50, 0x3c020800, 0x8c421b50,
++      0x1040ffec, 0x00000000, 0x3c040800, 0x0e000637, 0x8c8423f4, 0x0a00032c,
++      0x00000000, 0x3c030800, 0x90631b88, 0x24020002, 0x14620003, 0x3c034b65,
++      0x0a0002e3, 0x00008021, 0x8e22001c, 0x34637654, 0x10430002, 0x24100002,
++      0x24100001, 0x01002021, 0x0e000352, 0x02003021, 0x24020003, 0x3c010800,
++      0xa0221b88, 0x24020002, 0x1202000a, 0x24020001, 0x3c030800, 0x8c6323e0,
++      0x10620006, 0x00000000, 0x3c020800, 0x944223c8, 0x00021400, 0x0a000321,
++      0xae220014, 0x3c040800, 0x248423ca, 0x94820000, 0x00021400, 0xae220014,
++      0x3c020800, 0x8c421bac, 0x3c03c000, 0x3c010800, 0xa0201b88, 0x00431025,
+       0xaf625c5c, 0x8f625c50, 0x30420002, 0x10400009, 0x00000000, 0x2484f7e2,
+       0x8c820000, 0x00431025, 0xaf625c5c, 0x8f625c50, 0x30420002, 0x1440fffa,
+-      0x00000000, 0x3c020800, 0x24421b94, 0x8c430000, 0x24630001, 0xac430000,
++      0x00000000, 0x3c020800, 0x24421b74, 0x8c430000, 0x24630001, 0xac430000,
+       0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000c, 0x3c024000, 0x8f630c14,
+-      0x3c020800, 0x8c421b50, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b50,
++      0x3c020800, 0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30,
+       0x2c620002, 0x1040fff7, 0x00000000, 0x3c024000, 0x02421825, 0xaf635c9c,
+       0x8f625c90, 0x30420002, 0x1440fffc, 0x00000000, 0x12600003, 0x00000000,
+-      0x0e0004b9, 0x00000000, 0x8fbf0028, 0x8fb30024, 0x8fb20020, 0x8fb1001c,
+-      0x8fb00018, 0x03e00008, 0x27bd0030, 0x8f634450, 0x3c040800, 0x24841b98,
++      0x0e0004bf, 0x00000000, 0x8fbf0028, 0x8fb30024, 0x8fb20020, 0x8fb1001c,
++      0x8fb00018, 0x03e00008, 0x27bd0030, 0x8f634450, 0x3c040800, 0x24841b78,
+       0x8c820000, 0x00031c02, 0x0043102b, 0x14400007, 0x3c038000, 0x8c840004,
+       0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444,
+       0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008,
+       0x3042ffff, 0x3c024000, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002,
+       0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00805821,
+-      0x14c00017, 0x256e0008, 0x3c020800, 0x8c422404, 0x1040000a, 0x2402003e,
+-      0x3c010800, 0xa42223e0, 0x24020016, 0x3c010800, 0xa42223e2, 0x2402002a,
+-      0x3c010800, 0x0a000360, 0xa42223e4, 0x95620014, 0x3c010800, 0xa42223e0,
+-      0x8d670010, 0x00071402, 0x3c010800, 0xa42223e2, 0x3c010800, 0xa42723e4,
+-      0x3c040800, 0x948423e4, 0x3c030800, 0x946323e2, 0x95cf0006, 0x3c020800,
+-      0x944223e0, 0x00832023, 0x01e2c023, 0x3065ffff, 0x24a20028, 0x01c24821,
++      0x14c00011, 0x256e0008, 0x3c020800, 0x8c4223e4, 0x10400007, 0x24020016,
++      0x3c010800, 0xa42223c2, 0x2402002a, 0x3c010800, 0x0a000366, 0xa42223c4,
++      0x8d670010, 0x00071402, 0x3c010800, 0xa42223c2, 0x3c010800, 0xa42723c4,
++      0x3c040800, 0x948423c4, 0x3c030800, 0x946323c2, 0x95cf0006, 0x3c020800,
++      0x944223c0, 0x00832023, 0x01e2c023, 0x3065ffff, 0x24a20028, 0x01c24821,
+       0x3082ffff, 0x14c0001a, 0x01226021, 0x9582000c, 0x3042003f, 0x3c010800,
+-      0xa42223e6, 0x95820004, 0x95830006, 0x3c010800, 0xac2023f4, 0x3c010800,
+-      0xac2023f8, 0x00021400, 0x00431025, 0x3c010800, 0xac221bd0, 0x95220004,
+-      0x3c010800, 0xa4221bd4, 0x95230002, 0x01e51023, 0x0043102a, 0x10400010,
+-      0x24020001, 0x3c010800, 0x0a000394, 0xac222408, 0x3c030800, 0x8c6323f8,
+-      0x3c020800, 0x94421bd4, 0x00431021, 0xa5220004, 0x3c020800, 0x94421bd0,
+-      0xa5820004, 0x3c020800, 0x8c421bd0, 0xa5820006, 0x3c020800, 0x8c422400,
+-      0x3c0d0800, 0x8dad23f4, 0x3c0a0800, 0x144000e5, 0x8d4a23f8, 0x3c020800,
+-      0x94421bd4, 0x004a1821, 0x3063ffff, 0x0062182b, 0x24020002, 0x10c2000d,
+-      0x01435023, 0x3c020800, 0x944223e6, 0x30420009, 0x10400008, 0x00000000,
+-      0x9582000c, 0x3042fff6, 0xa582000c, 0x3c020800, 0x944223e6, 0x30420009,
+-      0x01a26823, 0x3c020800, 0x8c422408, 0x1040004a, 0x01203821, 0x3c020800,
+-      0x944223e2, 0x00004021, 0xa520000a, 0x01e21023, 0xa5220002, 0x3082ffff,
++      0xa42223c6, 0x95820004, 0x95830006, 0x3c010800, 0xac2023d4, 0x3c010800,
++      0xac2023d8, 0x00021400, 0x00431025, 0x3c010800, 0xac221bb0, 0x95220004,
++      0x3c010800, 0xa4221bb4, 0x95230002, 0x01e51023, 0x0043102a, 0x10400010,
++      0x24020001, 0x3c010800, 0x0a00039a, 0xac2223e8, 0x3c030800, 0x8c6323d8,
++      0x3c020800, 0x94421bb4, 0x00431021, 0xa5220004, 0x3c020800, 0x94421bb0,
++      0xa5820004, 0x3c020800, 0x8c421bb0, 0xa5820006, 0x3c020800, 0x8c4223e0,
++      0x3c0d0800, 0x8dad23d4, 0x3c0a0800, 0x144000e5, 0x8d4a23d8, 0x3c020800,
++      0x94421bb4, 0x004a1821, 0x3063ffff, 0x0062182b, 0x24020002, 0x10c2000d,
++      0x01435023, 0x3c020800, 0x944223c6, 0x30420009, 0x10400008, 0x00000000,
++      0x9582000c, 0x3042fff6, 0xa582000c, 0x3c020800, 0x944223c6, 0x30420009,
++      0x01a26823, 0x3c020800, 0x8c4223e8, 0x1040004a, 0x01203821, 0x3c020800,
++      0x944223c2, 0x00004021, 0xa520000a, 0x01e21023, 0xa5220002, 0x3082ffff,
+       0x00021042, 0x18400008, 0x00003021, 0x00401821, 0x94e20000, 0x25080001,
+       0x00c23021, 0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02, 0x30c2ffff,
+       0x00623021, 0x00061402, 0x00c23021, 0x00c02821, 0x00061027, 0xa522000a,
+@@ -4044,131 +4068,127 @@ static u32 tg3TsoFwText[] = {
+       0x30e2007f, 0x14400006, 0x25080001, 0x8d630000, 0x3c02007f, 0x3442ff80,
+       0x00625824, 0x25670008, 0x0109102a, 0x1440fff3, 0x00000000, 0x30820001,
+       0x10400005, 0x00061c02, 0xa0e00001, 0x94e20000, 0x00c23021, 0x00061c02,
+-      0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x0a000479, 0x30c6ffff,
+-      0x24020002, 0x14c20081, 0x00000000, 0x3c020800, 0x8c42241c, 0x14400007,
+-      0x00000000, 0x3c020800, 0x944223e2, 0x95230002, 0x01e21023, 0x10620077,
+-      0x00000000, 0x3c020800, 0x944223e2, 0x01e21023, 0xa5220002, 0x3c020800,
+-      0x8c42241c, 0x1040001a, 0x31e3ffff, 0x8dc70010, 0x3c020800, 0x94421ba6,
++      0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x0a00047f, 0x30c6ffff,
++      0x24020002, 0x14c20081, 0x00000000, 0x3c020800, 0x8c4223fc, 0x14400007,
++      0x00000000, 0x3c020800, 0x944223c2, 0x95230002, 0x01e21023, 0x10620077,
++      0x00000000, 0x3c020800, 0x944223c2, 0x01e21023, 0xa5220002, 0x3c020800,
++      0x8c4223fc, 0x1040001a, 0x31e3ffff, 0x8dc70010, 0x3c020800, 0x94421b86,
+       0x00e04021, 0x00072c02, 0x00aa2021, 0x00431023, 0x00823823, 0x00072402,
+       0x30e2ffff, 0x00823821, 0x00071027, 0xa522000a, 0x3102ffff, 0x3c040800,
+-      0x948423e4, 0x00453023, 0x00e02821, 0x00641823, 0x006d1821, 0x00c33021,
+-      0x00061c02, 0x30c2ffff, 0x0a000479, 0x00623021, 0x01203821, 0x00004021,
++      0x948423c4, 0x00453023, 0x00e02821, 0x00641823, 0x006d1821, 0x00c33021,
++      0x00061c02, 0x30c2ffff, 0x0a00047f, 0x00623021, 0x01203821, 0x00004021,
+       0x3082ffff, 0x00021042, 0x18400008, 0x00003021, 0x00401821, 0x94e20000,
+       0x25080001, 0x00c23021, 0x0103102a, 0x1440fffb, 0x24e70002, 0x00061c02,
+       0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c02821, 0x00061027,
+       0xa522000a, 0x00003021, 0x2527000c, 0x00004021, 0x94e20000, 0x25080001,
+       0x00c23021, 0x2d020004, 0x1440fffb, 0x24e70002, 0x95220002, 0x00004021,
+       0x91230009, 0x00442023, 0x01803821, 0x3082ffff, 0xa4e00010, 0x3c040800,
+-      0x948423e4, 0x00621821, 0x00c33021, 0x00061c02, 0x30c2ffff, 0x00623021,
+-      0x00061c02, 0x3c020800, 0x944223e0, 0x00c34821, 0x00441023, 0x00021fc2,
++      0x948423c4, 0x00621821, 0x00c33021, 0x00061c02, 0x30c2ffff, 0x00623021,
++      0x00061c02, 0x3c020800, 0x944223c0, 0x00c34821, 0x00441023, 0x00021fc2,
+       0x00431021, 0x00021043, 0x18400010, 0x00003021, 0x00402021, 0x94e20000,
+       0x24e70002, 0x00c23021, 0x30e2007f, 0x14400006, 0x25080001, 0x8d630000,
+       0x3c02007f, 0x3442ff80, 0x00625824, 0x25670008, 0x0104102a, 0x1440fff3,
+-      0x00000000, 0x3c020800, 0x944223fc, 0x00c23021, 0x3122ffff, 0x00c23021,
++      0x00000000, 0x3c020800, 0x944223dc, 0x00c23021, 0x3122ffff, 0x00c23021,
+       0x00061c02, 0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c04021,
+-      0x00061027, 0xa5820010, 0xadc00014, 0x0a000499, 0xadc00000, 0x8dc70010,
++      0x00061027, 0xa5820010, 0xadc00014, 0x0a00049f, 0xadc00000, 0x8dc70010,
+       0x00e04021, 0x11400007, 0x00072c02, 0x00aa3021, 0x00061402, 0x30c3ffff,
+       0x00433021, 0x00061402, 0x00c22821, 0x00051027, 0xa522000a, 0x3c030800,
+-      0x946323e4, 0x3102ffff, 0x01e21021, 0x00433023, 0x00cd3021, 0x00061c02,
++      0x946323c4, 0x3102ffff, 0x01e21021, 0x00433023, 0x00cd3021, 0x00061c02,
+       0x30c2ffff, 0x00623021, 0x00061402, 0x00c23021, 0x00c04021, 0x00061027,
+       0xa5820010, 0x3102ffff, 0x00051c00, 0x00431025, 0xadc20010, 0x3c020800,
+-      0x8c422404, 0x10400002, 0x25e2fff2, 0xa5c20034, 0x3c020800, 0x8c4223f8,
+-      0x3c040800, 0x8c8423f4, 0x24420001, 0x3c010800, 0xac2223f8, 0x3c020800,
+-      0x8c421bd0, 0x3303ffff, 0x00832021, 0x3c010800, 0xac2423f4, 0x00431821,
+-      0x0062102b, 0x10400003, 0x2482ffff, 0x3c010800, 0xac2223f4, 0x3c010800,
+-      0xac231bd0, 0x03e00008, 0x27bd0020, 0x27bdffb8, 0x3c050800, 0x24a51ba8,
++      0x8c4223e4, 0x10400002, 0x25e2fff2, 0xa5c20034, 0x3c020800, 0x8c4223d8,
++      0x3c040800, 0x8c8423d4, 0x24420001, 0x3c010800, 0xac2223d8, 0x3c020800,
++      0x8c421bb0, 0x3303ffff, 0x00832021, 0x3c010800, 0xac2423d4, 0x00431821,
++      0x0062102b, 0x10400003, 0x2482ffff, 0x3c010800, 0xac2223d4, 0x3c010800,
++      0xac231bb0, 0x03e00008, 0x27bd0020, 0x27bdffb8, 0x3c050800, 0x24a51b86,
+       0xafbf0044, 0xafbe0040, 0xafb7003c, 0xafb60038, 0xafb50034, 0xafb40030,
+-      0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x90a30000, 0x24020003,
+-      0x146200d5, 0x00000000, 0x3c090800, 0x95291ba6, 0x3c020800, 0x944223e0,
+-      0x3c030800, 0x8c631bc0, 0x3c040800, 0x8c841bbc, 0x01221023, 0x0064182a,
+-      0xa7a9001e, 0x106000c8, 0xa7a20016, 0x24be0020, 0x97b6001e, 0x24b30018,
+-      0x24b70014, 0x8fc20000, 0x14400008, 0x00000000, 0x8fc2fff8, 0x97a30016,
+-      0x8fc4fff4, 0x00431021, 0x0082202a, 0x148000ba, 0x00000000, 0x97d50818,
+-      0x32a2ffff, 0x104000ad, 0x00009021, 0x0040a021, 0x00008821, 0x0e00062d,
+-      0x00000000, 0x00403021, 0x14c00007, 0x00000000, 0x3c020800, 0x8c4223ec,
+-      0x24420001, 0x3c010800, 0x0a00059e, 0xac2223ec, 0x3c100800, 0x02118021,
+-      0x8e101bd8, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c,
+-      0x2407188c, 0xacc20018, 0x31021000, 0x10400004, 0x34e32000, 0x00081040,
+-      0x3042c000, 0x00623825, 0x31020080, 0x54400001, 0x34e70010, 0x3c020800,
+-      0x00511021, 0x8c421be0, 0x3c030800, 0x00711821, 0x8c631be4, 0x00021500,
+-      0x00031c00, 0x00431025, 0xacc20014, 0x96040008, 0x3242ffff, 0x00821021,
+-      0x0282102a, 0x14400002, 0x02b22823, 0x00802821, 0x8e020000, 0x02459021,
+-      0xacc20000, 0x8e020004, 0x00c02021, 0x26310010, 0xac820004, 0x30e2ffff,
+-      0xac800008, 0xa485000e, 0xac820010, 0x24020305, 0x0e0005aa, 0xa482000c,
+-      0x3242ffff, 0x0054102b, 0x1440ffc0, 0x3242ffff, 0x0a000596, 0x00000000,
+-      0x8e620000, 0x8e63fffc, 0x0043102a, 0x1040006c, 0x00000000, 0x8e62fff0,
+-      0x00028900, 0x3c100800, 0x02118021, 0x0e00062d, 0x8e101bd8, 0x00403021,
+-      0x14c00005, 0x00000000, 0x8e62082c, 0x24420001, 0x0a00059e, 0xae62082c,
+-      0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c, 0x2407188c,
+-      0xacc20018, 0x31021000, 0x10400004, 0x34e32000, 0x00081040, 0x3042c000,
+-      0x00623825, 0x3c020800, 0x00511021, 0x8c421be0, 0x3c030800, 0x00711821,
+-      0x8c631be4, 0x00021500, 0x00031c00, 0x00431025, 0xacc20014, 0x8e63fff4,
+-      0x96020008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021, 0x02c2102a,
+-      0x10400003, 0x00802821, 0x97a9001e, 0x01322823, 0x8e620000, 0x30a4ffff,
+-      0x00441021, 0xae620000, 0xa4c5000e, 0x8e020000, 0xacc20000, 0x8e020004,
+-      0x8e63fff4, 0x00431021, 0xacc20004, 0x8e63fff4, 0x96020008, 0x00641821,
+-      0x0062102a, 0x14400006, 0x02459021, 0x8e62fff0, 0xae60fff4, 0x24420001,
+-      0x0a000579, 0xae62fff0, 0xae63fff4, 0xacc00008, 0x3242ffff, 0x10560003,
+-      0x31020004, 0x10400006, 0x24020305, 0x31020080, 0x54400001, 0x34e70010,
+-      0x34e70020, 0x24020905, 0xa4c2000c, 0x8ee30000, 0x8ee20004, 0x14620007,
+-      0x3c02b49a, 0x8ee20860, 0x54400001, 0x34e70400, 0x3c024b65, 0x0a000590,
+-      0x34427654, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010, 0x0e0005aa,
+-      0x00c02021, 0x3242ffff, 0x0056102b, 0x1440ff96, 0x00000000, 0x8e620000,
+-      0x8e63fffc, 0x0043102a, 0x1440ff3e, 0x00000000, 0x8fbf0044, 0x8fbe0040,
+-      0x8fb7003c, 0x8fb60038, 0x8fb50034, 0x8fb40030, 0x8fb3002c, 0x8fb20028,
+-      0x8fb10024, 0x8fb00020, 0x03e00008, 0x27bd0048, 0x27bdffe8, 0xafbf0014,
+-      0xafb00010, 0x8f624450, 0x8f634410, 0x0a0005b9, 0x00808021, 0x8f626820,
+-      0x30422000, 0x10400003, 0x00000000, 0x0e0001e3, 0x00002021, 0x8f624450,
+-      0x8f634410, 0x3042ffff, 0x0043102b, 0x1440fff5, 0x00000000, 0x8f630c14,
+-      0x3063000f, 0x2c620002, 0x1440000b, 0x00000000, 0x8f630c14, 0x3c020800,
+-      0x8c421b50, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b50, 0x2c620002,
+-      0x1040fff7, 0x00000000, 0xaf705c18, 0x8f625c10, 0x30420002, 0x10400009,
+-      0x00000000, 0x8f626820, 0x30422000, 0x1040fff8, 0x00000000, 0x0e0001e3,
+-      0x00002021, 0x0a0005cc, 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008,
+-      0x27bd0018, 0x00000000, 0x00000000, 0x00000000, 0x27bdffe8, 0x3c1bc000,
++      0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x94a90000, 0x3c020800,
++      0x944223c0, 0x3c030800, 0x8c631ba0, 0x3c040800, 0x8c841b9c, 0x01221023,
++      0x0064182a, 0xa7a9001e, 0x106000bc, 0xa7a20016, 0x24be0022, 0x97b6001e,
++      0x24b3001a, 0x24b70016, 0x8fc20000, 0x14400008, 0x00000000, 0x8fc2fff8,
++      0x97a30016, 0x8fc4fff4, 0x00431021, 0x0082202a, 0x148000ae, 0x00000000,
++      0x97d50818, 0x32a2ffff, 0x104000a1, 0x00009021, 0x0040a021, 0x00008821,
++      0x0e000621, 0x00000000, 0x00403021, 0x14c00007, 0x00000000, 0x3c020800,
++      0x8c4223cc, 0x24420001, 0x3c010800, 0x0a000593, 0xac2223cc, 0x3c100800,
++      0x02118021, 0x8e101bb8, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c,
++      0x8e02000c, 0x2407188c, 0xacc20018, 0x31020080, 0x54400001, 0x34e70010,
++      0x3c020800, 0x00511021, 0x8c421bc0, 0x3c030800, 0x00711821, 0x8c631bc4,
++      0x00021500, 0x00031c00, 0x00431025, 0xacc20014, 0x96040008, 0x3242ffff,
++      0x00821021, 0x0282102a, 0x14400002, 0x02b22823, 0x00802821, 0x8e020000,
++      0x02459021, 0xacc20000, 0x8e020004, 0x00c02021, 0x26310010, 0xac820004,
++      0x30e2ffff, 0xac800008, 0xa485000e, 0xac820010, 0x24020305, 0x0e00059f,
++      0xa482000c, 0x3242ffff, 0x0054102b, 0x1440ffc6, 0x3242ffff, 0x0a00058b,
++      0x00000000, 0x8e620000, 0x8e63fffc, 0x0043102a, 0x10400066, 0x00000000,
++      0x8e62fff0, 0x00028900, 0x3c100800, 0x02118021, 0x0e000621, 0x8e101bb8,
++      0x00403021, 0x14c00005, 0x00000000, 0x8e62082c, 0x24420001, 0x0a000593,
++      0xae62082c, 0x9608000a, 0x31020040, 0x10400004, 0x2407180c, 0x8e02000c,
++      0x2407188c, 0xacc20018, 0x3c020800, 0x00511021, 0x8c421bc0, 0x3c030800,
++      0x00711821, 0x8c631bc4, 0x00021500, 0x00031c00, 0x00431025, 0xacc20014,
++      0x8e63fff4, 0x96020008, 0x00432023, 0x3242ffff, 0x3083ffff, 0x00431021,
++      0x02c2102a, 0x10400003, 0x00802821, 0x97a9001e, 0x01322823, 0x8e620000,
++      0x30a4ffff, 0x00441021, 0xae620000, 0xa4c5000e, 0x8e020000, 0xacc20000,
++      0x8e020004, 0x8e63fff4, 0x00431021, 0xacc20004, 0x8e63fff4, 0x96020008,
++      0x00641821, 0x0062102a, 0x14400006, 0x02459021, 0x8e62fff0, 0xae60fff4,
++      0x24420001, 0x0a00056e, 0xae62fff0, 0xae63fff4, 0xacc00008, 0x3242ffff,
++      0x10560003, 0x31020004, 0x10400006, 0x24020305, 0x31020080, 0x54400001,
++      0x34e70010, 0x34e70020, 0x24020905, 0xa4c2000c, 0x8ee30000, 0x8ee20004,
++      0x14620007, 0x3c02b49a, 0x8ee20860, 0x54400001, 0x34e70400, 0x3c024b65,
++      0x0a000585, 0x34427654, 0x344289ab, 0xacc2001c, 0x30e2ffff, 0xacc20010,
++      0x0e00059f, 0x00c02021, 0x3242ffff, 0x0056102b, 0x1440ff9c, 0x00000000,
++      0x8e620000, 0x8e63fffc, 0x0043102a, 0x1440ff4a, 0x00000000, 0x8fbf0044,
++      0x8fbe0040, 0x8fb7003c, 0x8fb60038, 0x8fb50034, 0x8fb40030, 0x8fb3002c,
++      0x8fb20028, 0x8fb10024, 0x8fb00020, 0x03e00008, 0x27bd0048, 0x27bdffe8,
++      0xafbf0014, 0xafb00010, 0x8f624450, 0x8f634410, 0x0a0005ae, 0x00808021,
++      0x8f626820, 0x30422000, 0x10400003, 0x00000000, 0x0e0001ef, 0x00002021,
++      0x8f624450, 0x8f634410, 0x3042ffff, 0x0043102b, 0x1440fff5, 0x00000000,
++      0x8f630c14, 0x3063000f, 0x2c620002, 0x1440000b, 0x00000000, 0x8f630c14,
++      0x3c020800, 0x8c421b30, 0x3063000f, 0x24420001, 0x3c010800, 0xac221b30,
++      0x2c620002, 0x1040fff7, 0x00000000, 0xaf705c18, 0x8f625c10, 0x30420002,
++      0x10400009, 0x00000000, 0x8f626820, 0x30422000, 0x1040fff8, 0x00000000,
++      0x0e0001ef, 0x00002021, 0x0a0005c1, 0x00000000, 0x8fbf0014, 0x8fb00010,
++      0x03e00008, 0x27bd0018, 0x00000000, 0x00000000, 0x27bdffe8, 0x3c1bc000,
+       0xafbf0014, 0xafb00010, 0xaf60680c, 0x8f626804, 0x34420082, 0xaf626804,
+-      0x8f634000, 0x24020b50, 0x3c010800, 0xac221b64, 0x24020b78, 0x3c010800,
+-      0xac221b74, 0x34630002, 0xaf634000, 0x0e00060d, 0x00808021, 0x3c010800,
+-      0xa0221b78, 0x304200ff, 0x24030002, 0x14430005, 0x00000000, 0x3c020800,
+-      0x8c421b64, 0x0a000600, 0xac5000c0, 0x3c020800, 0x8c421b64, 0xac5000bc,
+-      0x8f624434, 0x8f634438, 0x8f644410, 0x3c010800, 0xac221b6c, 0x3c010800,
+-      0xac231b7c, 0x3c010800, 0xac241b68, 0x8fbf0014, 0x8fb00010, 0x03e00008,
++      0x8f634000, 0x24020b50, 0x3c010800, 0xac221b44, 0x24020b78, 0x3c010800,
++      0xac221b54, 0x34630002, 0xaf634000, 0x0e000601, 0x00808021, 0x3c010800,
++      0xa0221b58, 0x304200ff, 0x24030002, 0x14430005, 0x00000000, 0x3c020800,
++      0x8c421b44, 0x0a0005f4, 0xac5000c0, 0x3c020800, 0x8c421b44, 0xac5000bc,
++      0x8f624434, 0x8f634438, 0x8f644410, 0x3c010800, 0xac221b4c, 0x3c010800,
++      0xac231b5c, 0x3c010800, 0xac241b48, 0x8fbf0014, 0x8fb00010, 0x03e00008,
+       0x27bd0018, 0x3c040800, 0x8c870000, 0x3c03aa55, 0x3463aa55, 0x3c06c003,
+       0xac830000, 0x8cc20000, 0x14430007, 0x24050002, 0x3c0355aa, 0x346355aa,
+       0xac830000, 0x8cc20000, 0x50430001, 0x24050001, 0x3c020800, 0xac470000,
+       0x03e00008, 0x00a01021, 0x27bdfff8, 0x18800009, 0x00002821, 0x8f63680c,
+       0x8f62680c, 0x1043fffe, 0x00000000, 0x24a50001, 0x00a4102a, 0x1440fff9,
+-      0x00000000, 0x03e00008, 0x27bd0008, 0x8f634450, 0x3c020800, 0x8c421b6c,
+-      0x00031c02, 0x0043102b, 0x14400008, 0x3c038000, 0x3c040800, 0x8c841b7c,
++      0x00000000, 0x03e00008, 0x27bd0008, 0x8f634450, 0x3c020800, 0x8c421b4c,
++      0x00031c02, 0x0043102b, 0x14400008, 0x3c038000, 0x3c040800, 0x8c841b5c,
+       0x8f624450, 0x00021c02, 0x0083102b, 0x1040fffc, 0x3c038000, 0xaf634444,
+       0x8f624444, 0x00431024, 0x1440fffd, 0x00000000, 0x8f624448, 0x03e00008,
+       0x3042ffff, 0x3082ffff, 0x2442e000, 0x2c422001, 0x14400003, 0x3c024000,
+-      0x0a000650, 0x2402ffff, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002,
++      0x0a000644, 0x2402ffff, 0x00822025, 0xaf645c38, 0x8f625c30, 0x30420002,
+       0x1440fffc, 0x00001021, 0x03e00008, 0x00000000, 0x8f624450, 0x3c030800,
+-      0x8c631b68, 0x0a000659, 0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b,
++      0x8c631b48, 0x0a00064d, 0x3042ffff, 0x8f624450, 0x3042ffff, 0x0043102b,
+       0x1440fffc, 0x00000000, 0x03e00008, 0x00000000, 0x27bdffe0, 0x00802821,
+-      0x3c040800, 0x24841b10, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010,
+-      0x0e000684, 0xafa00014, 0x0a000668, 0x00000000, 0x8fbf0018, 0x03e00008,
++      0x3c040800, 0x24841ae0, 0x00003021, 0x00003821, 0xafbf0018, 0xafa00010,
++      0x0e000678, 0xafa00014, 0x0a00065c, 0x00000000, 0x8fbf0018, 0x03e00008,
+       0x27bd0020, 0x00000000, 0x00000000, 0x00000000, 0x3c020800, 0x34423000,
+-      0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac221b84,
+-      0x24020040, 0x3c010800, 0xac221b88, 0x3c010800, 0xac201b80, 0xac600000,
++      0x3c030800, 0x34633000, 0x3c040800, 0x348437ff, 0x3c010800, 0xac221b64,
++      0x24020040, 0x3c010800, 0xac221b68, 0x3c010800, 0xac201b60, 0xac600000,
+       0x24630004, 0x0083102b, 0x5040fffd, 0xac600000, 0x03e00008, 0x00000000,
+-      0x00804821, 0x8faa0010, 0x3c020800, 0x8c421b80, 0x3c040800, 0x8c841b88,
+-      0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac231b80, 0x14400003,
+-      0x00004021, 0x3c010800, 0xac201b80, 0x3c020800, 0x8c421b80, 0x3c030800,
+-      0x8c631b84, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001,
+-      0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c421b80,
+-      0x3c030800, 0x8c631b84, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008,
++      0x00804821, 0x8faa0010, 0x3c020800, 0x8c421b60, 0x3c040800, 0x8c841b68,
++      0x8fab0014, 0x24430001, 0x0044102b, 0x3c010800, 0xac231b60, 0x14400003,
++      0x00004021, 0x3c010800, 0xac201b60, 0x3c020800, 0x8c421b60, 0x3c030800,
++      0x8c631b64, 0x91240000, 0x00021140, 0x00431021, 0x00481021, 0x25080001,
++      0xa0440000, 0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 0x8c421b60,
++      0x3c030800, 0x8c631b64, 0x8f64680c, 0x00021140, 0x00431021, 0xac440008,
+       0xac45000c, 0xac460010, 0xac470014, 0xac4a0018, 0x03e00008, 0xac4b001c,
+       0x00000000, 0x00000000,
+ };
+ u32 tg3TsoFwRodata[] = {
+-      0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541,
+-      0x00000000, 0x00000000, 0x00000000, 0x73746b6f, 0x66666c64,
+-      0x496e0000, 0x73746b6f, 0x66662a2a, 0x00000000, 0x53774576,
+-      0x656e7430, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+-      0x66617461, 0x6c457272, 0x00000000, 0x00000000, 0x00000000
++      0x4d61696e, 0x43707542, 0x00000000, 0x4d61696e, 0x43707541, 0x00000000,
++      0x00000000, 0x00000000, 0x73746b6f, 0x66666c64, 0x496e0000, 0x73746b6f,
++      0x66662a2a, 0x00000000, 0x53774576, 0x656e7430, 0x00000000, 0x00000000,
++      0x00000000, 0x00000000, 0x66617461, 0x6c457272, 0x00000000, 0x00000000,
+ };
+ #if 0 /* All zeros, don't eat up space with it. */
+@@ -4541,7 +4561,10 @@ static int tg3_reset_hw(struct tg3 *tp)
+       tg3_chip_reset(tp);
+-      tw32(GRC_MODE, tp->grc_mode);
++      val = tr32(GRC_MODE);
++      val &= GRC_MODE_HOST_STACKUP;
++      tw32(GRC_MODE, val | tp->grc_mode);
++
+       tg3_write_mem(tp,
+                     NIC_SRAM_FIRMWARE_MBOX,
+                     NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
+@@ -4597,17 +4620,6 @@ static int tg3_reset_hw(struct tg3 *tp)
+        */
+       tg3_init_rings(tp);
+-      /* Clear statistics/status block in chip, and status block in ram. */
+-      if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
+-              for (i = NIC_SRAM_STATS_BLK;
+-                   i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
+-                   i += sizeof(u32)) {
+-                      tg3_write_mem(tp, i, 0);
+-                      udelay(40);
+-              }
+-      }
+-      memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
+-
+       /* This value is determined during the probe time DMA
+        * engine test, tg3_test_dma.
+        */
+@@ -4706,6 +4718,17 @@ static int tg3_reset_hw(struct tg3 *tp)
+               return -ENODEV;
+       }
++      /* Clear statistics/status block in chip, and status block in ram. */
++      if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
++              for (i = NIC_SRAM_STATS_BLK;
++                   i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
++                   i += sizeof(u32)) {
++                      tg3_write_mem(tp, i, 0);
++                      udelay(40);
++              }
++      }
++      memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
++
+       /* Setup replenish threshold. */
+       tw32(RCVBDI_STD_THRESH, tp->rx_pending / 8);
+@@ -5760,14 +5783,20 @@ static void __tg3_set_rx_mode(struct net
+       rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC |
+                                 RX_MODE_KEEP_VLAN_TAG);
++
++      /* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG
++       * flag clear.
++       */
+ #if TG3_VLAN_TAG_USED
+-      if (!tp->vlgrp)
++      if (!tp->vlgrp &&
++          !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+               rx_mode |= RX_MODE_KEEP_VLAN_TAG;
+ #else
+       /* By definition, VLAN is disabled always in this
+        * case.
+        */
+-      rx_mode |= RX_MODE_KEEP_VLAN_TAG;
++      if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
++              rx_mode |= RX_MODE_KEEP_VLAN_TAG;
+ #endif
+       if (dev->flags & IFF_PROMISC) {
+@@ -6402,25 +6431,22 @@ struct subsys_tbl_ent {
+ static struct subsys_tbl_ent subsys_id_to_phy_id[] = {
+       /* Broadcom boards. */
+-      { 0x14e4, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */
+-      { 0x14e4, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */
+-      { 0x14e4, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */
+-      { 0x14e4, 0x0003, PHY_ID_SERDES  }, /* BCM95700A9 */
+-      { 0x14e4, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */
+-      { 0x14e4, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */
+-      { 0x14e4, 0x0007, PHY_ID_SERDES  }, /* BCM95701A7 */
+-      { 0x14e4, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */
+-      { 0x14e4, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */
+-      { 0x14e4, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */
+-      { 0x14e4, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */
++      { PCI_VENDOR_ID_BROADCOM, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */
++      { PCI_VENDOR_ID_BROADCOM, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */
++      { PCI_VENDOR_ID_BROADCOM, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */
++      { PCI_VENDOR_ID_BROADCOM, 0x0003, PHY_ID_SERDES  }, /* BCM95700A9 */
++      { PCI_VENDOR_ID_BROADCOM, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */
++      { PCI_VENDOR_ID_BROADCOM, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */
++      { PCI_VENDOR_ID_BROADCOM, 0x0007, PHY_ID_SERDES  }, /* BCM95701A7 */
++      { PCI_VENDOR_ID_BROADCOM, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */
++      { PCI_VENDOR_ID_BROADCOM, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */
++      { PCI_VENDOR_ID_BROADCOM, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */
++      { PCI_VENDOR_ID_BROADCOM, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */
+       /* 3com boards. */
+       { PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */
+       { PCI_VENDOR_ID_3COM, 0x1006, PHY_ID_BCM5701 }, /* 3C996BT */
+-      /* { PCI_VENDOR_ID_3COM, 0x1002, PHY_ID_XXX },     3C996CT */
+-      /* { PCI_VENDOR_ID_3COM, 0x1003, PHY_ID_XXX },     3C997T */
+       { PCI_VENDOR_ID_3COM, 0x1004, PHY_ID_SERDES  }, /* 3C996SX */
+-      /* { PCI_VENDOR_ID_3COM, 0x1005, PHY_ID_XXX },     3C997SZ */
+       { PCI_VENDOR_ID_3COM, 0x1007, PHY_ID_BCM5701 }, /* 3C1000T */
+       { PCI_VENDOR_ID_3COM, 0x1008, PHY_ID_BCM5701 }, /* 3C940BR01 */
+@@ -6435,7 +6461,10 @@ static struct subsys_tbl_ent subsys_id_t
+       { PCI_VENDOR_ID_COMPAQ, 0x009a, PHY_ID_BCM5701 }, /* BANSHEE_2 */
+       { PCI_VENDOR_ID_COMPAQ, 0x007d, PHY_ID_SERDES  }, /* CHANGELING */
+       { PCI_VENDOR_ID_COMPAQ, 0x0085, PHY_ID_BCM5701 }, /* NC7780 */
+-      { PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 }  /* NC7780_2 */
++      { PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 }, /* NC7780_2 */
++
++      /* IBM boards. */
++      { PCI_VENDOR_ID_IBM, 0x0281, PHY_ID_SERDES } /* IBM??? */
+ };
+ static int __devinit tg3_phy_probe(struct tg3 *tp)
+@@ -6716,6 +6745,7 @@ static int __devinit tg3_get_invariants(
+       u32 misc_ctrl_reg;
+       u32 cacheline_sz_reg;
+       u32 pci_state_reg, grc_misc_cfg;
++      u32 val;
+       u16 pci_cmd;
+       int err;
+@@ -6912,7 +6942,9 @@ static int __devinit tg3_get_invariants(
+       udelay(40);
+       /* Initialize data/descriptor byte/word swapping. */
+-      tw32(GRC_MODE, tp->grc_mode);
++      val = tr32(GRC_MODE);
++      val &= GRC_MODE_HOST_STACKUP;
++      tw32(GRC_MODE, val | tp->grc_mode);
+       tg3_switch_clocks(tp);
+@@ -6975,7 +7007,8 @@ static int __devinit tg3_get_invariants(
+           (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
+            tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
+            (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901 ||
+-            tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2)))
++            tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2 ||
++            tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)))
+               tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
+       err = tg3_phy_probe(tp);
+@@ -7636,6 +7669,9 @@ static int __devinit tg3_init_one(struct
+       dev->watchdog_timeo = TG3_TX_TIMEOUT;
+       dev->change_mtu = tg3_change_mtu;
+       dev->irq = pdev->irq;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++      dev->poll_controller = tg3_poll_controller;
++#endif
+       err = tg3_get_invariants(tp);
+       if (err) {
+--- linux-2.6.0/drivers/net/tlan.c     2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/tlan.c      2003-12-28 23:21:01.000000000 -0800
+@@ -814,6 +814,14 @@ static void  __init TLan_EisaProbe (void
+ } /* TLan_EisaProbe */
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void TLan_Poll(struct net_device *dev)
++{
++      disable_irq(dev->irq);
++      TLan_HandleInterrupt(dev->irq, dev, NULL);
++      enable_irq(dev->irq);
++}
++#endif
+       
+@@ -893,6 +901,9 @@ static int TLan_Init( struct net_device 
+       dev->get_stats = &TLan_GetStats;
+       dev->set_multicast_list = &TLan_SetMulticastList;
+       dev->do_ioctl = &TLan_ioctl;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++      dev->poll_controller = &TLan_Poll;
++#endif
+       dev->tx_timeout = &TLan_tx_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
+--- linux-2.6.0/drivers/net/tokenring/3c359.c  2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/tokenring/3c359.c   2003-12-28 23:21:01.000000000 -0800
+@@ -314,7 +314,6 @@ int __devinit xl_probe(struct pci_dev *p
+       dev->irq=pdev->irq;
+       dev->base_addr=pci_resource_start(pdev,0) ; 
+-      dev->init=NULL ; /* Must be null with new api, otherwise get called twice */
+       xl_priv->xl_card_name = pci_name(pdev);
+       xl_priv->xl_mmio=ioremap(pci_resource_start(pdev,1), XL_IO_SPACE);
+       xl_priv->pdev = pdev ; 
+@@ -332,7 +331,7 @@ int __devinit xl_probe(struct pci_dev *p
+               
+       if((i = xl_init(dev))) {
+               iounmap(xl_priv->xl_mmio) ; 
+-              kfree(dev) ; 
++              free_netdev(dev) ; 
+               pci_release_regions(pdev) ; 
+               return i ; 
+       }                               
+@@ -352,7 +351,7 @@ int __devinit xl_probe(struct pci_dev *p
+               printk(KERN_ERR "3C359, register netdev failed\n") ;  
+               pci_set_drvdata(pdev,NULL) ; 
+               iounmap(xl_priv->xl_mmio) ; 
+-              kfree(dev) ; 
++              free_netdev(dev) ; 
+               pci_release_regions(pdev) ; 
+               return i ; 
+       }
+--- linux-2.6.0/drivers/net/tokenring/abyss.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/tokenring/abyss.c   2003-12-28 23:21:01.000000000 -0800
+@@ -181,7 +181,7 @@ err_out_irq:
+ err_out_region:
+       release_region(pci_ioaddr, ABYSS_IO_EXTENT);
+ err_out_trdev:
+-      kfree(dev);
++      free_netdev(dev);
+       return ret;
+ }
+--- linux-2.6.0/drivers/net/tokenring/ibmtr.c  2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/tokenring/ibmtr.c   2003-12-28 23:21:01.000000000 -0800
+@@ -187,7 +187,7 @@ char __devinit *adapter_def(char type)
+ #define TRC_INITV 0x02                /*  verbose init trace points     */
+ unsigned char ibmtr_debug_trace = 0;
+-int           ibmtr_probe(struct net_device *dev);
++static int    ibmtr_probe(struct net_device *dev);
+ static int    ibmtr_probe1(struct net_device *dev, int ioaddr);
+ static unsigned char get_sram_size(struct tok_info *adapt_info);
+ static int    trdev_init(struct net_device *dev);
+@@ -313,6 +313,39 @@ static void __devinit find_turbo_adapter
+       }
+ }
++static void ibmtr_cleanup_card(struct net_device *dev)
++{
++      if (dev->base_addr) {
++              outb(0,dev->base_addr+ADAPTRESET);
++              
++              schedule_timeout(TR_RST_TIME); /* wait 50ms */
++
++              outb(0,dev->base_addr+ADAPTRESETREL);
++      }
++
++#ifndef PCMCIA
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr, IBMTR_IO_EXTENT);
++
++      { 
++              struct tok_info *ti = (struct tok_info *) dev->priv;
++              iounmap((u32 *)ti->mmio);
++              iounmap((u32 *)ti->sram_virt);
++      }
++#endif                
++}
++
++int ibmtr_probe_card(struct net_device *dev)
++{
++      int err = ibmtr_probe(dev);
++      if (!err) {
++              err = register_netdev(dev);
++              if (err)
++                      ibmtr_cleanup_card(dev);
++      }
++      return err;
++}
++
+ /****************************************************************************
+  *    ibmtr_probe():  Routine specified in the network device structure
+  *    to probe for an IBM Token Ring Adapter.  Routine outline:
+@@ -325,7 +358,7 @@ static void __devinit find_turbo_adapter
+  *    which references it.
+  ****************************************************************************/
+-int __devinit ibmtr_probe(struct net_device *dev)
++static int ibmtr_probe(struct net_device *dev)
+ {
+       int i;
+       int base_addr = dev->base_addr;
+@@ -1925,23 +1958,24 @@ static int __init ibmtr_init(void)
+       find_turbo_adapters(io);
+       for (i = 0; io[i] && (i < IBMTR_MAX_ADAPTERS); i++) {
++              struct net_device *dev;
+               irq[i] = 0;
+               mem[i] = 0;
+-              dev_ibmtr[i] = alloc_trdev(sizeof(struct tok_info));
+-              if (dev_ibmtr[i] == NULL) { 
++              dev = alloc_trdev(sizeof(struct tok_info));
++              if (dev == NULL) { 
+                       if (i == 0)
+                               return -ENOMEM;
+                       break;
+               }
+-              dev_ibmtr[i]->base_addr = io[i];
+-              dev_ibmtr[i]->irq = irq[i];
+-              dev_ibmtr[i]->mem_start = mem[i];
+-              dev_ibmtr[i]->init = &ibmtr_probe;
+-              if (register_netdev(dev_ibmtr[i]) != 0) {
+-                      kfree(dev_ibmtr[i]);
+-                      dev_ibmtr[i] = NULL;
++              dev->base_addr = io[i];
++              dev->irq = irq[i];
++              dev->mem_start = mem[i];
++
++              if (ibmtr_probe_card(dev)) {
++                      free_netdev(dev);
+                       continue;
+               }
++              dev_ibmtr[i] = dev;
+               count++;
+       }
+       if (count) return 0;
+@@ -1957,27 +1991,9 @@ static void __exit ibmtr_cleanup(void)
+       for (i = 0; i < IBMTR_MAX_ADAPTERS; i++){
+               if (!dev_ibmtr[i])
+                       continue;
+-              if (dev_ibmtr[i]->base_addr) {
+-                      outb(0,dev_ibmtr[i]->base_addr+ADAPTRESET);
+-                      
+-                      schedule_timeout(TR_RST_TIME); /* wait 50ms */
+-
+-                        outb(0,dev_ibmtr[i]->base_addr+ADAPTRESETREL);
+-                }
+-
+               unregister_netdev(dev_ibmtr[i]);
+-              free_irq(dev_ibmtr[i]->irq, dev_ibmtr[i]);
+-              release_region(dev_ibmtr[i]->base_addr, IBMTR_IO_EXTENT);
+-#ifndef PCMCIA
+-              { 
+-                      struct tok_info *ti = (struct tok_info *)
+-                              dev_ibmtr[i]->priv;
+-                      iounmap((u32 *)ti->mmio);
+-                      iounmap((u32 *)ti->sram_virt);
+-              }
+-#endif                
++              ibmtr_cleanup_card(dev_ibmtr[i]);
+               free_netdev(dev_ibmtr[i]);
+-              dev_ibmtr[i] = NULL;
+       }
+ }
+ module_exit(ibmtr_cleanup);
+--- linux-2.6.0/drivers/net/tokenring/madgemc.c        2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/tokenring/madgemc.c 2003-12-28 23:21:01.000000000 -0800
+@@ -197,7 +197,7 @@ static int __init madgemc_probe(void)
+               card = kmalloc(sizeof(struct madgemc_card), GFP_KERNEL);
+               if (card==NULL) {
+                       printk("madgemc: unable to allocate card struct\n");
+-                      kfree(dev);
++                      free_netdev(dev);
+                       if (madgemc_card_list)
+                               return 0;
+                       return -1;
+@@ -360,7 +360,7 @@ static int __init madgemc_probe(void)
+                       
+                       kfree(card);
+                       tmsdev_term(dev);
+-                      kfree(dev);
++                      free_netdev(dev);
+                       if (madgemc_card_list)
+                               return 0;
+                       return -1;
+@@ -399,7 +399,7 @@ static int __init madgemc_probe(void)
+                              MADGEMC_IO_EXTENT); 
+       getout1:
+               kfree(card);
+-              kfree(dev);
++              free_netdev(dev);
+               slot++;
+       }
+--- linux-2.6.0/drivers/net/tokenring/olympic.c        2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/tokenring/olympic.c 2003-12-28 23:21:01.000000000 -0800
+@@ -228,7 +228,6 @@ static int __devinit olympic_probe(struc
+ #endif
+       dev->irq=pdev->irq;
+       dev->base_addr=pci_resource_start(pdev, 0);
+-      dev->init=NULL; /* Must be NULL otherwise we get called twice */
+       olympic_priv->olympic_card_name = pci_name(pdev);
+       olympic_priv->pdev = pdev; 
+       olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256);
+--- linux-2.6.0/drivers/net/tokenring/proteon.c        2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/tokenring/proteon.c 2003-12-28 23:21:01.000000000 -0800
+@@ -63,7 +63,7 @@ static int dmalist[] __initdata = {
+ static char cardname[] = "Proteon 1392\0";
+-int proteon_probe(struct net_device *dev);
++struct net_device *proteon_probe(int unit);
+ static int proteon_open(struct net_device *dev);
+ static int proteon_close(struct net_device *dev);
+ static void proteon_read_eeprom(struct net_device *dev);
+@@ -89,80 +89,69 @@ static void proteon_sifwritew(struct net
+       outw(val, dev->base_addr + reg);
+ }
+-struct proteon_card {
+-      struct net_device *dev;
+-      struct proteon_card *next;
+-};
+-
+-static struct proteon_card *proteon_card_list;
+-
+-static int __init proteon_probe1(int ioaddr)
++static int __init proteon_probe1(struct net_device *dev, int ioaddr)
+ {
+       unsigned char chk1, chk2;
+       int i;
++      if (!request_region(ioaddr, PROTEON_IO_EXTENT, cardname))
++              return -ENODEV;
++              
++
+       chk1 = inb(ioaddr + 0x1f);      /* Get Proteon ID reg 1 */
+-      if (chk1 != 0x1f)
+-              return (-1);
++      if (chk1 != 0x1f) 
++              goto nodev;
++
+       chk1 = inb(ioaddr + 0x1e) & 0x07;       /* Get Proteon ID reg 0 */
+       for (i=0; i<16; i++) {
+               chk2 = inb(ioaddr + 0x1e) & 0x07;
+               if (((chk1 + 1) & 0x07) != chk2)
+-                      return (-1);
++                      goto nodev;
+               chk1 = chk2;
+       }
++
++      dev->base_addr = ioaddr;
+       return (0);
++nodev:
++      release_region(ioaddr, PROTEON_IO_EXTENT); 
++      return -ENODEV;
+ }
+-int __init proteon_probe(struct net_device *dev)
++struct net_device * __init proteon_probe(int unit)
+ {
+-        static int versionprinted;
++      struct net_device *dev = alloc_trdev(sizeof(struct net_local));
+       struct net_local *tp;
+-      int i,j;
+-      struct proteon_card *card;
+-
+-#ifndef MODULE
+-      netdev_boot_setup_check(dev);
+-      tr_setup(dev);
+-#endif
++        static int versionprinted;
++      const unsigned *port;
++      int j,err = 0;
+-      SET_MODULE_OWNER(dev);
+-      if (!dev->base_addr)
+-      {
+-              for(i = 0; portlist[i]; i++)
+-              {
+-                      if (!request_region(portlist[i], PROTEON_IO_EXTENT, cardname))
+-                              continue;
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+-                      if(proteon_probe1(portlist[i]))
+-                      {
+-                              release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+-                              continue;
+-                      }
++      if (unit >= 0) {
++              sprintf(dev->name, "tr%d", unit);
++              netdev_boot_setup_check(dev);
++      }
+-                      dev->base_addr = portlist[i];
+-                      break;
++      SET_MODULE_OWNER(dev);
++      if (dev->base_addr)     /* probe specific location */
++              err = proteon_probe1(dev, dev->base_addr);
++      else {
++              for (port = portlist; *port; port++) {
++                      err = proteon_probe1(dev, *port);
++                      if (!err)
++                              break;
+               }
+-              if(!dev->base_addr)
+-                      return -1;
+       }
+-      else
+-      {
+-              if (!request_region(dev->base_addr, PROTEON_IO_EXTENT, cardname))
+-                      return -1;
+-
+-              if(proteon_probe1(dev->base_addr))
+-              {
+-                      release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+-                      return -1;
+-              }
+-      } 
++      if (err)
++              goto out4;
+       /* At this point we have found a valid card. */
+       if (versionprinted++ == 0)
+               printk(KERN_DEBUG "%s", version);
++      err = -EIO;
+       if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL))
+               goto out4;
+@@ -264,14 +253,11 @@ int __init proteon_probe(struct net_devi
+       printk(KERN_DEBUG "%s:    IO: %#4lx  IRQ: %d  DMA: %d\n",
+              dev->name, dev->base_addr, dev->irq, dev->dma);
+               
+-      /* Enlist in the card list */
+-      card = kmalloc(sizeof(struct proteon_card), GFP_KERNEL);
+-      if (!card)
++      err = register_netdev(dev);
++      if (err)
+               goto out;
+-      card->next = proteon_card_list;
+-      proteon_card_list = card;
+-      card->dev = dev;
+-      return 0;
++
++      return dev;
+ out:
+       free_dma(dev->dma);
+ out2:
+@@ -280,7 +266,8 @@ out3:
+       tmsdev_term(dev);
+ out4:
+       release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+-      return -1;
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /*
+@@ -370,50 +357,50 @@ MODULE_PARM(io, "1-" __MODULE_STRING(ISA
+ MODULE_PARM(irq, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+ MODULE_PARM(dma, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+-static int __init setup_card(unsigned long io, unsigned irq, unsigned char dma)
++static struct net_device *proteon_dev[ISATR_MAX_ADAPTERS];
++
++static struct net_device * __init setup_card(unsigned long io, unsigned irq, unsigned char dma)
+ {
+-      int res = -ENOMEM;
+-      struct proteon_card *this_card;
+-      struct net_device *dev = alloc_trdev(0);
+-
+-      if (dev) {
+-              dev->base_addr = io;
+-              dev->irq       = irq;
+-              dev->dma       = dma;
+-              res = -ENODEV;
+-              if (proteon_probe(dev) == 0) {
+-                      res = register_netdev(dev);
+-                      if (!res)
+-                              return 0;
+-                      release_region(dev->base_addr, PROTEON_IO_EXTENT);
+-                      free_irq(dev->irq, dev);
+-                      free_dma(dev->dma);
+-                      tmsdev_term(dev);
+-                      this_card = proteon_card_list;
+-                      proteon_card_list = this_card->next;
+-                      kfree(this_card);
+-              }
+-              kfree(dev);
+-      }
+-      return res;
++      struct net_device *dev = alloc_trdev(sizeof(struct net_local));
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      dev->irq = irq;
++      dev->dma = dma;
++      err = proteon_probe1(dev, io);
++      if (err) 
++              goto out;
++              
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++ out1:
++      release_region(dev->base_addr, PROTEON_IO_EXTENT);
++      free_irq(dev->irq, dev);
++      free_dma(dev->dma);
++      tmsdev_term(dev);
++ out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ int init_module(void)
+ {
+-      int i, num;
++      struct net_device *dev;
++      int i, num = 0;
+-      num = 0;
+-      if (io[0]) { /* Only probe addresses from command line */
+-              for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
+-                      if (io[i] && setup_card(io[i], irq[i], dma[i]) == 0)
+-                              num++;
+-              }
+-      } else {
+-              for(i = 0; num < ISATR_MAX_ADAPTERS && portlist[i]; i++) {
+-                      if (setup_card(portlist[i], irq[num], dma[num]) == 0)
+-                              num++;
++      for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
++              dev = io[0] ? setup_card(io[i], irq[i], dma[i])
++                      : proteon_probe(-1);
++              if (!IS_ERR(dev)) {
++                      proteon_dev[i] = dev;
++                      ++num;
+               }
+       }
++
+       printk(KERN_NOTICE "proteon.c: %d cards found.\n", num);
+       /* Probe for cards. */
+       if (num == 0) {
+@@ -425,11 +412,13 @@ int init_module(void)
+ void cleanup_module(void)
+ {
+-      struct net_device *dev;
+-      struct proteon_card *this_card;
++      int i;
+-      while (proteon_card_list) {
+-              dev = proteon_card_list->dev;
++      for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
++              struct net_device *dev = proteon_dev[i];
++              
++              if (!dev) 
++                      continue;
+               
+               unregister_netdev(dev);
+               release_region(dev->base_addr, PROTEON_IO_EXTENT);
+@@ -437,9 +426,6 @@ void cleanup_module(void)
+               free_dma(dev->dma);
+               tmsdev_term(dev);
+               free_netdev(dev);
+-              this_card = proteon_card_list;
+-              proteon_card_list = this_card->next;
+-              kfree(this_card);
+       }
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/tokenring/skisa.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/tokenring/skisa.c   2003-12-28 23:21:01.000000000 -0800
+@@ -56,7 +56,7 @@ static unsigned int portlist[] __initdat
+ /* A zero-terminated list of IRQs to be probed. 
+  * Used again after initial probe for sktr_chipset_init, called from sktr_open.
+  */
+-static unsigned short irqlist[] = {
++static const unsigned short irqlist[] = {
+       3, 5, 9, 10, 11, 12, 15,
+       0
+ };
+@@ -69,7 +69,6 @@ static int dmalist[] __initdata = {
+ static char isa_cardname[] = "SK NET TR 4/16 ISA\0";
+-int sk_isa_probe(struct net_device *dev);
+ static int sk_isa_open(struct net_device *dev);
+ static int sk_isa_close(struct net_device *dev);
+ static void sk_isa_read_eeprom(struct net_device *dev);
+@@ -95,17 +94,14 @@ static void sk_isa_sifwritew(struct net_
+       outw(val, dev->base_addr + reg);
+ }
+-struct sk_isa_card {
+-      struct net_device *dev;
+-      struct sk_isa_card *next;
+-};
+-
+-static struct sk_isa_card *sk_isa_card_list;
+-static int __init sk_isa_probe1(int ioaddr)
++static int __init sk_isa_probe1(struct net_device *dev, int ioaddr)
+ {
+       unsigned char old, chk1, chk2;
++      if (!request_region(ioaddr, SK_ISA_IO_EXTENT, isa_cardname))
++              return -ENODEV;
++
+       old = inb(ioaddr + SIFADR);     /* Get the old SIFADR value */
+       chk1 = 0;       /* Begin with check value 0 */
+@@ -122,8 +118,10 @@ static int __init sk_isa_probe1(int ioad
+               chk2 = inb(ioaddr + SIFADD);
+               chk2 ^= 0x0FE;
+-              if(chk1 != chk2)
+-                      return (-1);    /* No adapter */
++              if(chk1 != chk2) {
++                      release_region(ioaddr, SK_ISA_IO_EXTENT);
++                      return -ENODEV;
++              }
+               chk1 -= 2;
+       } while(chk1 != 0);     /* Repeat 128 times (all byte values) */
+@@ -131,58 +129,45 @@ static int __init sk_isa_probe1(int ioad
+       /* Restore the SIFADR value */
+       outb(old, ioaddr + SIFADR);
+-      return (0);
++      dev->base_addr = ioaddr;
++      return 0;
+ }
+-int __init sk_isa_probe(struct net_device *dev)
++struct net_device * __init sk_isa_probe(int unit)
+ {
+-        static int versionprinted;
++      struct net_device *dev = alloc_trdev(sizeof(struct net_local));
+       struct net_local *tp;
+-      int i,j;
+-      struct sk_isa_card *card;
++        static int versionprinted;
++      const unsigned *port;
++      int j, err = 0;
+-#ifndef MODULE
+-      netdev_boot_setup_check(dev);
+-      tr_setup(dev);
+-#endif
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+-      SET_MODULE_OWNER(dev);
+-      if (!dev->base_addr)
+-      {
+-              for(i = 0; portlist[i]; i++)
+-              {
+-                      if (!request_region(portlist[i], SK_ISA_IO_EXTENT, isa_cardname))
+-                              continue;
+-
+-                      if(sk_isa_probe1(portlist[i]))
+-                      {
+-                              release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+-                              continue;
+-                      }
++      if (unit >= 0) {
++              sprintf(dev->name, "tr%d", unit);
++              netdev_boot_setup_check(dev);
++      }
+-                      dev->base_addr = portlist[i];
+-                      break;
++      SET_MODULE_OWNER(dev);
++      if (dev->base_addr)     /* probe specific location */
++              err = sk_isa_probe1(dev, dev->base_addr);
++      else {
++              for (port = portlist; *port; port++) {
++                      err = sk_isa_probe1(dev, *port);
++                      if (!err)
++                              break;
+               }
+-              if(!dev->base_addr)
+-                      return -1;
+       }
+-      else
+-      {
+-              if (!request_region(dev->base_addr, SK_ISA_IO_EXTENT, isa_cardname))
+-                      return -1;
+-
+-              if(sk_isa_probe1(dev->base_addr))
+-              {
+-                      release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+-                      return -1;
+-              }
+-      } 
++      if (err)
++              goto out4;
+       /* At this point we have found a valid card. */
+       if (versionprinted++ == 0)
+               printk(KERN_DEBUG "%s", version);
++      err = -EIO;
+       if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL))
+               goto out4;
+@@ -284,14 +269,11 @@ int __init sk_isa_probe(struct net_devic
+       printk(KERN_DEBUG "%s:    IO: %#4lx  IRQ: %d  DMA: %d\n",
+              dev->name, dev->base_addr, dev->irq, dev->dma);
+               
+-      /* Enlist in the card list */
+-      card = kmalloc(sizeof(struct sk_isa_card), GFP_KERNEL);
+-      if (!card)
++      err = register_netdev(dev);
++      if (err)
+               goto out;
+-      card->next = sk_isa_card_list;
+-      sk_isa_card_list = card;
+-      card->dev = dev;
+-      return 0;
++
++      return dev;
+ out:
+       free_dma(dev->dma);
+ out2:
+@@ -300,7 +282,8 @@ out3:
+       tmsdev_term(dev);
+ out4:
+       release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+-      return -1;
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ /*
+@@ -373,6 +356,8 @@ static int sk_isa_close(struct net_devic
+ #define ISATR_MAX_ADAPTERS 3
++static struct net_device *sk_isa_dev[ISATR_MAX_ADAPTERS];
++
+ static int io[ISATR_MAX_ADAPTERS];
+ static int irq[ISATR_MAX_ADAPTERS];
+ static int dma[ISATR_MAX_ADAPTERS];
+@@ -383,50 +368,54 @@ MODULE_PARM(io, "1-" __MODULE_STRING(ISA
+ MODULE_PARM(irq, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+ MODULE_PARM(dma, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+-static int __init setup_card(unsigned long io, unsigned irq, unsigned char dma)
++static struct net_device * __init setup_card(unsigned long io, unsigned irq, unsigned char dma)
+ {
+-      int res = -ENOMEM;
+-      struct sk_isa_card *this_card;
+-      struct net_device *dev = alloc_trdev(0);
+-
+-      if (dev) {
+-              dev->base_addr = io;
+-              dev->irq       = irq;
+-              dev->dma       = dma;
+-              res = -ENODEV;
+-              if (sk_isa_probe(dev) == 0) {
+-                      res = register_netdev(dev);
+-                      if (!res)
+-                              return 0;
+-                      release_region(dev->base_addr, SK_ISA_IO_EXTENT);
+-                      free_irq(dev->irq, dev);
+-                      free_dma(dev->dma);
+-                      tmsdev_term(dev);
+-                      this_card = sk_isa_card_list;
+-                      sk_isa_card_list = this_card->next;
+-                      kfree(this_card);
+-              }
+-              kfree(dev);
+-      }
+-      return res;
++      struct net_device *dev = alloc_trdev(sizeof(struct net_local));
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      dev->base_addr = io;
++      dev->irq       = irq;
++      dev->dma       = dma;
++
++      err = sk_isa_probe1(dev, io);
++      if (err)
++              goto out;
++
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++
++ out1:
++      release_region(dev->base_addr, SK_ISA_IO_EXTENT);
++      free_irq(dev->irq, dev);
++      free_dma(dev->dma);
++      tmsdev_term(dev);
++ out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
+ int init_module(void)
+ {
++      struct net_device *dev;
+       int i, num;
+       num = 0;
+-      if (io[0]) { /* Only probe addresses from command line */
+-              for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
+-                      if (io[i] && setup_card(io[i], irq[i], dma[i]) == 0)
+-                              num++;
+-              }
+-      } else {
+-              for(i = 0; num < ISATR_MAX_ADAPTERS && portlist[i]; i++) {
+-                      if (setup_card(portlist[i], irq[num], dma[num]) == 0)
+-                              num++;
++      for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
++              if (io[0])  /* Only probe addresses from command line */
++                      dev = setup_card(io[i], irq[i], dma[i]);
++              else
++                      dev = sk_isa_probe(-1);
++              if (!IS_ERR(dev)) {
++                      sk_isa_dev[i] = dev;
++                      ++num;
+               }
+       }
++
+       printk(KERN_NOTICE "skisa.c: %d cards found.\n", num);
+       /* Probe for cards. */
+       if (num == 0) {
+@@ -438,11 +427,13 @@ int init_module(void)
+ void cleanup_module(void)
+ {
+-      struct net_device *dev;
+-      struct sk_isa_card *this_card;
++      int i;
++
++      for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
++              struct net_device *dev = sk_isa_dev[i];
+-      while (sk_isa_card_list) {
+-              dev = sk_isa_card_list->dev;
++              if (!dev) 
++                      continue;
+               
+               unregister_netdev(dev);
+               release_region(dev->base_addr, SK_ISA_IO_EXTENT);
+@@ -450,9 +441,6 @@ void cleanup_module(void)
+               free_dma(dev->dma);
+               tmsdev_term(dev);
+               free_netdev(dev);
+-              this_card = sk_isa_card_list;
+-              sk_isa_card_list = this_card->next;
+-              kfree(this_card);
+       }
+ }
+ #endif /* MODULE */
+--- linux-2.6.0/drivers/net/tokenring/smctr.c  2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/tokenring/smctr.c   2003-12-28 23:21:01.000000000 -0800
+@@ -69,13 +69,6 @@ static const char cardname[] = "smctr";
+ #define SMCTR_IO_EXTENT   20
+-/* A zero-terminated list of I/O addresses to be probed. */
+-static unsigned int smctr_portlist[] __initdata = {
+-        0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300,
+-        0x320, 0x340, 0x360, 0x380,
+-        0
+-};
+-
+ #ifdef CONFIG_MCA
+ static unsigned int smctr_posid = 0x6ec6;
+ #endif
+@@ -219,7 +212,7 @@ static int smctr_open(struct net_device 
+ static int smctr_open_tr(struct net_device *dev);
+ /* P */
+-int __init smctr_probe (struct net_device *dev);
++struct net_device *smctr_probe(int unit);
+ static int __init smctr_probe1(struct net_device *dev, int ioaddr);
+ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
+         struct net_device *dev, __u16 rx_status);
+@@ -729,10 +722,6 @@ static int smctr_close(struct net_device
+       netif_stop_queue(dev);
+       
+-#ifdef MODULE
+-        MOD_DEC_USE_COUNT;
+-#endif
+-
+       tp->cleanup = 1;
+         /* Check to see if adapter is already in a closed state. */
+@@ -3490,10 +3479,6 @@ static int smctr_open(struct net_device 
+         if(err < 0)
+                 return (err);
+-#ifdef MODULE
+-        MOD_INC_USE_COUNT;
+-#endif
+-
+         return (err);
+ }
+@@ -3591,71 +3576,72 @@ out:
+         return (err);
+ }
+-/* Check for a network adapter of this type, and return '0 if one exists.
+- * If dev->base_addr == 0, probe all likely locations.
+- * If dev->base_addr == 1, always return failure.
++/* Check for a network adapter of this type, 
++ * and return device structure if one exists.
+  */
+-int __init smctr_probe (struct net_device *dev)
++struct net_device __init *smctr_probe(int unit)
+ {
+-        int i;
+-        int base_addr;
+-
+-#ifndef MODULE
+-      netdev_boot_setup_check(dev);
+-      tr_setup(dev);
+-#endif
++      struct net_device *dev = alloc_trdev(sizeof(struct net_local));
++      static const unsigned ports[] = {
++              0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300,
++              0x320, 0x340, 0x360, 0x380, 0
++      };
++      const unsigned *port;
++        int err = 0;
+-        base_addr = dev->base_addr;
+-        if(base_addr > 0x1ff)    /* Check a single specified location. */
+-                return (smctr_probe1(dev, base_addr));
+-        else if(base_addr != 0)  /* Don't probe at all. */
+-                return (-ENXIO);
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+-        for(i = 0; smctr_portlist[i]; i++)
+-        {
+-                int ioaddr = smctr_portlist[i];
+-                if (!smctr_probe1(dev, ioaddr))
+-                        return (0);
+-        }
++      SET_MODULE_OWNER(dev);
+-        return (-ENODEV);
+-}
++      if (unit >= 0) {
++              sprintf(dev->name, "tr%d", unit);
++              netdev_boot_setup_check(dev);
++      }
+-static void cleanup_card(struct net_device *dev)
+-{
++        if (dev->base_addr > 0x1ff)    /* Check a single specified location. */
++              err = smctr_probe1(dev, dev->base_addr);
++        else if(dev->base_addr != 0)  /* Don't probe at all. */
++                err =-ENXIO;
++      else {
++              for (port = ports; *port; port++) {
++                      err = smctr_probe1(dev, *port);
++                      if (!err)
++                              break;
++              }
++      }
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
+ #ifdef CONFIG_MCA
+-      struct net_local *tp = (struct net_local *)dev->priv;
+-      if (tp->slot_num)
++      { struct net_local *tp = (struct net_local *)dev->priv;
++        if (tp->slot_num)
+               mca_mark_as_unused(tp->slot_num);
++      }
+ #endif
+       release_region(dev->base_addr, SMCTR_IO_EXTENT);
+-      if (dev->irq)
+-              free_irq(dev->irq, dev);
+-      if (dev->priv)
+-              kfree(dev->priv);
++      free_irq(dev->irq, dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
+ }
++
+ static int __init smctr_probe1(struct net_device *dev, int ioaddr)
+ {
+         static unsigned version_printed;
+-        struct net_local *tp;
++        struct net_local *tp = dev->priv;
+         int err;
+         __u32 *ram;
+         if(smctr_debug && version_printed++ == 0)
+                 printk(version);
+-        /* Setup this devices private information structure */
+-        tp = (struct net_local *)kmalloc(sizeof(struct net_local),
+-                GFP_KERNEL);
+-        if(tp == NULL) {
+-              err = -ENOMEM;
+-              goto out;
+-      }
+-        memset(tp, 0, sizeof(struct net_local));
+         spin_lock_init(&tp->lock);
+-        
+-        dev->priv = tp;
+         dev->base_addr = ioaddr;
+       /* Actually detect an adapter now. */
+@@ -3664,7 +3650,7 @@ static int __init smctr_probe1(struct ne
+         {
+               if ((err = smctr_chk_mca(dev)) < 0) {
+                       err = -ENODEV;
+-                      goto out_tp;
++                      goto out;
+               }
+         }
+@@ -3679,7 +3665,6 @@ static int __init smctr_probe1(struct ne
+         if(err != UCODE_PRESENT && err != SUCCESS)
+         {
+                 printk(KERN_ERR "%s: Firmware load failed (%d)\n", dev->name, err);
+-              cleanup_card(dev);
+               err = -EIO;
+               goto out;
+         }
+@@ -3704,8 +3689,6 @@ static int __init smctr_probe1(struct ne
+         dev->set_multicast_list = &smctr_set_multicast_list;
+         return (0);
+-out_tp:
+-      kfree(tp);
+ out:
+       return err;
+ }
+@@ -5677,47 +5660,59 @@ static int smctr_wait_while_cbusy(struct
+ static struct net_device* dev_smctr[SMCTR_MAX_ADAPTERS];
+ static int io[SMCTR_MAX_ADAPTERS];
+ static int irq[SMCTR_MAX_ADAPTERS];
+-static int mem[SMCTR_MAX_ADAPTERS];
+ MODULE_LICENSE("GPL");
+-MODULE_PARM(io,  "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
++MODULE_PARM(io, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
+ MODULE_PARM(irq, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
+-MODULE_PARM(mem, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
+-MODULE_PARM(ringspeed, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
++MODULE_PARM(ringspeed, "i");
++
++static struct net_device *setup_card(int n)
++{
++      struct net_device *dev = alloc_trdev(sizeof(struct net_local));
++      int err;
++      
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      dev->irq = irq[n];
++      err = smctr_probe1(dev, io[n]);
++      if (err) 
++              goto out;
++              
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++ out1:
++#ifdef CONFIG_MCA
++      { struct net_local *tp = (struct net_local *)dev->priv;
++        if (tp->slot_num)
++              mca_mark_as_unused(tp->slot_num);
++      }
++#endif
++      release_region(dev->base_addr, SMCTR_IO_EXTENT);
++      free_irq(dev->irq, dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++                      
+ int init_module(void)
+ {
+-        int i;
++        int i, found = 0;
++      struct net_device *dev;
+         for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) {
+-              struct net_device *dev = alloc_trdev(0);
+-                irq[i] = 0;
+-                mem[i] = 0;
+-              if (!dev)
+-                      return -ENOMEM;
+-                dev->base_addr = io[i];
+-                dev->irq       = irq[i];
+-                dev->mem_start = mem[i];
+-
+-              if (smctr_probe(dev) != 0) {
+-                        kfree(dev);
+-                        if (i == 0) {
+-                                printk(KERN_ERR "%s: smctr_probe failed.\n",
+-                                        cardname);
+-                                return -EIO;
+-                        }
+-                      return 0;
+-                }
+-              if (register_netdev(dev) != 0) {
+-                        cleanup_card(dev);
+-                      kfree(dev);
+-                      continue;
+-                }
+-                dev_smctr[i] = dev;
++              dev = io[0]? setup_card(i) : smctr_probe(-1);
++              if (!IS_ERR(dev)) {
++                      ++found;
++                      dev_smctr[i] = dev;
++              }
+         }
+-        return (0);
++        return found ? 0 : -ENODEV;
+ }
+ void cleanup_module(void)
+@@ -5726,9 +5721,20 @@ void cleanup_module(void)
+         for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) {
+               struct net_device *dev = dev_smctr[i];
++
+               if (dev) {
++
+                       unregister_netdev(dev);
+-                      cleanup_card(dev);
++#ifdef CONFIG_MCA
++                      { struct net_local *tp = dev->priv;
++                      if (tp->slot_num)
++                              mca_mark_as_unused(tp->slot_num);
++                      }
++#endif
++                      release_region(dev->base_addr, SMCTR_IO_EXTENT);
++                      if (dev->irq)
++                              free_irq(dev->irq, dev);
++
+                       free_netdev(dev);
+               }
+         }
+--- linux-2.6.0/drivers/net/tokenring/tms380tr.c       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/tokenring/tms380tr.c        2003-12-28 23:21:01.000000000 -0800
+@@ -147,7 +147,6 @@ static void        tms380tr_hardware_send_pack
+                       struct net_local* tp);
+ /* "I" */
+ static int    tms380tr_init_adapter(struct net_device *dev);
+-static int    tms380tr_init_card(struct net_device *dev);
+ static void   tms380tr_init_ipb(struct net_local *tp);
+ static void   tms380tr_init_net_local(struct net_device *dev);
+ static void   tms380tr_init_opb(struct net_device *dev);
+@@ -232,15 +231,6 @@ static int madgemc_sifprobe(struct net_d
+ }
+ #endif
+-/* Dummy function */
+-static int tms380tr_init_card(struct net_device *dev)
+-{
+-      if(tms380tr_debug > 3)
+-              printk(KERN_DEBUG "%s: tms380tr_init_card\n", dev->name);
+-
+-      return (0);
+-}
+-
+ /*
+  * Open/initialize the board. This is called sometime after
+  * booting when the 'ifconfig' program is run.
+@@ -2386,7 +2376,6 @@ int tmsdev_init(struct net_device *dev, 
+       }
+       
+       /* These can be overridden by the card driver if needed */
+-      dev->init               = tms380tr_init_card;
+       dev->open               = tms380tr_open;
+       dev->stop               = tms380tr_close;
+       dev->do_ioctl           = NULL; 
+--- linux-2.6.0/drivers/net/tokenring/tmspci.c 2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/tokenring/tmspci.c  2003-12-28 23:21:01.000000000 -0800
+@@ -179,7 +179,7 @@ err_out_irq:
+ err_out_region:
+       release_region(pci_ioaddr, TMS_PCI_IO_EXTENT);
+ err_out_trdev:
+-      kfree(dev);
++      free_netdev(dev);
+       return ret;
+ }
+--- linux-2.6.0/drivers/net/tulip/de2104x.c    2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/tulip/de2104x.c     2003-12-28 23:21:01.000000000 -0800
+@@ -2084,7 +2084,7 @@ err_out_res:
+ err_out_disable:
+       pci_disable_device(pdev);
+ err_out_free:
+-      kfree(dev);
++      free_netdev(dev);
+       return rc;
+ }
+--- linux-2.6.0/drivers/net/tulip/dmfe.c       2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/net/tulip/dmfe.c        2003-12-28 23:21:01.000000000 -0800
+@@ -457,7 +457,7 @@ err_out_disable:
+       pci_disable_device(pdev);
+ err_out_free:
+       pci_set_drvdata(pdev, NULL);
+-      kfree(dev);
++      free_netdev(dev);
+       return err;
+ }
+--- linux-2.6.0/drivers/net/tulip/interrupt.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/net/tulip/interrupt.c   2003-12-28 23:21:01.000000000 -0800
+@@ -19,13 +19,13 @@
+ #include <linux/etherdevice.h>
+ #include <linux/pci.h>
+-
+ int tulip_rx_copybreak;
+ unsigned int tulip_max_interrupt_work;
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-
++#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
+ #define MIT_SIZE 15
++#define MIT_TABLE 15 /* We use 0 or max */
++
+ unsigned int mit_table[MIT_SIZE+1] =
+ {
+         /*  CRS11 21143 hardware Mitigation Control Interrupt
+@@ -99,16 +99,28 @@ int tulip_refill_rx(struct net_device *d
+       return refilled;
+ }
++#ifdef CONFIG_TULIP_NAPI
+-static int tulip_rx(struct net_device *dev)
++void oom_timer(unsigned long data)
++{
++        struct net_device *dev = (struct net_device *)data;
++      netif_rx_schedule(dev);
++}
++
++int tulip_poll(struct net_device *dev, int *budget)
+ {
+       struct tulip_private *tp = (struct tulip_private *)dev->priv;
+       int entry = tp->cur_rx % RX_RING_SIZE;
+-      int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
++      int rx_work_limit = *budget;
+       int received = 0;
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-        int drop = 0, mit_sel = 0;
++      if (!netif_running(dev))
++              goto done;
++
++      if (rx_work_limit > dev->quota)
++              rx_work_limit = dev->quota;
++
++#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
+ /* that one buffer is needed for mit activation; or might be a
+    bug in the ring buffer code; check later -- JHS*/
+@@ -119,6 +131,237 @@ static int tulip_rx(struct net_device *d
+       if (tulip_debug > 4)
+               printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
+                          tp->rx_ring[entry].status);
++
++       do {
++               /* Acknowledge current RX interrupt sources. */
++               outl((RxIntr | RxNoBuf), dev->base_addr + CSR5);
++ 
++ 
++               /* If we own the next entry, it is a new packet. Send it up. */
++               while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
++                       s32 status = le32_to_cpu(tp->rx_ring[entry].status);
++ 
++ 
++                       if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
++                               break;
++ 
++                       if (tulip_debug > 5)
++                               printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
++                                      dev->name, entry, status);
++                       if (--rx_work_limit < 0)
++                               goto not_done;
++ 
++                       if ((status & 0x38008300) != 0x0300) {
++                               if ((status & 0x38000300) != 0x0300) {
++                                /* Ingore earlier buffers. */
++                                       if ((status & 0xffff) != 0x7fff) {
++                                               if (tulip_debug > 1)
++                                                       printk(KERN_WARNING "%s: Oversized Ethernet frame "
++                                                              "spanned multiple buffers, status %8.8x!\n",
++                                                              dev->name, status);
++                                               tp->stats.rx_length_errors++;
++                                       }
++                               } else if (status & RxDescFatalErr) {
++                                /* There was a fatal error. */
++                                       if (tulip_debug > 2)
++                                               printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
++                                                      dev->name, status);
++                                       tp->stats.rx_errors++; /* end of a packet.*/
++                                       if (status & 0x0890) tp->stats.rx_length_errors++;
++                                       if (status & 0x0004) tp->stats.rx_frame_errors++;
++                                       if (status & 0x0002) tp->stats.rx_crc_errors++;
++                                       if (status & 0x0001) tp->stats.rx_fifo_errors++;
++                               }
++                       } else {
++                               /* Omit the four octet CRC from the length. */
++                               short pkt_len = ((status >> 16) & 0x7ff) - 4;
++                               struct sk_buff *skb;
++  
++#ifndef final_version
++                               if (pkt_len > 1518) {
++                                       printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
++                                              dev->name, pkt_len, pkt_len);
++                                       pkt_len = 1518;
++                                       tp->stats.rx_length_errors++;
++                               }
++#endif
++                               /* Check if the packet is long enough to accept without copying
++                                  to a minimally-sized skbuff. */
++                               if (pkt_len < tulip_rx_copybreak
++                                   && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
++                                       skb->dev = dev;
++                                       skb_reserve(skb, 2);    /* 16 byte align the IP header */
++                                       pci_dma_sync_single(tp->pdev,
++                                                           tp->rx_buffers[entry].mapping,
++                                                           pkt_len, PCI_DMA_FROMDEVICE);
++#if ! defined(__alpha__)
++                                       eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
++                                                        pkt_len, 0);
++                                       skb_put(skb, pkt_len);
++#else
++                                       memcpy(skb_put(skb, pkt_len),
++                                              tp->rx_buffers[entry].skb->tail,
++                                              pkt_len);
++#endif
++                               } else {        /* Pass up the skb already on the Rx ring. */
++                                       char *temp = skb_put(skb = tp->rx_buffers[entry].skb,
++                                                            pkt_len);
++  
++#ifndef final_version
++                                       if (tp->rx_buffers[entry].mapping !=
++                                           le32_to_cpu(tp->rx_ring[entry].buffer1)) {
++                                               printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
++                                                      "do not match in tulip_rx: %08x vs. %08x %p / %p.\n",
++                                                      dev->name,
++                                                      le32_to_cpu(tp->rx_ring[entry].buffer1),
++                                                      tp->rx_buffers[entry].mapping,
++                                                      skb->head, temp);
++                                       }
++#endif
++  
++                                       pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping,
++                                                        PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
++  
++                                       tp->rx_buffers[entry].skb = NULL;
++                                       tp->rx_buffers[entry].mapping = 0;
++                               }
++                               skb->protocol = eth_type_trans(skb, dev);
++  
++                               netif_receive_skb(skb);
++ 
++                               dev->last_rx = jiffies;
++                               tp->stats.rx_packets++;
++                               tp->stats.rx_bytes += pkt_len;
++                       }
++                       received++;
++
++                       entry = (++tp->cur_rx) % RX_RING_SIZE;
++                       if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/4)
++                               tulip_refill_rx(dev);
++ 
++                }
++ 
++               /* New ack strategy... irq does not ack Rx any longer
++                  hopefully this helps */
++ 
++               /* Really bad things can happen here... If new packet arrives
++                * and an irq arrives (tx or just due to occasionally unset
++                * mask), it will be acked by irq handler, but new thread
++                * is not scheduled. It is major hole in design.
++                * No idea how to fix this if "playing with fire" will fail
++                * tomorrow (night 011029). If it will not fail, we won
++                * finally: amount of IO did not increase at all. */
++       } while ((inl(dev->base_addr + CSR5) & RxIntr));
++ 
++done:
++ 
++ #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
++  
++          /* We use this simplistic scheme for IM. It's proven by
++             real life installations. We can have IM enabled
++            continuesly but this would cause unnecessary latency. 
++            Unfortunely we can't use all the NET_RX_* feedback here. 
++            This would turn on IM for devices that is not contributing 
++            to backlog congestion with unnecessary latency. 
++  
++             We monitor the the device RX-ring and have:
++  
++             HW Interrupt Mitigation either ON or OFF.
++  
++            ON:  More then 1 pkt received (per intr.) OR we are dropping 
++             OFF: Only 1 pkt received
++            
++             Note. We only use min and max (0, 15) settings from mit_table */
++  
++  
++          if( tp->flags &  HAS_INTR_MITIGATION) {
++                 if( received > 1 ) {
++                         if( ! tp->mit_on ) {
++                                 tp->mit_on = 1;
++                                 outl(mit_table[MIT_TABLE], dev->base_addr + CSR11);
++                         }
++                  }
++                 else {
++                         if( tp->mit_on ) {
++                                 tp->mit_on = 0;
++                                 outl(0, dev->base_addr + CSR11);
++                         }
++                  }
++          }
++
++#endif /* CONFIG_TULIP_NAPI_HW_MITIGATION */
++ 
++         dev->quota -= received;
++         *budget -= received;
++ 
++         tulip_refill_rx(dev);
++         
++         /* If RX ring is not full we are out of memory. */
++         if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) goto oom;
++ 
++         /* Remove us from polling list and enable RX intr. */
++ 
++         netif_rx_complete(dev);
++         outl(tulip_tbl[tp->chip_id].valid_intrs, dev->base_addr+CSR7);
++ 
++         /* The last op happens after poll completion. Which means the following:
++          * 1. it can race with disabling irqs in irq handler
++          * 2. it can race with dise/enabling irqs in other poll threads
++          * 3. if an irq raised after beginning loop, it will be immediately
++          *    triggered here.
++          *
++          * Summarizing: the logic results in some redundant irqs both
++          * due to races in masking and due to too late acking of already
++          * processed irqs. But it must not result in losing events.
++          */
++ 
++         return 0;
++ 
++ not_done:
++         if (!received) {
++
++                 received = dev->quota; /* Not to happen */
++         }
++         dev->quota -= received;
++         *budget -= received;
++ 
++         if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
++             tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
++                 tulip_refill_rx(dev);
++ 
++         if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL) goto oom;
++ 
++         return 1;
++ 
++ 
++ oom:    /* Executed with RX ints disabled */
++ 
++         
++         /* Start timer, stop polling, but do not enable rx interrupts. */
++         mod_timer(&tp->oom_timer, jiffies+1);
++       
++         /* Think: timer_pending() was an explicit signature of bug.
++          * Timer can be pending now but fired and completed
++          * before we did netif_rx_complete(). See? We would lose it. */
++ 
++         /* remove ourselves from the polling list */
++         netif_rx_complete(dev);
++ 
++         return 0;
++}
++
++#else /* CONFIG_TULIP_NAPI */
++
++static int tulip_rx(struct net_device *dev)
++{
++      struct tulip_private *tp = (struct tulip_private *)dev->priv;
++      int entry = tp->cur_rx % RX_RING_SIZE;
++      int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
++      int received = 0;
++
++      if (tulip_debug > 4)
++              printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
++                         tp->rx_ring[entry].status);
+       /* If we own the next entry, it is a new packet. Send it up. */
+       while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
+               s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+@@ -163,11 +406,6 @@ static int tulip_rx(struct net_device *d
+                       }
+ #endif
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                        drop = atomic_read(&netdev_dropping);
+-                        if (drop)
+-                                goto throttle;
+-#endif
+                       /* Check if the packet is long enough to accept without copying
+                          to a minimally-sized skbuff. */
+                       if (pkt_len < tulip_rx_copybreak
+@@ -209,44 +447,9 @@ static int tulip_rx(struct net_device *d
+                               tp->rx_buffers[entry].mapping = 0;
+                       }
+                       skb->protocol = eth_type_trans(skb, dev);
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                        mit_sel =
+-#endif
+-                      netif_rx(skb);
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                        switch (mit_sel) {
+-                        case NET_RX_SUCCESS:
+-                        case NET_RX_CN_LOW:
+-                        case NET_RX_CN_MOD:
+-                                break;
+-
+-                        case NET_RX_CN_HIGH:
+-                                rx_work_limit -= NET_RX_CN_HIGH; /* additional*/
+-                                break;
+-                        case NET_RX_DROP:
+-                                rx_work_limit = -1;
+-                                break;
+-                        default:
+-                                printk("unknown feedback return code %d\n", mit_sel);
+-                                break;
+-                        }
++                      netif_rx(skb);
+-                        drop = atomic_read(&netdev_dropping);
+-                        if (drop) {
+-throttle:
+-                                rx_work_limit = -1;
+-                                mit_sel = NET_RX_DROP;
+-
+-                                if (tp->fc_bit) {
+-                                        long ioaddr = dev->base_addr;
+-
+-                                        /* disable Rx & RxNoBuf ints. */
+-                                        outl(tulip_tbl[tp->chip_id].valid_intrs&RX_A_NBF_STOP, ioaddr + CSR7);
+-                                        set_bit(tp->fc_bit, &netdev_fc_xoff);
+-                                }
+-                        }
+-#endif
+                       dev->last_rx = jiffies;
+                       tp->stats.rx_packets++;
+                       tp->stats.rx_bytes += pkt_len;
+@@ -254,42 +457,9 @@ throttle:
+               received++;
+               entry = (++tp->cur_rx) % RX_RING_SIZE;
+       }
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-
+-        /* We use this simplistic scheme for IM. It's proven by
+-           real life installations. We can have IM enabled
+-           continuesly but this would cause unnecessary latency.
+-           Unfortunely we can't use all the NET_RX_* feedback here.
+-           This would turn on IM for devices that is not contributing
+-           to backlog congestion with unnecessary latency.
+-
+-           We monitor the device RX-ring and have:
+-
+-           HW Interrupt Mitigation either ON or OFF.
+-
+-           ON:  More then 1 pkt received (per intr.) OR we are dropping
+-           OFF: Only 1 pkt received
+-
+-           Note. We only use min and max (0, 15) settings from mit_table */
+-
+-
+-        if( tp->flags &  HAS_INTR_MITIGATION) {
+-                if((received > 1 || mit_sel == NET_RX_DROP)
+-                   && tp->mit_sel != 15 ) {
+-                        tp->mit_sel = 15;
+-                        tp->mit_change = 1; /* Force IM change */
+-                }
+-                if((received <= 1 && mit_sel != NET_RX_DROP) && tp->mit_sel != 0 ) {
+-                        tp->mit_sel = 0;
+-                        tp->mit_change = 1; /* Force IM change */
+-                }
+-        }
+-
+-        return RX_RING_SIZE+1; /* maxrx+1 */
+-#else
+       return received;
+-#endif
+ }
++#endif  /* CONFIG_TULIP_NAPI */
+ static inline unsigned int phy_interrupt (struct net_device *dev)
+ {
+@@ -323,7 +493,6 @@ irqreturn_t tulip_interrupt(int irq, voi
+       struct tulip_private *tp = (struct tulip_private *)dev->priv;
+       long ioaddr = dev->base_addr;
+       int csr5;
+-      int entry;
+       int missed;
+       int rx = 0;
+       int tx = 0;
+@@ -331,6 +500,11 @@ irqreturn_t tulip_interrupt(int irq, voi
+       int maxrx = RX_RING_SIZE;
+       int maxtx = TX_RING_SIZE;
+       int maxoi = TX_RING_SIZE;
++#ifdef CONFIG_TULIP_NAPI
++      int rxd = 0;
++#else
++      int entry;
++#endif
+       unsigned int work_count = tulip_max_interrupt_work;
+       unsigned int handled = 0;
+@@ -346,22 +520,41 @@ irqreturn_t tulip_interrupt(int irq, voi
+       tp->nir++;
+       do {
++
++#ifdef CONFIG_TULIP_NAPI
++
++              if (!rxd && (csr5 & (RxIntr | RxNoBuf))) {
++                      rxd++;
++                      /* Mask RX intrs and add the device to poll list. */
++                      outl(tulip_tbl[tp->chip_id].valid_intrs&~RxPollInt, ioaddr + CSR7);
++                      netif_rx_schedule(dev);
++                      
++                      if (!(csr5&~(AbnormalIntr|NormalIntr|RxPollInt|TPLnkPass)))
++                               break;
++              }
++              
++               /* Acknowledge the interrupt sources we handle here ASAP
++                  the poll function does Rx and RxNoBuf acking */
++              
++              outl(csr5 & 0x0001ff3f, ioaddr + CSR5);
++
++#else 
+               /* Acknowledge all of the current interrupt sources ASAP. */
+               outl(csr5 & 0x0001ffff, ioaddr + CSR5);
+-              if (tulip_debug > 4)
+-                      printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
+-                                 dev->name, csr5, inl(dev->base_addr + CSR5));
+               if (csr5 & (RxIntr | RxNoBuf)) {
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                        if ((!tp->fc_bit) ||
+-                          (!test_bit(tp->fc_bit, &netdev_fc_xoff)))
+-#endif
+                               rx += tulip_rx(dev);
+                       tulip_refill_rx(dev);
+               }
++#endif /*  CONFIG_TULIP_NAPI */
++              
++              if (tulip_debug > 4)
++                      printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x.\n",
++                             dev->name, csr5, inl(dev->base_addr + CSR5));
++              
++
+               if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) {
+                       unsigned int dirty_tx;
+@@ -462,15 +655,8 @@ irqreturn_t tulip_interrupt(int irq, voi
+                       }
+                       if (csr5 & RxDied) {            /* Missed a Rx frame. */
+                                 tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                              if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) {
+-                                      tp->stats.rx_errors++;
+-                                      tulip_start_rxtx(tp);
+-                              }
+-#else
+                               tp->stats.rx_errors++;
+                               tulip_start_rxtx(tp);
+-#endif
+                       }
+                       /*
+                        * NB: t21142_lnk_change() does a del_timer_sync(), so be careful if this
+@@ -504,10 +690,6 @@ irqreturn_t tulip_interrupt(int irq, voi
+                       if (tulip_debug > 2)
+                               printk(KERN_ERR "%s: Re-enabling interrupts, %8.8x.\n",
+                                          dev->name, csr5);
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                        if (tp->fc_bit && (test_bit(tp->fc_bit, &netdev_fc_xoff)))
+-                          if (net_ratelimit()) printk("BUG!! enabling interrupt when FC off (timerintr.) \n");
+-#endif
+                       outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
+                       tp->ttimer = 0;
+                       oi++;
+@@ -520,16 +702,9 @@ irqreturn_t tulip_interrupt(int irq, voi
+                        /* Acknowledge all interrupt sources. */
+                         outl(0x8001ffff, ioaddr + CSR5);
+                         if (tp->flags & HAS_INTR_MITIGATION) {
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-                                if(tp->mit_change) {
+-                                        outl(mit_table[tp->mit_sel], ioaddr + CSR11);
+-                                        tp->mit_change = 0;
+-                                }
+-#else
+                      /* Josip Loncaric at ICASE did extensive experimentation
+                       to develop a good interrupt mitigation setting.*/
+                                 outl(0x8b240000, ioaddr + CSR11);
+-#endif
+                         } else if (tp->chip_id == LC82C168) {
+                               /* the LC82C168 doesn't have a hw timer.*/
+                               outl(0x00, ioaddr + CSR7);
+@@ -537,10 +712,8 @@ irqreturn_t tulip_interrupt(int irq, voi
+                       } else {
+                           /* Mask all interrupting sources, set timer to
+                               re-enable. */
+-#ifndef CONFIG_NET_HW_FLOWCONTROL
+                                 outl(((~csr5) & 0x0001ebef) | AbnormalIntr | TimerInt, ioaddr + CSR7);
+                                 outl(0x0012, ioaddr + CSR11);
+-#endif
+                         }
+                       break;
+               }
+@@ -550,6 +723,21 @@ irqreturn_t tulip_interrupt(int irq, voi
+                       break;
+               csr5 = inl(ioaddr + CSR5);
++
++#ifdef CONFIG_TULIP_NAPI
++              if (rxd)
++                      csr5 &= ~RxPollInt;
++      } while ((csr5 & (TxNoBuf | 
++                        TxDied | 
++                        TxIntr | 
++                        TimerInt |
++                        /* Abnormal intr. */
++                        RxDied | 
++                        TxFIFOUnderflow | 
++                        TxJabber | 
++                        TPLnkFail |  
++                        SytemError )) != 0);
++#else 
+       } while ((csr5 & (NormalIntr|AbnormalIntr)) != 0);
+       tulip_refill_rx(dev);
+@@ -574,6 +762,7 @@ irqreturn_t tulip_interrupt(int irq, voi
+                       }
+               }
+       }
++#endif /* CONFIG_TULIP_NAPI */
+       if ((missed = inl(ioaddr + CSR8) & 0x1ffff)) {
+               tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
+--- linux-2.6.0/drivers/net/tulip/Kconfig      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/net/tulip/Kconfig       2003-12-28 23:21:01.000000000 -0800
+@@ -68,6 +68,26 @@ config TULIP_MMIO
+         obscure bugs if your mainboard has memory controller timing issues.
+         If in doubt, say N.
++config TULIP_NAPI
++      bool "Use NAPI RX polling "
++      depends on TULIP
++      ---help---
++        This is of useful for servers and routers dealing with high network loads.
++ 
++        See <file:Documentation/networking/NAPI_HOWTO.txt>.
++
++        If in doubt, say N.
++
++config TULIP_NAPI_HW_MITIGATION
++      bool "Use Interrupt Mitigation "
++      depends on TULIP_NAPI
++      ---help---
++        Use HW to reduce RX interrupts. Not strict necessary since NAPI reduces
++        RX interrupts but itself. Although this reduces RX interrupts even at
++        low levels traffic at the cost of a small latency.
++
++        If in doubt, say Y.
++
+ config DE4X5
+       tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA"
+       depends on NET_TULIP && (PCI || EISA)
+--- linux-2.6.0/drivers/net/tulip/tulip_core.c 2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/net/tulip/tulip_core.c  2003-12-28 23:21:01.000000000 -0800
+@@ -14,11 +14,17 @@
+ */
++#include <linux/config.h>
++
+ #define DRV_NAME      "tulip"
++#ifdef CONFIG_TULIP_NAPI
++#define DRV_VERSION    "1.1.13-NAPI" /* Keep at least for test */
++#else
+ #define DRV_VERSION   "1.1.13"
++#endif
+ #define DRV_RELDATE   "May 11, 2002"
+-#include <linux/config.h>
++
+ #include <linux/module.h>
+ #include "tulip.h"
+ #include <linux/pci.h>
+@@ -247,7 +253,7 @@ static void tulip_down(struct net_device
+ static struct net_device_stats *tulip_get_stats(struct net_device *dev);
+ static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+ static void set_rx_mode(struct net_device *dev);
+-
++static void poll_tulip(struct net_device *dev);
+ static void tulip_set_power_state (struct tulip_private *tp,
+@@ -466,29 +472,16 @@ media_picked:
+          to an alternate media type. */
+       tp->timer.expires = RUN_AT(next_tick);
+       add_timer(&tp->timer);
+-}
+-
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-/* Enable receiver */
+-void tulip_xon(struct net_device *dev)
+-{
+-        struct tulip_private *tp = (struct tulip_private *)dev->priv;
+-
+-        clear_bit(tp->fc_bit, &netdev_fc_xoff);
+-        if (netif_running(dev)){
+-
+-                tulip_refill_rx(dev);
+-                outl(tulip_tbl[tp->chip_id].valid_intrs,  dev->base_addr+CSR7);
+-        }
+-}
++#ifdef CONFIG_TULIP_NAPI
++      init_timer(&tp->oom_timer);
++        tp->oom_timer.data = (unsigned long)dev;
++        tp->oom_timer.function = oom_timer;
+ #endif
++}
+ static int
+ tulip_open(struct net_device *dev)
+ {
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-        struct tulip_private *tp = (struct tulip_private *)dev->priv;
+-#endif
+       int retval;
+       if ((retval = request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev)))
+@@ -498,10 +491,6 @@ tulip_open(struct net_device *dev)
+       tulip_up (dev);
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-        tp->fc_bit = netdev_register_fc(dev, tulip_xon);
+-#endif
+-
+       netif_start_queue (dev);
+       return 0;
+@@ -582,10 +571,7 @@ static void tulip_tx_timeout(struct net_
+ #endif
+       /* Stop and restart the chip's Tx processes . */
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-        if (tp->fc_bit && test_bit(tp->fc_bit,&netdev_fc_xoff))
+-                printk("BUG tx_timeout restarting rx when fc on\n");
+-#endif
++
+       tulip_restart_rxtx(tp);
+       /* Trigger an immediate transmit demand. */
+       outl(0, ioaddr + CSR1);
+@@ -742,7 +728,9 @@ static void tulip_down (struct net_devic
+       unsigned long flags;
+       del_timer_sync (&tp->timer);
+-
++#ifdef CONFIG_TULIP_NAPI
++      del_timer_sync (&tp->oom_timer);
++#endif
+       spin_lock_irqsave (&tp->lock, flags);
+       /* Disable interrupts by clearing the interrupt mask. */
+@@ -781,13 +769,6 @@ static int tulip_close (struct net_devic
+       netif_stop_queue (dev);
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-        if (tp->fc_bit) {
+-                int bit = tp->fc_bit;
+-                tp->fc_bit = 0;
+-                netdev_unregister_fc(bit);
+-        }
+-#endif
+       tulip_down (dev);
+       if (tulip_debug > 1)
+@@ -1629,10 +1610,17 @@ static int __devinit tulip_init_one (str
+       dev->hard_start_xmit = tulip_start_xmit;
+       dev->tx_timeout = tulip_tx_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
++#ifdef CONFIG_TULIP_NAPI
++      dev->poll = tulip_poll;
++      dev->weight = 16;
++#endif
+       dev->stop = tulip_close;
+       dev->get_stats = tulip_get_stats;
+       dev->do_ioctl = private_ioctl;
+       dev->set_multicast_list = set_rx_mode;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++      dev->poll_controller = &poll_tulip;
++#endif
+       if (register_netdev(dev))
+               goto err_out_free_ring;
+@@ -1725,7 +1713,7 @@ err_out_free_res:
+       pci_release_regions (pdev);
+ err_out_free_netdev:
+-      kfree (dev);
++      free_netdev (dev);
+       return -ENODEV;
+ }
+@@ -1789,6 +1777,22 @@ static void __devexit tulip_remove_one (
+       /* pci_power_off (pdev, -1); */
+ }
++#ifdef CONFIG_NET_POLL_CONTROLLER
++/*
++ * Polling 'interrupt' - used by things like netconsole to send skbs
++ * without having to re-enable interrupts. It's not called while
++ * the interrupt routine is executing.
++ */
++
++static void poll_tulip (struct net_device *dev)
++{
++      /* disable_irq here is not very nice, but with the lockless
++         interrupt handler we have no other choice. */
++      disable_irq(dev->irq);
++      tulip_interrupt (dev->irq, dev, NULL);
++      enable_irq(dev->irq);
++}
++#endif
+ static struct pci_driver tulip_driver = {
+       .name           = DRV_NAME,
+--- linux-2.6.0/drivers/net/tulip/tulip.h      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/net/tulip/tulip.h       2003-12-28 23:21:01.000000000 -0800
+@@ -126,6 +126,7 @@ enum pci_cfg_driver_reg {
+       CFDD_Snooze = (1 << 30),
+ };
++#define RxPollInt (RxIntr|RxNoBuf|RxDied|RxJabber)
+ /* The bits in the CSR5 status registers, mostly interrupt sources. */
+ enum status_bits {
+@@ -251,9 +252,9 @@ enum t21143_csr6_bits {
+    Making the Tx ring too large decreases the effectiveness of channel
+    bonding and packet priority.
+    There are no ill effects from too-large receive rings. */
+-#define TX_RING_SIZE  16
+-#define RX_RING_SIZE  32
++#define TX_RING_SIZE  32
++#define RX_RING_SIZE  128 
+ #define MEDIA_MASK     31
+ #define PKT_BUF_SZ            1536    /* Size of each temporary Rx buffer. */
+@@ -343,17 +344,15 @@ struct tulip_private {
+       int flags;
+       struct net_device_stats stats;
+       struct timer_list timer;        /* Media selection timer. */
++      struct timer_list oom_timer;    /* Out of memory timer. */
+       u32 mc_filter[2];
+       spinlock_t lock;
+       spinlock_t mii_lock;
+       unsigned int cur_rx, cur_tx;    /* The next free ring entry */
+       unsigned int dirty_rx, dirty_tx;        /* The ring entries to be free()ed. */
+-#ifdef CONFIG_NET_HW_FLOWCONTROL
+-#define RX_A_NBF_STOP 0xffffff3f /* To disable RX and RX-NOBUF ints. */
+-        int fc_bit;
+-        int mit_sel;
+-        int mit_change; /* Signal for Interrupt Mitigtion */
++#ifdef        CONFIG_TULIP_NAPI_HW_MITIGATION
++        int mit_on;
+ #endif
+       unsigned int full_duplex:1;     /* Full-duplex operation requested. */
+       unsigned int full_duplex_lock:1;
+@@ -415,6 +414,10 @@ extern unsigned int tulip_max_interrupt_
+ extern int tulip_rx_copybreak;
+ irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+ int tulip_refill_rx(struct net_device *dev);
++#ifdef CONFIG_TULIP_NAPI
++int tulip_poll(struct net_device *dev, int *budget);
++#endif
++
+ /* media.c */
+ int tulip_mdio_read(struct net_device *dev, int phy_id, int location);
+@@ -438,6 +441,7 @@ extern int tulip_debug;
+ extern const char * const medianame[];
+ extern const char tulip_media_cap[];
+ extern struct tulip_chip_table tulip_tbl[];
++void oom_timer(unsigned long data);
+ extern u8 t21040_csr13[];
+ #ifndef USE_IO_OPS
+--- linux-2.6.0/drivers/net/tulip/winbond-840.c        2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/net/tulip/winbond-840.c 2003-12-28 23:21:01.000000000 -0800
+@@ -530,7 +530,7 @@ err_out_free_res:
+ #endif
+       pci_release_regions(pdev);
+ err_out_netdev:
+-      kfree (dev);
++      free_netdev (dev);
+       return -ENODEV;
+ }
+--- linux-2.6.0/drivers/net/tulip/xircom_tulip_cb.c    2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/tulip/xircom_tulip_cb.c     2003-12-28 23:21:01.000000000 -0800
+@@ -648,8 +648,7 @@ err_out_cleardev:
+       pci_set_drvdata(pdev, NULL);
+       pci_release_regions(pdev);
+ err_out_free_netdev:
+-      unregister_netdev(dev);
+-      kfree(dev);
++      free_netdev(dev);
+       return -ENODEV;
+ }
+--- linux-2.6.0/drivers/net/tun.c      2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/net/tun.c       2003-12-28 23:21:01.000000000 -0800
+@@ -377,6 +377,7 @@ static struct tun_struct *tun_get_by_nam
+ static int tun_set_iff(struct file *file, struct ifreq *ifr)
+ {
+       struct tun_struct *tun;
++      struct net_device *dev;
+       int err;
+       tun = tun_get_by_name(ifr->ifr_name);
+@@ -394,7 +395,6 @@ static int tun_set_iff(struct file *file
+       else {
+               char *name;
+               unsigned long flags = 0;
+-              struct net_device *dev;
+               err = -EINVAL;
+@@ -424,16 +424,13 @@ static int tun_set_iff(struct file *file
+               if (strchr(dev->name, '%')) {
+                       err = dev_alloc_name(dev, dev->name);
+-                      if (err < 0) {
+-                              kfree(dev);
+-                              goto failed;
+-                      }
++                      if (err < 0)
++                              goto err_free_dev;
+               }
+-              if ((err = register_netdevice(tun->dev))) {
+-                      kfree(dev);
+-                      goto failed;
+-              }
++              err = register_netdevice(tun->dev);
++              if (err < 0)
++                      goto err_free_dev;
+       
+               list_add(&tun->list, &tun_dev_list);
+       }
+@@ -451,6 +448,9 @@ static int tun_set_iff(struct file *file
+       strcpy(ifr->ifr_name, tun->dev->name);
+       return 0;
++
++ err_free_dev:
++      free_netdev(dev);
+  failed:
+       return err;
+ }
+--- linux-2.6.0/drivers/net/typhoon.c  2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/net/typhoon.c   2003-12-28 23:21:01.000000000 -0800
+@@ -85,8 +85,8 @@ static const int multicast_filter_limit 
+ #define PKT_BUF_SZ            1536
+ #define DRV_MODULE_NAME               "typhoon"
+-#define DRV_MODULE_VERSION    "1.5.1"
+-#define DRV_MODULE_RELDATE    "03/06/26"
++#define DRV_MODULE_VERSION    "1.5.2"
++#define DRV_MODULE_RELDATE    "03/11/25"
+ #define PFX                   DRV_MODULE_NAME ": "
+ #define ERR_PFX                       KERN_ERR PFX
+@@ -127,7 +127,7 @@ static const int multicast_filter_limit 
+ static char version[] __devinitdata =
+     "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+-MODULE_AUTHOR("David Dillow <dillowd@y12.doe.gov>");
++MODULE_AUTHOR("David Dillow <dave@thedillows.org>");
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)");
+ MODULE_PARM(rx_copybreak, "i");
+@@ -146,11 +146,12 @@ struct typhoon_card_info {
+       int capabilities;
+ };
+-#define TYPHOON_CRYPTO_NONE           0
+-#define TYPHOON_CRYPTO_DES            1
+-#define TYPHOON_CRYPTO_3DES           2
+-#define       TYPHOON_CRYPTO_VARIABLE         4
+-#define TYPHOON_FIBER                 8
++#define TYPHOON_CRYPTO_NONE           0x00
++#define TYPHOON_CRYPTO_DES            0x01
++#define TYPHOON_CRYPTO_3DES           0x02
++#define       TYPHOON_CRYPTO_VARIABLE         0x04
++#define TYPHOON_FIBER                 0x08
++#define TYPHOON_WAKEUP_NEEDS_RESET    0x10
+ enum typhoon_cards {
+       TYPHOON_TX = 0, TYPHOON_TX95, TYPHOON_TX97, TYPHOON_SVR,
+@@ -307,7 +308,8 @@ enum state_values {
+ /* We'll wait up to six seconds for a reset, and half a second normally.
+  */
+ #define TYPHOON_UDELAY                        50
+-#define TYPHOON_RESET_TIMEOUT         (6 * HZ)
++#define TYPHOON_RESET_TIMEOUT_SLEEP   (6 * HZ)
++#define TYPHOON_RESET_TIMEOUT_NOSLEEP ((6 * 1000000) / TYPHOON_UDELAY)
+ #define TYPHOON_WAIT_TIMEOUT          ((1000000 / 2) / TYPHOON_UDELAY)
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 28)
+@@ -375,10 +377,12 @@ static int
+ typhoon_reset(unsigned long ioaddr, int wait_type)
+ {
+       int i, err = 0;
+-      int timeout = TYPHOON_RESET_TIMEOUT;
++      int timeout;
+       if(wait_type == WaitNoSleep)
+-              timeout = (timeout * 1000000) / (HZ * TYPHOON_UDELAY);
++              timeout = TYPHOON_RESET_TIMEOUT_NOSLEEP;
++      else
++              timeout = TYPHOON_RESET_TIMEOUT_SLEEP;
+       writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
+       writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS);
+@@ -1858,6 +1862,11 @@ typhoon_sleep(struct typhoon *tp, int st
+       if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_SLEEPING) < 0)
+               return -ETIMEDOUT;
++      /* Since we cannot monitor the status of the link while sleeping,
++       * tell the world it went away.
++       */
++      netif_carrier_off(tp->dev);
++
+       pci_enable_wake(tp->pdev, state, 1);
+       pci_disable_device(pdev);
+       return pci_set_power_state(pdev, state);
+@@ -1872,8 +1881,13 @@ typhoon_wakeup(struct typhoon *tp, int w
+       pci_set_power_state(pdev, 0);
+       pci_restore_state(pdev, tp->pci_state);
++      /* Post 2.x.x versions of the Sleep Image require a reset before
++       * we can download the Runtime Image. But let's not make users of
++       * the old firmware pay for the reset.
++       */
+       writel(TYPHOON_BOOTCMD_WAKEUP, ioaddr + TYPHOON_REG_COMMAND);
+-      if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0)
++      if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0 ||
++                      (tp->capabilities & TYPHOON_WAKEUP_NEEDS_RESET))
+               return typhoon_reset(ioaddr, wait_type);
+       return 0;
+@@ -2251,7 +2265,7 @@ typhoon_init_one(struct pci_dev *pdev, c
+       void *shared;
+       dma_addr_t shared_dma;
+       struct cmd_desc xp_cmd;
+-      struct resp_desc xp_resp;
++      struct resp_desc xp_resp[3];
+       int i;
+       int err = 0;
+@@ -2380,15 +2394,15 @@ typhoon_init_one(struct pci_dev *pdev, c
+       }
+       INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS);
+-      if(typhoon_issue_command(tp, 1, &xp_cmd, 1, &xp_resp) < 0) {
++      if(typhoon_issue_command(tp, 1, &xp_cmd, 1, xp_resp) < 0) {
+               printk(ERR_PFX "%s: cannot read MAC address\n",
+                      pci_name(pdev));
+               err = -EIO;
+               goto error_out_reset;
+       }
+-      *(u16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp.parm1));
+-      *(u32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp.parm2));
++      *(u16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp[0].parm1));
++      *(u32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2));
+       if(!is_valid_ether_addr(dev->dev_addr)) {
+               printk(ERR_PFX "%s: Could not obtain valid ethernet address, "
+@@ -2396,6 +2410,28 @@ typhoon_init_one(struct pci_dev *pdev, c
+               goto error_out_reset;
+       }
++      /* Read the Sleep Image version last, so the response is valid
++       * later when we print out the version reported.
++       */
++      INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS);
++      if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) {
++              printk(ERR_PFX "%s: Could not get Sleep Image version\n",
++                      pdev->slot_name);
++              goto error_out_reset;
++      }
++
++      tp->capabilities = typhoon_card_info[card_id].capabilities;
++      tp->xcvr_select = TYPHOON_XCVR_AUTONEG;
++
++      /* Typhoon 1.0 Sleep Images return one response descriptor to the
++       * READ_VERSIONS command. Those versions are OK after waking up
++       * from sleep without needing a reset. Typhoon 1.1+ Sleep Images
++       * seem to need a little extra help to get started. Since we don't
++       * know how to nudge it along, just kick it.
++       */
++      if(xp_resp[0].numDesc != 0)
++              tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET;
++
+       if(typhoon_sleep(tp, 3, 0) < 0) {
+               printk(ERR_PFX "%s: cannot put adapter to sleep\n",
+                      pci_name(pdev));
+@@ -2403,9 +2439,6 @@ typhoon_init_one(struct pci_dev *pdev, c
+               goto error_out_reset;
+       }
+-      tp->capabilities = typhoon_card_info[card_id].capabilities;
+-      tp->xcvr_select = TYPHOON_XCVR_AUTONEG;
+-
+       /* The chip-specific entries in the device structure. */
+       dev->open               = typhoon_open;
+       dev->hard_start_xmit    = typhoon_start_tx;
+@@ -2442,6 +2475,32 @@ typhoon_init_one(struct pci_dev *pdev, c
+               printk("%2.2x:", dev->dev_addr[i]);
+       printk("%2.2x\n", dev->dev_addr[i]);
++      /* xp_resp still contains the response to the READ_VERSIONS command.
++       * For debugging, let the user know what version he has.
++       */
++      if(xp_resp[0].numDesc == 0) {
++              /* This is the Typhoon 1.0 type Sleep Image, last 16 bits
++               * of version is Month/Day of build.
++               */
++              u16 monthday = le32_to_cpu(xp_resp[0].parm2) & 0xffff;
++              printk(KERN_INFO "%s: Typhoon 1.0 Sleep Image built "
++                      "%02u/%02u/2000\n", dev->name, monthday >> 8,
++                      monthday & 0xff);
++      } else if(xp_resp[0].numDesc == 2) {
++              /* This is the Typhoon 1.1+ type Sleep Image
++               */
++              u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2);
++              u8 *ver_string = (u8 *) &xp_resp[1];
++              ver_string[25] = 0;
++              printk(KERN_INFO "%s: Typhoon 1.1+ Sleep Image version "
++                      "%u.%u.%u.%u %s\n", dev->name, HIPQUAD(sleep_ver),
++                      ver_string);
++      } else {
++              printk(KERN_WARNING "%s: Unknown Sleep Image version "
++                      "(%u:%04x)\n", dev->name, xp_resp[0].numDesc,
++                      le32_to_cpu(xp_resp[0].parm2));
++      }
++              
+       return 0;
+ error_out_reset:
+--- linux-2.6.0/drivers/net/via-rhine.c        2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/net/via-rhine.c 2003-12-28 23:21:06.000000000 -0800
+@@ -615,6 +615,15 @@ static void __devinit reload_eeprom(long
+                       break;
+ }
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void via_rhine_poll(struct net_device *dev)
++{
++      disable_irq(dev->irq);
++      via_rhine_interrupt(dev->irq, (void *)dev, NULL);
++      enable_irq(dev->irq);
++}
++#endif
++
+ static int __devinit via_rhine_init_one (struct pci_dev *pdev,
+                                        const struct pci_device_id *ent)
+ {
+@@ -784,6 +793,9 @@ static int __devinit via_rhine_init_one 
+       dev->ethtool_ops = &netdev_ethtool_ops;
+       dev->tx_timeout = via_rhine_tx_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++      dev->poll_controller = via_rhine_poll;
++#endif
+       if (np->drv_flags & ReqTxAlign)
+               dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
+--- linux-2.6.0/drivers/net/wan/cosa.c 2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/wan/cosa.c  2003-12-28 23:21:01.000000000 -0800
+@@ -594,40 +594,47 @@ err_out: 
\f
+ /*---------- SPPP/HDLC netdevice ---------- */
++static void cosa_setup(struct net_device *d)
++{
++      d->open = cosa_sppp_open;
++      d->stop = cosa_sppp_close;
++      d->hard_start_xmit = cosa_sppp_tx;
++      d->do_ioctl = cosa_sppp_ioctl;
++      d->get_stats = cosa_net_stats;
++      d->tx_timeout = cosa_sppp_timeout;
++      d->watchdog_timeo = TX_TIMEOUT;
++}
++
+ static void sppp_channel_init(struct channel_data *chan)
+ {
+       struct net_device *d;
+       chan->if_ptr = &chan->pppdev;
+-      chan->pppdev.dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+-      memset(chan->pppdev.dev, 0, sizeof(struct net_device));
++      d = alloc_netdev(0, chan->name, cosa_setup);
++      if (!d) {
++              printk(KERN_WARNING "%s: alloc_netdev failed.\n", chan->name);
++              return;
++      }
++      chan->pppdev.dev = d;
+       sppp_attach(&chan->pppdev);
+-      d=chan->pppdev.dev;
+-      strcpy(d->name, chan->name);
+       d->base_addr = chan->cosa->datareg;
+       d->irq = chan->cosa->irq;
+       d->dma = chan->cosa->dma;
+       d->priv = chan;
+-      d->init = NULL;
+-      d->open = cosa_sppp_open;
+-      d->stop = cosa_sppp_close;
+-      d->hard_start_xmit = cosa_sppp_tx;
+-      d->do_ioctl = cosa_sppp_ioctl;
+-      d->get_stats = cosa_net_stats;
+-      d->tx_timeout = cosa_sppp_timeout;
+-      d->watchdog_timeo = TX_TIMEOUT;
+       if (register_netdev(d)) {
+               printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
+-              sppp_detach(chan->pppdev.dev);
+-              free_netdev(chan->pppdev.dev);
++              sppp_detach(d);
++              free_netdev(d);
++              chan->pppdev.dev = NULL;
+               return;
+       }
+ }
+ static void sppp_channel_delete(struct channel_data *chan)
+ {
+-      sppp_detach(chan->pppdev.dev);
+       unregister_netdev(chan->pppdev.dev);
++      sppp_detach(chan->pppdev.dev);
+       free_netdev(chan->pppdev.dev);
++      chan->pppdev.dev = NULL;
+ }
+ static int cosa_sppp_open(struct net_device *d)
+--- linux-2.6.0/drivers/net/wan/cycx_drv.c     2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/net/wan/cycx_drv.c      2003-12-28 23:22:33.000000000 -0800
+@@ -425,8 +425,8 @@ static int load_cyc2x(struct cycx_hw *hw
+       if (cksum != cfm->checksum) {
+               printk(KERN_ERR "%s:%s: firmware corrupted!\n",
+                               modname, __FUNCTION__);
+-              printk(KERN_ERR " cdsize = 0x%lx (expected 0x%lx)\n",
+-                              len - sizeof(struct cycx_firmware) - 1,
++              printk(KERN_ERR " cdsize = 0x%x (expected 0x%x)\n",
++                              len - (int)sizeof(struct cycx_firmware) - 1,
+                               cfm->info.codesize);
+               printk(KERN_ERR " chksum = 0x%x (expected 0x%x)\n",
+                               cksum, cfm->checksum);
+--- linux-2.6.0/drivers/net/wan/farsync.c      2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/wan/farsync.c       2003-12-28 23:21:01.000000000 -0800
+@@ -1313,8 +1313,6 @@ fst_open ( struct net_device *dev )
+         if ( err )
+                 return err;
+-        MOD_INC_USE_COUNT;
+-
+         fst_openport ( dev_to_port ( dev ));
+         netif_wake_queue ( dev );
+         return 0;
+@@ -1326,7 +1324,6 @@ fst_close ( struct net_device *dev )
+         netif_stop_queue ( dev );
+         fst_closeport ( dev_to_port ( dev ));
+         hdlc_close ( dev_to_hdlc  ( dev ));
+-        MOD_DEC_USE_COUNT;
+         return 0;
+ }
+--- linux-2.6.0/drivers/net/wan/hd64572.h      2003-06-14 12:18:28.000000000 -0700
++++ 25/drivers/net/wan/hd64572.h       2003-12-28 23:21:01.000000000 -0800
+@@ -23,8 +23,8 @@
+  *
+  */
+-#ifndef _HD64572_H
+-#define _HD64572_H
++#ifndef __HD64572_H
++#define __HD64572_H
+ /* Illegal Access Register */
+ #define       ILAR    0x00
+@@ -59,6 +59,9 @@
+ #define IR0_M(val, chan)      ((val)<<(8*(chan)))             /* Int MSCI */
+ /* MSCI Channel Registers */
++#define MSCI0_OFFSET 0x00
++#define MSCI1_OFFSET 0x80
++
+ #define MD0   0x138   /* Mode reg 0 */
+ #define MD1   0x139   /* Mode reg 1 */
+ #define MD2   0x13a   /* Mode reg 2 */
+@@ -107,6 +110,11 @@
+ #define RCR   0x156   /* Rx DMA Critical Request Reg */
+ /* Timer Registers */
++#define TIMER0RX_OFFSET 0x00
++#define TIMER0TX_OFFSET 0x10
++#define TIMER1RX_OFFSET 0x20
++#define TIMER1TX_OFFSET 0x30
++
+ #define TCNTL 0x200   /* Timer Upcounter L */
+ #define TCNTH 0x201   /* Timer Upcounter H */
+ #define TCONRL        0x204   /* Timer Constant Register L */
+@@ -132,6 +140,11 @@
+ #define DCR_TX(chan)  (0x59 + 2*chan) /* DMA Command Reg (Tx) */
+ /* DMA Channel Registers */
++#define DMAC0RX_OFFSET 0x00
++#define DMAC0TX_OFFSET 0x20
++#define DMAC1RX_OFFSET 0x40
++#define DMAC1TX_OFFSET 0x60
++
+ #define DARL  0x80    /* Dest Addr Register L (single-block, RX only) */
+ #define DARH  0x81    /* Dest Addr Register H (single-block, RX only) */
+ #define DARB  0x82    /* Dest Addr Register B (single-block, RX only) */
+@@ -166,7 +179,17 @@ typedef struct {
+       unsigned char   filler[5];      /* alignment filler (16 bytes) */ 
+ } pcsca_bd_t;
+-/* 
++/* Block Descriptor Structure */
++typedef struct {
++      u32 cp;                 /* pointer to next block descriptor */
++      u32 bp;                 /* buffer pointer */
++      u16 len;                /* data length */
++      u8 stat;                /* status */
++      u8 unused;              /* pads to 4-byte boundary */
++}pkt_desc;
++
++
++/*
+       Descriptor Status definitions:
+       Bit     Transmission    Reception
+@@ -190,6 +213,23 @@ typedef struct {
+ #define DST_SHRT      0x40    /* Short Frame  */
+ #define DST_EOM               0x80    /* End of Message  */
++/* Packet Descriptor Status bits */
++
++#define ST_TX_EOM     0x80    /* End of frame */
++#define ST_TX_UNDRRUN 0x08
++#define ST_TX_OWNRSHP 0x02
++#define ST_TX_EOT     0x01    /* End of transmition */
++
++#define ST_RX_EOM     0x80    /* End of frame */
++#define ST_RX_SHORT   0x40    /* Short frame */
++#define ST_RX_ABORT   0x20    /* Abort */
++#define ST_RX_RESBIT  0x10    /* Residual bit */
++#define ST_RX_OVERRUN 0x08    /* Overrun */
++#define ST_RX_CRC     0x04    /* CRC */
++#define ST_RX_OWNRSHP 0x02
++
++#define ST_ERROR_MASK 0x7C
++
+ /* Status Counter Registers */
+ #define CMCR  0x158   /* Counter Master Ctl Reg */
+ #define TECNTL        0x160   /* Tx EOM Counter L */
+@@ -246,11 +286,25 @@ typedef struct {
+ #define MD0_BIT_SYNC  0x80
+ #define MD0_TRANSP    0xc0
++#define MD0_HDLC        0x80  /* Bit-sync HDLC mode */
++
++#define MD0_CRC_NONE  0x00
++#define MD0_CRC_16_0  0x04
++#define MD0_CRC_16    0x05
++#define MD0_CRC_ITU32 0x06
++#define MD0_CRC_ITU   0x07
++
+ #define MD1_NOADDR    0x00
+ #define MD1_SADDR1    0x40
+ #define MD1_SADDR2    0x80
+ #define MD1_DADDR     0xc0
++#define MD2_NRZI_IEEE 0x40
++#define MD2_MANCHESTER        0x80
++#define MD2_FM_MARK   0xA0
++#define MD2_FM_SPACE  0xC0
++#define MD2_LOOPBACK  0x03    /* Local data Loopback */
++
+ #define MD2_F_DUPLEX  0x00
+ #define MD2_AUTO_ECHO 0x01
+ #define MD2_LOOP_HI_Z 0x02
+@@ -274,6 +328,10 @@ typedef struct {
+ #define CTL_URSKP     0x40
+ #define CTL_URCT      0x80
++#define CTL_NORTS     0x01
++#define CTL_NODTR     0x02
++#define CTL_IDLE      0x10
++
+ #define       RXS_BR0         0x01
+ #define       RXS_BR1         0x02
+ #define       RXS_BR2         0x04
+@@ -302,6 +360,12 @@ typedef struct {
+ #define       EXS_TES1        0x20
+ #define       EXS_TES2        0x40
++#define CLK_BRG_MASK  0x0F
++#define CLK_PIN_OUT   0x80
++#define CLK_LINE      0x00    /* clock line input */
++#define CLK_BRG       0x40    /* internal baud rate generator */
++#define CLK_TX_RXCLK  0x60    /* TX clock from RX clock */
++
+ #define CMD_RX_RST    0x11
+ #define CMD_RX_ENA    0x12
+ #define CMD_RX_DIS    0x13
+@@ -324,6 +388,10 @@ typedef struct {
+ #define CMD_SRCH_MODE 0x31
+ #define CMD_NOP               0x00
++#define CMD_RESET     0x21
++#define CMD_TX_ENABLE 0x02
++#define CMD_RX_ENABLE 0x12
++
+ #define ST0_RXRDY     0x01
+ #define ST0_TXRDY     0x02
+ #define ST0_RXINTB    0x20
+@@ -374,6 +442,8 @@ typedef struct {
+ #define IE0_RXINTB    0x20
+ #define IE0_RXINTA    0x40
+ #define IE0_TXINT     0x80
++#define IE0_UDRN      0x00008000 /* TX underrun MSCI interrupt enable */
++#define IE0_CDCD      0x00000400 /* CD level change interrupt enable */
+ #define IE1_IDLD      0x01
+ #define IE1_ABTD      0x02
+@@ -424,14 +494,28 @@ typedef struct {
+ #define DIR_EOM               0x40
+ #define DIR_EOT               0x80
++#define DIR_REFE      0x04
++#define DIR_UDRFE     0x04
++#define DIR_COAE      0x08
++#define DIR_COFE      0x10
++#define DIR_BOFE      0x20
++#define DIR_EOME      0x40
++#define DIR_EOTE      0x80
++
+ #define DMR_CNTE      0x02
+ #define DMR_NF                0x04
+ #define DMR_SEOME     0x08
+ #define DMR_TMOD      0x10
++#define DMER_DME        0x80  /* DMA Master Enable */
++
+ #define DCR_SW_ABT    0x01
+ #define DCR_FCT_CLR   0x02
++#define DCR_ABORT     0x01
++#define DCR_CLEAR_EOF 0x02
++
++#define PCR_COTE      0x80
+ #define PCR_PR0               0x01
+ #define PCR_PR1               0x02
+ #define PCR_PR2               0x04
+@@ -440,4 +524,4 @@ typedef struct {
+ #define PCR_OSB               0x40
+ #define PCR_BURST     0x80
+-#endif /* (_HD64572_H) */
++#endif /* (__HD64572_H) */
+--- linux-2.6.0/drivers/net/wan/Kconfig        2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wan/Kconfig 2003-12-28 23:23:06.000000000 -0800
+@@ -325,6 +325,21 @@ config HDLC_X25
+ comment "X.25/LAPB support is disabled"
+       depends on WAN && HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
++config PCI200SYN
++      tristate "Goramo PCI200SYN support"
++      depends on HDLC && PCI
++      help
++        This driver is for PCI200SYN cards made by Goramo sp. j.
++        If you have such a card, say Y here and see
++        <http://hq.pm.waw.pl/pub/hdlc/>
++
++        If you want to compile the driver as a module ( = code which can be
++        inserted in and removed from the running kernel whenever you want),
++        say M here and read <file:Documentation/modules.txt>.  The module
++        will be called pci200syn.
++
++        If unsure, say N here.
++
+ config WANXL
+       tristate "SBE Inc. wanXL support"
+       depends on HDLC && PCI
+@@ -334,7 +349,7 @@ config WANXL
+         If you want to compile the driver as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you want),
+-        say M here and read <file:Documentation/modules.txt>.  The module
++        say M here and read <file:Documentation/kbuild/modules.txt>.  The module
+         will be called wanxl.
+         If unsure, say N here.
+@@ -467,7 +482,7 @@ config SDLA
+         Say Y here if you need a driver for the Sangoma S502A, S502E, and
+         S508 Frame Relay Access Devices. These are multi-protocol cards, but
+         only frame relay is supported by the driver at this time. Please
+-        read <file:Documentation/framerelay.txt>.
++        read <file:Documentation/networking/framerelay.txt>.
+         To compile this driver as a module, choose M here: the module will be
+         called sdla.
+--- linux-2.6.0/drivers/net/wan/lmc/lmc_main.c 2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/wan/lmc/lmc_main.c  2003-12-28 23:21:01.000000000 -0800
+@@ -78,30 +78,22 @@
+ #include "lmc_debug.h"
+ #include "lmc_proto.h"
+-
+-static int Lmc_Count = 0;
+-static struct net_device *Lmc_root_dev = NULL;
+-static u8 cards_found = 0;
+-
+ static int lmc_first_load = 0;
+-int LMC_PKT_BUF_SZ = 1542;
++static int LMC_PKT_BUF_SZ = 1542;
+-#ifdef MODULE
+ static struct pci_device_id lmc_pci_tbl[] = {
+-    { 0x1011, 0x009, 0x1379, PCI_ANY_ID, 0, 0, 0},
+-    { 0, }
++      { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
++        PCI_VENDOR_ID_LMC, PCI_ANY_ID },
++      { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
++        PCI_ANY_ID, PCI_VENDOR_ID_LMC },
++      { 0 }
+ };
+ MODULE_DEVICE_TABLE(pci, lmc_pci_tbl);
+-
+ MODULE_LICENSE("GPL");
+-#endif
+-int lmc_probe_fake(struct net_device *dev);
+-static struct net_device *lmc_probe1(struct net_device *dev, unsigned long ioaddr, unsigned int irq,
+-                               int chip_id, int subdevice, int board_idx);
+ static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
+ static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
+ static int lmc_rx (struct net_device *dev);
+@@ -115,12 +107,9 @@ static void lmc_softreset(lmc_softc_t * 
+ static void lmc_running_reset(struct net_device *dev);
+ static int lmc_ifdown(struct net_device * const);
+ static void lmc_watchdog(unsigned long data);
+-static int lmc_init(struct net_device * const);
+ static void lmc_reset(lmc_softc_t * const sc);
+ static void lmc_dec_reset(lmc_softc_t * const sc);
+ static void lmc_driver_timeout(struct net_device *dev);
+-int lmc_setup(void);
+-
+ /*
+  * linux reserves 16 device specific IOCTLs.  We call them
+@@ -815,67 +804,77 @@ kick_timer:
+ }
+-static int lmc_init(struct net_device * const dev) /*fold00*/
++static void lmc_setup(struct net_device * const dev) /*fold00*/
+ {
+-    lmc_trace(dev, "lmc_init in");
+-    lmc_trace(dev, "lmc_init out");
+-      
+-    return 0;
++    lmc_trace(dev, "lmc_setup in");
++
++    dev->type = ARPHRD_HDLC;
++    dev->hard_start_xmit = lmc_start_xmit;
++    dev->open = lmc_open;
++    dev->stop = lmc_close;
++    dev->get_stats = lmc_get_stats;
++    dev->do_ioctl = lmc_ioctl;
++    dev->set_config = lmc_set_config;
++    dev->tx_timeout = lmc_driver_timeout;
++    dev->watchdog_timeo = (HZ); /* 1 second */
++    
++    lmc_trace(dev, "lmc_setup out");
+ }
+-/* This initializes each card from lmc_probe() */
+-static struct net_device *lmc_probe1 (struct net_device *dev, unsigned long ioaddr, unsigned int irq, /*fold00*/
+-                                  int chip_id, int subdevice, int board_idx)
++
++static int __devinit lmc_init_one(struct pci_dev *pdev,
++                                const struct pci_device_id *ent)
+ {
+-    lmc_softc_t *sc = NULL;
++    struct net_device *dev;
++    lmc_softc_t *sc;
++    u16 subdevice;
+     u_int16_t AdapModelNum;
+-
+-    /*
+-     * Allocate our own device structure
+-     */
+-
+-    dev = kmalloc (sizeof (struct net_device)+8, GFP_KERNEL);
+-    if (dev == NULL){
+-        printk (KERN_ERR "lmc: kmalloc for device failed\n");
+-        return NULL;
+-    }
+-    memset (dev, 0, sizeof (struct net_device));
+-
++    int err = -ENOMEM;
++    static int cards_found;
+ #ifndef GCOM
+-    /*
+-     *        Switch to common hdlc%d naming. We name by type not by vendor
+-     */
+-    
+-    dev_alloc_name(dev, "hdlc%d");
++    /* We name by type not by vendor */
++    static const char lmcname[] = "hdlc%d";
+ #else
+-    /*
++    /* 
+      * GCOM uses LMC vendor name so that clients can know which card
+      * to attach to.
+      */
+-    dev_alloc_name(dev, "lmc%d");
++    static const char lmcname[] = "lmc%d";
+ #endif
+-    lmc_trace(dev, "lmc_probe1 in");
++
++    /*
++     * Allocate our own device structure
++     */
++    dev = alloc_netdev(sizeof(lmc_softc_t), lmcname, lmc_setup);
++    if (!dev) {
++        printk (KERN_ERR "lmc:alloc_netdev for device failed\n");
++      goto out1;
++    }
++ 
++    lmc_trace(dev, "lmc_init_one in");
++
++    err = pci_enable_device(pdev);
++    if (err) {
++          printk(KERN_ERR "lmc: pci enable failed:%d\n", err);
++          goto out2;
++    }
+     
+-    Lmc_Count++;
++    if (pci_request_regions(pdev, "lmc")) {
++          printk(KERN_ERR "lmc: pci_request_region failed\n");
++          err = -EIO;
++          goto out3;
++    }
++
++    pci_set_drvdata(pdev, dev);
+     if(lmc_first_load == 0){
+-        printk(KERN_INFO "Lan Media Corporation WAN Driver Version %d.%d.%d\n",DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION,DRIVER_SUB_VERSION);
++        printk(KERN_INFO "Lan Media Corporation WAN Driver Version %d.%d.%d\n",
++             DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION,DRIVER_SUB_VERSION);
+         lmc_first_load = 1;
+     }
+     
+-    /*
+-     * Allocate space for the private data structure
+-     */
+-
+-    sc = kmalloc (sizeof (lmc_softc_t), GFP_KERNEL);
+-    if (sc == NULL) {
+-        printk (KERN_WARNING "%s: Cannot allocate memory for device state\n",
+-                dev->name);
+-        return (NULL);
+-    }
+-    memset (sc, 0, sizeof (lmc_softc_t));
+-    dev->priv = sc;
++    sc = dev->priv;
+     sc->lmc_device = dev;
+     sc->name = dev->name;
+@@ -883,8 +882,12 @@ static struct net_device *lmc_probe1 (st
+     /* An ioctl can cause a subsequent detach for raw frame interface */
+     sc->if_type = LMC_PPP;
+     sc->check = 0xBEAFCAFE;
+-    dev->base_addr = ioaddr;
+-    dev->irq = irq;
++    dev->base_addr = pci_resource_start(pdev, 0);
++    dev->irq = pdev->irq;
++
++    SET_MODULE_OWNER(dev);
++    SET_NETDEV_DEV(dev, &pdev->dev);
++
+     /*
+      * This will get the protocol layer ready and do any 1 time init's
+      * Must have a valid sc and dev structure
+@@ -893,19 +896,6 @@ static struct net_device *lmc_probe1 (st
+     lmc_proto_attach(sc);
+-    /* Just fill in the entries for the device */
+-
+-    dev->init = lmc_init;
+-    dev->type = ARPHRD_HDLC;
+-    dev->hard_start_xmit = lmc_start_xmit;
+-    dev->open = lmc_open;
+-    dev->stop = lmc_close;
+-    dev->get_stats = lmc_get_stats;
+-    dev->do_ioctl = lmc_ioctl;
+-    dev->set_config = lmc_set_config;
+-    dev->tx_timeout = lmc_driver_timeout;
+-    dev->watchdog_timeo = (HZ); /* 1 second */
+-    
+     /*
+      * Why were we changing this???
+      dev->tx_queue_len = 100;
+@@ -914,44 +904,45 @@ static struct net_device *lmc_probe1 (st
+     /* Init the spin lock so can call it latter */
+     spin_lock_init(&sc->lmc_lock);
++    pci_set_master(pdev);
+-    printk ("%s: detected at %lx, irq %d\n", dev->name, ioaddr, dev->irq);
++    printk ("%s: detected at %lx, irq %d\n", dev->name,
++          dev->base_addr, dev->irq);
+     if (register_netdev (dev) != 0) {
+         printk (KERN_ERR "%s: register_netdev failed.\n", dev->name);
+-        lmc_proto_detach(sc);
+-        kfree (dev->priv);
+-        kfree (dev);
+-        return NULL;
++      goto out4;
+     }
+-    /*
+-     * Request the region of registers we need, so that
+-     * later on, no one else will take our card away from
+-     * us.
+-     */
+-    request_region (ioaddr, LMC_REG_RANGE, dev->name);
+-
+     sc->lmc_cardtype = LMC_CARDTYPE_UNKNOWN;
+     sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;
++    /*
++     *
++     * Check either the subvendor or the subdevice, some systems reverse
++     * the setting in the bois, seems to be version and arch dependent?
++     * Fix the error, exchange the two values 
++     */
++    if ((subdevice = pdev->subsystem_device) == PCI_VENDOR_ID_LMC)
++          subdevice = pdev->subsystem_vendor;
++
+     switch (subdevice) {
+-    case PCI_PRODUCT_LMC_HSSI:
++    case PCI_DEVICE_ID_LMC_HSSI:
+         printk ("%s: LMC HSSI\n", dev->name);
+         sc->lmc_cardtype = LMC_CARDTYPE_HSSI;
+         sc->lmc_media = &lmc_hssi_media;
+         break;
+-    case PCI_PRODUCT_LMC_DS3:
++    case PCI_DEVICE_ID_LMC_DS3:
+         printk ("%s: LMC DS3\n", dev->name);
+         sc->lmc_cardtype = LMC_CARDTYPE_DS3;
+         sc->lmc_media = &lmc_ds3_media;
+         break;
+-    case PCI_PRODUCT_LMC_SSI:
++    case PCI_DEVICE_ID_LMC_SSI:
+         printk ("%s: LMC SSI\n", dev->name);
+         sc->lmc_cardtype = LMC_CARDTYPE_SSI;
+         sc->lmc_media = &lmc_ssi_media;
+         break;
+-    case PCI_PRODUCT_LMC_T1:
++    case PCI_DEVICE_ID_LMC_T1:
+         printk ("%s: LMC T1\n", dev->name);
+         sc->lmc_cardtype = LMC_CARDTYPE_T1;
+         sc->lmc_media = &lmc_t1_media;
+@@ -976,13 +967,13 @@ static struct net_device *lmc_probe1 (st
+     AdapModelNum = (lmc_mii_readreg (sc, 0, 3) & 0x3f0) >> 4;
+     if ((AdapModelNum == LMC_ADAP_T1
+-         && subdevice == PCI_PRODUCT_LMC_T1) ||               /* detect LMC1200 */
++         && subdevice == PCI_DEVICE_ID_LMC_T1) ||     /* detect LMC1200 */
+         (AdapModelNum == LMC_ADAP_SSI
+-         && subdevice == PCI_PRODUCT_LMC_SSI) ||      /* detect LMC1000 */
++         && subdevice == PCI_DEVICE_ID_LMC_SSI) ||    /* detect LMC1000 */
+         (AdapModelNum == LMC_ADAP_DS3
+-         && subdevice == PCI_PRODUCT_LMC_DS3) ||      /* detect LMC5245 */
++         && subdevice == PCI_DEVICE_ID_LMC_DS3) ||    /* detect LMC5245 */
+         (AdapModelNum == LMC_ADAP_HSSI
+-         && subdevice == PCI_PRODUCT_LMC_HSSI))
++         && subdevice == PCI_DEVICE_ID_LMC_HSSI))
+     {                         /* detect LMC5200 */
+     }
+@@ -996,10 +987,7 @@ static struct net_device *lmc_probe1 (st
+      */
+     LMC_CSR_WRITE (sc, csr_gp_timer, 0xFFFFFFFFUL);
+-    sc->board_idx = board_idx;
+-
+-    memset (&sc->stats, 0, sizeof (struct lmc_statistics));
+-
++    sc->board_idx = cards_found++;
+     sc->stats.check = STATCHECK;
+     sc->stats.version_size = (DRIVER_VERSION << 16) +
+         sizeof (struct lmc_statistics);
+@@ -1008,105 +996,40 @@ static struct net_device *lmc_probe1 (st
+     sc->lmc_ok = 0;
+     sc->last_link_status = 0;
+-    lmc_trace(dev, "lmc_probe1 out");
+-
+-    return dev;
+-}
+-
+-
+-/* This is the entry point.  This is what is called immediately. */
+-/* This goes out and finds the card */
++    lmc_trace(dev, "lmc_init_one out");
++    return 0;
+-int lmc_probe_fake(struct net_device *dev) /*fold00*/
+-{
+-    lmc_probe(NULL);
+-    /* Return 1 to unloaded bogus device */
+-    return 1;
++ out4:
++    lmc_proto_detach(sc);
++ out3:
++    if (pdev) {
++          pci_release_regions(pdev);
++          pci_set_drvdata(pdev, NULL);
++    }
++ out2:
++    free_netdev(dev);
++ out1:
++    return err;
+ }
+-int lmc_probe (struct net_device *dev) /*fold00*/
++/*
++ * Called from pci when removing module.
++ */
++static void __devexit lmc_remove_one (struct pci_dev *pdev)
+ {
+-    int pci_index = 0;
+-    unsigned long pci_ioaddr;
+-    unsigned int pci_irq_line;
+-    u16 vendor, subvendor, device, subdevice;
+-    u32 foundaddr = 0;
+-    u8 intcf = 0;
+-    struct pci_dev *pdev = NULL;
+-
+-    /* Loop basically until we don't find anymore. */
+-    while ((pdev = pci_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) {
+-      if (pci_enable_device(pdev))
+-              break;
+-
+-        vendor = pdev->vendor;
+-        device = pdev->device;
+-        pci_irq_line = pdev->irq;
+-        pci_ioaddr = pci_resource_start (pdev, 0);
+-      subvendor = pdev->subsystem_vendor;
+-      subdevice = pdev->subsystem_device;
+-
+-      pci_set_master (pdev);
+-
+-        /*
+-         * Make sure it's the correct card.  CHECK SUBVENDOR ID!
+-         * There are lots of tulip's out there.
+-         * Also check the region of registers we will soon be
+-         * poking, to make sure no one else has reserved them.
+-         * This prevents taking someone else's device.
+-         *
+-         * Check either the subvendor or the subdevice, some systems reverse
+-         * the setting in the bois, seems to be version and arch dependent?
+-         * Fix the two variables
+-         *
+-         */
+-        if (!(check_region (pci_ioaddr, LMC_REG_RANGE)) &&
+-            (vendor == CORRECT_VENDOR_ID) &&
+-            (device == CORRECT_DEV_ID) &&
+-            ((subvendor == PCI_VENDOR_LMC)  || (subdevice == PCI_VENDOR_LMC))){
+-            struct net_device *cur, *prev = NULL;
+-
+-            /* Fix the error, exchange the two values */
+-            if(subdevice == PCI_VENDOR_LMC){
+-                subdevice = subvendor;
+-                subvendor = PCI_VENDOR_LMC ;
+-            }
+-
+-            /* Make the call to actually setup this card */
+-            dev = lmc_probe1 (dev, pci_ioaddr, pci_irq_line,
+-                              device, subdevice, cards_found);
+-            if (dev == NULL) {
+-                printk ("lmc_probe: lmc_probe1 failed\n");
+-                goto lmc_probe_next_card;
+-            }
+-            /* insert the device into the chain of lmc devices */
+-            for (cur = Lmc_root_dev;
+-                 cur != NULL;
+-                 cur = ((lmc_softc_t *) cur->priv)->next_module) {
+-                prev = cur;
+-            }
+-
+-            if (prev == NULL)
+-                Lmc_root_dev = dev;
+-            else
+-                ((lmc_softc_t *) prev->priv)->next_module = dev;
+-
+-            ((lmc_softc_t *) dev->priv)->next_module = NULL;
+-            /* end insert */
+-
+-            foundaddr = dev->base_addr;
+-
+-            cards_found++;
+-            intcf++;
+-        }
+-    lmc_probe_next_card:
+-        pci_index++;
++    struct net_device *dev = pci_get_drvdata(pdev);
++    
++    if (dev) {
++          lmc_softc_t *sc = dev->priv;
++          
++          printk("%s: removing...\n", dev->name);
++          lmc_proto_detach(sc);
++          unregister_netdev(dev);
++          free_netdev(dev);
++          pci_release_regions(pdev);
++          pci_disable_device(pdev);
++          pci_set_drvdata(pdev, NULL);
+     }
+-
+-    if (cards_found < 1)
+-        return -1;
+-
+-    return foundaddr;
+ }
+ /* After this is called, packets can be sent.
+@@ -1181,8 +1104,6 @@ static int lmc_open (struct net_device *
+     
+     sc->stats.tx_tbusy0++ ;
+-    MOD_INC_USE_COUNT;
+-
+     /*
+      * select what interrupts we want to get
+      */
+@@ -1352,7 +1273,6 @@ static int lmc_ifdown (struct net_device
+     lmc_trace(dev, "lmc_ifdown out");
+-    MOD_DEC_USE_COUNT;
+     return 0;
+ }
+@@ -1850,12 +1770,11 @@ skip_out_of_mem:
+ static struct net_device_stats *lmc_get_stats (struct net_device *dev) /*fold00*/
+ {
+-    lmc_softc_t *sc;
++    lmc_softc_t *sc = dev->priv;
+     unsigned long flags;
+     lmc_trace(dev, "lmc_get_stats in");
+-    sc = dev->priv;
+     spin_lock_irqsave(&sc->lmc_lock, flags);
+@@ -1868,58 +1787,21 @@ static struct net_device_stats *lmc_get_
+     return (struct net_device_stats *) &sc->stats;
+ }
++static struct pci_driver lmc_driver = {
++      .name           = "lmc",
++      .id_table       = lmc_pci_tbl,
++      .probe          = lmc_init_one,
++      .remove         = __devexit_p(lmc_remove_one),
++};
++
+ static int __init init_lmc(void)
+ {
+-    printk ("lmc: module loaded\n");
+-
+-    /* Have lmc_probe search for all the cards, and allocate devices */
+-    if (lmc_probe (NULL) < 0)
+-        return -EIO;
+-
+-    return 0;
++    return pci_module_init(&lmc_driver);
+ }
+ static void __exit exit_lmc(void)
+ {
+-    struct net_device *dev, *next;
+-    lmc_softc_t *sc;
+-
+-    /* we have no pointer to our devices, since they are all dynamically
+-     * allocated.  So, here we loop through all the network devices
+-     * looking for ours.  When found, dispose of them properly.
+-     */
+-
+-    for (dev = Lmc_root_dev;
+-         dev != NULL;
+-         dev = next )
+-    {
+-
+-        next = ((lmc_softc_t *) dev->priv)->next_module; /* get it now before we deallocate it */
+-        printk ("%s: removing...\n", dev->name);
+-
+-        /* close the syncppp stuff, and release irq. Close is run on unreg net */
+-        lmc_close (dev);
+-      sc = dev->priv;
+-        if (sc != NULL)
+-            lmc_proto_detach(sc);
+-
+-        /* Remove the device from the linked list */
+-        unregister_netdev (dev);
+-
+-        /* Let go of the io region */;
+-        release_region (dev->base_addr, LMC_REG_RANGE);
+-
+-        /* free our allocated structures. */
+-        kfree (dev->priv);
+-        dev->priv = NULL;
+-
+-        free_netdev (dev);
+-        dev = NULL;
+-    }
+-
+-
+-    Lmc_root_dev = NULL;
+-    printk ("lmc module unloaded\n");
++    pci_unregister_driver(&lmc_driver);
+ }
+ module_init(init_lmc);
+@@ -2326,8 +2208,3 @@ bug_out:
+ }
+-
+-int lmc_setup(void) { /*FOLD00*/
+-   return lmc_probe(NULL);
+-}
+-
+--- linux-2.6.0/drivers/net/wan/lmc/lmc_var.h  2003-06-14 12:18:09.000000000 -0700
++++ 25/drivers/net/wan/lmc/lmc_var.h   2003-12-28 23:21:01.000000000 -0800
+@@ -390,7 +390,7 @@ struct lmc___softc {
+       struct timer_list       timer;
+       lmc_ctl_t               ictl;
+       u_int32_t               TxDescriptControlInit;  
+-      struct net_device               *next_module;   /* Link to the next module  */
++
+       int                     tx_TimeoutInd; /* additional driver state */
+       int                     tx_TimeoutDisplay;
+       unsigned int            lastlmc_taint_tx;
+@@ -519,18 +519,7 @@ struct lmc___softc {
+ #define TULIP_CMD_RECEIVEALL 0x40000000L
+ #endif
+-
+-/* PCI register values */
+-#define CORRECT_VENDOR_ID    0x1011
+-#define CORRECT_DEV_ID       9
+-
+-#define PCI_VENDOR_LMC                0x1376
+-#define PCI_PRODUCT_LMC_HSSI  0x0003
+-#define PCI_PRODUCT_LMC_DS3   0x0004
+-#define PCI_PRODUCT_LMC_SSI   0x0005
+-#define PCI_PRODUCT_LMC_T1      0x0006
+-
+-/* Adapcter module number */
++/* Adapter module number */
+ #define LMC_ADAP_HSSI           2
+ #define LMC_ADAP_DS3            3
+ #define LMC_ADAP_SSI            4
+--- linux-2.6.0/drivers/net/wan/Makefile       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wan/Makefile        2003-12-28 23:21:01.000000000 -0800
+@@ -67,6 +67,7 @@ endif
+ obj-$(CONFIG_N2)              += n2.o
+ obj-$(CONFIG_C101)            += c101.o
+ obj-$(CONFIG_WANXL)           += wanxl.o
++obj-$(CONFIG_PCI200SYN)               += pci200syn.o
+ ifeq ($(CONFIG_WANXL_BUILD_FIRMWARE),y)
+ ifeq ($(ARCH),m68k)
+--- linux-2.6.0/drivers/net/wan/pc300_drv.c    2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wan/pc300_drv.c     2003-12-28 23:21:01.000000000 -0800
+@@ -3165,7 +3165,6 @@ int cpc_open(struct net_device *dev)
+               return result;
+       }
+-      MOD_INC_USE_COUNT;
+       sprintf(ifr.ifr_name, "%s", dev->name);
+       cpc_opench(d);
+       netif_start_queue(dev);
+@@ -3201,7 +3200,6 @@ int cpc_close(struct net_device *dev)
+       }
+ #endif
+-      MOD_DEC_USE_COUNT;
+       return 0;
+ }
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/net/wan/pci200syn.c     2003-12-28 23:21:01.000000000 -0800
+@@ -0,0 +1,475 @@
++/*
++ * Goramo PCI200SYN synchronous serial card driver for Linux
++ *
++ * Copyright (C) 2002-2003 Krzysztof Halasa <khc@pm.waw.pl>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License
++ * as published by the Free Software Foundation.
++ *
++ * For information see http://hq.pm.waw.pl/hdlc/
++ *
++ * Sources of information:
++ *    Hitachi HD64572 SCA-II User's Manual
++ *    PLX Technology Inc. PCI9052 Data Book
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/in.h>
++#include <linux/string.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/moduleparam.h>
++#include <linux/netdevice.h>
++#include <linux/hdlc.h>
++#include <linux/pci.h>
++#include <asm/delay.h>
++#include <asm/io.h>
++
++#include "hd64572.h"
++
++static const char* version = "Goramo PCI200SYN driver version: 1.16";
++static const char* devname = "PCI200SYN";
++
++#undef DEBUG_PKT
++#define DEBUG_RINGS
++
++#define PCI200SYN_PLX_SIZE    0x80    /* PLX control window size (128b) */
++#define PCI200SYN_SCA_SIZE    0x400   /* SCA window size (1Kb) */
++#define ALL_PAGES_ALWAYS_MAPPED
++#define NEED_DETECT_RAM
++#define NEED_SCA_MSCI_INTR
++#define MAX_TX_BUFFERS                10
++
++static int pci_clock_freq = 33000000;
++#define CLOCK_BASE pci_clock_freq
++
++#define PCI_VENDOR_ID_GORAMO  0x10B5  /* uses PLX:9050 ID - this card */
++#define PCI_DEVICE_ID_PCI200SYN       0x9050  /* doesn't have its own ID      */
++
++
++/*
++ *      PLX PCI9052 local configuration and shared runtime registers.
++ *      This structure can be used to access 9052 registers (memory mapped).
++ */
++typedef struct {
++      u32 loc_addr_range[4];  /* 00-0Ch : Local Address Ranges */
++      u32 loc_rom_range;      /* 10h : Local ROM Range */
++      u32 loc_addr_base[4];   /* 14-20h : Local Address Base Addrs */
++      u32 loc_rom_base;       /* 24h : Local ROM Base */
++      u32 loc_bus_descr[4];   /* 28-34h : Local Bus Descriptors */
++      u32 rom_bus_descr;      /* 38h : ROM Bus Descriptor */
++      u32 cs_base[4];         /* 3C-48h : Chip Select Base Addrs */
++      u32 intr_ctrl_stat;     /* 4Ch : Interrupt Control/Status */
++      u32 init_ctrl;          /* 50h : EEPROM ctrl, Init Ctrl, etc */
++}plx9052;
++
++
++
++typedef struct port_s {
++      hdlc_device hdlc;       /* HDLC device struct - must be first */
++      struct card_s *card;
++      spinlock_t lock;        /* TX lock */
++      sync_serial_settings settings;
++      int rxpart;             /* partial frame received, next frame invalid*/
++      unsigned short encoding;
++      unsigned short parity;
++      u16 rxin;               /* rx ring buffer 'in' pointer */
++      u16 txin;               /* tx ring buffer 'in' and 'last' pointers */
++      u16 txlast;
++      u8 rxs, txs, tmc;       /* SCA registers */
++      u8 phy_node;            /* physical port # - 0 or 1 */
++}port_t;
++
++
++
++typedef struct card_s {
++      u8* rambase;            /* buffer memory base (virtual) */
++      u8* scabase;            /* SCA memory base (virtual) */
++      plx9052* plxbase;       /* PLX registers memory base (virtual) */
++      u16 rx_ring_buffers;    /* number of buffers in a ring */
++      u16 tx_ring_buffers;
++      u16 buff_offset;        /* offset of first buffer of first channel */
++      u8 irq;                 /* interrupt request level */
++
++      port_t ports[2];
++}card_t;
++
++
++#define sca_in(reg, card)          readb(card->scabase + (reg))
++#define sca_out(value, reg, card)    writeb(value, card->scabase + (reg))
++#define sca_inw(reg, card)         readw(card->scabase + (reg))
++#define sca_outw(value, reg, card)   writew(value, card->scabase + (reg))
++#define sca_inl(reg, card)         readl(card->scabase + (reg))
++#define sca_outl(value, reg, card)   writel(value, card->scabase + (reg))
++
++#define port_to_card(port)         (port->card)
++#define log_node(port)                     (port->phy_node)
++#define phy_node(port)                     (port->phy_node)
++#define winbase(card)              (card->rambase)
++#define get_port(card, port)       (&card->ports[port])
++#define sca_flush(card)                    (sca_in(IER0, card));
++
++static inline void new_memcpy_toio(char *dest, char *src, int length)
++{
++      int len;
++      do {
++              len = length > 256 ? 256 : length;
++              memcpy_toio(dest, src, len);
++              dest += len;
++              src += len;
++              length -= len;
++              readb(dest);
++      } while (len);
++}
++
++#undef memcpy_toio
++#define memcpy_toio new_memcpy_toio
++
++#include "hd6457x.c"
++
++
++static void pci200_set_iface(port_t *port)
++{
++      card_t *card = port->card;
++      u16 msci = get_msci(port);
++      u8 rxs = port->rxs & CLK_BRG_MASK;
++      u8 txs = port->txs & CLK_BRG_MASK;
++
++      sca_out(EXS_TES1, (phy_node(port) ? MSCI1_OFFSET : MSCI0_OFFSET) + EXS,
++              port_to_card(port));
++      switch(port->settings.clock_type) {
++      case CLOCK_INT:
++              rxs |= CLK_BRG; /* BRG output */
++              txs |= CLK_PIN_OUT | CLK_TX_RXCLK; /* RX clock */
++              break;
++
++      case CLOCK_TXINT:
++              rxs |= CLK_LINE; /* RXC input */
++              txs |= CLK_PIN_OUT | CLK_BRG; /* BRG output */
++              break;
++
++      case CLOCK_TXFROMRX:
++              rxs |= CLK_LINE; /* RXC input */
++              txs |= CLK_PIN_OUT | CLK_TX_RXCLK; /* RX clock */
++              break;
++
++      default:                /* EXTernal clock */
++              rxs |= CLK_LINE; /* RXC input */
++              txs |= CLK_PIN_OUT | CLK_LINE; /* TXC input */
++              break;
++      }
++
++      port->rxs = rxs;
++      port->txs = txs;
++      sca_out(rxs, msci + RXS, card);
++      sca_out(txs, msci + TXS, card);
++      sca_set_port(port);
++}
++
++
++
++static int pci200_open(struct net_device *dev)
++{
++      hdlc_device *hdlc = dev_to_hdlc(dev);
++      port_t *port = hdlc_to_port(hdlc);
++
++      int result = hdlc_open(hdlc);
++      if (result)
++              return result;
++
++      sca_open(hdlc);
++      pci200_set_iface(port);
++      sca_flush(port_to_card(port));
++      return 0;
++}
++
++
++
++static int pci200_close(struct net_device *dev)
++{
++      hdlc_device *hdlc = dev_to_hdlc(dev);
++      sca_close(hdlc);
++      sca_flush(port_to_card(dev_to_port(dev)));
++      hdlc_close(hdlc);
++      return 0;
++}
++
++
++
++static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
++{
++      const size_t size = sizeof(sync_serial_settings);
++      sync_serial_settings new_line, *line = ifr->ifr_settings.ifs_ifsu.sync;
++      hdlc_device *hdlc = dev_to_hdlc(dev);
++      port_t *port = hdlc_to_port(hdlc);
++
++#ifdef DEBUG_RINGS
++      if (cmd == SIOCDEVPRIVATE) {
++              sca_dump_rings(hdlc);
++              return 0;
++      }
++#endif
++      if (cmd != SIOCWANDEV)
++              return hdlc_ioctl(dev, ifr, cmd);
++
++      switch(ifr->ifr_settings.type) {
++      case IF_GET_IFACE:
++              ifr->ifr_settings.type = IF_IFACE_V35;
++              if (ifr->ifr_settings.size < size) {
++                      ifr->ifr_settings.size = size; /* data size wanted */
++                      return -ENOBUFS;
++              }
++              if (copy_to_user(line, &port->settings, size))
++                      return -EFAULT;
++              return 0;
++
++      case IF_IFACE_V35:
++      case IF_IFACE_SYNC_SERIAL:
++              if (!capable(CAP_NET_ADMIN))
++                      return -EPERM;
++
++              if (copy_from_user(&new_line, line, size))
++                      return -EFAULT;
++
++              if (new_line.clock_type != CLOCK_EXT &&
++                  new_line.clock_type != CLOCK_TXFROMRX &&
++                  new_line.clock_type != CLOCK_INT &&
++                  new_line.clock_type != CLOCK_TXINT)
++              return -EINVAL; /* No such clock setting */
++
++              if (new_line.loopback != 0 && new_line.loopback != 1)
++                      return -EINVAL;
++
++              memcpy(&port->settings, &new_line, size); /* Update settings */
++              pci200_set_iface(port);
++              sca_flush(port_to_card(port));
++              return 0;
++
++      default:
++              return hdlc_ioctl(dev, ifr, cmd);
++      }
++}
++
++
++
++static void pci200_pci_remove_one(struct pci_dev *pdev)
++{
++      int i;
++      card_t *card = pci_get_drvdata(pdev);
++
++      for(i = 0; i < 2; i++)
++              if (card->ports[i].card)
++                      unregister_hdlc_device(&card->ports[i].hdlc);
++
++      if (card->irq)
++              free_irq(card->irq, card);
++
++      if (card->rambase)
++              iounmap(card->rambase);
++      if (card->scabase)
++              iounmap(card->scabase);
++      if (card->plxbase)
++              iounmap(card->plxbase);
++
++      pci_release_regions(pdev);
++      pci_disable_device(pdev);
++      pci_set_drvdata(pdev, NULL);
++      kfree(card);
++}
++
++
++
++static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
++                                       const struct pci_device_id *ent)
++{
++      card_t *card;
++      u8 rev_id;
++      u32 *p;
++      int i;
++      u32 ramsize;
++      u32 ramphys;            /* buffer memory base */
++      u32 scaphys;            /* SCA memory base */
++      u32 plxphys;            /* PLX registers memory base */
++
++#ifndef MODULE
++      static int printed_version;
++      if (!printed_version++)
++              printk(KERN_INFO "%s\n", version);
++#endif
++
++      i = pci_enable_device(pdev);
++      if (i)
++              return i;
++
++      i = pci_request_regions(pdev, "PCI200SYN");
++      if (i) {
++              pci_disable_device(pdev);
++              return i;
++      }
++
++      card = kmalloc(sizeof(card_t), GFP_KERNEL);
++      if (card == NULL) {
++              printk(KERN_ERR "pci200syn: unable to allocate memory\n");
++              pci_release_regions(pdev);
++              pci_disable_device(pdev);
++              return -ENOBUFS;
++      }
++      memset(card, 0, sizeof(card_t));
++      pci_set_drvdata(pdev, card);
++
++      pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
++      if (pci_resource_len(pdev, 0) != PCI200SYN_PLX_SIZE ||
++          pci_resource_len(pdev, 2) != PCI200SYN_SCA_SIZE ||
++          pci_resource_len(pdev, 3) < 16384) {
++              printk(KERN_ERR "pci200syn: invalid card EEPROM parameters\n");
++              pci200_pci_remove_one(pdev);
++              return -EFAULT;
++      }
++
++      plxphys = pci_resource_start(pdev,0) & PCI_BASE_ADDRESS_MEM_MASK;
++      card->plxbase = ioremap(plxphys, PCI200SYN_PLX_SIZE);
++
++      scaphys = pci_resource_start(pdev,2) & PCI_BASE_ADDRESS_MEM_MASK;
++      card->scabase = ioremap(scaphys, PCI200SYN_SCA_SIZE);
++
++      ramphys = pci_resource_start(pdev,3) & PCI_BASE_ADDRESS_MEM_MASK;
++      card->rambase = ioremap(ramphys, pci_resource_len(pdev,3));
++
++      if (card->plxbase == NULL ||
++          card->scabase == NULL ||
++          card->rambase == NULL) {
++              printk(KERN_ERR "pci200syn: ioremap() failed\n");
++              pci200_pci_remove_one(pdev);
++      }
++
++      /* Reset PLX */
++      p = &card->plxbase->init_ctrl;
++      writel(readl(p) | 0x40000000, p);
++      readl(p);               /* Flush the write - do not use sca_flush */
++      udelay(1);
++
++      writel(readl(p) & ~0x40000000, p);
++      readl(p);               /* Flush the write - do not use sca_flush */
++      udelay(1);
++
++      ramsize = sca_detect_ram(card, card->rambase,
++                               pci_resource_len(pdev, 3));
++
++      /* number of TX + RX buffers for one port - this is dual port card */
++      i = ramsize / (2 * (sizeof(pkt_desc) + HDLC_MAX_MRU));
++      card->tx_ring_buffers = min(i / 2, MAX_TX_BUFFERS);
++      card->rx_ring_buffers = i - card->tx_ring_buffers;
++
++      card->buff_offset = 2 * sizeof(pkt_desc) * (card->tx_ring_buffers +
++                                                  card->rx_ring_buffers);
++
++      printk(KERN_INFO "pci200syn: %u KB RAM at 0x%x, IRQ%u, using %u TX +"
++             " %u RX packets rings\n", ramsize / 1024, ramphys,
++             pdev->irq, card->tx_ring_buffers, card->rx_ring_buffers);
++
++      if (card->tx_ring_buffers < 1) {
++              printk(KERN_ERR "pci200syn: RAM test failed\n");
++              pci200_pci_remove_one(pdev);
++              return -EFAULT;
++      }
++
++      /* Enable interrupts on the PCI bridge */
++      p = &card->plxbase->intr_ctrl_stat;
++      writew(readw(p) | 0x0040, p);
++
++      /* Allocate IRQ */
++      if(request_irq(pdev->irq, sca_intr, SA_SHIRQ, devname, card)) {
++              printk(KERN_WARNING "pci200syn: could not allocate IRQ%d.\n",
++                     pdev->irq);
++              pci200_pci_remove_one(pdev);
++              return -EBUSY;
++      }
++      card->irq = pdev->irq;
++
++      sca_init(card, 0);
++
++      for(i = 0; i < 2; i++) {
++              port_t *port = &card->ports[i];
++              struct net_device *dev = hdlc_to_dev(&port->hdlc);
++              port->phy_node = i;
++
++              spin_lock_init(&port->lock);
++              SET_MODULE_OWNER(dev);
++              dev->irq = card->irq;
++              dev->mem_start = ramphys;
++              dev->mem_end = ramphys + ramsize - 1;
++              dev->tx_queue_len = 50;
++              dev->do_ioctl = pci200_ioctl;
++              dev->open = pci200_open;
++              dev->stop = pci200_close;
++              port->hdlc.attach = sca_attach;
++              port->hdlc.xmit = sca_xmit;
++              port->settings.clock_type = CLOCK_EXT;
++              if(register_hdlc_device(&port->hdlc)) {
++                      printk(KERN_ERR "pci200syn: unable to register hdlc "
++                             "device\n");
++                      pci200_pci_remove_one(pdev);
++                      return -ENOBUFS;
++              }
++              port->card = card;
++              sca_init_sync_port(port);       /* Set up SCA memory */
++
++              printk(KERN_INFO "%s: PCI200SYN node %d\n",
++                     hdlc_to_name(&port->hdlc), port->phy_node);
++      }
++
++      sca_flush(card);
++      return 0;
++}
++
++
++
++static struct pci_device_id pci200_pci_tbl[] __devinitdata = {
++      { PCI_VENDOR_ID_GORAMO, PCI_DEVICE_ID_PCI200SYN, PCI_ANY_ID,
++        PCI_ANY_ID, 0, 0, 0 },
++      { 0, }
++};
++
++
++static struct pci_driver pci200_pci_driver = {
++      name:     "PCI200SYN",
++      id_table: pci200_pci_tbl,
++      probe:    pci200_pci_init_one,
++      remove:   pci200_pci_remove_one,
++};
++
++
++static int __init pci200_init_module(void)
++{
++#ifdef MODULE
++      printk(KERN_INFO "%s\n", version);
++#endif
++      if (pci_clock_freq < 1000000 || pci_clock_freq > 80000000) {
++              printk(KERN_ERR "pci200syn: Invalid PCI clock frequency\n");
++              return -EINVAL;
++      }
++      return pci_module_init(&pci200_pci_driver);
++}
++
++
++
++static void __exit pci200_cleanup_module(void)
++{
++      pci_unregister_driver(&pci200_pci_driver);
++}
++
++MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
++MODULE_DESCRIPTION("Goramo PCI200SYN serial port driver");
++MODULE_LICENSE("GPL v2");
++MODULE_DEVICE_TABLE(pci, pci200_pci_tbl);
++module_param(pci_clock_freq, int, 0444);
++MODULE_PARM_DESC(pci_clock_freq, "System PCI clock frequency in Hz");
++module_init(pci200_init_module);
++module_exit(pci200_cleanup_module);
+--- linux-2.6.0/drivers/net/wan/x25_asy.c      2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/wan/x25_asy.c       2003-12-28 23:21:01.000000000 -0800
+@@ -94,7 +94,7 @@ static struct x25_asy *x25_asy_alloc(voi
+                       return sl;
+               } else {
+                       printk("x25_asy_alloc() - register_netdev() failure.\n");
+-                      kfree(dev);
++                      free_netdev(dev);
+               }
+       }
+       return NULL;
+--- linux-2.6.0/drivers/net/wd.c       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wd.c        2003-12-28 23:21:01.000000000 -0800
+@@ -47,7 +47,6 @@ static const char version[] =
+ static unsigned int wd_portlist[] __initdata =
+ {0x300, 0x280, 0x380, 0x240, 0};
+-int wd_probe(struct net_device *dev);
+ static int wd_probe1(struct net_device *dev, int ioaddr);
+ static int wd_open(struct net_device *dev);
+@@ -83,11 +82,14 @@ static int wd_close(struct net_device *d
+       The wd_probe1() routine initializes the card and fills the
+       station address field. */
+-int __init wd_probe(struct net_device *dev)
++static int __init do_wd_probe(struct net_device *dev)
+ {
+       int i;
+       struct resource *r;
+       int base_addr = dev->base_addr;
++      int irq = dev->irq;
++      int mem_start = dev->mem_start;
++      int mem_end = dev->mem_end;
+       SET_MODULE_OWNER(dev);
+@@ -115,11 +117,45 @@ int __init wd_probe(struct net_device *d
+                       return 0;
+               }
+               release_region(ioaddr, WD_IO_EXTENT);
++              dev->irq = irq;
++              dev->mem_start = mem_start;
++              dev->mem_end = mem_end;
+       }
+       return -ENODEV;
+ }
++static void cleanup_card(struct net_device *dev)
++{
++      free_irq(dev->irq, dev);
++      release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
++}
++
++struct net_device * __init wd_probe(int unit)
++{
++      struct net_device *dev = alloc_ei_netdev();
++      int err;
++
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
++
++      err = do_wd_probe(dev);
++      if (err)
++              goto out;
++      err = register_netdev(dev);
++      if (err)
++              goto out1;
++      return dev;
++out1:
++      cleanup_card(dev);
++out:
++      free_netdev(dev);
++      return ERR_PTR(err);
++}
++
+ static int __init wd_probe1(struct net_device *dev, int ioaddr)
+ {
+       int i;
+@@ -262,19 +298,11 @@ static int __init wd_probe1(struct net_d
+       } else if (dev->irq == 2)               /* Fixup bogosity: IRQ2 is really IRQ9 */
+               dev->irq = 9;
+-      /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-      if (ethdev_init(dev)) {
+-              printk (" unable to get memory for dev->priv.\n");
+-              return -ENOMEM;
+-      }
+-
+       /* Snarf the interrupt now.  There's no point in waiting since we cannot
+          share and the board will usually be enabled. */
+       i = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
+       if (i) {
+               printk (" unable to get IRQ %d.\n", dev->irq);
+-              kfree(dev->priv);
+-              dev->priv = NULL;
+               return i;
+       }
+@@ -446,7 +474,7 @@ wd_close(struct net_device *dev)
\f
+ #ifdef MODULE
+ #define MAX_WD_CARDS  4       /* Max number of wd cards per module */
+-static struct net_device dev_wd[MAX_WD_CARDS];
++static struct net_device *dev_wd[MAX_WD_CARDS];
+ static int io[MAX_WD_CARDS];
+ static int irq[MAX_WD_CARDS];
+ static int mem[MAX_WD_CARDS];
+@@ -468,29 +496,35 @@ ISA device autoprobes on a running machi
+ int
+ init_module(void)
+ {
++      struct net_device *dev;
+       int this_dev, found = 0;
+       for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_wd[this_dev];
+-              dev->irq = irq[this_dev];
+-              dev->base_addr = io[this_dev];
+-              dev->mem_start = mem[this_dev];
+-              dev->mem_end = mem_end[this_dev];
+-              dev->init = wd_probe;
+               if (io[this_dev] == 0)  {
+                       if (this_dev != 0) break; /* only autoprobe 1st one */
+                       printk(KERN_NOTICE "wd.c: Presently autoprobing (not recommended) for a single card.\n");
+               }
+-              if (register_netdev(dev) != 0) {
+-                      printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
+-                      if (found != 0) {       /* Got at least one. */
+-                              return 0;
++              dev = alloc_ei_netdev();
++              if (!dev)
++                      break;
++              dev->irq = irq[this_dev];
++              dev->base_addr = io[this_dev];
++              dev->mem_start = mem[this_dev];
++              dev->mem_end = mem_end[this_dev];
++              if (do_wd_probe(dev) == 0) {
++                      if (register_netdev(dev) == 0) {
++                              dev_wd[found++] = dev;
++                              continue;
+                       }
+-                      return -ENXIO;
++                      cleanup_card(dev);
+               }
+-              found++;
+-      }
+-      return 0;
++              free_netdev(dev);
++              printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
++              break;
++      }
++      if (found)
++              return 0;
++      return -ENXIO;
+ }
+ void
+@@ -499,14 +533,11 @@ cleanup_module(void)
+       int this_dev;
+       for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
+-              struct net_device *dev = &dev_wd[this_dev];
+-              if (dev->priv != NULL) {
+-                      void *priv = dev->priv;
+-                      int ioaddr = dev->base_addr - WD_NIC_OFFSET;
+-                      free_irq(dev->irq, dev);
+-                      release_region(ioaddr, WD_IO_EXTENT);
++              struct net_device *dev = dev_wd[this_dev];
++              if (dev) {
+                       unregister_netdev(dev);
+-                      kfree(priv);
++                      cleanup_card(dev);
++                      free_netdev(dev);
+               }
+       }
+ }
+--- linux-2.6.0/drivers/net/wireless/airo.c    2003-12-17 21:20:02.000000000 -0800
++++ 25/drivers/net/wireless/airo.c     2003-12-28 23:21:01.000000000 -0800
+@@ -1027,7 +1027,6 @@ struct airo_info {
+ #define FLAG_802_11   7
+ #define FLAG_PENDING_XMIT 9
+ #define FLAG_PENDING_XMIT11 10
+-#define FLAG_PCI      11
+ #define JOB_MASK      0x1ff0000
+ #define JOB_DIE               16
+ #define JOB_XMIT      17
+@@ -4623,7 +4622,6 @@ static int __devinit airo_pci_probe(stru
+               return -ENODEV;
+       pci_set_drvdata(pdev, dev);
+-      set_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags);
+       return 0;
+ }
+@@ -4653,7 +4651,7 @@ static int __init airo_init_module( void
+ #ifdef CONFIG_PCI
+       printk( KERN_INFO "airo:  Probing for PCI adapters\n" );
+-      pci_module_init(&airo_driver);
++      pci_register_driver(&airo_driver);
+       printk( KERN_INFO "airo:  Finished probing for PCI adapters\n" );
+ #endif
+@@ -4665,22 +4663,15 @@ static int __init airo_init_module( void
+ static void __exit airo_cleanup_module( void )
+ {
+-      int is_pci = 0;
+       while( airo_devices ) {
+               printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name );
+-#ifdef CONFIG_PCI
+-              if (test_bit(FLAG_PCI, &((struct airo_info *)airo_devices->dev->priv)->flags))
+-                      is_pci = 1;
+-#endif
+               stop_airo_card( airo_devices->dev, 1 );
+       }
+       remove_proc_entry("aironet", proc_root_driver);
+-      if (is_pci) {
+ #ifdef CONFIG_PCI
+-              pci_unregister_driver(&airo_driver);
++      pci_unregister_driver(&airo_driver);
+ #endif
+-      }
+ }
+ #ifdef WIRELESS_EXT
+--- linux-2.6.0/drivers/net/wireless/airo_cs.c 2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wireless/airo_cs.c  2003-12-28 23:22:53.000000000 -0800
+@@ -233,7 +233,7 @@ static dev_link_t *airo_attach(void)
+       client_reg.event_handler = &airo_event;
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != 0) {
+               cs_error(link->handle, RegisterClient, ret);
+               airo_detach(link);
+@@ -277,7 +277,7 @@ static void airo_detach(dev_link_t *link
+       
+       /* Break the link with Card Services */
+       if (link->handle)
+-              CardServices(DeregisterClient, link->handle);
++              pcmcia_deregister_client(link->handle);
+       
+       
+       
+@@ -298,11 +298,8 @@ static void airo_detach(dev_link_t *link
+   
+   ======================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void airo_config(dev_link_t *link)
+ {
+@@ -329,9 +326,9 @@ static void airo_config(dev_link_t *link
+       tuple.TupleData = buf;
+       tuple.TupleDataMax = sizeof(buf);
+       tuple.TupleOffset = 0;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
+-      CS_CHECK(GetTupleData, handle, &tuple);
+-      CS_CHECK(ParseTuple, handle, &tuple, &parse);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++      CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+       link->conf.ConfigBase = parse.config.base;
+       link->conf.Present = parse.config.rmask[0];
+       
+@@ -351,12 +348,13 @@ static void airo_config(dev_link_t *link
+         will only use the CIS to fill in implementation-defined details.
+       */
+       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       while (1) {
+               cistpl_cftable_entry_t dflt = { 0 };
+               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+-              CFG_CHECK(GetTupleData, handle, &tuple);
+-              CFG_CHECK(ParseTuple, handle, &tuple, &parse);
++              if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++                              pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
++                      goto next_entry;
+               
+               if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
+               if (cfg->index == 0) goto next_entry;
+@@ -405,7 +403,8 @@ static void airo_config(dev_link_t *link
+               }
+               
+               /* This reserves IO space but doesn't actually enable it */
+-              CFG_CHECK(RequestIO, link->handle, &link->io); 
++              if (pcmcia_request_io(link->handle, &link->io) != 0)
++                      goto next_entry;
+               
+               /*
+                 Now set up a common memory window, if needed.  There is room
+@@ -425,16 +424,17 @@ static void airo_config(dev_link_t *link
+                       req.Base = mem->win[0].host_addr;
+                       req.Size = mem->win[0].len;
+                       req.AccessSpeed = 0;
+-                      link->win = (window_handle_t)link->handle;
+-                      CFG_CHECK(RequestWindow, &link->win, &req);
++                      if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
++                              goto next_entry;
+                       map.Page = 0; map.CardOffset = mem->win[0].card_addr;
+-                      CFG_CHECK(MapMemPage, link->win, &map);
++                      if (pcmcia_map_mem_page(link->win, &map) != 0)
++                              goto next_entry;
+               }
+               /* If we got this far, we're cool! */
+               break;
+               
+       next_entry:
+-              CS_CHECK(GetNextTuple, handle, &tuple);
++              CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
+       }
+       
+     /*
+@@ -443,14 +443,14 @@ static void airo_config(dev_link_t *link
+       irq structure is initialized.
+     */
+       if (link->conf.Attributes & CONF_ENABLE_IRQ)
+-              CS_CHECK(RequestIRQ, link->handle, &link->irq);
++              CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+       
+       /*
+         This actually configures the PCMCIA socket -- setting up
+         the I/O windows and the interrupt mapping, and putting the
+         card and host interface into "Memory and IO" mode.
+       */
+-      CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++      CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+       ((local_info_t*)link->priv)->eth_dev = 
+               init_airo_card( link->irq.AssignedIRQ,
+                               link->io.BasePort1, 1 );
+@@ -526,12 +526,12 @@ static void airo_release(dev_link_t *lin
+       
+       /* Don't bother checking to see if these succeed or not */
+       if (link->win)
+-              CardServices(ReleaseWindow, link->win);
+-      CardServices(ReleaseConfiguration, link->handle);
++              pcmcia_release_window(link->win);
++      pcmcia_release_configuration(link->handle);
+       if (link->io.NumPorts1)
+-              CardServices(ReleaseIO, link->handle, &link->io);
++              pcmcia_release_io(link->handle, &link->io);
+       if (link->irq.AssignedIRQ)
+-              CardServices(ReleaseIRQ, link->handle, &link->irq);
++              pcmcia_release_irq(link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+       if (link->state & DEV_STALE_CONFIG)
+@@ -576,7 +576,7 @@ static int airo_event(event_t event, int
+       case CS_EVENT_RESET_PHYSICAL:
+               if (link->state & DEV_CONFIG) {
+                       netif_device_detach(local->eth_dev);
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               }
+               break;
+       case CS_EVENT_PM_RESUME:
+@@ -584,7 +584,7 @@ static int airo_event(event_t event, int
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (link->state & DEV_CONFIG) {
+-                      CardServices(RequestConfiguration, link->handle, &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+                       reset_airo_card(local->eth_dev);
+                       netif_device_attach(local->eth_dev);
+               }
+--- linux-2.6.0/drivers/net/wireless/airport.c 2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/net/wireless/airport.c  2003-12-28 23:21:01.000000000 -0800
+@@ -216,7 +216,7 @@ airport_attach(struct macio_dev *mdev, c
+       if (! request_OF_resource(of_node, 0, " (airport)")) {
+               printk(KERN_ERR "airport: can't request IO resource !\n");
+-              kfree(dev);
++              free_netdev(dev);
+               return -ENODEV;
+       }
+--- linux-2.6.0/drivers/net/wireless/arlan.h   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wireless/arlan.h    2003-12-28 23:21:01.000000000 -0800
+@@ -57,12 +57,8 @@ extern int     arlan_command(struct net_
+  
+ #define SIDUNKNOWN -1
+ #define radioNodeIdUNKNOWN -1
+-#define encryptionKeyUNKNOWN '\0';
+ #define irqUNKNOWN 0
+-#define memUNKNOWN 0
+ #define debugUNKNOWN 0
+-#define probeUNKNOWN 1
+-#define numDevicesUNKNOWN 1
+ #define testMemoryUNKNOWN 1
+ #define spreadingCodeUNKNOWN 0
+ #define channelNumberUNKNOWN 0
+@@ -82,6 +78,8 @@ extern int     arlan_command(struct net_
+       #define ARLAN_DEBUG(a,b) 
+ #endif
++#define ARLAN_SHMEM_SIZE      0x2000
++
+ struct arlan_shmem
+ {
+       /* Header Signature */ 
+--- linux-2.6.0/drivers/net/wireless/arlan-main.c      2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/net/wireless/arlan-main.c       2003-12-28 23:21:01.000000000 -0800
+@@ -19,9 +19,7 @@ struct net_device *arlan_device[MAX_ARLA
+ static int SID = SIDUNKNOWN;
+ static int radioNodeId = radioNodeIdUNKNOWN;
+ static char encryptionKey[12] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
+-static int mem = memUNKNOWN;
+ int arlan_debug = debugUNKNOWN;
+-static int numDevices = numDevicesUNKNOWN;
+ static int spreadingCode = spreadingCodeUNKNOWN;
+ static int channelNumber = channelNumberUNKNOWN;
+ static int channelSet = channelSetUNKNOWN;
+@@ -45,9 +43,7 @@ static int mdebug;
+ MODULE_PARM(irq, "i");
+ MODULE_PARM(mem, "i");
+-MODULE_PARM(probe, "i");
+ MODULE_PARM(arlan_debug, "i");
+-MODULE_PARM(numDevices, "i");
+ MODULE_PARM(testMemory, "i");
+ MODULE_PARM(spreadingCode, "i");
+ MODULE_PARM(channelNumber, "i");
+@@ -69,9 +65,7 @@ MODULE_PARM(arlan_entry_and_exit_debug, 
+ MODULE_PARM(arlan_EEPROM_bad, "i");
+ MODULE_PARM_DESC(irq, "(unused)");
+ MODULE_PARM_DESC(mem, "Arlan memory address for single device probing");
+-MODULE_PARM_DESC(probe, "Arlan probe at initialization (0-1)");
+ MODULE_PARM_DESC(arlan_debug, "Arlan debug enable (0-1)");
+-MODULE_PARM_DESC(numDevices, "Number of Arlan devices; ignored if >1");
+ MODULE_PARM_DESC(testMemory, "(unused)");
+ MODULE_PARM_DESC(mdebug, "Arlan multicast debugging (0-1)");
+ MODULE_PARM_DESC(retries, "Arlan maximum packet retransmisions");
+@@ -88,7 +82,6 @@ MODULE_PARM_DESC(arlan_entry_and_exit_de
+ struct arlan_conf_stru arlan_conf[MAX_ARLANS];
+ static int arlans_found;
+-static  int   arlan_probe_here(struct net_device *dev, int ioaddr);
+ static  int   arlan_open(struct net_device *dev);
+ static  int   arlan_tx(struct sk_buff *skb, struct net_device *dev);
+ static  irqreturn_t arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+@@ -975,24 +968,27 @@ static int lastFoundAt = 0xbe000;
+  * probes on the ISA bus. A good device probes avoids doing writes, and
+  * verifies that the correct device exists and functions.
+  */
+-
+-static int __init arlan_check_fingerprint(int memaddr)
++#define ARLAN_SHMEM_SIZE      0x2000
++static int __init arlan_check_fingerprint(unsigned long memaddr)
+ {
+-      static char probeText[] = "TELESYSTEM SLW INC.    ARLAN \0";
+-      char tempBuf[49];
++      static const char probeText[] = "TELESYSTEM SLW INC.    ARLAN \0";
+       volatile struct arlan_shmem *arlan = (struct arlan_shmem *) memaddr;
++      unsigned long paddr = virt_to_phys((void *) memaddr);
++      char tempBuf[49];
+       ARLAN_DEBUG_ENTRY("arlan_check_fingerprint");
+-      if (check_mem_region(virt_to_phys((void *)memaddr),0x2000 )){
+-              // printk(KERN_WARNING "arlan: memory region %lx excluded from probing \n",virt_to_phys((void*)memaddr));
++
++      if (!request_mem_region(paddr, ARLAN_SHMEM_SIZE, "arlan")) {
++              // printk(KERN_WARNING "arlan: memory region %lx excluded from probing \n",paddr);
+               return -ENODEV;
+       }
++
+       memcpy_fromio(tempBuf, arlan->textRegion, 29);
+       tempBuf[30] = 0;
+       /* check for card at this address */
+       if (0 != strncmp(tempBuf, probeText, 29)){
+-// not                release_mem_region(virt_to_phys((void*)memaddr),0x2000);
++              release_mem_region(paddr, ARLAN_SHMEM_SIZE);
+               return -ENODEV;
+       }
+@@ -1000,51 +996,8 @@ static int __init arlan_check_fingerprin
+       ARLAN_DEBUG_EXIT("arlan_check_fingerprint");
+       return 0;
+-
+-
+-}
+-
+-static int __init arlan_probe_everywhere(struct net_device *dev)
+-{
+-      int m;
+-      int probed = 0;
+-      int found = 0;
+-
+-      SET_MODULE_OWNER(dev);
+-
+-      ARLAN_DEBUG_ENTRY("arlan_probe_everywhere");
+-      if (mem != 0 && numDevices == 1)        /* Check a single specified location. */
+-      {
+-              if (arlan_probe_here(dev, (int) phys_to_virt(  mem) ) == 0)
+-                      return 0;
+-              else
+-                      return -ENODEV;
+-      }
+-      for (m = (int)phys_to_virt(lastFoundAt) + 0x2000; m <= (int)phys_to_virt(0xDE000); m += 0x2000)
+-      {
+-              if (arlan_probe_here(dev, m) == 0)
+-              {
+-                      found++;
+-                      lastFoundAt = (int)virt_to_phys((void*)m);
+-                      break;
+-              }
+-              probed++;
+-      }
+-      if (found == 0 && probed != 0)
+-      {
+-              if (lastFoundAt == 0xbe000)
+-                      printk(KERN_ERR "arlan: No Arlan devices found \n");
+-              return -ENODEV;
+-      }
+-      else
+-              return 0;
+-
+-      ARLAN_DEBUG_EXIT("arlan_probe_everywhere");
+-
+-      return -ENODEV;
+ }
+-
+ static int arlan_change_mtu(struct net_device *dev, int new_mtu)
+ {
+       struct arlan_private *priv = dev->priv;
+@@ -1085,47 +1038,15 @@ static int arlan_mac_addr(struct net_dev
+-
+-static int __init
+-            arlan_allocate_device(int num, struct net_device *devs)
++static int __init arlan_setup_device(struct net_device *dev, int num)
+ {
++      struct arlan_private *ap = dev->priv;
++      int err;
+-      struct net_device *dev;
+-      struct arlan_private *ap;
++      ARLAN_DEBUG_ENTRY("arlan_setup_device");
+-      ARLAN_DEBUG_ENTRY("arlan_allocate_device");
++      ap->conf = (struct arlan_shmem *)(ap+1);
+-      if (!devs) {
+-              dev = init_etherdev(0, sizeof(struct arlan_private) + sizeof(struct arlan_shmem));
+-              if (!dev) {
+-                      printk(KERN_ERR "ARLAN: init_etherdev failed\n");
+-                      return 0;
+-              }
+-              ap = dev->priv;
+-              ap->conf = dev->priv + sizeof(struct arlan_private);
+-              ap->init_etherdev_alloc = 1;
+-      } else {
+-              dev = devs;
+-              dev->priv = kmalloc(sizeof(struct arlan_private) + sizeof(struct arlan_shmem), GFP_KERNEL);
+-              if (!dev->priv) {
+-                      printk(KERN_ERR "ARLAN: kmalloc of dev->priv failed\n");
+-                      return 0;
+-              }
+-              ap = dev->priv;
+-              ap->conf = dev->priv + sizeof(struct arlan_private);
+-              memset(ap, 0, sizeof(*ap));
+-      }
+-
+-      /* Fill in the 'dev' fields. */
+-      dev->base_addr = 0;
+-      dev->mem_start = 0;
+-      dev->mem_end = 0;
+-      dev->mtu = 1500;
+-      dev->flags = 0;         /* IFF_BROADCAST & IFF_MULTICAST & IFF_PROMISC; */
+-      dev->irq = 0;
+-      dev->dma = 0;
+-      dev->tx_queue_len = tx_queue_len;
+-      ether_setup(dev);
+       dev->tx_queue_len = tx_queue_len;
+       dev->open = arlan_open;
+       dev->stop = arlan_close;
+@@ -1138,41 +1059,45 @@ static int __init
+       dev->watchdog_timeo = 3*HZ;
+       
+       ap->irq_test_done = 0;
+-      arlan_device[num] = dev;
+       ap->Conf = &arlan_conf[num];
+       ap->Conf->pre_Command_Wait = 40;
+       ap->Conf->rx_tweak1 = 30;
+       ap->Conf->rx_tweak2 = 0;
+-      ARLAN_DEBUG_EXIT("arlan_allocate_device");
+-      return (int) dev;
+-}
++      err = register_netdev(dev);
++      if (err) {
++              release_mem_region(virt_to_phys((void *) dev->mem_start), 
++                         ARLAN_SHMEM_SIZE);
++              free_netdev(dev);
++              return err;
++      }
++      arlan_device[num] = dev;
++      ARLAN_DEBUG_EXIT("arlan_setup_device");
++      return 0;
++}
+-static int __init arlan_probe_here(struct net_device *dev, int memaddr)
++static int __init arlan_probe_here(struct net_device *dev, 
++                                 unsigned long memaddr)
+ {
+-      volatile struct arlan_shmem *arlan;
++      struct arlan_private *ap = dev->priv;
+       ARLAN_DEBUG_ENTRY("arlan_probe_here");
+       if (arlan_check_fingerprint(memaddr))
+               return -ENODEV;
+-      printk(KERN_NOTICE "%s: Arlan found at %x, \n ", dev->name, (int) virt_to_phys((void*)memaddr));
+-
+-      if (!arlan_allocate_device(arlans_found, dev))
+-              return -1;
+-
+-      ((struct arlan_private *) dev->priv)->card = (struct arlan_shmem *) memaddr;
+-      arlan = (void *) memaddr;
++      printk(KERN_NOTICE "%s: Arlan found at %x, \n ", dev->name, 
++             (int) virt_to_phys((void*)memaddr));
++      ap->card = (void *) memaddr;
+       dev->mem_start = memaddr;
+-      dev->mem_end = memaddr + 0x1FFF;
++      dev->mem_end = memaddr + ARLAN_SHMEM_SIZE-1;
+       if (dev->irq < 2)
+       {
+-              READSHM(dev->irq, arlan->irqLevel, u_char);
++              READSHM(dev->irq, ap->card->irqLevel, u_char);
+       } else if (dev->irq == 2)
+               dev->irq = 9;
+@@ -1183,8 +1108,6 @@ static int __init arlan_probe_here(struc
+ }
+-
+-
+ static int arlan_open(struct net_device *dev)
+ {
+       struct arlan_private *priv = dev->priv;
+@@ -1193,12 +1116,6 @@ static int arlan_open(struct net_device 
+       ARLAN_DEBUG_ENTRY("arlan_open");
+-      if (dev->mem_start == 0)
+-              ret = arlan_probe_everywhere(dev);
+-      if (ret != 0)
+-              return ret;
+-
+-      arlan = priv->card;
+       ret = request_irq(dev->irq, &arlan_interrupt, 0, dev->name, dev);
+       if (ret)
+       {
+@@ -1768,14 +1685,9 @@ static int arlan_close(struct net_device
+ {
+       struct arlan_private *priv = dev->priv;
+-      if (!priv)
+-      {
+-              printk(KERN_CRIT "arlan: No Device priv \n");
+-              return 0;
+-      }
+       ARLAN_DEBUG_ENTRY("arlan_close");
+-      del_timer(&priv->timer);
++      del_timer_sync(&priv->timer);
+       arlan_command(dev, ARLAN_COMMAND_POWERDOWN);
+@@ -1867,39 +1779,70 @@ static void arlan_set_multicast(struct n
+ }
+-int __init arlan_probe(struct net_device *dev)
++struct net_device * __init arlan_probe(int unit)
+ {
+-      printk("Arlan driver %s\n", arlan_version);
++      struct net_device *dev;
++      int err;
++      int m;
+-      if (arlan_probe_everywhere(dev))
+-              return -ENODEV;
++      ARLAN_DEBUG_ENTRY("arlan_probe");
+-      arlans_found++;
+-      return 0;
+-}
++      if (arlans_found == MAX_ARLANS)
++              return ERR_PTR(-ENODEV);
+-#ifdef  MODULE
++      /* 
++       * Reserve space for local data and a copy of the shared memory
++       * that is used by the /proc interface.
++       */
++      dev = alloc_etherdev(sizeof(struct arlan_private)
++                           + sizeof(struct arlan_shmem));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
+-static int probe = probeUNKNOWN;
++      SET_MODULE_OWNER(dev);
+-static int __init arlan_find_devices(void)
+-{
+-      int m;
+-      int found = 0;
++      if (unit >= 0) {
++              sprintf(dev->name, "eth%d", unit);
++              netdev_boot_setup_check(dev);
++              
++              if (dev->mem_start) {
++                      if (arlan_probe_here(dev, dev->mem_start) == 0)
++                              goto found;
++                      goto not_found;
++              }
++                      
++      }
+-      ARLAN_DEBUG_ENTRY("arlan_find_devices");
+-      if (mem != 0 && numDevices == 1)        /* Check a single specified location. */
+-              return 1;
+-      for (m =(int) phys_to_virt(0xc0000); m <=(int) phys_to_virt(0xDE000); m += 0x2000)
++
++      for (m = (int)phys_to_virt(lastFoundAt) + ARLAN_SHMEM_SIZE; 
++           m <= (int)phys_to_virt(0xDE000); 
++           m += ARLAN_SHMEM_SIZE)
+       {
+-              if (arlan_check_fingerprint(m) == 0)
+-                      found++;
++              if (arlan_probe_here(dev, m) == 0)
++              {
++                      lastFoundAt = (int)virt_to_phys((void*)m);
++                      goto found;
++              }
+       }
+-      ARLAN_DEBUG_EXIT("arlan_find_devices");
+-      return found;
++      if (lastFoundAt == 0xbe000)
++              printk(KERN_ERR "arlan: No Arlan devices found \n");
++
++ not_found:
++      free_netdev(dev);
++      return ERR_PTR(-ENODEV);
++
++ found:
++      err = arlan_setup_device(dev, arlans_found);
++      if (err)
++              dev = ERR_PTR(err);
++      else if (!arlans_found++)
++              printk(KERN_INFO "Arlan driver %s\n", arlan_version);
++
++      return dev;
+ }
++#ifdef  MODULE
+ int init_module(void)
+ {
+       int i = 0;
+@@ -1909,21 +1852,11 @@ int init_module(void)
+       if (channelSet != channelSetUNKNOWN || channelNumber != channelNumberUNKNOWN || systemId != systemIdUNKNOWN)
+               return -EINVAL;
+-      numDevices = arlan_find_devices();
+-      if (numDevices == 0)
+-              return -ENODEV;
+-
+-      for (i = 0; i < numDevices && i < MAX_ARLANS; i++)
+-      {
+-              if (!arlan_allocate_device(i, NULL))
+-                      return -ENOMEM;
++      for (i = 0; i < MAX_ARLANS; i++) {
++              struct net_device *dev = arlan_probe(i);
+-              if (arlan_device[i] == NULL)
+-                      return -ENOMEM;
+-
+-              if (probe)
+-                      arlan_probe_everywhere(arlan_device[i]);
+-//            arlan_command(arlan_device[i], ARLAN_COMMAND_POWERDOWN );
++              if (IS_ERR(dev)) 
++                      return PTR_ERR(dev);
+       }
+       init_arlan_proc();
+       printk(KERN_INFO "Arlan driver %s\n", arlan_version);
+@@ -1935,7 +1868,7 @@ int init_module(void)
+ void cleanup_module(void)
+ {
+       int i = 0;
+-      struct arlan_private *ap;
++      struct net_device *dev;
+       ARLAN_DEBUG_ENTRY("cleanup_module");
+@@ -1946,22 +1879,18 @@ void cleanup_module(void)
+       for (i = 0; i < MAX_ARLANS; i++)
+       {
+-              if (arlan_device[i])
+-              {
+-                      arlan_command(arlan_device[i], ARLAN_COMMAND_POWERDOWN );
+-
+-//                    release_mem_region(virt_to_phys(arlan_device[i]->mem_start), 0x2000 );
+-                      unregister_netdev(arlan_device[i]);
+-                      ap = arlan_device[i]->priv;
+-                      if (ap->init_etherdev_alloc) {
+-                              free_netdev(arlan_device[i]);
+-                              arlan_device[i] = NULL;
+-                      } else {
+-                              kfree(ap);
+-                              ap = NULL;
+-                      }
++              dev = arlan_device[i];
++              if (dev) {
++                      arlan_command(dev, ARLAN_COMMAND_POWERDOWN );
++
++                      unregister_netdev(dev);
++                      release_mem_region(virt_to_phys((void *) dev->mem_start), 
++                                         ARLAN_SHMEM_SIZE);
++                      free_netdev(dev);
++                      arlan_device[i] = NULL;
+               }
+       }
++
+       ARLAN_DEBUG_EXIT("cleanup_module");
+ }
+--- linux-2.6.0/drivers/net/wireless/atmel.c   2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/wireless/atmel.c    2003-12-28 23:21:01.000000000 -0800
+@@ -748,13 +748,13 @@ static int start_tx (struct sk_buff *skb
+       
+       if(priv->station_state != STATION_STATE_READY) {
+               priv->stats.tx_errors++;
+-              return 0;
++              goto done;
+       }
+       
+       if (priv->card && priv->present_callback && 
+           !(*priv->present_callback)(priv->card)) {
+               priv->stats.tx_errors++;
+-              return 0;
++              goto done;
+       }
+       
+       /* first ensure the timer func cannot run */
+@@ -804,6 +804,8 @@ static int start_tx (struct sk_buff *skb
+       
+       spin_unlock_irqrestore(&priv->irqlock, flags);
+       spin_unlock_bh(&priv->timerlock);
++
++done:
+       dev_kfree_skb(skb);
+       
+       return 0;       
+@@ -1441,7 +1443,7 @@ struct net_device *init_atmel_card( unsi
+  err_out_irq:
+       free_irq(dev->irq, dev);
+  err_out_free:
+-      kfree(dev);
++      free_netdev(dev);
+       return NULL;
+ }
+--- linux-2.6.0/drivers/net/wireless/atmel_cs.c        2003-10-17 15:58:03.000000000 -0700
++++ 25/drivers/net/wireless/atmel_cs.c 2003-12-28 23:22:53.000000000 -0800
+@@ -246,7 +246,7 @@ static dev_link_t *atmel_attach(void)
+       client_reg.event_handler = &atmel_event;
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != 0) {
+               cs_error(link->handle, RegisterClient, ret);
+               atmel_detach(link);
+@@ -282,7 +282,7 @@ static void atmel_detach(dev_link_t *lin
+               
+       /* Break the link with Card Services */
+       if (link->handle)
+-              CardServices(DeregisterClient, link->handle);
++              pcmcia_deregister_client(link->handle);
+       /* Unlink device structure, free pieces */
+       *linkp = link->next;
+@@ -299,11 +299,8 @@ static void atmel_detach(dev_link_t *lin
+   
+   ======================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ /* Call-back function to interrogate PCMCIA-specific information
+    about the current existance of the card */
+@@ -372,11 +369,11 @@ static void atmel_config(dev_link_t *lin
+       tuple.TupleOffset = 0;
+       
+       tuple.DesiredTuple = CISTPL_MANFID;
+-      if (CardServices(GetFirstTuple, handle, &tuple) == 0) {
++      if (pcmcia_get_first_tuple(handle, &tuple) == 0) {
+               int i;
+               cistpl_manfid_t *manfid;
+-              CS_CHECK(GetTupleData, handle, &tuple);
+-              CS_CHECK(ParseTuple, handle, &tuple, &parse);
++              CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++              CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+               manfid = &(parse.manfid);
+               for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
+                       if (!card_table[i].ver1 &&
+@@ -389,11 +386,11 @@ static void atmel_config(dev_link_t *lin
+       }
+       tuple.DesiredTuple = CISTPL_VERS_1;
+-      if (!done && (CardServices(GetFirstTuple, handle, &tuple) == 0)) {
++      if (!done && (pcmcia_get_first_tuple(handle, &tuple) == 0)) {
+               int i, j, k;
+               cistpl_vers_1_t *ver1;
+-              CS_CHECK(GetTupleData, handle, &tuple);
+-              CS_CHECK(ParseTuple, handle, &tuple, &parse);
++              CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++              CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+               ver1 = &(parse.version_1);
+               
+               for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
+@@ -429,9 +426,9 @@ static void atmel_config(dev_link_t *lin
+         registers.
+       */
+       tuple.DesiredTuple = CISTPL_CONFIG;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
+-      CS_CHECK(GetTupleData, handle, &tuple);
+-      CS_CHECK(ParseTuple, handle, &tuple, &parse);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++      CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+       link->conf.ConfigBase = parse.config.base;
+       link->conf.Present = parse.config.rmask[0];
+       
+@@ -451,12 +448,13 @@ static void atmel_config(dev_link_t *lin
+         will only use the CIS to fill in implementation-defined details.
+       */
+       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       while (1) {
+               cistpl_cftable_entry_t dflt = { 0 };
+               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+-              CFG_CHECK(GetTupleData, handle, &tuple);
+-              CFG_CHECK(ParseTuple, handle, &tuple, &parse);
++              if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++                              pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
++                      goto next_entry;
+               
+               if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
+               if (cfg->index == 0) goto next_entry;
+@@ -505,12 +503,14 @@ static void atmel_config(dev_link_t *lin
+               }
+               
+               /* This reserves IO space but doesn't actually enable it */
+-              CFG_CHECK(RequestIO, link->handle, &link->io); 
++              if (pcmcia_request_io(link->handle, &link->io) != 0)
++                      goto next_entry;
++
+               /* If we got this far, we're cool! */
+               break;
+               
+       next_entry:
+-              CS_CHECK(GetNextTuple, handle, &tuple);
++              CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
+       }
+       
+       /*
+@@ -519,14 +519,14 @@ static void atmel_config(dev_link_t *lin
+         irq structure is initialized.
+       */
+       if (link->conf.Attributes & CONF_ENABLE_IRQ)
+-              CS_CHECK(RequestIRQ, link->handle, &link->irq);
++              CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+       
+       /*
+         This actually configures the PCMCIA socket -- setting up
+         the I/O windows and the interrupt mapping, and putting the
+         card and host interface into "Memory and IO" mode.
+       */
+-      CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++      CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+       
+       if (link->irq.AssignedIRQ == 0) {
+               printk(KERN_ALERT 
+@@ -602,11 +602,11 @@ static void atmel_release(dev_link_t *li
+       ((local_info_t*)link->priv)->eth_dev = 0; 
+       
+       /* Don't bother checking to see if these succeed or not */
+-      CardServices(ReleaseConfiguration, link->handle);
++      pcmcia_release_configuration(link->handle);
+       if (link->io.NumPorts1)
+-              CardServices(ReleaseIO, link->handle, &link->io);
++              pcmcia_release_io(link->handle, &link->io);
+       if (link->irq.AssignedIRQ)
+-              CardServices(ReleaseIRQ, link->handle, &link->irq);
++              pcmcia_release_irq(link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+ }
+@@ -648,7 +648,7 @@ static int atmel_event(event_t event, in
+       case CS_EVENT_RESET_PHYSICAL:
+               if (link->state & DEV_CONFIG) {
+                       netif_device_detach(local->eth_dev);
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               }
+               break;
+       case CS_EVENT_PM_RESUME:
+@@ -656,7 +656,7 @@ static int atmel_event(event_t event, in
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (link->state & DEV_CONFIG) {
+-                      CardServices(RequestConfiguration, link->handle, &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+                       reset_atmel_card(local->eth_dev);
+                       netif_device_attach(local->eth_dev);
+               }
+--- linux-2.6.0/drivers/net/wireless/netwave_cs.c      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wireless/netwave_cs.c       2003-12-28 23:22:53.000000000 -0800
+@@ -513,7 +513,7 @@ static dev_link_t *netwave_attach(void)
+     client_reg.event_handler = &netwave_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != 0) {
+       cs_error(link->handle, RegisterClient, ret);
+       netwave_detach(link);
+@@ -555,7 +555,7 @@ static void netwave_detach(dev_link_t *l
+       
+     /* Break the link with Card Services */
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     
+     /* Locate device structure */
+     for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+@@ -998,8 +998,8 @@ static int netwave_ioctl(struct net_devi
+  *
+  */
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void netwave_pcmcia_config(dev_link_t *link) {
+     client_handle_t handle = link->handle;
+@@ -1024,9 +1024,9 @@ static void netwave_pcmcia_config(dev_li
+     tuple.TupleDataMax = 64;
+     tuple.TupleOffset = 0;
+     tuple.DesiredTuple = CISTPL_CONFIG;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     link->conf.Present = parse.config.rmask[0];
+@@ -1040,7 +1040,7 @@ static void netwave_pcmcia_config(dev_li
+      */
+     for (i = j = 0x0; j < 0x400; j += 0x20) {
+       link->io.BasePort1 = j ^ 0x300;
+-      i = CardServices(RequestIO, link->handle, &link->io);
++      i = pcmcia_request_io(link->handle, &link->io);
+       if (i == CS_SUCCESS) break;
+     }
+     if (i != CS_SUCCESS) {
+@@ -1052,13 +1052,13 @@ static void netwave_pcmcia_config(dev_li
+      *  Now allocate an interrupt line.  Note that this does not
+      *  actually assign a handler to the interrupt.
+      */
+-    CS_CHECK(RequestIRQ, handle, &link->irq);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
+     /*
+      *  This actually configures the PCMCIA socket -- setting up
+      *  the I/O windows and the interrupt mapping.
+      */
+-    CS_CHECK(RequestConfiguration, handle, &link->conf);
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
+     /*
+      *  Allocate a 32K memory window.  Note that the dev_link_t
+@@ -1071,10 +1071,9 @@ static void netwave_pcmcia_config(dev_li
+     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
+     req.Base = 0; req.Size = 0x8000;
+     req.AccessSpeed = mem_speed;
+-    link->win = (window_handle_t)link->handle;
+-    CS_CHECK(RequestWindow, &link->win, &req);
++    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
+     mem.CardOffset = 0x20000; mem.Page = 0; 
+-    CS_CHECK(MapMemPage, link->win, &mem);
++    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+     /* Store base address of the common window frame */
+     ramBase = ioremap(req.Base, 0x8000);
+@@ -1145,11 +1144,11 @@ static void netwave_release(dev_link_t *
+     /* Don't bother checking to see if these succeed or not */
+     if (link->win) {
+       iounmap(priv->ramBase);
+-      CardServices(ReleaseWindow, link->win);
++      pcmcia_release_window(link->win);
+     }
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     link->state &= ~DEV_CONFIG;
+@@ -1201,7 +1200,7 @@ static int netwave_event(event_t event, 
+       if (link->state & DEV_CONFIG) {
+           if (link->open)
+               netif_device_detach(dev);
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       }
+       break;
+     case CS_EVENT_PM_RESUME:
+@@ -1209,7 +1208,7 @@ static int netwave_event(event_t event, 
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG) {
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+           if (link->open) {
+               netwave_reset(dev);
+               netif_device_attach(dev);
+--- linux-2.6.0/drivers/net/wireless/orinoco_cs.c      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wireless/orinoco_cs.c       2003-12-28 23:22:53.000000000 -0800
+@@ -131,7 +131,7 @@ orinoco_cs_hard_reset(struct orinoco_pri
+       /* We need atomic ops here, because we're not holding the lock */
+       set_bit(0, &card->hard_reset_in_progress);
+-      err = CardServices(ResetCard, link->handle, NULL);
++      err = pcmcia_reset_card(link->handle, NULL);
+       if (err)
+               return err;
+@@ -150,7 +150,7 @@ static void
+ orinoco_cs_error(client_handle_t handle, int func, int ret)
+ {
+       error_info_t err = { func, ret };
+-      CardServices(ReportError, handle, &err);
++      pcmcia_report_error(handle, &err);
+ }
+ /*
+@@ -214,7 +214,7 @@ orinoco_cs_attach(void)
+       client_reg.Version = 0x0210; /* FIXME: what does this mean? */
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != CS_SUCCESS) {
+               orinoco_cs_error(link->handle, RegisterClient, ret);
+               orinoco_cs_detach(link);
+@@ -250,7 +250,7 @@ orinoco_cs_detach(dev_link_t * link)
+       /* Break the link with Card Services */
+       if (link->handle)
+-              CardServices(DeregisterClient, link->handle);
++              pcmcia_deregister_client(link->handle);
+       /* Unlink device structure, and free it */
+       *linkp = link->next;
+@@ -269,11 +269,8 @@ orinoco_cs_detach(dev_link_t * link)
+  * device available to the system.
+  */
+-#define CS_CHECK(fn, args...) \
+-      while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-      if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void
+ orinoco_cs_config(dev_link_t *link)
+@@ -290,7 +287,7 @@ orinoco_cs_config(dev_link_t *link)
+       tuple_t tuple;
+       cisparse_t parse;
+-      CS_CHECK(ValidateCIS, handle, &info);
++      CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info));
+       /*
+        * This reads the card's CONFIG tuple to find its
+@@ -301,9 +298,9 @@ orinoco_cs_config(dev_link_t *link)
+       tuple.TupleData = buf;
+       tuple.TupleDataMax = sizeof(buf);
+       tuple.TupleOffset = 0;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
+-      CS_CHECK(GetTupleData, handle, &tuple);
+-      CS_CHECK(ParseTuple, handle, &tuple, &parse);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++      CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+       link->conf.ConfigBase = parse.config.base;
+       link->conf.Present = parse.config.rmask[0];
+@@ -311,7 +308,7 @@ orinoco_cs_config(dev_link_t *link)
+       link->state |= DEV_CONFIG;
+       /* Look up the current Vcc */
+-      CS_CHECK(GetConfigurationInfo, handle, &conf);
++      CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
+       link->conf.Vcc = conf.Vcc;
+       /*
+@@ -329,13 +326,14 @@ orinoco_cs_config(dev_link_t *link)
+        * implementation-defined details.
+        */
+       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       while (1) {
+               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+               cistpl_cftable_entry_t dflt = { .index = 0 };
+-              CFG_CHECK(GetTupleData, handle, &tuple);
+-              CFG_CHECK(ParseTuple, handle, &tuple, &parse);
++              if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++                              pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
++                      goto next_entry;
+               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+                       dflt = *cfg;
+@@ -400,7 +398,8 @@ orinoco_cs_config(dev_link_t *link)
+                       }
+                       /* This reserves IO space but doesn't actually enable it */
+-                      CFG_CHECK(RequestIO, link->handle, &link->io);
++                      if (pcmcia_request_io(link->handle, &link->io) != 0)
++                              goto next_entry;
+               }
+@@ -410,8 +409,8 @@ orinoco_cs_config(dev_link_t *link)
+               
+       next_entry:
+               if (link->io.NumPorts1)
+-                      CardServices(ReleaseIO, link->handle, &link->io);
+-              last_ret = CardServices(GetNextTuple, handle, &tuple);
++                      pcmcia_release_io(link->handle, &link->io);
++              last_ret = pcmcia_get_next_tuple(handle, &tuple);
+               if (last_ret  == CS_NO_MORE_ITEMS) {
+                       printk(KERN_ERR "GetNextTuple().  No matching CIS configuration, "
+                              "maybe you need the ignore_cis_vcc=1 parameter.\n");
+@@ -438,7 +437,7 @@ orinoco_cs_config(dev_link_t *link)
+               link->irq.Handler = orinoco_interrupt; 
+               link->irq.Instance = dev; 
+               
+-              CS_CHECK(RequestIRQ, link->handle, &link->irq);
++              CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+       }
+       /* We initialize the hermes structure before completing PCMCIA
+@@ -452,7 +451,7 @@ orinoco_cs_config(dev_link_t *link)
+        * the I/O windows and the interrupt mapping, and putting the
+        * card and host interface into "Memory and IO" mode.
+        */
+-      CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++      CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+       /* Ok, we have the configuration, prepare to register the netdev */
+       dev->base_addr = link->io.BasePort1;
+@@ -521,11 +520,11 @@ orinoco_cs_release(dev_link_t *link)
+       spin_unlock_irqrestore(&priv->lock, flags);
+       /* Don't bother checking to see if these succeed or not */
+-      CardServices(ReleaseConfiguration, link->handle);
++      pcmcia_release_configuration(link->handle);
+       if (link->io.NumPorts1)
+-              CardServices(ReleaseIO, link->handle, &link->io);
++              pcmcia_release_io(link->handle, &link->io);
+       if (link->irq.AssignedIRQ)
+-              CardServices(ReleaseIRQ, link->handle, &link->irq);
++              pcmcia_release_irq(link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+ }                             /* orinoco_cs_release */
+@@ -587,7 +586,7 @@ orinoco_cs_event(event_t event, int prio
+                               spin_unlock_irqrestore(&priv->lock, flags);
+                       }
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               }
+               break;
+@@ -598,8 +597,7 @@ orinoco_cs_event(event_t event, int prio
+               if (link->state & DEV_CONFIG) {
+                       /* FIXME: should we double check that this is
+                        * the same card as we had before */
+-                      CardServices(RequestConfiguration, link->handle,
+-                                   &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+                       if (! test_bit(0, &card->hard_reset_in_progress)) {
+                               err = orinoco_reinit_firmware(dev);
+--- linux-2.6.0/drivers/net/wireless/orinoco_pci.c     2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/wireless/orinoco_pci.c      2003-12-28 23:21:01.000000000 -0800
+@@ -261,7 +261,7 @@ static int orinoco_pci_init_one(struct p
+               if (dev->irq)
+                       free_irq(dev->irq, dev);
+-              kfree(dev);
++              free_netdev(dev);
+       }
+       if (pci_ioaddr)
+@@ -360,6 +360,7 @@ static int orinoco_pci_resume(struct pci
+ }
+ static struct pci_device_id orinoco_pci_pci_id_table[] = {
++      {0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID,},
+       {0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID,},
+       {0,},
+ };
+--- linux-2.6.0/drivers/net/wireless/orinoco_plx.c     2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/wireless/orinoco_plx.c      2003-12-28 23:21:01.000000000 -0800
+@@ -263,7 +263,7 @@ static int orinoco_plx_init_one(struct p
+               if (dev->irq)
+                       free_irq(dev->irq, dev);
+               
+-              kfree(dev);
++              free_netdev(dev);
+       }
+       if (pccard_ioaddr)
+--- linux-2.6.0/drivers/net/wireless/orinoco_tmd.c     2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/wireless/orinoco_tmd.c      2003-12-28 23:21:01.000000000 -0800
+@@ -157,7 +157,7 @@ static int orinoco_tmd_init_one(struct p
+               if (dev->irq)
+                       free_irq(dev->irq, dev);
+               
+-              kfree(dev);
++              free_netdev(dev);
+       }
+       if (pccard_ioaddr)
+--- linux-2.6.0/drivers/net/wireless/ray_cs.c  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wireless/ray_cs.c   2003-12-28 23:22:53.000000000 -0800
+@@ -344,19 +344,14 @@ static dev_link_t *ray_attach(void)
+           return NULL;
+     /* Allocate space for private device-specific data */
+-    dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
++    dev = alloc_etherdev(sizeof(ray_dev_t));
+     if (!dev)
+           goto fail_alloc_dev;
+-    local = kmalloc(sizeof(ray_dev_t), GFP_KERNEL);
+-
+-    if (!local)
+-          goto fail_alloc_local;
++    local = dev->priv;
+     memset(link, 0, sizeof(struct dev_link_t));
+-    memset(dev, 0, sizeof(struct net_device));
+-    memset(local, 0, sizeof(ray_dev_t));
+     /* The io structure describes IO port mapping. None used here */
+     link->io.NumPorts1 = 0;
+@@ -379,7 +374,6 @@ static dev_link_t *ray_attach(void)
+     link->priv = dev;
+     link->irq.Instance = dev;
+     
+-    dev->priv = local;
+     local->finder = link;
+     local->card_status = CARD_INSERTED;
+     local->authentication_state = UNAUTHENTICATED;
+@@ -401,7 +395,6 @@ static dev_link_t *ray_attach(void)
+     DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
+     SET_MODULE_OWNER(dev);
+-    ether_setup(dev);
+     dev->init = &ray_dev_init;
+     dev->open = &ray_open;
+     dev->stop = &ray_dev_close;
+@@ -420,7 +413,7 @@ static dev_link_t *ray_attach(void)
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    DEBUG(2,"ray_cs ray_attach calling CardServices(RegisterClient...)\n");
++    DEBUG(2,"ray_cs ray_attach calling pcmcia_register_client(...)\n");
+     init_timer(&local->timer);
+@@ -434,8 +427,6 @@ static dev_link_t *ray_attach(void)
+     DEBUG(2,"ray_cs ray_attach ending\n");
+     return link;
+-fail_alloc_local:
+-    kfree(dev);
+ fail_alloc_dev:
+     kfree(link);
+     return NULL;
+@@ -478,9 +469,7 @@ static void ray_detach(dev_link_t *link)
+     if (link->priv) {
+         struct net_device *dev = link->priv;
+       if (link->dev) unregister_netdev(dev);
+-        if (dev->priv)
+-            kfree(dev->priv);
+-        kfree(link->priv);
++        free_netdev(dev);
+     }
+     kfree(link);
+     DEBUG(2,"ray_cs ray_detach ending\n");
+@@ -490,8 +479,8 @@ static void ray_detach(dev_link_t *link)
+     is received, to configure the PCMCIA socket, and to make the
+     ethernet device available to the system.
+ =============================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=fn(args))!=0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ #define MAX_TUPLE_SIZE 128
+ static void ray_config(dev_link_t *link)
+ {
+@@ -510,23 +499,23 @@ static void ray_config(dev_link_t *link)
+     /* This reads the card's CONFIG tuple to find its configuration regs */
+     tuple.DesiredTuple = CISTPL_CONFIG;
+-    CS_CHECK(pcmcia_get_first_tuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     tuple.TupleData = buf;
+     tuple.TupleDataMax = MAX_TUPLE_SIZE;
+     tuple.TupleOffset = 0;
+-    CS_CHECK(pcmcia_get_tuple_data, handle, &tuple);
+-    CS_CHECK(pcmcia_parse_tuple, handle, &tuple, &parse);
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     link->conf.Present = parse.config.rmask[0];
+     /* Determine card type and firmware version */
+     buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0;
+     tuple.DesiredTuple = CISTPL_VERS_1;
+-    CS_CHECK(pcmcia_get_first_tuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     tuple.TupleData = buf;
+     tuple.TupleDataMax = MAX_TUPLE_SIZE;
+     tuple.TupleOffset = 2;
+-    CS_CHECK(pcmcia_get_tuple_data, handle, &tuple);
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+     for (i=0; i<tuple.TupleDataLen - 4; i++) 
+         if (buf[i] == 0) buf[i] = ' ';
+@@ -538,22 +527,22 @@ static void ray_config(dev_link_t *link)
+     /* Now allocate an interrupt line.  Note that this does not
+        actually assign a handler to the interrupt.
+     */
+-    CS_CHECK(pcmcia_request_irq, link->handle, &link->irq);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+     dev->irq = link->irq.AssignedIRQ;
+     
+     /* This actually configures the PCMCIA socket -- setting up
+        the I/O windows and the interrupt mapping.
+     */
+-    CS_CHECK(pcmcia_request_configuration, link->handle, &link->conf);
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+ /*** Set up 32k window for shared memory (transmit and control) ************/
+     req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
+     req.Base = 0;
+     req.Size = 0x8000;
+     req.AccessSpeed = ray_mem_speed;
+-    CS_CHECK(pcmcia_request_window, &link->handle, &req, &link->win);
++    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
+     mem.CardOffset = 0x0000; mem.Page = 0;
+-    CS_CHECK(pcmcia_map_mem_page, link->win, &mem);
++    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+     local->sram = (UCHAR *)(ioremap(req.Base,req.Size));
+ /*** Set up 16k window for shared memory (receive buffer) ***************/
+@@ -561,9 +550,9 @@ static void ray_config(dev_link_t *link)
+     req.Base = 0;
+     req.Size = 0x4000;
+     req.AccessSpeed = ray_mem_speed;
+-    CS_CHECK(pcmcia_request_window, &link->handle, &req, &local->rmem_handle);
++    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->rmem_handle));
+     mem.CardOffset = 0x8000; mem.Page = 0;
+-    CS_CHECK(pcmcia_map_mem_page, local->rmem_handle, &mem);
++    CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
+     local->rmem = (UCHAR *)(ioremap(req.Base,req.Size));
+ /*** Set up window for attribute memory ***********************************/
+@@ -571,9 +560,9 @@ static void ray_config(dev_link_t *link)
+     req.Base = 0;
+     req.Size = 0x1000;
+     req.AccessSpeed = ray_mem_speed;
+-    CS_CHECK(pcmcia_request_window, &link->handle, &req, &local->amem_handle);
++    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->amem_handle));
+     mem.CardOffset = 0x0000; mem.Page = 0;
+-    CS_CHECK(pcmcia_map_mem_page, local->amem_handle, &mem);
++    CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
+     local->amem = (UCHAR *)(ioremap(req.Base,req.Size));
+     DEBUG(3,"ray_config sram=%p\n",local->sram);
+--- linux-2.6.0/drivers/net/wireless/strip.c   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wireless/strip.c    2003-12-28 23:21:01.000000000 -0800
+@@ -2564,7 +2564,7 @@ static void strip_free(struct strip *str
+       strip_info->magic = 0;
+-      kfree(strip_info->dev);
++      free_netdev(strip_info->dev);
+ }
+--- linux-2.6.0/drivers/net/wireless/wavelan.c 2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/wireless/wavelan.c  2003-12-28 23:21:01.000000000 -0800
+@@ -153,7 +153,7 @@ static inline void wv_16_on(unsigned lon
+  * Disable interrupts on the WaveLAN hardware.
+  * (called by wv_82586_stop())
+  */
+-static inline void wv_ints_off(device * dev)
++static inline void wv_ints_off(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -167,7 +167,7 @@ static inline void wv_ints_off(device * 
+  * Enable interrupts on the WaveLAN hardware.
+  * (called by wv_hw_reset())
+  */
+-static inline void wv_ints_on(device * dev)
++static inline void wv_ints_on(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -268,7 +268,7 @@ static inline u16 psa_crc(u8 * psa,        /* T
+ /*
+  * update the checksum field in the Wavelan's PSA
+  */
+-static void update_psa_checksum(device * dev, unsigned long ioaddr, u16 hacr)
++static void update_psa_checksum(struct net_device * dev, unsigned long ioaddr, u16 hacr)
+ {
+ #ifdef SET_PSA_CRC
+       psa_t psa;
+@@ -547,7 +547,7 @@ static inline void obram_write(unsigned 
+ /*
+  * Acknowledge the reading of the status issued by the i82586.
+  */
+-static void wv_ack(device * dev)
++static void wv_ack(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -589,7 +589,7 @@ static void wv_ack(device * dev)
+  * Set channel attention bit and busy wait until command has
+  * completed, then acknowledge completion of the command.
+  */
+-static inline int wv_synchronous_cmd(device * dev, const char *str)
++static inline int wv_synchronous_cmd(struct net_device * dev, const char *str)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -636,7 +636,7 @@ static inline int wv_synchronous_cmd(dev
+  * Check if done, and if OK.
+  */
+ static inline int
+-wv_config_complete(device * dev, unsigned long ioaddr, net_local * lp)
++wv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp)
+ {
+       unsigned short mcs_addr;
+       unsigned short status;
+@@ -703,7 +703,7 @@ wv_config_complete(device * dev, unsigne
+  * (called in wavelan_interrupt()).
+  * Note : the spinlock is already grabbed for us.
+  */
+-static int wv_complete(device * dev, unsigned long ioaddr, net_local * lp)
++static int wv_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp)
+ {
+       int nreaped = 0;
+@@ -845,7 +845,7 @@ if (lp->tx_n_in_use > 0)
+  * wavelan_interrupt is not an option), so you may experience
+  * delays sometimes.
+  */
+-static inline void wv_82586_reconfig(device * dev)
++static inline void wv_82586_reconfig(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long flags;
+@@ -954,7 +954,7 @@ static void wv_psa_show(psa_t * p)
+  * Print the formatted status of the Modem Management Controller.
+  * This function needs to be completed.
+  */
+-static void wv_mmc_show(device * dev)
++static void wv_mmc_show(struct net_device * dev)
+ {
+       unsigned long ioaddr = dev->base_addr;
+       net_local *lp = (net_local *) dev->priv;
+@@ -1137,7 +1137,7 @@ static void wv_scb_show(unsigned long io
+ /*
+  * Print the formatted status of the i82586's receive unit.
+  */
+-static void wv_ru_show(device * dev)
++static void wv_ru_show(struct net_device * dev)
+ {
+       /* net_local *lp = (net_local *) dev->priv; */
+@@ -1154,7 +1154,7 @@ static void wv_ru_show(device * dev)
+ /*
+  * Display info about one control block of the i82586 memory.
+  */
+-static void wv_cu_show_one(device * dev, net_local * lp, int i, u16 p)
++static void wv_cu_show_one(struct net_device * dev, net_local * lp, int i, u16 p)
+ {
+       unsigned long ioaddr;
+       ac_tx_t actx;
+@@ -1183,7 +1183,7 @@ static void wv_cu_show_one(device * dev,
+ /*
+  * Print status of the command unit of the i82586.
+  */
+-static void wv_cu_show(device * dev)
++static void wv_cu_show(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned int i;
+@@ -1209,7 +1209,7 @@ static void wv_cu_show(device * dev)
+ /*
+  * Print the formatted status of the WaveLAN PCMCIA device driver.
+  */
+-static void wv_dev_show(device * dev)
++static void wv_dev_show(struct net_device * dev)
+ {
+       printk(KERN_DEBUG "dev:");
+       printk(" state=%lX,", dev->state);
+@@ -1223,7 +1223,7 @@ static void wv_dev_show(device * dev)
+  * Print the formatted status of the WaveLAN PCMCIA device driver's
+  * private information.
+  */
+-static void wv_local_show(device * dev)
++static void wv_local_show(struct net_device * dev)
+ {
+       net_local *lp;
+@@ -1285,7 +1285,7 @@ static inline void wv_packet_info(u8 * p
+  * This is the information which is displayed by the driver at startup.
+  * There are lots of flags for configuring it to your liking.
+  */
+-static inline void wv_init_info(device * dev)
++static inline void wv_init_info(struct net_device * dev)
+ {
+       short ioaddr = dev->base_addr;
+       net_local *lp = (net_local *) dev->priv;
+@@ -1395,7 +1395,7 @@ static inline void wv_init_info(device *
+  * card open or closed.
+  * Used when the user read /proc/net/dev
+  */
+-static en_stats *wavelan_get_stats(device * dev)
++static en_stats *wavelan_get_stats(struct net_device * dev)
+ {
+ #ifdef DEBUG_IOCTL_TRACE
+       printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
+@@ -1412,7 +1412,7 @@ static en_stats *wavelan_get_stats(devic
+  * num_addrs > 0      Multicast mode, receive normal and MC packets,
+  *                    and do best-effort filtering.
+  */
+-static void wavelan_set_multicast_list(device * dev)
++static void wavelan_set_multicast_list(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+@@ -1485,7 +1485,7 @@ static void wavelan_set_multicast_list(d
+  * (Note : it was a nice way to test the reconfigure stuff...)
+  */
+ #ifdef SET_MAC_ADDRESS
+-static int wavelan_set_mac_address(device * dev, void *addr)
++static int wavelan_set_mac_address(struct net_device * dev, void *addr)
+ {
+       struct sockaddr *mac = addr;
+@@ -1724,7 +1724,7 @@ static inline int wv_frequency_list(unsi
+  * address with our list, and if they match, get the statistics.
+  * Sorry, but this function really needs the wireless extensions.
+  */
+-static inline void wl_spy_gather(device * dev,
++static inline void wl_spy_gather(struct net_device * dev,
+                                u8 *   mac,    /* MAC address */
+                                u8 *   stats)  /* Statistics to gather */
+ {
+@@ -1750,7 +1750,7 @@ static inline void wl_spy_gather(device 
+  * With this histogram you may detect if one WaveLAN is really weak,
+  * or you may also calculate the mean and standard deviation of the level.
+  */
+-static inline void wl_his_gather(device * dev, u8 * stats)
++static inline void wl_his_gather(struct net_device * dev, u8 * stats)
+ {                             /* Statistics to gather */
+       net_local *lp = (net_local *) dev->priv;
+       u8 level = stats[0] & MMR_SIGNAL_LVL;
+@@ -2415,7 +2415,7 @@ static const struct iw_handler_def       wavel
+  * Get wireless statistics.
+  * Called by /proc/net/wireless
+  */
+-static iw_stats *wavelan_get_wireless_stats(device * dev)
++static iw_stats *wavelan_get_wireless_stats(struct net_device * dev)
+ {
+       unsigned long ioaddr = dev->base_addr;
+       net_local *lp = (net_local *) dev->priv;
+@@ -2492,7 +2492,7 @@ static iw_stats *wavelan_get_wireless_st
+  * (called by wv_packet_rcv())
+  */
+ static inline void
+-wv_packet_read(device * dev, u16 buf_off, int sksize)
++wv_packet_read(struct net_device * dev, u16 buf_off, int sksize)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -2587,7 +2587,7 @@ wv_packet_read(device * dev, u16 buf_off
+  * (called in wavelan_interrupt()).
+  * Note : the spinlock is already grabbed for us.
+  */
+-static inline void wv_receive(device * dev)
++static inline void wv_receive(struct net_device * dev)
+ {
+       unsigned long ioaddr = dev->base_addr;
+       net_local *lp = (net_local *) dev->priv;
+@@ -2770,7 +2770,7 @@ static inline void wv_receive(device * d
+  *
+  * (called in wavelan_packet_xmit())
+  */
+-static inline int wv_packet_write(device * dev, void *buf, short length)
++static inline int wv_packet_write(struct net_device * dev, void *buf, short length)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -2901,7 +2901,7 @@ static inline int wv_packet_write(device
+  * the packet.  We also prevent reentrance.  Then we call the function
+  * to send the packet.
+  */
+-static int wavelan_packet_xmit(struct sk_buff *skb, device * dev)
++static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long flags;
+@@ -2966,7 +2966,7 @@ static int wavelan_packet_xmit(struct sk
+  * Routine to initialize the Modem Management Controller.
+  * (called by wv_hw_reset())
+  */
+-static inline int wv_mmc_init(device * dev)
++static inline int wv_mmc_init(struct net_device * dev)
+ {
+       unsigned long ioaddr = dev->base_addr;
+       net_local *lp = (net_local *) dev->priv;
+@@ -3138,7 +3138,7 @@ static inline int wv_mmc_init(device * d
+  * Start the receive unit.
+  * (called by wv_hw_reset())
+  */
+-static inline int wv_ru_start(device * dev)
++static inline int wv_ru_start(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -3230,7 +3230,7 @@ static inline int wv_ru_start(device * d
+  *
+  * (called by wv_hw_reset())
+  */
+-static inline int wv_cu_start(device * dev)
++static inline int wv_cu_start(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -3331,7 +3331,7 @@ static inline int wv_cu_start(device * d
+  *
+  * (called by wv_hw_reset())
+  */
+-static inline int wv_82586_start(device * dev)
++static inline int wv_82586_start(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -3463,7 +3463,7 @@ static inline int wv_82586_start(device 
+  *
+  * (called by wv_hw_reset(), wv_82586_reconfig(), wavelan_packet_xmit())
+  */
+-static void wv_82586_config(device * dev)
++static void wv_82586_config(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -3643,7 +3643,7 @@ static void wv_82586_config(device * dev
+  * WaveLAN controller (i82586).
+  * (called by wavelan_close())
+  */
+-static inline void wv_82586_stop(device * dev)
++static inline void wv_82586_stop(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -3680,7 +3680,7 @@ static inline void wv_82586_stop(device 
+  *    5. Start the LAN controller's receive unit
+  * (called by wavelan_interrupt(), wavelan_watchdog() & wavelan_open())
+  */
+-static int wv_hw_reset(device * dev)
++static int wv_hw_reset(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long ioaddr = dev->base_addr;
+@@ -3770,7 +3770,7 @@ static int wv_check_ioaddr(unsigned long
+  */
+ static irqreturn_t wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+-      device *dev;
++      struct net_device *dev;
+       unsigned long ioaddr;
+       net_local *lp;
+       u16 hasr;
+@@ -3923,7 +3923,7 @@ static irqreturn_t wavelan_interrupt(int
+  * kernel.  If the transmission completes, this timer is disabled. If
+  * the timer expires, we are called and we try to unlock the hardware.
+  */
+-static void wavelan_watchdog(device * dev)
++static void wavelan_watchdog(struct net_device *      dev)
+ {
+       net_local *     lp = (net_local *)dev->priv;
+       u_long          ioaddr = dev->base_addr;
+@@ -4003,7 +4003,7 @@ static void wavelan_watchdog(device *    de
+  * Configure and start up the WaveLAN PCMCIA adaptor.
+  * Called by NET3 when it "opens" the device.
+  */
+-static int wavelan_open(device * dev)
++static int wavelan_open(struct net_device * dev)
+ {
+       net_local *     lp = (net_local *)dev->priv;
+       unsigned long   flags;
+@@ -4058,7 +4058,7 @@ static int wavelan_open(device * dev)
+  * Shut down the WaveLAN ISA card.
+  * Called by NET3 when it "closes" the device.
+  */
+-static int wavelan_close(device * dev)
++static int wavelan_close(struct net_device * dev)
+ {
+       net_local *lp = (net_local *) dev->priv;
+       unsigned long flags;
+@@ -4091,12 +4091,24 @@ static int wavelan_close(device * dev)
+  * device structure
+  * (called by wavelan_probe() and via init_module()).
+  */
+-static int __init wavelan_config(device * dev)
++static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr)
+ {
+-      unsigned long ioaddr = dev->base_addr;
+       u8 irq_mask;
+       int irq;
+       net_local *lp;
++      mac_addr mac;
++      int err;
++
++      if (!request_region(ioaddr, sizeof(ha_t), "wavelan"))
++              return -EADDRINUSE;
++
++      err = wv_check_ioaddr(ioaddr, mac);
++      if (err)
++              goto out;
++
++      memcpy(dev->dev_addr, mac, 6);
++
++      dev->base_addr = ioaddr;
+ #ifdef DEBUG_CALLBACK_TRACE
+       printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%lx)\n",
+@@ -4136,25 +4148,18 @@ static int __init wavelan_config(device 
+                      "%s: wavelan_config(): could not wavelan_map_irq(%d).\n",
+                      dev->name, irq_mask);
+ #endif
+-              return -EAGAIN;
++              err = -EAGAIN;
++              goto out;
+       }
+       dev->irq = irq;
+-      if (!request_region(ioaddr, sizeof(ha_t), "wavelan"))
+-              return -EBUSY;
+-
+       dev->mem_start = 0x0000;
+       dev->mem_end = 0x0000;
+       dev->if_port = 0;
+       /* Initialize device structures */
+-      dev->priv = kmalloc(sizeof(net_local), GFP_KERNEL);
+-      if (dev->priv == NULL) {
+-              release_region(ioaddr, sizeof(ha_t));
+-              return -ENOMEM;
+-      }
+-      memset(dev->priv, 0x00, sizeof(net_local));
++      memset(dev->priv, 0, sizeof(net_local));
+       lp = (net_local *) dev->priv;
+       /* Back link to the device structure. */
+@@ -4172,12 +4177,6 @@ static int __init wavelan_config(device 
+       /* Init spinlock */
+       spin_lock_init(&lp->spinlock);
+-      /*
+-       * Fill in the fields of the device structure
+-       * with generic Ethernet values.
+-       */
+-      ether_setup(dev);
+-
+       SET_MODULE_OWNER(dev);
+       dev->open = wavelan_open;
+       dev->stop = wavelan_close;
+@@ -4204,6 +4203,9 @@ static int __init wavelan_config(device 
+       printk(KERN_DEBUG "%s: <-wavelan_config()\n", dev->name);
+ #endif
+       return 0;
++out:
++      release_region(ioaddr, sizeof(ha_t));
++      return err;
+ }
+ /*------------------------------------------------------------------*/
+@@ -4214,19 +4216,13 @@ static int __init wavelan_config(device 
+  * We follow the example in drivers/net/ne.c.
+  * (called in "Space.c")
+  */
+-int __init wavelan_probe(device * dev)
++struct net_device * __init wavelan_probe(int unit)
+ {
++      struct net_device *dev;
+       short base_addr;
+-      mac_addr mac;           /* MAC address (check existence of WaveLAN) */
++      int def_irq;
+       int i;
+-      int r;
+-
+-#ifdef DEBUG_CALLBACK_TRACE
+-      printk(KERN_DEBUG
+-             "%s: ->wavelan_probe(dev=0x%x (base_addr=0x%x))\n",
+-             dev->name, (unsigned int) dev,
+-             (unsigned int) dev->base_addr);
+-#endif
++      int r = 0;
+ #ifdef        STRUCT_CHECK
+       if (wv_struct_check() != (char *) NULL) {
+@@ -4237,8 +4233,20 @@ int __init wavelan_probe(device * dev)
+       }
+ #endif                                /* STRUCT_CHECK */
+-      /* Check the value of the command line parameter for base address. */
++      dev = alloc_etherdev(sizeof(net_local));
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++
++      sprintf(dev->name, "eth%d", unit);
++      netdev_boot_setup_check(dev);
+       base_addr = dev->base_addr;
++      def_irq = dev->irq;
++
++#ifdef DEBUG_CALLBACK_TRACE
++      printk(KERN_DEBUG
++             "%s: ->wavelan_probe(dev=%p (base_addr=0x%x))\n",
++             dev->name, dev, (unsigned int) dev->base_addr);
++#endif
+       /* Don't probe at all. */
+       if (base_addr < 0) {
+@@ -4247,16 +4255,9 @@ int __init wavelan_probe(device * dev)
+                      "%s: wavelan_probe(): invalid base address\n",
+                      dev->name);
+ #endif
+-              return -ENXIO;
+-      }
+-
+-      /* Check a single specified location. */
+-      if (base_addr > 0x100) {
+-              /* Check if there is something at this base address */
+-              if ((r = wv_check_ioaddr(base_addr, mac)) == 0) {
+-                      memcpy(dev->dev_addr, mac, 6);  /* Copy MAC address. */
+-                      r = wavelan_config(dev);
+-              }
++              r = -ENXIO;
++      } else if (base_addr > 0x100) { /* Check a single specified location. */
++              r = wavelan_config(dev, base_addr);
+ #ifdef DEBUG_CONFIG_INFO
+               if (r != 0)
+                       printk(KERN_DEBUG
+@@ -4267,35 +4268,33 @@ int __init wavelan_probe(device * dev)
+ #ifdef DEBUG_CALLBACK_TRACE
+               printk(KERN_DEBUG "%s: <-wavelan_probe()\n", dev->name);
+ #endif
+-              return r;
+-      }
+-
+-      /* Scan all possible addresses of the WaveLAN hardware. */
+-      for (i = 0; i < NELS(iobase); i++) {
+-              /* Check whether there is something at this base address. */
+-              if (wv_check_ioaddr(iobase[i], mac) == 0) {
+-                      dev->base_addr = iobase[i];     /* Copy base address. */
+-                      memcpy(dev->dev_addr, mac, 6);  /* Copy MAC address. */
+-                      if (wavelan_config(dev) == 0) {
++      } else { /* Scan all possible addresses of the WaveLAN hardware. */
++              for (i = 0; i < NELS(iobase); i++) {
++                      dev->irq = def_irq;
++                      if (wavelan_config(dev, iobase[i]) == 0) {
+ #ifdef DEBUG_CALLBACK_TRACE
+                               printk(KERN_DEBUG
+                                      "%s: <-wavelan_probe()\n",
+                                      dev->name);
+ #endif
+-                              return 0;
++                              break;
+                       }
+               }
++              if (i == NELS(iobase))
++                      r = -ENODEV;
+       }
+-
+-      /* We may have touched base_addr.  Another driver may not like it. */
+-      dev->base_addr = base_addr;
+-
+-#ifdef DEBUG_CONFIG_INFO
+-      printk(KERN_DEBUG "%s: wavelan_probe(): no device found\n",
+-             dev->name);
+-#endif
+-
+-      return -ENODEV;
++      if (r) 
++              goto out;
++      r = register_netdev(dev);
++      if (r)
++              goto out1;
++      return dev;
++out1:
++      release_region(dev->base_addr, sizeof(ha_t));
++      wavelan_list = wavelan_list->next;
++out:
++      free_netdev(dev);
++      return ERR_PTR(r);
+ }
+ /****************************** MODULE ******************************/
+@@ -4311,7 +4310,6 @@ int __init wavelan_probe(device * dev)
+  */
+ int init_module(void)
+ {
+-      mac_addr mac;           /* MAC address (check WaveLAN existence) */
+       int ret = -EIO;         /* Return error if no cards found */
+       int i;
+@@ -4337,38 +4335,28 @@ int init_module(void)
+       /* Loop on all possible base addresses. */
+       i = -1;
+       while ((io[++i] != 0) && (i < NELS(io))) {
+-              /* Check if there is something at this base address. */
+-              if (wv_check_ioaddr(io[i], mac) == 0) {
+-                      device *dev;
+-
+-                      /* Create device and set basic arguments. */
+-                      dev =
+-                          kmalloc(sizeof(struct net_device), GFP_KERNEL);
+-                      if (dev == NULL) {
+-                              ret = -ENOMEM;
+-                              break;
+-                      }
+-                      memset(dev, 0x00, sizeof(struct net_device));
+-                      memcpy(dev->name, name[i], IFNAMSIZ);   /* Copy name */
+-                      dev->base_addr = io[i];
+-                      dev->irq = irq[i];
+-                      dev->init = &wavelan_config;
+-                      memcpy(dev->dev_addr, mac, 6);  /* Copy MAC address. */
++              struct net_device *dev = alloc_etherdev(sizeof(net_local));
++              if (!dev)
++                      break;
++              memcpy(dev->name, name[i], IFNAMSIZ);   /* Copy name */
++              dev->base_addr = io[i];
++              dev->irq = irq[i];
+-                      /* Try to create the device. */
++              /* Check if there is something at this base address. */
++              if (wavelan_config(dev, io[i]) == 0) {
+                       if (register_netdev(dev) != 0) {
+-                              /* Deallocate everything. */
+-                              /* Note: if dev->priv is mallocated, there is no way to fail. */
+-                              kfree(dev);
++                              release_region(dev->base_addr, sizeof(ha_t));
++                              wavelan_list = wavelan_list->next;
+                       } else {
+-                              /* If at least one device OK, we do not fail */
+                               ret = 0;
++                              continue;
+                       }
+-              }               /* if there is something at the address */
+-      }                       /* Loop on all addresses. */
++              }
++              free_netdev(dev);
++      }
+ #ifdef DEBUG_CONFIG_ERROR
+-      if (wavelan_list == (net_local *) NULL)
++      if (!wavelan_list)
+               printk(KERN_WARNING
+                      "WaveLAN init_module(): no device found\n");
+ #endif
+@@ -4390,26 +4378,19 @@ void cleanup_module(void)
+ #endif
+       /* Loop on all devices and release them. */
+-      while (wavelan_list != (net_local *) NULL) {
+-              device *dev = wavelan_list->dev;
++      while (wavelan_list) {
++              struct net_device *dev = wavelan_list->dev;
+ #ifdef DEBUG_CONFIG_INFO
+               printk(KERN_DEBUG
+                      "%s: cleanup_module(): removing device at 0x%x\n",
+                      dev->name, (unsigned int) dev);
+ #endif
+-
+-              /* Release the ioport region. */
+-              release_region(dev->base_addr, sizeof(ha_t));
+-
+-              /* Definitely remove the device. */
+               unregister_netdev(dev);
+-              /* Unlink the device. */
++              release_region(dev->base_addr, sizeof(ha_t));
+               wavelan_list = wavelan_list->next;
+-              /* Free pieces. */
+-              kfree(dev->priv);
+               free_netdev(dev);
+       }
+--- linux-2.6.0/drivers/net/wireless/wavelan_cs.c      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wireless/wavelan_cs.c       2003-12-28 23:21:01.000000000 -0800
+@@ -131,7 +131,7 @@ hacr_write_slow(u_long     base,
+  * Read the Parameter Storage Area from the WaveLAN card's memory
+  */
+ static void
+-psa_read(device *     dev,
++psa_read(struct net_device *  dev,
+        int            o,      /* offset in PSA */
+        u_char *       b,      /* buffer to fill */
+        int            n)      /* size to read */
+@@ -155,7 +155,7 @@ psa_read(device *  dev,
+  * Write the Paramter Storage Area to the WaveLAN card's memory
+  */
+ static void
+-psa_write(device *    dev,
++psa_write(struct net_device * dev,
+         int           o,      /* Offset in psa */
+         u_char *      b,      /* Buffer in memory */
+         int           n)      /* Length of buffer */
+@@ -229,7 +229,7 @@ psa_crc(unsigned char *    psa,    /* The PSA 
+  * update the checksum field in the Wavelan's PSA
+  */
+ static void
+-update_psa_checksum(device *  dev)
++update_psa_checksum(struct net_device *       dev)
+ {
+ #ifdef SET_PSA_CRC
+   psa_t               psa;
+@@ -753,7 +753,7 @@ void wv_roam_handover(wavepoint_history 
+ }
+ /* Called when a WavePoint beacon is received */
+-static inline void wl_roam_gather(device *  dev,
++static inline void wl_roam_gather(struct net_device *  dev,
+                                 u_char *  hdr,   /* Beacon header */
+                                 u_char *  stats) /* SNR, Signal quality 
+                                                     of packet */
+@@ -831,7 +831,7 @@ static inline int WAVELAN_BEACON(unsigne
+  *  wv_82593_config() & wv_diag())
+  */
+ static int
+-wv_82593_cmd(device * dev,
++wv_82593_cmd(struct net_device *      dev,
+            char *     str,
+            int        cmd,
+            int        result)
+@@ -942,7 +942,7 @@ wv_82593_cmd(device *      dev,
+  * status for the WaveLAN.
+  */
+ static inline int
+-wv_diag(device *      dev)
++wv_diag(struct net_device *   dev)
+ {
+   int         ret = FALSE;
+@@ -963,7 +963,7 @@ wv_diag(device *   dev)
+  * The return value is the address to use for next the call.
+  */
+ static int
+-read_ringbuf(device * dev,
++read_ringbuf(struct net_device *      dev,
+            int        addr,
+            char *     buf,
+            int        len)
+@@ -1004,10 +1004,10 @@ read_ringbuf(device *  dev,
+  * some delay sometime...
+  */
+ static inline void
+-wv_82593_reconfig(device *    dev)
++wv_82593_reconfig(struct net_device * dev)
+ {
+   net_local *         lp = (net_local *)dev->priv;
+-  dev_link_t *                link = ((net_local *) dev->priv)->link;
++  dev_link_t *                link = lp->link;
+   unsigned long               flags;
+   /* Arm the flag, will be cleard in wv_82593_config() */
+@@ -1132,7 +1132,7 @@ wv_psa_show(psa_t *      p)
+  * This function need to be completed...
+  */
+ static void
+-wv_mmc_show(device *  dev)
++wv_mmc_show(struct net_device *       dev)
+ {
+   ioaddr_t    base = dev->base_addr;
+   net_local * lp = (net_local *)dev->priv;
+@@ -1222,7 +1222,7 @@ wv_mmc_show(device *     dev)
+  * Print the formatted status of the i82593's receive unit.
+  */
+ static void
+-wv_ru_show(device *   dev)
++wv_ru_show(struct net_device *        dev)
+ {
+   net_local *lp = (net_local *) dev->priv;
+@@ -1241,7 +1241,7 @@ wv_ru_show(device *      dev)
+  * Print the formatted status of the WaveLAN PCMCIA device driver.
+  */
+ static void
+-wv_dev_show(device *  dev)
++wv_dev_show(struct net_device *       dev)
+ {
+   printk(KERN_DEBUG "dev:");
+   printk(" state=%lX,", dev->state);
+@@ -1256,7 +1256,7 @@ wv_dev_show(device *     dev)
+  * private information.
+  */
+ static void
+-wv_local_show(device *        dev)
++wv_local_show(struct net_device *     dev)
+ {
+   net_local *lp;
+@@ -1314,7 +1314,7 @@ wv_packet_info(u_char *          p,              /* Packet t
+  * There  is a lot of flag to configure it at your will...
+  */
+ static inline void
+-wv_init_info(device * dev)
++wv_init_info(struct net_device *      dev)
+ {
+   ioaddr_t    base = dev->base_addr;
+   psa_t               psa;
+@@ -1412,7 +1412,7 @@ wv_init_info(device *    dev)
+  * Used when the user read /proc/net/dev
+  */
+ static en_stats       *
+-wavelan_get_stats(device *    dev)
++wavelan_get_stats(struct net_device * dev)
+ {
+ #ifdef DEBUG_IOCTL_TRACE
+   printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
+@@ -1431,7 +1431,7 @@ wavelan_get_stats(device *       dev)
+  */
+ static void
+-wavelan_set_multicast_list(device *   dev)
++wavelan_set_multicast_list(struct net_device *        dev)
+ {
+   net_local * lp = (net_local *) dev->priv;
+@@ -1529,7 +1529,7 @@ wavelan_set_multicast_list(device *      dev)
+  */
+ #ifdef SET_MAC_ADDRESS
+ static int
+-wavelan_set_mac_address(device *      dev,
++wavelan_set_mac_address(struct net_device *   dev,
+                       void *          addr)
+ {
+   struct sockaddr *   mac = addr;
+@@ -1796,7 +1796,7 @@ wv_frequency_list(u_long base,   /* i/o po
+  * Sorry, but this function really need wireless extensions...
+  */
+ static inline void
+-wl_spy_gather(device *        dev,
++wl_spy_gather(struct net_device *     dev,
+             u_char *  mac,            /* MAC address */
+             u_char *  stats)          /* Statistics to gather */
+ {
+@@ -1823,7 +1823,7 @@ wl_spy_gather(device *   dev,
+  * or you may also calculate the mean and standard deviation of the level...
+  */
+ static inline void
+-wl_his_gather(device *        dev,
++wl_his_gather(struct net_device *     dev,
+             u_char *  stats)          /* Statistics to gather */
+ {
+   net_local * lp = (net_local *) dev->priv;
+@@ -2785,7 +2785,7 @@ wavelan_ioctl(struct net_device *        dev,    /
+  * Called by /proc/net/wireless...
+  */
+ static iw_stats *
+-wavelan_get_wireless_stats(device *   dev)
++wavelan_get_wireless_stats(struct net_device *        dev)
+ {
+   ioaddr_t            base = dev->base_addr;
+   net_local *         lp = (net_local *) dev->priv;
+@@ -2847,7 +2847,7 @@ wavelan_get_wireless_stats(device *      dev)
+  * (called by wv_packet_rcv())
+  */
+ static inline int
+-wv_start_of_frame(device *    dev,
++wv_start_of_frame(struct net_device * dev,
+                 int           rfp,    /* end of frame */
+                 int           wrap)   /* start of buffer */
+ {
+@@ -2909,7 +2909,7 @@ wv_start_of_frame(device *       dev,
+  * (called by wv_packet_rcv())
+  */
+ static inline void
+-wv_packet_read(device *               dev,
++wv_packet_read(struct net_device *            dev,
+              int              fd_p,
+              int              sksize)
+ {
+@@ -3012,7 +3012,7 @@ wv_packet_read(device *          dev,
+  * Note : the spinlock is already grabbed for us and irq are disabled.
+  */
+ static inline void
+-wv_packet_rcv(device *        dev)
++wv_packet_rcv(struct net_device *     dev)
+ {
+   ioaddr_t    base = dev->base_addr;
+   net_local * lp = (net_local *) dev->priv;
+@@ -3146,7 +3146,7 @@ wv_packet_rcv(device *   dev)
+  * (called in wavelan_packet_xmit())
+  */
+ static inline void
+-wv_packet_write(device *      dev,
++wv_packet_write(struct net_device *   dev,
+               void *          buf,
+               short           length)
+ {
+@@ -3209,7 +3209,7 @@ wv_packet_write(device * dev,
+  */
+ static int
+ wavelan_packet_xmit(struct sk_buff *  skb,
+-                  device *            dev)
++                  struct net_device *         dev)
+ {
+   net_local *         lp = (net_local *)dev->priv;
+   unsigned long               flags;
+@@ -3273,7 +3273,7 @@ wavelan_packet_xmit(struct sk_buff *     skb
+  * (called by wv_hw_config())
+  */
+ static inline int
+-wv_mmc_init(device *  dev)
++wv_mmc_init(struct net_device *       dev)
+ {
+   ioaddr_t    base = dev->base_addr;
+   psa_t               psa;
+@@ -3467,7 +3467,7 @@ wv_mmc_init(device *     dev)
+  * (called in wv_ru_start() and wavelan_close() and wavelan_event())
+  */
+ static int
+-wv_ru_stop(device *   dev)
++wv_ru_stop(struct net_device *        dev)
+ {
+   ioaddr_t    base = dev->base_addr;
+   net_local * lp = (net_local *) dev->priv;
+@@ -3530,7 +3530,7 @@ wv_ru_stop(device *      dev)
+  * (called in wv_hw_reset() & wavelan_open())
+  */
+ static int
+-wv_ru_start(device *  dev)
++wv_ru_start(struct net_device *       dev)
+ {
+   ioaddr_t    base = dev->base_addr;
+   net_local * lp = (net_local *) dev->priv;
+@@ -3618,7 +3618,7 @@ wv_ru_start(device *     dev)
+  * (called by wv_hw_config(), wv_82593_reconfig() & wavelan_packet_xmit())
+  */
+ static int
+-wv_82593_config(device *      dev)
++wv_82593_config(struct net_device *   dev)
+ {
+   ioaddr_t                    base = dev->base_addr;
+   net_local *                 lp = (net_local *) dev->priv;
+@@ -3792,7 +3792,7 @@ wv_82593_config(device * dev)
+  * (called by wv_config())
+  */
+ static inline int
+-wv_pcmcia_reset(device *      dev)
++wv_pcmcia_reset(struct net_device *   dev)
+ {
+   int         i;
+   conf_reg_t  reg = { 0, CS_READ, CISREG_COR, 0 };
+@@ -3854,7 +3854,7 @@ wv_pcmcia_reset(device * dev)
+  * (called by wavelan_event() & wv_hw_reset())
+  */
+ static int
+-wv_hw_config(device * dev)
++wv_hw_config(struct net_device *      dev)
+ {
+   net_local *         lp = (net_local *) dev->priv;
+   ioaddr_t            base = dev->base_addr;
+@@ -3961,7 +3961,7 @@ wv_hw_config(device *    dev)
+  * (called by wavelan_event(), wavelan_watchdog() and wavelan_open())
+  */
+ static inline void
+-wv_hw_reset(device *  dev)
++wv_hw_reset(struct net_device *       dev)
+ {
+   net_local * lp = (net_local *) dev->priv;
+@@ -4004,7 +4004,7 @@ wv_pcmcia_config(dev_link_t *    link)
+   memreq_t            mem;
+   handle = link->handle;
+-  dev = (device *) link->priv;
++  dev = (struct net_device *) link->priv;
+ #ifdef DEBUG_CONFIG_TRACE
+   printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link);
+@@ -4150,7 +4150,7 @@ wv_pcmcia_config(dev_link_t *    link)
+ static void
+ wv_pcmcia_release(dev_link_t *link)
+ {
+-  device *    dev = (device *) link->priv;
++  struct net_device * dev = (struct net_device *) link->priv;
+ #ifdef DEBUG_CONFIG_TRACE
+   printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
+@@ -4200,13 +4200,13 @@ wavelan_interrupt(int          irq,
+                 void *        dev_id,
+                 struct pt_regs * regs)
+ {
+-  device *    dev;
++  struct net_device * dev;
+   net_local * lp;
+   ioaddr_t    base;
+   int         status0;
+   u_int               tx_status;
+-  if((dev = (device *)dev_id) == (device *) NULL)
++  if ((dev = dev_id) == NULL)
+     {
+ #ifdef DEBUG_INTERRUPT_ERROR
+       printk(KERN_WARNING "wavelan_interrupt(): irq %d for unknown device.\n",
+@@ -4467,7 +4467,7 @@ wavelan_interrupt(int            irq,
+  * deal with the multiple Tx buffers...
+  */
+ static void
+-wavelan_watchdog(device *     dev)
++wavelan_watchdog(struct net_device *  dev)
+ {
+   net_local *         lp = (net_local *) dev->priv;
+   ioaddr_t            base = dev->base_addr;
+@@ -4542,7 +4542,7 @@ wavelan_watchdog(device *        dev)
+  * Called by NET3 when it "open" the device.
+  */
+ static int
+-wavelan_open(device * dev)
++wavelan_open(struct net_device *      dev)
+ {
+   dev_link_t *        link = ((net_local *) dev->priv)->link;
+   net_local * lp = (net_local *)dev->priv;
+@@ -4597,7 +4597,7 @@ wavelan_open(device *    dev)
+  * Called by NET3 when it "close" the device.
+  */
+ static int
+-wavelan_close(device *        dev)
++wavelan_close(struct net_device *     dev)
+ {
+   dev_link_t *        link = ((net_local *) dev->priv)->link;
+   ioaddr_t    base = dev->base_addr;
+@@ -4661,7 +4661,7 @@ wavelan_attach(void)
+ {
+   client_reg_t        client_reg;     /* Register with cardmgr */
+   dev_link_t *        link;           /* Info for cardmgr */
+-  device *    dev;            /* Interface generic data */
++  struct net_device * dev;            /* Interface generic data */
+   net_local * lp;             /* Interface specific data */
+   int         i, ret;
+@@ -4699,22 +4699,14 @@ wavelan_attach(void)
+   dev_list = link;
+   /* Allocate the generic data structure */
+-  dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
++  dev = alloc_etherdev(sizeof(net_local));
+   if (!dev) {
+       kfree(link);
+       return NULL;
+   }
+-  memset(dev, 0x00, sizeof(struct net_device));
+   link->priv = link->irq.Instance = dev;
+-  /* Allocate the wavelan-specific data structure. */
+-  dev->priv = lp = (net_local *) kmalloc(sizeof(net_local), GFP_KERNEL);
+-  if (!lp) {
+-      kfree(link);
+-      kfree(dev);
+-      return NULL;
+-  }
+-  memset(lp, 0x00, sizeof(net_local));
++  lp = dev->priv;
+   /* Init specific data */
+   lp->configured = 0;
+@@ -4732,9 +4724,6 @@ wavelan_attach(void)
+   lp->link = link;
+   lp->dev = dev;
+-  /* Standard setup for generic data */
+-  ether_setup(dev);
+-
+   /* wavelan NET3 callbacks */
+   SET_MODULE_OWNER(dev);
+   dev->open = &wavelan_open;
+@@ -4852,22 +4841,16 @@ wavelan_detach(dev_link_t *    link)
+   /* Free pieces */
+   if(link->priv)
+     {
+-      device *        dev = (device *) link->priv;
++      struct net_device *     dev = (struct net_device *) link->priv;
+       /* Remove ourselves from the kernel list of ethernet devices */
+       /* Warning : can't be called from interrupt, timer or wavelan_close() */
+-      if(link->dev != NULL)
++      if (link->dev)
+       unregister_netdev(dev);
+       link->dev = NULL;
+-
+-      if(dev->priv)
+-      {
+-        /* Sound strange, but safe... */
+-        ((net_local *) dev->priv)->link = (dev_link_t *) NULL;
+-        ((net_local *) dev->priv)->dev = (device *) NULL;
+-        kfree(dev->priv);
+-      }
+-      kfree(link->priv);
++      ((net_local *) dev->priv)->link = NULL;
++      ((net_local *) dev->priv)->dev = NULL;
++      free_netdev(dev);
+     }
+   kfree(link);
+@@ -4889,7 +4872,7 @@ wavelan_event(event_t            event,          /* The ev
+             event_callback_args_t *   args)
+ {
+   dev_link_t *        link = (dev_link_t *) args->client_data;
+-  device *    dev = (device *) link->priv;
++  struct net_device * dev = (struct net_device *) link->priv;
+ #ifdef DEBUG_CALLBACK_TRACE
+   printk(KERN_DEBUG "->wavelan_event(): %s\n",
+--- linux-2.6.0/drivers/net/wireless/wavelan_cs.p.h    2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wireless/wavelan_cs.p.h     2003-12-28 23:21:01.000000000 -0800
+@@ -588,7 +588,6 @@ struct wavepoint_table
+ /****************************** TYPES ******************************/
+ /* Shortcuts */
+-typedef struct net_device     device;
+ typedef struct net_device_stats       en_stats;
+ typedef struct iw_statistics  iw_stats;
+ typedef struct iw_quality     iw_qual;
+@@ -611,7 +610,7 @@ typedef u_char             mac_addr[WAVELAN_ADDR_SI
+ struct net_local
+ {
+   dev_node_t  node;           /* ???? What is this stuff ???? */
+-  device *    dev;            /* Reverse link... */
++  struct net_device * dev;            /* Reverse link... */
+   spinlock_t  spinlock;       /* Serialize access to the hardware (SMP) */
+   dev_link_t *        link;           /* pcmcia structure */
+   en_stats    stats;          /* Ethernet interface statistics */
+@@ -673,11 +672,11 @@ static inline void
+       hacr_write_slow(u_long,
+                  u_char);
+ static void
+-      psa_read(device *,      /* Read the Parameter Storage Area */
++      psa_read(struct net_device *,   /* Read the Parameter Storage Area */
+                int,           /* offset in PSA */
+                u_char *,      /* buffer to fill */
+                int),          /* size to read */
+-      psa_write(device *,     /* Write to the PSA */
++      psa_write(struct net_device *,  /* Write to the PSA */
+                 int,          /* Offset in psa */
+                 u_char *,     /* Buffer in memory */
+                 int);         /* Length of buffer */
+@@ -707,57 +706,57 @@ static void
+                int);          /* number of registers */
+ /* ---------------------- I82593 SUBROUTINES ----------------------- */
+ static int
+-      wv_82593_cmd(device *,  /* synchronously send a command to i82593 */ 
++      wv_82593_cmd(struct net_device *,       /* synchronously send a command to i82593 */ 
+                    char *,
+                    int,
+                    int);
+ static inline int
+-      wv_diag(device *);      /* Diagnostique the i82593 */
++      wv_diag(struct net_device *);   /* Diagnostique the i82593 */
+ static int
+-      read_ringbuf(device *,  /* Read a receive buffer */
++      read_ringbuf(struct net_device *,       /* Read a receive buffer */
+                    int,
+                    char *,
+                    int);
+ static inline void
+-      wv_82593_reconfig(device *);    /* Reconfigure the controller */
++      wv_82593_reconfig(struct net_device *); /* Reconfigure the controller */
+ /* ------------------- DEBUG & INFO SUBROUTINES ------------------- */
+ static inline void
+-      wv_init_info(device *); /* display startup info */
++      wv_init_info(struct net_device *);      /* display startup info */
+ /* ------------------- IOCTL, STATS & RECONFIG ------------------- */
+ static en_stats       *
+-      wavelan_get_stats(device *);    /* Give stats /proc/net/dev */
++      wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */
+ /* ----------------------- PACKET RECEPTION ----------------------- */
+ static inline int
+-      wv_start_of_frame(device *,     /* Seek beggining of current frame */
++      wv_start_of_frame(struct net_device *,  /* Seek beggining of current frame */
+                         int,  /* end of frame */
+                         int); /* start of buffer */
+ static inline void
+-      wv_packet_read(device *,        /* Read a packet from a frame */
++      wv_packet_read(struct net_device *,     /* Read a packet from a frame */
+                      int,
+                      int),
+-      wv_packet_rcv(device *);        /* Read all packets waiting */
++      wv_packet_rcv(struct net_device *);     /* Read all packets waiting */
+ /* --------------------- PACKET TRANSMISSION --------------------- */
+ static inline void
+-      wv_packet_write(device *,       /* Write a packet to the Tx buffer */
++      wv_packet_write(struct net_device *,    /* Write a packet to the Tx buffer */
+                       void *,
+                       short);
+ static int
+       wavelan_packet_xmit(struct sk_buff *,   /* Send a packet */
+-                          device *);
++                          struct net_device *);
+ /* -------------------- HARDWARE CONFIGURATION -------------------- */
+ static inline int
+-      wv_mmc_init(device *);  /* Initialize the modem */
++      wv_mmc_init(struct net_device *);       /* Initialize the modem */
+ static int
+-      wv_ru_stop(device *),   /* Stop the i82593 receiver unit */
+-      wv_ru_start(device *);  /* Start the i82593 receiver unit */
++      wv_ru_stop(struct net_device *),        /* Stop the i82593 receiver unit */
++      wv_ru_start(struct net_device *);       /* Start the i82593 receiver unit */
+ static int
+-      wv_82593_config(device *);      /* Configure the i82593 */
++      wv_82593_config(struct net_device *);   /* Configure the i82593 */
+ static inline int
+-      wv_pcmcia_reset(device *);      /* Reset the pcmcia interface */
++      wv_pcmcia_reset(struct net_device *);   /* Reset the pcmcia interface */
+ static int
+-      wv_hw_config(device *); /* Reset & configure the whole hardware */
++      wv_hw_config(struct net_device *);      /* Reset & configure the whole hardware */
+ static inline void
+-      wv_hw_reset(device *);  /* Same, + start receiver unit */
++      wv_hw_reset(struct net_device *);       /* Same, + start receiver unit */
+ static inline int
+       wv_pcmcia_config(dev_link_t *); /* Configure the pcmcia interface */
+ static void
+@@ -768,11 +767,11 @@ static irqreturn_t
+                         void *,
+                         struct pt_regs *);
+ static void
+-      wavelan_watchdog(device *);     /* Transmission watchdog */
++      wavelan_watchdog(struct net_device *);  /* Transmission watchdog */
+ /* ------------------- CONFIGURATION CALLBACKS ------------------- */
+ static int
+-      wavelan_open(device *),         /* Open the device */
+-      wavelan_close(device *);        /* Close the device */
++      wavelan_open(struct net_device *),              /* Open the device */
++      wavelan_close(struct net_device *);     /* Close the device */
+ static dev_link_t *
+       wavelan_attach(void);           /* Create a new device */
+ static void
+--- linux-2.6.0/drivers/net/wireless/wavelan.p.h       2003-06-14 12:18:28.000000000 -0700
++++ 25/drivers/net/wireless/wavelan.p.h        2003-12-28 23:21:01.000000000 -0800
+@@ -469,7 +469,6 @@ static const char  *version        = "wavelan.c 
+ /****************************** TYPES ******************************/
+ /* Shortcuts */
+-typedef struct net_device             device;
+ typedef struct net_device_stats       en_stats;
+ typedef struct iw_statistics  iw_stats;
+ typedef struct iw_quality     iw_qual;
+@@ -492,7 +491,7 @@ typedef u_char             mac_addr[WAVELAN_ADDR_SI
+ struct net_local
+ {
+   net_local * next;           /* linked list of the devices */
+-  device *    dev;            /* reverse link */
++  struct net_device * dev;            /* reverse link */
+   spinlock_t  spinlock;       /* Serialize access to the hardware (SMP) */
+   en_stats    stats;          /* Ethernet interface statistics */
+   int         nresets;        /* number of hardware resets */
+@@ -542,8 +541,8 @@ static inline void
+                 u_short),     /* hacr   */
+       wv_16_on(u_long,        /* ioaddr */
+                u_short),      /* hacr   */
+-      wv_ints_off(device *),
+-      wv_ints_on(device *);
++      wv_ints_off(struct net_device *),
++      wv_ints_on(struct net_device *);
+ /* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
+ static void
+       psa_read(u_long,        /* Read the Parameter Storage Area. */
+@@ -592,57 +591,57 @@ static inline void
+                   u_char *,   /* b */
+                   int);       /* n */
+ static void
+-      wv_ack(device *);
++      wv_ack(struct net_device *);
+ static inline int
+-      wv_synchronous_cmd(device *,
++      wv_synchronous_cmd(struct net_device *,
+                          const char *),
+-      wv_config_complete(device *,
++      wv_config_complete(struct net_device *,
+                          u_long,
+                          net_local *);
+ static int
+-      wv_complete(device *,
++      wv_complete(struct net_device *,
+                   u_long,
+                   net_local *);
+ static inline void
+-      wv_82586_reconfig(device *);
++      wv_82586_reconfig(struct net_device *);
+ /* ------------------- DEBUG & INFO SUBROUTINES ------------------- */
+ #ifdef DEBUG_I82586_SHOW
+ static void
+       wv_scb_show(unsigned short);
+ #endif
+ static inline void
+-      wv_init_info(device *); /* display startup info */
++      wv_init_info(struct net_device *);      /* display startup info */
+ /* ------------------- IOCTL, STATS & RECONFIG ------------------- */
+ static en_stats       *
+-      wavelan_get_stats(device *);    /* Give stats /proc/net/dev */
++      wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */
+ static void
+-      wavelan_set_multicast_list(device *);
++      wavelan_set_multicast_list(struct net_device *);
+ /* ----------------------- PACKET RECEPTION ----------------------- */
+ static inline void
+-      wv_packet_read(device *,        /* Read a packet from a frame. */
++      wv_packet_read(struct net_device *,     /* Read a packet from a frame. */
+                      u_short,
+                      int),
+-      wv_receive(device *);   /* Read all packets waiting. */
++      wv_receive(struct net_device *);        /* Read all packets waiting. */
+ /* --------------------- PACKET TRANSMISSION --------------------- */
+ static inline int
+-      wv_packet_write(device *,       /* Write a packet to the Tx buffer. */
++      wv_packet_write(struct net_device *,    /* Write a packet to the Tx buffer. */
+                       void *,
+                       short);
+ static int
+       wavelan_packet_xmit(struct sk_buff *,   /* Send a packet. */
+-                          device *);
++                          struct net_device *);
+ /* -------------------- HARDWARE CONFIGURATION -------------------- */
+ static inline int
+-      wv_mmc_init(device *),          /* Initialize the modem. */
+-      wv_ru_start(device *),          /* Start the i82586 receiver unit. */
+-      wv_cu_start(device *),          /* Start the i82586 command unit. */
+-      wv_82586_start(device *);       /* Start the i82586. */
++      wv_mmc_init(struct net_device *),       /* Initialize the modem. */
++      wv_ru_start(struct net_device *),       /* Start the i82586 receiver unit. */
++      wv_cu_start(struct net_device *),       /* Start the i82586 command unit. */
++      wv_82586_start(struct net_device *);    /* Start the i82586. */
+ static void
+-      wv_82586_config(device *);      /* Configure the i82586. */
++      wv_82586_config(struct net_device *);   /* Configure the i82586. */
+ static inline void
+-      wv_82586_stop(device *);
++      wv_82586_stop(struct net_device *);
+ static int
+-      wv_hw_reset(device *),          /* Reset the WaveLAN hardware. */
++      wv_hw_reset(struct net_device *),       /* Reset the WaveLAN hardware. */
+       wv_check_ioaddr(u_long,         /* ioaddr */
+                       u_char *);      /* mac address (read) */
+ /* ---------------------- INTERRUPT HANDLING ---------------------- */
+@@ -651,14 +650,13 @@ static irqreturn_t
+                         void *,
+                         struct pt_regs *);
+ static void
+-      wavelan_watchdog(device *);     /* transmission watchdog */
++      wavelan_watchdog(struct net_device *);  /* transmission watchdog */
+ /* ------------------- CONFIGURATION CALLBACKS ------------------- */
+ static int
+-      wavelan_open(device *),         /* Open the device. */
+-      wavelan_close(device *),        /* Close the device. */
+-      wavelan_config(device *);       /* Configure one device. */
+-extern int
+-      wavelan_probe(device *);        /* See Space.c. */
++      wavelan_open(struct net_device *),      /* Open the device. */
++      wavelan_close(struct net_device *),     /* Close the device. */
++      wavelan_config(struct net_device *, unsigned short);/* Configure one device. */
++extern struct net_device *wavelan_probe(int unit);    /* See Space.c. */
+ /**************************** VARIABLES ****************************/
+--- linux-2.6.0/drivers/net/wireless/wl3501_cs.c       2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/net/wireless/wl3501_cs.c        2003-12-28 23:22:53.000000000 -0800
+@@ -1449,18 +1449,6 @@ fail:
+       goto out;
+ }
+-/**
+- * wl3501_init - "initialize" board
+- * @dev - network device
+- *
+- * We never need to do anything when a wl3501 device is "initialized" by the net
+- * software, because we only register already-found cards.
+- */
+-static int wl3501_init(struct net_device *dev)
+-{
+-      return 0;
+-}
+-
+ struct net_device_stats *wl3501_get_stats(struct net_device *dev)
+ {
+       struct wl3501_card *this = dev->priv;
+@@ -1586,7 +1574,7 @@ static void wl3501_detach(dev_link_t *li
+       /* Break the link with Card Services */
+       if (link->handle)
+-              CardServices(DeregisterClient, link->handle);
++              pcmcia_deregister_client(link->handle);
+       /* Unlink device structure, free pieces */
+       *linkp = link->next;
+@@ -2056,7 +2044,6 @@ static dev_link_t *wl3501_attach(void)
+       dev = alloc_etherdev(sizeof(struct wl3501_card));
+       if (!dev)
+               goto out_link;
+-      dev->init               = wl3501_init;
+       dev->open               = wl3501_open;
+       dev->stop               = wl3501_close;
+       dev->hard_start_xmit    = wl3501_hard_start_xmit;
+@@ -2083,7 +2070,7 @@ static dev_link_t *wl3501_attach(void)
+       client_reg.event_handler = wl3501_event;
+       client_reg.Version       = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret) {
+               cs_error(link->handle, RegisterClient, ret);
+               wl3501_detach(link);
+@@ -2097,8 +2084,8 @@ out_link:
+       goto out;
+ }
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret = CardServices(last_fn = (fn), args)) != 0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ /**
+  * wl3501_config - configure the PCMCIA socket and make eth device available
+@@ -2121,12 +2108,12 @@ static void wl3501_config(dev_link_t *li
+       /* This reads the card's CONFIG tuple to find its config registers. */
+       tuple.Attributes        = 0;
+       tuple.DesiredTuple      = CISTPL_CONFIG;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       tuple.TupleData         = bf;
+       tuple.TupleDataMax      = sizeof(bf);
+       tuple.TupleOffset       = 0;
+-      CS_CHECK(GetTupleData, handle, &tuple);
+-      CS_CHECK(ParseTuple, handle, &tuple, &parse);
++      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++      CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+       link->conf.ConfigBase   = parse.config.base;
+       link->conf.Present      = parse.config.rmask[0];
+@@ -2142,7 +2129,7 @@ static void wl3501_config(dev_link_t *li
+                * 0x200-0x2ff, and so on, because this seems safer */
+               link->io.BasePort1 = j;
+               link->io.BasePort2 = link->io.BasePort1 + 0x10;
+-              i = CardServices(RequestIO, link->handle, &link->io);
++              i = pcmcia_request_io(link->handle, &link->io);
+               if (i == CS_SUCCESS)
+                       break;
+       }
+@@ -2154,12 +2141,12 @@ static void wl3501_config(dev_link_t *li
+       /* Now allocate an interrupt line. Note that this does not actually
+        * assign a handler to the interrupt. */
+-      CS_CHECK(RequestIRQ, link->handle, &link->irq);
++      CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+       /* This actually configures the PCMCIA socket -- setting up the I/O
+        * windows and the interrupt mapping.  */
+-      CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++      CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+       dev->irq = link->irq.AssignedIRQ;
+       dev->base_addr = link->io.BasePort1;
+@@ -2249,9 +2236,9 @@ static void wl3501_release(dev_link_t *l
+       }
+       /* Don't bother checking to see if these succeed or not */
+-      CardServices(ReleaseConfiguration, link->handle);
+-      CardServices(ReleaseIO, link->handle, &link->io);
+-      CardServices(ReleaseIRQ, link->handle, &link->irq);
++      pcmcia_release_configuration(link->handle);
++      pcmcia_release_io(link->handle, &link->io);
++      pcmcia_release_irq(link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
+       if (link->state & DEV_STALE_CONFIG)
+@@ -2301,7 +2288,7 @@ static int wl3501_event(event_t event, i
+               if (link->state & DEV_CONFIG) {
+                       if (link->open)
+                               netif_device_detach(dev);
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               }
+               break;
+       case CS_EVENT_PM_RESUME:
+@@ -2310,8 +2297,7 @@ static int wl3501_event(event_t event, i
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (link->state & DEV_CONFIG) {
+-                      CardServices(RequestConfiguration, link->handle,
+-                                   &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+                       if (link->open) {
+                               wl3501_reset(dev);
+                               netif_device_attach(dev);
+--- linux-2.6.0/drivers/net/znet.c     2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/znet.c      2003-12-28 23:21:01.000000000 -0800
+@@ -372,10 +372,8 @@ static int __init znet_probe (void)
+       struct znet_private *znet;
+       struct net_device *dev;
+       char *p;
++      int err = -ENOMEM;
+-      if (znet_dev)                           /* Only look for a single adaptor */
+-              return -ENODEV;
+-      
+       /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */
+       for(p = (char *)phys_to_virt(0xf0000); p < (char *)phys_to_virt(0x100000); p++)
+               if (*p == 'N'  &&  strncmp(p, "NETIDBLK", 8) == 0)
+@@ -387,12 +385,14 @@ static int __init znet_probe (void)
+               return -ENODEV;
+       }
+-      if (!(znet_dev = dev = init_etherdev(0, sizeof(struct znet_private))))
+-                      return -ENOMEM;
++      dev = alloc_etherdev(sizeof(struct znet_private));
++      if (!dev)
++              return -ENOMEM;
++
++      SET_MODULE_OWNER (dev);
+       znet = dev->priv;
+-      SET_MODULE_OWNER (dev);
+       netinfo = (struct netidblk *)p;
+       dev->base_addr = netinfo->iobase1;
+       dev->irq = netinfo->irq1;
+@@ -430,7 +430,7 @@ static int __init znet_probe (void)
+       znet->io_size  = 2;
+       if (!(znet->rx_start = kmalloc (DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA)))
+-              goto free_netdev;
++              goto free_dev;
+       if (!(znet->tx_start = kmalloc (DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA)))
+               goto free_rx;
+@@ -452,19 +452,19 @@ static int __init znet_probe (void)
+       dev->set_multicast_list = &znet_set_multicast_list;
+       dev->tx_timeout = znet_tx_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
+-
++      err = register_netdev(dev);
++      if (err)
++              goto free_tx;
++      znet_dev = dev;
+       return 0;
+  free_tx:
+-      kfree (znet->tx_start);
++      kfree(znet->tx_start);
+  free_rx:
+-      kfree (znet->rx_start);
+- free_netdev:
+-      unregister_netdev (dev);
+-      kfree (dev);
+-      znet_dev = NULL;
+-
+-      return -ENOMEM;
++      kfree(znet->rx_start);
++ free_dev:
++      free_netdev(dev);
++      return err;
+ }
\f
+@@ -934,16 +934,14 @@ static void update_stop_hit(short ioaddr
+ static __exit void znet_cleanup (void)
+ {
+-#ifdef MODULE
+       if (znet_dev) {
+               struct znet_private *znet = znet_dev->priv;
++              unregister_netdev (znet_dev);
+               kfree (znet->rx_start);
+               kfree (znet->tx_start);
+-              unregister_netdev (znet_dev);
+               free_netdev (znet_dev);
+       }
+-#endif
+ }
+ module_init (znet_probe);
+--- linux-2.6.0/drivers/net/zorro8390.c        2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/net/zorro8390.c 2003-12-28 23:21:01.000000000 -0800
+@@ -103,18 +103,18 @@ static int __init zorro8390_probe(void)
+           continue;
+       board = z->resource.start;
+       ioaddr = board+cards[i].offset;
+-      dev = init_etherdev(0, 0);
+-      SET_MODULE_OWNER(dev);
++      dev = alloc_ei_netdev();
+       if (!dev)
+           return -ENOMEM;
++      SET_MODULE_OWNER(dev);
+       if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, dev->name)) {
+-          kfree(dev);
++          free_netdev(dev);
+           continue;
+       }
+       if ((err = zorro8390_init(dev, board, cards[i].name,
+                                 ZTWO_VADDR(ioaddr)))) {
+           release_mem_region(ioaddr, NE_IO_EXTENT*2);
+-          kfree(dev);
++          free_netdev(dev);
+           return err;
+       }
+       err = 0;
+@@ -129,6 +129,7 @@ static int __init zorro8390_init(struct 
+                                const char *name, unsigned long ioaddr)
+ {
+     int i;
++    int err;
+     unsigned char SA_prom[32];
+     int start_page, stop_page;
+     static u32 zorro8390_offsets[16] = {
+@@ -195,12 +196,6 @@ static int __init zorro8390_init(struct 
+     i = request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, dev->name, dev);
+     if (i) return i;
+-    /* Allocate dev->priv and fill in 8390 specific dev fields. */
+-    if (ethdev_init(dev)) {
+-      printk("Unable to get memory for dev->priv.\n");
+-      return -ENOMEM;
+-    }
+-
+     for(i = 0; i < ETHER_ADDR_LEN; i++) {
+ #ifdef DEBUG
+       printk(" %2.2x", SA_prom[i]);
+@@ -232,7 +227,10 @@ static int __init zorro8390_init(struct 
+     root_zorro8390_dev = dev;
+ #endif
+     NS8390_init(dev, 0);
+-    return 0;
++    err = register_netdev(dev);
++    if (err)
++      free_irq(IRQ_AMIGA_PORTS, dev);
++    return err;
+ }
+ static int zorro8390_open(struct net_device *dev)
+--- linux-2.6.0/drivers/parport/parport_cs.c   2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/parport/parport_cs.c    2003-12-28 23:22:54.000000000 -0800
+@@ -151,7 +151,7 @@ static dev_link_t *parport_attach(void)
+     client_reg.event_handler = &parport_event;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != CS_SUCCESS) {
+       cs_error(link->handle, RegisterClient, ret);
+       parport_detach(link);
+@@ -187,7 +187,7 @@ static void parport_detach(dev_link_t *l
+       parport_cs_release(link);
+     
+     if (link->handle) {
+-      ret = CardServices(DeregisterClient, link->handle);
++      ret = pcmcia_deregister_client(link->handle);
+       if (ret != CS_SUCCESS)
+           cs_error(link->handle, DeregisterClient, ret);
+     }
+@@ -206,11 +206,8 @@ static void parport_detach(dev_link_t *l
+ ======================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ void parport_config(dev_link_t *link)
+ {
+@@ -231,9 +228,9 @@ void parport_config(dev_link_t *link)
+     tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
+     tuple.Attributes = 0;
+     tuple.DesiredTuple = CISTPL_CONFIG;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     link->conf.Present = parse.config.rmask[0];
+     
+@@ -241,14 +238,15 @@ void parport_config(dev_link_t *link)
+     link->state |= DEV_CONFIG;
+     /* Not sure if this is right... look up the current Vcc */
+-    CS_CHECK(GetConfigurationInfo, handle, &conf);
++    CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
+     
+     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+     tuple.Attributes = 0;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     while (1) {
+-      CFG_CHECK(GetTupleData, handle, &tuple);
+-      CFG_CHECK(ParseTuple, handle, &tuple, &parse);
++      if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++              pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
++          goto next_entry;
+       if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+           cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+@@ -262,18 +260,19 @@ void parport_config(dev_link_t *link)
+               link->io.BasePort2 = io->win[1].base;
+               link->io.NumPorts2 = io->win[1].len;
+           }
+-          CFG_CHECK(RequestIO, link->handle, &link->io);
++          if (pcmcia_request_io(link->handle, &link->io) != 0)
++              goto next_entry;
+           /* If we've got this far, we're done */
+           break;
+       }
+       
+     next_entry:
+       if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
+-      CS_CHECK(GetNextTuple, handle, &tuple);
++      CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
+     }
+     
+-    CS_CHECK(RequestIRQ, handle, &link->irq);
+-    CS_CHECK(RequestConfiguration, handle, &link->conf);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
+     release_region(link->io.BasePort1, link->io.NumPorts1);
+     if (link->io.NumPorts2)
+@@ -335,9 +334,9 @@ void parport_cs_release(dev_link_t *link
+     info->ndev = 0;
+     link->dev = NULL;
+     
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     
+     link->state &= ~DEV_CONFIG;
+@@ -372,14 +371,14 @@ int parport_event(event_t event, int pri
+       /* Fall through... */
+     case CS_EVENT_RESET_PHYSICAL:
+       if (link->state & DEV_CONFIG)
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       break;
+     case CS_EVENT_PM_RESUME:
+       link->state &= ~DEV_SUSPEND;
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (DEV_OK(link))
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+       break;
+     }
+     return 0;
+--- linux-2.6.0/drivers/pci/Makefile   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/pci/Makefile    2003-12-28 23:21:44.000000000 -0800
+@@ -27,6 +27,7 @@ obj-$(CONFIG_PPC64) += setup-bus.o
+ obj-$(CONFIG_SGI_IP27) += setup-irq.o
+ obj-$(CONFIG_SGI_IP32) += setup-irq.o
+ obj-$(CONFIG_X86_VISWS) += setup-irq.o
++obj-$(CONFIG_PCI_USE_VECTOR) += msi.o
+ # Cardbus & CompactPCI use setup-bus
+ obj-$(CONFIG_HOTPLUG) += setup-bus.o
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/pci/msi.c       2003-12-28 23:21:44.000000000 -0800
+@@ -0,0 +1,1068 @@
++/*
++ * linux/drivers/pci/msi.c
++ */
++
++#include <linux/mm.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/init.h>
++#include <linux/config.h>
++#include <linux/ioport.h>
++#include <linux/smp_lock.h>
++#include <linux/pci.h>
++#include <linux/proc_fs.h>
++
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/smp.h>
++#include <asm/desc.h>
++#include <asm/io_apic.h>
++#include <mach_apic.h>
++
++#include <linux/pci_msi.h>
++
++_DEFINE_DBG_BUFFER
++
++static spinlock_t msi_lock = SPIN_LOCK_UNLOCKED;
++static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
++static kmem_cache_t* msi_cachep;
++
++static int pci_msi_enable = 1;
++static int nr_alloc_vectors = 0;
++static int nr_released_vectors = 0;
++static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
++static int nr_msix_devices = 0;
++
++#ifndef CONFIG_X86_IO_APIC
++int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1};
++u8 irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 };
++#endif
++
++static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags)
++{
++      memset(p, 0, NR_IRQS * sizeof(struct msi_desc));
++}
++
++static int msi_cache_init(void)
++{
++      msi_cachep = kmem_cache_create("msi_cache",
++                      NR_IRQS * sizeof(struct msi_desc),
++                      0, SLAB_HWCACHE_ALIGN, msi_cache_ctor, NULL);
++      if (!msi_cachep)
++              return -ENOMEM;
++
++      return 0;
++}
++
++static void msi_set_mask_bit(unsigned int vector, int flag)
++{
++      struct msi_desc *entry;
++
++      entry = (struct msi_desc *)msi_desc[vector];
++      if (!entry || !entry->dev || !entry->mask_base)
++              return;
++      switch (entry->msi_attrib.type) {
++      case PCI_CAP_ID_MSI:
++      {
++              int             pos;
++              unsigned int    mask_bits;
++
++              pos = entry->mask_base;
++              entry->dev->bus->ops->read(entry->dev->bus, entry->dev->devfn,
++                              pos, 4, &mask_bits);
++              mask_bits &= ~(1);
++              mask_bits |= flag;
++              entry->dev->bus->ops->write(entry->dev->bus, entry->dev->devfn,
++                              pos, 4, mask_bits);
++              break;
++      }
++      case PCI_CAP_ID_MSIX:
++      {
++              int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
++                      PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
++              writel(flag, entry->mask_base + offset);
++              break;
++      }
++      default:
++              break;
++      }
++}
++
++#ifdef CONFIG_SMP
++static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
++{
++      struct msi_desc *entry;
++      struct msg_address address;
++      unsigned int dest_id;
++
++      entry = (struct msi_desc *)msi_desc[vector];
++      if (!entry || !entry->dev)
++              return;
++
++      switch (entry->msi_attrib.type) {
++      case PCI_CAP_ID_MSI:
++      {
++              int pos;
++
++              if (!(pos = pci_find_capability(entry->dev, PCI_CAP_ID_MSI)))
++                      return;
++
++              entry->dev->bus->ops->read(entry->dev->bus, entry->dev->devfn,
++                      msi_lower_address_reg(pos), 4,
++                      &address.lo_address.value);
++              dest_id = (address.lo_address.u.dest_id &
++                      MSI_ADDRESS_HEADER_MASK) |
++                      (cpu_mask_to_apicid(cpu_mask) << MSI_TARGET_CPU_SHIFT);
++              address.lo_address.u.dest_id = dest_id;
++              entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
++              entry->dev->bus->ops->write(entry->dev->bus, entry->dev->devfn,
++                      msi_lower_address_reg(pos), 4,
++                      address.lo_address.value);
++              break;
++      }
++      case PCI_CAP_ID_MSIX:
++      {
++              int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
++                      PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET;
++
++              address.lo_address.value = readl(entry->mask_base + offset);
++              dest_id = (address.lo_address.u.dest_id &
++                      MSI_ADDRESS_HEADER_MASK) |
++                      (cpu_mask_to_apicid(cpu_mask) << MSI_TARGET_CPU_SHIFT);
++              address.lo_address.u.dest_id = dest_id;
++              entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask);
++              writel(address.lo_address.value, entry->mask_base + offset);
++              break;
++      }
++      default:
++              break;
++      }
++}
++
++static inline void move_msi(int vector)
++{
++      if (!cpus_empty(pending_irq_balance_cpumask[vector])) {
++              set_msi_affinity(vector, pending_irq_balance_cpumask[vector]);
++              cpus_clear(pending_irq_balance_cpumask[vector]);
++      }
++}
++#endif
++
++static void mask_MSI_irq(unsigned int vector)
++{
++      msi_set_mask_bit(vector, 1);
++}
++
++static void unmask_MSI_irq(unsigned int vector)
++{
++      msi_set_mask_bit(vector, 0);
++}
++
++static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector)
++{
++      return 0;       /* never anything pending */
++}
++
++static void pci_disable_msi(unsigned int vector);
++static void shutdown_msi_irq(unsigned int vector)
++{
++      pci_disable_msi(vector);
++}
++
++#define shutdown_msi_irq_wo_maskbit   shutdown_msi_irq
++static void enable_msi_irq_wo_maskbit(unsigned int vector) {}
++static void disable_msi_irq_wo_maskbit(unsigned int vector) {}
++static void ack_msi_irq_wo_maskbit(unsigned int vector) {}
++static void end_msi_irq_wo_maskbit(unsigned int vector)
++{
++      move_msi(vector);
++      ack_APIC_irq();
++}
++
++static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
++{
++      unmask_MSI_irq(vector);
++      return 0;       /* never anything pending */
++}
++
++#define shutdown_msi_irq_w_maskbit    shutdown_msi_irq
++#define enable_msi_irq_w_maskbit      unmask_MSI_irq
++#define disable_msi_irq_w_maskbit     mask_MSI_irq
++#define ack_msi_irq_w_maskbit         mask_MSI_irq
++
++static void end_msi_irq_w_maskbit(unsigned int vector)
++{
++      move_msi(vector);
++      unmask_MSI_irq(vector);
++      ack_APIC_irq();
++}
++
++/*
++ * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
++ * which implement the MSI-X Capability Structure.
++ */
++static struct hw_interrupt_type msix_irq_type = {
++      .typename       = "PCI MSI-X",
++      .startup        = startup_msi_irq_w_maskbit,
++      .shutdown       = shutdown_msi_irq_w_maskbit,
++      .enable         = enable_msi_irq_w_maskbit,
++      .disable        = disable_msi_irq_w_maskbit,
++      .ack            = ack_msi_irq_w_maskbit,
++      .end            = end_msi_irq_w_maskbit,
++      .set_affinity   = set_msi_irq_affinity
++};
++
++/*
++ * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
++ * which implement the MSI Capability Structure with
++ * Mask-and-Pending Bits.
++ */
++static struct hw_interrupt_type msi_irq_w_maskbit_type = {
++      .typename       = "PCI MSI",
++      .startup        = startup_msi_irq_w_maskbit,
++      .shutdown       = shutdown_msi_irq_w_maskbit,
++      .enable         = enable_msi_irq_w_maskbit,
++      .disable        = disable_msi_irq_w_maskbit,
++      .ack            = ack_msi_irq_w_maskbit,
++      .end            = end_msi_irq_w_maskbit,
++      .set_affinity   = set_msi_irq_affinity
++};
++
++/*
++ * Interrupt Type for MSI PCI/PCI-X/PCI-Express Devices,
++ * which implement the MSI Capability Structure without
++ * Mask-and-Pending Bits.
++ */
++static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
++      .typename       = "PCI MSI",
++      .startup        = startup_msi_irq_wo_maskbit,
++      .shutdown       = shutdown_msi_irq_wo_maskbit,
++      .enable         = enable_msi_irq_wo_maskbit,
++      .disable        = disable_msi_irq_wo_maskbit,
++      .ack            = ack_msi_irq_wo_maskbit,
++      .end            = end_msi_irq_wo_maskbit,
++      .set_affinity   = set_msi_irq_affinity
++};
++
++static void msi_data_init(struct msg_data *msi_data,
++                        unsigned int vector)
++{
++      memset(msi_data, 0, sizeof(struct msg_data));
++      msi_data->vector = (u8)vector;
++      msi_data->delivery_mode = MSI_DELIVERY_MODE;
++      msi_data->level = MSI_LEVEL_MODE;
++      msi_data->trigger = MSI_TRIGGER_MODE;
++}
++
++static void msi_address_init(struct msg_address *msi_address)
++{
++      unsigned int    dest_id;
++
++      memset(msi_address, 0, sizeof(struct msg_address));
++      msi_address->hi_address = (u32)0;
++      dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT) |
++               (MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT);
++      msi_address->lo_address.u.dest_mode = MSI_LOGICAL_MODE;
++      msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE;
++      msi_address->lo_address.u.dest_id = dest_id;
++}
++
++static int pci_vector_resources(void)
++{
++      static int res = -EINVAL;
++      int nr_free_vectors;
++
++      if (res == -EINVAL) {
++              int i, repeat;
++              for (i = NR_REPEATS; i > 0; i--) {
++                      if ((FIRST_DEVICE_VECTOR + i * 8) > FIRST_SYSTEM_VECTOR)
++                              continue;
++                      break;
++              }
++              i++;
++              repeat = (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)/i;
++              res = i * repeat - NR_RESERVED_VECTORS + 1;
++      }
++
++      nr_free_vectors = res + nr_released_vectors - nr_alloc_vectors;
++
++      return nr_free_vectors;
++}
++
++int assign_irq_vector(int irq)
++{
++      static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
++
++      if (irq != MSI_AUTO && IO_APIC_VECTOR(irq) > 0)
++              return IO_APIC_VECTOR(irq);
++next:
++      current_vector += 8;
++      if (current_vector == SYSCALL_VECTOR)
++              goto next;
++
++      if (current_vector > FIRST_SYSTEM_VECTOR) {
++              offset++;
++              current_vector = FIRST_DEVICE_VECTOR + offset;
++      }
++
++      if (current_vector == FIRST_SYSTEM_VECTOR)
++              return -ENOSPC;
++
++      vector_irq[current_vector] = irq;
++      if (irq != MSI_AUTO)
++              IO_APIC_VECTOR(irq) = current_vector;
++
++      nr_alloc_vectors++;
++
++      return current_vector;
++}
++
++static int assign_msi_vector(void)
++{
++      static int new_vector_avail = 1;
++      int vector;
++      unsigned long flags;
++
++      /*
++       * msi_lock is provided to ensure that successful allocation of MSI
++       * vector is assigned unique among drivers.
++       */
++      spin_lock_irqsave(&msi_lock, flags);
++      if (!(pci_vector_resources() > 0)) {
++              spin_unlock_irqrestore(&msi_lock, flags);
++              return -EBUSY;
++      }
++
++      if (!new_vector_avail) {
++              /*
++               * vector_irq[] = -1 indicates that this specific vector is:
++               * - assigned for MSI (since MSI have no associated IRQ) or
++               * - assigned for legacy if less than 16, or
++               * - having no corresponding 1:1 vector-to-IOxAPIC IRQ mapping
++               * vector_irq[] = 0 indicates that this vector, previously
++               * assigned for MSI, is freed by hotplug removed operations.
++               * This vector will be reused for any subsequent hotplug added
++               * operations.
++               * vector_irq[] > 0 indicates that this vector is assigned for
++               * IOxAPIC IRQs. This vector and its value provides a 1-to-1
++               * vector-to-IOxAPIC IRQ mapping.
++               */
++              for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
++                      if (vector_irq[vector] != 0)
++                              continue;
++                      vector_irq[vector] = -1;
++                      nr_released_vectors--;
++                      spin_unlock_irqrestore(&msi_lock, flags);
++                      return vector;
++              }
++              spin_unlock_irqrestore(&msi_lock, flags);
++              return -EBUSY;
++      }
++
++      vector = assign_irq_vector(MSI_AUTO);
++      if (vector  == (FIRST_SYSTEM_VECTOR - 8))
++              new_vector_avail = 0;
++
++      spin_unlock_irqrestore(&msi_lock, flags);
++      return vector;
++}
++
++static int get_new_vector(void)
++{
++      int vector;
++
++      if ((vector = assign_msi_vector()) > 0)
++              set_intr_gate(vector, interrupt[vector]);
++
++      return vector;
++}
++
++static int msi_init(void)
++{
++      static int status = -ENOMEM;
++
++      if (!status)
++              return status;
++
++      if ((status = msi_cache_init()) < 0) {
++              pci_msi_enable = 0;
++              printk(KERN_INFO "WARNING: MSI INIT FAILURE\n");
++              return status;
++      }
++      printk(KERN_INFO "MSI INIT SUCCESS\n");
++
++      return status;
++}
++
++static int get_msi_vector(struct pci_dev *dev)
++{
++      return get_new_vector();
++}
++
++static struct msi_desc* alloc_msi_entry(void)
++{
++      struct msi_desc *entry;
++
++      entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
++      if (!entry)
++              return NULL;
++
++      memset(entry, 0, sizeof(struct msi_desc));
++      entry->link.tail = entry->link.head = 0;        /* single message */
++      entry->dev = NULL;
++
++      return entry;
++}
++
++static void attach_msi_entry(struct msi_desc *entry, int vector)
++{
++      unsigned long flags;
++
++      spin_lock_irqsave(&msi_lock, flags);
++      msi_desc[vector] = entry;
++      spin_unlock_irqrestore(&msi_lock, flags);
++}
++
++static void irq_handler_init(int cap_id, int pos, int mask)
++{
++      spin_lock(&irq_desc[pos].lock);
++      if (cap_id == PCI_CAP_ID_MSIX)
++              irq_desc[pos].handler = &msix_irq_type;
++      else {
++              if (!mask)
++                      irq_desc[pos].handler = &msi_irq_wo_maskbit_type;
++              else
++                      irq_desc[pos].handler = &msi_irq_w_maskbit_type;
++      }
++      spin_unlock(&irq_desc[pos].lock);
++}
++
++static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
++{
++      u32 control;
++
++      dev->bus->ops->read(dev->bus, dev->devfn,
++              msi_control_reg(pos), 2, &control);
++      if (type == PCI_CAP_ID_MSI) {
++              /* Set enabled bits to single MSI & enable MSI_enable bit */
++              msi_enable(control, 1);
++              dev->bus->ops->write(dev->bus, dev->devfn,
++                      msi_control_reg(pos), 2, control);
++      } else {
++              msix_enable(control);
++              dev->bus->ops->write(dev->bus, dev->devfn,
++                      msi_control_reg(pos), 2, control);
++      }
++      if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
++              /* PCI Express Endpoint device detected */
++              u32 cmd;
++              dev->bus->ops->read(dev->bus, dev->devfn, PCI_COMMAND, 2, &cmd);
++              cmd |= PCI_COMMAND_INTX_DISABLE;
++              dev->bus->ops->write(dev->bus, dev->devfn, PCI_COMMAND, 2, cmd);
++      }
++}
++
++static void disable_msi_mode(struct pci_dev *dev, int pos, int type)
++{
++      u32 control;
++
++      dev->bus->ops->read(dev->bus, dev->devfn,
++              msi_control_reg(pos), 2, &control);
++      if (type == PCI_CAP_ID_MSI) {
++              /* Set enabled bits to single MSI & enable MSI_enable bit */
++              msi_disable(control);
++              dev->bus->ops->write(dev->bus, dev->devfn,
++                      msi_control_reg(pos), 2, control);
++      } else {
++              msix_disable(control);
++              dev->bus->ops->write(dev->bus, dev->devfn,
++                      msi_control_reg(pos), 2, control);
++      }
++      if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
++              /* PCI Express Endpoint device detected */
++              u32 cmd;
++              dev->bus->ops->read(dev->bus, dev->devfn, PCI_COMMAND, 2, &cmd);
++              cmd &= ~PCI_COMMAND_INTX_DISABLE;
++              dev->bus->ops->write(dev->bus, dev->devfn, PCI_COMMAND, 2, cmd);
++      }
++}
++
++static int msi_lookup_vector(struct pci_dev *dev)
++{
++      int vector;
++      unsigned long flags;
++
++      spin_lock_irqsave(&msi_lock, flags);
++      for (vector = FIRST_DEVICE_VECTOR; vector < NR_IRQS; vector++) {
++              if (!msi_desc[vector] || msi_desc[vector]->dev != dev ||
++                      msi_desc[vector]->msi_attrib.entry_nr ||
++                      msi_desc[vector]->msi_attrib.default_vector != dev->irq)
++                      continue;       /* not entry 0, skip */
++              spin_unlock_irqrestore(&msi_lock, flags);
++              /* This pre-assigned entry-0 MSI vector for this device
++                 already exits. Override dev->irq with this vector */
++              dev->irq = vector;
++              return 0;
++      }
++      spin_unlock_irqrestore(&msi_lock, flags);
++
++      return -EACCES;
++}
++
++void pci_scan_msi_device(struct pci_dev *dev)
++{
++      if (!dev)
++              return;
++
++      if (pci_find_capability(dev, PCI_CAP_ID_MSIX) > 0) {
++              nr_reserved_vectors++;
++              nr_msix_devices++;
++      } else if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0)
++              nr_reserved_vectors++;
++}
++
++/**
++ * msi_capability_init - configure device's MSI capability structure
++ * @dev: pointer to the pci_dev data structure of MSI device function
++ *
++ * Setup the MSI capability structure of device funtion with a single
++ * MSI vector, regardless of device function is capable of handling
++ * multiple messages. A return of zero indicates the successful setup
++ * of an entry zero with the new MSI vector or non-zero for otherwise.
++ **/
++static int msi_capability_init(struct pci_dev *dev)
++{
++      struct msi_desc *entry;
++      struct msg_address address;
++      struct msg_data data;
++      int pos, vector;
++      u32 control;
++
++      pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
++      if (!pos)
++              return -EINVAL;
++
++      dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos),
++              2, &control);
++      if (control & PCI_MSI_FLAGS_ENABLE)
++              return 0;
++
++      if (!msi_lookup_vector(dev)) {
++              /* Lookup Sucess */
++              enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
++              return 0;
++      }
++      /* MSI Entry Initialization */
++      if (!(entry = alloc_msi_entry()))
++              return -ENOMEM;
++
++      if ((vector = get_msi_vector(dev)) < 0) {
++              kmem_cache_free(msi_cachep, entry);
++              return -EBUSY;
++      }
++      entry->msi_attrib.type = PCI_CAP_ID_MSI;
++      entry->msi_attrib.entry_nr = 0;
++      entry->msi_attrib.maskbit = is_mask_bit_support(control);
++      entry->msi_attrib.default_vector = dev->irq;
++      dev->irq = vector;      /* save default pre-assigned ioapic vector */
++      entry->dev = dev;
++      if (is_mask_bit_support(control)) {
++              entry->mask_base = msi_mask_bits_reg(pos,
++                              is_64bit_address(control));
++      }
++      /* Replace with MSI handler */
++      irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit);
++      /* Configure MSI capability structure */
++      msi_address_init(&address);
++      msi_data_init(&data, vector);
++      entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >>
++                              MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
++      dev->bus->ops->write(dev->bus, dev->devfn, msi_lower_address_reg(pos),
++                              4, address.lo_address.value);
++      if (is_64bit_address(control)) {
++              dev->bus->ops->write(dev->bus, dev->devfn,
++                      msi_upper_address_reg(pos), 4, address.hi_address);
++              dev->bus->ops->write(dev->bus, dev->devfn,
++                      msi_data_reg(pos, 1), 2, *((u32*)&data));
++      } else
++              dev->bus->ops->write(dev->bus, dev->devfn,
++                      msi_data_reg(pos, 0), 2, *((u32*)&data));
++      if (entry->msi_attrib.maskbit) {
++              unsigned int maskbits, temp;
++              /* All MSIs are unmasked by default, Mask them all */
++              dev->bus->ops->read(dev->bus, dev->devfn,
++                      msi_mask_bits_reg(pos, is_64bit_address(control)), 4,
++                      &maskbits);
++              temp = (1 << multi_msi_capable(control));
++              temp = ((temp - 1) & ~temp);
++              maskbits |= temp;
++              dev->bus->ops->write(dev->bus, dev->devfn,
++                      msi_mask_bits_reg(pos, is_64bit_address(control)), 4,
++                      maskbits);
++      }
++      attach_msi_entry(entry, vector);
++      /* Set MSI enabled bits  */
++      enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
++
++      return 0;
++}
++
++/**
++ * msix_capability_init - configure device's MSI-X capability
++ * @dev: pointer to the pci_dev data structure of MSI-X device function
++ *
++ * Setup the MSI-X capability structure of device funtion with a
++ * single MSI-X vector. A return of zero indicates the successful setup
++ * of an entry zero with the new MSI-X vector or non-zero for otherwise.
++ * To request for additional MSI-X vectors, the device drivers are
++ * required to utilize the following supported APIs:
++ * 1) msi_alloc_vectors(...) for requesting one or more MSI-X vectors
++ * 2) msi_free_vectors(...) for releasing one or more MSI-X vectors
++ *    back to PCI subsystem before calling free_irq(...)
++ **/
++static int msix_capability_init(struct pci_dev        *dev)
++{
++      struct msi_desc *entry;
++      struct msg_address address;
++      struct msg_data data;
++      int vector = 0, pos, dev_msi_cap;
++      u32 phys_addr, table_offset;
++      u32 control;
++      u8 bir;
++      void *base;
++
++      pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
++      if (!pos)
++              return -EINVAL;
++
++      /* Request & Map MSI-X table region */
++      dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos), 2,
++              &control);
++      if (control & PCI_MSIX_FLAGS_ENABLE)
++              return 0;
++
++      if (!msi_lookup_vector(dev)) {
++              /* Lookup Sucess */
++              enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
++              return 0;
++      }
++
++      dev_msi_cap = multi_msix_capable(control);
++      dev->bus->ops->read(dev->bus, dev->devfn,
++              msix_table_offset_reg(pos), 4, &table_offset);
++      bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
++      phys_addr = pci_resource_start (dev, bir);
++      phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK);
++      if (!request_mem_region(phys_addr,
++              dev_msi_cap * PCI_MSIX_ENTRY_SIZE,
++              "MSI-X iomap Failure"))
++              return -ENOMEM;
++      base = ioremap_nocache(phys_addr, dev_msi_cap * PCI_MSIX_ENTRY_SIZE);
++      if (base == NULL)
++              goto free_region;
++      /* MSI Entry Initialization */
++      entry = alloc_msi_entry();
++      if (!entry)
++              goto free_iomap;
++      if ((vector = get_msi_vector(dev)) < 0)
++              goto free_entry;
++
++      entry->msi_attrib.type = PCI_CAP_ID_MSIX;
++      entry->msi_attrib.entry_nr = 0;
++      entry->msi_attrib.maskbit = 1;
++      entry->msi_attrib.default_vector = dev->irq;
++      dev->irq = vector;      /* save default pre-assigned ioapic vector */
++      entry->dev = dev;
++      entry->mask_base = (unsigned long)base;
++      /* Replace with MSI handler */
++      irq_handler_init(PCI_CAP_ID_MSIX, vector, 1);
++      /* Configure MSI-X capability structure */
++      msi_address_init(&address);
++      msi_data_init(&data, vector);
++      entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >>
++                              MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
++      writel(address.lo_address.value, base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
++      writel(address.hi_address, base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
++      writel(*(u32*)&data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
++      /* Initialize all entries from 1 up to 0 */
++      for (pos = 1; pos < dev_msi_cap; pos++) {
++              writel(0, base + pos * PCI_MSIX_ENTRY_SIZE +
++                      PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
++              writel(0, base + pos * PCI_MSIX_ENTRY_SIZE +
++                      PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
++              writel(0, base + pos * PCI_MSIX_ENTRY_SIZE +
++                      PCI_MSIX_ENTRY_DATA_OFFSET);
++      }
++      attach_msi_entry(entry, vector);
++      /* Set MSI enabled bits  */
++      enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
++
++      return 0;
++
++free_entry:
++      kmem_cache_free(msi_cachep, entry);
++free_iomap:
++      iounmap(base);
++free_region:
++      release_mem_region(phys_addr, dev_msi_cap * PCI_MSIX_ENTRY_SIZE);
++
++      return ((vector < 0) ? -EBUSY : -ENOMEM);
++}
++
++/**
++ * pci_enable_msi - configure device's MSI(X) capability structure
++ * @dev: pointer to the pci_dev data structure of MSI(X) device function
++ *
++ * Setup the MSI/MSI-X capability structure of device function with
++ * a single MSI(X) vector upon its software driver call to request for
++ * MSI(X) mode enabled on its hardware device function. A return of zero
++ * indicates the successful setup of an entry zero with the new MSI(X)
++ * vector or non-zero for otherwise.
++ **/
++int pci_enable_msi(struct pci_dev* dev)
++{
++      int status = -EINVAL;
++
++      if (!pci_msi_enable || !dev)
++              return status;
++
++      if (msi_init() < 0)
++              return -ENOMEM;
++
++      if ((status = msix_capability_init(dev)) == -EINVAL)
++              status = msi_capability_init(dev);
++      if (!status)
++              nr_reserved_vectors--;
++
++      return status;
++}
++
++static int msi_free_vector(struct pci_dev* dev, int vector);
++static void pci_disable_msi(unsigned int vector)
++{
++      int head, tail, type, default_vector;
++      struct msi_desc *entry;
++      struct pci_dev *dev;
++      unsigned long flags;
++
++      spin_lock_irqsave(&msi_lock, flags);
++      entry = msi_desc[vector];
++      if (!entry || !entry->dev) {
++              spin_unlock_irqrestore(&msi_lock, flags);
++              return;
++      }
++      dev = entry->dev;
++      type = entry->msi_attrib.type;
++      head = entry->link.head;
++      tail = entry->link.tail;
++      default_vector = entry->msi_attrib.default_vector;
++      spin_unlock_irqrestore(&msi_lock, flags);
++
++      disable_msi_mode(dev, pci_find_capability(dev, type), type);
++      /* Restore dev->irq to its default pin-assertion vector */
++      dev->irq = default_vector;
++      if (type == PCI_CAP_ID_MSIX && head != tail) {
++              /* Bad driver, which do not call msi_free_vectors before exit.
++                 We must do a cleanup here */
++              while (1) {
++                      spin_lock_irqsave(&msi_lock, flags);
++                      entry = msi_desc[vector];
++                      head = entry->link.head;
++                      tail = entry->link.tail;
++                      spin_unlock_irqrestore(&msi_lock, flags);
++                      if (tail == head)
++                              break;
++                      if (msi_free_vector(dev, entry->link.tail))
++                              break;
++              }
++      }
++}
++
++static int msi_alloc_vector(struct pci_dev* dev, int head)
++{
++      struct msi_desc *entry;
++      struct msg_address address;
++      struct msg_data data;
++      int i, offset, pos, dev_msi_cap, vector;
++      u32 low_address, control;
++      unsigned long base = 0L;
++      unsigned long flags;
++
++      spin_lock_irqsave(&msi_lock, flags);
++      entry = msi_desc[dev->irq];
++      if (!entry) {
++              spin_unlock_irqrestore(&msi_lock, flags);
++              return -EINVAL;
++      }
++      base = entry->mask_base;
++      spin_unlock_irqrestore(&msi_lock, flags);
++
++      pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
++      dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos),
++              2, &control);
++      dev_msi_cap = multi_msix_capable(control);
++      for (i = 1; i < dev_msi_cap; i++) {
++              if (!(low_address = readl(base + i * PCI_MSIX_ENTRY_SIZE)))
++                       break;
++      }
++      if (i >= dev_msi_cap)
++              return -EINVAL;
++
++      /* MSI Entry Initialization */
++      if (!(entry = alloc_msi_entry()))
++              return -ENOMEM;
++
++      if ((vector = get_new_vector()) < 0) {
++              kmem_cache_free(msi_cachep, entry);
++              return vector;
++      }
++      entry->msi_attrib.type = PCI_CAP_ID_MSIX;
++      entry->msi_attrib.entry_nr = i;
++      entry->msi_attrib.maskbit = 1;
++      entry->dev = dev;
++      entry->link.head = head;
++      entry->mask_base = base;
++      irq_handler_init(PCI_CAP_ID_MSIX, vector, 1);
++      /* Configure MSI-X capability structure */
++      msi_address_init(&address);
++      msi_data_init(&data, vector);
++      entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >>
++                              MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK);
++      offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
++      writel(address.lo_address.value, base + offset +
++              PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
++      writel(address.hi_address, base + offset +
++              PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
++      writel(*(u32*)&data, base + offset + PCI_MSIX_ENTRY_DATA_OFFSET);
++      writel(1, base + offset + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
++      attach_msi_entry(entry, vector);
++
++      return vector;
++}
++
++static int msi_free_vector(struct pci_dev* dev, int vector)
++{
++      struct msi_desc *entry;
++      int entry_nr, type;
++      unsigned long base = 0L;
++      unsigned long flags;
++
++      spin_lock_irqsave(&msi_lock, flags);
++      entry = msi_desc[vector];
++      if (!entry || entry->dev != dev) {
++              spin_unlock_irqrestore(&msi_lock, flags);
++              return -EINVAL;
++      }
++      type = entry->msi_attrib.type;
++      entry_nr = entry->msi_attrib.entry_nr;
++      base = entry->mask_base;
++      if (entry->link.tail != entry->link.head) {
++              msi_desc[entry->link.head]->link.tail = entry->link.tail;
++              if (entry->link.tail)
++                      msi_desc[entry->link.tail]->link.head = entry->link.head;
++      }
++      entry->dev = NULL;
++      vector_irq[vector] = 0;
++      nr_released_vectors++;
++      msi_desc[vector] = NULL;
++      spin_unlock_irqrestore(&msi_lock, flags);
++
++      kmem_cache_free(msi_cachep, entry);
++      if (type == PCI_CAP_ID_MSIX) {
++              int offset;
++
++              offset = entry_nr * PCI_MSIX_ENTRY_SIZE;
++              writel(1, base + offset + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
++              writel(0, base + offset + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
++      }
++
++      return 0;
++}
++
++/**
++ * msi_alloc_vectors - allocate additional MSI-X vectors
++ * @dev: pointer to the pci_dev data structure of MSI-X device function
++ * @vector: pointer to an array of new allocated MSI-X vectors
++ * @nvec: number of MSI-X vectors requested for allocation by device driver
++ *
++ * Allocate additional MSI-X vectors requested by device driver. A
++ * return of zero indicates the successful setup of MSI-X capability
++ * structure with new allocated MSI-X vectors or non-zero for otherwise.
++ **/
++int msi_alloc_vectors(struct pci_dev* dev, int *vector, int nvec)
++{
++      struct msi_desc *entry;
++      int i, head, pos, vec, free_vectors, alloc_vectors;
++      int *vectors = (int *)vector;
++      u32 control;
++      unsigned long flags;
++
++      if (!pci_msi_enable || !dev)
++              return -EINVAL;
++
++      if (!(pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)))
++              return -EINVAL;
++
++      dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos),                         2, &control);
++      if (nvec > multi_msix_capable(control))
++              return -EINVAL;
++
++      spin_lock_irqsave(&msi_lock, flags);
++      entry = msi_desc[dev->irq];
++      if (!entry || entry->dev != dev ||              /* legal call */
++         entry->msi_attrib.type != PCI_CAP_ID_MSIX || /* must be MSI-X */
++         entry->link.head != entry->link.tail) {      /* already multi */
++              spin_unlock_irqrestore(&msi_lock, flags);
++              return -EINVAL;
++      }
++      /*
++       * msi_lock is provided to ensure that enough vectors resources are
++       * available before granting.
++       */
++      free_vectors = pci_vector_resources();
++      /* Ensure that each MSI/MSI-X device has one vector reserved by
++         default to avoid any MSI-X driver to take all available
++         resources */
++      free_vectors -= nr_reserved_vectors;
++      /* Find the average of free vectors among MSI-X devices */
++      if (nr_msix_devices > 0)
++              free_vectors /= nr_msix_devices;
++      spin_unlock_irqrestore(&msi_lock, flags);
++
++      if (nvec > free_vectors)
++              return -EBUSY;
++
++      alloc_vectors = 0;
++      head = dev->irq;
++      for (i = 0; i < nvec; i++) {
++              if ((vec = msi_alloc_vector(dev, head)) < 0)
++                      break;
++              *(vectors + i) = vec;
++              head = vec;
++              alloc_vectors++;
++      }
++      if (alloc_vectors != nvec) {
++              for (i = 0; i < alloc_vectors; i++) {
++                      vec = *(vectors + i);
++                      msi_free_vector(dev, vec);
++              }
++              spin_lock_irqsave(&msi_lock, flags);
++              msi_desc[dev->irq]->link.tail = msi_desc[dev->irq]->link.head;
++              spin_unlock_irqrestore(&msi_lock, flags);
++              return -EBUSY;
++      }
++      if (nr_msix_devices > 0)
++              nr_msix_devices--;
++
++      return 0;
++}
++
++/**
++ * msi_free_vectors - reclaim MSI-X vectors to unused state
++ * @dev: pointer to the pci_dev data structure of MSI-X device function
++ * @vector: pointer to an array of released MSI-X vectors
++ * @nvec: number of MSI-X vectors requested for release by device driver
++ *
++ * Reclaim MSI-X vectors released by device driver to unused state,
++ * which may be used later on. A return of zero indicates the
++ * success or non-zero for otherwise. Device driver should call this
++ * before calling function free_irq.
++ **/
++int msi_free_vectors(struct pci_dev* dev, int *vector, int nvec)
++{
++      struct msi_desc *entry;
++      int i;
++      unsigned long flags;
++
++      if (!pci_msi_enable)
++              return -EINVAL;
++
++      spin_lock_irqsave(&msi_lock, flags);
++      entry = msi_desc[dev->irq];
++      if (!entry || entry->dev != dev ||
++              entry->msi_attrib.type != PCI_CAP_ID_MSIX ||
++              entry->link.head == entry->link.tail) { /* Nothing to free */
++              spin_unlock_irqrestore(&msi_lock, flags);
++              return -EINVAL;
++      }
++      spin_unlock_irqrestore(&msi_lock, flags);
++
++      for (i = 0; i < nvec; i++) {
++              if (*(vector + i) == dev->irq)
++                      continue;/* Don't free entry 0 if mistaken by driver */
++              msi_free_vector(dev, *(vector + i));
++      }
++
++      return 0;
++}
++
++/**
++ * msi_remove_pci_irq_vectors - reclaim MSI(X) vectors to unused state
++ * @dev: pointer to the pci_dev data structure of MSI(X) device function
++ *
++ * Being called during hotplug remove, from which the device funciton
++ * is hot-removed. All previous assigned MSI/MSI-X vectors, if
++ * allocated for this device function, are reclaimed to unused state,
++ * which may be used later on.
++ **/
++void msi_remove_pci_irq_vectors(struct pci_dev* dev)
++{
++      struct msi_desc *entry;
++      int type, temp;
++      unsigned long flags;
++
++      if (!pci_msi_enable || !dev)
++              return;
++
++      if (!pci_find_capability(dev, PCI_CAP_ID_MSI)) {
++              if (!pci_find_capability(dev, PCI_CAP_ID_MSIX))
++                      return;
++      }
++      temp = dev->irq;
++      if (msi_lookup_vector(dev))
++              return;
++
++      spin_lock_irqsave(&msi_lock, flags);
++      entry = msi_desc[dev->irq];
++      if (!entry || entry->dev != dev) {
++              spin_unlock_irqrestore(&msi_lock, flags);
++              return;
++      }
++      type = entry->msi_attrib.type;
++      spin_unlock_irqrestore(&msi_lock, flags);
++
++      msi_free_vector(dev, dev->irq);
++      if (type == PCI_CAP_ID_MSIX) {
++              int i, pos, dev_msi_cap;
++              u32 phys_addr, table_offset;
++              u32 control;
++              u8 bir;
++
++              pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
++              dev->bus->ops->read(dev->bus, dev->devfn, msi_control_reg(pos),                         2, &control);
++              dev_msi_cap = multi_msix_capable(control);
++              dev->bus->ops->read(dev->bus, dev->devfn,
++                      msix_table_offset_reg(pos), 4, &table_offset);
++              bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
++              phys_addr = pci_resource_start (dev, bir);
++              phys_addr += (u32)(table_offset & ~PCI_MSIX_FLAGS_BIRMASK);
++              for (i = FIRST_DEVICE_VECTOR; i < NR_IRQS; i++) {
++                      spin_lock_irqsave(&msi_lock, flags);
++                      if (!msi_desc[i] || msi_desc[i]->dev != dev) {
++                              spin_unlock_irqrestore(&msi_lock, flags);
++                              continue;
++                      }
++                      spin_unlock_irqrestore(&msi_lock, flags);
++                      msi_free_vector(dev, i);
++              }
++              writel(1, entry->mask_base + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
++              iounmap((void*)entry->mask_base);
++              release_mem_region(phys_addr, dev_msi_cap * PCI_MSIX_ENTRY_SIZE);
++      }
++      dev->irq = temp;
++      nr_reserved_vectors++;
++}
++
++EXPORT_SYMBOL(pci_enable_msi);
++EXPORT_SYMBOL(msi_alloc_vectors);
++EXPORT_SYMBOL(msi_free_vectors);
+--- linux-2.6.0/drivers/pci/pci.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/pci/pci.c       2003-12-28 23:21:47.000000000 -0800
+@@ -223,6 +223,8 @@ pci_set_power_state(struct pci_dev *dev,
+       int pm;
+       u16 pmcsr;
++      might_sleep();
++
+       /* bound the state we're entering */
+       if (state > 3) state = 3;
+--- linux-2.6.0/drivers/pci/pci.ids    2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/pci/pci.ids     2003-12-28 23:21:01.000000000 -0800
+@@ -3247,8 +3247,6 @@
+               1148 5061  SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+               1148 5071  SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
+               1148 9521  SK-9521 10/100/1000Base-T Adapter
+-      4400 SK-9Dxx Gigabit Ethernet Adapter
+-      4500 SK-9Mxx Gigabit Ethernet Adapter
+ 1149  Win System Corporation
+ 114a  VMIC
+       5579  VMIPCI-5579 (Reflective Memory Card)
+@@ -3540,7 +3538,22 @@
+ 11ab  Galileo Technology Ltd.
+       0146  GT-64010/64010A System Controller
+       4320  Gigabit Ethernet Adapter
+-              11ab 9521  Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter
++              1019 0f38  Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
++              1019 8001  Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
++              1043 173c  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
++              1043 811a  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
++              105b 0c19  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
++              10b8 b452  SMC EZ Card 1000 (SMC9452TXV.2)
++              11ab 0121  Marvell RDK-8001 Adapter
++              11ab 0321  Marvell RDK-8003 Adapter
++              11ab 1021  Marvell RDK-8010 Adapter
++              11ab 5021  Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
++              11ab 9521  Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
++              1458 e000  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
++              147b 1406  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
++              15d4 0047  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
++              1695 9025  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
++              17f2 1c03  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
+       4611  GT-64115 System Controller
+       4620  GT-64120/64120A/64121A System Controller
+       4801  GT-48001
+@@ -3803,8 +3816,6 @@
+       0802  Rocketport UPCI 8 port w/external I/F
+       0803  Rocketport UPCI 16 port w/external I/F
+       0805  Rocketport UPCI 8 port w/octa cable
+-      080C  RocketModem III 8 port
+-      080D  RocketModem III 4 port
+       0903  Rocketport Compact PCI 16 port w/external I/F
+ 11ff  Scion Corporation
+ 1200  CSS Corporation
+@@ -5312,11 +5323,13 @@
+               10b7 2000  3C998-T Dual Port 10/100/1000 PCI-X
+               10b7 3000  3C999-T Quad Port 10/100/1000 PCI-X
+               1166 1648  NetXtreme CIOB-E 1000Base-T
++      1649  NetXtreme BCM5704S Gigabit Ethernet
+       164d  NetXtreme BCM5702FE Gigabit Ethernet
+       1653  NetXtreme BCM5705 Gigabit Ethernet
+       1654  NetXtreme BCM5705 Gigabit Ethernet
+       165d  NetXtreme BCM5705M Gigabit Ethernet
+       165e  NetXtreme BCM5705M Gigabit Ethernet
++      166e  NetXtreme BCM5705F Gigabit Ethernet
+       1696  NetXtreme BCM5782 Gigabit Ethernet
+               14e4 000d  NetXtreme BCM5782 1000Base-T
+       169c  NetXtreme BCM5788 Gigabit Ethernet
+--- linux-2.6.0/drivers/pci/probe.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/pci/probe.c     2003-12-28 23:21:44.000000000 -0800
+@@ -176,7 +176,7 @@ void __devinit pci_read_bridge_bases(str
+               limit |= (io_limit_hi << 16);
+       }
+-      if (base && base <= limit) {
++      if (base <= limit) {
+               res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
+               res->start = base;
+               res->end = limit + 0xfff;
+@@ -187,7 +187,7 @@ void __devinit pci_read_bridge_bases(str
+       pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
+       base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
+       limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
+-      if (base && base <= limit) {
++      if (base <= limit) {
+               res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
+               res->start = base;
+               res->end = limit + 0xfffff;
+@@ -213,7 +213,7 @@ void __devinit pci_read_bridge_bases(str
+               }
+ #endif
+       }
+-      if (base && base <= limit) {
++      if (base <= limit) {
+               res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
+               res->start = base;
+               res->end = limit + 0xfffff;
+@@ -552,6 +552,7 @@ int __devinit pci_scan_slot(struct pci_b
+               struct pci_dev *dev;
+               dev = pci_scan_device(bus, devfn);
++              pci_scan_msi_device(dev);
+               if (func == 0) {
+                       if (!dev)
+                               break;
+--- linux-2.6.0/drivers/pci/proc.c     2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/pci/proc.c      2003-12-28 23:22:13.000000000 -0800
+@@ -25,7 +25,7 @@ proc_bus_pci_lseek(struct file *file, lo
+ {
+       loff_t new = -1;
+-      lock_kernel();
++      down(&file->f_dentry->d_inode->i_sem);
+       switch (whence) {
+       case 0:
+               new = off;
+@@ -37,10 +37,12 @@ proc_bus_pci_lseek(struct file *file, lo
+               new = PCI_CFG_SPACE_SIZE + off;
+               break;
+       }
+-      unlock_kernel();
+       if (new < 0 || new > PCI_CFG_SPACE_SIZE)
+-              return -EINVAL;
+-      return (file->f_pos = new);
++              new = -EINVAL;
++      else
++              file->f_pos = new;
++      up(&file->f_dentry->d_inode->i_sem);
++      return new;
+ }
+ static ssize_t
+--- linux-2.6.0/drivers/pci/remove.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/pci/remove.c    2003-12-28 23:21:44.000000000 -0800
+@@ -14,6 +14,8 @@ static void pci_free_resources(struct pc
+ {
+       int i;
++      msi_remove_pci_irq_vectors(dev);
++
+       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+               struct resource *res = dev->resource + i;
+               if (res->parent)
+--- linux-2.6.0/drivers/pci/setup-res.c        2003-11-23 19:03:00.000000000 -0800
++++ 25/drivers/pci/setup-res.c 2003-12-28 23:23:02.000000000 -0800
+@@ -84,6 +84,10 @@ pci_update_resource(struct pci_dev *dev,
+                              pci_name(dev), resno, new, check);
+               }
+       }
++      res->flags &= ~IORESOURCE_UNSET;
++      DBGC((KERN_INFO "PCI: moved device %s resource %d (%lx) to %x\n",
++              dev->slot_name, resno, res->flags,
++              new & ~PCI_REGION_FLAG_MASK));
+ }
+ int __init
+--- linux-2.6.0/drivers/pcmcia/cistpl.c        2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/pcmcia/cistpl.c 2003-12-28 23:22:48.000000000 -0800
+@@ -341,8 +341,11 @@ void destroy_cis_cache(struct pcmcia_soc
+ int verify_cis_cache(struct pcmcia_socket *s)
+ {
+       struct cis_cache_entry *cis;
+-      char buf[256];
++      char *buf;
++      buf = kmalloc(256, GFP_KERNEL);
++      if (buf == NULL)
++              return -1;
+       list_for_each_entry(cis, &s->cis_cache, node) {
+               int len = cis->len;
+@@ -355,9 +358,12 @@ int verify_cis_cache(struct pcmcia_socke
+ #endif
+                       read_cis_mem(s, cis->attr, cis->addr, len, buf);
+-              if (memcmp(buf, cis->cache, len) != 0)
++              if (memcmp(buf, cis->cache, len) != 0) {
++                      kfree(buf);
+                       return -1;
++              }
+       }
++      kfree(buf);
+       return 0;
+ }
+@@ -1404,19 +1410,24 @@ int pcmcia_parse_tuple(client_handle_t h
+ int read_tuple(client_handle_t handle, cisdata_t code, void *parse)
+ {
+     tuple_t tuple;
+-    cisdata_t buf[255];
++    cisdata_t *buf;
+     int ret;
+-    
++
++    buf = kmalloc(256, GFP_KERNEL);
++    if (buf == NULL)
++      return CS_OUT_OF_RESOURCE;
+     tuple.DesiredTuple = code;
+     tuple.Attributes = TUPLE_RETURN_COMMON;
+     ret = pcmcia_get_first_tuple(handle, &tuple);
+-    if (ret != CS_SUCCESS) return ret;
++    if (ret != CS_SUCCESS) goto done;
+     tuple.TupleData = buf;
+     tuple.TupleOffset = 0;
+-    tuple.TupleDataMax = sizeof(buf);
++    tuple.TupleDataMax = 255;
+     ret = pcmcia_get_tuple_data(handle, &tuple);
+-    if (ret != CS_SUCCESS) return ret;
++    if (ret != CS_SUCCESS) goto done;
+     ret = pcmcia_parse_tuple(handle, &tuple, parse);
++done:
++    kfree(buf);
+     return ret;
+ }
+@@ -1432,50 +1443,61 @@ int read_tuple(client_handle_t handle, c
+ int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
+ {
+-    tuple_t tuple;
+-    cisparse_t p;
++    tuple_t *tuple;
++    cisparse_t *p;
+     int ret, reserved, dev_ok = 0, ident_ok = 0;
+     if (CHECK_HANDLE(handle))
+       return CS_BAD_HANDLE;
++    tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
++    if (tuple == NULL)
++      return CS_OUT_OF_RESOURCE;
++    p = kmalloc(sizeof(*p), GFP_KERNEL);
++    if (p == NULL) {
++      kfree(tuple);
++      return CS_OUT_OF_RESOURCE;
++    }
+     info->Chains = reserved = 0;
+-    tuple.DesiredTuple = RETURN_FIRST_TUPLE;
+-    tuple.Attributes = TUPLE_RETURN_COMMON;
+-    ret = pcmcia_get_first_tuple(handle, &tuple);
++    tuple->DesiredTuple = RETURN_FIRST_TUPLE;
++    tuple->Attributes = TUPLE_RETURN_COMMON;
++    ret = pcmcia_get_first_tuple(handle, tuple);
+     if (ret != CS_SUCCESS)
+-      return CS_SUCCESS;
++      goto done;
+     /* First tuple should be DEVICE; we should really have either that
+        or a CFTABLE_ENTRY of some sort */
+-    if ((tuple.TupleCode == CISTPL_DEVICE) ||
+-      (read_tuple(handle, CISTPL_CFTABLE_ENTRY, &p) == CS_SUCCESS) ||
+-      (read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, &p) == CS_SUCCESS))
++    if ((tuple->TupleCode == CISTPL_DEVICE) ||
++      (read_tuple(handle, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) ||
++      (read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS))
+       dev_ok++;
+     /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
+        tuple, for card identification.  Certain old D-Link and Linksys
+        cards have only a broken VERS_2 tuple; hence the bogus test. */
+-    if ((read_tuple(handle, CISTPL_MANFID, &p) == CS_SUCCESS) ||
+-      (read_tuple(handle, CISTPL_VERS_1, &p) == CS_SUCCESS) ||
+-      (read_tuple(handle, CISTPL_VERS_2, &p) != CS_NO_MORE_ITEMS))
++    if ((read_tuple(handle, CISTPL_MANFID, p) == CS_SUCCESS) ||
++      (read_tuple(handle, CISTPL_VERS_1, p) == CS_SUCCESS) ||
++      (read_tuple(handle, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS))
+       ident_ok++;
+     if (!dev_ok && !ident_ok)
+-      return CS_SUCCESS;
++      goto done;
+     for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) {
+-      ret = pcmcia_get_next_tuple(handle, &tuple);
++      ret = pcmcia_get_next_tuple(handle, tuple);
+       if (ret != CS_SUCCESS) break;
+-      if (((tuple.TupleCode > 0x23) && (tuple.TupleCode < 0x40)) ||
+-          ((tuple.TupleCode > 0x47) && (tuple.TupleCode < 0x80)) ||
+-          ((tuple.TupleCode > 0x90) && (tuple.TupleCode < 0xff)))
++      if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
++          ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
++          ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
+           reserved++;
+     }
+     if ((info->Chains == MAX_TUPLES) || (reserved > 5) ||
+       ((!dev_ok || !ident_ok) && (info->Chains > 10)))
+       info->Chains = 0;
++done:
++    kfree(tuple);
++    kfree(p);
+     return CS_SUCCESS;
+ }
+--- linux-2.6.0/drivers/pcmcia/cs.c    2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/pcmcia/cs.c     2003-12-28 23:22:54.000000000 -0800
+@@ -1916,7 +1916,7 @@ int pcmcia_request_irq(client_handle_t h
+ {
+     struct pcmcia_socket *s;
+     config_t *c;
+-    int ret = 0, irq = 0;
++    int ret = CS_IN_USE, irq = 0;
+     
+     if (CHECK_HANDLE(handle))
+       return CS_BAD_HANDLE;
+@@ -1928,13 +1928,9 @@ int pcmcia_request_irq(client_handle_t h
+       return CS_CONFIGURATION_LOCKED;
+     if (c->state & CONFIG_IRQ_REQ)
+       return CS_IN_USE;
+-    
+-    /* Short cut: if there are no ISA interrupts, then it is PCI */
+-    if (!s->irq_mask) {
+-      irq = s->pci_irq;
+-      ret = (irq) ? 0 : CS_IN_USE;
++
+ #ifdef CONFIG_PCMCIA_PROBE
+-    } else if (s->irq.AssignedIRQ != 0) {
++    if (s->irq.AssignedIRQ != 0) {
+       /* If the interrupt is already assigned, it must match */
+       irq = s->irq.AssignedIRQ;
+       if (req->IRQInfo1 & IRQ_INFO2_VALID) {
+@@ -1943,7 +1939,6 @@ int pcmcia_request_irq(client_handle_t h
+       } else
+           ret = ((req->IRQInfo1&IRQ_MASK) == irq) ? 0 : CS_BAD_ARGS;
+     } else {
+-      ret = CS_IN_USE;
+       if (req->IRQInfo1 & IRQ_INFO2_VALID) {
+           u_int try, mask = req->IRQInfo2 & s->irq_mask;
+           for (try = 0; try < 2; try++) {
+@@ -1958,12 +1953,13 @@ int pcmcia_request_irq(client_handle_t h
+           irq = req->IRQInfo1 & IRQ_MASK;
+           ret = try_irq(req->Attributes, irq, 1);
+       }
+-#else
+-    } else {
+-      ret = CS_UNSUPPORTED_MODE;
++    }
+ #endif
++    if (ret != 0) {
++      if (!s->pci_irq)
++          return ret;
++      irq = s->pci_irq;
+     }
+-    if (ret != 0) return ret;
+     if (req->Attributes & IRQ_HANDLE_PRESENT) {
+       if (request_irq(irq, req->Handler,
+@@ -2293,149 +2289,6 @@ int pcmcia_report_error(client_handle_t 
+     return CS_SUCCESS;
+ } /* report_error */
+-/*====================================================================*/
+-
+-int CardServices(int func, void *a1, void *a2, void *a3)
+-{
+-
+-#ifdef PCMCIA_DEBUG
+-    if (pc_debug > 2) {
+-      int i;
+-      for (i = 0; i < SERVICE_COUNT; i++)
+-          if (service_table[i].key == func) break;
+-      if (i < SERVICE_COUNT)
+-          printk(KERN_DEBUG "cs: CardServices(%s, 0x%p, 0x%p)\n",
+-                 service_table[i].msg, a1, a2);
+-      else
+-          printk(KERN_DEBUG "cs: CardServices(Unknown func %d, "
+-                 "0x%p, 0x%p)\n", func, a1, a2);
+-    }
+-#endif
+-    switch (func) {
+-    case AccessConfigurationRegister:
+-      return pcmcia_access_configuration_register(a1, a2); break;
+-    case AdjustResourceInfo:
+-      return pcmcia_adjust_resource_info(a1, a2); break;
+-    case CheckEraseQueue:
+-      return pcmcia_check_erase_queue(a1); break;
+-    case CloseMemory:
+-      return pcmcia_close_memory(a1); break;
+-    case CopyMemory:
+-      return pcmcia_copy_memory(a1, a2); break;
+-    case DeregisterClient:
+-      return pcmcia_deregister_client(a1); break;
+-    case DeregisterEraseQueue:
+-      return pcmcia_deregister_erase_queue(a1); break;
+-    case GetFirstClient:
+-      return pcmcia_get_first_client(a1, a2); break;
+-    case GetCardServicesInfo:
+-      return pcmcia_get_card_services_info(a1); break;
+-    case GetConfigurationInfo:
+-      return pcmcia_get_configuration_info(a1, a2); break;
+-    case GetNextClient:
+-      return pcmcia_get_next_client(a1, a2); break;
+-    case GetFirstRegion:
+-      return pcmcia_get_first_region(a1, a2); break;
+-    case GetFirstTuple:
+-      return pcmcia_get_first_tuple(a1, a2); break;
+-    case GetNextRegion:
+-      return pcmcia_get_next_region(a1, a2); break;
+-    case GetNextTuple:
+-      return pcmcia_get_next_tuple(a1, a2); break;
+-    case GetStatus:
+-      return pcmcia_get_status(a1, a2); break;
+-    case GetTupleData:
+-      return pcmcia_get_tuple_data(a1, a2); break;
+-    case MapMemPage:
+-      return pcmcia_map_mem_page(a1, a2); break;
+-    case ModifyConfiguration:
+-      return pcmcia_modify_configuration(a1, a2); break;
+-    case ModifyWindow:
+-      return pcmcia_modify_window(a1, a2); break;
+-    case OpenMemory:
+-/*    return pcmcia_open_memory(a1, a2); */
+-    {
+-      memory_handle_t m;
+-        int ret = pcmcia_open_memory(a1, a2, &m);
+-        *(memory_handle_t *)a1 = m;
+-      return  ret;
+-    }
+-        break;
+-    case ParseTuple:
+-      return pcmcia_parse_tuple(a1, a2, a3); break;
+-    case ReadMemory:
+-      return pcmcia_read_memory(a1, a2, a3); break;
+-    case RegisterClient:
+-      return pcmcia_register_client(a1, a2); break;
+-    case RegisterEraseQueue:
+-    {
+-      eraseq_handle_t w;
+-        int ret = pcmcia_register_erase_queue(a1, a2, &w);
+-        *(eraseq_handle_t *)a1 = w;
+-      return  ret;
+-    }
+-        break;
+-/*    return pcmcia_register_erase_queue(a1, a2); break; */
+-
+-      return pcmcia_register_mtd(a1, a2); break;
+-    case ReleaseConfiguration:
+-      return pcmcia_release_configuration(a1); break;
+-    case ReleaseIO:
+-      return pcmcia_release_io(a1, a2); break;
+-    case ReleaseIRQ:
+-      return pcmcia_release_irq(a1, a2); break;
+-    case ReleaseWindow:
+-      return pcmcia_release_window(a1); break;
+-    case RequestConfiguration:
+-      return pcmcia_request_configuration(a1, a2); break;
+-    case RequestIO:
+-      return pcmcia_request_io(a1, a2); break;
+-    case RequestIRQ:
+-      return pcmcia_request_irq(a1, a2); break;
+-    case RequestWindow:
+-    {
+-      window_handle_t w;
+-        int ret = pcmcia_request_window(a1, a2, &w);
+-        *(window_handle_t *)a1 = w;
+-      return  ret;
+-    }
+-        break;
+-    case ResetCard:
+-      return pcmcia_reset_card(a1, a2); break;
+-    case SetEventMask:
+-      return pcmcia_set_event_mask(a1, a2); break;
+-    case ValidateCIS:
+-      return pcmcia_validate_cis(a1, a2); break;
+-    case WriteMemory:
+-      return pcmcia_write_memory(a1, a2, a3); break;
+-    case BindDevice:
+-      return pcmcia_bind_device(a1); break;
+-    case BindMTD:
+-      return pcmcia_bind_mtd(a1); break;
+-    case ReportError:
+-      return pcmcia_report_error(a1, a2); break;
+-    case SuspendCard:
+-      return pcmcia_suspend_card(a1, a2); break;
+-    case ResumeCard:
+-      return pcmcia_resume_card(a1, a2); break;
+-    case EjectCard:
+-      return pcmcia_eject_card(a1, a2); break;
+-    case InsertCard:
+-      return pcmcia_insert_card(a1, a2); break;
+-    case ReplaceCIS:
+-      return pcmcia_replace_cis(a1, a2); break;
+-    case GetFirstWindow:
+-      return pcmcia_get_first_window(a1, a2); break;
+-    case GetNextWindow:
+-      return pcmcia_get_next_window(a1, a2); break;
+-    case GetMemPage:
+-      return pcmcia_get_mem_page(a1, a2); break;
+-    default:
+-      return CS_UNSUPPORTED_FUNCTION; break;
+-    }
+-    
+-} /* CardServices */
+-
+ /*======================================================================
+     OS-specific module glue goes here
+@@ -2493,7 +2346,6 @@ EXPORT_SYMBOL(pcmcia_validate_cis);
+ EXPORT_SYMBOL(pcmcia_write_memory);
+ EXPORT_SYMBOL(dead_socket);
+-EXPORT_SYMBOL(CardServices);
+ EXPORT_SYMBOL(MTDHelperEntry);
+ EXPORT_SYMBOL(pcmcia_parse_events);
+--- linux-2.6.0/drivers/pcmcia/i82365.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/pcmcia/i82365.c 2003-12-28 23:22:48.000000000 -0800
+@@ -42,7 +42,6 @@
+ #include <linux/timer.h>
+ #include <linux/sched.h>
+ #include <linux/slab.h>
+-#include <linux/pci.h>
+ #include <linux/ioport.h>
+ #include <linux/delay.h>
+ #include <linux/workqueue.h>
+@@ -188,10 +187,6 @@ static struct timer_list poll_timer;
+ /*====================================================================*/
+-/* Default settings for PCI command configuration register */
+-#define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \
+-                PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)
+-
+ /* These definitions must match the pcic table! */
+ typedef enum pcic_id {
+     IS_I82365A, IS_I82365B, IS_I82365DF,
+@@ -202,15 +197,10 @@ typedef enum pcic_id {
+ /* Flags for classifying groups of controllers */
+ #define IS_VADEM      0x0001
+ #define IS_CIRRUS     0x0002
+-#define IS_TI         0x0004
+-#define IS_O2MICRO    0x0008
+ #define IS_VIA                0x0010
+-#define IS_TOPIC      0x0020
+-#define IS_RICOH      0x0040
+ #define IS_UNKNOWN    0x0400
+ #define IS_VG_PWR     0x0800
+ #define IS_DF_PWR     0x1000
+-#define IS_PCI                0x2000
+ #define IS_ALIVE      0x8000
+ typedef struct pcic_t {
+@@ -351,26 +341,24 @@ static u_int __init cirrus_set_opts(u_sh
+     if (has_ring == -1) has_ring = 1;
+     flip(p->misc2, PD67_MC2_IRQ15_RI, has_ring);
+     flip(p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode);
++    flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
+     if (p->misc2 & PD67_MC2_IRQ15_RI)
+       strcat(buf, " [ring]");
+     if (p->misc2 & PD67_MC2_DYNAMIC_MODE)
+       strcat(buf, " [dyn mode]");
++    if (p->misc2 & PD67_MC2_FREQ_BYPASS)
++      strcat(buf, " [freq bypass]");
+     if (p->misc1 & PD67_MC1_INPACK_ENA)
+       strcat(buf, " [inpack]");
+-    if (!(t->flags & IS_PCI)) {
+-      if (p->misc2 & PD67_MC2_IRQ15_RI)
+-          mask &= ~0x8000;
+-      if (has_led > 0) {
+-          strcat(buf, " [led]");
+-          mask &= ~0x1000;
+-      }
+-      if (has_dma > 0) {
+-          strcat(buf, " [dma]");
+-          mask &= ~0x0600;
+-      flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
+-      if (p->misc2 & PD67_MC2_FREQ_BYPASS)
+-          strcat(buf, " [freq bypass]");
+-      }
++    if (p->misc2 & PD67_MC2_IRQ15_RI)
++      mask &= ~0x8000;
++    if (has_led > 0) {
++      strcat(buf, " [led]");
++      mask &= ~0x1000;
++    }
++    if (has_dma > 0) {
++      strcat(buf, " [dma]");
++      mask &= ~0x0600;
+     }
+     if (!(t->flags & IS_VIA)) {
+       if (setup_time >= 0)
+@@ -540,7 +528,6 @@ static u_int __init test_irq(u_short soc
+     return (irq_hits != 1);
+ }
+-
+ static u_int __init isa_scan(u_short sock, u_int mask0)
+ {
+     u_int mask1 = 0;
+@@ -585,7 +572,6 @@ static u_int __init isa_scan(u_short soc
+     return mask1;
+ }
+-
+ /*====================================================================*/
+ /* Time conversion functions */
+@@ -597,7 +583,6 @@ static int to_cycles(int ns)
+ /*====================================================================*/
+-
+ static int __init identify(u_short port, u_short sock)
+ {
+     u_char val;
+@@ -700,7 +685,7 @@ static void __init add_socket(u_short po
+ static void __init add_pcic(int ns, int type)
+ {
+     u_int mask = 0, i, base;
+-    int use_pci = 0, isa_irq = 0;
++    int isa_irq = 0;
+     struct i82365_socket *t = &socket[sockets-ns];
+     base = sockets-ns;
+@@ -721,17 +706,16 @@ static void __init add_pcic(int ns, int 
+     mask &= I365_MASK & set_bridge_opts(base, ns);
+     /* Scan for ISA interrupts */
+     mask = isa_scan(base, mask);
+-    printk(KERN_INFO "    PCI card interrupts,");
+         
+     /* Poll if only two interrupts available */
+-    if (!use_pci && !poll_interval) {
++    if (!poll_interval) {
+       u_int tmp = (mask & 0xff20);
+       tmp = tmp & (tmp-1);
+       if ((tmp & (tmp-1)) == 0)
+           poll_interval = HZ;
+     }
+     /* Only try an ISA cs_irq if this is the first controller */
+-    if (!use_pci && !grab_irq && (cs_irq || !poll_interval)) {
++    if (!grab_irq && (cs_irq || !poll_interval)) {
+       /* Avoid irq 12 unless it is explicitly requested */
+       u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
+       for (cs_irq = 15; cs_irq > 0; cs_irq--)
+@@ -745,7 +729,7 @@ static void __init add_pcic(int ns, int 
+       }
+     }
+     
+-    if (!use_pci && !isa_irq) {
++    if (!isa_irq) {
+       if (poll_interval == 0)
+           poll_interval = HZ;
+       printk(" polling interval = %d ms\n",
+@@ -763,10 +747,8 @@ static void __init add_pcic(int ns, int 
+ } /* add_pcic */
+-
+ /*====================================================================*/
+-
+ #ifdef CONFIG_PNP
+ static struct isapnp_device_id id_table[] __initdata = {
+       {       ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('P', 'N', 'P'),
+@@ -832,7 +814,9 @@ static void __init isa_probe(void)
+           }
+       }
+     } else {
+-      for (i = 0; i < (extra_sockets ? 8 : 4); i += 2) {
++      for (i = 0; i < 8; i += 2) {
++          if (sockets && !extra_sockets && (i == 4))
++              break;
+           port = i365_base + 2*(i>>2);
+           sock = (i & 3);
+           id = identify(port, sock);
+@@ -856,7 +840,6 @@ static void __init isa_probe(void)
+     }
+ }
+-
+ /*====================================================================*/
+ static irqreturn_t pcic_interrupt(int irq, void *dev,
+@@ -872,8 +855,7 @@ static irqreturn_t pcic_interrupt(int ir
+     for (j = 0; j < 20; j++) {
+       active = 0;
+       for (i = 0; i < sockets; i++) {
+-          if ((socket[i].cs_irq != irq) &&
+-              (socket[i].socket.pci_irq != irq))
++          if (socket[i].cs_irq != irq)
+               continue;
+           handled = 1;
+           ISA_LOCK(i, flags);
+@@ -911,7 +893,6 @@ static irqreturn_t pcic_interrupt(int ir
+ static void pcic_interrupt_wrapper(u_long data)
+ {
+     pcic_interrupt(0, NULL, NULL);
+-    init_timer(&poll_timer);
+     poll_timer.expires = jiffies + poll_interval;
+     add_timer(&poll_timer);
+ }
+@@ -1039,7 +1020,7 @@ static int i365_set_socket(u_short sock,
+     
+     /* IO card, RESET flag, IO interrupt */
+     reg = t->intr;
+-    if (state->io_irq != t->socket.pci_irq) reg |= state->io_irq;
++    reg |= state->io_irq;
+     reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
+     reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
+     i365_set(sock, I365_INTCTL, reg);
+@@ -1177,8 +1158,7 @@ static int i365_set_mem_map(u_short sock
+     if ((map > 4) || (mem->card_start > 0x3ffffff) ||
+       (mem->sys_start > mem->sys_stop) || (mem->speed > 1000))
+       return -EINVAL;
+-    if (!(socket[sock].flags & IS_PCI) &&
+-      ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff)))
++    if ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff))
+       return -EINVAL;
+       
+     /* Turn off the window before changing anything */
+@@ -1211,6 +1191,7 @@ static int i365_set_mem_map(u_short sock
+     return 0;
+ } /* i365_set_mem_map */
++#if 0 /* driver model ordering issue */
+ /*======================================================================
+     Routines for accessing socket information and register dumps via
+@@ -1250,6 +1231,7 @@ static ssize_t show_exca(struct class_de
+ static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
+ static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
++#endif
+ /*====================================================================*/
+@@ -1385,7 +1367,7 @@ static int __init init_i82365(void)
+     if (driver_register(&i82365_driver))
+       return -1;
+-    printk(KERN_INFO "Intel PCIC probe: ");
++    printk(KERN_INFO "Intel ISA PCIC probe: ");
+     sockets = 0;
+     isa_probe();
+@@ -1414,10 +1396,12 @@ static int __init init_i82365(void)
+                           pcmcia_unregister_socket(&socket[i].socket);
+                   break;
+           }
++#if 0 /* driver model ordering issue */
+          class_device_create_file(&socket[i].socket.dev,
+                                   &class_device_attr_info);
+          class_device_create_file(&socket[i].socket.dev,
+                                   &class_device_attr_exca);
++#endif
+     }
+     /* Finally, schedule a polling interrupt */
+--- linux-2.6.0/drivers/pcmcia/yenta_socket.c  2003-11-23 19:03:01.000000000 -0800
++++ 25/drivers/pcmcia/yenta_socket.c   2003-12-28 23:22:47.000000000 -0800
+@@ -30,7 +30,7 @@
+ #if 0
+-#define DEBUG(x,args...)      printk("%s: " x, __FUNCTION__, ##args)
++#define DEBUG(x,args...)      printk(KERN_DEBUG "%s: " x, __FUNCTION__, ##args)
+ #else
+ #define DEBUG(x,args...)
+ #endif
+@@ -779,7 +779,7 @@ static void yenta_get_socket_capabilitie
+       socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
+       socket->socket.cb_dev = socket->dev;
+-      printk(KERN_INFO "Yenta: ISA IRQ list %04x, PCI irq%d\n",
++      printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
+              socket->socket.irq_mask, socket->cb_irq);
+ }
+@@ -860,7 +860,7 @@ static int __devinit yenta_probe (struct
+               goto disable;
+       if (!pci_resource_start(dev, 0)) {
+-              printk("No cardbus resource!\n");
++              printk(KERN_ERR "No cardbus resource!\n");
+               ret = -ENODEV;
+               goto release;
+       }
+@@ -916,7 +916,7 @@ static int __devinit yenta_probe (struct
+       /* Figure out what the dang thing can do for the PCMCIA layer... */
+       yenta_get_socket_capabilities(socket, isa_interrupts);
+-      printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
++      printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
+       /* Register it with the pcmcia layer.. */
+       ret = pcmcia_register_socket(&socket->socket);
+--- linux-2.6.0/drivers/pnp/isapnp/core.c      2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/pnp/isapnp/core.c       2003-12-28 23:22:08.000000000 -0800
+@@ -890,11 +890,9 @@ static int __init isapnp_build_device_li
+                       header[4], header[5], header[6], header[7], header[8]);
+               printk(KERN_DEBUG "checksum = 0x%x\n", checksum);
+ #endif
+-              /* Don't be strict on the checksum, here !
+-                   e.g. 'SCM SwapBox Plug and Play' has header[8]==0 (should be: b7)*/
+-              if (header[8] == 0)
+-                      ;
+-              else if (checksum == 0x00 || checksum != header[8])     /* not valid CSN */
++              /* Per Section 6.1 of the Plug and Play ISA Specification (Version 1.0a), */
++              /* Bit[7] of Vendor ID Byte 0 must be 0 */
++              if (header[0] & 0x80)   /* not valid CSN */
+                       continue;
+               if ((card = isapnp_alloc(sizeof(struct pnp_card))) == NULL)
+                       continue;
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/pnp/isapnp/Kconfig      2003-12-28 23:22:08.000000000 -0800
+@@ -0,0 +1,11 @@
++#
++# ISA Plug and Play configuration
++#
++config ISAPNP
++      bool "ISA Plug and Play support (EXPERIMENTAL)"
++      depends on PNP && EXPERIMENTAL
++      help
++        Say Y here if you would like support for ISA Plug and Play devices.
++        Some information is in <file:Documentation/isapnp.txt>.
++
++        If unsure, say Y.
+--- linux-2.6.0/drivers/pnp/Kconfig    2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/pnp/Kconfig     2003-12-28 23:22:08.000000000 -0800
+@@ -30,33 +30,9 @@ config PNP_DEBUG
+ comment "Protocols"
+       depends on PNP
+-config ISAPNP
+-      bool "ISA Plug and Play support (EXPERIMENTAL)"
+-      depends on PNP && EXPERIMENTAL
+-      help
+-        Say Y here if you would like support for ISA Plug and Play devices.
+-        Some information is in <file:Documentation/isapnp.txt>.
++source "drivers/pnp/isapnp/Kconfig"
+-        If unsure, say Y.
+-
+-config PNPBIOS
+-      bool "Plug and Play BIOS support (EXPERIMENTAL)"
+-      depends on PNP && EXPERIMENTAL
+-      ---help---
+-        Linux uses the PNPBIOS as defined in "Plug and Play BIOS
+-        Specification Version 1.0A May 5, 1994" to autodetect built-in
+-        mainboard resources (e.g. parallel port resources).
+-
+-        Some features (e.g. event notification, docking station information,
+-        ISAPNP services) are not used.
+-
+-        Note: ACPI is expected to supersede PNPBIOS some day, currently it
+-        co-exists nicely.
+-
+-        See latest pcmcia-cs (stand-alone package) for a nice "lspnp" tools,
+-        or have a look at /proc/bus/pnp.
+-
+-        If unsure, say Y.
++source "drivers/pnp/pnpbios/Kconfig"
+ endmenu
+--- linux-2.6.0/drivers/pnp/pnpbios/bioscalls.c        2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/pnp/pnpbios/bioscalls.c 2003-12-28 23:23:01.000000000 -0800
+@@ -493,7 +493,7 @@ static int __pnp_bios_read_escd(char *da
+       if (!pnp_bios_present())
+               return ESCD_FUNCTION_NOT_SUPPORTED;
+       status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
+-                             data, 65536, (void *)nvram_base, 65536);
++                             data, 65536, __va((void *)nvram_base), 65536);
+       return status;
+ }
+@@ -516,7 +516,7 @@ static int pnp_bios_write_escd(char *dat
+       if (!pnp_bios_present())
+               return ESCD_FUNCTION_NOT_SUPPORTED;
+       status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
+-                             data, 65536, nvram_base, 65536);
++                             data, 65536, __va((void *)nvram_base), 65536);
+       return status;
+ }
+ #endif
+--- linux-2.6.0/drivers/pnp/pnpbios/core.c     2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/pnp/pnpbios/core.c      2003-12-28 23:22:07.000000000 -0800
+@@ -353,16 +353,8 @@ static void __init build_devlist(void)
+       for(nodenum=0; nodenum<0xff; ) {
+               u8 thisnodenum = nodenum;
+-              /* eventually we will want to use PNPMODE_STATIC here but for now
+-               * dynamic will help us catch buggy bioses to add to the blacklist.
+-               */
+-              if (!pnpbios_dont_use_current_config) {
+-                      if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_DYNAMIC, node))
+-                              break;
+-              } else {
+-                      if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_STATIC, node))
+-                              break;
+-              }
++              if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_STATIC, node))
++                      break;
+               nodes_got++;
+               dev =  pnpbios_kmalloc(sizeof (struct pnp_dev), GFP_KERNEL);
+               if (!dev)
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/pnp/pnpbios/Kconfig     2003-12-28 23:22:08.000000000 -0800
+@@ -0,0 +1,41 @@
++#
++# Plug and Play BIOS configuration
++#
++config PNPBIOS
++      bool "Plug and Play BIOS support (EXPERIMENTAL)"
++      depends on PNP && EXPERIMENTAL
++      ---help---
++        Linux uses the PNPBIOS as defined in "Plug and Play BIOS
++        Specification Version 1.0A May 5, 1994" to autodetect built-in
++        mainboard resources (e.g. parallel port resources).
++
++        Some features (e.g. event notification, docking station information,
++        ISAPNP services) are not currently implemented.
++
++        If you would like the kernel to detect and allocate resources to
++        your mainboard devices (on some systems they are disabled by the
++        BIOS) say Y here.  Also the PNPBIOS can help prevent resource
++        conflicts between mainboard devices and other bus devices.
++
++        Note: ACPI is expected to supersede PNPBIOS some day, currently it
++        co-exists nicely.  If you have a non-ISA system that supports ACPI,
++        you probably don't need PNPBIOS support.
++
++config PNPBIOS_PROC_FS
++      bool "Plug and Play BIOS /proc interface"
++      depends on PNPBIOS && PROC_FS
++      ---help---
++        If you say Y here and to "/proc file system support", you will be
++        able to directly access the PNPBIOS.  This includes resource
++        allocation, ESCD, and other PNPBIOS services.  Using this
++        interface is potentially dangerous because the PNPBIOS driver will
++        not be notified of any resource changes made by writting directly.
++        Also some buggy systems will fault when accessing certain features
++        in the PNPBIOS /proc interface (e.g. ESCD).
++
++        See the latest pcmcia-cs (stand-alone package) for a nice set of
++        PNPBIOS /proc interface tools (lspnp and setpnp).
++
++        Unless you are debugging or have other specific reasons, it is
++        recommended that you say N here.
++
+--- linux-2.6.0/drivers/pnp/pnpbios/Makefile   2003-08-08 22:55:12.000000000 -0700
++++ 25/drivers/pnp/pnpbios/Makefile    2003-12-28 23:22:08.000000000 -0800
+@@ -2,6 +2,6 @@
+ # Makefile for the kernel PNPBIOS driver.
+ #
+-pnpbios-proc-$(CONFIG_PROC_FS) = proc.o
++pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o
+ obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y)
+--- linux-2.6.0/drivers/pnp/pnpbios/pnpbios.h  2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/pnp/pnpbios/pnpbios.h   2003-12-28 23:22:08.000000000 -0800
+@@ -36,7 +36,7 @@ extern void pnpid32_to_pnpid(u32 id, cha
+ extern void pnpbios_print_status(const char * module, u16 status);
+ extern void pnpbios_calls_init(union pnp_bios_install_struct * header);
+-#ifdef CONFIG_PROC_FS
++#ifdef CONFIG_PNPBIOS_PROC_FS
+ extern int pnpbios_interface_attach_device(struct pnp_bios_node * node);
+ extern int pnpbios_proc_init (void);
+ extern void pnpbios_proc_exit (void);
+@@ -44,4 +44,4 @@ extern void pnpbios_proc_exit (void);
+ static inline int pnpbios_interface_attach_device(struct pnp_bios_node * node) { return 0; }
+ static inline int pnpbios_proc_init (void) { return 0; }
+ static inline void pnpbios_proc_exit (void) { ; }
+-#endif /* CONFIG_PROC */
++#endif /* CONFIG_PNPBIOS_PROC_FS */
+--- linux-2.6.0/drivers/s390/block/dasd.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/s390/block/dasd.c       2003-12-28 23:21:17.000000000 -0800
+@@ -1643,9 +1643,9 @@ dasd_flush_request_queue(struct dasd_dev
+ }
+ static int
+-dasd_open(struct inode *inp, struct file *filp)
++dasd_open(struct block_device *bdev, struct file *filp)
+ {
+-      struct gendisk *disk = inp->i_bdev->bd_disk;
++      struct gendisk *disk = bdev->bd_disk;
+       struct dasd_device *device = disk->private_data;
+       int rc;
+@@ -1676,10 +1676,8 @@ out:
+       return rc;
+ }
+-static int
+-dasd_release(struct inode *inp, struct file *filp)
++static int dasd_release(struct gendisk *disk)
+ {
+-      struct gendisk *disk = inp->i_bdev->bd_disk;
+       struct dasd_device *device = disk->private_data;
+       if (device->state < DASD_STATE_BASIC) {
+--- linux-2.6.0/drivers/s390/block/dasd_int.h  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/s390/block/dasd_int.h   2003-12-28 23:21:12.000000000 -0800
+@@ -493,7 +493,7 @@ int  dasd_ioctl_init(void);
+ void dasd_ioctl_exit(void);
+ int  dasd_ioctl_no_register(struct module *, int, dasd_ioctl_fn_t);
+ int  dasd_ioctl_no_unregister(struct module *, int, dasd_ioctl_fn_t);
+-int  dasd_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
++int  dasd_ioctl(struct block_device *, struct file *, unsigned int, unsigned long);
+ /* externals in dasd_proc.c */
+ int dasd_proc_init(void);
+--- linux-2.6.0/drivers/s390/block/dasd_ioctl.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/s390/block/dasd_ioctl.c 2003-12-28 23:21:12.000000000 -0800
+@@ -78,10 +78,9 @@ dasd_ioctl_no_unregister(struct module *
+ }
+ int
+-dasd_ioctl(struct inode *inp, struct file *filp,
++dasd_ioctl(struct block_device *bdev, struct file *filp,
+          unsigned int no, unsigned long data)
+ {
+-      struct block_device *bdev = inp->i_bdev;
+       struct dasd_device *device = bdev->bd_disk->private_data;
+       struct dasd_ioctl *ioctl;
+       const char *dir;
+--- linux-2.6.0/drivers/s390/block/xpram.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/s390/block/xpram.c      2003-12-28 23:21:12.000000000 -0800
+@@ -328,7 +328,7 @@ fail:
+       return 0;
+ }
+-static int xpram_ioctl (struct inode *inode, struct file *filp,
++static int xpram_ioctl (struct block_device *bdev, struct file *filp,
+                unsigned int cmd, unsigned long arg)
+ {
+       struct hd_geometry *geo;
+--- linux-2.6.0/drivers/s390/char/tape_block.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/s390/char/tape_block.c  2003-12-28 23:21:17.000000000 -0800
+@@ -27,8 +27,8 @@
+ /*
+  * file operation structure for tape block frontend
+  */
+-static int tapeblock_open(struct inode *, struct file *);
+-static int tapeblock_release(struct inode *, struct file *);
++static int tapeblock_open(block_device *, struct file *);
++static int tapeblock_release(struct gendisk *);
+ static struct block_device_operations tapeblock_fops = {
+       .owner          = THIS_MODULE,
+@@ -299,9 +299,9 @@ static int tapeblock_mediumdetect(struct
+  * Block frontend tape device open function.
+  */
+ static int
+-tapeblock_open(struct inode *inode, struct file *filp)
++tapeblock_open(struct block_device *bdev, struct file *filp)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
++      struct gendisk *disk = bdev->bd_disk;
+       struct tape_device *device = disk->private_data;
+       int rc;
+@@ -336,9 +336,8 @@ tapeblock_open(struct inode *inode, stru
+  * Block frontend tape device release function.
+  */
+ static int
+-tapeblock_release(struct inode *inode, struct file *filp)
++tapeblock_release(struct gendisk *disk)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct tape_device *device = disk->private_data;
+       tape_release(device);
+--- linux-2.6.0/drivers/s390/net/qeth.c        2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/s390/net/qeth.c 2003-12-28 23:21:01.000000000 -0800
+@@ -9739,28 +9739,28 @@ static int
+ qeth_get_internal_functions(void)
+ {
+       struct net_device *dev;
+-
+-      dev = (struct net_device *) kmalloc(sizeof (struct net_device),
+-                                          GFP_KERNEL);
++#ifdef CONFIG_NET_ETHERNET
++      dev = alloc_etherdev(0);
+       if (!dev) {
+               PRINT_ERR("Not enough memory for internal functions.\n");
+               return -ENOMEM;
+       }
+-#ifdef CONFIG_NET_ETHERNET
+-      ether_setup(dev);
+       qeth_my_eth_header = dev->hard_header;
+       qeth_my_eth_rebuild_header = dev->rebuild_header;
+       qeth_my_eth_header_cache = dev->hard_header_cache;
+       qeth_my_eth_header_cache_update = dev->header_cache_update;
++      free_netdev(dev);
+ #endif
+ #ifdef CONFIG_TR
+-      tr_setup(dev);
++      dev = alloc_trdev(0);
++      if (!dev) {
++              PRINT_ERR("Not enough memory for internal functions.\n");
++              return -ENOMEM;
++      }
+       qeth_my_tr_header = dev->hard_header;
+       qeth_my_tr_rebuild_header = dev->rebuild_header;
++      free_netdev(dev);
+ #endif
+-
+-      kfree(dev);
+-
+       return 0;
+ }
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7770.c 2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7770.c  2003-12-28 23:21:39.000000000 -0800
+@@ -37,9 +37,7 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#30 $
+- *
+- * $FreeBSD$
++ * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#34 $
+  */
+ #ifdef __linux__
+@@ -47,6 +45,8 @@
+ #include "aic7xxx_inline.h"
+ #include "aic7xxx_93cx6.h"
+ #else
++#include <sys/cdefs.h>
++__FBSDID("$FreeBSD$");
+ #include <dev/aic7xxx/aic7xxx_osm.h>
+ #include <dev/aic7xxx/aic7xxx_inline.h>
+ #include <dev/aic7xxx/aic7xxx_93cx6.h>
+@@ -67,8 +67,7 @@ static ahc_device_setup_t ahc_aic7770_VL
+ static ahc_device_setup_t ahc_aic7770_EISA_setup;;
+ static ahc_device_setup_t ahc_aic7770_setup;
+-
+-struct aic7770_identity aic7770_ident_table [] =
++struct aic7770_identity aic7770_ident_table[] =
+ {
+       {
+               ID_AHA_274x,
+@@ -83,6 +82,12 @@ struct aic7770_identity aic7770_ident_ta
+               ahc_aic7770_VL_setup
+       },
+       {
++              ID_AHA_284x,
++              0xFFFFFFFE,
++              "Adaptec 284X SCSI adapter (BIOS Disabled)",
++              ahc_aic7770_VL_setup
++      },
++      {
+               ID_OLV_274x,
+               0xFFFFFFFF,
+               "Adaptec (Olivetti OEM) 274X SCSI adapter",
+@@ -154,7 +159,7 @@ aic7770_config(struct ahc_softc *ahc, st
+       ahc->bus_suspend = aic7770_suspend;
+       ahc->bus_resume = aic7770_resume;
+-      error = ahc_reset(ahc);
++      error = ahc_reset(ahc, /*reinit*/FALSE);
+       if (error != 0)
+               return (error);
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7770_osm.c     2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7770_osm.c      2003-12-28 23:21:39.000000000 -0800
+@@ -1,7 +1,7 @@
+ /*
+  * Linux driver attachment glue for aic7770 based controllers.
+  *
+- * Copyright (c) 2000-2001 Adaptec Inc.
++ * Copyright (c) 2000-2003 Adaptec Inc.
+  * All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+@@ -36,27 +36,90 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#13 $
++ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#16 $
+  */
+ #include "aic7xxx_osm.h"
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++#include <linux/device.h>
++#include <linux/eisa.h>
++
++#define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@')  /* Bits 26-30 */
++#define EISA_MFCTR_CHAR1(ID) (char)(((ID>>21) & 0x1F) | '@')  /* Bits 21-25 */
++#define EISA_MFCTR_CHAR2(ID) (char)(((ID>>16) & 0x1F) | '@')  /* Bits 16-20 */
++#define EISA_PRODUCT_ID(ID)  (short)((ID>>4)  & 0xFFF)        /* Bits  4-15 */
++#define EISA_REVISION_ID(ID) (uint8_t)(ID & 0x0F)             /* Bits  0-3  */
++
++static int aic7770_eisa_dev_probe(struct device *dev);
++static int aic7770_eisa_dev_remove(struct device *dev);
++static struct eisa_driver aic7770_driver = {
++      .driver = {
++              .name   = "aic7xxx",
++              .probe  = aic7770_eisa_dev_probe,
++              .remove = aic7770_eisa_dev_remove,
++      }
++};
++
++typedef  struct device *aic7770_dev_t;
++#else
+ #define MINSLOT                       1
+ #define NUMSLOTS              16
+ #define IDOFFSET              0x80
+-int
+-aic7770_linux_probe(Scsi_Host_Template *template)
++typedef void *aic7770_dev_t;
++#endif
++
++static int aic7770_linux_config(struct aic7770_identity *entry,
++                              aic7770_dev_t dev, u_int eisaBase);
++
++void
++ahc_linux_eisa_init(void)
+ {
+-#if defined(__i386__) || defined(__alpha__)
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++      struct eisa_device_id *eid;
++      struct aic7770_identity *id;
++      int i;
++
++      if (aic7xxx_probe_eisa_vl == 0)
++              return;
++
++      /*
++       * Linux requires the EISA IDs to be specified in
++       * the EISA ID string format.  Perform the conversion
++       * and setup a table with a NUL terminal entry.
++       */
++      aic7770_driver.id_table = malloc(sizeof(struct eisa_device_id) *
++                                       (ahc_num_aic7770_devs + 1),
++                                       M_DEVBUF, M_NOWAIT);
++      if (aic7770_driver.id_table == NULL)
++              return;
++
++      for (eid = (struct eisa_device_id *)aic7770_driver.id_table,
++           id = aic7770_ident_table, i = 0;
++           i < ahc_num_aic7770_devs; eid++, id++, i++) {
++
++              sprintf(eid->sig, "%c%c%c%03X%01X",
++                      EISA_MFCTR_CHAR0(id->full_id),
++                      EISA_MFCTR_CHAR1(id->full_id),
++                      EISA_MFCTR_CHAR2(id->full_id),
++                      EISA_PRODUCT_ID(id->full_id),
++                      EISA_REVISION_ID(id->full_id));
++              eid->driver_data = i;
++      }
++      eid->sig[0] = 0;
++
++      eisa_driver_register(&aic7770_driver);
++#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */
+       struct aic7770_identity *entry;
+-      struct ahc_softc *ahc;
+-      int i, slot;
+-      int eisaBase;
+-      int found;
++      u_int  slot;
++      u_int  eisaBase;
++      u_int  i;
++
++      if (aic7xxx_probe_eisa_vl == 0)
++              return;
+       eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
+-      found = 0;
+       for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
+               uint32_t eisa_id;
+               size_t   id_size;
+@@ -83,45 +146,65 @@ aic7770_linux_probe(Scsi_Host_Template *
+                       continue;  /* no EISA card in slot */
+               entry = aic7770_find_device(eisa_id);
+-              if (entry != NULL) {
+-                      char     buf[80];
+-                      char    *name;
+-                      int      error;
+-
+-                      /*
+-                       * Allocate a softc for this card and
+-                       * set it up for attachment by our
+-                       * common detect routine.
+-                       */
+-                      sprintf(buf, "ahc_eisa:%d", slot);
+-                      name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+-                      if (name == NULL)
+-                              break;
+-                      strcpy(name, buf);
+-                      ahc = ahc_alloc(template, name);
+-                      if (ahc == NULL) {
+-                              /*
+-                               * If we can't allocate this one,
+-                               * chances are we won't be able to
+-                               * allocate future card structures.
+-                               */
+-                              break;
+-                      }
+-                      error = aic7770_config(ahc, entry, eisaBase);
+-                      if (error != 0) {
+-                              ahc->bsh.ioport = 0;
+-                              ahc_free(ahc);
+-                              continue;
+-                      }
+-                      found++;
+-              }
++              if (entry != NULL)
++                      aic7770_linux_config(entry, NULL, eisaBase);
++      }
++#endif
++}
++
++void
++ahc_linux_eisa_exit(void)
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++      if (aic7xxx_probe_eisa_vl == 0)
++              return;
++
++      if (aic7770_driver.id_table != NULL) {
++              eisa_driver_unregister(&aic7770_driver);
++              free(aic7770_driver.id_table, M_DEVBUF);
+       }
+-      return (found);
+-#else
+-      return (0);
+ #endif
+ }
++static int
++aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev,
++                   u_int eisaBase)
++{
++      struct  ahc_softc *ahc;
++      char    buf[80];
++      char   *name;
++      int     error;
++
++      /*
++       * Allocate a softc for this card and
++       * set it up for attachment by our
++       * common detect routine.
++       */
++      sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
++      name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
++      if (name == NULL)
++              return (ENOMEM);
++      strcpy(name, buf);
++      ahc = ahc_alloc(&aic7xxx_driver_template, name);
++      if (ahc == NULL) {
++              free(name, M_DEVBUF);
++              return (ENOMEM);
++      }
++      ahc->dev_softc = dev;
++      error = aic7770_config(ahc, entry, eisaBase);
++      if (error != 0) {
++              ahc->bsh.ioport = 0;
++              ahc_free(ahc);
++              return (error);
++      }
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++      dev->driver_data = (void *)ahc;
++      if (aic7xxx_detect_complete)
++              error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
++#endif
++      return (error);
++}
++
+ int
+ aic7770_map_registers(struct ahc_softc *ahc, u_int port)
+ {
+@@ -129,6 +212,8 @@ aic7770_map_registers(struct ahc_softc *
+        * Lock out other contenders for our i/o space.
+        */
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
++      if (check_region(port, AHC_EISA_IOSIZE) != 0)
++              return (ENOMEM);
+       request_region(port, AHC_EISA_IOSIZE, "aic7xxx");
+ #else
+       if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0)
+@@ -155,3 +240,43 @@ aic7770_map_int(struct ahc_softc *ahc, u
+       
+       return (-error);
+ }
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++static int
++aic7770_eisa_dev_probe(struct device *dev)
++{
++      struct eisa_device *edev;
++
++      edev = to_eisa_device(dev);
++      return (aic7770_linux_config(aic7770_ident_table + edev->id.driver_data,
++                                  dev, edev->base_addr+AHC_EISA_SLOT_OFFSET));
++}
++
++static int
++aic7770_eisa_dev_remove(struct device *dev)
++{
++      struct ahc_softc *ahc;
++      u_long l;
++
++      /*
++       * We should be able to just perform
++       * the free directly, but check our
++       * list for extra sanity.
++       */
++      ahc_list_lock(&l);
++      ahc = ahc_find_softc((struct ahc_softc *)dev->driver_data);
++      if (ahc != NULL) {
++              u_long s;
++
++              TAILQ_REMOVE(&ahc_tailq, ahc, links);
++              ahc_list_unlock(&l);
++              ahc_lock(ahc, &s);
++              ahc_intr_enable(ahc, FALSE);
++              ahc_unlock(ahc, &s);
++              ahc_free(ahc);
++      } else
++              ahc_list_unlock(&l);
++
++      return (0);
++}
++#endif
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx_core.c    2003-06-14 12:17:55.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx_core.c     2003-12-28 23:21:39.000000000 -0800
+@@ -37,9 +37,7 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#194 $
+- *
+- * $FreeBSD$
++ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#224 $
+  */
+ #ifdef __linux__
+@@ -47,6 +45,8 @@
+ #include "aic79xx_inline.h"
+ #include "aicasm/aicasm_insformat.h"
+ #else
++#include <sys/cdefs.h>
++__FBSDID("$FreeBSD$");
+ #include <dev/aic7xxx/aic79xx_osm.h>
+ #include <dev/aic7xxx/aic79xx_inline.h>
+ #include <dev/aic7xxx/aicasm/aicasm_insformat.h>
+@@ -224,6 +224,14 @@ static u_int              ahd_resolve_seqaddr(struct
+ static void           ahd_download_instr(struct ahd_softc *ahd,
+                                          u_int instrptr, uint8_t *dconsts);
+ static int            ahd_probe_stack_size(struct ahd_softc *ahd);
++static void           ahd_other_scb_timeout(struct ahd_softc *ahd,
++                                            struct scb *scb,
++                                            struct scb *other_scb);
++static int            ahd_scb_active_in_fifo(struct ahd_softc *ahd,
++                                             struct scb *scb);
++static void           ahd_run_data_fifo(struct ahd_softc *ahd,
++                                        struct scb *scb);
++
+ #ifdef AHD_TARGET_MODE
+ static void           ahd_queue_lstate_event(struct ahd_softc *ahd,
+                                              struct ahd_tmode_lstate *lstate,
+@@ -328,10 +336,7 @@ ahd_restart(struct ahd_softc *ahd)
+       /* Always allow reselection */
+       ahd_outb(ahd, SCSISEQ1,
+                ahd_inb(ahd, SCSISEQ_TEMPLATE) & (ENSELI|ENRSELI|ENAUTOATNP));
+-      /* Ensure that no DMA operations are in progress */
+       ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
+-      ahd_outb(ahd, SCBHCNT, 0);
+-      ahd_outb(ahd, CCSCBCTL, CCSCBRESET);
+       ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
+       ahd_unpause(ahd);
+ }
+@@ -371,31 +376,119 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd
+       u_int           next_scbid;
+       saved_modes = ahd_save_modes(ahd);
+-      ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
++
++      /*
++       * Flush the good status FIFO for completed packetized commands.
++       */
++      ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
+       saved_scbptr = ahd_get_scbptr(ahd);
++      while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) {
++              u_int fifo_mode;
++              u_int i;
++              
++              scbid = ahd_inw(ahd, GSFIFO);
++              scb = ahd_lookup_scb(ahd, scbid);
++              if (scb == NULL) {
++                      printf("%s: Warning - GSFIFO SCB %d invalid\n",
++                             ahd_name(ahd), scbid);
++                      continue;
++              }
++              /*
++               * Determine if this transaction is still active in
++               * any FIFO.  If it is, we must flush that FIFO to
++               * the host before completing the  command.
++               */
++              fifo_mode = 0;
++rescan_fifos:
++              for (i = 0; i < 2; i++) {
++                      /* Toggle to the other mode. */
++                      fifo_mode ^= 1;
++                      ahd_set_modes(ahd, fifo_mode, fifo_mode);
++
++                      if (ahd_scb_active_in_fifo(ahd, scb) == 0)
++                              continue;
++
++                      ahd_run_data_fifo(ahd, scb);
++
++                      /*
++                       * Running this FIFO may cause a CFG4DATA for
++                       * this same transaction to assert in the other
++                       * FIFO or a new snapshot SAVEPTRS interrupt
++                       * in this FIFO.  Even running a FIFO may not
++                       * clear the transaction if we are still waiting
++                       * for data to drain to the host. We must loop
++                       * until the transaction is not active in either
++                       * FIFO just to be sure.  Reset our loop counter
++                       * so we will visit both FIFOs again before
++                       * declaring this transaction finished.  We
++                       * also delay a bit so that status has a chance
++                       * to change before we look at this FIFO again.
++                       */
++                      aic_delay(200);
++                      goto rescan_fifos;
++              }
++              ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
++              ahd_set_scbptr(ahd, scbid);
++              if ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_LIST_NULL) == 0
++               && ((ahd_inb_scbram(ahd, SCB_SGPTR) & SG_FULL_RESID) != 0
++                || (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR)
++                    & SG_LIST_NULL) != 0)) {
++                      u_int comp_head;
++
++                      /*
++                       * The transfer completed with a residual.
++                       * Place this SCB on the complete DMA list
++                       * so that we update our in-core copy of the
++                       * SCB before completing the command.
++                       */
++                      ahd_outb(ahd, SCB_SCSI_STATUS, 0);
++                      ahd_outb(ahd, SCB_SGPTR,
++                               ahd_inb_scbram(ahd, SCB_SGPTR)
++                               | SG_STATUS_VALID);
++                      ahd_outw(ahd, SCB_TAG, SCB_GET_TAG(scb));
++                      comp_head = ahd_inw(ahd, COMPLETE_DMA_SCB_HEAD);
++                      ahd_outw(ahd, SCB_NEXT_COMPLETE, comp_head);
++                      ahd_outw(ahd, COMPLETE_DMA_SCB_HEAD, SCB_GET_TAG(scb));
++              } else
++                      ahd_complete_scb(ahd, scb);
++      }
++      ahd_set_scbptr(ahd, saved_scbptr);
++
++      /*
++       * Setup for command channel portion of flush.
++       */
++      ahd_set_modes(ahd, AHD_MODE_CCHAN, AHD_MODE_CCHAN);
+       /*
+        * Wait for any inprogress DMA to complete and clear DMA state
+        * if this if for an SCB in the qinfifo.
+        */
+-      while ((ccscbctl = ahd_inb(ahd, CCSCBCTL) & (CCARREN|CCSCBEN)) != 0) {
++      while (((ccscbctl = ahd_inb(ahd, CCSCBCTL)) & (CCARREN|CCSCBEN)) != 0) {
+               if ((ccscbctl & (CCSCBDIR|CCARREN)) == (CCSCBDIR|CCARREN)) {
+                       if ((ccscbctl & ARRDONE) != 0)
+                               break;
+               } else if ((ccscbctl & CCSCBDONE) != 0)
+                       break;
+-              ahd_delay(200);
++              aic_delay(200);
+       }
+-      if ((ccscbctl & CCSCBDIR) != 0)
++      /*
++       * We leave the sequencer to cleanup in the case of DMA's to
++       * update the qoutfifo.  In all other cases (DMA's to the
++       * chip or a push of an SCB from the COMPLETE_DMA_SCB list),
++       * we disable the DMA engine so that the sequencer will not
++       * attempt to handle the DMA completion.
++       */
++      if ((ccscbctl & CCSCBDIR) != 0 || (ccscbctl & ARRDONE) != 0)
+               ahd_outb(ahd, CCSCBCTL, ccscbctl & ~(CCARREN|CCSCBEN));
+       /*
+-       * Complete any SCBs that just finished being
+-       * DMA'ed into the qoutfifo.
++       * Complete any SCBs that just finished
++       * being DMA'ed into the qoutfifo.
+        */
+       ahd_run_qoutfifo(ahd);
++      saved_scbptr = ahd_get_scbptr(ahd);
+       /*
+        * Manually update/complete any completed SCBs that are waiting to be
+        * DMA'ed back up to the host.
+@@ -438,31 +531,272 @@ ahd_flush_qoutfifo(struct ahd_softc *ahd
+               scbid = next_scbid;
+       }
+       ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL);
+-      ahd_set_scbptr(ahd, saved_scbptr);
+-
+-      /*
+-       * Flush the good status FIFO for compelted packetized commands.
+-       */
+-      ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
+-      while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) {
+-              scbid = (ahd_inb(ahd, GSFIFO+1) << 8)
+-                    | ahd_inb(ahd, GSFIFO);
+-              scb = ahd_lookup_scb(ahd, scbid);
+-              if (scb == NULL) {
+-                      printf("%s: Warning - GSFIFO SCB %d invalid\n",
+-                             ahd_name(ahd), scbid);
+-                      continue;
+-              }
+-              ahd_complete_scb(ahd, scb);
+-      }
+       /*
+        * Restore state.
+        */
++      ahd_set_scbptr(ahd, saved_scbptr);
+       ahd_restore_modes(ahd, saved_modes);
+       ahd->flags |= AHD_UPDATE_PEND_CMDS;
+ }
++/*
++ * Determine if an SCB for a packetized transaction
++ * is active in a FIFO.
++ */
++static int
++ahd_scb_active_in_fifo(struct ahd_softc *ahd, struct scb *scb)
++{
++
++      /*
++       * The FIFO is only active for our transaction if
++       * the SCBPTR matches the SCB's ID and the firmware
++       * has installed a handler for the FIFO or we have
++       * a pending SAVEPTRS or CFG4DATA interrupt.
++       */
++      if (ahd_get_scbptr(ahd) != SCB_GET_TAG(scb)
++       || ((ahd_inb(ahd, LONGJMP_ADDR+1) & INVALID_ADDR) != 0
++        && (ahd_inb(ahd, SEQINTSRC) & (CFG4DATA|SAVEPTRS)) == 0))
++              return (0);
++
++      return (1);
++}
++
++/*
++ * Run a data fifo to completion for a transaction we know
++ * has completed across the SCSI bus (good status has been
++ * received).  We are already set to the correct FIFO mode
++ * on entry to this routine.
++ *
++ * This function attempts to operate exactly as the firmware
++ * would when running this FIFO.  Care must be taken to update
++ * this routine any time the firmware's FIFO algorithm is
++ * changed.
++ */
++static void
++ahd_run_data_fifo(struct ahd_softc *ahd, struct scb *scb)
++{
++      u_int seqintsrc;
++
++      seqintsrc = ahd_inb(ahd, SEQINTSRC);
++      if ((seqintsrc & CFG4DATA) != 0) {
++              uint32_t datacnt;
++              uint32_t sgptr;
++
++              /*
++               * Clear full residual flag.
++               */
++              sgptr = ahd_inl_scbram(ahd, SCB_SGPTR) & ~SG_FULL_RESID;
++              ahd_outb(ahd, SCB_SGPTR, sgptr);
++
++              /*
++               * Load datacnt and address.
++               */
++              datacnt = ahd_inl_scbram(ahd, SCB_DATACNT);
++              if ((datacnt & AHD_DMA_LAST_SEG) != 0) {
++                      sgptr |= LAST_SEG;
++                      ahd_outb(ahd, SG_STATE, 0);
++              } else
++                      ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
++              ahd_outq(ahd, HADDR, ahd_inq_scbram(ahd, SCB_DATAPTR));
++              ahd_outl(ahd, HCNT, datacnt & AHD_SG_LEN_MASK);
++              ahd_outb(ahd, SG_CACHE_PRE, sgptr);
++              ahd_outb(ahd, DFCNTRL, PRELOADEN|SCSIEN|HDMAEN);
++
++              /*
++               * Initialize Residual Fields.
++               */
++              ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, datacnt >> 24);
++              ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr & SG_PTR_MASK);
++
++              /*
++               * Mark the SCB as having a FIFO in use.
++               */
++              ahd_outb(ahd, SCB_FIFO_USE_COUNT,
++                       ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) + 1);
++
++              /*
++               * Install a "fake" handler for this FIFO.
++               */
++              ahd_outw(ahd, LONGJMP_ADDR, 0);
++
++              /*
++               * Notify the hardware that we have satisfied
++               * this sequencer interrupt.
++               */
++              ahd_outb(ahd, CLRSEQINTSRC, CLRCFG4DATA);
++      } else if ((seqintsrc & SAVEPTRS) != 0) {
++              uint32_t sgptr;
++              uint32_t resid;
++
++              if ((ahd_inb(ahd, LONGJMP_ADDR+1)&INVALID_ADDR) != 0) {
++                      /*
++                       * Snapshot Save Pointers.  All that
++                       * is necessary to clear the snapshot
++                       * is a CLRCHN.
++                       */
++                      goto clrchn;
++              }
++
++              /*
++               * Disable S/G fetch so the DMA engine
++               * is available to future users.
++               */
++              if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0)
++                      ahd_outb(ahd, CCSGCTL, 0);
++              ahd_outb(ahd, SG_STATE, 0);
++
++              /*
++               * Flush the data FIFO.  Strickly only
++               * necessary for Rev A parts.
++               */
++              ahd_outb(ahd, DFCNTRL, ahd_inb(ahd, DFCNTRL) | FIFOFLUSH);
++
++              /*
++               * Calculate residual.
++               */
++              sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
++              resid = ahd_inl(ahd, SHCNT);
++              resid |= ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT+3) << 24;
++              ahd_outl(ahd, SCB_RESIDUAL_DATACNT, resid);
++              if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG) == 0) {
++                      /*
++                       * Must back up to the correct S/G element.
++                       * Typically this just means resetting our
++                       * low byte to the offset in the SG_CACHE,
++                       * but if we wrapped, we have to correct
++                       * the other bytes of the sgptr too.
++                       */
++                      if ((ahd_inb(ahd, SG_CACHE_SHADOW) & 0x80) != 0
++                       && (sgptr & 0x80) == 0)
++                              sgptr -= 0x100;
++                      sgptr &= ~0xFF;
++                      sgptr |= ahd_inb(ahd, SG_CACHE_SHADOW)
++                             & SG_ADDR_MASK;
++                      ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
++                      ahd_outb(ahd, SCB_RESIDUAL_DATACNT + 3, 0);
++              } else if ((resid & AHD_SG_LEN_MASK) == 0) {
++                      ahd_outb(ahd, SCB_RESIDUAL_SGPTR,
++                               sgptr | SG_LIST_NULL);
++              }
++              /*
++               * Save Pointers.
++               */
++              ahd_outq(ahd, SCB_DATAPTR, ahd_inq(ahd, SHADDR));
++              ahd_outl(ahd, SCB_DATACNT, resid);
++              ahd_outl(ahd, SCB_SGPTR, sgptr);
++              ahd_outb(ahd, CLRSEQINTSRC, CLRSAVEPTRS);
++              ahd_outb(ahd, SEQIMODE,
++                       ahd_inb(ahd, SEQIMODE) | ENSAVEPTRS);
++              /*
++               * If the data is to the SCSI bus, we are
++               * done, otherwise wait for FIFOEMP.
++               */
++              if ((ahd_inb(ahd, DFCNTRL) & DIRECTION) != 0)
++                      goto clrchn;
++      } else if ((ahd_inb(ahd, SG_STATE) & LOADING_NEEDED) != 0) {
++              uint32_t sgptr;
++              uint64_t data_addr;
++              uint32_t data_len;
++              u_int    dfcntrl;
++
++              /*
++               * Disable S/G fetch so the DMA engine
++               * is available to future users.  We won't
++               * be using the DMA engine to load segments.
++               */
++              if ((ahd_inb(ahd, SG_STATE) & FETCH_INPROG) != 0) {
++                      ahd_outb(ahd, CCSGCTL, 0);
++                      ahd_outb(ahd, SG_STATE, LOADING_NEEDED);
++              }
++
++              /*
++               * Wait for the DMA engine to notice that the
++               * host transfer is enabled and that there is
++               * space in the S/G FIFO for new segments before
++               * loading more segments.
++               */
++              if ((ahd_inb(ahd, DFSTATUS) & PRELOAD_AVAIL) != 0
++               && (ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0) {
++
++                      /*
++                       * Determine the offset of the next S/G
++                       * element to load.
++                       */
++                      sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
++                      sgptr &= SG_PTR_MASK;
++                      if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0) {
++                              struct ahd_dma64_seg *sg;
++
++                              sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
++                              data_addr = sg->addr;
++                              data_len = sg->len;
++                              sgptr += sizeof(*sg);
++                      } else {
++                              struct  ahd_dma_seg *sg;
++
++                              sg = ahd_sg_bus_to_virt(ahd, scb, sgptr);
++                              data_addr = sg->len & AHD_SG_HIGH_ADDR_MASK;
++                              data_addr <<= 8;
++                              data_addr |= sg->addr;
++                              data_len = sg->len;
++                              sgptr += sizeof(*sg);
++                      }
++
++                      /*
++                       * Update residual information.
++                       */
++                      ahd_outb(ahd, SCB_RESIDUAL_DATACNT+3, data_len >> 24);
++                      ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
++
++                      /*
++                       * Load the S/G.
++                       */
++                      if (data_len & AHD_DMA_LAST_SEG) {
++                              sgptr |= LAST_SEG;
++                              ahd_outb(ahd, SG_STATE, 0);
++                      }
++                      ahd_outq(ahd, HADDR, data_addr);
++                      ahd_outl(ahd, HCNT, data_len & AHD_SG_LEN_MASK);
++                      ahd_outb(ahd, SG_CACHE_PRE, sgptr & 0xFF);
++
++                      /*
++                       * Advertise the segment to the hardware.
++                       */
++                      dfcntrl = ahd_inb(ahd, DFCNTRL)|PRELOADEN|HDMAEN;
++                      if ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0) {
++                              /*
++                               * Use SCSIENWRDIS so that SCSIEN
++                               * is never modified by this
++                               * operation.
++                               */
++                              dfcntrl |= SCSIENWRDIS;
++                      }
++                      ahd_outb(ahd, DFCNTRL, dfcntrl);
++              }
++      } else if ((ahd_inb(ahd, SG_CACHE_SHADOW) & LAST_SEG_DONE) != 0) {
++
++              /*
++               * Transfer completed to the end of SG list
++               * and has flushed to the host.
++               */
++              ahd_outb(ahd, SCB_SGPTR,
++                       ahd_inb_scbram(ahd, SCB_SGPTR) | SG_LIST_NULL);
++              goto clrchn;
++      } else if ((ahd_inb(ahd, DFSTATUS) & FIFOEMP) != 0) {
++clrchn:
++              /*
++               * Clear any handler for this FIFO, decrement
++               * the FIFO use count for the SCB, and release
++               * the FIFO.
++               */
++              ahd_outb(ahd, LONGJMP_ADDR + 1, INVALID_ADDR);
++              ahd_outb(ahd, SCB_FIFO_USE_COUNT,
++                       ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT) - 1);
++              ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
++      }
++}
++
+ void
+ ahd_run_qoutfifo(struct ahd_softc *ahd)
+ {
+@@ -476,7 +810,7 @@ ahd_run_qoutfifo(struct ahd_softc *ahd)
+       while ((ahd->qoutfifo[ahd->qoutfifonext]
+            & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) {
+-              scb_index = ahd_le16toh(ahd->qoutfifo[ahd->qoutfifonext]
++              scb_index = aic_le16toh(ahd->qoutfifo[ahd->qoutfifonext]
+                                     & ~QOUTFIFO_ENTRY_VALID_LE);
+               scb = ahd_lookup_scb(ahd, scb_index);
+               if (scb == NULL) {
+@@ -556,26 +890,6 @@ ahd_handle_seqint(struct ahd_softc *ahd,
+                      ahd_name(ahd), seqintcode);
+ #endif
+       switch (seqintcode) {
+-      case BAD_SCB_STATUS:
+-      {
+-              struct  scb *scb;
+-              u_int   scbid;
+-              int     cmds_pending;
+-
+-              scbid = ahd_get_scbptr(ahd);
+-              scb = ahd_lookup_scb(ahd, scbid);
+-              if (scb != NULL) {
+-                      ahd_complete_scb(ahd, scb);
+-              } else {
+-                      printf("%s: WARNING no command for scb %d "
+-                             "(bad status)\n", ahd_name(ahd), scbid);
+-                      ahd_dump_card_state(ahd);
+-              }
+-              cmds_pending = ahd_inw(ahd, CMDS_PENDING);
+-              if (cmds_pending > 0)
+-                      ahd_outw(ahd, CMDS_PENDING, cmds_pending - 1);
+-              break;
+-      }
+       case ENTERING_NONPACK:
+       {
+               struct  scb *scb;
+@@ -589,7 +903,7 @@ ahd_handle_seqint(struct ahd_softc *ahd,
+                       /*
+                        * Somehow need to know if this
+                        * is from a selection or reselection.
+-                       * From that, we can termine target
++                       * From that, we can determine target
+                        * ID so we at least have an I_T nexus.
+                        */
+               } else {
+@@ -740,11 +1054,11 @@ ahd_handle_seqint(struct ahd_softc *ahd,
+                       ahd_outb(ahd, SAVED_LUN, 0);
+                       ahd_outb(ahd, SEQ_FLAGS, 0);
+                       ahd_assert_atn(ahd);
+-                      scb->flags &= ~(SCB_PACKETIZED);
++                      scb->flags &= ~SCB_PACKETIZED;
+                       scb->flags |= SCB_ABORT|SCB_CMDPHASE_ABORT;
+                       ahd_freeze_devq(ahd, scb);
+-                      ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
+-                      ahd_freeze_scb(scb);
++                      aic_set_transaction_status(scb, CAM_REQUEUE_REQ);
++                      aic_freeze_scb(scb);
+                       /*
+                        * Allow the sequencer to continue with
+@@ -796,7 +1110,8 @@ ahd_handle_seqint(struct ahd_softc *ahd,
+                        * attempt to complete this bogus SCB.
+                        */
+                       ahd_outb(ahd, SCB_CONTROL,
+-                               ahd_inb(ahd, SCB_CONTROL) & ~STATUS_RCVD);
++                               ahd_inb_scbram(ahd, SCB_CONTROL)
++                               & ~STATUS_RCVD);
+               }
+               break;
+       }
+@@ -991,7 +1306,7 @@ ahd_handle_seqint(struct ahd_softc *ahd,
+                              "NumSGs = %d.\n",
+                              ahd_inb(ahd, SEQ_FLAGS) & DPHASE
+                              ? "Have" : "Haven't",
+-                             ahd_get_transfer_length(scb), scb->sg_count);
++                             aic_get_transfer_length(scb), scb->sg_count);
+                       ahd_dump_sglist(scb);
+               }
+ #endif
+@@ -1001,8 +1316,8 @@ ahd_handle_seqint(struct ahd_softc *ahd,
+                * target does a command complete.
+                */
+               ahd_freeze_devq(ahd, scb);
+-              ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
+-              ahd_freeze_scb(scb);
++              aic_set_transaction_status(scb, CAM_DATA_RUN_ERR);
++              aic_freeze_scb(scb);
+               break;
+       }
+       case MKMSG_FAILED:
+@@ -1029,7 +1344,7 @@ ahd_handle_seqint(struct ahd_softc *ahd,
+                                          ROLE_INITIATOR, /*status*/0,
+                                          SEARCH_REMOVE);
+               ahd_outb(ahd, SCB_CONTROL,
+-                       ahd_inb(ahd, SCB_CONTROL) & ~MK_MESSAGE);
++                       ahd_inb_scbram(ahd, SCB_CONTROL) & ~MK_MESSAGE);
+               break;
+       }
+       case TASKMGMT_FUNC_COMPLETE:
+@@ -1263,7 +1578,7 @@ ahd_handle_scsiint(struct ahd_softc *ahd
+                        */
+                       ahd_scb_devinfo(ahd, &devinfo, scb);
+                       ahd_force_renegotiation(ahd, &devinfo);
+-                      ahd_set_transaction_status(scb, CAM_SEL_TIMEOUT);
++                      aic_set_transaction_status(scb, CAM_SEL_TIMEOUT);
+                       ahd_freeze_devq(ahd, scb);
+               }
+               ahd_outb(ahd, CLRINT, CLRSCSIINT);
+@@ -1710,8 +2025,8 @@ ahd_handle_pkt_busfree(struct ahd_softc 
+                       }
+                       scb->crc_retry_count++;
+               } else {
+-                      ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
+-                      ahd_freeze_scb(scb);
++                      aic_set_transaction_status(scb, CAM_UNCOR_PARITY);
++                      aic_freeze_scb(scb);
+                       ahd_freeze_devq(ahd, scb);
+               }
+               /* Return unpausing the sequencer. */
+@@ -1853,7 +2168,7 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
+                        && ahd_match_scb(ahd, scb, target, 'A',
+                                         CAM_LUN_WILDCARD, SCB_LIST_NULL,
+                                         ROLE_INITIATOR))
+-                              ahd_set_transaction_status(scb, CAM_REQ_CMP);
++                              aic_set_transaction_status(scb, CAM_REQ_CMP);
+ #endif
+                       ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD,
+                                           CAM_BDR_SENT, "Bus Device Reset",
+@@ -1880,21 +2195,32 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
+                       tinfo->goal.ppr_options = 0;
+                       ahd_qinfifo_requeue_tail(ahd, scb);
+                       printerror = 0;
+-              } else if ((ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
+-                       || ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE))
++              } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
+                       && ppr_busfree == 0) {
+                       /*
+-                       * Negotiation Rejected.  Go-async and
++                       * Negotiation Rejected.  Go-narrow and
+                        * retry command.
+                        */
+ #ifdef AHD_DEBUG
+                       if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
+-                              printf("Negotiation rejected busfree.\n");
++                              printf("WDTR negotiation rejected busfree.\n");
+ #endif
+                       ahd_set_width(ahd, &devinfo,
+                                     MSG_EXT_WDTR_BUS_8_BIT,
+                                     AHD_TRANS_CUR|AHD_TRANS_GOAL,
+                                     /*paused*/TRUE);
++                      ahd_qinfifo_requeue_tail(ahd, scb);
++                      printerror = 0;
++              } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
++                      && ppr_busfree == 0) {
++                      /*
++                       * Negotiation Rejected.  Go-async and
++                       * retry command.
++                       */
++#ifdef AHD_DEBUG
++                      if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
++                              printf("SDTR negotiation rejected busfree.\n");
++#endif
+                       ahd_set_syncrate(ahd, &devinfo,
+                                       /*period*/0, /*offset*/0,
+                                       /*ppr_options*/0,
+@@ -1933,8 +2259,8 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
+        && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) {
+               ahd_freeze_devq(ahd, scb);
+-              ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
+-              ahd_freeze_scb(scb);
++              aic_set_transaction_status(scb, CAM_REQUEUE_REQ);
++              aic_freeze_scb(scb);
+               if ((ahd->msg_flags & MSG_FLAG_IU_REQ_CHANGED) != 0) {
+                       ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
+                                      SCB_GET_CHANNEL(ahd, scb),
+@@ -1978,8 +2304,7 @@ ahd_handle_nonpkt_busfree(struct ahd_sof
+                      "PRGMCNT == 0x%x\n",
+                      ahd_lookup_phase_entry(lastphase)->phasemsg,
+                      aborted,
+-                     ahd_inb(ahd, PRGMCNT)
+-                      | (ahd_inb(ahd, PRGMCNT+1) << 8));
++                     ahd_inw(ahd, PRGMCNT));
+               ahd_dump_card_state(ahd);
+       }
+       /* Always restart the sequencer. */
+@@ -2023,7 +2348,7 @@ ahd_handle_proto_violation(struct ahd_so
+               printf("No SCB found during protocol violation\n");
+               goto proto_violation_reset;
+       } else {
+-              ahd_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
++              aic_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
+               if ((seq_flags & NO_CDB_SENT) != 0) {
+                       ahd_print_path(ahd, scb);
+                       printf("No or incomplete CDB sent to device.\n");
+@@ -2142,8 +2467,7 @@ ahd_clear_critical_section(struct ahd_so
+               u_int   i;
+               ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
+-              seqaddr = ahd_inb(ahd, CURADDR)
+-                      | (ahd_inb(ahd, CURADDR+1) << 8);
++              seqaddr = ahd_inw(ahd, CURADDR);
+               cs = ahd->critical_sections;
+               for (i = 0; i < ahd->num_critical_sections; i++, cs++) {
+@@ -2187,8 +2511,14 @@ ahd_clear_critical_section(struct ahd_so
+                       ahd_outb(ahd, LQOMODE0, 0);
+                       ahd_outb(ahd, LQOMODE1, 0);
+                       ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
+-                      simode1 = ahd_inb(ahd, SIMODE1);
+-                      ahd_outb(ahd, SIMODE1, ENBUSFREE);
++                      simode1 = ahd_inb(ahd, SIMODE1);
++                      /*
++                       * We don't clear ENBUSFREE.  Unfortunately
++                       * we cannot re-enable busfree detection within
++                       * the current connection, so we must leave it
++                       * on while single stepping.
++                       */
++                      ahd_outb(ahd, SIMODE1, simode1 & ENBUSFREE);
+                       ahd_outb(ahd, SEQCTL0, ahd_inb(ahd, SEQCTL0) | STEP);
+                       stepping = TRUE;
+               }
+@@ -2196,9 +2526,8 @@ ahd_clear_critical_section(struct ahd_so
+               ahd_outb(ahd, CLRINT, CLRSCSIINT);
+               ahd_set_modes(ahd, ahd->saved_src_mode, ahd->saved_dst_mode);
+               ahd_outb(ahd, HCNTRL, ahd->unpause);
+-              do {
+-                      ahd_delay(200);
+-              } while (!ahd_is_paused(ahd));
++              while (!ahd_is_paused(ahd))
++                      aic_delay(200);
+               ahd_update_modes(ahd);
+       }
+       if (stepping) {
+@@ -2274,10 +2603,10 @@ ahd_print_scb(struct scb *scb)
+       for (i = 0; i < sizeof(hscb->shared_data.idata.cdb); i++)
+               printf("%#02x", hscb->shared_data.idata.cdb[i]);
+       printf("        dataptr:%#x%x datacnt:%#x sgptr:%#x tag:%#x\n",
+-             (uint32_t)((ahd_le64toh(hscb->dataptr) >> 32) & 0xFFFFFFFF),
+-             (uint32_t)(ahd_le64toh(hscb->dataptr) & 0xFFFFFFFF),
+-             ahd_le32toh(hscb->datacnt),
+-             ahd_le32toh(hscb->sgptr),
++             (uint32_t)((aic_le64toh(hscb->dataptr) >> 32) & 0xFFFFFFFF),
++             (uint32_t)(aic_le64toh(hscb->dataptr) & 0xFFFFFFFF),
++             aic_le32toh(hscb->datacnt),
++             aic_le32toh(hscb->sgptr),
+              SCB_GET_TAG(scb));
+       ahd_dump_sglist(scb);
+ }
+@@ -2296,8 +2625,8 @@ ahd_dump_sglist(struct scb *scb)
+                               uint64_t addr;
+                               uint32_t len;
+-                              addr = ahd_le64toh(sg_list[i].addr);
+-                              len = ahd_le32toh(sg_list[i].len);
++                              addr = aic_le64toh(sg_list[i].addr);
++                              len = aic_le32toh(sg_list[i].len);
+                               printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
+                                      i,
+                                      (uint32_t)((addr >> 32) & 0xFFFFFFFF),
+@@ -2313,11 +2642,11 @@ ahd_dump_sglist(struct scb *scb)
+                       for (i = 0; i < scb->sg_count; i++) {
+                               uint32_t len;
+-                              len = ahd_le32toh(sg_list[i].len);
++                              len = aic_le32toh(sg_list[i].len);
+                               printf("sg[%d] - Addr 0x%x%x : Length %d%s\n",
+                                      i,
+-                                     (len >> 24) & SG_HIGH_ADDR_BITS,
+-                                     ahd_le32toh(sg_list[i].addr),
++                                     (len & AHD_SG_HIGH_ADDR_MASK) >> 24,
++                                     aic_le32toh(sg_list[i].addr),
+                                      len & AHD_SG_LEN_MASK,
+                                      len & AHD_DMA_LAST_SEG ? " Last" : "");
+                       }
+@@ -2859,14 +3188,25 @@ ahd_update_neg_table(struct ahd_softc *a
+               iocell_opts[AHD_PRECOMP_SLEW_INDEX] &= ~AHD_PRECOMP_MASK;
+               if ((ahd->features & AHD_NEW_IOCELL_OPTS) != 0
+-               && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0) {
++               && (ppr_opts & MSG_EXT_PPR_DT_REQ) != 0
++               && (ppr_opts & MSG_EXT_PPR_IU_REQ) == 0) {
+                       /*
+                        * Slow down our CRC interval to be
+-                       * compatible with devices that can't
+-                       * handle a CRC at full speed.
++                       * compatible with non-packetized
++                       * U160 devices that can't handle a
++                       * CRC at full speed.
+                        */
+                       con_opts |= ENSLOWCRC;
+               }
++
++              if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0) {
++                      /*
++                       * On H2A4, revert to a slower slewrate
++                       * on non-paced transfers.
++                       */
++                      iocell_opts[AHD_PRECOMP_SLEW_INDEX] &=
++                          ~AHD_SLEWRATE_MASK;
++              }
+       }
+       ahd_outb(ahd, ANNEXCOL, AHD_ANNEXCOL_PRECOMP_SLEW);
+@@ -2904,7 +3244,7 @@ ahd_update_pending_scbs(struct ahd_softc
+ {
+       struct          scb *pending_scb;
+       int             pending_scb_count;
+-      int             i;
++      u_int           scb_tag;
+       int             paused;
+       u_int           saved_scbptr;
+       ahd_mode_state  saved_modes;
+@@ -2962,17 +3302,14 @@ ahd_update_pending_scbs(struct ahd_softc
+       ahd_outb(ahd, SCSISEQ0, ahd_inb(ahd, SCSISEQ0) & ~ENSELO);
+       saved_scbptr = ahd_get_scbptr(ahd);
+       /* Ensure that the hscbs down on the card match the new information */
+-      for (i = 0; i < ahd->scb_data.maxhscbs; i++) {
++      for (scb_tag = 0; scb_tag < ahd->scb_data.maxhscbs; scb_tag++) {
+               struct  hardware_scb *pending_hscb;
+               u_int   control;
+-              u_int   scb_tag;
+-              ahd_set_scbptr(ahd, i);
+-              scb_tag = i;
+               pending_scb = ahd_lookup_scb(ahd, scb_tag);
+               if (pending_scb == NULL)
+                       continue;
+-
++              ahd_set_scbptr(ahd, scb_tag);
+               pending_hscb = pending_scb->hscb;
+               control = ahd_inb_scbram(ahd, SCB_CONTROL);
+               control &= ~MK_MESSAGE;
+@@ -3187,7 +3524,7 @@ ahd_setup_initiator_msgout(struct ahd_so
+                      devinfo->target_mask);
+               panic("SCB = %d, SCB Control = %x:%x, MSG_OUT = %x "
+                     "SCB flags = %x", SCB_GET_TAG(scb), scb->hscb->control,
+-                    ahd_inb(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT),
++                    ahd_inb_scbram(ahd, SCB_CONTROL), ahd_inb(ahd, MSG_OUT),
+                     scb->flags);
+       }
+@@ -3232,6 +3569,7 @@ ahd_build_transfer_msg(struct ahd_softc 
+        * may change.
+        */
+       period = tinfo->goal.period;
++      offset = tinfo->goal.offset;
+       ppr_options = tinfo->goal.ppr_options;
+       /* Target initiated PPR is not allowed in the SCSI spec */
+       if (devinfo->role == ROLE_TARGET)
+@@ -3239,7 +3577,7 @@ ahd_build_transfer_msg(struct ahd_softc 
+       ahd_devlimited_syncrate(ahd, tinfo, &period,
+                               &ppr_options, devinfo->role);
+       dowide = tinfo->curr.width != tinfo->goal.width;
+-      dosync = tinfo->curr.period != period;
++      dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
+       /*
+        * Only use PPR if we have options that need it, even if the device
+        * claims to support it.  There might be an expander in the way
+@@ -3249,7 +3587,7 @@ ahd_build_transfer_msg(struct ahd_softc 
+       if (!dowide && !dosync && !doppr) {
+               dowide = tinfo->goal.width != MSG_EXT_WDTR_BUS_8_BIT;
+-              dosync = tinfo->goal.period != 0;
++              dosync = tinfo->goal.offset != 0;
+       }
+       if (!dowide && !dosync && !doppr) {
+@@ -3725,8 +4063,13 @@ reswitch:
+               if ((ahd->msg_flags & MSG_FLAG_PACKETIZED) != 0) {
+                       printf("%s: Returning to Idle Loop\n",
+                              ahd_name(ahd));
+-                      ahd_outb(ahd, LASTPHASE, P_BUSFREE);
+                       ahd_clear_msg_state(ahd);
++
++                      /*
++                       * Perform the equivalent of a clear_target_state.
++                       */
++                      ahd_outb(ahd, LASTPHASE, P_BUSFREE);
++                      ahd_outb(ahd, SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT);
+                       ahd_outb(ahd, SEQCTL0, FASTMODE|SEQRESET);
+               } else {
+                       ahd_clear_msg_state(ahd);
+@@ -3983,22 +4326,30 @@ ahd_parse_msg(struct ahd_softc *ahd, str
+                               response = TRUE;
+                               sending_reply = TRUE;
+                       }
++                      /*
++                       * After a wide message, we are async, but
++                       * some devices don't seem to honor this portion
++                       * of the spec.  Force a renegotiation of the
++                       * sync component of our transfer agreement even
++                       * if our goal is async.  By updating our width
++                       * after forcing the negotiation, we avoid
++                       * renegotiating for width.
++                       */
++                      ahd_update_neg_request(ahd, devinfo, tstate,
++                                             tinfo, AHD_NEG_ALWAYS);
+                       ahd_set_width(ahd, devinfo, bus_width,
+                                     AHD_TRANS_ACTIVE|AHD_TRANS_GOAL,
+                                     /*paused*/TRUE);
+-                      /* After a wide message, we are async */
+-                      ahd_set_syncrate(ahd, devinfo, /*period*/0,
+-                                       /*offset*/0, /*ppr_options*/0,
+-                                       AHD_TRANS_ACTIVE, /*paused*/TRUE);
+                       if (sending_reply == FALSE && reject == FALSE) {
+-                              if (tinfo->goal.offset) {
+-                                      ahd->msgout_index = 0;
+-                                      ahd->msgout_len = 0;
+-                                      ahd_build_transfer_msg(ahd, devinfo);
+-                                      ahd->msgout_index = 0;
+-                                      response = TRUE;
+-                              }
++                              /*
++                               * We will always have an SDTR to send.
++                               */
++                              ahd->msgout_index = 0;
++                              ahd->msgout_len = 0;
++                              ahd_build_transfer_msg(ahd, devinfo);
++                              ahd->msgout_index = 0;
++                              response = TRUE;
+                       }
+                       done = MSGLOOP_MSGCOMPLETE;
+                       break;
+@@ -4326,7 +4677,7 @@ ahd_handle_msg_reject(struct ahd_softc *
+               ahd_outb(ahd, SCB_CONTROL,
+                        ahd_inb_scbram(ahd, SCB_CONTROL) & mask);
+               scb->hscb->control &= mask;
+-              ahd_set_transaction_tag(scb, /*enabled*/FALSE,
++              aic_set_transaction_tag(scb, /*enabled*/FALSE,
+                                       /*type*/MSG_SIMPLE_TASK);
+               ahd_outb(ahd, MSG_OUT, MSG_IDENTIFYFLAG);
+               ahd_assert_atn(ahd);
+@@ -4384,7 +4735,7 @@ ahd_handle_ign_wide_residue(struct ahd_s
+        * Perhaps add datadir to some spare bits in the hscb?
+        */
+       if ((ahd_inb(ahd, SEQ_FLAGS) & DPHASE) == 0
+-       || ahd_get_transfer_dir(scb) != CAM_DIR_IN) {
++       || aic_get_transfer_dir(scb) != CAM_DIR_IN) {
+               /*
+                * Ignore the message if we haven't
+                * seen an appropriate data phase yet.
+@@ -4401,7 +4752,8 @@ ahd_handle_ign_wide_residue(struct ahd_s
+               sgptr = ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
+               if ((sgptr & SG_LIST_NULL) != 0
+-               && (ahd_inb(ahd, SCB_TASK_ATTRIBUTE) & SCB_XFERLEN_ODD) != 0) {
++               && (ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
++                   & SCB_XFERLEN_ODD) != 0) {
+                       /*
+                        * If the residual occurred on the last
+                        * transfer and the transfer request was
+@@ -4438,18 +4790,18 @@ ahd_handle_ign_wide_residue(struct ahd_s
+                                * to load so we must go back one.
+                                */
+                               sg--;
+-                              sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
++                              sglen = aic_le32toh(sg->len) & AHD_SG_LEN_MASK;
+                               if (sg != scb->sg_list
+                                && sglen < (data_cnt & AHD_SG_LEN_MASK)) {
+                                       sg--;
+-                                      sglen = ahd_le32toh(sg->len);
++                                      sglen = aic_le32toh(sg->len);
+                                       /*
+                                        * Preserve High Address and SG_LIST
+                                        * bits while setting the count to 1.
+                                        */
+                                       data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK));
+-                                      data_addr = ahd_le64toh(sg->addr)
++                                      data_addr = aic_le64toh(sg->addr)
+                                                 + (sglen & AHD_SG_LEN_MASK)
+                                                 - 1;
+@@ -4471,18 +4823,18 @@ ahd_handle_ign_wide_residue(struct ahd_s
+                                * to load so we must go back one.
+                                */
+                               sg--;
+-                              sglen = ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
++                              sglen = aic_le32toh(sg->len) & AHD_SG_LEN_MASK;
+                               if (sg != scb->sg_list
+                                && sglen < (data_cnt & AHD_SG_LEN_MASK)) {
+                                       sg--;
+-                                      sglen = ahd_le32toh(sg->len);
++                                      sglen = aic_le32toh(sg->len);
+                                       /*
+                                        * Preserve High Address and SG_LIST
+                                        * bits while setting the count to 1.
+                                        */
+                                       data_cnt = 1|(sglen&(~AHD_SG_LEN_MASK));
+-                                      data_addr = ahd_le32toh(sg->addr)
++                                      data_addr = aic_le32toh(sg->addr)
+                                                 + (sglen & AHD_SG_LEN_MASK)
+                                                 - 1;
+@@ -4502,7 +4854,8 @@ ahd_handle_ign_wide_residue(struct ahd_s
+                        * correct for subsequent data transfers.
+                        */
+                       ahd_outb(ahd, SCB_TASK_ATTRIBUTE,
+-                          ahd_inb(ahd, SCB_TASK_ATTRIBUTE) ^ SCB_XFERLEN_ODD);
++                          ahd_inb_scbram(ahd, SCB_TASK_ATTRIBUTE)
++                          ^ SCB_XFERLEN_ODD);
+                       ahd_outl(ahd, SCB_RESIDUAL_SGPTR, sgptr);
+                       ahd_outl(ahd, SCB_RESIDUAL_DATACNT, data_cnt);
+@@ -4542,9 +4895,8 @@ ahd_reinitialize_dataptrs(struct ahd_sof
+        */
+       ahd_outb(ahd, DFFSXFRCTL, CLRCHN);
+       wait = 1000;
+-      do {
+-              ahd_delay(100);
+-      } while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE));
++      while (--wait && !(ahd_inb(ahd, MDFFSTAT) & FIFOFREE))
++              aic_delay(100);
+       if (wait == 0) {
+               ahd_print_path(ahd, scb);
+               printf("ahd_reinitialize_dataptrs: Forcing FIFO free.\n");
+@@ -4560,10 +4912,7 @@ ahd_reinitialize_dataptrs(struct ahd_sof
+        * Determine initial values for data_addr and data_cnt
+        * for resuming the data phase.
+        */
+-      sgptr = (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 3) << 24)
+-            | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 2) << 16)
+-            | (ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR + 1) << 8)
+-            | ahd_inb_scbram(ahd, SCB_RESIDUAL_SGPTR);
++      sgptr = ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR);
+       sgptr &= SG_PTR_MASK;
+       resid = (ahd_inb_scbram(ahd, SCB_RESIDUAL_DATACNT + 2) << 16)
+@@ -4578,13 +4927,10 @@ ahd_reinitialize_dataptrs(struct ahd_sof
+               /* The residual sg_ptr always points to the next sg */
+               sg--;
+-              dataptr = ahd_le64toh(sg->addr)
+-                      + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK)
++              dataptr = aic_le64toh(sg->addr)
++                      + (aic_le32toh(sg->len) & AHD_SG_LEN_MASK)
+                       - resid;
+-              ahd_outb(ahd, HADDR + 7, dataptr >> 56);
+-              ahd_outb(ahd, HADDR + 6, dataptr >> 48);
+-              ahd_outb(ahd, HADDR + 5, dataptr >> 40);
+-              ahd_outb(ahd, HADDR + 4, dataptr >> 32);
++              ahd_outl(ahd, HADDR + 4, dataptr >> 32);
+       } else {
+               struct   ahd_dma_seg *sg;
+@@ -4593,16 +4939,13 @@ ahd_reinitialize_dataptrs(struct ahd_sof
+               /* The residual sg_ptr always points to the next sg */
+               sg--;
+-              dataptr = ahd_le32toh(sg->addr)
+-                      + (ahd_le32toh(sg->len) & AHD_SG_LEN_MASK)
++              dataptr = aic_le32toh(sg->addr)
++                      + (aic_le32toh(sg->len) & AHD_SG_LEN_MASK)
+                       - resid;
+               ahd_outb(ahd, HADDR + 4,
+-                       (ahd_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24);
++                       (aic_le32toh(sg->len) & ~AHD_SG_LEN_MASK) >> 24);
+       }
+-      ahd_outb(ahd, HADDR + 3, dataptr >> 24);
+-      ahd_outb(ahd, HADDR + 2, dataptr >> 16);
+-      ahd_outb(ahd, HADDR + 1, dataptr >> 8);
+-      ahd_outb(ahd, HADDR, dataptr);
++      ahd_outl(ahd, HADDR, dataptr);
+       ahd_outb(ahd, HCNT + 2, resid >> 16);
+       ahd_outb(ahd, HCNT + 1, resid >> 8);
+       ahd_outb(ahd, HCNT, resid);
+@@ -4796,8 +5139,8 @@ ahd_alloc(void *platform_arg, char *name
+       ahd->bugs = AHD_BUGNONE;
+       ahd->flags = AHD_SPCHK_ENB_A|AHD_RESET_BUS_A|AHD_TERM_ENB_A
+                  | AHD_EXTENDED_TRANS_A|AHD_STPWLEVEL_A;
+-      ahd_timer_init(&ahd->reset_timer);
+-      ahd_timer_init(&ahd->stat_timer);
++      aic_timer_init(&ahd->reset_timer);
++      aic_timer_init(&ahd->stat_timer);
+       ahd->int_coalescing_timer = AHD_INT_COALESCING_TIMER_DEFAULT;
+       ahd->int_coalescing_maxcmds = AHD_INT_COALESCING_MAXCMDS_DEFAULT;
+       ahd->int_coalescing_mincmds = AHD_INT_COALESCING_MINCMDS_DEFAULT;
+@@ -4833,24 +5176,24 @@ ahd_softc_insert(struct ahd_softc *ahd)
+ {
+       struct ahd_softc *list_ahd;
+-#if AHD_PCI_CONFIG > 0
++#if AIC_PCI_CONFIG > 0
+       /*
+        * Second Function PCI devices need to inherit some
+        * settings from function 0.
+        */
+       if ((ahd->features & AHD_MULTI_FUNC) != 0) {
+               TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
+-                      ahd_dev_softc_t list_pci;
+-                      ahd_dev_softc_t pci;
++                      aic_dev_softc_t list_pci;
++                      aic_dev_softc_t pci;
+                       list_pci = list_ahd->dev_softc;
+                       pci = ahd->dev_softc;
+-                      if (ahd_get_pci_slot(list_pci) == ahd_get_pci_slot(pci)
+-                       && ahd_get_pci_bus(list_pci) == ahd_get_pci_bus(pci)) {
++                      if (aic_get_pci_slot(list_pci) == aic_get_pci_slot(pci)
++                       && aic_get_pci_bus(list_pci) == aic_get_pci_bus(pci)) {
+                               struct ahd_softc *master;
+                               struct ahd_softc *slave;
+-                              if (ahd_get_pci_function(list_pci) == 0) {
++                              if (aic_get_pci_function(list_pci) == 0) {
+                                       master = list_ahd;
+                                       slave = ahd;
+                               } else {
+@@ -4915,27 +5258,27 @@ ahd_free(struct ahd_softc *ahd)
+ {
+       int i;
++      ahd_terminate_recovery_thread(ahd);
+       switch (ahd->init_level) {
+       default:
+       case 5:
+               ahd_shutdown(ahd);
+-              TAILQ_REMOVE(&ahd_tailq, ahd, links);
+               /* FALLTHROUGH */
+       case 4:
+-              ahd_dmamap_unload(ahd, ahd->shared_data_dmat,
+-                                ahd->shared_data_dmamap);
++              aic_dmamap_unload(ahd, ahd->shared_data_dmat,
++                                ahd->shared_data_map.dmamap);
+               /* FALLTHROUGH */
+       case 3:
+-              ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo,
+-                              ahd->shared_data_dmamap);
+-              ahd_dmamap_destroy(ahd, ahd->shared_data_dmat,
+-                                 ahd->shared_data_dmamap);
++              aic_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo,
++                              ahd->shared_data_map.dmamap);
++              aic_dmamap_destroy(ahd, ahd->shared_data_dmat,
++                                 ahd->shared_data_map.dmamap);
+               /* FALLTHROUGH */
+       case 2:
+-              ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat);
++              aic_dma_tag_destroy(ahd, ahd->shared_data_dmat);
+       case 1:
+ #ifndef __linux__
+-              ahd_dma_tag_destroy(ahd, ahd->buffer_dmat);
++              aic_dma_tag_destroy(ahd, ahd->buffer_dmat);
+ #endif
+               break;
+       case 0:
+@@ -4943,7 +5286,7 @@ ahd_free(struct ahd_softc *ahd)
+       }
+ #ifndef __linux__
+-      ahd_dma_tag_destroy(ahd, ahd->parent_dmat);
++      aic_dma_tag_destroy(ahd, ahd->parent_dmat);
+ #endif
+       ahd_platform_free(ahd);
+       ahd_fini_scbdata(ahd);
+@@ -4996,19 +5339,24 @@ ahd_shutdown(void *arg)
+       /*
+        * Stop periodic timer callbacks.
+        */
+-      ahd_timer_stop(&ahd->reset_timer);
+-      ahd_timer_stop(&ahd->stat_timer);
++      aic_timer_stop(&ahd->reset_timer);
++      aic_timer_stop(&ahd->stat_timer);
+       /* This will reset most registers to 0, but not all */
+-      ahd_reset(ahd);
++      ahd_reset(ahd, /*reinit*/FALSE);
+ }
+ /*
+  * Reset the controller and record some information about it
+- * that is only available just after a reset.
++ * that is only available just after a reset.  If "reinit" is
++ * non-zero, this reset occured after initial configuration
++ * and the caller requests that the chip be fully reinitialized
++ * to a runable state.  Chip interrupts are *not* enabled after
++ * a reinitialization.  The caller must enable interrupts via
++ * ahd_intr_enable().
+  */
+ int
+-ahd_reset(struct ahd_softc *ahd)
++ahd_reset(struct ahd_softc *ahd, int reinit)
+ {
+       u_int    sxfrctl1;
+       int      wait;
+@@ -5024,7 +5372,7 @@ ahd_reset(struct ahd_softc *ahd)
+       ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
+       sxfrctl1 = ahd_inb(ahd, SXFRCTL1);
+-      cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
++      cmd = aic_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
+       if ((ahd->bugs & AHD_PCIX_CHIPRST_BUG) != 0) {
+               uint32_t mod_cmd;
+@@ -5038,7 +5386,7 @@ ahd_reset(struct ahd_softc *ahd)
+                * PERR and SERR responses during the CHIPRST.
+                */
+               mod_cmd = cmd & ~(PCIM_CMD_PERRESPEN|PCIM_CMD_SERRESPEN);
+-              ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
++              aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
+                                    mod_cmd, /*bytes*/2);
+       }
+       ahd_outb(ahd, HCNTRL, CHIPRST | ahd->pause);
+@@ -5051,7 +5399,7 @@ ahd_reset(struct ahd_softc *ahd)
+        */
+       wait = 1000;
+       do {
+-              ahd_delay(1000);
++              aic_delay(1000);
+       } while (--wait && !(ahd_inb(ahd, HCNTRL) & CHIPRSTACK));
+       if (wait == 0) {
+@@ -5065,9 +5413,9 @@ ahd_reset(struct ahd_softc *ahd)
+                * Clear any latched PCI error status and restore
+                * previous SERR and PERR response enables.
+                */
+-              ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
++              aic_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
+                                    0xFF, /*bytes*/1);
+-              ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
++              aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
+                                    cmd, /*bytes*/2);
+       }
+@@ -5101,7 +5449,7 @@ ahd_reset(struct ahd_softc *ahd)
+        * If a recovery action has forced a chip reset,
+        * re-initialize the chip to our liking.
+        */
+-      if (ahd->init_level > 0)
++      if (reinit != 0)
+               ahd_chip_init(ahd);
+       return (0);
+@@ -5194,7 +5542,7 @@ ahd_init_scbdata(struct ahd_softc *ahd)
+        */
+       /* DMA tag for our hardware scb structures */
+-      if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
++      if (aic_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
+                              /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+                              /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+                              /*highaddr*/BUS_SPACE_MAXADDR,
+@@ -5208,7 +5556,7 @@ ahd_init_scbdata(struct ahd_softc *ahd)
+       scb_data->init_level++;
+       /* DMA tag for our S/G structures. */
+-      if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/8,
++      if (aic_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/8,
+                              /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+                              /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+                              /*highaddr*/BUS_SPACE_MAXADDR,
+@@ -5227,7 +5575,7 @@ ahd_init_scbdata(struct ahd_softc *ahd)
+       scb_data->init_level++;
+       /* DMA tag for our sense buffers.  We allocate in page sized chunks */
+-      if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
++      if (aic_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
+                              /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+                              /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+                              /*highaddr*/BUS_SPACE_MAXADDR,
+@@ -5315,13 +5663,13 @@ ahd_fini_scbdata(struct ahd_softc *ahd)
+               while ((sns_map = SLIST_FIRST(&scb_data->sense_maps)) != NULL) {
+                       SLIST_REMOVE_HEAD(&scb_data->sense_maps, links);
+-                      ahd_dmamap_unload(ahd, scb_data->sense_dmat,
++                      aic_dmamap_unload(ahd, scb_data->sense_dmat,
+                                         sns_map->dmamap);
+-                      ahd_dmamem_free(ahd, scb_data->sense_dmat,
++                      aic_dmamem_free(ahd, scb_data->sense_dmat,
+                                       sns_map->vaddr, sns_map->dmamap);
+                       free(sns_map, M_DEVBUF);
+               }
+-              ahd_dma_tag_destroy(ahd, scb_data->sense_dmat);
++              aic_dma_tag_destroy(ahd, scb_data->sense_dmat);
+               /* FALLTHROUGH */
+       }
+       case 6:
+@@ -5330,13 +5678,13 @@ ahd_fini_scbdata(struct ahd_softc *ahd)
+               while ((sg_map = SLIST_FIRST(&scb_data->sg_maps)) != NULL) {
+                       SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
+-                      ahd_dmamap_unload(ahd, scb_data->sg_dmat,
++                      aic_dmamap_unload(ahd, scb_data->sg_dmat,
+                                         sg_map->dmamap);
+-                      ahd_dmamem_free(ahd, scb_data->sg_dmat,
++                      aic_dmamem_free(ahd, scb_data->sg_dmat,
+                                       sg_map->vaddr, sg_map->dmamap);
+                       free(sg_map, M_DEVBUF);
+               }
+-              ahd_dma_tag_destroy(ahd, scb_data->sg_dmat);
++              aic_dma_tag_destroy(ahd, scb_data->sg_dmat);
+               /* FALLTHROUGH */
+       }
+       case 5:
+@@ -5345,13 +5693,13 @@ ahd_fini_scbdata(struct ahd_softc *ahd)
+               while ((hscb_map = SLIST_FIRST(&scb_data->hscb_maps)) != NULL) {
+                       SLIST_REMOVE_HEAD(&scb_data->hscb_maps, links);
+-                      ahd_dmamap_unload(ahd, scb_data->hscb_dmat,
++                      aic_dmamap_unload(ahd, scb_data->hscb_dmat,
+                                         hscb_map->dmamap);
+-                      ahd_dmamem_free(ahd, scb_data->hscb_dmat,
++                      aic_dmamem_free(ahd, scb_data->hscb_dmat,
+                                       hscb_map->vaddr, hscb_map->dmamap);
+                       free(hscb_map, M_DEVBUF);
+               }
+-              ahd_dma_tag_destroy(ahd, scb_data->hscb_dmat);
++              aic_dma_tag_destroy(ahd, scb_data->hscb_dmat);
+               /* FALLTHROUGH */
+       }
+       case 4:
+@@ -5382,6 +5730,7 @@ ahd_setup_iocell_workaround(struct ahd_s
+               printf("%s: Setting up iocell workaround\n", ahd_name(ahd));
+ #endif
+       ahd_restore_modes(ahd, saved_modes);
++      ahd->flags &= ~AHD_HAD_FIRST_SEL;
+ }
+ static void
+@@ -5390,6 +5739,8 @@ ahd_iocell_first_selection(struct ahd_so
+       ahd_mode_state  saved_modes;
+       u_int           sblkctl;
++      if ((ahd->flags & AHD_HAD_FIRST_SEL) != 0)
++              return;
+       saved_modes = ahd_save_modes(ahd);
+       ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
+       sblkctl = ahd_inb(ahd, SBLKCTL);
+@@ -5409,6 +5760,7 @@ ahd_iocell_first_selection(struct ahd_so
+       ahd_outb(ahd, SIMODE0, ahd_inb(ahd, SIMODE0) & ~(ENSELDO|ENSELDI));
+       ahd_outb(ahd, CLRINT, CLRSCSIINT);
+       ahd_restore_modes(ahd, saved_modes);
++      ahd->flags |= AHD_HAD_FIRST_SEL;
+ }
+ /*************************** SCB Management ***********************************/
+@@ -5552,7 +5904,7 @@ ahd_free_scb(struct ahd_softc *ahd, stru
+                                scb, links.le);
+       }
+-      ahd_platform_scb_free(ahd, scb);
++      aic_platform_scb_free(ahd, scb);
+ }
+ void
+@@ -5583,7 +5935,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+               offset = (PAGE_SIZE / sizeof(*hscb)) - scb_data->scbs_left;
+               hscb_map = SLIST_FIRST(&scb_data->hscb_maps);
+               hscb = &((struct hardware_scb *)hscb_map->vaddr)[offset];
+-              hscb_busaddr = hscb_map->physaddr + (offset * sizeof(*hscb));
++              hscb_busaddr = hscb_map->busaddr + (offset * sizeof(*hscb));
+       } else {
+               hscb_map = malloc(sizeof(*hscb_map), M_DEVBUF, M_NOWAIT);
+@@ -5591,7 +5943,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+                       return;
+               /* Allocate the next batch of hardware SCBs */
+-              if (ahd_dmamem_alloc(ahd, scb_data->hscb_dmat,
++              if (aic_dmamem_alloc(ahd, scb_data->hscb_dmat,
+                                    (void **)&hscb_map->vaddr,
+                                    BUS_DMA_NOWAIT, &hscb_map->dmamap) != 0) {
+                       free(hscb_map, M_DEVBUF);
+@@ -5600,12 +5952,12 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+               SLIST_INSERT_HEAD(&scb_data->hscb_maps, hscb_map, links);
+-              ahd_dmamap_load(ahd, scb_data->hscb_dmat, hscb_map->dmamap,
++              aic_dmamap_load(ahd, scb_data->hscb_dmat, hscb_map->dmamap,
+                               hscb_map->vaddr, PAGE_SIZE, ahd_dmamap_cb,
+-                              &hscb_map->physaddr, /*flags*/0);
++                              &hscb_map->busaddr, /*flags*/0);
+               hscb = (struct hardware_scb *)hscb_map->vaddr;
+-              hscb_busaddr = hscb_map->physaddr;
++              hscb_busaddr = hscb_map->busaddr;
+               scb_data->scbs_left = PAGE_SIZE / sizeof(*hscb);
+       }
+@@ -5616,7 +5968,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+                      - scb_data->sgs_left) * ahd_sglist_size(ahd);
+               sg_map = SLIST_FIRST(&scb_data->sg_maps);
+               segs = sg_map->vaddr + offset;
+-              sg_busaddr = sg_map->physaddr + offset;
++              sg_busaddr = sg_map->busaddr + offset;
+       } else {
+               sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
+@@ -5624,7 +5976,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+                       return;
+               /* Allocate the next batch of S/G lists */
+-              if (ahd_dmamem_alloc(ahd, scb_data->sg_dmat,
++              if (aic_dmamem_alloc(ahd, scb_data->sg_dmat,
+                                    (void **)&sg_map->vaddr,
+                                    BUS_DMA_NOWAIT, &sg_map->dmamap) != 0) {
+                       free(sg_map, M_DEVBUF);
+@@ -5633,12 +5985,12 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+               SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
+-              ahd_dmamap_load(ahd, scb_data->sg_dmat, sg_map->dmamap,
++              aic_dmamap_load(ahd, scb_data->sg_dmat, sg_map->dmamap,
+                               sg_map->vaddr, ahd_sglist_allocsize(ahd),
+-                              ahd_dmamap_cb, &sg_map->physaddr, /*flags*/0);
++                              ahd_dmamap_cb, &sg_map->busaddr, /*flags*/0);
+               segs = sg_map->vaddr;
+-              sg_busaddr = sg_map->physaddr;
++              sg_busaddr = sg_map->busaddr;
+               scb_data->sgs_left =
+                   ahd_sglist_allocsize(ahd) / ahd_sglist_size(ahd);
+ #ifdef AHD_DEBUG
+@@ -5653,7 +6005,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+               offset = PAGE_SIZE - (AHD_SENSE_BUFSIZE * scb_data->sense_left);
+               sense_map = SLIST_FIRST(&scb_data->sense_maps);
+               sense_data = sense_map->vaddr + offset;
+-              sense_busaddr = sense_map->physaddr + offset;
++              sense_busaddr = sense_map->busaddr + offset;
+       } else {
+               sense_map = malloc(sizeof(*sense_map), M_DEVBUF, M_NOWAIT);
+@@ -5661,7 +6013,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+                       return;
+               /* Allocate the next batch of sense buffers */
+-              if (ahd_dmamem_alloc(ahd, scb_data->sense_dmat,
++              if (aic_dmamem_alloc(ahd, scb_data->sense_dmat,
+                                    (void **)&sense_map->vaddr,
+                                    BUS_DMA_NOWAIT, &sense_map->dmamap) != 0) {
+                       free(sense_map, M_DEVBUF);
+@@ -5670,12 +6022,12 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+               SLIST_INSERT_HEAD(&scb_data->sense_maps, sense_map, links);
+-              ahd_dmamap_load(ahd, scb_data->sense_dmat, sense_map->dmamap,
++              aic_dmamap_load(ahd, scb_data->sense_dmat, sense_map->dmamap,
+                               sense_map->vaddr, PAGE_SIZE, ahd_dmamap_cb,
+-                              &sense_map->physaddr, /*flags*/0);
++                              &sense_map->busaddr, /*flags*/0);
+               sense_data = sense_map->vaddr;
+-              sense_busaddr = sense_map->physaddr;
++              sense_busaddr = sense_map->busaddr;
+               scb_data->sense_left = PAGE_SIZE / AHD_SENSE_BUFSIZE;
+ #ifdef AHD_DEBUG
+               if (ahd_debug & AHD_SHOW_MEMORY)
+@@ -5716,7 +6068,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+               next_scb->sense_busaddr = sense_busaddr;
+               memset(hscb, 0, sizeof(*hscb));
+               next_scb->hscb = hscb;
+-              hscb->hscb_busaddr = ahd_htole32(hscb_busaddr);
++              hscb->hscb_busaddr = aic_htole32(hscb_busaddr);
+               /*
+                * The sequencer always starts with the second entry.
+@@ -5731,7 +6083,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+               next_scb->ahd_softc = ahd;
+               next_scb->flags = SCB_FLAG_NONE;
+ #ifndef __linux__
+-              error = ahd_dmamap_create(ahd, ahd->buffer_dmat, /*flags*/0,
++              error = aic_dmamap_create(ahd, ahd->buffer_dmat, /*flags*/0,
+                                         &next_scb->dmamap);
+               if (error != 0) {
+                       free(next_scb, M_DEVBUF);
+@@ -5739,7 +6091,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd)
+                       break;
+               }
+ #endif
+-              next_scb->hscb->tag = ahd_htole16(scb_data->numscbs);
++              next_scb->hscb->tag = aic_htole16(scb_data->numscbs);
+               col_tag = scb_data->numscbs ^ 0x100;
+               next_scb->col_scb = ahd_find_scb_by_tag(ahd, col_tag);
+               if (next_scb->col_scb != NULL)
+@@ -5799,7 +6151,6 @@ static const char *termstat_strings[] = 
+ int
+ ahd_init(struct ahd_softc *ahd)
+ {
+-      uint8_t         *base_vaddr;
+       uint8_t         *next_vaddr;
+       bus_addr_t       next_baddr;
+       size_t           driver_data_size;
+@@ -5842,7 +6193,7 @@ ahd_init(struct ahd_softc *ahd)
+ #ifndef __linux__
+       /* DMA tag for mapping buffers into device visible space. */
+-      if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
++      if (aic_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
+                              /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+                              /*lowaddr*/ahd->flags & AHD_39BIT_ADDRESSING
+                                       ? (bus_addr_t)0x7FFFFFFFFFULL
+@@ -5873,7 +6224,7 @@ ahd_init(struct ahd_softc *ahd)
+               driver_data_size += AHD_TMODE_CMDS * sizeof(struct target_cmd);
+       if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0)
+               driver_data_size += PKT_OVERRUN_BUFSIZE;
+-      if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
++      if (aic_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1,
+                              /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+                              /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+                              /*highaddr*/BUS_SPACE_MAXADDR,
+@@ -5888,21 +6239,24 @@ ahd_init(struct ahd_softc *ahd)
+       ahd->init_level++;
+       /* Allocation of driver data */
+-      if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat,
+-                           (void **)&base_vaddr,
+-                           BUS_DMA_NOWAIT, &ahd->shared_data_dmamap) != 0) {
++      if (aic_dmamem_alloc(ahd, ahd->shared_data_dmat,
++                           (void **)&ahd->shared_data_map.vaddr,
++                           BUS_DMA_NOWAIT,
++                           &ahd->shared_data_map.dmamap) != 0) {
+               return (ENOMEM);
+       }
+       ahd->init_level++;
+       /* And permanently map it in */
+-      ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap,
+-                      base_vaddr, driver_data_size, ahd_dmamap_cb,
+-                      &ahd->shared_data_busaddr, /*flags*/0);
+-      ahd->qoutfifo = (uint16_t *)base_vaddr;
++      aic_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,
++                      ahd->shared_data_map.vaddr, driver_data_size,
++                      ahd_dmamap_cb, &ahd->shared_data_map.busaddr,
++                      /*flags*/0);
++      ahd->qoutfifo = (uint16_t *)ahd->shared_data_map.vaddr;
+       next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE];
+-      next_baddr = ahd->shared_data_busaddr + AHD_QOUT_SIZE*sizeof(uint16_t);
++      next_baddr = ahd->shared_data_map.busaddr
++                 + AHD_QOUT_SIZE*sizeof(uint16_t);
+       if ((ahd->features & AHD_TARGETMODE) != 0) {
+               ahd->targetcmds = (struct target_cmd *)next_vaddr;
+               next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd);
+@@ -5923,7 +6277,8 @@ ahd_init(struct ahd_softc *ahd)
+        * specially from the DMA safe memory chunk used for the QOUTFIFO.
+        */
+       ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr;
+-      ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr);
++      ahd->next_queued_hscb_map = &ahd->shared_data_map;
++      ahd->next_queued_hscb->hscb_busaddr = aic_htole32(next_baddr);
+       ahd->init_level++;
+@@ -6014,7 +6369,7 @@ ahd_init(struct ahd_softc *ahd)
+       }
+ init_done:
+       ahd_restart(ahd);
+-      ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
++      aic_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
+                       ahd_stat_timer, ahd);
+       return (0);
+ }
+@@ -6075,7 +6430,7 @@ ahd_chip_init(struct ahd_softc *ahd)
+       for (wait = 10000;
+            (ahd_inb(ahd, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
+            wait--)
+-              ahd_delay(100);
++              aic_delay(100);
+       /* Clear any false bus resets due to the transceivers settling */
+       ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
+@@ -6174,7 +6529,7 @@ ahd_chip_init(struct ahd_softc *ahd)
+               ahd_outb(ahd, LUNLEN,
+                        sizeof(ahd->next_queued_hscb->pkt_long_lun) - 1);
+       } else {
+-              ahd_outb(ahd, LUNLEN, sizeof(ahd->next_queued_hscb->lun) - 1);
++              ahd_outb(ahd, LUNLEN, LUNLEN_SINGLE_LEVEL_LUN);
+       }
+       ahd_outb(ahd, CDBLIMIT, SCB_CDB_LEN_PTR - 1);
+       ahd_outb(ahd, MAXCMD, 0xFF);
+@@ -6215,6 +6570,7 @@ ahd_chip_init(struct ahd_softc *ahd)
+       ahd_outb(ahd, CLRSINT3, NTRAMPERR|OSRAMPERR);
+       ahd_outb(ahd, CLRINT, CLRSCSIINT);
++#if NEEDS_MORE_TESTING
+       /*
+        * Always enable abort on incoming L_Qs if this feature is
+        * supported.  We use this to catch invalid SCB references.
+@@ -6222,6 +6578,7 @@ ahd_chip_init(struct ahd_softc *ahd)
+       if ((ahd->bugs & AHD_ABORT_LQI_BUG) == 0)
+               ahd_outb(ahd, LQCTL1, ABORTPENDING);
+       else
++#endif
+               ahd_outb(ahd, LQCTL1, 0);
+       /* All of our queues are empty */
+@@ -6271,15 +6628,9 @@ ahd_chip_init(struct ahd_softc *ahd)
+       /*
+        * Tell the sequencer where it can find our arrays in memory.
+        */
+-      busaddr = ahd->shared_data_busaddr;
+-      ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF);
+-      ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF);
+-      ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF);
+-      ahd_outb(ahd, SHARED_DATA_ADDR + 3, (busaddr >> 24) & 0xFF);
+-      ahd_outb(ahd, QOUTFIFO_NEXT_ADDR, busaddr & 0xFF);
+-      ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 1, (busaddr >> 8) & 0xFF);
+-      ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 2, (busaddr >> 16) & 0xFF);
+-      ahd_outb(ahd, QOUTFIFO_NEXT_ADDR + 3, (busaddr >> 24) & 0xFF);
++      busaddr = ahd->shared_data_map.busaddr;
++      ahd_outl(ahd, SHARED_DATA_ADDR, busaddr);
++      ahd_outl(ahd, QOUTFIFO_NEXT_ADDR, busaddr);
+       /*
+        * Setup the allowed SCSI Sequences based on operational mode.
+@@ -6327,11 +6678,8 @@ ahd_chip_init(struct ahd_softc *ahd)
+       /*
+        * Tell the sequencer which SCB will be the next one it receives.
+        */
+-      busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
+-      ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
+-      ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
+-      ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
+-      ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
++      busaddr = aic_le32toh(ahd->next_queued_hscb->hscb_busaddr);
++      ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);
+       /*
+        * Default to coalescing disabled.
+@@ -6652,6 +7000,12 @@ ahd_pause_and_flushwork(struct ahd_softc
+               struct scb *waiting_scb;
+               ahd_unpause(ahd);
++              /*
++               * Give the sequencer some time to service
++               * any active selections.
++               */
++              aic_delay(200);
++
+               ahd_intr(ahd);
+               ahd_pause(ahd);
+               ahd_clear_critical_section(ahd);
+@@ -6703,141 +7057,24 @@ ahd_pause_and_flushwork(struct ahd_softc
+ int
+ ahd_suspend(struct ahd_softc *ahd)
+ {
+-#if 0
+-      uint8_t *ptr;
+-      int      i;
+       ahd_pause_and_flushwork(ahd);
+-      if (LIST_FIRST(&ahd->pending_scbs) != NULL)
+-              return (EBUSY);
+-
+-#if AHD_TARGET_MODE
+-      /*
+-       * XXX What about ATIOs that have not yet been serviced?
+-       * Perhaps we should just refuse to be suspended if we
+-       * are acting in a target role.
+-       */
+-      if (ahd->pending_device != NULL)
++      if (LIST_FIRST(&ahd->pending_scbs) != NULL) {
++              ahd_unpause(ahd);
+               return (EBUSY);
+-#endif
+-
+-      /* Save volatile registers */
+-      ahd->suspend_state.channel[0].scsiseq = ahd_inb(ahd, SCSISEQ0);
+-      ahd->suspend_state.channel[0].sxfrctl0 = ahd_inb(ahd, SXFRCTL0);
+-      ahd->suspend_state.channel[0].sxfrctl1 = ahd_inb(ahd, SXFRCTL1);
+-      ahd->suspend_state.channel[0].simode0 = ahd_inb(ahd, SIMODE0);
+-      ahd->suspend_state.channel[0].simode1 = ahd_inb(ahd, SIMODE1);
+-      ahd->suspend_state.channel[0].seltimer = ahd_inb(ahd, SELTIMER);
+-      ahd->suspend_state.channel[0].seqctl = ahd_inb(ahd, SEQCTL0);
+-      ahd->suspend_state.dscommand0 = ahd_inb(ahd, DSCOMMAND0);
+-      ahd->suspend_state.dspcistatus = ahd_inb(ahd, DSPCISTATUS);
+-
+-      if ((ahd->features & AHD_DT) != 0) {
+-              u_int sfunct;
+-
+-              sfunct = ahd_inb(ahd, SFUNCT) & ~ALT_MODE;
+-              ahd_outb(ahd, SFUNCT, sfunct | ALT_MODE);
+-              ahd->suspend_state.optionmode = ahd_inb(ahd, OPTIONMODE);
+-              ahd_outb(ahd, SFUNCT, sfunct);
+-              ahd->suspend_state.crccontrol1 = ahd_inb(ahd, CRCCONTROL1);
+-      }
+-
+-      if ((ahd->features & AHD_MULTI_FUNC) != 0)
+-              ahd->suspend_state.scbbaddr = ahd_inb(ahd, SCBBADDR);
+-
+-      if ((ahd->features & AHD_ULTRA2) != 0)
+-              ahd->suspend_state.dff_thrsh = ahd_inb(ahd, DFF_THRSH);
+-
+-      ptr = ahd->suspend_state.scratch_ram;
+-      for (i = 0; i < 64; i++)
+-              *ptr++ = ahd_inb(ahd, SRAM_BASE + i);
+-
+-      if ((ahd->features & AHD_MORE_SRAM) != 0) {
+-              for (i = 0; i < 16; i++)
+-                      *ptr++ = ahd_inb(ahd, TARG_OFFSET + i);
+-      }
+-
+-      ptr = ahd->suspend_state.btt;
+-      for (i = 0;i < AHD_NUM_TARGETS; i++) {
+-              int j;
+-
+-              for (j = 0;j < AHD_NUM_LUNS_NONPKT; j++) {
+-                      u_int tcl;
+-
+-                      tcl = BUILD_TCL_RAW(i, 'A', j);
+-                      *ptr = ahd_find_busy_tcl(ahd, tcl);
+-              }
+       }
+       ahd_shutdown(ahd);
+-#endif
+       return (0);
+ }
+ int
+ ahd_resume(struct ahd_softc *ahd)
+ {
+-#if 0
+-      uint8_t *ptr;
+-      int      i;
+-
+-      ahd_reset(ahd);
+-
+-      ahd_build_free_scb_list(ahd);
+-
+-      /* Restore volatile registers */
+-      ahd_outb(ahd, SCSISEQ0, ahd->suspend_state.channel[0].scsiseq);
+-      ahd_outb(ahd, SXFRCTL0, ahd->suspend_state.channel[0].sxfrctl0);
+-      ahd_outb(ahd, SXFRCTL1, ahd->suspend_state.channel[0].sxfrctl1);
+-      ahd_outb(ahd, SIMODE0, ahd->suspend_state.channel[0].simode0);
+-      ahd_outb(ahd, SIMODE1, ahd->suspend_state.channel[0].simode1);
+-      ahd_outb(ahd, SELTIMER, ahd->suspend_state.channel[0].seltimer);
+-      ahd_outb(ahd, SEQCTL0, ahd->suspend_state.channel[0].seqctl);
+-      if ((ahd->features & AHD_ULTRA2) != 0)
+-              ahd_outb(ahd, SCSIID_ULTRA2, ahd->our_id);
+-      else
+-              ahd_outb(ahd, SCSIID, ahd->our_id);
+-
+-      ahd_outb(ahd, DSCOMMAND0, ahd->suspend_state.dscommand0);
+-      ahd_outb(ahd, DSPCISTATUS, ahd->suspend_state.dspcistatus);
+-
+-      if ((ahd->features & AHD_DT) != 0) {
+-              u_int sfunct;
+-              sfunct = ahd_inb(ahd, SFUNCT) & ~ALT_MODE;
+-              ahd_outb(ahd, SFUNCT, sfunct | ALT_MODE);
+-              ahd_outb(ahd, OPTIONMODE, ahd->suspend_state.optionmode);
+-              ahd_outb(ahd, SFUNCT, sfunct);
+-              ahd_outb(ahd, CRCCONTROL1, ahd->suspend_state.crccontrol1);
+-      }
+-
+-      if ((ahd->features & AHD_MULTI_FUNC) != 0)
+-              ahd_outb(ahd, SCBBADDR, ahd->suspend_state.scbbaddr);
+-
+-      if ((ahd->features & AHD_ULTRA2) != 0)
+-              ahd_outb(ahd, DFF_THRSH, ahd->suspend_state.dff_thrsh);
+-
+-      ptr = ahd->suspend_state.scratch_ram;
+-      for (i = 0; i < 64; i++)
+-              ahd_outb(ahd, SRAM_BASE + i, *ptr++);
+-
+-      if ((ahd->features & AHD_MORE_SRAM) != 0) {
+-              for (i = 0; i < 16; i++)
+-                      ahd_outb(ahd, TARG_OFFSET + i, *ptr++);
+-      }
+-
+-      ptr = ahd->suspend_state.btt;
+-      for (i = 0;i < AHD_NUM_TARGETS; i++) {
+-              int j;
+-
+-              for (j = 0;j < AHD_NUM_LUNS; j++) {
+-                      u_int tcl;
+-
+-                      tcl = BUILD_TCL(i << 4, j);
+-                      ahd_busy_tcl(ahd, tcl, *ptr);
+-              }
+-      }
+-#endif
++      ahd_reset(ahd, /*reinit*/TRUE);
++      ahd_intr_enable(ahd, TRUE); 
++      ahd_restart(ahd);
+       return (0);
+ }
+@@ -6980,11 +7217,8 @@ ahd_qinfifo_requeue(struct ahd_softc *ah
+       if (prev_scb == NULL) {
+               uint32_t busaddr;
+-              busaddr = ahd_le32toh(scb->hscb->hscb_busaddr);
+-              ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
+-              ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
+-              ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
+-              ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
++              busaddr = aic_le32toh(scb->hscb->hscb_busaddr);
++              ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);
+       } else {
+               prev_scb->hscb->next_hscb_busaddr = scb->hscb->hscb_busaddr;
+               ahd_sync_scb(ahd, prev_scb, 
+@@ -7090,11 +7324,8 @@ ahd_search_qinfifo(struct ahd_softc *ahd
+        * for removal will be re-added to the queue as we go.
+        */
+       ahd->qinfifonext = qinstart;
+-      busaddr = ahd_le32toh(ahd->next_queued_hscb->hscb_busaddr);
+-      ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 0, busaddr & 0xFF);
+-      ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 1, (busaddr >> 8) & 0xFF);
+-      ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 2, (busaddr >> 16) & 0xFF);
+-      ahd_outb(ahd, NEXT_QUEUED_SCB_ADDR + 3, (busaddr >> 24) & 0xFF);
++      busaddr = aic_le32toh(ahd->next_queued_hscb->hscb_busaddr);
++      ahd_outl(ahd, NEXT_QUEUED_SCB_ADDR, busaddr);
+       while (qinpos != qintail) {
+               scb = ahd_lookup_scb(ahd, ahd->qinfifo[qinpos]);
+@@ -7115,13 +7346,13 @@ ahd_search_qinfifo(struct ahd_softc *ahd
+                               cam_status ostat;
+                               cam_status cstat;
+-                              ostat = ahd_get_transaction_status(scb);
++                              ostat = aic_get_transaction_status(scb);
+                               if (ostat == CAM_REQ_INPROG)
+-                                      ahd_set_transaction_status(scb,
++                                      aic_set_transaction_status(scb,
+                                                                  status);
+-                              cstat = ahd_get_transaction_status(scb);
++                              cstat = aic_get_transaction_status(scb);
+                               if (cstat != CAM_REQ_CMP)
+-                                      ahd_freeze_scb(scb);
++                                      aic_freeze_scb(scb);
+                               if ((scb->flags & SCB_ACTIVE) == 0)
+                                       printf("Inactive SCB in qinfifo\n");
+                               ahd_done(ahd, scb);
+@@ -7257,12 +7488,12 @@ ahd_search_scb_list(struct ahd_softc *ah
+                       cam_status ostat;
+                       cam_status cstat;
+-                      ostat = ahd_get_transaction_status(scb);
++                      ostat = aic_get_transaction_status(scb);
+                       if (ostat == CAM_REQ_INPROG)
+-                              ahd_set_transaction_status(scb, status);
+-                      cstat = ahd_get_transaction_status(scb);
++                              aic_set_transaction_status(scb, status);
++                      cstat = aic_get_transaction_status(scb);
+                       if (cstat != CAM_REQ_CMP)
+-                              ahd_freeze_scb(scb);
++                              aic_freeze_scb(scb);
+                       if ((scb->flags & SCB_ACTIVE) == 0)
+                               printf("Inactive SCB in Waiting List\n");
+                       ahd_done(ahd, scb);
+@@ -7453,11 +7684,11 @@ ahd_abort_scbs(struct ahd_softc *ahd, in
+               if (ahd_match_scb(ahd, scbp, target, channel, lun, tag, role)) {
+                       cam_status ostat;
+-                      ostat = ahd_get_transaction_status(scbp);
++                      ostat = aic_get_transaction_status(scbp);
+                       if (ostat == CAM_REQ_INPROG)
+-                              ahd_set_transaction_status(scbp, status);
+-                      if (ahd_get_transaction_status(scbp) != CAM_REQ_CMP)
+-                              ahd_freeze_scb(scbp);
++                              aic_set_transaction_status(scbp, status);
++                      if (aic_get_transaction_status(scbp) != CAM_REQ_CMP)
++                              aic_freeze_scb(scbp);
+                       if ((scbp->flags & SCB_ACTIVE) == 0)
+                               printf("Inactive SCB on pending list\n");
+                       ahd_done(ahd, scbp);
+@@ -7479,9 +7710,12 @@ ahd_reset_current_bus(struct ahd_softc *
+       ahd_outb(ahd, SIMODE1, ahd_inb(ahd, SIMODE1) & ~ENSCSIRST);
+       scsiseq = ahd_inb(ahd, SCSISEQ0) & ~(ENSELO|ENARBO|SCSIRSTO);
+       ahd_outb(ahd, SCSISEQ0, scsiseq | SCSIRSTO);
+-      ahd_delay(AHD_BUSRESET_DELAY);
++      ahd_flush_device_writes(ahd);
++      aic_delay(AHD_BUSRESET_DELAY);
+       /* Turn off the bus reset */
+       ahd_outb(ahd, SCSISEQ0, scsiseq);
++      ahd_flush_device_writes(ahd);
++      aic_delay(AHD_BUSRESET_DELAY);
+       if ((ahd->bugs & AHD_SCSIRST_BUG) != 0) {
+               /*
+                * 2A Razor #474
+@@ -7489,8 +7723,7 @@ ahd_reset_current_bus(struct ahd_softc *
+                * SCSI bus resets that we initiate, so
+                * we must reset the chip.
+                */
+-              ahd_delay(AHD_BUSRESET_DELAY);
+-              ahd_reset(ahd);
++              ahd_reset(ahd, /*reinit*/TRUE);
+               ahd_intr_enable(ahd, /*enable*/TRUE);
+               AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
+       }
+@@ -7550,7 +7783,7 @@ ahd_reset_channel(struct ahd_softc *ahd,
+               ahd_outb(ahd, DFCNTRL,
+                        ahd_inb(ahd, DFCNTRL) & ~(SCSIEN|HDMAEN));
+               while ((ahd_inb(ahd, DFCNTRL) & HDMAENACK) != 0)
+-                      ahd_delay(10);
++                      aic_delay(10);
+               /*
+                * Set CURRFIFO to the now inactive channel.
+                */
+@@ -7563,7 +7796,7 @@ ahd_reset_channel(struct ahd_softc *ahd,
+        */
+       ahd_clear_msg_state(ahd);
+       ahd_outb(ahd, SIMODE1,
+-               ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST|ENBUSFREE));
++               ahd_inb(ahd, SIMODE1) & ~(ENBUSFREE|ENSCSIRST));
+       if (initiate_reset)
+               ahd_reset_current_bus(ahd);
+@@ -7645,8 +7878,8 @@ ahd_reset_channel(struct ahd_softc *ahd,
+        */
+       if ((ahd->flags & AHD_RESET_POLL_ACTIVE) == 0) {
+               ahd->flags |= AHD_RESET_POLL_ACTIVE;
+-              ahd_freeze_simq(ahd);
+-              ahd_timer_reset(&ahd->reset_timer, 0, ahd_reset_poll, ahd);
++              aic_freeze_simq(ahd);
++              aic_timer_reset(&ahd->reset_timer, 0, ahd_reset_poll, ahd);
+       }
+       return (found);
+ }
+@@ -7674,7 +7907,7 @@ ahd_reset_poll(void *arg)
+       ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
+       ahd_outb(ahd, CLRSINT1, CLRSCSIRSTI);
+       if ((ahd_inb(ahd, SSTAT1) & SCSIRSTI) != 0) {
+-              ahd_timer_reset(&ahd->reset_timer, AHD_RESET_POLL_US,
++              aic_timer_reset(&ahd->reset_timer, AHD_RESET_POLL_US,
+                               ahd_reset_poll, ahd);
+               ahd_unpause(ahd);
+               ahd_unlock(ahd, &s);
+@@ -7689,7 +7922,7 @@ ahd_reset_poll(void *arg)
+       ahd_unpause(ahd);
+       ahd->flags &= ~AHD_RESET_POLL_ACTIVE;
+       ahd_unlock(ahd, &s);
+-      ahd_release_simq(ahd);
++      aic_release_simq(ahd);
+       ahd_list_unlock(&l);
+ }
+@@ -7732,7 +7965,7 @@ ahd_stat_timer(void *arg)
+       ahd->cmdcmplt_bucket = (ahd->cmdcmplt_bucket+1) & (AHD_STAT_BUCKETS-1);
+       ahd->cmdcmplt_total -= ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket];
+       ahd->cmdcmplt_counts[ahd->cmdcmplt_bucket] = 0;
+-      ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
++      aic_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
+                       ahd_stat_timer, ahd);
+       ahd_unlock(ahd, &s);
+       ahd_list_unlock(&l);
+@@ -7753,8 +7986,9 @@ ahd_handle_scb_status(struct ahd_softc *
+ void
+ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
+ {
+-      struct hardware_scb *hscb;
+-      u_int  qfreeze_cnt;
++      struct  hardware_scb *hscb;
++      u_int   qfreeze_cnt;
++      int     paused;
+       /*
+        * The sequencer freezes its select-out queue
+@@ -7764,9 +7998,16 @@ ahd_handle_scsi_status(struct ahd_softc 
+        */
+       hscb = scb->hscb; 
++      if (ahd_is_paused(ahd)) {
++              paused = 1;
++      } else {
++              paused = 0;
++              ahd_pause(ahd);
++      }
++
+       /* Freeze the queue until the client sees the error. */
+       ahd_freeze_devq(ahd, scb);
+-      ahd_freeze_scb(scb);
++      aic_freeze_scb(scb);
+       qfreeze_cnt = ahd_inw(ahd, QFREEZE_COUNT);
+       if (qfreeze_cnt == 0) {
+               printf("%s: Bad status with 0 qfreeze count!\n", ahd_name(ahd));
+@@ -7778,6 +8019,9 @@ ahd_handle_scsi_status(struct ahd_softc 
+               ahd_outb(ahd, SEQ_FLAGS2,
+                        ahd_inb(ahd, SEQ_FLAGS2) & ~SELECTOUT_QFROZEN);
++      if (paused == 0)
++              ahd_unpause(ahd);
++
+       /* Don't want to clobber the original sense code */
+       if ((scb->flags & SCB_SENSE) != 0) {
+               /*
+@@ -7785,12 +8029,12 @@ ahd_handle_scsi_status(struct ahd_softc 
+                * a normal command completion.
+                */
+               scb->flags &= ~SCB_SENSE;
+-              ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
++              aic_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
+               ahd_done(ahd, scb);
+               return;
+       }
+-      ahd_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
+-      ahd_set_scsi_status(scb, hscb->shared_data.istatus.scsi_status);
++      aic_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
++      aic_set_scsi_status(scb, hscb->shared_data.istatus.scsi_status);
+       switch (hscb->shared_data.istatus.scsi_status) {
+       case STATUS_PKT_SENSE:
+       {
+@@ -7798,7 +8042,7 @@ ahd_handle_scsi_status(struct ahd_softc 
+               ahd_sync_sense(ahd, scb, BUS_DMASYNC_POSTREAD);
+               siu = (struct scsi_status_iu_header *)scb->sense_data;
+-              ahd_set_scsi_status(scb, siu->status);
++              aic_set_scsi_status(scb, siu->status);
+ #ifdef AHD_DEBUG
+               if ((ahd_debug & AHD_SHOW_SENSE) != 0) {
+                       ahd_print_path(ahd, scb);
+@@ -7839,7 +8083,7 @@ ahd_handle_scsi_status(struct ahd_softc 
+                               }
+                       }
+                       if (siu->status == SCSI_STATUS_OK)
+-                              ahd_set_transaction_status(scb,
++                              aic_set_transaction_status(scb,
+                                                          CAM_REQ_CMP_ERR);
+               }
+               if ((siu->flags & SIU_SNSVALID) != 0) {
+@@ -7869,7 +8113,7 @@ ahd_handle_scsi_status(struct ahd_softc 
+               }
+ #endif
+-              if (ahd_perform_autosense(scb) == 0)
++              if (aic_perform_autosense(scb) == 0)
+                       break;
+               ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
+@@ -7897,7 +8141,7 @@ ahd_handle_scsi_status(struct ahd_softc 
+ #endif
+               scb->sg_count = 0;
+               sg = ahd_sg_setup(ahd, scb, sg, ahd_get_sense_bufaddr(ahd, scb),
+-                                ahd_get_sense_bufsize(ahd, scb),
++                                aic_get_sense_bufsize(ahd, scb),
+                                 /*last*/TRUE);
+               sc->opcode = REQUEST_SENSE;
+               sc->byte2 = 0;
+@@ -7906,7 +8150,7 @@ ahd_handle_scsi_status(struct ahd_softc 
+                       sc->byte2 = SCB_GET_LUN(scb) << 5;
+               sc->unused[0] = 0;
+               sc->unused[1] = 0;
+-              sc->length = ahd_get_sense_bufsize(ahd, scb);
++              sc->length = aic_get_sense_bufsize(ahd, scb);
+               sc->control = 0;
+               /*
+@@ -7926,7 +8170,7 @@ ahd_handle_scsi_status(struct ahd_softc 
+                * errors will be reported before any data
+                * phases occur.
+                */
+-              if (ahd_get_residual(scb) == ahd_get_transfer_length(scb)) {
++              if (aic_get_residual(scb) == aic_get_transfer_length(scb)) {
+                       ahd_update_neg_request(ahd, &devinfo,
+                                              tstate, targ_info,
+                                              AHD_NEG_IF_NON_ASYNC);
+@@ -7945,7 +8189,7 @@ ahd_handle_scsi_status(struct ahd_softc 
+                * Ensure we have enough time to actually
+                * retrieve the sense.
+                */
+-              ahd_scb_timer_reset(scb, 5 * 1000000);
++              aic_scb_timer_reset(scb, 5 * 1000000);
+               break;
+       }
+       case SCSI_STATUS_OK:
+@@ -7987,7 +8231,7 @@ ahd_calc_residual(struct ahd_softc *ahd,
+        */
+       hscb = scb->hscb;
+-      sgptr = ahd_le32toh(hscb->sgptr);
++      sgptr = aic_le32toh(hscb->sgptr);
+       if ((sgptr & SG_STATUS_VALID) == 0)
+               /* Case 1 */
+               return;
+@@ -8004,10 +8248,10 @@ ahd_calc_residual(struct ahd_softc *ahd,
+        * regardless of the role for this SCB.
+        */
+       spkt = &hscb->shared_data.istatus;
+-      resid_sgptr = ahd_le32toh(spkt->residual_sgptr);
++      resid_sgptr = aic_le32toh(spkt->residual_sgptr);
+       if ((sgptr & SG_FULL_RESID) != 0) {
+               /* Case 3 */
+-              resid = ahd_get_transfer_length(scb);
++              resid = aic_get_transfer_length(scb);
+       } else if ((resid_sgptr & SG_LIST_NULL) != 0) {
+               /* Case 4 */
+               return;
+@@ -8016,8 +8260,8 @@ ahd_calc_residual(struct ahd_softc *ahd,
+               printf("data overrun detected Tag == 0x%x.\n",
+                      SCB_GET_TAG(scb));
+               ahd_freeze_devq(ahd, scb);
+-              ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
+-              ahd_freeze_scb(scb);
++              aic_set_transaction_status(scb, CAM_DATA_RUN_ERR);
++              aic_freeze_scb(scb);
+               return;
+       } else if ((resid_sgptr & ~SG_PTR_MASK) != 0) {
+               panic("Bogus resid sgptr value 0x%x\n", resid_sgptr);
+@@ -8029,7 +8273,7 @@ ahd_calc_residual(struct ahd_softc *ahd,
+                * Remainder of the SG where the transfer
+                * stopped.  
+                */
+-              resid = ahd_le32toh(spkt->residual_datacnt) & AHD_SG_LEN_MASK;
++              resid = aic_le32toh(spkt->residual_datacnt) & AHD_SG_LEN_MASK;
+               sg = ahd_sg_bus_to_virt(ahd, scb, resid_sgptr & SG_PTR_MASK);
+               /* The residual sg_ptr always points to the next sg */
+@@ -8040,15 +8284,15 @@ ahd_calc_residual(struct ahd_softc *ahd,
+                * SG segments that are after the SG where
+                * the transfer stopped.
+                */
+-              while ((ahd_le32toh(sg->len) & AHD_DMA_LAST_SEG) == 0) {
++              while ((aic_le32toh(sg->len) & AHD_DMA_LAST_SEG) == 0) {
+                       sg++;
+-                      resid += ahd_le32toh(sg->len) & AHD_SG_LEN_MASK;
++                      resid += aic_le32toh(sg->len) & AHD_SG_LEN_MASK;
+               }
+       }
+       if ((scb->flags & SCB_SENSE) == 0)
+-              ahd_set_residual(scb, resid);
++              aic_set_residual(scb, resid);
+       else
+-              ahd_set_sense_residual(scb, resid);
++              aic_set_sense_residual(scb, resid);
+ #ifdef AHD_DEBUG
+       if ((ahd_debug & AHD_SHOW_MISC) != 0) {
+@@ -8160,8 +8404,7 @@ ahd_dumpseq(struct ahd_softc* ahd)
+       max_prog = 2048;
+       ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
+-      ahd_outb(ahd, PRGMCNT, 0);
+-      ahd_outb(ahd, PRGMCNT+1, 0);
++      ahd_outw(ahd, PRGMCNT, 0);
+       for (i = 0; i < max_prog; i++) {
+               uint8_t ins_bytes[4];
+@@ -8276,8 +8519,7 @@ ahd_loadseq(struct ahd_softc *ahd)
+       downloaded = 0;
+       skip_addr = 0;
+       ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE|LOADRAM);
+-      ahd_outb(ahd, PRGMCNT, 0);
+-      ahd_outb(ahd, PRGMCNT+1, 0);
++      ahd_outw(ahd, PRGMCNT, 0);
+       for (i = 0; i < sizeof(seqprog)/4; i++) {
+               if (ahd_check_patch(ahd, &cur_patch, i, &skip_addr) == 0) {
+@@ -8406,7 +8648,7 @@ ahd_download_instr(struct ahd_softc *ahd
+       /*
+        * The firmware is always compiled into a little endian format.
+        */
+-      instr.integer = ahd_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
++      instr.integer = aic_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
+       fmt1_ins = &instr.format1;
+       fmt3_ins = NULL;
+@@ -8454,7 +8696,7 @@ ahd_download_instr(struct ahd_softc *ahd
+                       instr.format1.parity = 1;
+               /* The sequencer is a little endian cpu */
+-              instr.integer = ahd_htole32(instr.integer);
++              instr.integer = aic_htole32(instr.integer);
+               ahd_outsb(ahd, SEQRAM, instr.bytes, 4);
+               break;
+       }
+@@ -8580,11 +8822,15 @@ ahd_dump_card_state(struct ahd_softc *ah
+       printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n"
+              "%s: Dumping Card State at program address 0x%x Mode 0x%x\n",
+              ahd_name(ahd), 
+-             ahd_inb(ahd, CURADDR) | (ahd_inb(ahd, CURADDR+1) << 8),
++             ahd_inw(ahd, CURADDR),
+              ahd_build_mode_state(ahd, ahd->saved_src_mode,
+                                   ahd->saved_dst_mode));
+       if (paused)
+               printf("Card was paused\n");
++
++      if (ahd_check_cmdcmpltqueues(ahd))
++              printf("Completions are pending\n");
++
+       /*
+        * Mode independent registers.
+        */
+@@ -8634,10 +8880,12 @@ ahd_dump_card_state(struct ahd_softc *ah
+               if (i++ > AHD_SCB_MAX)
+                       break;
+               cur_col = printf("\n%3d FIFO_USE[0x%x] ", SCB_GET_TAG(scb),
+-                               ahd_inb(ahd, SCB_FIFO_USE_COUNT));
++                               ahd_inb_scbram(ahd, SCB_FIFO_USE_COUNT));
+               ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
+-              ahd_scb_control_print(ahd_inb(ahd, SCB_CONTROL), &cur_col, 60);
+-              ahd_scb_scsiid_print(ahd_inb(ahd, SCB_SCSIID), &cur_col, 60);
++              ahd_scb_control_print(ahd_inb_scbram(ahd, SCB_CONTROL),
++                                    &cur_col, 60);
++              ahd_scb_scsiid_print(ahd_inb_scbram(ahd, SCB_SCSIID),
++                                   &cur_col, 60);
+       }
+       printf("\nTotal %d\n", i);
+@@ -8666,7 +8914,7 @@ ahd_dump_card_state(struct ahd_softc *ah
+       while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
+               ahd_set_scbptr(ahd, scb_index);
+               printf("%d ", scb_index);
+-              scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE);
++              scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
+       }
+       printf("\n");
+@@ -8676,7 +8924,7 @@ ahd_dump_card_state(struct ahd_softc *ah
+       while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
+               ahd_set_scbptr(ahd, scb_index);
+               printf("%d ", scb_index);
+-              scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE);
++              scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
+       }
+       printf("\n");
+@@ -8687,7 +8935,7 @@ ahd_dump_card_state(struct ahd_softc *ah
+       while (!SCBID_IS_NULL(scb_index) && i++ < AHD_SCB_MAX) {
+               ahd_set_scbptr(ahd, scb_index);
+               printf("%d ", scb_index);
+-              scb_index = ahd_inw(ahd, SCB_NEXT_COMPLETE);
++              scb_index = ahd_inw_scbram(ahd, SCB_NEXT_COMPLETE);
+       }
+       printf("\n");
+       ahd_set_scbptr(ahd, saved_scb_index);
+@@ -8766,15 +9014,16 @@ ahd_dump_card_state(struct ahd_softc *ah
+              ahd_name(ahd), ahd_inw(ahd, REG0), ahd_inw(ahd, SINDEX),
+              ahd_inw(ahd, DINDEX));
+       printf("%s: SCBPTR == 0x%x, SCB_NEXT == 0x%x, SCB_NEXT2 == 0x%x\n",
+-             ahd_name(ahd), ahd_get_scbptr(ahd), ahd_inw(ahd, SCB_NEXT),
+-             ahd_inw(ahd, SCB_NEXT2));
++             ahd_name(ahd), ahd_get_scbptr(ahd),
++             ahd_inw_scbram(ahd, SCB_NEXT),
++             ahd_inw_scbram(ahd, SCB_NEXT2));
+       printf("CDB %x %x %x %x %x %x\n",
+-             ahd_inb(ahd, SCB_CDB_STORE),
+-             ahd_inb(ahd, SCB_CDB_STORE+1),
+-             ahd_inb(ahd, SCB_CDB_STORE+2),
+-             ahd_inb(ahd, SCB_CDB_STORE+3),
+-             ahd_inb(ahd, SCB_CDB_STORE+4),
+-             ahd_inb(ahd, SCB_CDB_STORE+5));
++             ahd_inb_scbram(ahd, SCB_CDB_STORE),
++             ahd_inb_scbram(ahd, SCB_CDB_STORE+1),
++             ahd_inb_scbram(ahd, SCB_CDB_STORE+2),
++             ahd_inb_scbram(ahd, SCB_CDB_STORE+3),
++             ahd_inb_scbram(ahd, SCB_CDB_STORE+4),
++             ahd_inb_scbram(ahd, SCB_CDB_STORE+5));
+       printf("STACK:");
+       for (i = 0; i < ahd->stack_size; i++) {
+               ahd->saved_stack[i] =
+@@ -8806,16 +9055,292 @@ ahd_dump_scbs(struct ahd_softc *ahd)
+               ahd_set_scbptr(ahd, i);
+               printf("%3d", i);
+               printf("(CTRL 0x%x ID 0x%x N 0x%x N2 0x%x SG 0x%x, RSG 0x%x)\n",
+-                     ahd_inb(ahd, SCB_CONTROL),
+-                     ahd_inb(ahd, SCB_SCSIID), ahd_inw(ahd, SCB_NEXT),
+-                     ahd_inw(ahd, SCB_NEXT2), ahd_inl(ahd, SCB_SGPTR),
+-                     ahd_inl(ahd, SCB_RESIDUAL_SGPTR));
++                     ahd_inb_scbram(ahd, SCB_CONTROL),
++                     ahd_inb_scbram(ahd, SCB_SCSIID),
++                     ahd_inw_scbram(ahd, SCB_NEXT),
++                     ahd_inw_scbram(ahd, SCB_NEXT2),
++                     ahd_inl_scbram(ahd, SCB_SGPTR),
++                     ahd_inl_scbram(ahd, SCB_RESIDUAL_SGPTR));
+       }
+       printf("\n");
+       ahd_set_scbptr(ahd, saved_scb_index);
+       ahd_restore_modes(ahd, saved_modes);
+ }
++
++/*************************** Timeout Handling *********************************/
++void
++ahd_timeout(struct scb *scb)
++{
++      struct ahd_softc *ahd;
++
++      ahd = scb->ahd_softc;
++      if ((scb->flags & SCB_ACTIVE) != 0) {
++              if ((scb->flags & SCB_TIMEDOUT) == 0) {
++                      LIST_INSERT_HEAD(&ahd->timedout_scbs, scb,
++                                       timedout_links);
++                      scb->flags |= SCB_TIMEDOUT;
++              }
++              ahd_wakeup_recovery_thread(ahd);
++      }
++}
++
++/*
++ * ahd_recover_commands determines if any of the commands that have currently
++ * timedout are the root cause for this timeout.  Innocent commands are given
++ * a new timeout while we wait for the command executing on the bus to timeout.
++ * This routine is invoked from a thread context so we are allowed to sleep.
++ * Our lock is not held on entry.
++ */
++void
++ahd_recover_commands(struct ahd_softc *ahd)
++{
++      struct  scb *scb;
++      struct  scb *active_scb;
++      long    s;
++      int     found;
++      int     was_paused;
++      u_int   active_scbptr;
++      u_int   last_phase;
++
++      ahd_lock(ahd, &s);
++
++      /*
++       * Pause the controller and manually flush any
++       * commands that have just completed but that our
++       * interrupt handler has yet to see.
++       */
++      was_paused = ahd_is_paused(ahd);
++      ahd_pause_and_flushwork(ahd);
++
++      if (LIST_EMPTY(&ahd->timedout_scbs) != 0) {
++              /*
++               * The timedout commands have already
++               * completed.  This typically means
++               * that either the timeout value was on
++               * the hairy edge of what the device
++               * requires or - more likely - interrupts
++               * are not happening.
++               */
++              printf("%s: Timedout SCBs already complete. "
++                     "Interrupts may not be functioning.\n", ahd_name(ahd));
++              ahd_unpause(ahd);
++              ahd_unlock(ahd, &s);
++              return;
++      }
++
++      printf("%s: Recovery Initiated - Card was %spaused\n", ahd_name(ahd),
++             was_paused ? "" : "not ");
++      ahd_dump_card_state(ahd);
++
++      /*
++       * Determine identity of SCB acting on the bus.
++       * This test only catches non-packetized transactions.
++       * Due to the fleeting nature of packetized operations,
++       * we can't easily determine that a packetized operation
++       * is on the bus.
++       */
++      ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
++      last_phase = ahd_inb(ahd, LASTPHASE);
++      active_scbptr = ahd_get_scbptr(ahd);
++      active_scb = NULL;
++      if (last_phase != P_BUSFREE
++       || (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0)
++              active_scb = ahd_lookup_scb(ahd, active_scbptr);
++
++      while ((scb = LIST_FIRST(&ahd->timedout_scbs)) != NULL) {
++              int     target;
++              int     lun;
++              char    channel;
++
++              target = SCB_GET_TARGET(ahd, scb);
++              channel = SCB_GET_CHANNEL(ahd, scb);
++              lun = SCB_GET_LUN(scb);
++
++              ahd_print_path(ahd, scb);
++              printf("SCB 0x%x - timed out\n", scb->hscb->tag);
++
++              if (scb->flags & (SCB_DEVICE_RESET|SCB_ABORT)) {
++                      /*
++                       * Been down this road before.
++                       * Do a full bus reset.
++                       */
++                      aic_set_transaction_status(scb, CAM_CMD_TIMEOUT);
++bus_reset:
++                      found = ahd_reset_channel(ahd, channel,
++                                                /*Initiate Reset*/TRUE);
++                      printf("%s: Issued Channel %c Bus Reset. "
++                             "%d SCBs aborted\n", ahd_name(ahd), channel,
++                             found);
++                      continue;
++              }
++
++              /*
++               * Remove the command from the timedout list in
++               * preparation for requeing it.
++               */
++              LIST_REMOVE(scb, timedout_links);
++              scb->flags &= ~SCB_TIMEDOUT;
++
++              if (active_scb != NULL) {
++
++                      if (active_scb != scb) {
++                              /*
++                               * If the active SCB is not us, assume that
++                               * the active SCB has a longer timeout than
++                               * the timedout SCB, and wait for the active
++                               * SCB to timeout.
++                               */ 
++                              ahd_other_scb_timeout(ahd, scb, active_scb);
++                              continue;
++                      } 
++
++                      /*
++                       * We're active on the bus, so assert ATN
++                       * and hope that the target responds.
++                       */
++                      ahd_set_recoveryscb(ahd, active_scb);
++                      active_scb->flags |= SCB_RECOVERY_SCB|SCB_DEVICE_RESET;
++                      ahd_outb(ahd, MSG_OUT, HOST_MSG);
++                      ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
++                      ahd_print_path(ahd, active_scb);
++                      printf("BDR message in message buffer\n");
++                      aic_scb_timer_reset(scb, 2 * 1000000);
++                      break;
++              } else if (last_phase != P_BUSFREE
++                      && ahd_inb(ahd, SCSIPHASE) == 0) {
++                      /*
++                       * SCB is not identified, there
++                       * is no pending REQ, and the sequencer
++                       * has not seen a busfree.  Looks like
++                       * a stuck connection waiting to
++                       * go busfree.  Reset the bus.
++                       */
++                      printf("%s: Connection stuck awaiting busfree or "
++                             "Identify Msg.\n", ahd_name(ahd));
++                      goto bus_reset;
++              } else if (ahd_search_qinfifo(ahd, target, channel, lun,
++                                            scb->hscb->tag, ROLE_INITIATOR,
++                                            /*status*/0, SEARCH_COUNT) > 0) {
++
++                      /*
++                       * We haven't even gone out on the bus
++                       * yet, so the timeout must be due to
++                       * some other command.  Reset the timer
++                       * and go on.
++                       */
++                      ahd_other_scb_timeout(ahd, scb, scb);
++              } else {
++                      /*
++                       * This SCB is for a disconnected transaction
++                       * and we haven't found a better candidate on
++                       * the bus to explain this timeout.
++                       */
++                      ahd_set_recoveryscb(ahd, scb);
++
++                      /*
++                       * Actually re-queue this SCB in an attempt
++                       * to select the device before it reconnects.
++                       * In either case (selection or reselection),
++                       * we will now issue a target reset to the
++                       * timed-out device.
++                       *
++                       * Set the MK_MESSAGE control bit indicating
++                       * that we desire to send a message.  We
++                       * also set the disconnected flag since
++                       * in the paging case there is no guarantee
++                       * that our SCB control byte matches the
++                       * version on the card.  We don't want the
++                       * sequencer to abort the command thinking
++                       * an unsolicited reselection occurred.
++                       */
++                      scb->flags |= SCB_DEVICE_RESET;
++                      scb->hscb->cdb_len = 0;
++                      scb->hscb->task_attribute = 0;
++                      scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK;
++
++                      ahd_set_scbptr(ahd, SCB_GET_TAG(scb));
++                      if ((scb->flags & SCB_PACKETIZED) != 0) {
++                              /*
++                               * Mark the SCB has having an outstanding
++                               * task management function.  Should the command
++                               * complete normally before the task management
++                               * function can be sent, the host will be
++                               * notified to abort our requeued SCB.
++                               */
++                              ahd_outb(ahd, SCB_TASK_MANAGEMENT,
++                                       scb->hscb->task_management);
++                      } else {
++                              /*
++                               * If non-packetized, set the MK_MESSAGE control
++                               * bit indicating that we desire to send a
++                               * message.  We also set the disconnected flag
++                               * since there is no guarantee that our SCB
++                               * control byte matches the version on the
++                               * card.  We don't want the sequencer to abort
++                               * the command thinking an unsolicited
++                               * reselection occurred.
++                               */
++                              scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
++
++                              /*
++                               * The sequencer will never re-reference the
++                               * in-core SCB.  To make sure we are notified
++                               * during reslection, set the MK_MESSAGE flag in
++                               * the card's copy of the SCB.
++                               */
++                              ahd_outb(ahd, SCB_CONTROL,
++                                       ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE);
++                      }
++
++                      /*
++                       * Clear out any entries in the QINFIFO first
++                       * so we are the next SCB for this target
++                       * to run.
++                       */
++                      ahd_search_qinfifo(ahd, target, channel, lun,
++                                         SCB_LIST_NULL, ROLE_INITIATOR,
++                                         CAM_REQUEUE_REQ, SEARCH_COMPLETE);
++                      ahd_qinfifo_requeue_tail(ahd, scb);
++                      ahd_set_scbptr(ahd, active_scbptr);
++                      ahd_print_path(ahd, scb);
++                      printf("Queuing a BDR SCB\n");
++                      aic_scb_timer_reset(scb, 2 * 1000000);
++                      break;
++              }
++      }
++      
++      /*
++       * Any remaining SCBs were not the "culprit", so remove
++       * them from the timeout list.  The timer for these commands
++       * will be reset once the recovery SCB completes.
++       */
++      while ((scb = LIST_FIRST(&ahd->timedout_scbs)) != NULL) {
++
++              LIST_REMOVE(scb, timedout_links);
++              scb->flags &= ~SCB_TIMEDOUT;
++      }
++
++      ahd_unpause(ahd);
++      ahd_unlock(ahd, &s);
++}
++
++static void
++ahd_other_scb_timeout(struct ahd_softc *ahd, struct scb *scb,
++                    struct scb *other_scb)
++{
++      u_int   newtimeout;
++
++      ahd_print_path(ahd, scb);
++      printf("Other SCB Timeout%s",
++             (scb->flags & SCB_OTHERTCL_TIMEOUT) != 0
++             ? " again\n" : "\n");
++      scb->flags |= SCB_OTHERTCL_TIMEOUT;
++      newtimeout = MAX(aic_get_timeout(other_scb),
++                       aic_get_timeout(scb));
++      aic_scb_timer_reset(scb, newtimeout);
++}
++
+ /**************************** Flexport Logic **********************************/
+ /*
+  * Read count 16bit words from 16bit word address start_addr from the
+@@ -8922,9 +9447,9 @@ ahd_wait_seeprom(struct ahd_softc *ahd)
+ {
+       int cnt;
+-      cnt = 20;
++      cnt = 5000;
+       while ((ahd_inb(ahd, SEESTAT) & (SEEARBACK|SEEBUSY)) != 0 && --cnt)
+-              ahd_delay(5);
++              aic_delay(5);
+       if (cnt == 0)
+               return (ETIMEDOUT);
+@@ -9066,7 +9591,7 @@ ahd_wait_flexport(struct ahd_softc *ahd)
+       AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
+       cnt = 1000000 * 2 / 5;
+       while ((ahd_inb(ahd, BRDCTL) & FLXARBACK) == 0 && --cnt)
+-              ahd_delay(5);
++              aic_delay(5);
+       if (cnt == 0)
+               return (ETIMEDOUT);
+@@ -9192,6 +9717,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd,
+                       ahd->flags &= ~AHD_INITIATORROLE;
+               ahd_pause(ahd);
+               ahd_loadseq(ahd);
++              ahd_restart(ahd);
+               ahd_unlock(ahd, &s);
+       }
+       cel = &ccb->cel;
+@@ -9267,13 +9793,9 @@ ahd_handle_en_lun(struct ahd_softc *ahd,
+                       if ((ahd->features & AHD_MULTI_TID) != 0) {
+                               u_int targid_mask;
+-                              targid_mask = ahd_inb(ahd, TARGID)
+-                                          | (ahd_inb(ahd, TARGID + 1) << 8);
+-
++                              targid_mask = ahd_inw(ahd, TARGID);
+                               targid_mask |= target_mask;
+-                              ahd_outb(ahd, TARGID, targid_mask);
+-                              ahd_outb(ahd, TARGID+1, (targid_mask >> 8));
+-                              
++                              ahd_outw(ahd, TARGID, targid_mask);
+                               ahd_update_scsiid(ahd, targid_mask);
+                       } else {
+                               u_int our_id;
+@@ -9387,14 +9909,9 @@ ahd_handle_en_lun(struct ahd_softc *ahd,
+                               if (ahd->features & AHD_MULTI_TID) {
+                                       u_int targid_mask;
+-                                      targid_mask = ahd_inb(ahd, TARGID)
+-                                                  | (ahd_inb(ahd, TARGID + 1)
+-                                                     << 8);
+-
++                                      targid_mask = ahd_inw(ahd, TARGID);
+                                       targid_mask &= ~target_mask;
+-                                      ahd_outb(ahd, TARGID, targid_mask);
+-                                      ahd_outb(ahd, TARGID+1,
+-                                               (targid_mask >> 8));
++                                      ahd_outw(ahd, TARGID, targid_mask);
+                                       ahd_update_scsiid(ahd, targid_mask);
+                               }
+                       }
+@@ -9425,6 +9942,11 @@ ahd_handle_en_lun(struct ahd_softc *ahd,
+                               ahd->flags |= AHD_INITIATORROLE;
+                               ahd_pause(ahd);
+                               ahd_loadseq(ahd);
++                              ahd_restart(ahd);
++                              /*
++                               * Unpaused.  The extra unpause
++                               * that follows is harmless.
++                               */
+                       }
+               }
+               ahd_unpause(ahd);
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx.h 2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx.h  2003-12-28 23:21:39.000000000 -0800
+@@ -37,7 +37,7 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#90 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#101 $
+  *
+  * $FreeBSD$
+  */
+@@ -74,9 +74,9 @@ struct scb_platform_data;
+ #define ALL_TARGETS_MASK 0xFFFF
+ #define INITIATOR_WILDCARD    (~0)
+ #define       SCB_LIST_NULL           0xFF00
+-#define       SCB_LIST_NULL_LE        (ahd_htole16(SCB_LIST_NULL))
++#define       SCB_LIST_NULL_LE        (aic_htole16(SCB_LIST_NULL))
+ #define QOUTFIFO_ENTRY_VALID 0x8000
+-#define QOUTFIFO_ENTRY_VALID_LE (ahd_htole16(0x8000))
++#define QOUTFIFO_ENTRY_VALID_LE (aic_htole16(0x8000))
+ #define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL)
+ #define SCSIID_TARGET(ahd, scsiid)    \
+@@ -118,7 +118,7 @@ struct scb_platform_data;
+       ((lun) | ((target) << 8))
+ #define SCB_GET_TAG(scb) \
+-      ahd_le16toh(scb->hscb->tag)
++      aic_le16toh(scb->hscb->tag)
+ #ifndef       AHD_TARGET_MODE
+ #undef        AHD_TMODE_ENABLE
+@@ -229,8 +229,10 @@ typedef enum {
+       AHD_RTI                 = 0x04000,/* Retained Training Support */
+       AHD_NEW_IOCELL_OPTS     = 0x08000,/* More Signal knobs in the IOCELL */
+       AHD_NEW_DFCNTRL_OPTS    = 0x10000,/* SCSIENWRDIS bit */
++      AHD_FAST_CDB_DELIVERY   = 0x20000,/* CDB acks released to Output Sync */
+       AHD_REMOVABLE           = 0x00000,/* Hot-Swap supported - None so far*/
+       AHD_AIC7901_FE          = AHD_FENONE,
++      AHD_AIC7901A_FE         = AHD_FENONE,
+       AHD_AIC7902_FE          = AHD_MULTI_FUNC
+ } ahd_feature;
+@@ -372,7 +374,9 @@ typedef enum {
+       AHD_HP_BOARD          = 0x100000,
+       AHD_RESET_POLL_ACTIVE = 0x200000,
+       AHD_UPDATE_PEND_CMDS  = 0x400000,
+-      AHD_RUNNING_QOUTFIFO  = 0x800000
++      AHD_RUNNING_QOUTFIFO  = 0x800000,
++      AHD_HAD_FIRST_SEL     = 0x1000000,
++      AHD_SHUTDOWN_RECOVERY = 0x2000000 /* Terminate recovery thread. */
+ } ahd_flag;
+ /************************* Hardware  SCB Definition ***************************/
+@@ -494,21 +498,21 @@ struct hardware_scb {
+  *      transfer.
+  */ 
+ #define SG_PTR_MASK   0xFFFFFFF8
+-/*16*/        uint64_t dataptr;
+-/*24*/        uint32_t datacnt;       /* Byte 3 is spare. */
+-/*28*/        uint32_t sgptr;
+-/*32*/        uint32_t hscb_busaddr;
+-/*36*/        uint32_t next_hscb_busaddr;
+-/*40*/        uint8_t  control;       /* See SCB_CONTROL in aic79xx.reg for details */
+-/*41*/        uint8_t  scsiid;        /*
++/*16*/        uint16_t tag;           /* Reused by Sequencer. */
++/*18*/        uint8_t  control;       /* See SCB_CONTROL in aic79xx.reg for details */
++/*19*/        uint8_t  scsiid;        /*
+                                * Selection out Id
+                                * Our Id (bits 0-3) Their ID (bits 4-7)
+                                */
+-/*42*/        uint8_t  lun;
+-/*43*/        uint8_t  task_attribute;
+-/*44*/        uint8_t  cdb_len;
+-/*45*/        uint8_t  task_management;
+-/*46*/        uint16_t tag;           /* Reused by Sequencer. */
++/*20*/        uint8_t  lun;
++/*21*/        uint8_t  task_attribute;
++/*22*/        uint8_t  cdb_len;
++/*23*/        uint8_t  task_management;
++/*24*/        uint64_t dataptr;
++/*32*/        uint32_t datacnt;       /* Byte 3 is spare. */
++/*36*/        uint32_t sgptr;
++/*40*/        uint32_t hscb_busaddr;
++/*44*/        uint32_t next_hscb_busaddr;
+ /********** Long lun field only downloaded for full 8 byte lun support ********/
+ /*48*/  uint8_t        pkt_long_lun[8];
+ /******* Fields below are not Downloaded (Sequencer may use for scratch) ******/
+@@ -546,7 +550,7 @@ struct ahd_dma64_seg {
+ struct map_node {
+       bus_dmamap_t             dmamap;
+-      bus_addr_t               physaddr;
++      bus_addr_t               busaddr;
+       uint8_t                 *vaddr;
+       SLIST_ENTRY(map_node)    links;
+ };
+@@ -588,12 +592,16 @@ typedef enum {
+       SCB_PKT_SENSE           = 0x02000,
+       SCB_CMDPHASE_ABORT      = 0x04000,
+       SCB_ON_COL_LIST         = 0x08000,
+-      SCB_SILENT              = 0x10000 /*
++      SCB_SILENT              = 0x10000,/*
+                                          * Be quiet about transmission type
+                                          * errors.  They are expected and we
+                                          * don't want to upset the user.  This
+                                          * flag is typically used during DV.
+                                          */
++      SCB_TIMEDOUT            = 0x20000/*
++                                        * SCB has timed out and is on the
++                                        * timedout list.
++                                        */
+ } scb_flag;
+ struct scb {
+@@ -610,8 +618,9 @@ struct scb {
+       } links2;
+ #define pending_links links2.le
+ #define collision_links links2.le
++      LIST_ENTRY(scb)           timedout_links;
+       struct scb               *col_scb;
+-      ahd_io_ctx_t              io_ctx;
++      aic_io_ctx_t              io_ctx;
+       struct ahd_softc         *ahd_softc;
+       scb_flag                  flags;
+ #ifndef __linux__
+@@ -1059,6 +1068,7 @@ struct ahd_softc {
+       struct scb_data           scb_data;
+       struct hardware_scb      *next_queued_hscb;
++      struct map_node          *next_queued_hscb_map;
+       /*
+        * SCBs that have been sent to the controller
+@@ -1066,6 +1076,11 @@ struct ahd_softc {
+       LIST_HEAD(, scb)          pending_scbs;
+       /*
++       * SCBs whose timeout routine has been called.
++       */
++      LIST_HEAD(, scb)          timedout_scbs;
++
++      /*
+        * Current register window mode information.
+        */
+       ahd_mode                  dst_mode;
+@@ -1086,7 +1101,7 @@ struct ahd_softc {
+       /*
+        * Platform specific device information.
+        */
+-      ahd_dev_softc_t           dev_softc;
++      aic_dev_softc_t           dev_softc;
+       /*
+        * Bus specific device information.
+@@ -1116,8 +1131,8 @@ struct ahd_softc {
+       /*
+        * Timer handles for timer driven callbacks.
+        */
+-      ahd_timer_t               reset_timer;
+-      ahd_timer_t               stat_timer;
++      aic_timer_t               reset_timer;
++      aic_timer_t               stat_timer;
+       /*
+        * Statistics.
+@@ -1194,8 +1209,7 @@ struct ahd_softc {
+        */
+       bus_dma_tag_t             parent_dmat;
+       bus_dma_tag_t             shared_data_dmat;
+-      bus_dmamap_t              shared_data_dmamap;
+-      bus_addr_t                shared_data_busaddr;
++      struct map_node           shared_data_map;
+       /* Information saved through suspend/resume cycles */
+       struct ahd_suspend_state  suspend_state;
+@@ -1296,9 +1310,9 @@ struct ahd_devinfo {
+ };
+ /****************************** PCI Structures ********************************/
+-#define AHD_PCI_IOADDR0       PCIR_MAPS       /* I/O BAR*/
+-#define AHD_PCI_MEMADDR       (PCIR_MAPS + 4) /* Memory BAR */
+-#define AHD_PCI_IOADDR1       (PCIR_MAPS + 12)/* Second I/O BAR */
++#define AHD_PCI_IOADDR0       PCIR_BAR(0)     /* I/O BAR*/
++#define AHD_PCI_MEMADDR       PCIR_BAR(1)     /* Memory BAR */
++#define AHD_PCI_IOADDR1       PCIR_BAR(3)     /* Second I/O BAR */
+ typedef int (ahd_device_setup_t)(struct ahd_softc *);
+@@ -1338,7 +1352,7 @@ ahd_unbusy_tcl(struct ahd_softc *ahd, u_
+ }
+ /***************************** PCI Front End *********************************/
+-struct        ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t);
++struct        ahd_pci_identity *ahd_find_pci_device(aic_dev_softc_t);
+ int                     ahd_pci_config(struct ahd_softc *,
+                                        struct ahd_pci_identity *);
+ int   ahd_pci_test_register_access(struct ahd_softc *);
+@@ -1379,13 +1393,13 @@ struct scb             *ahd_get_scb(struct ahd_soft
+ void                   ahd_free_scb(struct ahd_softc *ahd, struct scb *scb);
+ void                   ahd_alloc_scbs(struct ahd_softc *ahd);
+ void                   ahd_free(struct ahd_softc *ahd);
+-int                    ahd_reset(struct ahd_softc *ahd);
++int                    ahd_reset(struct ahd_softc *ahd, int reinit);
+ void                   ahd_shutdown(void *arg);
+-int                   ahd_write_flexport(struct ahd_softc *ahd,
+-                                         u_int addr, u_int value);
+-int                   ahd_read_flexport(struct ahd_softc *ahd, u_int addr,
+-                                        uint8_t *value);
+-int                   ahd_wait_flexport(struct ahd_softc *ahd);
++int                    ahd_write_flexport(struct ahd_softc *ahd,
++                                          u_int addr, u_int value);
++int                    ahd_read_flexport(struct ahd_softc *ahd, u_int addr,
++                                         uint8_t *value);
++int                    ahd_wait_flexport(struct ahd_softc *ahd);
+ /*************************** Interrupt Services *******************************/
+ void                  ahd_pci_intr(struct ahd_softc *ahd);
+@@ -1430,6 +1444,8 @@ void                     ahd_handle_scsi_status(struct ahd
+                                              struct scb *scb);
+ void                  ahd_calc_residual(struct ahd_softc *ahd,
+                                         struct scb *scb);
++void                  ahd_timeout(struct scb *scb);
++void                  ahd_recover_commands(struct ahd_softc *ahd);
+ /*************************** Utility Functions ********************************/
+ struct ahd_phase_table_entry*
+                       ahd_lookup_phase_entry(int phase);
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx_inline.h  2003-06-14 12:18:09.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx_inline.h   2003-12-28 23:21:39.000000000 -0800
+@@ -37,7 +37,7 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#50 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#55 $
+  *
+  * $FreeBSD$
+  */
+@@ -250,15 +250,15 @@ ahd_sg_setup(struct ahd_softc *ahd, stru
+               struct ahd_dma64_seg *sg;
+               sg = (struct ahd_dma64_seg *)sgptr;
+-              sg->addr = ahd_htole64(addr);
+-              sg->len = ahd_htole32(len | (last ? AHD_DMA_LAST_SEG : 0));
++              sg->addr = aic_htole64(addr);
++              sg->len = aic_htole32(len | (last ? AHD_DMA_LAST_SEG : 0));
+               return (sg + 1);
+       } else {
+               struct ahd_dma_seg *sg;
+               sg = (struct ahd_dma_seg *)sgptr;
+-              sg->addr = ahd_htole32(addr & 0xFFFFFFFF);
+-              sg->len = ahd_htole32(len | ((addr >> 8) & 0x7F000000)
++              sg->addr = aic_htole32(addr & 0xFFFFFFFF);
++              sg->len = aic_htole32(len | ((addr >> 8) & 0x7F000000)
+                                   | (last ? AHD_DMA_LAST_SEG : 0));
+               return (sg + 1);
+       }
+@@ -273,7 +273,7 @@ ahd_setup_scb_common(struct ahd_softc *a
+               /* XXX what about ACA??  It is type 4, but TAG_TYPE == 0x3. */
+               scb->hscb->task_attribute = scb->hscb->control & SCB_TAG_TYPE;
+       } else {
+-              if (ahd_get_transfer_length(scb) & 0x01)
++              if (aic_get_transfer_length(scb) & 0x01)
+                       scb->hscb->task_attribute = SCB_XFERLEN_ODD;
+               else
+                       scb->hscb->task_attribute = 0;
+@@ -282,7 +282,7 @@ ahd_setup_scb_common(struct ahd_softc *a
+       if (scb->hscb->cdb_len <= MAX_CDB_LEN_WITH_SENSE_ADDR
+        || (scb->hscb->cdb_len & SCB_CDB_LEN_PTR) != 0)
+               scb->hscb->shared_data.idata.cdb_plus_saddr.sense_addr =
+-                  ahd_htole32(scb->sense_busaddr);
++                  aic_htole32(scb->sense_busaddr);
+ }
+ static __inline void
+@@ -308,8 +308,8 @@ ahd_setup_data_scb(struct ahd_softc *ahd
+               if ((ahd->flags & AHD_39BIT_ADDRESSING) != 0) {
+                       uint64_t high_addr;
+-                      high_addr = ahd_le32toh(sg->len) & 0x7F000000;
+-                      scb->hscb->dataptr |= ahd_htole64(high_addr << 8);
++                      high_addr = aic_le32toh(sg->len) & 0x7F000000;
++                      scb->hscb->dataptr |= aic_htole64(high_addr << 8);
+               }
+               scb->hscb->datacnt = sg->len;
+       }
+@@ -319,13 +319,13 @@ ahd_setup_data_scb(struct ahd_softc *ahd
+        * sequencer will clear as soon as a data transfer
+        * occurs.
+        */
+-      scb->hscb->sgptr = ahd_htole32(scb->sg_list_busaddr|SG_FULL_RESID);
++      scb->hscb->sgptr = aic_htole32(scb->sg_list_busaddr|SG_FULL_RESID);
+ }
+ static __inline void
+ ahd_setup_noxfer_scb(struct ahd_softc *ahd, struct scb *scb)
+ {
+-      scb->hscb->sgptr = ahd_htole32(SG_LIST_NULL);
++      scb->hscb->sgptr = aic_htole32(SG_LIST_NULL);
+       scb->hscb->dataptr = 0;
+       scb->hscb->datacnt = 0;
+ }
+@@ -383,7 +383,7 @@ ahd_sg_virt_to_bus(struct ahd_softc *ahd
+ static __inline void
+ ahd_sync_scb(struct ahd_softc *ahd, struct scb *scb, int op)
+ {
+-      ahd_dmamap_sync(ahd, ahd->scb_data.hscb_dmat,
++      aic_dmamap_sync(ahd, ahd->scb_data.hscb_dmat,
+                       scb->hscb_map->dmamap,
+                       /*offset*/(uint8_t*)scb->hscb - scb->hscb_map->vaddr,
+                       /*len*/sizeof(*scb->hscb), op);
+@@ -395,7 +395,7 @@ ahd_sync_sglist(struct ahd_softc *ahd, s
+       if (scb->sg_count == 0)
+               return;
+-      ahd_dmamap_sync(ahd, ahd->scb_data.sg_dmat,
++      aic_dmamap_sync(ahd, ahd->scb_data.sg_dmat,
+                       scb->sg_map->dmamap,
+                       /*offset*/scb->sg_list_busaddr - ahd_sg_size(ahd),
+                       /*len*/ahd_sg_size(ahd) * scb->sg_count, op);
+@@ -404,7 +404,7 @@ ahd_sync_sglist(struct ahd_softc *ahd, s
+ static __inline void
+ ahd_sync_sense(struct ahd_softc *ahd, struct scb *scb, int op)
+ {
+-      ahd_dmamap_sync(ahd, ahd->scb_data.sense_dmat,
++      aic_dmamap_sync(ahd, ahd->scb_data.sense_dmat,
+                       scb->sense_map->dmamap,
+                       /*offset*/scb->sense_busaddr,
+                       /*len*/AHD_SENSE_BUFSIZE, op);
+@@ -455,6 +455,8 @@ static __inline u_int      ahd_inb_scbram(str
+ static __inline u_int ahd_inw_scbram(struct ahd_softc *ahd, u_int offset);
+ static __inline uint32_t
+                       ahd_inl_scbram(struct ahd_softc *ahd, u_int offset);
++static __inline uint64_t
++                      ahd_inq_scbram(struct ahd_softc *ahd, u_int offset);
+ static __inline void  ahd_swap_with_next_hscb(struct ahd_softc *ahd,
+                                               struct scb *scb);
+ static __inline void  ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb);
+@@ -470,7 +472,7 @@ ahd_complete_scb(struct ahd_softc *ahd, 
+ {
+       uint32_t sgptr;
+-      sgptr = ahd_le32toh(scb->hscb->sgptr);
++      sgptr = aic_le32toh(scb->hscb->sgptr);
+       if ((sgptr & SG_STATUS_VALID) != 0)
+               ahd_handle_scb_status(ahd, scb);
+       else
+@@ -486,7 +488,7 @@ ahd_update_residual(struct ahd_softc *ah
+ {
+       uint32_t sgptr;
+-      sgptr = ahd_le32toh(scb->hscb->sgptr);
++      sgptr = aic_le32toh(scb->hscb->sgptr);
+       if ((sgptr & SG_STATUS_VALID) != 0)
+               ahd_calc_residual(ahd, scb);
+ }
+@@ -520,12 +522,21 @@ do {                                                             \
+ static __inline uint16_t
+ ahd_inw(struct ahd_softc *ahd, u_int port)
+ {
++      /*
++       * Read high byte first as some registers increment
++       * or have other side effects when the low byte is
++       * read.
++       */
+       return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port));
+ }
+ static __inline void
+ ahd_outw(struct ahd_softc *ahd, u_int port, u_int value)
+ {
++      /*
++       * Write low byte first to accomodate registers
++       * such as PRGMCNT where the order maters.
++       */
+       ahd_outb(ahd, port, value & 0xFF);
+       ahd_outb(ahd, port+1, (value >> 8) & 0xFF);
+ }
+@@ -697,10 +708,15 @@ ahd_inw_scbram(struct ahd_softc *ahd, u_
+ static __inline uint32_t
+ ahd_inl_scbram(struct ahd_softc *ahd, u_int offset)
+ {
+-      return (ahd_inb_scbram(ahd, offset)
+-            | (ahd_inb_scbram(ahd, offset+1) << 8)
+-            | (ahd_inb_scbram(ahd, offset+2) << 16)
+-            | (ahd_inb_scbram(ahd, offset+3) << 24));
++      return (ahd_inw_scbram(ahd, offset)
++            | (ahd_inw_scbram(ahd, offset+2) << 16));
++}
++
++static __inline uint64_t
++ahd_inq_scbram(struct ahd_softc *ahd, u_int offset)
++{
++      return (ahd_inl_scbram(ahd, offset)
++            | ((uint64_t)ahd_inl_scbram(ahd, offset+4)) << 32);
+ }
+ static __inline struct scb *
+@@ -720,7 +736,8 @@ ahd_lookup_scb(struct ahd_softc *ahd, u_
+ static __inline void
+ ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb)
+ {
+-      struct hardware_scb *q_hscb;
++      struct   hardware_scb *q_hscb;
++      struct   map_node *q_hscb_map;
+       uint32_t saved_hscb_busaddr;
+       /*
+@@ -736,6 +753,7 @@ ahd_swap_with_next_hscb(struct ahd_softc
+        * locate the correct SCB by SCB_TAG.
+        */
+       q_hscb = ahd->next_queued_hscb;
++      q_hscb_map = ahd->next_queued_hscb_map;
+       saved_hscb_busaddr = q_hscb->hscb_busaddr;
+       memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));
+       q_hscb->hscb_busaddr = saved_hscb_busaddr;
+@@ -743,7 +761,9 @@ ahd_swap_with_next_hscb(struct ahd_softc
+       /* Now swap HSCB pointers. */
+       ahd->next_queued_hscb = scb->hscb;
++      ahd->next_queued_hscb_map = scb->hscb_map;
+       scb->hscb = q_hscb;
++      scb->hscb_map = q_hscb_map;
+       /* Now define the mapping from tag to SCB in the scbindex */
+       ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb;
+@@ -783,13 +803,13 @@ ahd_queue_scb(struct ahd_softc *ahd, str
+       if ((ahd_debug & AHD_SHOW_QUEUE) != 0) {
+               uint64_t host_dataptr;
+-              host_dataptr = ahd_le64toh(scb->hscb->dataptr);
++              host_dataptr = aic_le64toh(scb->hscb->dataptr);
+               printf("%s: Queueing SCB 0x%x bus addr 0x%x - 0x%x%x/0x%x\n",
+                      ahd_name(ahd),
+-                     SCB_GET_TAG(scb), ahd_le32toh(scb->hscb->hscb_busaddr),
++                     SCB_GET_TAG(scb), aic_le32toh(scb->hscb->hscb_busaddr),
+                      (u_int)((host_dataptr >> 32) & 0xFFFFFFFF),
+                      (u_int)(host_dataptr & 0xFFFFFFFF),
+-                     ahd_le32toh(scb->hscb->datacnt));
++                     aic_le32toh(scb->hscb->datacnt));
+       }
+ #endif
+       /* Tell the adapter about the newly queued SCB */
+@@ -817,8 +837,8 @@ static __inline int        ahd_intr(struct ahd_
+ static __inline void
+ ahd_sync_qoutfifo(struct ahd_softc *ahd, int op)
+ {
+-      ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap,
+-                      /*offset*/0, /*len*/AHC_SCB_MAX * sizeof(uint16_t), op);
++      aic_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,
++                      /*offset*/0, /*len*/AHD_SCB_MAX * sizeof(uint16_t), op);
+ }
+ static __inline void
+@@ -826,8 +846,8 @@ ahd_sync_tqinfifo(struct ahd_softc *ahd,
+ {
+ #ifdef AHD_TARGET_MODE
+       if ((ahd->flags & AHD_TARGETROLE) != 0) {
+-              ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
+-                              ahd->shared_data_dmamap,
++              aic_dmamap_sync(ahd, ahd->shared_data_dmat,
++                              ahd->shared_data_map.dmamap,
+                               ahd_targetcmd_offset(ahd, 0),
+                               sizeof(struct target_cmd) * AHD_TMODE_CMDS,
+                               op);
+@@ -847,7 +867,7 @@ ahd_check_cmdcmpltqueues(struct ahd_soft
+       u_int retval;
+       retval = 0;
+-      ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap,
++      aic_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,
+                       /*offset*/ahd->qoutfifonext, /*len*/2,
+                       BUS_DMASYNC_POSTREAD);
+       if ((ahd->qoutfifo[ahd->qoutfifonext]
+@@ -856,8 +876,8 @@ ahd_check_cmdcmpltqueues(struct ahd_soft
+ #ifdef AHD_TARGET_MODE
+       if ((ahd->flags & AHD_TARGETROLE) != 0
+        && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) {
+-              ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
+-                              ahd->shared_data_dmamap,
++              aic_dmamap_sync(ahd, ahd->shared_data_dmat,
++                              ahd->shared_data_map.dmamap,
+                               ahd_targetcmd_offset(ahd, ahd->tqinfifofnext),
+                               /*len*/sizeof(struct target_cmd),
+                               BUS_DMASYNC_POSTREAD);
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx_osm.c     2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx_osm.c      2003-12-28 23:21:39.000000000 -0800
+@@ -1,7 +1,7 @@
+ /*
+  * Adaptec AIC79xx device driver for Linux.
+  *
+- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#169 $
++ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#193 $
+  *
+  * --------------------------------------------------------------------------
+  * Copyright (c) 1994-2000 Justin T. Gibbs.
+@@ -62,6 +62,16 @@
+ #include <linux/mm.h>         /* For fetching system memory size */
++/************************* Magic SysReq Support *******************************/
++static struct aic_sysrq_key_op ahd_sysrq_op =
++{
++      aic_sysrq_handler,
++      "aic79xxstatedump",
++      "Dump aic79xx controller information to Console"
++};
++
++static int ahd_sysrq_key;
++
+ /*
+  * Lock protecting manipulation of the ahd softc list.
+  */
+@@ -425,7 +435,7 @@ static char *aic79xx = NULL;
+ static char dummy_buffer[60] = "Please don't trounce on me insmod!!\n";
+ MODULE_AUTHOR("Maintainer: Justin T. Gibbs <gibbs@scsiguy.com>");
+-MODULE_DESCRIPTION("Adaptec Aic77XX/78XX SCSI Host Bus Adapter driver");
++MODULE_DESCRIPTION("Adaptec Aic790X U320 SCSI Host Bus Adapter driver");
+ #ifdef MODULE_LICENSE
+ MODULE_LICENSE("Dual BSD/GPL");
+ #endif
+@@ -466,7 +476,7 @@ MODULE_PARM_DESC(aic79xx,
+ #endif
+ static void ahd_linux_handle_scsi_status(struct ahd_softc *,
+-                                       struct ahd_linux_device *,
++                                       struct aic_linux_device *,
+                                        struct scb *);
+ static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd,
+                                        Scsi_Cmnd *cmd);
+@@ -478,21 +488,20 @@ static void ahd_linux_initialize_scsi_bu
+ static void ahd_linux_size_nseg(void);
+ static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd);
+ static void ahd_linux_start_dv(struct ahd_softc *ahd);
+-static void ahd_linux_dv_timeout(struct scsi_cmnd *cmd);
+ static int  ahd_linux_dv_thread(void *data);
+ static void ahd_linux_kill_dv_thread(struct ahd_softc *ahd);
+ static void ahd_linux_dv_target(struct ahd_softc *ahd, u_int target);
+ static void ahd_linux_dv_transition(struct ahd_softc *ahd,
+                                   struct scsi_cmnd *cmd,
+                                   struct ahd_devinfo *devinfo,
+-                                  struct ahd_linux_target *targ);
++                                  struct aic_linux_target *targ);
+ static void ahd_linux_dv_fill_cmd(struct ahd_softc *ahd,
+                                 struct scsi_cmnd *cmd,
+                                 struct ahd_devinfo *devinfo);
+ static void ahd_linux_dv_inq(struct ahd_softc *ahd,
+                            struct scsi_cmnd *cmd,
+                            struct ahd_devinfo *devinfo,
+-                           struct ahd_linux_target *targ,
++                           struct aic_linux_target *targ,
+                            u_int request_length);
+ static void ahd_linux_dv_tur(struct ahd_softc *ahd,
+                            struct scsi_cmnd *cmd,
+@@ -500,19 +509,19 @@ static void ahd_linux_dv_tur(struct ahd_
+ static void ahd_linux_dv_rebd(struct ahd_softc *ahd,
+                             struct scsi_cmnd *cmd,
+                             struct ahd_devinfo *devinfo,
+-                            struct ahd_linux_target *targ);
++                            struct aic_linux_target *targ);
+ static void ahd_linux_dv_web(struct ahd_softc *ahd,
+                            struct scsi_cmnd *cmd,
+                            struct ahd_devinfo *devinfo,
+-                           struct ahd_linux_target *targ);
++                           struct aic_linux_target *targ);
+ static void ahd_linux_dv_reb(struct ahd_softc *ahd,
+                            struct scsi_cmnd *cmd,
+                            struct ahd_devinfo *devinfo,
+-                           struct ahd_linux_target *targ);
++                           struct aic_linux_target *targ);
+ static void ahd_linux_dv_su(struct ahd_softc *ahd,
+                           struct scsi_cmnd *cmd,
+                           struct ahd_devinfo *devinfo,
+-                          struct ahd_linux_target *targ);
++                          struct aic_linux_target *targ);
+ static __inline int
+          ahd_linux_dv_fallback(struct ahd_softc *ahd,
+                                struct ahd_devinfo *devinfo);
+@@ -520,103 +529,57 @@ static int ahd_linux_fallback(struct ahd
+                             struct ahd_devinfo *devinfo);
+ static __inline int ahd_linux_dv_fallback(struct ahd_softc *ahd,
+                                         struct ahd_devinfo *devinfo);
+-static void ahd_linux_dv_complete(Scsi_Cmnd *cmd);
+-static void ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ);
++static void ahd_linux_generate_dv_pattern(struct aic_linux_target *targ);
+ static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd,
+                                    struct ahd_devinfo *devinfo);
+ static u_int ahd_linux_user_dv_setting(struct ahd_softc *ahd);
+ static void ahd_linux_setup_user_rd_strm_settings(struct ahd_softc *ahd);
+-static void ahd_linux_device_queue_depth(struct ahd_softc *ahd,
+-                                       struct ahd_linux_device *dev);
+-static struct ahd_linux_target*       ahd_linux_alloc_target(struct ahd_softc*,
++static void aic_linux_device_queue_depth(struct ahd_softc *ahd,
++                                       struct aic_linux_device *dev);
++static struct aic_linux_target*       ahd_linux_alloc_target(struct ahd_softc*,
+                                                      u_int, u_int);
+ static void                   ahd_linux_free_target(struct ahd_softc*,
+-                                                    struct ahd_linux_target*);
+-static struct ahd_linux_device*       ahd_linux_alloc_device(struct ahd_softc*,
+-                                                     struct ahd_linux_target*,
++                                                    struct aic_linux_target*);
++static struct aic_linux_device*       ahd_linux_alloc_device(struct ahd_softc*,
++                                                     struct aic_linux_target*,
+                                                      u_int);
+ static void                   ahd_linux_free_device(struct ahd_softc*,
+-                                                    struct ahd_linux_device*);
+-static void ahd_linux_run_device_queue(struct ahd_softc*,
+-                                     struct ahd_linux_device*);
++                                                    struct aic_linux_device*);
+ static void ahd_linux_setup_tag_info_global(char *p);
+ static aic_option_callback_t ahd_linux_setup_tag_info;
+ static aic_option_callback_t ahd_linux_setup_rd_strm_info;
+ static aic_option_callback_t ahd_linux_setup_dv;
+ static aic_option_callback_t ahd_linux_setup_iocell_info;
+ static int ahd_linux_next_unit(void);
+-static void ahd_runq_tasklet(unsigned long data);
+ static int aic79xx_setup(char *c);
+ /****************************** Inlines ***************************************/
+ static __inline void ahd_schedule_completeq(struct ahd_softc *ahd);
+-static __inline void ahd_schedule_runq(struct ahd_softc *ahd);
+-static __inline void ahd_setup_runq_tasklet(struct ahd_softc *ahd);
+-static __inline void ahd_teardown_runq_tasklet(struct ahd_softc *ahd);
+-static __inline struct ahd_linux_device*
++static __inline struct aic_linux_device*
+                    ahd_linux_get_device(struct ahd_softc *ahd, u_int channel,
+                                         u_int target, u_int lun, int alloc);
+-static struct ahd_cmd *ahd_linux_run_complete_queue(struct ahd_softc *ahd);
+-static __inline void ahd_linux_check_device_queue(struct ahd_softc *ahd,
+-                                                struct ahd_linux_device *dev);
+-static __inline struct ahd_linux_device *
+-                   ahd_linux_next_device_to_run(struct ahd_softc *ahd);
+-static __inline void ahd_linux_run_device_queues(struct ahd_softc *ahd);
+ static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
+-
+-static __inline int ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb,
+-                                    struct ahd_dma_seg *sg,
+-                                    bus_addr_t addr, bus_size_t len);
++static __inline struct ahd_dma_seg*
++                   ahd_linux_sg_setup(struct ahd_softc *ahd, struct scb *scb,
++                                      struct ahd_dma_seg *sg, bus_addr_t addr,
++                                      bus_size_t len, int last_seg);
+ static __inline void
+ ahd_schedule_completeq(struct ahd_softc *ahd)
+ {
+-      if ((ahd->platform_data->flags & AHD_RUN_CMPLT_Q_TIMER) == 0) {
+-              ahd->platform_data->flags |= AHD_RUN_CMPLT_Q_TIMER;
++      if ((ahd->platform_data->flags & AIC_RUN_CMPLT_Q_TIMER) == 0) {
++              ahd->platform_data->flags |= AIC_RUN_CMPLT_Q_TIMER;
+               ahd->platform_data->completeq_timer.expires = jiffies;
+               add_timer(&ahd->platform_data->completeq_timer);
+       }
+ }
+-/*
+- * Must be called with our lock held.
+- */
+-static __inline void
+-ahd_schedule_runq(struct ahd_softc *ahd)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      tasklet_schedule(&ahd->platform_data->runq_tasklet);
+-#else
+-      /*
+-       * Tasklets are not available, so run inline.
+-       */
+-      ahd_runq_tasklet((unsigned long)ahd);
+-#endif
+-}
+-
+-static __inline
+-void ahd_setup_runq_tasklet(struct ahd_softc *ahd)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      tasklet_init(&ahd->platform_data->runq_tasklet, ahd_runq_tasklet,
+-                   (unsigned long)ahd);
+-#endif
+-}
+-
+-static __inline void
+-ahd_teardown_runq_tasklet(struct ahd_softc *ahd)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      tasklet_kill(&ahd->platform_data->runq_tasklet);
+-#endif
+-}
+-
+-static __inline struct ahd_linux_device*
++static __inline struct aic_linux_device*
+ ahd_linux_get_device(struct ahd_softc *ahd, u_int channel, u_int target,
+                    u_int lun, int alloc)
+ {
+-      struct ahd_linux_target *targ;
+-      struct ahd_linux_device *dev;
++      struct aic_linux_target *targ;
++      struct aic_linux_device *dev;
+       u_int target_offset;
+       target_offset = target;
+@@ -638,10 +601,10 @@ ahd_linux_get_device(struct ahd_softc *a
+ }
+ #define AHD_LINUX_MAX_RETURNED_ERRORS 4
+-static struct ahd_cmd *
++static struct aic_cmd *
+ ahd_linux_run_complete_queue(struct ahd_softc *ahd)
+ {     
+-      struct  ahd_cmd *acmd;
++      struct  aic_cmd *acmd;
+       u_long  done_flags;
+       int     with_errors;
+@@ -666,7 +629,7 @@ ahd_linux_run_complete_queue(struct ahd_
+                            acmd, acmd_links.tqe);
+               cmd = &acmd_scsi_cmd(acmd);
+               cmd->host_scribble = NULL;
+-              if (ahd_cmd_get_transaction_status(cmd) != DID_OK
++              if (aic_cmd_get_transaction_status(cmd) != DID_OK
+                || (cmd->result & 0xFF) != SCSI_STATUS_OK)
+                       with_errors++;
+@@ -677,46 +640,6 @@ ahd_linux_run_complete_queue(struct ahd_
+ }
+ static __inline void
+-ahd_linux_check_device_queue(struct ahd_softc *ahd,
+-                           struct ahd_linux_device *dev)
+-{
+-      if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) != 0
+-       && dev->active == 0) {
+-              dev->flags &= ~AHD_DEV_FREEZE_TIL_EMPTY;
+-              dev->qfrozen--;
+-      }
+-
+-      if (TAILQ_FIRST(&dev->busyq) == NULL
+-       || dev->openings == 0 || dev->qfrozen != 0)
+-              return;
+-
+-      ahd_linux_run_device_queue(ahd, dev);
+-}
+-
+-static __inline struct ahd_linux_device *
+-ahd_linux_next_device_to_run(struct ahd_softc *ahd)
+-{
+-      
+-      if ((ahd->flags & AHD_RESOURCE_SHORTAGE) != 0
+-       || (ahd->platform_data->qfrozen != 0
+-        && AHD_DV_SIMQ_FROZEN(ahd) == 0))
+-              return (NULL);
+-      return (TAILQ_FIRST(&ahd->platform_data->device_runq));
+-}
+-
+-static __inline void
+-ahd_linux_run_device_queues(struct ahd_softc *ahd)
+-{
+-      struct ahd_linux_device *dev;
+-
+-      while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) {
+-              TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links);
+-              dev->flags &= ~AHD_DEV_ON_RUN_LIST;
+-              ahd_linux_check_device_queue(ahd, dev);
+-      }
+-}
+-
+-static __inline void
+ ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
+ {
+       Scsi_Cmnd *cmd;
+@@ -729,34 +652,22 @@ ahd_linux_unmap_scb(struct ahd_softc *ah
+               struct scatterlist *sg;
+               sg = (struct scatterlist *)cmd->request_buffer;
+-              pci_unmap_sg(ahd->dev_softc, sg, cmd->use_sg, direction);
++              aic_unmap_sg(ahd, sg, cmd->use_sg, direction);
+       } else if (cmd->request_bufflen != 0) {
+-              pci_unmap_single(ahd->dev_softc,
++              aic_unmap_single(ahd,
+                                scb->platform_data->buf_busaddr,
+                                cmd->request_bufflen, direction);
+       }
+ }
+-static __inline int
+-ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb,
+-                struct ahd_dma_seg *sg, bus_addr_t addr, bus_size_t len)
++static __inline struct ahd_dma_seg*
++ahd_linux_sg_setup(struct ahd_softc *ahd, struct scb *scb,
++                 struct ahd_dma_seg *sg, bus_addr_t addr,
++                 bus_size_t len, int last_seg)
+ {
+-      int      consumed;
+-
+-      if ((scb->sg_count + 1) > AHD_NSEG)
+-              panic("Too few segs for dma mapping.  "
+-                    "Increase AHD_NSEG\n");
+-
+-      consumed = 1;
+-      sg->addr = ahd_htole32(addr & 0xFFFFFFFF);
++      sg = ahd_sg_setup(ahd, scb, sg, addr, len, last_seg);
+       scb->platform_data->xfer_len += len;
+-
+-      if (sizeof(bus_addr_t) > 4
+-       && (ahd->flags & AHD_39BIT_ADDRESSING) != 0)
+-              len |= (addr >> 8) & AHD_SG_HIGH_ADDR_MASK;
+-
+-      sg->len = ahd_htole32(len);
+-      return (consumed);
++      return (sg);
+ }
+ /******************************** Macros **************************************/
+@@ -797,7 +708,7 @@ static int    ahd_linux_abort(Scsi_Cmnd 
+  * number of segments needed for the current transfer.  Since the code that
+  * sizes the SCSI malloc pool does not take into consideration fragmentation
+  * of the pool, executing transactions numbering just a fraction of our
+- * concurrent transaction limit with SG list lengths aproaching AHC_NSEG will
++ * concurrent transaction limit with SG list lengths aproaching AHD_NSEG will
+  * quickly depleat the SCSI malloc pool of usable space.  Unfortunately, the
+  * mid-layer does not properly handle this scsi malloc failures for the S/G
+  * array and the result can be a lockup of the I/O subsystem.  We try to size
+@@ -848,6 +759,165 @@ ahd_linux_size_nseg(void)
+ #endif
+ }
++/************************** Error Recovery ************************************/
++static int ahd_linux_recovery_thread(void *arg);
++
++static int
++ahd_linux_recovery_thread(void *arg)
++{
++      struct ahd_softc *ahd;
++      u_long s;
++
++      ahd = (struct ahd_softc *)arg;
++
++      /*
++       * Complete thread creation.
++       */
++      lock_kernel();
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
++      /*
++       * Don't care about any signals.
++       */
++      siginitsetinv(&current->blocked, 0);
++
++      daemonize();
++      sprintf(current->comm, "ahd_recovery_%d", ahd->unit);
++#else
++      daemonize("ahd_recovery_%d", ahd->unit);
++#endif
++      unlock_kernel();
++
++      while (1) {
++
++              /*
++               * Use down_interruptible() rather than down() to
++               * avoid inclusion in the load average.
++               */
++              down_interruptible(&ahd->platform_data->recovery_sem);
++
++              ahd_lock(ahd, &s);
++              if ((ahd->flags & AHD_SHUTDOWN_RECOVERY) != 0) {
++                      ahd_unlock(ahd, &s);
++                      break;
++              }
++
++              /*
++               * Don't bother the recovery handler if the
++               * list has been cleared by a previous run
++               * of the handler.  This can happen when
++               * several SCBs timeout before our handler
++               * can run causing our semaphore to be up'ed
++               * repeatedly.  The extra calls need to be
++               * avoided so that the recovery handler doesn't
++               * confuse this case with timeouts occuring
++               * due to interrupts failing to function.
++               */
++              if (LIST_EMPTY(&ahd->timedout_scbs) != 0) {
++                      ahd_unlock(ahd, &s);
++                      continue;
++              }
++
++              ahd_unlock(ahd, &s);
++              ahd_recover_commands(ahd);
++
++              /*
++               * Process any pent up completions.
++               */
++              ahd_lock(ahd, &s);
++              aic_schedule_runq(ahd);
++              ahd_linux_run_complete_queue(ahd);
++              ahd_unlock(ahd, &s);
++      }
++      up(&ahd->platform_data->recovery_ending_sem);
++      return(0);
++}
++
++int
++ahd_spawn_recovery_thread(struct ahd_softc *ahd)
++{
++      ahd->platform_data->recovery_pid =
++          kernel_thread(ahd_linux_recovery_thread, ahd, 0);
++      
++      if (ahd->platform_data->recovery_pid < 0)
++              return (-ahd->platform_data->recovery_pid);
++
++      return (0);
++}
++
++void
++ahd_terminate_recovery_thread(struct ahd_softc *ahd)
++{
++      u_long s;
++
++      ahd_lock(ahd, &s);
++      if (ahd->platform_data->recovery_pid != 0) {
++              ahd->flags |= AHD_SHUTDOWN_RECOVERY;
++              ahd_unlock(ahd, &s);
++              up(&ahd->platform_data->recovery_sem);
++
++              /*
++               * Use the recovery_ending_sem as an indicator that
++               * the dv thread is exiting.  Note that the dv
++               * thread must still return after performing
++               * the up on our semaphore before it has
++               * completely exited this module.  Unfortunately,
++               * there seems to be no easy way to wait for the
++               * exit of a thread for which you are not the
++               * parent (dv threads are parented by init).
++               * Cross your fingers...
++               */
++              down(&ahd->platform_data->recovery_ending_sem);
++
++              /*
++               * Mark the recovery thread as already dead.  This
++               * avoids attempting to kill it a second time.
++               * This is necessary because we must kill the
++               * our threads before calling ahd_free() in the
++               * module shutdown case to avoid bogus locking
++               * in the SCSI mid-layer, but when ahd_free() is
++               * called without killing the DV thread in the
++               * instance detach case, so ahd_platform_free()
++               * calls us again to verify that the DV thread
++               * is dead.
++               */
++              ahd->platform_data->recovery_pid = 0;
++      } else {
++              ahd_unlock(ahd, &s);
++      }
++}
++
++void
++ahd_set_recoveryscb(struct ahd_softc *ahd, struct scb *scb)
++{
++      if ((scb->flags & SCB_RECOVERY_SCB) == 0) {
++              struct scb *list_scb;
++
++              scb->flags |= SCB_RECOVERY_SCB;
++
++              /*
++               * Take all queued, but not sent SCBs out of the equation.
++               * Also ensure that no new commands are queued to us while we
++               * try to fix this problem.
++               */
++              if ((scb->platform_data->flags & AIC_RELEASE_SIMQ) == 0) {
++                      aic_freeze_simq(ahd);
++                      scb->platform_data->flags |= AIC_RELEASE_SIMQ;
++              }
++
++              /*
++               * Go through all of our pending SCBs and remove
++               * any scheduled timeouts for them.  We will reschedule
++               * them after we've successfully fixed this problem.
++               */
++              LIST_FOREACH(list_scb, &ahd->pending_scbs, pending_links) {
++
++                      scsi_delete_timer(list_scb->io_ctx);
++                      list_scb->platform_data->flags &= ~AIC_TIMEOUT_ACTIVE;
++              }
++      }
++}
++
++/********************** Host Template Entry Points ****************************/
+ /*
+  * Try to detect an Adaptec 79XX controller.
+  */
+@@ -870,7 +940,7 @@ ahd_linux_detect(Scsi_Host_Template *tem
+        * that some of our hacks^H^H^H^H^Hassumptions aren't
+        * violated.
+        */
+-      if (offsetof(struct ahd_cmd_internal, end)
++      if (offsetof(struct aic_cmd_internal, end)
+         > offsetof(struct scsi_cmnd, host_scribble)) {
+               printf("ahd_linux_detect: SCSI data structures changed.\n");
+               printf("ahd_linux_detect: Unable to attach\n");
+@@ -938,7 +1008,6 @@ ahd_linux_release(struct Scsi_Host * hos
+       struct ahd_softc *ahd;
+       u_long l;
+-      ahd_list_lock(&l);
+       if (host != NULL) {
+               /*
+@@ -946,17 +1015,20 @@ ahd_linux_release(struct Scsi_Host * hos
+                * the free directly, but check our
+                * list for extra sanity.
+                */
++              ahd_list_lock(&l);
+               ahd = ahd_find_softc(*(struct ahd_softc **)host->hostdata);
+               if (ahd != NULL) {
+                       u_long s;
++                      TAILQ_REMOVE(&ahd_tailq, ahd, links);
++                      ahd_list_unlock(&l);
+                       ahd_lock(ahd, &s);
+                       ahd_intr_enable(ahd, FALSE);
+                       ahd_unlock(ahd, &s);
+                       ahd_free(ahd);
+-              }
++              } else
++                      ahd_list_unlock(&l);
+       }
+-      ahd_list_unlock(&l);
+       return (0);
+ }
+ #endif
+@@ -996,7 +1068,7 @@ static int
+ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
+ {
+       struct   ahd_softc *ahd;
+-      struct   ahd_linux_device *dev;
++      struct   aic_linux_device *dev;
+       u_long   flags;
+       ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
+@@ -1015,9 +1087,9 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*
+        * perform DV.
+        */
+       if (ahd->platform_data->qfrozen != 0
+-       && AHD_DV_CMD(cmd) == 0) {
++       && AIC_DV_CMD(cmd) == 0) {
+-              ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ);
++              aic_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ);
+               ahd_linux_queue_cmd_complete(ahd, cmd);
+               ahd_schedule_completeq(ahd);
+               ahd_midlayer_entrypoint_unlock(ahd, &flags);
+@@ -1027,7 +1099,8 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*
+                                  cmd->device->id, cmd->device->lun,
+                                  /*alloc*/TRUE);
+       if (dev == NULL) {
+-              ahd_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
++
++              aic_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
+               ahd_linux_queue_cmd_complete(ahd, cmd);
+               ahd_schedule_completeq(ahd);
+               ahd_midlayer_entrypoint_unlock(ahd, &flags);
+@@ -1035,14 +1108,30 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*
+                      ahd_name(ahd));
+               return (0);
+       }
+-      if (cmd->cmd_len > MAX_CDB_LEN)
+-              return (-EINVAL);
++
++      if (cmd->cmd_len > MAX_CDB_LEN) {
++
++              aic_cmd_set_transaction_status(cmd, CAM_REQ_INVALID);
++              ahd_linux_queue_cmd_complete(ahd, cmd);
++              ahd_schedule_completeq(ahd);
++              ahd_midlayer_entrypoint_unlock(ahd, &flags);
++              printf("%s: aic79xx_linux_queue -"
++                     "CDB length of %d exceeds max!\n",
++                     ahd_name(ahd), cmd->cmd_len);
++              return (0);
++      }
++
++      /*
++       * We perform our own timeout handling.
++       */
++      scsi_delete_timer(cmd);
++
+       cmd->result = CAM_REQ_INPROG << 16;
+-      TAILQ_INSERT_TAIL(&dev->busyq, (struct ahd_cmd *)cmd, acmd_links.tqe);
+-      if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) {
++      TAILQ_INSERT_TAIL(&dev->busyq, (struct aic_cmd *)cmd, acmd_links.tqe);
++      if ((dev->flags & AIC_DEV_ON_RUN_LIST) == 0) {
+               TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links);
+-              dev->flags |= AHD_DEV_ON_RUN_LIST;
+-              ahd_linux_run_device_queues(ahd);
++              dev->flags |= AIC_DEV_ON_RUN_LIST;
++              aic_linux_run_device_queues(ahd);
+       }
+       ahd_midlayer_entrypoint_unlock(ahd, &flags);
+       return (0);
+@@ -1064,7 +1153,7 @@ static int
+ ahd_linux_slave_configure(Scsi_Device *device)
+ {
+       struct  ahd_softc *ahd;
+-      struct  ahd_linux_device *dev;
++      struct  aic_linux_device *dev;
+       u_long  flags;
+       ahd = *((struct ahd_softc **)device->host->hostdata);
+@@ -1080,10 +1169,10 @@ ahd_linux_slave_configure(Scsi_Device *d
+                                  device->id, device->lun,
+                                  /*alloc*/TRUE);
+       if (dev != NULL) {
+-              dev->flags &= ~AHD_DEV_UNCONFIGURED;
+-              dev->flags |= AHD_DEV_SLAVE_CONFIGURED;
++              dev->flags &= ~AIC_DEV_UNCONFIGURED;
++              dev->flags |= AIC_DEV_SLAVE_CONFIGURED;
+               dev->scsi_device = device;
+-              ahd_linux_device_queue_depth(ahd, dev);
++              aic_linux_device_queue_depth(ahd, dev);
+       }
+       ahd_midlayer_entrypoint_unlock(ahd, &flags);
+       return (0);
+@@ -1093,7 +1182,7 @@ static void
+ ahd_linux_slave_destroy(Scsi_Device *device)
+ {
+       struct  ahd_softc *ahd;
+-      struct  ahd_linux_device *dev;
++      struct  aic_linux_device *dev;
+       u_long  flags;
+       ahd = *((struct ahd_softc **)device->host->hostdata);
+@@ -1112,11 +1201,10 @@ ahd_linux_slave_destroy(Scsi_Device *dev
+        * the refcounting process.
+        */
+       if (dev != NULL
+-       && (dev->flags & AHD_DEV_SLAVE_CONFIGURED) != 0) {
+-              dev->flags |= AHD_DEV_UNCONFIGURED;
++       && (dev->flags & AIC_DEV_SLAVE_CONFIGURED) != 0) {
++              dev->flags |= AIC_DEV_UNCONFIGURED;
+               if (TAILQ_EMPTY(&dev->busyq)
+-               && dev->active == 0
+-               && (dev->flags & AHD_DEV_TIMER_ACTIVE) == 0)
++               && dev->active == 0)
+                       ahd_linux_free_device(ahd, dev);
+       }
+       ahd_midlayer_entrypoint_unlock(ahd, &flags);
+@@ -1156,7 +1244,7 @@ ahd_linux_select_queue_depth(struct Scsi
+                       continue;
+               if (device->host == host) {
+-                      struct   ahd_linux_device *dev;
++                      struct   aic_linux_device *dev;
+                       /*
+                        * Since Linux has attached to the device, configure
+@@ -1167,13 +1255,13 @@ ahd_linux_select_queue_depth(struct Scsi
+                                                  device->id, device->lun,
+                                                  /*alloc*/TRUE);
+                       if (dev != NULL) {
+-                              dev->flags &= ~AHD_DEV_UNCONFIGURED;
++                              dev->flags &= ~AIC_DEV_UNCONFIGURED;
+                               dev->scsi_device = device;
+-                              ahd_linux_device_queue_depth(ahd, dev);
++                              aic_linux_device_queue_depth(ahd, dev);
+                               device->queue_depth = dev->openings
+                                                   + dev->active;
+-                              if ((dev->flags & (AHD_DEV_Q_BASIC
+-                                              | AHD_DEV_Q_TAGGED)) == 0) {
++                              if ((dev->flags & (AIC_DEV_Q_BASIC
++                                              | AIC_DEV_Q_TAGGED)) == 0) {
+                                       /*
+                                        * We allow the OS to queue 2 untagged
+                                        * transactions to us at any time even
+@@ -1262,9 +1350,9 @@ static int
+ ahd_linux_abort(Scsi_Cmnd *cmd)
+ {
+       struct ahd_softc *ahd;
+-      struct ahd_cmd *acmd;
+-      struct ahd_cmd *list_acmd;
+-      struct ahd_linux_device *dev;
++      struct aic_cmd *acmd;
++      struct aic_cmd *list_acmd;
++      struct aic_linux_device *dev;
+       struct scb *pending_scb;
+       u_long s;
+       u_int  saved_scbptr;
+@@ -1282,7 +1370,7 @@ ahd_linux_abort(Scsi_Cmnd *cmd)
+       paused = FALSE;
+       wait = FALSE;
+       ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
+-      acmd = (struct ahd_cmd *)cmd;
++      acmd = (struct aic_cmd *)cmd;
+       printf("%s:%d:%d:%d: Attempting to abort cmd %p:",
+              ahd_name(ahd), cmd->device->channel, cmd->device->id,
+@@ -1341,6 +1429,17 @@ ahd_linux_abort(Scsi_Cmnd *cmd)
+                      cmd->device->lun);
+               TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe);
+               cmd->result = DID_ABORT << 16;
++              /*
++               * The completion handler believes that
++               * commands without active timers running
++               * have lost the race of completing before
++               * their timer expires.  Since commands in
++               * our busy queues do not have timers running,
++               * appease the mid-layer by adding a timer
++               * now.  This timer will be immediately
++               * canceled by the midlayer.
++               */
++              scsi_add_timer(cmd, 60*HZ, aic_linux_midlayer_timeout);
+               ahd_linux_queue_cmd_complete(ahd, cmd);
+               retval = SUCCESS;
+               goto done;
+@@ -1516,7 +1615,7 @@ done:
+               struct timer_list timer;
+               int ret;
+-              pending_scb->platform_data->flags |= AHD_SCB_UP_EH_SEM;
++              pending_scb->platform_data->flags |= AIC_SCB_UP_EH_SEM;
+               spin_unlock_irq(&ahd->platform_data->spin_lock);
+               init_timer(&timer);
+               timer.data = (u_long)pending_scb;
+@@ -1533,7 +1632,7 @@ done:
+               }
+               spin_lock_irq(&ahd->platform_data->spin_lock);
+       }
+-      ahd_schedule_runq(ahd);
++      aic_schedule_runq(ahd);
+       ahd_linux_run_complete_queue(ahd);
+       ahd_midlayer_entrypoint_unlock(ahd, &s);
+       return (retval);
+@@ -1554,7 +1653,7 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
+ {
+       struct  ahd_softc *ahd;
+       struct  scsi_cmnd *recovery_cmd;
+-      struct  ahd_linux_device *dev;
++      struct  aic_linux_device *dev;
+       struct  ahd_initiator_tinfo *tinfo;
+       struct  ahd_tmode_tstate *tstate;
+       struct  scb *scb;
+@@ -1592,9 +1691,11 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
+       recovery_cmd->host_scribble = (char *)scb;
+       scb->io_ctx = recovery_cmd;
+       scb->platform_data->dev = dev;
++      scb->platform_data->flags = 0;
+       scb->sg_count = 0;
+-      ahd_set_residual(scb, 0);
+-      ahd_set_sense_residual(scb, 0);
++      aic_set_residual(scb, 0);
++      aic_set_sense_residual(scb, 0);
++      scb->platform_data->xfer_len = 0;
+       hscb = scb->hscb;
+       hscb->control = 0;
+       hscb->scsiid = BUILD_SCSIID(ahd, cmd);
+@@ -1613,7 +1714,7 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
+       LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
+       ahd_queue_scb(ahd, scb);
+-      scb->platform_data->flags |= AHD_SCB_UP_EH_SEM;
++      scb->platform_data->flags |= AIC_SCB_UP_EH_SEM;
+       spin_unlock_irq(&ahd->platform_data->spin_lock);
+       init_timer(&timer);
+       timer.data = (u_long)scb;
+@@ -1629,7 +1730,7 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
+               retval = FAILED;
+       }
+       spin_lock_irq(&ahd->platform_data->spin_lock);
+-      ahd_schedule_runq(ahd);
++      aic_schedule_runq(ahd);
+       ahd_linux_run_complete_queue(ahd);
+       ahd_midlayer_entrypoint_unlock(ahd, &s);
+       printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
+@@ -1665,189 +1766,8 @@ ahd_linux_bus_reset(Scsi_Cmnd *cmd)
+       return (SUCCESS);
+ }
+-Scsi_Host_Template aic79xx_driver_template = {
+-      .module                 = THIS_MODULE,
+-      .name                   = "aic79xx",
+-      .proc_info              = ahd_linux_proc_info,
+-      .info                   = ahd_linux_info,
+-      .queuecommand           = ahd_linux_queue,
+-      .eh_abort_handler       = ahd_linux_abort,
+-      .eh_device_reset_handler = ahd_linux_dev_reset,
+-      .eh_bus_reset_handler   = ahd_linux_bus_reset,
+-#if defined(__i386__)
+-      .bios_param             = ahd_linux_biosparam,
+-#endif
+-      .can_queue              = AHD_MAX_QUEUE,
+-      .this_id                = -1,
+-      .cmd_per_lun            = 2,
+-      .use_clustering         = ENABLE_CLUSTERING,
+-      .slave_alloc            = ahd_linux_slave_alloc,
+-      .slave_configure        = ahd_linux_slave_configure,
+-      .slave_destroy          = ahd_linux_slave_destroy,
+-};
+-
+-/**************************** Tasklet Handler *********************************/
+-
+-/*
+- * In 2.4.X and above, this routine is called from a tasklet,
+- * so we must re-acquire our lock prior to executing this code.
+- * In all prior kernels, ahd_schedule_runq() calls this routine
+- * directly and ahd_schedule_runq() is called with our lock held.
+- */
+-static void
+-ahd_runq_tasklet(unsigned long data)
+-{
+-      struct ahd_softc* ahd;
+-      struct ahd_linux_device *dev;
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      u_long flags;
+-#endif
+-
+-      ahd = (struct ahd_softc *)data;
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      ahd_lock(ahd, &flags);
+-#endif
+-      while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) {
+-      
+-              TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links);
+-              dev->flags &= ~AHD_DEV_ON_RUN_LIST;
+-              ahd_linux_check_device_queue(ahd, dev);
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-              /* Yeild to our interrupt handler */
+-              ahd_unlock(ahd, &flags);
+-              ahd_lock(ahd, &flags);
+-#endif
+-      }
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      ahd_unlock(ahd, &flags);
+-#endif
+-}
+-
+-/******************************** Bus DMA *************************************/
+-int
+-ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent,
+-                 bus_size_t alignment, bus_size_t boundary,
+-                 bus_addr_t lowaddr, bus_addr_t highaddr,
+-                 bus_dma_filter_t *filter, void *filterarg,
+-                 bus_size_t maxsize, int nsegments,
+-                 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
+-{
+-      bus_dma_tag_t dmat;
+-
+-      dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT);
+-      if (dmat == NULL)
+-              return (ENOMEM);
+-
+-      /*
+-       * Linux is very simplistic about DMA memory.  For now don't
+-       * maintain all specification information.  Once Linux supplies
+-       * better facilities for doing these operations, or the
+-       * needs of this particular driver change, we might need to do
+-       * more here.
+-       */
+-      dmat->alignment = alignment;
+-      dmat->boundary = boundary;
+-      dmat->maxsize = maxsize;
+-      *ret_tag = dmat;
+-      return (0);
+-}
+-
+-void
+-ahd_dma_tag_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat)
+-{
+-      free(dmat, M_DEVBUF);
+-}
+-
+-int
+-ahd_dmamem_alloc(struct ahd_softc *ahd, bus_dma_tag_t dmat, void** vaddr,
+-               int flags, bus_dmamap_t *mapp)
+-{
+-      bus_dmamap_t map;
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT);
+-      if (map == NULL)
+-              return (ENOMEM);
+-      /*
+-       * Although we can dma data above 4GB, our
+-       * "consistent" memory is below 4GB for
+-       * space efficiency reasons (only need a 4byte
+-       * address).  For this reason, we have to reset
+-       * our dma mask when doing allocations.
+-       */
+-      if (ahd->dev_softc != NULL)
+-              ahd_pci_set_dma_mask(ahd->dev_softc, 0xFFFFFFFF);
+-      *vaddr = pci_alloc_consistent(ahd->dev_softc,
+-                                    dmat->maxsize, &map->bus_addr);
+-      if (ahd->dev_softc != NULL)
+-              ahd_pci_set_dma_mask(ahd->dev_softc,
+-                                   ahd->platform_data->hw_dma_mask);
+-#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */
+-      /*
+-       * At least in 2.2.14, malloc is a slab allocator so all
+-       * allocations are aligned.  We assume for these kernel versions
+-       * that all allocations will be bellow 4Gig, physically contiguous,
+-       * and accessible via DMA by the controller.
+-       */
+-      map = NULL; /* No additional information to store */
+-      *vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT);
+-#endif
+-      if (*vaddr == NULL)
+-              return (ENOMEM);
+-      *mapp = map;
+-      return(0);
+-}
+-
+-void
+-ahd_dmamem_free(struct ahd_softc *ahd, bus_dma_tag_t dmat,
+-              void* vaddr, bus_dmamap_t map)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      pci_free_consistent(ahd->dev_softc, dmat->maxsize,
+-                          vaddr, map->bus_addr);
+-#else
+-      free(vaddr, M_DEVBUF);
+-#endif
+-}
+-
+-int
+-ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map,
+-              void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
+-              void *cb_arg, int flags)
+-{
+-      /*
+-       * Assume for now that this will only be used during
+-       * initialization and not for per-transaction buffer mapping.
+-       */
+-      bus_dma_segment_t stack_sg;
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      stack_sg.ds_addr = map->bus_addr;
+-#else
+-#define VIRT_TO_BUS(a) (uint32_t)virt_to_bus((void *)(a))
+-      stack_sg.ds_addr = VIRT_TO_BUS(buf);
+-#endif
+-      stack_sg.ds_len = dmat->maxsize;
+-      cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0);
+-      return (0);
+-}
+-
+-void
+-ahd_dmamap_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
+-{
+-      /*
+-       * The map may is NULL in our < 2.3.X implementation.
+-       */
+-      if (map != NULL)
+-              free(map, M_DEVBUF);
+-}
+-
+-int
+-ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
+-{
+-      /* Nothing to do */
+-      return (0);
+-}
++Scsi_Host_Template aic79xx_driver_template = 
++      AIC_TEMPLATE_INITIALIZER("aic79xx", /*max_sectors*/8192);
+ /********************* Platform Dependent Functions ***************************/
+ /*
+@@ -1883,19 +1803,19 @@ ahd_softc_comp(struct ahd_softc *lahd, s
+       /* Still equal.  Sort by bus/slot/func. */
+       if (aic79xx_reverse_scan != 0)
+-              value = ahd_get_pci_bus(lahd->dev_softc)
+-                    - ahd_get_pci_bus(rahd->dev_softc);
++              value = aic_get_pci_bus(lahd->dev_softc)
++                    - aic_get_pci_bus(rahd->dev_softc);
+       else
+-              value = ahd_get_pci_bus(rahd->dev_softc)
+-                    - ahd_get_pci_bus(lahd->dev_softc);
++              value = aic_get_pci_bus(rahd->dev_softc)
++                    - aic_get_pci_bus(lahd->dev_softc);
+       if (value != 0)
+               return (value);
+       if (aic79xx_reverse_scan != 0)
+-              value = ahd_get_pci_slot(lahd->dev_softc)
+-                    - ahd_get_pci_slot(rahd->dev_softc);
++              value = aic_get_pci_slot(lahd->dev_softc)
++                    - aic_get_pci_slot(rahd->dev_softc);
+       else
+-              value = ahd_get_pci_slot(rahd->dev_softc)
+-                    - ahd_get_pci_slot(lahd->dev_softc);
++              value = aic_get_pci_slot(rahd->dev_softc)
++                    - aic_get_pci_slot(lahd->dev_softc);
+       if (value != 0)
+               return (value);
+@@ -2072,9 +1992,16 @@ ahd_linux_register_host(struct ahd_softc
+       char    *new_name;
+       u_long  s;
+       u_long  target;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++      int     error;
++#endif
+       template->name = ahd->description;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       host = scsi_host_alloc(template, sizeof(struct ahd_softc *));
++#else
++      host = scsi_register(template, sizeof(struct ahd_softc *));
++#endif
+       if (host == NULL)
+               return (ENOMEM);
+@@ -2083,8 +2010,12 @@ ahd_linux_register_host(struct ahd_softc
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       scsi_assign_lock(host, &ahd->platform_data->spin_lock);
+ #elif AHD_SCSI_HAS_HOST_LOCK != 0
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,21)
++      host->host_lock = &ahd->platform_data->spin_lock;
++#else
+       host->lock = &ahd->platform_data->spin_lock;
+ #endif
++#endif
+       ahd->platform_data->host = host;
+       host->can_queue = AHD_MAX_QUEUE;
+       host->cmd_per_lun = 2;
+@@ -2110,13 +2041,20 @@ ahd_linux_register_host(struct ahd_softc
+       ahd_linux_setup_user_rd_strm_settings(ahd);
+       ahd_linux_initialize_scsi_bus(ahd);
+       ahd_unlock(ahd, &s);
++      ahd_sysrq_key = aic_install_sysrq(&ahd_sysrq_op);
++      ahd_spawn_recovery_thread(ahd);
++      if (ahd->platform_data->recovery_pid < 0) {
++              printf("%s: Failed to create recovery thread, error= %d\n",
++                     ahd_name(ahd), ahd->platform_data->recovery_pid);
++              return (-ahd->platform_data->recovery_pid);
++      }
+       ahd->platform_data->dv_pid = kernel_thread(ahd_linux_dv_thread, ahd, 0);
+-      ahd_lock(ahd, &s);
+       if (ahd->platform_data->dv_pid < 0) {
+               printf("%s: Failed to create DV thread, error= %d\n",
+                      ahd_name(ahd), ahd->platform_data->dv_pid);
+               return (-ahd->platform_data->dv_pid);
+       }
++      ahd_lock(ahd, &s);
+       /*
+        * Initially allocate *all* of our linux target objects
+        * so that the DV thread will scan them all in parallel
+@@ -2136,7 +2074,7 @@ ahd_linux_register_host(struct ahd_softc
+                * It is expected that either an external application
+                * or a modified kernel will be used to probe this
+                * ID if it is appropriate.  To accommodate these
+-               * installations, ahc_linux_alloc_target() will allocate
++               * installations, ahd_linux_alloc_target() will allocate
+                * for our ID if asked to do so.
+                */
+               if (target == ahd->our_id) 
+@@ -2149,7 +2087,9 @@ ahd_linux_register_host(struct ahd_softc
+       ahd_unlock(ahd, &s);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+-      scsi_add_host(host, &ahd->dev_softc->dev); /* XXX handle failure */
++      error = scsi_add_host(host, ahd->dev_softc);
++      if (error != 0)
++              return (-error);
+       scsi_scan_host(host);
+ #endif
+       return (0);
+@@ -2225,17 +2165,6 @@ ahd_linux_initialize_scsi_bus(struct ahd
+               ahd_update_neg_request(ahd, &devinfo, tstate,
+                                      tinfo, AHD_NEG_ALWAYS);
+       }
+-      /* Give the bus some time to recover */
+-      if ((ahd->flags & AHD_RESET_BUS_A) != 0) {
+-              ahd_freeze_simq(ahd);
+-              init_timer(&ahd->platform_data->reset_timer);
+-              ahd->platform_data->reset_timer.data = (u_long)ahd;
+-              ahd->platform_data->reset_timer.expires =
+-                  jiffies + (AIC79XX_RESET_DELAY * HZ)/1000;
+-              ahd->platform_data->reset_timer.function =
+-                  (ahd_linux_callback_t *)ahd_release_simq;
+-              add_timer(&ahd->platform_data->reset_timer);
+-      }
+ }
+ int
+@@ -2248,24 +2177,32 @@ ahd_platform_alloc(struct ahd_softc *ahd
+       memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data));
+       TAILQ_INIT(&ahd->platform_data->completeq);
+       TAILQ_INIT(&ahd->platform_data->device_runq);
+-      ahd->platform_data->irq = AHD_LINUX_NOIRQ;
++      ahd->platform_data->irq = AIC_LINUX_NOIRQ;
+       ahd->platform_data->hw_dma_mask = 0xFFFFFFFF;
+       ahd_lockinit(ahd);
+       ahd_done_lockinit(ahd);
++      init_timer(&ahd->platform_data->bus_settle_timer);
++      ahd->platform_data->bus_settle_timer.data = (u_long)ahd;
++      ahd->platform_data->bus_settle_timer.function =
++          (aic_linux_callback_t *)aic_bus_settle_complete;
+       init_timer(&ahd->platform_data->completeq_timer);
+       ahd->platform_data->completeq_timer.data = (u_long)ahd;
+       ahd->platform_data->completeq_timer.function =
+-          (ahd_linux_callback_t *)ahd_linux_thread_run_complete_queue;
++          (aic_linux_callback_t *)ahd_linux_thread_run_complete_queue;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+       init_MUTEX_LOCKED(&ahd->platform_data->eh_sem);
+       init_MUTEX_LOCKED(&ahd->platform_data->dv_sem);
+       init_MUTEX_LOCKED(&ahd->platform_data->dv_cmd_sem);
++      init_MUTEX_LOCKED(&ahd->platform_data->recovery_sem);
++      init_MUTEX_LOCKED(&ahd->platform_data->recovery_ending_sem);
+ #else
+       ahd->platform_data->eh_sem = MUTEX_LOCKED;
+       ahd->platform_data->dv_sem = MUTEX_LOCKED;
+       ahd->platform_data->dv_cmd_sem = MUTEX_LOCKED;
++      ahd->platform_data->recovery_sem = MUTEX_LOCKED;
++      ahd->platform_data->recovery_ending_sem = MUTEX_LOCKED;
+ #endif
+-      ahd_setup_runq_tasklet(ahd);
++      aic_setup_tasklets(ahd);
+       ahd->seltime = (aic79xx_seltime & 0x3) << 4;
+       return (0);
+ }
+@@ -2273,19 +2210,22 @@ ahd_platform_alloc(struct ahd_softc *ahd
+ void
+ ahd_platform_free(struct ahd_softc *ahd)
+ {
+-      struct ahd_linux_target *targ;
+-      struct ahd_linux_device *dev;
++      struct aic_linux_target *targ;
++      struct aic_linux_device *dev;
+       int i, j;
++      aic_remove_sysrq(ahd_sysrq_key, &ahd_sysrq_op);
+       if (ahd->platform_data != NULL) {
+               del_timer_sync(&ahd->platform_data->completeq_timer);
+               ahd_linux_kill_dv_thread(ahd);
+-              ahd_teardown_runq_tasklet(ahd);
++              aic_teardown_tasklets(ahd);
+               if (ahd->platform_data->host != NULL) {
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+                       scsi_remove_host(ahd->platform_data->host);
+-#endif
+                       scsi_host_put(ahd->platform_data->host);
++#else
++                      scsi_unregister(ahd->platform_data->host);
++#endif
+               }
+               /* destroy all of the device and target objects */
+@@ -2299,6 +2239,7 @@ ahd_platform_free(struct ahd_softc *ahd)
+                                       if (targ->devices[j] == NULL)
+                                               continue;
+                                       dev = targ->devices[j];
++                                      del_timer_sync(&dev->timer);
+                                       ahd_linux_free_device(ahd, dev);
+                               }
+                               /*
+@@ -2309,7 +2250,7 @@ ahd_platform_free(struct ahd_softc *ahd)
+                       }
+               }
+-              if (ahd->platform_data->irq != AHD_LINUX_NOIRQ)
++              if (ahd->platform_data->irq != AIC_LINUX_NOIRQ)
+                       free_irq(ahd->platform_data->irq, ahd);
+               if (ahd->tags[0] == BUS_SPACE_PIO
+                && ahd->bshs[0].ioport != 0)
+@@ -2377,7 +2318,7 @@ void
+ ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
+                     ahd_queue_alg alg)
+ {
+-      struct ahd_linux_device *dev;
++      struct aic_linux_device *dev;
+       int was_queuing;
+       int now_queuing;
+@@ -2386,27 +2327,27 @@ ahd_platform_set_tags(struct ahd_softc *
+                                  devinfo->lun, /*alloc*/FALSE);
+       if (dev == NULL)
+               return;
+-      was_queuing = dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED);
++      was_queuing = dev->flags & (AIC_DEV_Q_BASIC|AIC_DEV_Q_TAGGED);
+       switch (alg) {
+       default:
+       case AHD_QUEUE_NONE:
+               now_queuing = 0;
+               break; 
+       case AHD_QUEUE_BASIC:
+-              now_queuing = AHD_DEV_Q_BASIC;
++              now_queuing = AIC_DEV_Q_BASIC;
+               break;
+       case AHD_QUEUE_TAGGED:
+-              now_queuing = AHD_DEV_Q_TAGGED;
++              now_queuing = AIC_DEV_Q_TAGGED;
+               break;
+       }
+-      if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) == 0
++      if ((dev->flags & AIC_DEV_FREEZE_TIL_EMPTY) == 0
+        && (was_queuing != now_queuing)
+        && (dev->active != 0)) {
+-              dev->flags |= AHD_DEV_FREEZE_TIL_EMPTY;
++              dev->flags |= AIC_DEV_FREEZE_TIL_EMPTY;
+               dev->qfrozen++;
+       }
+-      dev->flags &= ~(AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED|AHD_DEV_PERIODIC_OTAG);
++      dev->flags &= ~(AIC_DEV_Q_BASIC|AIC_DEV_Q_TAGGED|AIC_DEV_PERIODIC_OTAG);
+       if (now_queuing) {
+               u_int usertags;
+@@ -2426,11 +2367,11 @@ ahd_platform_set_tags(struct ahd_softc *
+                        */
+                       dev->openings = 1;
+               } else if (alg == AHD_QUEUE_TAGGED) {
+-                      dev->flags |= AHD_DEV_Q_TAGGED;
++                      dev->flags |= AIC_DEV_Q_TAGGED;
+                       if (aic79xx_periodic_otag != 0)
+-                              dev->flags |= AHD_DEV_PERIODIC_OTAG;
++                              dev->flags |= AIC_DEV_PERIODIC_OTAG;
+               } else
+-                      dev->flags |= AHD_DEV_Q_BASIC;
++                      dev->flags |= AIC_DEV_Q_BASIC;
+       } else {
+               /* We can only have one opening. */
+               dev->maxtags = 0;
+@@ -2438,13 +2379,13 @@ ahd_platform_set_tags(struct ahd_softc *
+       }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       if (dev->scsi_device != NULL) {
+-              switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) {
+-              case AHD_DEV_Q_BASIC:
++              switch ((dev->flags & (AIC_DEV_Q_BASIC|AIC_DEV_Q_TAGGED))) {
++              case AIC_DEV_Q_BASIC:
+                       scsi_adjust_queue_depth(dev->scsi_device,
+                                               MSG_SIMPLE_TASK,
+                                               dev->openings + dev->active);
+                       break;
+-              case AHD_DEV_Q_TAGGED:
++              case AIC_DEV_Q_TAGGED:
+                       scsi_adjust_queue_depth(dev->scsi_device,
+                                               MSG_ORDERED_TASK,
+                                               dev->openings + dev->active);
+@@ -2497,9 +2438,9 @@ ahd_platform_abort_scbs(struct ahd_softc
+       for (; targ < maxtarg; targ++) {
+               for (; clun < maxlun; clun++) {
+-                      struct ahd_linux_device *dev;
+-                      struct ahd_busyq *busyq;
+-                      struct ahd_cmd *acmd;
++                      struct aic_linux_device *dev;
++                      struct aic_busyq *busyq;
++                      struct aic_cmd *acmd;
+                       dev = ahd_linux_get_device(ahd, /*chan*/0, targ,
+                                                  clun, /*alloc*/FALSE);
+@@ -2515,6 +2456,18 @@ ahd_platform_abort_scbs(struct ahd_softc
+                                            acmd_links.tqe);
+                               count++;
+                               cmd->result = status << 16;
++                              /*
++                               * The completion handler believes that
++                               * commands without active timers running
++                               * have lost the race of completing before
++                               * their timer expires.  Since commands in
++                               * our busy queues do not have timers running,
++                               * appease the mid-layer by adding a timer
++                               * now.  This timer will be immediately
++                               * canceled by the midlayer.
++                               */
++                              scsi_add_timer(cmd, 60*HZ,
++                                             aic_linux_midlayer_timeout);
+                               ahd_linux_queue_cmd_complete(ahd, cmd);
+                       }
+               }
+@@ -2530,7 +2483,7 @@ ahd_linux_thread_run_complete_queue(stru
+       ahd_lock(ahd, &flags);
+       del_timer(&ahd->platform_data->completeq_timer);
+-      ahd->platform_data->flags &= ~AHD_RUN_CMPLT_Q_TIMER;
++      ahd->platform_data->flags &= ~AIC_RUN_CMPLT_Q_TIMER;
+       ahd_linux_run_complete_queue(ahd);
+       ahd_unlock(ahd, &flags);
+ }
+@@ -2543,14 +2496,23 @@ ahd_linux_start_dv(struct ahd_softc *ahd
+        * Freeze the simq and signal ahd_linux_queue to not let any
+        * more commands through
+        */
+-      if ((ahd->platform_data->flags & AHD_DV_ACTIVE) == 0) {
++      if ((ahd->platform_data->flags & AIC_DV_ACTIVE) == 0) {
+ #ifdef AHD_DEBUG
+               if (ahd_debug & AHD_SHOW_DV)
+                       printf("%s: Starting DV\n", ahd_name(ahd));
+ #endif
+-              ahd->platform_data->flags |= AHD_DV_ACTIVE;
+-              ahd_freeze_simq(ahd);
++              ahd->platform_data->flags |= AIC_DV_ACTIVE;
++
++              /*
++               * Prevent upper layer from sending any
++               * commands to us.
++               */
++              aic_freeze_simq(ahd);
++              scsi_block_requests(ahd->platform_data->host);
++              ahd_platform_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
++                                      CAM_LUN_WILDCARD, SCB_LIST_NULL,
++                                      ROLE_INITIATOR, CAM_REQUEUE_REQ);
+               /* Wake up the DV kthread */
+               up(&ahd->platform_data->dv_sem);
+@@ -2589,6 +2551,7 @@ ahd_linux_dv_thread(void *data)
+       unlock_kernel();
+       while (1) {
++
+               /*
+                * Use down_interruptible() rather than down() to
+                * avoid inclusion in the load average.
+@@ -2597,7 +2560,7 @@ ahd_linux_dv_thread(void *data)
+               /* Check to see if we've been signaled to exit */
+               ahd_lock(ahd, &s);
+-              if ((ahd->platform_data->flags & AHD_DV_SHUTDOWN) != 0) {
++              if ((ahd->platform_data->flags & AIC_DV_SHUTDOWN) != 0) {
+                       ahd_unlock(ahd, &s);
+                       break;
+               }
+@@ -2614,7 +2577,7 @@ ahd_linux_dv_thread(void *data)
+                */
+               ahd_lock(ahd, &s);
+               while (LIST_FIRST(&ahd->pending_scbs) != NULL) {
+-                      ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_EMPTY;
++                      ahd->platform_data->flags |= AIC_DV_WAIT_SIMQ_EMPTY;
+                       ahd_unlock(ahd, &s);
+                       down_interruptible(&ahd->platform_data->dv_sem);
+                       ahd_lock(ahd, &s);
+@@ -2624,8 +2587,8 @@ ahd_linux_dv_thread(void *data)
+                * Wait for the SIMQ to be released so that DV is the
+                * only reason the queue is frozen.
+                */
+-              while (AHD_DV_SIMQ_FROZEN(ahd) == 0) {
+-                      ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_RELEASE;
++              while (AIC_DV_SIMQ_FROZEN(ahd) == 0) {
++                      ahd->platform_data->flags |= AIC_DV_WAIT_SIMQ_RELEASE;
+                       ahd_unlock(ahd, &s);
+                       down_interruptible(&ahd->platform_data->dv_sem);
+                       ahd_lock(ahd, &s);
+@@ -2636,14 +2599,17 @@ ahd_linux_dv_thread(void *data)
+                       ahd_linux_dv_target(ahd, target);
+               ahd_lock(ahd, &s);
+-              ahd->platform_data->flags &= ~AHD_DV_ACTIVE;
+-              ahd_unlock(ahd, &s);
++              ahd->platform_data->flags &= ~AIC_DV_ACTIVE;
+               /*
+                * Release the SIMQ so that normal commands are
+                * allowed to continue on the bus.
+                */
+-              ahd_release_simq(ahd);
++              aic_release_simq_locked(ahd);
++
++              ahd_unlock(ahd, &s);
++
++              scsi_unblock_requests(ahd->platform_data->host);
+       }
+       up(&ahd->platform_data->eh_sem);
+       return (0);
+@@ -2656,7 +2622,7 @@ ahd_linux_kill_dv_thread(struct ahd_soft
+       ahd_lock(ahd, &s);
+       if (ahd->platform_data->dv_pid != 0) {
+-              ahd->platform_data->flags |= AHD_DV_SHUTDOWN;
++              ahd->platform_data->flags |= AIC_DV_SHUTDOWN;
+               ahd_unlock(ahd, &s);
+               up(&ahd->platform_data->dv_sem);
+@@ -2676,10 +2642,10 @@ ahd_linux_kill_dv_thread(struct ahd_soft
+               /*
+                * Mark the dv thread as already dead.  This
+                * avoids attempting to kill it a second time.
+-               * This is necessary because we must kill the
+-               * DV thread before calling ahd_free() in the
++               * This is necessary because we must kill our
++               * threads before calling ahd_free() in the
+                * module shutdown case to avoid bogus locking
+-               * in the SCSI mid-layer, but we ahd_free() is
++               * in the SCSI mid-layer, but when ahd_free() is
+                * called without killing the DV thread in the
+                * instance detach case, so ahd_platform_free()
+                * calls us again to verify that the DV thread
+@@ -2699,10 +2665,10 @@ ahd_linux_kill_dv_thread(struct ahd_soft
+       ahd_set_dv_state(ahd, targ, newstate, __LINE__)
+ static __inline void
+-ahd_set_dv_state(struct ahd_softc *ahd, struct ahd_linux_target *targ,
+-               ahd_dv_state newstate, u_int line)
++ahd_set_dv_state(struct ahd_softc *ahd, struct aic_linux_target *targ,
++               aic_dv_state newstate, u_int line)
+ {
+-      ahd_dv_state oldstate;
++      aic_dv_state oldstate;
+       oldstate = targ->dv_state;
+ #ifdef AHD_DEBUG
+@@ -2722,7 +2688,7 @@ static void
+ ahd_linux_dv_target(struct ahd_softc *ahd, u_int target_offset)
+ {
+       struct   ahd_devinfo devinfo;
+-      struct   ahd_linux_target *targ;
++      struct   aic_linux_target *targ;
+       struct   scsi_cmnd *cmd;
+       struct   scsi_device *scsi_dev;
+       struct   scsi_sense_data *sense;
+@@ -2736,7 +2702,7 @@ ahd_linux_dv_target(struct ahd_softc *ah
+       echo_size = 0;
+       ahd_lock(ahd, &s);
+       targ = ahd->platform_data->targets[target_offset];
+-      if (targ == NULL || (targ->flags & AHD_DV_REQUIRED) == 0) {
++      if (targ == NULL || (targ->flags & AIC_DV_REQUIRED) == 0) {
+               ahd_unlock(ahd, &s);
+               return;
+       }
+@@ -2759,14 +2725,14 @@ ahd_linux_dv_target(struct ahd_softc *ah
+       scsi_dev->channel = devinfo.channel - 'A';
+       ahd->platform_data->dv_scsi_dev = scsi_dev;
+-      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_SHORT_ASYNC);
++      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_INQ_SHORT_ASYNC);
+-      while (targ->dv_state != AHD_DV_STATE_EXIT) {
++      while (targ->dv_state != AIC_DV_STATE_EXIT) {
+               timeout = AHD_LINUX_DV_TIMEOUT;
+               switch (targ->dv_state) {
+-              case AHD_DV_STATE_INQ_SHORT_ASYNC:
+-              case AHD_DV_STATE_INQ_ASYNC:
+-              case AHD_DV_STATE_INQ_ASYNC_VERIFY:
++              case AIC_DV_STATE_INQ_SHORT_ASYNC:
++              case AIC_DV_STATE_INQ_ASYNC:
++              case AIC_DV_STATE_INQ_ASYNC_VERIFY:
+                       /*
+                        * Set things to async narrow to reduce the
+                        * chance that the INQ will fail.
+@@ -2778,36 +2744,36 @@ ahd_linux_dv_target(struct ahd_softc *ah
+                                     AHD_TRANS_GOAL, /*paused*/FALSE);
+                       ahd_unlock(ahd, &s);
+                       timeout = 10 * HZ;
+-                      targ->flags &= ~AHD_INQ_VALID;
++                      targ->flags &= ~AIC_INQ_VALID;
+                       /* FALLTHROUGH */
+-              case AHD_DV_STATE_INQ_VERIFY:
++              case AIC_DV_STATE_INQ_VERIFY:
+               {
+                       u_int inq_len;
+-                      if (targ->dv_state == AHD_DV_STATE_INQ_SHORT_ASYNC)
++                      if (targ->dv_state == AIC_DV_STATE_INQ_SHORT_ASYNC)
+                               inq_len = AHD_LINUX_DV_INQ_SHORT_LEN;
+                       else
+                               inq_len = targ->inq_data->additional_length + 5;
+                       ahd_linux_dv_inq(ahd, cmd, &devinfo, targ, inq_len);
+                       break;
+               }
+-              case AHD_DV_STATE_TUR:
+-              case AHD_DV_STATE_BUSY:
++              case AIC_DV_STATE_TUR:
++              case AIC_DV_STATE_BUSY:
+                       timeout = 5 * HZ;
+                       ahd_linux_dv_tur(ahd, cmd, &devinfo);
+                       break;
+-              case AHD_DV_STATE_REBD:
++              case AIC_DV_STATE_REBD:
+                       ahd_linux_dv_rebd(ahd, cmd, &devinfo, targ);
+                       break;
+-              case AHD_DV_STATE_WEB:
++              case AIC_DV_STATE_WEB:
+                       ahd_linux_dv_web(ahd, cmd, &devinfo, targ);
+                       break;
+-              case AHD_DV_STATE_REB:
++              case AIC_DV_STATE_REB:
+                       ahd_linux_dv_reb(ahd, cmd, &devinfo, targ);
+                       break;
+-              case AHD_DV_STATE_SU:
++              case AIC_DV_STATE_SU:
+                       ahd_linux_dv_su(ahd, cmd, &devinfo, targ);
+                       timeout = 50 * HZ;
+                       break;
+@@ -2819,8 +2785,6 @@ ahd_linux_dv_target(struct ahd_softc *ah
+               }
+               /* Queue the command and wait for it to complete */
+-              /* Abuse eh_timeout in the scsi_cmnd struct for our purposes */
+-              init_timer(&cmd->eh_timeout);
+ #ifdef AHD_DEBUG
+               if ((ahd_debug & AHD_SHOW_MESSAGES) != 0)
+                       /*
+@@ -2830,7 +2794,9 @@ ahd_linux_dv_target(struct ahd_softc *ah
+                        */
+                       timeout += HZ;
+ #endif
+-              scsi_add_timer(cmd, timeout, ahd_linux_dv_timeout);
++              init_timer(&cmd->eh_timeout);
++              cmd->timeout_per_command = timeout;
++
+               /*
+                * In 2.5.X, it is assumed that all calls from the
+                * "midlayer" (which we are emulating) will have the
+@@ -2849,13 +2815,14 @@ ahd_linux_dv_target(struct ahd_softc *ah
+               spin_unlock_irqrestore(&io_request_lock, s);
+ #endif
+               down_interruptible(&ahd->platform_data->dv_cmd_sem);
++
+               /*
+                * Wait for the SIMQ to be released so that DV is the
+                * only reason the queue is frozen.
+                */
+               ahd_lock(ahd, &s);
+-              while (AHD_DV_SIMQ_FROZEN(ahd) == 0) {
+-                      ahd->platform_data->flags |= AHD_DV_WAIT_SIMQ_RELEASE;
++              while (AIC_DV_SIMQ_FROZEN(ahd) == 0) {
++                      ahd->platform_data->flags |= AIC_DV_WAIT_SIMQ_RELEASE;
+                       ahd_unlock(ahd, &s);
+                       down_interruptible(&ahd->platform_data->dv_sem);
+                       ahd_lock(ahd, &s);
+@@ -2866,7 +2833,7 @@ ahd_linux_dv_target(struct ahd_softc *ah
+       }
+ out:
+-      if ((targ->flags & AHD_INQ_VALID) != 0
++      if ((targ->flags & AIC_INQ_VALID) != 0
+        && ahd_linux_get_device(ahd, devinfo.channel - 'A',
+                                devinfo.target, devinfo.lun,
+                                /*alloc*/FALSE) == NULL) {
+@@ -2877,7 +2844,7 @@ out:
+                * parameters found in the inquiry string.
+                */
+               ahd_linux_filter_inquiry(ahd, &devinfo);
+-              if ((targ->flags & (AHD_BASIC_DV|AHD_ENHANCED_DV)) != 0) {
++              if ((targ->flags & (AIC_BASIC_DV|AIC_ENHANCED_DV)) != 0) {
+                       ahd_print_devinfo(ahd, &devinfo);
+                       printf("DV failed to configure device.  "
+                              "Please file a bug report against "
+@@ -2902,7 +2869,7 @@ out:
+               free(targ->dv_buffer1, M_DEVBUF);
+               targ->dv_buffer1 = NULL;
+       }
+-      targ->flags &= ~AHD_DV_REQUIRED;
++      targ->flags &= ~AIC_DV_REQUIRED;
+       if (targ->refcount == 0)
+               ahd_linux_free_target(ahd, targ);
+       ahd_unlock(ahd, &s);
+@@ -2911,13 +2878,13 @@ out:
+ static void
+ ahd_linux_dv_transition(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
+                       struct ahd_devinfo *devinfo,
+-                      struct ahd_linux_target *targ)
++                      struct aic_linux_target *targ)
+ {
+       u_int32_t status;
+       status = aic_error_action(cmd, targ->inq_data,
+-                                ahd_cmd_get_transaction_status(cmd),
+-                                ahd_cmd_get_scsi_status(cmd));
++                                aic_cmd_get_transaction_status(cmd),
++                                aic_cmd_get_scsi_status(cmd));
+       
+ #ifdef AHD_DEBUG
+@@ -2930,8 +2897,8 @@ ahd_linux_dv_transition(struct ahd_softc
+ #endif
+       switch (targ->dv_state) {
+-      case AHD_DV_STATE_INQ_SHORT_ASYNC:
+-      case AHD_DV_STATE_INQ_ASYNC:
++      case AIC_DV_STATE_INQ_SHORT_ASYNC:
++      case AIC_DV_STATE_INQ_ASYNC:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               {
+@@ -2940,21 +2907,21 @@ ahd_linux_dv_transition(struct ahd_softc
+               }
+               case SS_INQ_REFRESH:
+                       AHD_SET_DV_STATE(ahd, targ,
+-                                       AHD_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_TUR:
+               case SS_RETRY:
+                       AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
+-                      if (ahd_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ)
+                               targ->dv_state_retry--;
+                       if ((status & SS_ERRMASK) == EBUSY)
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY);
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_BUSY);
+                       if (targ->dv_state_retry < 10)
+                               break;
+                       /* FALLTHROUGH */
+               default:
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+ #ifdef AHD_DEBUG
+                       if (ahd_debug & AHD_SHOW_DV) {
+                               ahd_print_devinfo(ahd, devinfo);
+@@ -2964,7 +2931,7 @@ ahd_linux_dv_transition(struct ahd_softc
+                       break;
+               }
+               break;
+-      case AHD_DV_STATE_INQ_ASYNC_VERIFY:
++      case AIC_DV_STATE_INQ_ASYNC_VERIFY:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               {
+@@ -2978,12 +2945,12 @@ ahd_linux_dv_transition(struct ahd_softc
+                                * Try from the top again.
+                                */
+                               AHD_SET_DV_STATE(ahd, targ,
+-                                               AHD_DV_STATE_INQ_SHORT_ASYNC);
++                                               AIC_DV_STATE_INQ_SHORT_ASYNC);
+                               break;
+                       }
+                       AHD_SET_DV_STATE(ahd, targ, targ->dv_state+1);
+-                      targ->flags |= AHD_INQ_VALID;
++                      targ->flags |= AIC_INQ_VALID;
+                       if (ahd_linux_user_dv_setting(ahd) == 0)
+                               break;
+@@ -2996,33 +2963,33 @@ ahd_linux_dv_transition(struct ahd_softc
+                       default:
+                       case SID_SPI_CLOCK_ST:
+                               /* Assume only basic DV is supported. */
+-                              targ->flags |= AHD_BASIC_DV;
++                              targ->flags |= AIC_BASIC_DV;
+                               break;
+                       case SID_SPI_CLOCK_DT:
+                       case SID_SPI_CLOCK_DT_ST:
+-                              targ->flags |= AHD_ENHANCED_DV;
++                              targ->flags |= AIC_ENHANCED_DV;
+                               break;
+                       }
+                       break;
+               }
+               case SS_INQ_REFRESH:
+                       AHD_SET_DV_STATE(ahd, targ,
+-                                       AHD_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_TUR:
+               case SS_RETRY:
+                       AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
+-                      if (ahd_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ)
+                               targ->dv_state_retry--;
+                       if ((status & SS_ERRMASK) == EBUSY)
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY);
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_BUSY);
+                       if (targ->dv_state_retry < 10)
+                               break;
+                       /* FALLTHROUGH */
+               default:
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+ #ifdef AHD_DEBUG
+                       if (ahd_debug & AHD_SHOW_DV) {
+                               ahd_print_devinfo(ahd, devinfo);
+@@ -3032,14 +2999,14 @@ ahd_linux_dv_transition(struct ahd_softc
+                       break;
+               }
+               break;
+-      case AHD_DV_STATE_INQ_VERIFY:
++      case AIC_DV_STATE_INQ_VERIFY:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               {
+                       if (memcmp(targ->inq_data, targ->dv_buffer,
+                                  AHD_LINUX_DV_INQ_LEN) == 0) {
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+                               break;
+                       }
+@@ -3061,7 +3028,7 @@ ahd_linux_dv_transition(struct ahd_softc
+ #endif
+                       if (ahd_linux_dv_fallback(ahd, devinfo) != 0) {
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+                               break;
+                       }
+                       /*
+@@ -3074,18 +3041,18 @@ ahd_linux_dv_transition(struct ahd_softc
+               }
+               case SS_INQ_REFRESH:
+                       AHD_SET_DV_STATE(ahd, targ,
+-                                       AHD_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_TUR:
+               case SS_RETRY:
+                       AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
+-                      if (ahd_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ) {
+                               targ->dv_state_retry--;
+                       } else if ((status & SSQ_FALLBACK) != 0) {
+                               if (ahd_linux_dv_fallback(ahd, devinfo) != 0) {
+                                       AHD_SET_DV_STATE(ahd, targ,
+-                                                       AHD_DV_STATE_EXIT);
++                                                       AIC_DV_STATE_EXIT);
+                                       break;
+                               }
+                               /*
+@@ -3094,12 +3061,12 @@ ahd_linux_dv_transition(struct ahd_softc
+                                */
+                               targ->dv_state_retry = 0;
+                       } else if ((status & SS_ERRMASK) == EBUSY)
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY);
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_BUSY);
+                       if (targ->dv_state_retry < 10)
+                               break;
+                       /* FALLTHROUGH */
+               default:
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+ #ifdef AHD_DEBUG
+                       if (ahd_debug & AHD_SHOW_DV) {
+                               ahd_print_devinfo(ahd, devinfo);
+@@ -3110,33 +3077,33 @@ ahd_linux_dv_transition(struct ahd_softc
+               }
+               break;
+-      case AHD_DV_STATE_TUR:
++      case AIC_DV_STATE_TUR:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+-                      if ((targ->flags & AHD_BASIC_DV) != 0) {
++                      if ((targ->flags & AIC_BASIC_DV) != 0) {
+                               ahd_linux_filter_inquiry(ahd, devinfo);
+                               AHD_SET_DV_STATE(ahd, targ,
+-                                               AHD_DV_STATE_INQ_VERIFY);
+-                      } else if ((targ->flags & AHD_ENHANCED_DV) != 0) {
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_REBD);
++                                               AIC_DV_STATE_INQ_VERIFY);
++                      } else if ((targ->flags & AIC_ENHANCED_DV) != 0) {
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_REBD);
+                       } else {
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+                       }
+                       break;
+               case SS_RETRY:
+               case SS_TUR:
+                       if ((status & SS_ERRMASK) == EBUSY) {
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_BUSY);
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_BUSY);
+                               break;
+                       }
+                       AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
+-                      if (ahd_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ) {
+                               targ->dv_state_retry--;
+                       } else if ((status & SSQ_FALLBACK) != 0) {
+                               if (ahd_linux_dv_fallback(ahd, devinfo) != 0) {
+                                       AHD_SET_DV_STATE(ahd, targ,
+-                                                       AHD_DV_STATE_EXIT);
++                                                       AIC_DV_STATE_EXIT);
+                                       break;
+                               }
+                               /*
+@@ -3152,7 +3119,7 @@ ahd_linux_dv_transition(struct ahd_softc
+                                       printf("DV TUR reties exhausted\n");
+                               }
+ #endif
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+                               break;
+                       }
+                       if (status & SSQ_DELAY)
+@@ -3160,25 +3127,25 @@ ahd_linux_dv_transition(struct ahd_softc
+                       break;
+               case SS_START:
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_SU);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_SU);
+                       break;
+               case SS_INQ_REFRESH:
+                       AHD_SET_DV_STATE(ahd, targ,
+-                                       AHD_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               default:
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+                       break;
+               }
+               break;
+-      case AHD_DV_STATE_REBD:
++      case AIC_DV_STATE_REBD:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               {
+                       uint32_t echo_size;
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_WEB);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_WEB);
+                       echo_size = scsi_3btoul(&targ->dv_buffer[1]);
+                       echo_size &= 0x1FFF;
+ #ifdef AHD_DEBUG
+@@ -3188,7 +3155,17 @@ ahd_linux_dv_transition(struct ahd_softc
+                       }
+ #endif
+                       if (echo_size == 0) {
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                              /*
++                               * Fall back to basic DV.
++                               */
++                              if (bootverbose) {
++                                      ahd_print_devinfo(ahd, devinfo);
++                                      printf("Echo Buffer unavailable.  "
++                                             "Performing basic DV.\n");
++                              }
++                              targ->flags &= ~AIC_ENHANCED_DV;
++                              targ->flags |= AIC_BASIC_DV;
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_TUR);
+                               break;
+                       }
+@@ -3203,11 +3180,11 @@ ahd_linux_dv_transition(struct ahd_softc
+               }
+               case SS_INQ_REFRESH:
+                       AHD_SET_DV_STATE(ahd, targ,
+-                                       AHD_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_RETRY:
+                       AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
+-                      if (ahd_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ)
+                               targ->dv_state_retry--;
+                       if (targ->dv_state_retry <= 10)
+@@ -3226,30 +3203,30 @@ ahd_linux_dv_transition(struct ahd_softc
+                        * and try level 1 DV.
+                        */
+                       ahd_linux_filter_inquiry(ahd, devinfo);
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_VERIFY);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_INQ_VERIFY);
+                       targ->dv_echo_size = 0;
+                       break;
+               }
+               break;
+-      case AHD_DV_STATE_WEB:
++      case AIC_DV_STATE_WEB:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_REB);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_REB);
+                       break;
+               case SS_INQ_REFRESH:
+                       AHD_SET_DV_STATE(ahd, targ,
+-                                       AHD_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_RETRY:
+                       AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
+-                      if (ahd_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ) {
+                               targ->dv_state_retry--;
+                       } else if ((status & SSQ_FALLBACK) != 0) {
+                               if (ahd_linux_dv_fallback(ahd, devinfo) != 0) {
+                                       AHD_SET_DV_STATE(ahd, targ,
+-                                                       AHD_DV_STATE_EXIT);
++                                                       AIC_DV_STATE_EXIT);
+                                       break;
+                               }
+                               /*
+@@ -3268,22 +3245,22 @@ ahd_linux_dv_transition(struct ahd_softc
+                       }
+ #endif
+               default:
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+                       break;
+               }
+               break;
+-      case AHD_DV_STATE_REB:
++      case AIC_DV_STATE_REB:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+                       if (memcmp(targ->dv_buffer, targ->dv_buffer1,
+                                  targ->dv_echo_size) != 0) {
+                               if (ahd_linux_dv_fallback(ahd, devinfo) != 0)
+                                       AHD_SET_DV_STATE(ahd, targ,
+-                                                       AHD_DV_STATE_EXIT);
++                                                       AIC_DV_STATE_EXIT);
+                               else
+                                       AHD_SET_DV_STATE(ahd, targ,
+-                                                       AHD_DV_STATE_WEB);
++                                                       AIC_DV_STATE_WEB);
+                               break;
+                       }
+                       
+@@ -3295,24 +3272,24 @@ ahd_linux_dv_transition(struct ahd_softc
+                               free(targ->dv_buffer1, M_DEVBUF);
+                               targ->dv_buffer1 = NULL;
+                       }
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+                       break;
+               case SS_INQ_REFRESH:
+                       AHD_SET_DV_STATE(ahd, targ,
+-                                       AHD_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_RETRY:
+                       AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
+-                      if (ahd_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ) {
+                               targ->dv_state_retry--;
+                       } else if ((status & SSQ_FALLBACK) != 0) {
+                               if (ahd_linux_dv_fallback(ahd, devinfo) != 0) {
+                                       AHD_SET_DV_STATE(ahd, targ,
+-                                                       AHD_DV_STATE_EXIT);
++                                                       AIC_DV_STATE_EXIT);
+                                       break;
+                               }
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_WEB);
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_WEB);
+                       }
+                       if (targ->dv_state_retry <= 10) {
+                               if ((status & (SSQ_DELAY_RANDOM|SSQ_DELAY))!= 0)
+@@ -3327,35 +3304,35 @@ ahd_linux_dv_transition(struct ahd_softc
+ #endif
+                       /* FALLTHROUGH */
+               default:
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+                       break;
+               }
+               break;
+-      case AHD_DV_STATE_SU:
++      case AIC_DV_STATE_SU:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               case SS_INQ_REFRESH:
+                       AHD_SET_DV_STATE(ahd, targ,
+-                                       AHD_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               default:
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+                       break;
+               }
+               break;
+-      case AHD_DV_STATE_BUSY:
++      case AIC_DV_STATE_BUSY:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               case SS_INQ_REFRESH:
+                       AHD_SET_DV_STATE(ahd, targ,
+-                                       AHD_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_TUR:
+               case SS_RETRY:
+                       AHD_SET_DV_STATE(ahd, targ, targ->dv_state);
+-                      if (ahd_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ) {
+                               targ->dv_state_retry--;
+                       } else if (targ->dv_state_retry < 60) {
+@@ -3368,11 +3345,11 @@ ahd_linux_dv_transition(struct ahd_softc
+                                       printf("DV BUSY reties exhausted\n");
+                               }
+ #endif
+-                              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+                       }
+                       break;
+               default:
+-                      AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++                      AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+                       break;
+               }
+               break;
+@@ -3380,7 +3357,7 @@ ahd_linux_dv_transition(struct ahd_softc
+       default:
+               printf("%s: Invalid DV completion state %d\n", ahd_name(ahd),
+                      targ->dv_state);
+-              AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_EXIT);
++              AHD_SET_DV_STATE(ahd, targ, AIC_DV_STATE_EXIT);
+               break;
+       }
+ }
+@@ -3400,7 +3377,7 @@ ahd_linux_dv_fill_cmd(struct ahd_softc *
+  */
+ static void
+ ahd_linux_dv_inq(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
+-               struct ahd_devinfo *devinfo, struct ahd_linux_target *targ,
++               struct ahd_devinfo *devinfo, struct aic_linux_target *targ,
+                u_int request_length)
+ {
+@@ -3413,7 +3390,7 @@ ahd_linux_dv_inq(struct ahd_softc *ahd, 
+       if (targ->inq_data == NULL)
+               targ->inq_data = malloc(AHD_LINUX_DV_INQ_LEN,
+                                       M_DEVBUF, M_WAITOK);
+-      if (targ->dv_state > AHD_DV_STATE_INQ_ASYNC) {
++      if (targ->dv_state > AIC_DV_STATE_INQ_ASYNC) {
+               if (targ->dv_buffer != NULL)
+                       free(targ->dv_buffer, M_DEVBUF);
+               targ->dv_buffer = malloc(AHD_LINUX_DV_INQ_LEN,
+@@ -3426,7 +3403,7 @@ ahd_linux_dv_inq(struct ahd_softc *ahd, 
+       cmd->cmnd[0] = INQUIRY;
+       cmd->cmnd[4] = request_length;
+       cmd->request_bufflen = request_length;
+-      if (targ->dv_state > AHD_DV_STATE_INQ_ASYNC)
++      if (targ->dv_state > AIC_DV_STATE_INQ_ASYNC)
+               cmd->request_buffer = targ->dv_buffer;
+       else
+               cmd->request_buffer = targ->inq_data;
+@@ -3455,7 +3432,7 @@ ahd_linux_dv_tur(struct ahd_softc *ahd, 
+ static void
+ ahd_linux_dv_rebd(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
+-               struct ahd_devinfo *devinfo, struct ahd_linux_target *targ)
++               struct ahd_devinfo *devinfo, struct aic_linux_target *targ)
+ {
+ #ifdef AHD_DEBUG
+@@ -3480,7 +3457,7 @@ ahd_linux_dv_rebd(struct ahd_softc *ahd,
+ static void
+ ahd_linux_dv_web(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
+-               struct ahd_devinfo *devinfo, struct ahd_linux_target *targ)
++               struct ahd_devinfo *devinfo, struct aic_linux_target *targ)
+ {
+ #ifdef AHD_DEBUG
+@@ -3502,7 +3479,7 @@ ahd_linux_dv_web(struct ahd_softc *ahd, 
+ static void
+ ahd_linux_dv_reb(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
+-               struct ahd_devinfo *devinfo, struct ahd_linux_target *targ)
++               struct ahd_devinfo *devinfo, struct aic_linux_target *targ)
+ {
+ #ifdef AHD_DEBUG
+@@ -3525,7 +3502,7 @@ ahd_linux_dv_reb(struct ahd_softc *ahd, 
+ static void
+ ahd_linux_dv_su(struct ahd_softc *ahd, struct scsi_cmnd *cmd,
+               struct ahd_devinfo *devinfo,
+-              struct ahd_linux_target *targ)
++              struct aic_linux_target *targ)
+ {
+       u_int le;
+@@ -3560,7 +3537,7 @@ ahd_linux_dv_fallback(struct ahd_softc *
+ static int
+ ahd_linux_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
+ {
+-      struct  ahd_linux_target *targ;
++      struct  aic_linux_target *targ;
+       struct  ahd_initiator_tinfo *tinfo;
+       struct  ahd_transinfo *goal;
+       struct  ahd_tmode_tstate *tstate;
+@@ -3731,7 +3708,7 @@ ahd_linux_fallback(struct ahd_softc *ahd
+       return (0);
+ }
+-static void
++void
+ ahd_linux_dv_timeout(struct scsi_cmnd *cmd)
+ {
+       struct  ahd_softc *ahd;
+@@ -3765,29 +3742,18 @@ ahd_linux_dv_timeout(struct scsi_cmnd *c
+        * error code.
+        */
+       if ((scb->flags & SCB_SENSE) != 0)
+-              ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
++              aic_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
+       else
+-              ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
++              aic_set_transaction_status(scb, CAM_CMD_TIMEOUT);
+       ahd_reset_channel(ahd, cmd->device->channel + 'A', /*initiate*/TRUE);
+-      /*
+-       * Add a minimal bus settle delay for devices that are slow to
+-       * respond after bus resets.
+-       */
+-      ahd_freeze_simq(ahd);
+-      init_timer(&ahd->platform_data->reset_timer);
+-      ahd->platform_data->reset_timer.data = (u_long)ahd;
+-      ahd->platform_data->reset_timer.expires = jiffies + HZ / 2;
+-      ahd->platform_data->reset_timer.function =
+-          (ahd_linux_callback_t *)ahd_release_simq;
+-      add_timer(&ahd->platform_data->reset_timer);
+-      if (ahd_linux_next_device_to_run(ahd) != NULL)
+-              ahd_schedule_runq(ahd);
++      if (aic_linux_next_device_to_run(ahd) != NULL)
++              aic_schedule_runq(ahd);
+       ahd_linux_run_complete_queue(ahd);
+       ahd_unlock(ahd, &flags);
+ }
+-static void
++void
+ ahd_linux_dv_complete(struct scsi_cmnd *cmd)
+ {
+       struct ahd_softc *ahd;
+@@ -3809,7 +3775,7 @@ ahd_linux_dv_complete(struct scsi_cmnd *
+ }
+ static void
+-ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ)
++ahd_linux_generate_dv_pattern(struct aic_linux_target *targ)
+ {
+       uint16_t b;
+       u_int    i;
+@@ -3975,8 +3941,8 @@ ahd_linux_setup_user_rd_strm_settings(st
+  * Determines the queue depth for a given device.
+  */
+ static void
+-ahd_linux_device_queue_depth(struct ahd_softc *ahd,
+-                           struct ahd_linux_device *dev)
++aic_linux_device_queue_depth(struct ahd_softc *ahd,
++                           struct aic_linux_device *dev)
+ {
+       struct  ahd_devinfo devinfo;
+       u_int   tags;
+@@ -3999,10 +3965,10 @@ ahd_linux_device_queue_depth(struct ahd_
+       }
+ }
+-static void
+-ahd_linux_run_device_queue(struct ahd_softc *ahd, struct ahd_linux_device *dev)
++void
++ahd_linux_run_device_queue(struct ahd_softc *ahd, struct aic_linux_device *dev)
+ {
+-      struct   ahd_cmd *acmd;
++      struct   aic_cmd *acmd;
+       struct   scsi_cmnd *cmd;
+       struct   scb *scb;
+       struct   hardware_scb *hscb;
+@@ -4011,7 +3977,7 @@ ahd_linux_run_device_queue(struct ahd_so
+       u_int    col_idx;
+       uint16_t mask;
+-      if ((dev->flags & AHD_DEV_ON_RUN_LIST) != 0)
++      if ((dev->flags & AIC_DEV_ON_RUN_LIST) != 0)
+               panic("running device on run list");
+       while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL
+@@ -4022,11 +3988,11 @@ ahd_linux_run_device_queue(struct ahd_so
+                * running is because the whole controller Q is frozen.
+                */
+               if (ahd->platform_data->qfrozen != 0
+-               && AHD_DV_SIMQ_FROZEN(ahd) == 0) {
++               && AIC_DV_SIMQ_FROZEN(ahd) == 0) {
+                       TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq,
+                                         dev, links);
+-                      dev->flags |= AHD_DEV_ON_RUN_LIST;
++                      dev->flags |= AIC_DEV_ON_RUN_LIST;
+                       return;
+               }
+@@ -4037,7 +4003,7 @@ ahd_linux_run_device_queue(struct ahd_so
+                */
+               tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
+                                           cmd->device->id, &tstate);
+-              if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0
++              if ((dev->flags & (AIC_DEV_Q_TAGGED|AIC_DEV_Q_BASIC)) == 0
+                || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
+                       col_idx = AHD_NEVER_COL_IDX;
+               } else {
+@@ -4047,13 +4013,14 @@ ahd_linux_run_device_queue(struct ahd_so
+               if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
+                       TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq,
+                                        dev, links);
+-                      dev->flags |= AHD_DEV_ON_RUN_LIST;
++                      dev->flags |= AIC_DEV_ON_RUN_LIST;
+                       ahd->flags |= AHD_RESOURCE_SHORTAGE;
+                       return;
+               }
+               TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe);
+               scb->io_ctx = cmd;
+               scb->platform_data->dev = dev;
++              scb->platform_data->flags = 0;
+               hscb = scb->hscb;
+               cmd->host_scribble = (char *)scb;
+@@ -4069,7 +4036,7 @@ ahd_linux_run_device_queue(struct ahd_so
+               if ((ahd->user_discenable & mask) != 0)
+                       hscb->control |= DISCENB;
+-              if (AHD_DV_CMD(cmd) != 0)
++              if (AIC_DV_CMD(cmd) != 0)
+                       scb->flags |= SCB_SILENT;
+               if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0)
+@@ -4080,7 +4047,7 @@ ahd_linux_run_device_queue(struct ahd_so
+                       scb->hscb->control |= MK_MESSAGE;
+               }
+-              if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
++              if ((dev->flags & (AIC_DEV_Q_TAGGED|AIC_DEV_Q_BASIC)) != 0) {
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+                       int     msg_bytes;
+                       uint8_t tag_msgs[2];
+@@ -4092,8 +4059,8 @@ ahd_linux_run_device_queue(struct ahd_so
+                                       dev->commands_since_idle_or_otag = 0;
+                       } else
+ #endif
+-                      if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH
+-                       && (dev->flags & AHD_DEV_Q_TAGGED) != 0) {
++                      if (dev->commands_since_idle_or_otag == AIC_OTAG_THRESH
++                       && (dev->flags & AIC_DEV_Q_TAGGED) != 0) {
+                               hscb->control |= MSG_ORDERED_TASK;
+                               dev->commands_since_idle_or_otag = 0;
+                       } else {
+@@ -4105,8 +4072,9 @@ ahd_linux_run_device_queue(struct ahd_so
+               memcpy(hscb->shared_data.idata.cdb, cmd->cmnd, hscb->cdb_len);
+               scb->sg_count = 0;
+-              ahd_set_residual(scb, 0);
+-              ahd_set_sense_residual(scb, 0);
++              aic_set_residual(scb, 0);
++              aic_set_sense_residual(scb, 0);
++              scb->platform_data->xfer_len = 0;
+               if (cmd->use_sg != 0) {
+                       void    *sg;
+                       struct   scatterlist *cur_seg;
+@@ -4115,18 +4083,15 @@ ahd_linux_run_device_queue(struct ahd_so
+                       cur_seg = (struct scatterlist *)cmd->request_buffer;
+                       dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+-                      nseg = pci_map_sg(ahd->dev_softc, cur_seg,
+-                                        cmd->use_sg, dir);
+-                      scb->platform_data->xfer_len = 0;
++                      nseg = aic_map_sg(ahd, cur_seg, cmd->use_sg, dir);
+                       for (sg = scb->sg_list; nseg > 0; nseg--, cur_seg++) {
+                               bus_addr_t addr;
+                               bus_size_t len;
+                               addr = sg_dma_address(cur_seg);
+                               len = sg_dma_len(cur_seg);
+-                              scb->platform_data->xfer_len += len;
+-                              sg = ahd_sg_setup(ahd, scb, sg, addr, len,
+-                                                /*last*/nseg == 1);
++                              sg = ahd_linux_sg_setup(ahd, scb, sg, addr, len,
++                                                      /*last*/nseg == 1);
+                       }
+               } else if (cmd->request_bufflen != 0) {
+                       void *sg;
+@@ -4135,13 +4100,13 @@ ahd_linux_run_device_queue(struct ahd_so
+                       sg = scb->sg_list;
+                       dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+-                      addr = pci_map_single(ahd->dev_softc,
++                      addr = aic_map_single(ahd,
+                                             cmd->request_buffer,
+                                             cmd->request_bufflen, dir);
+-                      scb->platform_data->xfer_len = cmd->request_bufflen;
+                       scb->platform_data->buf_busaddr = addr;
+-                      sg = ahd_sg_setup(ahd, scb, sg, addr,
+-                                        cmd->request_bufflen, /*last*/TRUE);
++                      sg = ahd_linux_sg_setup(ahd, scb, sg, addr,
++                                              cmd->request_bufflen,
++                                              /*last*/TRUE);
+               }
+               LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
+@@ -4157,9 +4122,10 @@ ahd_linux_run_device_queue(struct ahd_so
+                               dev->target->cmds_since_error = 0;
+               }
+-              if ((dev->flags & AHD_DEV_PERIODIC_OTAG) != 0)
++              if ((dev->flags & AIC_DEV_PERIODIC_OTAG) != 0)
+                       dev->commands_since_idle_or_otag++;
+               scb->flags |= SCB_ACTIVE;
++              aic_scb_timer_start(scb);
+               ahd_queue_scb(ahd, scb);
+       }
+ }
+@@ -4177,8 +4143,8 @@ ahd_linux_isr(int irq, void *dev_id, str
+       ahd = (struct ahd_softc *) dev_id;
+       ahd_lock(ahd, &flags); 
+       ours = ahd_intr(ahd);
+-      if (ahd_linux_next_device_to_run(ahd) != NULL)
+-              ahd_schedule_runq(ahd);
++      if (aic_linux_next_device_to_run(ahd) != NULL)
++              aic_schedule_runq(ahd);
+       ahd_linux_run_complete_queue(ahd);
+       ahd_unlock(ahd, &flags);
+       return IRQ_RETVAL(ours);
+@@ -4192,10 +4158,10 @@ ahd_platform_flushwork(struct ahd_softc 
+               ;
+ }
+-static struct ahd_linux_target*
++static struct aic_linux_target*
+ ahd_linux_alloc_target(struct ahd_softc *ahd, u_int channel, u_int target)
+ {
+-      struct ahd_linux_target *targ;
++      struct aic_linux_target *targ;
+       targ = malloc(sizeof(*targ), M_DEVBUF, M_NOWAIT);
+       if (targ == NULL)
+@@ -4203,14 +4169,14 @@ ahd_linux_alloc_target(struct ahd_softc 
+       memset(targ, 0, sizeof(*targ));
+       targ->channel = channel;
+       targ->target = target;
+-      targ->ahd = ahd;
+-      targ->flags = AHD_DV_REQUIRED;
++      targ->softc = ahd;
++      targ->flags = AIC_DV_REQUIRED;
+       ahd->platform_data->targets[target] = targ;
+       return (targ);
+ }
+ static void
+-ahd_linux_free_target(struct ahd_softc *ahd, struct ahd_linux_target *targ)
++ahd_linux_free_target(struct ahd_softc *ahd, struct aic_linux_target *targ)
+ {
+       struct ahd_devinfo devinfo;
+       struct ahd_initiator_tinfo *tinfo;
+@@ -4246,11 +4212,11 @@ ahd_linux_free_target(struct ahd_softc *
+       free(targ, M_DEVBUF);
+ }
+-static struct ahd_linux_device*
++static struct aic_linux_device*
+ ahd_linux_alloc_device(struct ahd_softc *ahd,
+-               struct ahd_linux_target *targ, u_int lun)
++               struct aic_linux_target *targ, u_int lun)
+ {
+-      struct ahd_linux_device *dev;
++      struct aic_linux_device *dev;
+       dev = malloc(sizeof(*dev), M_DEVBUG, M_NOWAIT);
+       if (dev == NULL)
+@@ -4258,7 +4224,7 @@ ahd_linux_alloc_device(struct ahd_softc 
+       memset(dev, 0, sizeof(*dev));
+       init_timer(&dev->timer);
+       TAILQ_INIT(&dev->busyq);
+-      dev->flags = AHD_DEV_UNCONFIGURED;
++      dev->flags = AIC_DEV_UNCONFIGURED;
+       dev->lun = lun;
+       dev->target = targ;
+@@ -4281,9 +4247,9 @@ ahd_linux_alloc_device(struct ahd_softc 
+ }
+ static void
+-ahd_linux_free_device(struct ahd_softc *ahd, struct ahd_linux_device *dev)
++ahd_linux_free_device(struct ahd_softc *ahd, struct aic_linux_device *dev)
+ {
+-      struct ahd_linux_target *targ;
++      struct aic_linux_target *targ;
+       del_timer(&dev->timer);
+       targ = dev->target;
+@@ -4291,7 +4257,7 @@ ahd_linux_free_device(struct ahd_softc *
+       free(dev, M_DEVBUF);
+       targ->refcount--;
+       if (targ->refcount == 0
+-       && (targ->flags & AHD_DV_REQUIRED) == 0)
++       && (targ->flags & AIC_DV_REQUIRED) == 0)
+               ahd_linux_free_target(ahd, targ);
+ }
+@@ -4303,7 +4269,7 @@ ahd_send_async(struct ahd_softc *ahd, ch
+       case AC_TRANSFER_NEG:
+       {
+               char    buf[80];
+-              struct  ahd_linux_target *targ;
++              struct  aic_linux_target *targ;
+               struct  info_str info;
+               struct  ahd_initiator_tinfo *tinfo;
+               struct  ahd_tmode_tstate *tstate;
+@@ -4391,6 +4357,20 @@ ahd_send_async(struct ahd_softc *ahd, ch
+                                             channel - 'A');
+               }
+ #endif
++              /*
++               * Add a minimal bus settle delay for devices that are slow to
++               * respond after bus resets.
++               */
++              if ((ahd->platform_data->flags & AIC_BUS_SETTLE_TIMER) == 0) {
++                      aic_freeze_simq(ahd);
++                      ahd->platform_data->flags |= AIC_BUS_SETTLE_TIMER;
++                      ahd->platform_data->bus_settle_timer.expires =
++                          jiffies + (AIC79XX_RESET_DELAY * HZ)/1000;
++                      add_timer(&ahd->platform_data->bus_settle_timer);
++              } else {
++                      mod_timer(&ahd->platform_data->bus_settle_timer,
++                                jiffies + (AIC79XX_RESET_DELAY * HZ)/1000);
++              }
+                 break;
+         default:
+                 panic("ahd_send_async: Unexpected async event");
+@@ -4404,14 +4384,18 @@ void
+ ahd_done(struct ahd_softc *ahd, struct scb *scb)
+ {
+       Scsi_Cmnd *cmd;
+-      struct    ahd_linux_device *dev;
++      struct    aic_linux_device *dev;
+       if ((scb->flags & SCB_ACTIVE) == 0) {
+               printf("SCB %d done'd twice\n", SCB_GET_TAG(scb));
+               ahd_dump_card_state(ahd);
+               panic("Stopping for safety");
+       }
++
+       LIST_REMOVE(scb, pending_links);
++      if ((scb->flags & SCB_TIMEDOUT) != 0)
++              LIST_REMOVE(scb, timedout_links);
++
+       cmd = scb->io_ctx;
+       dev = scb->platform_data->dev;
+       dev->active--;
+@@ -4429,11 +4413,11 @@ ahd_done(struct ahd_softc *ahd, struct s
+        * the sense buffer looks "sane".
+        */
+       cmd->sense_buffer[0] = 0;
+-      if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) {
++      if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) {
+               uint32_t amount_xferred;
+               amount_xferred =
+-                  ahd_get_transfer_length(scb) - ahd_get_residual(scb);
++                  aic_get_transfer_length(scb) - aic_get_residual(scb);
+               if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) {
+ #ifdef AHD_DEBUG
+                       if ((ahd_debug & AHD_SHOW_MISC) != 0) {
+@@ -4441,7 +4425,17 @@ ahd_done(struct ahd_softc *ahd, struct s
+                               printf("Set CAM_UNCOR_PARITY\n");
+                       }
+ #endif
+-                      ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
++                      aic_set_transaction_status(scb, CAM_UNCOR_PARITY);
++#ifdef AHD_REPORT_UNDERFLOWS
++              /*
++               * This code is disabled by default as some
++               * clients of the SCSI system do not properly
++               * initialize the underflow parameter.  This
++               * results in spurious termination of commands
++               * that complete as expected (e.g. underflow is
++               * allowed as command can return variable amounts
++               * of data.
++               */
+               } else if (amount_xferred < scb->io_ctx->underflow) {
+                       u_int i;
+@@ -4453,30 +4447,31 @@ ahd_done(struct ahd_softc *ahd, struct s
+                       ahd_print_path(ahd, scb);
+                       printf("Saw underflow (%ld of %ld bytes). "
+                              "Treated as error\n",
+-                              ahd_get_residual(scb),
+-                              ahd_get_transfer_length(scb));
+-                      ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
++                              aic_get_residual(scb),
++                              aic_get_transfer_length(scb));
++                      aic_set_transaction_status(scb, CAM_DATA_RUN_ERR);
++#endif
+               } else {
+-                      ahd_set_transaction_status(scb, CAM_REQ_CMP);
++                      aic_set_transaction_status(scb, CAM_REQ_CMP);
+               }
+-      } else if (ahd_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
++      } else if (aic_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
+               ahd_linux_handle_scsi_status(ahd, dev, scb);
+-      } else if (ahd_get_transaction_status(scb) == CAM_SEL_TIMEOUT) {
+-              dev->flags |= AHD_DEV_UNCONFIGURED;
+-              if (AHD_DV_CMD(cmd) == FALSE)
+-                      dev->target->flags &= ~AHD_DV_REQUIRED;
++      } else if (aic_get_transaction_status(scb) == CAM_SEL_TIMEOUT) {
++              dev->flags |= AIC_DEV_UNCONFIGURED;
++              if (AIC_DV_CMD(cmd) == FALSE)
++                      dev->target->flags &= ~AIC_DV_REQUIRED;
+       }
+       /*
+        * Start DV for devices that require it assuming the first command
+        * sent does not result in a selection timeout.
+        */
+-      if (ahd_get_transaction_status(scb) != CAM_SEL_TIMEOUT
+-       && (dev->target->flags & AHD_DV_REQUIRED) != 0)
++      if (aic_get_transaction_status(scb) != CAM_SEL_TIMEOUT
++       && (dev->target->flags & AIC_DV_REQUIRED) != 0)
+               ahd_linux_start_dv(ahd);
+       if (dev->openings == 1
+-       && ahd_get_transaction_status(scb) == CAM_REQ_CMP
+-       && ahd_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
++       && aic_get_transaction_status(scb) == CAM_REQ_CMP
++       && aic_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
+               dev->tag_success_count++;
+       /*
+        * Some devices deal with temporary internal resource
+@@ -4485,7 +4480,7 @@ ahd_done(struct ahd_softc *ahd, struct s
+        * back to our previous queue depth.
+        */
+       if ((dev->openings + dev->active) < dev->maxtags
+-       && dev->tag_success_count > AHD_TAG_SUCCESS_INTERVAL) {
++       && dev->tag_success_count > AIC_TAG_SUCCESS_INTERVAL) {
+               dev->tag_success_count = 0;
+               dev->openings++;
+       }
+@@ -4494,39 +4489,68 @@ ahd_done(struct ahd_softc *ahd, struct s
+               dev->commands_since_idle_or_otag = 0;
+       if (TAILQ_EMPTY(&dev->busyq)) {
+-              if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0
+-               && dev->active == 0
+-               && (dev->flags & AHD_DEV_TIMER_ACTIVE) == 0)
++              if ((dev->flags & AIC_DEV_UNCONFIGURED) != 0
++               && dev->active == 0)
+                       ahd_linux_free_device(ahd, dev);
+-      } else if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) {
++      } else if ((dev->flags & AIC_DEV_ON_RUN_LIST) == 0) {
+               TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links);
+-              dev->flags |= AHD_DEV_ON_RUN_LIST;
++              dev->flags |= AIC_DEV_ON_RUN_LIST;
+       }
+       if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
+               printf("Recovery SCB completes\n");
+-              if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
+-               || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
+-                      ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
+-              if ((scb->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) {
+-                      scb->platform_data->flags &= ~AHD_SCB_UP_EH_SEM;
++              if (aic_get_transaction_status(scb) == CAM_BDR_SENT
++               || aic_get_transaction_status(scb) == CAM_REQ_ABORTED)
++                      aic_set_transaction_status(scb, CAM_CMD_TIMEOUT);
++              if ((scb->platform_data->flags & AIC_SCB_UP_EH_SEM) != 0) {
++                      scb->platform_data->flags &= ~AIC_SCB_UP_EH_SEM;
+                       up(&ahd->platform_data->eh_sem);
++              } else {
++                      struct  scb *list_scb;
++
++                      /*
++                       * We were able to complete the command successfully,
++                       * so reinstate the timeouts for all other pending
++                       * commands.
++                       */
++                      LIST_FOREACH(list_scb,
++                                   &ahd->pending_scbs, pending_links) {
++
++                              aic_scb_timer_start(list_scb);
++                      }
+               }
+       }
++      if ((scb->platform_data->flags & AIC_TIMEOUT_ACTIVE) == 0) {
++              /*
++               * The completion handler believes that
++               * commands without active timers running
++               * have lost the race of completing before
++               * their timer expires.  Since commands in
++               * our busy queues do not have timers running,
++               * appease the mid-layer by adding a timer
++               * now.  This timer will be immediately
++               * canceled by the midlayer.
++               */
++              scsi_add_timer(cmd, 60*HZ, aic_linux_midlayer_timeout);
++      }
++
++      if ((scb->platform_data->flags & AIC_RELEASE_SIMQ) != 0)
++              aic_release_simq_locked(ahd);
++
+       ahd_free_scb(ahd, scb);
+       ahd_linux_queue_cmd_complete(ahd, cmd);
+-      if ((ahd->platform_data->flags & AHD_DV_WAIT_SIMQ_EMPTY) != 0
++      if ((ahd->platform_data->flags & AIC_DV_WAIT_SIMQ_EMPTY) != 0
+        && LIST_FIRST(&ahd->pending_scbs) == NULL) {
+-              ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_EMPTY;
++              ahd->platform_data->flags &= ~AIC_DV_WAIT_SIMQ_EMPTY;
+               up(&ahd->platform_data->dv_sem);
+       }
+ }
+ static void
+ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
+-                           struct ahd_linux_device *dev, struct scb *scb)
++                           struct aic_linux_device *dev, struct scb *scb)
+ {
+       struct  ahd_devinfo devinfo;
+@@ -4546,7 +4570,7 @@ ahd_linux_handle_scsi_status(struct ahd_
+        * we don't clobber the device with too many
+        * commands.
+        */
+-      switch (ahd_get_scsi_status(scb)) {
++      switch (aic_get_scsi_status(scb)) {
+       default:
+               break;
+       case SCSI_STATUS_CHECK_COND:
+@@ -4560,13 +4584,15 @@ ahd_linux_handle_scsi_status(struct ahd_
+                */
+               cmd = scb->io_ctx;
+               if ((scb->flags & (SCB_SENSE|SCB_PKT_SENSE)) != 0) {
+-                      struct scsi_status_iu_header *siu;
+-                      u_int sense_size;
+-                      u_int sense_offset;
++                      struct  scsi_status_iu_header *siu;
++                      struct  scsi_sense_data *sense;
++                      u_int   sense_size;
++                      u_int   sense_offset;
++                      int     error_code, sense_key, asc, ascq;
+                       if (scb->flags & SCB_SENSE) {
+                               sense_size = MIN(sizeof(struct scsi_sense_data)
+-                                             - ahd_get_sense_residual(scb),
++                                             - aic_get_sense_residual(scb),
+                                                sizeof(cmd->sense_buffer));
+                               sense_offset = 0;
+                       } else {
+@@ -4581,10 +4607,10 @@ ahd_linux_handle_scsi_status(struct ahd_
+                               sense_offset = SIU_SENSE_OFFSET(siu);
+                       }
++                      sense = (struct scsi_sense_data *)
++                          (ahd_get_sense_buf(ahd, scb) + sense_offset);
+                       memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
+-                      memcpy(cmd->sense_buffer,
+-                             ahd_get_sense_buf(ahd, scb)
+-                             + sense_offset, sense_size);
++                      memcpy(cmd->sense_buffer, sense, sense_size);
+                       cmd->result |= (DRIVER_SENSE << 24);
+ #ifdef AHD_DEBUG
+@@ -4601,6 +4627,23 @@ ahd_linux_handle_scsi_status(struct ahd_
+                               printf("\n");
+                       }
+ #endif
++                      /*
++                       * If this is not a DV command and the target
++                       * provides some status that makes us believe
++                       * that the target has changed (power on reset,
++                       * etc.) kick off a DV scan to re-validate the
++                       * device.
++                       */
++                      if (AIC_DV_CMD(cmd) != 0)
++                              break;
++
++                      scsi_extract_sense(sense, &error_code,
++                                         &sense_key, &asc, &ascq);
++                      if (error_code == SSD_CURRENT_ERROR
++                       && sense_key == SSD_KEY_UNIT_ATTENTION
++                       && asc == 0x29
++                       && (ascq == 0 || ascq == 1))
++                              dev->target->flags |= AIC_DV_REQUIRED;
+               }
+               break;
+       }
+@@ -4640,7 +4683,7 @@ ahd_linux_handle_scsi_status(struct ahd_
+                                * this device.
+                                */
+                               if (dev->last_queuefull_same_count
+-                               == AHD_LOCK_TAGS_COUNT) {
++                               == AIC_LOCK_TAGS_COUNT) {
+                                       dev->maxtags = dev->active;
+                                       ahd_print_path(ahd, scb);
+                                       printf("Locking max tag count at %d\n",
+@@ -4650,10 +4693,10 @@ ahd_linux_handle_scsi_status(struct ahd_
+                               dev->tags_on_last_queuefull = dev->active;
+                               dev->last_queuefull_same_count = 0;
+                       }
+-                      ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
+-                      ahd_set_scsi_status(scb, SCSI_STATUS_OK);
++                      aic_set_transaction_status(scb, CAM_REQUEUE_REQ);
++                      aic_set_scsi_status(scb, SCSI_STATUS_OK);
+                       ahd_platform_set_tags(ahd, &devinfo,
+-                                   (dev->flags & AHD_DEV_Q_BASIC)
++                                   (dev->flags & AIC_DEV_Q_BASIC)
+                                  ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
+                       break;
+               }
+@@ -4663,9 +4706,9 @@ ahd_linux_handle_scsi_status(struct ahd_
+                */
+               dev->openings = 1;
+               ahd_platform_set_tags(ahd, &devinfo,
+-                           (dev->flags & AHD_DEV_Q_BASIC)
++                           (dev->flags & AIC_DEV_Q_BASIC)
+                          ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
+-              ahd_set_scsi_status(scb, SCSI_STATUS_BUSY);
++              aic_set_scsi_status(scb, SCSI_STATUS_BUSY);
+               /* FALLTHROUGH */
+       }
+       case SCSI_STATUS_BUSY:
+@@ -4673,13 +4716,13 @@ ahd_linux_handle_scsi_status(struct ahd_
+                * Set a short timer to defer sending commands for
+                * a bit since Linux will not delay in this case.
+                */
+-              if ((dev->flags & AHD_DEV_TIMER_ACTIVE) != 0) {
++              if ((dev->flags & AIC_DEV_TIMER_ACTIVE) != 0) {
+                       printf("%s:%c:%d: Device Timer still active during "
+                              "busy processing\n", ahd_name(ahd),
+                               dev->target->channel, dev->target->target);
+                       break;
+               }
+-              dev->flags |= AHD_DEV_TIMER_ACTIVE;
++              dev->flags |= AIC_DEV_TIMER_ACTIVE;
+               dev->qfrozen++;
+               init_timer(&dev->timer);
+               dev->timer.data = (u_long)dev;
+@@ -4705,9 +4748,9 @@ ahd_linux_queue_cmd_complete(struct ahd_
+        * not guarantee the order that aborted commands will be
+        * returned to us.
+        */
+-      struct ahd_completeq *completeq;
+-      struct ahd_cmd *list_cmd;
+-      struct ahd_cmd *acmd;
++      struct aic_completeq *completeq;
++      struct aic_cmd *list_cmd;
++      struct aic_cmd *acmd;
+       /*
+        * Map CAM error codes into Linux Error codes.  We
+@@ -4715,13 +4758,13 @@ ahd_linux_queue_cmd_complete(struct ahd_
+        * full error information available when making
+        * state change decisions.
+        */
+-      if (AHD_DV_CMD(cmd) == FALSE) {
++      if (AIC_DV_CMD(cmd) == FALSE) {
+               uint32_t status;
+               u_int new_status;
+-              status = ahd_cmd_get_transaction_status(cmd);
++              status = aic_cmd_get_transaction_status(cmd);
+               if (status != CAM_REQ_CMP) {
+-                      struct ahd_linux_device *dev;
++                      struct aic_linux_device *dev;
+                       struct ahd_devinfo devinfo;
+                       cam_status cam_status;
+                       uint32_t action;
+@@ -4741,8 +4784,8 @@ ahd_linux_queue_cmd_complete(struct ahd_
+                                           dev->target->channel == 0 ? 'A':'B',
+                                           ROLE_INITIATOR);
+-                      scsi_status = ahd_cmd_get_scsi_status(cmd);
+-                      cam_status = ahd_cmd_get_transaction_status(cmd);
++                      scsi_status = aic_cmd_get_scsi_status(cmd);
++                      cam_status = aic_cmd_get_transaction_status(cmd);
+                       action = aic_error_action(cmd, dev->target->inq_data,
+                                                 cam_status, scsi_status);
+                       if ((action & SSQ_FALLBACK) != 0) {
+@@ -4785,7 +4828,17 @@ no_fallback:
+                       new_status = DID_PARITY;
+                       break;
+               case CAM_CMD_TIMEOUT:
+-                      new_status = DID_TIME_OUT;
++                      /*
++                       *  Returning DID_TIME_OUT will 
++                       *  wake up the error recovery
++                       *  thread instead of doing the
++                       *  command retry we desire. Since
++                       *  we have already recovered the
++                       *  command, returning DID_ERROR
++                       *  will cause a retry up to the
++                       *  retry limit for this command.
++                       */
++                      new_status = DID_ERROR;
+                       break;
+               case CAM_UA_ABORT:
+               case CAM_REQ_CMP_ERR:
+@@ -4815,7 +4868,7 @@ no_fallback:
+                       if (cmd->retries > 0)
+                               cmd->retries--;
+                       new_status = DID_OK;
+-                      ahd_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);
++                      aic_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);
+                       cmd->result |= (DRIVER_SENSE << 24);
+                       memset(cmd->sense_buffer, 0,
+                              sizeof(cmd->sense_buffer));
+@@ -4829,12 +4882,12 @@ no_fallback:
+                       break;
+               }
+-              ahd_cmd_set_transaction_status(cmd, new_status);
++              aic_cmd_set_transaction_status(cmd, new_status);
+       }
+       completeq = &ahd->platform_data->completeq;
+       list_cmd = TAILQ_FIRST(completeq);
+-      acmd = (struct ahd_cmd *)cmd;
++      acmd = (struct aic_cmd *)cmd;
+       while (list_cmd != NULL
+           && acmd_scsi_cmd(list_cmd).serial_number
+            < acmd_scsi_cmd(acmd).serial_number)
+@@ -4854,7 +4907,7 @@ ahd_linux_filter_inquiry(struct ahd_soft
+       struct  ahd_transinfo *goal;
+       struct  ahd_transinfo *curr;
+       struct  ahd_tmode_tstate *tstate;
+-      struct  ahd_linux_device *dev;
++      struct  aic_linux_device *dev;
+       u_int   width;
+       u_int   period;
+       u_int   offset;
+@@ -4876,9 +4929,9 @@ ahd_linux_filter_inquiry(struct ahd_soft
+       sid = (struct scsi_inquiry_data *)dev->target->inq_data;
+       if (SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) {
+-              dev->flags &= ~AHD_DEV_UNCONFIGURED;
++              dev->flags &= ~AIC_DEV_UNCONFIGURED;
+       } else {
+-              dev->flags |= AHD_DEV_UNCONFIGURED;
++              dev->flags |= AIC_DEV_UNCONFIGURED;
+               return;
+       }
+@@ -4944,48 +4997,6 @@ ahd_linux_filter_inquiry(struct ahd_soft
+                        AHD_TRANS_GOAL, /*paused*/FALSE);
+ }
+-void
+-ahd_freeze_simq(struct ahd_softc *ahd)
+-{
+-      ahd->platform_data->qfrozen++;
+-      if (ahd->platform_data->qfrozen == 1) {
+-              scsi_block_requests(ahd->platform_data->host);
+-              ahd_platform_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
+-                                      CAM_LUN_WILDCARD, SCB_LIST_NULL,
+-                                      ROLE_INITIATOR, CAM_REQUEUE_REQ);
+-      }
+-}
+-
+-void
+-ahd_release_simq(struct ahd_softc *ahd)
+-{
+-      u_long s;
+-      int    unblock_reqs;
+-
+-      unblock_reqs = 0;
+-      ahd_lock(ahd, &s);
+-      if (ahd->platform_data->qfrozen > 0)
+-              ahd->platform_data->qfrozen--;
+-      if (ahd->platform_data->qfrozen == 0) {
+-              unblock_reqs = 1;
+-      }
+-      if (AHD_DV_SIMQ_FROZEN(ahd)
+-       && ((ahd->platform_data->flags & AHD_DV_WAIT_SIMQ_RELEASE) != 0)) {
+-              ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_RELEASE;
+-              up(&ahd->platform_data->dv_sem);
+-      }
+-      ahd_schedule_runq(ahd);
+-      ahd_unlock(ahd, &s);
+-      /*
+-       * There is still a race here.  The mid-layer
+-       * should keep its own freeze count and use
+-       * a bottom half handler to run the queues
+-       * so we can unblock with our own lock held.
+-       */
+-      if (unblock_reqs)
+-              scsi_unblock_requests(ahd->platform_data->host);
+-}
+-
+ static void
+ ahd_linux_sem_timeout(u_long arg)
+ {
+@@ -4996,8 +5007,8 @@ ahd_linux_sem_timeout(u_long arg)
+       scb = (struct scb *)arg;
+       ahd = scb->ahd_softc;
+       ahd_lock(ahd, &s);
+-      if ((scb->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) {
+-              scb->platform_data->flags &= ~AHD_SCB_UP_EH_SEM;
++      if ((scb->platform_data->flags & AIC_SCB_UP_EH_SEM) != 0) {
++              scb->platform_data->flags &= ~AIC_SCB_UP_EH_SEM;
+               up(&ahd->platform_data->eh_sem);
+       }
+       ahd_unlock(ahd, &s);
+@@ -5006,20 +5017,21 @@ ahd_linux_sem_timeout(u_long arg)
+ static void
+ ahd_linux_dev_timed_unfreeze(u_long arg)
+ {
+-      struct ahd_linux_device *dev;
++      struct aic_linux_device *dev;
+       struct ahd_softc *ahd;
+       u_long s;
+-      dev = (struct ahd_linux_device *)arg;
+-      ahd = dev->target->ahd;
++      dev = (struct aic_linux_device *)arg;
++      ahd = dev->target->softc;
+       ahd_lock(ahd, &s);
+-      dev->flags &= ~AHD_DEV_TIMER_ACTIVE;
++      dev->flags &= ~AIC_DEV_TIMER_ACTIVE;
+       if (dev->qfrozen > 0)
+               dev->qfrozen--;
+       if (dev->qfrozen == 0
+-       && (dev->flags & AHD_DEV_ON_RUN_LIST) == 0)
++       && (dev->flags & AIC_DEV_ON_RUN_LIST) == 0)
+               ahd_linux_run_device_queue(ahd, dev);
+-      if ((dev->flags & AHD_DEV_UNCONFIGURED) != 0
++      if ((dev->flags & AIC_DEV_UNCONFIGURED) != 0
++       && TAILQ_EMPTY(&dev->busyq)
+        && dev->active == 0)
+               ahd_linux_free_device(ahd, dev);
+       ahd_unlock(ahd, &s);
+@@ -5028,17 +5040,26 @@ ahd_linux_dev_timed_unfreeze(u_long arg)
+ void
+ ahd_platform_dump_card_state(struct ahd_softc *ahd)
+ {
+-      struct ahd_linux_device *dev;
++      struct Scsi_Host *host;
++      struct aic_linux_device *dev;
+       int target;
+       int maxtarget;
+       int lun;
+       int i;
++      host = ahd->platform_data->host;
++      printf("%s: Host Status: Failed(%d) %s%s%s\n",
++             ahd_name(ahd),
++             host->host_failed,
++             host->eh_active ? "eh_active " : "",
++             host->host_blocked ? "host_blocked " : "",
++             host->host_self_blocked ? "host_self_blocked " : "");
++             
+       maxtarget = (ahd->features & AHD_WIDE) ? 15 : 7;
+       for (target = 0; target <=maxtarget; target++) {
+               for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
+-                      struct ahd_cmd *acmd;
++                      struct aic_cmd *acmd;
+                       dev = ahd_linux_get_device(ahd, 0, target,
+                                                  lun, /*alloc*/FALSE);
+@@ -5077,20 +5098,18 @@ static void __exit
+ ahd_linux_exit(void)
+ {
+       struct ahd_softc *ahd;
+-      u_long l;
+       /*
+-       * Shutdown DV threads before going into the SCSI mid-layer.
++       * Shutdown our threads before going into the SCSI mid-layer.
+        * This avoids situations where the mid-layer locks the entire
+        * kernel so that waiting for our DV threads to exit leads
+        * to deadlock.
+        */
+-      ahd_list_lock(&l);
+       TAILQ_FOREACH(ahd, &ahd_tailq, links) {
+               ahd_linux_kill_dv_thread(ahd);
++              ahd_terminate_recovery_thread(ahd);
+       }
+-      ahd_list_unlock(&l);
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+       /*
+        * In 2.4 we have to unregister from the PCI core _after_
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx_osm.h     2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx_osm.h      2003-12-28 23:21:39.000000000 -0800
+@@ -36,51 +36,22 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#133 $
++ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#153 $
+  *
+  */
+ #ifndef _AIC79XX_LINUX_H_
+ #define _AIC79XX_LINUX_H_
+-#include <linux/types.h>
+-#include <linux/blkdev.h>
+-#include <linux/delay.h>
+-#include <linux/ioport.h>
+-#include <linux/pci.h>
+-#include <linux/smp_lock.h>
+ #include <linux/version.h>
+-#include <linux/module.h>
+-#include <asm/byteorder.h>
+-#include <asm/io.h>
+ #ifndef KERNEL_VERSION
+ #define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
+ #endif
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-#include <linux/interrupt.h> /* For tasklet support. */
+ #include <linux/config.h>
+-#include <linux/slab.h>
+-#else
+-#include <linux/malloc.h>
+ #endif
+-/* Core SCSI definitions */
+-#define AIC_LIB_PREFIX ahd
+-#include "scsi.h"
+-#include "hosts.h"
+-
+-/* Name space conflict with BSD queue macros */
+-#ifdef LIST_HEAD
+-#undef LIST_HEAD
+-#endif
+-
+-#include "cam.h"
+-#include "queue.h"
+-#include "scsi_message.h"
+-#include "scsi_iu.h"
+-#include "aiclib.h"
+-
+ /*********************************** Debugging ********************************/
+ #ifdef CONFIG_AIC79XX_DEBUG_ENABLE
+ #ifdef CONFIG_AIC79XX_DEBUG_MASK
+@@ -96,188 +67,27 @@
+ /* No debugging code. */
+ #endif
+-/********************************** Misc Macros *******************************/
+-#define       roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
+-#define       powerof2(x)     ((((x)-1)&(x))==0)
+-
+-/************************* Forward Declarations *******************************/
+-struct ahd_softc;
+-typedef struct pci_dev *ahd_dev_softc_t;
+-typedef Scsi_Cmnd      *ahd_io_ctx_t;
+-
+-/******************************* Byte Order ***********************************/
+-#define ahd_htobe16(x)        cpu_to_be16(x)
+-#define ahd_htobe32(x)        cpu_to_be32(x)
+-#define ahd_htobe64(x)        cpu_to_be64(x)
+-#define ahd_htole16(x)        cpu_to_le16(x)
+-#define ahd_htole32(x)        cpu_to_le32(x)
+-#define ahd_htole64(x)        cpu_to_le64(x)
+-
+-#define ahd_be16toh(x)        be16_to_cpu(x)
+-#define ahd_be32toh(x)        be32_to_cpu(x)
+-#define ahd_be64toh(x)        be64_to_cpu(x)
+-#define ahd_le16toh(x)        le16_to_cpu(x)
+-#define ahd_le32toh(x)        le32_to_cpu(x)
+-#define ahd_le64toh(x)        le64_to_cpu(x)
+-
+-#ifndef LITTLE_ENDIAN
+-#define LITTLE_ENDIAN 1234
+-#endif
+-
+-#ifndef BIG_ENDIAN
+-#define BIG_ENDIAN 4321
+-#endif
+-
+-#ifndef BYTE_ORDER
+-#if defined(__BIG_ENDIAN)
+-#define BYTE_ORDER BIG_ENDIAN
+-#endif
+-#if defined(__LITTLE_ENDIAN)
+-#define BYTE_ORDER LITTLE_ENDIAN
+-#endif
+-#endif /* BYTE_ORDER */
+-
+-/************************* Configuration Data *********************************/
+-extern uint32_t aic79xx_allow_memio;
+-extern int aic79xx_detect_complete;
+-extern Scsi_Host_Template aic79xx_driver_template;
+-
+-/***************************** Bus Space/DMA **********************************/
+-
+-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,17)
+-typedef dma_addr_t bus_addr_t;
+-#else
+-typedef uint32_t bus_addr_t;
+-#endif
+-typedef uint32_t bus_size_t;
+-
+-typedef enum {
+-      BUS_SPACE_MEMIO,
+-      BUS_SPACE_PIO
+-} bus_space_tag_t;
+-
+-typedef union {
+-      u_long            ioport;
+-      volatile uint8_t *maddr;
+-} bus_space_handle_t;
+-
+-typedef struct bus_dma_segment
+-{
+-      bus_addr_t      ds_addr;
+-      bus_size_t      ds_len;
+-} bus_dma_segment_t;
+-
+-struct ahd_linux_dma_tag
+-{
+-      bus_size_t      alignment;
+-      bus_size_t      boundary;
+-      bus_size_t      maxsize;
+-};
+-typedef struct ahd_linux_dma_tag* bus_dma_tag_t;
+-
+-struct ahd_linux_dmamap
+-{
+-      bus_addr_t      bus_addr;
+-};
+-typedef struct ahd_linux_dmamap* bus_dmamap_t;
+-
+-typedef int bus_dma_filter_t(void*, bus_addr_t);
+-typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
+-
+-#define BUS_DMA_WAITOK                0x0
+-#define BUS_DMA_NOWAIT                0x1
+-#define BUS_DMA_ALLOCNOW      0x2
+-#define BUS_DMA_LOAD_SEGS     0x4     /*
+-                                       * Argument is an S/G list not
+-                                       * a single buffer.
+-                                       */
+-
+-#define BUS_SPACE_MAXADDR     0xFFFFFFFF
+-#define BUS_SPACE_MAXADDR_32BIT       0xFFFFFFFF
+-#define BUS_SPACE_MAXSIZE_32BIT       0xFFFFFFFF
+-
+-int   ahd_dma_tag_create(struct ahd_softc *, bus_dma_tag_t /*parent*/,
+-                         bus_size_t /*alignment*/, bus_size_t /*boundary*/,
+-                         bus_addr_t /*lowaddr*/, bus_addr_t /*highaddr*/,
+-                         bus_dma_filter_t*/*filter*/, void */*filterarg*/,
+-                         bus_size_t /*maxsize*/, int /*nsegments*/,
+-                         bus_size_t /*maxsegsz*/, int /*flags*/,
+-                         bus_dma_tag_t */*dma_tagp*/);
+-
+-void  ahd_dma_tag_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/);
+-
+-int   ahd_dmamem_alloc(struct ahd_softc *, bus_dma_tag_t /*dmat*/,
+-                       void** /*vaddr*/, int /*flags*/,
+-                       bus_dmamap_t* /*mapp*/);
+-
+-void  ahd_dmamem_free(struct ahd_softc *, bus_dma_tag_t /*dmat*/,
+-                      void* /*vaddr*/, bus_dmamap_t /*map*/);
+-
+-void  ahd_dmamap_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/,
+-                         bus_dmamap_t /*map*/);
+-
+-int   ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t /*dmat*/,
+-                      bus_dmamap_t /*map*/, void * /*buf*/,
+-                      bus_size_t /*buflen*/, bus_dmamap_callback_t *,
+-                      void */*callback_arg*/, int /*flags*/);
+-
+-int   ahd_dmamap_unload(struct ahd_softc *, bus_dma_tag_t, bus_dmamap_t);
+-
+-/*
+- * Operations performed by ahd_dmamap_sync().
+- */
+-#define BUS_DMASYNC_PREREAD   0x01    /* pre-read synchronization */
+-#define BUS_DMASYNC_POSTREAD  0x02    /* post-read synchronization */
+-#define BUS_DMASYNC_PREWRITE  0x04    /* pre-write synchronization */
+-#define BUS_DMASYNC_POSTWRITE 0x08    /* post-write synchronization */
+-
+-/*
+- * XXX
+- * ahd_dmamap_sync is only used on buffers allocated with
+- * the pci_alloc_consistent() API.  Although I'm not sure how
+- * this works on architectures with a write buffer, Linux does
+- * not have an API to sync "coherent" memory.  Perhaps we need
+- * to do an mb()?
+- */
+-#define ahd_dmamap_sync(ahd, dma_tag, dmamap, offset, len, op)
+-
+-/************************** Timer DataStructures ******************************/
+-typedef struct timer_list ahd_timer_t;
+-
+ /********************************** Includes **********************************/
++/* Core SCSI definitions */
++#define AIC_LIB_PREFIX ahd
++#define AIC_CONST_PREFIX AHD
++
+ #ifdef CONFIG_AIC79XX_REG_PRETTY_PRINT
+ #define AIC_DEBUG_REGISTERS 1
+ #else
+ #define AIC_DEBUG_REGISTERS 0
+ #endif
+-#include "aic79xx.h"
+-
+-/***************************** Timer Facilities *******************************/
+-#define ahd_timer_init init_timer
+-#define ahd_timer_stop del_timer_sync
+-typedef void ahd_linux_callback_t (u_long);  
+-static __inline void ahd_timer_reset(ahd_timer_t *timer, u_int usec,
+-                                   ahd_callback_t *func, void *arg);
+-static __inline void ahd_scb_timer_reset(struct scb *scb, u_int usec);
+-
+-static __inline void
+-ahd_timer_reset(ahd_timer_t *timer, u_int usec, ahd_callback_t *func, void *arg)
+-{
+-      struct ahd_softc *ahd;
++#define AIC_CORE_INCLUDE "aic79xx.h"
++#include "aiclib.h"
+-      ahd = (struct ahd_softc *)arg;
+-      del_timer(timer);
+-      timer->data = (u_long)arg;
+-      timer->expires = jiffies + (usec * HZ)/1000000;
+-      timer->function = (ahd_linux_callback_t*)func;
+-      add_timer(timer);
+-}
++/************************* Configuration Data *********************************/
++extern uint32_t aic79xx_allow_memio;
++extern int aic79xx_detect_complete;
++extern Scsi_Host_Template aic79xx_driver_template;
+-static __inline void
+-ahd_scb_timer_reset(struct scb *scb, u_int usec)
+-{
+-      mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000);
+-}
++/***************************** Domain Validation ******************************/
++void ahd_linux_dv_complete(Scsi_Cmnd *cmd);
++void ahd_linux_dv_timeout(struct scsi_cmnd *cmd);
+ /***************************** SMP support ************************************/
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17)
+@@ -292,193 +102,7 @@ ahd_scb_timer_reset(struct scb *scb, u_i
+ #define AHD_SCSI_HAS_HOST_LOCK 0
+ #endif
+-#define AIC79XX_DRIVER_VERSION "1.3.9"
+-
+-/**************************** Front End Queues ********************************/
+-/*
+- * Data structure used to cast the Linux struct scsi_cmnd to something
+- * that allows us to use the queue macros.  The linux structure has
+- * plenty of space to hold the links fields as required by the queue
+- * macros, but the queue macors require them to have the correct type.
+- */
+-struct ahd_cmd_internal {
+-      /* Area owned by the Linux scsi layer. */
+-      uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)];
+-      union {
+-              STAILQ_ENTRY(ahd_cmd)   ste;
+-              LIST_ENTRY(ahd_cmd)     le;
+-              TAILQ_ENTRY(ahd_cmd)    tqe;
+-      } links;
+-      uint32_t                        end;
+-};
+-
+-struct ahd_cmd {
+-      union {
+-              struct ahd_cmd_internal icmd;
+-              struct scsi_cmnd        scsi_cmd;
+-      } un;
+-};
+-
+-#define acmd_icmd(cmd) ((cmd)->un.icmd)
+-#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd)
+-#define acmd_links un.icmd.links
+-
+-/*************************** Device Data Structures ***************************/
+-/*
+- * A per probed device structure used to deal with some error recovery
+- * scenarios that the Linux mid-layer code just doesn't know how to
+- * handle.  The structure allocated for a device only becomes persistent
+- * after a successfully completed inquiry command to the target when
+- * that inquiry data indicates a lun is present.
+- */
+-TAILQ_HEAD(ahd_busyq, ahd_cmd);
+-typedef enum {
+-      AHD_DEV_UNCONFIGURED     = 0x01,
+-      AHD_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
+-      AHD_DEV_TIMER_ACTIVE     = 0x04, /* Our timer is active */
+-      AHD_DEV_ON_RUN_LIST      = 0x08, /* Queued to be run later */
+-      AHD_DEV_Q_BASIC          = 0x10, /* Allow basic device queuing */
+-      AHD_DEV_Q_TAGGED         = 0x20, /* Allow full SCSI2 command queueing */
+-      AHD_DEV_PERIODIC_OTAG    = 0x40, /* Send OTAG to prevent starvation */
+-      AHD_DEV_SLAVE_CONFIGURED = 0x80  /* slave_configure() has been called */
+-} ahd_linux_dev_flags;
+-
+-struct ahd_linux_target;
+-struct ahd_linux_device {
+-      TAILQ_ENTRY(ahd_linux_device) links;
+-      struct                  ahd_busyq busyq;
+-
+-      /*
+-       * The number of transactions currently
+-       * queued to the device.
+-       */
+-      int                     active;
+-
+-      /*
+-       * The currently allowed number of 
+-       * transactions that can be queued to
+-       * the device.  Must be signed for
+-       * conversion from tagged to untagged
+-       * mode where the device may have more
+-       * than one outstanding active transaction.
+-       */
+-      int                     openings;
+-
+-      /*
+-       * A positive count indicates that this
+-       * device's queue is halted.
+-       */
+-      u_int                   qfrozen;
+-      
+-      /*
+-       * Cumulative command counter.
+-       */
+-      u_long                  commands_issued;
+-
+-      /*
+-       * The number of tagged transactions when
+-       * running at our current opening level
+-       * that have been successfully received by
+-       * this device since the last QUEUE FULL.
+-       */
+-      u_int                   tag_success_count;
+-#define AHD_TAG_SUCCESS_INTERVAL 50
+-
+-      ahd_linux_dev_flags     flags;
+-
+-      /*
+-       * Per device timer.
+-       */
+-      struct timer_list       timer;
+-
+-      /*
+-       * The high limit for the tags variable.
+-       */
+-      u_int                   maxtags;
+-
+-      /*
+-       * The computed number of tags outstanding
+-       * at the time of the last QUEUE FULL event.
+-       */
+-      u_int                   tags_on_last_queuefull;
+-
+-      /*
+-       * How many times we have seen a queue full
+-       * with the same number of tags.  This is used
+-       * to stop our adaptive queue depth algorithm
+-       * on devices with a fixed number of tags.
+-       */
+-      u_int                   last_queuefull_same_count;
+-#define AHD_LOCK_TAGS_COUNT 50
+-
+-      /*
+-       * How many transactions have been queued
+-       * without the device going idle.  We use
+-       * this statistic to determine when to issue
+-       * an ordered tag to prevent transaction
+-       * starvation.  This statistic is only updated
+-       * if the AHD_DEV_PERIODIC_OTAG flag is set
+-       * on this device.
+-       */
+-      u_int                   commands_since_idle_or_otag;
+-#define AHD_OTAG_THRESH       500
+-
+-      int                     lun;
+-      Scsi_Device            *scsi_device;
+-      struct                  ahd_linux_target *target;
+-};
+-
+-typedef enum {
+-      AHD_DV_REQUIRED          = 0x01,
+-      AHD_INQ_VALID            = 0x02,
+-      AHD_BASIC_DV             = 0x04,
+-      AHD_ENHANCED_DV          = 0x08
+-} ahd_linux_targ_flags;
+-
+-/* DV States */
+-typedef enum {
+-      AHD_DV_STATE_EXIT = 0,
+-      AHD_DV_STATE_INQ_SHORT_ASYNC,
+-      AHD_DV_STATE_INQ_ASYNC,
+-      AHD_DV_STATE_INQ_ASYNC_VERIFY,
+-      AHD_DV_STATE_TUR,
+-      AHD_DV_STATE_REBD,
+-      AHD_DV_STATE_INQ_VERIFY,
+-      AHD_DV_STATE_WEB,
+-      AHD_DV_STATE_REB,
+-      AHD_DV_STATE_SU,
+-      AHD_DV_STATE_BUSY
+-} ahd_dv_state;
+-
+-struct ahd_linux_target {
+-      struct ahd_linux_device  *devices[AHD_NUM_LUNS];
+-      int                       channel;
+-      int                       target;
+-      int                       refcount;
+-      struct ahd_transinfo      last_tinfo;
+-      struct ahd_softc         *ahd;
+-      ahd_linux_targ_flags      flags;
+-      struct scsi_inquiry_data *inq_data;
+-      /*
+-       * The next "fallback" period to use for narrow/wide transfers.
+-       */
+-      uint8_t                   dv_next_narrow_period;
+-      uint8_t                   dv_next_wide_period;
+-      uint8_t                   dv_max_width;
+-      uint8_t                   dv_max_ppr_options;
+-      uint8_t                   dv_last_ppr_options;
+-      u_int                     dv_echo_size;
+-      ahd_dv_state              dv_state;
+-      u_int                     dv_state_retry;
+-      uint8_t                  *dv_buffer;
+-      uint8_t                  *dv_buffer1;
+-
+-      /*
+-       * Cumulative counter of errors.
+-       */
+-      u_long                  errors_detected;
+-      u_long                  cmds_since_error;
+-};
++#define AIC79XX_DRIVER_VERSION "2.0.5"
+ /********************* Definitions Required by the Core ***********************/
+ /*
+@@ -500,100 +124,21 @@ extern u_int ahd_linux_nseg;
+ #define       AHD_NSEG 128
+ #endif
+-/*
+- * Per-SCB OSM storage.
+- */
+-typedef enum {
+-      AHD_SCB_UP_EH_SEM = 0x1
+-} ahd_linux_scb_flags;
+-
+-struct scb_platform_data {
+-      struct ahd_linux_device *dev;
+-      bus_addr_t               buf_busaddr;
+-      uint32_t                 xfer_len;
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
+-      uint32_t                 resid;         /* Transfer residual */
+-#endif
+-      uint32_t                 sense_resid;   /* Auto-Sense residual */
+-      ahd_linux_scb_flags      flags;
+-};
+-
+-/*
+- * Define a structure used for each host adapter.  All members are
+- * aligned on a boundary >= the size of the member to honor the
+- * alignment restrictions of the various platforms supported by
+- * this driver.
+- */
+-typedef enum {
+-      AHD_DV_WAIT_SIMQ_EMPTY   = 0x01,
+-      AHD_DV_WAIT_SIMQ_RELEASE = 0x02,
+-      AHD_DV_ACTIVE            = 0x04,
+-      AHD_DV_SHUTDOWN          = 0x08,
+-      AHD_RUN_CMPLT_Q_TIMER    = 0x10
+-} ahd_linux_softc_flags;
+-
+-TAILQ_HEAD(ahd_completeq, ahd_cmd);
+-
+-struct ahd_platform_data {
+-      /*
+-       * Fields accessed from interrupt context.
+-       */
+-      struct ahd_linux_target *targets[AHD_NUM_TARGETS]; 
+-      TAILQ_HEAD(, ahd_linux_device) device_runq;
+-      struct ahd_completeq     completeq;
+-
+-      spinlock_t               spin_lock;
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      struct tasklet_struct    runq_tasklet;
+-#endif
+-      u_int                    qfrozen;
+-      pid_t                    dv_pid;
+-      struct timer_list        completeq_timer;
+-      struct timer_list        reset_timer;
+-      struct timer_list        stats_timer;
+-      struct semaphore         eh_sem;
+-      struct semaphore         dv_sem;
+-      struct semaphore         dv_cmd_sem;    /* XXX This needs to be in
+-                                               * the target struct
+-                                               */
+-      struct scsi_device      *dv_scsi_dev;
+-      struct Scsi_Host        *host;          /* pointer to scsi host */
+-#define AHD_LINUX_NOIRQ       ((uint32_t)~0)
+-      uint32_t                 irq;           /* IRQ for this adapter */
+-      uint32_t                 bios_address;
+-      uint32_t                 mem_busaddr;   /* Mem Base Addr */
+-      bus_addr_t               hw_dma_mask;
+-      ahd_linux_softc_flags    flags;
+-};
+-
+-/************************** OS Utility Wrappers *******************************/
+-#define printf printk
+-#define M_NOWAIT GFP_ATOMIC
+-#define M_WAITOK 0
+-#define malloc(size, type, flags) kmalloc(size, flags)
+-#define free(ptr, type) kfree(ptr)
+-
+-static __inline void ahd_delay(long);
+-static __inline void
+-ahd_delay(long usec)
+-{
+-      /*
+-       * udelay on Linux can have problems for
+-       * multi-millisecond waits.  Wait at most
+-       * 1024us per call.
+-       */
+-      while (usec > 0) {
+-              udelay(usec % 1024);
+-              usec -= 1024;
+-      }
+-}
+-
++/************************** Error Recovery ************************************/
++static __inline void  ahd_wakeup_recovery_thread(struct ahd_softc *ahd); 
++  
++static __inline void
++ahd_wakeup_recovery_thread(struct ahd_softc *ahd)
++{ 
++      up(&ahd->platform_data->recovery_sem);
++}
++ 
++int                   ahd_spawn_recovery_thread(struct ahd_softc *ahd);
++void                  ahd_terminate_recovery_thread(struct ahd_softc *ahd);
++void                  ahd_set_recoveryscb(struct ahd_softc *ahd,
++                                          struct scb *scb);
+ /***************************** Low Level I/O **********************************/
+-#if defined(__powerpc__) || defined(__i386__) || defined(__ia64__)
+-#define MMAPIO
+-#endif
+-
+ static __inline uint8_t ahd_inb(struct ahd_softc * ahd, long port);
+ static __inline uint16_t ahd_inw_atomic(struct ahd_softc * ahd, long port);
+ static __inline void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
+@@ -603,21 +148,18 @@ static __inline void ahd_outsb(struct ah
+                              uint8_t *, int count);
+ static __inline void ahd_insb(struct ahd_softc * ahd, long port,
+                              uint8_t *, int count);
++static __inline void ahd_flush_device_writes(struct ahd_softc *);
+ static __inline uint8_t
+ ahd_inb(struct ahd_softc * ahd, long port)
+ {
+       uint8_t x;
+-#ifdef MMAPIO
+       if (ahd->tags[0] == BUS_SPACE_MEMIO) {
+               x = readb(ahd->bshs[0].maddr + port);
+       } else {
+               x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
+       }
+-#else
+-      x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
+-#endif
+       mb();
+       return (x);
+ }
+@@ -626,16 +168,12 @@ static __inline uint16_t
+ ahd_inw_atomic(struct ahd_softc * ahd, long port)
+ {
+       uint8_t x;
+-#ifdef MMAPIO
+       if (ahd->tags[0] == BUS_SPACE_MEMIO) {
+               x = readw(ahd->bshs[0].maddr + port);
+       } else {
+               x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
+       }
+-#else
+-      x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
+-#endif
+       mb();
+       return (x);
+ }
+@@ -643,30 +181,22 @@ ahd_inw_atomic(struct ahd_softc * ahd, l
+ static __inline void
+ ahd_outb(struct ahd_softc * ahd, long port, uint8_t val)
+ {
+-#ifdef MMAPIO
+       if (ahd->tags[0] == BUS_SPACE_MEMIO) {
+               writeb(val, ahd->bshs[0].maddr + port);
+       } else {
+               outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
+       }
+-#else
+-      outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
+-#endif
+       mb();
+ }
+ static __inline void
+ ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val)
+ {
+-#ifdef MMAPIO
+       if (ahd->tags[0] == BUS_SPACE_MEMIO) {
+               writew(val, ahd->bshs[0].maddr + port);
+       } else {
+               outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
+       }
+-#else
+-      outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
+-#endif
+       mb();
+ }
+@@ -698,6 +228,13 @@ ahd_insb(struct ahd_softc * ahd, long po
+               *array++ = ahd_inb(ahd, port);
+ }
++static __inline void
++ahd_flush_device_writes(struct ahd_softc *ahd)
++{
++      /* XXX Is this sufficient for all architectures??? */
++      ahd_inb(ahd, INTSTAT);
++}
++
+ /**************************** Initialization **********************************/
+ int           ahd_linux_register_host(struct ahd_softc *,
+                                       Scsi_Host_Template *);
+@@ -826,384 +363,29 @@ ahd_list_unlock(unsigned long *flags)
+ }
+ /******************************* PCI Definitions ******************************/
+-/*
+- * PCIM_xxx: mask to locate subfield in register
+- * PCIR_xxx: config register offset
+- * PCIC_xxx: device class
+- * PCIS_xxx: device subclass
+- * PCIP_xxx: device programming interface
+- * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
+- * PCID_xxx: device ID
+- */
+-#define PCIR_DEVVENDOR                0x00
+-#define PCIR_VENDOR           0x00
+-#define PCIR_DEVICE           0x02
+-#define PCIR_COMMAND          0x04
+-#define PCIM_CMD_PORTEN               0x0001
+-#define PCIM_CMD_MEMEN                0x0002
+-#define PCIM_CMD_BUSMASTEREN  0x0004
+-#define PCIM_CMD_MWRICEN      0x0010
+-#define PCIM_CMD_PERRESPEN    0x0040
+-#define       PCIM_CMD_SERRESPEN      0x0100
+-#define PCIR_STATUS           0x06
+-#define PCIR_REVID            0x08
+-#define PCIR_PROGIF           0x09
+-#define PCIR_SUBCLASS         0x0a
+-#define PCIR_CLASS            0x0b
+-#define PCIR_CACHELNSZ                0x0c
+-#define PCIR_LATTIMER         0x0d
+-#define PCIR_HEADERTYPE               0x0e
+-#define PCIM_MFDEV            0x80
+-#define PCIR_BIST             0x0f
+-#define PCIR_CAP_PTR          0x34
+-
+-/* config registers for header type 0 devices */
+-#define PCIR_MAPS     0x10
+-#define PCIR_SUBVEND_0        0x2c
+-#define PCIR_SUBDEV_0 0x2e
+-
+-/****************************** PCI-X definitions *****************************/
+-#define PCIXR_COMMAND 0x96
+-#define PCIXR_DEVADDR 0x98
+-#define PCIXM_DEVADDR_FNUM    0x0003  /* Function Number */
+-#define PCIXM_DEVADDR_DNUM    0x00F8  /* Device Number */
+-#define PCIXM_DEVADDR_BNUM    0xFF00  /* Bus Number */
+-#define PCIXR_STATUS  0x9A
+-#define PCIXM_STATUS_64BIT    0x0001  /* Active 64bit connection to device. */
+-#define PCIXM_STATUS_133CAP   0x0002  /* Device is 133MHz capable */
+-#define PCIXM_STATUS_SCDISC   0x0004  /* Split Completion Discarded */
+-#define PCIXM_STATUS_UNEXPSC  0x0008  /* Unexpected Split Completion */
+-#define PCIXM_STATUS_CMPLEXDEV        0x0010  /* Device Complexity (set == bridge) */
+-#define PCIXM_STATUS_MAXMRDBC 0x0060  /* Maximum Burst Read Count */
+-#define PCIXM_STATUS_MAXSPLITS        0x0380  /* Maximum Split Transactions */
+-#define PCIXM_STATUS_MAXCRDS  0x1C00  /* Maximum Cumulative Read Size */
+-#define PCIXM_STATUS_RCVDSCEM 0x2000  /* Received a Split Comp w/Error msg */
+-
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+ extern struct pci_driver aic79xx_pci_driver;
+ #endif
+-typedef enum
+-{
+-      AHD_POWER_STATE_D0,
+-      AHD_POWER_STATE_D1,
+-      AHD_POWER_STATE_D2,
+-      AHD_POWER_STATE_D3
+-} ahd_power_state;
+-
+-void ahd_power_state_change(struct ahd_softc *ahd,
+-                          ahd_power_state new_state);
+-
+ /******************************* PCI Routines *********************************/
+ int                    ahd_linux_pci_init(void);
+ void                   ahd_linux_pci_exit(void);
+ int                    ahd_pci_map_registers(struct ahd_softc *ahd);
+ int                    ahd_pci_map_int(struct ahd_softc *ahd);
+-static __inline uint32_t ahd_pci_read_config(ahd_dev_softc_t pci,
+-                                           int reg, int width);
+-
+-static __inline uint32_t
+-ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width)
+-{
+-      switch (width) {
+-      case 1:
+-      {
+-              uint8_t retval;
+-
+-              pci_read_config_byte(pci, reg, &retval);
+-              return (retval);
+-      }
+-      case 2:
+-      {
+-              uint16_t retval;
+-              pci_read_config_word(pci, reg, &retval);
+-              return (retval);
+-      }
+-      case 4:
+-      {
+-              uint32_t retval;
+-              pci_read_config_dword(pci, reg, &retval);
+-              return (retval);
+-      }
+-      default:
+-              panic("ahd_pci_read_config: Read size too big");
+-              /* NOTREACHED */
+-              return (0);
+-      }
+-}
+-
+-static __inline void ahd_pci_write_config(ahd_dev_softc_t pci,
+-                                        int reg, uint32_t value,
+-                                        int width);
+-
+-static __inline void
+-ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width)
+-{
+-      switch (width) {
+-      case 1:
+-              pci_write_config_byte(pci, reg, value);
+-              break;
+-      case 2:
+-              pci_write_config_word(pci, reg, value);
+-              break;
+-      case 4:
+-              pci_write_config_dword(pci, reg, value);
+-              break;
+-      default:
+-              panic("ahd_pci_write_config: Write size too big");
+-              /* NOTREACHED */
+-      }
+-}
+-
+-static __inline int ahd_get_pci_function(ahd_dev_softc_t);
+-static __inline int
+-ahd_get_pci_function(ahd_dev_softc_t pci)
+-{
+-      return (PCI_FUNC(pci->devfn));
+-}
+-
+-static __inline int ahd_get_pci_slot(ahd_dev_softc_t);
+-static __inline int
+-ahd_get_pci_slot(ahd_dev_softc_t pci)
+-{
+-      return (PCI_SLOT(pci->devfn));
+-}
+-
+-static __inline int ahd_get_pci_bus(ahd_dev_softc_t);
+-static __inline int
+-ahd_get_pci_bus(ahd_dev_softc_t pci)
+-{
+-      return (pci->bus->number);
+-}
+-
+-static __inline void ahd_flush_device_writes(struct ahd_softc *);
+-static __inline void
+-ahd_flush_device_writes(struct ahd_softc *ahd)
+-{
+-      /* XXX Is this sufficient for all architectures??? */
+-      ahd_inb(ahd, INTSTAT);
+-}
+-
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0)
+-#define pci_map_sg(pdev, sg_list, nseg, direction) (nseg)
+-#define pci_unmap_sg(pdev, sg_list, nseg, direction)
+-#define sg_dma_address(sg) (VIRT_TO_BUS((sg)->address))
+-#define sg_dma_len(sg) ((sg)->length)
+-#define pci_map_single(pdev, buffer, bufflen, direction) \
+-      (VIRT_TO_BUS(buffer))
+-#define pci_unmap_single(pdev, buffer, buflen, direction)
+-#endif
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
+-#define ahd_pci_set_dma_mask pci_set_dma_mask
+-#else
+-/*
+- * Always "return" 0 for success.
+- */
+-#define ahd_pci_set_dma_mask(dev_softc, mask) \
+-      (((dev_softc)->dma_mask = mask) && 0)
+-#endif
+ /**************************** Proc FS Support *********************************/
+-int   ahd_linux_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
+-
+-/*************************** Domain Validation ********************************/
+-#define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete)
+-#define AHD_DV_SIMQ_FROZEN(ahd)                                       \
+-      ((((ahd)->platform_data->flags & AHD_DV_ACTIVE) != 0)   \
+-       && (ahd)->platform_data->qfrozen == 1)
+-
+-/*********************** Transaction Access Wrappers **************************/
+-static __inline void ahd_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t);
+-static __inline void ahd_set_transaction_status(struct scb *, uint32_t);
+-static __inline void ahd_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t);
+-static __inline void ahd_set_scsi_status(struct scb *, uint32_t);
+-static __inline uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd);
+-static __inline uint32_t ahd_get_transaction_status(struct scb *);
+-static __inline uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd);
+-static __inline uint32_t ahd_get_scsi_status(struct scb *);
+-static __inline void ahd_set_transaction_tag(struct scb *, int, u_int);
+-static __inline u_long ahd_get_transfer_length(struct scb *);
+-static __inline int ahd_get_transfer_dir(struct scb *);
+-static __inline void ahd_set_residual(struct scb *, u_long);
+-static __inline void ahd_set_sense_residual(struct scb *scb, u_long resid);
+-static __inline u_long ahd_get_residual(struct scb *);
+-static __inline u_long ahd_get_sense_residual(struct scb *);
+-static __inline int ahd_perform_autosense(struct scb *);
+-static __inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *,
+-                                             struct scb *);
+-static __inline void ahd_notify_xfer_settings_change(struct ahd_softc *,
+-                                                   struct ahd_devinfo *);
+-static __inline void ahd_platform_scb_free(struct ahd_softc *ahd,
+-                                         struct scb *scb);
+-static __inline void ahd_freeze_scb(struct scb *scb);
+-
+-static __inline
+-void ahd_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status)
+-{
+-      cmd->result &= ~(CAM_STATUS_MASK << 16);
+-      cmd->result |= status << 16;
+-}
+-
+-static __inline
+-void ahd_set_transaction_status(struct scb *scb, uint32_t status)
+-{
+-      ahd_cmd_set_transaction_status(scb->io_ctx,status);
+-}
+-
+-static __inline
+-void ahd_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status)
+-{
+-      cmd->result &= ~0xFFFF;
+-      cmd->result |= status;
+-}
+-
+-static __inline
+-void ahd_set_scsi_status(struct scb *scb, uint32_t status)
+-{
+-      ahd_cmd_set_scsi_status(scb->io_ctx, status);
+-}
+-
+-static __inline
+-uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd)
+-{
+-      return ((cmd->result >> 16) & CAM_STATUS_MASK);
+-}
+-
+-static __inline
+-uint32_t ahd_get_transaction_status(struct scb *scb)
+-{
+-      return (ahd_cmd_get_transaction_status(scb->io_ctx));
+-}
+-
+-static __inline
+-uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd)
+-{
+-      return (cmd->result & 0xFFFF);
+-}
+-
+-static __inline
+-uint32_t ahd_get_scsi_status(struct scb *scb)
+-{
+-      return (ahd_cmd_get_scsi_status(scb->io_ctx));
+-}
+-
+-static __inline
+-void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type)
+-{
+-      /*
+-       * Nothing to do for linux as the incoming transaction
+-       * has no concept of tag/non tagged, etc.
+-       */
+-}
+-
+-static __inline
+-u_long ahd_get_transfer_length(struct scb *scb)
+-{
+-      return (scb->platform_data->xfer_len);
+-}
+-
+-static __inline
+-int ahd_get_transfer_dir(struct scb *scb)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,40)
+-      return (scb->io_ctx->sc_data_direction);
+-#else
+-      if (scb->io_ctx->bufflen == 0)
+-              return (CAM_DIR_NONE);
+-
+-      switch(scb->io_ctx->cmnd[0]) {
+-      case 0x08:  /* READ(6)  */
+-      case 0x28:  /* READ(10) */
+-      case 0xA8:  /* READ(12) */
+-              return (CAM_DIR_IN);
+-        case 0x0A:  /* WRITE(6)  */
+-        case 0x2A:  /* WRITE(10) */
+-        case 0xAA:  /* WRITE(12) */
+-              return (CAM_DIR_OUT);
+-        default:
+-              return (CAM_DIR_NONE);
+-        }
+-#endif
+-}
+-
+-static __inline
+-void ahd_set_residual(struct scb *scb, u_long resid)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      scb->io_ctx->resid = resid;
+-#else
+-      scb->platform_data->resid = resid;
+-#endif
+-}
+-
+-static __inline
+-void ahd_set_sense_residual(struct scb *scb, u_long resid)
+-{
+-      scb->platform_data->sense_resid = resid;
+-}
+-
+-static __inline
+-u_long ahd_get_residual(struct scb *scb)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      return (scb->io_ctx->resid);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++int   ahd_linux_proc_info(char *, char **, off_t, int, int, int);
+ #else
+-      return (scb->platform_data->resid);
++int   ahd_linux_proc_info(struct Scsi_Host *, char *, char **,
++                          off_t, int, int);
+ #endif
+-}
+-
+-static __inline
+-u_long ahd_get_sense_residual(struct scb *scb)
+-{
+-      return (scb->platform_data->sense_resid);
+-}
+-
+-static __inline
+-int ahd_perform_autosense(struct scb *scb)
+-{
+-      /*
+-       * We always perform autosense in Linux.
+-       * On other platforms this is set on a
+-       * per-transaction basis.
+-       */
+-      return (1);
+-}
+-
+-static __inline uint32_t
+-ahd_get_sense_bufsize(struct ahd_softc *ahd, struct scb *scb)
+-{
+-      return (sizeof(struct scsi_sense_data));
+-}
+-
+-static __inline void
+-ahd_notify_xfer_settings_change(struct ahd_softc *ahd,
+-                              struct ahd_devinfo *devinfo)
+-{
+-      /* Nothing to do here for linux */
+-}
+-
+-static __inline void
+-ahd_platform_scb_free(struct ahd_softc *ahd, struct scb *scb)
+-{
+-      ahd->flags &= ~AHD_RESOURCE_SHORTAGE;
+-}
++/*********************** Transaction Access Wrappers **************************/
+ int   ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg);
+ void  ahd_platform_free(struct ahd_softc *ahd);
+ void  ahd_platform_init(struct ahd_softc *ahd);
+ void  ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
+-void  ahd_freeze_simq(struct ahd_softc *ahd);
+-void  ahd_release_simq(struct ahd_softc *ahd);
+-
+-static __inline void
+-ahd_freeze_scb(struct scb *scb)
+-{
+-      if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
+-                scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
+-                scb->platform_data->dev->qfrozen++;
+-        }
+-}
+ void  ahd_platform_set_tags(struct ahd_softc *ahd,
+                             struct ahd_devinfo *devinfo, ahd_queue_alg);
+@@ -1221,9 +403,9 @@ void      ahd_print_path(struct ahd_softc *, 
+ void  ahd_platform_dump_card_state(struct ahd_softc *ahd);
+ #ifdef CONFIG_PCI
+-#define AHD_PCI_CONFIG 1
++#define AIC_PCI_CONFIG 1
+ #else
+-#define AHD_PCI_CONFIG 0
++#define AIC_PCI_CONFIG 0
+ #endif
+ #define bootverbose aic79xx_verbose
+ extern uint32_t aic79xx_verbose;
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx_osm_pci.c 2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx_osm_pci.c  2003-12-28 23:21:39.000000000 -0800
+@@ -36,12 +36,18 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#23 $
++ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#29 $
+  */
+ #include "aic79xx_osm.h"
+ #include "aic79xx_inline.h"
++/*
++ * Include aiclib_pci.c as part of our
++ * "module dependencies are hard" work around.
++ */
++#include "aiclib_pci.c"
++
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+ struct pci_device_id
+ {
+@@ -52,11 +58,9 @@ static int  ahd_linux_pci_dev_probe(struc
+                                       const struct pci_device_id *ent);
+ static int    ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd,
+                                                u_long *base, u_long *base2);
+-#ifdef MMAPIO
+ static int    ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
+                                                u_long *bus_addr,
+                                                uint8_t **maddr);
+-#endif
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+ static void   ahd_linux_pci_dev_remove(struct pci_dev *pdev);
+@@ -94,12 +98,14 @@ ahd_linux_pci_dev_remove(struct pci_dev 
+       if (ahd != NULL) {
+               u_long s;
++              TAILQ_REMOVE(&ahd_tailq, ahd, links);
++              ahd_list_unlock(&l);
+               ahd_lock(ahd, &s);
+               ahd_intr_enable(ahd, FALSE);
+               ahd_unlock(ahd, &s);
+               ahd_free(ahd);
+-      }
+-      ahd_list_unlock(&l);
++      } else
++              ahd_list_unlock(&l);
+ }
+ #endif /* !LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) */
+@@ -108,7 +114,7 @@ ahd_linux_pci_dev_probe(struct pci_dev *
+ {
+       char             buf[80];
+       struct           ahd_softc *ahd;
+-      ahd_dev_softc_t  pci;
++      aic_dev_softc_t  dev;
+       struct           ahd_pci_identity *entry;
+       char            *name;
+       int              error;
+@@ -119,7 +125,7 @@ ahd_linux_pci_dev_probe(struct pci_dev *
+       TAILQ_FOREACH(ahd, &ahd_tailq, links) {
+               struct pci_dev *probed_pdev;
+-              probed_pdev = ahd->dev_softc;
++              probed_pdev = aic_pci_dev(ahd);
+               if (probed_pdev->bus->number == pdev->bus->number
+                && probed_pdev->devfn == pdev->devfn)
+                       break;
+@@ -129,8 +135,8 @@ ahd_linux_pci_dev_probe(struct pci_dev *
+               return (-ENODEV);
+       }
+-      pci = pdev;
+-      entry = ahd_find_pci_device(pci);
++      dev = aic_pci_dev_to_dev(pdev);
++      entry = ahd_find_pci_device(dev);
+       if (entry == NULL)
+               return (-ENODEV);
+@@ -140,9 +146,9 @@ ahd_linux_pci_dev_probe(struct pci_dev *
+        * common detect routine.
+        */
+       sprintf(buf, "ahd_pci:%d:%d:%d",
+-              ahd_get_pci_bus(pci),
+-              ahd_get_pci_slot(pci),
+-              ahd_get_pci_function(pci));
++              aic_get_pci_bus(dev),
++              aic_get_pci_slot(dev),
++              aic_get_pci_function(dev));
+       name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+       if (name == NULL)
+               return (-ENOMEM);
+@@ -150,6 +156,7 @@ ahd_linux_pci_dev_probe(struct pci_dev *
+       ahd = ahd_alloc(NULL, name);
+       if (ahd == NULL)
+               return (-ENOMEM);
++      ahd->dev_softc = dev;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+       if (pci_enable_device(pdev)) {
+               ahd_free(ahd);
+@@ -163,23 +170,22 @@ ahd_linux_pci_dev_probe(struct pci_dev *
+               bus_addr_t mask_39bit;
+               memsize = ahd_linux_get_memsize();
+-              mask_64bit = (bus_addr_t)(0xFFFFFFFFFFFFFFFFULL&(bus_addr_t)~0);
+-              mask_39bit = (bus_addr_t)(0x7FFFFFFFFFULL&(bus_addr_t)~0);
++              mask_64bit = (bus_addr_t)0xFFFFFFFFFFFFFFFFULL;
++              mask_39bit = (bus_addr_t)0x7FFFFFFFFFULL;
+               if (memsize >= 0x8000000000ULL
+-               && ahd_pci_set_dma_mask(pdev, mask_64bit) == 0) {
++               && aic_set_dma_mask(ahd, mask_64bit) == 0) {
+                       ahd->flags |= AHD_64BIT_ADDRESSING;
+                       ahd->platform_data->hw_dma_mask = mask_64bit;
+               } else if (memsize > 0x80000000
+-                      && ahd_pci_set_dma_mask(pdev, mask_39bit) == 0) {
++                      && aic_set_dma_mask(ahd, mask_39bit) == 0) {
+                       ahd->flags |= AHD_39BIT_ADDRESSING;
+                       ahd->platform_data->hw_dma_mask = mask_39bit;
+               }
+       } else {
+-              ahd_pci_set_dma_mask(pdev, 0xFFFFFFFF);
++              aic_set_dma_mask(ahd, 0xFFFFFFFF);
+               ahd->platform_data->hw_dma_mask = 0xFFFFFFFF;
+       }
+ #endif
+-      ahd->dev_softc = pci;
+       error = ahd_pci_config(ahd, entry);
+       if (error != 0) {
+               ahd_free(ahd);
+@@ -218,10 +224,8 @@ ahd_linux_pci_init(void)
+       pdev = NULL;
+       class = PCI_CLASS_STORAGE_SCSI << 8;
+       while ((pdev = pci_find_class(class, pdev)) != NULL) {
+-              ahd_dev_softc_t pci;
+               int error;
+-              pci = pdev;
+               error = ahd_linux_pci_dev_probe(pdev, /*pci_devid*/NULL);
+               if (error == 0)
+                       found++;
+@@ -240,17 +244,18 @@ static int
+ ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base,
+                                u_long *base2)
+ {
++
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      *base = pci_resource_start(ahd->dev_softc, 0);
++      *base = pci_resource_start(aic_pci_dev(ahd), 0);
+       /*
+        * This is really the 3rd bar and should be at index 2,
+        * but the Linux PCI code doesn't know how to "count" 64bit
+        * bars.
+        */
+-      *base2 = pci_resource_start(ahd->dev_softc, 3);
++      *base2 = pci_resource_start(aic_pci_dev(ahd), 3);
+ #else
+-      *base = ahd_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR0, 4);
+-      *base2 = ahd_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR1, 4);
++      *base = aic_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR0, 4);
++      *base2 = aic_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR1, 4);
+       *base &= PCI_BASE_ADDRESS_IO_MASK;
+       *base2 &= PCI_BASE_ADDRESS_IO_MASK;
+ #endif
+@@ -273,7 +278,6 @@ ahd_linux_pci_reserve_io_regions(struct 
+       return (0);
+ }
+-#ifdef MMAPIO
+ static int
+ ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
+                                u_long *bus_addr,
+@@ -292,11 +296,11 @@ ahd_linux_pci_reserve_mem_region(struct 
+       error = 0;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      start = pci_resource_start(ahd->dev_softc, 1);
++      start = pci_resource_start(aic_pci_dev(ahd), 1);
+       base_page = start & PAGE_MASK;
+       base_offset = start - base_page;
+ #else
+-      start = ahd_pci_read_config(ahd->dev_softc, PCIR_MAPS+4, 4);
++      start = aic_pci_read_config(ahd->dev_softc, PCIR_MAPS+4, 4);
+       base_offset = start & PCI_BASE_ADDRESS_MEM_MASK;
+       base_page = base_offset & PAGE_MASK;
+       base_offset -= base_page;
+@@ -321,7 +325,6 @@ ahd_linux_pci_reserve_mem_region(struct 
+               error = ENOMEM;
+       return (error);
+ }
+-#endif
+ int
+ ahd_pci_map_registers(struct ahd_softc *ahd)
+@@ -334,11 +337,10 @@ ahd_pci_map_registers(struct ahd_softc *
+       /*
+        * If its allowed, we prefer memory mapped access.
+        */
+-      command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 4);
++      command = aic_pci_read_config(ahd->dev_softc, PCIR_COMMAND, 4);
+       command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN);
+       base = 0;
+       maddr = NULL;
+-#ifdef MMAPIO
+       error = ahd_linux_pci_reserve_mem_region(ahd, &base, &maddr);
+       if (error == 0) {
+               ahd->platform_data->mem_busaddr = base;
+@@ -346,16 +348,16 @@ ahd_pci_map_registers(struct ahd_softc *
+               ahd->bshs[0].maddr = maddr;
+               ahd->tags[1] = BUS_SPACE_MEMIO;
+               ahd->bshs[1].maddr = maddr + 0x100;
+-              ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
++              aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
+                                    command | PCIM_CMD_MEMEN, 4);
+               if (ahd_pci_test_register_access(ahd) != 0) {
+                       printf("aic79xx: PCI Device %d:%d:%d "
+                              "failed memory mapped test.  Using PIO.\n",
+-                             ahd_get_pci_bus(ahd->dev_softc),
+-                             ahd_get_pci_slot(ahd->dev_softc),
+-                             ahd_get_pci_function(ahd->dev_softc));
++                             aic_get_pci_bus(ahd->dev_softc),
++                             aic_get_pci_slot(ahd->dev_softc),
++                             aic_get_pci_function(ahd->dev_softc));
+                       iounmap((void *)((u_long)maddr & PAGE_MASK));
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+                       release_mem_region(ahd->platform_data->mem_busaddr,
+@@ -368,12 +370,11 @@ ahd_pci_map_registers(struct ahd_softc *
+       } else if (bootverbose) {
+               printf("aic79xx: PCI%d:%d:%d MEM region 0x%lx "
+                      "unavailable. Cannot memory map device.\n",
+-                     ahd_get_pci_bus(ahd->dev_softc),
+-                     ahd_get_pci_slot(ahd->dev_softc),
+-                     ahd_get_pci_function(ahd->dev_softc),
++                     aic_get_pci_bus(ahd->dev_softc),
++                     aic_get_pci_slot(ahd->dev_softc),
++                     aic_get_pci_function(ahd->dev_softc),
+                      base);
+       }
+-#endif
+       if (maddr == NULL) {
+               u_long   base2;
+@@ -388,13 +389,13 @@ ahd_pci_map_registers(struct ahd_softc *
+               } else {
+                       printf("aic79xx: PCI%d:%d:%d IO regions 0x%lx and 0x%lx"
+                              "unavailable. Cannot map device.\n",
+-                             ahd_get_pci_bus(ahd->dev_softc),
+-                             ahd_get_pci_slot(ahd->dev_softc),
+-                             ahd_get_pci_function(ahd->dev_softc),
++                             aic_get_pci_bus(ahd->dev_softc),
++                             aic_get_pci_slot(ahd->dev_softc),
++                             aic_get_pci_function(ahd->dev_softc),
+                              base, base2);
+               }
+       }
+-      ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4);
++      aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4);
+       return (error);
+ }
+@@ -403,49 +404,10 @@ ahd_pci_map_int(struct ahd_softc *ahd)
+ {
+       int error;
+-      error = request_irq(ahd->dev_softc->irq, ahd_linux_isr,
++      error = request_irq(aic_pci_dev(ahd)->irq, ahd_linux_isr,
+                           SA_SHIRQ, "aic79xx", ahd);
+       if (error == 0)
+-              ahd->platform_data->irq = ahd->dev_softc->irq;
++              ahd->platform_data->irq = aic_pci_dev(ahd)->irq;
+       
+       return (-error);
+ }
+-
+-void
+-ahd_power_state_change(struct ahd_softc *ahd, ahd_power_state new_state)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      pci_set_power_state(ahd->dev_softc, new_state);
+-#else
+-      uint32_t cap;
+-      u_int cap_offset;
+-
+-      /*
+-       * Traverse the capability list looking for
+-       * the power management capability.
+-       */
+-      cap = 0;
+-      cap_offset = ahd_pci_read_config(ahd->dev_softc,
+-                                       PCIR_CAP_PTR, /*bytes*/1);
+-      while (cap_offset != 0) {
+-
+-              cap = ahd_pci_read_config(ahd->dev_softc,
+-                                        cap_offset, /*bytes*/4);
+-              if ((cap & 0xFF) == 1
+-               && ((cap >> 16) & 0x3) > 0) {
+-                      uint32_t pm_control;
+-
+-                      pm_control = ahd_pci_read_config(ahd->dev_softc,
+-                                                       cap_offset + 4,
+-                                                       /*bytes*/4);
+-                      pm_control &= ~0x3;
+-                      pm_control |= new_state;
+-                      ahd_pci_write_config(ahd->dev_softc,
+-                                           cap_offset + 4,
+-                                           pm_control, /*bytes*/2);
+-                      break;
+-              }
+-              cap_offset = (cap >> 8) & 0xFF;
+-      }
+-#endif 
+-}
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx_pci.c     2003-06-14 12:18:09.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx_pci.c      2003-12-28 23:21:39.000000000 -0800
+@@ -38,15 +38,15 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#73 $
+- *
+- * $FreeBSD$
++ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#84 $
+  */
+ #ifdef __linux__
+ #include "aic79xx_osm.h"
+ #include "aic79xx_inline.h"
+ #else
++#include <sys/cdefs.h>
++__FBSDID("$FreeBSD$");
+ #include <dev/aic7xxx/aic79xx_osm.h>
+ #include <dev/aic7xxx/aic79xx_inline.h>
+ #endif
+@@ -75,13 +75,13 @@ ahd_compose_id(u_int device, u_int vendo
+ #define ID_AHA_29320ALP                       0x8017900500449005ull
+ #define ID_AIC7901A                   0x801E9005FFFF9005ull
+-#define ID_AHA_29320                  0x8012900500429005ull
+-#define ID_AHA_29320B                 0x8013900500439005ull
+ #define ID_AHA_29320LP                        0x8014900500449005ull
+ #define ID_AIC7902                    0x801F9005FFFF9005ull
+ #define ID_AIC7902_B                  0x801D9005FFFF9005ull
+ #define ID_AHA_39320                  0x8010900500409005ull
++#define ID_AHA_29320                  0x8012900500429005ull
++#define ID_AHA_29320B                 0x8013900500439005ull
+ #define ID_AHA_39320_B                        0x8015900500409005ull
+ #define ID_AHA_39320A                 0x8016900500409005ull
+ #define ID_AHA_39320D                 0x8011900500419005ull
+@@ -117,6 +117,7 @@ ahd_compose_id(u_int device, u_int vendo
+ static ahd_device_setup_t ahd_aic7901_setup;
+ static ahd_device_setup_t ahd_aic7901A_setup;
+ static ahd_device_setup_t ahd_aic7902_setup;
++static ahd_device_setup_t ahd_aic790X_setup;
+ struct ahd_pci_identity ahd_pci_ident_table [] =
+ {
+@@ -135,24 +136,24 @@ struct ahd_pci_identity ahd_pci_ident_ta
+       },
+       /* aic7901A based controllers */
+       {
+-              ID_AHA_29320,
++              ID_AHA_29320LP,
+               ID_ALL_MASK,
+-              "Adaptec 29320 Ultra320 SCSI adapter",
++              "Adaptec 29320LP Ultra320 SCSI adapter",
+               ahd_aic7901A_setup
+       },
++      /* aic7902 based controllers */ 
+       {
+-              ID_AHA_29320B,
++              ID_AHA_29320,
+               ID_ALL_MASK,
+-              "Adaptec 29320B Ultra320 SCSI adapter",
+-              ahd_aic7901A_setup
++              "Adaptec 29320 Ultra320 SCSI adapter",
++              ahd_aic7902_setup
+       },
+       {
+-              ID_AHA_29320LP,
++              ID_AHA_29320B,
+               ID_ALL_MASK,
+-              "Adaptec 29320LP Ultra320 SCSI adapter",
+-              ahd_aic7901A_setup
++              "Adaptec 29320B Ultra320 SCSI adapter",
++              ahd_aic7902_setup
+       },
+-      /* aic7902 based controllers */ 
+       {
+               ID_AHA_39320,
+               ID_ALL_MASK,
+@@ -195,18 +196,6 @@ struct ahd_pci_identity ahd_pci_ident_ta
+               "Adaptec (HP OEM) 39320D Ultra320 SCSI adapter",
+               ahd_aic7902_setup
+       },
+-      {
+-              ID_AHA_29320,
+-              ID_ALL_MASK,
+-              "Adaptec 29320 Ultra320 SCSI adapter",
+-              ahd_aic7902_setup
+-      },
+-      {
+-              ID_AHA_29320B,
+-              ID_ALL_MASK,
+-              "Adaptec 29320B Ultra320 SCSI adapter",
+-              ahd_aic7902_setup
+-      },
+       /* Generic chip probes for devices we don't know 'exactly' */
+       {
+               ID_AIC7901 & ID_DEV_VENDOR_MASK,
+@@ -274,7 +263,7 @@ static void        ahd_configure_termination(st
+ static void   ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
+ struct ahd_pci_identity *
+-ahd_find_pci_device(ahd_dev_softc_t pci)
++ahd_find_pci_device(aic_dev_softc_t pci)
+ {
+       uint64_t  full_id;
+       uint16_t  device;
+@@ -284,10 +273,10 @@ ahd_find_pci_device(ahd_dev_softc_t pci)
+       struct    ahd_pci_identity *entry;
+       u_int     i;
+-      vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
+-      device = ahd_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
+-      subvendor = ahd_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
+-      subdevice = ahd_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
++      vendor = aic_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
++      device = aic_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
++      subvendor = aic_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
++      subdevice = aic_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
+       full_id = ahd_compose_id(device,
+                                vendor,
+                                subdevice,
+@@ -320,7 +309,7 @@ ahd_pci_config(struct ahd_softc *ahd, st
+       /*
+        * Record if this is an HP board.
+        */
+-      subvendor = ahd_pci_read_config(ahd->dev_softc,
++      subvendor = aic_pci_read_config(ahd->dev_softc,
+                                       PCIR_SUBVEND_0, /*bytes*/2);
+       if (subvendor == SUBID_HP)
+               ahd->flags |= AHD_HP_BOARD;
+@@ -329,7 +318,7 @@ ahd_pci_config(struct ahd_softc *ahd, st
+       if (error != 0)
+               return (error);
+       
+-      devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
++      devconfig = aic_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
+       if ((devconfig & PCIXINITPAT) == PCIXINIT_PCI33_66) {
+               ahd->chip |= AHD_PCI;
+               /* Disable PCIX workarounds when running in PCI mode. */
+@@ -339,7 +328,7 @@ ahd_pci_config(struct ahd_softc *ahd, st
+       }
+       ahd->bus_description = pci_bus_modes[PCI_BUS_MODES_INDEX(devconfig)];
+-      ahd_power_state_change(ahd, AHD_POWER_STATE_D0);
++      aic_power_state_change(ahd, AIC_POWER_STATE_D0);
+       error = ahd_pci_map_registers(ahd);
+       if (error != 0)
+@@ -357,17 +346,17 @@ ahd_pci_config(struct ahd_softc *ahd, st
+               if (bootverbose)
+                       printf("%s: Enabling 39Bit Addressing\n",
+                              ahd_name(ahd));
+-              devconfig = ahd_pci_read_config(ahd->dev_softc,
++              devconfig = aic_pci_read_config(ahd->dev_softc,
+                                               DEVCONFIG, /*bytes*/4);
+               devconfig |= DACEN;
+-              ahd_pci_write_config(ahd->dev_softc, DEVCONFIG,
++              aic_pci_write_config(ahd->dev_softc, DEVCONFIG,
+                                    devconfig, /*bytes*/4);
+       }
+       
+       /* Ensure busmastering is enabled */
+-      command = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
++      command = aic_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
+       command |= PCIM_CMD_BUSMASTEREN;
+-      ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
++      aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
+       error = ahd_softc_init(ahd);
+       if (error != 0)
+@@ -375,12 +364,12 @@ ahd_pci_config(struct ahd_softc *ahd, st
+       ahd->bus_intr = ahd_pci_intr;
+-      error = ahd_reset(ahd);
++      error = ahd_reset(ahd, /*reinit*/FALSE);
+       if (error != 0)
+               return (ENXIO);
+       ahd->pci_cachesize =
+-          ahd_pci_read_config(ahd->dev_softc, CSIZE_LATTIME,
++          aic_pci_read_config(ahd->dev_softc, CSIZE_LATTIME,
+                               /*bytes*/1) & CACHESIZE;
+       ahd->pci_cachesize *= 4;
+@@ -418,9 +407,11 @@ ahd_pci_config(struct ahd_softc *ahd, st
+ int
+ ahd_pci_test_register_access(struct ahd_softc *ahd)
+ {
+-      uint32_t        cmd;
+-      int             error;
+-      uint8_t         hcntrl;
++      uint32_t cmd;
++      u_int    targpcistat;
++      u_int    pci_status1;
++      int      error;
++      uint8_t  hcntrl;
+       error = EIO;
+@@ -428,8 +419,8 @@ ahd_pci_test_register_access(struct ahd_
+        * Enable PCI error interrupt status, but suppress NMIs
+        * generated by SERR raised due to target aborts.
+        */
+-      cmd = ahd_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
+-      ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
++      cmd = aic_pci_read_config(ahd->dev_softc, PCIR_COMMAND, /*bytes*/2);
++      aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND,
+                            cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
+       /*
+@@ -449,11 +440,25 @@ ahd_pci_test_register_access(struct ahd_
+        * or read prefetching could be initiated by the
+        * CPU or host bridge.  Our device does not support
+        * either, so look for data corruption and/or flaged
+-       * PCI errors.
++       * PCI errors.  First pause without causing another
++       * chip reset.
+        */
++      hcntrl &= ~CHIPRST;
+       ahd_outb(ahd, HCNTRL, hcntrl|PAUSE);
+       while (ahd_is_paused(ahd) == 0)
+               ;
++
++      /* Clear any PCI errors that occurred before our driver attached. */
++      ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
++      targpcistat = ahd_inb(ahd, TARGPCISTAT);
++      ahd_outb(ahd, TARGPCISTAT, targpcistat);
++      pci_status1 = aic_pci_read_config(ahd->dev_softc,
++                                        PCIR_STATUS + 1, /*bytes*/1);
++      aic_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
++                           pci_status1, /*bytes*/1);
++      ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
++      ahd_outb(ahd, CLRINT, CLRPCIINT);
++
+       ahd_outb(ahd, SEQCTL0, PERRORDIS);
+       ahd_outl(ahd, SRAM_BASE, 0x5aa555aa);
+       if (ahd_inl(ahd, SRAM_BASE) != 0x5aa555aa)
+@@ -472,23 +477,20 @@ ahd_pci_test_register_access(struct ahd_
+ fail:
+       if ((ahd_inb(ahd, INTSTAT) & PCIINT) != 0) {
+-              u_int targpcistat;
+-              u_int pci_status1;
+               ahd_set_modes(ahd, AHD_MODE_CFG, AHD_MODE_CFG);
+               targpcistat = ahd_inb(ahd, TARGPCISTAT);
+               /* Silently clear any latched errors. */
+               ahd_outb(ahd, TARGPCISTAT, targpcistat);
+-              pci_status1 = ahd_pci_read_config(ahd->dev_softc,
++              pci_status1 = aic_pci_read_config(ahd->dev_softc,
+                                                 PCIR_STATUS + 1, /*bytes*/1);
+-              ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
++              aic_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
+                                    pci_status1, /*bytes*/1);
+               ahd_outb(ahd, CLRINT, CLRPCIINT);
+       }
+-
+       ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS);
+-      ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
++      aic_pci_write_config(ahd->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
+       return (error);
+ }
+@@ -637,14 +639,14 @@ ahd_configure_termination(struct ahd_sof
+       uint8_t  termctl;
+       uint32_t devconfig;
+-      devconfig = ahd_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
++      devconfig = aic_pci_read_config(ahd->dev_softc, DEVCONFIG, /*bytes*/4);
+       devconfig &= ~STPWLEVEL;
+       if ((ahd->flags & AHD_STPWLEVEL_A) != 0)
+               devconfig |= STPWLEVEL;
+       if (bootverbose)
+               printf("%s: STPWLEVEL is %s\n",
+                      ahd_name(ahd), (devconfig & STPWLEVEL) ? "on" : "off");
+-      ahd_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
++      aic_pci_write_config(ahd->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
+  
+       /* Make sure current sensing is off. */
+       if ((ahd->flags & AHD_CURRENT_SENSING) != 0) {
+@@ -689,6 +691,7 @@ ahd_configure_termination(struct ahd_sof
+        * Now set the termination based on what we found.
+        */
+       sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
++      ahd->flags &= ~AHD_TERM_ENB_A;
+       if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
+               ahd->flags |= AHD_TERM_ENB_A;
+               sxfrctl1 |= STPWEN;
+@@ -821,9 +824,9 @@ ahd_pci_intr(struct ahd_softc *ahd)
+                       }
+               }       
+       }
+-      pci_status1 = ahd_pci_read_config(ahd->dev_softc,
++      pci_status1 = aic_pci_read_config(ahd->dev_softc,
+                                         PCIR_STATUS + 1, /*bytes*/1);
+-      ahd_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
++      aic_pci_write_config(ahd->dev_softc, PCIR_STATUS + 1,
+                            pci_status1, /*bytes*/1);
+       ahd_restore_modes(ahd, saved_modes);
+       ahd_outb(ahd, CLRINT, CLRPCIINT);
+@@ -845,7 +848,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd
+        * Check for splits in all modes.  Modes 0 and 1
+        * additionally have SG engine splits to look at.
+        */
+-      pcix_status = ahd_pci_read_config(ahd->dev_softc, PCIXR_STATUS,
++      pcix_status = aic_pci_read_config(ahd->dev_softc, PCIXR_STATUS,
+                                         /*bytes*/2);
+       printf("%s: PCI Split Interrupt - PCI-X status = 0x%x\n",
+              ahd_name(ahd), pcix_status);
+@@ -894,7 +897,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd
+       /*
+        * Clear PCI-X status bits.
+        */
+-      ahd_pci_write_config(ahd->dev_softc, PCIXR_STATUS,
++      aic_pci_write_config(ahd->dev_softc, PCIXR_STATUS,
+                            pcix_status, /*bytes*/2);
+       ahd_outb(ahd, CLRINT, CLRSPLTINT);
+       ahd_restore_modes(ahd, saved_modes);
+@@ -903,44 +906,44 @@ ahd_pci_split_intr(struct ahd_softc *ahd
+ static int
+ ahd_aic7901_setup(struct ahd_softc *ahd)
+ {
+-      int error;
+-      error = ahd_aic7902_setup(ahd);
+-      if (error != 0)
+-              return (error);
+       ahd->chip = AHD_AIC7901;
+-      return (0);
++      ahd->features = AHD_AIC7901_FE;
++      return (ahd_aic790X_setup(ahd));
+ }
+ static int
+ ahd_aic7901A_setup(struct ahd_softc *ahd)
+ {
+-      int error;
+-      error = ahd_aic7902_setup(ahd);
+-      if (error != 0)
+-              return (error);
+       ahd->chip = AHD_AIC7901A;
+-      return (0);
++      ahd->features = AHD_AIC7901A_FE;
++      return (ahd_aic790X_setup(ahd));
+ }
+ static int
+ ahd_aic7902_setup(struct ahd_softc *ahd)
+ {
+-      ahd_dev_softc_t pci;
++      ahd->chip = AHD_AIC7902;
++      ahd->features = AHD_AIC7902_FE;
++      return (ahd_aic790X_setup(ahd));
++}
++
++static int
++ahd_aic790X_setup(struct ahd_softc *ahd)
++{
++      aic_dev_softc_t pci;
+       u_int rev;
+       pci = ahd->dev_softc;
+-      rev = ahd_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
++      rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
+       if (rev < ID_AIC7902_PCI_REV_A4) {
+               printf("%s: Unable to attach to unsupported chip revision %d\n",
+                      ahd_name(ahd), rev);
+-              ahd_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
++              aic_pci_write_config(pci, PCIR_COMMAND, 0, /*bytes*/2);
+               return (ENXIO);
+       }
+-      ahd->channel = ahd_get_pci_function(pci) + 'A';
+-      ahd->chip = AHD_AIC7902;
+-      ahd->features = AHD_AIC7902_FE;
++      ahd->channel = aic_get_pci_function(pci) + 'A';
+       if (rev < ID_AIC7902_PCI_REV_B0) {
+               /*
+                * Enable A series workarounds.
+@@ -968,9 +971,14 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
+               u_int devconfig1;
+               ahd->features |= AHD_RTI|AHD_NEW_IOCELL_OPTS
+-                            |  AHD_NEW_DFCNTRL_OPTS;
+-              ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_ABORT_LQI_BUG
+-                        |  AHD_INTCOLLISION_BUG|AHD_EARLY_REQ_BUG;
++                            |  AHD_NEW_DFCNTRL_OPTS|AHD_FAST_CDB_DELIVERY;
++              ahd->bugs |= AHD_LQOOVERRUN_BUG|AHD_EARLY_REQ_BUG;
++
++              /*
++               * Some issues have been resolved in the 7901B.
++               */
++              if ((ahd->features & AHD_MULTI_FUNC) != 0)
++                      ahd->bugs |= AHD_INTCOLLISION_BUG|AHD_ABORT_LQI_BUG;
+               /*
+                * IO Cell paramter setup.
+@@ -985,10 +993,10 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
+                * XXX - Find out exactly what this does from the hardware
+                *       folks!
+                */
+-              devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
+-              ahd_pci_write_config(pci, DEVCONFIG1,
++              devconfig1 = aic_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
++              aic_pci_write_config(pci, DEVCONFIG1,
+                                    devconfig1|PREQDIS, /*bytes*/1);
+-              devconfig1 = ahd_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
++              devconfig1 = aic_pci_read_config(pci, DEVCONFIG1, /*bytes*/1);
+       }
+       return (0);
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx_proc.c    2003-06-14 12:18:29.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx_proc.c     2003-12-28 23:21:39.000000000 -0800
+@@ -37,7 +37,7 @@
+  * String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
+  * sym driver.
+  *
+- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#17 $
++ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#20 $
+  */
+ #include "aic79xx_osm.h"
+ #include "aic79xx_inline.h"
+@@ -49,7 +49,7 @@ static void  ahd_dump_target_state(struct
+                                     u_int our_id, char channel,
+                                     u_int target_id, u_int target_offset);
+ static void   ahd_dump_device_state(struct info_str *info,
+-                                    struct ahd_linux_device *dev);
++                                    struct aic_linux_device *dev);
+ static int    ahd_proc_write_seeprom(struct ahd_softc *ahd,
+                                      char *buffer, int length);
+@@ -166,7 +166,7 @@ ahd_dump_target_state(struct ahd_softc *
+                     u_int our_id, char channel, u_int target_id,
+                     u_int target_offset)
+ {
+-      struct  ahd_linux_target *targ;
++      struct  aic_linux_target *targ;
+       struct  ahd_initiator_tinfo *tinfo;
+       struct  ahd_tmode_tstate *tstate;
+       int     lun;
+@@ -187,7 +187,7 @@ ahd_dump_target_state(struct ahd_softc *
+       copy_info(info, "\tTransmission Errors %ld\n", targ->errors_detected);
+       for (lun = 0; lun < AHD_NUM_LUNS; lun++) {
+-              struct ahd_linux_device *dev;
++              struct aic_linux_device *dev;
+               dev = targ->devices[lun];
+@@ -199,7 +199,7 @@ ahd_dump_target_state(struct ahd_softc *
+ }
+ static void
+-ahd_dump_device_state(struct info_str *info, struct ahd_linux_device *dev)
++ahd_dump_device_state(struct info_str *info, struct aic_linux_device *dev)
+ {
+       copy_info(info, "\tChannel %c Target %d Lun %d Settings\n",
+                 dev->target->channel + 'A', dev->target->target, dev->lun);
+@@ -278,8 +278,13 @@ done:
+  * Return information to handle /proc support for the driver.
+  */
+ int
+-ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset,
+-                int length, int inout)
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ahd_linux_proc_info(char *buffer, char **start, off_t offset,
++                  int length, int hostno, int inout)
++#else
++ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
++                  off_t offset, int length, int inout)
++#endif
+ {
+       struct  ahd_softc *ahd;
+       struct  info_str info;
+@@ -291,10 +296,14 @@ ahd_linux_proc_info(struct Scsi_Host *sh
+       retval = -EINVAL;
+       ahd_list_lock(&l);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+       TAILQ_FOREACH(ahd, &ahd_tailq, links) {
+-              if (ahd->platform_data->host == shost)
++              if (ahd->platform_data->host->host_no == hostno)
+                       break;
+       }
++#else
++      ahd = ahd_find_softc(*(struct ahd_softc **)shost->hostdata);
++#endif
+       if (ahd == NULL)
+               goto done;
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx.reg       2003-06-14 12:18:34.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx.reg        2003-12-28 23:21:39.000000000 -0800
+@@ -39,7 +39,7 @@
+  *
+  * $FreeBSD$
+  */
+-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $"
++VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $"
+ /*
+  * This file is processed by the aic7xxx_asm utility for use in assembling
+@@ -1377,7 +1377,10 @@ register LUNLEN {
+       address                 0x030
+       access_mode     RW
+       modes           M_CFG
++      mask            ILUNLEN 0x0F
++      mask            TLUNLEN 0xF0
+ }
++const LUNLEN_SINGLE_LEVEL_LUN 0xF
+ /*
+  * CDB Limit
+@@ -3797,32 +3800,8 @@ scb {
+               size    4
+               alias   SCB_NEXT_COMPLETE
+       }
+-      SCB_DATAPTR {
+-              size    8
+-      }
+-      SCB_DATACNT {
+-              /*
+-               * The last byte is really the high address bits for
+-               * the data address.
+-               */
+-              size    4
+-              field   SG_LAST_SEG             0x80    /* In the fourth byte */
+-              field   SG_HIGH_ADDR_BITS       0x7F    /* In the fourth byte */
+-      }
+-      SCB_SGPTR {
+-              size    4
+-              field   SG_STATUS_VALID 0x04    /* In the first byte */
+-              field   SG_FULL_RESID   0x02    /* In the first byte */
+-              field   SG_LIST_NULL    0x01    /* In the first byte */
+-      }
+-      SCB_BUSADDR {
+-              size    4
+-      }
+-      SCB_NEXT {
+-              alias   SCB_NEXT_SCB_BUSADDR
+-              size    2
+-      }
+-      SCB_NEXT2 {
++      SCB_TAG {
++              alias   SCB_FIFO_USE_COUNT
+               size    2
+       }
+       SCB_CONTROL {
+@@ -3859,8 +3838,32 @@ scb {
+       SCB_TASK_MANAGEMENT {
+               size    1
+       }
+-      SCB_TAG {
+-              alias   SCB_FIFO_USE_COUNT
++      SCB_DATAPTR {
++              size    8
++      }
++      SCB_DATACNT {
++              /*
++               * The last byte is really the high address bits for
++               * the data address.
++               */
++              size    4
++              field   SG_LAST_SEG             0x80    /* In the fourth byte */
++              field   SG_HIGH_ADDR_BITS       0x7F    /* In the fourth byte */
++      }
++      SCB_SGPTR {
++              size    4
++              field   SG_STATUS_VALID 0x04    /* In the first byte */
++              field   SG_FULL_RESID   0x02    /* In the first byte */
++              field   SG_LIST_NULL    0x01    /* In the first byte */
++      }
++      SCB_BUSADDR {
++              size    4
++      }
++      SCB_NEXT {
++              alias   SCB_NEXT_SCB_BUSADDR
++              size    2
++      }
++      SCB_NEXT2 {
+               size    2
+       }
+       SCB_SPARE {
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped     2003-06-14 12:18:51.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped      2003-12-28 23:21:39.000000000 -0800
+@@ -2,8 +2,8 @@
+  * DO NOT EDIT - This file is automatically generated
+  *             from the following source files:
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
+- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#107 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
+  */
+ typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
+ typedef struct ahd_reg_parse_entry {
+@@ -2239,94 +2239,94 @@ ahd_reg_print_t ahd_scb_sense_busaddr_pr
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_dataptr_print;
++ahd_reg_print_t ahd_scb_tag_print;
+ #else
+-#define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x190, regvalue, cur_col, wrap)
++#define ahd_scb_tag_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_TAG", 0x190, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_datacnt_print;
++ahd_reg_print_t ahd_scb_control_print;
+ #else
+-#define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_DATACNT", 0x198, regvalue, cur_col, wrap)
++#define ahd_scb_control_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_CONTROL", 0x192, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_sgptr_print;
++ahd_reg_print_t ahd_scb_scsiid_print;
+ #else
+-#define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_SGPTR", 0x19c, regvalue, cur_col, wrap)
++#define ahd_scb_scsiid_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_SCSIID", 0x193, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_busaddr_print;
++ahd_reg_print_t ahd_scb_lun_print;
+ #else
+-#define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1a0, regvalue, cur_col, wrap)
++#define ahd_scb_lun_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_LUN", 0x194, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_next_print;
++ahd_reg_print_t ahd_scb_task_attribute_print;
+ #else
+-#define ahd_scb_next_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_NEXT", 0x1a4, regvalue, cur_col, wrap)
++#define ahd_scb_task_attribute_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", 0x195, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_next2_print;
++ahd_reg_print_t ahd_scb_cdb_len_print;
+ #else
+-#define ahd_scb_next2_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_NEXT2", 0x1a6, regvalue, cur_col, wrap)
++#define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x196, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_control_print;
++ahd_reg_print_t ahd_scb_task_management_print;
+ #else
+-#define ahd_scb_control_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_CONTROL", 0x1a8, regvalue, cur_col, wrap)
++#define ahd_scb_task_management_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x197, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_scsiid_print;
++ahd_reg_print_t ahd_scb_dataptr_print;
+ #else
+-#define ahd_scb_scsiid_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_SCSIID", 0x1a9, regvalue, cur_col, wrap)
++#define ahd_scb_dataptr_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_DATAPTR", 0x198, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_lun_print;
++ahd_reg_print_t ahd_scb_datacnt_print;
+ #else
+-#define ahd_scb_lun_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_LUN", 0x1aa, regvalue, cur_col, wrap)
++#define ahd_scb_datacnt_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_DATACNT", 0x1a0, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_task_attribute_print;
++ahd_reg_print_t ahd_scb_sgptr_print;
+ #else
+-#define ahd_scb_task_attribute_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE", 0x1ab, regvalue, cur_col, wrap)
++#define ahd_scb_sgptr_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_SGPTR", 0x1a4, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_cdb_len_print;
++ahd_reg_print_t ahd_scb_busaddr_print;
+ #else
+-#define ahd_scb_cdb_len_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_CDB_LEN", 0x1ac, regvalue, cur_col, wrap)
++#define ahd_scb_busaddr_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_BUSADDR", 0x1a8, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_task_management_print;
++ahd_reg_print_t ahd_scb_next_print;
+ #else
+-#define ahd_scb_task_management_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT", 0x1ad, regvalue, cur_col, wrap)
++#define ahd_scb_next_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_NEXT", 0x1ac, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+-ahd_reg_print_t ahd_scb_tag_print;
++ahd_reg_print_t ahd_scb_next2_print;
+ #else
+-#define ahd_scb_tag_print(regvalue, cur_col, wrap) \
+-    ahd_print_register(NULL, 0, "SCB_TAG", 0x1ae, regvalue, cur_col, wrap)
++#define ahd_scb_next2_print(regvalue, cur_col, wrap) \
++    ahd_print_register(NULL, 0, "SCB_NEXT2", 0x1ae, regvalue, cur_col, wrap)
+ #endif
+ #if AIC_DEBUG_REGISTERS
+@@ -2557,6 +2557,8 @@ ahd_reg_print_t ahd_scb_disconnected_lis
+ #define       SHORTTHRESH                     0x2f
+ #define       LUNLEN                          0x30
++#define               TLUNLEN                 0xf0
++#define               ILUNLEN                 0x0f
+ #define       CDBLIMIT                        0x31
+@@ -3648,25 +3650,10 @@ ahd_reg_print_t ahd_scb_disconnected_lis
+ #define       SCB_SENSE_BUSADDR               0x18c
+ #define       SCB_NEXT_COMPLETE               0x18c
+-#define       SCB_DATAPTR                     0x190
+-
+-#define       SCB_DATACNT                     0x198
+-#define               SG_LAST_SEG             0x80
+-#define               SG_HIGH_ADDR_BITS       0x7f
+-
+-#define       SCB_SGPTR                       0x19c
+-#define               SG_STATUS_VALID         0x04
+-#define               SG_FULL_RESID           0x02
+-#define               SG_LIST_NULL            0x01
++#define       SCB_TAG                         0x190
++#define       SCB_FIFO_USE_COUNT              0x190
+-#define       SCB_BUSADDR                     0x1a0
+-
+-#define       SCB_NEXT                        0x1a4
+-#define       SCB_NEXT_SCB_BUSADDR            0x1a4
+-
+-#define       SCB_NEXT2                       0x1a6
+-
+-#define       SCB_CONTROL                     0x1a8
++#define       SCB_CONTROL                     0x192
+ #define               TARGET_SCB              0x80
+ #define               DISCENB                 0x40
+ #define               TAG_ENB                 0x20
+@@ -3675,23 +3662,38 @@ ahd_reg_print_t ahd_scb_disconnected_lis
+ #define               DISCONNECTED            0x04
+ #define               SCB_TAG_TYPE            0x03
+-#define       SCB_SCSIID                      0x1a9
++#define       SCB_SCSIID                      0x193
+ #define               TID                     0xf0
+ #define               OID                     0x0f
+-#define       SCB_LUN                         0x1aa
++#define       SCB_LUN                         0x194
+ #define               LID                     0xff
+-#define       SCB_TASK_ATTRIBUTE              0x1ab
++#define       SCB_TASK_ATTRIBUTE              0x195
+ #define               SCB_XFERLEN_ODD         0x01
+-#define       SCB_CDB_LEN                     0x1ac
++#define       SCB_CDB_LEN                     0x196
+ #define               SCB_CDB_LEN_PTR         0x80
+-#define       SCB_TASK_MANAGEMENT             0x1ad
++#define       SCB_TASK_MANAGEMENT             0x197
++
++#define       SCB_DATAPTR                     0x198
++
++#define       SCB_DATACNT                     0x1a0
++#define               SG_LAST_SEG             0x80
++#define               SG_HIGH_ADDR_BITS       0x7f
++
++#define       SCB_SGPTR                       0x1a4
++#define               SG_STATUS_VALID         0x04
++#define               SG_FULL_RESID           0x02
++#define               SG_LIST_NULL            0x01
++
++#define       SCB_BUSADDR                     0x1a8
++
++#define       SCB_NEXT                        0x1ac
++#define       SCB_NEXT_SCB_BUSADDR            0x1ac
+-#define       SCB_TAG                         0x1ae
+-#define       SCB_FIFO_USE_COUNT              0x1ae
++#define       SCB_NEXT2                       0x1ae
+ #define       SCB_SPARE                       0x1b0
+ #define       SCB_PKT_LUN                     0x1b0
+@@ -3720,6 +3722,7 @@ ahd_reg_print_t ahd_scb_disconnected_lis
+ #define       AHD_PRECOMP_CUTBACK_29  0x06
+ #define       AHD_NUM_PER_DEV_ANNEXCOLS       0x04
+ #define       B_CURRFIFO_0    0x02
++#define       LUNLEN_SINGLE_LEVEL_LUN 0x0f
+ #define       NVRAM_SCB_OFFSET        0x2c
+ #define       AHD_TIMER_MAX_US        0x18ffe7
+ #define       AHD_TIMER_MAX_TICKS     0xffff
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped       2003-06-14 12:17:56.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped        2003-12-28 23:21:39.000000000 -0800
+@@ -2,8 +2,8 @@
+  * DO NOT EDIT - This file is automatically generated
+  *             from the following source files:
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#93 $
+- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#68 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#107 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
+  */
+ #include "aic79xx_osm.h"
+@@ -489,10 +489,15 @@ ahd_shortthresh_print(u_int regvalue, u_
+           0x2f, regvalue, cur_col, wrap));
+ }
++static ahd_reg_parse_entry_t LUNLEN_parse_table[] = {
++      { "ILUNLEN",            0x0f, 0x0f },
++      { "TLUNLEN",            0xf0, 0xf0 }
++};
++
+ int
+ ahd_lunlen_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+-      return (ahd_print_register(NULL, 0, "LUNLEN",
++      return (ahd_print_register(LUNLEN_parse_table, 2, "LUNLEN",
+           0x30, regvalue, cur_col, wrap));
+ }
+@@ -3486,58 +3491,12 @@ ahd_scb_sense_busaddr_print(u_int regval
+ }
+ int
+-ahd_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
++ahd_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+-      return (ahd_print_register(NULL, 0, "SCB_DATAPTR",
++      return (ahd_print_register(NULL, 0, "SCB_TAG",
+           0x190, regvalue, cur_col, wrap));
+ }
+-static ahd_reg_parse_entry_t SCB_DATACNT_parse_table[] = {
+-      { "SG_HIGH_ADDR_BITS",  0x7f, 0x7f },
+-      { "SG_LAST_SEG",        0x80, 0x80 }
+-};
+-
+-int
+-ahd_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
+-{
+-      return (ahd_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT",
+-          0x198, regvalue, cur_col, wrap));
+-}
+-
+-static ahd_reg_parse_entry_t SCB_SGPTR_parse_table[] = {
+-      { "SG_LIST_NULL",       0x01, 0x01 },
+-      { "SG_FULL_RESID",      0x02, 0x02 },
+-      { "SG_STATUS_VALID",    0x04, 0x04 }
+-};
+-
+-int
+-ahd_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
+-{
+-      return (ahd_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR",
+-          0x19c, regvalue, cur_col, wrap));
+-}
+-
+-int
+-ahd_scb_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
+-{
+-      return (ahd_print_register(NULL, 0, "SCB_BUSADDR",
+-          0x1a0, regvalue, cur_col, wrap));
+-}
+-
+-int
+-ahd_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap)
+-{
+-      return (ahd_print_register(NULL, 0, "SCB_NEXT",
+-          0x1a4, regvalue, cur_col, wrap));
+-}
+-
+-int
+-ahd_scb_next2_print(u_int regvalue, u_int *cur_col, u_int wrap)
+-{
+-      return (ahd_print_register(NULL, 0, "SCB_NEXT2",
+-          0x1a6, regvalue, cur_col, wrap));
+-}
+-
+ static ahd_reg_parse_entry_t SCB_CONTROL_parse_table[] = {
+       { "SCB_TAG_TYPE",       0x03, 0x03 },
+       { "DISCONNECTED",       0x04, 0x04 },
+@@ -3552,7 +3511,7 @@ int
+ ahd_scb_control_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+       return (ahd_print_register(SCB_CONTROL_parse_table, 7, "SCB_CONTROL",
+-          0x1a8, regvalue, cur_col, wrap));
++          0x192, regvalue, cur_col, wrap));
+ }
+ static ahd_reg_parse_entry_t SCB_SCSIID_parse_table[] = {
+@@ -3564,7 +3523,7 @@ int
+ ahd_scb_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+       return (ahd_print_register(SCB_SCSIID_parse_table, 2, "SCB_SCSIID",
+-          0x1a9, regvalue, cur_col, wrap));
++          0x193, regvalue, cur_col, wrap));
+ }
+ static ahd_reg_parse_entry_t SCB_LUN_parse_table[] = {
+@@ -3575,14 +3534,18 @@ int
+ ahd_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+       return (ahd_print_register(SCB_LUN_parse_table, 1, "SCB_LUN",
+-          0x1aa, regvalue, cur_col, wrap));
++          0x194, regvalue, cur_col, wrap));
+ }
++static ahd_reg_parse_entry_t SCB_TASK_ATTRIBUTE_parse_table[] = {
++      { "SCB_XFERLEN_ODD",    0x01, 0x01 }
++};
++
+ int
+ ahd_scb_task_attribute_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+-      return (ahd_print_register(NULL, 0, "SCB_TASK_ATTRIBUTE",
+-          0x1ab, regvalue, cur_col, wrap));
++      return (ahd_print_register(SCB_TASK_ATTRIBUTE_parse_table, 1, "SCB_TASK_ATTRIBUTE",
++          0x195, regvalue, cur_col, wrap));
+ }
+ static ahd_reg_parse_entry_t SCB_CDB_LEN_parse_table[] = {
+@@ -3593,20 +3556,66 @@ int
+ ahd_scb_cdb_len_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+       return (ahd_print_register(SCB_CDB_LEN_parse_table, 1, "SCB_CDB_LEN",
+-          0x1ac, regvalue, cur_col, wrap));
++          0x196, regvalue, cur_col, wrap));
+ }
+ int
+ ahd_scb_task_management_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+       return (ahd_print_register(NULL, 0, "SCB_TASK_MANAGEMENT",
+-          0x1ad, regvalue, cur_col, wrap));
++          0x197, regvalue, cur_col, wrap));
+ }
+ int
+-ahd_scb_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
++ahd_scb_dataptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+-      return (ahd_print_register(NULL, 0, "SCB_TAG",
++      return (ahd_print_register(NULL, 0, "SCB_DATAPTR",
++          0x198, regvalue, cur_col, wrap));
++}
++
++static ahd_reg_parse_entry_t SCB_DATACNT_parse_table[] = {
++      { "SG_HIGH_ADDR_BITS",  0x7f, 0x7f },
++      { "SG_LAST_SEG",        0x80, 0x80 }
++};
++
++int
++ahd_scb_datacnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
++{
++      return (ahd_print_register(SCB_DATACNT_parse_table, 2, "SCB_DATACNT",
++          0x1a0, regvalue, cur_col, wrap));
++}
++
++static ahd_reg_parse_entry_t SCB_SGPTR_parse_table[] = {
++      { "SG_LIST_NULL",       0x01, 0x01 },
++      { "SG_FULL_RESID",      0x02, 0x02 },
++      { "SG_STATUS_VALID",    0x04, 0x04 }
++};
++
++int
++ahd_scb_sgptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
++{
++      return (ahd_print_register(SCB_SGPTR_parse_table, 3, "SCB_SGPTR",
++          0x1a4, regvalue, cur_col, wrap));
++}
++
++int
++ahd_scb_busaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
++{
++      return (ahd_print_register(NULL, 0, "SCB_BUSADDR",
++          0x1a8, regvalue, cur_col, wrap));
++}
++
++int
++ahd_scb_next_print(u_int regvalue, u_int *cur_col, u_int wrap)
++{
++      return (ahd_print_register(NULL, 0, "SCB_NEXT",
++          0x1ac, regvalue, cur_col, wrap));
++}
++
++int
++ahd_scb_next2_print(u_int regvalue, u_int *cur_col, u_int wrap)
++{
++      return (ahd_print_register(NULL, 0, "SCB_NEXT2",
+           0x1ae, regvalue, cur_col, wrap));
+ }
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx.seq       2003-06-14 12:18:30.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx.seq        2003-12-28 23:21:39.000000000 -0800
+@@ -40,7 +40,7 @@
+  * $FreeBSD$
+  */
+-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $"
++VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#107 $"
+ PATCH_ARG_LIST = "struct ahd_softc *ahd"
+ PREFIX = "ahd_"
+@@ -90,6 +90,13 @@ idle_loop_check_nonpackreq:
+       test    SSTAT2, NONPACKREQ jz . + 2;
+       call    unexpected_nonpkt_phase_find_ctxt;
+       if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {
++              /*
++               * On Rev A. hardware, the busy LED is only
++               * turned on automaically during selections
++               * and re-selections.  Make the LED status
++               * more useful by forcing it to be on so
++               * long as one of our data FIFOs is active.
++               */
+               and     A, FIFO0FREE|FIFO1FREE, DFFSTAT;
+               cmp     A, FIFO0FREE|FIFO1FREE jne . + 3;
+               and     SBLKCTL, ~DIAGLEDEN|DIAGLEDON;
+@@ -101,9 +108,9 @@ idle_loop_check_nonpackreq:
+       call    idle_loop_cchan;
+       jmp     idle_loop;
+-BEGIN_CRITICAL;
+ idle_loop_gsfifo:
+       SET_MODE(M_SCSI, M_SCSI)
++BEGIN_CRITICAL;
+ idle_loop_gsfifo_in_scsi_mode:
+       test    LQISTAT2, LQIGSAVAIL jz return;
+       /*
+@@ -152,25 +159,28 @@ END_CRITICAL;
+ idle_loop_service_fifos:
+       SET_MODE(M_DFF0, M_DFF0)
++BEGIN_CRITICAL;
+       test    LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo;
+       call    longjmp;
++END_CRITICAL;
+ idle_loop_next_fifo:
+       SET_MODE(M_DFF1, M_DFF1)
++BEGIN_CRITICAL;
+       test    LONGJMP_ADDR[1], INVALID_ADDR jz longjmp;
++END_CRITICAL;
+ return:
+       ret;
+ idle_loop_cchan:
+       SET_MODE(M_CCHAN, M_CCHAN)
+       test    QOFF_CTLSTA, HS_MAILBOX_ACT jz  hs_mailbox_empty;
+-      mov     LOCAL_HS_MAILBOX, HS_MAILBOX;
+       or      QOFF_CTLSTA, HS_MAILBOX_ACT;
++      mov     LOCAL_HS_MAILBOX, HS_MAILBOX;
+ hs_mailbox_empty:
+ BEGIN_CRITICAL;
+       test    CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle;
+       test    CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog;
+       test    CCSCBCTL, CCSCBDONE jz return;
+-END_CRITICAL;
+       /* FALLTHROUGH */
+ scbdma_tohost_done:
+       test    CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone;
+@@ -180,26 +190,18 @@ scbdma_tohost_done:
+        * bad SCSI status (currently only for underruns), we
+        * queue the SCB for normal completion.  Otherwise, we
+        * wait until any select-out activity has halted, and
+-       * then notify the host so that the transaction can be
+-       * dealt with.
++       * then queue the completion.
+        */
+-      test    SCB_SCSI_STATUS, 0xff jnz scbdma_notify_host;
+-      and     CCSCBCTL, ~(CCARREN|CCSCBEN);
+-      bmov    COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;
+-      bmov    SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;
+-      bmov    COMPLETE_SCB_HEAD, SCBPTR, 2 ret;
+-scbdma_notify_host:
++      test    SCB_SCSI_STATUS, 0xff jz scbdma_queue_completion;
+       SET_MODE(M_SCSI, M_SCSI)
+       test    SCSISEQ0, ENSELO jnz return;
+       test    SSTAT0, (SELDO|SELINGO) jnz return;
+       SET_MODE(M_CCHAN, M_CCHAN)
+-      /*
+-       * Remove SCB and notify host.
+-       */
++scbdma_queue_completion:
+       and     CCSCBCTL, ~(CCARREN|CCSCBEN);
+       bmov    COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;
+-      SET_SEQINTCODE(BAD_SCB_STATUS)
+-      ret;
++      bmov    SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;
++      bmov    COMPLETE_SCB_HEAD, SCBPTR, 2 ret;
+ fill_qoutfifo_dmadone:
+       and     CCSCBCTL, ~(CCARREN|CCSCBEN);
+       call    qoutfifo_updated;
+@@ -208,6 +210,7 @@ fill_qoutfifo_dmadone:
+       test    QOFF_CTLSTA, SDSCB_ROLLOVR jz return;
+       bmov    QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4;
+       xor     QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID_TOGGLE ret;
++END_CRITICAL;
+ qoutfifo_updated:
+       /*
+@@ -276,7 +279,7 @@ fetch_new_scb_done:
+        * knows the correct location to store the SCB.
+        * Set it to zero before processing the SCB.
+        */
+-      mov     SCB_FIFO_USE_COUNT, ALLZEROS;
++      clr     SCB_FIFO_USE_COUNT;
+       /* Update the next SCB address to download. */
+       bmov    NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4;
+       mvi     SCB_NEXT[1], SCB_LIST_NULL;
+@@ -490,14 +493,30 @@ allocate_fifo1:
+ SET_SRC_MODE  M_SCSI;
+ SET_DST_MODE  M_SCSI;
+ select_in:
++      if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {
++              /*
++               * On Rev A. hardware, the busy LED is only
++               * turned on automaically during selections
++               * and re-selections.  Make the LED status
++               * more useful by forcing it to be on from
++               * the point of selection until our idle
++               * loop determines that neither of our FIFOs
++               * are busy.  This handles the non-packetized
++               * case nicely as we will not return to the
++               * idle loop until the busfree at the end of
++               * each transaction.
++               */
++              or      SBLKCTL, DIAGLEDEN|DIAGLEDON;
++      }
+       if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
+               /*
+-               * This exposes a window whereby a
+-               * busfree just after a selection will
+-               * be missed, but there is no other safe
+-               * way to enable busfree detection if
+-               * the busfreerev function is broken.
++               * Test to ensure that the bus has not
++               * already gone free prior to clearing
++               * any stale busfree status.  This avoids
++               * a window whereby a busfree just after
++               * a selection could be missed.
+                */
++              test    SCSISIGI, BSYI jz . + 2;
+               mvi     CLRSINT1,CLRBUSFREE;
+               or      SIMODE1, ENBUSFREE;
+       }
+@@ -527,6 +546,21 @@ SET_SRC_MODE      M_SCSI;
+ SET_DST_MODE  M_SCSI;
+ select_out:
+ BEGIN_CRITICAL;
++      if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {
++              /*
++               * On Rev A. hardware, the busy LED is only
++               * turned on automaically during selections
++               * and re-selections.  Make the LED status
++               * more useful by forcing it to be on from
++               * the point of re-selection until our idle
++               * loop determines that neither of our FIFOs
++               * are busy.  This handles the non-packetized
++               * case nicely as we will not return to the
++               * idle loop until the busfree at the end of
++               * each transaction.
++               */
++              or      SBLKCTL, DIAGLEDEN|DIAGLEDON;
++      }
+       /* Clear out all SCBs that have been successfully sent. */
+       if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) {
+               /*
+@@ -582,9 +616,6 @@ found_last_sent_scb:
+               bmov    CURRSCB, SCBPTR, 2;
+ curscb_ww_done:
+       } else {
+-              /*
+-               * Untested - Verify with Rev B.
+-               */
+               bmov    SCBPTR, CURRSCB, 2;
+       }
+@@ -651,12 +682,13 @@ select_out_non_packetized:
+       and     SCSISEQ0, ~ENSELO;
+       if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
+               /*
+-               * This exposes a window whereby a
+-               * busfree just after a selection will
+-               * be missed, but there is no other safe
+-               * way to enable busfree detection if
+-               * the busfreerev function is broken.
++               * Test to ensure that the bus has not
++               * already gone free prior to clearing
++               * any stale busfree status.  This avoids
++               * a window whereby a busfree just after
++               * a selection could be missed.
+                */
++              test    SCSISIGI, BSYI jz . + 2;
+               mvi     CLRSINT1,CLRBUSFREE;
+               or      SIMODE1, ENBUSFREE;
+       }
+@@ -729,13 +761,38 @@ p_command_embedded:
+       mvi     DFCNTRL, SCSIEN;
+ p_command_xfer:
+       and     SEQ_FLAGS, ~NO_CDB_SENT;
+-      test    DFCNTRL, SCSIEN jnz .;
++      if ((ahd->features & AHD_FAST_CDB_DELIVERY) != 0) {
++              /*
++               * To speed up CDB delivery in Rev B, all CDB acks
++               * are "released" to the output sync as soon as the
++               * command phase starts.  There is only one problem
++               * with this approach.  If the target changes phase
++               * before all data are sent, we have left over acks
++               * that can go out on the bus in a data phase.  Due
++               * to other chip contraints, this only happens if
++               * the target goes to data-in, but if the acks go
++               * out before we can test SDONE, we'll think that
++               * the transfer has completed successfully.  Work
++               * around this by taking advantage of the 400ns or
++               * 800ns dead time between command phase and the REQ
++               * of the new phase.  If the transfer has completed
++               * successfully, SCSIEN should fall *long* before we
++               * see a phase change.  We thus treat any phasemiss
++               * that occurs before SCSIEN falls as an incomplete
++               * transfer.
++               */
++              test    SSTAT1, PHASEMIS jnz p_command_xfer_failed;
++              test    DFCNTRL, SCSIEN jnz . - 1;
++      } else {
++              test    DFCNTRL, SCSIEN jnz .;
++      }
+       /*
+        * DMA Channel automatically disabled.
+        * Don't allow a data phase if the command
+        * was not fully transferred.
+        */
+       test    SSTAT2, SDONE jnz ITloop;
++p_command_xfer_failed:
+       or      SEQ_FLAGS, NO_CDB_SENT;
+       jmp     ITloop;
+@@ -1061,8 +1118,10 @@ queue_scb_completion:
+       test    SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */
+       test    SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb;
+ complete:
++BEGIN_CRITICAL;
+       bmov    SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;
+       bmov    COMPLETE_SCB_HEAD, SCBPTR, 2 ret;
++END_CRITICAL;
+ bad_status:
+       cmp     SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb;
+       call    freeze_queue;
+@@ -1073,9 +1132,11 @@ upload_scb:
+        * it on the host.
+        */
+       bmov    SCB_TAG, SCBPTR, 2;
++BEGIN_CRITICAL;
+       bmov    SCB_NEXT_COMPLETE, COMPLETE_DMA_SCB_HEAD, 2;
+       bmov    COMPLETE_DMA_SCB_HEAD, SCBPTR, 2;
+       or      SCB_SGPTR, SG_STATUS_VALID ret;
++END_CRITICAL;
+ /*
+  * Is it a disconnect message?  Set a flag in the SCB to remind us
+@@ -1122,8 +1183,18 @@ SET_DST_MODE    M_DFF1;
+ await_busfree_clrchn:
+       mvi     DFFSXFRCTL, CLRCHN;
+ await_busfree_not_m_dff:
+-      call    clear_target_state;
++      /* clear target specific flags */
++      mvi     SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT;
+       test    SSTAT1,REQINIT|BUSFREE  jz .;
++      /*
++       * We only set BUSFREE status once either a new
++       * phase has been detected or we are really
++       * BUSFREE.  This allows the driver to know
++       * that we are active on the bus even though
++       * no identified transaction exists should a
++       * timeout occur while awaiting busfree.
++       */
++      mvi     LASTPHASE, P_BUSFREE;
+       test    SSTAT1, BUSFREE jnz idle_loop;
+       SET_SEQINTCODE(MISSED_BUSFREE)
+@@ -1178,11 +1249,6 @@ msgin_rdptrs_get_fifo:
+       call    allocate_fifo;
+       jmp     mesgin_done;
+-clear_target_state:
+-      mvi     LASTPHASE, P_BUSFREE;
+-      /* clear target specific flags */
+-      mvi     SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret;
+-
+ phase_lock:     
+       if ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0) {
+               /*
+@@ -1634,7 +1700,7 @@ export seq_isr:
+                * savepointer in the current FIFO.  We do this so that
+                * a pending CTXTDONE or SAVEPTR is visible in the active
+                * FIFO.  This status is the only way we can detect if we
+-               * have lost the race (e.g. host paused us) and our attepts
++               * have lost the race (e.g. host paused us) and our attempts
+                * to disable the channel occurred after all REQs were
+                * already seen and acked (REQINIT never comes true).
+                */
+@@ -1643,7 +1709,7 @@ export seq_isr:
+               test    DFCNTRL, DIRECTION jz interrupt_return;
+               and     DFCNTRL, ~SCSIEN;
+ snapshot_wait_data_valid:
+-              test    SEQINTSRC, (CTXTDONE|SAVEPTRS) jnz snapshot_data_valid;
++              test    SEQINTSRC, (CTXTDONE|SAVEPTRS) jnz interrupt_return;
+               test    SSTAT1, REQINIT jz snapshot_wait_data_valid;
+ snapshot_data_valid:
+               or      DFCNTRL, SCSIEN;
+@@ -1810,7 +1876,6 @@ pkt_saveptrs_check_status:
+       dec     SCB_FIFO_USE_COUNT;
+       test    SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle;
+       mvi     DFFSXFRCTL, CLRCHN ret;
+-END_CRITICAL;
+ /*
+  * LAST_SEG_DONE status has been seen in the current FIFO.
+@@ -1819,7 +1884,6 @@ END_CRITICAL;
+  * Check for overrun and see if we can complete this command.
+  */
+ pkt_last_seg_done:
+-BEGIN_CRITICAL;
+       /*
+        * Mark transfer as completed.
+        */
+@@ -1959,12 +2023,14 @@ SET_DST_MODE   M_SCSI;
+       test    SSTAT0, SELDO jnz return;
+       mvi     SCBPTR[1], SCB_LIST_NULL;
+ unexpected_nonpkt_phase:
+-      test    MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz . + 3;
++      test    MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))
++              jnz unexpected_nonpkt_mode_cleared;
+ SET_SRC_MODE  M_DFF0;
+ SET_DST_MODE  M_DFF0;
+       or      LONGJMP_ADDR[1], INVALID_ADDR;
+       dec     SCB_FIFO_USE_COUNT;
+       mvi     DFFSXFRCTL, CLRCHN;
++unexpected_nonpkt_mode_cleared:
+       mvi     CLRSINT2, CLRNONPACKREQ;
+       test    SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase;
+       SET_SEQINTCODE(ENTERING_NONPACK)
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped     2003-06-14 12:18:48.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped      2003-12-28 23:21:39.000000000 -0800
+@@ -2,25 +2,25 @@
+  * DO NOT EDIT - This file is automatically generated
+  *             from the following source files:
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
+- * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#69 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#107 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
+  */
+ static uint8_t seqprog[] = {
+       0xff, 0x02, 0x06, 0x78,
+-      0x00, 0xea, 0x50, 0x59,
++      0x00, 0xea, 0x46, 0x59,
+       0x01, 0xea, 0x04, 0x30,
+       0xff, 0x04, 0x0c, 0x78,
+-      0x19, 0xea, 0x50, 0x59,
++      0x19, 0xea, 0x46, 0x59,
+       0x19, 0xea, 0x04, 0x00,
+-      0x33, 0xea, 0x44, 0x59,
++      0x33, 0xea, 0x3a, 0x59,
+       0x33, 0xea, 0x00, 0x00,
+       0x60, 0x3a, 0x1a, 0x68,
+       0x04, 0x47, 0x1b, 0x68,
+       0xff, 0x21, 0x1b, 0x70,
+-      0x40, 0x4b, 0x92, 0x69,
+-      0x00, 0xe2, 0x54, 0x59,
+-      0x40, 0x4b, 0x92, 0x69,
+-      0x20, 0x4b, 0x82, 0x69,
++      0x40, 0x4b, 0x8c, 0x69,
++      0x00, 0xe2, 0x4a, 0x59,
++      0x40, 0x4b, 0x8c, 0x69,
++      0x20, 0x4b, 0x78, 0x69,
+       0xfc, 0x42, 0x24, 0x78,
+       0x10, 0x40, 0x24, 0x78,
+       0x00, 0xe2, 0xc4, 0x5d,
+@@ -35,70 +35,65 @@ static uint8_t seqprog[] = {
+       0x00, 0xe2, 0x56, 0x58,
+       0x00, 0xe2, 0x66, 0x58,
+       0x00, 0xe2, 0x06, 0x40,
+-      0x33, 0xea, 0x44, 0x59,
++      0x33, 0xea, 0x3a, 0x59,
+       0x33, 0xea, 0x00, 0x00,
+       0x01, 0x52, 0x64, 0x78,
+       0x02, 0x58, 0x50, 0x31,
+       0xff, 0xea, 0x10, 0x0b,
+-      0xff, 0xad, 0x4f, 0x78,
++      0xff, 0x97, 0x4f, 0x78,
+       0x50, 0x4b, 0x4a, 0x68,
+       0xbf, 0x3a, 0x74, 0x08,
+-      0x14, 0xea, 0x50, 0x59,
++      0x14, 0xea, 0x46, 0x59,
+       0x14, 0xea, 0x04, 0x00,
+-      0x08, 0xa8, 0x51, 0x03,
+-      0xff, 0xae, 0x3f, 0x68,
+-      0x00, 0xe2, 0x56, 0x5b,
++      0x08, 0x92, 0x25, 0x03,
++      0xff, 0x90, 0x3f, 0x68,
++      0x00, 0xe2, 0x58, 0x5b,
+       0x00, 0xe2, 0x3e, 0x40,
+-      0x00, 0xea, 0x44, 0x59,
++      0x00, 0xea, 0x3a, 0x59,
+       0x01, 0xea, 0x00, 0x30,
+       0x80, 0xf9, 0x5e, 0x68,
+-      0x00, 0xe2, 0x42, 0x59,
+-      0x11, 0xea, 0x44, 0x59,
++      0x00, 0xe2, 0x38, 0x59,
++      0x11, 0xea, 0x3a, 0x59,
+       0x11, 0xea, 0x00, 0x00,
+-      0x80, 0xf9, 0x42, 0x79,
++      0x80, 0xf9, 0x38, 0x79,
+       0xff, 0xea, 0xd4, 0x0d,
+-      0x22, 0xea, 0x44, 0x59,
++      0x22, 0xea, 0x3a, 0x59,
+       0x22, 0xea, 0x00, 0x00,
+       0x10, 0x16, 0x70, 0x78,
+-      0x01, 0x0b, 0xa2, 0x32,
+       0x10, 0x16, 0x2c, 0x00,
+-      0x18, 0xad, 0x00, 0x79,
+-      0x04, 0xad, 0xca, 0x68,
++      0x01, 0x0b, 0xa2, 0x32,
++      0x18, 0xad, 0xf6, 0x78,
++      0x04, 0xad, 0xc0, 0x68,
+       0x80, 0xad, 0x64, 0x78,
+-      0x10, 0xad, 0x98, 0x78,
+-      0xff, 0x88, 0x83, 0x68,
+-      0xe7, 0xad, 0x5a, 0x09,
+-      0x02, 0x8c, 0x59, 0x32,
+-      0x02, 0x28, 0x19, 0x33,
+-      0x02, 0xa8, 0x50, 0x36,
+-      0x33, 0xea, 0x44, 0x59,
++      0x10, 0xad, 0x8e, 0x78,
++      0xff, 0x88, 0x87, 0x78,
++      0x33, 0xea, 0x3a, 0x59,
+       0x33, 0xea, 0x00, 0x00,
+       0x40, 0x3a, 0x64, 0x68,
+       0x50, 0x4b, 0x64, 0x68,
+-      0x22, 0xea, 0x44, 0x59,
++      0x22, 0xea, 0x3a, 0x59,
+       0x22, 0xea, 0x00, 0x00,
+       0xe7, 0xad, 0x5a, 0x09,
+       0x02, 0x8c, 0x59, 0x32,
+-      0x1a, 0xea, 0x50, 0x59,
+-      0x1a, 0xea, 0x04, 0x00,
+-      0xff, 0xea, 0xd4, 0x0d,
++      0x02, 0x28, 0x19, 0x33,
++      0x02, 0xa8, 0x50, 0x36,
+       0xe7, 0xad, 0x5a, 0x09,
+-      0x00, 0xe2, 0xa6, 0x58,
++      0x00, 0xe2, 0x9c, 0x58,
+       0xff, 0xea, 0x56, 0x02,
+       0x04, 0x7c, 0x78, 0x32,
+       0x20, 0x16, 0x64, 0x78,
+       0x04, 0x38, 0x79, 0x32,
+       0x80, 0x37, 0x6f, 0x16,
+-      0xff, 0x2d, 0xb5, 0x60,
+-      0xff, 0x29, 0xb5, 0x60,
+-      0x40, 0x51, 0xc5, 0x78,
+-      0xff, 0x4f, 0xb5, 0x68,
++      0xff, 0x2d, 0xab, 0x60,
++      0xff, 0x29, 0xab, 0x60,
++      0x40, 0x51, 0xbb, 0x78,
++      0xff, 0x4f, 0xab, 0x68,
+       0xff, 0x4d, 0xc1, 0x19,
+       0x00, 0x4e, 0xd5, 0x19,
+-      0x00, 0xe2, 0xc4, 0x50,
++      0x00, 0xe2, 0xba, 0x50,
+       0x01, 0x4c, 0xc1, 0x31,
+       0x00, 0x50, 0xd5, 0x19,
+-      0x00, 0xe2, 0xc4, 0x48,
++      0x00, 0xe2, 0xba, 0x48,
+       0x80, 0x18, 0x64, 0x78,
+       0x02, 0x4a, 0x1d, 0x30,
+       0x10, 0xea, 0x18, 0x00,
+@@ -113,30 +108,30 @@ static uint8_t seqprog[] = {
+       0xff, 0xea, 0xc0, 0x09,
+       0x01, 0x4e, 0x9d, 0x1a,
+       0x00, 0x4f, 0x9f, 0x22,
+-      0x01, 0xaa, 0x6d, 0x33,
+-      0x01, 0xea, 0x5c, 0x33,
+-      0x04, 0xa4, 0x49, 0x32,
+-      0xff, 0xea, 0x4a, 0x03,
+-      0xff, 0xea, 0x4e, 0x03,
++      0x01, 0x94, 0x6d, 0x33,
++      0xff, 0xea, 0x20, 0x0b,
++      0x04, 0xac, 0x49, 0x32,
++      0xff, 0xea, 0x5a, 0x03,
++      0xff, 0xea, 0x5e, 0x03,
+       0x01, 0x10, 0xd4, 0x31,
+-      0x10, 0xa8, 0xf5, 0x68,
+-      0x3d, 0xa9, 0xc5, 0x29,
++      0x10, 0x92, 0xeb, 0x68,
++      0x3d, 0x93, 0xc5, 0x29,
+       0xfe, 0xe2, 0xc4, 0x09,
+       0x01, 0xea, 0xc6, 0x01,
+       0x02, 0xe2, 0xc8, 0x31,
+       0x02, 0xec, 0x50, 0x31,
+       0x02, 0xa0, 0xda, 0x31,
+-      0xff, 0xa9, 0xf4, 0x70,
+-      0x02, 0xa0, 0x48, 0x37,
+-      0xff, 0x21, 0xfd, 0x70,
++      0xff, 0xa9, 0xea, 0x70,
++      0x02, 0xa0, 0x58, 0x37,
++      0xff, 0x21, 0xf3, 0x70,
+       0x02, 0x22, 0x51, 0x31,
+-      0x02, 0xa0, 0x4c, 0x33,
++      0x02, 0xa0, 0x5c, 0x33,
+       0x02, 0xa0, 0x44, 0x36,
+       0x02, 0xa0, 0x40, 0x32,
+       0x02, 0xa0, 0x44, 0x36,
+-      0x04, 0x47, 0x05, 0x69,
+-      0x40, 0x16, 0x30, 0x69,
+-      0xff, 0x2d, 0x35, 0x61,
++      0x04, 0x47, 0xfb, 0x68,
++      0x40, 0x16, 0x26, 0x69,
++      0xff, 0x2d, 0x2b, 0x61,
+       0xff, 0x29, 0x65, 0x70,
+       0x01, 0x37, 0xc1, 0x31,
+       0x02, 0x28, 0x55, 0x32,
+@@ -149,20 +144,20 @@ static uint8_t seqprog[] = {
+       0x01, 0x50, 0xa1, 0x1a,
+       0xff, 0x4e, 0x9d, 0x1a,
+       0xff, 0x4f, 0x9f, 0x22,
+-      0xff, 0x8d, 0x29, 0x71,
+-      0x80, 0xac, 0x28, 0x71,
+-      0x20, 0x16, 0x28, 0x69,
++      0xff, 0x8d, 0x1f, 0x71,
++      0x80, 0xac, 0x1e, 0x71,
++      0x20, 0x16, 0x1e, 0x69,
+       0x02, 0x8c, 0x51, 0x31,
+-      0x00, 0xe2, 0x12, 0x41,
++      0x00, 0xe2, 0x08, 0x41,
+       0x01, 0xac, 0x08, 0x31,
+       0x09, 0xea, 0x5a, 0x01,
+       0x02, 0x8c, 0x51, 0x32,
+       0xff, 0xea, 0x1a, 0x07,
+       0x04, 0x24, 0xf9, 0x30,
+-      0x1d, 0xea, 0x3a, 0x41,
++      0x1d, 0xea, 0x30, 0x41,
+       0x02, 0x2c, 0x51, 0x31,
+-      0x04, 0xa0, 0xf9, 0x30,
+-      0x19, 0xea, 0x3a, 0x41,
++      0x04, 0xa8, 0xf9, 0x30,
++      0x19, 0xea, 0x30, 0x41,
+       0x06, 0xea, 0x08, 0x81,
+       0x01, 0xe2, 0x5a, 0x35,
+       0x02, 0xf2, 0xf0, 0x35,
+@@ -179,26 +174,28 @@ static uint8_t seqprog[] = {
+       0x02, 0x20, 0xbd, 0x30,
+       0x02, 0x20, 0xb9, 0x30,
+       0x02, 0x20, 0x51, 0x31,
+-      0x4c, 0xa9, 0xd7, 0x28,
+-      0x10, 0xa8, 0x63, 0x79,
++      0x4c, 0x93, 0xd7, 0x28,
++      0x10, 0x92, 0x59, 0x79,
+       0x01, 0x6b, 0xc0, 0x30,
+       0x02, 0x64, 0xc8, 0x00,
+       0x40, 0x3a, 0x74, 0x04,
+       0x00, 0xe2, 0x56, 0x58,
+-      0x33, 0xea, 0x44, 0x59,
++      0x33, 0xea, 0x3a, 0x59,
+       0x33, 0xea, 0x00, 0x00,
+       0x30, 0x3f, 0xc0, 0x09,
+-      0x30, 0xe0, 0x64, 0x61,
+-      0x20, 0x3f, 0x7a, 0x69,
+-      0x10, 0x3f, 0x64, 0x79,
++      0x30, 0xe0, 0x5a, 0x61,
++      0x20, 0x3f, 0x70, 0x69,
++      0x10, 0x3f, 0x5a, 0x79,
+       0x02, 0xea, 0x7e, 0x00,
+-      0x00, 0xea, 0x44, 0x59,
++      0x00, 0xea, 0x3a, 0x59,
+       0x01, 0xea, 0x00, 0x30,
+       0x02, 0x48, 0x51, 0x35,
+       0x01, 0xea, 0x7e, 0x00,
+-      0x11, 0xea, 0x44, 0x59,
++      0x11, 0xea, 0x3a, 0x59,
+       0x11, 0xea, 0x00, 0x00,
+       0x02, 0x48, 0x51, 0x35,
++      0xc0, 0x4a, 0x94, 0x00,
++      0x04, 0x41, 0x7e, 0x79,
+       0x08, 0xea, 0x98, 0x00,
+       0x08, 0x57, 0xae, 0x00,
+       0x08, 0x3c, 0x78, 0x00,
+@@ -206,11 +203,12 @@ static uint8_t seqprog[] = {
+       0x0f, 0x67, 0xc0, 0x09,
+       0x00, 0x34, 0x69, 0x02,
+       0x20, 0xea, 0x96, 0x00,
+-      0x00, 0xe2, 0xf8, 0x41,
+-      0x40, 0x3a, 0xae, 0x69,
++      0x00, 0xe2, 0xf6, 0x41,
++      0xc0, 0x4a, 0x94, 0x00,
++      0x40, 0x3a, 0xaa, 0x69,
+       0x02, 0x55, 0x06, 0x68,
+-      0x02, 0x56, 0xae, 0x69,
+-      0xff, 0x5b, 0xae, 0x61,
++      0x02, 0x56, 0xaa, 0x69,
++      0xff, 0x5b, 0xaa, 0x61,
+       0x02, 0x20, 0x51, 0x31,
+       0x80, 0xea, 0xb2, 0x01,
+       0x44, 0xea, 0x00, 0x00,
+@@ -218,146 +216,149 @@ static uint8_t seqprog[] = {
+       0x33, 0xea, 0x00, 0x00,
+       0xff, 0xea, 0xb2, 0x09,
+       0xff, 0xe0, 0xc0, 0x19,
+-      0xff, 0xe0, 0xb0, 0x79,
+-      0x02, 0xa4, 0x51, 0x31,
+-      0x00, 0xe2, 0xa6, 0x41,
++      0xff, 0xe0, 0xac, 0x79,
++      0x02, 0xac, 0x51, 0x31,
++      0x00, 0xe2, 0xa2, 0x41,
+       0x02, 0x5e, 0x50, 0x31,
+       0x02, 0xa8, 0xb8, 0x30,
+       0x02, 0x5c, 0x50, 0x31,
+-      0xff, 0xa5, 0xc1, 0x71,
+-      0x02, 0xa4, 0x41, 0x31,
++      0xff, 0xad, 0xbd, 0x71,
++      0x02, 0xac, 0x41, 0x31,
+       0x02, 0x22, 0x51, 0x31,
+-      0x02, 0xa0, 0x4c, 0x33,
++      0x02, 0xa0, 0x5c, 0x33,
+       0x02, 0xa0, 0x44, 0x32,
+-      0x00, 0xe2, 0xca, 0x41,
+-      0x10, 0xa8, 0xcb, 0x69,
+-      0x3d, 0xa9, 0xc9, 0x29,
++      0x00, 0xe2, 0xc6, 0x41,
++      0x10, 0x92, 0xc7, 0x69,
++      0x3d, 0x93, 0xc9, 0x29,
+       0x01, 0xe4, 0xc8, 0x01,
+       0x01, 0xea, 0xca, 0x01,
+       0xff, 0xea, 0xda, 0x01,
+       0x02, 0x20, 0x51, 0x31,
+-      0x02, 0xa6, 0x41, 0x32,
+-      0xff, 0x21, 0xd3, 0x61,
++      0x02, 0xae, 0x41, 0x32,
++      0xff, 0x21, 0xcf, 0x61,
+       0xff, 0xea, 0x46, 0x02,
+       0x02, 0x5c, 0x50, 0x31,
+       0x40, 0xea, 0x96, 0x00,
+       0x02, 0x56, 0xcc, 0x6d,
+       0x01, 0x55, 0xcc, 0x6d,
+-      0x10, 0xa8, 0xdf, 0x79,
+-      0x10, 0x40, 0xe8, 0x69,
+-      0x01, 0x56, 0xe8, 0x79,
+-      0xff, 0xad, 0x07, 0x78,
+-      0x13, 0xea, 0x50, 0x59,
++      0x10, 0x92, 0xdb, 0x79,
++      0x10, 0x40, 0xe4, 0x69,
++      0x01, 0x56, 0xe4, 0x79,
++      0xff, 0x97, 0x07, 0x78,
++      0x13, 0xea, 0x46, 0x59,
+       0x13, 0xea, 0x04, 0x00,
+       0x00, 0xe2, 0x06, 0x40,
+       0xbf, 0x3a, 0x74, 0x08,
++      0x04, 0x41, 0xea, 0x79,
+       0x08, 0xea, 0x98, 0x00,
+       0x08, 0x57, 0xae, 0x00,
+-      0x01, 0xa9, 0x69, 0x32,
+-      0x01, 0xaa, 0x6b, 0x32,
++      0x01, 0x93, 0x69, 0x32,
++      0x01, 0x94, 0x6b, 0x32,
+       0x40, 0xea, 0x66, 0x02,
+       0x08, 0x3c, 0x78, 0x00,
+       0x80, 0xea, 0x62, 0x02,
+       0x00, 0xe2, 0xb8, 0x5b,
+       0x01, 0x36, 0xc1, 0x31,
+       0x9f, 0xe0, 0x4c, 0x7c,
+-      0x80, 0xe0, 0x0c, 0x72,
+-      0xa0, 0xe0, 0x44, 0x72,
+-      0xc0, 0xe0, 0x3a, 0x72,
+-      0xe0, 0xe0, 0x74, 0x72,
+-      0x01, 0xea, 0x50, 0x59,
++      0x80, 0xe0, 0x0a, 0x72,
++      0xa0, 0xe0, 0x46, 0x72,
++      0xc0, 0xe0, 0x3c, 0x72,
++      0xe0, 0xe0, 0x76, 0x72,
++      0x01, 0xea, 0x46, 0x59,
+       0x01, 0xea, 0x04, 0x00,
+-      0x00, 0xe2, 0xf8, 0x41,
+-      0x80, 0x33, 0x13, 0x7a,
+-      0x03, 0xea, 0x50, 0x59,
++      0x00, 0xe2, 0xf6, 0x41,
++      0x80, 0x33, 0x11, 0x7a,
++      0x03, 0xea, 0x46, 0x59,
+       0x03, 0xea, 0x04, 0x00,
+-      0xee, 0x00, 0x1a, 0x6a,
++      0xee, 0x00, 0x18, 0x6a,
+       0x05, 0xea, 0xb4, 0x00,
+-      0x33, 0xea, 0x44, 0x59,
++      0x33, 0xea, 0x3a, 0x59,
+       0x33, 0xea, 0x00, 0x00,
+       0x02, 0xa8, 0x90, 0x32,
+-      0x00, 0xe2, 0x6a, 0x59,
+-      0xef, 0xac, 0xd5, 0x19,
+-      0x00, 0xe2, 0x2a, 0x52,
++      0x00, 0xe2, 0x60, 0x59,
++      0xef, 0x96, 0xd5, 0x19,
++      0x00, 0xe2, 0x28, 0x52,
+       0x09, 0x80, 0xe1, 0x30,
+       0x02, 0xea, 0x36, 0x00,
+       0xa8, 0xea, 0x32, 0x00,
+-      0x00, 0xe2, 0x30, 0x42,
+-      0x01, 0xac, 0xd1, 0x30,
++      0x00, 0xe2, 0x2e, 0x42,
++      0x01, 0x96, 0xd1, 0x30,
+       0x10, 0x80, 0x89, 0x31,
+       0x20, 0xea, 0x32, 0x00,
+       0xbf, 0x33, 0x67, 0x0a,
+-      0x20, 0x19, 0x32, 0x6a,
+-      0x02, 0x4d, 0xf8, 0x69,
++      0x10, 0x4c, 0x38, 0x6a,
++      0x20, 0x19, 0x30, 0x6a,
++      0x20, 0x19, 0x34, 0x6a,
++      0x02, 0x4d, 0xf6, 0x69,
+       0x40, 0x33, 0x67, 0x02,
+-      0x00, 0xe2, 0xf8, 0x41,
+-      0x80, 0x33, 0xb5, 0x6a,
++      0x00, 0xe2, 0xf6, 0x41,
++      0x80, 0x33, 0xb7, 0x6a,
+       0x01, 0x44, 0x10, 0x33,
+-      0x08, 0xa8, 0x51, 0x03,
+-      0x00, 0xe2, 0xf8, 0x41,
++      0x08, 0x92, 0x25, 0x03,
++      0x00, 0xe2, 0xf6, 0x41,
+       0x10, 0xea, 0x80, 0x00,
+       0x01, 0x31, 0xc5, 0x31,
+-      0x80, 0xe2, 0x60, 0x62,
+-      0x10, 0xa8, 0x85, 0x6a,
+-      0xc0, 0xaa, 0xc5, 0x01,
+-      0x40, 0xa8, 0x51, 0x6a,
++      0x80, 0xe2, 0x62, 0x62,
++      0x10, 0x92, 0x87, 0x6a,
++      0xc0, 0x94, 0xc5, 0x01,
++      0x40, 0x92, 0x53, 0x6a,
+       0xbf, 0xe2, 0xc4, 0x09,
+-      0x20, 0xa8, 0x65, 0x7a,
++      0x20, 0x92, 0x67, 0x7a,
+       0x01, 0xe2, 0x88, 0x30,
+       0x00, 0xe2, 0xb8, 0x5b,
+-      0xa0, 0x36, 0x6d, 0x62,
+-      0x23, 0xa8, 0x89, 0x08,
++      0xa0, 0x36, 0x6f, 0x62,
++      0x23, 0x92, 0x89, 0x08,
+       0x00, 0xe2, 0xb8, 0x5b,
+-      0xa0, 0x36, 0x6d, 0x62,
+-      0x00, 0xa8, 0x64, 0x42,
+-      0xff, 0xe2, 0x64, 0x62,
+-      0x00, 0xe2, 0x84, 0x42,
++      0xa0, 0x36, 0x6f, 0x62,
++      0x00, 0xa8, 0x66, 0x42,
++      0xff, 0xe2, 0x66, 0x62,
++      0x00, 0xe2, 0x86, 0x42,
+       0x40, 0xea, 0x98, 0x00,
+       0x01, 0xe2, 0x88, 0x30,
+       0x00, 0xe2, 0xb8, 0x5b,
+-      0xa0, 0x36, 0x43, 0x72,
++      0xa0, 0x36, 0x45, 0x72,
+       0x40, 0xea, 0x98, 0x00,
+       0x01, 0x31, 0x89, 0x32,
+       0x08, 0xea, 0x62, 0x02,
+-      0x00, 0xe2, 0xf8, 0x41,
++      0x00, 0xe2, 0xf6, 0x41,
+       0xe0, 0xea, 0xd4, 0x5b,
+-      0x80, 0xe0, 0xc0, 0x6a,
+-      0x04, 0xe0, 0x66, 0x73,
+-      0x02, 0xe0, 0x96, 0x73,
+-      0x00, 0xea, 0x1e, 0x73,
+-      0x03, 0xe0, 0xa6, 0x73,
+-      0x23, 0xe0, 0x96, 0x72,
+-      0x08, 0xe0, 0xbc, 0x72,
++      0x80, 0xe0, 0xc2, 0x6a,
++      0x04, 0xe0, 0x68, 0x73,
++      0x02, 0xe0, 0x9a, 0x73,
++      0x00, 0xea, 0x20, 0x73,
++      0x03, 0xe0, 0xaa, 0x73,
++      0x23, 0xe0, 0x98, 0x72,
++      0x08, 0xe0, 0xbe, 0x72,
+       0x00, 0xe2, 0xb8, 0x5b,
+-      0x07, 0xea, 0x50, 0x59,
++      0x07, 0xea, 0x46, 0x59,
+       0x07, 0xea, 0x04, 0x00,
+-      0x08, 0x42, 0xf9, 0x71,
+-      0x04, 0x42, 0x93, 0x62,
++      0x08, 0x42, 0xf7, 0x71,
++      0x04, 0x42, 0x95, 0x62,
+       0x01, 0x43, 0x89, 0x30,
+-      0x00, 0xe2, 0x84, 0x42,
++      0x00, 0xe2, 0x86, 0x42,
+       0x01, 0x44, 0xd4, 0x31,
+-      0x00, 0xe2, 0x84, 0x42,
++      0x00, 0xe2, 0x86, 0x42,
+       0x01, 0x00, 0x60, 0x32,
+-      0x33, 0xea, 0x44, 0x59,
++      0x33, 0xea, 0x3a, 0x59,
+       0x33, 0xea, 0x00, 0x00,
+       0x4c, 0x34, 0xc1, 0x28,
+       0x01, 0x64, 0xc0, 0x31,
+-      0x00, 0x30, 0x45, 0x59,
++      0x00, 0x30, 0x3b, 0x59,
+       0x01, 0x30, 0x01, 0x30,
+-      0x01, 0xe0, 0xba, 0x7a,
++      0x01, 0xe0, 0xbc, 0x7a,
+       0xa0, 0xea, 0xca, 0x5b,
+-      0x01, 0xa0, 0xba, 0x62,
+-      0x01, 0x84, 0xaf, 0x7a,
+-      0x01, 0xab, 0xbd, 0x6a,
+-      0x05, 0xea, 0x50, 0x59,
++      0x01, 0xa0, 0xbc, 0x62,
++      0x01, 0x84, 0xb1, 0x7a,
++      0x01, 0x95, 0xbf, 0x6a,
++      0x05, 0xea, 0x46, 0x59,
+       0x05, 0xea, 0x04, 0x00,
+-      0x00, 0xe2, 0xbc, 0x42,
+-      0x03, 0xea, 0x50, 0x59,
++      0x00, 0xe2, 0xbe, 0x42,
++      0x03, 0xea, 0x46, 0x59,
+       0x03, 0xea, 0x04, 0x00,
+-      0x00, 0xe2, 0xbc, 0x42,
++      0x00, 0xe2, 0xbe, 0x42,
+       0x07, 0xea, 0xdc, 0x5b,
+       0x01, 0x44, 0xd4, 0x31,
+-      0x00, 0xe2, 0xf8, 0x41,
++      0x00, 0xe2, 0xf6, 0x41,
+       0x3f, 0xe0, 0x6a, 0x0a,
+       0xc0, 0x34, 0xc1, 0x09,
+       0x00, 0x35, 0x51, 0x01,
+@@ -368,54 +369,54 @@ static uint8_t seqprog[] = {
+       0x01, 0xea, 0xc6, 0x01,
+       0x02, 0xe2, 0xc8, 0x31,
+       0x02, 0xec, 0x40, 0x31,
+-      0xff, 0xa1, 0xdc, 0x72,
++      0xff, 0xa1, 0xde, 0x72,
+       0x02, 0xe8, 0xda, 0x31,
+       0x02, 0xa0, 0x50, 0x31,
+-      0x00, 0xe2, 0xfe, 0x42,
++      0x00, 0xe2, 0x00, 0x43,
+       0x80, 0x33, 0x67, 0x02,
+       0x01, 0x44, 0xd4, 0x31,
+       0x00, 0xe2, 0xb8, 0x5b,
+       0x01, 0x33, 0x67, 0x02,
+-      0xe0, 0x36, 0x19, 0x63,
++      0xe0, 0x36, 0x1b, 0x63,
+       0x02, 0x33, 0x67, 0x02,
+-      0x20, 0x46, 0x12, 0x63,
++      0x20, 0x46, 0x14, 0x63,
+       0xff, 0xea, 0x52, 0x09,
+       0xa8, 0xea, 0xca, 0x5b,
+-      0x04, 0xa8, 0xf9, 0x7a,
++      0x04, 0x92, 0xfb, 0x7a,
+       0x01, 0x34, 0xc1, 0x31,
+-      0x00, 0xa9, 0xf9, 0x62,
++      0x00, 0x93, 0xfb, 0x62,
+       0x01, 0x35, 0xc1, 0x31,
+-      0x00, 0xaa, 0x03, 0x73,
++      0x00, 0x94, 0x05, 0x73,
+       0x01, 0xa9, 0x52, 0x11,
+-      0xff, 0xa9, 0xee, 0x6a,
+-      0x00, 0xe2, 0x12, 0x43,
++      0xff, 0xa9, 0xf0, 0x6a,
++      0x00, 0xe2, 0x14, 0x43,
+       0x10, 0x33, 0x67, 0x02,
+-      0x04, 0xa8, 0x13, 0x7b,
+-      0xfb, 0xa8, 0x51, 0x0b,
++      0x04, 0x92, 0x15, 0x7b,
++      0xfb, 0x92, 0x25, 0x0b,
+       0xff, 0xea, 0x66, 0x0a,
+-      0x01, 0x9c, 0x0d, 0x6b,
++      0x01, 0xa4, 0x0f, 0x6b,
+       0x02, 0xa8, 0x90, 0x32,
+-      0x00, 0xe2, 0x6a, 0x59,
+-      0x10, 0xa8, 0xbd, 0x7a,
++      0x00, 0xe2, 0x60, 0x59,
++      0x10, 0x92, 0xbf, 0x7a,
+       0xff, 0xea, 0xdc, 0x5b,
+-      0x00, 0xe2, 0xbc, 0x42,
+-      0x04, 0xea, 0x50, 0x59,
++      0x00, 0xe2, 0xbe, 0x42,
++      0x04, 0xea, 0x46, 0x59,
+       0x04, 0xea, 0x04, 0x00,
+-      0x00, 0xe2, 0xbc, 0x42,
+-      0x04, 0xea, 0x50, 0x59,
++      0x00, 0xe2, 0xbe, 0x42,
++      0x04, 0xea, 0x46, 0x59,
+       0x04, 0xea, 0x04, 0x00,
+-      0x00, 0xe2, 0xf8, 0x41,
+-      0x08, 0xa8, 0xb5, 0x7a,
+-      0xc0, 0x33, 0x29, 0x7b,
+-      0x80, 0x33, 0xb5, 0x6a,
+-      0xff, 0x88, 0x29, 0x6b,
+-      0x40, 0x33, 0xb5, 0x6a,
+-      0x10, 0xa8, 0x2f, 0x7b,
+-      0x0a, 0xea, 0x50, 0x59,
++      0x00, 0xe2, 0xf6, 0x41,
++      0x08, 0x92, 0xb7, 0x7a,
++      0xc0, 0x33, 0x2b, 0x7b,
++      0x80, 0x33, 0xb7, 0x6a,
++      0xff, 0x88, 0x2b, 0x6b,
++      0x40, 0x33, 0xb7, 0x6a,
++      0x10, 0x92, 0x31, 0x7b,
++      0x0a, 0xea, 0x46, 0x59,
+       0x0a, 0xea, 0x04, 0x00,
+-      0x00, 0xe2, 0x4e, 0x5b,
+-      0x00, 0xe2, 0x82, 0x43,
+-      0x50, 0x4b, 0x36, 0x6b,
++      0x00, 0xe2, 0x50, 0x5b,
++      0x00, 0xe2, 0x84, 0x43,
++      0x50, 0x4b, 0x38, 0x6b,
+       0xbf, 0x3a, 0x74, 0x08,
+       0x01, 0xe0, 0xf4, 0x31,
+       0xff, 0xea, 0xc0, 0x09,
+@@ -425,25 +426,25 @@ static uint8_t seqprog[] = {
+       0x01, 0xfa, 0xc0, 0x35,
+       0x02, 0xa8, 0x84, 0x32,
+       0x02, 0xea, 0xb4, 0x00,
+-      0x33, 0xea, 0x44, 0x59,
++      0x33, 0xea, 0x3a, 0x59,
+       0x33, 0xea, 0x00, 0x00,
+       0x02, 0x42, 0x51, 0x31,
+-      0xff, 0xae, 0x65, 0x68,
+-      0xff, 0x88, 0x5b, 0x6b,
+-      0x01, 0x9c, 0x57, 0x6b,
+-      0x02, 0x9c, 0x5f, 0x6b,
+-      0x01, 0x84, 0x5f, 0x7b,
++      0xff, 0x90, 0x65, 0x68,
++      0xff, 0x88, 0x5d, 0x6b,
++      0x01, 0xa4, 0x59, 0x6b,
++      0x02, 0xa4, 0x61, 0x6b,
++      0x01, 0x84, 0x61, 0x7b,
+       0x02, 0x28, 0x19, 0x33,
+       0x02, 0xa8, 0x50, 0x36,
+-      0xff, 0x88, 0x5f, 0x73,
+-      0x00, 0xe2, 0x32, 0x5b,
+-      0x02, 0xa8, 0x5c, 0x33,
++      0xff, 0x88, 0x61, 0x73,
++      0x00, 0xe2, 0x34, 0x5b,
++      0x02, 0xa8, 0x20, 0x33,
+       0x02, 0x2c, 0x19, 0x33,
+       0x02, 0xa8, 0x58, 0x32,
+-      0x04, 0x9c, 0x39, 0x07,
+-      0xc0, 0x33, 0xb5, 0x6a,
+-      0x04, 0xa8, 0x51, 0x03,
+-      0x20, 0xa8, 0x83, 0x6b,
++      0x04, 0xa4, 0x49, 0x07,
++      0xc0, 0x33, 0xb7, 0x6a,
++      0x04, 0x92, 0x25, 0x03,
++      0x20, 0x92, 0x85, 0x6b,
+       0x02, 0xa8, 0x40, 0x31,
+       0xc0, 0x34, 0xc1, 0x09,
+       0x00, 0x35, 0x51, 0x01,
+@@ -458,30 +459,29 @@ static uint8_t seqprog[] = {
+       0xf7, 0x57, 0xae, 0x08,
+       0x08, 0xea, 0x98, 0x00,
+       0x01, 0x44, 0xd4, 0x31,
+-      0xee, 0x00, 0x8c, 0x6b,
++      0xee, 0x00, 0x8e, 0x6b,
+       0x02, 0xea, 0xb4, 0x00,
+-      0x00, 0xe2, 0xb4, 0x5b,
+-      0x09, 0x4c, 0x8e, 0x7b,
++      0xc0, 0xea, 0x66, 0x02,
++      0x09, 0x4c, 0x90, 0x7b,
++      0x01, 0xea, 0x6c, 0x02,
+       0x08, 0x4c, 0x06, 0x68,
+-      0x0b, 0xea, 0x50, 0x59,
++      0x0b, 0xea, 0x46, 0x59,
+       0x0b, 0xea, 0x04, 0x00,
+       0x01, 0x44, 0xd4, 0x31,
+-      0x20, 0x33, 0xf9, 0x79,
+-      0x00, 0xe2, 0x9e, 0x5b,
+-      0x00, 0xe2, 0xf8, 0x41,
+-      0x01, 0x84, 0xa3, 0x7b,
+-      0x01, 0x9c, 0x39, 0x07,
+-      0x08, 0x60, 0x20, 0x33,
+-      0x08, 0x80, 0x31, 0x37,
++      0x20, 0x33, 0xf7, 0x79,
++      0x00, 0xe2, 0xa2, 0x5b,
++      0x00, 0xe2, 0xf6, 0x41,
++      0x01, 0x84, 0xa7, 0x7b,
++      0x01, 0xa4, 0x49, 0x07,
++      0x08, 0x60, 0x30, 0x33,
++      0x08, 0x80, 0x41, 0x37,
+       0xdf, 0x33, 0x67, 0x0a,
+-      0xee, 0x00, 0xb0, 0x6b,
++      0xee, 0x00, 0xb4, 0x6b,
+       0x05, 0xea, 0xb4, 0x00,
+-      0x33, 0xea, 0x44, 0x59,
++      0x33, 0xea, 0x3a, 0x59,
+       0x33, 0xea, 0x00, 0x00,
+-      0x00, 0xe2, 0x6a, 0x59,
+-      0x00, 0xe2, 0xbc, 0x42,
+-      0x01, 0xea, 0x6c, 0x02,
+-      0xc0, 0xea, 0x66, 0x06,
++      0x00, 0xe2, 0x60, 0x59,
++      0x00, 0xe2, 0xbe, 0x42,
+       0xff, 0x42, 0xc4, 0x6b,
+       0x01, 0x41, 0xb8, 0x6b,
+       0x02, 0x41, 0xb8, 0x7b,
+@@ -495,7 +495,7 @@ static uint8_t seqprog[] = {
+       0xff, 0x42, 0xcc, 0x7b,
+       0x04, 0x4c, 0xcc, 0x6b,
+       0xe0, 0x41, 0x6c, 0x0a,
+-      0xe0, 0x36, 0xf9, 0x61,
++      0xe0, 0x36, 0xf7, 0x61,
+       0xff, 0xea, 0xca, 0x09,
+       0x01, 0xe2, 0xc8, 0x31,
+       0x01, 0x46, 0xda, 0x35,
+@@ -542,42 +542,42 @@ static uint8_t seqprog[] = {
+       0x01, 0xac, 0xd4, 0x99,
+       0x00, 0xe2, 0x64, 0x50,
+       0xfe, 0xa6, 0x4c, 0x0d,
+-      0x0b, 0x90, 0xe1, 0x30,
+-      0xfd, 0x9c, 0x49, 0x09,
+-      0x80, 0x9b, 0x39, 0x7c,
++      0x0b, 0x98, 0xe1, 0x30,
++      0xfd, 0xa4, 0x49, 0x09,
++      0x80, 0xa3, 0x39, 0x7c,
+       0x02, 0xa4, 0x48, 0x01,
+       0x01, 0xa4, 0x36, 0x30,
+       0xa8, 0xea, 0x32, 0x00,
+-      0xfd, 0x9c, 0x39, 0x0b,
+-      0x05, 0x9b, 0x07, 0x33,
++      0xfd, 0xa4, 0x49, 0x0b,
++      0x05, 0xa3, 0x07, 0x33,
+       0x80, 0x83, 0x45, 0x6c,
+       0x02, 0xea, 0x4c, 0x05,
+       0xff, 0xea, 0x4c, 0x0d,
+-      0x00, 0xe2, 0x3e, 0x59,
++      0x00, 0xe2, 0x34, 0x59,
+       0x02, 0xa6, 0xe6, 0x6b,
+       0x80, 0xf9, 0xf2, 0x05,
+       0xc0, 0x33, 0x53, 0x7c,
+-      0x03, 0xea, 0x50, 0x59,
++      0x03, 0xea, 0x46, 0x59,
+       0x03, 0xea, 0x04, 0x00,
+       0x20, 0x33, 0x77, 0x7c,
+       0x01, 0x84, 0x5d, 0x6c,
+-      0x06, 0xea, 0x50, 0x59,
++      0x06, 0xea, 0x46, 0x59,
+       0x06, 0xea, 0x04, 0x00,
+       0x00, 0xe2, 0x7a, 0x44,
+       0x01, 0x00, 0x60, 0x32,
+       0xee, 0x00, 0x66, 0x6c,
+       0x05, 0xea, 0xb4, 0x00,
+-      0x33, 0xea, 0x44, 0x59,
++      0x33, 0xea, 0x3a, 0x59,
+       0x33, 0xea, 0x00, 0x00,
+       0x80, 0x3d, 0x7a, 0x00,
+       0xfc, 0x42, 0x68, 0x7c,
+       0x7f, 0x3d, 0x7a, 0x08,
+-      0x00, 0x30, 0x45, 0x59,
++      0x00, 0x30, 0x3b, 0x59,
+       0x01, 0x30, 0x01, 0x30,
+-      0x09, 0xea, 0x50, 0x59,
++      0x09, 0xea, 0x46, 0x59,
+       0x09, 0xea, 0x04, 0x00,
+-      0x00, 0xe2, 0xf8, 0x41,
+-      0x01, 0x9c, 0x5d, 0x6c,
++      0x00, 0xe2, 0xf6, 0x41,
++      0x01, 0xa4, 0x5d, 0x6c,
+       0x00, 0xe2, 0x30, 0x5c,
+       0x20, 0x33, 0x67, 0x02,
+       0x01, 0x00, 0x60, 0x32,
+@@ -586,7 +586,7 @@ static uint8_t seqprog[] = {
+       0x00, 0xe2, 0x56, 0x58,
+       0x00, 0xe2, 0x66, 0x58,
+       0x00, 0xe2, 0x3a, 0x58,
+-      0x00, 0x30, 0x45, 0x59,
++      0x00, 0x30, 0x3b, 0x59,
+       0x01, 0x30, 0x01, 0x30,
+       0x20, 0x19, 0x82, 0x6c,
+       0x00, 0xe2, 0xb2, 0x5c,
+@@ -601,11 +601,11 @@ static uint8_t seqprog[] = {
+       0x03, 0x42, 0x4c, 0x6c,
+       0x00, 0xe2, 0xe0, 0x5b,
+       0x80, 0xf9, 0xf2, 0x01,
+-      0x04, 0x33, 0xf9, 0x79,
+-      0x00, 0xe2, 0xf8, 0x41,
++      0x04, 0x33, 0xf7, 0x79,
++      0x00, 0xe2, 0xf6, 0x41,
+       0x08, 0x5d, 0xba, 0x6c,
+       0x00, 0xe2, 0x56, 0x58,
+-      0x00, 0x30, 0x45, 0x59,
++      0x00, 0x30, 0x3b, 0x59,
+       0x01, 0x30, 0x01, 0x30,
+       0x02, 0x1b, 0xaa, 0x7c,
+       0x08, 0x5d, 0xb8, 0x7c,
+@@ -619,7 +619,7 @@ static uint8_t seqprog[] = {
+       0xf8, 0x1b, 0x08, 0x0b,
+       0xff, 0xea, 0x06, 0x0b,
+       0x03, 0x68, 0x00, 0x37,
+-      0x00, 0xe2, 0xc4, 0x58,
++      0x00, 0xe2, 0xba, 0x58,
+       0x10, 0xea, 0x18, 0x00,
+       0xf9, 0xd9, 0xb2, 0x0d,
+       0x01, 0xd9, 0xb2, 0x05,
+@@ -631,7 +631,7 @@ static uint8_t seqprog[] = {
+       0x11, 0x00, 0x00, 0x10,
+       0x04, 0x19, 0x08, 0x7d,
+       0xdf, 0x19, 0x32, 0x08,
+-      0x60, 0x5b, 0xe6, 0x6c,
++      0x60, 0x5b, 0x08, 0x6d,
+       0x01, 0x4c, 0xe2, 0x7c,
+       0x20, 0x19, 0x32, 0x00,
+       0x01, 0xd9, 0xb2, 0x05,
+@@ -641,29 +641,29 @@ static uint8_t seqprog[] = {
+       0x08, 0x5b, 0x0a, 0x6d,
+       0x20, 0x5b, 0xfa, 0x6c,
+       0x02, 0x5b, 0x2a, 0x6d,
+-      0x0e, 0xea, 0x50, 0x59,
++      0x0e, 0xea, 0x46, 0x59,
+       0x0e, 0xea, 0x04, 0x00,
+       0x80, 0xf9, 0xea, 0x6c,
+       0xdf, 0x5c, 0xb8, 0x08,
+       0x01, 0xd9, 0xb2, 0x05,
+-      0x01, 0x9c, 0xe5, 0x6d,
++      0x01, 0xa4, 0xe5, 0x6d,
+       0x00, 0xe2, 0x30, 0x5c,
+       0x00, 0xe2, 0x34, 0x5d,
+-      0x01, 0xae, 0x5d, 0x1b,
++      0x01, 0x90, 0x21, 0x1b,
+       0x01, 0xd9, 0xb2, 0x05,
+-      0x00, 0xe2, 0x32, 0x5b,
+-      0xf3, 0xac, 0xd5, 0x19,
++      0x00, 0xe2, 0x34, 0x5b,
++      0xf3, 0x96, 0xd5, 0x19,
+       0x00, 0xe2, 0x18, 0x55,
+-      0x80, 0xac, 0x19, 0x6d,
+-      0x0f, 0xea, 0x50, 0x59,
++      0x80, 0x96, 0x19, 0x6d,
++      0x0f, 0xea, 0x46, 0x59,
+       0x0f, 0xea, 0x04, 0x00,
+       0x00, 0xe2, 0x20, 0x45,
+       0x04, 0x8c, 0xe1, 0x30,
+       0x01, 0xea, 0xf2, 0x00,
+       0x02, 0xea, 0x36, 0x00,
+       0xa8, 0xea, 0x32, 0x00,
+-      0xff, 0xad, 0x27, 0x7d,
+-      0x14, 0xea, 0x50, 0x59,
++      0xff, 0x97, 0x27, 0x7d,
++      0x14, 0xea, 0x46, 0x59,
+       0x14, 0xea, 0x04, 0x00,
+       0x00, 0xe2, 0x96, 0x5d,
+       0x01, 0xd9, 0xb2, 0x05,
+@@ -673,14 +673,14 @@ static uint8_t seqprog[] = {
+       0x00, 0xe2, 0x8e, 0x5d,
+       0x01, 0xd9, 0xb2, 0x05,
+       0x02, 0xa6, 0x44, 0x7d,
+-      0x00, 0xe2, 0x3e, 0x59,
++      0x00, 0xe2, 0x34, 0x59,
+       0x20, 0x5b, 0x52, 0x6d,
+       0xfc, 0x42, 0x3e, 0x7d,
+       0x10, 0x40, 0x40, 0x6d,
+       0x20, 0x4d, 0x42, 0x7d,
+       0x08, 0x5d, 0x52, 0x6d,
+       0x02, 0xa6, 0xe6, 0x6b,
+-      0x00, 0xe2, 0x3e, 0x59,
++      0x00, 0xe2, 0x34, 0x59,
+       0x20, 0x5b, 0x52, 0x6d,
+       0x01, 0x1b, 0x72, 0x6d,
+       0xfc, 0x42, 0x4e, 0x7d,
+@@ -690,22 +690,22 @@ static uint8_t seqprog[] = {
+       0x02, 0x19, 0x32, 0x00,
+       0x01, 0x5b, 0x40, 0x31,
+       0x00, 0xe2, 0xb2, 0x5c,
+-      0x00, 0xe2, 0x9e, 0x5b,
++      0x00, 0xe2, 0xa2, 0x5b,
+       0x20, 0xea, 0xb6, 0x00,
+       0x00, 0xe2, 0xe0, 0x5b,
+       0x20, 0x5c, 0xb8, 0x00,
+       0x04, 0x19, 0x68, 0x6d,
+       0x01, 0x1a, 0x68, 0x6d,
+-      0x00, 0xe2, 0x3e, 0x59,
++      0x00, 0xe2, 0x34, 0x59,
+       0x01, 0x1a, 0x64, 0x78,
+       0x80, 0xf9, 0xf2, 0x01,
+       0x20, 0xa0, 0xcc, 0x7d,
+-      0xff, 0xae, 0x5d, 0x1b,
+-      0x08, 0xa8, 0x43, 0x6b,
++      0xff, 0x90, 0x21, 0x1b,
++      0x08, 0x92, 0x45, 0x6b,
+       0x02, 0xea, 0xb4, 0x04,
+-      0x01, 0x9c, 0x39, 0x03,
++      0x01, 0xa4, 0x49, 0x03,
+       0x40, 0x5b, 0x82, 0x6d,
+-      0x00, 0xe2, 0x3e, 0x59,
++      0x00, 0xe2, 0x34, 0x59,
+       0x40, 0x5b, 0x82, 0x6d,
+       0x04, 0x5d, 0xe6, 0x7d,
+       0x01, 0x1a, 0xe6, 0x7d,
+@@ -714,14 +714,14 @@ static uint8_t seqprog[] = {
+       0x04, 0x5d, 0xe6, 0x7d,
+       0x01, 0x1a, 0xe6, 0x7d,
+       0x80, 0xf9, 0xf2, 0x01,
+-      0xff, 0xae, 0x5d, 0x1b,
+-      0x08, 0xa8, 0x43, 0x6b,
++      0xff, 0x90, 0x21, 0x1b,
++      0x08, 0x92, 0x45, 0x6b,
+       0x02, 0xea, 0xb4, 0x04,
+-      0x00, 0xe2, 0x3e, 0x59,
++      0x00, 0xe2, 0x34, 0x59,
+       0x01, 0x1b, 0x64, 0x78,
+       0x80, 0xf9, 0xf2, 0x01,
+       0x02, 0xea, 0xb4, 0x04,
+-      0x00, 0xe2, 0x3e, 0x59,
++      0x00, 0xe2, 0x34, 0x59,
+       0x01, 0x1b, 0xaa, 0x6d,
+       0x40, 0x5b, 0xb8, 0x7d,
+       0x01, 0x1b, 0xaa, 0x6d,
+@@ -729,45 +729,45 @@ static uint8_t seqprog[] = {
+       0x01, 0x1a, 0x64, 0x78,
+       0x80, 0xf9, 0xf2, 0x01,
+       0xff, 0xea, 0x10, 0x03,
+-      0x08, 0xa8, 0x51, 0x03,
+-      0x00, 0xe2, 0x42, 0x43,
++      0x08, 0x92, 0x25, 0x03,
++      0x00, 0xe2, 0x44, 0x43,
+       0x01, 0x1a, 0xb4, 0x7d,
+       0x40, 0x5b, 0xb0, 0x7d,
+       0x01, 0x1a, 0x9e, 0x6d,
+       0xfc, 0x42, 0x64, 0x78,
+       0x01, 0x1a, 0xb8, 0x6d,
+-      0x10, 0xea, 0x50, 0x59,
++      0x10, 0xea, 0x46, 0x59,
+       0x10, 0xea, 0x04, 0x00,
+       0xfc, 0x42, 0x64, 0x78,
+       0x10, 0x40, 0xbe, 0x6d,
+       0x20, 0x4d, 0x64, 0x78,
+       0x40, 0x5b, 0x9e, 0x6d,
+       0x01, 0x1a, 0x64, 0x78,
+-      0x01, 0xae, 0x5d, 0x1b,
++      0x01, 0x90, 0x21, 0x1b,
+       0x30, 0x3f, 0xc0, 0x09,
+       0x30, 0xe0, 0x64, 0x60,
+       0x40, 0x4b, 0x64, 0x68,
+       0xff, 0xea, 0x52, 0x01,
+-      0xee, 0x00, 0xd2, 0x6d,
++      0xee, 0x00, 0xd4, 0x6d,
+       0x80, 0xf9, 0xf2, 0x01,
+-      0xff, 0xae, 0x5d, 0x1b,
++      0xff, 0x90, 0x21, 0x1b,
+       0x02, 0xea, 0xb4, 0x00,
+       0x20, 0xea, 0x9a, 0x00,
+       0xf3, 0x42, 0xde, 0x6d,
+-      0x12, 0xea, 0x50, 0x59,
++      0x12, 0xea, 0x46, 0x59,
+       0x12, 0xea, 0x04, 0x00,
+-      0x00, 0xe2, 0xf8, 0x41,
+-      0x0d, 0xea, 0x50, 0x59,
++      0x00, 0xe2, 0xf6, 0x41,
++      0x0d, 0xea, 0x46, 0x59,
+       0x0d, 0xea, 0x04, 0x00,
+-      0x00, 0xe2, 0xf8, 0x41,
+-      0x01, 0xae, 0x5d, 0x1b,
+-      0x11, 0xea, 0x50, 0x59,
++      0x00, 0xe2, 0xf6, 0x41,
++      0x01, 0x90, 0x21, 0x1b,
++      0x11, 0xea, 0x46, 0x59,
+       0x11, 0xea, 0x04, 0x00,
+-      0x00, 0xe2, 0x32, 0x5b,
++      0x00, 0xe2, 0x34, 0x5b,
+       0x08, 0x5a, 0xb4, 0x00,
+       0x00, 0xe2, 0x0c, 0x5e,
+       0xa8, 0xea, 0x32, 0x00,
+-      0x00, 0xe2, 0x3e, 0x59,
++      0x00, 0xe2, 0x34, 0x59,
+       0x80, 0x1a, 0xfa, 0x7d,
+       0x00, 0xe2, 0x0c, 0x5e,
+       0x80, 0x19, 0x32, 0x00,
+@@ -776,9 +776,9 @@ static uint8_t seqprog[] = {
+       0x20, 0x4d, 0x64, 0x78,
+       0x02, 0x84, 0x09, 0x03,
+       0x40, 0x5b, 0xcc, 0x7d,
+-      0xff, 0xae, 0x5d, 0x1b,
++      0xff, 0x90, 0x21, 0x1b,
+       0x80, 0xf9, 0xf2, 0x01,
+-      0x08, 0xa8, 0x43, 0x6b,
++      0x08, 0x92, 0x45, 0x6b,
+       0x02, 0xea, 0xb4, 0x04,
+       0x01, 0x38, 0xe1, 0x30,
+       0x05, 0x39, 0xe3, 0x98,
+@@ -794,12 +794,20 @@ static uint8_t seqprog[] = {
+ };
+ typedef int ahd_patch_func_t (struct ahd_softc *ahd);
++static ahd_patch_func_t ahd_patch23_func;
++
++static int
++ahd_patch23_func(struct ahd_softc *ahd)
++{
++      return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0);
++}
++
+ static ahd_patch_func_t ahd_patch22_func;
+ static int
+ ahd_patch22_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0);
++      return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0);
+ }
+ static ahd_patch_func_t ahd_patch21_func;
+@@ -807,7 +815,7 @@ static ahd_patch_func_t ahd_patch21_func
+ static int
+ ahd_patch21_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0);
++      return ((ahd->features & AHD_RTI) == 0);
+ }
+ static ahd_patch_func_t ahd_patch20_func;
+@@ -815,7 +823,7 @@ static ahd_patch_func_t ahd_patch20_func
+ static int
+ ahd_patch20_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->features & AHD_RTI) == 0);
++      return ((ahd->flags & AHD_INITIATORROLE) != 0);
+ }
+ static ahd_patch_func_t ahd_patch19_func;
+@@ -823,7 +831,7 @@ static ahd_patch_func_t ahd_patch19_func
+ static int
+ ahd_patch19_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->flags & AHD_INITIATORROLE) != 0);
++      return ((ahd->flags & AHD_TARGETROLE) != 0);
+ }
+ static ahd_patch_func_t ahd_patch18_func;
+@@ -831,7 +839,7 @@ static ahd_patch_func_t ahd_patch18_func
+ static int
+ ahd_patch18_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->flags & AHD_TARGETROLE) != 0);
++      return ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0);
+ }
+ static ahd_patch_func_t ahd_patch17_func;
+@@ -839,7 +847,7 @@ static ahd_patch_func_t ahd_patch17_func
+ static int
+ ahd_patch17_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0);
++      return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0);
+ }
+ static ahd_patch_func_t ahd_patch16_func;
+@@ -847,7 +855,7 @@ static ahd_patch_func_t ahd_patch16_func
+ static int
+ ahd_patch16_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0);
++      return ((ahd->flags & AHD_39BIT_ADDRESSING) != 0);
+ }
+ static ahd_patch_func_t ahd_patch15_func;
+@@ -855,7 +863,7 @@ static ahd_patch_func_t ahd_patch15_func
+ static int
+ ahd_patch15_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->flags & AHD_39BIT_ADDRESSING) != 0);
++      return ((ahd->flags & AHD_64BIT_ADDRESSING) != 0);
+ }
+ static ahd_patch_func_t ahd_patch14_func;
+@@ -863,7 +871,7 @@ static ahd_patch_func_t ahd_patch14_func
+ static int
+ ahd_patch14_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->flags & AHD_64BIT_ADDRESSING) != 0);
++      return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) == 0);
+ }
+ static ahd_patch_func_t ahd_patch13_func;
+@@ -871,7 +879,7 @@ static ahd_patch_func_t ahd_patch13_func
+ static int
+ ahd_patch13_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) == 0);
++      return ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0);
+ }
+ static ahd_patch_func_t ahd_patch12_func;
+@@ -879,7 +887,7 @@ static ahd_patch_func_t ahd_patch12_func
+ static int
+ ahd_patch12_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0);
++      return ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0);
+ }
+ static ahd_patch_func_t ahd_patch11_func;
+@@ -887,7 +895,7 @@ static ahd_patch_func_t ahd_patch11_func
+ static int
+ ahd_patch11_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0);
++      return ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0);
+ }
+ static ahd_patch_func_t ahd_patch10_func;
+@@ -895,7 +903,7 @@ static ahd_patch_func_t ahd_patch10_func
+ static int
+ ahd_patch10_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0);
++      return ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0);
+ }
+ static ahd_patch_func_t ahd_patch9_func;
+@@ -903,7 +911,7 @@ static ahd_patch_func_t ahd_patch9_func;
+ static int
+ ahd_patch9_func(struct ahd_softc *ahd)
+ {
+-      return ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0);
++      return ((ahd->features & AHD_FAST_CDB_DELIVERY) != 0);
+ }
+ static ahd_patch_func_t ahd_patch8_func;
+@@ -1003,73 +1011,75 @@ static struct patch {
+       { ahd_patch0_func, 48, 1, 1 },
+       { ahd_patch2_func, 51, 1, 2 },
+       { ahd_patch0_func, 52, 1, 1 },
++      { ahd_patch2_func, 61, 1, 2 },
++      { ahd_patch0_func, 62, 1, 1 },
+       { ahd_patch2_func, 65, 1, 2 },
+       { ahd_patch0_func, 66, 1, 1 },
+-      { ahd_patch2_func, 69, 1, 2 },
+-      { ahd_patch0_func, 70, 1, 1 },
+-      { ahd_patch1_func, 73, 1, 2 },
+-      { ahd_patch0_func, 74, 1, 1 },
+-      { ahd_patch4_func, 107, 1, 1 },
+-      { ahd_patch2_func, 162, 6, 1 },
+-      { ahd_patch1_func, 168, 2, 1 },
+-      { ahd_patch5_func, 170, 1, 1 },
+-      { ahd_patch2_func, 179, 1, 2 },
+-      { ahd_patch0_func, 180, 1, 1 },
+-      { ahd_patch6_func, 181, 2, 2 },
+-      { ahd_patch0_func, 183, 6, 3 },
+-      { ahd_patch2_func, 186, 1, 2 },
+-      { ahd_patch0_func, 187, 1, 1 },
+-      { ahd_patch2_func, 190, 1, 2 },
+-      { ahd_patch0_func, 191, 1, 1 },
+-      { ahd_patch7_func, 193, 2, 1 },
+-      { ahd_patch5_func, 201, 16, 2 },
+-      { ahd_patch0_func, 217, 1, 1 },
+-      { ahd_patch8_func, 237, 2, 1 },
+-      { ahd_patch1_func, 241, 1, 2 },
+-      { ahd_patch0_func, 242, 1, 1 },
+-      { ahd_patch7_func, 245, 2, 1 },
+-      { ahd_patch1_func, 259, 1, 2 },
+-      { ahd_patch0_func, 260, 1, 1 },
+-      { ahd_patch1_func, 263, 1, 2 },
+-      { ahd_patch0_func, 264, 1, 1 },
+-      { ahd_patch2_func, 267, 1, 2 },
+-      { ahd_patch0_func, 268, 1, 1 },
+-      { ahd_patch1_func, 323, 1, 2 },
+-      { ahd_patch0_func, 324, 1, 1 },
+-      { ahd_patch2_func, 332, 1, 2 },
+-      { ahd_patch0_func, 333, 1, 1 },
+-      { ahd_patch2_func, 336, 1, 2 },
+-      { ahd_patch0_func, 337, 1, 1 },
+-      { ahd_patch1_func, 343, 1, 2 },
+-      { ahd_patch0_func, 344, 1, 1 },
+-      { ahd_patch1_func, 346, 1, 2 },
+-      { ahd_patch0_func, 347, 1, 1 },
+-      { ahd_patch9_func, 366, 1, 1 },
+-      { ahd_patch9_func, 369, 1, 1 },
+-      { ahd_patch9_func, 371, 1, 1 },
+-      { ahd_patch9_func, 383, 1, 1 },
+-      { ahd_patch1_func, 393, 1, 2 },
+-      { ahd_patch0_func, 394, 1, 1 },
+-      { ahd_patch1_func, 396, 1, 2 },
+-      { ahd_patch0_func, 397, 1, 1 },
+-      { ahd_patch1_func, 405, 1, 2 },
+-      { ahd_patch0_func, 406, 1, 1 },
+-      { ahd_patch2_func, 419, 1, 2 },
+-      { ahd_patch0_func, 420, 1, 1 },
+-      { ahd_patch10_func, 450, 1, 1 },
+-      { ahd_patch1_func, 457, 1, 2 },
+-      { ahd_patch0_func, 458, 1, 1 },
+-      { ahd_patch2_func, 470, 1, 2 },
+-      { ahd_patch0_func, 471, 1, 1 },
+-      { ahd_patch11_func, 476, 6, 2 },
++      { ahd_patch4_func, 102, 1, 1 },
++      { ahd_patch2_func, 157, 6, 1 },
++      { ahd_patch1_func, 163, 2, 1 },
++      { ahd_patch5_func, 165, 1, 1 },
++      { ahd_patch2_func, 174, 1, 2 },
++      { ahd_patch0_func, 175, 1, 1 },
++      { ahd_patch6_func, 176, 2, 2 },
++      { ahd_patch0_func, 178, 6, 3 },
++      { ahd_patch2_func, 181, 1, 2 },
++      { ahd_patch0_func, 182, 1, 1 },
++      { ahd_patch2_func, 185, 1, 2 },
++      { ahd_patch0_func, 186, 1, 1 },
++      { ahd_patch3_func, 188, 1, 1 },
++      { ahd_patch7_func, 189, 3, 1 },
++      { ahd_patch3_func, 198, 1, 1 },
++      { ahd_patch5_func, 199, 16, 2 },
++      { ahd_patch0_func, 215, 1, 1 },
++      { ahd_patch8_func, 235, 2, 1 },
++      { ahd_patch1_func, 239, 1, 2 },
++      { ahd_patch0_func, 240, 1, 1 },
++      { ahd_patch7_func, 243, 3, 1 },
++      { ahd_patch1_func, 258, 1, 2 },
++      { ahd_patch0_func, 259, 1, 1 },
++      { ahd_patch1_func, 262, 1, 2 },
++      { ahd_patch0_func, 263, 1, 1 },
++      { ahd_patch2_func, 266, 1, 2 },
++      { ahd_patch0_func, 267, 1, 1 },
++      { ahd_patch9_func, 280, 2, 2 },
++      { ahd_patch0_func, 282, 1, 1 },
++      { ahd_patch1_func, 324, 1, 2 },
++      { ahd_patch0_func, 325, 1, 1 },
++      { ahd_patch2_func, 333, 1, 2 },
++      { ahd_patch0_func, 334, 1, 1 },
++      { ahd_patch2_func, 337, 1, 2 },
++      { ahd_patch0_func, 338, 1, 1 },
++      { ahd_patch1_func, 344, 1, 2 },
++      { ahd_patch0_func, 345, 1, 1 },
++      { ahd_patch1_func, 347, 1, 2 },
++      { ahd_patch0_func, 348, 1, 1 },
++      { ahd_patch10_func, 367, 1, 1 },
++      { ahd_patch10_func, 370, 1, 1 },
++      { ahd_patch10_func, 372, 1, 1 },
++      { ahd_patch10_func, 384, 1, 1 },
++      { ahd_patch1_func, 394, 1, 2 },
++      { ahd_patch0_func, 395, 1, 1 },
++      { ahd_patch1_func, 397, 1, 2 },
++      { ahd_patch0_func, 398, 1, 1 },
++      { ahd_patch1_func, 406, 1, 2 },
++      { ahd_patch0_func, 407, 1, 1 },
++      { ahd_patch2_func, 420, 1, 2 },
++      { ahd_patch0_func, 421, 1, 1 },
++      { ahd_patch11_func, 451, 1, 1 },
++      { ahd_patch1_func, 459, 1, 2 },
++      { ahd_patch0_func, 460, 1, 1 },
++      { ahd_patch2_func, 472, 1, 2 },
++      { ahd_patch0_func, 473, 1, 1 },
++      { ahd_patch12_func, 476, 6, 2 },
+       { ahd_patch0_func, 482, 1, 1 },
+-      { ahd_patch12_func, 505, 1, 1 },
+-      { ahd_patch13_func, 514, 1, 1 },
+-      { ahd_patch14_func, 515, 1, 2 },
++      { ahd_patch13_func, 505, 1, 1 },
++      { ahd_patch14_func, 514, 1, 1 },
++      { ahd_patch15_func, 515, 1, 2 },
+       { ahd_patch0_func, 516, 1, 1 },
+-      { ahd_patch15_func, 519, 1, 1 },
+-      { ahd_patch14_func, 520, 1, 1 },
+-      { ahd_patch16_func, 531, 1, 2 },
++      { ahd_patch16_func, 519, 1, 1 },
++      { ahd_patch15_func, 520, 1, 1 },
++      { ahd_patch17_func, 531, 1, 2 },
+       { ahd_patch0_func, 532, 1, 1 },
+       { ahd_patch1_func, 551, 1, 2 },
+       { ahd_patch0_func, 552, 1, 1 },
+@@ -1083,25 +1093,25 @@ static struct patch {
+       { ahd_patch0_func, 569, 1, 1 },
+       { ahd_patch2_func, 580, 1, 2 },
+       { ahd_patch0_func, 581, 1, 1 },
+-      { ahd_patch17_func, 585, 1, 1 },
+-      { ahd_patch18_func, 590, 1, 1 },
+-      { ahd_patch19_func, 591, 2, 1 },
+-      { ahd_patch18_func, 595, 1, 2 },
++      { ahd_patch18_func, 585, 1, 1 },
++      { ahd_patch19_func, 590, 1, 1 },
++      { ahd_patch20_func, 591, 2, 1 },
++      { ahd_patch19_func, 595, 1, 2 },
+       { ahd_patch0_func, 596, 1, 1 },
+       { ahd_patch2_func, 599, 1, 2 },
+       { ahd_patch0_func, 600, 1, 1 },
+       { ahd_patch2_func, 615, 1, 2 },
+       { ahd_patch0_func, 616, 1, 1 },
+-      { ahd_patch20_func, 617, 14, 1 },
++      { ahd_patch21_func, 617, 14, 1 },
+       { ahd_patch1_func, 635, 1, 2 },
+       { ahd_patch0_func, 636, 1, 1 },
+-      { ahd_patch20_func, 637, 1, 1 },
++      { ahd_patch21_func, 637, 1, 1 },
+       { ahd_patch1_func, 649, 1, 2 },
+       { ahd_patch0_func, 650, 1, 1 },
+       { ahd_patch1_func, 657, 1, 2 },
+       { ahd_patch0_func, 658, 1, 1 },
+-      { ahd_patch17_func, 681, 1, 1 },
+-      { ahd_patch17_func, 719, 1, 1 },
++      { ahd_patch18_func, 681, 1, 1 },
++      { ahd_patch18_func, 719, 1, 1 },
+       { ahd_patch1_func, 730, 1, 2 },
+       { ahd_patch0_func, 731, 1, 1 },
+       { ahd_patch1_func, 748, 1, 2 },
+@@ -1110,11 +1120,11 @@ static struct patch {
+       { ahd_patch0_func, 752, 1, 1 },
+       { ahd_patch1_func, 755, 1, 2 },
+       { ahd_patch0_func, 756, 1, 1 },
+-      { ahd_patch21_func, 758, 1, 2 },
++      { ahd_patch22_func, 758, 1, 2 },
+       { ahd_patch0_func, 759, 2, 1 },
+-      { ahd_patch22_func, 762, 4, 2 },
++      { ahd_patch23_func, 762, 4, 2 },
+       { ahd_patch0_func, 766, 1, 1 },
+-      { ahd_patch22_func, 774, 11, 1 }
++      { ahd_patch23_func, 774, 11, 1 }
+ };
+ static struct cs {
+@@ -1123,15 +1133,18 @@ static struct cs {
+ } critical_sections[] = {
+       { 11, 12 },
+       { 13, 14 },
+-      { 29, 42 },
+-      { 56, 59 },
+-      { 101, 128 },
+-      { 129, 157 },
+-      { 159, 162 },
+-      { 170, 178 },
+-      { 201, 250 },
+-      { 681, 697 },
+-      { 697, 711 },
++      { 31, 42 },
++      { 45, 47 },
++      { 49, 50 },
++      { 56, 78 },
++      { 96, 123 },
++      { 124, 152 },
++      { 154, 157 },
++      { 165, 173 },
++      { 198, 249 },
++      { 428, 430 },
++      { 433, 436 },
++      { 681, 711 },
+       { 721, 725 }
+ };
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx_93cx6.c   2003-06-14 12:18:35.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx_93cx6.c    2003-12-28 23:21:39.000000000 -0800
+@@ -28,9 +28,7 @@
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#17 $
+- *
+- * $FreeBSD$
++ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#19 $
+  */
+ /*
+@@ -64,7 +62,6 @@
+  *   is preceded by an initial zero (leading 0, followed by 16-bits, MSB
+  *   first).  The clock cycling from low to high initiates the next data
+  *   bit to be sent from the chip.
+- *
+  */
+ #ifdef __linux__
+@@ -72,6 +69,8 @@
+ #include "aic7xxx_inline.h"
+ #include "aic7xxx_93cx6.h"
+ #else
++#include <sys/cdefs.h>
++__FBSDID("$FreeBSD$");
+ #include <dev/aic7xxx/aic7xxx_osm.h>
+ #include <dev/aic7xxx/aic7xxx_inline.h>
+ #include <dev/aic7xxx/aic7xxx_93cx6.h>
+@@ -81,14 +80,22 @@
+  * Right now, we only have to read the SEEPROM.  But we make it easier to
+  * add other 93Cx6 functions.
+  */
+-static struct seeprom_cmd {
++struct seeprom_cmd {
+       uint8_t len;
+-      uint8_t bits[9];
+-} seeprom_read = {3, {1, 1, 0}};
++      uint8_t bits[11];
++};
++/* Short opcodes for the c46 */
+ static struct seeprom_cmd seeprom_ewen = {9, {1, 0, 0, 1, 1, 0, 0, 0, 0}};
+ static struct seeprom_cmd seeprom_ewds = {9, {1, 0, 0, 0, 0, 0, 0, 0, 0}};
++
++/* Long opcodes for the C56/C66 */
++static struct seeprom_cmd seeprom_long_ewen = {11, {1, 0, 0, 1, 1, 0, 0, 0, 0}};
++static struct seeprom_cmd seeprom_long_ewds = {11, {1, 0, 0, 0, 0, 0, 0, 0, 0}};
++
++/* Common opcodes */
+ static struct seeprom_cmd seeprom_write = {3, {1, 0, 1}};
++static struct seeprom_cmd seeprom_read  = {3, {1, 1, 0}};
+ /*
+  * Wait for the SEERDY to go high; about 800 ns.
+@@ -222,12 +229,25 @@ int
+ ahc_write_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
+                 u_int start_addr, u_int count)
+ {
++      struct seeprom_cmd *ewen, *ewds;
+       uint16_t v;
+       uint8_t temp;
+       int i, k;
+       /* Place the chip into write-enable mode */
+-      send_seeprom_cmd(sd, &seeprom_ewen);
++      if (sd->sd_chip == C46) {
++              ewen = &seeprom_ewen;
++              ewds = &seeprom_ewds;
++      } else if (sd->sd_chip == C56_66) {
++              ewen = &seeprom_long_ewen;
++              ewds = &seeprom_long_ewds;
++      } else {
++              printf("ahc_write_seeprom: unsupported seeprom type %d\n",
++                     sd->sd_chip);
++              return (0);
++      }
++
++      send_seeprom_cmd(sd, ewen);
+       reset_seeprom(sd);
+       /* Write all requested data out to the seeprom. */
+@@ -277,7 +297,7 @@ ahc_write_seeprom(struct seeprom_descrip
+       }
+       /* Put the chip back into write-protect mode */
+-      send_seeprom_cmd(sd, &seeprom_ewds);
++      send_seeprom_cmd(sd, ewds);
+       reset_seeprom(sd);
+       return (1);
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx_core.c    2003-06-14 12:18:09.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx_core.c     2003-12-28 23:21:39.000000000 -0800
+@@ -37,9 +37,7 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#131 $
+- *
+- * $FreeBSD$
++ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#147 $
+  */
+ #ifdef __linux__
+@@ -47,6 +45,8 @@
+ #include "aic7xxx_inline.h"
+ #include "aicasm/aicasm_insformat.h"
+ #else
++#include <sys/cdefs.h>
++__FBSDID("$FreeBSD$");
+ #include <dev/aic7xxx/aic7xxx_osm.h>
+ #include <dev/aic7xxx/aic7xxx_inline.h>
+ #include <dev/aic7xxx/aicasm/aicasm_insformat.h>
+@@ -320,7 +320,7 @@ ahc_run_qoutfifo(struct ahc_softc *ahc)
+                        */
+                       modnext = ahc->qoutfifonext & ~0x3;
+                       *((uint32_t *)(&ahc->qoutfifo[modnext])) = 0xFFFFFFFFUL;
+-                      ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
++                      aic_dmamap_sync(ahc, ahc->shared_data_dmat,
+                                       ahc->shared_data_dmamap,
+                                       /*offset*/modnext, /*len*/4,
+                                       BUS_DMASYNC_PREREAD);
+@@ -458,14 +458,14 @@ ahc_handle_seqint(struct ahc_softc *ahc,
+                        * complete.
+                        */
+                       scb->flags &= ~SCB_SENSE;
+-                      ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
++                      aic_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
+                       break;
+               }
+-              ahc_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
++              aic_set_transaction_status(scb, CAM_SCSI_STATUS_ERROR);
+               /* Freeze the queue until the client sees the error. */
+               ahc_freeze_devq(ahc, scb);
+-              ahc_freeze_scb(scb);
+-              ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
++              aic_freeze_scb(scb);
++              aic_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
+               switch (hscb->shared_data.status.scsi_status) {
+               case SCSI_STATUS_OK:
+                       printf("%s: Interrupted for staus of 0???\n",
+@@ -487,7 +487,7 @@ ahc_handle_seqint(struct ahc_softc *ahc,
+                       }
+ #endif
+-                      if (ahc_perform_autosense(scb) == 0)
++                      if (aic_perform_autosense(scb) == 0)
+                               break;
+                       targ_info = ahc_fetch_transinfo(ahc,
+@@ -509,12 +509,12 @@ ahc_handle_seqint(struct ahc_softc *ahc,
+                       }
+ #endif
+                       sg->addr = ahc_get_sense_bufaddr(ahc, scb);
+-                      sg->len = ahc_get_sense_bufsize(ahc, scb);
++                      sg->len = aic_get_sense_bufsize(ahc, scb);
+                       sg->len |= AHC_DMA_LAST_SEG;
+                       /* Fixup byte order */
+-                      sg->addr = ahc_htole32(sg->addr);
+-                      sg->len = ahc_htole32(sg->len);
++                      sg->addr = aic_htole32(sg->addr);
++                      sg->len = aic_htole32(sg->len);
+                       sc->opcode = REQUEST_SENSE;
+                       sc->byte2 = 0;
+@@ -543,8 +543,8 @@ ahc_handle_seqint(struct ahc_softc *ahc,
+                        * errors will be reported before any data
+                        * phases occur.
+                        */
+-                      if (ahc_get_residual(scb) 
+-                       == ahc_get_transfer_length(scb)) {
++                      if (aic_get_residual(scb) 
++                       == aic_get_transfer_length(scb)) {
+                               ahc_update_neg_request(ahc, &devinfo,
+                                                      tstate, targ_info,
+                                                      AHC_NEG_IF_NON_ASYNC);
+@@ -558,7 +558,7 @@ ahc_handle_seqint(struct ahc_softc *ahc,
+                       hscb->dataptr = sg->addr; 
+                       hscb->datacnt = sg->len;
+                       hscb->sgptr = scb->sg_list_phys | SG_FULL_RESID;
+-                      hscb->sgptr = ahc_htole32(hscb->sgptr);
++                      hscb->sgptr = aic_htole32(hscb->sgptr);
+                       scb->sg_count = 1;
+                       scb->flags |= SCB_SENSE;
+                       ahc_qinfifo_requeue_tail(ahc, scb);
+@@ -567,7 +567,7 @@ ahc_handle_seqint(struct ahc_softc *ahc,
+                        * Ensure we have enough time to actually
+                        * retrieve the sense.
+                        */
+-                      ahc_scb_timer_reset(scb, 5 * 1000000);
++                      aic_scb_timer_reset(scb, 5 * 1000000);
+                       break;
+               }
+               default:
+@@ -768,7 +768,7 @@ ahc_handle_seqint(struct ahc_softc *ahc,
+                                       if ((ahc_inb(ahc, SCSISIGI)
+                                         & (CDI|MSGI)) != 0)
+                                               break;
+-                                      ahc_delay(100);
++                                      aic_delay(100);
+                               }
+                               ahc_outb(ahc, SXFRCTL1,
+                                        ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
+@@ -782,7 +782,7 @@ ahc_handle_seqint(struct ahc_softc *ahc,
+                                       scb_index = ahc_inb(ahc, SCB_TAG);
+                                       scb = ahc_lookup_scb(ahc, scb_index);
+                                       if (scb != NULL)
+-                                              ahc_set_transaction_status(scb,
++                                              aic_set_transaction_status(scb,
+                                                   CAM_UNCOR_PARITY);
+                                       ahc_reset_channel(ahc, devinfo.channel, 
+                                                         /*init reset*/TRUE);
+@@ -820,16 +820,16 @@ ahc_handle_seqint(struct ahc_softc *ahc,
+               ahc_print_path(ahc, scb);
+               printf("%s seen Data Phase.  Length = %ld.  NumSGs = %d.\n",
+                      ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't",
+-                     ahc_get_transfer_length(scb), scb->sg_count);
++                     aic_get_transfer_length(scb), scb->sg_count);
+               if (scb->sg_count > 0) {
+                       for (i = 0; i < scb->sg_count; i++) {
+                               printf("sg[%d] - Addr 0x%x%x : Length %d\n",
+                                      i,
+-                                     (ahc_le32toh(scb->sg_list[i].len) >> 24
++                                     (aic_le32toh(scb->sg_list[i].len) >> 24
+                                       & SG_HIGH_ADDR_BITS),
+-                                     ahc_le32toh(scb->sg_list[i].addr),
+-                                     ahc_le32toh(scb->sg_list[i].len)
++                                     aic_le32toh(scb->sg_list[i].addr),
++                                     aic_le32toh(scb->sg_list[i].len)
+                                      & AHC_SG_LEN_MASK);
+                       }
+               }
+@@ -839,12 +839,12 @@ ahc_handle_seqint(struct ahc_softc *ahc,
+                */
+               ahc_freeze_devq(ahc, scb);
+               if ((scb->flags & SCB_SENSE) == 0) {
+-                      ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
++                      aic_set_transaction_status(scb, CAM_DATA_RUN_ERR);
+               } else {
+                       scb->flags &= ~SCB_SENSE;
+-                      ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
++                      aic_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
+               }
+-              ahc_freeze_scb(scb);
++              aic_freeze_scb(scb);
+               if ((ahc->features & AHC_ULTRA2) != 0) {
+                       /*
+@@ -1188,7 +1188,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc
+                        */
+                       ahc_scb_devinfo(ahc, &devinfo, scb);
+                       ahc_force_renegotiation(ahc, &devinfo);
+-                      ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT);
++                      aic_set_transaction_status(scb, CAM_SEL_TIMEOUT);
+                       ahc_freeze_devq(ahc, scb);
+               }
+               ahc_outb(ahc, CLRINT, CLRSCSIINT);
+@@ -1270,7 +1270,7 @@ ahc_handle_scsiint(struct ahc_softc *ahc
+                                                 CAM_LUN_WILDCARD,
+                                                 SCB_LIST_NULL,
+                                                 ROLE_INITIATOR)) {
+-                                      ahc_set_transaction_status(scb, CAM_REQ_CMP);
++                                      aic_set_transaction_status(scb, CAM_REQ_CMP);
+                               }
+ #endif
+                               ahc_compile_devinfo(&devinfo,
+@@ -1304,17 +1304,23 @@ ahc_handle_scsiint(struct ahc_softc *ahc
+                               ahc_qinfifo_requeue_tail(ahc, scb);
+                               printerror = 0;
+                       } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
+-                                              MSG_EXT_WDTR, FALSE)
+-                              || ahc_sent_msg(ahc, AHCMSG_EXT,
+-                                              MSG_EXT_SDTR, FALSE)) {
++                                              MSG_EXT_WDTR, FALSE)) {
+                               /*
+-                               * Negotiation Rejected.  Go-async and
++                               * Negotiation Rejected.  Go-narrow and
+                                * retry command.
+                                */
+                               ahc_set_width(ahc, &devinfo,
+                                             MSG_EXT_WDTR_BUS_8_BIT,
+                                             AHC_TRANS_CUR|AHC_TRANS_GOAL,
+                                             /*paused*/TRUE);
++                              ahc_qinfifo_requeue_tail(ahc, scb);
++                              printerror = 0;
++                      } else if (ahc_sent_msg(ahc, AHCMSG_EXT,
++                                              MSG_EXT_SDTR, FALSE)) {
++                              /*
++                               * Negotiation Rejected.  Go-async and
++                               * retry command.
++                               */
+                               ahc_set_syncrate(ahc, &devinfo,
+                                               /*syncrate*/NULL,
+                                               /*period*/0, /*offset*/0,
+@@ -1463,7 +1469,7 @@ ahc_clear_critical_section(struct ahc_so
+                                * current connection, so we must
+                                * leave it on while single stepping.
+                                */
+-                              ahc_outb(ahc, SIMODE1, ENBUSFREE);
++                              ahc_outb(ahc, SIMODE1, simode1 & ENBUSFREE);
+                       else
+                               ahc_outb(ahc, SIMODE1, 0);
+                       ahc_outb(ahc, CLRINT, CLRSCSIINT);
+@@ -1476,7 +1482,7 @@ ahc_clear_critical_section(struct ahc_so
+               }
+               ahc_outb(ahc, HCNTRL, ahc->unpause);
+               while (!ahc_is_paused(ahc))
+-                      ahc_delay(200);
++                      aic_delay(200);
+       }
+       if (stepping) {
+               ahc_outb(ahc, SIMODE0, simode0);
+@@ -1524,18 +1530,18 @@ ahc_print_scb(struct scb *scb)
+       for (i = 0; i < sizeof(hscb->shared_data.cdb); i++)
+               printf("%#02x", hscb->shared_data.cdb[i]);
+       printf("        dataptr:%#x datacnt:%#x sgptr:%#x tag:%#x\n",
+-              ahc_le32toh(hscb->dataptr),
+-              ahc_le32toh(hscb->datacnt),
+-              ahc_le32toh(hscb->sgptr),
++              aic_le32toh(hscb->dataptr),
++              aic_le32toh(hscb->datacnt),
++              aic_le32toh(hscb->sgptr),
+               hscb->tag);
+       if (scb->sg_count > 0) {
+               for (i = 0; i < scb->sg_count; i++) {
+                       printf("sg[%d] - Addr 0x%x%x : Length %d\n",
+                              i,
+-                             (ahc_le32toh(scb->sg_list[i].len) >> 24
++                             (aic_le32toh(scb->sg_list[i].len) >> 24
+                               & SG_HIGH_ADDR_BITS),
+-                             ahc_le32toh(scb->sg_list[i].addr),
+-                             ahc_le32toh(scb->sg_list[i].len));
++                             aic_le32toh(scb->sg_list[i].addr),
++                             aic_le32toh(scb->sg_list[i].len));
+               }
+       }
+ }
+@@ -2373,6 +2379,7 @@ ahc_build_transfer_msg(struct ahc_softc 
+        * may change.
+        */
+       period = tinfo->goal.period;
++      offset = tinfo->goal.offset;
+       ppr_options = tinfo->goal.ppr_options;
+       /* Target initiated PPR is not allowed in the SCSI spec */
+       if (devinfo->role == ROLE_TARGET)
+@@ -2380,7 +2387,7 @@ ahc_build_transfer_msg(struct ahc_softc 
+       rate = ahc_devlimited_syncrate(ahc, tinfo, &period,
+                                      &ppr_options, devinfo->role);
+       dowide = tinfo->curr.width != tinfo->goal.width;
+-      dosync = tinfo->curr.period != period;
++      dosync = tinfo->curr.offset != offset || tinfo->curr.period != period;
+       /*
+        * Only use PPR if we have options that need it, even if the device
+        * claims to support it.  There might be an expander in the way
+@@ -2568,7 +2575,7 @@ ahc_handle_proto_violation(struct ahc_so
+               printf("No SCB found during protocol violation\n");
+               goto proto_violation_reset;
+       } else {
+-              ahc_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
++              aic_set_transaction_status(scb, CAM_SEQUENCE_FAIL);
+               if ((seq_flags & NO_CDB_SENT) != 0) {
+                       ahc_print_path(ahc, scb);
+                       printf("No or incomplete CDB sent to device.\n");
+@@ -3176,23 +3183,30 @@ ahc_parse_msg(struct ahc_softc *ahc, str
+                               response = TRUE;
+                               sending_reply = TRUE;
+                       }
++                      /*
++                       * After a wide message, we are async, but
++                       * some devices don't seem to honor this portion
++                       * of the spec.  Force a renegotiation of the
++                       * sync component of our transfer agreement even
++                       * if our goal is async.  By updating our width
++                       * after forcing the negotiation, we avoid
++                       * renegotiating for width.
++                       */
++                      ahc_update_neg_request(ahc, devinfo, tstate,
++                                             tinfo, AHC_NEG_ALWAYS);
+                       ahc_set_width(ahc, devinfo, bus_width,
+                                     AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
+                                     /*paused*/TRUE);
+-                      /* After a wide message, we are async */
+-                      ahc_set_syncrate(ahc, devinfo,
+-                                       /*syncrate*/NULL, /*period*/0,
+-                                       /*offset*/0, /*ppr_options*/0,
+-                                       AHC_TRANS_ACTIVE, /*paused*/TRUE);
+                       if (sending_reply == FALSE && reject == FALSE) {
+-                              if (tinfo->goal.offset) {
+-                                      ahc->msgout_index = 0;
+-                                      ahc->msgout_len = 0;
+-                                      ahc_build_transfer_msg(ahc, devinfo);
+-                                      ahc->msgout_index = 0;
+-                                      response = TRUE;
+-                              }
++                              /*
++                               * We will always have an SDTR to send.
++                               */
++                              ahc->msgout_index = 0;
++                              ahc->msgout_len = 0;
++                              ahc_build_transfer_msg(ahc, devinfo);
++                              ahc->msgout_index = 0;
++                              response = TRUE;
+                       }
+                       done = MSGLOOP_MSGCOMPLETE;
+                       break;
+@@ -3499,7 +3513,7 @@ ahc_handle_msg_reject(struct ahc_softc *
+               ahc_outb(ahc, SCB_CONTROL,
+                        ahc_inb(ahc, SCB_CONTROL) & mask);
+               scb->hscb->control &= mask;
+-              ahc_set_transaction_tag(scb, /*enabled*/FALSE,
++              aic_set_transaction_tag(scb, /*enabled*/FALSE,
+                                       /*type*/MSG_SIMPLE_TASK);
+               ahc_outb(ahc, MSG_OUT, MSG_IDENTIFYFLAG);
+               ahc_assert_atn(ahc);
+@@ -3556,7 +3570,7 @@ ahc_handle_ign_wide_residue(struct ahc_s
+        * Perhaps add datadir to some spare bits in the hscb?
+        */
+       if ((ahc_inb(ahc, SEQ_FLAGS) & DPHASE) == 0
+-       || ahc_get_transfer_dir(scb) != CAM_DIR_IN) {
++       || aic_get_transfer_dir(scb) != CAM_DIR_IN) {
+               /*
+                * Ignore the message if we haven't
+                * seen an appropriate data phase yet.
+@@ -3612,18 +3626,18 @@ ahc_handle_ign_wide_residue(struct ahc_s
+                        * to load so we must go back one.
+                        */
+                       sg--;
+-                      sglen = ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
++                      sglen = aic_le32toh(sg->len) & AHC_SG_LEN_MASK;
+                       if (sg != scb->sg_list
+                        && sglen < (data_cnt & AHC_SG_LEN_MASK)) {
+                               sg--;
+-                              sglen = ahc_le32toh(sg->len);
++                              sglen = aic_le32toh(sg->len);
+                               /*
+                                * Preserve High Address and SG_LIST bits
+                                * while setting the count to 1.
+                                */
+                               data_cnt = 1 | (sglen & (~AHC_SG_LEN_MASK));
+-                              data_addr = ahc_le32toh(sg->addr)
++                              data_addr = aic_le32toh(sg->addr)
+                                         + (sglen & AHC_SG_LEN_MASK) - 1;
+                               /*
+@@ -3679,8 +3693,8 @@ ahc_reinitialize_dataptrs(struct ahc_sof
+             | (ahc_inb(ahc, SCB_RESIDUAL_DATACNT + 1) << 8)
+             | ahc_inb(ahc, SCB_RESIDUAL_DATACNT);
+-      dataptr = ahc_le32toh(sg->addr)
+-              + (ahc_le32toh(sg->len) & AHC_SG_LEN_MASK)
++      dataptr = aic_le32toh(sg->addr)
++              + (aic_le32toh(sg->len) & AHC_SG_LEN_MASK)
+               - resid;
+       if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {
+               u_int dscommand1;
+@@ -3688,7 +3702,7 @@ ahc_reinitialize_dataptrs(struct ahc_sof
+               dscommand1 = ahc_inb(ahc, DSCOMMAND1);
+               ahc_outb(ahc, DSCOMMAND1, dscommand1 | HADDLDSEL0);
+               ahc_outb(ahc, HADDR,
+-                       (ahc_le32toh(sg->len) >> 24) & SG_HIGH_ADDR_BITS);
++                       (aic_le32toh(sg->len) >> 24) & SG_HIGH_ADDR_BITS);
+               ahc_outb(ahc, DSCOMMAND1, dscommand1);
+       }
+       ahc_outb(ahc, HADDR + 3, dataptr >> 24);
+@@ -3869,7 +3883,7 @@ ahc_softc_insert(struct ahc_softc *ahc)
+ {
+       struct ahc_softc *list_ahc;
+-#if AHC_PCI_CONFIG > 0
++#if AIC_PCI_CONFIG > 0
+       /*
+        * Second Function PCI devices need to inherit some
+        * settings from function 0.
+@@ -3877,17 +3891,17 @@ ahc_softc_insert(struct ahc_softc *ahc)
+       if ((ahc->chip & AHC_BUS_MASK) == AHC_PCI
+        && (ahc->features & AHC_MULTI_FUNC) != 0) {
+               TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
+-                      ahc_dev_softc_t list_pci;
+-                      ahc_dev_softc_t pci;
++                      aic_dev_softc_t list_pci;
++                      aic_dev_softc_t pci;
+                       list_pci = list_ahc->dev_softc;
+                       pci = ahc->dev_softc;
+-                      if (ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
+-                       && ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)) {
++                      if (aic_get_pci_slot(list_pci) == aic_get_pci_slot(pci)
++                       && aic_get_pci_bus(list_pci) == aic_get_pci_bus(pci)) {
+                               struct ahc_softc *master;
+                               struct ahc_softc *slave;
+-                              if (ahc_get_pci_function(list_pci) == 0) {
++                              if (aic_get_pci_function(list_pci) == 0) {
+                                       master = list_ahc;
+                                       slave = ahc;
+                               } else {
+@@ -3955,27 +3969,27 @@ ahc_free(struct ahc_softc *ahc)
+ {
+       int i;
++      ahc_terminate_recovery_thread(ahc);
+       switch (ahc->init_level) {
+       default:
+       case 5:
+               ahc_shutdown(ahc);
+-              TAILQ_REMOVE(&ahc_tailq, ahc, links);
+               /* FALLTHROUGH */
+       case 4:
+-              ahc_dmamap_unload(ahc, ahc->shared_data_dmat,
++              aic_dmamap_unload(ahc, ahc->shared_data_dmat,
+                                 ahc->shared_data_dmamap);
+               /* FALLTHROUGH */
+       case 3:
+-              ahc_dmamem_free(ahc, ahc->shared_data_dmat, ahc->qoutfifo,
++              aic_dmamem_free(ahc, ahc->shared_data_dmat, ahc->qoutfifo,
+                               ahc->shared_data_dmamap);
+-              ahc_dmamap_destroy(ahc, ahc->shared_data_dmat,
++              aic_dmamap_destroy(ahc, ahc->shared_data_dmat,
+                                  ahc->shared_data_dmamap);
+               /* FALLTHROUGH */
+       case 2:
+-              ahc_dma_tag_destroy(ahc, ahc->shared_data_dmat);
++              aic_dma_tag_destroy(ahc, ahc->shared_data_dmat);
+       case 1:
+ #ifndef __linux__
+-              ahc_dma_tag_destroy(ahc, ahc->buffer_dmat);
++              aic_dma_tag_destroy(ahc, ahc->buffer_dmat);
+ #endif
+               break;
+       case 0:
+@@ -3983,7 +3997,7 @@ ahc_free(struct ahc_softc *ahc)
+       }
+ #ifndef __linux__
+-      ahc_dma_tag_destroy(ahc, ahc->parent_dmat);
++      aic_dma_tag_destroy(ahc, ahc->parent_dmat);
+ #endif
+       ahc_platform_free(ahc);
+       ahc_fini_scbdata(ahc);
+@@ -4033,7 +4047,7 @@ ahc_shutdown(void *arg)
+       ahc = (struct ahc_softc *)arg;
+       /* This will reset most registers to 0, but not all */
+-      ahc_reset(ahc);
++      ahc_reset(ahc, /*reinit*/FALSE);
+       ahc_outb(ahc, SCSISEQ, 0);
+       ahc_outb(ahc, SXFRCTL0, 0);
+       ahc_outb(ahc, DSPCISTATUS, 0);
+@@ -4044,10 +4058,15 @@ ahc_shutdown(void *arg)
+ /*
+  * Reset the controller and record some information about it
+- * that is only available just after a reset.
++ * that is only available just after a reset.  If "reinit" is
++ * non-zero, this reset occured after initial configuration
++ * and the caller requests that the chip be fully reinitialized
++ * to a runable state.  Chip interrupts are *not* enabled after
++ * a reinitialization.  The caller must enable interrupts via
++ * ahc_intr_enable().
+  */
+ int
+-ahc_reset(struct ahc_softc *ahc)
++ahc_reset(struct ahc_softc *ahc, int reinit)
+ {
+       u_int   sblkctl;
+       u_int   sxfrctl1_a, sxfrctl1_b;
+@@ -4060,14 +4079,6 @@ ahc_reset(struct ahc_softc *ahc)
+        * to disturb the integrity of the bus.
+        */
+       ahc_pause(ahc);
+-      if ((ahc_inb(ahc, HCNTRL) & CHIPRST) != 0) {
+-              /*
+-               * The chip has not been initialized since
+-               * PCI/EISA/VLB bus reset.  Don't trust
+-               * "left over BIOS data".
+-               */
+-              ahc->flags |= AHC_NO_BIOS_INIT;
+-      }
+       sxfrctl1_b = 0;
+       if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
+               u_int sblkctl;
+@@ -4093,7 +4104,7 @@ ahc_reset(struct ahc_softc *ahc)
+        */
+       wait = 1000;
+       do {
+-              ahc_delay(1000);
++              aic_delay(1000);
+       } while (--wait && !(ahc_inb(ahc, HCNTRL) & CHIPRSTACK));
+       if (wait == 0) {
+@@ -4143,7 +4154,7 @@ ahc_reset(struct ahc_softc *ahc)
+       ahc_outb(ahc, SXFRCTL1, sxfrctl1_a);
+       error = 0;
+-      if (ahc->init_level > 0)
++      if (reinit != 0)
+               /*
+                * If a recovery action has forced a chip reset,
+                * re-initialize the chip to our liking.
+@@ -4273,7 +4284,7 @@ ahc_init_scbdata(struct ahc_softc *ahc)
+        */
+       /* DMA tag for our hardware scb structures */
+-      if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
++      if (aic_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
+                              /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+                              /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+                              /*highaddr*/BUS_SPACE_MAXADDR,
+@@ -4288,7 +4299,7 @@ ahc_init_scbdata(struct ahc_softc *ahc)
+       scb_data->init_level++;
+       /* Allocation for our hscbs */
+-      if (ahc_dmamem_alloc(ahc, scb_data->hscb_dmat,
++      if (aic_dmamem_alloc(ahc, scb_data->hscb_dmat,
+                            (void **)&scb_data->hscbs,
+                            BUS_DMA_NOWAIT, &scb_data->hscb_dmamap) != 0) {
+               goto error_exit;
+@@ -4297,7 +4308,7 @@ ahc_init_scbdata(struct ahc_softc *ahc)
+       scb_data->init_level++;
+       /* And permanently map them */
+-      ahc_dmamap_load(ahc, scb_data->hscb_dmat, scb_data->hscb_dmamap,
++      aic_dmamap_load(ahc, scb_data->hscb_dmat, scb_data->hscb_dmamap,
+                       scb_data->hscbs,
+                       AHC_SCB_MAX_ALLOC * sizeof(struct hardware_scb),
+                       ahc_dmamap_cb, &scb_data->hscb_busaddr, /*flags*/0);
+@@ -4305,7 +4316,7 @@ ahc_init_scbdata(struct ahc_softc *ahc)
+       scb_data->init_level++;
+       /* DMA tag for our sense buffers */
+-      if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
++      if (aic_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
+                              /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+                              /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+                              /*highaddr*/BUS_SPACE_MAXADDR,
+@@ -4320,7 +4331,7 @@ ahc_init_scbdata(struct ahc_softc *ahc)
+       scb_data->init_level++;
+       /* Allocate them */
+-      if (ahc_dmamem_alloc(ahc, scb_data->sense_dmat,
++      if (aic_dmamem_alloc(ahc, scb_data->sense_dmat,
+                            (void **)&scb_data->sense,
+                            BUS_DMA_NOWAIT, &scb_data->sense_dmamap) != 0) {
+               goto error_exit;
+@@ -4329,7 +4340,7 @@ ahc_init_scbdata(struct ahc_softc *ahc)
+       scb_data->init_level++;
+       /* And permanently map them */
+-      ahc_dmamap_load(ahc, scb_data->sense_dmat, scb_data->sense_dmamap,
++      aic_dmamap_load(ahc, scb_data->sense_dmat, scb_data->sense_dmamap,
+                       scb_data->sense,
+                       AHC_SCB_MAX_ALLOC * sizeof(struct scsi_sense_data),
+                       ahc_dmamap_cb, &scb_data->sense_busaddr, /*flags*/0);
+@@ -4337,7 +4348,7 @@ ahc_init_scbdata(struct ahc_softc *ahc)
+       scb_data->init_level++;
+       /* DMA tag for our S/G structures.  We allocate in page sized chunks */
+-      if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/8,
++      if (aic_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/8,
+                              /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+                              /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+                              /*highaddr*/BUS_SPACE_MAXADDR,
+@@ -4394,35 +4405,35 @@ ahc_fini_scbdata(struct ahc_softc *ahc)
+               while ((sg_map = SLIST_FIRST(&scb_data->sg_maps))!= NULL) {
+                       SLIST_REMOVE_HEAD(&scb_data->sg_maps, links);
+-                      ahc_dmamap_unload(ahc, scb_data->sg_dmat,
++                      aic_dmamap_unload(ahc, scb_data->sg_dmat,
+                                         sg_map->sg_dmamap);
+-                      ahc_dmamem_free(ahc, scb_data->sg_dmat,
++                      aic_dmamem_free(ahc, scb_data->sg_dmat,
+                                       sg_map->sg_vaddr,
+                                       sg_map->sg_dmamap);
+                       free(sg_map, M_DEVBUF);
+               }
+-              ahc_dma_tag_destroy(ahc, scb_data->sg_dmat);
++              aic_dma_tag_destroy(ahc, scb_data->sg_dmat);
+       }
+       case 6:
+-              ahc_dmamap_unload(ahc, scb_data->sense_dmat,
++              aic_dmamap_unload(ahc, scb_data->sense_dmat,
+                                 scb_data->sense_dmamap);
+       case 5:
+-              ahc_dmamem_free(ahc, scb_data->sense_dmat, scb_data->sense,
++              aic_dmamem_free(ahc, scb_data->sense_dmat, scb_data->sense,
+                               scb_data->sense_dmamap);
+-              ahc_dmamap_destroy(ahc, scb_data->sense_dmat,
++              aic_dmamap_destroy(ahc, scb_data->sense_dmat,
+                                  scb_data->sense_dmamap);
+       case 4:
+-              ahc_dma_tag_destroy(ahc, scb_data->sense_dmat);
++              aic_dma_tag_destroy(ahc, scb_data->sense_dmat);
+       case 3:
+-              ahc_dmamap_unload(ahc, scb_data->hscb_dmat,
++              aic_dmamap_unload(ahc, scb_data->hscb_dmat,
+                                 scb_data->hscb_dmamap);
+       case 2:
+-              ahc_dmamem_free(ahc, scb_data->hscb_dmat, scb_data->hscbs,
++              aic_dmamem_free(ahc, scb_data->hscb_dmat, scb_data->hscbs,
+                               scb_data->hscb_dmamap);
+-              ahc_dmamap_destroy(ahc, scb_data->hscb_dmat,
++              aic_dmamap_destroy(ahc, scb_data->hscb_dmat,
+                                  scb_data->hscb_dmamap);
+       case 1:
+-              ahc_dma_tag_destroy(ahc, scb_data->hscb_dmat);
++              aic_dma_tag_destroy(ahc, scb_data->hscb_dmat);
+               break;
+       case 0:
+               break;
+@@ -4455,7 +4466,7 @@ ahc_alloc_scbs(struct ahc_softc *ahc)
+               return;
+       /* Allocate S/G space for the next batch of SCBS */
+-      if (ahc_dmamem_alloc(ahc, scb_data->sg_dmat,
++      if (aic_dmamem_alloc(ahc, scb_data->sg_dmat,
+                            (void **)&sg_map->sg_vaddr,
+                            BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) {
+               free(sg_map, M_DEVBUF);
+@@ -4464,7 +4475,7 @@ ahc_alloc_scbs(struct ahc_softc *ahc)
+       SLIST_INSERT_HEAD(&scb_data->sg_maps, sg_map, links);
+-      ahc_dmamap_load(ahc, scb_data->sg_dmat, sg_map->sg_dmamap,
++      aic_dmamap_load(ahc, scb_data->sg_dmat, sg_map->sg_dmamap,
+                       sg_map->sg_vaddr, PAGE_SIZE, ahc_dmamap_cb,
+                       &sg_map->sg_physaddr, /*flags*/0);
+@@ -4491,9 +4502,9 @@ ahc_alloc_scbs(struct ahc_softc *ahc)
+                */
+               next_scb->sg_list_phys = physaddr + sizeof(struct ahc_dma_seg);
+               next_scb->ahc_softc = ahc;
+-              next_scb->flags = SCB_FREE;
++              next_scb->flags = SCB_FLAG_NONE;
+ #ifndef __linux__
+-              error = ahc_dmamap_create(ahc, ahc->buffer_dmat, /*flags*/0,
++              error = aic_dmamap_create(ahc, ahc->buffer_dmat, /*flags*/0,
+                                         &next_scb->dmamap);
+               if (error != 0)
+                       break;
+@@ -4725,14 +4736,12 @@ ahc_chip_init(struct ahc_softc *ahc)
+                * never settle, so don't complain if we
+                * fail here.
+                */
+-              ahc_pause(ahc);
+               for (wait = 5000;
+                    (ahc_inb(ahc, SBLKCTL) & (ENAB40|ENAB20)) == 0 && wait;
+                    wait--)
+-                      ahc_delay(100);
+-              ahc_unpause(ahc);
++                      aic_delay(100);
+       }
+-
++      ahc_restart(ahc);
+       return (0);
+ }
+@@ -4743,6 +4752,7 @@ int
+ ahc_init(struct ahc_softc *ahc)
+ {
+       int      max_targ;
++      int      error;
+       u_int    i;
+       u_int    scsi_conf;
+       u_int    ultraenb;
+@@ -4800,7 +4810,7 @@ ahc_init(struct ahc_softc *ahc)
+ #ifndef __linux__
+       /* DMA tag for mapping buffers into device visible space. */
+-      if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
++      if (aic_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
+                              /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+                              /*lowaddr*/ahc->flags & AHC_39BIT_ADDRESSING
+                                       ? (bus_addr_t)0x7FFFFFFFFFULL
+@@ -4831,7 +4841,7 @@ ahc_init(struct ahc_softc *ahc)
+       if ((ahc->features & AHC_TARGETMODE) != 0)
+               driver_data_size += AHC_TMODE_CMDS * sizeof(struct target_cmd)
+                                + /*DMA WideOdd Bug Buffer*/1;
+-      if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
++      if (aic_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1,
+                              /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1,
+                              /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+                              /*highaddr*/BUS_SPACE_MAXADDR,
+@@ -4846,7 +4856,7 @@ ahc_init(struct ahc_softc *ahc)
+       ahc->init_level++;
+       /* Allocation of driver data */
+-      if (ahc_dmamem_alloc(ahc, ahc->shared_data_dmat,
++      if (aic_dmamem_alloc(ahc, ahc->shared_data_dmat,
+                            (void **)&ahc->qoutfifo,
+                            BUS_DMA_NOWAIT, &ahc->shared_data_dmamap) != 0) {
+               return (ENOMEM);
+@@ -4855,7 +4865,7 @@ ahc_init(struct ahc_softc *ahc)
+       ahc->init_level++;
+       /* And permanently map it in */
+-      ahc_dmamap_load(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
++      aic_dmamap_load(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
+                       ahc->qoutfifo, driver_data_size, ahc_dmamap_cb,
+                       &ahc->shared_data_busaddr, /*flags*/0);
+@@ -4898,6 +4908,13 @@ ahc_init(struct ahc_softc *ahc)
+               }
+       }
++      /*
++       * Fire up a recovery thread for this controller.
++       */
++      error = ahc_spawn_recovery_thread(ahc);
++      if (error != 0)
++              return (error);
++
+       if (ahc->scb_data->maxhscbs < AHC_SCB_MAX_ALLOC) {
+               ahc->flags |= AHC_PAGESCBS;
+       } else {
+@@ -5095,8 +5112,14 @@ ahc_pause_and_flushwork(struct ahc_softc
+       ahc->flags |= AHC_ALL_INTERRUPTS;
+       paused = FALSE;
+       do {
+-              if (paused)
++              if (paused) {
+                       ahc_unpause(ahc);
++                      /*
++                       * Give the sequencer some time to service
++                       * any active selections.
++                       */
++                      aic_delay(200);
++              }
+               ahc_intr(ahc);
+               ahc_pause(ahc);
+               paused = TRUE;
+@@ -5145,7 +5168,9 @@ int
+ ahc_resume(struct ahc_softc *ahc)
+ {
+-      ahc_reset(ahc);
++      ahc_reset(ahc, /*reinit*/TRUE);
++      ahc_intr_enable(ahc, TRUE); 
++      ahc_restart(ahc);
+       return (0);
+ }
+@@ -5380,12 +5405,12 @@ ahc_search_qinfifo(struct ahc_softc *ahc
+                               cam_status ostat;
+                               cam_status cstat;
+-                              ostat = ahc_get_transaction_status(scb);
++                              ostat = aic_get_transaction_status(scb);
+                               if (ostat == CAM_REQ_INPROG)
+-                                      ahc_set_transaction_status(scb, status);
+-                              cstat = ahc_get_transaction_status(scb);
++                                      aic_set_transaction_status(scb, status);
++                              cstat = aic_get_transaction_status(scb);
+                               if (cstat != CAM_REQ_CMP)
+-                                      ahc_freeze_scb(scb);
++                                      aic_freeze_scb(scb);
+                               if ((scb->flags & SCB_ACTIVE) == 0)
+                                       printf("Inactive SCB in qinfifo\n");
+                               ahc_done(ahc, scb);
+@@ -5492,13 +5517,13 @@ ahc_search_qinfifo(struct ahc_softc *ahc
+                               cam_status ostat;
+                               cam_status cstat;
+-                              ostat = ahc_get_transaction_status(scb);
++                              ostat = aic_get_transaction_status(scb);
+                               if (ostat == CAM_REQ_INPROG)
+-                                      ahc_set_transaction_status(scb,
++                                      aic_set_transaction_status(scb,
+                                                                  status);
+-                              cstat = ahc_get_transaction_status(scb);
++                              cstat = aic_get_transaction_status(scb);
+                               if (cstat != CAM_REQ_CMP)
+-                                      ahc_freeze_scb(scb);
++                                      aic_freeze_scb(scb);
+                               if ((scb->flags & SCB_ACTIVE) == 0)
+                                       printf("Inactive SCB in Waiting List\n");
+                               ahc_done(ahc, scb);
+@@ -5520,7 +5545,7 @@ ahc_search_qinfifo(struct ahc_softc *ahc
+       }
+       ahc_outb(ahc, SCBPTR, curscbptr);
+-      found += ahc_search_untagged_queues(ahc, /*ahc_io_ctx_t*/NULL, target,
++      found += ahc_search_untagged_queues(ahc, /*aic_io_ctx_t*/NULL, target,
+                                           channel, lun, status, action);
+       if (action == SEARCH_COMPLETE)
+@@ -5529,7 +5554,7 @@ ahc_search_qinfifo(struct ahc_softc *ahc
+ }
+ int
+-ahc_search_untagged_queues(struct ahc_softc *ahc, ahc_io_ctx_t ctx,
++ahc_search_untagged_queues(struct ahc_softc *ahc, aic_io_ctx_t ctx,
+                          int target, char channel, int lun, uint32_t status,
+                          ahc_search_action action)
+ {
+@@ -5600,12 +5625,12 @@ ahc_search_untagged_queues(struct ahc_so
+                               cam_status ostat;
+                               cam_status cstat;
+-                              ostat = ahc_get_transaction_status(scb);
++                              ostat = aic_get_transaction_status(scb);
+                               if (ostat == CAM_REQ_INPROG)
+-                                      ahc_set_transaction_status(scb, status);
+-                              cstat = ahc_get_transaction_status(scb);
++                                      aic_set_transaction_status(scb, status);
++                              cstat = aic_get_transaction_status(scb);
+                               if (cstat != CAM_REQ_CMP)
+-                                      ahc_freeze_scb(scb);
++                                      aic_freeze_scb(scb);
+                               if ((scb->flags & SCB_ACTIVE) == 0)
+                                       printf("Inactive SCB in untaggedQ\n");
+                               ahc_done(ahc, scb);
+@@ -5904,11 +5929,11 @@ ahc_abort_scbs(struct ahc_softc *ahc, in
+               if (ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)) {
+                       cam_status ostat;
+-                      ostat = ahc_get_transaction_status(scbp);
++                      ostat = aic_get_transaction_status(scbp);
+                       if (ostat == CAM_REQ_INPROG)
+-                              ahc_set_transaction_status(scbp, status);
+-                      if (ahc_get_transaction_status(scbp) != CAM_REQ_CMP)
+-                              ahc_freeze_scb(scbp);
++                              aic_set_transaction_status(scbp, status);
++                      if (aic_get_transaction_status(scbp) != CAM_REQ_CMP)
++                              aic_freeze_scb(scbp);
+                       if ((scbp->flags & SCB_ACTIVE) == 0)
+                               printf("Inactive SCB on pending list\n");
+                       ahc_done(ahc, scbp);
+@@ -5930,7 +5955,7 @@ ahc_reset_current_bus(struct ahc_softc *
+       scsiseq = ahc_inb(ahc, SCSISEQ);
+       ahc_outb(ahc, SCSISEQ, scsiseq | SCSIRSTO);
+       ahc_flush_device_writes(ahc);
+-      ahc_delay(AHC_BUSRESET_DELAY);
++      aic_delay(AHC_BUSRESET_DELAY);
+       /* Turn off the bus reset */
+       ahc_outb(ahc, SCSISEQ, scsiseq & ~SCSIRSTO);
+@@ -6137,7 +6162,7 @@ ahc_calc_residual(struct ahc_softc *ahc,
+        */
+       hscb = scb->hscb;
+-      sgptr = ahc_le32toh(hscb->sgptr);
++      sgptr = aic_le32toh(hscb->sgptr);
+       if ((sgptr & SG_RESID_VALID) == 0)
+               /* Case 1 */
+               return;
+@@ -6148,10 +6173,10 @@ ahc_calc_residual(struct ahc_softc *ahc,
+               return;
+       spkt = &hscb->shared_data.status;
+-      resid_sgptr = ahc_le32toh(spkt->residual_sg_ptr);
++      resid_sgptr = aic_le32toh(spkt->residual_sg_ptr);
+       if ((sgptr & SG_FULL_RESID) != 0) {
+               /* Case 3 */
+-              resid = ahc_get_transfer_length(scb);
++              resid = aic_get_transfer_length(scb);
+       } else if ((resid_sgptr & SG_LIST_NULL) != 0) {
+               /* Case 4 */
+               return;
+@@ -6164,7 +6189,7 @@ ahc_calc_residual(struct ahc_softc *ahc,
+                * Remainder of the SG where the transfer
+                * stopped.  
+                */
+-              resid = ahc_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;
++              resid = aic_le32toh(spkt->residual_datacnt) & AHC_SG_LEN_MASK;
+               sg = ahc_sg_bus_to_virt(scb, resid_sgptr & SG_PTR_MASK);
+               /* The residual sg_ptr always points to the next sg */
+@@ -6175,15 +6200,15 @@ ahc_calc_residual(struct ahc_softc *ahc,
+                * SG segments that are after the SG where
+                * the transfer stopped.
+                */
+-              while ((ahc_le32toh(sg->len) & AHC_DMA_LAST_SEG) == 0) {
++              while ((aic_le32toh(sg->len) & AHC_DMA_LAST_SEG) == 0) {
+                       sg++;
+-                      resid += ahc_le32toh(sg->len) & AHC_SG_LEN_MASK;
++                      resid += aic_le32toh(sg->len) & AHC_SG_LEN_MASK;
+               }
+       }
+       if ((scb->flags & SCB_SENSE) == 0)
+-              ahc_set_residual(scb, resid);
++              aic_set_residual(scb, resid);
+       else
+-              ahc_set_sense_residual(scb, resid);
++              aic_set_sense_residual(scb, resid);
+ #ifdef AHC_DEBUG
+       if ((ahc_debug & AHC_SHOW_MISC) != 0) {
+@@ -6407,7 +6432,6 @@ ahc_loadseq(struct ahc_softc *ahc)
+               memcpy(ahc->critical_sections, cs_table, cs_count);
+       }
+       ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE);
+-      ahc_restart(ahc);
+       if (bootverbose) {
+               printf(" %d instructions downloaded\n", downloaded);
+@@ -6464,7 +6488,7 @@ ahc_download_instr(struct ahc_softc *ahc
+       /*
+        * The firmware is always compiled into a little endian format.
+        */
+-      instr.integer = ahc_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
++      instr.integer = aic_le32toh(*(uint32_t*)&seqprog[instrptr * 4]);
+       fmt1_ins = &instr.format1;
+       fmt3_ins = NULL;
+@@ -6569,7 +6593,7 @@ ahc_download_instr(struct ahc_softc *ahc
+                       }
+               }
+               /* The sequencer is a little endian cpu */
+-              instr.integer = ahc_htole32(instr.integer);
++              instr.integer = aic_htole32(instr.integer);
+               ahc_outsb(ahc, SEQRAM, instr.bytes, 4);
+               break;
+       default:
+@@ -6809,6 +6833,324 @@ ahc_dump_card_state(struct ahc_softc *ah
+               ahc_unpause(ahc);
+ }
++/*************************** Timeout Handling *********************************/
++void
++ahc_timeout(struct scb *scb)
++{
++      struct ahc_softc *ahc;
++
++      ahc = scb->ahc_softc;
++      if ((scb->flags & SCB_ACTIVE) != 0) {
++              if ((scb->flags & SCB_TIMEDOUT) == 0) {
++                      LIST_INSERT_HEAD(&ahc->timedout_scbs, scb,
++                                       timedout_links);
++                      scb->flags |= SCB_TIMEDOUT;
++              }
++              ahc_wakeup_recovery_thread(ahc);
++      }
++}
++
++/*
++ * ahc_recover_commands determines if any of the commands that have currently
++ * timedout are the root cause for this timeout.  Innocent commands are given
++ * a new timeout while we wait for the command executing on the bus to timeout.
++ * This routine is invoked from a thread context so we are allowed to sleep.
++ * Our lock is not held on entry.
++ */
++void
++ahc_recover_commands(struct ahc_softc *ahc)
++{
++      struct  scb *scb;
++      long    s;
++      int     found;
++      int     restart_needed;
++      u_int   last_phase;
++
++      ahc_lock(ahc, &s);
++
++      /*
++       * Pause the controller and manually flush any
++       * commands that have just completed but that our
++       * interrupt handler has yet to see.
++       */
++      ahc_pause_and_flushwork(ahc);
++
++      if (LIST_EMPTY(&ahc->timedout_scbs) != 0) {
++              /*
++               * The timedout commands have already
++               * completed.  This typically means
++               * that either the timeout value was on
++               * the hairy edge of what the device
++               * requires or - more likely - interrupts
++               * are not happening.
++               */
++              printf("%s: Timedout SCBs already complete. "
++                     "Interrupts may not be functioning.\n", ahc_name(ahc));
++              ahc_unpause(ahc);
++              ahc_unlock(ahc, &s);
++              return;
++      }
++
++      restart_needed = 0;
++      printf("%s: Recovery Initiated\n", ahc_name(ahc));
++      ahc_dump_card_state(ahc);
++
++      last_phase = ahc_inb(ahc, LASTPHASE);
++      while ((scb = LIST_FIRST(&ahc->timedout_scbs)) != NULL) {
++              u_int   active_scb_index;
++              u_int   saved_scbptr;
++              int     target;
++              int     lun;
++              int     i;
++              char    channel;
++
++              target = SCB_GET_TARGET(ahc, scb);
++              channel = SCB_GET_CHANNEL(ahc, scb);
++              lun = SCB_GET_LUN(scb);
++
++              ahc_print_path(ahc, scb);
++              printf("SCB 0x%x - timed out\n", scb->hscb->tag);
++              if (scb->sg_count > 0) {
++                      for (i = 0; i < scb->sg_count; i++) {
++                              printf("sg[%d] - Addr 0x%x : Length %d\n",
++                                     i,
++                                     scb->sg_list[i].addr,
++                                     scb->sg_list[i].len & AHC_SG_LEN_MASK);
++                      }
++              }
++              if (scb->flags & (SCB_DEVICE_RESET|SCB_ABORT)) {
++                      /*
++                       * Been down this road before.
++                       * Do a full bus reset.
++                       */
++                      aic_set_transaction_status(scb, CAM_CMD_TIMEOUT);
++bus_reset:
++                      found = ahc_reset_channel(ahc, channel,
++                                                /*Initiate Reset*/TRUE);
++                      printf("%s: Issued Channel %c Bus Reset. "
++                             "%d SCBs aborted\n", ahc_name(ahc), channel,
++                             found);
++                      continue;
++              }
++
++              /*
++               * Remove the command from the timedout list in
++               * preparation for requeing it.
++               */
++              LIST_REMOVE(scb, timedout_links);
++              scb->flags &= ~SCB_TIMEDOUT;
++
++              /*
++               * If we are a target, transition to bus free and report
++               * the timeout.
++               * 
++               * The target/initiator that is holding up the bus may not
++               * be the same as the one that triggered this timeout
++               * (different commands have different timeout lengths).
++               * If the bus is idle and we are actiing as the initiator
++               * for this request, queue a BDR message to the timed out
++               * target.  Otherwise, if the timed out transaction is
++               * active:
++               *   Initiator transaction:
++               *      Stuff the message buffer with a BDR message and assert
++               *      ATN in the hopes that the target will let go of the bus
++               *      and go to the mesgout phase.  If this fails, we'll
++               *      get another timeout 2 seconds later which will attempt
++               *      a bus reset.
++               *
++               *   Target transaction:
++               *      Transition to BUS FREE and report the error.
++               *      It's good to be the target!
++               */
++              saved_scbptr = ahc_inb(ahc, SCBPTR);
++              active_scb_index = ahc_inb(ahc, SCB_TAG);
++
++              if ((ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) == 0
++                && (active_scb_index < ahc->scb_data->numscbs)) {
++                      struct scb *active_scb;
++
++                      /*
++                       * If the active SCB is not us, assume that
++                       * the active SCB has a longer timeout than
++                       * the timedout SCB, and wait for the active
++                       * SCB to timeout.
++                       */ 
++                      active_scb = ahc_lookup_scb(ahc, active_scb_index);
++                      if (active_scb != scb) {
++                              u_int   newtimeout;
++
++                              ahc_print_path(ahc, scb);
++                              printf("Other SCB Timeout%s",
++                                     (scb->flags & SCB_OTHERTCL_TIMEOUT) != 0
++                                     ? " again\n" : "\n");
++                              scb->flags |= SCB_OTHERTCL_TIMEOUT;
++                              newtimeout =
++                                  MAX(aic_get_timeout(active_scb),
++                                      aic_get_timeout(scb));
++                              aic_scb_timer_reset(scb, newtimeout);
++                              continue;
++                      } 
++
++                      /* It's us */
++                      if ((scb->flags & SCB_TARGET_SCB) != 0) {
++
++                              /*
++                               * Send back any queued up transactions
++                               * and properly record the error condition.
++                               */
++                              ahc_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb),
++                                             SCB_GET_CHANNEL(ahc, scb),
++                                             SCB_GET_LUN(scb),
++                                             scb->hscb->tag,
++                                             ROLE_TARGET,
++                                             CAM_CMD_TIMEOUT);
++
++                              /* Will clear us from the bus */
++                              restart_needed = 1;
++                              break;
++                      }
++
++                      ahc_set_recoveryscb(ahc, active_scb);
++                      ahc_outb(ahc, MSG_OUT, HOST_MSG);
++                      ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
++                      ahc_print_path(ahc, active_scb);
++                      printf("BDR message in message buffer\n");
++                      active_scb->flags |= SCB_DEVICE_RESET;
++                      aic_scb_timer_reset(scb, 2 * 1000000);
++              } else if (last_phase != P_BUSFREE
++                      && (ahc_inb(ahc, SSTAT1) & REQINIT) == 0) {
++                      /*
++                       * SCB is not identified, there
++                       * is no pending REQ, and the sequencer
++                       * has not seen a busfree.  Looks like
++                       * a stuck connection waiting to
++                       * go busfree.  Reset the bus.
++                       */
++                      printf("%s: Connection stuck awaiting busfree or "
++                             "Identify Msg.\n", ahc_name(ahc));
++                      goto bus_reset;
++              } else {
++                      int      disconnected;
++
++                      if (last_phase != P_BUSFREE
++                       && (ahc_inb(ahc, SSTAT0) & TARGET) != 0) {
++                              /* Hung target selection.  Goto busfree */
++                              printf("%s: Hung target selection\n",
++                                     ahc_name(ahc));
++                              restart_needed = 1;
++                              break;
++                      }
++
++                      /* XXX Shouldn't panic.  Just punt instead? */
++                      if ((scb->flags & SCB_TARGET_SCB) != 0)
++                              panic("Timed-out target SCB but bus idle");
++
++                      if (ahc_search_qinfifo(ahc, target, channel, lun,
++                                             scb->hscb->tag, ROLE_INITIATOR,
++                                             /*status*/0, SEARCH_COUNT) > 0) {
++                              disconnected = FALSE;
++                      } else {
++                              disconnected = TRUE;
++                      }
++
++                      if (disconnected) {
++
++                              ahc_set_recoveryscb(ahc, scb);
++                              /*
++                               * Actually re-queue this SCB in an attempt
++                               * to select the device before it reconnects.
++                               * In either case (selection or reselection),
++                               * we will now issue a target reset to the
++                               * timed-out device.
++                               *
++                               * Set the MK_MESSAGE control bit indicating
++                               * that we desire to send a message.  We
++                               * also set the disconnected flag since
++                               * in the paging case there is no guarantee
++                               * that our SCB control byte matches the
++                               * version on the card.  We don't want the
++                               * sequencer to abort the command thinking
++                               * an unsolicited reselection occurred.
++                               */
++                              scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
++                              scb->flags |= SCB_DEVICE_RESET;
++
++                              /*
++                               * Remove any cached copy of this SCB in the
++                               * disconnected list in preparation for the
++                               * queuing of our abort SCB.  We use the
++                               * same element in the SCB, SCB_NEXT, for
++                               * both the qinfifo and the disconnected list.
++                               */
++                              ahc_search_disc_list(ahc, target, channel,
++                                                   lun, scb->hscb->tag,
++                                                   /*stop_on_first*/TRUE,
++                                                   /*remove*/TRUE,
++                                                   /*save_state*/FALSE);
++
++                              /*
++                               * In the non-paging case, the sequencer will
++                               * never re-reference the in-core SCB.
++                               * To make sure we are notified during
++                               * reslection, set the MK_MESSAGE flag in
++                               * the card's copy of the SCB.
++                               */
++                              if ((ahc->flags & AHC_PAGESCBS) == 0) {
++                                      ahc_outb(ahc, SCBPTR, scb->hscb->tag);
++                                      ahc_outb(ahc, SCB_CONTROL,
++                                               ahc_inb(ahc, SCB_CONTROL)
++                                              | MK_MESSAGE);
++                              }
++
++                              /*
++                               * Clear out any entries in the QINFIFO first
++                               * so we are the next SCB for this target
++                               * to run.
++                               */
++                              ahc_search_qinfifo(ahc,
++                                                 SCB_GET_TARGET(ahc, scb),
++                                                 channel, SCB_GET_LUN(scb),
++                                                 SCB_LIST_NULL,
++                                                 ROLE_INITIATOR,
++                                                 CAM_REQUEUE_REQ,
++                                                 SEARCH_COMPLETE);
++                              ahc_print_path(ahc, scb);
++                              printf("Queuing a BDR SCB\n");
++                              ahc_qinfifo_requeue_tail(ahc, scb);
++                              ahc_outb(ahc, SCBPTR, saved_scbptr);
++                              aic_scb_timer_reset(scb, 2 * 1000000);
++                      } else {
++                              /* Go "immediatly" to the bus reset */
++                              /* This shouldn't happen */
++                              ahc_set_recoveryscb(ahc, scb);
++                              ahc_print_path(ahc, scb);
++                              printf("SCB %d: Immediate reset.  "
++                                      "Flags = 0x%x\n", scb->hscb->tag,
++                                      scb->flags);
++                              goto bus_reset;
++                      }
++              }
++              break;
++      }
++      
++      /*
++       * Any remaining SCBs were not the "culprit", so remove
++       * them from the timeout list.  The timer for these commands
++       * will be reset once the recovery SCB completes.
++       */
++      while ((scb = LIST_FIRST(&ahc->timedout_scbs)) != NULL) {
++
++              LIST_REMOVE(scb, timedout_links);
++              scb->flags &= ~SCB_TIMEDOUT;
++      }
++
++      if (restart_needed)
++              ahc_restart(ahc);
++      else
++              ahc_unpause(ahc);
++      ahc_unlock(ahc, &s);
++}
++
+ /************************* Target Mode ****************************************/
+ #ifdef AHC_TARGET_MODE
+ cam_status
+@@ -6968,11 +7310,12 @@ ahc_handle_en_lun(struct ahc_softc *ahc,
+                        */
+                       ahc->flags = saved_flags;
+                       (void)ahc_loadseq(ahc);
+-                      ahc_unpause(ahc);
++                      ahc_restart(ahc);
+                       ahc_unlock(ahc, &s);
+                       ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
+                       return;
+               }
++              ahc_restart(ahc);
+               ahc_unlock(ahc, &s);
+       }
+       cel = &ccb->cel;
+@@ -7207,12 +7550,16 @@ ahc_handle_en_lun(struct ahc_softc *ahc,
+                               printf("Configuring Initiator Mode\n");
+                               ahc->flags &= ~AHC_TARGETROLE;
+                               ahc->flags |= AHC_INITIATORROLE;
+-                              ahc_pause(ahc);
+                               /*
+                                * Returning to a configuration that
+                                * fit previously will always succeed.
+                                */
+                               (void)ahc_loadseq(ahc);
++                              ahc_restart(ahc);
++                              /*
++                               * Unpaused.  The extra unpause
++                               * that follows is harmless.
++                               */
+                       }
+               }
+               ahc_unpause(ahc);
+@@ -7282,7 +7629,7 @@ ahc_run_tqinfifo(struct ahc_softc *ahc, 
+                       break;
+               cmd->cmd_valid = 0;
+-              ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
++              aic_dmamap_sync(ahc, ahc->shared_data_dmat,
+                               ahc->shared_data_dmamap,
+                               ahc_targetcmd_offset(ahc, ahc->tqinfifonext),
+                               sizeof(struct target_cmd),
+@@ -7419,7 +7766,7 @@ ahc_handle_target_cmd(struct ahc_softc *
+                      initiator, target, lun, ahc->pending_device);
+ #endif
+               ahc->pending_device = lstate;
+-              ahc_freeze_ccb((union ccb *)atio);
++              aic_freeze_ccb((union ccb *)atio);
+               atio->ccb_h.flags |= CAM_DIS_DISCONNECT;
+       }
+       xpt_done((union ccb*)atio);
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx.h 2003-06-14 12:18:22.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx.h  2003-12-28 23:21:39.000000000 -0800
+@@ -37,7 +37,7 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#77 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#85 $
+  *
+  * $FreeBSD$
+  */
+@@ -243,7 +243,7 @@ typedef enum {
+        */
+       AHC_AIC7850_FE  = AHC_SPIOCAP|AHC_AUTOPAUSE|AHC_TARGETMODE|AHC_ULTRA,
+       AHC_AIC7860_FE  = AHC_AIC7850_FE,
+-      AHC_AIC7870_FE  = AHC_TARGETMODE,
++      AHC_AIC7870_FE  = AHC_TARGETMODE|AHC_AUTOPAUSE,
+       AHC_AIC7880_FE  = AHC_AIC7870_FE|AHC_ULTRA,
+       /*
+        * Although we have space for both the initiator and
+@@ -366,7 +366,8 @@ typedef enum {
+       AHC_SCB_CONFIG_USED   = 0x4000000, /* No SEEPROM but SCB2 had info. */
+       AHC_NO_BIOS_INIT      = 0x8000000, /* No BIOS left over settings. */
+       AHC_DISABLE_PCI_PERR  = 0x10000000,
+-      AHC_HAS_TERM_LOGIC    = 0x20000000
++      AHC_HAS_TERM_LOGIC    = 0x20000000,
++      AHC_SHUTDOWN_RECOVERY = 0x40000000 /* Terminate recovery thread. */
+ } ahc_flag;
+ /************************* Hardware  SCB Definition ***************************/
+@@ -411,6 +412,7 @@ struct target_data {
+       uint8_t  initiator_tag;         /* Initiator's transaction tag */
+ };
++#define MAX_CDB_LEN 16
+ struct hardware_scb {
+ /*0*/ union {
+               /*
+@@ -530,7 +532,7 @@ struct sg_map_node {
+  * The current state of this SCB.
+  */
+ typedef enum {
+-      SCB_FREE                = 0x0000,
++      SCB_FLAG_NONE           = 0x0000,
+       SCB_OTHERTCL_TIMEOUT    = 0x0002,/*
+                                         * Another device was active
+                                         * during the first timeout for
+@@ -560,12 +562,16 @@ typedef enum {
+                                         * to report the error.
+                                         */
+       SCB_TARGET_SCB          = 0x2000,
+-      SCB_SILENT              = 0x4000 /*
++      SCB_SILENT              = 0x4000,/*
+                                         * Be quiet about transmission type
+                                         * errors.  They are expected and we
+                                         * don't want to upset the user.  This
+                                         * flag is typically used during DV.
+                                         */
++      SCB_TIMEDOUT            = 0x8000 /*
++                                        * SCB has timed out and is on the
++                                        * timedout list.
++                                        */
+ } scb_flag;
+ struct scb {
+@@ -575,7 +581,8 @@ struct scb {
+               TAILQ_ENTRY(scb)  tqe;
+       } links;
+       LIST_ENTRY(scb)           pending_links;
+-      ahc_io_ctx_t              io_ctx;
++      LIST_ENTRY(scb)           timedout_links;
++      aic_io_ctx_t              io_ctx;
+       struct ahc_softc         *ahc_softc;
+       scb_flag                  flags;
+ #ifndef __linux__
+@@ -929,6 +936,11 @@ struct ahc_softc {
+       LIST_HEAD(, scb)          pending_scbs;
+       /*
++       * SCBs whose timeout routine has been called.
++       */
++      LIST_HEAD(, scb)          timedout_scbs;
++
++      /*
+        * Counting lock for deferring the release of additional
+        * untagged transactions from the untagged_queues.  When
+        * the lock is decremented to 0, all queues in the
+@@ -958,7 +970,7 @@ struct ahc_softc {
+       /*
+        * Platform specific device information.
+        */
+-      ahc_dev_softc_t           dev_softc;
++      aic_dev_softc_t           dev_softc;
+       /*
+        * Bus specific device information.
+@@ -1135,6 +1147,9 @@ struct ahc_devinfo {
+ };
+ /****************************** PCI Structures ********************************/
++#define       AHC_PCI_IOADDR  PCIR_BAR(0)     /* I/O Address */
++#define       AHC_PCI_MEMADDR PCIR_BAR(1)     /* Mem I/O Address */
++
+ typedef int (ahc_device_setup_t)(struct ahc_softc *);
+ struct ahc_pci_identity {
+@@ -1143,17 +1158,17 @@ struct ahc_pci_identity {
+       char                    *name;
+       ahc_device_setup_t      *setup;
+ };
+-extern struct ahc_pci_identity ahc_pci_ident_table [];
++extern struct ahc_pci_identity ahc_pci_ident_table[];
+ extern const u_int ahc_num_pci_devs;
+ /***************************** VL/EISA Declarations ***************************/
+ struct aic7770_identity {
+       uint32_t                 full_id;
+       uint32_t                 id_mask;
+-      char                    *name;
++      const char              *name;
+       ahc_device_setup_t      *setup;
+ };
+-extern struct aic7770_identity aic7770_ident_table [];
++extern struct aic7770_identity aic7770_ident_table[];
+ extern const int ahc_num_aic7770_devs;
+ #define AHC_EISA_SLOT_OFFSET  0xc00
+@@ -1167,7 +1182,7 @@ void                     ahc_busy_tcl(struct ahc_softc *ah
+                                    u_int tcl, u_int busyid);
+ /***************************** PCI Front End *********************************/
+-struct ahc_pci_identity       *ahc_find_pci_device(ahc_dev_softc_t);
++struct ahc_pci_identity       *ahc_find_pci_device(aic_dev_softc_t);
+ int                    ahc_pci_config(struct ahc_softc *,
+                                       struct ahc_pci_identity *);
+ int                    ahc_pci_test_register_access(struct ahc_softc *);
+@@ -1205,7 +1220,7 @@ void                      ahc_set_unit(struct ahc_softc *,
+ void                   ahc_set_name(struct ahc_softc *, char *);
+ void                   ahc_alloc_scbs(struct ahc_softc *ahc);
+ void                   ahc_free(struct ahc_softc *ahc);
+-int                    ahc_reset(struct ahc_softc *ahc);
++int                    ahc_reset(struct ahc_softc *ahc, int reinit);
+ void                   ahc_shutdown(void *arg);
+ /*************************** Interrupt Services *******************************/
+@@ -1231,7 +1246,7 @@ int                      ahc_search_qinfifo(struct ahc_soft
+                                          role_t role, uint32_t status,
+                                          ahc_search_action action);
+ int                   ahc_search_untagged_queues(struct ahc_softc *ahc,
+-                                                 ahc_io_ctx_t ctx,
++                                                 aic_io_ctx_t ctx,
+                                                  int target, char channel,
+                                                  int lun, uint32_t status,
+                                                  ahc_search_action action);
+@@ -1248,6 +1263,8 @@ int                      ahc_abort_scbs(struct ahc_softc *a
+ void                  ahc_restart(struct ahc_softc *ahc);
+ void                  ahc_calc_residual(struct ahc_softc *ahc,
+                                         struct scb *scb);
++void                  ahc_timeout(struct scb *scb);
++void                  ahc_recover_commands(struct ahc_softc *ahc);
+ /*************************** Utility Functions ********************************/
+ struct ahc_phase_table_entry*
+                       ahc_lookup_phase_entry(int phase);
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx_inline.h  2003-06-14 12:18:51.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx_inline.h   2003-12-28 23:21:39.000000000 -0800
+@@ -37,7 +37,7 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#43 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_inline.h#47 $
+  *
+  * $FreeBSD$
+  */
+@@ -196,7 +196,7 @@ ahc_hscb_busaddr(struct ahc_softc *ahc, 
+ static __inline void
+ ahc_sync_scb(struct ahc_softc *ahc, struct scb *scb, int op)
+ {
+-      ahc_dmamap_sync(ahc, ahc->scb_data->hscb_dmat,
++      aic_dmamap_sync(ahc, ahc->scb_data->hscb_dmat,
+                       ahc->scb_data->hscb_dmamap,
+                       /*offset*/(scb->hscb - ahc->hscbs) * sizeof(*scb->hscb),
+                       /*len*/sizeof(*scb->hscb), op);
+@@ -208,7 +208,7 @@ ahc_sync_sglist(struct ahc_softc *ahc, s
+       if (scb->sg_count == 0)
+               return;
+-      ahc_dmamap_sync(ahc, ahc->scb_data->sg_dmat, scb->sg_map->sg_dmamap,
++      aic_dmamap_sync(ahc, ahc->scb_data->sg_dmat, scb->sg_map->sg_dmamap,
+                       /*offset*/(scb->sg_list - scb->sg_map->sg_vaddr)
+                               * sizeof(struct ahc_dma_seg),
+                       /*len*/sizeof(struct ahc_dma_seg) * scb->sg_count, op);
+@@ -272,7 +272,7 @@ ahc_update_residual(struct ahc_softc *ah
+ {
+       uint32_t sgptr;
+-      sgptr = ahc_le32toh(scb->hscb->sgptr);
++      sgptr = aic_le32toh(scb->hscb->sgptr);
+       if ((sgptr & SG_RESID_VALID) != 0)
+               ahc_calc_residual(ahc, scb);
+ }
+@@ -383,13 +383,13 @@ ahc_free_scb(struct ahc_softc *ahc, stru
+       hscb = scb->hscb;
+       /* Clean up for the next user */
+       ahc->scb_data->scbindex[hscb->tag] = NULL;
+-      scb->flags = SCB_FREE;
++      scb->flags = SCB_FLAG_NONE;
+       hscb->control = 0;
+       SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links.sle);
+       /* Notify the OSM that a resource is now available. */
+-      ahc_platform_scb_free(ahc, scb);
++      aic_platform_scb_free(ahc, scb);
+ }
+ static __inline struct scb *
+@@ -427,7 +427,7 @@ ahc_swap_with_next_hscb(struct ahc_softc
+       memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));
+       if ((scb->flags & SCB_CDB32_PTR) != 0) {
+               q_hscb->shared_data.cdb_ptr =
+-                  ahc_htole32(ahc_hscb_busaddr(ahc, q_hscb->tag)
++                  aic_htole32(ahc_hscb_busaddr(ahc, q_hscb->tag)
+                             + offsetof(struct hardware_scb, cdb32));
+       }
+       q_hscb->tag = saved_tag;
+@@ -458,7 +458,7 @@ ahc_queue_scb(struct ahc_softc *ahc, str
+        * Setup data "oddness".
+        */
+       scb->hscb->lun &= LID;
+-      if (ahc_get_transfer_length(scb) & 0x1)
++      if (aic_get_transfer_length(scb) & 0x1)
+               scb->hscb->lun |= SCB_XFERLEN_ODD;
+       /*
+@@ -512,7 +512,7 @@ static __inline int        ahc_intr(struct ahc_
+ static __inline void
+ ahc_sync_qoutfifo(struct ahc_softc *ahc, int op)
+ {
+-      ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
++      aic_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
+                       /*offset*/0, /*len*/256, op);
+ }
+@@ -521,7 +521,7 @@ ahc_sync_tqinfifo(struct ahc_softc *ahc,
+ {
+ #ifdef AHC_TARGET_MODE
+       if ((ahc->flags & AHC_TARGETROLE) != 0) {
+-              ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
++              aic_dmamap_sync(ahc, ahc->shared_data_dmat,
+                               ahc->shared_data_dmamap,
+                               ahc_targetcmd_offset(ahc, 0),
+                               sizeof(struct target_cmd) * AHC_TMODE_CMDS,
+@@ -542,7 +542,7 @@ ahc_check_cmdcmpltqueues(struct ahc_soft
+       u_int retval;
+       retval = 0;
+-      ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
++      aic_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
+                       /*offset*/ahc->qoutfifonext, /*len*/1,
+                       BUS_DMASYNC_POSTREAD);
+       if (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL)
+@@ -550,7 +550,7 @@ ahc_check_cmdcmpltqueues(struct ahc_soft
+ #ifdef AHC_TARGET_MODE
+       if ((ahc->flags & AHC_TARGETROLE) != 0
+        && (ahc->flags & AHC_TQINFIFO_BLOCKED) == 0) {
+-              ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
++              aic_dmamap_sync(ahc, ahc->shared_data_dmat,
+                               ahc->shared_data_dmamap,
+                               ahc_targetcmd_offset(ahc, ahc->tqinfifofnext),
+                               /*len*/sizeof(struct target_cmd),
+@@ -593,7 +593,7 @@ ahc_intr(struct ahc_softc *ahc)
+       }
+       if ((intstat & INT_PEND) == 0) {
+-#if AHC_PCI_CONFIG > 0
++#if AIC_PCI_CONFIG > 0
+               if (ahc->unsolicited_ints > 500) {
+                       ahc->unsolicited_ints = 0;
+                       if ((ahc->chip & AHC_PCI) != 0
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx_osm.c     2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx_osm.c      2003-12-28 23:21:40.000000000 -0800
+@@ -1,7 +1,7 @@
+ /*
+  * Adaptec AIC7xxx device driver for Linux.
+  *
+- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#232 $
++ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#256 $
+  *
+  * Copyright (c) 1994 John Aycock
+  *   The University of Calgary Department of Computer Science.
+@@ -139,7 +139,16 @@
+ #endif
+ #include <linux/mm.h>         /* For fetching system memory size */
+-#include <linux/blkdev.h>             /* For block_size() */
++
++/************************* Magic SysReq Support *******************************/
++static struct aic_sysrq_key_op ahc_sysrq_op =
++{
++      aic_sysrq_handler,
++      "aic7xxxstatedump",
++      "Dump aic7xxx controller information to Console"
++};
++
++static int ahc_sysrq_key;
+ /*
+  * Lock protecting manipulation of the ahc softc list.
+@@ -293,7 +302,7 @@ static adapter_tag_info_t aic7xxx_tag_in
+ #define AIC7XXX_CONFIGED_DV -1
+ #endif
+-static uint8_t aic7xxx_dv_settings[] =
++static int8_t aic7xxx_dv_settings[] =
+ {
+       AIC7XXX_CONFIGED_DV,
+       AIC7XXX_CONFIGED_DV,
+@@ -391,9 +400,9 @@ static uint32_t aic7xxx_pci_parity = ~0;
+  * would result in never finding any devices :)
+  */
+ #ifndef CONFIG_AIC7XXX_PROBE_EISA_VL
+-static uint32_t aic7xxx_probe_eisa_vl;
++uint32_t aic7xxx_probe_eisa_vl;
+ #else
+-static uint32_t aic7xxx_probe_eisa_vl = ~0;
++uint32_t aic7xxx_probe_eisa_vl = ~0;
+ #endif
+ /*
+@@ -482,35 +491,32 @@ MODULE_PARM_DESC(aic7xxx,
+ #endif
+ static void ahc_linux_handle_scsi_status(struct ahc_softc *,
+-                                       struct ahc_linux_device *,
++                                       struct aic_linux_device *,
+                                        struct scb *);
+ static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
+                                        Scsi_Cmnd *cmd);
+ static void ahc_linux_filter_inquiry(struct ahc_softc*, struct ahc_devinfo*);
+ static void ahc_linux_sem_timeout(u_long arg);
+-static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
+-static void ahc_linux_release_simq(u_long arg);
+ static void ahc_linux_dev_timed_unfreeze(u_long arg);
+ static int  ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag);
+ static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
+ static void ahc_linux_size_nseg(void);
+ static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc);
+ static void ahc_linux_start_dv(struct ahc_softc *ahc);
+-static void ahc_linux_dv_timeout(struct scsi_cmnd *cmd);
+ static int  ahc_linux_dv_thread(void *data);
+ static void ahc_linux_kill_dv_thread(struct ahc_softc *ahc);
+ static void ahc_linux_dv_target(struct ahc_softc *ahc, u_int target);
+ static void ahc_linux_dv_transition(struct ahc_softc *ahc,
+                                   struct scsi_cmnd *cmd,
+                                   struct ahc_devinfo *devinfo,
+-                                  struct ahc_linux_target *targ);
++                                  struct aic_linux_target *targ);
+ static void ahc_linux_dv_fill_cmd(struct ahc_softc *ahc,
+                                 struct scsi_cmnd *cmd,
+                                 struct ahc_devinfo *devinfo);
+ static void ahc_linux_dv_inq(struct ahc_softc *ahc,
+                            struct scsi_cmnd *cmd,
+                            struct ahc_devinfo *devinfo,
+-                           struct ahc_linux_target *targ,
++                           struct aic_linux_target *targ,
+                            u_int request_length);
+ static void ahc_linux_dv_tur(struct ahc_softc *ahc,
+                            struct scsi_cmnd *cmd,
+@@ -518,58 +524,48 @@ static void ahc_linux_dv_tur(struct ahc_
+ static void ahc_linux_dv_rebd(struct ahc_softc *ahc,
+                             struct scsi_cmnd *cmd,
+                             struct ahc_devinfo *devinfo,
+-                            struct ahc_linux_target *targ);
++                            struct aic_linux_target *targ);
+ static void ahc_linux_dv_web(struct ahc_softc *ahc,
+                            struct scsi_cmnd *cmd,
+                            struct ahc_devinfo *devinfo,
+-                           struct ahc_linux_target *targ);
++                           struct aic_linux_target *targ);
+ static void ahc_linux_dv_reb(struct ahc_softc *ahc,
+                            struct scsi_cmnd *cmd,
+                            struct ahc_devinfo *devinfo,
+-                           struct ahc_linux_target *targ);
++                           struct aic_linux_target *targ);
+ static void ahc_linux_dv_su(struct ahc_softc *ahc,
+                           struct scsi_cmnd *cmd,
+                           struct ahc_devinfo *devinfo,
+-                          struct ahc_linux_target *targ);
++                          struct aic_linux_target *targ);
+ static int ahc_linux_fallback(struct ahc_softc *ahc,
+                             struct ahc_devinfo *devinfo);
+-static void ahc_linux_dv_complete(Scsi_Cmnd *cmd);
+-static void ahc_linux_generate_dv_pattern(struct ahc_linux_target *targ);
++static void ahc_linux_generate_dv_pattern(struct aic_linux_target *targ);
+ static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
+                                    struct ahc_devinfo *devinfo);
+ static u_int ahc_linux_user_dv_setting(struct ahc_softc *ahc);
+-static void ahc_linux_device_queue_depth(struct ahc_softc *ahc,
+-                                       struct ahc_linux_device *dev);
+-static struct ahc_linux_target*       ahc_linux_alloc_target(struct ahc_softc*,
++static void aic_linux_device_queue_depth(struct ahc_softc *ahc,
++                                       struct aic_linux_device *dev);
++static struct aic_linux_target*       ahc_linux_alloc_target(struct ahc_softc*,
+                                                      u_int, u_int);
+ static void                   ahc_linux_free_target(struct ahc_softc*,
+-                                                    struct ahc_linux_target*);
+-static struct ahc_linux_device*       ahc_linux_alloc_device(struct ahc_softc*,
+-                                                     struct ahc_linux_target*,
++                                                    struct aic_linux_target*);
++static struct aic_linux_device*       ahc_linux_alloc_device(struct ahc_softc*,
++                                                     struct aic_linux_target*,
+                                                      u_int);
+ static void                   ahc_linux_free_device(struct ahc_softc*,
+-                                                    struct ahc_linux_device*);
+-static void ahc_linux_run_device_queue(struct ahc_softc*,
+-                                     struct ahc_linux_device*);
++                                                    struct aic_linux_device*);
+ static void ahc_linux_setup_tag_info_global(char *p);
+ static aic_option_callback_t ahc_linux_setup_tag_info;
+ static aic_option_callback_t ahc_linux_setup_dv;
+ static int  aic7xxx_setup(char *s);
+ static int  ahc_linux_next_unit(void);
+-static void ahc_runq_tasklet(unsigned long data);
+-static struct ahc_cmd *ahc_linux_run_complete_queue(struct ahc_softc *ahc);
++static struct aic_cmd *ahc_linux_run_complete_queue(struct ahc_softc *ahc);
+ /********************************* Inlines ************************************/
+-static __inline void ahc_schedule_runq(struct ahc_softc *ahc);
+-static __inline struct ahc_linux_device*
++static __inline struct aic_linux_device*
+                    ahc_linux_get_device(struct ahc_softc *ahc, u_int channel,
+                                         u_int target, u_int lun, int alloc);
+ static __inline void ahc_schedule_completeq(struct ahc_softc *ahc);
+-static __inline void ahc_linux_check_device_queue(struct ahc_softc *ahc,
+-                                                struct ahc_linux_device *dev);
+-static __inline struct ahc_linux_device *
+-                   ahc_linux_next_device_to_run(struct ahc_softc *ahc);
+-static __inline void ahc_linux_run_device_queues(struct ahc_softc *ahc);
+ static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*);
+ static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
+@@ -579,35 +575,19 @@ static __inline int ahc_linux_map_seg(st
+ static __inline void
+ ahc_schedule_completeq(struct ahc_softc *ahc)
+ {
+-      if ((ahc->platform_data->flags & AHC_RUN_CMPLT_Q_TIMER) == 0) {
+-              ahc->platform_data->flags |= AHC_RUN_CMPLT_Q_TIMER;
++      if ((ahc->platform_data->flags & AIC_RUN_CMPLT_Q_TIMER) == 0) {
++              ahc->platform_data->flags |= AIC_RUN_CMPLT_Q_TIMER;
+               ahc->platform_data->completeq_timer.expires = jiffies;
+               add_timer(&ahc->platform_data->completeq_timer);
+       }
+ }
+-/*
+- * Must be called with our lock held.
+- */
+-static __inline void
+-ahc_schedule_runq(struct ahc_softc *ahc)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      tasklet_schedule(&ahc->platform_data->runq_tasklet);
+-#else
+-      /*
+-       * Tasklets are not available, so run inline.
+-       */
+-      ahc_runq_tasklet((unsigned long)ahc);
+-#endif
+-}
+-
+-static __inline struct ahc_linux_device*
++static __inline struct aic_linux_device*
+ ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target,
+                    u_int lun, int alloc)
+ {
+-      struct ahc_linux_target *targ;
+-      struct ahc_linux_device *dev;
++      struct aic_linux_target *targ;
++      struct aic_linux_device *dev;
+       u_int target_offset;
+       target_offset = target;
+@@ -629,10 +609,10 @@ ahc_linux_get_device(struct ahc_softc *a
+ }
+ #define AHC_LINUX_MAX_RETURNED_ERRORS 4
+-static struct ahc_cmd *
++static struct aic_cmd *
+ ahc_linux_run_complete_queue(struct ahc_softc *ahc)
+ {
+-      struct  ahc_cmd *acmd;
++      struct  aic_cmd *acmd;
+       u_long  done_flags;
+       int     with_errors;
+@@ -657,7 +637,7 @@ ahc_linux_run_complete_queue(struct ahc_
+                            acmd, acmd_links.tqe);
+               cmd = &acmd_scsi_cmd(acmd);
+               cmd->host_scribble = NULL;
+-              if (ahc_cmd_get_transaction_status(cmd) != DID_OK
++              if (aic_cmd_get_transaction_status(cmd) != DID_OK
+                || (cmd->result & 0xFF) != SCSI_STATUS_OK)
+                       with_errors++;
+@@ -666,47 +646,6 @@ ahc_linux_run_complete_queue(struct ahc_
+       ahc_done_unlock(ahc, &done_flags);
+       return (acmd);
+ }
+-
+-static __inline void
+-ahc_linux_check_device_queue(struct ahc_softc *ahc,
+-                           struct ahc_linux_device *dev)
+-{
+-      if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) != 0
+-       && dev->active == 0) {
+-              dev->flags &= ~AHC_DEV_FREEZE_TIL_EMPTY;
+-              dev->qfrozen--;
+-      }
+-
+-      if (TAILQ_FIRST(&dev->busyq) == NULL
+-       || dev->openings == 0 || dev->qfrozen != 0)
+-              return;
+-
+-      ahc_linux_run_device_queue(ahc, dev);
+-}
+-
+-static __inline struct ahc_linux_device *
+-ahc_linux_next_device_to_run(struct ahc_softc *ahc)
+-{
+-      
+-      if ((ahc->flags & AHC_RESOURCE_SHORTAGE) != 0
+-       || (ahc->platform_data->qfrozen != 0
+-        && AHC_DV_SIMQ_FROZEN(ahc) == 0))
+-              return (NULL);
+-      return (TAILQ_FIRST(&ahc->platform_data->device_runq));
+-}
+-
+-static __inline void
+-ahc_linux_run_device_queues(struct ahc_softc *ahc)
+-{
+-      struct ahc_linux_device *dev;
+-
+-      while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) {
+-              TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links);
+-              dev->flags &= ~AHC_DEV_ON_RUN_LIST;
+-              ahc_linux_check_device_queue(ahc, dev);
+-      }
+-}
+-
+ static __inline void
+ ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb)
+ {
+@@ -718,10 +657,10 @@ ahc_linux_unmap_scb(struct ahc_softc *ah
+               struct scatterlist *sg;
+               sg = (struct scatterlist *)cmd->request_buffer;
+-              pci_unmap_sg(ahc->dev_softc, sg, cmd->use_sg,
++              aic_unmap_sg(ahc, sg, cmd->use_sg,
+                            scsi_to_pci_dma_dir(cmd->sc_data_direction));
+       } else if (cmd->request_bufflen != 0) {
+-              pci_unmap_single(ahc->dev_softc,
++              aic_unmap_single(ahc,
+                                scb->platform_data->buf_busaddr,
+                                cmd->request_bufflen,
+                                scsi_to_pci_dma_dir(cmd->sc_data_direction));
+@@ -739,20 +678,19 @@ ahc_linux_map_seg(struct ahc_softc *ahc,
+                     "Increase AHC_NSEG\n");
+       consumed = 1;
+-      sg->addr = ahc_htole32(addr & 0xFFFFFFFF);
++      sg->addr = aic_htole32(addr & 0xFFFFFFFF);
+       scb->platform_data->xfer_len += len;
+       if (sizeof(bus_addr_t) > 4
+        && (ahc->flags & AHC_39BIT_ADDRESSING) != 0)
+               len |= (addr >> 8) & AHC_SG_HIGH_ADDR_MASK;
+-      sg->len = ahc_htole32(len);
++      sg->len = aic_htole32(len);
+       return (consumed);
+ }
+ /************************  Host template entry points *************************/
+ static int       ahc_linux_detect(Scsi_Host_Template *);
+-static int       ahc_linux_release(struct Scsi_Host *);
+ static int       ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
+ static const char *ahc_linux_info(struct Scsi_Host *);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+@@ -765,6 +703,7 @@ static int    ahc_linux_biosparam(struct
+                                      sector_t, int[]);
+ #endif
+ #else
++static int       ahc_linux_release(struct Scsi_Host *);
+ static void      ahc_linux_select_queue_depth(struct Scsi_Host *host,
+                                               Scsi_Device *scsi_devs);
+ #if defined(__i386__)
+@@ -836,6 +775,164 @@ ahc_linux_size_nseg(void)
+ #endif
+ }
++/************************** Error Recovery ************************************/
++static int ahc_linux_recovery_thread(void *arg);
++
++static int
++ahc_linux_recovery_thread(void *arg)
++{
++      struct ahc_softc *ahc;
++      u_long s;
++
++      ahc = (struct ahc_softc *)arg;
++
++      /*
++       * Complete thread creation.
++       */
++      lock_kernel();
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
++      /*
++       * Don't care about any signals.
++       */
++      siginitsetinv(&current->blocked, 0);
++
++      daemonize();
++      sprintf(current->comm, "ahc_recovery_%d", ahc->unit);
++#else
++      daemonize("ahc_recovery_%d", ahc->unit);
++#endif
++      unlock_kernel();
++
++      while (1) {
++
++              /*
++               * Use down_interruptible() rather than down() to
++               * avoid inclusion in the load average.
++               */
++              down_interruptible(&ahc->platform_data->recovery_sem);
++
++              ahc_lock(ahc, &s);
++              if ((ahc->flags & AHC_SHUTDOWN_RECOVERY) != 0) {
++                      ahc_unlock(ahc, &s);
++                      break;
++              }
++
++              /*
++               * Don't bother the recovery handler if the
++               * list has been cleared by a previous run
++               * of the handler.  This can happen when
++               * several SCBs timeout before our handler
++               * can run causing our semaphore to be up'ed
++               * repeatedly.  The extra calls need to be
++               * avoided so that the recovery handler doesn't
++               * confuse this case with timeouts occuring
++               * due to interrupts failing to function.
++               */
++              if (LIST_EMPTY(&ahc->timedout_scbs) != 0) {
++                      ahc_unlock(ahc, &s);
++                      continue;
++              }
++              ahc_unlock(ahc, &s);
++              ahc_recover_commands(ahc);
++
++              /*
++               * Process any pent up completions.
++               */
++              ahc_lock(ahc, &s);
++              aic_schedule_runq(ahc);
++              ahc_linux_run_complete_queue(ahc);
++              ahc_unlock(ahc, &s);
++      }
++      up(&ahc->platform_data->recovery_ending_sem);
++      return(0);
++}
++
++int
++ahc_spawn_recovery_thread(struct ahc_softc *ahc)
++{
++      ahc->platform_data->recovery_pid =
++          kernel_thread(ahc_linux_recovery_thread, ahc, 0);
++
++      if (ahc->platform_data->recovery_pid < 0)
++              return (-ahc->platform_data->recovery_pid);
++
++      return (0);
++}
++
++void
++ahc_terminate_recovery_thread(struct ahc_softc *ahc)
++{
++      u_long s;
++
++      ahc_lock(ahc, &s);
++      if (ahc->platform_data->recovery_pid != 0) {
++              ahc->flags |= AHC_SHUTDOWN_RECOVERY;
++              ahc_unlock(ahc, &s);
++              up(&ahc->platform_data->recovery_sem);
++
++              /*
++               * Use the recovery_ending_sem as an indicator that
++               * the dv thread is exiting.  Note that the dv
++               * thread must still return after performing
++               * the up on our semaphore before it has
++               * completely exited this module.  Unfortunately,
++               * there seems to be no easy way to wait for the
++               * exit of a thread for which you are not the
++               * parent (dv threads are parented by init).
++               * Cross your fingers...
++               */
++              down(&ahc->platform_data->recovery_ending_sem);
++
++              /*
++               * Mark the recovery thread as already dead.  This
++               * avoids attempting to kill it a second time.
++               * This is necessary because we must kill the
++               * our threads before calling ahc_free() in the
++               * module shutdown case to avoid bogus locking
++               * in the SCSI mid-layer, but when ahc_free() is
++               * called without killing the DV thread in the
++               * instance detach case, so ahc_platform_free()
++               * calls us again to verify that the DV thread
++               * is dead.
++               */
++              ahc->platform_data->recovery_pid = 0;
++      } else {
++              ahc_unlock(ahc, &s);
++      }
++}
++
++void
++ahc_set_recoveryscb(struct ahc_softc *ahc, struct scb *scb)
++{
++      if ((scb->flags & SCB_RECOVERY_SCB) == 0) {
++              struct scb *list_scb;
++
++              scb->flags |= SCB_RECOVERY_SCB;
++
++              /*
++               * Take all queued, but not sent SCBs out of the equation.
++               * Also ensure that no new commands are queued to us while we
++               * try to fix this problem.
++               */
++              if ((scb->platform_data->flags & AIC_RELEASE_SIMQ) == 0) {
++                      aic_freeze_simq(ahc);
++                      scb->platform_data->flags |= AIC_RELEASE_SIMQ;
++              }
++
++              /*
++               * Go through all of our pending SCBs and remove
++               * any scheduled timeouts for them.  We will reschedule
++               * them after we've successfully fixed this problem.
++               */
++              LIST_FOREACH(list_scb, &ahc->pending_scbs, pending_links) {
++
++                      scsi_delete_timer(list_scb->io_ctx);
++                      list_scb->platform_data->flags &= ~AIC_TIMEOUT_ACTIVE;
++              }
++      }
++}
++
++/************************ Linux Entry Points **********************************/
+ /*
+  * Try to detect an Adaptec 7XXX controller.
+  */
+@@ -858,7 +955,7 @@ ahc_linux_detect(Scsi_Host_Template *tem
+        * that some of our hacks^H^H^H^H^Hassumptions aren't
+        * violated.
+        */
+-      if (offsetof(struct ahc_cmd_internal, end)
++      if (offsetof(struct aic_cmd_internal, end)
+         > offsetof(struct scsi_cmnd, host_scribble)) {
+               printf("ahc_linux_detect: SCSI data structures changed.\n");
+               printf("ahc_linux_detect: Unable to attach\n");
+@@ -895,8 +992,9 @@ ahc_linux_detect(Scsi_Host_Template *tem
+       ahc_linux_pci_init();
+ #endif
+-      if (aic7xxx_probe_eisa_vl != 0)
+-              aic7770_linux_probe(template);
++#ifdef CONFIG_EISA
++      ahc_linux_eisa_init();
++#endif
+       /*
+        * Register with the SCSI layer all
+@@ -915,6 +1013,7 @@ ahc_linux_detect(Scsi_Host_Template *tem
+       return (found);
+ }
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ /*
+  * Free the passed in Scsi_Host memory structures prior to unloading the
+  * module.
+@@ -925,7 +1024,6 @@ ahc_linux_release(struct Scsi_Host * hos
+       struct ahc_softc *ahc;
+       u_long l;
+-      ahc_list_lock(&l);
+       if (host != NULL) {
+               /*
+@@ -933,19 +1031,23 @@ ahc_linux_release(struct Scsi_Host * hos
+                * the free directly, but check our
+                * list for extra sanity.
+                */
++              ahc_list_lock(&l);
+               ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata);
+               if (ahc != NULL) {
+                       u_long s;
++                      TAILQ_REMOVE(&ahc_tailq, ahc, links);
++                      ahc_list_unlock(&l);
+                       ahc_lock(ahc, &s);
+                       ahc_intr_enable(ahc, FALSE);
+                       ahc_unlock(ahc, &s);
+                       ahc_free(ahc);
+-              }
++              } else
++                      ahc_list_unlock(&l);
+       }
+-      ahc_list_unlock(&l);
+       return (0);
+ }
++#endif
+ /*
+  * Return a string describing the driver.
+@@ -982,7 +1084,7 @@ static int
+ ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
+ {
+       struct   ahc_softc *ahc;
+-      struct   ahc_linux_device *dev;
++      struct   aic_linux_device *dev;
+       u_long   flags;
+       ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
+@@ -1001,9 +1103,9 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*
+        * perform DV.
+        */
+       if (ahc->platform_data->qfrozen != 0
+-       && AHC_DV_CMD(cmd) == 0) {
++       && AIC_DV_CMD(cmd) == 0) {
+-              ahc_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ);
++              aic_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ);
+               ahc_linux_queue_cmd_complete(ahc, cmd);
+               ahc_schedule_completeq(ahc);
+               ahc_midlayer_entrypoint_unlock(ahc, &flags);
+@@ -1012,7 +1114,8 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*
+       dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id,
+                                  cmd->device->lun, /*alloc*/TRUE);
+       if (dev == NULL) {
+-              ahc_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
++
++              aic_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
+               ahc_linux_queue_cmd_complete(ahc, cmd);
+               ahc_schedule_completeq(ahc);
+               ahc_midlayer_entrypoint_unlock(ahc, &flags);
+@@ -1020,12 +1123,30 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*
+                      ahc_name(ahc));
+               return (0);
+       }
++
++      if (cmd->cmd_len > MAX_CDB_LEN) {
++
++              aic_cmd_set_transaction_status(cmd, CAM_REQ_INVALID);
++              ahc_linux_queue_cmd_complete(ahc, cmd);
++              ahc_schedule_completeq(ahc);
++              ahc_midlayer_entrypoint_unlock(ahc, &flags);
++              printf("%s: aic7xxx_linux_queue -"
++                     "CDB length of %d exceeds max!\n",
++                     ahc_name(ahc), cmd->cmd_len);
++              return (0);
++      }
++
++      /*
++       * We perform our own timeout handling.
++       */
++      scsi_delete_timer(cmd);
++
+       cmd->result = CAM_REQ_INPROG << 16;
+-      TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe);
+-      if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) {
++      TAILQ_INSERT_TAIL(&dev->busyq, (struct aic_cmd *)cmd, acmd_links.tqe);
++      if ((dev->flags & AIC_DEV_ON_RUN_LIST) == 0) {
+               TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links);
+-              dev->flags |= AHC_DEV_ON_RUN_LIST;
+-              ahc_linux_run_device_queues(ahc);
++              dev->flags |= AIC_DEV_ON_RUN_LIST;
++              aic_linux_run_device_queues(ahc);
+       }
+       ahc_midlayer_entrypoint_unlock(ahc, &flags);
+       return (0);
+@@ -1047,7 +1168,7 @@ static int
+ ahc_linux_slave_configure(Scsi_Device *device)
+ {
+       struct  ahc_softc *ahc;
+-      struct  ahc_linux_device *dev;
++      struct  aic_linux_device *dev;
+       u_long  flags;
+       ahc = *((struct ahc_softc **)device->host->hostdata);
+@@ -1063,9 +1184,9 @@ ahc_linux_slave_configure(Scsi_Device *d
+                                  device->id, device->lun,
+                                  /*alloc*/TRUE);
+       if (dev != NULL) {
+-              dev->flags &= ~AHC_DEV_UNCONFIGURED;
++              dev->flags &= ~AIC_DEV_UNCONFIGURED;
+               dev->scsi_device = device;
+-              ahc_linux_device_queue_depth(ahc, dev);
++              aic_linux_device_queue_depth(ahc, dev);
+       }
+       ahc_midlayer_entrypoint_unlock(ahc, &flags);
+       return (0);
+@@ -1075,7 +1196,7 @@ static void
+ ahc_linux_slave_destroy(Scsi_Device *device)
+ {
+       struct  ahc_softc *ahc;
+-      struct  ahc_linux_device *dev;
++      struct  aic_linux_device *dev;
+       u_long  flags;
+       ahc = *((struct ahc_softc **)device->host->hostdata);
+@@ -1093,11 +1214,10 @@ ahc_linux_slave_destroy(Scsi_Device *dev
+        * the refcounting process.
+        */
+       if (dev != NULL
+-       && (dev->flags & AHC_DEV_SLAVE_CONFIGURED) != 0) {
+-              dev->flags |= AHC_DEV_UNCONFIGURED;
++       && (dev->flags & AIC_DEV_SLAVE_CONFIGURED) != 0) {
++              dev->flags |= AIC_DEV_UNCONFIGURED;
+               if (TAILQ_EMPTY(&dev->busyq)
+-               && dev->active == 0
+-               && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0)
++               && dev->active == 0)
+                       ahc_linux_free_device(ahc, dev);
+       }
+       ahc_midlayer_entrypoint_unlock(ahc, &flags);
+@@ -1136,7 +1256,7 @@ ahc_linux_select_queue_depth(struct Scsi
+                       continue;
+               if (device->host == host) {
+-                      struct   ahc_linux_device *dev;
++                      struct   aic_linux_device *dev;
+                       /*
+                        * Since Linux has attached to the device, configure
+@@ -1147,13 +1267,13 @@ ahc_linux_select_queue_depth(struct Scsi
+                                                  device->id, device->lun,
+                                                  /*alloc*/TRUE);
+                       if (dev != NULL) {
+-                              dev->flags &= ~AHC_DEV_UNCONFIGURED;
++                              dev->flags &= ~AIC_DEV_UNCONFIGURED;
+                               dev->scsi_device = device;
+-                              ahc_linux_device_queue_depth(ahc, dev);
++                              aic_linux_device_queue_depth(ahc, dev);
+                               device->queue_depth = dev->openings
+                                                   + dev->active;
+-                              if ((dev->flags & (AHC_DEV_Q_BASIC
+-                                              | AHC_DEV_Q_TAGGED)) == 0) {
++                              if ((dev->flags & (AIC_DEV_Q_BASIC
++                                              | AIC_DEV_Q_TAGGED)) == 0) {
+                                       /*
+                                        * We allow the OS to queue 2 untagged
+                                        * transactions to us at any time even
+@@ -1291,63 +1411,8 @@ ahc_linux_bus_reset(Scsi_Cmnd *cmd)
+       return SUCCESS;
+ }
+-Scsi_Host_Template aic7xxx_driver_template = {
+-      .module                 = THIS_MODULE,
+-      .name                   = "aic7xxx",
+-      .proc_info              = ahc_linux_proc_info,
+-      .info                   = ahc_linux_info,
+-      .queuecommand           = ahc_linux_queue,
+-      .eh_abort_handler       = ahc_linux_abort,
+-      .eh_device_reset_handler = ahc_linux_dev_reset,
+-      .eh_bus_reset_handler   = ahc_linux_bus_reset,
+-#if defined(__i386__)
+-      .bios_param             = ahc_linux_biosparam,
+-#endif
+-      .can_queue              = AHC_MAX_QUEUE,
+-      .this_id                = -1,
+-      .cmd_per_lun            = 2,
+-      .use_clustering         = ENABLE_CLUSTERING,
+-      .slave_alloc            = ahc_linux_slave_alloc,
+-      .slave_configure        = ahc_linux_slave_configure,
+-      .slave_destroy          = ahc_linux_slave_destroy,
+-};
+-
+-/**************************** Tasklet Handler *********************************/
+-
+-/*
+- * In 2.4.X and above, this routine is called from a tasklet,
+- * so we must re-acquire our lock prior to executing this code.
+- * In all prior kernels, ahc_schedule_runq() calls this routine
+- * directly and ahc_schedule_runq() is called with our lock held.
+- */
+-static void
+-ahc_runq_tasklet(unsigned long data)
+-{
+-      struct ahc_softc* ahc;
+-      struct ahc_linux_device *dev;
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      u_long flags;
+-#endif
+-
+-      ahc = (struct ahc_softc *)data;
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      ahc_lock(ahc, &flags);
+-#endif
+-      while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) {
+-      
+-              TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links);
+-              dev->flags &= ~AHC_DEV_ON_RUN_LIST;
+-              ahc_linux_check_device_queue(ahc, dev);
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-              /* Yeild to our interrupt handler */
+-              ahc_unlock(ahc, &flags);
+-              ahc_lock(ahc, &flags);
+-#endif
+-      }
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      ahc_unlock(ahc, &flags);
+-#endif
+-}
++Scsi_Host_Template aic7xxx_driver_template =
++      AIC_TEMPLATE_INITIALIZER("aic7xxx", /* max_sectors*/8192);
+ /******************************** Macros **************************************/
+ #define BUILD_SCSIID(ahc, cmd)                                                    \
+@@ -1355,132 +1420,6 @@ ahc_runq_tasklet(unsigned long data)
+       | (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \
+       | (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB))
+-/******************************** Bus DMA *************************************/
+-int
+-ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent,
+-                 bus_size_t alignment, bus_size_t boundary,
+-                 bus_addr_t lowaddr, bus_addr_t highaddr,
+-                 bus_dma_filter_t *filter, void *filterarg,
+-                 bus_size_t maxsize, int nsegments,
+-                 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
+-{
+-      bus_dma_tag_t dmat;
+-
+-      dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT);
+-      if (dmat == NULL)
+-              return (ENOMEM);
+-
+-      /*
+-       * Linux is very simplistic about DMA memory.  For now don't
+-       * maintain all specification information.  Once Linux supplies
+-       * better facilities for doing these operations, or the
+-       * needs of this particular driver change, we might need to do
+-       * more here.
+-       */
+-      dmat->alignment = alignment;
+-      dmat->boundary = boundary;
+-      dmat->maxsize = maxsize;
+-      *ret_tag = dmat;
+-      return (0);
+-}
+-
+-void
+-ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat)
+-{
+-      free(dmat, M_DEVBUF);
+-}
+-
+-int
+-ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr,
+-               int flags, bus_dmamap_t *mapp)
+-{
+-      bus_dmamap_t map;
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT);
+-      if (map == NULL)
+-              return (ENOMEM);
+-      /*
+-       * Although we can dma data above 4GB, our
+-       * "consistent" memory is below 4GB for
+-       * space efficiency reasons (only need a 4byte
+-       * address).  For this reason, we have to reset
+-       * our dma mask when doing allocations.
+-       */
+-      if (ahc->dev_softc != NULL)
+-              ahc_pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF);
+-      *vaddr = pci_alloc_consistent(ahc->dev_softc,
+-                                    dmat->maxsize, &map->bus_addr);
+-      if (ahc->dev_softc != NULL)
+-              ahc_pci_set_dma_mask(ahc->dev_softc,
+-                                   ahc->platform_data->hw_dma_mask);
+-#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */
+-      /*
+-       * At least in 2.2.14, malloc is a slab allocator so all
+-       * allocations are aligned.  We assume for these kernel versions
+-       * that all allocations will be bellow 4Gig, physically contiguous,
+-       * and accessible via DMA by the controller.
+-       */
+-      map = NULL; /* No additional information to store */
+-      *vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT);
+-#endif
+-      if (*vaddr == NULL)
+-              return (ENOMEM);
+-      *mapp = map;
+-      return(0);
+-}
+-
+-void
+-ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat,
+-              void* vaddr, bus_dmamap_t map)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      pci_free_consistent(ahc->dev_softc, dmat->maxsize,
+-                          vaddr, map->bus_addr);
+-#else
+-      free(vaddr, M_DEVBUF);
+-#endif
+-}
+-
+-int
+-ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map,
+-              void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
+-              void *cb_arg, int flags)
+-{
+-      /*
+-       * Assume for now that this will only be used during
+-       * initialization and not for per-transaction buffer mapping.
+-       */
+-      bus_dma_segment_t stack_sg;
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      stack_sg.ds_addr = map->bus_addr;
+-#else
+-#define VIRT_TO_BUS(a) (uint32_t)virt_to_bus((void *)(a))
+-      stack_sg.ds_addr = VIRT_TO_BUS(buf);
+-#endif
+-      stack_sg.ds_len = dmat->maxsize;
+-      cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0);
+-      return (0);
+-}
+-
+-void
+-ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
+-{
+-      /*
+-       * The map may is NULL in our < 2.3.X implementation.
+-       */
+-      if (map != NULL)
+-              free(map, M_DEVBUF);
+-}
+-
+-int
+-ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
+-{
+-      /* Nothing to do */
+-      return (0);
+-}
+-
+ /********************* Platform Dependent Functions ***************************/
+ /*
+  * Compare "left hand" softc with "right hand" softc, returning:
+@@ -1525,24 +1464,25 @@ ahc_softc_comp(struct ahc_softc *lahc, s
+       /* Still equal.  Sort by BIOS address, ioport, or bus/slot/func. */
+       switch (rvalue) {
++#ifdef CONFIG_PCI
+       case AHC_PCI:
+       {
+               char primary_channel;
+               if (aic7xxx_reverse_scan != 0)
+-                      value = ahc_get_pci_bus(lahc->dev_softc)
+-                            - ahc_get_pci_bus(rahc->dev_softc);
++                      value = aic_get_pci_bus(lahc->dev_softc)
++                            - aic_get_pci_bus(rahc->dev_softc);
+               else
+-                      value = ahc_get_pci_bus(rahc->dev_softc)
+-                            - ahc_get_pci_bus(lahc->dev_softc);
++                      value = aic_get_pci_bus(rahc->dev_softc)
++                            - aic_get_pci_bus(lahc->dev_softc);
+               if (value != 0)
+                       break;
+               if (aic7xxx_reverse_scan != 0)
+-                      value = ahc_get_pci_slot(lahc->dev_softc)
+-                            - ahc_get_pci_slot(rahc->dev_softc);
++                      value = aic_get_pci_slot(lahc->dev_softc)
++                            - aic_get_pci_slot(rahc->dev_softc);
+               else
+-                      value = ahc_get_pci_slot(rahc->dev_softc)
+-                            - ahc_get_pci_slot(lahc->dev_softc);
++                      value = aic_get_pci_slot(rahc->dev_softc)
++                            - aic_get_pci_slot(lahc->dev_softc);
+               if (value != 0)
+                       break;
+               /*
+@@ -1557,6 +1497,8 @@ ahc_softc_comp(struct ahc_softc *lahc, s
+                       value = 1;
+               break;
+       }
++#endif
++#ifdef CONFIG_EISA
+       case AHC_EISA:
+               if ((rahc->flags & AHC_BIOS_ENABLED) != 0) {
+                       value = rahc->platform_data->bios_address
+@@ -1566,6 +1508,7 @@ ahc_softc_comp(struct ahc_softc *lahc, s
+                             - lahc->bsh.ioport; 
+               }
+               break;
++#endif
+       default:
+               panic("ahc_softc_sort: invalid bus type");
+       }
+@@ -1699,9 +1642,16 @@ ahc_linux_register_host(struct ahc_softc
+       char    *new_name;
+       u_long   s;
+       u_int    targ_offset;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++      int      error;
++#endif
+       template->name = ahc->description;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       host = scsi_host_alloc(template, sizeof(struct ahc_softc *));
++#else
++      host = scsi_register(template, sizeof(struct ahc_softc *));
++#endif
+       if (host == NULL)
+               return (ENOMEM);
+@@ -1710,8 +1660,12 @@ ahc_linux_register_host(struct ahc_softc
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       scsi_assign_lock(host, &ahc->platform_data->spin_lock);
+ #elif AHC_SCSI_HAS_HOST_LOCK != 0
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,21)
++      host->host_lock = &ahc->platform_data->spin_lock;
++#else
+       host->lock = &ahc->platform_data->spin_lock;
+ #endif
++#endif
+       ahc->platform_data->host = host;
+       host->can_queue = AHC_MAX_QUEUE;
+       host->cmd_per_lun = 2;
+@@ -1736,13 +1690,20 @@ ahc_linux_register_host(struct ahc_softc
+ #endif
+       ahc_linux_initialize_scsi_bus(ahc);
+       ahc_unlock(ahc, &s);
++      ahc_sysrq_key = aic_install_sysrq(&ahc_sysrq_op);
++      ahc_spawn_recovery_thread(ahc);
++      if (ahc->platform_data->recovery_pid < 0) {
++              printf("%s: Failed to create recovery thread, error= %d\n",
++                     ahc_name(ahc), ahc->platform_data->recovery_pid);
++              return (-ahc->platform_data->recovery_pid);
++      }
+       ahc->platform_data->dv_pid = kernel_thread(ahc_linux_dv_thread, ahc, 0);
+-      ahc_lock(ahc, &s);
+       if (ahc->platform_data->dv_pid < 0) {
+               printf("%s: Failed to create DV thread, error= %d\n",
+                      ahc_name(ahc), ahc->platform_data->dv_pid);
+               return (-ahc->platform_data->dv_pid);
+       }
++      ahc_lock(ahc, &s);
+       /*
+        * Initially allocate *all* of our linux target objects
+        * so that the DV thread will scan them all in parallel
+@@ -1787,7 +1748,9 @@ ahc_linux_register_host(struct ahc_softc
+       ahc_unlock(ahc, &s);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+-      scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */
++      error = scsi_add_host(host, ahc->dev_softc);
++      if (error != 0)
++              return (-error);
+       scsi_scan_host(host);
+ #endif
+       return (0);
+@@ -1885,17 +1848,6 @@ ahc_linux_initialize_scsi_bus(struct ahc
+               ahc_update_neg_request(ahc, &devinfo, tstate,
+                                      tinfo, AHC_NEG_ALWAYS);
+       }
+-      /* Give the bus some time to recover */
+-      if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
+-              ahc_linux_freeze_simq(ahc);
+-              init_timer(&ahc->platform_data->reset_timer);
+-              ahc->platform_data->reset_timer.data = (u_long)ahc;
+-              ahc->platform_data->reset_timer.expires =
+-                  jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000;
+-              ahc->platform_data->reset_timer.function =
+-                  ahc_linux_release_simq;
+-              add_timer(&ahc->platform_data->reset_timer);
+-      }
+ }
+ int
+@@ -1909,27 +1861,32 @@ ahc_platform_alloc(struct ahc_softc *ahc
+       memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
+       TAILQ_INIT(&ahc->platform_data->completeq);
+       TAILQ_INIT(&ahc->platform_data->device_runq);
+-      ahc->platform_data->irq = AHC_LINUX_NOIRQ;
++      ahc->platform_data->irq = AIC_LINUX_NOIRQ;
+       ahc->platform_data->hw_dma_mask = 0xFFFFFFFF;
+       ahc_lockinit(ahc);
+       ahc_done_lockinit(ahc);
++      init_timer(&ahc->platform_data->bus_settle_timer);
++      ahc->platform_data->bus_settle_timer.data = (u_long)ahc;
++      ahc->platform_data->bus_settle_timer.function =
++          (aic_linux_callback_t *)aic_bus_settle_complete;
+       init_timer(&ahc->platform_data->completeq_timer);
+       ahc->platform_data->completeq_timer.data = (u_long)ahc;
+       ahc->platform_data->completeq_timer.function =
+-          (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue;
++          (aic_linux_callback_t *)ahc_linux_thread_run_complete_queue;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+       init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
+       init_MUTEX_LOCKED(&ahc->platform_data->dv_sem);
+       init_MUTEX_LOCKED(&ahc->platform_data->dv_cmd_sem);
++      init_MUTEX_LOCKED(&ahc->platform_data->recovery_sem);
++      init_MUTEX_LOCKED(&ahc->platform_data->recovery_ending_sem);
+ #else
+       ahc->platform_data->eh_sem = MUTEX_LOCKED;
+       ahc->platform_data->dv_sem = MUTEX_LOCKED;
+       ahc->platform_data->dv_cmd_sem = MUTEX_LOCKED;
++      ahc->platform_data->recovery_sem = MUTEX_LOCKED;
++      ahc->platform_data->recovery_ending_sem = MUTEX_LOCKED;
+ #endif
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet,
+-                   (unsigned long)ahc);
+-#endif
++      aic_setup_tasklets(ahc);
+       ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
+       ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
+       if (aic7xxx_pci_parity == 0)
+@@ -1941,21 +1898,22 @@ ahc_platform_alloc(struct ahc_softc *ahc
+ void
+ ahc_platform_free(struct ahc_softc *ahc)
+ {
+-      struct ahc_linux_target *targ;
+-      struct ahc_linux_device *dev;
++      struct aic_linux_target *targ;
++      struct aic_linux_device *dev;
+       int i, j;
++      aic_remove_sysrq(ahc_sysrq_key, &ahc_sysrq_op);
+       if (ahc->platform_data != NULL) {
+               del_timer_sync(&ahc->platform_data->completeq_timer);
+               ahc_linux_kill_dv_thread(ahc);
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-              tasklet_kill(&ahc->platform_data->runq_tasklet);
+-#endif
++              aic_teardown_tasklets(ahc);
+               if (ahc->platform_data->host != NULL) {
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+                       scsi_remove_host(ahc->platform_data->host);
+-#endif
+                       scsi_host_put(ahc->platform_data->host);
++#else
++                      scsi_unregister(ahc->platform_data->host);
++#endif
+               }
+               /* destroy all of the device and target objects */
+@@ -1969,6 +1927,7 @@ ahc_platform_free(struct ahc_softc *ahc)
+                                       if (targ->devices[j] == NULL)
+                                               continue;
+                                       dev = targ->devices[j];
++                                      del_timer_sync(&dev->timer);
+                                       ahc_linux_free_device(ahc, dev);
+                               }
+                               /*
+@@ -1979,7 +1938,7 @@ ahc_platform_free(struct ahc_softc *ahc)
+                       }
+               }
+-              if (ahc->platform_data->irq != AHC_LINUX_NOIRQ)
++              if (ahc->platform_data->irq != AIC_LINUX_NOIRQ)
+                       free_irq(ahc->platform_data->irq, ahc);
+               if (ahc->tag == BUS_SPACE_PIO
+                && ahc->bsh.ioport != 0)
+@@ -2024,7 +1983,7 @@ void
+ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
+                     ahc_queue_alg alg)
+ {
+-      struct ahc_linux_device *dev;
++      struct aic_linux_device *dev;
+       int was_queuing;
+       int now_queuing;
+@@ -2033,27 +1992,27 @@ ahc_platform_set_tags(struct ahc_softc *
+                                  devinfo->lun, /*alloc*/FALSE);
+       if (dev == NULL)
+               return;
+-      was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED);
++      was_queuing = dev->flags & (AIC_DEV_Q_BASIC|AIC_DEV_Q_TAGGED);
+       switch (alg) {
+       default:
+       case AHC_QUEUE_NONE:
+               now_queuing = 0;
+               break; 
+       case AHC_QUEUE_BASIC:
+-              now_queuing = AHC_DEV_Q_BASIC;
++              now_queuing = AIC_DEV_Q_BASIC;
+               break;
+       case AHC_QUEUE_TAGGED:
+-              now_queuing = AHC_DEV_Q_TAGGED;
++              now_queuing = AIC_DEV_Q_TAGGED;
+               break;
+       }
+-      if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) == 0
++      if ((dev->flags & AIC_DEV_FREEZE_TIL_EMPTY) == 0
+        && (was_queuing != now_queuing)
+        && (dev->active != 0)) {
+-              dev->flags |= AHC_DEV_FREEZE_TIL_EMPTY;
++              dev->flags |= AIC_DEV_FREEZE_TIL_EMPTY;
+               dev->qfrozen++;
+       }
+-      dev->flags &= ~(AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED|AHC_DEV_PERIODIC_OTAG);
++      dev->flags &= ~(AIC_DEV_Q_BASIC|AIC_DEV_Q_TAGGED|AIC_DEV_PERIODIC_OTAG);
+       if (now_queuing) {
+               u_int usertags;
+@@ -2073,11 +2032,11 @@ ahc_platform_set_tags(struct ahc_softc *
+                        */
+                       dev->openings = 1;
+               } else if (alg == AHC_QUEUE_TAGGED) {
+-                      dev->flags |= AHC_DEV_Q_TAGGED;
++                      dev->flags |= AIC_DEV_Q_TAGGED;
+                       if (aic7xxx_periodic_otag != 0)
+-                              dev->flags |= AHC_DEV_PERIODIC_OTAG;
++                              dev->flags |= AIC_DEV_PERIODIC_OTAG;
+               } else
+-                      dev->flags |= AHC_DEV_Q_BASIC;
++                      dev->flags |= AIC_DEV_Q_BASIC;
+       } else {
+               /* We can only have one opening. */
+               dev->maxtags = 0;
+@@ -2085,13 +2044,13 @@ ahc_platform_set_tags(struct ahc_softc *
+       }
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+       if (dev->scsi_device != NULL) {
+-              switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
+-              case AHC_DEV_Q_BASIC:
++              switch ((dev->flags & (AIC_DEV_Q_BASIC|AIC_DEV_Q_TAGGED))) {
++              case AIC_DEV_Q_BASIC:
+                       scsi_adjust_queue_depth(dev->scsi_device,
+                                               MSG_SIMPLE_TASK,
+                                               dev->openings + dev->active);
+                       break;
+-              case AHC_DEV_Q_TAGGED:
++              case AIC_DEV_Q_TAGGED:
+                       scsi_adjust_queue_depth(dev->scsi_device,
+                                               MSG_ORDERED_TASK,
+                                               dev->openings + dev->active);
+@@ -2155,9 +2114,9 @@ ahc_platform_abort_scbs(struct ahc_softc
+               for (; targ < maxtarg; targ++) {
+                       for (; clun < maxlun; clun++) {
+-                              struct ahc_linux_device *dev;
+-                              struct ahc_busyq *busyq;
+-                              struct ahc_cmd *acmd;
++                              struct aic_linux_device *dev;
++                              struct aic_busyq *busyq;
++                              struct aic_cmd *acmd;
+                               dev = ahc_linux_get_device(ahc, chan,
+                                                          targ, clun,
+@@ -2174,6 +2133,20 @@ ahc_platform_abort_scbs(struct ahc_softc
+                                                    acmd_links.tqe);
+                                       count++;
+                                       cmd->result = status << 16;
++                                      /*
++                                       * The completion handler believes that
++                                       * commands without active timers
++                                       * running have lost the race of
++                                       * completing before their timer
++                                       * expires.  Since commands in our
++                                       * busy queues do not have timers
++                                       * running, appease the mid-layer by
++                                       * adding a timer now.  This timer will
++                                       * be immediately canceled by the
++                                       * midlayer.
++                                       */
++                                      scsi_add_timer(cmd, 60*HZ,
++                                          aic_linux_midlayer_timeout);
+                                       ahc_linux_queue_cmd_complete(ahc, cmd);
+                               }
+                       }
+@@ -2190,7 +2163,7 @@ ahc_linux_thread_run_complete_queue(stru
+       ahc_lock(ahc, &flags);
+       del_timer(&ahc->platform_data->completeq_timer);
+-      ahc->platform_data->flags &= ~AHC_RUN_CMPLT_Q_TIMER;
++      ahc->platform_data->flags &= ~AIC_RUN_CMPLT_Q_TIMER;
+       ahc_linux_run_complete_queue(ahc);
+       ahc_unlock(ahc, &flags);
+ }
+@@ -2203,14 +2176,23 @@ ahc_linux_start_dv(struct ahc_softc *ahc
+        * Freeze the simq and signal ahc_linux_queue to not let any
+        * more commands through.
+        */
+-      if ((ahc->platform_data->flags & AHC_DV_ACTIVE) == 0) {
++      if ((ahc->platform_data->flags & AIC_DV_ACTIVE) == 0) {
+ #ifdef AHC_DEBUG
+               if (ahc_debug & AHC_SHOW_DV)
+                       printf("%s: Waking DV thread\n", ahc_name(ahc));
+ #endif
+-              ahc->platform_data->flags |= AHC_DV_ACTIVE;
+-              ahc_linux_freeze_simq(ahc);
++              ahc->platform_data->flags |= AIC_DV_ACTIVE;
++
++              /*
++               * Prevent upper layer from sending any
++               * commands to us.
++               */
++              aic_freeze_simq(ahc);
++              scsi_block_requests(ahc->platform_data->host);
++              ahc_platform_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
++                                      CAM_LUN_WILDCARD, SCB_LIST_NULL,
++                                      ROLE_INITIATOR, CAM_REQUEUE_REQ);
+               /* Wake up the DV kthread */
+               up(&ahc->platform_data->dv_sem);
+@@ -2224,7 +2206,7 @@ ahc_linux_kill_dv_thread(struct ahc_soft
+       ahc_lock(ahc, &s);
+       if (ahc->platform_data->dv_pid != 0) {
+-              ahc->platform_data->flags |= AHC_DV_SHUTDOWN;
++              ahc->platform_data->flags |= AIC_DV_SHUTDOWN;
+               ahc_unlock(ahc, &s);
+               up(&ahc->platform_data->dv_sem);
+@@ -2299,7 +2281,7 @@ ahc_linux_dv_thread(void *data)
+               /* Check to see if we've been signaled to exit */
+               ahc_lock(ahc, &s);
+-              if ((ahc->platform_data->flags & AHC_DV_SHUTDOWN) != 0) {
++              if ((ahc->platform_data->flags & AIC_DV_SHUTDOWN) != 0) {
+                       ahc_unlock(ahc, &s);
+                       break;
+               }
+@@ -2316,7 +2298,7 @@ ahc_linux_dv_thread(void *data)
+                */
+               ahc_lock(ahc, &s);
+               while (LIST_FIRST(&ahc->pending_scbs) != NULL) {
+-                      ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_EMPTY;
++                      ahc->platform_data->flags |= AIC_DV_WAIT_SIMQ_EMPTY;
+                       ahc_unlock(ahc, &s);
+                       down_interruptible(&ahc->platform_data->dv_sem);
+                       ahc_lock(ahc, &s);
+@@ -2326,8 +2308,8 @@ ahc_linux_dv_thread(void *data)
+                * Wait for the SIMQ to be released so that DV is the
+                * only reason the queue is frozen.
+                */
+-              while (AHC_DV_SIMQ_FROZEN(ahc) == 0) {
+-                      ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_RELEASE;
++              while (AIC_DV_SIMQ_FROZEN(ahc) == 0) {
++                      ahc->platform_data->flags |= AIC_DV_WAIT_SIMQ_RELEASE;
+                       ahc_unlock(ahc, &s);
+                       down_interruptible(&ahc->platform_data->dv_sem);
+                       ahc_lock(ahc, &s);
+@@ -2338,14 +2320,16 @@ ahc_linux_dv_thread(void *data)
+                       ahc_linux_dv_target(ahc, target);
+               ahc_lock(ahc, &s);
+-              ahc->platform_data->flags &= ~AHC_DV_ACTIVE;
+-              ahc_unlock(ahc, &s);
++              ahc->platform_data->flags &= ~AIC_DV_ACTIVE;
+               /*
+                * Release the SIMQ so that normal commands are
+                * allowed to continue on the bus.
+                */
+-              ahc_linux_release_simq((u_long)ahc);
++              aic_release_simq_locked(ahc);
++              ahc_unlock(ahc, &s);
++
++              scsi_unblock_requests(ahc->platform_data->host);
+       }
+       up(&ahc->platform_data->eh_sem);
+       return (0);
+@@ -2359,10 +2343,10 @@ ahc_linux_dv_thread(void *data)
+       ahc_set_dv_state(ahc, targ, newstate, __LINE__)
+ static __inline void
+-ahc_set_dv_state(struct ahc_softc *ahc, struct ahc_linux_target *targ,
+-               ahc_dv_state newstate, u_int line)
++ahc_set_dv_state(struct ahc_softc *ahc, struct aic_linux_target *targ,
++               aic_dv_state newstate, u_int line)
+ {
+-      ahc_dv_state oldstate;
++      aic_dv_state oldstate;
+       oldstate = targ->dv_state;
+ #ifdef AHC_DEBUG
+@@ -2382,7 +2366,7 @@ static void
+ ahc_linux_dv_target(struct ahc_softc *ahc, u_int target_offset)
+ {
+       struct   ahc_devinfo devinfo;
+-      struct   ahc_linux_target *targ;
++      struct   aic_linux_target *targ;
+       struct   scsi_cmnd *cmd;
+       struct   scsi_device *scsi_dev;
+       struct   scsi_sense_data *sense;
+@@ -2396,7 +2380,7 @@ ahc_linux_dv_target(struct ahc_softc *ah
+       echo_size = 0;
+       ahc_lock(ahc, &s);
+       targ = ahc->platform_data->targets[target_offset];
+-      if (targ == NULL || (targ->flags & AHC_DV_REQUIRED) == 0) {
++      if (targ == NULL || (targ->flags & AIC_DV_REQUIRED) == 0) {
+               ahc_unlock(ahc, &s);
+               return;
+       }
+@@ -2421,14 +2405,14 @@ ahc_linux_dv_target(struct ahc_softc *ah
+       scsi_dev->channel = devinfo.channel - 'A';
+       ahc->platform_data->dv_scsi_dev = scsi_dev;
+-      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_SHORT_ASYNC);
++      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_INQ_SHORT_ASYNC);
+-      while (targ->dv_state != AHC_DV_STATE_EXIT) {
++      while (targ->dv_state != AIC_DV_STATE_EXIT) {
+               timeout = AHC_LINUX_DV_TIMEOUT;
+               switch (targ->dv_state) {
+-              case AHC_DV_STATE_INQ_SHORT_ASYNC:
+-              case AHC_DV_STATE_INQ_ASYNC:
+-              case AHC_DV_STATE_INQ_ASYNC_VERIFY:
++              case AIC_DV_STATE_INQ_SHORT_ASYNC:
++              case AIC_DV_STATE_INQ_ASYNC:
++              case AIC_DV_STATE_INQ_ASYNC_VERIFY:
+                       /*
+                        * Set things to async narrow to reduce the
+                        * chance that the INQ will fail.
+@@ -2440,36 +2424,36 @@ ahc_linux_dv_target(struct ahc_softc *ah
+                                     AHC_TRANS_GOAL, /*paused*/FALSE);
+                       ahc_unlock(ahc, &s);
+                       timeout = 10 * HZ;
+-                      targ->flags &= ~AHC_INQ_VALID;
++                      targ->flags &= ~AIC_INQ_VALID;
+                       /* FALLTHROUGH */
+-              case AHC_DV_STATE_INQ_VERIFY:
++              case AIC_DV_STATE_INQ_VERIFY:
+               {
+                       u_int inq_len;
+-                      if (targ->dv_state == AHC_DV_STATE_INQ_SHORT_ASYNC)
++                      if (targ->dv_state == AIC_DV_STATE_INQ_SHORT_ASYNC)
+                               inq_len = AHC_LINUX_DV_INQ_SHORT_LEN;
+                       else
+                               inq_len = targ->inq_data->additional_length + 5;
+                       ahc_linux_dv_inq(ahc, cmd, &devinfo, targ, inq_len);
+                       break;
+               }
+-              case AHC_DV_STATE_TUR:
+-              case AHC_DV_STATE_BUSY:
++              case AIC_DV_STATE_TUR:
++              case AIC_DV_STATE_BUSY:
+                       timeout = 5 * HZ;
+                       ahc_linux_dv_tur(ahc, cmd, &devinfo);
+                       break;
+-              case AHC_DV_STATE_REBD:
++              case AIC_DV_STATE_REBD:
+                       ahc_linux_dv_rebd(ahc, cmd, &devinfo, targ);
+                       break;
+-              case AHC_DV_STATE_WEB:
++              case AIC_DV_STATE_WEB:
+                       ahc_linux_dv_web(ahc, cmd, &devinfo, targ);
+                       break;
+-              case AHC_DV_STATE_REB:
++              case AIC_DV_STATE_REB:
+                       ahc_linux_dv_reb(ahc, cmd, &devinfo, targ);
+                       break;
+-              case AHC_DV_STATE_SU:
++              case AIC_DV_STATE_SU:
+                       ahc_linux_dv_su(ahc, cmd, &devinfo, targ);
+                       timeout = 50 * HZ;
+                       break;
+@@ -2481,8 +2465,6 @@ ahc_linux_dv_target(struct ahc_softc *ah
+               }
+               /* Queue the command and wait for it to complete */
+-              /* Abuse eh_timeout in the scsi_cmnd struct for our purposes */
+-              init_timer(&cmd->eh_timeout);
+ #ifdef AHC_DEBUG
+               if ((ahc_debug & AHC_SHOW_MESSAGES) != 0)
+                       /*
+@@ -2492,7 +2474,9 @@ ahc_linux_dv_target(struct ahc_softc *ah
+                        */
+                       timeout += HZ;
+ #endif
+-              scsi_add_timer(cmd, timeout, ahc_linux_dv_timeout);
++              init_timer(&cmd->eh_timeout);
++              cmd->timeout_per_command = timeout;
++
+               /*
+                * In 2.5.X, it is assumed that all calls from the
+                * "midlayer" (which we are emulating) will have the
+@@ -2516,8 +2500,8 @@ ahc_linux_dv_target(struct ahc_softc *ah
+                * only reason the queue is frozen.
+                */
+               ahc_lock(ahc, &s);
+-              while (AHC_DV_SIMQ_FROZEN(ahc) == 0) {
+-                      ahc->platform_data->flags |= AHC_DV_WAIT_SIMQ_RELEASE;
++              while (AIC_DV_SIMQ_FROZEN(ahc) == 0) {
++                      ahc->platform_data->flags |= AIC_DV_WAIT_SIMQ_RELEASE;
+                       ahc_unlock(ahc, &s);
+                       down_interruptible(&ahc->platform_data->dv_sem);
+                       ahc_lock(ahc, &s);
+@@ -2528,7 +2512,7 @@ ahc_linux_dv_target(struct ahc_softc *ah
+       }
+ out:
+-      if ((targ->flags & AHC_INQ_VALID) != 0
++      if ((targ->flags & AIC_INQ_VALID) != 0
+        && ahc_linux_get_device(ahc, devinfo.channel - 'A',
+                                devinfo.target, devinfo.lun,
+                                /*alloc*/FALSE) == NULL) {
+@@ -2539,7 +2523,7 @@ out:
+                * parameters found in the inquiry string.
+                */
+               ahc_linux_filter_inquiry(ahc, &devinfo);
+-              if ((targ->flags & (AHC_BASIC_DV|AHC_ENHANCED_DV)) != 0) {
++              if ((targ->flags & (AIC_BASIC_DV|AIC_ENHANCED_DV)) != 0) {
+                       ahc_print_devinfo(ahc, &devinfo);
+                       printf("DV failed to configure device.  "
+                              "Please file a bug report against "
+@@ -2564,7 +2548,7 @@ out:
+               free(targ->dv_buffer1, M_DEVBUF);
+               targ->dv_buffer1 = NULL;
+       }
+-      targ->flags &= ~AHC_DV_REQUIRED;
++      targ->flags &= ~AIC_DV_REQUIRED;
+       if (targ->refcount == 0)
+               ahc_linux_free_target(ahc, targ);
+       ahc_unlock(ahc, &s);
+@@ -2573,13 +2557,13 @@ out:
+ static void
+ ahc_linux_dv_transition(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
+                       struct ahc_devinfo *devinfo,
+-                      struct ahc_linux_target *targ)
++                      struct aic_linux_target *targ)
+ {
+       u_int32_t status;
+       status = aic_error_action(cmd, targ->inq_data,
+-                                ahc_cmd_get_transaction_status(cmd),
+-                                ahc_cmd_get_scsi_status(cmd));
++                                aic_cmd_get_transaction_status(cmd),
++                                aic_cmd_get_scsi_status(cmd));
+       
+ #ifdef AHC_DEBUG
+       if (ahc_debug & AHC_SHOW_DV) {
+@@ -2591,8 +2575,8 @@ ahc_linux_dv_transition(struct ahc_softc
+ #endif
+       switch (targ->dv_state) {
+-      case AHC_DV_STATE_INQ_SHORT_ASYNC:
+-      case AHC_DV_STATE_INQ_ASYNC:
++      case AIC_DV_STATE_INQ_SHORT_ASYNC:
++      case AIC_DV_STATE_INQ_ASYNC:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               {
+@@ -2601,21 +2585,21 @@ ahc_linux_dv_transition(struct ahc_softc
+               }
+               case SS_INQ_REFRESH:
+                       AHC_SET_DV_STATE(ahc, targ,
+-                                       AHC_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_TUR:
+               case SS_RETRY:
+                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
+-                      if (ahc_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ)
+                               targ->dv_state_retry--;
+                       if ((status & SS_ERRMASK) == EBUSY)
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_BUSY);
+                       if (targ->dv_state_retry < 10)
+                               break;
+                       /* FALLTHROUGH */
+               default:
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+ #ifdef AHC_DEBUG
+                       if (ahc_debug & AHC_SHOW_DV) {
+                               ahc_print_devinfo(ahc, devinfo);
+@@ -2625,7 +2609,7 @@ ahc_linux_dv_transition(struct ahc_softc
+                       break;
+               }
+               break;
+-      case AHC_DV_STATE_INQ_ASYNC_VERIFY:
++      case AIC_DV_STATE_INQ_ASYNC_VERIFY:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               {
+@@ -2639,12 +2623,12 @@ ahc_linux_dv_transition(struct ahc_softc
+                                * Try from the top again.
+                                */
+                               AHC_SET_DV_STATE(ahc, targ,
+-                                               AHC_DV_STATE_INQ_SHORT_ASYNC);
++                                               AIC_DV_STATE_INQ_SHORT_ASYNC);
+                               break;
+                       }
+                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state+1);
+-                      targ->flags |= AHC_INQ_VALID;
++                      targ->flags |= AIC_INQ_VALID;
+                       if (ahc_linux_user_dv_setting(ahc) == 0)
+                               break;
+@@ -2657,33 +2641,33 @@ ahc_linux_dv_transition(struct ahc_softc
+                       default:
+                       case SID_SPI_CLOCK_ST:
+                               /* Assume only basic DV is supported. */
+-                              targ->flags |= AHC_BASIC_DV;
++                              targ->flags |= AIC_BASIC_DV;
+                               break;
+                       case SID_SPI_CLOCK_DT:
+                       case SID_SPI_CLOCK_DT_ST:
+-                              targ->flags |= AHC_ENHANCED_DV;
++                              targ->flags |= AIC_ENHANCED_DV;
+                               break;
+                       }
+                       break;
+               }
+               case SS_INQ_REFRESH:
+                       AHC_SET_DV_STATE(ahc, targ,
+-                                       AHC_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_TUR:
+               case SS_RETRY:
+                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
+-                      if (ahc_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ)
+                               targ->dv_state_retry--;
+                       if ((status & SS_ERRMASK) == EBUSY)
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_BUSY);
+                       if (targ->dv_state_retry < 10)
+                               break;
+                       /* FALLTHROUGH */
+               default:
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+ #ifdef AHC_DEBUG
+                       if (ahc_debug & AHC_SHOW_DV) {
+                               ahc_print_devinfo(ahc, devinfo);
+@@ -2693,14 +2677,14 @@ ahc_linux_dv_transition(struct ahc_softc
+                       break;
+               }
+               break;
+-      case AHC_DV_STATE_INQ_VERIFY:
++      case AIC_DV_STATE_INQ_VERIFY:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               {
+                       if (memcmp(targ->inq_data, targ->dv_buffer,
+                                  AHC_LINUX_DV_INQ_LEN) == 0) {
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+                               break;
+                       }
+ #ifdef AHC_DEBUG
+@@ -2721,7 +2705,7 @@ ahc_linux_dv_transition(struct ahc_softc
+ #endif
+                       if (ahc_linux_fallback(ahc, devinfo) != 0) {
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+                               break;
+                       }
+                       /*
+@@ -2734,18 +2718,18 @@ ahc_linux_dv_transition(struct ahc_softc
+               }
+               case SS_INQ_REFRESH:
+                       AHC_SET_DV_STATE(ahc, targ,
+-                                       AHC_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_TUR:
+               case SS_RETRY:
+                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
+-                      if (ahc_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ) {
+                               targ->dv_state_retry--;
+                       } else if ((status & SSQ_FALLBACK) != 0) {
+                               if (ahc_linux_fallback(ahc, devinfo) != 0) {
+                                       AHC_SET_DV_STATE(ahc, targ,
+-                                                       AHC_DV_STATE_EXIT);
++                                                       AIC_DV_STATE_EXIT);
+                                       break;
+                               }
+                               /*
+@@ -2754,12 +2738,12 @@ ahc_linux_dv_transition(struct ahc_softc
+                                */
+                               targ->dv_state_retry = 0;
+                       } else if ((status & SS_ERRMASK) == EBUSY)
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_BUSY);
+                       if (targ->dv_state_retry < 10)
+                               break;
+                       /* FALLTHROUGH */
+               default:
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+ #ifdef AHC_DEBUG
+                       if (ahc_debug & AHC_SHOW_DV) {
+                               ahc_print_devinfo(ahc, devinfo);
+@@ -2770,33 +2754,33 @@ ahc_linux_dv_transition(struct ahc_softc
+               }
+               break;
+-      case AHC_DV_STATE_TUR:
++      case AIC_DV_STATE_TUR:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+-                      if ((targ->flags & AHC_BASIC_DV) != 0) {
++                      if ((targ->flags & AIC_BASIC_DV) != 0) {
+                               ahc_linux_filter_inquiry(ahc, devinfo);
+                               AHC_SET_DV_STATE(ahc, targ,
+-                                               AHC_DV_STATE_INQ_VERIFY);
+-                      } else if ((targ->flags & AHC_ENHANCED_DV) != 0) {
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REBD);
++                                               AIC_DV_STATE_INQ_VERIFY);
++                      } else if ((targ->flags & AIC_ENHANCED_DV) != 0) {
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_REBD);
+                       } else {
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+                       }
+                       break;
+               case SS_RETRY:
+               case SS_TUR:
+                       if ((status & SS_ERRMASK) == EBUSY) {
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_BUSY);
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_BUSY);
+                               break;
+                       }
+                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
+-                      if (ahc_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ) {
+                               targ->dv_state_retry--;
+                       } else if ((status & SSQ_FALLBACK) != 0) {
+                               if (ahc_linux_fallback(ahc, devinfo) != 0) {
+                                       AHC_SET_DV_STATE(ahc, targ,
+-                                                       AHC_DV_STATE_EXIT);
++                                                       AIC_DV_STATE_EXIT);
+                                       break;
+                               }
+                               /*
+@@ -2812,7 +2796,7 @@ ahc_linux_dv_transition(struct ahc_softc
+                                       printf("DV TUR reties exhausted\n");
+                               }
+ #endif
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+                               break;
+                       }
+                       if (status & SSQ_DELAY)
+@@ -2820,25 +2804,25 @@ ahc_linux_dv_transition(struct ahc_softc
+                       break;
+               case SS_START:
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_SU);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_SU);
+                       break;
+               case SS_INQ_REFRESH:
+                       AHC_SET_DV_STATE(ahc, targ,
+-                                       AHC_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               default:
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+                       break;
+               }
+               break;
+-      case AHC_DV_STATE_REBD:
++      case AIC_DV_STATE_REBD:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               {
+                       uint32_t echo_size;
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_WEB);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_WEB);
+                       echo_size = scsi_3btoul(&targ->dv_buffer[1]);
+                       echo_size &= 0x1FFF;
+ #ifdef AHC_DEBUG
+@@ -2848,7 +2832,17 @@ ahc_linux_dv_transition(struct ahc_softc
+                       }
+ #endif
+                       if (echo_size == 0) {
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                              /*
++                               * Fall back to basic DV.
++                               */
++                              if (bootverbose) {
++                                      ahc_print_devinfo(ahc, devinfo);
++                                      printf("Echo Buffer unavailable.  "
++                                             "Performing basic DV.\n");
++                              }
++                              targ->flags &= ~AIC_ENHANCED_DV;
++                              targ->flags |= AIC_BASIC_DV;
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_TUR);
+                               break;
+                       }
+@@ -2863,11 +2857,11 @@ ahc_linux_dv_transition(struct ahc_softc
+               }
+               case SS_INQ_REFRESH:
+                       AHC_SET_DV_STATE(ahc, targ,
+-                                       AHC_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_RETRY:
+                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
+-                      if (ahc_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ)
+                               targ->dv_state_retry--;
+                       if (targ->dv_state_retry <= 10)
+@@ -2886,30 +2880,30 @@ ahc_linux_dv_transition(struct ahc_softc
+                        * and try level 1 DV.
+                        */
+                       ahc_linux_filter_inquiry(ahc, devinfo);
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_VERIFY);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_INQ_VERIFY);
+                       targ->dv_echo_size = 0;
+                       break;
+               }
+               break;
+-      case AHC_DV_STATE_WEB:
++      case AIC_DV_STATE_WEB:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_REB);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_REB);
+                       break;
+               case SS_INQ_REFRESH:
+                       AHC_SET_DV_STATE(ahc, targ,
+-                                       AHC_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_RETRY:
+                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
+-                      if (ahc_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ) {
+                               targ->dv_state_retry--;
+                       } else if ((status & SSQ_FALLBACK) != 0) {
+                               if (ahc_linux_fallback(ahc, devinfo) != 0) {
+                                       AHC_SET_DV_STATE(ahc, targ,
+-                                                       AHC_DV_STATE_EXIT);
++                                                       AIC_DV_STATE_EXIT);
+                                       break;
+                               }
+                               /*
+@@ -2928,22 +2922,22 @@ ahc_linux_dv_transition(struct ahc_softc
+                       }
+ #endif
+               default:
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+                       break;
+               }
+               break;
+-      case AHC_DV_STATE_REB:
++      case AIC_DV_STATE_REB:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+                       if (memcmp(targ->dv_buffer, targ->dv_buffer1,
+                                  targ->dv_echo_size) != 0) {
+                               if (ahc_linux_fallback(ahc, devinfo) != 0)
+                                       AHC_SET_DV_STATE(ahc, targ,
+-                                                       AHC_DV_STATE_EXIT);
++                                                       AIC_DV_STATE_EXIT);
+                               else
+                                       AHC_SET_DV_STATE(ahc, targ,
+-                                                       AHC_DV_STATE_WEB);
++                                                       AIC_DV_STATE_WEB);
+                               break;
+                       }
+                       
+@@ -2955,24 +2949,24 @@ ahc_linux_dv_transition(struct ahc_softc
+                               free(targ->dv_buffer1, M_DEVBUF);
+                               targ->dv_buffer1 = NULL;
+                       }
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+                       break;
+               case SS_INQ_REFRESH:
+                       AHC_SET_DV_STATE(ahc, targ,
+-                                       AHC_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_RETRY:
+                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
+-                      if (ahc_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ) {
+                               targ->dv_state_retry--;
+                       } else if ((status & SSQ_FALLBACK) != 0) {
+                               if (ahc_linux_fallback(ahc, devinfo) != 0) {
+                                       AHC_SET_DV_STATE(ahc, targ,
+-                                                       AHC_DV_STATE_EXIT);
++                                                       AIC_DV_STATE_EXIT);
+                                       break;
+                               }
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_WEB);
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_WEB);
+                       }
+                       if (targ->dv_state_retry <= 10) {
+                               if ((status & (SSQ_DELAY_RANDOM|SSQ_DELAY))!= 0)
+@@ -2987,35 +2981,35 @@ ahc_linux_dv_transition(struct ahc_softc
+ #endif
+                       /* FALLTHROUGH */
+               default:
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+                       break;
+               }
+               break;
+-      case AHC_DV_STATE_SU:
++      case AIC_DV_STATE_SU:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               case SS_INQ_REFRESH:
+                       AHC_SET_DV_STATE(ahc, targ,
+-                                       AHC_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               default:
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+                       break;
+               }
+               break;
+-      case AHC_DV_STATE_BUSY:
++      case AIC_DV_STATE_BUSY:
+               switch (status & SS_MASK) {
+               case SS_NOP:
+               case SS_INQ_REFRESH:
+                       AHC_SET_DV_STATE(ahc, targ,
+-                                       AHC_DV_STATE_INQ_SHORT_ASYNC);
++                                       AIC_DV_STATE_INQ_SHORT_ASYNC);
+                       break;
+               case SS_TUR:
+               case SS_RETRY:
+                       AHC_SET_DV_STATE(ahc, targ, targ->dv_state);
+-                      if (ahc_cmd_get_transaction_status(cmd)
++                      if (aic_cmd_get_transaction_status(cmd)
+                        == CAM_REQUEUE_REQ) {
+                               targ->dv_state_retry--;
+                       } else if (targ->dv_state_retry < 60) {
+@@ -3028,11 +3022,11 @@ ahc_linux_dv_transition(struct ahc_softc
+                                       printf("DV BUSY reties exhausted\n");
+                               }
+ #endif
+-                              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+                       }
+                       break;
+               default:
+-                      AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++                      AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+                       break;
+               }
+               break;
+@@ -3040,7 +3034,7 @@ ahc_linux_dv_transition(struct ahc_softc
+       default:
+               printf("%s: Invalid DV completion state %d\n", ahc_name(ahc),
+                      targ->dv_state);
+-              AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_EXIT);
++              AHC_SET_DV_STATE(ahc, targ, AIC_DV_STATE_EXIT);
+               break;
+       }
+ }
+@@ -3060,7 +3054,7 @@ ahc_linux_dv_fill_cmd(struct ahc_softc *
+  */
+ static void
+ ahc_linux_dv_inq(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
+-               struct ahc_devinfo *devinfo, struct ahc_linux_target *targ,
++               struct ahc_devinfo *devinfo, struct aic_linux_target *targ,
+                u_int request_length)
+ {
+@@ -3073,7 +3067,7 @@ ahc_linux_dv_inq(struct ahc_softc *ahc, 
+       if (targ->inq_data == NULL)
+               targ->inq_data = malloc(AHC_LINUX_DV_INQ_LEN,
+                                       M_DEVBUF, M_WAITOK);
+-      if (targ->dv_state > AHC_DV_STATE_INQ_ASYNC) {
++      if (targ->dv_state > AIC_DV_STATE_INQ_ASYNC) {
+               if (targ->dv_buffer != NULL)
+                       free(targ->dv_buffer, M_DEVBUF);
+               targ->dv_buffer = malloc(AHC_LINUX_DV_INQ_LEN,
+@@ -3086,7 +3080,7 @@ ahc_linux_dv_inq(struct ahc_softc *ahc, 
+       cmd->cmnd[0] = INQUIRY;
+       cmd->cmnd[4] = request_length;
+       cmd->request_bufflen = request_length;
+-      if (targ->dv_state > AHC_DV_STATE_INQ_ASYNC)
++      if (targ->dv_state > AIC_DV_STATE_INQ_ASYNC)
+               cmd->request_buffer = targ->dv_buffer;
+       else
+               cmd->request_buffer = targ->inq_data;
+@@ -3115,7 +3109,7 @@ ahc_linux_dv_tur(struct ahc_softc *ahc, 
+ static void
+ ahc_linux_dv_rebd(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
+-               struct ahc_devinfo *devinfo, struct ahc_linux_target *targ)
++               struct ahc_devinfo *devinfo, struct aic_linux_target *targ)
+ {
+ #ifdef AHC_DEBUG
+@@ -3140,7 +3134,7 @@ ahc_linux_dv_rebd(struct ahc_softc *ahc,
+ static void
+ ahc_linux_dv_web(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
+-               struct ahc_devinfo *devinfo, struct ahc_linux_target *targ)
++               struct ahc_devinfo *devinfo, struct aic_linux_target *targ)
+ {
+ #ifdef AHC_DEBUG
+@@ -3162,7 +3156,7 @@ ahc_linux_dv_web(struct ahc_softc *ahc, 
+ static void
+ ahc_linux_dv_reb(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
+-               struct ahc_devinfo *devinfo, struct ahc_linux_target *targ)
++               struct ahc_devinfo *devinfo, struct aic_linux_target *targ)
+ {
+ #ifdef AHC_DEBUG
+@@ -3185,7 +3179,7 @@ ahc_linux_dv_reb(struct ahc_softc *ahc, 
+ static void
+ ahc_linux_dv_su(struct ahc_softc *ahc, struct scsi_cmnd *cmd,
+               struct ahc_devinfo *devinfo,
+-              struct ahc_linux_target *targ)
++              struct aic_linux_target *targ)
+ {
+       u_int le;
+@@ -3207,7 +3201,7 @@ ahc_linux_dv_su(struct ahc_softc *ahc, s
+ static int
+ ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
+ {
+-      struct  ahc_linux_target *targ;
++      struct  aic_linux_target *targ;
+       struct  ahc_initiator_tinfo *tinfo;
+       struct  ahc_transinfo *goal;
+       struct  ahc_tmode_tstate *tstate;
+@@ -3386,7 +3380,7 @@ ahc_linux_fallback(struct ahc_softc *ahc
+       return (0);
+ }
+-static void
++void
+ ahc_linux_dv_timeout(struct scsi_cmnd *cmd)
+ {
+       struct  ahc_softc *ahc;
+@@ -3420,29 +3414,19 @@ ahc_linux_dv_timeout(struct scsi_cmnd *c
+        * error code.
+        */
+       if ((scb->flags & SCB_SENSE) != 0)
+-              ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
++              aic_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
+       else
+-              ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
++              aic_set_transaction_status(scb, CAM_CMD_TIMEOUT);
+       ahc_reset_channel(ahc, cmd->device->channel + 'A', /*initiate*/TRUE);
+-      /*
+-       * Add a minimal bus settle delay for devices that are slow to
+-       * respond after bus resets.
+-       */
+-      ahc_linux_freeze_simq(ahc);
+-      init_timer(&ahc->platform_data->reset_timer);
+-      ahc->platform_data->reset_timer.data = (u_long)ahc;
+-      ahc->platform_data->reset_timer.expires = jiffies + HZ / 2;
+-      ahc->platform_data->reset_timer.function =
+-          (ahc_linux_callback_t *)ahc_linux_release_simq;
+-      add_timer(&ahc->platform_data->reset_timer);
+-      if (ahc_linux_next_device_to_run(ahc) != NULL)
+-              ahc_schedule_runq(ahc);
++      if (aic_linux_next_device_to_run(ahc) != NULL)
++              aic_schedule_runq(ahc);
++
+       ahc_linux_run_complete_queue(ahc);
+       ahc_unlock(ahc, &flags);
+ }
+-static void
++void
+ ahc_linux_dv_complete(struct scsi_cmnd *cmd)
+ {
+       struct ahc_softc *ahc;
+@@ -3464,7 +3448,7 @@ ahc_linux_dv_complete(struct scsi_cmnd *
+ }
+ static void
+-ahc_linux_generate_dv_pattern(struct ahc_linux_target *targ)
++ahc_linux_generate_dv_pattern(struct aic_linux_target *targ)
+ {
+       uint16_t b;
+       u_int    i;
+@@ -3596,8 +3580,8 @@ ahc_linux_user_dv_setting(struct ahc_sof
+  * Determines the queue depth for a given device.
+  */
+ static void
+-ahc_linux_device_queue_depth(struct ahc_softc *ahc,
+-                           struct ahc_linux_device *dev)
++aic_linux_device_queue_depth(struct ahc_softc *ahc,
++                           struct aic_linux_device *dev)
+ {
+       struct  ahc_devinfo devinfo;
+       u_int   tags;
+@@ -3621,10 +3605,10 @@ ahc_linux_device_queue_depth(struct ahc_
+       }
+ }
+-static void
+-ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev)
++void
++ahc_linux_run_device_queue(struct ahc_softc *ahc, struct aic_linux_device *dev)
+ {
+-      struct   ahc_cmd *acmd;
++      struct   aic_cmd *acmd;
+       struct   scsi_cmnd *cmd;
+       struct   scb *scb;
+       struct   hardware_scb *hscb;
+@@ -3632,7 +3616,7 @@ ahc_linux_run_device_queue(struct ahc_so
+       struct   ahc_tmode_tstate *tstate;
+       uint16_t mask;
+-      if ((dev->flags & AHC_DEV_ON_RUN_LIST) != 0)
++      if ((dev->flags & AIC_DEV_ON_RUN_LIST) != 0)
+               panic("running device on run list");
+       while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL
+@@ -3643,10 +3627,10 @@ ahc_linux_run_device_queue(struct ahc_so
+                * running is because the whole controller Q is frozen.
+                */
+               if (ahc->platform_data->qfrozen != 0
+-               && AHC_DV_SIMQ_FROZEN(ahc) == 0) {
++               && AIC_DV_SIMQ_FROZEN(ahc) == 0) {
+                       TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
+                                         dev, links);
+-                      dev->flags |= AHC_DEV_ON_RUN_LIST;
++                      dev->flags |= AIC_DEV_ON_RUN_LIST;
+                       return;
+               }
+               /*
+@@ -3655,7 +3639,7 @@ ahc_linux_run_device_queue(struct ahc_so
+               if ((scb = ahc_get_scb(ahc)) == NULL) {
+                       TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq,
+                                        dev, links);
+-                      dev->flags |= AHC_DEV_ON_RUN_LIST;
++                      dev->flags |= AIC_DEV_ON_RUN_LIST;
+                       ahc->flags |= AHC_RESOURCE_SHORTAGE;
+                       return;
+               }
+@@ -3663,6 +3647,7 @@ ahc_linux_run_device_queue(struct ahc_so
+               cmd = &acmd_scsi_cmd(acmd);
+               scb->io_ctx = cmd;
+               scb->platform_data->dev = dev;
++              scb->platform_data->flags = 0;
+               hscb = scb->hscb;
+               cmd->host_scribble = (char *)scb;
+@@ -3684,7 +3669,7 @@ ahc_linux_run_device_queue(struct ahc_so
+               if ((ahc->user_discenable & mask) != 0)
+                       hscb->control |= DISCENB;
+-              if (AHC_DV_CMD(cmd) != 0)
++              if (AIC_DV_CMD(cmd) != 0)
+                       scb->flags |= SCB_SILENT;
+               if ((tstate->auto_negotiate & mask) != 0) {
+@@ -3692,7 +3677,7 @@ ahc_linux_run_device_queue(struct ahc_so
+                       scb->hscb->control |= MK_MESSAGE;
+               }
+-              if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
++              if ((dev->flags & (AIC_DEV_Q_TAGGED|AIC_DEV_Q_BASIC)) != 0) {
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+                       int     msg_bytes;
+                       uint8_t tag_msgs[2];
+@@ -3704,8 +3689,8 @@ ahc_linux_run_device_queue(struct ahc_so
+                                       dev->commands_since_idle_or_otag = 0;
+                       } else
+ #endif
+-                      if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
+-                       && (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
++                      if (dev->commands_since_idle_or_otag == AIC_OTAG_THRESH
++                       && (dev->flags & AIC_DEV_Q_TAGGED) != 0) {
+                               hscb->control |= MSG_ORDERED_TASK;
+                               dev->commands_since_idle_or_otag = 0;
+                       } else {
+@@ -3722,8 +3707,8 @@ ahc_linux_run_device_queue(struct ahc_so
+               }
+               scb->platform_data->xfer_len = 0;
+-              ahc_set_residual(scb, 0);
+-              ahc_set_sense_residual(scb, 0);
++              aic_set_residual(scb, 0);
++              aic_set_sense_residual(scb, 0);
+               scb->sg_count = 0;
+               if (cmd->use_sg != 0) {
+                       struct  ahc_dma_seg *sg;
+@@ -3732,7 +3717,7 @@ ahc_linux_run_device_queue(struct ahc_so
+                       int     nseg;
+                       cur_seg = (struct scatterlist *)cmd->request_buffer;
+-                      nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
++                      nseg = aic_map_sg(ahc, cur_seg, cmd->use_sg,
+                           scsi_to_pci_dma_dir(cmd->sc_data_direction));
+                       end_seg = cur_seg + nseg;
+                       /* Copy the segments into the SG list. */
+@@ -3755,13 +3740,13 @@ ahc_linux_run_device_queue(struct ahc_so
+                               cur_seg++;
+                       }
+                       sg--;
+-                      sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
++                      sg->len |= aic_htole32(AHC_DMA_LAST_SEG);
+                       /*
+                        * Reset the sg list pointer.
+                        */
+                       scb->hscb->sgptr =
+-                          ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
++                          aic_htole32(scb->sg_list_phys | SG_FULL_RESID);
+                       /*
+                        * Copy the first SG into the "current"
+@@ -3774,7 +3759,7 @@ ahc_linux_run_device_queue(struct ahc_so
+                       bus_addr_t addr;
+                       sg = scb->sg_list;
+-                      addr = pci_map_single(ahc->dev_softc,
++                      addr = aic_map_single(ahc,
+                              cmd->request_buffer,
+                              cmd->request_bufflen,
+                              scsi_to_pci_dma_dir(cmd->sc_data_direction));
+@@ -3782,13 +3767,13 @@ ahc_linux_run_device_queue(struct ahc_so
+                       scb->sg_count = ahc_linux_map_seg(ahc, scb,
+                                                         sg, addr,
+                                                         cmd->request_bufflen);
+-                      sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
++                      sg->len |= aic_htole32(AHC_DMA_LAST_SEG);
+                       /*
+                        * Reset the sg list pointer.
+                        */
+                       scb->hscb->sgptr =
+-                          ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
++                          aic_htole32(scb->sg_list_phys | SG_FULL_RESID);
+                       /*
+                        * Copy the first SG into the "current"
+@@ -3797,7 +3782,7 @@ ahc_linux_run_device_queue(struct ahc_so
+                       scb->hscb->dataptr = sg->addr;
+                       scb->hscb->datacnt = sg->len;
+               } else {
+-                      scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
++                      scb->hscb->sgptr = aic_htole32(SG_LIST_NULL);
+                       scb->hscb->dataptr = 0;
+                       scb->hscb->datacnt = 0;
+                       scb->sg_count = 0;
+@@ -3808,7 +3793,7 @@ ahc_linux_run_device_queue(struct ahc_so
+               dev->openings--;
+               dev->active++;
+               dev->commands_issued++;
+-              if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0)
++              if ((dev->flags & AIC_DEV_PERIODIC_OTAG) != 0)
+                       dev->commands_since_idle_or_otag++;
+               /*
+@@ -3830,6 +3815,7 @@ ahc_linux_run_device_queue(struct ahc_so
+                               continue;
+               }
+               scb->flags |= SCB_ACTIVE;
++              aic_scb_timer_start(scb);
+               ahc_queue_scb(ahc, scb);
+       }
+ }
+@@ -3847,8 +3833,8 @@ ahc_linux_isr(int irq, void *dev_id, str
+       ahc = (struct ahc_softc *) dev_id;
+       ahc_lock(ahc, &flags); 
+       ours = ahc_intr(ahc);
+-      if (ahc_linux_next_device_to_run(ahc) != NULL)
+-              ahc_schedule_runq(ahc);
++      if (aic_linux_next_device_to_run(ahc) != NULL)
++              aic_schedule_runq(ahc);
+       ahc_linux_run_complete_queue(ahc);
+       ahc_unlock(ahc, &flags);
+       return IRQ_RETVAL(ours);
+@@ -3862,10 +3848,10 @@ ahc_platform_flushwork(struct ahc_softc 
+               ;
+ }
+-static struct ahc_linux_target*
++static struct aic_linux_target*
+ ahc_linux_alloc_target(struct ahc_softc *ahc, u_int channel, u_int target)
+ {
+-      struct ahc_linux_target *targ;
++      struct aic_linux_target *targ;
+       u_int target_offset;
+       target_offset = target;
+@@ -3878,14 +3864,14 @@ ahc_linux_alloc_target(struct ahc_softc 
+       memset(targ, 0, sizeof(*targ));
+       targ->channel = channel;
+       targ->target = target;
+-      targ->ahc = ahc;
+-      targ->flags = AHC_DV_REQUIRED;
++      targ->softc = ahc;
++      targ->flags = AIC_DV_REQUIRED;
+       ahc->platform_data->targets[target_offset] = targ;
+       return (targ);
+ }
+ static void
+-ahc_linux_free_target(struct ahc_softc *ahc, struct ahc_linux_target *targ)
++ahc_linux_free_target(struct ahc_softc *ahc, struct aic_linux_target *targ)
+ {
+       struct ahc_devinfo devinfo;
+       struct ahc_initiator_tinfo *tinfo;
+@@ -3925,11 +3911,11 @@ ahc_linux_free_target(struct ahc_softc *
+       free(targ, M_DEVBUF);
+ }
+-static struct ahc_linux_device*
++static struct aic_linux_device*
+ ahc_linux_alloc_device(struct ahc_softc *ahc,
+-               struct ahc_linux_target *targ, u_int lun)
++               struct aic_linux_target *targ, u_int lun)
+ {
+-      struct ahc_linux_device *dev;
++      struct aic_linux_device *dev;
+       dev = malloc(sizeof(*dev), M_DEVBUG, M_NOWAIT);
+       if (dev == NULL)
+@@ -3937,7 +3923,7 @@ ahc_linux_alloc_device(struct ahc_softc 
+       memset(dev, 0, sizeof(*dev));
+       init_timer(&dev->timer);
+       TAILQ_INIT(&dev->busyq);
+-      dev->flags = AHC_DEV_UNCONFIGURED;
++      dev->flags = AIC_DEV_UNCONFIGURED;
+       dev->lun = lun;
+       dev->target = targ;
+@@ -3960,17 +3946,17 @@ ahc_linux_alloc_device(struct ahc_softc 
+ }
+ static void
+-ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
++ahc_linux_free_device(struct ahc_softc *ahc, struct aic_linux_device *dev)
+ {
+-      struct ahc_linux_target *targ;
++      struct aic_linux_target *targ;
+-      del_timer_sync(&dev->timer);
++      del_timer(&dev->timer);
+       targ = dev->target;
+       targ->devices[dev->lun] = NULL;
+       free(dev, M_DEVBUF);
+       targ->refcount--;
+       if (targ->refcount == 0
+-       && (targ->flags & AHC_DV_REQUIRED) == 0)
++       && (targ->flags & AIC_DV_REQUIRED) == 0)
+               ahc_linux_free_target(ahc, targ);
+ }
+@@ -3982,7 +3968,7 @@ ahc_send_async(struct ahc_softc *ahc, ch
+       case AC_TRANSFER_NEG:
+       {
+               char    buf[80];
+-              struct  ahc_linux_target *targ;
++              struct  aic_linux_target *targ;
+               struct  info_str info;
+               struct  ahc_initiator_tinfo *tinfo;
+               struct  ahc_tmode_tstate *tstate;
+@@ -4076,6 +4062,20 @@ ahc_send_async(struct ahc_softc *ahc, ch
+                                             channel - 'A');
+               }
+ #endif
++              /*
++               * Add a minimal bus settle delay for devices that are slow to
++               * respond after bus resets.
++               */
++              if ((ahc->platform_data->flags & AIC_BUS_SETTLE_TIMER) == 0) {
++                      aic_freeze_simq(ahc);
++                      ahc->platform_data->flags |= AIC_BUS_SETTLE_TIMER;
++                      ahc->platform_data->bus_settle_timer.expires =
++                          jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000;
++                      add_timer(&ahc->platform_data->bus_settle_timer);
++              } else {
++                      mod_timer(&ahc->platform_data->bus_settle_timer,
++                                jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000);
++              }
+                 break;
+         default:
+                 panic("ahc_send_async: Unexpected async event");
+@@ -4089,9 +4089,11 @@ void
+ ahc_done(struct ahc_softc *ahc, struct scb *scb)
+ {
+       Scsi_Cmnd *cmd;
+-      struct     ahc_linux_device *dev;
++      struct     aic_linux_device *dev;
+       LIST_REMOVE(scb, pending_links);
++      if ((scb->flags & SCB_TIMEDOUT) != 0)
++              LIST_REMOVE(scb, timedout_links);
+       if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
+               struct scb_tailq *untagged_q;
+               int target_offset;
+@@ -4124,11 +4126,11 @@ ahc_done(struct ahc_softc *ahc, struct s
+        * the sense buffer looks "sane".
+        */
+       cmd->sense_buffer[0] = 0;
+-      if (ahc_get_transaction_status(scb) == CAM_REQ_INPROG) {
++      if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) {
+               uint32_t amount_xferred;
+               amount_xferred =
+-                  ahc_get_transfer_length(scb) - ahc_get_residual(scb);
++                  aic_get_transfer_length(scb) - aic_get_residual(scb);
+               if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) {
+ #ifdef AHC_DEBUG
+                       if ((ahc_debug & AHC_SHOW_MISC) != 0) {
+@@ -4136,7 +4138,17 @@ ahc_done(struct ahc_softc *ahc, struct s
+                               printf("Set CAM_UNCOR_PARITY\n");
+                       }
+ #endif
+-                      ahc_set_transaction_status(scb, CAM_UNCOR_PARITY);
++                      aic_set_transaction_status(scb, CAM_UNCOR_PARITY);
++#ifdef AHC_REPORT_UNDERFLOWS
++              /*
++               * This code is disabled by default as some
++               * clients of the SCSI system do not properly
++               * initialize the underflow parameter.  This
++               * results in spurious termination of commands
++               * that complete as expected (e.g. underflow is
++               * allowed as command can return variable amounts
++               * of data.
++               */
+               } else if (amount_xferred < scb->io_ctx->underflow) {
+                       u_int i;
+@@ -4148,30 +4160,31 @@ ahc_done(struct ahc_softc *ahc, struct s
+                       ahc_print_path(ahc, scb);
+                       printf("Saw underflow (%ld of %ld bytes). "
+                              "Treated as error\n",
+-                              ahc_get_residual(scb),
+-                              ahc_get_transfer_length(scb));
+-                      ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
++                              aic_get_residual(scb),
++                              aic_get_transfer_length(scb));
++                      aic_set_transaction_status(scb, CAM_DATA_RUN_ERR);
++#endif
+               } else {
+-                      ahc_set_transaction_status(scb, CAM_REQ_CMP);
++                      aic_set_transaction_status(scb, CAM_REQ_CMP);
+               }
+-      } else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
++      } else if (aic_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
+               ahc_linux_handle_scsi_status(ahc, dev, scb);
+-      } else if (ahc_get_transaction_status(scb) == CAM_SEL_TIMEOUT) {
+-              dev->flags |= AHC_DEV_UNCONFIGURED;
+-              if (AHC_DV_CMD(cmd) == FALSE)
+-                      dev->target->flags &= ~AHC_DV_REQUIRED;
++      } else if (aic_get_transaction_status(scb) == CAM_SEL_TIMEOUT) {
++              dev->flags |= AIC_DEV_UNCONFIGURED;
++              if (AIC_DV_CMD(cmd) == FALSE)
++                      dev->target->flags &= ~AIC_DV_REQUIRED;
+       }
+       /*
+        * Start DV for devices that require it assuming the first command
+        * sent does not result in a selection timeout.
+        */
+-      if (ahc_get_transaction_status(scb) != CAM_SEL_TIMEOUT
+-       && (dev->target->flags & AHC_DV_REQUIRED) != 0)
++      if (aic_get_transaction_status(scb) != CAM_SEL_TIMEOUT
++       && (dev->target->flags & AIC_DV_REQUIRED) != 0)
+               ahc_linux_start_dv(ahc);
+       if (dev->openings == 1
+-       && ahc_get_transaction_status(scb) == CAM_REQ_CMP
+-       && ahc_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
++       && aic_get_transaction_status(scb) == CAM_REQ_CMP
++       && aic_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
+               dev->tag_success_count++;
+       /*
+        * Some devices deal with temporary internal resource
+@@ -4180,7 +4193,7 @@ ahc_done(struct ahc_softc *ahc, struct s
+        * back to our previous queue depth.
+        */
+       if ((dev->openings + dev->active) < dev->maxtags
+-       && dev->tag_success_count > AHC_TAG_SUCCESS_INTERVAL) {
++       && dev->tag_success_count > AIC_TAG_SUCCESS_INTERVAL) {
+               dev->tag_success_count = 0;
+               dev->openings++;
+       }
+@@ -4189,32 +4202,61 @@ ahc_done(struct ahc_softc *ahc, struct s
+               dev->commands_since_idle_or_otag = 0;
+       if (TAILQ_EMPTY(&dev->busyq)) {
+-              if ((dev->flags & AHC_DEV_UNCONFIGURED) != 0
+-               && dev->active == 0
+-               && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0)
++              if ((dev->flags & AIC_DEV_UNCONFIGURED) != 0
++               && dev->active == 0)
+                       ahc_linux_free_device(ahc, dev);
+-      } else if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) {
++      } else if ((dev->flags & AIC_DEV_ON_RUN_LIST) == 0) {
+               TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links);
+-              dev->flags |= AHC_DEV_ON_RUN_LIST;
++              dev->flags |= AIC_DEV_ON_RUN_LIST;
+       }
+       if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
+               printf("Recovery SCB completes\n");
+-              if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
+-               || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
+-                      ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
+-              if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) {
+-                      ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE;
++              if (aic_get_transaction_status(scb) == CAM_BDR_SENT
++               || aic_get_transaction_status(scb) == CAM_REQ_ABORTED)
++                      aic_set_transaction_status(scb, CAM_CMD_TIMEOUT);
++              if ((scb->platform_data->flags & AIC_SCB_UP_EH_SEM) != 0) {
++                      scb->platform_data->flags &= ~AIC_SCB_UP_EH_SEM;
+                       up(&ahc->platform_data->eh_sem);
++              } else {
++                      struct  scb *list_scb;
++
++                      /*
++                       * We were able to complete the command successfully,
++                       * so reinstate the timeouts for all other pending
++                       * commands.
++                       */
++                      LIST_FOREACH(list_scb,
++                                   &ahc->pending_scbs, pending_links) {
++
++                              aic_scb_timer_start(list_scb);
++                      }
+               }
+       }
++      if ((scb->platform_data->flags & AIC_TIMEOUT_ACTIVE) == 0) {
++              /*
++               * The completion handler believes that
++               * commands without active timers running
++               * have lost the race of completing before
++               * their timer expires.  Since commands in
++               * our busy queues do not have timers running,
++               * appease the mid-layer by adding a timer
++               * now.  This timer will be immediately
++               * canceled by the midlayer.
++               */
++              scsi_add_timer(cmd, 60*HZ, aic_linux_midlayer_timeout);
++      }
++
++      if ((scb->platform_data->flags & AIC_RELEASE_SIMQ) != 0)
++              aic_release_simq_locked(ahc);
++
+       ahc_free_scb(ahc, scb);
+       ahc_linux_queue_cmd_complete(ahc, cmd);
+-      if ((ahc->platform_data->flags & AHC_DV_WAIT_SIMQ_EMPTY) != 0
++      if ((ahc->platform_data->flags & AIC_DV_WAIT_SIMQ_EMPTY) != 0
+        && LIST_FIRST(&ahc->pending_scbs) == NULL) {
+-              ahc->platform_data->flags &= ~AHC_DV_WAIT_SIMQ_EMPTY;
++              ahc->platform_data->flags &= ~AIC_DV_WAIT_SIMQ_EMPTY;
+               up(&ahc->platform_data->dv_sem);
+       }
+               
+@@ -4222,7 +4264,7 @@ ahc_done(struct ahc_softc *ahc, struct s
+ static void
+ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
+-                           struct ahc_linux_device *dev, struct scb *scb)
++                           struct aic_linux_device *dev, struct scb *scb)
+ {
+       struct  ahc_devinfo devinfo;
+@@ -4242,7 +4284,7 @@ ahc_linux_handle_scsi_status(struct ahc_
+        * we don't clobber the device with too many
+        * commands.
+        */
+-      switch (ahc_get_scsi_status(scb)) {
++      switch (aic_get_scsi_status(scb)) {
+       default:
+               break;
+       case SCSI_STATUS_CHECK_COND:
+@@ -4256,13 +4298,15 @@ ahc_linux_handle_scsi_status(struct ahc_
+                */
+               cmd = scb->io_ctx;
+               if (scb->flags & SCB_SENSE) {
+-                      u_int sense_size;
++                      struct  scsi_sense_data *sense;
++                      u_int   sense_size;
++                      int     error_code, sense_key, asc, ascq;
++                      sense = ahc_get_sense_buf(ahc, scb);
+                       sense_size = MIN(sizeof(struct scsi_sense_data)
+-                                     - ahc_get_sense_residual(scb),
++                                     - aic_get_sense_residual(scb),
+                                        sizeof(cmd->sense_buffer));
+-                      memcpy(cmd->sense_buffer,
+-                             ahc_get_sense_buf(ahc, scb), sense_size);
++                      memcpy(cmd->sense_buffer, sense, sense_size);
+                       if (sense_size < sizeof(cmd->sense_buffer))
+                               memset(&cmd->sense_buffer[sense_size], 0,
+                                      sizeof(cmd->sense_buffer) - sense_size);
+@@ -4281,6 +4325,23 @@ ahc_linux_handle_scsi_status(struct ahc_
+                               printf("\n");
+                       }
+ #endif
++                      /*
++                       * If this is not a DV command and the target
++                       * provides some status that makes us believe
++                       * that the target has changed (power on reset,
++                       * etc.) kick off a DV scan to re-validate the
++                       * device.
++                       */
++                      if (AIC_DV_CMD(cmd) != 0)
++                              break;
++
++                      scsi_extract_sense(sense, &error_code,
++                                         &sense_key, &asc, &ascq);
++                      if (error_code == SSD_CURRENT_ERROR
++                       && sense_key == SSD_KEY_UNIT_ATTENTION
++                       && asc == 0x29
++                       && (ascq == 0 || ascq == 1))
++                              dev->target->flags |= AIC_DV_REQUIRED;
+               }
+               break;
+       }
+@@ -4317,7 +4378,7 @@ ahc_linux_handle_scsi_status(struct ahc_
+                                * this device.
+                                */
+                               if (dev->last_queuefull_same_count
+-                               == AHC_LOCK_TAGS_COUNT) {
++                               == AIC_LOCK_TAGS_COUNT) {
+                                       dev->maxtags = dev->active;
+                                       ahc_print_path(ahc, scb);
+                                       printf("Locking max tag count at %d\n",
+@@ -4327,10 +4388,10 @@ ahc_linux_handle_scsi_status(struct ahc_
+                               dev->tags_on_last_queuefull = dev->active;
+                               dev->last_queuefull_same_count = 0;
+                       }
+-                      ahc_set_transaction_status(scb, CAM_REQUEUE_REQ);
+-                      ahc_set_scsi_status(scb, SCSI_STATUS_OK);
++                      aic_set_transaction_status(scb, CAM_REQUEUE_REQ);
++                      aic_set_scsi_status(scb, SCSI_STATUS_OK);
+                       ahc_platform_set_tags(ahc, &devinfo,
+-                                   (dev->flags & AHC_DEV_Q_BASIC)
++                                   (dev->flags & AIC_DEV_Q_BASIC)
+                                  ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
+                       break;
+               }
+@@ -4339,9 +4400,9 @@ ahc_linux_handle_scsi_status(struct ahc_
+                * as if the target returned BUSY SCSI status.
+                */
+               dev->openings = 1;
+-              ahc_set_scsi_status(scb, SCSI_STATUS_BUSY);
++              aic_set_scsi_status(scb, SCSI_STATUS_BUSY);
+               ahc_platform_set_tags(ahc, &devinfo,
+-                           (dev->flags & AHC_DEV_Q_BASIC)
++                           (dev->flags & AIC_DEV_Q_BASIC)
+                          ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
+               /* FALLTHROUGH */
+       }
+@@ -4351,13 +4412,13 @@ ahc_linux_handle_scsi_status(struct ahc_
+                * Set a short timer to defer sending commands for
+                * a bit since Linux will not delay in this case.
+                */
+-              if ((dev->flags & AHC_DEV_TIMER_ACTIVE) != 0) {
++              if ((dev->flags & AIC_DEV_TIMER_ACTIVE) != 0) {
+                       printf("%s:%c:%d: Device Timer still active during "
+                              "busy processing\n", ahc_name(ahc),
+                               dev->target->channel, dev->target->target);
+                       break;
+               }
+-              dev->flags |= AHC_DEV_TIMER_ACTIVE;
++              dev->flags |= AIC_DEV_TIMER_ACTIVE;
+               dev->qfrozen++;
+               init_timer(&dev->timer);
+               dev->timer.data = (u_long)dev;
+@@ -4384,9 +4445,9 @@ ahc_linux_queue_cmd_complete(struct ahc_
+        * not guarantee the order that aborted commands will be
+        * returned to us.
+        */
+-      struct ahc_completeq *completeq;
+-      struct ahc_cmd *list_cmd;
+-      struct ahc_cmd *acmd;
++      struct aic_completeq *completeq;
++      struct aic_cmd *list_cmd;
++      struct aic_cmd *acmd;
+       /*
+        * Map CAM error codes into Linux Error codes.  We
+@@ -4394,10 +4455,10 @@ ahc_linux_queue_cmd_complete(struct ahc_
+        * full error information available when making
+        * state change decisions.
+        */
+-      if (AHC_DV_CMD(cmd) == FALSE) {
++      if (AIC_DV_CMD(cmd) == FALSE) {
+               u_int new_status;
+-              switch (ahc_cmd_get_transaction_status(cmd)) {
++              switch (aic_cmd_get_transaction_status(cmd)) {
+               case CAM_REQ_INPROG:
+               case CAM_REQ_CMP:
+               case CAM_SCSI_STATUS_ERROR:
+@@ -4424,7 +4485,17 @@ ahc_linux_queue_cmd_complete(struct ahc_
+                       new_status = DID_PARITY;
+                       break;
+               case CAM_CMD_TIMEOUT:
+-                      new_status = DID_TIME_OUT;
++                      /*
++                       *  Returning DID_TIME_OUT will 
++                       *  wake up the error recovery
++                       *  thread instead of doing the
++                       *  command retry we desire. Since
++                       *  we have already recovered the
++                       *  command, returning DID_ERROR
++                       *  will cause a retry up to the
++                       *  retry limit for this command.
++                       */
++                      new_status = DID_ERROR;
+                       break;
+               case CAM_UA_ABORT:
+               case CAM_REQ_CMP_ERR:
+@@ -4454,7 +4525,7 @@ ahc_linux_queue_cmd_complete(struct ahc_
+                       if (cmd->retries > 0)
+                               cmd->retries--;
+                       new_status = DID_OK;
+-                      ahc_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);
++                      aic_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);
+                       cmd->result |= (DRIVER_SENSE << 24);
+                       memset(cmd->sense_buffer, 0,
+                              sizeof(cmd->sense_buffer));
+@@ -4468,12 +4539,12 @@ ahc_linux_queue_cmd_complete(struct ahc_
+                       break;
+               }
+-              ahc_cmd_set_transaction_status(cmd, new_status);
++              aic_cmd_set_transaction_status(cmd, new_status);
+       }
+       completeq = &ahc->platform_data->completeq;
+       list_cmd = TAILQ_FIRST(completeq);
+-      acmd = (struct ahc_cmd *)cmd;
++      acmd = (struct aic_cmd *)cmd;
+       while (list_cmd != NULL
+           && acmd_scsi_cmd(list_cmd).serial_number
+            < acmd_scsi_cmd(acmd).serial_number)
+@@ -4494,7 +4565,7 @@ ahc_linux_filter_inquiry(struct ahc_soft
+       struct  ahc_transinfo *curr;
+       struct  ahc_tmode_tstate *tstate;
+       struct  ahc_syncrate *syncrate;
+-      struct  ahc_linux_device *dev;
++      struct  aic_linux_device *dev;
+       u_int   maxsync;
+       u_int   width;
+       u_int   period;
+@@ -4517,9 +4588,9 @@ ahc_linux_filter_inquiry(struct ahc_soft
+       sid = (struct scsi_inquiry_data *)dev->target->inq_data;
+       if (SID_QUAL(sid) == SID_QUAL_LU_CONNECTED) {
+-              dev->flags &= ~AHC_DEV_UNCONFIGURED;
++              dev->flags &= ~AIC_DEV_UNCONFIGURED;
+       } else {
+-              dev->flags |= AHC_DEV_UNCONFIGURED;
++              dev->flags |= AIC_DEV_UNCONFIGURED;
+               return;
+       }
+@@ -4596,82 +4667,38 @@ ahc_linux_filter_inquiry(struct ahc_soft
+ static void
+ ahc_linux_sem_timeout(u_long arg)
+ {
++      struct  scb *scb;
+       struct  ahc_softc *ahc;
+       u_long  s;
+-      ahc = (struct ahc_softc *)arg;
+-
++      scb = (struct scb *)arg;
++      ahc = scb->ahc_softc;
+       ahc_lock(ahc, &s);
+-      if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) {
+-              ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE;
++      if ((scb->platform_data->flags & AIC_SCB_UP_EH_SEM) != 0) {
++              scb->platform_data->flags &= ~AIC_SCB_UP_EH_SEM;
+               up(&ahc->platform_data->eh_sem);
+       }
+       ahc_unlock(ahc, &s);
+ }
+ static void
+-ahc_linux_freeze_simq(struct ahc_softc *ahc)
+-{
+-      ahc->platform_data->qfrozen++;
+-      if (ahc->platform_data->qfrozen == 1) {
+-              scsi_block_requests(ahc->platform_data->host);
+-
+-              /* XXX What about Twin channels? */
+-              ahc_platform_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
+-                                      CAM_LUN_WILDCARD, SCB_LIST_NULL,
+-                                      ROLE_INITIATOR, CAM_REQUEUE_REQ);
+-      }
+-}
+-
+-static void
+-ahc_linux_release_simq(u_long arg)
+-{
+-      struct ahc_softc *ahc;
+-      u_long s;
+-      int    unblock_reqs;
+-
+-      ahc = (struct ahc_softc *)arg;
+-
+-      unblock_reqs = 0;
+-      ahc_lock(ahc, &s);
+-      if (ahc->platform_data->qfrozen > 0)
+-              ahc->platform_data->qfrozen--;
+-      if (ahc->platform_data->qfrozen == 0)
+-              unblock_reqs = 1;
+-      if (AHC_DV_SIMQ_FROZEN(ahc)
+-       && ((ahc->platform_data->flags & AHC_DV_WAIT_SIMQ_RELEASE) != 0)) {
+-              ahc->platform_data->flags &= ~AHC_DV_WAIT_SIMQ_RELEASE;
+-              up(&ahc->platform_data->dv_sem);
+-      }
+-      ahc_schedule_runq(ahc);
+-      ahc_unlock(ahc, &s);
+-      /*
+-       * There is still a race here.  The mid-layer
+-       * should keep its own freeze count and use
+-       * a bottom half handler to run the queues
+-       * so we can unblock with our own lock held.
+-       */
+-      if (unblock_reqs)
+-              scsi_unblock_requests(ahc->platform_data->host);
+-}
+-
+-static void
+ ahc_linux_dev_timed_unfreeze(u_long arg)
+ {
+-      struct ahc_linux_device *dev;
++      struct aic_linux_device *dev;
+       struct ahc_softc *ahc;
+       u_long s;
+-      dev = (struct ahc_linux_device *)arg;
+-      ahc = dev->target->ahc;
++      dev = (struct aic_linux_device *)arg;
++      ahc = dev->target->softc;
+       ahc_lock(ahc, &s);
+-      dev->flags &= ~AHC_DEV_TIMER_ACTIVE;
++      dev->flags &= ~AIC_DEV_TIMER_ACTIVE;
+       if (dev->qfrozen > 0)
+               dev->qfrozen--;
+       if (dev->qfrozen == 0
+-       && (dev->flags & AHC_DEV_ON_RUN_LIST) == 0)
++       && (dev->flags & AIC_DEV_ON_RUN_LIST) == 0)
+               ahc_linux_run_device_queue(ahc, dev);
+-      if (TAILQ_EMPTY(&dev->busyq)
++      if ((dev->flags & AIC_DEV_UNCONFIGURED) != 0
++       && TAILQ_EMPTY(&dev->busyq)
+        && dev->active == 0)
+               ahc_linux_free_device(ahc, dev);
+       ahc_unlock(ahc, &s);
+@@ -4681,9 +4708,9 @@ static int
+ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag)
+ {
+       struct ahc_softc *ahc;
+-      struct ahc_cmd *acmd;
+-      struct ahc_cmd *list_acmd;
+-      struct ahc_linux_device *dev;
++      struct aic_cmd *acmd;
++      struct aic_cmd *list_acmd;
++      struct aic_linux_device *dev;
+       struct scb *pending_scb;
+       u_long s;
+       u_int  saved_scbptr;
+@@ -4701,7 +4728,7 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *
+       paused = FALSE;
+       wait = FALSE;
+       ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
+-      acmd = (struct ahc_cmd *)cmd;
++      acmd = (struct aic_cmd *)cmd;
+       printf("%s:%d:%d:%d: Attempting to queue a%s message\n",
+              ahc_name(ahc), cmd->device->channel,
+@@ -4763,13 +4790,24 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *
+               if (flag == SCB_ABORT) {
+                       TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe);
+                       cmd->result = DID_ABORT << 16;
++                      /*
++                       * The completion handler believes that
++                       * commands without active timers running
++                       * have lost the race of completing before
++                       * their timer expires.  Since commands in our
++                       * busy queues do not have timers running,
++                       * appease the mid-layer by adding a timer
++                       * now.  This timer will be immediately
++                       * canceled by the midlayer.
++                       */
++                      scsi_add_timer(cmd, 60*HZ, aic_linux_midlayer_timeout);
+                       ahc_linux_queue_cmd_complete(ahc, cmd);
+                       retval = SUCCESS;
+                       goto done;
+               }
+       }
+-      if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
++      if ((dev->flags & (AIC_DEV_Q_BASIC|AIC_DEV_Q_TAGGED)) == 0
+        && ahc_search_untagged_queues(ahc, cmd, cmd->device->id,
+                                      cmd->device->channel + 'A',
+                                      cmd->device->lun,
+@@ -4985,10 +5023,10 @@ done:
+               struct timer_list timer;
+               int ret;
+-              ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE;
++              pending_scb->platform_data->flags |= AIC_SCB_UP_EH_SEM;
+               spin_unlock_irq(&ahc->platform_data->spin_lock);
+               init_timer(&timer);
+-              timer.data = (u_long)ahc;
++              timer.data = (u_long)pending_scb;
+               timer.expires = jiffies + (5 * HZ);
+               timer.function = ahc_linux_sem_timeout;
+               add_timer(&timer);
+@@ -5002,7 +5040,7 @@ done:
+               }
+               spin_lock_irq(&ahc->platform_data->spin_lock);
+       }
+-      ahc_schedule_runq(ahc);
++      aic_schedule_runq(ahc);
+       ahc_linux_run_complete_queue(ahc);
+       ahc_midlayer_entrypoint_unlock(ahc, &s);
+       return (retval);
+@@ -5011,7 +5049,8 @@ done:
+ void
+ ahc_platform_dump_card_state(struct ahc_softc *ahc)
+ {
+-      struct ahc_linux_device *dev;
++      struct Scsi_Host *host;
++      struct aic_linux_device *dev;
+       int channel;
+       int maxchannel;
+       int target;
+@@ -5019,6 +5058,14 @@ ahc_platform_dump_card_state(struct ahc_
+       int lun;
+       int i;
++      host = ahc->platform_data->host;
++      printf("%s: Host Status: Failed(%d) %s%s%s\n",
++             ahc_name(ahc),
++             host->host_failed,
++             host->eh_active ? "eh_active " : "",
++             host->host_blocked ? "host_blocked " : "",
++             host->host_self_blocked ? "host_self_blocked " : "");
++             
+       maxchannel = (ahc->features & AHC_TWIN) ? 1 : 0;
+       maxtarget = (ahc->features & AHC_WIDE) ? 15 : 7;
+       for (channel = 0; channel <= maxchannel; channel++) {
+@@ -5026,7 +5073,7 @@ ahc_platform_dump_card_state(struct ahc_
+               for (target = 0; target <=maxtarget; target++) {
+                       for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
+-                              struct ahc_cmd *acmd;
++                              struct aic_cmd *acmd;
+                               dev = ahc_linux_get_device(ahc, channel, target,
+                                                          lun, /*alloc*/FALSE);
+@@ -5068,41 +5115,33 @@ static void __exit
+ ahc_linux_exit(void)
+ {
+       struct ahc_softc *ahc;
+-      u_long l;
+       /*
+-       * Shutdown DV threads before going into the SCSI mid-layer.
++       * Shutdown our threads before going into the SCSI mid-layer.
+        * This avoids situations where the mid-layer locks the entire
+        * kernel so that waiting for our DV threads to exit leads
+        * to deadlock.
+        */
+-      ahc_list_lock(&l);
+       TAILQ_FOREACH(ahc, &ahc_tailq, links) {
+               ahc_linux_kill_dv_thread(ahc);
++              ahc_terminate_recovery_thread(ahc);
+       }
+-      ahc_list_unlock(&l);
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+-
+-      ahc_linux_pci_exit();
+-
+-      /*
+-       * Get rid of the non-pci devices.  
+-       *
+-       * XXX(hch): switch over eisa support to new LDM-based API
+-       */
+-      TAILQ_FOREACH(ahc, &ahc_tailq, links)
+-              ahc_linux_release(ahc->platform_data->host);
+-#else
+-      scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+       /*
+        * In 2.4 we have to unregister from the PCI core _after_
+        * unregistering from the scsi midlayer to avoid dangling
+        * references.
+        */
++      scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
++#endif
++#ifdef CONFIG_PCI
+       ahc_linux_pci_exit();
+ #endif
++#ifdef CONFIG_EISA
++      ahc_linux_eisa_exit();
++#endif
+ }
+ module_init(ahc_linux_init);
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx_osm.h     2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx_osm.h      2003-12-28 23:21:40.000000000 -0800
+@@ -53,50 +53,22 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#147 $
++ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#166 $
+  *
+  */
+ #ifndef _AIC7XXX_LINUX_H_
+ #define _AIC7XXX_LINUX_H_
+-#include <linux/types.h>
+-#include <linux/blkdev.h>
+-#include <linux/delay.h>
+-#include <linux/ioport.h>
+-#include <linux/pci.h>
+-#include <linux/smp_lock.h>
+ #include <linux/version.h>
+-#include <linux/module.h>
+-#include <asm/byteorder.h>
+-#include <asm/io.h>
+ #ifndef KERNEL_VERSION
+ #define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
+ #endif
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-#include <linux/interrupt.h> /* For tasklet support. */
+ #include <linux/config.h>
+-#include <linux/slab.h>
+-#else
+-#include <linux/malloc.h>
+ #endif
+-/* Core SCSI definitions */
+-#define AIC_LIB_PREFIX ahc
+-#include "scsi.h"
+-#include "hosts.h"
+-
+-/* Name space conflict with BSD queue macros */
+-#ifdef LIST_HEAD
+-#undef LIST_HEAD
+-#endif
+-
+-#include "cam.h"
+-#include "queue.h"
+-#include "scsi_message.h"
+-#include "aiclib.h"
+-
+ /*********************************** Debugging ********************************/
+ #ifdef CONFIG_AIC7XXX_DEBUG_ENABLE
+ #ifdef CONFIG_AIC7XXX_DEBUG_MASK
+@@ -111,42 +83,18 @@
+ /* No debugging code. */
+ #endif
+-/************************* Forward Declarations *******************************/
+-struct ahc_softc;
+-typedef struct pci_dev *ahc_dev_softc_t;
+-typedef Scsi_Cmnd      *ahc_io_ctx_t;
+-
+-/******************************* Byte Order ***********************************/
+-#define ahc_htobe16(x)        cpu_to_be16(x)
+-#define ahc_htobe32(x)        cpu_to_be32(x)
+-#define ahc_htobe64(x)        cpu_to_be64(x)
+-#define ahc_htole16(x)        cpu_to_le16(x)
+-#define ahc_htole32(x)        cpu_to_le32(x)
+-#define ahc_htole64(x)        cpu_to_le64(x)
+-
+-#define ahc_be16toh(x)        be16_to_cpu(x)
+-#define ahc_be32toh(x)        be32_to_cpu(x)
+-#define ahc_be64toh(x)        be64_to_cpu(x)
+-#define ahc_le16toh(x)        le16_to_cpu(x)
+-#define ahc_le32toh(x)        le32_to_cpu(x)
+-#define ahc_le64toh(x)        le64_to_cpu(x)
+-
+-#ifndef LITTLE_ENDIAN
+-#define LITTLE_ENDIAN 1234
+-#endif
+-
+-#ifndef BIG_ENDIAN
+-#define BIG_ENDIAN 4321
+-#endif
++/********************************** Includes **********************************/
++/* Core SCSI definitions */
++#define AIC_LIB_PREFIX ahc
++#define AIC_CONST_PREFIX AHC
+-#ifndef BYTE_ORDER
+-#if defined(__BIG_ENDIAN)
+-#define BYTE_ORDER BIG_ENDIAN
+-#endif
+-#if defined(__LITTLE_ENDIAN)
+-#define BYTE_ORDER LITTLE_ENDIAN
++#ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT
++#define AIC_DEBUG_REGISTERS 1
++#else
++#define AIC_DEBUG_REGISTERS 0
+ #endif
+-#endif /* BYTE_ORDER */
++#define       AIC_CORE_INCLUDE "aic7xxx.h"
++#include "aiclib.h"
+ /************************* Configuration Data *********************************/
+ extern u_int aic7xxx_no_probe;
+@@ -154,142 +102,9 @@ extern u_int aic7xxx_allow_memio;
+ extern int aic7xxx_detect_complete;
+ extern Scsi_Host_Template aic7xxx_driver_template;
+-/***************************** Bus Space/DMA **********************************/
+-
+-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,17)
+-typedef dma_addr_t bus_addr_t;
+-#else
+-typedef uint32_t bus_addr_t;
+-#endif
+-typedef uint32_t bus_size_t;
+-
+-typedef enum {
+-      BUS_SPACE_MEMIO,
+-      BUS_SPACE_PIO
+-} bus_space_tag_t;
+-
+-typedef union {
+-      u_long            ioport;
+-      volatile uint8_t *maddr;
+-} bus_space_handle_t;
+-
+-typedef struct bus_dma_segment
+-{
+-      bus_addr_t      ds_addr;
+-      bus_size_t      ds_len;
+-} bus_dma_segment_t;
+-
+-struct ahc_linux_dma_tag
+-{
+-      bus_size_t      alignment;
+-      bus_size_t      boundary;
+-      bus_size_t      maxsize;
+-};
+-typedef struct ahc_linux_dma_tag* bus_dma_tag_t;
+-
+-struct ahc_linux_dmamap
+-{
+-      bus_addr_t      bus_addr;
+-};
+-typedef struct ahc_linux_dmamap* bus_dmamap_t;
+-
+-typedef int bus_dma_filter_t(void*, bus_addr_t);
+-typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
+-
+-#define BUS_DMA_WAITOK                0x0
+-#define BUS_DMA_NOWAIT                0x1
+-#define BUS_DMA_ALLOCNOW      0x2
+-#define BUS_DMA_LOAD_SEGS     0x4     /*
+-                                       * Argument is an S/G list not
+-                                       * a single buffer.
+-                                       */
+-
+-#define BUS_SPACE_MAXADDR     0xFFFFFFFF
+-#define BUS_SPACE_MAXADDR_32BIT       0xFFFFFFFF
+-#define BUS_SPACE_MAXSIZE_32BIT       0xFFFFFFFF
+-
+-int   ahc_dma_tag_create(struct ahc_softc *, bus_dma_tag_t /*parent*/,
+-                         bus_size_t /*alignment*/, bus_size_t /*boundary*/,
+-                         bus_addr_t /*lowaddr*/, bus_addr_t /*highaddr*/,
+-                         bus_dma_filter_t*/*filter*/, void */*filterarg*/,
+-                         bus_size_t /*maxsize*/, int /*nsegments*/,
+-                         bus_size_t /*maxsegsz*/, int /*flags*/,
+-                         bus_dma_tag_t */*dma_tagp*/);
+-
+-void  ahc_dma_tag_destroy(struct ahc_softc *, bus_dma_tag_t /*tag*/);
+-
+-int   ahc_dmamem_alloc(struct ahc_softc *, bus_dma_tag_t /*dmat*/,
+-                       void** /*vaddr*/, int /*flags*/,
+-                       bus_dmamap_t* /*mapp*/);
+-
+-void  ahc_dmamem_free(struct ahc_softc *, bus_dma_tag_t /*dmat*/,
+-                      void* /*vaddr*/, bus_dmamap_t /*map*/);
+-
+-void  ahc_dmamap_destroy(struct ahc_softc *, bus_dma_tag_t /*tag*/,
+-                         bus_dmamap_t /*map*/);
+-
+-int   ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t /*dmat*/,
+-                      bus_dmamap_t /*map*/, void * /*buf*/,
+-                      bus_size_t /*buflen*/, bus_dmamap_callback_t *,
+-                      void */*callback_arg*/, int /*flags*/);
+-
+-int   ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t);
+-
+-/*
+- * Operations performed by ahc_dmamap_sync().
+- */
+-#define BUS_DMASYNC_PREREAD   0x01    /* pre-read synchronization */
+-#define BUS_DMASYNC_POSTREAD  0x02    /* post-read synchronization */
+-#define BUS_DMASYNC_PREWRITE  0x04    /* pre-write synchronization */
+-#define BUS_DMASYNC_POSTWRITE 0x08    /* post-write synchronization */
+-
+-/*
+- * XXX
+- * ahc_dmamap_sync is only used on buffers allocated with
+- * the pci_alloc_consistent() API.  Although I'm not sure how
+- * this works on architectures with a write buffer, Linux does
+- * not have an API to sync "coherent" memory.  Perhaps we need
+- * to do an mb()?
+- */
+-#define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op)
+-
+-/************************** Timer DataStructures ******************************/
+-typedef struct timer_list ahc_timer_t;
+-
+-/********************************** Includes **********************************/
+-#ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT
+-#define AIC_DEBUG_REGISTERS 1
+-#else
+-#define AIC_DEBUG_REGISTERS 0
+-#endif
+-#include "aic7xxx.h"
+-
+-/***************************** Timer Facilities *******************************/
+-#define ahc_timer_init init_timer
+-#define ahc_timer_stop del_timer_sync
+-typedef void ahc_linux_callback_t (u_long);  
+-static __inline void ahc_timer_reset(ahc_timer_t *timer, int usec,
+-                                   ahc_callback_t *func, void *arg);
+-static __inline void ahc_scb_timer_reset(struct scb *scb, u_int usec);
+-
+-static __inline void
+-ahc_timer_reset(ahc_timer_t *timer, int usec, ahc_callback_t *func, void *arg)
+-{
+-      struct ahc_softc *ahc;
+-
+-      ahc = (struct ahc_softc *)arg;
+-      del_timer(timer);
+-      timer->data = (u_long)arg;
+-      timer->expires = jiffies + (usec * HZ)/1000000;
+-      timer->function = (ahc_linux_callback_t*)func;
+-      add_timer(timer);
+-}
+-
+-static __inline void
+-ahc_scb_timer_reset(struct scb *scb, u_int usec)
+-{
+-      mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000);
+-}
++/***************************** Domain Validation ******************************/
++void ahc_linux_dv_complete(Scsi_Cmnd *cmd);
++void ahc_linux_dv_timeout(struct scsi_cmnd *cmd);
+ /***************************** SMP support ************************************/
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17)
+@@ -304,187 +119,7 @@ ahc_scb_timer_reset(struct scb *scb, u_i
+ #define AHC_SCSI_HAS_HOST_LOCK 0
+ #endif
+-#define AIC7XXX_DRIVER_VERSION "6.2.35"
+-
+-/**************************** Front End Queues ********************************/
+-/*
+- * Data structure used to cast the Linux struct scsi_cmnd to something
+- * that allows us to use the queue macros.  The linux structure has
+- * plenty of space to hold the links fields as required by the queue
+- * macros, but the queue macors require them to have the correct type.
+- */
+-struct ahc_cmd_internal {
+-      /* Area owned by the Linux scsi layer. */
+-      uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)];
+-      union {
+-              STAILQ_ENTRY(ahc_cmd)   ste;
+-              LIST_ENTRY(ahc_cmd)     le;
+-              TAILQ_ENTRY(ahc_cmd)    tqe;
+-      } links;
+-      uint32_t                        end;
+-};
+-
+-struct ahc_cmd {
+-      union {
+-              struct ahc_cmd_internal icmd;
+-              struct scsi_cmnd        scsi_cmd;
+-      } un;
+-};
+-
+-#define acmd_icmd(cmd) ((cmd)->un.icmd)
+-#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd)
+-#define acmd_links un.icmd.links
+-
+-/*************************** Device Data Structures ***************************/
+-/*
+- * A per probed device structure used to deal with some error recovery
+- * scenarios that the Linux mid-layer code just doesn't know how to
+- * handle.  The structure allocated for a device only becomes persistent
+- * after a successfully completed inquiry command to the target when
+- * that inquiry data indicates a lun is present.
+- */
+-TAILQ_HEAD(ahc_busyq, ahc_cmd);
+-typedef enum {
+-      AHC_DEV_UNCONFIGURED     = 0x01,
+-      AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
+-      AHC_DEV_TIMER_ACTIVE     = 0x04, /* Our timer is active */
+-      AHC_DEV_ON_RUN_LIST      = 0x08, /* Queued to be run later */
+-      AHC_DEV_Q_BASIC          = 0x10, /* Allow basic device queuing */
+-      AHC_DEV_Q_TAGGED         = 0x20, /* Allow full SCSI2 command queueing */
+-      AHC_DEV_PERIODIC_OTAG    = 0x40, /* Send OTAG to prevent starvation */
+-      AHC_DEV_SLAVE_CONFIGURED = 0x80  /* slave_configure() has been called */
+-} ahc_linux_dev_flags;
+-
+-struct ahc_linux_target;
+-struct ahc_linux_device {
+-      TAILQ_ENTRY(ahc_linux_device) links;
+-      struct          ahc_busyq busyq;
+-
+-      /*
+-       * The number of transactions currently
+-       * queued to the device.
+-       */
+-      int                     active;
+-
+-      /*
+-       * The currently allowed number of 
+-       * transactions that can be queued to
+-       * the device.  Must be signed for
+-       * conversion from tagged to untagged
+-       * mode where the device may have more
+-       * than one outstanding active transaction.
+-       */
+-      int                     openings;
+-
+-      /*
+-       * A positive count indicates that this
+-       * device's queue is halted.
+-       */
+-      u_int                   qfrozen;
+-      
+-      /*
+-       * Cumulative command counter.
+-       */
+-      u_long                  commands_issued;
+-
+-      /*
+-       * The number of tagged transactions when
+-       * running at our current opening level
+-       * that have been successfully received by
+-       * this device since the last QUEUE FULL.
+-       */
+-      u_int                   tag_success_count;
+-#define AHC_TAG_SUCCESS_INTERVAL 50
+-
+-      ahc_linux_dev_flags     flags;
+-
+-      /*
+-       * Per device timer.
+-       */
+-      struct timer_list       timer;
+-
+-      /*
+-       * The high limit for the tags variable.
+-       */
+-      u_int                   maxtags;
+-
+-      /*
+-       * The computed number of tags outstanding
+-       * at the time of the last QUEUE FULL event.
+-       */
+-      u_int                   tags_on_last_queuefull;
+-
+-      /*
+-       * How many times we have seen a queue full
+-       * with the same number of tags.  This is used
+-       * to stop our adaptive queue depth algorithm
+-       * on devices with a fixed number of tags.
+-       */
+-      u_int                   last_queuefull_same_count;
+-#define AHC_LOCK_TAGS_COUNT 50
+-
+-      /*
+-       * How many transactions have been queued
+-       * without the device going idle.  We use
+-       * this statistic to determine when to issue
+-       * an ordered tag to prevent transaction
+-       * starvation.  This statistic is only updated
+-       * if the AHC_DEV_PERIODIC_OTAG flag is set
+-       * on this device.
+-       */
+-      u_int                   commands_since_idle_or_otag;
+-#define AHC_OTAG_THRESH       500
+-
+-      int                     lun;
+-      Scsi_Device            *scsi_device;
+-      struct                  ahc_linux_target *target;
+-};
+-
+-typedef enum {
+-      AHC_DV_REQUIRED          = 0x01,
+-      AHC_INQ_VALID            = 0x02,
+-      AHC_BASIC_DV             = 0x04,
+-      AHC_ENHANCED_DV          = 0x08
+-} ahc_linux_targ_flags;
+-
+-/* DV States */
+-typedef enum {
+-      AHC_DV_STATE_EXIT = 0,
+-      AHC_DV_STATE_INQ_SHORT_ASYNC,
+-      AHC_DV_STATE_INQ_ASYNC,
+-      AHC_DV_STATE_INQ_ASYNC_VERIFY,
+-      AHC_DV_STATE_TUR,
+-      AHC_DV_STATE_REBD,
+-      AHC_DV_STATE_INQ_VERIFY,
+-      AHC_DV_STATE_WEB,
+-      AHC_DV_STATE_REB,
+-      AHC_DV_STATE_SU,
+-      AHC_DV_STATE_BUSY
+-} ahc_dv_state;
+-
+-struct ahc_linux_target {
+-      struct ahc_linux_device  *devices[AHC_NUM_LUNS];
+-      int                       channel;
+-      int                       target;
+-      int                       refcount;
+-      struct ahc_transinfo      last_tinfo;
+-      struct ahc_softc         *ahc;
+-      ahc_linux_targ_flags      flags;
+-      struct scsi_inquiry_data *inq_data;
+-      /*
+-       * The next "fallback" period to use for narrow/wide transfers.
+-       */
+-      uint8_t                   dv_next_narrow_period;
+-      uint8_t                   dv_next_wide_period;
+-      uint8_t                   dv_max_width;
+-      uint8_t                   dv_max_ppr_options;
+-      uint8_t                   dv_last_ppr_options;
+-      u_int                     dv_echo_size;
+-      ahc_dv_state              dv_state;
+-      u_int                     dv_state_retry;
+-      char                     *dv_buffer;
+-      char                     *dv_buffer1;
+-};
++#define AIC7XXX_DRIVER_VERSION "6.3.4"
+ /********************* Definitions Required by the Core ***********************/
+ /*
+@@ -506,120 +141,39 @@ extern u_int ahc_linux_nseg;
+ #define       AHC_NSEG 128
+ #endif
+-/*
+- * Per-SCB OSM storage.
+- */
+-typedef enum {
+-      AHC_UP_EH_SEMAPHORE = 0x1
+-} ahc_linux_scb_flags;
+-
+-struct scb_platform_data {
+-      struct ahc_linux_device *dev;
+-      bus_addr_t               buf_busaddr;
+-      uint32_t                 xfer_len;
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
+-      uint32_t                 resid;         /* Transfer residual */
+-#endif
+-      uint32_t                 sense_resid;   /* Auto-Sense residual */
+-      ahc_linux_scb_flags      flags;
+-};
+-
+-/*
+- * Define a structure used for each host adapter.  All members are
+- * aligned on a boundary >= the size of the member to honor the
+- * alignment restrictions of the various platforms supported by
+- * this driver.
+- */
+-typedef enum {
+-      AHC_DV_WAIT_SIMQ_EMPTY   = 0x01,
+-      AHC_DV_WAIT_SIMQ_RELEASE = 0x02,
+-      AHC_DV_ACTIVE            = 0x04,
+-      AHC_DV_SHUTDOWN          = 0x08,
+-      AHC_RUN_CMPLT_Q_TIMER    = 0x10
+-} ahc_linux_softc_flags;
+-
+-TAILQ_HEAD(ahc_completeq, ahc_cmd);
+-
+-struct ahc_platform_data {
+-      /*
+-       * Fields accessed from interrupt context.
+-       */
+-      struct ahc_linux_target *targets[AHC_NUM_TARGETS]; 
+-      TAILQ_HEAD(, ahc_linux_device) device_runq;
+-      struct ahc_completeq     completeq;
+-
+-      spinlock_t               spin_lock;
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      struct tasklet_struct    runq_tasklet;
+-#endif
+-      u_int                    qfrozen;
+-      pid_t                    dv_pid;
+-      struct timer_list        completeq_timer;
+-      struct timer_list        reset_timer;
+-      struct semaphore         eh_sem;
+-      struct semaphore         dv_sem;
+-      struct semaphore         dv_cmd_sem;    /* XXX This needs to be in
+-                                               * the target struct
+-                                               */
+-      struct scsi_device      *dv_scsi_dev;
+-      struct Scsi_Host        *host;          /* pointer to scsi host */
+-#define AHC_LINUX_NOIRQ       ((uint32_t)~0)
+-      uint32_t                 irq;           /* IRQ for this adapter */
+-      uint32_t                 bios_address;
+-      uint32_t                 mem_busaddr;   /* Mem Base Addr */
+-      bus_addr_t               hw_dma_mask;
+-      ahc_linux_softc_flags    flags;
+-};
+-
+-/************************** OS Utility Wrappers *******************************/
+-#define printf printk
+-#define M_NOWAIT GFP_ATOMIC
+-#define M_WAITOK 0
+-#define malloc(size, type, flags) kmalloc(size, flags)
+-#define free(ptr, type) kfree(ptr)
+-
+-static __inline void ahc_delay(long);
+-static __inline void
+-ahc_delay(long usec)
+-{
+-      /*
+-       * udelay on Linux can have problems for
+-       * multi-millisecond waits.  Wait at most
+-       * 1024us per call.
+-       */
+-      while (usec > 0) {
+-              udelay(usec % 1024);
+-              usec -= 1024;
+-      }
+-}
+-
++/************************** Error Recovery ************************************/
++static __inline void  ahc_wakeup_recovery_thread(struct ahc_softc *ahc); 
++  
++static __inline void
++ahc_wakeup_recovery_thread(struct ahc_softc *ahc)
++{ 
++      up(&ahc->platform_data->recovery_sem);
++}
++ 
++int                   ahc_spawn_recovery_thread(struct ahc_softc *ahc);
++void                  ahc_terminate_recovery_thread(struct ahc_softc *ahc);
++void                  ahc_set_recoveryscb(struct ahc_softc *ahc,
++                                          struct scb *scb);
+ /***************************** Low Level I/O **********************************/
+-#if defined(__powerpc__) || defined(__i386__) || defined(__ia64__)
+-#define MMAPIO
+-#endif
+-
+ static __inline uint8_t ahc_inb(struct ahc_softc * ahc, long port);
+ static __inline void ahc_outb(struct ahc_softc * ahc, long port, uint8_t val);
+ static __inline void ahc_outsb(struct ahc_softc * ahc, long port,
+                              uint8_t *, int count);
+ static __inline void ahc_insb(struct ahc_softc * ahc, long port,
+                              uint8_t *, int count);
++static __inline void ahc_flush_device_writes(struct ahc_softc *);
+ static __inline uint8_t
+ ahc_inb(struct ahc_softc * ahc, long port)
+ {
+       uint8_t x;
+-#ifdef MMAPIO
+       if (ahc->tag == BUS_SPACE_MEMIO) {
+               x = readb(ahc->bsh.maddr + port);
+       } else {
+               x = inb(ahc->bsh.ioport + port);
+       }
+-#else
+-      x = inb(ahc->bsh.ioport + port);
+-#endif
+       mb();
+       return (x);
+ }
+@@ -627,15 +181,11 @@ ahc_inb(struct ahc_softc * ahc, long por
+ static __inline void
+ ahc_outb(struct ahc_softc * ahc, long port, uint8_t val)
+ {
+-#ifdef MMAPIO
+       if (ahc->tag == BUS_SPACE_MEMIO) {
+               writeb(val, ahc->bsh.maddr + port);
+       } else {
+               outb(val, ahc->bsh.ioport + port);
+       }
+-#else
+-      outb(val, ahc->bsh.ioport + port);
+-#endif
+       mb();
+ }
+@@ -667,6 +217,13 @@ ahc_insb(struct ahc_softc * ahc, long po
+               *array++ = ahc_inb(ahc, port);
+ }
++static __inline void
++ahc_flush_device_writes(struct ahc_softc *ahc)
++{
++      /* XXX Is this sufficient for all architectures??? */
++      ahc_inb(ahc, INTSTAT);
++}
++
+ /**************************** Initialization **********************************/
+ int           ahc_linux_register_host(struct ahc_softc *,
+                                       Scsi_Host_Template *);
+@@ -795,174 +352,41 @@ ahc_list_unlock(unsigned long *flags)
+ }
+ /******************************* PCI Definitions ******************************/
+-/*
+- * PCIM_xxx: mask to locate subfield in register
+- * PCIR_xxx: config register offset
+- * PCIC_xxx: device class
+- * PCIS_xxx: device subclass
+- * PCIP_xxx: device programming interface
+- * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
+- * PCID_xxx: device ID
+- */
+-#define PCIR_DEVVENDOR                0x00
+-#define PCIR_VENDOR           0x00
+-#define PCIR_DEVICE           0x02
+-#define PCIR_COMMAND          0x04
+-#define PCIM_CMD_PORTEN               0x0001
+-#define PCIM_CMD_MEMEN                0x0002
+-#define PCIM_CMD_BUSMASTEREN  0x0004
+-#define PCIM_CMD_MWRICEN      0x0010
+-#define PCIM_CMD_PERRESPEN    0x0040
+-#define       PCIM_CMD_SERRESPEN      0x0100
+-#define PCIR_STATUS           0x06
+-#define PCIR_REVID            0x08
+-#define PCIR_PROGIF           0x09
+-#define PCIR_SUBCLASS         0x0a
+-#define PCIR_CLASS            0x0b
+-#define PCIR_CACHELNSZ                0x0c
+-#define PCIR_LATTIMER         0x0d
+-#define PCIR_HEADERTYPE               0x0e
+-#define PCIM_MFDEV            0x80
+-#define PCIR_BIST             0x0f
+-#define PCIR_CAP_PTR          0x34
+-
+-/* config registers for header type 0 devices */
+-#define PCIR_MAPS     0x10
+-#define PCIR_SUBVEND_0        0x2c
+-#define PCIR_SUBDEV_0 0x2e
+-
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+ extern struct pci_driver aic7xxx_pci_driver;
+ #endif
+-typedef enum
+-{
+-      AHC_POWER_STATE_D0,
+-      AHC_POWER_STATE_D1,
+-      AHC_POWER_STATE_D2,
+-      AHC_POWER_STATE_D3
+-} ahc_power_state;
+-
+-void ahc_power_state_change(struct ahc_softc *ahc,
+-                          ahc_power_state new_state);
+ /**************************** VL/EISA Routines ********************************/
+-int                    aic7770_linux_probe(Scsi_Host_Template *);
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) \
++  && (defined(__i386__) || defined(__alpha__)) \
++  && (!defined(CONFIG_EISA)))
++#define CONFIG_EISA
++#endif
++
++#ifdef CONFIG_EISA
++extern uint32_t aic7xxx_probe_eisa_vl;
++void                   ahc_linux_eisa_init(void);
++void                   ahc_linux_eisa_exit(void);
+ int                    aic7770_map_registers(struct ahc_softc *ahc,
+                                              u_int port);
+ int                    aic7770_map_int(struct ahc_softc *ahc, u_int irq);
++#endif
+ /******************************* PCI Routines *********************************/
++#ifdef CONFIG_PCI
+ int                    ahc_linux_pci_init(void);
+ void                   ahc_linux_pci_exit(void);
+ int                    ahc_pci_map_registers(struct ahc_softc *ahc);
+ int                    ahc_pci_map_int(struct ahc_softc *ahc);
++#endif 
+-static __inline uint32_t ahc_pci_read_config(ahc_dev_softc_t pci,
+-                                           int reg, int width);
+-
+-static __inline uint32_t
+-ahc_pci_read_config(ahc_dev_softc_t pci, int reg, int width)
+-{
+-      switch (width) {
+-      case 1:
+-      {
+-              uint8_t retval;
+-
+-              pci_read_config_byte(pci, reg, &retval);
+-              return (retval);
+-      }
+-      case 2:
+-      {
+-              uint16_t retval;
+-              pci_read_config_word(pci, reg, &retval);
+-              return (retval);
+-      }
+-      case 4:
+-      {
+-              uint32_t retval;
+-              pci_read_config_dword(pci, reg, &retval);
+-              return (retval);
+-      }
+-      default:
+-              panic("ahc_pci_read_config: Read size too big");
+-              /* NOTREACHED */
+-              return (0);
+-      }
+-}
+-
+-static __inline void ahc_pci_write_config(ahc_dev_softc_t pci,
+-                                        int reg, uint32_t value,
+-                                        int width);
+-
+-static __inline void
+-ahc_pci_write_config(ahc_dev_softc_t pci, int reg, uint32_t value, int width)
+-{
+-      switch (width) {
+-      case 1:
+-              pci_write_config_byte(pci, reg, value);
+-              break;
+-      case 2:
+-              pci_write_config_word(pci, reg, value);
+-              break;
+-      case 4:
+-              pci_write_config_dword(pci, reg, value);
+-              break;
+-      default:
+-              panic("ahc_pci_write_config: Write size too big");
+-              /* NOTREACHED */
+-      }
+-}
+-
+-static __inline int ahc_get_pci_function(ahc_dev_softc_t);
+-static __inline int
+-ahc_get_pci_function(ahc_dev_softc_t pci)
+-{
+-      return (PCI_FUNC(pci->devfn));
+-}
+-
+-static __inline int ahc_get_pci_slot(ahc_dev_softc_t);
+-static __inline int
+-ahc_get_pci_slot(ahc_dev_softc_t pci)
+-{
+-      return (PCI_SLOT(pci->devfn));
+-}
+-
+-static __inline int ahc_get_pci_bus(ahc_dev_softc_t);
+-static __inline int
+-ahc_get_pci_bus(ahc_dev_softc_t pci)
+-{
+-      return (pci->bus->number);
+-}
+-
+-static __inline void ahc_flush_device_writes(struct ahc_softc *);
+-static __inline void
+-ahc_flush_device_writes(struct ahc_softc *ahc)
+-{
+-      /* XXX Is this sufficient for all architectures??? */
+-      ahc_inb(ahc, INTSTAT);
+-}
+-
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0)
+-#define pci_map_sg(pdev, sg_list, nseg, direction) (nseg)
+-#define pci_unmap_sg(pdev, sg_list, nseg, direction)
+-#define sg_dma_address(sg) (VIRT_TO_BUS((sg)->address))
+-#define sg_dma_len(sg) ((sg)->length)
+-#define pci_map_single(pdev, buffer, bufflen, direction) \
+-      (VIRT_TO_BUS(buffer))
+-#define pci_unmap_single(pdev, buffer, buflen, direction)
+-#endif
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
+-#define ahc_pci_set_dma_mask pci_set_dma_mask
++/**************************** Proc FS Support *********************************/
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++int   ahc_linux_proc_info(char *, char **, off_t, int, int, int);
+ #else
+-/*
+- * Always "return" 0 for success.
+- */
+-#define ahc_pci_set_dma_mask(dev_softc, mask)                         \
+-      (((dev_softc)->dma_mask = mask) && 0)
++int   ahc_linux_proc_info(struct Scsi_Host *, char *, char **,
++                          off_t, int, int);
+ #endif
+-/**************************** Proc FS Support *********************************/
+-int   ahc_linux_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
+ /*************************** Domain Validation ********************************/
+ #define AHC_DV_CMD(cmd) ((cmd)->scsi_done == ahc_linux_dv_complete)
+@@ -971,194 +395,9 @@ int      ahc_linux_proc_info(struct Scsi_Host
+        && (ahc)->platform_data->qfrozen == 1)
+ /*********************** Transaction Access Wrappers *************************/
+-static __inline void ahc_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t);
+-static __inline void ahc_set_transaction_status(struct scb *, uint32_t);
+-static __inline void ahc_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t);
+-static __inline void ahc_set_scsi_status(struct scb *, uint32_t);
+-static __inline uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd);
+-static __inline uint32_t ahc_get_transaction_status(struct scb *);
+-static __inline uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd);
+-static __inline uint32_t ahc_get_scsi_status(struct scb *);
+-static __inline void ahc_set_transaction_tag(struct scb *, int, u_int);
+-static __inline u_long ahc_get_transfer_length(struct scb *);
+-static __inline int ahc_get_transfer_dir(struct scb *);
+-static __inline void ahc_set_residual(struct scb *, u_long);
+-static __inline void ahc_set_sense_residual(struct scb *scb, u_long resid);
+-static __inline u_long ahc_get_residual(struct scb *);
+-static __inline u_long ahc_get_sense_residual(struct scb *);
+-static __inline int ahc_perform_autosense(struct scb *);
+-static __inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *,
+-                                             struct scb *);
+-static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *,
+-                                                   struct ahc_devinfo *);
+-static __inline void ahc_platform_scb_free(struct ahc_softc *ahc,
+-                                         struct scb *scb);
+-static __inline void ahc_freeze_scb(struct scb *scb);
+-
+-static __inline
+-void ahc_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status)
+-{
+-      cmd->result &= ~(CAM_STATUS_MASK << 16);
+-      cmd->result |= status << 16;
+-}
+-
+-static __inline
+-void ahc_set_transaction_status(struct scb *scb, uint32_t status)
+-{
+-      ahc_cmd_set_transaction_status(scb->io_ctx,status);
+-}
+-
+-static __inline
+-void ahc_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status)
+-{
+-      cmd->result &= ~0xFFFF;
+-      cmd->result |= status;
+-}
+-
+-static __inline
+-void ahc_set_scsi_status(struct scb *scb, uint32_t status)
+-{
+-      ahc_cmd_set_scsi_status(scb->io_ctx, status);
+-}
+-
+-static __inline
+-uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd)
+-{
+-      return ((cmd->result >> 16) & CAM_STATUS_MASK);
+-}
+-
+-static __inline
+-uint32_t ahc_get_transaction_status(struct scb *scb)
+-{
+-      return (ahc_cmd_get_transaction_status(scb->io_ctx));
+-}
+-
+-static __inline
+-uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd)
+-{
+-      return (cmd->result & 0xFFFF);
+-}
+-
+-static __inline
+-uint32_t ahc_get_scsi_status(struct scb *scb)
+-{
+-      return (ahc_cmd_get_scsi_status(scb->io_ctx));
+-}
+-
+-static __inline
+-void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type)
+-{
+-      /*
+-       * Nothing to do for linux as the incoming transaction
+-       * has no concept of tag/non tagged, etc.
+-       */
+-}
+-
+-static __inline
+-u_long ahc_get_transfer_length(struct scb *scb)
+-{
+-      return (scb->platform_data->xfer_len);
+-}
+-
+-static __inline
+-int ahc_get_transfer_dir(struct scb *scb)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,40)
+-      return (scb->io_ctx->sc_data_direction);
+-#else
+-      if (scb->io_ctx->bufflen == 0)
+-              return (CAM_DIR_NONE);
+-
+-      switch(scb->io_ctx->cmnd[0]) {
+-      case 0x08:  /* READ(6)  */
+-      case 0x28:  /* READ(10) */
+-      case 0xA8:  /* READ(12) */
+-              return (CAM_DIR_IN);
+-        case 0x0A:  /* WRITE(6)  */
+-        case 0x2A:  /* WRITE(10) */
+-        case 0xAA:  /* WRITE(12) */
+-              return (CAM_DIR_OUT);
+-        default:
+-              return (CAM_DIR_NONE);
+-        }
+-#endif
+-}
+-
+-static __inline
+-void ahc_set_residual(struct scb *scb, u_long resid)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      scb->io_ctx->resid = resid;
+-#else
+-      scb->platform_data->resid = resid;
+-#endif
+-}
+-
+-static __inline
+-void ahc_set_sense_residual(struct scb *scb, u_long resid)
+-{
+-      scb->platform_data->sense_resid = resid;
+-}
+-
+-static __inline
+-u_long ahc_get_residual(struct scb *scb)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      return (scb->io_ctx->resid);
+-#else
+-      return (scb->platform_data->resid);
+-#endif
+-}
+-
+-static __inline
+-u_long ahc_get_sense_residual(struct scb *scb)
+-{
+-      return (scb->platform_data->sense_resid);
+-}
+-
+-static __inline
+-int ahc_perform_autosense(struct scb *scb)
+-{
+-      /*
+-       * We always perform autosense in Linux.
+-       * On other platforms this is set on a
+-       * per-transaction basis.
+-       */
+-      return (1);
+-}
+-
+-static __inline uint32_t
+-ahc_get_sense_bufsize(struct ahc_softc *ahc, struct scb *scb)
+-{
+-      return (sizeof(struct scsi_sense_data));
+-}
+-
+-static __inline void
+-ahc_notify_xfer_settings_change(struct ahc_softc *ahc,
+-                              struct ahc_devinfo *devinfo)
+-{
+-      /* Nothing to do here for linux */
+-}
+-
+-static __inline void
+-ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb)
+-{
+-      ahc->flags &= ~AHC_RESOURCE_SHORTAGE;
+-}
+-
+ int   ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);
+ void  ahc_platform_free(struct ahc_softc *ahc);
+ void  ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
+-
+-static __inline void
+-ahc_freeze_scb(struct scb *scb)
+-{
+-      if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
+-                scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
+-                scb->platform_data->dev->qfrozen++;
+-        }
+-}
+-
+ void  ahc_platform_set_tags(struct ahc_softc *ahc,
+                             struct ahc_devinfo *devinfo, ahc_queue_alg);
+ int   ahc_platform_abort_scbs(struct ahc_softc *ahc, int target,
+@@ -1175,9 +414,9 @@ void      ahc_print_path(struct ahc_softc *, 
+ void  ahc_platform_dump_card_state(struct ahc_softc *ahc);
+ #ifdef CONFIG_PCI
+-#define AHC_PCI_CONFIG 1
++#define AIC_PCI_CONFIG 1
+ #else
+-#define AHC_PCI_CONFIG 0
++#define AIC_PCI_CONFIG 0
+ #endif
+ #define bootverbose aic7xxx_verbose
+ extern u_int aic7xxx_verbose;
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c  2003-12-28 23:21:40.000000000 -0800
+@@ -36,11 +36,17 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#45 $
++ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#52 $
+  */
+ #include "aic7xxx_osm.h"
++/*
++ * Include aiclib_pci.c as part of our
++ * "module dependencies are hard" work around.
++ */
++#include "aiclib_pci.c"
++
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+ struct pci_device_id
+ {
+@@ -51,11 +57,9 @@ static int  ahc_linux_pci_dev_probe(struc
+                                       const struct pci_device_id *ent);
+ static int    ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc,
+                                               u_long *base);
+-#ifdef MMAPIO
+ static int    ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
+                                                u_long *bus_addr,
+                                                uint8_t **maddr);
+-#endif /* MMAPIO */
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+ static void   ahc_linux_pci_dev_remove(struct pci_dev *pdev);
+@@ -97,12 +101,14 @@ ahc_linux_pci_dev_remove(struct pci_dev 
+       if (ahc != NULL) {
+               u_long s;
++              TAILQ_REMOVE(&ahc_tailq, ahc, links);
++              ahc_list_unlock(&l);
+               ahc_lock(ahc, &s);
+               ahc_intr_enable(ahc, FALSE);
+               ahc_unlock(ahc, &s);
+               ahc_free(ahc);
+-      }
+-      ahc_list_unlock(&l);
++      } else
++              ahc_list_unlock(&l);
+ }
+ #endif /* !LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) */
+@@ -112,7 +118,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *
+       char             buf[80];
+       bus_addr_t       mask_39bit;
+       struct           ahc_softc *ahc;
+-      ahc_dev_softc_t  pci;
++      aic_dev_softc_t  dev;
+       struct           ahc_pci_identity *entry;
+       char            *name;
+       int              error;
+@@ -123,7 +129,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *
+       TAILQ_FOREACH(ahc, &ahc_tailq, links) {
+               struct pci_dev *probed_pdev;
+-              probed_pdev = ahc->dev_softc;
++              probed_pdev = aic_dev_to_pci_dev(ahc->dev_softc);
+               if (probed_pdev->bus->number == pdev->bus->number
+                && probed_pdev->devfn == pdev->devfn)
+                       break;
+@@ -133,8 +139,8 @@ ahc_linux_pci_dev_probe(struct pci_dev *
+               return (-ENODEV);
+       }
+-      pci = pdev;
+-      entry = ahc_find_pci_device(pci);
++      dev = aic_pci_dev_to_dev(pdev);
++      entry = ahc_find_pci_device(dev);
+       if (entry == NULL)
+               return (-ENODEV);
+@@ -144,9 +150,9 @@ ahc_linux_pci_dev_probe(struct pci_dev *
+        * common detect routine.
+        */
+       sprintf(buf, "ahc_pci:%d:%d:%d",
+-              ahc_get_pci_bus(pci),
+-              ahc_get_pci_slot(pci),
+-              ahc_get_pci_function(pci));
++              aic_get_pci_bus(dev),
++              aic_get_pci_slot(dev),
++              aic_get_pci_function(dev));
+       name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+       if (name == NULL)
+               return (-ENOMEM);
+@@ -154,6 +160,8 @@ ahc_linux_pci_dev_probe(struct pci_dev *
+       ahc = ahc_alloc(NULL, name);
+       if (ahc == NULL)
+               return (-ENOMEM);
++      ahc->dev_softc = dev;
++
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+       if (pci_enable_device(pdev)) {
+               ahc_free(ahc);
+@@ -161,18 +169,17 @@ ahc_linux_pci_dev_probe(struct pci_dev *
+       }
+       pci_set_master(pdev);
+-      mask_39bit = (bus_addr_t)(0x7FFFFFFFFFULL & (bus_addr_t)~0);
++      mask_39bit = (bus_addr_t)0x7FFFFFFFFFULL;
+       if (sizeof(bus_addr_t) > 4
+        && ahc_linux_get_memsize() > 0x80000000
+-       && ahc_pci_set_dma_mask(pdev, mask_39bit) == 0) {
++       && aic_set_dma_mask(ahc, mask_39bit) == 0) {
+               ahc->flags |= AHC_39BIT_ADDRESSING;
+               ahc->platform_data->hw_dma_mask = mask_39bit;
+       } else {
+-              ahc_pci_set_dma_mask(pdev, 0xFFFFFFFF);
++              aic_set_dma_mask(ahc, 0xFFFFFFFF);
+               ahc->platform_data->hw_dma_mask = 0xFFFFFFFF;
+       }
+ #endif
+-      ahc->dev_softc = pci;
+       error = ahc_pci_config(ahc, entry);
+       if (error != 0) {
+               ahc_free(ahc);
+@@ -211,10 +218,8 @@ ahc_linux_pci_init(void)
+       pdev = NULL;
+       class = PCI_CLASS_STORAGE_SCSI << 8;
+       while ((pdev = pci_find_class(class, pdev)) != NULL) {
+-              ahc_dev_softc_t pci;
+               int error;
+-              pci = pdev;
+               error = ahc_linux_pci_dev_probe(pdev, /*pci_devid*/NULL);
+               if (error == 0)
+                       found++;
+@@ -236,9 +241,9 @@ ahc_linux_pci_reserve_io_region(struct a
+               return (ENOMEM);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      *base = pci_resource_start(ahc->dev_softc, 0);
++      *base = pci_resource_start(aic_pci_dev(ahc), 0);
+ #else
+-      *base = ahc_pci_read_config(ahc->dev_softc, PCIR_MAPS, 4);
++      *base = aic_pci_read_config(ahc->dev_softc, PCIR_MAPS, 4);
+       *base &= PCI_BASE_ADDRESS_IO_MASK;
+ #endif
+       if (*base == 0)
+@@ -254,7 +259,6 @@ ahc_linux_pci_reserve_io_region(struct a
+       return (0);
+ }
+-#ifdef MMAPIO
+ static int
+ ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
+                                u_long *bus_addr,
+@@ -267,11 +271,11 @@ ahc_linux_pci_reserve_mem_region(struct 
+       error = 0;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+-      start = pci_resource_start(ahc->dev_softc, 1);
++      start = pci_resource_start(aic_pci_dev(ahc), 1);
+       base_page = start & PAGE_MASK;
+       base_offset = start - base_page;
+ #else
+-      start = ahc_pci_read_config(ahc->dev_softc, PCIR_MAPS+4, 4);
++      start = aic_pci_read_config(ahc->dev_softc, PCIR_MAPS+4, 4);
+       base_offset = start & PCI_BASE_ADDRESS_MEM_MASK;
+       base_page = base_offset & PAGE_MASK;
+       base_offset -= base_page;
+@@ -296,7 +300,6 @@ ahc_linux_pci_reserve_mem_region(struct 
+               error = ENOMEM;
+       return (error);
+ }
+-#endif /* MMAPIO */
+ int
+ ahc_pci_map_registers(struct ahc_softc *ahc)
+@@ -309,17 +312,16 @@ ahc_pci_map_registers(struct ahc_softc *
+       /*
+        * If its allowed, we prefer memory mapped access.
+        */
+-      command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, 4);
++      command = aic_pci_read_config(ahc->dev_softc, PCIR_COMMAND, 4);
+       command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN);
+       base = 0;
+       maddr = NULL;
+-#ifdef MMAPIO
+       error = ahc_linux_pci_reserve_mem_region(ahc, &base, &maddr);
+       if (error == 0) {
+               ahc->platform_data->mem_busaddr = base;
+               ahc->tag = BUS_SPACE_MEMIO;
+               ahc->bsh.maddr = maddr;
+-              ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
++              aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
+                                    command | PCIM_CMD_MEMEN, 4);
+               /*
+@@ -330,9 +332,9 @@ ahc_pci_map_registers(struct ahc_softc *
+                       printf("aic7xxx: PCI Device %d:%d:%d "
+                              "failed memory mapped test.  Using PIO.\n",
+-                             ahc_get_pci_bus(ahc->dev_softc),
+-                             ahc_get_pci_slot(ahc->dev_softc),
+-                             ahc_get_pci_function(ahc->dev_softc));
++                             aic_get_pci_bus(ahc->dev_softc),
++                             aic_get_pci_slot(ahc->dev_softc),
++                             aic_get_pci_function(ahc->dev_softc));
+                       iounmap((void *)((u_long)maddr & PAGE_MASK));
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+                       release_mem_region(ahc->platform_data->mem_busaddr,
+@@ -345,12 +347,11 @@ ahc_pci_map_registers(struct ahc_softc *
+       } else {
+               printf("aic7xxx: PCI%d:%d:%d MEM region 0x%lx "
+                      "unavailable. Cannot memory map device.\n",
+-                     ahc_get_pci_bus(ahc->dev_softc),
+-                     ahc_get_pci_slot(ahc->dev_softc),
+-                     ahc_get_pci_function(ahc->dev_softc),
++                     aic_get_pci_bus(ahc->dev_softc),
++                     aic_get_pci_slot(ahc->dev_softc),
++                     aic_get_pci_function(ahc->dev_softc),
+                      base);
+       }
+-#endif /* MMAPIO */
+       /*
+        * We always prefer memory mapped access.
+@@ -358,20 +359,20 @@ ahc_pci_map_registers(struct ahc_softc *
+       if (maddr == NULL) {
+               error = ahc_linux_pci_reserve_io_region(ahc, &base);
+-              if (error == 0) {
++              if (error == 0 && ahc_pci_test_register_access(ahc) == 0) {
+                       ahc->tag = BUS_SPACE_PIO;
+                       ahc->bsh.ioport = base;
+                       command |= PCIM_CMD_PORTEN;
+               } else {
+                       printf("aic7xxx: PCI%d:%d:%d IO region 0x%lx[0..255] "
+                              "unavailable. Cannot map device.\n",
+-                             ahc_get_pci_bus(ahc->dev_softc),
+-                             ahc_get_pci_slot(ahc->dev_softc),
+-                             ahc_get_pci_function(ahc->dev_softc),
++                             aic_get_pci_bus(ahc->dev_softc),
++                             aic_get_pci_slot(ahc->dev_softc),
++                             aic_get_pci_function(ahc->dev_softc),
+                              base);
+               }
+       }
+-      ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, 4);
++      aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, 4);
+       return (error);
+ }
+@@ -380,49 +381,10 @@ ahc_pci_map_int(struct ahc_softc *ahc)
+ {
+       int error;
+-      error = request_irq(ahc->dev_softc->irq, ahc_linux_isr,
++      error = request_irq(aic_pci_dev(ahc)->irq, ahc_linux_isr,
+                           SA_SHIRQ, "aic7xxx", ahc);
+       if (error == 0)
+-              ahc->platform_data->irq = ahc->dev_softc->irq;
++              ahc->platform_data->irq = aic_pci_dev(ahc)->irq;
+       
+       return (-error);
+ }
+-
+-void
+-ahc_power_state_change(struct ahc_softc *ahc, ahc_power_state new_state)
+-{
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+-      pci_set_power_state(ahc->dev_softc, new_state);
+-#else
+-      uint32_t cap;
+-      u_int cap_offset;
+-
+-      /*
+-       * Traverse the capability list looking for
+-       * the power management capability.
+-       */
+-      cap = 0;
+-      cap_offset = ahc_pci_read_config(ahc->dev_softc,
+-                                       PCIR_CAP_PTR, /*bytes*/1);
+-      while (cap_offset != 0) {
+-
+-              cap = ahc_pci_read_config(ahc->dev_softc,
+-                                        cap_offset, /*bytes*/4);
+-              if ((cap & 0xFF) == 1
+-               && ((cap >> 16) & 0x3) > 0) {
+-                      uint32_t pm_control;
+-
+-                      pm_control = ahc_pci_read_config(ahc->dev_softc,
+-                                                       cap_offset + 4,
+-                                                       /*bytes*/4);
+-                      pm_control &= ~0x3;
+-                      pm_control |= new_state;
+-                      ahc_pci_write_config(ahc->dev_softc,
+-                                           cap_offset + 4,
+-                                           pm_control, /*bytes*/2);
+-                      break;
+-              }
+-              cap_offset = (cap >> 8) & 0xFF;
+-      }
+-#endif 
+-}
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx_pci.c     2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx_pci.c      2003-12-28 23:21:40.000000000 -0800
+@@ -39,9 +39,7 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#66 $
+- *
+- * $FreeBSD$
++ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#78 $
+  */
+ #ifdef __linux__
+@@ -49,14 +47,13 @@
+ #include "aic7xxx_inline.h"
+ #include "aic7xxx_93cx6.h"
+ #else
++#include <sys/cdefs.h>
++__FBSDID("$FreeBSD$");
+ #include <dev/aic7xxx/aic7xxx_osm.h>
+ #include <dev/aic7xxx/aic7xxx_inline.h>
+ #include <dev/aic7xxx/aic7xxx_93cx6.h>
+ #endif
+-#define AHC_PCI_IOADDR        PCIR_MAPS       /* I/O Address */
+-#define AHC_PCI_MEMADDR       (PCIR_MAPS + 4) /* Mem I/O Address */
+-
+ static __inline uint64_t
+ ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
+ {
+@@ -76,7 +73,7 @@ ahc_compose_id(u_int device, u_int vendo
+ #define ID_9005_SISL_MASK             0x000FFFFF00000000ull
+ #define ID_9005_SISL_ID                       0x0005900500000000ull
+ #define ID_AIC7850                    0x5078900400000000ull
+-#define ID_AHA_2902_04_10_15_20_30C   0x5078900478509004ull
++#define ID_AHA_2902_04_10_15_20C_30C  0x5078900478509004ull
+ #define ID_AIC7855                    0x5578900400000000ull
+ #define ID_AIC7859                    0x3860900400000000ull
+ #define ID_AHA_2930CU                 0x3860900438699004ull
+@@ -133,6 +130,7 @@ ahc_compose_id(u_int device, u_int vendo
+ #define ID_AHA_29160C                 0x0080900562209005ull
+ #define ID_AHA_29160B                 0x00809005E2209005ull
+ #define ID_AHA_19160B                 0x0081900562A19005ull
++#define ID_AHA_2915_30LP              0x0082900502109005ull
+ #define ID_AIC7896                    0x005F9005FFFF9005ull
+ #define ID_AIC7896_ARO                        0x00539005FFFF9005ull
+@@ -245,9 +243,9 @@ struct ahc_pci_identity ahc_pci_ident_ta
+ {
+       /* aic7850 based controllers */
+       {
+-              ID_AHA_2902_04_10_15_20_30C,
++              ID_AHA_2902_04_10_15_20C_30C,
+               ID_ALL_MASK,
+-              "Adaptec 2902/04/10/15/20/30C SCSI adapter",
++              "Adaptec 2902/04/10/15/20C/30C SCSI adapter",
+               ahc_aic785X_setup
+       },
+       /* aic7860 based controllers */
+@@ -470,6 +468,12 @@ struct ahc_pci_identity ahc_pci_ident_ta
+               "Adaptec aic7892 Ultra160 SCSI adapter (ARO)",
+               ahc_aic7892_setup
+       },
++      {
++              ID_AHA_2915_30LP,
++              ID_ALL_MASK,
++              "Adaptec 2915/30LP Ultra160 SCSI adapter",
++              ahc_aic7892_setup
++      },
+       /* aic7895 based controllers */ 
+       {
+               ID_AHA_2940U_DUAL,
+@@ -738,7 +742,7 @@ ahc_9005_subdevinfo_valid(uint16_t devic
+ }
+ struct ahc_pci_identity *
+-ahc_find_pci_device(ahc_dev_softc_t pci)
++ahc_find_pci_device(aic_dev_softc_t pci)
+ {
+       uint64_t  full_id;
+       uint16_t  device;
+@@ -748,10 +752,10 @@ ahc_find_pci_device(ahc_dev_softc_t pci)
+       struct    ahc_pci_identity *entry;
+       u_int     i;
+-      vendor = ahc_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
+-      device = ahc_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
+-      subvendor = ahc_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
+-      subdevice = ahc_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
++      vendor = aic_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
++      device = aic_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
++      subvendor = aic_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
++      subdevice = aic_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
+       full_id = ahc_compose_id(device, vendor, subdevice, subvendor);
+       /*
+@@ -761,7 +765,7 @@ ahc_find_pci_device(ahc_dev_softc_t pci)
+        * to sanity check it prior to accepting the subdevice
+        * ID as valid.
+        */
+-      if (ahc_get_pci_function(pci) > 0
++      if (aic_get_pci_function(pci) > 0
+        && ahc_9005_subdevinfo_valid(vendor, device, subvendor, subdevice)
+        && SUBID_9005_MFUNCENB(subdevice) == 0)
+               return (NULL);
+@@ -798,7 +802,7 @@ ahc_pci_config(struct ahc_softc *ahc, st
+       ahc->chip |= AHC_PCI;
+       ahc->description = entry->name;
+-      ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
++      aic_power_state_change(ahc, AIC_POWER_STATE_D0);
+       error = ahc_pci_map_registers(ahc);
+       if (error != 0)
+@@ -812,7 +816,7 @@ ahc_pci_config(struct ahc_softc *ahc, st
+        */
+       ahc_intr_enable(ahc, FALSE);
+-      devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
++      devconfig = aic_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
+       /*
+        * If we need to support high memory, enable dual
+@@ -831,13 +835,13 @@ ahc_pci_config(struct ahc_softc *ahc, st
+       /* Ensure that pci error generation, a test feature, is disabled. */
+       devconfig |= PCIERRGENDIS;
+-      ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
++      aic_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
+       /* Ensure busmastering is enabled */
+-      command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
++      command = aic_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
+       command |= PCIM_CMD_BUSMASTEREN;
+-      ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
++      aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/2);
+       /* On all PCI adapters, we allow SCB paging */
+       ahc->flags |= AHC_PAGESCBS;
+@@ -877,7 +881,7 @@ ahc_pci_config(struct ahc_softc *ahc, st
+               scsiseq = 0;
+       }
+-      error = ahc_reset(ahc);
++      error = ahc_reset(ahc, /*reinit*/FALSE);
+       if (error != 0)
+               return (ENXIO);
+@@ -920,14 +924,14 @@ ahc_pci_config(struct ahc_softc *ahc, st
+       ahc_outb(ahc, DSCOMMAND0, dscommand0);
+       ahc->pci_cachesize =
+-          ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME,
++          aic_pci_read_config(ahc->dev_softc, CSIZE_LATTIME,
+                               /*bytes*/1) & CACHESIZE;
+       ahc->pci_cachesize *= 4;
+       if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0
+        && ahc->pci_cachesize == 4) {
+-              ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME,
++              aic_pci_write_config(ahc->dev_softc, CSIZE_LATTIME,
+                                    0, /*bytes*/1);
+               ahc->pci_cachesize = 0;
+       }
+@@ -939,7 +943,7 @@ ahc_pci_config(struct ahc_softc *ahc, st
+       if ((ahc->features & AHC_ULTRA) != 0) {
+               uint32_t devconfig;
+-              devconfig = ahc_pci_read_config(ahc->dev_softc,
++              devconfig = aic_pci_read_config(ahc->dev_softc,
+                                               DEVCONFIG, /*bytes*/4);
+               if ((devconfig & REXTVALID) == 0)
+                       ahc->features &= ~AHC_ULTRA;
+@@ -1005,11 +1009,11 @@ ahc_pci_config(struct ahc_softc *ahc, st
+        * that occur during runtime and resume events.
+        */
+       ahc->bus_softc.pci_softc.devconfig =
+-          ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
++          aic_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
+       ahc->bus_softc.pci_softc.command =
+-          ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1);
++          aic_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1);
+       ahc->bus_softc.pci_softc.csize_lattime =
+-          ahc_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1);
++          aic_pci_read_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1);
+       ahc->bus_softc.pci_softc.dscommand0 = ahc_inb(ahc, DSCOMMAND0);
+       ahc->bus_softc.pci_softc.dspcistatus = ahc_inb(ahc, DSPCISTATUS);
+       if ((ahc->features & AHC_DT) != 0) {
+@@ -1063,7 +1067,7 @@ ahc_ext_scbram_present(struct ahc_softc 
+       uint32_t devconfig;
+       chip = ahc->chip & AHC_CHIPID_MASK;
+-      devconfig = ahc_pci_read_config(ahc->dev_softc,
++      devconfig = aic_pci_read_config(ahc->dev_softc,
+                                       DEVCONFIG, /*bytes*/4);
+       single_user = (devconfig & MPORTMODE) != 0;
+@@ -1101,13 +1105,13 @@ ahc_scbram_config(struct ahc_softc *ahc,
+                * Set the SCB Base addr (highest address bit)
+                * depending on which channel we are.
+                */
+-              ahc_outb(ahc, SCBBADDR, ahc_get_pci_function(ahc->dev_softc));
++              ahc_outb(ahc, SCBBADDR, aic_get_pci_function(ahc->dev_softc));
+       }
+       ahc->flags &= ~AHC_LSCBS_ENABLED;
+       if (large)
+               ahc->flags |= AHC_LSCBS_ENABLED;
+-      devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
++      devconfig = aic_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4);
+       if ((ahc->features & AHC_ULTRA2) != 0) {
+               u_int dscommand0;
+@@ -1140,7 +1144,7 @@ ahc_scbram_config(struct ahc_softc *ahc,
+       else
+               devconfig &= ~EXTSCBPEN;
+-      ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
++      aic_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4);
+ }
+ /*
+@@ -1263,8 +1267,8 @@ ahc_pci_test_register_access(struct ahc_
+        * Enable PCI error interrupt status, but suppress NMIs
+        * generated by SERR raised due to target aborts.
+        */
+-      cmd = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
+-      ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
++      cmd = aic_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/2);
++      aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
+                            cmd & ~PCIM_CMD_SERRESPEN, /*bytes*/2);
+       /*
+@@ -1276,26 +1280,46 @@ ahc_pci_test_register_access(struct ahc_
+        * use for this test.
+        */
+       hcntrl = ahc_inb(ahc, HCNTRL);
++
+       if (hcntrl == 0xFF)
+               goto fail;
++      if ((hcntrl & CHIPRST) != 0) {
++              /*
++               * The chip has not been initialized since
++               * PCI/EISA/VLB bus reset.  Don't trust
++               * "left over BIOS data".
++               */
++              ahc->flags |= AHC_NO_BIOS_INIT;
++      }
++
+       /*
+        * Next create a situation where write combining
+        * or read prefetching could be initiated by the
+        * CPU or host bridge.  Our device does not support
+        * either, so look for data corruption and/or flagged
+-       * PCI errors.
++       * PCI errors.  First pause without causing another
++       * chip reset.
+        */
++      hcntrl &= ~CHIPRST;
+       ahc_outb(ahc, HCNTRL, hcntrl|PAUSE);
+       while (ahc_is_paused(ahc) == 0)
+               ;
++
++      /* Clear any PCI errors that occurred before our driver attached. */
++      status1 = aic_pci_read_config(ahc->dev_softc,
++                                    PCIR_STATUS + 1, /*bytes*/1);
++      aic_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
++                           status1, /*bytes*/1);
++      ahc_outb(ahc, CLRINT, CLRPARERR);
++
+       ahc_outb(ahc, SEQCTL, PERRORDIS);
+       ahc_outb(ahc, SCBPTR, 0);
+       ahc_outl(ahc, SCB_BASE, 0x5aa555aa);
+       if (ahc_inl(ahc, SCB_BASE) != 0x5aa555aa)
+               goto fail;
+-      status1 = ahc_pci_read_config(ahc->dev_softc,
++      status1 = aic_pci_read_config(ahc->dev_softc,
+                                     PCIR_STATUS + 1, /*bytes*/1);
+       if ((status1 & STA) != 0)
+               goto fail;
+@@ -1304,13 +1328,13 @@ ahc_pci_test_register_access(struct ahc_
+ fail:
+       /* Silently clear any latched errors. */
+-      status1 = ahc_pci_read_config(ahc->dev_softc,
++      status1 = aic_pci_read_config(ahc->dev_softc,
+                                     PCIR_STATUS + 1, /*bytes*/1);
+-      ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
++      aic_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
+                            status1, /*bytes*/1);
+       ahc_outb(ahc, CLRINT, CLRPARERR);
+       ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS);
+-      ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
++      aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND, cmd, /*bytes*/2);
+       return (error);
+ }
+@@ -1380,6 +1404,10 @@ check_extport(struct ahc_softc *ahc, u_i
+                       sd.sd_chip = C56_66;
+               }
+               ahc_release_seeprom(&sd);
++
++              /* Remember the SEEPROM type for later */
++              if (sd.sd_chip == C56_66)
++                      ahc->flags |= AHC_LARGE_SEEPROM;
+       }
+       if (!have_seeprom) {
+@@ -1565,12 +1593,12 @@ ahc_parse_pci_eeprom(struct ahc_softc *a
+               uint32_t devconfig;
+               /* Honor the STPWLEVEL settings */
+-              devconfig = ahc_pci_read_config(ahc->dev_softc,
++              devconfig = aic_pci_read_config(ahc->dev_softc,
+                                               DEVCONFIG, /*bytes*/4);
+               devconfig &= ~STPWLEVEL;
+               if ((sc->bios_control & CFSTPWLEVEL) != 0)
+                       devconfig |= STPWLEVEL;
+-              ahc_pci_write_config(ahc->dev_softc, DEVCONFIG,
++              aic_pci_write_config(ahc->dev_softc, DEVCONFIG,
+                                    devconfig, /*bytes*/4);
+       }
+       /* Set SCSICONF info */
+@@ -1883,10 +1911,10 @@ aic785X_cable_detect(struct ahc_softc *a
+       ahc_outb(ahc, SPIOCAP, spiocap);
+       ahc_outb(ahc, BRDCTL, BRDRW|BRDCS);
+       ahc_flush_device_writes(ahc);
+-      ahc_delay(500);
++      aic_delay(500);
+       ahc_outb(ahc, BRDCTL, 0);
+       ahc_flush_device_writes(ahc);
+-      ahc_delay(500);
++      aic_delay(500);
+       brdctl = ahc_inb(ahc, BRDCTL);
+       *internal50_present = (brdctl & BRDDAT5) ? 0 : 1;
+       *externalcable_present = (brdctl & BRDDAT6) ? 0 : 1;
+@@ -1912,7 +1940,7 @@ ahc_acquire_seeprom(struct ahc_softc *ah
+       SEEPROM_OUTB(sd, sd->sd_MS);
+       wait = 1000;  /* 1 second timeout in msec */
+       while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) {
+-              ahc_delay(1000);  /* delay 1 msec */
++              aic_delay(1000);  /* delay 1 msec */
+       }
+       if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) {
+               SEEPROM_OUTB(sd, 0); 
+@@ -1992,7 +2020,7 @@ ahc_pci_intr(struct ahc_softc *ahc)
+       if ((error & PCIERRSTAT) == 0)
+               return;
+-      status1 = ahc_pci_read_config(ahc->dev_softc,
++      status1 = aic_pci_read_config(ahc->dev_softc,
+                                     PCIR_STATUS + 1, /*bytes*/1);
+       printf("%s: PCI error Interrupt at seqaddr = 0x%x\n",
+@@ -2022,7 +2050,7 @@ ahc_pci_intr(struct ahc_softc *ahc)
+       }
+       /* Clear latched errors. */
+-      ahc_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
++      aic_pci_write_config(ahc->dev_softc, PCIR_STATUS + 1,
+                            status1, /*bytes*/1);
+       if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) {
+@@ -2083,7 +2111,7 @@ static int
+ ahc_pci_resume(struct ahc_softc *ahc)
+ {
+-      ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
++      aic_power_state_change(ahc, AIC_POWER_STATE_D0);
+       /*
+        * We assume that the OS has restored our register
+@@ -2091,11 +2119,11 @@ ahc_pci_resume(struct ahc_softc *ahc)
+        * that the OS doesn't know about and rely on our chip
+        * reset handler to handle the rest.
+        */
+-      ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4,
++      aic_pci_write_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4,
+                            ahc->bus_softc.pci_softc.devconfig);
+-      ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1,
++      aic_pci_write_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1,
+                            ahc->bus_softc.pci_softc.command);
+-      ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1,
++      aic_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, /*bytes*/1,
+                            ahc->bus_softc.pci_softc.csize_lattime);
+       if ((ahc->flags & AHC_HAS_TERM_LOGIC) != 0) {
+               struct  seeprom_descriptor sd;
+@@ -2118,7 +2146,7 @@ ahc_pci_resume(struct ahc_softc *ahc)
+ static int
+ ahc_aic785X_setup(struct ahc_softc *ahc)
+ {
+-      ahc_dev_softc_t pci;
++      aic_dev_softc_t pci;
+       uint8_t rev;
+       pci = ahc->dev_softc;
+@@ -2126,7 +2154,7 @@ ahc_aic785X_setup(struct ahc_softc *ahc)
+       ahc->chip = AHC_AIC7850;
+       ahc->features = AHC_AIC7850_FE;
+       ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
+-      rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
++      rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
+       if (rev >= 1)
+               ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
+       ahc->instruction_ram_size = 512;
+@@ -2136,7 +2164,7 @@ ahc_aic785X_setup(struct ahc_softc *ahc)
+ static int
+ ahc_aic7860_setup(struct ahc_softc *ahc)
+ {
+-      ahc_dev_softc_t pci;
++      aic_dev_softc_t pci;
+       uint8_t rev;
+       pci = ahc->dev_softc;
+@@ -2144,7 +2172,7 @@ ahc_aic7860_setup(struct ahc_softc *ahc)
+       ahc->chip = AHC_AIC7860;
+       ahc->features = AHC_AIC7860_FE;
+       ahc->bugs |= AHC_TMODE_WIDEODD_BUG|AHC_CACHETHEN_BUG|AHC_PCI_MWI_BUG;
+-      rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
++      rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
+       if (rev >= 1)
+               ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
+       ahc->instruction_ram_size = 512;
+@@ -2211,7 +2239,7 @@ ahc_aha494X_setup(struct ahc_softc *ahc)
+ static int
+ ahc_aic7880_setup(struct ahc_softc *ahc)
+ {
+-      ahc_dev_softc_t pci;
++      aic_dev_softc_t pci;
+       uint8_t rev;
+       pci = ahc->dev_softc;
+@@ -2219,7 +2247,7 @@ ahc_aic7880_setup(struct ahc_softc *ahc)
+       ahc->chip = AHC_AIC7880;
+       ahc->features = AHC_AIC7880_FE;
+       ahc->bugs |= AHC_TMODE_WIDEODD_BUG;
+-      rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
++      rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
+       if (rev >= 1) {
+               ahc->bugs |= AHC_PCI_2_1_RETRY_BUG;
+       } else {
+@@ -2262,7 +2290,7 @@ ahc_aha398XU_setup(struct ahc_softc *ahc
+ static int
+ ahc_aic7890_setup(struct ahc_softc *ahc)
+ {
+-      ahc_dev_softc_t pci;
++      aic_dev_softc_t pci;
+       uint8_t rev;
+       pci = ahc->dev_softc;
+@@ -2270,7 +2298,7 @@ ahc_aic7890_setup(struct ahc_softc *ahc)
+       ahc->chip = AHC_AIC7890;
+       ahc->features = AHC_AIC7890_FE;
+       ahc->flags |= AHC_NEWEEPROM_FMT;
+-      rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
++      rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
+       if (rev == 0)
+               ahc->bugs |= AHC_AUTOFLUSH_BUG|AHC_CACHETHEN_BUG;
+       ahc->instruction_ram_size = 768;
+@@ -2293,15 +2321,15 @@ ahc_aic7892_setup(struct ahc_softc *ahc)
+ static int
+ ahc_aic7895_setup(struct ahc_softc *ahc)
+ {
+-      ahc_dev_softc_t pci;
++      aic_dev_softc_t pci;
+       uint8_t rev;
+       pci = ahc->dev_softc;
+-      ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
++      ahc->channel = aic_get_pci_function(pci) == 1 ? 'B' : 'A';
+       /*
+        * The 'C' revision of the aic7895 has a few additional features.
+        */
+-      rev = ahc_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
++      rev = aic_pci_read_config(pci, PCIR_REVID, /*bytes*/1);
+       if (rev >= 4) {
+               ahc->chip = AHC_AIC7895C;
+               ahc->features = AHC_AIC7895C_FE;
+@@ -2317,9 +2345,9 @@ ahc_aic7895_setup(struct ahc_softc *ahc)
+                * we have.  Disabling MWI reduces performance, so
+                * turn it on again.
+                */
+-              command = ahc_pci_read_config(pci, PCIR_COMMAND, /*bytes*/1);
++              command = aic_pci_read_config(pci, PCIR_COMMAND, /*bytes*/1);
+               command |= PCIM_CMD_MWRICEN;
+-              ahc_pci_write_config(pci, PCIR_COMMAND, command, /*bytes*/1);
++              aic_pci_write_config(pci, PCIR_COMMAND, command, /*bytes*/1);
+               ahc->bugs |= AHC_PCI_MWI_BUG;
+       }
+       /*
+@@ -2336,10 +2364,10 @@ ahc_aic7895_setup(struct ahc_softc *ahc)
+        * Cachesize must also be zero due to stray DAC
+        * problem when sitting behind some bridges.
+        */
+-      ahc_pci_write_config(pci, CSIZE_LATTIME, 0, /*bytes*/1);
+-      devconfig = ahc_pci_read_config(pci, DEVCONFIG, /*bytes*/1);
++      aic_pci_write_config(pci, CSIZE_LATTIME, 0, /*bytes*/1);
++      devconfig = aic_pci_read_config(pci, DEVCONFIG, /*bytes*/1);
+       devconfig |= MRDCEN;
+-      ahc_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1);
++      aic_pci_write_config(pci, DEVCONFIG, devconfig, /*bytes*/1);
+ #endif
+       ahc->flags |= AHC_NEWEEPROM_FMT;
+       ahc->instruction_ram_size = 512;
+@@ -2349,10 +2377,10 @@ ahc_aic7895_setup(struct ahc_softc *ahc)
+ static int
+ ahc_aic7896_setup(struct ahc_softc *ahc)
+ {
+-      ahc_dev_softc_t pci;
++      aic_dev_softc_t pci;
+       pci = ahc->dev_softc;
+-      ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
++      ahc->channel = aic_get_pci_function(pci) == 1 ? 'B' : 'A';
+       ahc->chip = AHC_AIC7896;
+       ahc->features = AHC_AIC7896_FE;
+       ahc->flags |= AHC_NEWEEPROM_FMT;
+@@ -2364,10 +2392,10 @@ ahc_aic7896_setup(struct ahc_softc *ahc)
+ static int
+ ahc_aic7899_setup(struct ahc_softc *ahc)
+ {
+-      ahc_dev_softc_t pci;
++      aic_dev_softc_t pci;
+       pci = ahc->dev_softc;
+-      ahc->channel = ahc_get_pci_function(pci) == 1 ? 'B' : 'A';
++      ahc->channel = aic_get_pci_function(pci) == 1 ? 'B' : 'A';
+       ahc->chip = AHC_AIC7899;
+       ahc->features = AHC_AIC7899_FE;
+       ahc->flags |= AHC_NEWEEPROM_FMT;
+@@ -2398,10 +2426,10 @@ ahc_raid_setup(struct ahc_softc *ahc)
+ static int
+ ahc_aha394XX_setup(struct ahc_softc *ahc)
+ {
+-      ahc_dev_softc_t pci;
++      aic_dev_softc_t pci;
+       pci = ahc->dev_softc;
+-      switch (ahc_get_pci_slot(pci)) {
++      switch (aic_get_pci_slot(pci)) {
+       case AHC_394X_SLOT_CHANNEL_A:
+               ahc->channel = 'A';
+               break;
+@@ -2411,7 +2439,7 @@ ahc_aha394XX_setup(struct ahc_softc *ahc
+       default:
+               printf("adapter at unexpected slot %d\n"
+                      "unable to map to a channel\n",
+-                     ahc_get_pci_slot(pci));
++                     aic_get_pci_slot(pci));
+               ahc->channel = 'A';
+       }
+       return (0);
+@@ -2420,10 +2448,10 @@ ahc_aha394XX_setup(struct ahc_softc *ahc
+ static int
+ ahc_aha398XX_setup(struct ahc_softc *ahc)
+ {
+-      ahc_dev_softc_t pci;
++      aic_dev_softc_t pci;
+       pci = ahc->dev_softc;
+-      switch (ahc_get_pci_slot(pci)) {
++      switch (aic_get_pci_slot(pci)) {
+       case AHC_398X_SLOT_CHANNEL_A:
+               ahc->channel = 'A';
+               break;
+@@ -2436,7 +2464,7 @@ ahc_aha398XX_setup(struct ahc_softc *ahc
+       default:
+               printf("adapter at unexpected slot %d\n"
+                      "unable to map to a channel\n",
+-                     ahc_get_pci_slot(pci));
++                     aic_get_pci_slot(pci));
+               ahc->channel = 'A';
+               break;
+       }
+@@ -2447,10 +2475,10 @@ ahc_aha398XX_setup(struct ahc_softc *ahc
+ static int
+ ahc_aha494XX_setup(struct ahc_softc *ahc)
+ {
+-      ahc_dev_softc_t pci;
++      aic_dev_softc_t pci;
+       pci = ahc->dev_softc;
+-      switch (ahc_get_pci_slot(pci)) {
++      switch (aic_get_pci_slot(pci)) {
+       case AHC_494X_SLOT_CHANNEL_A:
+               ahc->channel = 'A';
+               break;
+@@ -2466,7 +2494,7 @@ ahc_aha494XX_setup(struct ahc_softc *ahc
+       default:
+               printf("adapter at unexpected slot %d\n"
+                      "unable to map to a channel\n",
+-                     ahc_get_pci_slot(pci));
++                     aic_get_pci_slot(pci));
+               ahc->channel = 'A';
+       }
+       ahc->flags |= AHC_LARGE_SEEPROM;
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx_proc.c    2003-06-14 12:17:56.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx_proc.c     2003-12-28 23:21:40.000000000 -0800
+@@ -37,7 +37,7 @@
+  * String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
+  * sym driver.
+  *
+- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#27 $
++ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_proc.c#32 $
+  */
+ #include "aic7xxx_osm.h"
+ #include "aic7xxx_inline.h"
+@@ -50,7 +50,7 @@ static void  ahc_dump_target_state(struct
+                                     u_int our_id, char channel,
+                                     u_int target_id, u_int target_offset);
+ static void   ahc_dump_device_state(struct info_str *info,
+-                                    struct ahc_linux_device *dev);
++                                    struct aic_linux_device *dev);
+ static int    ahc_proc_write_seeprom(struct ahc_softc *ahc,
+                                      char *buffer, int length);
+@@ -141,7 +141,7 @@ ahc_dump_target_state(struct ahc_softc *
+                     u_int our_id, char channel, u_int target_id,
+                     u_int target_offset)
+ {
+-      struct  ahc_linux_target *targ;
++      struct  aic_linux_target *targ;
+       struct  ahc_initiator_tinfo *tinfo;
+       struct  ahc_tmode_tstate *tstate;
+       int     lun;
+@@ -163,7 +163,7 @@ ahc_dump_target_state(struct ahc_softc *
+       ahc_format_transinfo(info, &tinfo->curr);
+       for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
+-              struct ahc_linux_device *dev;
++              struct aic_linux_device *dev;
+               dev = targ->devices[lun];
+@@ -175,7 +175,7 @@ ahc_dump_target_state(struct ahc_softc *
+ }
+ static void
+-ahc_dump_device_state(struct info_str *info, struct ahc_linux_device *dev)
++ahc_dump_device_state(struct info_str *info, struct aic_linux_device *dev)
+ {
+       copy_info(info, "\tChannel %c Target %d Lun %d Settings\n",
+                 dev->target->channel + 'A', dev->target->target, dev->lun);
+@@ -204,7 +204,8 @@ ahc_proc_write_seeprom(struct ahc_softc 
+               ahc_pause(ahc);
+       if (length != sizeof(struct seeprom_config)) {
+-              printf("ahc_proc_write_seeprom: incorrect buffer size\n");
++              printf("ahc_proc_write_seeprom: incorrect buffer size %d\n",
++                     length);
+               goto done;
+       }
+@@ -215,7 +216,7 @@ ahc_proc_write_seeprom(struct ahc_softc 
+       }
+       sd.sd_ahc = ahc;
+-#if AHC_PCI_CONFIG > 0
++#if AIC_PCI_CONFIG > 0
+       if ((ahc->chip & AHC_PCI) != 0) {
+               sd.sd_control_offset = SEECTL;
+               sd.sd_status_offset = SEECTL;
+@@ -271,7 +272,7 @@ ahc_proc_write_seeprom(struct ahc_softc 
+                                 sizeof(struct seeprom_config)/2);
+               ahc_read_seeprom(&sd, (uint16_t *)ahc->seep_config,
+                                start_addr, sizeof(struct seeprom_config)/2);
+-#if AHC_PCI_CONFIG > 0
++#if AIC_PCI_CONFIG > 0
+               if ((ahc->chip & AHC_VL) == 0)
+                       ahc_release_seeprom(&sd);
+ #endif
+@@ -289,8 +290,13 @@ done:
+  * Return information to handle /proc support for the driver.
+  */
+ int
+-ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset,
+-                int length, int inout)
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++ahc_linux_proc_info(char *buffer, char **start, off_t offset,
++                  int length, int hostno, int inout)
++#else
++ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
++                  off_t offset, int length, int inout)
++#endif
+ {
+       struct  ahc_softc *ahc;
+       struct  info_str info;
+@@ -302,10 +308,14 @@ ahc_linux_proc_info(struct Scsi_Host *sh
+       retval = -EINVAL;
+       ahc_list_lock(&s);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+       TAILQ_FOREACH(ahc, &ahc_tailq, links) {
+-              if (ahc->platform_data->host == shost)
++              if (ahc->platform_data->host->host_no == hostno)
+                       break;
+       }
++#else
++      ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata);
++#endif
+       if (ahc == NULL)
+               goto done;
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx.reg       2003-06-14 12:18:51.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx.reg        2003-12-28 23:21:40.000000000 -0800
+@@ -39,7 +39,7 @@
+  *
+  * $FreeBSD$
+  */
+-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $"
++VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#40 $"
+ /*
+  * This file is processed by the aic7xxx_asm utility for use in assembling
+@@ -1306,7 +1306,6 @@ scratch_ram {
+        */
+       MWI_RESIDUAL {
+               size            1
+-              alias   TARG_IMMEDIATE_SCB
+       }
+       /*
+        * SCBID of the next SCB to be started by the controller.
+@@ -1461,6 +1460,7 @@ scratch_ram {
+        */
+       LAST_MSG {
+               size            1
++              alias   TARG_IMMEDIATE_SCB
+       }
+       /*
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped     2003-06-14 12:18:24.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped      2003-12-28 23:21:40.000000000 -0800
+@@ -2,8 +2,8 @@
+  * DO NOT EDIT - This file is automatically generated
+  *             from the following source files:
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $
+- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#58 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#40 $
+  */
+ typedef int (ahc_reg_print_t)(u_int, u_int *, u_int);
+ typedef struct ahc_reg_parse_entry {
+@@ -1298,7 +1298,6 @@ ahc_reg_print_t ahc_sg_cache_pre_print;
+ #define       CMDSIZE_TABLE_TAIL              0x34
+ #define       MWI_RESIDUAL                    0x38
+-#define       TARG_IMMEDIATE_SCB              0x38
+ #define       NEXT_QUEUED_SCB                 0x39
+@@ -1380,6 +1379,7 @@ ahc_reg_print_t ahc_sg_cache_pre_print;
+ #define       RETURN_2                        0x52
+ #define       LAST_MSG                        0x53
++#define       TARG_IMMEDIATE_SCB              0x53
+ #define       SCSISEQ_TEMPLATE                0x54
+ #define               ENSELO                  0x40
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped       2003-06-14 12:18:22.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped        2003-12-28 23:21:40.000000000 -0800
+@@ -2,8 +2,8 @@
+  * DO NOT EDIT - This file is automatically generated
+  *             from the following source files:
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $
+- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#38 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#58 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#40 $
+  */
+ #include "aic7xxx_osm.h"
+@@ -747,13 +747,6 @@ ahc_scsiseq_template_print(u_int regvalu
+           0x54, regvalue, cur_col, wrap));
+ }
+-int
+-ahc_data_count_odd_print(u_int regvalue, u_int *cur_col, u_int wrap)
+-{
+-      return (ahc_print_register(NULL, 0, "DATA_COUNT_ODD",
+-          0x55, regvalue, cur_col, wrap));
+-}
+-
+ static ahc_reg_parse_entry_t HA_274_BIOSGLOBAL_parse_table[] = {
+       { "HA_274_EXTENDED_TRANS",0x01, 0x01 }
+ };
+@@ -1416,13 +1409,14 @@ ahc_scb_scsiid_print(u_int regvalue, u_i
+ }
+ static ahc_reg_parse_entry_t SCB_LUN_parse_table[] = {
+-      { "LID",                0xff, 0xff }
++      { "SCB_XFERLEN_ODD",    0x80, 0x80 },
++      { "LID",                0x3f, 0x3f }
+ };
+ int
+ ahc_scb_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+-      return (ahc_print_register(SCB_LUN_parse_table, 1, "SCB_LUN",
++      return (ahc_print_register(SCB_LUN_parse_table, 2, "SCB_LUN",
+           0xba, regvalue, cur_col, wrap));
+ }
+@@ -1662,28 +1656,26 @@ ahc_dff_thrsh_print(u_int regvalue, u_in
+ static ahc_reg_parse_entry_t SG_CACHE_SHADOW_parse_table[] = {
+       { "LAST_SEG_DONE",      0x01, 0x01 },
+       { "LAST_SEG",           0x02, 0x02 },
+-      { "ODD_SEG",            0x04, 0x04 },
+       { "SG_ADDR_MASK",       0xf8, 0xf8 }
+ };
+ int
+ ahc_sg_cache_shadow_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+-      return (ahc_print_register(SG_CACHE_SHADOW_parse_table, 4, "SG_CACHE_SHADOW",
++      return (ahc_print_register(SG_CACHE_SHADOW_parse_table, 3, "SG_CACHE_SHADOW",
+           0xfc, regvalue, cur_col, wrap));
+ }
+ static ahc_reg_parse_entry_t SG_CACHE_PRE_parse_table[] = {
+       { "LAST_SEG_DONE",      0x01, 0x01 },
+       { "LAST_SEG",           0x02, 0x02 },
+-      { "ODD_SEG",            0x04, 0x04 },
+       { "SG_ADDR_MASK",       0xf8, 0xf8 }
+ };
+ int
+ ahc_sg_cache_pre_print(u_int regvalue, u_int *cur_col, u_int wrap)
+ {
+-      return (ahc_print_register(SG_CACHE_PRE_parse_table, 4, "SG_CACHE_PRE",
++      return (ahc_print_register(SG_CACHE_PRE_parse_table, 3, "SG_CACHE_PRE",
+           0xfc, regvalue, cur_col, wrap));
+ }
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx.seq       2003-06-14 12:18:30.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx.seq        2003-12-28 23:21:40.000000000 -0800
+@@ -40,7 +40,7 @@
+  * $FreeBSD$
+  */
+-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $"
++VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#58 $"
+ PATCH_ARG_LIST = "struct ahc_softc *ahc"
+ PREFIX = "ahc_"
+@@ -679,6 +679,7 @@ await_busfree:
+               clr     SCSIBUSL;       /* Prevent bit leakage durint SELTO */
+       }
+       and     SXFRCTL0, ~SPIOEN;
++      mvi     SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT;
+       test    SSTAT1,REQINIT|BUSFREE  jz .;
+       test    SSTAT1, BUSFREE jnz poll_for_work;
+       mvi     MISSED_BUSFREE call set_seqint;
+@@ -1097,7 +1098,7 @@ ultra2_dmahalt:
+               test    SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz dma_mid_sg;
+               if ((ahc->flags & AHC_TARGETROLE) != 0) {
+                       test    SSTAT0, TARGET jz dma_last_sg;
+-                      if ((ahc->flags & AHC_TMODE_WIDEODD_BUG) != 0) {
++                      if ((ahc->bugs & AHC_TMODE_WIDEODD_BUG) != 0) {
+                               test    DMAPARAMS, DIRECTION jz dma_mid_sg;
+                       }
+               }
+--- linux-2.6.0/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped     2003-06-14 12:18:52.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped      2003-12-28 23:21:40.000000000 -0800
+@@ -2,13 +2,13 @@
+  * DO NOT EDIT - This file is automatically generated
+  *             from the following source files:
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $
+- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#58 $
++ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#40 $
+  */
+ static uint8_t seqprog[] = {
+       0xb2, 0x00, 0x00, 0x08,
+       0xf7, 0x11, 0x22, 0x08,
+-      0x00, 0x65, 0xec, 0x59,
++      0x00, 0x65, 0xee, 0x59,
+       0xf7, 0x01, 0x02, 0x08,
+       0xff, 0x6a, 0x24, 0x08,
+       0x40, 0x00, 0x40, 0x68,
+@@ -21,15 +21,15 @@ static uint8_t seqprog[] = {
+       0x01, 0x4d, 0xc8, 0x30,
+       0x00, 0x4c, 0x12, 0x70,
+       0x01, 0x39, 0xa2, 0x30,
+-      0x00, 0x6a, 0xc0, 0x5e,
++      0x00, 0x6a, 0xc2, 0x5e,
+       0x01, 0x51, 0x20, 0x31,
+       0x01, 0x57, 0xae, 0x00,
+       0x0d, 0x6a, 0x76, 0x00,
+-      0x00, 0x51, 0x12, 0x5e,
++      0x00, 0x51, 0x14, 0x5e,
+       0x01, 0x51, 0xc8, 0x30,
+       0x00, 0x39, 0xc8, 0x60,
+       0x00, 0xbb, 0x30, 0x70,
+-      0xc1, 0x6a, 0xd8, 0x5e,
++      0xc1, 0x6a, 0xda, 0x5e,
+       0x01, 0xbf, 0x72, 0x30,
+       0x01, 0x40, 0x7e, 0x31,
+       0x01, 0x90, 0x80, 0x30,
+@@ -49,10 +49,10 @@ static uint8_t seqprog[] = {
+       0x08, 0x6a, 0x78, 0x00,
+       0x01, 0x50, 0xc8, 0x30,
+       0xe0, 0x6a, 0xcc, 0x00,
+-      0x48, 0x6a, 0xfc, 0x5d,
++      0x48, 0x6a, 0xfe, 0x5d,
+       0x01, 0x6a, 0xdc, 0x01,
+       0x88, 0x6a, 0xcc, 0x00,
+-      0x48, 0x6a, 0xfc, 0x5d,
++      0x48, 0x6a, 0xfe, 0x5d,
+       0x01, 0x6a, 0x26, 0x01,
+       0xf0, 0x19, 0x7a, 0x08,
+       0x0f, 0x18, 0xc8, 0x08,
+@@ -93,7 +93,7 @@ static uint8_t seqprog[] = {
+       0x00, 0x65, 0x20, 0x41,
+       0x02, 0x57, 0xae, 0x00,
+       0x00, 0x65, 0x9e, 0x40,
+-      0x61, 0x6a, 0xd8, 0x5e,
++      0x61, 0x6a, 0xda, 0x5e,
+       0x08, 0x51, 0x20, 0x71,
+       0x02, 0x0b, 0xb2, 0x78,
+       0x00, 0x65, 0xae, 0x40,
+@@ -106,7 +106,7 @@ static uint8_t seqprog[] = {
+       0x80, 0x3d, 0x7a, 0x00,
+       0x20, 0x6a, 0x16, 0x00,
+       0x00, 0x65, 0xcc, 0x41,
+-      0x00, 0x65, 0xb2, 0x5e,
++      0x00, 0x65, 0xb4, 0x5e,
+       0x00, 0x65, 0x12, 0x40,
+       0x20, 0x11, 0xd2, 0x68,
+       0x20, 0x6a, 0x18, 0x00,
+@@ -140,27 +140,27 @@ static uint8_t seqprog[] = {
+       0x80, 0x0b, 0xc4, 0x79,
+       0x12, 0x01, 0x02, 0x00,
+       0x01, 0xab, 0xac, 0x30,
+-      0xe4, 0x6a, 0x6e, 0x5d,
++      0xe4, 0x6a, 0x70, 0x5d,
+       0x40, 0x6a, 0x16, 0x00,
+-      0x80, 0x3e, 0x84, 0x5d,
++      0x80, 0x3e, 0x86, 0x5d,
+       0x20, 0xb8, 0x18, 0x79,
+-      0x20, 0x6a, 0x84, 0x5d,
+-      0x00, 0xab, 0x84, 0x5d,
++      0x20, 0x6a, 0x86, 0x5d,
++      0x00, 0xab, 0x86, 0x5d,
+       0x01, 0xa9, 0x78, 0x30,
+       0x10, 0xb8, 0x20, 0x79,
+-      0xe4, 0x6a, 0x6e, 0x5d,
++      0xe4, 0x6a, 0x70, 0x5d,
+       0x00, 0x65, 0xae, 0x40,
+       0x10, 0x03, 0x3c, 0x69,
+       0x08, 0x3c, 0x5a, 0x69,
+       0x04, 0x3c, 0x92, 0x69,
+       0x02, 0x3c, 0x98, 0x69,
+       0x01, 0x3c, 0x44, 0x79,
+-      0xff, 0x6a, 0x70, 0x00,
++      0xff, 0x6a, 0xa6, 0x00,
+       0x00, 0x65, 0xa4, 0x59,
+-      0x00, 0x6a, 0xc0, 0x5e,
+-      0xff, 0x38, 0x30, 0x71,
++      0x00, 0x6a, 0xc2, 0x5e,
++      0xff, 0x53, 0x30, 0x71,
+       0x0d, 0x6a, 0x76, 0x00,
+-      0x00, 0x38, 0x12, 0x5e,
++      0x00, 0x53, 0x14, 0x5e,
+       0x00, 0x65, 0xea, 0x58,
+       0x12, 0x01, 0x02, 0x00,
+       0x00, 0x65, 0x18, 0x41,
+@@ -168,10 +168,10 @@ static uint8_t seqprog[] = {
+       0x00, 0x65, 0xf2, 0x58,
+       0xfd, 0x57, 0xae, 0x08,
+       0x00, 0x65, 0xae, 0x40,
+-      0xe4, 0x6a, 0x6e, 0x5d,
++      0xe4, 0x6a, 0x70, 0x5d,
+       0x20, 0x3c, 0x4a, 0x79,
+-      0x02, 0x6a, 0x84, 0x5d,
+-      0x04, 0x6a, 0x84, 0x5d,
++      0x02, 0x6a, 0x86, 0x5d,
++      0x04, 0x6a, 0x86, 0x5d,
+       0x01, 0x03, 0x4c, 0x69,
+       0xf7, 0x11, 0x22, 0x08,
+       0xff, 0x6a, 0x24, 0x08,
+@@ -182,13 +182,13 @@ static uint8_t seqprog[] = {
+       0x80, 0x86, 0xc8, 0x08,
+       0x01, 0x4f, 0xc8, 0x30,
+       0x00, 0x50, 0x6c, 0x61,
+-      0xc4, 0x6a, 0x6e, 0x5d,
++      0xc4, 0x6a, 0x70, 0x5d,
+       0x40, 0x3c, 0x68, 0x79,
+-      0x28, 0x6a, 0x84, 0x5d,
++      0x28, 0x6a, 0x86, 0x5d,
+       0x00, 0x65, 0x4c, 0x41,
+-      0x08, 0x6a, 0x84, 0x5d,
++      0x08, 0x6a, 0x86, 0x5d,
+       0x00, 0x65, 0x4c, 0x41,
+-      0x84, 0x6a, 0x6e, 0x5d,
++      0x84, 0x6a, 0x70, 0x5d,
+       0x00, 0x65, 0xf2, 0x58,
+       0x01, 0x66, 0xc8, 0x30,
+       0x01, 0x64, 0xd8, 0x31,
+@@ -208,16 +208,16 @@ static uint8_t seqprog[] = {
+       0xf7, 0x3c, 0x78, 0x08,
+       0x00, 0x65, 0x20, 0x41,
+       0x40, 0xaa, 0x7e, 0x10,
+-      0x04, 0xaa, 0x6e, 0x5d,
+-      0x00, 0x65, 0x56, 0x42,
+-      0xc4, 0x6a, 0x6e, 0x5d,
++      0x04, 0xaa, 0x70, 0x5d,
++      0x00, 0x65, 0x58, 0x42,
++      0xc4, 0x6a, 0x70, 0x5d,
+       0xc0, 0x6a, 0x7e, 0x00,
+-      0x00, 0xa8, 0x84, 0x5d,
++      0x00, 0xa8, 0x86, 0x5d,
+       0xe4, 0x6a, 0x06, 0x00,
+-      0x00, 0x6a, 0x84, 0x5d,
++      0x00, 0x6a, 0x86, 0x5d,
+       0x00, 0x65, 0x4c, 0x41,
+       0x10, 0x3c, 0xa8, 0x69,
+-      0x00, 0xbb, 0x8a, 0x44,
++      0x00, 0xbb, 0x8c, 0x44,
+       0x18, 0x6a, 0xda, 0x01,
+       0x01, 0x69, 0xd8, 0x31,
+       0x1c, 0x6a, 0xd0, 0x01,
+@@ -227,31 +227,32 @@ static uint8_t seqprog[] = {
+       0x01, 0x93, 0x26, 0x01,
+       0x03, 0x6a, 0x2a, 0x01,
+       0x01, 0x69, 0x32, 0x31,
+-      0x1c, 0x6a, 0xe0, 0x5d,
++      0x1c, 0x6a, 0xe2, 0x5d,
+       0x0a, 0x93, 0x26, 0x01,
+-      0x00, 0x65, 0xa8, 0x5e,
++      0x00, 0x65, 0xaa, 0x5e,
+       0x01, 0x50, 0xa0, 0x18,
+       0x02, 0x6a, 0x22, 0x05,
+       0x1a, 0x01, 0x02, 0x00,
+       0x80, 0x6a, 0x74, 0x00,
+       0x40, 0x6a, 0x78, 0x00,
+       0x40, 0x6a, 0x16, 0x00,
+-      0x00, 0x65, 0xd8, 0x5d,
++      0x00, 0x65, 0xda, 0x5d,
+       0x01, 0x3f, 0xc8, 0x30,
+-      0xbf, 0x64, 0x56, 0x7a,
+-      0x80, 0x64, 0x9e, 0x73,
+-      0xa0, 0x64, 0x00, 0x74,
+-      0xc0, 0x64, 0xf4, 0x73,
+-      0xe0, 0x64, 0x30, 0x74,
+-      0x01, 0x6a, 0xd8, 0x5e,
++      0xbf, 0x64, 0x58, 0x7a,
++      0x80, 0x64, 0xa0, 0x73,
++      0xa0, 0x64, 0x02, 0x74,
++      0xc0, 0x64, 0xf6, 0x73,
++      0xe0, 0x64, 0x32, 0x74,
++      0x01, 0x6a, 0xda, 0x5e,
+       0x00, 0x65, 0xcc, 0x41,
+       0xf7, 0x11, 0x22, 0x08,
+       0x01, 0x06, 0xd4, 0x30,
+       0xff, 0x6a, 0x24, 0x08,
+       0xf7, 0x01, 0x02, 0x08,
+-      0x09, 0x0c, 0xe6, 0x79,
++      0xc0, 0x6a, 0x78, 0x00,
++      0x09, 0x0c, 0xe8, 0x79,
+       0x08, 0x0c, 0x04, 0x68,
+-      0xb1, 0x6a, 0xd8, 0x5e,
++      0xb1, 0x6a, 0xda, 0x5e,
+       0xff, 0x6a, 0x26, 0x09,
+       0x12, 0x01, 0x02, 0x00,
+       0x02, 0x6a, 0x08, 0x30,
+@@ -264,29 +265,29 @@ static uint8_t seqprog[] = {
+       0x00, 0xa5, 0x4a, 0x21,
+       0x00, 0xa6, 0x4c, 0x21,
+       0x00, 0xa7, 0x4e, 0x25,
+-      0x08, 0xeb, 0xdc, 0x7e,
+-      0x80, 0xeb, 0x06, 0x7a,
++      0x08, 0xeb, 0xde, 0x7e,
++      0x80, 0xeb, 0x08, 0x7a,
+       0xff, 0x6a, 0xd6, 0x09,
+-      0x08, 0xeb, 0x0a, 0x6a,
++      0x08, 0xeb, 0x0c, 0x6a,
+       0xff, 0x6a, 0xd4, 0x0c,
+-      0x80, 0xa3, 0xdc, 0x6e,
+-      0x88, 0xeb, 0x20, 0x72,
+-      0x08, 0xeb, 0xdc, 0x6e,
+-      0x04, 0xea, 0x24, 0xe2,
+-      0x08, 0xee, 0xdc, 0x6e,
++      0x80, 0xa3, 0xde, 0x6e,
++      0x88, 0xeb, 0x22, 0x72,
++      0x08, 0xeb, 0xde, 0x6e,
++      0x04, 0xea, 0x26, 0xe2,
++      0x08, 0xee, 0xde, 0x6e,
+       0x04, 0x6a, 0xd0, 0x81,
+       0x05, 0xa4, 0xc0, 0x89,
+       0x03, 0xa5, 0xc2, 0x31,
+       0x09, 0x6a, 0xd6, 0x05,
+-      0x00, 0x65, 0x08, 0x5a,
++      0x00, 0x65, 0x0a, 0x5a,
+       0x06, 0xa4, 0xd4, 0x89,
+-      0x80, 0x94, 0xdc, 0x7e,
++      0x80, 0x94, 0xde, 0x7e,
+       0x07, 0xe9, 0x10, 0x31,
+       0x01, 0xe9, 0x46, 0x31,
+-      0x00, 0xa3, 0xba, 0x5e,
+-      0x00, 0x65, 0xfa, 0x59,
++      0x00, 0xa3, 0xbc, 0x5e,
++      0x00, 0x65, 0xfc, 0x59,
+       0x01, 0xa4, 0xca, 0x30,
+-      0x80, 0xa3, 0x34, 0x7a,
++      0x80, 0xa3, 0x36, 0x7a,
+       0x02, 0x65, 0xca, 0x00,
+       0x01, 0x65, 0xf8, 0x31,
+       0x80, 0x93, 0x26, 0x01,
+@@ -294,162 +295,162 @@ static uint8_t seqprog[] = {
+       0x01, 0x8c, 0xc8, 0x30,
+       0x00, 0x88, 0xc8, 0x18,
+       0x02, 0x64, 0xc8, 0x88,
+-      0xff, 0x64, 0xdc, 0x7e,
+-      0xff, 0x8d, 0x4a, 0x6a,
+-      0xff, 0x8e, 0x4a, 0x6a,
++      0xff, 0x64, 0xde, 0x7e,
++      0xff, 0x8d, 0x4c, 0x6a,
++      0xff, 0x8e, 0x4c, 0x6a,
+       0x03, 0x8c, 0xd4, 0x98,
+-      0x00, 0x65, 0xdc, 0x56,
++      0x00, 0x65, 0xde, 0x56,
+       0x01, 0x64, 0x70, 0x30,
+       0xff, 0x64, 0xc8, 0x10,
+       0x01, 0x64, 0xc8, 0x18,
+       0x00, 0x8c, 0x18, 0x19,
+       0xff, 0x8d, 0x1a, 0x21,
+       0xff, 0x8e, 0x1c, 0x25,
+-      0xc0, 0x3c, 0x5a, 0x7a,
+-      0x21, 0x6a, 0xd8, 0x5e,
++      0xc0, 0x3c, 0x5c, 0x7a,
++      0x21, 0x6a, 0xda, 0x5e,
+       0xa8, 0x6a, 0x76, 0x00,
+       0x79, 0x6a, 0x76, 0x00,
+-      0x40, 0x3f, 0x62, 0x6a,
++      0x40, 0x3f, 0x64, 0x6a,
+       0x04, 0x3b, 0x76, 0x00,
+       0x04, 0x6a, 0xd4, 0x81,
+-      0x20, 0x3c, 0x6a, 0x7a,
+-      0x51, 0x6a, 0xd8, 0x5e,
+-      0x00, 0x65, 0x82, 0x42,
++      0x20, 0x3c, 0x6c, 0x7a,
++      0x51, 0x6a, 0xda, 0x5e,
++      0x00, 0x65, 0x84, 0x42,
+       0x20, 0x3c, 0x78, 0x00,
+-      0x00, 0xb3, 0xba, 0x5e,
++      0x00, 0xb3, 0xbc, 0x5e,
+       0x07, 0xac, 0x10, 0x31,
+       0x05, 0xb3, 0x46, 0x31,
+       0x88, 0x6a, 0xcc, 0x00,
+-      0xac, 0x6a, 0xee, 0x5d,
++      0xac, 0x6a, 0xf0, 0x5d,
+       0xa3, 0x6a, 0xcc, 0x00,
+-      0xb3, 0x6a, 0xf2, 0x5d,
+-      0x00, 0x65, 0x3a, 0x5a,
++      0xb3, 0x6a, 0xf4, 0x5d,
++      0x00, 0x65, 0x3c, 0x5a,
+       0xfd, 0xa4, 0x48, 0x09,
+       0x03, 0x8c, 0x10, 0x30,
+-      0x00, 0x65, 0xe6, 0x5d,
+-      0x01, 0xa4, 0x94, 0x7a,
++      0x00, 0x65, 0xe8, 0x5d,
++      0x01, 0xa4, 0x96, 0x7a,
+       0x04, 0x3b, 0x76, 0x08,
+       0x01, 0x3b, 0x26, 0x31,
+       0x80, 0x02, 0x04, 0x00,
+-      0x10, 0x0c, 0x8a, 0x7a,
+-      0x03, 0x9e, 0x8c, 0x6a,
++      0x10, 0x0c, 0x8c, 0x7a,
++      0x03, 0x9e, 0x8e, 0x6a,
+       0x7f, 0x02, 0x04, 0x08,
+-      0x91, 0x6a, 0xd8, 0x5e,
++      0x91, 0x6a, 0xda, 0x5e,
+       0x00, 0x65, 0xcc, 0x41,
+       0x01, 0xa4, 0xca, 0x30,
+-      0x80, 0xa3, 0x9a, 0x7a,
++      0x80, 0xa3, 0x9c, 0x7a,
+       0x02, 0x65, 0xca, 0x00,
+       0x01, 0x65, 0xf8, 0x31,
+       0x01, 0x3b, 0x26, 0x31,
+-      0x00, 0x65, 0x0e, 0x5a,
+-      0x01, 0xfc, 0xa8, 0x6a,
+-      0x80, 0x0b, 0x9e, 0x6a,
+-      0x10, 0x0c, 0x9e, 0x7a,
+-      0x20, 0x93, 0x9e, 0x6a,
++      0x00, 0x65, 0x10, 0x5a,
++      0x01, 0xfc, 0xaa, 0x6a,
++      0x80, 0x0b, 0xa0, 0x6a,
++      0x10, 0x0c, 0xa0, 0x7a,
++      0x20, 0x93, 0xa0, 0x6a,
+       0x02, 0x93, 0x26, 0x01,
+-      0x02, 0xfc, 0xb2, 0x7a,
+-      0x40, 0x0d, 0xc6, 0x6a,
++      0x02, 0xfc, 0xb4, 0x7a,
++      0x40, 0x0d, 0xc8, 0x6a,
+       0x01, 0xa4, 0x48, 0x01,
+-      0x00, 0x65, 0xc6, 0x42,
+-      0x40, 0x0d, 0xb8, 0x6a,
+-      0x00, 0x65, 0x0e, 0x5a,
+-      0x00, 0x65, 0xaa, 0x42,
+-      0x80, 0xfc, 0xc2, 0x7a,
+-      0x80, 0xa4, 0xc2, 0x6a,
++      0x00, 0x65, 0xc8, 0x42,
++      0x40, 0x0d, 0xba, 0x6a,
++      0x00, 0x65, 0x10, 0x5a,
++      0x00, 0x65, 0xac, 0x42,
++      0x80, 0xfc, 0xc4, 0x7a,
++      0x80, 0xa4, 0xc4, 0x6a,
+       0xff, 0xa5, 0x4a, 0x19,
+       0xff, 0xa6, 0x4c, 0x21,
+       0xff, 0xa7, 0x4e, 0x21,
+       0xf8, 0xfc, 0x48, 0x09,
+       0x7f, 0xa3, 0x46, 0x09,
+-      0x04, 0x3b, 0xe2, 0x6a,
++      0x04, 0x3b, 0xe4, 0x6a,
+       0x02, 0x93, 0x26, 0x01,
+-      0x01, 0x94, 0xc8, 0x7a,
+-      0x01, 0x94, 0xc8, 0x7a,
+-      0x01, 0x94, 0xc8, 0x7a,
+-      0x01, 0x94, 0xc8, 0x7a,
+-      0x01, 0x94, 0xc8, 0x7a,
+-      0x01, 0xa4, 0xe0, 0x7a,
+-      0x01, 0xfc, 0xd6, 0x7a,
+-      0x01, 0x94, 0xe2, 0x6a,
+-      0x01, 0x94, 0xe2, 0x6a,
+-      0x01, 0x94, 0xe2, 0x6a,
+-      0x00, 0x65, 0x82, 0x42,
+-      0x01, 0x94, 0xe0, 0x7a,
+-      0x10, 0x94, 0xe2, 0x6a,
++      0x01, 0x94, 0xca, 0x7a,
++      0x01, 0x94, 0xca, 0x7a,
++      0x01, 0x94, 0xca, 0x7a,
++      0x01, 0x94, 0xca, 0x7a,
++      0x01, 0x94, 0xca, 0x7a,
++      0x01, 0xa4, 0xe2, 0x7a,
++      0x01, 0xfc, 0xd8, 0x7a,
++      0x01, 0x94, 0xe4, 0x6a,
++      0x01, 0x94, 0xe4, 0x6a,
++      0x01, 0x94, 0xe4, 0x6a,
++      0x00, 0x65, 0x84, 0x42,
++      0x01, 0x94, 0xe2, 0x7a,
++      0x10, 0x94, 0xe4, 0x6a,
+       0xd7, 0x93, 0x26, 0x09,
+-      0x28, 0x93, 0xe6, 0x6a,
++      0x28, 0x93, 0xe8, 0x6a,
+       0x01, 0x85, 0x0a, 0x01,
+-      0x02, 0xfc, 0xee, 0x6a,
++      0x02, 0xfc, 0xf0, 0x6a,
+       0x01, 0x14, 0x46, 0x31,
+       0xff, 0x6a, 0x10, 0x09,
+       0xfe, 0x85, 0x0a, 0x09,
+-      0xff, 0x38, 0xfc, 0x6a,
+-      0x80, 0xa3, 0xfc, 0x7a,
+-      0x80, 0x0b, 0xfa, 0x7a,
+-      0x04, 0x3b, 0xfc, 0x7a,
++      0xff, 0x38, 0xfe, 0x6a,
++      0x80, 0xa3, 0xfe, 0x7a,
++      0x80, 0x0b, 0xfc, 0x7a,
++      0x04, 0x3b, 0xfe, 0x7a,
+       0xbf, 0x3b, 0x76, 0x08,
+       0x01, 0x3b, 0x26, 0x31,
+-      0x00, 0x65, 0x0e, 0x5a,
+-      0x01, 0x0b, 0x0a, 0x6b,
+-      0x10, 0x0c, 0xfe, 0x7a,
+-      0x04, 0x93, 0x08, 0x6b,
+-      0x01, 0x94, 0x06, 0x7b,
+-      0x10, 0x94, 0x08, 0x6b,
++      0x00, 0x65, 0x10, 0x5a,
++      0x01, 0x0b, 0x0c, 0x6b,
++      0x10, 0x0c, 0x00, 0x7b,
++      0x04, 0x93, 0x0a, 0x6b,
++      0x01, 0x94, 0x08, 0x7b,
++      0x10, 0x94, 0x0a, 0x6b,
+       0xc7, 0x93, 0x26, 0x09,
+       0x01, 0x99, 0xd4, 0x30,
+-      0x38, 0x93, 0x0c, 0x6b,
+-      0xff, 0x08, 0x5a, 0x6b,
+-      0xff, 0x09, 0x5a, 0x6b,
+-      0xff, 0x0a, 0x5a, 0x6b,
+-      0xff, 0x38, 0x28, 0x7b,
++      0x38, 0x93, 0x0e, 0x6b,
++      0xff, 0x08, 0x5c, 0x6b,
++      0xff, 0x09, 0x5c, 0x6b,
++      0xff, 0x0a, 0x5c, 0x6b,
++      0xff, 0x38, 0x2a, 0x7b,
+       0x04, 0x14, 0x10, 0x31,
+       0x01, 0x38, 0x18, 0x31,
+       0x02, 0x6a, 0x1a, 0x31,
+       0x88, 0x6a, 0xcc, 0x00,
+-      0x14, 0x6a, 0xf4, 0x5d,
+-      0x00, 0x38, 0xe0, 0x5d,
++      0x14, 0x6a, 0xf6, 0x5d,
++      0x00, 0x38, 0xe2, 0x5d,
+       0xff, 0x6a, 0x70, 0x08,
+-      0x00, 0x65, 0x54, 0x43,
+-      0x80, 0xa3, 0x2e, 0x7b,
++      0x00, 0x65, 0x56, 0x43,
++      0x80, 0xa3, 0x30, 0x7b,
+       0x01, 0xa4, 0x48, 0x01,
+-      0x00, 0x65, 0x5a, 0x43,
+-      0x08, 0xeb, 0x34, 0x7b,
+-      0x00, 0x65, 0x0e, 0x5a,
+-      0x08, 0xeb, 0x30, 0x6b,
++      0x00, 0x65, 0x5c, 0x43,
++      0x08, 0xeb, 0x36, 0x7b,
++      0x00, 0x65, 0x10, 0x5a,
++      0x08, 0xeb, 0x32, 0x6b,
+       0x07, 0xe9, 0x10, 0x31,
+       0x01, 0xe9, 0xca, 0x30,
+       0x01, 0x65, 0x46, 0x31,
+-      0x00, 0x6a, 0xba, 0x5e,
++      0x00, 0x6a, 0xbc, 0x5e,
+       0x88, 0x6a, 0xcc, 0x00,
+-      0xa4, 0x6a, 0xf4, 0x5d,
+-      0x08, 0x6a, 0xe0, 0x5d,
++      0xa4, 0x6a, 0xf6, 0x5d,
++      0x08, 0x6a, 0xe2, 0x5d,
+       0x0d, 0x93, 0x26, 0x01,
+-      0x00, 0x65, 0xa8, 0x5e,
++      0x00, 0x65, 0xaa, 0x5e,
+       0x88, 0x6a, 0xcc, 0x00,
+-      0x00, 0x65, 0x8a, 0x5e,
++      0x00, 0x65, 0x8c, 0x5e,
+       0x01, 0x99, 0x46, 0x31,
+-      0x00, 0xa3, 0xba, 0x5e,
++      0x00, 0xa3, 0xbc, 0x5e,
+       0x01, 0x88, 0x10, 0x31,
+-      0x00, 0x65, 0x3a, 0x5a,
+-      0x00, 0x65, 0xfa, 0x59,
++      0x00, 0x65, 0x3c, 0x5a,
++      0x00, 0x65, 0xfc, 0x59,
+       0x03, 0x8c, 0x10, 0x30,
+-      0x00, 0x65, 0xe6, 0x5d,
+-      0x80, 0x0b, 0x82, 0x6a,
+-      0x80, 0x0b, 0x62, 0x6b,
+-      0x01, 0x0c, 0x5c, 0x7b,
+-      0x10, 0x0c, 0x82, 0x7a,
+-      0x03, 0x9e, 0x82, 0x6a,
+-      0x00, 0x65, 0x04, 0x5a,
+-      0x00, 0x6a, 0xba, 0x5e,
+-      0x01, 0xa4, 0x82, 0x6b,
+-      0xff, 0x38, 0x78, 0x7b,
++      0x00, 0x65, 0xe8, 0x5d,
++      0x80, 0x0b, 0x84, 0x6a,
++      0x80, 0x0b, 0x64, 0x6b,
++      0x01, 0x0c, 0x5e, 0x7b,
++      0x10, 0x0c, 0x84, 0x7a,
++      0x03, 0x9e, 0x84, 0x6a,
++      0x00, 0x65, 0x06, 0x5a,
++      0x00, 0x6a, 0xbc, 0x5e,
++      0x01, 0xa4, 0x84, 0x6b,
++      0xff, 0x38, 0x7a, 0x7b,
+       0x01, 0x38, 0xc8, 0x30,
+       0x00, 0x08, 0x40, 0x19,
+       0xff, 0x6a, 0xc8, 0x08,
+       0x00, 0x09, 0x42, 0x21,
+       0x00, 0x0a, 0x44, 0x21,
+       0xff, 0x6a, 0x70, 0x08,
+-      0x00, 0x65, 0x7a, 0x43,
++      0x00, 0x65, 0x7c, 0x43,
+       0x03, 0x08, 0x40, 0x31,
+       0x03, 0x08, 0x40, 0x31,
+       0x01, 0x08, 0x40, 0x31,
+@@ -461,16 +462,16 @@ static uint8_t seqprog[] = {
+       0x04, 0x3c, 0xcc, 0x79,
+       0xfb, 0x3c, 0x78, 0x08,
+       0x04, 0x93, 0x20, 0x79,
+-      0x01, 0x0c, 0x8e, 0x6b,
++      0x01, 0x0c, 0x90, 0x6b,
+       0x80, 0xba, 0x20, 0x79,
+       0x80, 0x04, 0x20, 0x79,
+-      0xe4, 0x6a, 0x6e, 0x5d,
+-      0x23, 0x6a, 0x84, 0x5d,
+-      0x01, 0x6a, 0x84, 0x5d,
++      0xe4, 0x6a, 0x70, 0x5d,
++      0x23, 0x6a, 0x86, 0x5d,
++      0x01, 0x6a, 0x86, 0x5d,
+       0x00, 0x65, 0x20, 0x41,
+       0x00, 0x65, 0xcc, 0x41,
+-      0x80, 0x3c, 0xa2, 0x7b,
+-      0x21, 0x6a, 0xd8, 0x5e,
++      0x80, 0x3c, 0xa4, 0x7b,
++      0x21, 0x6a, 0xda, 0x5e,
+       0x01, 0xbc, 0x18, 0x31,
+       0x02, 0x6a, 0x1a, 0x31,
+       0x02, 0x6a, 0xf8, 0x01,
+@@ -480,16 +481,16 @@ static uint8_t seqprog[] = {
+       0xff, 0x6a, 0x12, 0x08,
+       0xff, 0x6a, 0x14, 0x08,
+       0xf3, 0xbc, 0xd4, 0x18,
+-      0xa0, 0x6a, 0xc8, 0x53,
++      0xa0, 0x6a, 0xca, 0x53,
+       0x04, 0xa0, 0x10, 0x31,
+       0xac, 0x6a, 0x26, 0x01,
+       0x04, 0xa0, 0x10, 0x31,
+       0x03, 0x08, 0x18, 0x31,
+       0x88, 0x6a, 0xcc, 0x00,
+-      0xa0, 0x6a, 0xf4, 0x5d,
+-      0x00, 0xbc, 0xe0, 0x5d,
++      0xa0, 0x6a, 0xf6, 0x5d,
++      0x00, 0xbc, 0xe2, 0x5d,
+       0x3d, 0x6a, 0x26, 0x01,
+-      0x00, 0x65, 0xe0, 0x43,
++      0x00, 0x65, 0xe2, 0x43,
+       0xff, 0x6a, 0x10, 0x09,
+       0xa4, 0x6a, 0x26, 0x01,
+       0x0c, 0xa0, 0x32, 0x31,
+@@ -499,128 +500,128 @@ static uint8_t seqprog[] = {
+       0x36, 0x6a, 0x26, 0x01,
+       0x02, 0x93, 0x26, 0x01,
+       0x35, 0x6a, 0x26, 0x01,
+-      0x00, 0x65, 0x9c, 0x5e,
+-      0x00, 0x65, 0x9c, 0x5e,
++      0x00, 0x65, 0x9e, 0x5e,
++      0x00, 0x65, 0x9e, 0x5e,
+       0x02, 0x93, 0x26, 0x01,
+       0xbf, 0x3c, 0x78, 0x08,
+-      0x04, 0x0b, 0xe6, 0x6b,
+-      0x10, 0x0c, 0xe2, 0x7b,
+-      0x01, 0x03, 0xe6, 0x6b,
+-      0x20, 0x93, 0xe8, 0x6b,
+-      0x04, 0x0b, 0xee, 0x6b,
++      0x04, 0x0b, 0xe8, 0x6b,
++      0x10, 0x0c, 0xe4, 0x7b,
++      0x01, 0x03, 0xe8, 0x6b,
++      0x20, 0x93, 0xea, 0x6b,
++      0x04, 0x0b, 0xf0, 0x6b,
+       0x40, 0x3c, 0x78, 0x00,
+       0xc7, 0x93, 0x26, 0x09,
+-      0x38, 0x93, 0xf0, 0x6b,
++      0x38, 0x93, 0xf2, 0x6b,
+       0x00, 0x65, 0xcc, 0x41,
+-      0x80, 0x3c, 0x56, 0x6c,
++      0x80, 0x3c, 0x58, 0x6c,
+       0x01, 0x06, 0x50, 0x31,
+       0x80, 0xb8, 0x70, 0x01,
+       0x00, 0x65, 0xcc, 0x41,
+       0x10, 0x3f, 0x06, 0x00,
+       0x10, 0x6a, 0x06, 0x00,
+       0x01, 0x3a, 0xca, 0x30,
+-      0x80, 0x65, 0x1c, 0x64,
+-      0x10, 0xb8, 0x40, 0x6c,
++      0x80, 0x65, 0x1e, 0x64,
++      0x10, 0xb8, 0x42, 0x6c,
+       0xc0, 0x3e, 0xca, 0x00,
+-      0x40, 0xb8, 0x0c, 0x6c,
++      0x40, 0xb8, 0x0e, 0x6c,
+       0xbf, 0x65, 0xca, 0x08,
+-      0x20, 0xb8, 0x20, 0x7c,
++      0x20, 0xb8, 0x22, 0x7c,
+       0x01, 0x65, 0x0c, 0x30,
+-      0x00, 0x65, 0xd8, 0x5d,
+-      0xa0, 0x3f, 0x28, 0x64,
++      0x00, 0x65, 0xda, 0x5d,
++      0xa0, 0x3f, 0x2a, 0x64,
+       0x23, 0xb8, 0x0c, 0x08,
+-      0x00, 0x65, 0xd8, 0x5d,
+-      0xa0, 0x3f, 0x28, 0x64,
+-      0x00, 0xbb, 0x20, 0x44,
+-      0xff, 0x65, 0x20, 0x64,
+-      0x00, 0x65, 0x40, 0x44,
++      0x00, 0x65, 0xda, 0x5d,
++      0xa0, 0x3f, 0x2a, 0x64,
++      0x00, 0xbb, 0x22, 0x44,
++      0xff, 0x65, 0x22, 0x64,
++      0x00, 0x65, 0x42, 0x44,
+       0x40, 0x6a, 0x18, 0x00,
+       0x01, 0x65, 0x0c, 0x30,
+-      0x00, 0x65, 0xd8, 0x5d,
+-      0xa0, 0x3f, 0xfc, 0x73,
++      0x00, 0x65, 0xda, 0x5d,
++      0xa0, 0x3f, 0xfe, 0x73,
+       0x40, 0x6a, 0x18, 0x00,
+       0x01, 0x3a, 0xa6, 0x30,
+       0x08, 0x6a, 0x74, 0x00,
+       0x00, 0x65, 0xcc, 0x41,
+-      0x64, 0x6a, 0x68, 0x5d,
+-      0x80, 0x64, 0xd8, 0x6c,
+-      0x04, 0x64, 0x9a, 0x74,
+-      0x02, 0x64, 0xaa, 0x74,
+-      0x00, 0x6a, 0x60, 0x74,
+-      0x03, 0x64, 0xc8, 0x74,
+-      0x23, 0x64, 0x48, 0x74,
+-      0x08, 0x64, 0x5c, 0x74,
+-      0x61, 0x6a, 0xd8, 0x5e,
+-      0x00, 0x65, 0xd8, 0x5d,
++      0x64, 0x6a, 0x6a, 0x5d,
++      0x80, 0x64, 0xda, 0x6c,
++      0x04, 0x64, 0x9c, 0x74,
++      0x02, 0x64, 0xac, 0x74,
++      0x00, 0x6a, 0x62, 0x74,
++      0x03, 0x64, 0xca, 0x74,
++      0x23, 0x64, 0x4a, 0x74,
++      0x08, 0x64, 0x5e, 0x74,
++      0x61, 0x6a, 0xda, 0x5e,
++      0x00, 0x65, 0xda, 0x5d,
+       0x08, 0x51, 0xce, 0x71,
+-      0x00, 0x65, 0x40, 0x44,
+-      0x80, 0x04, 0x5a, 0x7c,
+-      0x51, 0x6a, 0x5e, 0x5d,
+-      0x01, 0x51, 0x5a, 0x64,
+-      0x01, 0xa4, 0x52, 0x7c,
+-      0x80, 0xba, 0x5c, 0x6c,
+-      0x41, 0x6a, 0xd8, 0x5e,
+-      0x00, 0x65, 0x5c, 0x44,
+-      0x21, 0x6a, 0xd8, 0x5e,
+-      0x00, 0x65, 0x5c, 0x44,
+-      0x07, 0x6a, 0x54, 0x5d,
++      0x00, 0x65, 0x42, 0x44,
++      0x80, 0x04, 0x5c, 0x7c,
++      0x51, 0x6a, 0x60, 0x5d,
++      0x01, 0x51, 0x5c, 0x64,
++      0x01, 0xa4, 0x54, 0x7c,
++      0x80, 0xba, 0x5e, 0x6c,
++      0x41, 0x6a, 0xda, 0x5e,
++      0x00, 0x65, 0x5e, 0x44,
++      0x21, 0x6a, 0xda, 0x5e,
++      0x00, 0x65, 0x5e, 0x44,
++      0x07, 0x6a, 0x56, 0x5d,
+       0x01, 0x06, 0xd4, 0x30,
+       0x00, 0x65, 0xcc, 0x41,
+-      0x80, 0xb8, 0x56, 0x7c,
+-      0xc0, 0x3c, 0x6a, 0x7c,
+-      0x80, 0x3c, 0x56, 0x6c,
+-      0xff, 0xa8, 0x6a, 0x6c,
+-      0x40, 0x3c, 0x56, 0x6c,
+-      0x10, 0xb8, 0x6e, 0x7c,
+-      0xa1, 0x6a, 0xd8, 0x5e,
+-      0x01, 0xb4, 0x74, 0x6c,
+-      0x02, 0xb4, 0x76, 0x6c,
+-      0x01, 0xa4, 0x76, 0x7c,
+-      0xff, 0xa8, 0x86, 0x7c,
++      0x80, 0xb8, 0x58, 0x7c,
++      0xc0, 0x3c, 0x6c, 0x7c,
++      0x80, 0x3c, 0x58, 0x6c,
++      0xff, 0xa8, 0x6c, 0x6c,
++      0x40, 0x3c, 0x58, 0x6c,
++      0x10, 0xb8, 0x70, 0x7c,
++      0xa1, 0x6a, 0xda, 0x5e,
++      0x01, 0xb4, 0x76, 0x6c,
++      0x02, 0xb4, 0x78, 0x6c,
++      0x01, 0xa4, 0x78, 0x7c,
++      0xff, 0xa8, 0x88, 0x7c,
+       0x04, 0xb4, 0x68, 0x01,
+       0x01, 0x6a, 0x76, 0x00,
+-      0x00, 0xbb, 0x12, 0x5e,
+-      0xff, 0xa8, 0x86, 0x7c,
+-      0x71, 0x6a, 0xd8, 0x5e,
+-      0x40, 0x51, 0x86, 0x64,
+-      0x00, 0x65, 0xb2, 0x5e,
++      0x00, 0xbb, 0x14, 0x5e,
++      0xff, 0xa8, 0x88, 0x7c,
++      0x71, 0x6a, 0xda, 0x5e,
++      0x40, 0x51, 0x88, 0x64,
++      0x00, 0x65, 0xb4, 0x5e,
+       0x00, 0x65, 0xde, 0x41,
+-      0x00, 0xbb, 0x8a, 0x5c,
++      0x00, 0xbb, 0x8c, 0x5c,
+       0x00, 0x65, 0xde, 0x41,
+-      0x00, 0x65, 0xb2, 0x5e,
++      0x00, 0x65, 0xb4, 0x5e,
+       0x01, 0x65, 0xa2, 0x30,
+       0x01, 0xf8, 0xc8, 0x30,
+       0x01, 0x4e, 0xc8, 0x30,
+-      0x00, 0x6a, 0xb6, 0xdd,
+-      0x00, 0x51, 0xc8, 0x5d,
++      0x00, 0x6a, 0xb8, 0xdd,
++      0x00, 0x51, 0xca, 0x5d,
+       0x01, 0x4e, 0x9c, 0x18,
+       0x02, 0x6a, 0x22, 0x05,
+-      0xc0, 0x3c, 0x56, 0x6c,
++      0xc0, 0x3c, 0x58, 0x6c,
+       0x04, 0xb8, 0x70, 0x01,
+-      0x00, 0x65, 0xd4, 0x5e,
++      0x00, 0x65, 0xd6, 0x5e,
+       0x20, 0xb8, 0xde, 0x69,
+       0x01, 0xbb, 0xa2, 0x30,
+       0x3f, 0xba, 0x7c, 0x08,
+-      0x00, 0xb9, 0xce, 0x5c,
++      0x00, 0xb9, 0xd0, 0x5c,
+       0x00, 0x65, 0xde, 0x41,
+       0x01, 0x06, 0xd4, 0x30,
+       0x20, 0x3c, 0xcc, 0x79,
+-      0x20, 0x3c, 0x5c, 0x7c,
+-      0x01, 0xa4, 0xb8, 0x7c,
++      0x20, 0x3c, 0x5e, 0x7c,
++      0x01, 0xa4, 0xba, 0x7c,
+       0x01, 0xb4, 0x68, 0x01,
+       0x00, 0x65, 0xcc, 0x41,
+-      0x00, 0x65, 0x5c, 0x44,
++      0x00, 0x65, 0x5e, 0x44,
+       0x04, 0x14, 0x58, 0x31,
+       0x01, 0x06, 0xd4, 0x30,
+       0x08, 0xa0, 0x60, 0x31,
+       0xac, 0x6a, 0xcc, 0x00,
+-      0x14, 0x6a, 0xf4, 0x5d,
++      0x14, 0x6a, 0xf6, 0x5d,
+       0x01, 0x06, 0xd4, 0x30,
+-      0xa0, 0x6a, 0xec, 0x5d,
++      0xa0, 0x6a, 0xee, 0x5d,
+       0x00, 0x65, 0xcc, 0x41,
+       0xdf, 0x3c, 0x78, 0x08,
+       0x12, 0x01, 0x02, 0x00,
+-      0x00, 0x65, 0x5c, 0x44,
++      0x00, 0x65, 0x5e, 0x44,
+       0x4c, 0x65, 0xcc, 0x28,
+       0x01, 0x3e, 0x20, 0x31,
+       0xd0, 0x66, 0xcc, 0x18,
+@@ -631,102 +632,102 @@ static uint8_t seqprog[] = {
+       0xd0, 0x65, 0xca, 0x18,
+       0x01, 0x3e, 0x20, 0x31,
+       0x30, 0x65, 0xd4, 0x18,
+-      0x00, 0x65, 0xe6, 0x4c,
++      0x00, 0x65, 0xe8, 0x4c,
+       0xe1, 0x6a, 0x22, 0x01,
+       0xff, 0x6a, 0xd4, 0x08,
+       0x20, 0x65, 0xd4, 0x18,
+-      0x00, 0x65, 0xee, 0x54,
++      0x00, 0x65, 0xf0, 0x54,
+       0xe1, 0x6a, 0x22, 0x01,
+       0xff, 0x6a, 0xd4, 0x08,
+       0x20, 0x65, 0xca, 0x18,
+       0xe0, 0x65, 0xd4, 0x18,
+-      0x00, 0x65, 0xf8, 0x4c,
++      0x00, 0x65, 0xfa, 0x4c,
+       0xe1, 0x6a, 0x22, 0x01,
+       0xff, 0x6a, 0xd4, 0x08,
+       0xd0, 0x65, 0xd4, 0x18,
+-      0x00, 0x65, 0x00, 0x55,
++      0x00, 0x65, 0x02, 0x55,
+       0xe1, 0x6a, 0x22, 0x01,
+       0xff, 0x6a, 0xd4, 0x08,
+       0x01, 0x6c, 0xa2, 0x30,
+-      0xff, 0x51, 0x12, 0x75,
+-      0x00, 0x51, 0x8e, 0x5d,
++      0xff, 0x51, 0x14, 0x75,
++      0x00, 0x51, 0x90, 0x5d,
+       0x01, 0x51, 0x20, 0x31,
+-      0x00, 0x65, 0x34, 0x45,
++      0x00, 0x65, 0x36, 0x45,
+       0x3f, 0xba, 0xc8, 0x08,
+-      0x00, 0x3e, 0x34, 0x75,
+-      0x00, 0x65, 0xb0, 0x5e,
++      0x00, 0x3e, 0x36, 0x75,
++      0x00, 0x65, 0xb2, 0x5e,
+       0x80, 0x3c, 0x78, 0x00,
+       0x01, 0x06, 0xd4, 0x30,
+-      0x00, 0x65, 0xd8, 0x5d,
++      0x00, 0x65, 0xda, 0x5d,
+       0x01, 0x3c, 0x78, 0x00,
+-      0xe0, 0x3f, 0x50, 0x65,
++      0xe0, 0x3f, 0x52, 0x65,
+       0x02, 0x3c, 0x78, 0x00,
+-      0x20, 0x12, 0x50, 0x65,
+-      0x51, 0x6a, 0x5e, 0x5d,
+-      0x00, 0x51, 0x8e, 0x5d,
+-      0x51, 0x6a, 0x5e, 0x5d,
++      0x20, 0x12, 0x52, 0x65,
++      0x51, 0x6a, 0x60, 0x5d,
++      0x00, 0x51, 0x90, 0x5d,
++      0x51, 0x6a, 0x60, 0x5d,
+       0x01, 0x51, 0x20, 0x31,
+       0x04, 0x3c, 0x78, 0x00,
+       0x01, 0xb9, 0xc8, 0x30,
+-      0x00, 0x3d, 0x4e, 0x65,
++      0x00, 0x3d, 0x50, 0x65,
+       0x08, 0x3c, 0x78, 0x00,
+       0x3f, 0xba, 0xc8, 0x08,
+-      0x00, 0x3e, 0x4e, 0x65,
++      0x00, 0x3e, 0x50, 0x65,
+       0x10, 0x3c, 0x78, 0x00,
+-      0x04, 0xb8, 0x4e, 0x7d,
++      0x04, 0xb8, 0x50, 0x7d,
+       0xfb, 0xb8, 0x70, 0x09,
+-      0x20, 0xb8, 0x44, 0x6d,
++      0x20, 0xb8, 0x46, 0x6d,
+       0x01, 0x90, 0xc8, 0x30,
+       0xff, 0x6a, 0xa2, 0x00,
+-      0x00, 0x3d, 0xce, 0x5c,
++      0x00, 0x3d, 0xd0, 0x5c,
+       0x01, 0x64, 0x20, 0x31,
+       0xff, 0x6a, 0x78, 0x08,
+       0x00, 0x65, 0xea, 0x58,
+-      0x10, 0xb8, 0x5c, 0x7c,
+-      0xff, 0x6a, 0x54, 0x5d,
+-      0x00, 0x65, 0x5c, 0x44,
+-      0x00, 0x65, 0xb0, 0x5e,
+-      0x31, 0x6a, 0xd8, 0x5e,
+-      0x00, 0x65, 0x5c, 0x44,
++      0x10, 0xb8, 0x5e, 0x7c,
++      0xff, 0x6a, 0x56, 0x5d,
++      0x00, 0x65, 0x5e, 0x44,
++      0x00, 0x65, 0xb2, 0x5e,
++      0x31, 0x6a, 0xda, 0x5e,
++      0x00, 0x65, 0x5e, 0x44,
+       0x10, 0x3f, 0x06, 0x00,
+       0x10, 0x6a, 0x06, 0x00,
+       0x01, 0x65, 0x74, 0x34,
+-      0x81, 0x6a, 0xd8, 0x5e,
+-      0x00, 0x65, 0x60, 0x45,
++      0x81, 0x6a, 0xda, 0x5e,
++      0x00, 0x65, 0x62, 0x45,
+       0x01, 0x06, 0xd4, 0x30,
+-      0x01, 0x0c, 0x60, 0x7d,
+-      0x04, 0x0c, 0x5a, 0x6d,
++      0x01, 0x0c, 0x62, 0x7d,
++      0x04, 0x0c, 0x5c, 0x6d,
+       0xe0, 0x03, 0x7e, 0x08,
+       0xe0, 0x3f, 0xcc, 0x61,
+       0x01, 0x65, 0xcc, 0x30,
+       0x01, 0x12, 0xda, 0x34,
+       0x01, 0x06, 0xd4, 0x34,
+-      0x01, 0x03, 0x6e, 0x6d,
++      0x01, 0x03, 0x70, 0x6d,
+       0x40, 0x03, 0xcc, 0x08,
+       0x01, 0x65, 0x06, 0x30,
+       0x40, 0x65, 0xc8, 0x08,
+-      0x00, 0x66, 0x7c, 0x75,
+-      0x40, 0x65, 0x7c, 0x7d,
+-      0x00, 0x65, 0x7c, 0x5d,
++      0x00, 0x66, 0x7e, 0x75,
++      0x40, 0x65, 0x7e, 0x7d,
++      0x00, 0x65, 0x7e, 0x5d,
+       0xff, 0x6a, 0xd4, 0x08,
+       0xff, 0x6a, 0xd4, 0x08,
+       0xff, 0x6a, 0xd4, 0x08,
+       0xff, 0x6a, 0xd4, 0x0c,
+       0x08, 0x01, 0x02, 0x00,
+-      0x02, 0x0b, 0x86, 0x7d,
++      0x02, 0x0b, 0x88, 0x7d,
+       0x01, 0x65, 0x0c, 0x30,
+-      0x02, 0x0b, 0x8a, 0x7d,
++      0x02, 0x0b, 0x8c, 0x7d,
+       0xf7, 0x01, 0x02, 0x0c,
+       0x01, 0x65, 0xc8, 0x30,
+-      0xff, 0x41, 0xae, 0x75,
++      0xff, 0x41, 0xb0, 0x75,
+       0x01, 0x41, 0x20, 0x31,
+       0xff, 0x6a, 0xa4, 0x00,
+-      0x00, 0x65, 0x9e, 0x45,
+-      0xff, 0xbf, 0xae, 0x75,
++      0x00, 0x65, 0xa0, 0x45,
++      0xff, 0xbf, 0xb0, 0x75,
+       0x01, 0x90, 0xa4, 0x30,
+       0x01, 0xbf, 0x20, 0x31,
+-      0x00, 0xbb, 0x98, 0x65,
+-      0xff, 0x52, 0xac, 0x75,
++      0x00, 0xbb, 0x9a, 0x65,
++      0xff, 0x52, 0xae, 0x75,
+       0x01, 0xbf, 0xcc, 0x30,
+       0x01, 0x90, 0xca, 0x30,
+       0x01, 0x52, 0x20, 0x31,
+@@ -734,28 +735,28 @@ static uint8_t seqprog[] = {
+       0x01, 0x65, 0x20, 0x35,
+       0x01, 0xbf, 0x82, 0x34,
+       0x01, 0x64, 0xa2, 0x30,
+-      0x00, 0x6a, 0xc0, 0x5e,
++      0x00, 0x6a, 0xc2, 0x5e,
+       0x0d, 0x6a, 0x76, 0x00,
+-      0x00, 0x51, 0x12, 0x46,
++      0x00, 0x51, 0x14, 0x46,
+       0x01, 0x65, 0xa4, 0x30,
+       0xe0, 0x6a, 0xcc, 0x00,
+-      0x48, 0x6a, 0x06, 0x5e,
++      0x48, 0x6a, 0x08, 0x5e,
+       0x01, 0x6a, 0xd0, 0x01,
+       0x01, 0x6a, 0xdc, 0x05,
+       0x88, 0x6a, 0xcc, 0x00,
+-      0x48, 0x6a, 0x06, 0x5e,
+-      0x01, 0x6a, 0xe0, 0x5d,
++      0x48, 0x6a, 0x08, 0x5e,
++      0x01, 0x6a, 0xe2, 0x5d,
+       0x01, 0x6a, 0x26, 0x05,
+       0x01, 0x65, 0xd8, 0x31,
+       0x09, 0xee, 0xdc, 0x01,
+-      0x80, 0xee, 0xcc, 0x7d,
++      0x80, 0xee, 0xce, 0x7d,
+       0xff, 0x6a, 0xdc, 0x0d,
+       0x01, 0x65, 0x32, 0x31,
+       0x0a, 0x93, 0x26, 0x01,
+-      0x00, 0x65, 0xa8, 0x46,
+-      0x81, 0x6a, 0xd8, 0x5e,
+-      0x01, 0x0c, 0xd8, 0x7d,
+-      0x04, 0x0c, 0xd6, 0x6d,
++      0x00, 0x65, 0xaa, 0x46,
++      0x81, 0x6a, 0xda, 0x5e,
++      0x01, 0x0c, 0xda, 0x7d,
++      0x04, 0x0c, 0xd8, 0x6d,
+       0xe0, 0x03, 0x06, 0x08,
+       0xe0, 0x03, 0x7e, 0x0c,
+       0x01, 0x65, 0x18, 0x31,
+@@ -774,7 +775,7 @@ static uint8_t seqprog[] = {
+       0x01, 0x6c, 0xda, 0x34,
+       0x3d, 0x64, 0xa4, 0x28,
+       0x55, 0x64, 0xc8, 0x28,
+-      0x00, 0x65, 0x06, 0x46,
++      0x00, 0x65, 0x08, 0x46,
+       0x2e, 0x64, 0xa4, 0x28,
+       0x66, 0x64, 0xc8, 0x28,
+       0x00, 0x6c, 0xda, 0x18,
+@@ -785,63 +786,63 @@ static uint8_t seqprog[] = {
+       0x00, 0x6c, 0xda, 0x24,
+       0x01, 0x65, 0xc8, 0x30,
+       0xe0, 0x6a, 0xcc, 0x00,
+-      0x44, 0x6a, 0x02, 0x5e,
++      0x44, 0x6a, 0x04, 0x5e,
+       0x01, 0x90, 0xe2, 0x31,
+-      0x04, 0x3b, 0x26, 0x7e,
++      0x04, 0x3b, 0x28, 0x7e,
+       0x30, 0x6a, 0xd0, 0x01,
+       0x20, 0x6a, 0xd0, 0x01,
+       0x1d, 0x6a, 0xdc, 0x01,
+-      0xdc, 0xee, 0x22, 0x66,
+-      0x00, 0x65, 0x3e, 0x46,
++      0xdc, 0xee, 0x24, 0x66,
++      0x00, 0x65, 0x40, 0x46,
+       0x20, 0x6a, 0xd0, 0x01,
+       0x01, 0x6a, 0xdc, 0x01,
+       0x20, 0xa0, 0xd8, 0x31,
+       0x09, 0xee, 0xdc, 0x01,
+-      0x80, 0xee, 0x2e, 0x7e,
++      0x80, 0xee, 0x30, 0x7e,
+       0x11, 0x6a, 0xdc, 0x01,
+-      0x50, 0xee, 0x32, 0x66,
++      0x50, 0xee, 0x34, 0x66,
+       0x20, 0x6a, 0xd0, 0x01,
+       0x09, 0x6a, 0xdc, 0x01,
+-      0x88, 0xee, 0x38, 0x66,
++      0x88, 0xee, 0x3a, 0x66,
+       0x19, 0x6a, 0xdc, 0x01,
+-      0xd8, 0xee, 0x3c, 0x66,
++      0xd8, 0xee, 0x3e, 0x66,
+       0xff, 0x6a, 0xdc, 0x09,
+-      0x18, 0xee, 0x40, 0x6e,
++      0x18, 0xee, 0x42, 0x6e,
+       0xff, 0x6a, 0xd4, 0x0c,
+       0x88, 0x6a, 0xcc, 0x00,
+-      0x44, 0x6a, 0x02, 0x5e,
+-      0x20, 0x6a, 0xe0, 0x5d,
++      0x44, 0x6a, 0x04, 0x5e,
++      0x20, 0x6a, 0xe2, 0x5d,
+       0x01, 0x3b, 0x26, 0x31,
+-      0x04, 0x3b, 0x5a, 0x6e,
++      0x04, 0x3b, 0x5c, 0x6e,
+       0xa0, 0x6a, 0xca, 0x00,
+       0x20, 0x65, 0xc8, 0x18,
+-      0x00, 0x65, 0x98, 0x5e,
+-      0x00, 0x65, 0x52, 0x66,
++      0x00, 0x65, 0x9a, 0x5e,
++      0x00, 0x65, 0x54, 0x66,
+       0x0a, 0x93, 0x26, 0x01,
+-      0x00, 0x65, 0xa8, 0x46,
++      0x00, 0x65, 0xaa, 0x46,
+       0xa0, 0x6a, 0xcc, 0x00,
+       0xff, 0x6a, 0xc8, 0x08,
+-      0x20, 0x94, 0x5e, 0x6e,
+-      0x10, 0x94, 0x60, 0x6e,
+-      0x08, 0x94, 0x7a, 0x6e,
+-      0x08, 0x94, 0x7a, 0x6e,
+-      0x08, 0x94, 0x7a, 0x6e,
++      0x20, 0x94, 0x60, 0x6e,
++      0x10, 0x94, 0x62, 0x6e,
++      0x08, 0x94, 0x7c, 0x6e,
++      0x08, 0x94, 0x7c, 0x6e,
++      0x08, 0x94, 0x7c, 0x6e,
+       0xff, 0x8c, 0xc8, 0x10,
+       0xc1, 0x64, 0xc8, 0x18,
+       0xf8, 0x64, 0xc8, 0x08,
+       0x01, 0x99, 0xda, 0x30,
+-      0x00, 0x66, 0x6e, 0x66,
+-      0xc0, 0x66, 0xaa, 0x76,
++      0x00, 0x66, 0x70, 0x66,
++      0xc0, 0x66, 0xac, 0x76,
+       0x60, 0x66, 0xc8, 0x18,
+       0x3d, 0x64, 0xc8, 0x28,
+-      0x00, 0x65, 0x5e, 0x46,
++      0x00, 0x65, 0x60, 0x46,
+       0xf7, 0x93, 0x26, 0x09,
+-      0x08, 0x93, 0x7c, 0x6e,
++      0x08, 0x93, 0x7e, 0x6e,
+       0x00, 0x62, 0xc4, 0x18,
+-      0x00, 0x65, 0xa8, 0x5e,
+-      0x00, 0x65, 0x88, 0x5e,
+-      0x00, 0x65, 0x88, 0x5e,
+-      0x00, 0x65, 0x88, 0x5e,
++      0x00, 0x65, 0xaa, 0x5e,
++      0x00, 0x65, 0x8a, 0x5e,
++      0x00, 0x65, 0x8a, 0x5e,
++      0x00, 0x65, 0x8a, 0x5e,
+       0x01, 0x99, 0xda, 0x30,
+       0x01, 0x99, 0xda, 0x30,
+       0x01, 0x99, 0xda, 0x30,
+@@ -858,11 +859,11 @@ static uint8_t seqprog[] = {
+       0x01, 0x6c, 0x32, 0x31,
+       0x01, 0x6c, 0x32, 0x31,
+       0x01, 0x6c, 0x32, 0x35,
+-      0x08, 0x94, 0xa8, 0x7e,
++      0x08, 0x94, 0xaa, 0x7e,
+       0xf7, 0x93, 0x26, 0x09,
+-      0x08, 0x93, 0xac, 0x6e,
++      0x08, 0x93, 0xae, 0x6e,
+       0xff, 0x6a, 0xd4, 0x0c,
+-      0x04, 0xb8, 0xd4, 0x6e,
++      0x04, 0xb8, 0xd6, 0x6e,
+       0x01, 0x42, 0x7e, 0x31,
+       0xff, 0x6a, 0x76, 0x01,
+       0x01, 0x90, 0x84, 0x34,
+@@ -870,14 +871,14 @@ static uint8_t seqprog[] = {
+       0x01, 0x85, 0x0a, 0x01,
+       0x7f, 0x65, 0x10, 0x09,
+       0xfe, 0x85, 0x0a, 0x0d,
+-      0xff, 0x42, 0xd0, 0x66,
+-      0xff, 0x41, 0xc8, 0x66,
+-      0xd1, 0x6a, 0xd8, 0x5e,
++      0xff, 0x42, 0xd2, 0x66,
++      0xff, 0x41, 0xca, 0x66,
++      0xd1, 0x6a, 0xda, 0x5e,
+       0xff, 0x6a, 0xca, 0x04,
+       0x01, 0x41, 0x20, 0x31,
+       0x01, 0xbf, 0x82, 0x30,
+       0x01, 0x6a, 0x76, 0x00,
+-      0x00, 0xbb, 0x12, 0x46,
++      0x00, 0xbb, 0x14, 0x46,
+       0x01, 0x42, 0x20, 0x31,
+       0x01, 0xbf, 0x84, 0x34,
+       0x01, 0x41, 0x7e, 0x31,
+@@ -941,7 +942,7 @@ static ahc_patch_func_t ahc_patch17_func
+ static int
+ ahc_patch17_func(struct ahc_softc *ahc)
+ {
+-      return ((ahc->flags & AHC_TMODE_WIDEODD_BUG) != 0);
++      return ((ahc->bugs & AHC_TMODE_WIDEODD_BUG) != 0);
+ }
+ static ahc_patch_func_t ahc_patch16_func;
+@@ -1142,152 +1143,152 @@ static struct patch {
+       { ahc_patch0_func, 196, 1, 1 },
+       { ahc_patch9_func, 212, 6, 2 },
+       { ahc_patch0_func, 218, 6, 1 },
+-      { ahc_patch8_func, 226, 20, 2 },
++      { ahc_patch8_func, 226, 21, 2 },
+       { ahc_patch1_func, 241, 1, 1 },
+-      { ahc_patch1_func, 248, 1, 2 },
+-      { ahc_patch0_func, 249, 2, 2 },
+-      { ahc_patch11_func, 250, 1, 1 },
+-      { ahc_patch9_func, 258, 27, 3 },
+-      { ahc_patch1_func, 274, 10, 2 },
+-      { ahc_patch13_func, 277, 1, 1 },
+-      { ahc_patch14_func, 285, 14, 1 },
+-      { ahc_patch1_func, 301, 1, 2 },
+-      { ahc_patch0_func, 302, 1, 1 },
+-      { ahc_patch9_func, 305, 1, 1 },
+-      { ahc_patch13_func, 310, 1, 1 },
+-      { ahc_patch9_func, 311, 2, 2 },
+-      { ahc_patch0_func, 313, 4, 1 },
+-      { ahc_patch14_func, 317, 1, 1 },
+-      { ahc_patch15_func, 319, 2, 3 },
+-      { ahc_patch9_func, 319, 1, 2 },
+-      { ahc_patch0_func, 320, 1, 1 },
+-      { ahc_patch6_func, 325, 1, 2 },
+-      { ahc_patch0_func, 326, 1, 1 },
+-      { ahc_patch1_func, 330, 47, 11 },
+-      { ahc_patch6_func, 337, 2, 4 },
+-      { ahc_patch7_func, 337, 1, 1 },
+-      { ahc_patch8_func, 338, 1, 1 },
+-      { ahc_patch0_func, 339, 1, 1 },
+-      { ahc_patch16_func, 340, 1, 1 },
+-      { ahc_patch6_func, 356, 6, 3 },
+-      { ahc_patch16_func, 356, 5, 1 },
+-      { ahc_patch0_func, 362, 7, 1 },
+-      { ahc_patch13_func, 372, 5, 1 },
+-      { ahc_patch0_func, 377, 52, 17 },
+-      { ahc_patch14_func, 377, 1, 1 },
+-      { ahc_patch7_func, 379, 2, 2 },
+-      { ahc_patch17_func, 380, 1, 1 },
+-      { ahc_patch9_func, 383, 1, 1 },
+-      { ahc_patch18_func, 390, 1, 1 },
+-      { ahc_patch14_func, 395, 9, 3 },
+-      { ahc_patch9_func, 396, 3, 2 },
+-      { ahc_patch0_func, 399, 3, 1 },
+-      { ahc_patch9_func, 407, 6, 2 },
+-      { ahc_patch0_func, 413, 9, 2 },
+-      { ahc_patch13_func, 413, 1, 1 },
+-      { ahc_patch13_func, 422, 2, 1 },
+-      { ahc_patch14_func, 424, 1, 1 },
+-      { ahc_patch9_func, 426, 1, 2 },
+-      { ahc_patch0_func, 427, 1, 1 },
+-      { ahc_patch7_func, 428, 1, 1 },
++      { ahc_patch1_func, 249, 1, 2 },
++      { ahc_patch0_func, 250, 2, 2 },
++      { ahc_patch11_func, 251, 1, 1 },
++      { ahc_patch9_func, 259, 27, 3 },
++      { ahc_patch1_func, 275, 10, 2 },
++      { ahc_patch13_func, 278, 1, 1 },
++      { ahc_patch14_func, 286, 14, 1 },
++      { ahc_patch1_func, 302, 1, 2 },
++      { ahc_patch0_func, 303, 1, 1 },
++      { ahc_patch9_func, 306, 1, 1 },
++      { ahc_patch13_func, 311, 1, 1 },
++      { ahc_patch9_func, 312, 2, 2 },
++      { ahc_patch0_func, 314, 4, 1 },
++      { ahc_patch14_func, 318, 1, 1 },
++      { ahc_patch15_func, 320, 2, 3 },
++      { ahc_patch9_func, 320, 1, 2 },
++      { ahc_patch0_func, 321, 1, 1 },
++      { ahc_patch6_func, 326, 1, 2 },
++      { ahc_patch0_func, 327, 1, 1 },
++      { ahc_patch1_func, 331, 47, 11 },
++      { ahc_patch6_func, 338, 2, 4 },
++      { ahc_patch7_func, 338, 1, 1 },
++      { ahc_patch8_func, 339, 1, 1 },
++      { ahc_patch0_func, 340, 1, 1 },
++      { ahc_patch16_func, 341, 1, 1 },
++      { ahc_patch6_func, 357, 6, 3 },
++      { ahc_patch16_func, 357, 5, 1 },
++      { ahc_patch0_func, 363, 7, 1 },
++      { ahc_patch13_func, 373, 5, 1 },
++      { ahc_patch0_func, 378, 52, 17 },
++      { ahc_patch14_func, 378, 1, 1 },
++      { ahc_patch7_func, 380, 2, 2 },
++      { ahc_patch17_func, 381, 1, 1 },
++      { ahc_patch9_func, 384, 1, 1 },
++      { ahc_patch18_func, 391, 1, 1 },
++      { ahc_patch14_func, 396, 9, 3 },
++      { ahc_patch9_func, 397, 3, 2 },
++      { ahc_patch0_func, 400, 3, 1 },
++      { ahc_patch9_func, 408, 6, 2 },
++      { ahc_patch0_func, 414, 9, 2 },
++      { ahc_patch13_func, 414, 1, 1 },
++      { ahc_patch13_func, 423, 2, 1 },
++      { ahc_patch14_func, 425, 1, 1 },
++      { ahc_patch9_func, 427, 1, 2 },
++      { ahc_patch0_func, 428, 1, 1 },
+       { ahc_patch7_func, 429, 1, 1 },
+-      { ahc_patch8_func, 430, 3, 3 },
+-      { ahc_patch6_func, 431, 1, 2 },
+-      { ahc_patch0_func, 432, 1, 1 },
+-      { ahc_patch9_func, 433, 1, 1 },
+-      { ahc_patch15_func, 434, 1, 2 },
+-      { ahc_patch13_func, 434, 1, 1 },
+-      { ahc_patch14_func, 436, 9, 4 },
+-      { ahc_patch9_func, 436, 1, 1 },
+-      { ahc_patch9_func, 443, 2, 1 },
+-      { ahc_patch0_func, 445, 4, 3 },
+-      { ahc_patch9_func, 445, 1, 2 },
+-      { ahc_patch0_func, 446, 3, 1 },
+-      { ahc_patch1_func, 450, 2, 1 },
+-      { ahc_patch7_func, 452, 10, 2 },
+-      { ahc_patch0_func, 462, 1, 1 },
+-      { ahc_patch8_func, 463, 118, 22 },
+-      { ahc_patch1_func, 465, 3, 2 },
+-      { ahc_patch0_func, 468, 5, 3 },
+-      { ahc_patch9_func, 468, 2, 2 },
+-      { ahc_patch0_func, 470, 3, 1 },
+-      { ahc_patch1_func, 475, 2, 2 },
+-      { ahc_patch0_func, 477, 6, 3 },
+-      { ahc_patch9_func, 477, 2, 2 },
+-      { ahc_patch0_func, 479, 3, 1 },
+-      { ahc_patch1_func, 485, 2, 2 },
+-      { ahc_patch0_func, 487, 9, 7 },
+-      { ahc_patch9_func, 487, 5, 6 },
+-      { ahc_patch19_func, 487, 1, 2 },
+-      { ahc_patch0_func, 488, 1, 1 },
+-      { ahc_patch19_func, 490, 1, 2 },
+-      { ahc_patch0_func, 491, 1, 1 },
+-      { ahc_patch0_func, 492, 4, 1 },
+-      { ahc_patch6_func, 497, 3, 2 },
+-      { ahc_patch0_func, 500, 1, 1 },
+-      { ahc_patch6_func, 510, 1, 2 },
+-      { ahc_patch0_func, 511, 1, 1 },
+-      { ahc_patch20_func, 548, 7, 1 },
+-      { ahc_patch3_func, 583, 1, 2 },
+-      { ahc_patch0_func, 584, 1, 1 },
+-      { ahc_patch21_func, 587, 1, 1 },
+-      { ahc_patch8_func, 589, 106, 33 },
+-      { ahc_patch4_func, 591, 1, 1 },
+-      { ahc_patch1_func, 597, 2, 2 },
+-      { ahc_patch0_func, 599, 1, 1 },
+-      { ahc_patch1_func, 602, 1, 2 },
+-      { ahc_patch0_func, 603, 1, 1 },
+-      { ahc_patch9_func, 604, 3, 3 },
+-      { ahc_patch15_func, 605, 1, 1 },
+-      { ahc_patch0_func, 607, 4, 1 },
+-      { ahc_patch19_func, 616, 2, 2 },
+-      { ahc_patch0_func, 618, 1, 1 },
+-      { ahc_patch19_func, 622, 10, 3 },
+-      { ahc_patch5_func, 624, 8, 1 },
+-      { ahc_patch0_func, 632, 9, 2 },
+-      { ahc_patch5_func, 633, 8, 1 },
+-      { ahc_patch4_func, 643, 1, 2 },
+-      { ahc_patch0_func, 644, 1, 1 },
+-      { ahc_patch19_func, 645, 1, 2 },
+-      { ahc_patch0_func, 646, 3, 2 },
+-      { ahc_patch4_func, 648, 1, 1 },
+-      { ahc_patch5_func, 649, 1, 1 },
+-      { ahc_patch5_func, 652, 1, 1 },
+-      { ahc_patch5_func, 654, 1, 1 },
+-      { ahc_patch4_func, 656, 2, 2 },
+-      { ahc_patch0_func, 658, 2, 1 },
+-      { ahc_patch5_func, 660, 1, 1 },
+-      { ahc_patch5_func, 663, 1, 1 },
+-      { ahc_patch5_func, 666, 1, 1 },
+-      { ahc_patch19_func, 670, 1, 1 },
+-      { ahc_patch19_func, 673, 1, 1 },
+-      { ahc_patch4_func, 679, 1, 1 },
+-      { ahc_patch6_func, 682, 1, 2 },
+-      { ahc_patch0_func, 683, 1, 1 },
+-      { ahc_patch7_func, 695, 16, 1 },
+-      { ahc_patch4_func, 711, 20, 1 },
+-      { ahc_patch9_func, 732, 4, 2 },
+-      { ahc_patch0_func, 736, 4, 1 },
+-      { ahc_patch9_func, 740, 4, 2 },
+-      { ahc_patch0_func, 744, 3, 1 },
+-      { ahc_patch6_func, 750, 1, 1 },
+-      { ahc_patch22_func, 752, 14, 1 },
+-      { ahc_patch7_func, 766, 3, 1 },
+-      { ahc_patch9_func, 778, 24, 8 },
+-      { ahc_patch19_func, 782, 1, 2 },
+-      { ahc_patch0_func, 783, 1, 1 },
+-      { ahc_patch15_func, 788, 4, 2 },
+-      { ahc_patch0_func, 792, 7, 3 },
+-      { ahc_patch23_func, 792, 5, 2 },
+-      { ahc_patch0_func, 797, 2, 1 },
+-      { ahc_patch0_func, 802, 42, 3 },
+-      { ahc_patch18_func, 814, 18, 2 },
+-      { ahc_patch0_func, 832, 1, 1 },
+-      { ahc_patch4_func, 856, 1, 1 },
+-      { ahc_patch4_func, 857, 3, 2 },
+-      { ahc_patch0_func, 860, 1, 1 },
+-      { ahc_patch13_func, 861, 3, 1 },
+-      { ahc_patch4_func, 864, 12, 1 }
++      { ahc_patch7_func, 430, 1, 1 },
++      { ahc_patch8_func, 431, 3, 3 },
++      { ahc_patch6_func, 432, 1, 2 },
++      { ahc_patch0_func, 433, 1, 1 },
++      { ahc_patch9_func, 434, 1, 1 },
++      { ahc_patch15_func, 435, 1, 2 },
++      { ahc_patch13_func, 435, 1, 1 },
++      { ahc_patch14_func, 437, 9, 4 },
++      { ahc_patch9_func, 437, 1, 1 },
++      { ahc_patch9_func, 444, 2, 1 },
++      { ahc_patch0_func, 446, 4, 3 },
++      { ahc_patch9_func, 446, 1, 2 },
++      { ahc_patch0_func, 447, 3, 1 },
++      { ahc_patch1_func, 451, 2, 1 },
++      { ahc_patch7_func, 453, 10, 2 },
++      { ahc_patch0_func, 463, 1, 1 },
++      { ahc_patch8_func, 464, 118, 22 },
++      { ahc_patch1_func, 466, 3, 2 },
++      { ahc_patch0_func, 469, 5, 3 },
++      { ahc_patch9_func, 469, 2, 2 },
++      { ahc_patch0_func, 471, 3, 1 },
++      { ahc_patch1_func, 476, 2, 2 },
++      { ahc_patch0_func, 478, 6, 3 },
++      { ahc_patch9_func, 478, 2, 2 },
++      { ahc_patch0_func, 480, 3, 1 },
++      { ahc_patch1_func, 486, 2, 2 },
++      { ahc_patch0_func, 488, 9, 7 },
++      { ahc_patch9_func, 488, 5, 6 },
++      { ahc_patch19_func, 488, 1, 2 },
++      { ahc_patch0_func, 489, 1, 1 },
++      { ahc_patch19_func, 491, 1, 2 },
++      { ahc_patch0_func, 492, 1, 1 },
++      { ahc_patch0_func, 493, 4, 1 },
++      { ahc_patch6_func, 498, 3, 2 },
++      { ahc_patch0_func, 501, 1, 1 },
++      { ahc_patch6_func, 511, 1, 2 },
++      { ahc_patch0_func, 512, 1, 1 },
++      { ahc_patch20_func, 549, 7, 1 },
++      { ahc_patch3_func, 584, 1, 2 },
++      { ahc_patch0_func, 585, 1, 1 },
++      { ahc_patch21_func, 588, 1, 1 },
++      { ahc_patch8_func, 590, 106, 33 },
++      { ahc_patch4_func, 592, 1, 1 },
++      { ahc_patch1_func, 598, 2, 2 },
++      { ahc_patch0_func, 600, 1, 1 },
++      { ahc_patch1_func, 603, 1, 2 },
++      { ahc_patch0_func, 604, 1, 1 },
++      { ahc_patch9_func, 605, 3, 3 },
++      { ahc_patch15_func, 606, 1, 1 },
++      { ahc_patch0_func, 608, 4, 1 },
++      { ahc_patch19_func, 617, 2, 2 },
++      { ahc_patch0_func, 619, 1, 1 },
++      { ahc_patch19_func, 623, 10, 3 },
++      { ahc_patch5_func, 625, 8, 1 },
++      { ahc_patch0_func, 633, 9, 2 },
++      { ahc_patch5_func, 634, 8, 1 },
++      { ahc_patch4_func, 644, 1, 2 },
++      { ahc_patch0_func, 645, 1, 1 },
++      { ahc_patch19_func, 646, 1, 2 },
++      { ahc_patch0_func, 647, 3, 2 },
++      { ahc_patch4_func, 649, 1, 1 },
++      { ahc_patch5_func, 650, 1, 1 },
++      { ahc_patch5_func, 653, 1, 1 },
++      { ahc_patch5_func, 655, 1, 1 },
++      { ahc_patch4_func, 657, 2, 2 },
++      { ahc_patch0_func, 659, 2, 1 },
++      { ahc_patch5_func, 661, 1, 1 },
++      { ahc_patch5_func, 664, 1, 1 },
++      { ahc_patch5_func, 667, 1, 1 },
++      { ahc_patch19_func, 671, 1, 1 },
++      { ahc_patch19_func, 674, 1, 1 },
++      { ahc_patch4_func, 680, 1, 1 },
++      { ahc_patch6_func, 683, 1, 2 },
++      { ahc_patch0_func, 684, 1, 1 },
++      { ahc_patch7_func, 696, 16, 1 },
++      { ahc_patch4_func, 712, 20, 1 },
++      { ahc_patch9_func, 733, 4, 2 },
++      { ahc_patch0_func, 737, 4, 1 },
++      { ahc_patch9_func, 741, 4, 2 },
++      { ahc_patch0_func, 745, 3, 1 },
++      { ahc_patch6_func, 751, 1, 1 },
++      { ahc_patch22_func, 753, 14, 1 },
++      { ahc_patch7_func, 767, 3, 1 },
++      { ahc_patch9_func, 779, 24, 8 },
++      { ahc_patch19_func, 783, 1, 2 },
++      { ahc_patch0_func, 784, 1, 1 },
++      { ahc_patch15_func, 789, 4, 2 },
++      { ahc_patch0_func, 793, 7, 3 },
++      { ahc_patch23_func, 793, 5, 2 },
++      { ahc_patch0_func, 798, 2, 1 },
++      { ahc_patch0_func, 803, 42, 3 },
++      { ahc_patch18_func, 815, 18, 2 },
++      { ahc_patch0_func, 833, 1, 1 },
++      { ahc_patch4_func, 857, 1, 1 },
++      { ahc_patch4_func, 858, 3, 2 },
++      { ahc_patch0_func, 861, 1, 1 },
++      { ahc_patch13_func, 862, 3, 1 },
++      { ahc_patch4_func, 865, 12, 1 }
+ };
+ static struct cs {
+@@ -1296,11 +1297,11 @@ static struct cs {
+ } critical_sections[] = {
+       { 11, 18 },
+       { 21, 30 },
+-      { 711, 727 },
+-      { 857, 860 },
+-      { 864, 870 },
+-      { 872, 874 },
+-      { 874, 876 }
++      { 712, 728 },
++      { 858, 861 },
++      { 865, 871 },
++      { 873, 875 },
++      { 875, 877 }
+ };
+ static const int num_critical_sections = sizeof(critical_sections)
+--- linux-2.6.0/drivers/scsi/aic7xxx/aicasm/aicasm.c   2003-06-14 12:18:06.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aicasm/aicasm.c    2003-12-28 23:21:40.000000000 -0800
+@@ -37,7 +37,7 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#22 $
++ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#23 $
+  *
+  * $FreeBSD$
+  */
+@@ -609,10 +609,10 @@ output_listing(char *ifilename)
+               while (line < cur_instr->srcline) {
+                       fgets(buf, sizeof(buf), ifile);
+-                              fprintf(listfile, "\t\t%s", buf);
++                              fprintf(listfile, "             \t%s", buf);
+                               line++;
+               }
+-              fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr,
++              fprintf(listfile, "%04x %02x%02x%02x%02x", instrptr,
+ #if BYTE_ORDER == LITTLE_ENDIAN
+                       cur_instr->format.bytes[0],
+                       cur_instr->format.bytes[1],
+@@ -624,14 +624,23 @@ output_listing(char *ifilename)
+                       cur_instr->format.bytes[1],
+                       cur_instr->format.bytes[0]);
+ #endif
+-              fgets(buf, sizeof(buf), ifile);
+-              fprintf(listfile, "\t%s", buf);
+-              line++;
++              /*
++               * Macro expansions can cause several instructions
++               * to be output for a single source line.  Only
++               * advance the line once in these cases.
++               */
++              if (line == cur_instr->srcline) {
++                      fgets(buf, sizeof(buf), ifile);
++                      fprintf(listfile, "\t%s", buf);
++                      line++;
++              } else {
++                      fprintf(listfile, "\n");
++              }
+               instrptr++;
+       }
+       /* Dump the remainder of the file */
+       while(fgets(buf, sizeof(buf), ifile) != NULL)
+-              fprintf(listfile, "\t\t%s", buf);
++              fprintf(listfile, "             %s", buf);
+       fclose(ifile);
+ }
+--- linux-2.6.0/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l        2003-06-14 12:18:09.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.l 2003-12-28 23:21:40.000000000 -0800
+@@ -38,7 +38,7 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#7 $
++ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#8 $
+  *
+  * $FreeBSD$
+  */
+@@ -78,6 +78,7 @@ MCARG                [^(), \t]+
+ \n                    {
+                               ++yylineno;
+                       }
++\r                    ;
+ <ARGLIST>{SPACE}      ;
+ <ARGLIST>\(           {
+                               parren_count++;
+--- linux-2.6.0/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l      2003-06-14 12:18:29.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aicasm/aicasm_scan.l       2003-12-28 23:21:40.000000000 -0800
+@@ -38,7 +38,7 @@
+  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGES.
+  *
+- * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#18 $
++ * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#19 $
+  *
+  * $FreeBSD$
+  */
+@@ -87,6 +87,7 @@ MBODY                ((\\[^\n])*[^\n\\]*)+
+ %%
+ \n                    { ++yylineno; }
++\r                    ;
+ "/*"                  { BEGIN COMMENT;  /* Enter comment eating state */ }
+ <COMMENT>"/*"         { fprintf(stderr, "Warning! Comment within comment."); }
+ <COMMENT>\n           { ++yylineno; }
+@@ -114,6 +115,7 @@ if[ \t]*\(         {
+                               }
+                       }
+ <CEXPR>\n             { ++yylineno; }
++<CEXPR>\r             ;
+ <CEXPR>[^()\n]+       {
+                               char *yptr;
+@@ -359,6 +361,7 @@ else                       { return T_ELSE; }
+                               /* Eat escaped newlines. */
+                               ++yylineno;
+                       }
++<MACROBODY>\r         ;
+ <MACROBODY>\n         {
+                               /* Macros end on the first unescaped newline. */
+                               BEGIN INITIAL;
+@@ -369,10 +372,17 @@ else                     { return T_ELSE; }
+                       }
+ <MACROBODY>{MBODY}    {
+                               char *yptr;
++                              char c;
+                               yptr = yytext;
+-                              while (*yptr)
+-                                      *string_buf_ptr++ = *yptr++;
++                              while (c = *yptr++) {
++                                      /*
++                                       * Strip carriage returns.
++                                       */
++                                      if (c == '\r')
++                                              continue;
++                                      *string_buf_ptr++ = c;
++                              }
+                       }
+ {WORD}\(              {
+                               char *yptr;
+--- linux-2.6.0/drivers/scsi/aic7xxx/aicasm/Makefile   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/aic7xxx/aicasm/Makefile    2003-12-28 23:21:40.000000000 -0800
+@@ -49,11 +49,19 @@ aicdb.h:
+ clean:
+       rm -f $(clean-files)
++# Create a dependency chain in generated files
++# to avoid concurrent invocations of the single
++# rule that builds them all.
++aicasm_gram.c: aicasm_gram.h
+ aicasm_gram.c aicasm_gram.h: aicasm_gram.y
+       $(YACC) $(YFLAGS) -b $(<:.y=) $<
+       mv $(<:.y=).tab.c $(<:.y=.c)
+       mv $(<:.y=).tab.h $(<:.y=.h)
++# Create a dependency chain in generated files
++# to avoid concurrent invocations of the single
++# rule that builds them all.
++aicasm_macro_gram.c: aicasm_macro_gram.h
+ aicasm_macro_gram.c aicasm_macro_gram.h: aicasm_macro_gram.y
+       $(YACC) $(YFLAGS) -b $(<:.y=) -p mm $<
+       mv $(<:.y=).tab.c $(<:.y=.c)
+--- linux-2.6.0/drivers/scsi/aic7xxx/aiclib.c  2003-07-27 12:14:39.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aiclib.c   2003-12-28 23:21:40.000000000 -0800
+@@ -30,16 +30,6 @@
+  * $Id$
+  */
+-#include <linux/blkdev.h>
+-#include <linux/delay.h>
+-#include <linux/version.h>
+-
+-/* Core SCSI definitions */
+-#include "scsi.h"
+-#include "hosts.h"
+-#include "aiclib.h"
+-#include "cam.h"
+-
+ #ifndef FALSE
+ #define FALSE   0
+ #endif /* FALSE */
+@@ -1410,3 +1400,336 @@ aic_parse_brace_option(char *opt_name, c
+       }
+       return (opt_arg);
+ }
++
++/************************* Magic SysReq Support *******************************/
++void
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++aic_sysrq_handler(int key, struct pt_regs *unused, struct kbd_struct *unused1,
++                struct tty_struct *unused2)
++#else
++aic_sysrq_handler(int key, struct pt_regs *unused, struct tty_struct *unused2)
++#endif
++{
++#ifdef CONFIG_MAGIC_SYSRQ
++      struct aic_softc *aic;
++      u_long l;
++
++      aic_list_lock(&l);
++
++      TAILQ_FOREACH(aic, &aic_tailq, links) {
++              u_long s;
++
++              aic_lock(aic, &s);
++              aic_dump_card_state(aic);
++              aic_unlock(aic, &s);
++      }
++      aic_list_unlock(&l);
++#endif
++}
++
++int
++aic_install_sysrq(struct aic_sysrq_key_op *key_op)
++{
++#ifdef CONFIG_MAGIC_SYSRQ
++      char *str;
++      int len;
++      int i;
++
++      str = key_op->help_msg;
++      len = strlen(str);
++      for (i = 0; i < len; i++) {
++              int key;
++
++              key = str[i];
++              if (register_sysrq_key(key, key_op) == 0) {
++
++                      if (key >= 'a' && key <= 'z')
++                              str[i] = key + ('A' - 'a');
++                      return (key);
++              }
++      }
++#endif
++      return (0);
++}
++
++void
++aic_remove_sysrq(int key, struct aic_sysrq_key_op *key_op)
++{
++#ifdef CONFIG_MAGIC_SYSRQ
++      unregister_sysrq_key(key, key_op);
++#endif
++}
++
++/******************************** Bus DMA *************************************/
++int
++aic_dma_tag_create(struct aic_softc *aic, bus_dma_tag_t parent,
++                 bus_size_t alignment, bus_size_t boundary,
++                 bus_addr_t lowaddr, bus_addr_t highaddr,
++                 bus_dma_filter_t *filter, void *filterarg,
++                 bus_size_t maxsize, int nsegments,
++                 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
++{
++      bus_dma_tag_t dmat;
++
++      dmat = malloc(sizeof(*dmat), M_DEVBUF, M_NOWAIT);
++      if (dmat == NULL)
++              return (ENOMEM);
++
++      /*
++       * Linux is very simplistic about DMA memory.  For now don't
++       * maintain all specification information.  Once Linux supplies
++       * better facilities for doing these operations, or the
++       * needs of this particular driver change, we might need to do
++       * more here.
++       */
++      dmat->alignment = alignment;
++      dmat->boundary = boundary;
++      dmat->maxsize = maxsize;
++      *ret_tag = dmat;
++      return (0);
++}
++
++void
++aic_dma_tag_destroy(struct aic_softc *aic, bus_dma_tag_t dmat)
++{
++      free(dmat, M_DEVBUF);
++}
++
++int
++aic_dmamem_alloc(struct aic_softc *aic, bus_dma_tag_t dmat, void** vaddr,
++               int flags, bus_dmamap_t *mapp)
++{
++      bus_dmamap_t map;
++
++      map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT);
++      if (map == NULL)
++              return (ENOMEM);
++      /*
++       * Although we can dma data above 4GB, our
++       * coherent memory is below 4GB for
++       * space efficiency reasons (only need a 4byte
++       * address).  For this reason, we have to reset
++       * our dma mask when doing allocations.
++       */
++      aic_set_dma_mask(aic, 0xFFFFFFFF);
++      *vaddr = aic_alloc_coherent(aic, dmat->maxsize, &map->bus_addr);
++      aic_set_dma_mask(aic, aic->platform_data->hw_dma_mask);
++      if (*vaddr == NULL)
++              return (ENOMEM);
++      *mapp = map;
++      return(0);
++}
++
++void
++aic_dmamem_free(struct aic_softc *aic, bus_dma_tag_t dmat,
++              void* vaddr, bus_dmamap_t map)
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
++      aic_free_coherent(aic, dmat->maxsize, vaddr, map->bus_addr);
++#else
++      free(vaddr, M_DEVBUF);
++#endif
++}
++
++int
++aic_dmamap_load(struct aic_softc *aic, bus_dma_tag_t dmat, bus_dmamap_t map,
++              void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
++              void *cb_arg, int flags)
++{
++      /*
++       * Assume for now that this will only be used during
++       * initialization and not for per-transaction buffer mapping.
++       */
++      bus_dma_segment_t stack_sg;
++
++      stack_sg.ds_addr = map->bus_addr;
++      stack_sg.ds_len = dmat->maxsize;
++      cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0);
++      return (0);
++}
++
++void
++aic_dmamap_destroy(struct aic_softc *aic, bus_dma_tag_t dmat, bus_dmamap_t map)
++{
++      free(map, M_DEVBUF);
++}
++
++int
++aic_dmamap_unload(struct aic_softc *aic, bus_dma_tag_t dmat, bus_dmamap_t map)
++{
++      /* Nothing to do */
++      return (0);
++}
++
++/***************************** Queue Handling ********************************/
++/*
++ * In 2.4.X and above, this routine is called from a tasklet,
++ * so we must re-acquire our lock prior to executing this code.
++ * In all prior kernels, aic_schedule_runq() calls this routine
++ * directly and aic_schedule_runq() is called with our lock held.
++ */
++void
++aic_runq_tasklet(unsigned long data)
++{
++      struct aic_softc* aic;
++      struct aic_linux_device *dev;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++      u_long flags;
++#endif
++
++      aic = (struct aic_softc *)data;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++      aic_lock(aic, &flags);
++#endif
++      while ((dev = aic_linux_next_device_to_run(aic)) != NULL) {
++      
++              TAILQ_REMOVE(&aic->platform_data->device_runq, dev, links);
++              dev->flags &= ~AIC_DEV_ON_RUN_LIST;
++              aic_linux_check_device_queue(aic, dev);
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++              /* Yeild to our interrupt handler */
++              aic_unlock(aic, &flags);
++              aic_lock(aic, &flags);
++#endif
++      }
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++      aic_unlock(aic, &flags);
++#endif
++}
++
++void
++aic_unblock_tasklet(unsigned long data)
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++      struct aic_softc* aic;
++
++      aic = (struct aic_softc *)data;
++      scsi_unblock_requests(aic->platform_data->host);
++#else
++#error "Fix 2.2.X Kernel Support"
++#endif
++}
++
++void
++aic_bus_settle_complete(u_long data)
++{
++      struct aic_softc *aic;
++      u_long s;
++
++      aic = (struct aic_softc *)data;
++      /*
++       * Guard against our bottom half scheduling another
++       * bus settle delay just as our timer runs.  If this
++       * occurs, do nothing.  The newly scheduled timer will
++       * take care of things.
++       */
++      aic_lock(aic, &s);
++      if (timer_pending(&aic->platform_data->bus_settle_timer) == 0) {
++              aic->platform_data->flags &= ~AIC_BUS_SETTLE_TIMER;
++              aic_release_simq_locked(aic);
++      }
++      aic_unlock(aic, &s);
++}
++
++void
++aic_freeze_simq(struct aic_softc *aic)
++{
++      aic->platform_data->qfrozen++;
++      if (aic->platform_data->qfrozen == 1)
++              scsi_block_requests(aic->platform_data->host);
++}
++
++void
++aic_release_simq(struct aic_softc *aic)
++{
++      u_long s;
++
++      aic_lock(aic, &s);
++      aic_release_simq_locked(aic);
++      aic_unlock(aic, &s);
++}
++
++void
++aic_release_simq_locked(struct aic_softc *aic)
++{
++
++      if (aic->platform_data->qfrozen > 0)
++              aic->platform_data->qfrozen--;
++      if (AIC_DV_SIMQ_FROZEN(aic)
++       && ((aic->platform_data->flags & AIC_DV_WAIT_SIMQ_RELEASE) != 0)) {
++              aic->platform_data->flags &= ~AIC_DV_WAIT_SIMQ_RELEASE;
++              up(&aic->platform_data->dv_sem);
++      }
++      if (aic->platform_data->qfrozen == 0) {
++              aic_schedule_unblock(aic);
++              aic_schedule_runq(aic);
++      }
++}
++
++/***************************** Timer Facilities *******************************/
++void
++aic_platform_timeout(struct scsi_cmnd *cmd)
++{
++
++      if (AIC_DV_CMD(cmd) != 0) {
++
++              aic_linux_dv_timeout(cmd);
++      } else {
++              struct  scb *scb;
++              struct  aic_softc *aic;
++              u_long  s;
++
++              scb = (struct scb *)cmd->host_scribble;
++              aic = scb->aic_softc;
++              aic_lock(aic, &s);
++
++              if (scb == NULL
++               || scb->flags == SCB_FLAG_NONE) {
++                      int done_late;
++
++                      /*
++                       * Handle timeout/completion races.
++                       * If the command is still sitting on
++                       * our completion queue, just re-instate
++                       * the timeout.  If we've already completed
++                       * the command, the function pointer in our
++                       * timer will be cleared and we will need to
++                       * additionally complete it again to the mid-layer.
++                       *
++                       * Since done_late is cleared by adding a
++                       * timer, we must save off its value first.
++                       */
++                      done_late = cmd->eh_timeout.function == NULL;
++                      scsi_add_timer(cmd, 60*HZ, aic_linux_midlayer_timeout);
++                      if (done_late)
++                              cmd->scsi_done(cmd);
++              } else if ((scb->platform_data->flags & AIC_TIMEOUT_ACTIVE)) {
++
++                      /*
++                       * Handle the case of timeouts that expire just
++                       * as we delete timers during recovery by skipping
++                       * SCBs that don't have timers active.
++                       */
++                      scb->platform_data->flags &= ~AIC_TIMEOUT_ACTIVE;
++
++                      /*
++                       * We must clear out the function pointer so that
++                       * scsi_add_timer does not believe that a del_timer
++                       * is required before setting up a new timer for
++                       * this command.
++                       */
++                      scb->io_ctx->eh_timeout.function = NULL;
++                      aic_timeout(scb);
++              }
++              aic_unlock(aic, &s);
++      }
++}
++
++void
++aic_linux_midlayer_timeout(struct scsi_cmnd *cmd)
++{
++      struct aic_softc *aic;
++
++      aic = *(struct aic_softc **)cmd->device->host->hostdata;
++      printf("%s: midlayer_timeout\n", aic_name(aic));
++}
+--- linux-2.6.0/drivers/scsi/aic7xxx/aiclib.h  2003-06-14 12:17:57.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aiclib.h   2003-12-28 23:21:40.000000000 -0800
+@@ -1,4 +1,5 @@
+ /*
++ * SCSI definitions...
+  * Largely written by Julian Elischer (julian@tfs.com)
+  * for TRW Financial Systems.
+  *
+@@ -57,6 +58,42 @@
+ #ifndef       _AICLIB_H
+ #define _AICLIB_H
++#include <linux/types.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/pci.h>
++#include <linux/smp_lock.h>
++#include <linux/module.h>
++#include <asm/byteorder.h>
++#include <asm/io.h>
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++#include <linux/slab.h>
++#else
++#include <linux/malloc.h>
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++#include <linux/interrupt.h> /* For tasklet support. */
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++#include <linux/blk.h>
++#endif
++#include <linux/blkdev.h>
++
++#include "scsi.h"
++#include "hosts.h"
++
++/* Name space conflict with BSD queue macros */
++#ifdef LIST_HEAD
++#undef LIST_HEAD
++#endif
++#include "cam.h"
++#include "queue.h"
++#include "scsi_message.h"
++#include "scsi_iu.h"
++
+ /*
+  * Linux Interrupt Support.
+  */
+@@ -66,9 +103,731 @@ typedef void irqreturn_t;
+ #endif
+ /*
+- * SCSI command format
++ * Linux Timer Support.
++ */
++#define AIC_USECS_PER_JIFFY (1000000/HZ)
++
++/**************************** Module Library Hack *****************************/
++/*
++ * What we'd like to do is have a single "scsi library" module that both the
++ * aic7xxx and aic79xx drivers could load and depend on.  A cursory examination
++ * of implementing module dependencies in Linux (handling the install and
++ * initrd cases) does not look promissing.  For now, we just duplicate this
++ * code in both drivers using a simple symbol renaming scheme that hides this
++ * hack from the drivers.
++ */
++#define AIC_LIB_ENTRY_CONCAT(x, prefix)       prefix ## x
++#define       AIC_LIB_ENTRY_EXPAND(x, prefix) AIC_LIB_ENTRY_CONCAT(x, prefix)
++#define AIC_LIB_ENTRY(x)              AIC_LIB_ENTRY_EXPAND(x, AIC_LIB_PREFIX)
++
++#define AIC_CONST_ENTRY(x)            AIC_LIB_ENTRY_EXPAND(x,AIC_CONST_PREFIX)
++
++#define       aic_sense_desc                  AIC_LIB_ENTRY(_sense_desc)
++#define       aic_sense_error_action          AIC_LIB_ENTRY(_sense_error_action)
++#define       aic_error_action                AIC_LIB_ENTRY(_error_action)
++#define       aic_op_desc                     AIC_LIB_ENTRY(_op_desc)
++#define       aic_cdb_string                  AIC_LIB_ENTRY(_cdb_string)
++#define aic_print_inquiry             AIC_LIB_ENTRY(_print_inquiry)
++#define aic_calc_syncsrate            AIC_LIB_ENTRY(_calc_syncrate)
++#define       aic_calc_syncparam              AIC_LIB_ENTRY(_calc_syncparam)
++#define       aic_calc_speed                  AIC_LIB_ENTRY(_calc_speed)
++#define       aic_inquiry_match               AIC_LIB_ENTRY(_inquiry_match)
++#define       aic_static_inquiry_match        AIC_LIB_ENTRY(_static_inquiry_match)
++#define       aic_parse_brace_option          AIC_LIB_ENTRY(_parse_brace_option)
++#define       aic_power_state_change          AIC_LIB_ENTRY(_power_state_change)
++#define       aic_sysrq_handler               AIC_LIB_ENTRY(_sysrq_handler)
++#define       aic_install_sysrq               AIC_LIB_ENTRY(_install_sysrq)
++#define       aic_remove_sysrq                AIC_LIB_ENTRY(_remove_sysrq)
++#define       aic_list_lock                   AIC_LIB_ENTRY(_list_lock)
++#define       aic_list_unlock                 AIC_LIB_ENTRY(_list_unlock)
++#define       aic_lock                        AIC_LIB_ENTRY(_lock)
++#define       aic_unlock                      AIC_LIB_ENTRY(_unlock)
++#define       aic_dump_card_state             AIC_LIB_ENTRY(_dump_card_state)
++#define       aic_linux_dv_complete           AIC_LIB_ENTRY(_linux_dv_complete)
++#define       aic_linux_run_device_queue      AIC_LIB_ENTRY(_linux_run_device_queue)
++#define       aic_linux_dv_timeout            AIC_LIB_ENTRY(_linux_dv_timeout)
++#define       aic_linux_midlayer_timeout      AIC_LIB_ENTRY(_linux_midlayer_timeout)
++#define       aic_freeze_simq                 AIC_LIB_ENTRY(_freeze_simq)
++#define       aic_bus_settle_complete         AIC_LIB_ENTRY(_bus_settle_complete)
++#define       aic_release_simq                AIC_LIB_ENTRY(_release_simq)
++#define       aic_release_simq                AIC_LIB_ENTRY(_release_simq)
++#define       aic_release_simq_locked         AIC_LIB_ENTRY(_release_simq_locked)
++#define       aic_dma_tag_create              AIC_LIB_ENTRY(_dma_tag_create)
++#define       aic_dma_tag_destroy             AIC_LIB_ENTRY(_dma_tag_destroy)
++#define       aic_dmamem_alloc                AIC_LIB_ENTRY(_dmamem_alloc)
++#define       aic_dmamem_free                 AIC_LIB_ENTRY(_dmamem_free)
++#define       aic_dmamap_create               AIC_LIB_ENTRY(_dmamap_create)
++#define       aic_dmamap_destroy              AIC_LIB_ENTRY(_dmamap_destroy)
++#define       aic_dmamap_load                 AIC_LIB_ENTRY(_dmamap_load)
++#define       aic_dmamap_unload               AIC_LIB_ENTRY(_dmamap_unload)
++#define       aic_dmamap_destroy              AIC_LIB_ENTRY(_dmamap_destroy)
++#define       aic_timeout                     AIC_LIB_ENTRY(_timeout)
++#define       aic_runq_tasklet                AIC_LIB_ENTRY(_runq_tasklet)
++#define       aic_unblock_tasklet             AIC_LIB_ENTRY(_unblock_tasklet)
++#define       aic_platform_timeout            AIC_LIB_ENTRY(_platform_timeout)
++#define       aic_name                        AIC_LIB_ENTRY(_name)
++
++#define       aic_tailq                       AIC_LIB_ENTRY(_tailq)
++#define       aic_softc                       AIC_LIB_ENTRY(_softc)
++#define       aic_transinfo                   AIC_LIB_ENTRY(_transinfo)
++#define       aic_platform_data               AIC_LIB_ENTRY(_platform_data)
++#define       aic_devinfo                     AIC_LIB_ENTRY(_devinfo)
++#define       aic_callback_t                  AIC_LIB_ENTRY(_callback_t)
++
++#define       AIC_NUM_LUNS                    AIC_CONST_ENTRY(_NUM_LUNS)
++#define       AIC_NUM_TARGETS                 AIC_CONST_ENTRY(_NUM_TARGETS)
++#define       AIC_RESOURCE_SHORTAGE           AIC_CONST_ENTRY(_RESOURCE_SHORTAGE)
++
++/*************************** Forward Declarations *****************************/
++struct aic_softc;
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
++typedef struct device *aic_dev_softc_t;
++#else
++typedef struct pci_dev *aic_dev_softc_t;
++#endif
++typedef Scsi_Cmnd     *aic_io_ctx_t;
++
++/*************************** Timer DataStructures *****************************/
++typedef struct timer_list aic_timer_t;
++
++/***************************** Bus Space/DMA **********************************/
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,17)
++typedef dma_addr_t bus_addr_t;
++#else
++typedef uint32_t bus_addr_t;
++#endif
++typedef uint32_t bus_size_t;
++
++typedef enum {
++      BUS_SPACE_MEMIO,
++      BUS_SPACE_PIO
++} bus_space_tag_t;
++
++typedef union {
++      u_long            ioport;
++      volatile uint8_t *maddr;
++} bus_space_handle_t;
++
++typedef struct bus_dma_segment
++{
++      bus_addr_t      ds_addr;
++      bus_size_t      ds_len;
++} bus_dma_segment_t;
++
++struct aic_linux_dma_tag
++{
++      bus_size_t      alignment;
++      bus_size_t      boundary;
++      bus_size_t      maxsize;
++};
++typedef struct aic_linux_dma_tag* bus_dma_tag_t;
++
++struct aic_linux_dmamap
++{
++      bus_addr_t      bus_addr;
++};
++typedef struct aic_linux_dmamap* bus_dmamap_t;
++
++typedef int bus_dma_filter_t(void*, bus_addr_t);
++typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
++
++#define BUS_DMA_WAITOK                0x0
++#define BUS_DMA_NOWAIT                0x1
++#define BUS_DMA_ALLOCNOW      0x2
++#define BUS_DMA_LOAD_SEGS     0x4     /*
++                                       * Argument is an S/G list not
++                                       * a single buffer.
++                                       */
++
++#define BUS_SPACE_MAXADDR     0xFFFFFFFF
++#define BUS_SPACE_MAXADDR_32BIT       0xFFFFFFFF
++#define BUS_SPACE_MAXSIZE_32BIT       0xFFFFFFFF
++
++int   aic_dma_tag_create(struct aic_softc *, bus_dma_tag_t /*parent*/,
++                         bus_size_t /*alignment*/, bus_size_t /*boundary*/,
++                         bus_addr_t /*lowaddr*/, bus_addr_t /*highaddr*/,
++                         bus_dma_filter_t*/*filter*/, void */*filterarg*/,
++                         bus_size_t /*maxsize*/, int /*nsegments*/,
++                         bus_size_t /*maxsegsz*/, int /*flags*/,
++                         bus_dma_tag_t */*dma_tagp*/);
++
++void  aic_dma_tag_destroy(struct aic_softc *, bus_dma_tag_t /*tag*/);
++
++int   aic_dmamem_alloc(struct aic_softc *, bus_dma_tag_t /*dmat*/,
++                       void** /*vaddr*/, int /*flags*/,
++                       bus_dmamap_t* /*mapp*/);
++
++void  aic_dmamem_free(struct aic_softc *, bus_dma_tag_t /*dmat*/,
++                      void* /*vaddr*/, bus_dmamap_t /*map*/);
++
++void  aic_dmamap_destroy(struct aic_softc *, bus_dma_tag_t /*tag*/,
++                         bus_dmamap_t /*map*/);
++
++int   aic_dmamap_load(struct aic_softc *aic, bus_dma_tag_t /*dmat*/,
++                      bus_dmamap_t /*map*/, void * /*buf*/,
++                      bus_size_t /*buflen*/, bus_dmamap_callback_t *,
++                      void */*callback_arg*/, int /*flags*/);
++
++int   aic_dmamap_unload(struct aic_softc *, bus_dma_tag_t, bus_dmamap_t);
++
++/*
++ * Operations performed by aic_dmamap_sync().
+  */
++#define BUS_DMASYNC_PREREAD   0x01    /* pre-read synchronization */
++#define BUS_DMASYNC_POSTREAD  0x02    /* post-read synchronization */
++#define BUS_DMASYNC_PREWRITE  0x04    /* pre-write synchronization */
++#define BUS_DMASYNC_POSTWRITE 0x08    /* post-write synchronization */
++
++/*
++ * XXX
++ * aic_dmamap_sync is only used on buffers allocated with
++ * the pci_alloc_consistent() API.  Although I'm not sure how
++ * this works on architectures with a write buffer, Linux does
++ * not have an API to sync "coherent" memory.  Perhaps we need
++ * to do an mb()?
++ */
++#define aic_dmamap_sync(aic, dma_tag, dmamap, offset, len, op)
++
++/*************************** Linux DMA Wrappers *******************************/
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++#define       aic_alloc_coherent(aic, size, bus_addr_ptr) \
++      dma_alloc_coherent(aic->dev_softc, size, bus_addr_ptr, /*flag*/0)
++
++#define       aic_free_coherent(aic, size, vaddr, bus_addr) \
++      dma_free_coherent(aic->dev_softc, size, vaddr, bus_addr)
++
++#define       aic_map_single(aic, buf, size, direction) \
++      dma_map_single(aic->dev_softc, buf, size, direction)
++
++#define       aic_unmap_single(aic, busaddr, size, direction) \
++      dma_unmap_single(aic->dev_softc, busaddr, size, direction)
++
++#define       aic_map_sg(aic, sg_list, num_sg, direction) \
++      dma_map_sg(aic->dev_softc, sg_list, num_sg, direction)
++
++#define       aic_unmap_sg(aic, sg_list, num_sg, direction) \
++      dma_unmap_sg(aic->dev_softc, sg_list, num_sg, direction)
++
++#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)
++
++#define       aic_alloc_coherent(aic, size, bus_addr_ptr) \
++      pci_alloc_consistent(aic->dev_softc, size, bus_addr_ptr)
++
++#define       aic_free_coherent(aic, size, vaddr, bus_addr) \
++      pci_free_consistent(aic->dev_softc, size, vaddr, bus_addr)
++
++#define       aic_map_single(aic, buf, size, direction) \
++      pci_map_single(aic->dev_softc, buf, size, direction)
++
++#define       aic_unmap_single(aic, busaddr, size, direction) \
++      pci_unmap_single(aic->dev_softc, busaddr, size, direction)
++
++#define       aic_map_sg(aic, sg_list, num_sg, direction) \
++      pci_map_sg(aic->dev_softc, sg_list, num_sg, direction)
++
++#define       aic_unmap_sg(aic, sg_list, num_sg, direction) \
++      pci_unmap_sg(aic->dev_softc, sg_list, num_sg, direction)
++
++#else
++
++static __inline void *aic_alloc_coherent(struct aic_softc *aic,
++                                       bus_size_t size, bus_addr_t *baddrp);
++
++/*
++ * At least in 2.2.14, malloc is a slab allocator so all
++ * allocations are aligned.  We assume for these kernel versions
++ * that all allocations will be bellow 4Gig, physically contiguous,
++ * and accessible via DMA by the controller.
++ */
++static __inline void *
++aic_alloc_coherent(struct aic_softc *aic, bus_size_t size, bus_addr_t *baddrp)
++{
++      void *vaddr;
++
++      vaddr_ = malloc(size, M_DEVBUF, M_NOWAIT);
++      if (vaddr != NULL)
++              *baddrp = virt_to_bus(vaddr);
++      return (vaddr);
++}
++
++#define       aic_free_coherent(aic, size, vaddr, bus_addr) \
++      free(vaddr, M_DEVBUF)
++
++#define aic_map_sg(pdev, sg_list, nseg, direction) (nseg)
++#define aic_unmap_sg(pdev, sg_list, nseg, direction)
++#define aic_map_single(pdev, buffer, bufflen, direction) \
++      (VIRT_TO_BUS(buffer))
++#define aic_unmap_single(pdev, buffer, buflen, direction)
++#define sg_dma_address(sg) (VIRT_TO_BUS((sg)->address))
++#define sg_dma_len(sg) ((sg)->length)
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++
++#define aic_set_dma_mask(aic, mask) dma_set_mask(aic->dev_softc, mask)
++
++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
++
++/*
++ * Device softc is NULL for EISA devices.
++ */
++#define aic_set_dma_mask(aic, mask)                   \
++      ((aic)->dev_softc == NULL ? 0 : pci_set_dma_mask(aic->dev_softc, mask))
++
++#else
++/*
++ * Device softc is NULL for EISA devices.
++ * Always "return" 0 for success.
++ */
++#define aic_set_dma_mask(aic, mask)                   \
++    (((aic)->dev_softc == NULL)                               \
++     ? 0                                              \
++     : (((aic)->dev_softc->dma_mask = mask) && 0))
++#endif
++
++/************************* Host Template Macros *******************************/
++#if defined CONFIG_HIGHIO
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
++/* Assume RedHat Distribution with its different HIGHIO conventions. */
++#define       AIC_TEMPLATE_DMA_SETTINGS()     \
++      .can_dma_32             = 1,    \
++      .single_sg_okay         = 1,
++#else
++#define       AIC_TEMPLATE_DMA_SETTINGS()     \
++      .highmem_io             = 1,
++#endif
++#else
++#define       AIC_TEMPLATE_DMA_SETTINGS()
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
++#define       AIC_TEMPLATE_MAX_SECTORS(sectors) \
++      .max_sectors            = (sectors),
++#else
++#define       AIC_TEMPLATE_MAX_SECTORS(sectors)
++#endif
++
++#if defined(__i386__)
++#define       AIC_TEMPLATE_BIOSPARAM() \
++      .bios_param             = AIC_LIB_ENTRY(_linux_biosparam),
++#else
++#define       AIC_TEMPLATE_BIOSPARAM()
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++#define       AIC_TEMPLATE_VERSIONED_ENTRIES() \
++      .slave_alloc            = AIC_LIB_ENTRY(_linux_slave_alloc), \
++      .slave_configure        = AIC_LIB_ENTRY(_linux_slave_configure), \
++      .slave_destroy          = AIC_LIB_ENTRY(_linux_slave_destroy)
++#else
++#define       AIC_TEMPLATE_VERSIONED_ENTRIES() \
++      .detect                 = AIC_LIB_ENTRY(_linux_detect), \
++      .release                = AIC_LIB_ENTRY(_linux_release), \
++      .select_queue_depths    = AIC_LIB_ENTRY(_linux_select_queue_depth), \
++      .use_new_eh_code        = 1
++#endif
++
++#define AIC_TEMPLATE_INITIALIZER(NAME, MAX_SECTORS)                   \
++{                                                                     \
++      .module                 = THIS_MODULE,                          \
++      .name                   = NAME,                                 \
++      .proc_info              = AIC_LIB_ENTRY(_linux_proc_info),      \
++      .info                   = AIC_LIB_ENTRY(_linux_info),           \
++      .queuecommand           = AIC_LIB_ENTRY(_linux_queue),          \
++      .eh_abort_handler       = AIC_LIB_ENTRY(_linux_abort),          \
++      .eh_device_reset_handler = AIC_LIB_ENTRY(_linux_dev_reset),     \
++      .eh_bus_reset_handler   = AIC_LIB_ENTRY(_linux_bus_reset),      \
++      .can_queue              = AIC_CONST_ENTRY(_MAX_QUEUE),          \
++      .this_id                = -1,                                   \
++      .cmd_per_lun            = 2,                                    \
++      .use_clustering         = ENABLE_CLUSTERING,                    \
++      AIC_TEMPLATE_MAX_SECTORS(MAX_SECTORS)                           \
++      AIC_TEMPLATE_DMA_SETTINGS()                                     \
++      AIC_TEMPLATE_BIOSPARAM()                                        \
++      AIC_TEMPLATE_VERSIONED_ENTRIES()                                \
++}
++
++/************************** OS Utility Wrappers *******************************/
++#define printf printk
++#define M_NOWAIT GFP_ATOMIC
++#define M_WAITOK 0
++#define malloc(size, type, flags) kmalloc(size, flags)
++#define free(ptr, type) kfree(ptr)
++
++static __inline void aic_delay(long);
++static __inline void
++aic_delay(long usec)
++{
++      /*
++       * udelay on Linux can have problems for
++       * multi-millisecond waits.  Wait at most
++       * 1024us per call.
++       */
++      while (usec > 0) {
++              udelay(usec % 1024);
++              usec -= 1024;
++      }
++}
++
++/********************************** Misc Macros *******************************/
++#define       roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
++#define       powerof2(x)     ((((x)-1)&(x))==0)
++
++/******************************* Byte Order ***********************************/
++#define aic_htobe16(x)        cpu_to_be16(x)
++#define aic_htobe32(x)        cpu_to_be32(x)
++#define aic_htobe64(x)        cpu_to_be64(x)
++#define aic_htole16(x)        cpu_to_le16(x)
++#define aic_htole32(x)        cpu_to_le32(x)
++#define aic_htole64(x)        cpu_to_le64(x)
++
++#define aic_be16toh(x)        be16_to_cpu(x)
++#define aic_be32toh(x)        be32_to_cpu(x)
++#define aic_be64toh(x)        be64_to_cpu(x)
++#define aic_le16toh(x)        le16_to_cpu(x)
++#define aic_le32toh(x)        le32_to_cpu(x)
++#define aic_le64toh(x)        le64_to_cpu(x)
++
++#ifndef LITTLE_ENDIAN
++#define LITTLE_ENDIAN 1234
++#endif
++
++#ifndef BIG_ENDIAN
++#define BIG_ENDIAN 4321
++#endif
++
++#ifndef BYTE_ORDER
++#if defined(__BIG_ENDIAN)
++#define BYTE_ORDER BIG_ENDIAN
++#endif
++#if defined(__LITTLE_ENDIAN)
++#define BYTE_ORDER LITTLE_ENDIAN
++#endif
++#endif /* BYTE_ORDER */
++
++/********************************* Core Includes ******************************/
++#include AIC_CORE_INCLUDE
++
++/**************************** Front End Queues ********************************/
++/*
++ * Data structure used to cast the Linux struct scsi_cmnd to something
++ * that allows us to use the queue macros.  The linux structure has
++ * plenty of space to hold the links fields as required by the queue
++ * macros, but the queue macors require them to have the correct type.
++ */
++struct aic_cmd_internal {
++      /* Area owned by the Linux scsi layer. */
++      uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)];
++      union {
++              STAILQ_ENTRY(aic_cmd)   ste;
++              LIST_ENTRY(aic_cmd)     le;
++              TAILQ_ENTRY(aic_cmd)    tqe;
++      } links;
++      uint32_t                        end;
++};
++
++struct aic_cmd {
++      union {
++              struct aic_cmd_internal icmd;
++              struct scsi_cmnd        scsi_cmd;
++      } un;
++};
++
++#define acmd_icmd(cmd) ((cmd)->un.icmd)
++#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd)
++#define acmd_links un.icmd.links
++
++/*************************** Device Data Structures ***************************/
++/*
++ * A per probed device structure used to deal with some error recovery
++ * scenarios that the Linux mid-layer code just doesn't know how to
++ * handle.  The structure allocated for a device only becomes persistent
++ * after a successfully completed inquiry command to the target when
++ * that inquiry data indicates a lun is present.
++ */
++TAILQ_HEAD(aic_busyq, aic_cmd);
++typedef enum {
++      AIC_DEV_UNCONFIGURED     = 0x01,
++      AIC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
++      AIC_DEV_TIMER_ACTIVE     = 0x04, /* Our timer is active */
++      AIC_DEV_ON_RUN_LIST      = 0x08, /* Queued to be run later */
++      AIC_DEV_Q_BASIC          = 0x10, /* Allow basic device queuing */
++      AIC_DEV_Q_TAGGED         = 0x20, /* Allow full SCSI2 command queueing */
++      AIC_DEV_PERIODIC_OTAG    = 0x40, /* Send OTAG to prevent starvation */
++      AIC_DEV_SLAVE_CONFIGURED = 0x80  /* slave_configure() has been called */
++} aic_linux_dev_flags;
++
++struct aic_linux_target;
++struct aic_linux_device {
++      TAILQ_ENTRY(aic_linux_device) links;
++      struct                  aic_busyq busyq;
++
++      /*
++       * The number of transactions currently
++       * queued to the device.
++       */
++      int                     active;
++
++      /*
++       * The currently allowed number of 
++       * transactions that can be queued to
++       * the device.  Must be signed for
++       * conversion from tagged to untagged
++       * mode where the device may have more
++       * than one outstanding active transaction.
++       */
++      int                     openings;
++
++      /*
++       * A positive count indicates that this
++       * device's queue is halted.
++       */
++      u_int                   qfrozen;
++      
++      /*
++       * Cumulative command counter.
++       */
++      u_long                  commands_issued;
++
++      /*
++       * The number of tagged transactions when
++       * running at our current opening level
++       * that have been successfully received by
++       * this device since the last QUEUE FULL.
++       */
++      u_int                   tag_success_count;
++#define AIC_TAG_SUCCESS_INTERVAL 50
++
++      aic_linux_dev_flags     flags;
++
++      /*
++       * Per device timer.
++       */
++      struct timer_list       timer;
++
++      /*
++       * The high limit for the tags variable.
++       */
++      u_int                   maxtags;
++
++      /*
++       * The computed number of tags outstanding
++       * at the time of the last QUEUE FULL event.
++       */
++      u_int                   tags_on_last_queuefull;
++
++      /*
++       * How many times we have seen a queue full
++       * with the same number of tags.  This is used
++       * to stop our adaptive queue depth algorithm
++       * on devices with a fixed number of tags.
++       */
++      u_int                   last_queuefull_same_count;
++#define AIC_LOCK_TAGS_COUNT 50
++
++      /*
++       * How many transactions have been queued
++       * without the device going idle.  We use
++       * this statistic to determine when to issue
++       * an ordered tag to prevent transaction
++       * starvation.  This statistic is only updated
++       * if the AIC_DEV_PERIODIC_OTAG flag is set
++       * on this device.
++       */
++      u_int                   commands_since_idle_or_otag;
++#define AIC_OTAG_THRESH       500
++
++      int                     lun;
++      Scsi_Device            *scsi_device;
++      struct                  aic_linux_target *target;
++};
++
++typedef enum {
++      AIC_DV_REQUIRED          = 0x01,
++      AIC_INQ_VALID            = 0x02,
++      AIC_BASIC_DV             = 0x04,
++      AIC_ENHANCED_DV          = 0x08
++} aic_linux_targ_flags;
++
++/* DV States */
++typedef enum {
++      AIC_DV_STATE_EXIT = 0,
++      AIC_DV_STATE_INQ_SHORT_ASYNC,
++      AIC_DV_STATE_INQ_ASYNC,
++      AIC_DV_STATE_INQ_ASYNC_VERIFY,
++      AIC_DV_STATE_TUR,
++      AIC_DV_STATE_REBD,
++      AIC_DV_STATE_INQ_VERIFY,
++      AIC_DV_STATE_WEB,
++      AIC_DV_STATE_REB,
++      AIC_DV_STATE_SU,
++      AIC_DV_STATE_BUSY
++} aic_dv_state;
++
++struct aic_linux_target {
++      struct aic_linux_device  *devices[AIC_NUM_LUNS];
++      int                       channel;
++      int                       target;
++      int                       refcount;
++      struct aic_transinfo      last_tinfo;
++      struct aic_softc         *softc;
++      aic_linux_targ_flags      flags;
++      struct scsi_inquiry_data *inq_data;
++      /*
++       * The next "fallback" period to use for narrow/wide transfers.
++       */
++      uint8_t                   dv_next_narrow_period;
++      uint8_t                   dv_next_wide_period;
++      uint8_t                   dv_max_width;
++      uint8_t                   dv_max_ppr_options;
++      uint8_t                   dv_last_ppr_options;
++      u_int                     dv_echo_size;
++      aic_dv_state              dv_state;
++      u_int                     dv_state_retry;
++      uint8_t                  *dv_buffer;
++      uint8_t                  *dv_buffer1;
++
++      /*
++       * Cumulative counter of errors.
++       */
++      u_long                  errors_detected;
++      u_long                  cmds_since_error;
++};
++
++/*************** OSM Dependent Components of Core Datastructures **************/
++/*
++ * Per-SCB OSM storage.
++ */
++typedef enum {
++      AIC_SCB_UP_EH_SEM       = 0x1,
++      AIC_TIMEOUT_ACTIVE      = 0x2,
++      AIC_RELEASE_SIMQ        = 0x4
++} aic_linux_scb_flags;
++
++struct scb_platform_data {
++      struct aic_linux_device *dev;
++      bus_addr_t               buf_busaddr;
++      uint32_t                 xfer_len;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
++      uint32_t                 resid;         /* Transfer residual */
++#endif
++      uint32_t                 sense_resid;   /* Auto-Sense residual */
++      aic_linux_scb_flags      flags;
++};
++
++/*
++ * Define a structure used for each host adapter.  All members are
++ * aligned on a boundary >= the size of the member to honor the
++ * alignment restrictions of the various platforms supported by
++ * this driver.
++ */
++typedef enum {
++      AIC_DV_WAIT_SIMQ_EMPTY   = 0x01,
++      AIC_DV_WAIT_SIMQ_RELEASE = 0x02,
++      AIC_DV_ACTIVE            = 0x04,
++      AIC_DV_SHUTDOWN          = 0x08,
++      AIC_RUN_CMPLT_Q_TIMER    = 0x10,
++      AIC_BUS_SETTLE_TIMER     = 0x20
++} aic_linux_softc_flags;
++
++TAILQ_HEAD(aic_completeq, aic_cmd);
++
++struct aic_platform_data {
++      /*
++       * Fields accessed from interrupt context.
++       */
++      struct aic_linux_target *targets[AIC_NUM_TARGETS]; 
++      TAILQ_HEAD(, aic_linux_device) device_runq;
++      struct aic_completeq     completeq;
++
++      spinlock_t               spin_lock;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++      struct tasklet_struct    runq_tasklet;
++      struct tasklet_struct    unblock_tasklet;
++#endif
++      u_int                    qfrozen;
++      pid_t                    dv_pid;
++      pid_t                    recovery_pid;
++      struct timer_list        completeq_timer;
++      struct timer_list        bus_settle_timer;
++      struct timer_list        stats_timer;
++      struct semaphore         eh_sem;
++      struct semaphore         dv_sem;
++      struct semaphore         dv_cmd_sem;
++      struct semaphore         recovery_sem;
++      struct semaphore         recovery_ending_sem;
++      struct scsi_device      *dv_scsi_dev;
++      struct Scsi_Host        *host;          /* pointer to scsi host */
++#define AIC_LINUX_NOIRQ       ((uint32_t)~0)
++      uint32_t                 irq;           /* IRQ for this adapter */
++      uint32_t                 bios_address;
++      uint32_t                 mem_busaddr;   /* Mem Base Addr */
++      bus_addr_t               hw_dma_mask;
++      aic_linux_softc_flags    flags;
++};
++
++/***************************** Timer Facilities *******************************/
++typedef void aic_linux_callback_t (u_long);  
++void aic_platform_timeout(struct scsi_cmnd *);
++void aic_linux_midlayer_timeout(struct scsi_cmnd *);
++
++#define aic_timer_init init_timer
++#define aic_timer_stop del_timer_sync
++static __inline void aic_timer_reset(aic_timer_t *timer, uint32_t usec,
++                                   aic_callback_t *func, void *arg);
++static __inline uint32_t aic_get_timeout(struct scb *);
++static __inline void aic_scb_timer_start(struct scb *scb);
++static __inline void aic_scb_timer_reset(struct scb *scb, uint32_t usec);
++static __inline void
++aic_timer_reset(aic_timer_t *timer, uint32_t usec,
++              aic_callback_t *func, void *arg)
++{
++      struct aic_softc *aic;
++
++      aic = (struct aic_softc *)arg;
++      del_timer(timer);
++      timer->data = (u_long)arg;
++      timer->expires = jiffies + (usec / AIC_USECS_PER_JIFFY);
++      timer->function = (aic_linux_callback_t*)func;
++      add_timer(timer);
++}
++
++static __inline uint32_t
++aic_get_timeout(struct scb *scb)
++{
++
++      /*
++       * Convert from jiffies to usec.
++       */
++      return (scb->io_ctx->timeout_per_command * AIC_USECS_PER_JIFFY);
++}
++
++static __inline void
++aic_scb_timer_start(struct scb *scb)
++{
++      scb->platform_data->flags |= AIC_TIMEOUT_ACTIVE;
++      scsi_add_timer(scb->io_ctx, scb->io_ctx->timeout_per_command,
++                     aic_platform_timeout);
++}
++
++static __inline void
++aic_scb_timer_reset(struct scb *scb, uint32_t usec)
++{
++      /*
++       * Restore timer data that is clobbered by scsi_delete_timer().
++       */
++      scb->io_ctx->eh_timeout.data = (unsigned long)scb->io_ctx;
++      scb->io_ctx->eh_timeout.function =
++          (void (*)(unsigned long))aic_platform_timeout;
++      scb->platform_data->flags |= AIC_TIMEOUT_ACTIVE;
++      mod_timer(&scb->io_ctx->eh_timeout,
++                jiffies + (usec / AIC_USECS_PER_JIFFY));
++}
++
++/************************* SCSI command formats *******************************/
+ /*
+  * Define dome bits that are in ALL (or a lot of) scsi commands
+  */
+@@ -865,6 +1624,368 @@ typedef enum {
+ extern const char *scsi_sense_key_text[];
++/*************************** Domain Validation ********************************/
++#define AIC_DV_CMD(cmd) ((cmd)->scsi_done == aic_linux_dv_complete)
++#define AIC_DV_SIMQ_FROZEN(aic)                                       \
++      ((((aic)->platform_data->flags & AIC_DV_ACTIVE) != 0)   \
++       && (aic)->platform_data->qfrozen == 1)
++
++/*********************** Transaction Access Wrappers **************************/
++static __inline void aic_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t);
++static __inline void aic_set_transaction_status(struct scb *, uint32_t);
++static __inline void aic_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t);
++static __inline void aic_set_scsi_status(struct scb *, uint32_t);
++static __inline uint32_t aic_cmd_get_transaction_status(Scsi_Cmnd *cmd);
++static __inline uint32_t aic_get_transaction_status(struct scb *);
++static __inline uint32_t aic_cmd_get_scsi_status(Scsi_Cmnd *cmd);
++static __inline uint32_t aic_get_scsi_status(struct scb *);
++static __inline void aic_set_transaction_tag(struct scb *, int, u_int);
++static __inline u_long aic_get_transfer_length(struct scb *);
++static __inline int aic_get_transfer_dir(struct scb *);
++static __inline void aic_set_residual(struct scb *, u_long);
++static __inline void aic_set_sense_residual(struct scb *scb, u_long resid);
++static __inline u_long aic_get_residual(struct scb *);
++static __inline u_long aic_get_sense_residual(struct scb *);
++static __inline int aic_perform_autosense(struct scb *);
++static __inline uint32_t aic_get_sense_bufsize(struct aic_softc *,
++                                             struct scb *);
++static __inline void aic_notify_xfer_settings_change(struct aic_softc *,
++                                                   struct aic_devinfo *);
++static __inline void aic_platform_scb_free(struct aic_softc *aic,
++                                         struct scb *scb);
++static __inline void aic_freeze_scb(struct scb *scb);
++
++static __inline
++void aic_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status)
++{
++      cmd->result &= ~(CAM_STATUS_MASK << 16);
++      cmd->result |= status << 16;
++}
++
++static __inline
++void aic_set_transaction_status(struct scb *scb, uint32_t status)
++{
++      aic_cmd_set_transaction_status(scb->io_ctx,status);
++}
++
++static __inline
++void aic_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status)
++{
++      cmd->result &= ~0xFFFF;
++      cmd->result |= status;
++}
++
++static __inline
++void aic_set_scsi_status(struct scb *scb, uint32_t status)
++{
++      aic_cmd_set_scsi_status(scb->io_ctx, status);
++}
++
++static __inline
++uint32_t aic_cmd_get_transaction_status(Scsi_Cmnd *cmd)
++{
++      return ((cmd->result >> 16) & CAM_STATUS_MASK);
++}
++
++static __inline
++uint32_t aic_get_transaction_status(struct scb *scb)
++{
++      return (aic_cmd_get_transaction_status(scb->io_ctx));
++}
++
++static __inline
++uint32_t aic_cmd_get_scsi_status(Scsi_Cmnd *cmd)
++{
++      return (cmd->result & 0xFFFF);
++}
++
++static __inline
++uint32_t aic_get_scsi_status(struct scb *scb)
++{
++      return (aic_cmd_get_scsi_status(scb->io_ctx));
++}
++
++static __inline
++void aic_set_transaction_tag(struct scb *scb, int enabled, u_int type)
++{
++      /*
++       * Nothing to do for linux as the incoming transaction
++       * has no concept of tag/non tagged, etc.
++       */
++}
++
++static __inline
++u_long aic_get_transfer_length(struct scb *scb)
++{
++      return (scb->platform_data->xfer_len);
++}
++
++static __inline
++int aic_get_transfer_dir(struct scb *scb)
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,40)
++      return (scb->io_ctx->sc_data_direction);
++#else
++      if (scb->io_ctx->bufflen == 0)
++              return (CAM_DIR_NONE);
++
++      switch(scb->io_ctx->cmnd[0]) {
++      case 0x08:  /* READ(6)  */
++      case 0x28:  /* READ(10) */
++      case 0xA8:  /* READ(12) */
++              return (CAM_DIR_IN);
++        case 0x0A:  /* WRITE(6)  */
++        case 0x2A:  /* WRITE(10) */
++        case 0xAA:  /* WRITE(12) */
++              return (CAM_DIR_OUT);
++        default:
++              return (CAM_DIR_NONE);
++        }
++#endif
++}
++
++static __inline
++void aic_set_residual(struct scb *scb, u_long resid)
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
++      scb->io_ctx->resid = resid;
++#else
++      scb->platform_data->resid = resid;
++#endif
++}
++
++static __inline
++void aic_set_sense_residual(struct scb *scb, u_long resid)
++{
++      scb->platform_data->sense_resid = resid;
++}
++
++static __inline
++u_long aic_get_residual(struct scb *scb)
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
++      return (scb->io_ctx->resid);
++#else
++      return (scb->platform_data->resid);
++#endif
++}
++
++static __inline
++u_long aic_get_sense_residual(struct scb *scb)
++{
++      return (scb->platform_data->sense_resid);
++}
++
++static __inline
++int aic_perform_autosense(struct scb *scb)
++{
++      /*
++       * We always perform autosense in Linux.
++       * On other platforms this is set on a
++       * per-transaction basis.
++       */
++      return (1);
++}
++
++static __inline uint32_t
++aic_get_sense_bufsize(struct aic_softc *aic, struct scb *scb)
++{
++      return (sizeof(struct scsi_sense_data));
++}
++
++static __inline void
++aic_notify_xfer_settings_change(struct aic_softc *aic,
++                              struct aic_devinfo *devinfo)
++{
++      /* Nothing to do here for linux */
++}
++
++static __inline void
++aic_platform_scb_free(struct aic_softc *aic, struct scb *scb)
++{
++      aic->flags &= ~AIC_RESOURCE_SHORTAGE;
++}
++
++static __inline void
++aic_freeze_scb(struct scb *scb)
++{
++      if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
++                scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
++                scb->platform_data->dev->qfrozen++;
++        }
++}
++
++/******************************* PCI Definitions ******************************/
++/*
++ * PCIM_xxx: mask to locate subfield in register
++ * PCIR_xxx: config register offset
++ * PCIC_xxx: device class
++ * PCIS_xxx: device subclass
++ * PCIP_xxx: device programming interface
++ * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
++ * PCID_xxx: device ID
++ */
++#define PCIR_DEVVENDOR                0x00
++#define PCIR_VENDOR           0x00
++#define PCIR_DEVICE           0x02
++#define PCIR_COMMAND          0x04
++#define PCIM_CMD_PORTEN               0x0001
++#define PCIM_CMD_MEMEN                0x0002
++#define PCIM_CMD_BUSMASTEREN  0x0004
++#define PCIM_CMD_MWRICEN      0x0010
++#define PCIM_CMD_PERRESPEN    0x0040
++#define       PCIM_CMD_SERRESPEN      0x0100
++#define PCIR_STATUS           0x06
++#define PCIR_REVID            0x08
++#define PCIR_PROGIF           0x09
++#define PCIR_SUBCLASS         0x0a
++#define PCIR_CLASS            0x0b
++#define PCIR_CACHELNSZ                0x0c
++#define PCIR_LATTIMER         0x0d
++#define PCIR_HEADERTYPE               0x0e
++#define PCIM_MFDEV            0x80
++#define PCIR_BIST             0x0f
++#define PCIR_CAP_PTR          0x34
++
++/* config registers for header type 0 devices */
++#define PCIR_MAPS     0x10
++#define PCIR_BARS     PCIR_MAPS
++#define PCIR_BAR(x)   (PCIR_BARS + (x) * 4)
++#define PCIR_SUBVEND_0        0x2c
++#define PCIR_SUBDEV_0 0x2e
++
++typedef enum
++{
++      AIC_POWER_STATE_D0,
++      AIC_POWER_STATE_D1,
++      AIC_POWER_STATE_D2,
++      AIC_POWER_STATE_D3
++} aic_power_state;
++
++/****************************** PCI-X definitions *****************************/
++#define PCIXR_COMMAND 0x96
++#define PCIXR_DEVADDR 0x98
++#define PCIXM_DEVADDR_FNUM    0x0003  /* Function Number */
++#define PCIXM_DEVADDR_DNUM    0x00F8  /* Device Number */
++#define PCIXM_DEVADDR_BNUM    0xFF00  /* Bus Number */
++#define PCIXR_STATUS  0x9A
++#define PCIXM_STATUS_64BIT    0x0001  /* Active 64bit connection to device. */
++#define PCIXM_STATUS_133CAP   0x0002  /* Device is 133MHz capable */
++#define PCIXM_STATUS_SCDISC   0x0004  /* Split Completion Discarded */
++#define PCIXM_STATUS_UNEXPSC  0x0008  /* Unexpected Split Completion */
++#define PCIXM_STATUS_CMPLEXDEV        0x0010  /* Device Complexity (set == bridge) */
++#define PCIXM_STATUS_MAXMRDBC 0x0060  /* Maximum Burst Read Count */
++#define PCIXM_STATUS_MAXSPLITS        0x0380  /* Maximum Split Transactions */
++#define PCIXM_STATUS_MAXCRDS  0x1C00  /* Maximum Cumulative Read Size */
++#define PCIXM_STATUS_RCVDSCEM 0x2000  /* Received a Split Comp w/Error msg */
++
++/**************************** KObject Wrappers ********************************/
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++#define       aic_dev_to_pci_dev(dev)         to_pci_dev(dev)
++#define       aic_dev_to_eisa_dev(dev)        to_eisa_dev(dev)
++#define       aic_pci_dev_to_dev(pci)         (&pci->dev)
++#define       aic_eisa_dev_to_dev(eisa)       (&eisa->dev)
++#else
++#define       aic_dev_to_pci_dev(dev)         (dev)
++#define       aic_dev_to_eisa_dev(dev)        (NULL)
++#define       aic_pci_dev_to_dev(pci)         (pci)
++#define       aic_eisa_dev_to_dev(eisa)       (NULL)
++#endif
++
++#define       aic_pci_dev(aic)                aic_dev_to_pci_dev((aic)->dev_softc)
++#define       aic_eisa_dev(aic)               aic_dev_to_eisa_dev((aic)->dev_softc)
++/***************************** PCI Routines ***********************************/
++static __inline uint32_t aic_pci_read_config(aic_dev_softc_t dev,
++                                           int reg, int width);
++static __inline void aic_pci_write_config(aic_dev_softc_t dev,
++                                        int reg, uint32_t value,
++                                        int width);
++static __inline int aic_get_pci_function(aic_dev_softc_t);
++static __inline int aic_get_pci_slot(aic_dev_softc_t);
++static __inline int aic_get_pci_bus(aic_dev_softc_t);
++
++static __inline uint32_t
++aic_pci_read_config(aic_dev_softc_t dev, int reg, int width)
++{
++      struct pci_dev *pci;
++
++      pci = aic_dev_to_pci_dev(dev);
++      switch (width) {
++      case 1:
++      {
++              uint8_t retval;
++
++              pci_read_config_byte(pci, reg, &retval);
++              return (retval);
++      }
++      case 2:
++      {
++              uint16_t retval;
++              pci_read_config_word(pci, reg, &retval);
++              return (retval);
++      }
++      case 4:
++      {
++              uint32_t retval;
++              pci_read_config_dword(pci, reg, &retval);
++              return (retval);
++      }
++      default:
++              panic("aic_pci_read_config: Read size too big");
++              /* NOTREACHED */
++              return (0);
++      }
++}
++
++static __inline void
++aic_pci_write_config(aic_dev_softc_t dev, int reg, uint32_t value, int width)
++{
++      struct pci_dev *pci;
++
++      pci = aic_dev_to_pci_dev(dev);
++      switch (width) {
++      case 1:
++              pci_write_config_byte(pci, reg, value);
++              break;
++      case 2:
++              pci_write_config_word(pci, reg, value);
++              break;
++      case 4:
++              pci_write_config_dword(pci, reg, value);
++              break;
++      default:
++              panic("aic_pci_write_config: Write size too big");
++              /* NOTREACHED */
++      }
++}
++
++static __inline int
++aic_get_pci_function(aic_dev_softc_t dev)
++{
++      struct pci_dev *pci;
++
++      pci = aic_dev_to_pci_dev(dev);
++      return (PCI_FUNC(pci->devfn));
++}
++
++static __inline int
++aic_get_pci_slot(aic_dev_softc_t dev)
++{
++      struct pci_dev *pci;
++
++      pci = aic_dev_to_pci_dev(dev);
++      return (PCI_SLOT(pci->devfn));
++}
++
++static __inline int
++aic_get_pci_bus(aic_dev_softc_t dev)
++{
++      struct pci_dev *pci;
++
++      pci = aic_dev_to_pci_dev(dev);
++      return (pci->bus->number);
++}
++
+ /************************* Large Disk Handling ********************************/
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ static __inline int aic_sector_div(u_long capacity, int heads, int sectors);
+@@ -886,34 +2007,31 @@ aic_sector_div(sector_t capacity, int he
+ }
+ #endif
+-/**************************** Module Library Hack *****************************/
+-/*
+- * What we'd like to do is have a single "scsi library" module that both the
+- * aic7xxx and aic79xx drivers could load and depend on.  A cursory examination
+- * of implementing module dependencies in Linux (handling the install and
+- * initrd cases) does not look promissing.  For now, we just duplicate this
+- * code in both drivers using a simple symbol renaming scheme that hides this
+- * hack from the drivers.
+- */
+-#define AIC_LIB_ENTRY_CONCAT(x, prefix)       prefix ## x
+-#define       AIC_LIB_ENTRY_EXPAND(x, prefix) AIC_LIB_ENTRY_CONCAT(x, prefix)
+-#define AIC_LIB_ENTRY(x)              AIC_LIB_ENTRY_EXPAND(x, AIC_LIB_PREFIX)
++/************************* Magic SysReq Support *******************************/
++#include <linux/sysrq.h>
+-#define       aic_sense_desc                  AIC_LIB_ENTRY(_sense_desc)
+-#define       aic_sense_error_action          AIC_LIB_ENTRY(_sense_error_action)
+-#define       aic_error_action                AIC_LIB_ENTRY(_error_action)
+-#define       aic_op_desc                     AIC_LIB_ENTRY(_op_desc)
+-#define       aic_cdb_string                  AIC_LIB_ENTRY(_cdb_string)
+-#define aic_print_inquiry             AIC_LIB_ENTRY(_print_inquiry)
+-#define aic_calc_syncsrate            AIC_LIB_ENTRY(_calc_syncrate)
+-#define       aic_calc_syncparam              AIC_LIB_ENTRY(_calc_syncparam)
+-#define       aic_calc_speed                  AIC_LIB_ENTRY(_calc_speed)
+-#define       aic_inquiry_match               AIC_LIB_ENTRY(_inquiry_match)
+-#define       aic_static_inquiry_match        AIC_LIB_ENTRY(_static_inquiry_match)
+-#define       aic_parse_brace_option          AIC_LIB_ENTRY(_parse_brace_option)
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
++typedef void aic_sysrq_handler_t (int, struct pt_regs *, struct kbd_struct *,
++                                struct tty_struct *);
++#else
++typedef void aic_sysrq_handler_t (int, struct pt_regs *, struct tty_struct *);
++#endif
+-/******************************************************************************/
++#ifdef CONFIG_MAGIC_SYSRQ
++#define       aic_sysrq_key_op sysrq_key_op
++#else
++struct aic_sysrq_key_op {
++      aic_sysrq_handler_t *handler;
++      char *help_msg;
++      char *action_msg;
++};
++#endif
++aic_sysrq_handler_t   aic_sysrq_handler;
++int                   aic_install_sysrq(struct aic_sysrq_key_op *);
++void                  aic_remove_sysrq(int key,
++                                       struct aic_sysrq_key_op *key_op);
++/************************ SCSI Library Functions *****************************/
+ void                  aic_sense_desc(int /*sense_key*/, int /*asc*/,
+                                      int /*ascq*/, struct scsi_inquiry_data*,
+                                      const char** /*sense_key_desc*/,
+@@ -1043,4 +2161,115 @@ scsi_4btoul(uint8_t *bytes)
+       return (rv);
+ }
++/******************************* PCI Funcitons ********************************/
++void aic_power_state_change(struct aic_softc *aic, aic_power_state new_state);
++
++/******************************* Queue Handling *******************************/
++void               aic_runq_tasklet(unsigned long data);
++void               aic_unblock_tasklet(unsigned long data);
++void               aic_linux_run_device_queue(struct aic_softc*,
++                                              struct aic_linux_device*);
++void               aic_bus_settle_complete(u_long data);
++void               aic_freeze_simq(struct aic_softc *aic);
++void               aic_release_simq(struct aic_softc *aic);
++void               aic_release_simq_locked(struct aic_softc *aic);
++static __inline void aic_schedule_runq(struct aic_softc *aic);
++static __inline void aic_schedule_unblock(struct aic_softc *aic);
++static __inline struct aic_linux_device *
++                   aic_linux_next_device_to_run(struct aic_softc *aic);
++static __inline void aic_linux_check_device_queue(struct aic_softc *aic,
++                                                struct aic_linux_device *dev);
++static __inline void aic_linux_run_device_queues(struct aic_softc *aic);
++
++/*
++ * Must be called with our lock held.
++ */
++static __inline void
++aic_schedule_runq(struct aic_softc *aic)
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++      tasklet_schedule(&aic->platform_data->runq_tasklet);
++#else
++      /*
++       * Tasklets are not available, so run inline.
++       */
++      aic_runq_tasklet((unsigned long)aic);
++#endif
++}
++
++static __inline void
++aic_schedule_unblock(struct aic_softc *aic)
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++      tasklet_schedule(&aic->platform_data->unblock_tasklet);
++#else
++#error "Fix 2.2.X Kernel Support"
++#endif
++}
++
++static __inline struct aic_linux_device *
++aic_linux_next_device_to_run(struct aic_softc *aic)
++{
++      
++      if ((aic->flags & AIC_RESOURCE_SHORTAGE) != 0
++       || (aic->platform_data->qfrozen != 0
++        && AIC_DV_SIMQ_FROZEN(aic) == 0))
++              return (NULL);
++      return (TAILQ_FIRST(&aic->platform_data->device_runq));
++}
++
++static __inline void
++aic_linux_check_device_queue(struct aic_softc *aic,
++                           struct aic_linux_device *dev)
++{
++      if ((dev->flags & AIC_DEV_FREEZE_TIL_EMPTY) != 0
++       && dev->active == 0) {
++              dev->flags &= ~AIC_DEV_FREEZE_TIL_EMPTY;
++              dev->qfrozen--;
++      }
++
++      if (TAILQ_FIRST(&dev->busyq) == NULL
++       || dev->openings == 0 || dev->qfrozen != 0)
++              return;
++
++      aic_linux_run_device_queue(aic, dev);
++}
++
++static __inline void
++aic_linux_run_device_queues(struct aic_softc *aic)
++{
++      struct aic_linux_device *dev;
++
++      while ((dev = aic_linux_next_device_to_run(aic)) != NULL) {
++              TAILQ_REMOVE(&aic->platform_data->device_runq, dev, links);
++              dev->flags &= ~AIC_DEV_ON_RUN_LIST;
++              aic_linux_check_device_queue(aic, dev);
++      }
++}
++
++/****************************** Tasklet Support *******************************/
++static __inline void  aic_setup_tasklets(struct aic_softc *aic);
++static __inline void  aic_teardown_tasklets(struct aic_softc *aic);
++
++static __inline void
++aic_setup_tasklets(struct aic_softc *aic)
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++      tasklet_init(&aic->platform_data->runq_tasklet, aic_runq_tasklet,
++                   (unsigned long)aic);
++      tasklet_init(&aic->platform_data->unblock_tasklet, aic_unblock_tasklet,
++                   (unsigned long)aic);
++#endif
++}
++
++static __inline void
++aic_teardown_tasklets(struct aic_softc *aic)
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++      tasklet_kill(&aic->platform_data->runq_tasklet);
++      tasklet_kill(&aic->platform_data->unblock_tasklet);
++#endif
++}
++
++
+ #endif /*_AICLIB_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/aiclib_pci.c       2003-12-28 23:21:40.000000000 -0800
+@@ -0,0 +1,79 @@
++/*
++ * Implementation of Utility functions for PCI controller types.
++ *
++ * Copyright (c) 2000-2003 Adaptec Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions, and the following disclaimer,
++ *    without modification.
++ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
++ *    substantially similar to the "NO WARRANTY" disclaimer below
++ *    ("Disclaimer") and any redistribution must be conditioned upon
++ *    including a substantially similar Disclaimer requirement for further
++ *    binary redistribution.
++ * 3. Neither the names of the above-listed copyright holders nor the names
++ *    of any contributors may be used to endorse or promote products derived
++ *    from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL") version 2 as published by the Free
++ * Software Foundation.
++ *
++ * NO WARRANTY
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGES.
++ *
++ * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#25 $
++ */
++
++void
++aic_power_state_change(struct aic_softc *aic, aic_power_state new_state)
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++      pci_set_power_state(aic_dev_to_pci_dev(aic->dev_softc), new_state);
++#else
++      uint32_t cap;
++      u_int cap_offset;
++
++      /*
++       * Traverse the capability list looking for
++       * the power management capability.
++       */
++      cap = 0;
++      cap_offset = aic_pci_read_config(aic->dev_softc,
++                                       PCIR_CAP_PTR, /*bytes*/1);
++      while (cap_offset != 0) {
++
++              cap = aic_pci_read_config(aic->dev_softc,
++                                        cap_offset, /*bytes*/4);
++              if ((cap & 0xFF) == 1
++               && ((cap >> 16) & 0x3) > 0) {
++                      uint32_t pm_control;
++
++                      pm_control = aic_pci_read_config(aic->dev_softc,
++                                                       cap_offset + 4,
++                                                       /*bytes*/4);
++                      pm_control &= ~0x3;
++                      pm_control |= new_state;
++                      aic_pci_write_config(aic->dev_softc,
++                                           cap_offset + 4,
++                                           pm_control, /*bytes*/2);
++                      break;
++              }
++              cap_offset = (cap >> 8) & 0xFF;
++      }
++#endif 
++}
+--- linux-2.6.0/drivers/scsi/aic7xxx/Kconfig.aic7xxx   2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/scsi/aic7xxx/Kconfig.aic7xxx    2003-12-28 23:21:40.000000000 -0800
+@@ -1,18 +1,16 @@
+ #
+ # AIC7XXX and AIC79XX 2.5.X Kernel configuration File.
+-# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic7xxx#6 $
++# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic7xxx#8 $
+ #
+ config SCSI_AIC7XXX
+       tristate "Adaptec AIC7xxx Fast -> U160 support (New Driver)"
++      depends on PCI || EISA
+       ---help---
+       This driver supports all of Adaptec's Fast through Ultra 160 PCI
+       based SCSI controllers as well as the aic7770 based EISA and VLB
+       SCSI controllers (the 274x and 284x series).  For AAA and ARO based
+       configurations, only SCSI functionality is provided.
+-      To compile this driver as a module, choose M here: the
+-      module will be called aic7xxx.
+-
+ config AIC7XXX_CMDS_PER_DEVICE
+       int "Maximum number of TCQ commands per device"
+       depends on SCSI_AIC7XXX
+@@ -50,7 +48,7 @@ config AIC7XXX_RESET_DELAY_MS
+ config AIC7XXX_PROBE_EISA_VL
+       bool "Probe for EISA and VL AIC7XXX Adapters"
+-      depends on SCSI_AIC7XXX
++      depends on SCSI_AIC7XXX && EISA
+       help
+       Probe for EISA and VLB Aic7xxx controllers.  In many newer systems,
+       the invasive probes necessary to detect these controllers can cause
+--- linux-2.6.0/drivers/scsi/aic7xxx/Makefile  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/aic7xxx/Makefile   2003-12-28 23:21:40.000000000 -0800
+@@ -1,7 +1,7 @@
+ #
+ # Makefile for the Linux aic7xxx SCSI driver.
+ #
+-# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Makefile#6 $
++# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Makefile#8 $
+ #
+ # Let kbuild descend into aicasm when cleaning
+@@ -12,15 +12,15 @@ obj-$(CONFIG_SCSI_AIC79XX) += aic79xx.o
+ # Core Fast -> U160 files
+ aic7xxx-y                                     += aic7xxx_core.o       \
+-                                                 aic7xxx_93cx6.o      \
+-                                                 aic7770.o
++                                                 aic7xxx_93cx6.o
++aic7xxx-$(CONFIG_EISA)                                += aic7770.o
+ aic7xxx-$(CONFIG_PCI)                         += aic7xxx_pci.o
+ aic7xxx-$(CONFIG_AIC7XXX_REG_PRETTY_PRINT)    += aic7xxx_reg_print.o
+ # Platform Specific Fast -> U160 Files
+ aic7xxx-y                                     += aic7xxx_osm.o        \
+-                                                 aic7xxx_proc.o       \
+-                                                 aic7770_osm.o
++                                                 aic7xxx_proc.o
++aic7xxx-$(CONFIG_EISA)                                += aic7770_osm.o
+ aic7xxx-$(CONFIG_PCI)                         += aic7xxx_osm_pci.o
+ # Core U320 files
+@@ -58,6 +58,13 @@ aicasm-7xxx-opts-$(CONFIG_AIC7XXX_REG_PR
+       -p $(obj)/aic7xxx_reg_print.c -i aic7xxx_osm.h
+ ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y)
++# Create a dependency chain in generated files
++# to avoid concurrent invocations of the single
++# rule that builds them all.
++aic7xxx_seq.h: aic7xxx_reg.h
++ifeq ($(CONFIG_AIC7XXX_REG_PRETTY_PRINT),y)
++aic7xxx_reg.h: aic7xxx_reg_print.c
++endif
+ $(aic7xxx-gen-y): $(src)/aic7xxx.seq $(src)/aic7xxx.reg $(obj)/aicasm/aicasm
+       $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic7xxx_reg.h \
+                             $(aicasm-7xxx-opts-y) -o $(obj)/aic7xxx_seq.h \
+@@ -72,6 +79,13 @@ aicasm-79xx-opts-$(CONFIG_AIC79XX_REG_PR
+       -p $(obj)/aic79xx_reg_print.c -i aic79xx_osm.h
+ ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y)
++# Create a dependency chain in generated files
++# to avoid concurrent invocations of the single
++# rule that builds them all.
++aic79xx_seq.h: aic79xx_reg.h
++ifeq ($(CONFIG_AIC79XX_REG_PRETTY_PRINT),y)
++aic79xx_reg.h: aic79xx_reg_print.c
++endif
+ $(aic79xx-gen-y): $(src)/aic79xx.seq $(src)/aic79xx.reg $(obj)/aicasm/aicasm
+       $(obj)/aicasm/aicasm -I$(src) -r $(obj)/aic79xx_reg.h \
+                             $(aicasm-79xx-opts-y) -o $(obj)/aic79xx_seq.h \
+--- linux-2.6.0/drivers/scsi/aic7xxx_old/aic7xxx_proc.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/aic7xxx_old/aic7xxx_proc.c 2003-12-28 23:21:41.000000000 -0800
+@@ -90,9 +90,7 @@ aic7xxx_proc_info ( struct Scsi_Host *HB
+   unsigned char i;
+   unsigned char tindex;
+-  HBAptr = NULL;
+-
+-  for(p=first_aic7xxx; p->host != HBAptr; p=p->next)
++  for(p=first_aic7xxx; p && p->host != HBAptr; p=p->next)
+     ;
+   if (!p)
+--- linux-2.6.0/drivers/scsi/BusLogic.c        2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/scsi/BusLogic.c 2003-12-28 23:22:18.000000000 -0800
+@@ -3462,6 +3462,18 @@ static boolean BusLogic_WriteOutgoingMai
+   return false;
+ }
++/* Error Handling (EH) support */
++
++static int BusLogic_host_reset(Scsi_Cmnd *SCpnt)
++{
++      BusLogic_HostAdapter_T *HostAdapter =
++              (BusLogic_HostAdapter_T *) SCpnt->device->host->hostdata;
++
++      /* printk("BusLogic_host_reset\n"); */
++      HostAdapter->HostAdapterExternalReset = 1;
++      BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
++      return SUCCESS;
++}
+ /*
+   BusLogic_QueueCommand creates a CCB for Command and places it into an
+@@ -4589,220 +4601,8 @@ static boolean BusLogic_ParseKeyword(cha
+   adapters whereas the remaining options apply individually only to the
+   selected host adapter.
+-  The BusLogic Driver Probing Options comprise the following:
+-
+-  IO:<integer>
+-
+-    The "IO:" option specifies an ISA I/O Address to be probed for a non-PCI
+-    MultiMaster Host Adapter.  If neither "IO:" nor "NoProbeISA" options are
+-    specified, then the standard list of BusLogic MultiMaster ISA I/O Addresses
+-    will be probed (0x330, 0x334, 0x230, 0x234, 0x130, and 0x134).  Multiple
+-    "IO:" options may be specified to precisely determine the I/O Addresses to
+-    be probed, but the probe order will always follow the standard list.
+-
+-  NoProbe
+-
+-    The "NoProbe" option disables all probing and therefore no BusLogic Host
+-    Adapters will be detected.
+-
+-  NoProbeISA
+-
+-    The "NoProbeISA" option disables probing of the standard BusLogic ISA I/O
+-    Addresses and therefore only PCI MultiMaster and FlashPoint Host Adapters
+-    will be detected.
+-
+-  NoProbePCI
+-
+-    The "NoProbePCI" options disables the interrogation of PCI Configuration
+-    Space and therefore only ISA Multimaster Host Adapters will be detected, as
+-    well as PCI Multimaster Host Adapters that have their ISA Compatible I/O
+-    Port set to "Primary" or "Alternate".
+-
+-  NoSortPCI
+-
+-    The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be
+-    enumerated in the order provided by the PCI BIOS, ignoring any setting of
+-    the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option.
+-
+-  MultiMasterFirst
+-
+-    The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed
+-    before FlashPoint Host Adapters.  By default, if both FlashPoint and PCI
+-    MultiMaster Host Adapters are present, this driver will probe for
+-    FlashPoint Host Adapters first unless the BIOS primary disk is controlled
+-    by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host
+-    Adapters will be probed first.
+-
+-  FlashPointFirst
+-
+-    The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed
+-    before MultiMaster Host Adapters.
+-
+-  The BusLogic Driver Tagged Queuing Options allow for explicitly specifying
+-  the Queue Depth and whether Tagged Queuing is permitted for each Target
+-  Device (assuming that the Target Device supports Tagged Queuing).  The Queue
+-  Depth is the number of SCSI Commands that are allowed to be concurrently
+-  presented for execution (either to the Host Adapter or Target Device).  Note
+-  that explicitly enabling Tagged Queuing may lead to problems; the option to
+-  enable or disable Tagged Queuing is provided primarily to allow disabling
+-  Tagged Queuing on Target Devices that do not implement it correctly.  The
+-  following options are available:
+-
+-  QueueDepth:<integer>
+-
+-    The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all
+-    Target Devices that support Tagged Queuing, as well as the maximum Queue
+-    Depth for devices that do not support Tagged Queuing.  If no Queue Depth
+-    option is provided, the Queue Depth will be determined automatically based
+-    on the Host Adapter's Total Queue Depth and the number, type, speed, and
+-    capabilities of the detected Target Devices.  For Host Adapters that
+-    require ISA Bounce Buffers, the Queue Depth is automatically set by default
+-    to BusLogic_TaggedQueueDepthBB or BusLogic_UntaggedQueueDepthBB to avoid
+-    excessive preallocation of DMA Bounce Buffer memory.  Target Devices that
+-    do not support Tagged Queuing always have their Queue Depth set to
+-    BusLogic_UntaggedQueueDepth or BusLogic_UntaggedQueueDepthBB, unless a
+-    lower Queue Depth option is provided.  A Queue Depth of 1 automatically
+-    disables Tagged Queuing.
+-
+-  QueueDepth:[<integer>,<integer>...]
+-
+-    The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth
+-    individually for each Target Device.  If an <integer> is omitted, the
+-    associated Target Device will have its Queue Depth selected automatically.
+-
+-  TaggedQueuing:Default
+-
+-    The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing
+-    based on the firmware version of the BusLogic Host Adapter and based on
+-    whether the Queue Depth allows queuing multiple commands.
+-
+-  TaggedQueuing:Enable
+-
+-    The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for
+-    all Target Devices on this Host Adapter, overriding any limitation that
+-    would otherwise be imposed based on the Host Adapter firmware version.
+-
+-  TaggedQueuing:Disable
+-
+-    The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing
+-    for all Target Devices on this Host Adapter.
+-
+-  TaggedQueuing:<Target-Spec>
+-
+-    The "TaggedQueuing:<Target-Spec>" or "TQ:<Target-Spec>" option controls
+-    Tagged Queuing individually for each Target Device.  <Target-Spec> is a
+-    sequence of "Y", "N", and "X" characters.  "Y" enables Tagged Queuing, "N"
+-    disables Tagged Queuing, and "X" accepts the default based on the firmware
+-    version.  The first character refers to Target Device 0, the second to
+-    Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters
+-    does not cover all the Target Devices, unspecified characters are assumed
+-    to be "X".
+-
+-  The BusLogic Driver Error Recovery Option allows for explicitly specifying
+-  the Error Recovery action to be performed when BusLogic_ResetCommand is
+-  called due to a SCSI Command failing to complete successfully.  The following
+-  options are available:
+-
+-  ErrorRecovery:Default
+-
+-    The "ErrorRecovery:Default" or "ER:Default" option selects between the Hard
+-    Reset and Bus Device Reset options based on the recommendation of the SCSI
+-    Subsystem.
+-
+-  ErrorRecovery:HardReset
+-
+-    The "ErrorRecovery:HardReset" or "ER:HardReset" option will initiate a Host
+-    Adapter Hard Reset which also causes a SCSI Bus Reset.
+-
+-  ErrorRecovery:BusDeviceReset
+-
+-    The "ErrorRecovery:BusDeviceReset" or "ER:BusDeviceReset" option will send
+-    a Bus Device Reset message to the individual Target Device causing the
+-    error.  If Error Recovery is again initiated for this Target Device and no
+-    SCSI Command to this Target Device has completed successfully since the Bus
+-    Device Reset message was sent, then a Hard Reset will be attempted.
+-
+-  ErrorRecovery:None
+-
+-    The "ErrorRecovery:None" or "ER:None" option suppresses Error Recovery.
+-    This option should only be selected if a SCSI Bus Reset or Bus Device Reset
+-    will cause the Target Device or a critical operation to suffer a complete
+-    and unrecoverable failure.
+-
+-  ErrorRecovery:<Target-Spec>
+-
+-    The "ErrorRecovery:<Target-Spec>" or "ER:<Target-Spec>" option controls
+-    Error Recovery individually for each Target Device.  <Target-Spec> is a
+-    sequence of "D", "H", "B", and "N" characters.  "D" selects Default, "H"
+-    selects Hard Reset, "B" selects Bus Device Reset, and "N" selects None.
+-    The first character refers to Target Device 0, the second to Target Device
+-    1, and so on; if the sequence of "D", "H", "B", and "N" characters does not
+-    cover all the possible Target Devices, unspecified characters are assumed
+-    to be "D".
+-
+-  The BusLogic Driver Miscellaneous Options comprise the following:
+-
+-  BusSettleTime:<seconds>
+-
+-    The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in
+-    seconds.  The Bus Settle Time is the amount of time to wait between a Host
+-    Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI
+-    Commands.  If unspecified, it defaults to BusLogic_DefaultBusSettleTime.
+-
+-  InhibitTargetInquiry
+-
+-    The "InhibitTargetInquiry" option inhibits the execution of an Inquire
+-    Target Devices or Inquire Installed Devices command on MultiMaster Host
+-    Adapters.  This may be necessary with some older Target Devices that do not
+-    respond correctly when Logical Units above 0 are addressed.
+-
+-  The BusLogic Driver Debugging Options comprise the following:
+-
+-  TraceProbe
+-
+-    The "TraceProbe" option enables tracing of Host Adapter Probing.
+-
+-  TraceHardwareReset
+-
+-    The "TraceHardwareReset" option enables tracing of Host Adapter Hardware
+-    Reset.
+-
+-  TraceConfiguration
+-
+-    The "TraceConfiguration" option enables tracing of Host Adapter
+-    Configuration.
+-
+-  TraceErrors
+-
+-    The "TraceErrors" option enables tracing of SCSI Commands that return an
+-    error from the Target Device.  The CDB and Sense Data will be printed for
+-    each SCSI Command that fails.
+-
+-  Debug
+-
+-    The "Debug" option enables all debugging options.
+-
+-  The following examples demonstrate setting the Queue Depth for Target Devices
+-  1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target
+-  Devices on the second host adapter to 31, and the Bus Settle Time on the
+-  second host adapter to 30 seconds.
+-
+-  Linux Kernel Command Line:
+-
+-    linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30
+-
+-  LILO Linux Boot Loader (in /etc/lilo.conf):
+-
+-    append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"
+-
+-  INSMOD Loadable Kernel Module Installation Facility:
+-
+-    insmod BusLogic.o \
+-      'BusLogic="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
+-
+-  NOTE: Module Utilities 2.1.71 or later is required for correct parsing
+-      of driver options containing commas.
+-
++  The BusLogic Driver Probing Options are described in
++  <file:Documentation/scsi/BusLogic.txt>.
+ */
+ static int __init BusLogic_ParseDriverOptions(char *OptionsString)
+@@ -5126,6 +4926,7 @@ static SCSI_Host_Template_T driver_templ
+       .queuecommand           = BusLogic_QueueCommand,
+       .slave_configure        = BusLogic_SlaveConfigure,
+       .bios_param             = BusLogic_BIOSDiskParameters,
++      .eh_host_reset_handler  = BusLogic_host_reset,
+       .unchecked_isa_dma      = 1,
+       .max_sectors            = 128,
+       .use_clustering         = ENABLE_CLUSTERING,
+--- linux-2.6.0/drivers/scsi/hosts.c   2003-11-23 19:03:01.000000000 -0800
++++ 25/drivers/scsi/hosts.c    2003-12-28 23:22:30.000000000 -0800
+@@ -109,7 +109,7 @@ int scsi_add_host(struct Scsi_Host *shos
+       }
+       if (!shost->shost_gendev.parent)
+-              shost->shost_gendev.parent = dev ? dev : &legacy_bus;
++              shost->shost_gendev.parent = dev ? dev : &platform_bus;
+       error = device_add(&shost->shost_gendev);
+       if (error)
+--- linux-2.6.0/drivers/scsi/ide-scsi.c        2003-12-17 21:20:02.000000000 -0800
++++ 25/drivers/scsi/ide-scsi.c 2003-12-28 23:21:17.000000000 -0800
+@@ -636,24 +636,23 @@ static ide_driver_t idescsi_driver = {
+       .drives                 = LIST_HEAD_INIT(idescsi_driver.drives),
+ };
+-static int idescsi_ide_open(struct inode *inode, struct file *filp)
++static int idescsi_ide_open(struct block_device *bdev, struct file *filp)
+ {
+-      ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++      ide_drive_t *drive = bdev->bd_disk->private_data;
+       drive->usage++;
+       return 0;
+ }
+-static int idescsi_ide_release(struct inode *inode, struct file *filp)
++static int idescsi_ide_release(struct gendisk *disk)
+ {
+-      ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
++      ide_drive_t *drive = disk->private_data;
+       drive->usage--;
+       return 0;
+ }
+-static int idescsi_ide_ioctl(struct inode *inode, struct file *file,
++static int idescsi_ide_ioctl(struct block_device *bdev, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+ {
+-      struct block_device *bdev = inode->i_bdev;
+       return generic_ide_ioctl(bdev, cmd, arg);
+ }
+--- linux-2.6.0/drivers/scsi/Kconfig   2003-11-23 19:03:01.000000000 -0800
++++ 25/drivers/scsi/Kconfig    2003-12-28 23:21:49.000000000 -0800
+@@ -55,6 +55,14 @@ config BLK_DEV_SD
+         In this case, do not compile the driver for your SCSI host adapter
+         (below) as a module either.
++config MAX_SD_DISKS
++      int "Maximum number of SCSI disks to support (256-8192)"
++      depends on BLK_DEV_SD
++      default "256"
++      help
++      The maximum number SCSI disks to support. Default is 256.
++      Change this value if you want kernel to support lots of SCSI devices.
++
+ config CHR_DEV_ST
+       tristate "SCSI tape support"
+       depends on SCSI
+@@ -911,37 +919,34 @@ config SCSI_SYM53C8XX_DMA_ADDRESSING_MOD
+       depends on SCSI_SYM53C8XX_2
+       default "1"
+       ---help---
+-        This option only applies to PCI-SCSI chip that are PCI DAC capable 
+-        (875A, 895A, 896, 1010-33, 1010-66, 1000).
++        This option only applies to PCI-SCSI chips that are PCI DAC
++        capable (875A, 895A, 896, 1010-33, 1010-66, 1000).
+-        When set to 0, only PCI 32 bit DMA addressing (SAC) will be performed.
+-        When set to 1, 40 bit DMA addressing (with upper 24 bits of address 
+-        set to zero) is supported. The addressable range is here 1 TB.
+-        When set to 2, full 64 bits of address for DMA are supported, but only
+-        16 segments of 4 GB can be addressed. The addressable range is so 
+-        limited to 64 GB.
+-
+-        The safest value is 0 (32 bit DMA addressing) that is guessed to still 
+-        fit most of real machines.
+-
+-        The preferred value 1 (40 bit DMA addressing) should make happy 
+-        properly engineered PCI DAC capable host bridges. You may configure
+-        this option for Intel platforms with more than 4 GB of memory.
+-
+-        The still experimental value 2 (64 bit DMA addressing with 16 x 4GB 
+-        segments limitation) can be used on systems that require PCI address 
+-        bits past bit 39 to be set for the addressing of memory using PCI 
+-        DAC cycles.
++        When set to 0, the driver will program the chip to only perform
++        32-bit DMA.  When set to 1, the chip will be able to perform DMA
++        to addresses up to 1TB.  When set to 2, the driver supports the
++        full 64-bit DMA address range, but can only address 16 segments
++        of 4 GB each.  This limits the total addressable range to 64 GB.
++
++        Most machines with less than 4GB of memory should use a setting
++        of 0 for best performance.  If your machine has 4GB of memory
++        or more, you should set this option to 1 (the default).
++
++        The still experimental value 2 (64 bit DMA addressing with 16
++        x 4GB segments limitation) can be used on systems that require
++        PCI address bits past bit 39 to be set for the addressing of
++        memory using PCI DAC cycles.
+ config SCSI_SYM53C8XX_DEFAULT_TAGS
+       int "default tagged command queue depth"
+       depends on SCSI_SYM53C8XX_2
+       default "16"
+       help
+-        This is the default value of the command queue depth the driver will 
+-        announce to the generic SCSI layer for devices that support tagged 
+-        command queueing. This value can be changed from the boot command line.
+-        This is a soft limit that cannot exceed CONFIG_SCSI_SYM53C8XX_MAX_TAGS.
++        This is the default value of the command queue depth the
++        driver will announce to the generic SCSI layer for devices
++        that support tagged command queueing. This value can be changed
++        from the boot command line.  This is a soft limit that cannot
++        exceed CONFIG_SCSI_SYM53C8XX_MAX_TAGS.
+ config SCSI_SYM53C8XX_MAX_TAGS
+       int "maximum number of queued commands"
+@@ -954,11 +959,12 @@ config SCSI_SYM53C8XX_MAX_TAGS
+         This value is used as a compiled-in hard limit.
+ config SCSI_SYM53C8XX_IOMAPPED
+-      bool "use normal IO"
++      bool "use port IO"
+       depends on SCSI_SYM53C8XX_2
+       help
+-        If you say Y here, the driver will preferently use normal IO rather than 
+-        memory mapped IO.
++        If you say Y here, the driver will use port IO to access
++        the card.  This is significantly slower then using memory
++        mapped IO.  Most people should answer N.
+ config SCSI_ZALON
+       tristate "Zalon SCSI support"
+--- linux-2.6.0/drivers/scsi/pcmcia/aha152x_stub.c     2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/scsi/pcmcia/aha152x_stub.c      2003-12-28 23:22:54.000000000 -0800
+@@ -153,7 +153,7 @@ static dev_link_t *aha152x_attach(void)
+       CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != 0) {
+       cs_error(link->handle, RegisterClient, ret);
+       aha152x_detach(link);
+@@ -181,7 +181,7 @@ static void aha152x_detach(dev_link_t *l
+       aha152x_release_cs(link);
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     
+     /* Unlink device structure, free bits */
+     *linkp = link->next;
+@@ -191,11 +191,8 @@ static void aha152x_detach(dev_link_t *l
+ /*====================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void aha152x_config_cs(dev_link_t *link)
+ {
+@@ -214,19 +211,20 @@ static void aha152x_config_cs(dev_link_t
+     tuple.TupleData = tuple_data;
+     tuple.TupleDataMax = 64;
+     tuple.TupleOffset = 0;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     /* Configure card */
+     link->state |= DEV_CONFIG;
+     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     while (1) {
+-      CFG_CHECK(GetTupleData, handle, &tuple);
+-      CFG_CHECK(ParseTuple, handle, &tuple, &parse);
++      if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++              pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
++          goto next_entry;
+       /* For New Media T&J, look for a SCSI window */
+       if (parse.cftable_entry.io.win[0].len >= 0x20)
+           link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
+@@ -236,15 +234,15 @@ static void aha152x_config_cs(dev_link_t
+       if ((parse.cftable_entry.io.nwin > 0) &&
+           (link->io.BasePort1 < 0xffff)) {
+           link->conf.ConfigIndex = parse.cftable_entry.index;
+-          i = CardServices(RequestIO, handle, &link->io);
++          i = pcmcia_request_io(handle, &link->io);
+           if (i == CS_SUCCESS) break;
+       }
+     next_entry:
+-      CS_CHECK(GetNextTuple, handle, &tuple);
++      CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
+     }
+     
+-    CS_CHECK(RequestIRQ, handle, &link->irq);
+-    CS_CHECK(RequestConfiguration, handle, &link->conf);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
+     
+     /* A bad hack... */
+     release_region(link->io.BasePort1, link->io.NumPorts1);
+@@ -291,9 +289,9 @@ static void aha152x_release_cs(dev_link_
+       scsi_remove_host(info->host);
+       link->dev = NULL;
+     
+-      CardServices(ReleaseConfiguration, link->handle);
+-      CardServices(ReleaseIO, link->handle, &link->io);
+-      CardServices(ReleaseIRQ, link->handle, &link->irq);
++      pcmcia_release_configuration(link->handle);
++      pcmcia_release_io(link->handle, &link->io);
++      pcmcia_release_irq(link->handle, &link->irq);
+     
+       link->state &= ~DEV_CONFIG;
+       scsi_unregister(info->host);
+@@ -322,7 +320,7 @@ static int aha152x_event(event_t event, 
+       /* Fall through... */
+     case CS_EVENT_RESET_PHYSICAL:
+       if (link->state & DEV_CONFIG)
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       break;
+     case CS_EVENT_PM_RESUME:
+       link->state &= ~DEV_SUSPEND;
+@@ -330,7 +328,7 @@ static int aha152x_event(event_t event, 
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG) {
+           Scsi_Cmnd tmp;
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+           tmp.device->host = info->host;
+           aha152x_host_reset(&tmp);
+       }
+--- linux-2.6.0/drivers/scsi/pcmcia/fdomain_stub.c     2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/scsi/pcmcia/fdomain_stub.c      2003-12-28 23:22:54.000000000 -0800
+@@ -142,7 +142,7 @@ static dev_link_t *fdomain_attach(void)
+       CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+     client_reg.Version = 0x0210;
+     client_reg.event_callback_args.client_data = link;
+-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
++    ret = pcmcia_register_client(&link->handle, &client_reg);
+     if (ret != 0) {
+       cs_error(link->handle, RegisterClient, ret);
+       fdomain_detach(link);
+@@ -170,7 +170,7 @@ static void fdomain_detach(dev_link_t *l
+       fdomain_release(link);
+     if (link->handle)
+-      CardServices(DeregisterClient, link->handle);
++      pcmcia_deregister_client(link->handle);
+     
+     /* Unlink device structure, free bits */
+     *linkp = link->next;
+@@ -180,11 +180,8 @@ static void fdomain_detach(dev_link_t *l
+ /*====================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void fdomain_config(dev_link_t *link)
+ {
+@@ -203,29 +200,30 @@ static void fdomain_config(dev_link_t *l
+     tuple.TupleData = tuple_data;
+     tuple.TupleDataMax = 64;
+     tuple.TupleOffset = 0;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
+-    CS_CHECK(GetTupleData, handle, &tuple);
+-    CS_CHECK(ParseTuple, handle, &tuple, &parse);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+     link->conf.ConfigBase = parse.config.base;
+     /* Configure card */
+     link->state |= DEV_CONFIG;
+     
+     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+-    CS_CHECK(GetFirstTuple, handle, &tuple);
++    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+     while (1) {
+-      CFG_CHECK(GetTupleData, handle, &tuple);
+-      CFG_CHECK(ParseTuple, handle, &tuple, &parse);
++      if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++              pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
++          goto next_entry;
+       link->conf.ConfigIndex = parse.cftable_entry.index;
+       link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
+-      i = CardServices(RequestIO, handle, &link->io);
++      i = pcmcia_request_io(handle, &link->io);
+       if (i == CS_SUCCESS) break;
+     next_entry:
+-      CS_CHECK(GetNextTuple, handle, &tuple);
++      CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
+     }
+-    CS_CHECK(RequestIRQ, handle, &link->irq);
+-    CS_CHECK(RequestConfiguration, handle, &link->conf);
++    CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
++    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
+     
+     /* A bad hack... */
+     release_region(link->io.BasePort1, link->io.NumPorts1);
+@@ -271,9 +269,9 @@ static void fdomain_release(dev_link_t *
+     scsi_remove_host(info->host);
+     link->dev = NULL;
+     
+-    CardServices(ReleaseConfiguration, link->handle);
+-    CardServices(ReleaseIO, link->handle, &link->io);
+-    CardServices(ReleaseIRQ, link->handle, &link->irq);
++    pcmcia_release_configuration(link->handle);
++    pcmcia_release_io(link->handle, &link->io);
++    pcmcia_release_irq(link->handle, &link->irq);
+     scsi_unregister(info->host);
+@@ -304,14 +302,14 @@ static int fdomain_event(event_t event, 
+       /* Fall through... */
+     case CS_EVENT_RESET_PHYSICAL:
+       if (link->state & DEV_CONFIG)
+-          CardServices(ReleaseConfiguration, link->handle);
++          pcmcia_release_configuration(link->handle);
+       break;
+     case CS_EVENT_PM_RESUME:
+       link->state &= ~DEV_SUSPEND;
+       /* Fall through... */
+     case CS_EVENT_CARD_RESET:
+       if (link->state & DEV_CONFIG) {
+-          CardServices(RequestConfiguration, link->handle, &link->conf);
++          pcmcia_request_configuration(link->handle, &link->conf);
+           fdomain_16x0_bus_reset(NULL);
+       }
+       break;
+--- linux-2.6.0/drivers/scsi/pcmcia/nsp_cs.c   2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/scsi/pcmcia/nsp_cs.c    2003-12-28 23:22:54.000000000 -0800
+@@ -1681,7 +1681,7 @@ static dev_link_t *nsp_cs_attach(void)
+       client_reg.event_handler = &nsp_cs_event;
+       client_reg.Version       = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != CS_SUCCESS) {
+               cs_error(link->handle, RegisterClient, ret);
+               nsp_cs_detach(link);
+@@ -1721,7 +1721,7 @@ static void nsp_cs_detach(dev_link_t *li
+       /* Break the link with Card Services */
+       if (link->handle) {
+-              CardServices(DeregisterClient, link->handle);
++              pcmcia_deregister_client(link->handle);
+       }
+       /* Unlink device structure, free bits */
+@@ -1737,10 +1737,8 @@ static void nsp_cs_detach(dev_link_t *li
+     is received, to configure the PCMCIA socket, and to make the
+     ethernet device available to the system.
+ ======================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ /*====================================================================*/
+ static void nsp_cs_config(dev_link_t *link)
+ {
+@@ -1768,9 +1766,9 @@ static void nsp_cs_config(dev_link_t *li
+       tuple.TupleData       = tuple_data;
+       tuple.TupleDataMax    = sizeof(tuple_data);
+       tuple.TupleOffset     = 0;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
+-      CS_CHECK(GetTupleData,  handle, &tuple);
+-      CS_CHECK(ParseTuple,    handle, &tuple, &parse);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++      CS_CHECK(GetTupleData,  pcmcia_get_tuple_data(handle, &tuple));
++      CS_CHECK(ParseTuple,    pcmcia_parse_tuple(handle, &tuple, &parse));
+       link->conf.ConfigBase = parse.config.base;
+       link->conf.Present    = parse.config.rmask[0];
+@@ -1778,16 +1776,17 @@ static void nsp_cs_config(dev_link_t *li
+       link->state           |= DEV_CONFIG;
+       /* Look up the current Vcc */
+-      CS_CHECK(GetConfigurationInfo, handle, &conf);
++      CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
+       link->conf.Vcc = conf.Vcc;
+       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       while (1) {
+               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+-              CFG_CHECK(GetTupleData, handle, &tuple);
+-              CFG_CHECK(ParseTuple,   handle, &tuple, &parse);
++              if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++                              pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
++                      goto next_entry;
+               if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
+               if (cfg->index == 0) { goto next_entry; }
+@@ -1842,7 +1841,8 @@ static void nsp_cs_config(dev_link_t *li
+                               link->io.NumPorts2 = io->win[1].len;
+                       }
+                       /* This reserves IO space but doesn't actually enable it */
+-                      CFG_CHECK(RequestIO, link->handle, &link->io);
++                      if (pcmcia_request_io(link->handle, &link->io) != 0)
++                              goto next_entry;
+               }
+               if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+@@ -1856,10 +1856,11 @@ static void nsp_cs_config(dev_link_t *li
+                               req.Size = 0x1000;
+                       }
+                       req.AccessSpeed = 0;
+-                      link->win = (window_handle_t)link->handle;
+-                      CFG_CHECK(RequestWindow, &link->win, &req);
++                      if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
++                              goto next_entry;
+                       map.Page = 0; map.CardOffset = mem->win[0].card_addr;
+-                      CFG_CHECK(MapMemPage, link->win, &map);
++                      if (pcmcia_map_mem_page(link->win, &map) != 0)
++                              goto next_entry;
+                       data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
+                       data->MmioLength  = req.Size;
+@@ -1871,15 +1872,15 @@ static void nsp_cs_config(dev_link_t *li
+               nsp_dbg(NSP_DEBUG_INIT, "next");
+               if (link->io.NumPorts1) {
+-                      CardServices(ReleaseIO, link->handle, &link->io);
++                      pcmcia_release_io(link->handle, &link->io);
+               }
+-              CS_CHECK(GetNextTuple, handle, &tuple);
++              CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
+       }
+       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+-              CS_CHECK(RequestIRQ, link->handle, &link->irq);
++              CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+       }
+-      CS_CHECK(RequestConfiguration, handle, &link->conf);
++      CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
+       if (free_ports) {
+               if (link->io.BasePort1) {
+@@ -2007,7 +2008,6 @@ static void nsp_cs_config(dev_link_t *li
+       return;
+ } /* nsp_cs_config */
+ #undef CS_CHECK
+-#undef CFG_CHECK
+ /*======================================================================
+@@ -2042,14 +2042,14 @@ static void nsp_cs_release(dev_link_t *l
+               if (data != NULL) {
+                       iounmap((void *)(data->MmioAddress));
+               }
+-              CardServices(ReleaseWindow, link->win);
++              pcmcia_release_window(link->win);
+       }
+-      CardServices(ReleaseConfiguration,  link->handle);
++      pcmcia_release_configuration(link->handle);
+       if (link->io.NumPorts1) {
+-              CardServices(ReleaseIO,     link->handle, &link->io);
++              pcmcia_release_io(link->handle, &link->io);
+       }
+       if (link->irq.AssignedIRQ) {
+-              CardServices(ReleaseIRQ,    link->handle, &link->irq);
++              pcmcia_release_irq(link->handle, &link->irq);
+       }
+       link->state &= ~DEV_CONFIG;
+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
+@@ -2119,7 +2119,7 @@ static int nsp_cs_event(event_t                 
+               info->stop = 1;
+               if (link->state & DEV_CONFIG) {
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               }
+               break;
+@@ -2130,7 +2130,7 @@ static int nsp_cs_event(event_t                 
+       case CS_EVENT_CARD_RESET:
+               nsp_dbg(NSP_DEBUG_INIT, "event: reset");
+               if (link->state & DEV_CONFIG) {
+-                      CardServices(RequestConfiguration, link->handle, &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+               }
+               info->stop = 0;
+@@ -2177,7 +2177,7 @@ static int __init nsp_cs_init(void)
+       servinfo_t serv;
+       nsp_msg(KERN_INFO, "loading...");
+-      CardServices(GetCardServicesInfo, &serv);
++      pcmcia_get_card_services_info(&serv);
+       if (serv.Revision != CS_RELEASE_CODE) {
+               nsp_msg(KERN_DEBUG, "Card Services release does not match!");
+               return -EINVAL;
+--- linux-2.6.0/drivers/scsi/pcmcia/nsp_cs.h   2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/scsi/pcmcia/nsp_cs.h    2003-12-28 23:22:54.000000000 -0800
+@@ -457,7 +457,7 @@ static inline struct Scsi_Host *scsi_hos
+ static void cs_error(client_handle_t handle, int func, int ret)
+ {
+       error_info_t err = { func, ret };
+-      CardServices(ReportError, handle, &err);
++      pcmcia_report_error(handle, &err);
+ }
+ /* scatter-gather table */
+--- linux-2.6.0/drivers/scsi/pcmcia/qlogic_stub.c      2003-08-22 19:23:41.000000000 -0700
++++ 25/drivers/scsi/pcmcia/qlogic_stub.c       2003-12-28 23:22:54.000000000 -0800
+@@ -140,7 +140,7 @@ static dev_link_t *qlogic_attach(void)
+       client_reg.EventMask = CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != 0) {
+               cs_error(link->handle, RegisterClient, ret);
+               qlogic_detach(link);
+@@ -169,7 +169,7 @@ static void qlogic_detach(dev_link_t * l
+               qlogic_release(link);
+       if (link->handle)
+-              CardServices(DeregisterClient, link->handle);
++              pcmcia_deregister_client(link->handle);
+       /* Unlink device structure, free bits */
+       *linkp = link->next;
+@@ -179,11 +179,8 @@ static void qlogic_detach(dev_link_t * l
+ /*====================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void qlogic_config(dev_link_t * link)
+ {
+@@ -201,37 +198,38 @@ static void qlogic_config(dev_link_t * l
+       tuple.TupleDataMax = 64;
+       tuple.TupleOffset = 0;
+       tuple.DesiredTuple = CISTPL_CONFIG;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
+-      CS_CHECK(GetTupleData, handle, &tuple);
+-      CS_CHECK(ParseTuple, handle, &tuple, &parse);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++      CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+       link->conf.ConfigBase = parse.config.base;
+       tuple.DesiredTuple = CISTPL_MANFID;
+-      if ((CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) && (CardServices(GetTupleData, handle, &tuple) == CS_SUCCESS))
++      if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS))
+               info->manf_id = le16_to_cpu(tuple.TupleData[0]);
+       /* Configure card */
+       link->state |= DEV_CONFIG;
+       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       while (1) {
+-              CFG_CHECK(GetTupleData, handle, &tuple);
+-              CFG_CHECK(ParseTuple, handle, &tuple, &parse);
++              if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++                              pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
++                      goto next_entry;
+               link->conf.ConfigIndex = parse.cftable_entry.index;
+               link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
+               link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
+               if (link->io.BasePort1 != 0) {
+-                      i = CardServices(RequestIO, handle, &link->io);
++                      i = pcmcia_request_io(handle, &link->io);
+                       if (i == CS_SUCCESS)
+                               break;
+               }
+             next_entry:
+-              CS_CHECK(GetNextTuple, handle, &tuple);
++              CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
+       }
+-      CS_CHECK(RequestIRQ, handle, &link->irq);
+-      CS_CHECK(RequestConfiguration, handle, &link->conf);
++      CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
++      CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
+       if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
+               /* set ATAcmd */
+@@ -284,9 +282,9 @@ static void qlogic_release(dev_link_t *l
+       scsi_remove_host(info->host);
+       link->dev = NULL;
+-      CardServices(ReleaseConfiguration, link->handle);
+-      CardServices(ReleaseIO, link->handle, &link->io);
+-      CardServices(ReleaseIRQ, link->handle, &link->irq);
++      pcmcia_release_configuration(link->handle);
++      pcmcia_release_io(link->handle, &link->io);
++      pcmcia_release_irq(link->handle, &link->irq);
+       scsi_unregister(info->host);
+@@ -316,7 +314,7 @@ static int qlogic_event(event_t event, i
+               /* Fall through... */
+       case CS_EVENT_RESET_PHYSICAL:
+               if (link->state & DEV_CONFIG)
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               break;
+       case CS_EVENT_PM_RESUME:
+               link->state &= ~DEV_SUSPEND;
+@@ -324,7 +322,7 @@ static int qlogic_event(event_t event, i
+       case CS_EVENT_CARD_RESET:
+               if (link->state & DEV_CONFIG) {
+                       scsi_info_t *info = link->priv;
+-                      CardServices(RequestConfiguration, link->handle, &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+                       if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
+                               outb(0x80, link->io.BasePort1 + 0xd);
+                               outb(0x24, link->io.BasePort1 + 0x9);
+--- linux-2.6.0/drivers/scsi/qla1280.c 2003-12-17 21:20:02.000000000 -0800
++++ 25/drivers/scsi/qla1280.c  2003-12-28 23:21:38.000000000 -0800
+@@ -4,6 +4,7 @@
+ * QLogic  QLA1280 (Ultra2)  and  QLA12160 (Ultra3) SCSI driver
+ * Copyright (C) 2000 Qlogic Corporation (www.qlogic.com)
+ * Copyright (C) 2001-2003 Jes Sorensen, Wild Open Source Inc.
++* Copyright (C) 2003 Christoph Hellwig
+ *
+ * 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
+@@ -16,13 +17,17 @@
+ * General Public License for more details.
+ *
+ ******************************************************************************/
+-#define QLA1280_VERSION      "3.23.37.1"
++#define QLA1280_VERSION      "3.23.38.1"
+ /*****************************************************************************
+     Revision History:
+     Rev  3.23.37.1 December 17, 2003, Jes Sorensen
+       - Delete completion queue from srb if mailbox command failed to
+         to avoid qla1280_done completeting qla1280_error_action's
+         obsolete context
++    Rev  3.23.38 October 18, 2003, Christoph Hellwig
++      - Convert to new-style hotplugable driver for 2.6
++      - Fix missing scsi_unregister/scsi_host_put on HBA removal
++      - Kill some of cruft
+     Rev  3.23.37 October 1, 2003, Jes Sorensen
+       - Make MMIO depend on CONFIG_X86_VISWS instead of yet another
+         random CONFIG option
+@@ -341,9 +346,6 @@
+  * Compile time Options:
+  *            0 - Disable and 1 - Enable
+  */
+-#define  QL1280_LUN_SUPPORT   0
+-#define  WATCHDOGTIMER                0
+-
+ #define  DEBUG_QLA1280_INTR   0
+ #define  DEBUG_PRINT_NVRAM    0
+ #define  DEBUG_QLA1280                0
+@@ -423,6 +425,14 @@ scsi_adjust_queue_depth(Scsi_Device *dev
+       }
+       device->queue_depth = depth;
+ }
++static inline struct Scsi_Host *scsi_host_alloc(Scsi_Host_Template *t, size_t s)
++{
++      return scsi_register(t, s);
++}
++static inline void scsi_host_put(struct Scsi_Host *h)
++{
++      scsi_unregister(h);
++}
+ #else
+ #define HOST_LOCK                     ha->host->host_lock
+ #endif
+@@ -435,30 +445,23 @@ scsi_adjust_queue_depth(Scsi_Device *dev
+ #define ia64_platform_is(foo)         (!strcmp(x, platform_name))
+ #endif
++static int qla1280_probe_one(struct pci_dev *, const struct pci_device_id *);
++static void qla1280_remove_one(struct pci_dev *);
++
+ /*
+  *  QLogic Driver Support Function Prototypes.
+  */
+ static void qla1280_done(struct scsi_qla_host *, struct srb **, struct srb **);
+-static void qla1280_done_q_put(struct srb *, struct srb **, struct srb **);
+-static int qla1280_slave_configure(Scsi_Device *);
+ #if LINUX_VERSION_CODE < 0x020545
+-static void qla1280_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
+ static void qla1280_get_target_options(struct scsi_cmnd *, struct scsi_qla_host *);
+ #endif
+-
+-static int qla1280_return_status(struct response * sts, Scsi_Cmnd * cp);
+-static void qla1280_mem_free(struct scsi_qla_host *ha);
+ static int qla1280_get_token(char *);
+ static int qla1280_setup(char *s) __init;
+-static inline void qla1280_enable_intrs(struct scsi_qla_host *);
+-static inline void qla1280_disable_intrs(struct scsi_qla_host *);
+ /*
+  *  QLogic ISP1280 Hardware Support Function Prototypes.
+  */
+-static int qla1280_initialize_adapter(struct scsi_qla_host *ha);
+ static int qla1280_isp_firmware(struct scsi_qla_host *);
+-static int qla1280_pci_config(struct scsi_qla_host *);
+ static int qla1280_chip_diag(struct scsi_qla_host *);
+ static int qla1280_setup_chip(struct scsi_qla_host *);
+ static int qla1280_init_rings(struct scsi_qla_host *);
+@@ -477,7 +480,6 @@ static void qla1280_poll(struct scsi_qla
+ static void qla1280_reset_adapter(struct scsi_qla_host *);
+ static void qla1280_marker(struct scsi_qla_host *, int, int, int, u8);
+ static void qla1280_isp_cmd(struct scsi_qla_host *);
+-irqreturn_t qla1280_intr_handler(int, void *, struct pt_regs *);
+ static void qla1280_isr(struct scsi_qla_host *, struct srb **, struct srb **);
+ static void qla1280_rst_aen(struct scsi_qla_host *);
+ static void qla1280_status_entry(struct scsi_qla_host *, struct response *,
+@@ -490,11 +492,9 @@ static uint16_t qla1280_debounce_registe
+ static request_t *qla1280_req_pkt(struct scsi_qla_host *);
+ static int qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *,
+                                          unsigned int);
+-static int qla1280_mem_alloc(struct scsi_qla_host *ha);
+-
+-static void qla12160_get_target_parameters(struct scsi_qla_host *,
++static void qla1280_get_target_parameters(struct scsi_qla_host *,
+                                          Scsi_Device *);
+-static int qla12160_set_target_parameters(struct scsi_qla_host *, int, int);
++static int qla1280_set_target_parameters(struct scsi_qla_host *, int, int);
+ static struct qla_driver_setup driver_setup __initdata;
+@@ -529,10 +529,6 @@ qla1280_data_direction(struct scsi_cmnd 
+       return flags;
+ }
+               
+-#if QL1280_LUN_SUPPORT
+-static void qla1280_enable_lun(struct scsi_qla_host *, int, int);
+-#endif
+-
+ #if DEBUG_QLA1280
+ static void __qla1280_print_scsi_cmd(Scsi_Cmnd * cmd);
+ static void __qla1280_dump_buffer(char *, int);
+@@ -551,8 +547,6 @@ MODULE_PARM(qla1280, "s");
+ __setup("qla1280=", qla1280_setup);
+ #endif
+-MODULE_LICENSE("GPL");
+-
+ /* We use the Scsi_Pointer structure that's included with each command
+  * SCSI_Cmnd as a scratchpad for our SRB.
+@@ -576,28 +570,23 @@ MODULE_LICENSE("GPL");
+ #define       CMD_RESULT(Cmnd)        Cmnd->result
+ #define       CMD_HANDLE(Cmnd)        Cmnd->host_scribble
+ #if LINUX_VERSION_CODE < 0x020545
+-#define       CMD_HOST(Cmnd)          Cmnd->host
+ #define CMD_REQUEST(Cmnd)     Cmnd->request.cmd
+-#define SCSI_BUS_32(Cmnd)     Cmnd->channel
+-#define SCSI_TCN_32(Cmnd)     Cmnd->target
+-#define SCSI_LUN_32(Cmnd)     Cmnd->lun
+ #else
+-#define       CMD_HOST(Cmnd)          Cmnd->device->host
+ #define CMD_REQUEST(Cmnd)     Cmnd->request->cmd
++#endif
++
++#define CMD_HOST(Cmnd)                Cmnd->device->host
+ #define SCSI_BUS_32(Cmnd)     Cmnd->device->channel
+ #define SCSI_TCN_32(Cmnd)     Cmnd->device->id
+ #define SCSI_LUN_32(Cmnd)     Cmnd->device->lun
+-#endif
++
+ /*****************************************/
+ /*   ISP Boards supported by this driver */
+ /*****************************************/
+-#define NUM_OF_ISP_DEVICES    6
+-
+ struct qla_boards {
+       unsigned char name[9];  /* Board ID String */
+-      unsigned long device_id;        /* Device PCI ID   */
+       int numPorts;           /* Number of SCSI ports */
+       unsigned short *fwcode; /* pointer to FW array         */
+       unsigned short *fwlen;  /* number of words in array    */
+@@ -605,28 +594,38 @@ struct qla_boards {
+       unsigned char *fwver;   /* Ptr to F/W version array    */
+ };
+-struct qla_boards ql1280_board_tbl[NUM_OF_ISP_DEVICES] = {
+-      /* Name ,  Board PCI Device ID,         Number of ports */
+-      {"QLA12160", PCI_DEVICE_ID_QLOGIC_ISP12160, 2,
+-       &fw12160i_code01[0], &fw12160i_length01,
++/* NOTE: qla1280_pci_tbl and ql1280_board_tbl must be in the same order */
++static struct pci_device_id qla1280_pci_tbl[] = {
++      {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP12160,
++              PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++      {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1080,
++              PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
++      {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240,
++              PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
++      {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1280,
++              PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
++      {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160,
++              PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
++      {0,}
++};
++MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
++
++static struct qla_boards ql1280_board_tbl[] = {
++      /* Name ,  Number of ports, FW details */
++      {"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01,
+        &fw12160i_addr01, &fw12160i_version_str[0]},
+-      {"QLA1080", PCI_DEVICE_ID_QLOGIC_ISP1080, 1,
+-       &fw1280ei_code01[0], &fw1280ei_length01,
++      {"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01,
+        &fw1280ei_addr01, &fw1280ei_version_str[0]},
+-      {"QLA1240", PCI_DEVICE_ID_QLOGIC_ISP1240, 2,
+-       &fw1280ei_code01[0], &fw1280ei_length01,
++      {"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01,
+        &fw1280ei_addr01, &fw1280ei_version_str[0]},
+-      {"QLA1280", PCI_DEVICE_ID_QLOGIC_ISP1280, 2,
+-       &fw1280ei_code01[0], &fw1280ei_length01,
++      {"QLA1280", 2, &fw1280ei_code01[0], &fw1280ei_length01,
+        &fw1280ei_addr01, &fw1280ei_version_str[0]},
+-      {"QLA10160", PCI_DEVICE_ID_QLOGIC_ISP10160, 1,
+-       &fw12160i_code01[0], &fw12160i_length01,
++      {"QLA10160", 1, &fw12160i_code01[0], &fw12160i_length01,
+        &fw12160i_addr01, &fw12160i_version_str[0]},
+-      {"        ", 0, 0}
++      {"        ", 0}
+ };
+ static int qla1280_verbose = 1;
+-static struct scsi_qla_host *qla1280_hostlist;
+ static int qla1280_buffer_size;
+ static char *qla1280_buffer;
+@@ -675,31 +674,19 @@ static int qla1280_proc_info(struct Scsi
+       int size = 0;
+       int len = 0;
+       struct qla_boards *bdp;
+-#ifdef BOGUS_QUEUE
+-      struct scsi_lu *up;
+-      uint32_t b, t, l;
+-#endif
+-#if LINUX_VERSION_CODE >= 0x020600
+-      ha = (struct scsi_qla_host *)host->hostdata;
+-#else
++#if LINUX_VERSION_CODE < 0x020600
+       struct Scsi_Host *host;
+-      /* Find the host that was specified */
+-      for (ha = qla1280_hostlist; (ha != NULL)
+-                   && ha->host->host_no != hostno; ha = ha->next) ;
+-
+-      /* if host wasn't found then exit */
+-      if (!ha) {
+-              size =  sprintf(buffer, "Can't find adapter for host "
+-                              "number %d\n", hostno);
+-              if (size > length) {
+-                      return size;
+-              } else {
+-                      return 0;
+-              }
++
++      for (host = scsi_hostlist; host; host = host->next) {
++              if (host->host_no == hostno)
++                      goto found;
+       }
+-      host = ha->host;
++      return -ESRCH;
++
++ found:
+ #endif
++      ha = (struct scsi_qla_host *)host->hostdata;
+       if (inout)
+               return -ENOSYS;
+@@ -753,51 +740,6 @@ static int qla1280_proc_info(struct Scsi
+       size = sprintf(PROC_BUF, "\n"); /* 1       */
+       len += size;
+-      size = sprintf(PROC_BUF, "SCSI device Information:\n");
+-      len += size;
+-#ifdef BOGUS_QUEUE
+-      /* scan for all equipment stats */
+-      for (b = 0; b < MAX_BUSES; b++)
+-              for (t = 0; t < MAX_TARGETS; t++) {
+-                      for (l = 0; l < MAX_LUNS; l++) {
+-                              up = LU_Q(ha, b, t, l);
+-                              if (up == NULL)
+-                                      continue;
+-                              /* unused device/lun */
+-                              if (up->io_cnt == 0 || up->io_cnt < 2)
+-                                      continue;
+-                              /* total reads since boot */
+-                              /* total writes since boot */
+-                              /* total requests since boot  */
+-                              size = sprintf (PROC_BUF,
+-                                              "(%2d:%2d:%2d): Total reqs %ld,",
+-                                              b, t, l, up->io_cnt);
+-                              len += size;
+-                              /* current number of pending requests */
+-                              size =  sprintf(PROC_BUF, " Pend reqs %d,",
+-                                              up->q_outcnt);
+-                              len += size;
+-#if 0
+-                              /* avg response time */
+-                              size = sprintf(PROC_BUF, " Avg resp time %ld%%,",
+-                                             (up->resp_time / up->io_cnt) *
+-                                             100);
+-                              len += size;
+-
+-                              /* avg active time */
+-                              size = sprintf(PROC_BUF,
+-                                             " Avg active time %ld%%\n",
+-                                             (up->act_time / up->io_cnt) * 100);
+-#else
+-                              size = sprintf(PROC_BUF, "\n");
+-#endif
+-                              len += size;
+-                      }
+-                      if (len >= qla1280_buffer_size)
+-                              break;
+-              }
+-#endif
+-
+       if (len >= qla1280_buffer_size) {
+               printk(KERN_WARNING
+                      "qla1280: Overflow buffer in qla1280_proc.c\n");
+@@ -875,312 +817,6 @@ static int qla1280_read_nvram(struct scs
+       return chksum;
+ }
+-
+-/**************************************************************************
+- * qla1280_do_device_init
+- *    This routine will register the device with the SCSI subsystem,
+- *    initialize the host adapter structure and call the device init
+- *    routines.
+- *
+- * Input:
+- *     pdev      - pointer to struct pci_dev for adapter
+- *     template  - pointer to SCSI template
+- *     devnum    - the device number
+- *     bdp       - pointer to struct _qlaboards
+- *     num_hosts - the host number
+- *
+- * Returns:
+- *  host - pointer to SCSI host structure
+- **************************************************************************/
+-struct Scsi_Host *
+-qla1280_do_device_init(struct pci_dev *pdev, Scsi_Host_Template * template,
+-                     int devnum, struct qla_boards *bdp, int num_hosts)
+-{
+-      struct Scsi_Host *host;
+-      struct scsi_qla_host *ha;
+-
+-      printk(KERN_INFO "qla1280: %s found on PCI bus %i, dev %i\n",
+-             bdp->name, pdev->bus->number, PCI_SLOT(pdev->devfn));
+-
+-      host = scsi_register(template, sizeof(struct scsi_qla_host));
+-      if (!host) {
+-              printk(KERN_WARNING
+-                     "qla1280: Failed to register host, aborting.\n");
+-              goto error;
+-      }
+-
+-#if LINUX_VERSION_CODE < 0x020545
+-      scsi_set_pci_device(host, pdev);
+-#else
+-      scsi_set_device(host, &pdev->dev);
+-#endif
+-      ha = (struct scsi_qla_host *)host->hostdata;
+-      /* Clear our data area */
+-      memset(ha, 0, sizeof(struct scsi_qla_host));
+-      /* Sanitize the information from PCI BIOS.  */
+-      host->irq = pdev->irq;
+-      ha->pci_bus = pdev->bus->number;
+-      ha->pci_device_fn = pdev->devfn;
+-      ha->pdev = pdev;
+-      ha->device_id = bdp->device_id;
+-      ha->devnum = devnum;    /* specifies microcode load address */
+-
+-      if (qla1280_mem_alloc(ha)) {
+-              printk(KERN_INFO "qla1x160: Failed to get memory\n");
+-              goto error_scsi_unregister;
+-      }
+-
+-      ha->ports = bdp->numPorts;
+-      /* following needed for all cases of OS versions */
+-      ha->host = host;
+-      ha->host_no = host->host_no;
+-
+-      host->can_queue = 0xfffff;      /* unlimited  */
+-      host->cmd_per_lun = 1;
+-      host->base = (unsigned long)ha->mmpbase;
+-      host->max_channel = bdp->numPorts - 1;
+-      host->max_lun = MAX_LUNS - 1;
+-      host->max_id = MAX_TARGETS;
+-      host->max_sectors = 1024;
+-#if LINUX_VERSION_CODE < 0x020545
+-      host->select_queue_depths = qla1280_select_queue_depth;
+-#endif
+-
+-      ha->instance = num_hosts;
+-      host->unique_id = ha->instance;
+-
+-      if (qla1280_pci_config(ha)) {
+-              printk(KERN_INFO "qla1x160: Unable to configure PCI\n");
+-              goto error_mem_alloced;
+-      }
+-
+-      /* Disable ISP interrupts. */
+-      qla1280_disable_intrs(ha);
+-
+-      /* Register the IRQ with Linux (sharable) */
+-      if (request_irq(host->irq, qla1280_intr_handler, SA_SHIRQ,
+-                      "qla1280", ha)) {
+-              printk("qla1280 : Failed to reserve interrupt %d already "
+-                     "in use\n", host->irq);
+-              goto error_iounmap;
+-      }
+-#if !MEMORY_MAPPED_IO
+-      /* Register the I/O space with Linux */
+-      if (!request_region(host->io_port, 0xff, "qla1280")) {
+-              printk("qla1280: Failed to reserve i/o region 0x%04lx-0x%04lx"
+-                     " already in use\n",
+-                     host->io_port, host->io_port + 0xff);
+-              goto error_free_irq;
+-      }
+-#endif
+-
+-      /* load the F/W, read paramaters, and init the H/W */
+-      if (qla1280_initialize_adapter(ha)) {
+-              printk(KERN_INFO "qla1x160: Failed to initialize adapter\n");
+-              goto error_release_region;
+-      }
+-
+-      /* set our host ID  (need to do something about our two IDs) */
+-      host->this_id = ha->bus_settings[0].id;
+-
+-      return host;
+-
+- error_release_region:
+-#if !MEMORY_MAPPED_IO
+-      release_region(host->io_port, 0xff);
+- error_free_irq:
+-#endif
+-      free_irq(host->irq, ha);
+- error_iounmap:
+-#if MEMORY_MAPPED_IO
+-      if (ha->mmpbase)
+-              iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK));
+-#endif
+- error_mem_alloced:
+-      qla1280_mem_free(ha);
+- error_scsi_unregister:
+-      scsi_unregister(host);
+- error:
+-      return NULL;
+-}
+-
+-/**************************************************************************
+- * qla1280_detect
+- *    This routine will probe for Qlogic 1280 SCSI host adapters.
+- *    It returns the number of host adapters of a particular
+- *    type that were found.    It also initialize all data necessary for
+- *    the driver.  It is passed-in the host number, so that it
+- *    knows where its first entry is in the scsi_hosts[] array.
+- *
+- * Input:
+- *     template - pointer to SCSI template
+- *
+- * Returns:
+- *  num - number of host adapters found.
+- **************************************************************************/
+-static int
+-qla1280_detect(Scsi_Host_Template * template)
+-{
+-      struct pci_dev *pdev = NULL;
+-      struct Scsi_Host *host;
+-      struct scsi_qla_host *ha, *cur_ha;
+-      struct qla_boards *bdp;
+-      uint16_t subsys_vendor, subsys_device;
+-      int num_hosts = 0;
+-      int devnum = 0;
+-
+-      ENTER("qla1280_detect");
+-
+-      if (sizeof(struct srb) > sizeof(Scsi_Pointer)) {
+-              printk(KERN_WARNING
+-                     "qla1280_detect: [WARNING] struct srb too big\n");
+-              return 0;
+-      }
+-#ifdef MODULE
+-      /*
+-       * If we are called as a module, the qla1280 pointer may not be null
+-       * and it would point to our bootup string, just like on the lilo
+-       * command line.  IF not NULL, then process this config string with
+-       * qla1280_setup
+-       *
+-       * Boot time Options
+-       * To add options at boot time add a line to your lilo.conf file like:
+-       * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}"
+-       * which will result in the first four devices on the first two
+-       * controllers being set to a tagged queue depth of 32.
+-       */
+-      if (qla1280)
+-              qla1280_setup(qla1280);
+-#endif
+-
+-      bdp = &ql1280_board_tbl[0];
+-      qla1280_hostlist = NULL;
+-      template->proc_name = "qla1280";
+-
+-      /* First Initialize QLA12160 on PCI Bus 1 Dev 2 */
+-      while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC, bdp->device_id,
+-                                     PCI_ANY_ID, PCI_ANY_ID, pdev))) {
+-
+-              /* find QLA12160 device on PCI bus=1 slot=2 */
+-              if ((pdev->bus->number != 1) || (PCI_SLOT(pdev->devfn) != 2))
+-                      continue;
+-
+-              /* Bypass all AMI SUBSYS VENDOR IDs */
+-              if (pdev->subsystem_vendor == PCI_VENDOR_ID_AMI) {
+-                      printk(KERN_INFO
+-                             "qla1x160: Skip AMI SubSys Vendor ID Chip\n");
+-                      continue;
+-              }
+-
+-              if (pci_enable_device(pdev))
+-                      goto find_devices;
+-
+-              host = qla1280_do_device_init(pdev, template, devnum,
+-                                            bdp, num_hosts);
+-              if (!host)
+-                      continue;
+-              ha = (struct scsi_qla_host *)host->hostdata;
+-
+-              /* this preferred device will always be the first one found */
+-              cur_ha = qla1280_hostlist = ha;
+-              num_hosts++;
+-      }
+-
+- find_devices:
+-
+-      pdev = NULL;
+-      /* Try and find each different type of adapter we support */
+-      for (devnum = 0; bdp->device_id != 0 && devnum < NUM_OF_ISP_DEVICES;
+-           devnum++, bdp++) {
+-              /* PCI_SUBSYSTEM_IDS supported */
+-              while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC,
+-                                             bdp->device_id, PCI_ANY_ID,
+-                                             PCI_ANY_ID, pdev))) {
+-                      if (pci_enable_device(pdev))
+-                              continue;
+-                      /* found an adapter */
+-                      subsys_vendor = pdev->subsystem_vendor;
+-                      subsys_device = pdev->subsystem_device;
+-
+-                      /*
+-                       * skip QLA12160 already initialized on
+-                       * PCI Bus 1 Dev 2 since we already initialized
+-                       * and presented it
+-                       */
+-                      if ((bdp->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160)&&
+-                          (pdev->bus->number == 1) &&
+-                          (PCI_SLOT(pdev->devfn) == 2))
+-                              continue;
+-
+-                      /* Bypass all AMI SUBSYS VENDOR IDs */
+-                      if (subsys_vendor == PCI_VENDOR_ID_AMI) {
+-                              printk(KERN_INFO
+-                                     "qla1x160: Skip AMI SubSys Vendor ID Chip\n");
+-                              continue;
+-                      }
+-                      dprintk(1, "qla1x160: Supported Device Found VID=%x "
+-                             "DID=%x SSVID=%x SSDID=%x\n", pdev->vendor,
+-                             pdev->device, subsys_vendor, subsys_device);
+-
+-                      host = qla1280_do_device_init(pdev, template,
+-                                                    devnum, bdp, num_hosts);
+-                      if (!host)
+-                              continue;
+-                      ha = (struct scsi_qla_host *)host->hostdata;
+-
+-                      if (qla1280_hostlist == NULL) {
+-                              cur_ha = qla1280_hostlist = ha;
+-                      } else {
+-                              cur_ha = qla1280_hostlist;
+-                              while (cur_ha->next != NULL)
+-                                      cur_ha = cur_ha->next;
+-                              cur_ha->next = ha;
+-                      }
+-                      num_hosts++;
+-              }               /* end of WHILE */
+-      }                       /* end of FOR */
+-
+-      LEAVE("qla1280_detect");
+-      return num_hosts;
+-}
+-
+-/**************************************************************************
+- *   qla1280_release
+- *   Free the passed in Scsi_Host memory structures prior to unloading the
+- *   module.
+- **************************************************************************/
+-static int
+-qla1280_release(struct Scsi_Host *host)
+-{
+-      struct scsi_qla_host *ha = (struct scsi_qla_host *)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);
+-
+-#if MEMORY_MAPPED_IO
+-      if (ha->mmpbase)
+-              iounmap(ha->mmpbase);
+-#else
+-      /* release io space registers  */
+-      if (host->io_port)
+-              release_region(host->io_port, 0xff);
+-#endif                                /* MEMORY_MAPPED_IO */
+-
+-      qla1280_mem_free(ha);
+-
+-      ENTER("qla1280_release");
+-      return 0;
+-}
+-
+ /**************************************************************************
+  *   qla1280_info
+  *     Return a string describing the driver.
+@@ -1197,11 +833,11 @@ qla1280_info(struct Scsi_Host *host)
+       ha = (struct scsi_qla_host *)host->hostdata;
+       bdp = &ql1280_board_tbl[ha->devnum];
+       memset(bp, 0, sizeof(qla1280_scsi_name_buffer));
++
+       sprintf (bp,
+-               "QLogic %s PCI to SCSI Host Adapter: bus %d device %d irq %d\n"
++               "QLogic %s PCI to SCSI Host Adapter\n"
+                "       Firmware version: %2d.%02d.%02d, Driver version %s",
+-               &bdp->name[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3,
+-               host->irq, bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
++               &bdp->name[0], bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
+                QLA1280_VERSION);
+       return bp;
+ }
+@@ -1220,38 +856,19 @@ qla1280_info(struct Scsi_Host *host)
+ static int
+ qla1280_queuecommand(Scsi_Cmnd * cmd, void (*fn) (Scsi_Cmnd *))
+ {
+-      struct scsi_qla_host *ha;
+-      struct srb *sp;
+-      struct Scsi_Host *host;
+-      int bus, target, lun;
+-      int status;
+-
+-      /*ENTER("qla1280_queuecommand");
+-       */
+-      dprintk(2, "qla1280_queuecommand(): jiffies %li\n", jiffies);
+-
+-      host = CMD_HOST(cmd);
+-      ha = (struct scsi_qla_host *)host->hostdata;
++      struct Scsi_Host *host = cmd->device->host;
++      struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
++      struct srb *sp = (struct srb *)&cmd->SCp;
+-      /* send command to adapter */
+-      sp = (struct srb *)CMD_SP(cmd);
+-      sp->cmd = cmd;
+       cmd->scsi_done = fn;
++      sp->cmd = cmd;
+       sp->flags = 0;
+       qla1280_print_scsi_cmd(5, cmd);
+-      /* Generate LU queue on bus, target, LUN */
+-      bus = SCSI_BUS_32(cmd);
+-      target = SCSI_TCN_32(cmd);
+-      lun = SCSI_LUN_32(cmd);
+       if (ha->flags.enable_64bit_addressing)
+-              status = qla1280_64bit_start_scsi(ha, sp);
+-      else
+-              status = qla1280_32bit_start_scsi(ha, sp);
+-
+-      /*LEAVE("qla1280_queuecommand"); */
+-      return status;
++              return qla1280_64bit_start_scsi(ha, sp);
++      return qla1280_32bit_start_scsi(ha, sp);
+ }
+ enum action {
+@@ -1564,29 +1181,105 @@ qla1280_biosparam(struct scsi_device *sd
+       unsigned long capacity = disk->capacity;
+ #endif
+-      heads = 64;
+-      sectors = 32;
+-      cylinders = (unsigned long)capacity / (heads * sectors);
+-      if (cylinders > 1024) {
+-              heads = 255;
+-              sectors = 63;
+-              cylinders = (unsigned long)capacity / (heads * sectors);
+-              /* if (cylinders > 1023)
+-                 cylinders = 1023; */
++      heads = 64;
++      sectors = 32;
++      cylinders = (unsigned long)capacity / (heads * sectors);
++      if (cylinders > 1024) {
++              heads = 255;
++              sectors = 63;
++              cylinders = (unsigned long)capacity / (heads * sectors);
++              /* if (cylinders > 1023)
++                 cylinders = 1023; */
++      }
++
++      geom[0] = heads;
++      geom[1] = sectors;
++      geom[2] = cylinders;
++
++      return 0;
++}
++
++#if LINUX_VERSION_CODE < 0x020600
++static int
++qla1280_detect(Scsi_Host_Template *template)
++{
++      struct pci_device_id *id = &qla1280_pci_tbl[0];
++      struct pci_dev *pdev = NULL;
++      int num_hosts = 0;
++
++      if (sizeof(struct srb) > sizeof(Scsi_Pointer)) {
++              printk(KERN_WARNING
++                     "qla1280: struct srb too big, aborting\n");
++              return 0;
++      }
++
++#ifdef MODULE
++      /*
++       * If we are called as a module, the qla1280 pointer may not be null
++       * and it would point to our bootup string, just like on the lilo
++       * command line.  IF not NULL, then process this config string with
++       * qla1280_setup
++       *
++       * Boot time Options
++       * To add options at boot time add a line to your lilo.conf file like:
++       * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}"
++       * which will result in the first four devices on the first two
++       * controllers being set to a tagged queue depth of 32.
++       */
++      if (qla1280)
++              qla1280_setup(qla1280);
++#endif
++
++      /* First Initialize QLA12160 on PCI Bus 1 Dev 2 */
++      while ((pdev = pci_find_device(id->vendor, id->device, pdev))) {
++              if (pdev->bus->number == 1 && PCI_SLOT(pdev->devfn) == 2) {
++                      if (!qla1280_probe_one(pdev, id))
++                              num_hosts++;
++              }
++      }
++
++      pdev = NULL;
++      /* Try and find each different type of adapter we support */
++      for (id = &qla1280_pci_tbl[0]; id->device; id++) {
++              while ((pdev = pci_find_device(id->vendor, id->device, pdev))) {
++                      /*
++                       * skip QLA12160 already initialized on
++                       * PCI Bus 1 Dev 2 since we already initialized
++                       * and presented it
++                       */
++                      if (id->device == PCI_DEVICE_ID_QLOGIC_ISP12160 &&
++                          pdev->bus->number == 1 &&
++                          PCI_SLOT(pdev->devfn) == 2)
++                              continue;
++
++                      if (!qla1280_probe_one(pdev, id))
++                              num_hosts++;
++              }
+       }
+-      geom[0] = heads;
+-      geom[1] = sectors;
+-      geom[2] = cylinders;
++      return num_hosts;
++}
++
++/*
++ * This looks a bit ugly as we could just pass down host to
++ * qla1280_remove_one, but I want to keep qla1280_release purely a wrapper
++ * around pci_driver::remove as used from 2.6 onwards.
++ */
++static int
++qla1280_release(struct Scsi_Host *host)
++{
++      struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
++      qla1280_remove_one(ha->pdev);
+       return 0;
+ }
++#endif
+ /**************************************************************************
+  * qla1280_intr_handler
+  *   Handles the H/W interrupt
+  **************************************************************************/
+-irqreturn_t
++static irqreturn_t
+ qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+ {
+       struct scsi_qla_host *ha;
+@@ -1624,7 +1317,7 @@ qla1280_intr_handler(int irq, void *dev_
+ static int
+-qla12160_set_target_parameters(struct scsi_qla_host *ha, int bus, int target)
++qla1280_set_target_parameters(struct scsi_qla_host *ha, int bus, int target)
+ {
+       uint8_t mr;
+       uint16_t mb[MAILBOX_REGISTER_COUNT];
+@@ -1633,8 +1326,8 @@ qla12160_set_target_parameters(struct sc
+       nv = &ha->nvram;
+-      if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+-          ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160)
++      if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
++          ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160)
+               is1x160 = 1;
+       else
+               is1x160 = 0;
+@@ -1721,8 +1414,8 @@ qla1280_slave_configure(Scsi_Device *dev
+           (driver_setup.wide_mask &&
+            (~driver_setup.wide_mask & (1 << target))))
+               nv->bus[bus].target[target].parameter.f.enable_wide = 0;
+-      if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+-          ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) {
++      if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
++          ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160) {
+               if (driver_setup.no_ppr ||
+                   (driver_setup.ppr_mask &&
+                    (~driver_setup.ppr_mask & (1 << target))))
+@@ -1730,11 +1423,9 @@ qla1280_slave_configure(Scsi_Device *dev
+       }
+       spin_lock_irqsave(HOST_LOCK, flags);
+-      if (nv->bus[bus].target[target].parameter.f.enable_sync) {
+-              status = qla12160_set_target_parameters(ha, bus, target);
+-      }
+-
+-      qla12160_get_target_parameters(ha, device);
++      if (nv->bus[bus].target[target].parameter.f.enable_sync)
++              status = qla1280_set_target_parameters(ha, bus, target);
++      qla1280_get_target_parameters(ha, device);
+       spin_unlock_irqrestore(HOST_LOCK, flags);
+       return status;
+ }
+@@ -1761,16 +1452,11 @@ qla1280_select_queue_depth(struct Scsi_H
+       if (scsi_devs)
+               qla1280_check_for_dead_scsi_bus(ha, scsi_devs->channel);
+-
+       LEAVE("qla1280_select_queue_depth");
+ }
+ #endif
+ /*
+- * Driver Support Routines
+- */
+-
+-/*
+  * qla1280_done
+  *      Process completed commands.
+  *
+@@ -1972,100 +1658,19 @@ qla1280_done_q_put(struct srb * sp, stru
+       LEAVE("qla1280_put_done_q");
+ }
+-
+-/*
+-* qla1280_mem_alloc
+-*      Allocates adapter memory.
+-*
+-* Returns:
+-*      0  = success.
+-*      1  = failure.
+-*/
+-static int
+-qla1280_mem_alloc(struct scsi_qla_host *ha)
+-{
+-      int status = 1;
+-      dma_addr_t dma_handle;
+-
+-      ENTER("qla1280_mem_alloc");
+-
+-      /* get consistent memory allocated for request and response rings */
+-      ha->request_ring = pci_alloc_consistent(ha->pdev,
+-                                              ((REQUEST_ENTRY_CNT + 1) *
+-                                               (sizeof(request_t))),
+-                                              &dma_handle);
+-      if (!ha->request_ring)
+-              goto error;
+-      ha->request_dma = dma_handle;
+-      ha->response_ring = pci_alloc_consistent(ha->pdev,
+-                                               ((RESPONSE_ENTRY_CNT + 1) *
+-                                                (sizeof(struct response))),
+-                                               &dma_handle);
+-      if (!ha->response_ring)
+-              goto error;
+-      ha->response_dma = dma_handle;
+-      status = 0;
+-      goto finish;
+-
+- error:
+-      if (status)
+-              dprintk(2, "qla1280_mem_alloc: **** FAILED ****\n");
+-
+-      if (ha->request_ring)
+-              pci_free_consistent(ha->pdev,
+-                                    ((REQUEST_ENTRY_CNT + 1) *
+-                                   (sizeof(request_t))),
+-                                    ha->request_ring, ha->request_dma);
+- finish:
+-      LEAVE("qla1280_mem_alloc");
+-      return status;
+-}
+-
+-/*
+- * qla1280_mem_free
+- *      Frees adapter allocated memory.
+- *
+- * Input:
+- *      ha = adapter block pointer.
+- */
+-static void
+-qla1280_mem_free(struct scsi_qla_host *ha)
+-{
+-      ENTER("qlc1280_mem_free");
+-      /* free consistent memory allocated for request and response rings */
+-      if (ha->request_ring)
+-              pci_free_consistent(ha->pdev,
+-                                  ((REQUEST_ENTRY_CNT + 1) *
+-                                   (sizeof(request_t))),
+-                                  ha->request_ring, ha->request_dma);
+-
+-      if (ha->response_ring)
+-              pci_free_consistent(ha->pdev,
+-                                  ((RESPONSE_ENTRY_CNT + 1) *
+-                                   (sizeof(struct response))),
+-                                  ha->response_ring, ha->response_dma);
+-
+-      if (qla1280_buffer) {
+-              free_page((unsigned long) qla1280_buffer);
+-              qla1280_buffer = NULL;
+-      }
+-
+-      LEAVE("qlc1280_mem_free");
+-}
+-
+ /****************************************************************************/
+ /*                QLogic ISP1280 Hardware Support Functions.                */
+ /****************************************************************************/
+  /*
+-    * qla2100_enable_intrs
+-    * qla2100_disable_intrs
+-    *
+-    * Input:
+-    *      ha = adapter block pointer.
+-    *
+-    * Returns:
+-    *      None
++  * qla2100_enable_intrs
++  * qla2100_disable_intrs
++  *
++  * Input:
++  *      ha = adapter block pointer.
++  *
++  * Returns:
++  *      None
+   */
+ static inline void
+ qla1280_enable_intrs(struct scsi_qla_host *ha)
+@@ -2101,7 +1706,7 @@ qla1280_disable_intrs(struct scsi_qla_ho
+  * Returns:
+  *      0 = success
+  */
+-static int
++static int __devinit
+ qla1280_initialize_adapter(struct scsi_qla_host *ha)
+ {
+       struct device_reg *reg;
+@@ -2297,7 +1902,7 @@ qla1280_isp_firmware(struct scsi_qla_hos
+  * Returns:
+  *      0 = success.
+  */
+-static int
++static int __devinit
+ qla1280_pci_config(struct scsi_qla_host *ha)
+ {
+ #if MEMORY_MAPPED_IO
+@@ -2724,8 +2329,8 @@ qla1280_nvram_config(struct scsi_qla_hos
+       ENTER("qla1280_nvram_config");
+-      if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+-          ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160)
++      if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
++          ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160)
+               is1x160 = 1;
+       else
+               is1x160 = 0;
+@@ -4207,48 +3812,6 @@ qla1280_isp_cmd(struct scsi_qla_host *ha
+       LEAVE("qla1280_isp_cmd");
+ }
+-#if QL1280_LUN_SUPPORT
+-/*
+- * qla1280_enable_lun
+- *      Issue enable LUN entry IOCB.
+- *
+- * Input:
+- *      ha  = adapter block pointer.
+- *      bus = SCSI BUS number.
+- *      lun  = LUN number.
+- */
+-static void
+-qla1280_enable_lun(struct scsi_qla_host *ha, int bus, int lun)
+-{
+-      struct elun_entry *pkt;
+-
+-      ENTER("qla1280_enable_lun");
+-
+-      /* Get request packet. */
+-      /*
+-        if (pkt = (struct elun_entry *)qla1280_req_pkt(ha))
+-        {
+-        pkt->entry_type = ENABLE_LUN_TYPE;
+-        pkt->lun = cpu_to_le16(bus ? lun | BIT_15 : lun);
+-        pkt->command_count = 32;
+-        pkt->immed_notify_count = 1;
+-        pkt->group_6_length = MAX_CMDSZ;
+-        pkt->group_7_length = MAX_CMDSZ;
+-        pkt->timeout = cpu_to_le16(0x30);
+-
+-        qla1280_isp_cmd(ha);
+-        }
+-      */
+-      pkt = (struct elun_entry *) 1;
+-
+-      if (!pkt)
+-              dprintk(2, "qla1280_enable_lun: **** FAILED ****\n");
+-      else
+-              dprintk(3, "qla1280_enable_lun: exiting normally\n");
+-}
+-#endif
+-
+-
+ /****************************************************************************/
+ /*                        Interrupt Service Routine.                        */
+ /****************************************************************************/
+@@ -4894,7 +4457,7 @@ qla1280_check_for_dead_scsi_bus(struct s
+ }
+ static void
+-qla12160_get_target_parameters(struct scsi_qla_host *ha, Scsi_Device *device)
++qla1280_get_target_parameters(struct scsi_qla_host *ha, Scsi_Device *device)
+ {
+       uint16_t mb[MAILBOX_REGISTER_COUNT];
+       int bus, target, lun;
+@@ -5136,34 +4699,274 @@ qla1280_get_token(char *str)
+       return ret;
+ }
+-
+-static Scsi_Host_Template driver_template = {
+-      .proc_info              = qla1280_proc_info,
++static Scsi_Host_Template qla1280_driver_template = {
++      .proc_name              = "qla1280",
+       .name                   = "Qlogic ISP 1280/12160",
++#if LINUX_VERSION_CODE >= 0x020545
++      .slave_configure        = qla1280_slave_configure,
++#else
+       .detect                 = qla1280_detect,
+       .release                = qla1280_release,
++#endif
+       .info                   = qla1280_info,
+       .queuecommand           = qla1280_queuecommand,
+-#if LINUX_VERSION_CODE >= 0x020545
+-      .slave_configure        = qla1280_slave_configure,
+-#endif
+       .eh_abort_handler       = qla1280_eh_abort,
+       .eh_device_reset_handler= qla1280_eh_device_reset,
+       .eh_bus_reset_handler   = qla1280_eh_bus_reset,
+       .eh_host_reset_handler  = qla1280_eh_adapter_reset,
+       .bios_param             = qla1280_biosparam,
+-      .can_queue              = 255,
++      .proc_info              = qla1280_proc_info,
++      .can_queue              = 0xfffff,
+       .this_id                = -1,
+       .sg_tablesize           = SG_ALL,
+-      .cmd_per_lun            = 3,
++      .cmd_per_lun            = 1,
+       .use_clustering         = ENABLE_CLUSTERING,
+ #if LINUX_VERSION_CODE < 0x020545
+       .use_new_eh_code        = 1,
+ #endif
+ };
+-#include "scsi_module.c"
++static int __devinit
++qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
++{
++      int devnum = id->driver_data;
++      struct qla_boards *bdp = &ql1280_board_tbl[devnum];
++      struct Scsi_Host *host;
++      struct scsi_qla_host *ha;
++      int error = -ENODEV;
++
++      /* Bypass all AMI SUBSYS VENDOR IDs */
++      if (pdev->subsystem_vendor == PCI_VENDOR_ID_AMI) {
++              printk(KERN_INFO
++                     "qla1280: Skipping AMI SubSys Vendor ID Chip\n");
++              goto error;
++      }
++
++      printk(KERN_INFO "qla1280: %s found on PCI bus %i, dev %i\n",
++             bdp->name, pdev->bus->number, PCI_SLOT(pdev->devfn));
++
++      if (pci_enable_device(pdev)) {
++              printk(KERN_WARNING
++                     "qla1280: Failed to enabled pci device, aborting.\n");
++              goto error;
++      }
++
++      error = -ENOMEM;
++      host = scsi_host_alloc(&qla1280_driver_template, sizeof(*ha));
++      if (!host) {
++              printk(KERN_WARNING
++                     "qla1280: Failed to register host, aborting.\n");
++              goto error;
++      }
++
++      ha = (struct scsi_qla_host *)host->hostdata;
++      memset(ha, 0, sizeof(struct scsi_qla_host));
++
++      ha->pdev = pdev;
++      ha->devnum = devnum;    /* specifies microcode load address */
++
++      ha->request_ring = pci_alloc_consistent(ha->pdev,
++                      ((REQUEST_ENTRY_CNT + 1) * (sizeof(request_t))),
++                      &ha->request_dma);
++      if (!ha->request_ring) {
++              printk(KERN_INFO "qla1280: Failed to get request memory\n");
++              goto error_put_host;
++      }
++
++      ha->response_ring = pci_alloc_consistent(ha->pdev,
++                      ((RESPONSE_ENTRY_CNT + 1) * (sizeof(struct response))),
++                      &ha->response_dma);
++      if (!ha->response_ring) {
++              printk(KERN_INFO "qla1280: Failed to get response memory\n");
++              goto error_free_request_ring;
++      }
++
++      ha->ports = bdp->numPorts;
++
++      ha->host = host;
++      ha->host_no = host->host_no;
++
++      host->irq = pdev->irq;
++      host->base = (unsigned long)ha->mmpbase;
++      host->max_channel = bdp->numPorts - 1;
++      host->max_lun = MAX_LUNS - 1;
++      host->max_id = MAX_TARGETS;
++      host->max_sectors = 1024;
++      host->unique_id = host->host_no;
++
++#if LINUX_VERSION_CODE < 0x020545
++      host->select_queue_depths = qla1280_select_queue_depth;
++#endif
++
++      error = -ENODEV;
++      if (qla1280_pci_config(ha)) {
++              printk(KERN_INFO "qla1280: Unable to configure PCI\n");
++              goto error_free_response_ring;
++      }
++
++      /* Disable ISP interrupts. */
++      qla1280_disable_intrs(ha);
++
++      /* Register the IRQ with Linux (sharable) */
++      if (request_irq(pdev->irq, qla1280_intr_handler, SA_SHIRQ,
++                              "qla1280", ha)) {
++              printk("qla1280 : Failed to reserve interrupt %d already "
++                     "in use\n", pdev->irq);
++              goto error_iounmap;
++      }
++
++#if !MEMORY_MAPPED_IO
++      /* Register the I/O space with Linux */
++      if (!request_region(host->io_port, 0xff, "qla1280")) {
++              printk("qla1280: Failed to reserve i/o region 0x%04lx-0x%04lx"
++                     " already in use\n",
++                     host->io_port, host->io_port + 0xff);
++              goto error_free_irq;
++      }
++#endif
++
++      /* load the F/W, read paramaters, and init the H/W */
++      if (qla1280_initialize_adapter(ha)) {
++              printk(KERN_INFO "qla1x160: Failed to initialize adapter\n");
++              goto error_release_region;
++      }
++
++      /* set our host ID  (need to do something about our two IDs) */
++      host->this_id = ha->bus_settings[0].id;
++
++      pci_set_drvdata(pdev, host);
++
++#if LINUX_VERSION_CODE >= 0x020600
++      error = scsi_add_host(host, &pdev->dev);
++      if (error)
++              goto error_disable_adapter;
++      scsi_scan_host(host);
++#else
++      scsi_set_pci_device(host, pdev);
++#endif
++
++      return 0;
++
++#if LINUX_VERSION_CODE >= 0x020600
++ error_disable_adapter:
++      WRT_REG_WORD(&ha->iobase->ictrl, 0);
++#endif
++ error_release_region:
++#if !MEMORY_MAPPED_IO
++      release_region(host->io_port, 0xff);
++ error_free_irq:
++#endif
++      free_irq(pdev->irq, ha);
++ error_iounmap:
++#if MEMORY_MAPPED_IO
++      iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK));
++#endif
++ error_free_response_ring:
++      pci_free_consistent(ha->pdev,
++                      ((RESPONSE_ENTRY_CNT + 1) * (sizeof(struct response))),
++                      ha->response_ring, ha->response_dma);
++ error_free_request_ring:
++      pci_free_consistent(ha->pdev,
++                      ((REQUEST_ENTRY_CNT + 1) * (sizeof(request_t))),
++                      ha->request_ring, ha->request_dma);
++ error_put_host:
++      scsi_host_put(host);
++ error:
++      return error;
++}
++
++/*
++ * Older ia64 toolchains have problems with relative links when this
++ * goes into the .exit.text section
++ */
++#if !defined(CONFIG_QLA1280_MODULE) && defined(__ia64__) && (__GNUC__ == 2)
++static void
++#else
++static void __devexit
++#endif
++qla1280_remove_one(struct pci_dev *pdev)
++{
++      struct Scsi_Host *host = pci_get_drvdata(pdev);
++      struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
++
++#if LINUX_VERSION_CODE >= 0x020600
++      scsi_remove_host(host);
++#endif
++
++      WRT_REG_WORD(&ha->iobase->ictrl, 0);
++
++      free_irq(pdev->irq, ha);
++
++#if MEMORY_MAPPED_IO
++      iounmap(ha->mmpbase);
++#else
++      release_region(host->io_port, 0xff);
++#endif
++
++      pci_free_consistent(ha->pdev,
++                      ((REQUEST_ENTRY_CNT + 1) * (sizeof(request_t))),
++                      ha->request_ring, ha->request_dma);
++      pci_free_consistent(ha->pdev,
++                      ((RESPONSE_ENTRY_CNT + 1) * (sizeof(struct response))),
++                      ha->response_ring, ha->response_dma);
++
++      scsi_host_put(host);
++}
++
++#if LINUX_VERSION_CODE >= 0x020600
++static struct pci_driver qla1280_pci_driver = {
++      .name           = "qla1280",
++      .id_table       = qla1280_pci_tbl,
++      .probe          = qla1280_probe_one,
++      .remove         = __devexit_p(qla1280_remove_one),
++};
++
++static int __init
++qla1280_init(void)
++{
++      if (sizeof(struct srb) > sizeof(Scsi_Pointer)) {
++              printk(KERN_WARNING
++                     "qla1280: struct srb too big, aborting\n");
++              return -EINVAL;
++      }
++
++#ifdef MODULE
++      /*
++       * If we are called as a module, the qla1280 pointer may not be null
++       * and it would point to our bootup string, just like on the lilo
++       * command line.  IF not NULL, then process this config string with
++       * qla1280_setup
++       *
++       * Boot time Options
++       * To add options at boot time add a line to your lilo.conf file like:
++       * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}"
++       * which will result in the first four devices on the first two
++       * controllers being set to a tagged queue depth of 32.
++       */
++      if (qla1280)
++              qla1280_setup(qla1280);
++#endif
++
++      return pci_module_init(&qla1280_pci_driver);
++}
++static void __exit
++qla1280_exit(void)
++{
++      pci_unregister_driver(&qla1280_pci_driver);
++}
++
++module_init(qla1280_init);
++module_exit(qla1280_exit);
++
++#else
++# define driver_template qla1280_driver_template
++# include "scsi_module.c"
++#endif
++
++MODULE_AUTHOR("Qlogic & Jes Sorensen");
++MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver");
++MODULE_LICENSE("GPL");
+ /*
+  * Overrides for Emacs so that we almost follow Linus's tabbing style.
+--- linux-2.6.0/drivers/scsi/qla1280.h 2003-09-27 18:57:45.000000000 -0700
++++ 25/drivers/scsi/qla1280.h  2003-12-28 23:21:38.000000000 -0800
+@@ -1021,11 +1021,7 @@ struct scsi_qla_host {
+       unsigned char *mmpbase; /* memory mapped address */
+       unsigned long host_no;
+-      unsigned long instance;
+       struct pci_dev *pdev;
+-      uint32_t device_id;
+-      uint8_t pci_bus;
+-      uint8_t pci_device_fn;
+       uint8_t devnum;
+       uint8_t revision;
+       uint8_t ports;
+@@ -1040,18 +1036,9 @@ struct scsi_qla_host {
+       /* BUS configuration data */
+       struct bus_param bus_settings[MAX_BUSES];
+-#if 0
+-      /* bottom half run queue */
+-      struct tq_struct run_qla_bh;
+-#endif
+-
+       /* Received ISP mailbox data. */
+       volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT];
+-#ifdef UNUSED
+-      struct timer_list dev_timer[MAX_TARGETS];
+-#endif
+-
+       dma_addr_t request_dma;         /* Physical Address */
+       request_t *request_ring;        /* Base virtual address */
+       request_t *request_ring_ptr;    /* Current address. */
+@@ -1063,15 +1050,6 @@ struct scsi_qla_host {
+       struct response *response_ring_ptr;     /* Current address. */
+       uint16_t rsp_ring_index;        /* Current index. */
+-#if WATCHDOGTIMER
+-      /* Watchdog queue, lock and total timer */
+-      uint8_t watchdog_q_lock;        /* Lock for watchdog queue */
+-      struct srb *wdg_q_first;        /* First job on watchdog queue */
+-      struct srb *wdg_q_last; /* Last job on watchdog queue */
+-      uint32_t total_timeout; /* Total timeout (quantum count) */
+-      uint32_t watchdogactive;
+-#endif
+-
+       struct srb *done_q_first;       /* First job on done queue */
+       struct srb *done_q_last;        /* Last job on done queue */
+--- linux-2.6.0/drivers/scsi/sd.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sd.c       2003-12-28 23:21:45.000000000 -0800
+@@ -62,6 +62,7 @@
+  */
+ #define SD_MAJORS     16
+ #define SD_DISKS      (SD_MAJORS << 4)
++#define TOTAL_SD_DISKS        CONFIG_MAX_SD_DISKS
+ /*
+  * Time out in seconds for disks and Magneto-opticals (which are slower).
+@@ -95,7 +96,7 @@ struct scsi_disk {
+ };
+-static unsigned long sd_index_bits[SD_DISKS / BITS_PER_LONG];
++static unsigned long sd_index_bits[TOTAL_SD_DISKS / BITS_PER_LONG];
+ static spinlock_t sd_index_lock = SPIN_LOCK_UNLOCKED;
+ static int sd_revalidate_disk(struct gendisk *disk);
+@@ -130,6 +131,9 @@ static int sd_major(int major_idx)
+               return SCSI_DISK1_MAJOR + major_idx - 1;
+       case 8 ... 15:
+               return SCSI_DISK8_MAJOR + major_idx - 8;
++#define MAX_IDX        (TOTAL_SD_DISKS >> 4)
++      case 16 ... MAX_IDX:
++              return SCSI_DISK15_MAJOR;
+       default:
+               BUG();
+               return 0;       /* shut up gcc */
+@@ -378,9 +382,9 @@ queue:
+  *    In the latter case @inode and @filp carry an abridged amount
+  *    of information as noted above.
+  **/
+-static int sd_open(struct inode *inode, struct file *filp)
++static int sd_open(struct block_device *bdev, struct file *filp)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
++      struct gendisk *disk = bdev->bd_disk;
+       struct scsi_disk *sdkp = scsi_disk(disk);
+       struct scsi_device *sdev;
+       int retval;
+@@ -402,7 +406,7 @@ static int sd_open(struct inode *inode, 
+               goto error_out;
+       if (sdev->removable || sdkp->write_prot)
+-              check_disk_change(inode->i_bdev);
++              check_disk_change(bdev);
+       /*
+        * If the drive is empty, just let the open fail.
+@@ -453,9 +457,8 @@ error_out:
+  *    Note: may block (uninterruptible) if error recovery is underway
+  *    on this disk.
+  **/
+-static int sd_release(struct inode *inode, struct file *filp)
++static int sd_release(struct gendisk *disk)
+ {
+-      struct gendisk *disk = inode->i_bdev->bd_disk;
+       struct scsi_disk *sdkp = scsi_disk(disk);
+       struct scsi_device *sdev = sdkp->device;
+@@ -518,10 +521,9 @@ static int sd_hdio_getgeo(struct block_d
+  *    Note: most ioctls are forward onto the block subsystem or further
+  *    down in the scsi subsytem.
+  **/
+-static int sd_ioctl(struct inode * inode, struct file * filp, 
++static int sd_ioctl(struct block_device *bdev, struct file *filp,
+                   unsigned int cmd, unsigned long arg)
+ {
+-      struct block_device *bdev = inode->i_bdev;
+       struct gendisk *disk = bdev->bd_disk;
+       struct scsi_device *sdp = scsi_disk(disk)->device;
+       int error;
+@@ -1320,8 +1322,8 @@ static int sd_probe(struct device *dev)
+               goto out_free;
+       spin_lock(&sd_index_lock);
+-      index = find_first_zero_bit(sd_index_bits, SD_DISKS);
+-      if (index == SD_DISKS) {
++      index = find_first_zero_bit(sd_index_bits, TOTAL_SD_DISKS);
++      if (index == TOTAL_SD_DISKS) {
+               spin_unlock(&sd_index_lock);
+               error = -EBUSY;
+               goto out_put;
+@@ -1336,15 +1338,24 @@ static int sd_probe(struct device *dev)
+       sdkp->openers = 0;
+       gd->major = sd_major(index >> 4);
+-      gd->first_minor = (index & 15) << 4;
++      if (index > SD_DISKS)
++              gd->first_minor = ((index - SD_DISKS) & 15) << 4;
++      else
++              gd->first_minor = (index & 15) << 4;
+       gd->minors = 16;
+       gd->fops = &sd_fops;
+-      if (index >= 26) {
++      if (index < 26) {
++              sprintf(gd->disk_name, "sd%c", 'a' + index % 26);
++      } else if (index < (26*27)) {
+               sprintf(gd->disk_name, "sd%c%c",
+                       'a' + index/26-1,'a' + index % 26);
+       } else {
+-              sprintf(gd->disk_name, "sd%c", 'a' + index % 26);
++              const unsigned int m1 = (index/ 26 - 1) / 26 - 1;
++              const unsigned int m2 = (index / 26 - 1) % 26;
++              const unsigned int m3 = index % 26;
++              sprintf(gd->disk_name, "sd%c%c%c",
++                      'a' + m1, 'a' + m2, 'a' + m3);
+       }
+       strcpy(gd->devfs_name, sdp->devfs_name);
+--- linux-2.6.0/drivers/scsi/sg.c      2003-11-23 19:03:01.000000000 -0800
++++ 25/drivers/scsi/sg.c       2003-12-28 23:22:25.000000000 -0800
+@@ -1118,7 +1118,7 @@ sg_rb_correct4mmap(Sg_scatter_hold * rsv
+ }
+ static struct page *
+-sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int unused)
++sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
+ {
+       Sg_fd *sfp;
+       struct page *page = NOPAGE_SIGBUS;
+@@ -1158,6 +1158,8 @@ sg_vma_nopage(struct vm_area_struct *vma
+               page = virt_to_page(page_ptr);
+               get_page(page); /* increment page count */
+       }
++      if (type)
++              *type = VM_FAULT_MINOR;
+       return page;
+ }
+@@ -2974,3 +2976,4 @@ sg_proc_version_info(char *buffer, int *
+ module_init(init_sg);
+ module_exit(exit_sg);
++MODULE_ALIAS_CHARDEV_MAJOR(SCSI_GENERIC_MAJOR);
+--- linux-2.6.0/drivers/scsi/sr.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sr.c       2003-12-28 23:22:35.000000000 -0800
+@@ -67,7 +67,8 @@ MODULE_PARM(xa_test, "i");   /* see sr_ioc
+       (CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \
+        CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \
+        CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \
+-       CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET)
++       CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \
++       CDC_MRW|CDC_MRW_W|CDC_RAM)
+ static int sr_probe(struct device *);
+ static int sr_remove(struct device *);
+@@ -413,22 +414,22 @@ queue:
+       return 1;
+ }
+-static int sr_block_open(struct inode *inode, struct file *file)
++static int sr_block_open(struct block_device *bdev, struct file *file)
+ {
+-      struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
+-      return cdrom_open(&cd->cdi, inode, file);
++      struct scsi_cd *cd = scsi_cd(bdev->bd_disk);
++      return cdrom_open(&cd->cdi, bdev, file);
+ }
+-static int sr_block_release(struct inode *inode, struct file *file)
++static int sr_block_release(struct gendisk *disk)
+ {
+-      struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
+-      return cdrom_release(&cd->cdi, file);
++      struct scsi_cd *cd = scsi_cd(disk);
++      return cdrom_release(&cd->cdi);
+ }
+-static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
+-                        unsigned long arg)
++static int sr_block_ioctl(struct block_device *bdev, struct file *file,
++                        unsigned cmd, unsigned long arg)
+ {
+-      struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
++      struct scsi_cd *cd = scsi_cd(bdev->bd_disk);
+       struct scsi_device *sdev = cd->device;
+         /*
+@@ -440,7 +441,7 @@ static int sr_block_ioctl(struct inode *
+                 case SCSI_IOCTL_GET_BUS_NUMBER:
+                         return scsi_ioctl(sdev, cmd, (void *)arg);
+       }
+-      return cdrom_ioctl(&cd->cdi, inode, cmd, arg);
++      return cdrom_ioctl(&cd->cdi, bdev, cmd, arg);
+ }
+ static int sr_block_media_changed(struct gendisk *disk)
+@@ -692,7 +693,7 @@ Enomem:
+ static void get_capabilities(struct scsi_cd *cd)
+ {
+       unsigned char *buffer;
+-      int rc, n;
++      int rc, n, mrw_write = 0, mrw = 1;
+       struct scsi_mode_data data;
+       struct scsi_request *SRpnt;
+       unsigned char cmd[MAX_COMMAND_SIZE];
+@@ -765,6 +766,15 @@ static void get_capabilities(struct scsi
+               printk("%s: scsi-1 drive\n", cd->cdi.name);
+               return;
+       }
++
++      if (cdrom_is_mrw(&cd->cdi, &mrw_write)) {
++              mrw = 0;
++              cd->cdi.mask |= CDC_MRW;
++              cd->cdi.mask |= CDC_MRW_W;
++      }
++      if (!mrw_write)
++              cd->cdi.mask |= CDC_MRW_W;
++
+       n = data.header_length + data.block_descriptor_length;
+       cd->cdi.speed = ((buffer[n + 8] << 8) + buffer[n + 9]) / 176;
+       cd->readcd_known = 1;
+@@ -788,9 +798,7 @@ static void get_capabilities(struct scsi
+       if ((buffer[n + 3] & 0x20) == 0) {
+               /* can't write DVD-RAM media */
+               cd->cdi.mask |= CDC_DVD_RAM;
+-      } else {
+-              cd->device->writeable = 1;
+-      }
++      } else
+       if ((buffer[n + 3] & 0x10) == 0)
+               /* can't write DVD-R media */
+               cd->cdi.mask |= CDC_DVD_R;
+@@ -814,6 +822,12 @@ static void get_capabilities(struct scsi
+       /*else    I don't think it can close its tray
+               cd->cdi.mask |= CDC_CLOSE_TRAY; */
++      /*
++       * if DVD-RAM of MRW-W, we are randomly writeable
++       */
++      if ((cd->cdi.mask & (CDC_DVD_RAM | CDC_MRW_W)) != (CDC_DVD_RAM | CDC_MRW_W))
++              cd->device->writeable = 1;
++
+       scsi_release_request(SRpnt);
+       kfree(buffer);
+ }
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym53c8xx.h   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sym53c8xx_2/sym53c8xx.h    2003-12-28 23:21:49.000000000 -0800
+@@ -55,19 +55,7 @@
+ #include <linux/config.h>
+-/*
+- *  Use normal IO if configured.
+- *  Normal IO forced for alpha.
+- *  Forced to MMIO for sparc.
+- */
+-#if defined(__alpha__)
+-#define       SYM_CONF_IOMAPPED
+-#elif defined(__sparc__)
+-#undef SYM_CONF_IOMAPPED
+-/* #elif defined(__powerpc__) */
+-/* #define    SYM_CONF_IOMAPPED */
+-/* #define SYM_OPT_NO_BUS_MEMORY_MAPPING */
+-#elif defined(CONFIG_SCSI_SYM53C8XX_IOMAPPED)
++#ifdef CONFIG_SCSI_SYM53C8XX_IOMAPPED
+ #define       SYM_CONF_IOMAPPED
+ #endif
+@@ -93,8 +81,6 @@
+  */
+ #if 1
+ #define SYM_CONF_NVRAM_SUPPORT                (1)
+-#define SYM_SETUP_SYMBIOS_NVRAM               (1)
+-#define SYM_SETUP_TEKRAM_NVRAM                (1)
+ #endif
+ /*
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym_fw1.h     2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sym53c8xx_2/sym_fw1.h      2003-12-28 23:21:49.000000000 -0800
+@@ -234,10 +234,6 @@ struct SYM_FWB_SCR {
+ struct SYM_FWZ_SCR {
+       u32 snooptest           [  9];
+       u32 snoopend            [  2];
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      u32 start_ram           [  1];
+-      u32 scripta0_ba         [  4];
+-#endif
+ };
+ static struct SYM_FWA_SCR SYM_FWA_SCR = {
+@@ -1851,24 +1847,5 @@ static struct SYM_FWZ_SCR SYM_FWZ_SCR = 
+        */
+       SCR_INT,
+               99,
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      /*
+-       *  We may use MEMORY MOVE instructions to load the on chip-RAM,
+-       *  if it happens that mapping PCI memory is not possible.
+-       *  But writing the RAM from the CPU is the preferred method, 
+-       *  since PCI 2.2 seems to disallow PCI self-mastering.
+-       */
+-}/*-------------------------< START_RAM >------------------------*/,{
+-      /*
+-       *  Load the script into on-chip RAM, 
+-       *  and jump to start point.
+-       */
+-      SCR_COPY (sizeof(struct SYM_FWA_SCR)),
+-}/*-------------------------< SCRIPTA0_BA >----------------------*/,{
+-              0,
+-              PADDR_A (start),
+-      SCR_JUMP,
+-              PADDR_A (init),
+-#endif /* SYM_OPT_NO_BUS_MEMORY_MAPPING */
+ }/*--------------------------<>----------------------------------*/
+ };
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym_fw2.h     2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sym53c8xx_2/sym_fw2.h      2003-12-28 23:21:49.000000000 -0800
+@@ -228,14 +228,6 @@ struct SYM_FWB_SCR {
+ struct SYM_FWZ_SCR {
+       u32 snooptest           [  6];
+       u32 snoopend            [  2];
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      u32 start_ram           [  1];
+-      u32 scripta0_ba         [  4];
+-      u32 start_ram64         [  3];
+-      u32 scripta0_ba64       [  3];
+-      u32 scriptb0_ba64       [  6];
+-      u32 ram_seg64           [  1];
+-#endif
+ };
+ static struct SYM_FWA_SCR SYM_FWA_SCR = {
+@@ -1944,51 +1936,5 @@ static struct SYM_FWZ_SCR SYM_FWZ_SCR = 
+        */
+       SCR_INT,
+               99,
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      /*
+-       *  We may use MEMORY MOVE instructions to load the on chip-RAM,
+-       *  if it happens that mapping PCI memory is not possible.
+-       *  But writing the RAM from the CPU is the preferred method, 
+-       *  since PCI 2.2 seems to disallow PCI self-mastering.
+-       */
+-}/*-------------------------< START_RAM >------------------------*/,{
+-      /*
+-       *  Load the script into on-chip RAM, 
+-       *  and jump to start point.
+-       */
+-      SCR_COPY (sizeof(struct SYM_FWA_SCR)),
+-}/*-------------------------< SCRIPTA0_BA >----------------------*/,{
+-              0,
+-              PADDR_A (start),
+-      SCR_JUMP,
+-              PADDR_A (init),
+-}/*-------------------------< START_RAM64 >----------------------*/,{
+-      /*
+-       *  Load the RAM and start for 64 bit PCI (895A,896).
+-       *  Both scripts (script and scripth) are loaded into 
+-       *  the RAM which is 8K (4K for 825A/875/895).
+-       *  We also need to load some 32-63 bit segments 
+-       *  address of the SCRIPTS processor.
+-       *  LOAD/STORE ABSOLUTE always refers to on-chip RAM 
+-       *  in our implementation. The main memory is 
+-       *  accessed using LOAD/STORE DSA RELATIVE.
+-       */
+-      SCR_LOAD_REL (mmws, 4),
+-              offsetof (struct sym_hcb, scr_ram_seg),
+-      SCR_COPY (sizeof(struct SYM_FWA_SCR)),
+-}/*-------------------------< SCRIPTA0_BA64 >--------------------*/,{
+-              0,
+-              PADDR_A (start),
+-      SCR_COPY (sizeof(struct SYM_FWB_SCR)),
+-}/*-------------------------< SCRIPTB0_BA64 >--------------------*/,{
+-              0,
+-              PADDR_B  (start64),
+-      SCR_LOAD_REL (mmrs, 4),
+-              offsetof (struct sym_hcb, scr_ram_seg),
+-      SCR_JUMP64,
+-              PADDR_B (start64),
+-}/*-------------------------< RAM_SEG64 >------------------------*/,{
+-              0,
+-#endif /* SYM_OPT_NO_BUS_MEMORY_MAPPING */
+ }/*-------------------------<>-----------------------------------*/
+ };
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym_fw.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sym53c8xx_2/sym_fw.c       2003-12-28 23:21:49.000000000 -0800
+@@ -89,9 +89,6 @@ static struct sym_fwb_ofs sym_fw1b_ofs =
+ };
+ static struct sym_fwz_ofs sym_fw1z_ofs = {
+       SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      SYM_GEN_Z(struct SYM_FWZ_SCR, start_ram)
+-#endif
+ };
+ #undef        SYM_FWA_SCR
+ #undef        SYM_FWB_SCR
+@@ -122,10 +119,6 @@ static struct sym_fwb_ofs sym_fw2b_ofs =
+ };
+ static struct sym_fwz_ofs sym_fw2z_ofs = {
+       SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      SYM_GEN_Z(struct SYM_FWZ_SCR, start_ram)
+-      SYM_GEN_Z(struct SYM_FWZ_SCR, start_ram64)
+-#endif
+ };
+ #undef        SYM_FWA_SCR
+ #undef        SYM_FWB_SCR
+@@ -146,22 +139,10 @@ sym_fw1_patch(hcb_p np)
+ {
+       struct sym_fw1a_scr *scripta0;
+       struct sym_fw1b_scr *scriptb0;
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      struct sym_fw1z_scr *scriptz0 = 
+-              (struct sym_fw1z_scr *) np->scriptz0;
+-#endif
+       scripta0 = (struct sym_fw1a_scr *) np->scripta0;
+       scriptb0 = (struct sym_fw1b_scr *) np->scriptb0;
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      /*
+-       *  Set up BUS physical address of SCRIPTS that is to 
+-       *  be copied to on-chip RAM by the SCRIPTS processor.
+-       */
+-      scriptz0->scripta0_ba[0]        = cpu_to_scr(vtobus(scripta0));
+-#endif
+-
+       /*
+        *  Remove LED support if not needed.
+        */
+@@ -199,25 +180,10 @@ sym_fw2_patch(hcb_p np)
+ {
+       struct sym_fw2a_scr *scripta0;
+       struct sym_fw2b_scr *scriptb0;
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      struct sym_fw2z_scr *scriptz0 = 
+-              (struct sym_fw2z_scr *) np->scriptz0;
+-#endif
+       scripta0 = (struct sym_fw2a_scr *) np->scripta0;
+       scriptb0 = (struct sym_fw2b_scr *) np->scriptb0;
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      /*
+-       *  Set up BUS physical address of SCRIPTS that is to 
+-       *  be copied to on-chip RAM by the SCRIPTS processor.
+-       */
+-      scriptz0->scripta0_ba64[0]      = /* Nothing is missing here */
+-      scriptz0->scripta0_ba[0]        = cpu_to_scr(vtobus(scripta0));
+-      scriptz0->scriptb0_ba64[0]      = cpu_to_scr(vtobus(scriptb0));
+-      scriptz0->ram_seg64[0]          = np->scr_ram_seg;
+-#endif
+-
+       /*
+        *  Remove LED support if not needed.
+        */
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym_fw.h      2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sym53c8xx_2/sym_fw.h       2003-12-28 23:21:49.000000000 -0800
+@@ -113,10 +113,6 @@ struct sym_fwb_ofs {
+ };
+ struct sym_fwz_ofs {
+       SYM_GEN_FW_Z(u_short)
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      SYM_GEN_Z(u_short, start_ram)
+-      SYM_GEN_Z(u_short, start_ram64)
+-#endif
+ };
+ /*
+@@ -136,10 +132,6 @@ struct sym_fwb_ba {
+ };
+ struct sym_fwz_ba {
+       SYM_GEN_FW_Z(u32)
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-      SYM_GEN_Z(u32, start_ram)
+-      SYM_GEN_Z(u32, start_ram64)
+-#endif
+ };
+ #undef        SYM_GEN_A
+ #undef        SYM_GEN_B
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym_glue.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sym53c8xx_2/sym_glue.c     2003-12-28 23:21:49.000000000 -0800
+@@ -167,34 +167,16 @@ struct sym_ucmd {                /* Override the SCSI 
+ #define SYM_SCMD_PTR(ucmd) sym_que_entry(ucmd, struct scsi_cmnd, SCp)
+ #define SYM_SOFTC_PTR(cmd) (((struct host_data *)cmd->device->host->hostdata)->ncb)
+-/*
+- *  Deal with DMA mapping/unmapping.
+- */
+-#define       bus_unmap_sg(pdev, sgptr, sgcnt, dir)           \
+-      pci_unmap_sg(pdev, sgptr, sgcnt, dir)
+-#define       bus_unmap_single(pdev, mapping, bufptr, dir)    \
+-      pci_unmap_single(pdev, mapping, bufptr, dir)
+-#define       bus_map_single(pdev, bufptr, bufsiz, dir)       \
+-      pci_map_single(pdev, bufptr, bufsiz, dir)
+-#define       bus_map_sg(pdev, sgptr, sgcnt, dir)             \
+-      pci_map_sg(pdev, sgptr, sgcnt, dir)
+-#define       bus_dma_sync_sg(pdev, sgptr, sgcnt, dir)        \
+-      pci_dma_sync_sg(pdev, sgptr, sgcnt, dir)
+-#define       bus_dma_sync_single(pdev, mapping, bufsiz, dir) \
+-      pci_dma_sync_single(pdev, mapping, bufsiz, dir)
+-#define bus_sg_dma_address(sc)        sg_dma_address(sc)
+-#define bus_sg_dma_len(sc)    sg_dma_len(sc)
+-
+ static void __unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
+ {
+       int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+       switch(SYM_UCMD_PTR(cmd)->data_mapped) {
+       case 2:
+-              bus_unmap_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
++              pci_unmap_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
+               break;
+       case 1:
+-              bus_unmap_single(pdev, SYM_UCMD_PTR(cmd)->data_mapping,
++              pci_unmap_single(pdev, SYM_UCMD_PTR(cmd)->data_mapping,
+                                cmd->request_bufflen, dma_dir);
+               break;
+       }
+@@ -206,7 +188,7 @@ static dma_addr_t __map_scsi_single_data
+       dma_addr_t mapping;
+       int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+-      mapping = bus_map_single(pdev, cmd->request_buffer,
++      mapping = pci_map_single(pdev, cmd->request_buffer,
+                                cmd->request_bufflen, dma_dir);
+       if (mapping) {
+               SYM_UCMD_PTR(cmd)->data_mapped  = 1;
+@@ -221,7 +203,7 @@ static int __map_scsi_sg_data(struct pci
+       int use_sg;
+       int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+-      use_sg = bus_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
++      use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
+       if (use_sg > 0) {
+               SYM_UCMD_PTR(cmd)->data_mapped  = 2;
+               SYM_UCMD_PTR(cmd)->data_mapping = use_sg;
+@@ -236,10 +218,10 @@ static void __sync_scsi_data(struct pci_
+       switch(SYM_UCMD_PTR(cmd)->data_mapped) {
+       case 2:
+-              bus_dma_sync_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
++              pci_dma_sync_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
+               break;
+       case 1:
+-              bus_dma_sync_single(pdev, SYM_UCMD_PTR(cmd)->data_mapping,
++              pci_dma_sync_single(pdev, SYM_UCMD_PTR(cmd)->data_mapping,
+                                   cmd->request_bufflen, dma_dir);
+               break;
+       }
+@@ -469,8 +451,8 @@ static int sym_scatter(struct sym_hcb *n
+               data = &cp->phys.data[SYM_CONF_MAX_SG - use_sg];
+               for (segment = 0; segment < use_sg; segment++) {
+-                      dma_addr_t baddr = bus_sg_dma_address(&scatter[segment]);
+-                      unsigned int len = bus_sg_dma_len(&scatter[segment]);
++                      dma_addr_t baddr = sg_dma_address(&scatter[segment]);
++                      unsigned int len = sg_dma_len(&scatter[segment]);
+                       sym_build_sge(np, &data[segment], baddr, len);
+                       cp->data_len += len;
+@@ -1595,10 +1577,8 @@ static void sym_free_resources(struct sy
+       if (np->s.mmio_va)
+               iounmap(np->s.mmio_va);
+ #endif
+-#ifndef SYM_OPT_NO_BUS_MEMORY_MAPPING
+       if (np->s.ram_va)
+               iounmap(np->s.ram_va);
+-#endif
+       /*
+        *  Free O/S independent resources.
+        */
+@@ -1650,14 +1630,13 @@ out_err32:
+  *  If all is OK, install interrupt handling and
+  *  start the timer daemon.
+  */
+-static int __devinit 
+-sym_attach (struct scsi_host_template *tpnt, int unit, struct sym_device *dev)
++static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt,
++              int unit, struct sym_device *dev)
+ {
+       struct host_data *host_data;
+       struct sym_hcb *np = NULL;
+       struct Scsi_Host *instance = NULL;
+       unsigned long flags;
+-      struct sym_nvram *nvram = dev->nvram;
+       struct sym_fw *fw;
+       printk(KERN_INFO
+@@ -1762,20 +1741,18 @@ sym_attach (struct scsi_host_template *t
+                       np->ram_ws = 8192;
+               else
+                       np->ram_ws = 4096;
+-#ifndef SYM_OPT_NO_BUS_MEMORY_MAPPING
+               np->s.ram_va = ioremap(dev->s.base_2_c, np->ram_ws);
+               if (!np->s.ram_va) {
+                       printf_err("%s: can't map PCI MEMORY region\n",
+                               sym_name(np));
+                       goto attach_failed;
+               }
+-#endif
+       }
+       /*
+        *  Perform O/S independent stuff.
+        */
+-      if (sym_hcb_attach(np, fw, nvram))
++      if (sym_hcb_attach(np, fw, dev->nvram))
+               goto attach_failed;
+@@ -1843,13 +1820,7 @@ sym_attach (struct scsi_host_template *t
+       spin_unlock_irqrestore(instance->host_lock, flags);
+-      /*
+-       *  Now let the generic SCSI driver
+-       *  look for the SCSI devices on the bus ..
+-       */
+-      scsi_add_host(instance, &dev->pdev->dev); /* XXX: handle failure */
+-      scsi_scan_host(instance);
+-      return 0;
++      return instance;
+  reset_failed:
+       printf_err("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, "
+@@ -1857,13 +1828,13 @@ sym_attach (struct scsi_host_template *t
+       spin_unlock_irqrestore(instance->host_lock, flags);
+  attach_failed:
+       if (!instance)
+-              return -1;
++              return NULL;
+       printf_info("%s: giving up ...\n", sym_name(np));
+       if (np)
+               sym_free_resources(np);
+       scsi_host_put(instance);
+-      return -1;
++      return NULL;
+  }
+@@ -2115,7 +2086,7 @@ sym53c8xx_pci_init(struct pci_dev *pdev,
+        *  Ignore Symbios chips controlled by various RAID controllers.
+        *  These controllers set value 0x52414944 at RAM end - 16.
+        */
+-#if defined(__i386__) && !defined(SYM_OPT_NO_BUS_MEMORY_MAPPING)
++#if defined(__i386__)
+       if (base_2_c) {
+               unsigned int ram_size, ram_val;
+               void *ram_ptr;
+@@ -2202,12 +2173,9 @@ sym53c8xx_pci_init(struct pci_dev *pdev,
+ /*
+- *  Linux release module stuff.
+- *
+  *  Called before unloading the module.
+  *  Detach the host.
+  *  We have to free resources and halt the NCR chip.
+- *
+  */
+ static int __devexit sym_detach(struct sym_hcb *np)
+ {
+@@ -2216,18 +2184,15 @@ static int __devexit sym_detach(struct s
+       del_timer_sync(&np->s.timer);
+       /*
+-       *  Reset NCR chip.
+-       *  We should use sym_soft_reset(), but we donnot want to do 
+-       *  so, since we may not be safe if interrupts occur.
++       * Reset NCR chip.
++       * We should use sym_soft_reset(), but we don't want to do
++       * so, since we may not be safe if interrupts occur.
+        */
+       printk("%s: resetting chip\n", sym_name(np));
+       OUTB (nc_istat, SRST);
+       UDELAY (10);
+       OUTB (nc_istat, 0);
+-      /*
+-       *  Free host resources
+-       */
+       sym_free_resources(np);
+       return 1;
+@@ -2336,6 +2301,7 @@ static int __devinit sym2_probe(struct p
+ {
+       struct sym_device sym_dev;
+       struct sym_nvram nvram;
++      struct Scsi_Host *instance;
+       memset(&sym_dev, 0, sizeof(sym_dev));
+       memset(&nvram, 0, sizeof(nvram));
+@@ -2354,12 +2320,20 @@ static int __devinit sym2_probe(struct p
+       sym_get_nvram(&sym_dev, &nvram);
+-      if (sym_attach(&sym2_template, attach_count, &sym_dev))
++      instance = sym_attach(&sym2_template, attach_count, &sym_dev);
++      if (!instance)
+               goto free;
++      if (scsi_add_host(instance, &pdev->dev))
++              goto detach;
++      scsi_scan_host(instance);
++
+       attach_count++;
++
+       return 0;
++ detach:
++      sym_detach(pci_get_drvdata(pdev));
+  free:
+       pci_release_regions(pdev);
+  disable:
+@@ -2369,7 +2343,13 @@ static int __devinit sym2_probe(struct p
+ static void __devexit sym2_remove(struct pci_dev *pdev)
+ {
+-      sym_detach(pci_get_drvdata(pdev));
++      struct sym_hcb *np = pci_get_drvdata(pdev);
++      struct Scsi_Host *host = np->s.host;
++
++      scsi_remove_host(host);
++      scsi_host_put(host);
++
++      sym_detach(np);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym_glue.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sym53c8xx_2/sym_glue.h     2003-12-28 23:21:49.000000000 -0800
+@@ -74,10 +74,6 @@
+ #define bzero(d, n)   memset((d), 0, (n))
+ #endif
+-#ifndef bcmp
+-#define bcmp(a, b, n) memcmp((a), (b), (n))
+-#endif
+-
+ /*
+  *  General driver includes.
+  */
+@@ -96,7 +92,6 @@
+ #define SYM_OPT_SNIFF_INQUIRY
+ #define SYM_OPT_LIMIT_COMMAND_REORDERING
+ #define       SYM_OPT_ANNOUNCE_TRANSFER_RATE
+-#define       SYM_OPT_BUS_DMA_ABSTRACTION
+ /*
+  *  Print a message with severity.
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym_hipd.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sym53c8xx_2/sym_hipd.c     2003-12-28 23:21:49.000000000 -0800
+@@ -50,7 +50,7 @@
+  * SUCH DAMAGE.
+  */
+-#define SYM_DRIVER_NAME       "sym-2.1.18b"
++#define SYM_DRIVER_NAME       "sym-2.1.18f"
+ #ifdef __FreeBSD__
+ #include <dev/sym/sym_glue.h>
+@@ -751,8 +751,6 @@ static u32 parisc_setup_hcb(hcb_p np, u3
+                               &np->maxwide, &scsi_mode))
+               return period;
+-      printk("scsi_mode = %d, period = %ld\n", scsi_mode, pdc_period);
+-
+       if (scsi_mode >= 0) {
+               /* C3000 PDC reports period/mode */
+               SYM_SETUP_SCSI_DIFF = 0;
+@@ -1060,12 +1058,10 @@ static int sym_prepare_setting(hcb_p np,
+                *  and BUS width.
+                */
+               if (np->features & FE_ULTRA3) {
+-                      if (tp->tinfo.user.period <= 9  &&
+-                          tp->tinfo.user.width == BUS_16_BIT) {
+-                              tp->tinfo.user.options |= PPR_OPT_DT;
+-                              tp->tinfo.user.offset   = np->maxoffs_dt;
+-                              tp->tinfo.user.spi_version = 3;
+-                      }
++                      tp->tinfo.user.options |= PPR_OPT_DT;
++                      tp->tinfo.user.period = np->minsync_dt;
++                      tp->tinfo.user.offset = np->maxoffs_dt;
++                      tp->tinfo.user.spi_version = 3;
+               }
+               if (!tp->usrtags)
+@@ -1962,13 +1958,6 @@ void sym_start_up (hcb_p np, int reason)
+               if (sym_verbose >= 2)
+                       printf ("%s: Downloading SCSI SCRIPTS.\n",
+                               sym_name(np));
+-#ifdef SYM_OPT_NO_BUS_MEMORY_MAPPING
+-              np->fw_patch(np);
+-              if (np->ram_ws == 8192)
+-                      phys = SCRIPTZ_BA (np, start_ram64);
+-              else
+-                      phys = SCRIPTZ_BA (np, start_ram);
+-#else
+               if (np->ram_ws == 8192) {
+                       OUTRAM_OFF(4096, np->scriptb0, np->scriptb_sz);
+                       phys =  scr_to_cpu(np->scr_ram_seg);
+@@ -1980,7 +1969,6 @@ void sym_start_up (hcb_p np, int reason)
+               else
+                       phys = SCRIPTA_BA (np, init);
+               OUTRAM_OFF(0, np->scripta0, np->scripta_sz);
+-#endif
+       }
+       else
+               phys = SCRIPTA_BA (np, init);
+@@ -2136,9 +2124,15 @@ sym_setsync(hcb_p np, int target,
+       sym_settrans(np, target, 0, ofs, per, wide, div, fak);
+-      tp->tinfo.goal.period   = tp->tinfo.curr.period  = per;
+-      tp->tinfo.goal.offset   = tp->tinfo.curr.offset  = ofs;
+-      tp->tinfo.goal.options  = tp->tinfo.curr.options = 0;
++      tp->tinfo.curr.period  = per;
++      tp->tinfo.curr.offset  = ofs;
++      tp->tinfo.curr.options = 0;
++
++      if (!(tp->tinfo.goal.options & PPR_OPT_MASK)) {
++              tp->tinfo.goal.period   = per;
++              tp->tinfo.goal.offset   = ofs;
++              tp->tinfo.goal.options  = 0;
++      }
+       sym_xpt_async_nego_sync(np, target);
+ }
+@@ -4151,8 +4145,10 @@ sym_ppr_nego_check(hcb_p np, int req, in
+       /*
+        *  Check values against our limits.
+        */
+-      if (wide > np->maxwide)
+-              {chg = 1; wide = np->maxwide;}
++      if (wide > np->maxwide) {
++              chg = 1;
++              wide = np->maxwide;
++      }
+       if (!wide || !(np->features & FE_ULTRA3))
+               dt &= ~PPR_OPT_DT;
+       if (req) {
+@@ -4306,8 +4302,10 @@ sym_wide_nego_check(hcb_p np, int req, i
+       /*
+        *  Check values against our limits.
+        */
+-      if (wide > np->maxwide)
+-              {chg = 1; wide = np->maxwide;}
++      if (wide > np->maxwide) {
++              chg = 1;
++              wide = np->maxwide;
++      }
+       if (req) {
+               if (wide > tp->tinfo.user.width)
+                       {chg = 1; wide = tp->tinfo.user.width;}
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym_hipd.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sym53c8xx_2/sym_hipd.h     2003-12-28 23:21:49.000000000 -0800
+@@ -59,12 +59,6 @@
+  *  They may be defined in platform specific headers, if they 
+  *  are useful.
+  *
+- *    SYM_OPT_NO_BUS_MEMORY_MAPPING
+- *        When this option is set, the driver will not load the 
+- *        on-chip RAM using MMIO, but let the SCRIPTS processor 
+- *        do the work using MOVE MEMORY instructions.
+- *        (set for Linux/PPC)
+- *
+  *    SYM_OPT_HANDLE_DIR_UNKNOWN
+  *        When this option is set, the SCRIPTS used by the driver 
+  *        are able to handle SCSI transfers with direction not 
+@@ -75,12 +69,6 @@
+  *        When this option is set, the driver will use a queue per 
+  *        device and handle QUEUE FULL status requeuing internally.
+  *
+- *    SYM_OPT_BUS_DMA_ABSTRACTION
+- *        When this option is set, the driver allocator is responsible 
+- *        of maintaining bus physical addresses and so provides virtual 
+- *        to bus physical address translation of driver data structures.
+- *        (set for FreeBSD-4 and Linux 2.3)
+- *
+  *    SYM_OPT_SNIFF_INQUIRY
+  *        When this option is set, the driver sniff out successful 
+  *        INQUIRY response and performs negotiations accordingly.
+@@ -92,10 +80,8 @@
+  *        (set for Linux)
+  */
+ #if 0
+-#define SYM_OPT_NO_BUS_MEMORY_MAPPING
+ #define SYM_OPT_HANDLE_DIR_UNKNOWN
+ #define SYM_OPT_HANDLE_DEVICE_QUEUEING
+-#define SYM_OPT_BUS_DMA_ABSTRACTION
+ #define SYM_OPT_SNIFF_INQUIRY
+ #define SYM_OPT_LIMIT_COMMAND_REORDERING
+ #endif
+@@ -958,9 +944,7 @@ struct sym_hcb {
+       /*
+        *  DMA pool handle for this HBA.
+        */
+-#ifdef        SYM_OPT_BUS_DMA_ABSTRACTION
+       m_pool_ident_t  bus_dmat;
+-#endif
+       /*
+        *  O/S specific data structure
+@@ -1133,9 +1117,20 @@ struct sym_hcb {
+ /*
+  *  NVRAM reading (sym_nvram.c).
+  */
++#if SYM_CONF_NVRAM_SUPPORT
+ void sym_nvram_setup_host (hcb_p np, struct sym_nvram *nvram);
+ void sym_nvram_setup_target (hcb_p np, int target, struct sym_nvram *nvp);
+ int sym_read_nvram (sdev_p np, struct sym_nvram *nvp);
++#else
++static inline void sym_nvram_setup_host(hcb_p np, struct sym_nvram *nvram) { }
++static inline void sym_nvram_setup_target(hcb_p np, struct sym_nvram *nvram) { }
++static inline int sym_read_nvram(sdev_p np, struct sym_nvram *nvp)
++{
++      nvp->type = 0;
++      return 0;
++}
++#endif
++
+ /*
+  *  FIRMWARES (sym_fw.c)
+@@ -1347,7 +1342,6 @@ typedef struct sym_m_link {
+  *  Virtual to bus physical translation for a given cluster.
+  *  Such a structure is only useful with DMA abstraction.
+  */
+-#ifdef        SYM_OPT_BUS_DMA_ABSTRACTION
+ typedef struct sym_m_vtob {   /* Virtual to Bus address translation */
+       struct sym_m_vtob *next;
+ #ifdef        SYM_HAVE_M_SVTOB
+@@ -1363,7 +1357,6 @@ typedef struct sym_m_vtob {      /* Virtual t
+ #define VTOB_HASH_MASK                (VTOB_HASH_SIZE-1)
+ #define VTOB_HASH_CODE(m)     \
+       ((((m_addr_t) (m)) >> SYM_MEM_CLUSTER_SHIFT) & VTOB_HASH_MASK)
+-#endif        /* SYM_OPT_BUS_DMA_ABSTRACTION */
+ /*
+  *  Memory pool of a given kind.
+@@ -1375,7 +1368,6 @@ typedef struct sym_m_vtob {      /* Virtual t
+  *     method are expected to tell the driver about.
+  */
+ typedef struct sym_m_pool {
+-#ifdef        SYM_OPT_BUS_DMA_ABSTRACTION
+       m_pool_ident_t  dev_dmat;       /* Identifies the pool (see above) */
+       m_addr_t (*get_mem_cluster)(struct sym_m_pool *);
+ #ifdef        SYM_MEM_FREE_UNUSED
+@@ -1389,10 +1381,6 @@ typedef struct sym_m_pool {
+       int nump;
+       m_vtob_p vtob[VTOB_HASH_SIZE];
+       struct sym_m_pool *next;
+-#else
+-#define M_GET_MEM_CLUSTER()           sym_get_mem_cluster()
+-#define M_FREE_MEM_CLUSTER(p)         sym_free_mem_cluster(p)
+-#endif        /* SYM_OPT_BUS_DMA_ABSTRACTION */
+       struct sym_m_link h[SYM_MEM_CLUSTER_SHIFT - SYM_MEM_SHIFT + 1];
+ } *m_pool_p;
+@@ -1406,12 +1394,10 @@ void *sym_calloc_unlocked(int size, char
+  *  Alloc, free and translate addresses to bus physical 
+  *  for DMAable memory.
+  */
+-#ifdef        SYM_OPT_BUS_DMA_ABSTRACTION
+ void *__sym_calloc_dma_unlocked(m_pool_ident_t dev_dmat, int size, char *name);
+ void 
+ __sym_mfree_dma_unlocked(m_pool_ident_t dev_dmat, void *m,int size, char *name);
+ u32 __vtobus_unlocked(m_pool_ident_t dev_dmat, void *m);
+-#endif
+ /*
+  * Verbs used by the driver code for DMAable memory handling.
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym_malloc.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sym53c8xx_2/sym_malloc.c   2003-12-28 23:21:49.000000000 -0800
+@@ -204,18 +204,9 @@ static void __sym_mfree(m_pool_p mp, voi
+ /*
+  *  Default memory pool we donnot need to involve in DMA.
+  *
+- *  If DMA abtraction is not needed, the generic allocator 
+- *  calls directly some kernel allocator.
+- *
+  *  With DMA abstraction, we use functions (methods), to 
+  *  distinguish between non DMAable memory and DMAable memory.
+  */
+-#ifndef       SYM_OPT_BUS_DMA_ABSTRACTION
+-
+-static struct sym_m_pool mp0;
+-
+-#else
+-
+ static m_addr_t ___mp0_get_mem_cluster(m_pool_p mp)
+ {
+       m_addr_t m = (m_addr_t) sym_get_mem_cluster();
+@@ -240,8 +231,6 @@ static struct sym_m_pool mp0 =
+       {0, ___mp0_get_mem_cluster};
+ #endif
+-#endif        /* SYM_OPT_BUS_DMA_ABSTRACTION */
+-
+ /*
+  * Actual memory allocation routine for non-DMAed memory.
+  */
+@@ -260,7 +249,6 @@ void sym_mfree_unlocked(void *ptr, int s
+       __sym_mfree(&mp0, ptr, size, name);
+ }
+-#ifdef        SYM_OPT_BUS_DMA_ABSTRACTION
+ /*
+  *  Methods that maintains DMAable pools according to user allocations.
+  *  New pools are created on the fly when a new pool id is provided.
+@@ -417,5 +405,3 @@ u32 __vtobus_unlocked(m_pool_ident_t dev
+               panic("sym: VTOBUS FAILED!\n");
+       return (u32)(vp ? vp->baddr + (((m_addr_t) m) - a) : 0);
+ }
+-
+-#endif        /* SYM_OPT_BUS_DMA_ABSTRACTION */
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym_misc.c    2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/scsi/sym53c8xx_2/sym_misc.c     2003-12-28 23:22:24.000000000 -0800
+@@ -328,7 +328,6 @@ printf("XXXXXX [%d] inq_version=%x inq_b
+           tp->inq_byte56  != inq_byte56) {
+               tp->inq_version = inq_version;
+               tp->inq_byte7   = inq_byte7;
+-              tp->inq_byte56  = inq_byte56;
+               return 1;
+       }
+       return 0;
+--- linux-2.6.0/drivers/scsi/sym53c8xx_2/sym_nvram.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/scsi/sym53c8xx_2/sym_nvram.c    2003-12-28 23:21:49.000000000 -0800
+@@ -59,25 +59,22 @@
+ /*
+  *  Some poor and bogus sync table that refers to Tekram NVRAM layout.
+  */
+-#if SYM_CONF_NVRAM_SUPPORT
+ static u_char Tekram_sync[16] =
+       {25,31,37,43, 50,62,75,125, 12,15,18,21, 6,7,9,10};
+ #ifdef        SYM_CONF_DEBUG_NVRAM
+ static u_char Tekram_boot_delay[7] = {3, 5, 10, 20, 30, 60, 120};
+ #endif
+-#endif
+ /*
+  *  Get host setup from NVRAM.
+  */
+-void sym_nvram_setup_host (hcb_p np, struct sym_nvram *nvram)
++void sym_nvram_setup_host(struct sym_hcb *np, struct sym_nvram *nvram)
+ {
+-#if SYM_CONF_NVRAM_SUPPORT
+       /*
+        *  Get parity checking, host ID, verbose mode 
+        *  and miscellaneous host flags from NVRAM.
+        */
+-      switch(nvram->type) {
++      switch (nvram->type) {
+       case SYM_SYMBIOS_NVRAM:
+               if (!(nvram->data.Symbios.flags & SYMBIOS_PARITY_ENABLE))
+                       np->rv_scntl0  &= ~0x0a;
+@@ -95,41 +92,15 @@ void sym_nvram_setup_host (hcb_p np, str
+       default:
+               break;
+       }
+-#endif
+-}
+-
+-/*
+- *  Get target setup from NVRAM.
+- */
+-#if SYM_CONF_NVRAM_SUPPORT
+-static void sym_Symbios_setup_target(hcb_p np,int target, Symbios_nvram *nvram);
+-static void sym_Tekram_setup_target(hcb_p np,int target, Tekram_nvram *nvram);
+-#endif
+-
+-void sym_nvram_setup_target (hcb_p np, int target, struct sym_nvram *nvp)
+-{
+-#if SYM_CONF_NVRAM_SUPPORT
+-      switch(nvp->type) {
+-      case SYM_SYMBIOS_NVRAM:
+-              sym_Symbios_setup_target (np, target, &nvp->data.Symbios);
+-              break;
+-      case SYM_TEKRAM_NVRAM:
+-              sym_Tekram_setup_target (np, target, &nvp->data.Tekram);
+-              break;
+-      default:
+-              break;
+-      }
+-#endif
+ }
+-#if SYM_CONF_NVRAM_SUPPORT
+ /*
+  *  Get target set-up from Symbios format NVRAM.
+  */
+ static void
+-sym_Symbios_setup_target(hcb_p np, int target, Symbios_nvram *nvram)
++sym_Symbios_setup_target(struct sym_hcb *np, int target, Symbios_nvram *nvram)
+ {
+-      tcb_p tp = &np->target[target];
++      struct sym_tcb *tp = &np->target[target];
+       Symbios_target *tn = &nvram->target[target];
+       tp->tinfo.user.period = tn->sync_period ? (tn->sync_period + 3) / 4 : 0;
+@@ -149,9 +120,9 @@ sym_Symbios_setup_target(hcb_p np, int t
+  *  Get target set-up from Tekram format NVRAM.
+  */
+ static void
+-sym_Tekram_setup_target(hcb_p np, int target, Tekram_nvram *nvram)
++sym_Tekram_setup_target(struct sym_hcb *np, int target, Tekram_nvram *nvram)
+ {
+-      tcb_p tp = &np->target[target];
++      struct sym_tcb *tp = &np->target[target];
+       struct Tekram_target *tn = &nvram->target[target];
+       int i;
+@@ -160,8 +131,8 @@ sym_Tekram_setup_target(hcb_p np, int ta
+               tp->tinfo.user.period = Tekram_sync[i];
+       }
+-      tp->tinfo.user.width =
+-              (tn->flags & TEKRAM_WIDE_NEGO) ? BUS_16_BIT : BUS_8_BIT;
++      tp->tinfo.user.width = (tn->flags & TEKRAM_WIDE_NEGO) ?
++              BUS_16_BIT : BUS_8_BIT;
+       if (tn->flags & TEKRAM_TAGGED_COMMANDS) {
+               tp->usrtags = 2 << nvram->max_tags_index;
+@@ -175,11 +146,28 @@ sym_Tekram_setup_target(hcb_p np, int ta
+               np->rv_scntl0  &= ~0x0a; /* SCSI parity checking disabled */
+ }
++/*
++ *  Get target setup from NVRAM.
++ */
++void sym_nvram_setup_target(struct sym_hcb *np, int target, struct sym_nvram *nvp)
++{
++      switch (nvp->type) {
++      case SYM_SYMBIOS_NVRAM:
++              sym_Symbios_setup_target(np, target, &nvp->data.Symbios);
++              break;
++      case SYM_TEKRAM_NVRAM:
++              sym_Tekram_setup_target(np, target, &nvp->data.Tekram);
++              break;
++      default:
++              break;
++      }
++}
++
+ #ifdef        SYM_CONF_DEBUG_NVRAM
+ /*
+  *  Dump Symbios format NVRAM for debugging purpose.
+  */
+-static void sym_display_Symbios_nvram(sdev_p np, Symbios_nvram *nvram)
++static void sym_display_Symbios_nvram(struct sym_device *np, Symbios_nvram *nvram)
+ {
+       int i;
+@@ -211,7 +199,7 @@ static void sym_display_Symbios_nvram(sd
+ /*
+  *  Dump TEKRAM format NVRAM for debugging purpose.
+  */
+-static void sym_display_Tekram_nvram(sdev_p np, Tekram_nvram *nvram)
++static void sym_display_Tekram_nvram(struct sym_device *np, Tekram_nvram *nvram)
+ {
+       int i, tags, boot_delay;
+       char *rem;
+@@ -221,7 +209,7 @@ static void sym_display_Tekram_nvram(sde
+       boot_delay = 0;
+       if (nvram->boot_delay_index < 6)
+               boot_delay = Tekram_boot_delay[nvram->boot_delay_index];
+-      switch((nvram->flags & TEKRAM_REMOVABLE_FLAGS) >> 6) {
++      switch ((nvram->flags & TEKRAM_REMOVABLE_FLAGS) >> 6) {
+       default:
+       case 0: rem = "";                       break;
+       case 1: rem = " REMOVABLE=boot device"; break;
+@@ -257,49 +245,12 @@ static void sym_display_Tekram_nvram(sde
+               sync);
+       }
+ }
+-#endif        /* SYM_CONF_DEBUG_NVRAM */
+-#endif        /* SYM_CONF_NVRAM_SUPPORT */
+-
+-
+-/*
+- *  Try reading Symbios or Tekram NVRAM
+- */
+-#if SYM_CONF_NVRAM_SUPPORT
+-static int sym_read_Symbios_nvram (sdev_p np, Symbios_nvram *nvram);
+-static int sym_read_Tekram_nvram  (sdev_p np, Tekram_nvram *nvram);
+-#endif
+-
+-int sym_read_nvram (sdev_p np, struct sym_nvram *nvp)
+-{
+-#if SYM_CONF_NVRAM_SUPPORT
+-      /*
+-       *  Try to read SYMBIOS nvram.
+-       *  Try to read TEKRAM nvram if Symbios nvram not found.
+-       */
+-      if      (SYM_SETUP_SYMBIOS_NVRAM &&
+-               !sym_read_Symbios_nvram (np, &nvp->data.Symbios)) {
+-              nvp->type = SYM_SYMBIOS_NVRAM;
+-#ifdef SYM_CONF_DEBUG_NVRAM
+-              sym_display_Symbios_nvram(np, &nvp->data.Symbios);
+-#endif
+-      }
+-      else if (SYM_SETUP_TEKRAM_NVRAM &&
+-               !sym_read_Tekram_nvram (np, &nvp->data.Tekram)) {
+-              nvp->type = SYM_TEKRAM_NVRAM;
+-#ifdef SYM_CONF_DEBUG_NVRAM
+-              sym_display_Tekram_nvram(np, &nvp->data.Tekram);
+-#endif
+-      }
+-      else
+-              nvp->type = 0;
+ #else
+-      nvp->type = 0;
+-#endif
+-      return nvp->type;
+-}
++static void sym_display_Symbios_nvram(struct sym_device *np, Symbios_nvram *nvram) { }
++static void sym_display_Tekram_nvram(struct sym_device *np, Tekram_nvram *nvram) { }
++#endif        /* SYM_CONF_DEBUG_NVRAM */
+-#if SYM_CONF_NVRAM_SUPPORT
+ /*
+  *  24C16 EEPROM reading.
+  *
+@@ -316,11 +267,11 @@ int sym_read_nvram (sdev_p np, struct sy
+ /*
+  *  Set/clear data/clock bit in GPIO0
+  */
+-static void S24C16_set_bit(sdev_p np, u_char write_bit, u_char *gpreg, 
++static void S24C16_set_bit(struct sym_device *np, u_char write_bit, u_char *gpreg,
+                         int bit_mode)
+ {
+       UDELAY (5);
+-      switch (bit_mode){
++      switch (bit_mode) {
+       case SET_BIT:
+               *gpreg |= write_bit;
+               break;
+@@ -342,7 +293,7 @@ static void S24C16_set_bit(sdev_p np, u_
+ /*
+  *  Send START condition to NVRAM to wake it up.
+  */
+-static void S24C16_start(sdev_p np, u_char *gpreg)
++static void S24C16_start(struct sym_device *np, u_char *gpreg)
+ {
+       S24C16_set_bit(np, 1, gpreg, SET_BIT);
+       S24C16_set_bit(np, 0, gpreg, SET_CLK);
+@@ -353,7 +304,7 @@ static void S24C16_start(sdev_p np, u_ch
+ /*
+  *  Send STOP condition to NVRAM - puts NVRAM to sleep... ZZzzzz!!
+  */
+-static void S24C16_stop(sdev_p np, u_char *gpreg)
++static void S24C16_stop(struct sym_device *np, u_char *gpreg)
+ {
+       S24C16_set_bit(np, 0, gpreg, SET_CLK);
+       S24C16_set_bit(np, 1, gpreg, SET_BIT);
+@@ -363,7 +314,7 @@ static void S24C16_stop(sdev_p np, u_cha
+  *  Read or write a bit to the NVRAM,
+  *  read if GPIO0 input else write if GPIO0 output
+  */
+-static void S24C16_do_bit(sdev_p np, u_char *read_bit, u_char write_bit, 
++static void S24C16_do_bit(struct sym_device *np, u_char *read_bit, u_char write_bit,
+                        u_char *gpreg)
+ {
+       S24C16_set_bit(np, write_bit, gpreg, SET_BIT);
+@@ -378,7 +329,7 @@ static void S24C16_do_bit(sdev_p np, u_c
+  *  Output an ACK to the NVRAM after reading,
+  *  change GPIO0 to output and when done back to an input
+  */
+-static void S24C16_write_ack(sdev_p np, u_char write_bit, u_char *gpreg, 
++static void S24C16_write_ack(struct sym_device *np, u_char write_bit, u_char *gpreg,
+                           u_char *gpcntl)
+ {
+       OUTB (nc_gpcntl, *gpcntl & 0xfe);
+@@ -390,7 +341,7 @@ static void S24C16_write_ack(sdev_p np, 
+  *  Input an ACK from NVRAM after writing,
+  *  change GPIO0 to input and when done back to an output
+  */
+-static void S24C16_read_ack(sdev_p np, u_char *read_bit, u_char *gpreg, 
++static void S24C16_read_ack(struct sym_device *np, u_char *read_bit, u_char *gpreg,
+                          u_char *gpcntl)
+ {
+       OUTB (nc_gpcntl, *gpcntl | 0x01);
+@@ -402,7 +353,7 @@ static void S24C16_read_ack(sdev_p np, u
+  *  WRITE a byte to the NVRAM and then get an ACK to see it was accepted OK,
+  *  GPIO0 must already be set as an output
+  */
+-static void S24C16_write_byte(sdev_p np, u_char *ack_data, u_char write_data, 
++static void S24C16_write_byte(struct sym_device *np, u_char *ack_data, u_char write_data,
+                            u_char *gpreg, u_char *gpcntl)
+ {
+       int x;
+@@ -417,7 +368,7 @@ static void S24C16_write_byte(sdev_p np,
+  *  READ a byte from the NVRAM and then send an ACK to say we have got it,
+  *  GPIO0 must already be set as an input
+  */
+-static void S24C16_read_byte(sdev_p np, u_char *read_data, u_char ack_data, 
++static void S24C16_read_byte(struct sym_device *np, u_char *read_data, u_char ack_data,
+                           u_char *gpreg, u_char *gpcntl)
+ {
+       int x;
+@@ -435,7 +386,7 @@ static void S24C16_read_byte(sdev_p np, 
+ /*
+  *  Read 'len' bytes starting at 'offset'.
+  */
+-static int sym_read_S24C16_nvram (sdev_p np, int offset, u_char *data, int len)
++static int sym_read_S24C16_nvram(struct sym_device *np, int offset, u_char *data, int len)
+ {
+       u_char  gpcntl, gpreg;
+       u_char  old_gpcntl, old_gpreg;
+@@ -514,7 +465,7 @@ out:
+  *  Try reading Symbios NVRAM.
+  *  Return 0 if OK.
+  */
+-static int sym_read_Symbios_nvram (sdev_p np, Symbios_nvram *nvram)
++static int sym_read_Symbios_nvram(struct sym_device *np, Symbios_nvram *nvram)
+ {
+       static u_char Symbios_trailer[6] = {0xfe, 0xfe, 0, 0, 0, 0};
+       u_char *data = (u_char *) nvram;
+@@ -528,7 +479,7 @@ static int sym_read_Symbios_nvram (sdev_
+       /* check valid NVRAM signature, verify byte count and checksum */
+       if (nvram->type != 0 ||
+-          bcmp(nvram->trailer, Symbios_trailer, 6) ||
++          memcmp(nvram->trailer, Symbios_trailer, 6) ||
+           nvram->byte_count != len - 12)
+               return 1;
+@@ -555,7 +506,7 @@ static int sym_read_Symbios_nvram (sdev_
+ /*
+  *  Pulse clock bit in GPIO0
+  */
+-static void T93C46_Clk(sdev_p np, u_char *gpreg)
++static void T93C46_Clk(struct sym_device *np, u_char *gpreg)
+ {
+       OUTB (nc_gpreg, *gpreg | 0x04);
+       UDELAY (2);
+@@ -565,7 +516,7 @@ static void T93C46_Clk(sdev_p np, u_char
+ /* 
+  *  Read bit from NVRAM
+  */
+-static void T93C46_Read_Bit(sdev_p np, u_char *read_bit, u_char *gpreg)
++static void T93C46_Read_Bit(struct sym_device *np, u_char *read_bit, u_char *gpreg)
+ {
+       UDELAY (2);
+       T93C46_Clk(np, gpreg);
+@@ -575,7 +526,7 @@ static void T93C46_Read_Bit(sdev_p np, u
+ /*
+  *  Write bit to GPIO0
+  */
+-static void T93C46_Write_Bit(sdev_p np, u_char write_bit, u_char *gpreg)
++static void T93C46_Write_Bit(struct sym_device *np, u_char write_bit, u_char *gpreg)
+ {
+       if (write_bit & 0x01)
+               *gpreg |= 0x02;
+@@ -593,7 +544,7 @@ static void T93C46_Write_Bit(sdev_p np, 
+ /*
+  *  Send STOP condition to NVRAM - puts NVRAM to sleep... ZZZzzz!!
+  */
+-static void T93C46_Stop(sdev_p np, u_char *gpreg)
++static void T93C46_Stop(struct sym_device *np, u_char *gpreg)
+ {
+       *gpreg &= 0xef;
+       OUTB (nc_gpreg, *gpreg);
+@@ -605,7 +556,7 @@ static void T93C46_Stop(sdev_p np, u_cha
+ /*
+  *  Send read command and address to NVRAM
+  */
+-static void T93C46_Send_Command(sdev_p np, u_short write_data, 
++static void T93C46_Send_Command(struct sym_device *np, u_short write_data,
+                               u_char *read_bit, u_char *gpreg)
+ {
+       int x;
+@@ -620,7 +571,8 @@ static void T93C46_Send_Command(sdev_p n
+ /*
+  *  READ 2 bytes from the NVRAM
+  */
+-static void T93C46_Read_Word(sdev_p np, u_short *nvram_data, u_char *gpreg)
++static void T93C46_Read_Word(struct sym_device *np,
++              unsigned short *nvram_data, unsigned char *gpreg)
+ {
+       int x;
+       u_char read_bit;
+@@ -639,13 +591,13 @@ static void T93C46_Read_Word(sdev_p np, 
+ /*
+  *  Read Tekram NvRAM data.
+  */
+-static int T93C46_Read_Data(sdev_p np, u_short *data,int len,u_char *gpreg)
++static int T93C46_Read_Data(struct sym_device *np, unsigned short *data,
++              int len, unsigned char *gpreg)
+ {
+-      u_char  read_bit;
+-      int     x;
++      int x;
+       for (x = 0; x < len; x++)  {
+-
++              unsigned char read_bit;
+               /* output read command and address */
+               T93C46_Send_Command(np, 0x180 | x, &read_bit, gpreg);
+               if (read_bit & 0x01)
+@@ -660,7 +612,7 @@ static int T93C46_Read_Data(sdev_p np, u
+ /*
+  *  Try reading 93C46 Tekram NVRAM.
+  */
+-static int sym_read_T93C46_nvram (sdev_p np, Tekram_nvram *nvram)
++static int sym_read_T93C46_nvram(struct sym_device *np, Tekram_nvram *nvram)
+ {
+       u_char gpcntl, gpreg;
+       u_char old_gpcntl, old_gpreg;
+@@ -692,7 +644,7 @@ static int sym_read_T93C46_nvram (sdev_p
+  *  Try reading Tekram NVRAM.
+  *  Return 0 if OK.
+  */
+-static int sym_read_Tekram_nvram (sdev_p np, Tekram_nvram *nvram)
++static int sym_read_Tekram_nvram (struct sym_device *np, Tekram_nvram *nvram)
+ {
+       u_char *data = (u_char *) nvram;
+       int len = sizeof(*nvram);
+@@ -700,13 +652,13 @@ static int sym_read_Tekram_nvram (sdev_p
+       int x;
+       switch (np->device_id) {
+-      case PCI_ID_SYM53C885:
+-      case PCI_ID_SYM53C895:
+-      case PCI_ID_SYM53C896:
++      case PCI_DEVICE_ID_NCR_53C885:
++      case PCI_DEVICE_ID_NCR_53C895:
++      case PCI_DEVICE_ID_NCR_53C896:
+               x = sym_read_S24C16_nvram(np, TEKRAM_24C16_NVRAM_ADDRESS,
+                                         data, len);
+               break;
+-      case PCI_ID_SYM53C875:
++      case PCI_DEVICE_ID_NCR_53C875:
+               x = sym_read_S24C16_nvram(np, TEKRAM_24C16_NVRAM_ADDRESS,
+                                         data, len);
+               if (!x)
+@@ -727,4 +679,19 @@ static int sym_read_Tekram_nvram (sdev_p
+       return 0;
+ }
+-#endif        /* SYM_CONF_NVRAM_SUPPORT */
++/*
++ *  Try reading Symbios or Tekram NVRAM
++ */
++int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp)
++{
++      if (!sym_read_Symbios_nvram(np, &nvp->data.Symbios)) {
++              nvp->type = SYM_SYMBIOS_NVRAM;
++              sym_display_Symbios_nvram(np, &nvp->data.Symbios);
++      } else if (!sym_read_Tekram_nvram(np, &nvp->data.Tekram)) {
++              nvp->type = SYM_TEKRAM_NVRAM;
++              sym_display_Tekram_nvram(np, &nvp->data.Tekram);
++      } else {
++              nvp->type = 0;
++      }
++      return nvp->type;
++}
+--- linux-2.6.0/drivers/serial/8250.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/serial/8250.c   2003-12-28 23:21:07.000000000 -0800
+@@ -844,7 +844,7 @@ receive_chars(struct uart_8250_port *up,
+               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
+                       tty->flip.work.func((void *)tty);
+                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+-                              return; // if TTY_DONT_FLIP is set
++                              return; /* if TTY_DONT_FLIP is set */
+               }
+               ch = serial_inp(up, UART_RX);
+               *tty->flip.char_buf_ptr = ch;
+@@ -1205,12 +1205,21 @@ static void serial8250_break_ctl(struct 
+       spin_unlock_irqrestore(&up->port.lock, flags);
+ }
++#ifdef CONFIG_KGDB
++static int kgdb_irq = -1;
++#endif
++
+ static int serial8250_startup(struct uart_port *port)
+ {
+       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       unsigned long flags;
+       int retval;
++#ifdef CONFIG_KGDB
++      if (up->port.irq == kgdb_irq)
++              return -EBUSY;
++#endif
++
+       up->capabilities = uart_config[up->port.type].flags;
+       if (up->port.type == PORT_16C950) {
+@@ -1876,6 +1885,10 @@ static void __init serial8250_register_p
+       for (i = 0; i < UART_NR; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
++#ifdef CONFIG_KGDB
++              if (up->port.irq == kgdb_irq)
++                      up->port.kgdb = 1;
++#endif
+               up->port.line = i;
+               up->port.ops = &serial8250_pops;
+               init_timer(&up->timer);
+@@ -2145,6 +2158,31 @@ void serial8250_resume_port(int line)
+       uart_resume_port(&serial8250_reg, &serial8250_ports[line].port);
+ }
++#ifdef CONFIG_KGDB
++/*
++ * Find all the ports using the given irq and shut them down.
++ * Result should be that the irq will be released.
++ */
++void shutdown_for_kgdb(struct async_struct * info)
++{
++        int irq = info->state->irq;
++        struct uart_8250_port *up;
++      int ttyS;
++
++      kgdb_irq = irq;                 /* save for later init */
++      for (ttyS = 0; ttyS < UART_NR; ttyS++){
++              up =  &serial8250_ports[ttyS];
++              if (up->port.irq == irq && (irq_lists + irq)->head) {
++#ifdef CONFIG_DEBUG_SPINLOCK   /* ugly business... */
++                      if(up->port.lock.magic != SPINLOCK_MAGIC)
++                              spin_lock_init(&up->port.lock);
++#endif
++                      serial8250_shutdown(&up->port);
++              }
++        }
++}
++#endif        /* CONFIG_KGDB */
++
+ static int __init serial8250_init(void)
+ {
+       int ret, i;
+--- linux-2.6.0/drivers/serial/serial_core.c   2003-11-23 19:03:01.000000000 -0800
++++ 25/drivers/serial/serial_core.c    2003-12-28 23:21:51.000000000 -0800
+@@ -1862,6 +1862,9 @@ uart_set_options(struct uart_port *port,
+       if (flow == 'r')
+               termios.c_cflag |= CRTSCTS;
++      if (!port->ops)
++              return 0;       /* "console=" on ia64 */
++
+       port->ops->set_termios(port, &termios, NULL);
+       co->cflag = termios.c_cflag;
+@@ -1975,6 +1978,11 @@ uart_configure_port(struct uart_driver *
+ {
+       unsigned int flags;
++#ifdef CONFIG_KGDB
++      if (port->kgdb)
++              return;
++#endif
++
+       /*
+        * If there isn't a port here, don't do anything further.
+        */
+--- linux-2.6.0/drivers/serial/serial_cs.c     2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/serial/serial_cs.c      2003-12-28 23:22:54.000000000 -0800
+@@ -149,9 +149,9 @@ static void serial_remove(dev_link_t *li
+               info->link.dev = NULL;
+               if (!info->slave) {
+-                      CardServices(ReleaseConfiguration, info->link.handle);
+-                      CardServices(ReleaseIO, info->link.handle, &info->link.io);
+-                      CardServices(ReleaseIRQ, info->link.handle, &info->link.irq);
++                      pcmcia_release_configuration(info->link.handle);
++                      pcmcia_release_io(info->link.handle, &info->link.io);
++                      pcmcia_release_irq(info->link.handle, &info->link.irq);
+               }
+               info->link.state &= ~DEV_CONFIG;
+@@ -211,7 +211,7 @@ static dev_link_t *serial_attach(void)
+       client_reg.event_handler = &serial_event;
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != CS_SUCCESS) {
+               cs_error(link->handle, RegisterClient, ret);
+               serial_detach(link);
+@@ -256,7 +256,7 @@ static void serial_detach(dev_link_t * l
+       serial_remove(link);
+       if (link->handle) {
+-              ret = CardServices(DeregisterClient, link->handle);
++              ret = pcmcia_deregister_client(link->handle);
+               if (ret != CS_SUCCESS)
+                       cs_error(link->handle, DeregisterClient, ret);
+       }
+@@ -300,20 +300,30 @@ static int setup_serial(struct serial_in
+ /*====================================================================*/
+ static int
+-get_tuple(int fn, client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
++first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
+ {
+       int i;
+-      i = CardServices(fn, handle, tuple);
++      i = pcmcia_get_first_tuple(handle, tuple);
+       if (i != CS_SUCCESS)
+               return CS_NO_MORE_ITEMS;
+-      i = CardServices(GetTupleData, handle, tuple);
++      i = pcmcia_get_tuple_data(handle, tuple);
+       if (i != CS_SUCCESS)
+               return i;
+-      return CardServices(ParseTuple, handle, tuple, parse);
++      return pcmcia_parse_tuple(handle, tuple, parse);
+ }
+-#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
+-#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
++static int
++next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
++{
++      int i;
++      i = pcmcia_get_next_tuple(handle, tuple);
++      if (i != CS_SUCCESS)
++              return CS_NO_MORE_ITEMS;
++      i = pcmcia_get_tuple_data(handle, tuple);
++      if (i != CS_SUCCESS)
++              return i;
++      return pcmcia_parse_tuple(handle, tuple, parse);
++}
+ /*====================================================================*/
+@@ -330,7 +340,7 @@ static int simple_config(dev_link_t * li
+       int i, j, try;
+       /* If the card is already configured, look up the port and irq */
+-      i = CardServices(GetConfigurationInfo, handle, &config);
++      i = pcmcia_get_configuration_info(handle, &config);
+       if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
+               ioaddr_t port = 0;
+               if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
+@@ -367,9 +377,7 @@ static int simple_config(dev_link_t * li
+                               link->io.BasePort1 = cf->io.win[0].base;
+                               link->io.IOAddrLines = (try == 0) ?
+                                   16 : cf->io.flags & CISTPL_IO_LINES_MASK;
+-                              i =
+-                                  CardServices(RequestIO, link->handle,
+-                                               &link->io);
++                              i = pcmcia_request_io(link->handle, &link->io);
+                               if (i == CS_SUCCESS)
+                                       goto found_port;
+                       }
+@@ -389,8 +397,7 @@ static int simple_config(dev_link_t * li
+                       for (j = 0; j < 5; j++) {
+                               link->io.BasePort1 = base[j];
+                               link->io.IOAddrLines = base[j] ? 16 : 3;
+-                              i = CardServices(RequestIO, link->handle,
+-                                               &link->io);
++                              i = pcmcia_request_io(link->handle, &link->io);
+                               if (i == CS_SUCCESS)
+                                       goto found_port;
+                       }
+@@ -406,14 +413,14 @@ static int simple_config(dev_link_t * li
+               return -1;
+       }
+-      i = CardServices(RequestIRQ, link->handle, &link->irq);
++      i = pcmcia_request_irq(link->handle, &link->irq);
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestIRQ, i);
+               link->irq.AssignedIRQ = 0;
+       }
+       if (info->multi && (info->manfid == MANFID_3COM))
+               link->conf.ConfigIndex &= ~(0x08);
+-      i = CardServices(RequestConfiguration, link->handle, &link->conf);
++      i = pcmcia_request_configuration(link->handle, &link->conf);
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestConfiguration, i);
+               return -1;
+@@ -433,7 +440,7 @@ static int multi_config(dev_link_t * lin
+       config_info_t config;
+       int i, base2 = 0;
+-      i = CardServices(GetConfigurationInfo, handle, &config);
++      i = pcmcia_get_configuration_info(handle, &config);
+       if (i != CS_SUCCESS) {
+               cs_error(handle, GetConfigurationInfo, i);
+               return -1;
+@@ -458,7 +465,7 @@ static int multi_config(dev_link_t * lin
+                       link->io.BasePort1 = cf->io.win[0].base;
+                       link->io.IOAddrLines =
+                           cf->io.flags & CISTPL_IO_LINES_MASK;
+-                      i = CardServices(RequestIO, link->handle, &link->io);
++                      i = pcmcia_request_io(link->handle, &link->io);
+                       base2 = link->io.BasePort1 + 8;
+                       if (i == CS_SUCCESS)
+                               break;
+@@ -478,9 +485,7 @@ static int multi_config(dev_link_t * lin
+                               link->io.BasePort2 = cf->io.win[1].base;
+                               link->io.IOAddrLines =
+                                   cf->io.flags & CISTPL_IO_LINES_MASK;
+-                              i =
+-                                  CardServices(RequestIO, link->handle,
+-                                               &link->io);
++                              i = pcmcia_request_io(link->handle, &link->io);
+                               base2 = link->io.BasePort2;
+                               if (i == CS_SUCCESS)
+                                       break;
+@@ -494,7 +499,7 @@ static int multi_config(dev_link_t * lin
+               return -1;
+       }
+-      i = CardServices(RequestIRQ, link->handle, &link->irq);
++      i = pcmcia_request_irq(link->handle, &link->irq);
+       if (i != CS_SUCCESS) {
+               printk(KERN_NOTICE
+                      "serial_cs: no usable port range found, giving up\n");
+@@ -506,7 +511,7 @@ static int multi_config(dev_link_t * lin
+               link->conf.Present |= PRESENT_EXT_STATUS;
+               link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
+       }
+-      i = CardServices(RequestConfiguration, link->handle, &link->conf);
++      i = pcmcia_request_configuration(link->handle, &link->conf);
+       if (i != CS_SUCCESS) {
+               cs_error(link->handle, RequestConfiguration, i);
+               return -1;
+@@ -543,9 +548,6 @@ static int multi_config(dev_link_t * lin
+ ======================================================================*/
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+-
+ void serial_config(dev_link_t * link)
+ {
+       client_handle_t handle = link->handle;
+@@ -619,10 +621,18 @@ void serial_config(dev_link_t * link)
+       if (info->manfid == MANFID_IBM) {
+               conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
+-              CS_CHECK(AccessConfigurationRegister, link->handle, &reg);
++              last_ret = pcmcia_access_configuration_register(link->handle, &reg);
++              if (last_ret) {
++                      last_fn = AccessConfigurationRegister;
++                      goto cs_failed;
++              }
+               reg.Action = CS_WRITE;
+               reg.Value = reg.Value | 1;
+-              CS_CHECK(AccessConfigurationRegister, link->handle, &reg);
++              last_ret = pcmcia_access_configuration_register(link->handle, &reg);
++              if (last_ret) {
++                      last_fn = AccessConfigurationRegister;
++                      goto cs_failed;
++              }
+       }
+       link->dev = &info->node[0];
+@@ -668,7 +678,7 @@ serial_event(event_t event, int priority
+               /* Fall through... */
+       case CS_EVENT_RESET_PHYSICAL:
+               if ((link->state & DEV_CONFIG) && !info->slave)
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               break;
+       case CS_EVENT_PM_RESUME:
+@@ -676,8 +686,7 @@ serial_event(event_t event, int priority
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (DEV_OK(link) && !info->slave)
+-                      CardServices(RequestConfiguration, link->handle,
+-                                   &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+               break;
+       }
+       return 0;
+--- linux-2.6.0/drivers/telephony/ixj_pcmcia.c 2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/telephony/ixj_pcmcia.c  2003-12-28 23:22:54.000000000 -0800
+@@ -77,7 +77,7 @@ static dev_link_t *ixj_attach(void)
+       client_reg.event_handler = &ixj_event;
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != CS_SUCCESS) {
+               cs_error(link->handle, RegisterClient, ret);
+               ixj_detach(link);
+@@ -100,7 +100,7 @@ static void ixj_detach(dev_link_t * link
+       if (link->state & DEV_CONFIG)
+               ixj_cs_release(link);
+       if (link->handle) {
+-              ret = CardServices(DeregisterClient, link->handle);
++              ret = pcmcia_deregister_client(link->handle);
+               if (ret != CS_SUCCESS)
+                       cs_error(link->handle, DeregisterClient, ret);
+       }
+@@ -110,11 +110,8 @@ static void ixj_detach(dev_link_t * link
+         kfree(link);
+ }
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+-
+-#define CFG_CHECK(fn, args...) \
+-if (CardServices(fn, args) != 0) goto next_entry
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void ixj_get_serial(dev_link_t * link, IXJ * j)
+ {
+@@ -130,8 +127,8 @@ static void ixj_get_serial(dev_link_t * 
+       tuple.TupleDataMax = 80;
+       tuple.Attributes = 0;
+       tuple.DesiredTuple = CISTPL_VERS_1;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
+-      CS_CHECK(GetTupleData, handle, &tuple);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+       str = (char *) buf;
+       printk("PCMCIA Version %d.%d\n", str[0], str[1]);
+       str += 2;
+@@ -202,19 +199,20 @@ static void ixj_config(dev_link_t * link
+       tuple.TupleDataMax = 255;
+       tuple.Attributes = 0;
+       tuple.DesiredTuple = CISTPL_CONFIG;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
+-      CS_CHECK(GetTupleData, handle, &tuple);
+-      CS_CHECK(ParseTuple, handle, &tuple, &parse);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++      CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+       link->conf.ConfigBase = parse.config.base;
+       link->conf.Present = parse.config.rmask[0];
+       link->state |= DEV_CONFIG;
+-      CS_CHECK(GetConfigurationInfo, handle, &conf);
++      CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
+       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+       tuple.Attributes = 0;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       while (1) {
+-              CFG_CHECK(GetTupleData, handle, &tuple);
+-              CFG_CHECK(ParseTuple, handle, &tuple, &parse);
++              if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
++                              pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
++                      goto next_entry;
+               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+                       link->conf.ConfigIndex = cfg->index;
+@@ -224,17 +222,18 @@ static void ixj_config(dev_link_t * link
+                               link->io.BasePort2 = io->win[1].base;
+                               link->io.NumPorts2 = io->win[1].len;
+                       }
+-                      CFG_CHECK(RequestIO, link->handle, &link->io);
++                      if (pcmcia_request_io(link->handle, &link->io) != 0)
++                              goto next_entry;
+                       /* If we've got this far, we're done */
+                       break;
+               }
+             next_entry:
+               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+                       dflt = *cfg;
+-              CS_CHECK(GetNextTuple, handle, &tuple);
++              CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
+       }
+-      CS_CHECK(RequestConfiguration, handle, &link->conf);
++      CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
+       /*
+        *      Register the card with the core.
+@@ -258,8 +257,8 @@ static void ixj_cs_release(dev_link_t *l
+       DEBUG(0, "ixj_cs_release(0x%p)\n", link);
+       info->ndev = 0;
+       link->dev = NULL;
+-      CardServices(ReleaseConfiguration, link->handle);
+-      CardServices(ReleaseIO, link->handle, &link->io);
++      pcmcia_release_configuration(link->handle);
++      pcmcia_release_io(link->handle, &link->io);
+       link->state &= ~DEV_CONFIG;
+ }
+@@ -284,14 +283,14 @@ static int ixj_event(event_t event, int 
+               /* Fall through... */
+       case CS_EVENT_RESET_PHYSICAL:
+               if (link->state & DEV_CONFIG)
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               break;
+       case CS_EVENT_PM_RESUME:
+               link->state &= ~DEV_SUSPEND;
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (DEV_OK(link))
+-                      CardServices(RequestConfiguration, link->handle, &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+               break;
+       }
+       return 0;
+--- linux-2.6.0/drivers/usb/class/cdc-acm.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/usb/class/cdc-acm.c     2003-12-28 23:22:00.000000000 -0800
+@@ -1,5 +1,5 @@
+ /*
+- * acm.c  Version 0.22
++ * cdc-acm.c
+  *
+  * Copyright (c) 1999 Armin Fuerst    <fuerst@in.tum.de>
+  * Copyright (c) 1999 Pavel Machek    <pavel@suse.cz>
+@@ -26,6 +26,7 @@
+  *    v0.21 - revert to probing on device for devices with multiple configs
+  *    v0.22 - probe only the control interface. if usbcore doesn't choose the
+  *            config we want, sysadmin changes bConfigurationValue in sysfs.
++ *    v0.23 - use softirq for rx processing, as needed by tty layer
+  */
+ /*
+@@ -44,6 +45,8 @@
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+  */
++#undef DEBUG
++
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+@@ -54,14 +57,13 @@
+ #include <linux/module.h>
+ #include <linux/smp_lock.h>
+ #include <asm/uaccess.h>
+-#undef DEBUG
+ #include <linux/usb.h>
+ #include <asm/byteorder.h>
+ /*
+  * Version Information
+  */
+-#define DRIVER_VERSION "v0.21"
++#define DRIVER_VERSION "v0.23"
+ #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
+ #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
+@@ -146,7 +148,8 @@ struct acm {
+       struct tty_struct *tty;                         /* the corresponding tty */
+       struct urb *ctrlurb, *readurb, *writeurb;       /* urbs */
+       struct acm_line line;                           /* line coding (bits, stop, parity) */
+-      struct work_struct work;                                        /* work queue entry for line discipline waking up */
++      struct work_struct work;                        /* work queue entry for line discipline waking up */
++      struct tasklet_struct bh;                       /* rx processing */
+       unsigned int ctrlin;                            /* input control lines (DCD, DSR, RI, break, overruns) */
+       unsigned int ctrlout;                           /* output control lines (DTR, RTS) */
+       unsigned int writesize;                         /* max packet size for the output bulk endpoint */
+@@ -184,9 +187,10 @@ static int acm_ctrl_msg(struct acm *acm,
+ #define acm_send_break(acm, ms)               acm_ctrl_msg(acm, ACM_REQ_SEND_BREAK, ms, NULL, 0)
+ /*
+- * Interrupt handler for various ACM control events
++ * Interrupt handlers for various ACM device responses
+  */
++/* control interface reports status changes with "interrupt" transfers */
+ static void acm_ctrl_irq(struct urb *urb, struct pt_regs *regs)
+ {
+       struct acm *acm = urb->context;
+@@ -251,20 +255,30 @@ exit:
+                    __FUNCTION__, status);
+ }
++/* data interface returns incoming bytes, or we got unthrottled */
+ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
+ {
+       struct acm *acm = urb->context;
+-      struct tty_struct *tty = acm->tty;
+-      unsigned char *data = urb->transfer_buffer;
+-      int i = 0;
+       if (!ACM_READY(acm))
+               return;
+       if (urb->status)
+-              dbg("nonzero read bulk status received: %d", urb->status);
++              dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status);
++
++      /* calling tty_flip_buffer_push() in_irq() isn't allowed */
++      tasklet_schedule(&acm->bh);
++}
++
++static void acm_rx_tasklet(unsigned long _acm)
++{
++      struct acm *acm = (void *)_acm;
++      struct urb *urb = acm->readurb;
++      struct tty_struct *tty = acm->tty;
++      unsigned char *data = urb->transfer_buffer;
++      int i = 0;
+-      if (!urb->status && !acm->throttle)  {
++      if (urb->actual_length > 0 && !acm->throttle)  {
+               for (i = 0; i < urb->actual_length && !acm->throttle; i++) {
+                       /* if we insert more than TTY_FLIPBUF_SIZE characters,
+                        * we drop them. */
+@@ -285,10 +299,12 @@ static void acm_read_bulk(struct urb *ur
+       urb->actual_length = 0;
+       urb->dev = acm->dev;
+-      if (usb_submit_urb(urb, GFP_ATOMIC))
+-              dbg("failed resubmitting read urb");
++      i = usb_submit_urb(urb, GFP_ATOMIC);
++      if (i)
++              dev_dbg(&acm->data->dev, "bulk rx resubmit %d\n", i);
+ }
++/* data interface wrote those outgoing bytes */
+ static void acm_write_bulk(struct urb *urb, struct pt_regs *regs)
+ {
+       struct acm *acm = (struct acm *)urb->context;
+@@ -621,6 +637,8 @@ static int acm_probe (struct usb_interfa
+                       acm->minor = minor;
+                       acm->dev = dev;
++                      acm->bh.func = acm_rx_tasklet;
++                      acm->bh.data = (unsigned long) acm;
+                       INIT_WORK(&acm->work, acm_softint, acm);
+                       if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
+--- linux-2.6.0/drivers/usb/core/urb.c 2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/usb/core/urb.c  2003-12-28 23:22:11.000000000 -0800
+@@ -268,7 +268,7 @@ int usb_submit_urb(struct urb *urb, int 
+               /* "high bandwidth" mode, 1-3 packets/uframe? */
+               if (dev->speed == USB_SPEED_HIGH) {
+                       int     mult = 1 + ((max >> 11) & 0x03);
+-                      max &= 0x03ff;
++                      max &= 0x07ff;
+                       max *= mult;
+               }
+--- linux-2.6.0/drivers/usb/gadget/ether.c     2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/usb/gadget/ether.c      2003-12-28 23:21:01.000000000 -0800
+@@ -1761,9 +1761,7 @@ eth_bind (struct usb_gadget *gadget)
+       /* network device setup */
+       dev->net = net;
+       SET_MODULE_OWNER (net);
+-      net->priv = dev;
+       strcpy (net->name, "usb%d");
+-      ether_setup (net);
+       /* one random address for the gadget device ... both of these could
+        * reasonably come from an id prom or a module parameter.
+--- linux-2.6.0/drivers/usb/host/ehci-sched.c  2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/usb/host/ehci-sched.c   2003-12-28 23:22:11.000000000 -0800
+@@ -580,10 +580,10 @@ itd_fill (
+               maxp = urb->dev->epmaxpacketout [epnum];
+               buf1 = 0;
+       }
+-      buf1 |= (maxp & 0x03ff);
++      buf1 |= (maxp & 0x07ff);
+       multi = 1;
+       multi += (maxp >> 11) & 0x03;
+-      maxp &= 0x03ff;
++      maxp &= 0x07ff;
+       maxp *= multi;
+       /* transfer can't fit in any uframe? */ 
+--- linux-2.6.0/drivers/usb/image/scanner.c    2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/usb/image/scanner.c     2003-12-28 23:23:06.000000000 -0800
+@@ -282,7 +282,7 @@
+  *      for common error messages rather than the maintainer.
+  *
+  * 0.4.7  11/28/2001
+- *    - Fixed typo in Documentation/scanner.txt.  Thanks to
++ *    - Fixed typo in Documentation/usb/scanner.txt.  Thanks to
+  *      Karel <karel.vervaeke@pandora.be> for pointing it out.
+  *    - Added ID's for a Memorex 6136u. Thanks to Álvaro Gaspar de
+  *      Valenzuela" <agaspard@utsi.edu>.
+--- linux-2.6.0/drivers/usb/input/powermate.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/usb/input/powermate.c   2003-12-28 23:22:01.000000000 -0800
+@@ -54,7 +54,11 @@
+ #define UPDATE_PULSE_AWAKE       (1<<2)
+ #define UPDATE_PULSE_MODE        (1<<3)
+-#define POWERMATE_PAYLOAD_SIZE 3
++/* at least two versions of the hardware exist, with differing payload
++   sizes. the first three bytes always contain the "interesting" data in
++   the relevant format. */
++#define POWERMATE_PAYLOAD_SIZE_MAX 6
++#define POWERMATE_PAYLOAD_SIZE_MIN 3
+ struct powermate_device {
+       signed char *data;
+       dma_addr_t data_dma;
+@@ -269,7 +273,7 @@ static int powermate_input_event(struct 
+ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_device *pm)
+ {
+-      pm->data = usb_buffer_alloc(udev, POWERMATE_PAYLOAD_SIZE,
++      pm->data = usb_buffer_alloc(udev, POWERMATE_PAYLOAD_SIZE_MAX,
+                                   SLAB_ATOMIC, &pm->data_dma);
+       if (!pm->data)
+               return -1;
+@@ -284,7 +288,7 @@ static int powermate_alloc_buffers(struc
+ static void powermate_free_buffers(struct usb_device *udev, struct powermate_device *pm)
+ {
+       if (pm->data)
+-              usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE,
++              usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE_MAX,
+                               pm->data, pm->data_dma);
+       if (pm->configcr)
+               usb_buffer_free(udev, sizeof(*(pm->configcr)),
+@@ -347,12 +351,14 @@ static int powermate_probe(struct usb_in
+       pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
+       maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+-      if (maxp != POWERMATE_PAYLOAD_SIZE)
+-              printk("powermate: Expected payload of %d bytes, found %d bytes!\n", POWERMATE_PAYLOAD_SIZE, maxp);
+-
++      if(maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX){
++              printk("powermate: Expected payload of %d--%d bytes, found %d bytes!\n",
++                      POWERMATE_PAYLOAD_SIZE_MIN, POWERMATE_PAYLOAD_SIZE_MAX, maxp);
++              maxp = POWERMATE_PAYLOAD_SIZE_MAX;
++      }
+       usb_fill_int_urb(pm->irq, udev, pipe, pm->data,
+-                       POWERMATE_PAYLOAD_SIZE, powermate_irq,
++                       maxp, powermate_irq,
+                        pm, endpoint->bInterval);
+       pm->irq->transfer_dma = pm->data_dma;
+       pm->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+--- linux-2.6.0/drivers/video/aty/aty128fb.c   2003-10-17 15:58:04.000000000 -0700
++++ 25/drivers/video/aty/aty128fb.c    2003-12-28 23:23:00.000000000 -0800
+@@ -1536,6 +1536,7 @@ aty128_init(struct pci_dev *pdev, const 
+       /* fill in info */
+       info->fbops = &aty128fb_ops;
+       info->flags = FBINFO_FLAG_DEFAULT;
++      info->dev = &pdev->dev;
+ #ifdef CONFIG_PMAC_PBOOK
+       par->lcd_on = default_lcd_on;
+--- linux-2.6.0/drivers/video/cirrusfb.c       2003-06-14 12:18:32.000000000 -0700
++++ 25/drivers/video/cirrusfb.c        2003-12-28 23:23:00.000000000 -0800
+@@ -2528,7 +2528,7 @@ static int __init clgen_pci_setup (struc
+       pdev = clgen_pci_dev_get (btype);
+       if (!pdev) {
+-              printk (KERN_ERR " Couldn't find PCI device\n");
++              printk (KERN_INFO "cirrusfb: couldn't find Cirrus Logic PCI device\n");
+               DPRINTK ("EXIT, returning 1\n");
+               return 1;
+       }
+@@ -2787,6 +2787,7 @@ int __init clgenfb_init(void)
+       fb_info->gen.info.switch_con = &fbgen_switch;
+       fb_info->gen.info.updatevar = &fbgen_update_var;
+       fb_info->gen.info.flags = FBINFO_FLAG_DEFAULT;
++      fb_info->gen.info.dev = fb_info->pdev;
+       for (j = 0; j < 256; j++) {
+               if (j < 16) {
+--- linux-2.6.0/drivers/video/cyber2000fb.c    2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/video/cyber2000fb.c     2003-12-28 23:23:00.000000000 -0800
+@@ -1366,6 +1366,7 @@ static int __devinit cyberpro_common_pro
+       cfb->fb.fix.smem_len   = smem_size;
+       cfb->fb.fix.mmio_len   = MMIO_SIZE;
+       cfb->fb.screen_base    = cfb->region;
++      cfb->fb.dev            = &cfb->dev->dev;
+       err = -EINVAL;
+       if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
+--- linux-2.6.0/drivers/video/fbmem.c  2003-09-08 13:58:58.000000000 -0700
++++ 25/drivers/video/fbmem.c   2003-12-28 23:23:00.000000000 -0800
+@@ -31,6 +31,7 @@
+ #include <linux/kmod.h>
+ #endif
+ #include <linux/devfs_fs_kernel.h>
++#include <linux/device.h>
+ #if defined(__mc68000__) || defined(CONFIG_APUS)
+ #include <asm/setup.h>
+@@ -1199,6 +1200,10 @@ static struct file_operations fb_fops = 
+ #endif
+ };
++static struct class fb_class = {
++      .name   = "video",
++};
++
+ /**
+  *    register_framebuffer - registers a frame buffer device
+  *    @fb_info: frame buffer info structure
+@@ -1242,6 +1247,8 @@ register_framebuffer(struct fb_info *fb_
+       devfs_mk_cdev(MKDEV(FB_MAJOR, i),
+                       S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i);
++
++      simple_add_class_device(&fb_class, MKDEV(FB_MAJOR, i), fb_info->dev, "fb%d", i);
+       return 0;
+ }
+@@ -1270,6 +1277,7 @@ unregister_framebuffer(struct fb_info *f
+               kfree(fb_info->pixmap.addr);
+       registered_fb[i]=NULL;
+       num_registered_fb--;
++      simple_remove_class_device(MKDEV(FB_MAJOR, i));
+       return 0;
+ }
+@@ -1294,6 +1302,8 @@ fbmem_init(void)
+       if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
+               printk("unable to get major %d for fb devs\n", FB_MAJOR);
++      class_register(&fb_class);
++
+ #ifdef CONFIG_FB_OF
+       if (ofonly) {
+               offb_init();
+--- linux-2.6.0/drivers/video/fbmon.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/drivers/video/fbmon.c   2003-12-28 23:21:48.000000000 -0800
+@@ -890,30 +890,6 @@ struct __fb_timings {
+       u32 vtotal;
+ };
+-/*
+- * a simple function to get the square root of integers 
+- */
+-static u32 fb_sqrt(int x)
+-{
+-      register int op, res, one;
+-
+-      op = x;
+-      res = 0;
+-
+-      one = 1 << 30;
+-      while (one > op) one >>= 2;
+-
+-      while (one != 0) {
+-              if (op >= res + one) {
+-                      op = op - (res + one);
+-                      res = res +  2 * one;
+-              }
+-              res /= 2;
+-              one /= 4;
+-      }
+-      return((u32) res);
+-}
+-
+ /**
+  * fb_get_vblank - get vertical blank time
+  * @hfreq: horizontal freq
+@@ -1002,7 +978,7 @@ static u32 fb_get_hblank_by_dclk(u32 dcl
+       h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk);
+       h_period *=10000; 
+-      h_period = fb_sqrt((int) h_period);
++      h_period = int_sqrt(h_period);
+       h_period -= (100 - C_VAL) * 100;
+       h_period *= 1000; 
+       h_period /= 2 * M_VAL;
+--- linux-2.6.0/drivers/video/hgafb.c  2003-06-14 12:18:30.000000000 -0700
++++ 25/drivers/video/hgafb.c   2003-12-28 23:22:57.000000000 -0800
+@@ -539,7 +539,7 @@ static struct fb_ops hgafb_ops = {
+ int __init hgafb_init(void)
+ {
+       if (! hga_card_detect()) {
+-              printk(KERN_ERR "hgafb: HGA card not detected.\n");
++              printk(KERN_INFO "hgafb: HGA card not detected.\n");
+               return -EINVAL;
+       }
+--- linux-2.6.0/drivers/video/i810/i810_main.c 2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/video/i810/i810_main.c  2003-12-28 23:23:00.000000000 -0800
+@@ -1880,6 +1880,7 @@ static int __devinit i810fb_init_pci (st
+       info->fbops = &par->i810fb_ops;
+       info->pseudo_palette = par->pseudo_palette;
+       info->flags = FBINFO_FLAG_DEFAULT;
++      info->dev = &dev->dev;
+       
+       fb_alloc_cmap(&info->cmap, 256, 0);
+--- linux-2.6.0/drivers/video/igafb.c  2003-11-26 13:53:35.000000000 -0800
++++ 25/drivers/video/igafb.c   2003-12-28 23:23:00.000000000 -0800
+@@ -332,7 +332,7 @@ static struct fb_ops igafb_ops = {
+ #endif
+ };
+-static int __init iga_init(struct fb_info *info, struct iga_par *par)
++static int __init iga_init(struct fb_info *info, struct iga_par *par, struct pci_dev *dev)
+ {
+         char vramsz = iga_inb(par, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL) 
+                                                        & MEM_SIZE_ALIAS;
+@@ -358,6 +358,7 @@ static int __init iga_init(struct fb_inf
+       info->fbops = &igafb_ops;
+       info->flags = FBINFO_FLAG_DEFAULT;
++      info->dev = &dev->dev;
+       fb_alloc_cmap(&info->cmap, video_cmap_len, 0);
+@@ -529,7 +530,7 @@ int __init igafb_init(void)
+       info->fix = igafb_fix;
+       info->pseudo_palette = (void *)(par + 1);
+-      if (!iga_init(info, par)) {
++      if (!iga_init(info, par, pdev)) {
+               iounmap((void *)par->io_base);
+               iounmap(info->screen_base);
+               if (par->mmap_map)
+--- linux-2.6.0/drivers/video/imsttfb.c        2003-10-17 15:58:04.000000000 -0700
++++ 25/drivers/video/imsttfb.c 2003-12-28 23:23:00.000000000 -0800
+@@ -1348,7 +1348,7 @@ static struct fb_ops imsttfb_ops = {
+ };
+ static void __init 
+-init_imstt(struct fb_info *info)
++init_imstt(struct fb_info *info, struct pci_dev *pdev)
+ {
+       struct imstt_par *par = (struct imstt_par *) info->par;
+       __u32 i, tmp, *ip, *end;
+@@ -1442,6 +1442,7 @@ init_imstt(struct fb_info *info)
+       info->fbops = &imsttfb_ops;
+       info->flags = FBINFO_FLAG_DEFAULT;
++      info->dev = &pdev->dev;
+       fb_alloc_cmap(&info->cmap, 0, 0);
+@@ -1520,7 +1521,7 @@ imsttfb_probe(struct pci_dev *pdev, cons
+       par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);
+       info->par = par;
+       info->pseudo_palette = (void *) (par + 1);
+-      init_imstt(info);
++      init_imstt(info, pdev);
+       pci_set_drvdata(pdev, info);
+       return 0;
+--- linux-2.6.0/drivers/video/matrox/matroxfb_crtc2.c  2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/video/matrox/matroxfb_crtc2.c   2003-12-28 23:23:00.000000000 -0800
+@@ -605,6 +605,7 @@ static int matroxfb_dh_regit(CPMINFO str
+       m2info->fbcon.flags = FBINFO_FLAG_DEFAULT;
+       m2info->fbcon.currcon = -1;
+       m2info->fbcon.pseudo_palette = m2info->cmap;
++      m2info->fbcon.dev = &m2info->primary_dev->pcidev->dev;
+       fb_alloc_cmap(&m2info->fbcon.cmap, 256, 1);
+       if (mem < 64)
+--- linux-2.6.0/drivers/video/neofb.c  2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/video/neofb.c   2003-12-28 23:23:00.000000000 -0800
+@@ -1943,6 +1943,7 @@ static struct fb_info *__devinit neo_all
+       info->flags = FBINFO_FLAG_DEFAULT;
+       info->par = par;
+       info->pseudo_palette = (void *) (par + 1);
++      info->dev = &dev->dev;
+       fb_alloc_cmap(&info->cmap, NR_PALETTE, 0);
+--- linux-2.6.0/drivers/video/radeonfb.c       2003-11-23 19:03:01.000000000 -0800
++++ 25/drivers/video/radeonfb.c        2003-12-28 23:23:00.000000000 -0800
+@@ -679,7 +679,7 @@ static __inline__ int _max(int val1, int
+  */
+         
+ static char *mode_option __initdata;
+-static char noaccel = 1;
++static char noaccel = 0;
+ static char mirror = 0;
+ static int panel_yres __initdata = 0;
+ static char force_dfp __initdata = 0;
+@@ -1099,7 +1099,7 @@ static int radeon_get_dfpinfo_BIOS(struc
+       printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",
+               rinfo->panel_xres, rinfo->panel_yres);
+-      for(i=0; i<20; i++) {
++      for(i=0; i<21; i++) {
+               tmp0 = rinfo->bios_seg + readw(tmp+64+i*2);
+               if (tmp0 == 0)
+                       break;
+@@ -1241,9 +1241,6 @@ static void radeon_engine_init (struct r
+       radeon_fifo_wait (1);
+       OUTREG(RB2D_DSTCACHE_MODE, 0);
+-      /* XXX */
+-      rinfo->pitch = ((rinfo->xres_virtual * (rinfo->bpp / 8) + 0x3f)) >> 6;
+-
+       radeon_fifo_wait (1);
+       temp = INREG(DEFAULT_PITCH_OFFSET);
+       OUTREG(DEFAULT_PITCH_OFFSET, ((temp & 0xc0000000) | 
+@@ -1782,6 +1779,7 @@ static int radeonfb_set_par (struct fb_i
+       int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
+       int primary_mon = PRIMARY_MONITOR(rinfo);
+       int depth = var_to_depth(mode);
++        int accel = (mode->accel_flags & FB_ACCELF_TEXT) != 0;
+       rinfo->xres = mode->xres;
+       rinfo->yres = mode->yres;
+@@ -1878,7 +1876,15 @@ static int radeonfb_set_par (struct fb_i
+       newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
+                                        (vsync_wid << 16) | (v_sync_pol  << 23));
+-      newmode.crtc_pitch = (mode->xres_virtual >> 3);
++      if (accel) {
++              /* We first calculate the engine pitch */
++              rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
++                              & ~(0x3f)) >> 6;
++
++              /* Then, re-multiply it to get the CRTC pitch */
++              newmode.crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8);
++      } else
++              newmode.crtc_pitch = (mode->xres_virtual >> 3);
+       newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
+ #if defined(__BIG_ENDIAN)
+@@ -2085,18 +2091,21 @@ static int radeonfb_set_par (struct fb_i
+       if (!rinfo->asleep) {
+               radeon_write_mode (rinfo, &newmode);
+               /* (re)initialize the engine */
+-              if (!noaccel)
++              if (noaccel)
+                       radeon_engine_init (rinfo);
+       
+       }
+       /* Update fix */
+-        info->fix.line_length = rinfo->pitch*64;
++      if (accel)
++              info->fix.line_length = rinfo->pitch*64;
++        else
++              info->fix.line_length = mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8);
+         info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+ #ifdef CONFIG_BOOTX_TEXT
+       /* Update debug text engine */
+       btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
+-                           rinfo->depth, rinfo->pitch*64);
++                           rinfo->depth, info->fix.line_length);
+ #endif
+       return 0;
+@@ -3022,17 +3031,13 @@ static int radeonfb_pci_register (struct
+        */
+       radeon_save_state (rinfo, &rinfo->init_state);
+-      if (!noaccel) {
+-              /* initialize the engine */
+-              radeon_engine_init (rinfo);
+-      }
+-
+       /* set all the vital stuff */
+       radeon_set_fbinfo (rinfo);
+       pci_set_drvdata(pdev, rinfo);
+       rinfo->next = board_list;
+       board_list = rinfo;
++      rinfo->info.dev = &pdev->dev;
+       if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
+               printk ("radeonfb: could not register framebuffer\n");
+--- linux-2.6.0/drivers/video/riva/fbdev.c     2003-09-27 18:57:46.000000000 -0700
++++ 25/drivers/video/riva/fbdev.c      2003-12-28 23:23:00.000000000 -0800
+@@ -1751,6 +1751,7 @@ static int __devinit rivafb_probe(struct
+       if (info->pixmap.addr == NULL)
+               goto err_out_kfree1;
+       memset(info->pixmap.addr, 0, 64 * 1024);
++      info->dev = &pd->dev;
+       strcat(rivafb_fix.id, rci->name);
+       default_par->riva.Architecture = rci->arch_rev;
+--- linux-2.6.0/drivers/video/sis/init301.c    2003-07-13 21:44:34.000000000 -0700
++++ 25/drivers/video/sis/init301.c     2003-12-28 23:22:17.000000000 -0800
+@@ -11712,7 +11712,7 @@ SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_
+   }
+   temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 1);
+-  if(temp = 0xFFFF) return;
++  if(temp == 0xFFFF) return;
+   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
+   for(i=0x14, j=0; i<=0x17; i++, j++) {
+--- linux-2.6.0/drivers/video/sis/sis_main.c   2003-06-14 12:18:25.000000000 -0700
++++ 25/drivers/video/sis/sis_main.c    2003-12-28 23:23:00.000000000 -0800
+@@ -4507,6 +4507,7 @@ int __init sisfb_init(void)
+               sis_fb_info.par = &ivideo;
+               sis_fb_info.screen_base = ivideo.video_vbase;
+               sis_fb_info.fbops = &sisfb_ops;
++              sis_fb_info.dev = &pdev->dev;
+               sisfb_get_fix(&sis_fb_info.fix, -1, &sis_fb_info);
+               sis_fb_info.pseudo_palette = pseudo_palette;
+               
+--- linux-2.6.0/drivers/video/sstfb.c  2003-10-08 15:07:09.000000000 -0700
++++ 25/drivers/video/sstfb.c   2003-12-28 23:23:00.000000000 -0800
+@@ -1477,6 +1477,7 @@ static int __devinit sstfb_probe(struct 
+       info->fbops     = &sstfb_ops;
+       info->currcon   = -1;
+       info->pseudo_palette = &all->pseudo_palette;
++      info->dev       = &pdev->dev;
+       fix->type       = FB_TYPE_PACKED_PIXELS;
+       fix->visual     = FB_VISUAL_TRUECOLOR;
+--- linux-2.6.0/drivers/video/tdfxfb.c 2003-08-08 22:55:13.000000000 -0700
++++ 25/drivers/video/tdfxfb.c  2003-12-28 23:23:00.000000000 -0800
+@@ -1248,6 +1248,7 @@ static int __devinit tdfxfb_probe(struct
+       info->par               = default_par;
+       info->pseudo_palette    = (void *)(default_par + 1); 
+       info->flags             = FBINFO_FLAG_DEFAULT;
++      info->dev               = &pdev->dev;
+ #ifndef MODULE
+       if (!mode_option)
+--- linux-2.6.0/drivers/video/tgafb.c  2003-06-14 12:18:28.000000000 -0700
++++ 25/drivers/video/tgafb.c   2003-12-28 23:23:00.000000000 -0800
+@@ -1430,6 +1430,7 @@ tgafb_pci_register(struct pci_dev *pdev,
+       all->info.currcon = -1;
+       all->info.par = &all->par;
+       all->info.pseudo_palette = all->pseudo_palette;
++      all->info.dev = &pdev->dev;
+       /* This should give a reasonable default video mode.  */
+--- linux-2.6.0/drivers/video/tridentfb.c      2003-10-17 15:58:04.000000000 -0700
++++ 25/drivers/video/tridentfb.c       2003-12-28 23:23:02.000000000 -0800
+@@ -723,7 +723,7 @@ static int tridentfb_check_var(struct fb
+       if (bpp == 24 )
+               bpp = var->bits_per_pixel = 32;
+       /* check whether resolution fits on panel and in memory*/
+-      if (var->xres > nativex)
++      if (flatpanel && nativex && var->xres > nativex)
+               return -EINVAL;
+       if (var->xres * var->yres_virtual * bpp/8 > info->fix.smem_len)
+               return -EINVAL;
+@@ -1156,6 +1156,7 @@ static int __devinit trident_pci_probe(s
+               default_var.accel_flags &= ~FB_ACCELF_TEXT;
+       default_var.activate |= FB_ACTIVATE_NOW;
+       fb_info.var = default_var;
++      fb_info.dev = &dev->dev;
+       if (register_framebuffer(&fb_info) < 0) {
+               output("Could not register Trident framebuffer\n");
+               return -EINVAL;
+--- linux-2.6.0/fs/aio.c       2003-11-23 19:03:01.000000000 -0800
++++ 25/fs/aio.c        2003-12-28 23:26:44.000000000 -0800
+@@ -27,6 +27,8 @@
+ #include <linux/aio.h>
+ #include <linux/highmem.h>
+ #include <linux/workqueue.h>
++#include <linux/writeback.h>
++#include <linux/pagemap.h>
+ #include <asm/kmap_types.h>
+ #include <asm/uaccess.h>
+@@ -38,6 +40,9 @@
+ #define dprintk(x...) do { ; } while (0)
+ #endif
++long aio_run = 0; /* for testing only */
++long aio_wakeups = 0; /* for testing only */
++
+ /*------ sysctl variables----*/
+ atomic_t aio_nr = ATOMIC_INIT(0);     /* current system wide number of aio requests */
+ unsigned aio_max_nr = 0x10000;        /* system wide maximum number of aio requests */
+@@ -47,6 +52,7 @@ static kmem_cache_t  *kiocb_cachep;
+ static kmem_cache_t   *kioctx_cachep;
+ static struct workqueue_struct *aio_wq;
++static struct workqueue_struct *aio_fput_wq;
+ /* Used for rare fput completion. */
+ static void aio_fput_routine(void *);
+@@ -74,6 +80,7 @@ static int __init aio_setup(void)
+               panic("unable to create kioctx cache");
+       aio_wq = create_workqueue("aio");
++      aio_fput_wq = create_workqueue("aio_fput");
+       pr_debug("aio_setup: sizeof(struct page) = %d\n", (int)sizeof(struct page));
+@@ -281,6 +288,7 @@ static void aio_cancel_all(struct kioctx
+               struct kiocb *iocb = list_kiocb(pos);
+               list_del_init(&iocb->ki_list);
+               cancel = iocb->ki_cancel;
++              kiocbSetCancelled(iocb);
+               if (cancel) {
+                       iocb->ki_users++;
+                       spin_unlock_irq(&ctx->ctx_lock);
+@@ -341,6 +349,11 @@ void exit_aio(struct mm_struct *mm)
+               aio_cancel_all(ctx);
+               wait_for_all_aios(ctx);
++              /*
++               * this is an overkill, but ensures we don't leave
++               * the ctx on the aio_wq
++               */
++              flush_workqueue(aio_wq);
+               if (1 != atomic_read(&ctx->users))
+                       printk(KERN_DEBUG
+@@ -400,6 +413,7 @@ static struct kiocb *__aio_get_req(struc
+       req->ki_cancel = NULL;
+       req->ki_retry = NULL;
+       req->ki_user_obj = NULL;
++      INIT_LIST_HEAD(&req->ki_run_list);
+       /* Check if the completion queue has enough free space to
+        * accept an event from this io.
+@@ -499,7 +513,7 @@ static int __aio_put_req(struct kioctx *
+               spin_lock(&fput_lock);
+               list_add(&req->ki_list, &fput_head);
+               spin_unlock(&fput_lock);
+-              queue_work(aio_wq, &fput_work);
++              queue_work(aio_fput_wq, &fput_work);
+       } else
+               really_put_req(ctx, req);
+       return 1;
+@@ -541,65 +555,324 @@ struct kioctx *lookup_ioctx(unsigned lon
+       return ioctx;
+ }
++/*
++ * use_mm
++ *    Makes the calling kernel thread take on the specified
++ *    mm context.
++ *    Called by the retry thread execute retries within the
++ *    iocb issuer's mm context, so that copy_from/to_user
++ *    operations work seamlessly for aio.
++ *    (Note: this routine is intended to be called only
++ *    from a kernel thread context)
++ */
+ static void use_mm(struct mm_struct *mm)
+ {
+-      struct mm_struct *active_mm = current->active_mm;
++      struct mm_struct *active_mm;
++      struct task_struct *tsk = current;
++
++      task_lock(tsk);
++      active_mm = tsk->active_mm;
+       atomic_inc(&mm->mm_count);
+-      current->mm = mm;
+-      if (mm != active_mm) {
+-              current->active_mm = mm;
+-              activate_mm(active_mm, mm);
+-      }
++      tsk->mm = mm;
++      tsk->active_mm = mm;
++      activate_mm(active_mm, mm);
++      task_unlock(tsk);
++
+       mmdrop(active_mm);
+ }
+-static void unuse_mm(struct mm_struct *mm)
++/*
++ * unuse_mm
++ *    Reverses the effect of use_mm, i.e. releases the
++ *    specified mm context which was earlier taken on
++ *    by the calling kernel thread
++ *    (Note: this routine is intended to be called only
++ *    from a kernel thread context)
++ *
++ * Comments: Called with ctx->ctx_lock held. This nests
++ * task_lock instead ctx_lock.
++ */
++void unuse_mm(struct mm_struct *mm)
+ {
+-      current->mm = NULL;
++      struct task_struct *tsk = current;
++
++      task_lock(tsk);
++      tsk->mm = NULL;
+       /* active_mm is still 'mm' */
+-      enter_lazy_tlb(mm, current);
++      enter_lazy_tlb(mm, tsk);
++      task_unlock(tsk);
+ }
+-/* Run on kevent's context.  FIXME: needs to be per-cpu and warn if an
+- * operation blocks.
++/*
++ * Queue up a kiocb to be retried. Assumes that the kiocb
++ * has already been marked as kicked, and places it on
++ * the retry run list for the corresponding ioctx, if it
++ * isn't already queued. Returns 1 if it actually queued
++ * the kiocb (to tell the caller to activate the work
++ * queue to process it), or 0, if it found that it was
++ * already queued.
++ *
++ * Should be called with the spin lock iocb->ki_ctx->ctx_lock
++ * held
+  */
+-static void aio_kick_handler(void *data)
++static inline int __queue_kicked_iocb(struct kiocb *iocb)
+ {
+-      struct kioctx *ctx = data;
++      struct kioctx   *ctx = iocb->ki_ctx;
+-      use_mm(ctx->mm);
++      if (list_empty(&iocb->ki_run_list)) {
++              list_add_tail(&iocb->ki_run_list,
++                      &ctx->run_list);
++              iocb->ki_queued++;
++              return 1;
++      }
++      return 0;
++}
+-      spin_lock_irq(&ctx->ctx_lock);
+-      while (!list_empty(&ctx->run_list)) {
+-              struct kiocb *iocb;
+-              long ret;
++/* aio_run_iocb
++ *     This is the core aio execution routine. It is
++ *     invoked both for initial i/o submission and
++ *     subsequent retries via the aio_kick_handler.
++ *       Expects to be invoked with iocb->ki_ctx->lock
++ *       already held. The lock is released and reaquired
++ *       as needed during processing.
++ *
++ * Calls the iocb retry method (already setup for the
++ * iocb on initial submission) for operation specific
++ * handling, but takes care of most of common retry
++ * execution details for a given iocb. The retry method
++ * needs to be non-blocking as far as possible, to avoid
++ * holding up other iocbs waiting to be serviced by the
++ * retry kernel thread.
++ *
++ * The trickier parts in this code have to do with
++ * ensuring that only one retry instance is in progress
++ * for a given iocb at any time. Providing that guarantee
++ * simplifies the coding of individual aio operations as
++ * it avoids various potential races.
++ */
++static ssize_t aio_run_iocb(struct kiocb *iocb)
++{
++      struct kioctx   *ctx = iocb->ki_ctx;
++      ssize_t (*retry)(struct kiocb *);
++      ssize_t ret;
+-              iocb = list_entry(ctx->run_list.next, struct kiocb,
+-                                ki_run_list);
+-              list_del(&iocb->ki_run_list);
+-              iocb->ki_users ++;
+-              spin_unlock_irq(&ctx->ctx_lock);
++      if (iocb->ki_retried++ > 1024*1024) {
++              printk("Maximal retry count.  Bytes done %Zd\n",
++                      iocb->ki_nbytes - iocb->ki_left);
++              return -EAGAIN;
++      }
+-              kiocbClearKicked(iocb);
+-              ret = iocb->ki_retry(iocb);
++      if (!(iocb->ki_retried & 0xff)) {
++              pr_debug("%ld retry: %d of %d (kick %ld, Q %ld run %ld, wake %ld)\n",
++                      iocb->ki_retried,
++                      iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes,
++                      iocb->ki_kicked, iocb->ki_queued, aio_run, aio_wakeups);
++      }
++
++      if (!(retry = iocb->ki_retry)) {
++              printk("aio_run_iocb: iocb->ki_retry = NULL\n");
++              return 0;
++      }
++
++      /*
++       * We don't want the next retry iteration for this
++       * operation to start until this one has returned and
++       * updated the iocb state. However, wait_queue functions
++       * can trigger a kick_iocb from interrupt context in the
++       * meantime, indicating that data is available for the next
++       * iteration. We want to remember that and enable the
++       * next retry iteration _after_ we are through with
++       * this one.
++       *
++       * So, in order to be able to register a "kick", but
++       * prevent it from being queued now, we clear the kick
++       * flag, but make the kick code *think* that the iocb is
++       * still on the run list until we are actually done.
++       * When we are done with this iteration, we check if
++       * the iocb was kicked in the meantime and if so, queue
++       * it up afresh.
++       */
++
++      kiocbClearKicked(iocb);
++
++      /*
++       * This is so that aio_complete knows it doesn't need to
++       * pull the iocb off the run list (We can't just call
++       * INIT_LIST_HEAD because we don't want a kick_iocb to
++       * queue this on the run list yet)
++       */
++      iocb->ki_run_list.next = iocb->ki_run_list.prev = NULL;
++      iocb->ki_retry = NULL;
++      spin_unlock_irq(&ctx->ctx_lock);
++
++      /* Quit retrying if the i/o has been cancelled */
++      if (kiocbIsCancelled(iocb)) {
++              ret = -EINTR;
++              aio_complete(iocb, ret, 0);
++              /* must not access the iocb after this */
++              goto out;
++      }
++
++      /*
++       * Now we are all set to call the retry method in async
++       * context. By setting this thread's io_wait context
++       * to point to the wait queue entry inside the currently
++       * running iocb for the duration of the retry, we ensure
++       * that async notification wakeups are queued by the
++       * operation instead of blocking waits, and when notified,
++       * cause the iocb to be kicked for continuation (through
++       * the aio_wake_function callback).
++       */
++      BUG_ON(current->io_wait != NULL);
++      current->io_wait = &iocb->ki_wait;
++      ret = retry(iocb);
++      current->io_wait = NULL;
++
++      if (-EIOCBRETRY != ret) {
+               if (-EIOCBQUEUED != ret) {
++                      BUG_ON(!list_empty(&iocb->ki_wait.task_list));
+                       aio_complete(iocb, ret, 0);
+-                      iocb = NULL;
++                      /* must not access the iocb after this */
+               }
++      } else {
++              /*
++               * Issue an additional retry to avoid waiting forever if
++               * no waits were queued (e.g. in case of a short read).
++               */
++              if (list_empty(&iocb->ki_wait.task_list))
++                      kiocbSetKicked(iocb);
++      }
++out:
++      spin_lock_irq(&ctx->ctx_lock);
+-              spin_lock_irq(&ctx->ctx_lock);
+-              if (NULL != iocb)
+-                      __aio_put_req(ctx, iocb);
++      if (-EIOCBRETRY == ret) {
++              /*
++               * OK, now that we are done with this iteration
++               * and know that there is more left to go,
++               * this is where we let go so that a subsequent
++               * "kick" can start the next iteration
++               */
++              iocb->ki_retry = retry;
++              /* will make __queue_kicked_iocb succeed from here on */
++              INIT_LIST_HEAD(&iocb->ki_run_list);
++              /* we must queue the next iteration ourselves, if it
++               * has already been kicked */
++              if (kiocbIsKicked(iocb)) {
++                      __queue_kicked_iocb(iocb);
++              }
+       }
++      return ret;
++}
++
++/*
++ * __aio_run_iocbs:
++ *    Process all pending retries queued on the ioctx
++ *    run list.
++ * Assumes it is operating within the aio issuer's mm
++ * context. Expects to be called with ctx->ctx_lock held
++ */
++static int __aio_run_iocbs(struct kioctx *ctx)
++{
++      struct kiocb *iocb;
++      int count = 0;
++      LIST_HEAD(run_list);
++
++      list_splice_init(&ctx->run_list, &run_list);
++      while (!list_empty(&run_list)) {
++              iocb = list_entry(run_list.next, struct kiocb,
++                      ki_run_list);
++              list_del(&iocb->ki_run_list);
++              /*
++               * Hold an extra reference while retrying i/o.
++               */
++              iocb->ki_users++;       /* grab extra reference */
++              aio_run_iocb(iocb);
++              if (__aio_put_req(ctx, iocb))  /* drop extra ref */
++                      put_ioctx(ctx);
++              count++;
++      }
++      aio_run++;
++      if (!list_empty(&ctx->run_list))
++              return 1;
++      return 0;
++}
++
++/*
++ * aio_run_iocbs:
++ *    Process all pending retries queued on the ioctx
++ *    run list.
++ * Assumes it is operating within the aio issuer's mm
++ * context.
++ */
++static inline void aio_run_iocbs(struct kioctx *ctx)
++{
++      int requeue;
++
++      spin_lock_irq(&ctx->ctx_lock);
++      requeue = __aio_run_iocbs(ctx);
+       spin_unlock_irq(&ctx->ctx_lock);
++      if (requeue)
++              queue_work(aio_wq, &ctx->wq);
++}
++/*
++ * aio_kick_handler:
++ *    Work queue handler triggered to process pending
++ *    retries on an ioctx. Takes on the aio issuer's
++ *    mm context before running the iocbs, so that
++ *    copy_xxx_user operates on the issuer's address
++ *    space.
++ * Run on aiod's context.
++ */
++static void aio_kick_handler(void *data)
++{
++      struct kioctx *ctx = data;
++      mm_segment_t oldfs = get_fs();
++      int requeue;
++
++      set_fs(USER_DS);
++      use_mm(ctx->mm);
++      spin_lock_irq(&ctx->ctx_lock);
++      requeue = __aio_run_iocbs(ctx);
+       unuse_mm(ctx->mm);
++      spin_unlock_irq(&ctx->ctx_lock);
++      set_fs(oldfs);
++      if (requeue)
++              queue_work(aio_wq, &ctx->wq);
+ }
+-void kick_iocb(struct kiocb *iocb)
++
++/*
++ * Called by kick_iocb to queue the kiocb for retry
++ * and if required activate the aio work queue to process
++ * it
++ */
++void queue_kicked_iocb(struct kiocb *iocb)
+ {
+       struct kioctx   *ctx = iocb->ki_ctx;
++      unsigned long flags;
++      int run = 0;
++
++      WARN_ON((!list_empty(&iocb->ki_wait.task_list)));
++      spin_lock_irqsave(&ctx->ctx_lock, flags);
++      run = __queue_kicked_iocb(iocb);
++      spin_unlock_irqrestore(&ctx->ctx_lock, flags);
++      if (run) {
++              queue_work(aio_wq, &ctx->wq);
++              aio_wakeups++;
++      }
++}
++
++/*
++ * kick_iocb:
++ *    Called typically from a wait queue callback context
++ *    (aio_wake_function) to trigger a retry of the iocb.
++ *    The retry is usually executed by aio workqueue
++ *    threads (See aio_kick_handler).
++ */
++void kick_iocb(struct kiocb *iocb)
++{
+       /* sync iocbs are easy: they can only ever be executing from a 
+        * single context. */
+       if (is_sync_kiocb(iocb)) {
+@@ -608,12 +881,10 @@ void kick_iocb(struct kiocb *iocb)
+               return;
+       }
++      iocb->ki_kicked++;
++      /* If its already kicked we shouldn't queue it again */
+       if (!kiocbTryKick(iocb)) {
+-              unsigned long flags;
+-              spin_lock_irqsave(&ctx->ctx_lock, flags);
+-              list_add_tail(&iocb->ki_run_list, &ctx->run_list);
+-              spin_unlock_irqrestore(&ctx->ctx_lock, flags);
+-              schedule_work(&ctx->wq);
++              queue_kicked_iocb(iocb);
+       }
+ }
+@@ -666,6 +937,9 @@ int aio_complete(struct kiocb *iocb, lon
+        */
+       spin_lock_irqsave(&ctx->ctx_lock, flags);
++      if (iocb->ki_run_list.prev && !list_empty(&iocb->ki_run_list))
++              list_del_init(&iocb->ki_run_list);
++
+       ring = kmap_atomic(info->ring_pages[0], KM_IRQ1);
+       tail = info->tail;
+@@ -694,6 +968,11 @@ int aio_complete(struct kiocb *iocb, lon
+       pr_debug("added to ring %p at [%lu]\n", iocb, tail);
++      pr_debug("%ld retries: %d of %d (kicked %ld, Q %ld run %ld wake %ld)\n",
++              iocb->ki_retried,
++              iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes,
++              iocb->ki_kicked, iocb->ki_queued, aio_run, aio_wakeups);
++
+       /* everything turned out well, dispose of the aiocb. */
+       ret = __aio_put_req(ctx, iocb);
+@@ -808,6 +1087,7 @@ static int read_events(struct kioctx *ct
+       int                     i = 0;
+       struct io_event         ent;
+       struct timeout          to;
++      int                     event_loop = 0; /* testing only */
+       /* needed to zero any padding within an entry (there shouldn't be 
+        * any, but C is fun!
+@@ -857,7 +1137,6 @@ static int read_events(struct kioctx *ct
+               add_wait_queue_exclusive(&ctx->wait, &wait);
+               do {
+                       set_task_state(tsk, TASK_INTERRUPTIBLE);
+-
+                       ret = aio_read_evt(ctx, &ent);
+                       if (ret)
+                               break;
+@@ -867,6 +1146,7 @@ static int read_events(struct kioctx *ct
+                       if (to.timed_out)       /* Only check after read evt */
+                               break;
+                       schedule();
++                      event_loop++;
+                       if (signal_pending(tsk)) {
+                               ret = -EINTR;
+                               break;
+@@ -894,6 +1174,9 @@ static int read_events(struct kioctx *ct
+       if (timeout)
+               clear_timeout(&to);
+ out:
++      pr_debug("event loop executed %d times\n", event_loop);
++      pr_debug("aio_run %ld\n", aio_run);
++      pr_debug("aio_wakeups %ld\n", aio_wakeups);
+       return i ? i : ret;
+ }
+@@ -923,6 +1206,11 @@ static void io_destroy(struct kioctx *io
+       aio_cancel_all(ioctx);
+       wait_for_all_aios(ioctx);
++      /*
++       * this is an overkill, but ensures we don't leave
++       * the ctx on the aio_wq
++       */
++      flush_workqueue(aio_wq);
+       put_ioctx(ioctx);       /* once for the lookup */
+ }
+@@ -985,13 +1273,191 @@ asmlinkage long sys_io_destroy(aio_conte
+       return -EINVAL;
+ }
++/*
++ * Retry method for aio_read (also used for first time submit)
++ * Responsible for updating iocb state as retries progress
++ */
++static ssize_t aio_pread(struct kiocb *iocb)
++{
++      struct file *file = iocb->ki_filp;
++      ssize_t ret = 0;
++
++      ret = file->f_op->aio_read(iocb, iocb->ki_buf,
++              iocb->ki_left, iocb->ki_pos);
++
++      /*
++       * Can't just depend on iocb->ki_left to determine
++       * whether we are done. This may have been a short read.
++       */
++      if (ret > 0) {
++              iocb->ki_buf += ret;
++              iocb->ki_left -= ret;
++
++              ret = -EIOCBRETRY;
++      }
++
++      /* This means we must have transferred all that we could */
++      /* No need to retry anymore */
++      if ((ret == 0) || (iocb->ki_left == 0))
++              ret = iocb->ki_nbytes - iocb->ki_left;
++
++      return ret;
++}
++
++/*
++ * Retry method for aio_write (also used for first time submit)
++ * Responsible for updating iocb state as retries progress
++ */
++static ssize_t aio_pwrite(struct kiocb *iocb)
++{
++      struct file *file = iocb->ki_filp;
++      struct address_space *mapping = file->f_mapping;
++      struct inode *inode = mapping->host;
++      ssize_t ret = 0;
++
++      ret = file->f_op->aio_write(iocb, iocb->ki_buf,
++                              iocb->ki_left, iocb->ki_pos);
++
++      /*
++       * Even if iocb->ki_left = 0, we may need to wait
++       * for a balance_dirty_pages to complete
++       */
++      if (ret > 0) {
++              iocb->ki_buf += iocb->ki_buf ? ret : 0;
++              iocb->ki_left -= ret;
++
++              ret = -EIOCBRETRY;
++      }
++
++      /* This means we must have transferred all that we could */
++      /* No need to retry anymore unless we need to osync data */
++      if (ret == 0) {
++              ret = iocb->ki_nbytes - iocb->ki_left;
++              if (!iocb->ki_buf)
++                      return ret;
++
++              /* Set things up for potential O_SYNC */
++              if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++                      iocb->ki_buf = NULL;
++                      iocb->ki_pos -= ret; /* back up fpos */
++                      iocb->ki_left = ret; /* sync what we have written out */
++                      iocb->ki_nbytes = ret;
++                      ret = -EIOCBRETRY;
++              }
++      }
++
++      return ret;
++}
++
++static ssize_t aio_fdsync(struct kiocb *iocb)
++{
++      struct file *file = iocb->ki_filp;
++      ssize_t ret = -EINVAL;
++
++      if (file->f_op->aio_fsync)
++              ret = file->f_op->aio_fsync(iocb, 1);
++      return ret;
++}
++
++static ssize_t aio_fsync(struct kiocb *iocb)
++{
++      struct file *file = iocb->ki_filp;
++      ssize_t ret = -EINVAL;
++
++      if (file->f_op->aio_fsync)
++              ret = file->f_op->aio_fsync(iocb, 0);
++      return ret;
++}
++
++/*
++ * aio_setup_iocb:
++ *    Performs the initial checks and aio retry method
++ *    setup for the kiocb at the time of io submission.
++ */
++ssize_t aio_setup_iocb(struct kiocb *kiocb)
++{
++      struct file *file = kiocb->ki_filp;
++      ssize_t ret = 0;
++
++      switch (kiocb->ki_opcode) {
++      case IOCB_CMD_PREAD:
++              ret = -EBADF;
++              if (unlikely(!(file->f_mode & FMODE_READ)))
++                      break;
++              ret = -EFAULT;
++              if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf,
++                      kiocb->ki_left)))
++                      break;
++              ret = -EINVAL;
++              if (file->f_op->aio_read)
++                      kiocb->ki_retry = aio_pread;
++              break;
++      case IOCB_CMD_PWRITE:
++              ret = -EBADF;
++              if (unlikely(!(file->f_mode & FMODE_WRITE)))
++                      break;
++              ret = -EFAULT;
++              if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf,
++                      kiocb->ki_left)))
++                      break;
++              ret = -EINVAL;
++              if (file->f_op->aio_write)
++                      kiocb->ki_retry = aio_pwrite;
++              break;
++      case IOCB_CMD_FDSYNC:
++              ret = -EINVAL;
++              if (file->f_op->aio_fsync)
++                      kiocb->ki_retry = aio_fdsync;
++              break;
++      case IOCB_CMD_FSYNC:
++              ret = -EINVAL;
++              if (file->f_op->aio_fsync)
++                      kiocb->ki_retry = aio_fsync;
++              break;
++      default:
++              dprintk("EINVAL: io_submit: no operation provided\n");
++              ret = -EINVAL;
++      }
++
++      if (!kiocb->ki_retry)
++              return ret;
++
++      return 0;
++}
++
++/*
++ * aio_wake_function:
++ *    wait queue callback function for aio notification,
++ *    Simply triggers a retry of the operation via kick_iocb.
++ *
++ *    This callback is specified in the wait queue entry in
++ *    a kiocb (current->io_wait points to this wait queue
++ *    entry when an aio operation executes; it is used
++ *    instead of a synchronous wait when an i/o blocking
++ *    condition is encountered during aio).
++ *
++ * Note:
++ * This routine is executed with the wait queue lock held.
++ * Since kick_iocb acquires iocb->ctx->ctx_lock, it nests
++ * the ioctx lock inside the wait queue lock. This is safe
++ * because this callback isn't used for wait queues which
++ * are nested inside ioctx lock (i.e. ctx->wait)
++ */
++int aio_wake_function(wait_queue_t *wait, unsigned mode, int sync)
++{
++      struct kiocb *iocb = container_of(wait, struct kiocb, ki_wait);
++
++      list_del_init(&wait->task_list);
++      kick_iocb(iocb);
++      return 1;
++}
++
+ int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
+                        struct iocb *iocb)
+ {
+       struct kiocb *req;
+       struct file *file;
+       ssize_t ret;
+-      char *buf;
+       /* enforce forwards compatibility on users */
+       if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2 ||
+@@ -1032,52 +1498,31 @@ int io_submit_one(struct kioctx *ctx, st
+       req->ki_user_data = iocb->aio_data;
+       req->ki_pos = iocb->aio_offset;
+-      buf = (char *)(unsigned long)iocb->aio_buf;
++      req->ki_buf = (char *)(unsigned long)iocb->aio_buf;
++      req->ki_left = req->ki_nbytes = iocb->aio_nbytes;
++      req->ki_opcode = iocb->aio_lio_opcode;
++      init_waitqueue_func_entry(&req->ki_wait, aio_wake_function);
++      INIT_LIST_HEAD(&req->ki_wait.task_list);
++      req->ki_run_list.next = req->ki_run_list.prev = NULL;
++      req->ki_retry = NULL;
++      req->ki_retried = 0;
++      req->ki_kicked = 0;
++      req->ki_queued = 0;
++      aio_run = 0;
++      aio_wakeups = 0;
+-      switch (iocb->aio_lio_opcode) {
+-      case IOCB_CMD_PREAD:
+-              ret = -EBADF;
+-              if (unlikely(!(file->f_mode & FMODE_READ)))
+-                      goto out_put_req;
+-              ret = -EFAULT;
+-              if (unlikely(!access_ok(VERIFY_WRITE, buf, iocb->aio_nbytes)))
+-                      goto out_put_req;
+-              ret = -EINVAL;
+-              if (file->f_op->aio_read)
+-                      ret = file->f_op->aio_read(req, buf,
+-                                      iocb->aio_nbytes, req->ki_pos);
+-              break;
+-      case IOCB_CMD_PWRITE:
+-              ret = -EBADF;
+-              if (unlikely(!(file->f_mode & FMODE_WRITE)))
+-                      goto out_put_req;
+-              ret = -EFAULT;
+-              if (unlikely(!access_ok(VERIFY_READ, buf, iocb->aio_nbytes)))
+-                      goto out_put_req;
+-              ret = -EINVAL;
+-              if (file->f_op->aio_write)
+-                      ret = file->f_op->aio_write(req, buf,
+-                                      iocb->aio_nbytes, req->ki_pos);
+-              break;
+-      case IOCB_CMD_FDSYNC:
+-              ret = -EINVAL;
+-              if (file->f_op->aio_fsync)
+-                      ret = file->f_op->aio_fsync(req, 1);
+-              break;
+-      case IOCB_CMD_FSYNC:
+-              ret = -EINVAL;
+-              if (file->f_op->aio_fsync)
+-                      ret = file->f_op->aio_fsync(req, 0);
+-              break;
+-      default:
+-              dprintk("EINVAL: io_submit: no operation provided\n");
+-              ret = -EINVAL;
+-      }
++      ret = aio_setup_iocb(req);
++
++      if (ret)
++              goto out_put_req;
++
++      spin_lock_irq(&ctx->ctx_lock);
++      ret = aio_run_iocb(req);
++      spin_unlock_irq(&ctx->ctx_lock);
++      if (-EIOCBRETRY == ret)
++              queue_work(aio_wq, &ctx->wq);
+       aio_put_req(req);       /* drop extra ref to req */
+-      if (likely(-EIOCBQUEUED == ret))
+-              return 0;
+-      aio_complete(req, ret, 0);      /* will drop i/o ref to req */
+       return 0;
+ out_put_req:
+--- linux-2.6.0/fs/binfmt_elf.c        2003-10-25 14:45:46.000000000 -0700
++++ 25/fs/binfmt_elf.c 2003-12-28 23:22:21.000000000 -0800
+@@ -82,13 +82,17 @@ static struct linux_binfmt elf_format = 
+ #define BAD_ADDR(x)   ((unsigned long)(x) > TASK_SIZE)
+-static void set_brk(unsigned long start, unsigned long end)
++static int set_brk(unsigned long start, unsigned long end)
+ {
+       start = ELF_PAGEALIGN(start);
+       end = ELF_PAGEALIGN(end);
+-      if (end > start)
+-              do_brk(start, end - start);
++      if (end > start) {
++              unsigned long addr = do_brk(start, end - start);
++              if (BAD_ADDR(addr))
++                      return addr;
++      }
+       current->mm->start_brk = current->mm->brk = end;
++      return 0;
+ }
+@@ -381,8 +385,11 @@ static unsigned long load_elf_interp(str
+       elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);   /* What we have mapped so far */
+       /* Map the last of the bss segment */
+-      if (last_bss > elf_bss)
+-              do_brk(elf_bss, last_bss - elf_bss);
++      if (last_bss > elf_bss) {
++              error = do_brk(elf_bss, last_bss - elf_bss);
++              if (BAD_ADDR(error))
++                      goto out_close;
++      }
+       *interp_load_addr = load_addr;
+       error = ((unsigned long) interp_elf_ex->e_entry) + load_addr;
+@@ -466,6 +473,7 @@ static int load_elf_binary(struct linux_
+       struct elfhdr interp_elf_ex;
+       struct exec interp_ex;
+       char passed_fileno[6];
++      struct files_struct *files;
+       
+       /* Get the exec-header */
+       elf_ex = *((struct elfhdr *) bprm->buf);
+@@ -498,9 +506,20 @@ static int load_elf_binary(struct linux_
+       if (retval < 0)
+               goto out_free_ph;
++      files = current->files;         /* Refcounted so ok */
++      if(unshare_files() < 0)
++              goto out_free_ph;
++      if (files == current->files) {
++              put_files_struct(files);
++              files = NULL;
++      }
++
++      /* exec will make our files private anyway, but for the a.out
++         loader stuff we need to do it earlier */
++
+       retval = get_unused_fd();
+       if (retval < 0)
+-              goto out_free_ph;
++              goto out_free_fh;
+       get_file(bprm->file);
+       fd_install(elf_exec_fileno = retval, bprm->file);
+@@ -631,6 +650,13 @@ static int load_elf_binary(struct linux_
+       if (retval)
+               goto out_free_dentry;
++      /* Discard our unneeded old files struct */
++      if (files) {
++              steal_locks(files);
++              put_files_struct(files);
++              files = NULL;
++      }
++
+       /* OK, This is the point of no return */
+       current->mm->start_data = 0;
+       current->mm->end_data = 0;
+@@ -672,7 +698,12 @@ static int load_elf_binary(struct linux_
+                       /* There was a PT_LOAD segment with p_memsz > p_filesz
+                          before this one. Map anonymous pages, if needed,
+                          and clear the area.  */
+-                      set_brk (elf_bss + load_bias, elf_brk + load_bias);
++                      retval = set_brk (elf_bss + load_bias,
++                                        elf_brk + load_bias);
++                      if (retval) {
++                              send_sig(SIGKILL, current, 0);
++                              goto out_free_dentry;
++                      }
+                       nbyte = ELF_PAGEOFFSET(elf_bss);
+                       if (nbyte) {
+                               nbyte = ELF_MIN_ALIGN - nbyte;
+@@ -737,6 +768,18 @@ static int load_elf_binary(struct linux_
+       start_data += load_bias;
+       end_data += load_bias;
++      /* Calling set_brk effectively mmaps the pages that we need
++       * for the bss and break sections.  We must do this before
++       * mapping in the interpreter, to make sure it doesn't wind
++       * up getting placed where the bss needs to go.
++       */
++      retval = set_brk(elf_bss, elf_brk);
++      if (retval) {
++              send_sig(SIGKILL, current, 0);
++              goto out_free_dentry;
++      }
++      padzero(elf_bss);
++
+       if (elf_interpreter) {
+               if (interpreter_type == INTERPRETER_AOUT)
+                       elf_entry = load_aout_interp(&interp_ex,
+@@ -745,19 +788,17 @@ static int load_elf_binary(struct linux_
+                       elf_entry = load_elf_interp(&interp_elf_ex,
+                                                   interpreter,
+                                                   &interp_load_addr);
+-
+-              allow_write_access(interpreter);
+-              fput(interpreter);
+-              kfree(elf_interpreter);
+-
+               if (BAD_ADDR(elf_entry)) {
+                       printk(KERN_ERR "Unable to load interpreter\n");
+-                      kfree(elf_phdata);
+                       send_sig(SIGSEGV, current, 0);
+                       retval = -ENOEXEC; /* Nobody gets to see this, but.. */
+-                      goto out;
++                      goto out_free_dentry;
+               }
+               reloc_func_desc = interp_load_addr;
++
++              allow_write_access(interpreter);
++              fput(interpreter);
++              kfree(elf_interpreter);
+       } else {
+               elf_entry = elf_ex.e_entry;
+       }
+@@ -782,13 +823,6 @@ static int load_elf_binary(struct linux_
+       current->mm->end_data = end_data;
+       current->mm->start_stack = bprm->p;
+-      /* Calling set_brk effectively mmaps the pages that we need
+-       * for the bss and break sections
+-       */
+-      set_brk(elf_bss, elf_brk);
+-
+-      padzero(elf_bss);
+-
+       if (current->personality & MMAP_PAGE_ZERO) {
+               /* Why this, you ask???  Well SVr4 maps page 0 as read-only,
+                  and some applications "depend" upon this behavior.
+@@ -835,6 +869,11 @@ out_free_interp:
+               kfree(elf_interpreter);
+ out_free_file:
+       sys_close(elf_exec_fileno);
++out_free_fh:
++      if (files) {
++              put_files_struct(current->files);
++              current->files = files;
++      }
+ out_free_ph:
+       kfree(elf_phdata);
+       goto out;
+--- linux-2.6.0/fs/binfmt_som.c        2003-06-14 12:18:07.000000000 -0700
++++ 25/fs/binfmt_som.c 2003-12-28 23:21:23.000000000 -0800
+@@ -217,7 +217,7 @@ load_som_binary(struct linux_binprm * bp
+                       (char *) hpuxhdr, size);
+       if (retval < 0)
+               goto out_free;
+-
++#error "Fix security hole before enabling me"
+       retval = get_unused_fd();
+       if (retval < 0)
+               goto out_free;
+--- linux-2.6.0/fs/block_dev.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/block_dev.c  2003-12-28 23:21:22.000000000 -0800
+@@ -25,6 +25,22 @@
+ #include <linux/namei.h>
+ #include <asm/uaccess.h>
++struct bdev_inode {
++      struct block_device bdev;
++      struct inode vfs_inode;
++};
++
++static inline struct bdev_inode *BDEV_I(struct inode *inode)
++{
++      return container_of(inode, struct bdev_inode, vfs_inode);
++}
++
++inline struct block_device *I_BDEV(struct inode *inode)
++{
++      return &BDEV_I(inode)->bdev;
++}
++
++EXPORT_SYMBOL(I_BDEV);
+ static sector_t max_block(struct block_device *bdev)
+ {
+@@ -100,10 +116,10 @@ static int
+ blkdev_get_block(struct inode *inode, sector_t iblock,
+               struct buffer_head *bh, int create)
+ {
+-      if (iblock >= max_block(inode->i_bdev))
++      if (iblock >= max_block(I_BDEV(inode)))
+               return -EIO;
+-      bh->b_bdev = inode->i_bdev;
++      bh->b_bdev = I_BDEV(inode);
+       bh->b_blocknr = iblock;
+       set_buffer_mapped(bh);
+       return 0;
+@@ -113,10 +129,10 @@ static int
+ blkdev_get_blocks(struct inode *inode, sector_t iblock,
+               unsigned long max_blocks, struct buffer_head *bh, int create)
+ {
+-      if ((iblock + max_blocks) > max_block(inode->i_bdev))
++      if ((iblock + max_blocks) > max_block(I_BDEV(inode)))
+               return -EIO;
+-      bh->b_bdev = inode->i_bdev;
++      bh->b_bdev = I_BDEV(inode);
+       bh->b_blocknr = iblock;
+       bh->b_size = max_blocks << inode->i_blkbits;
+       set_buffer_mapped(bh);
+@@ -128,9 +144,9 @@ blkdev_direct_IO(int rw, struct kiocb *i
+                       loff_t offset, unsigned long nr_segs)
+ {
+       struct file *file = iocb->ki_filp;
+-      struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++      struct inode *inode = file->f_mapping->host;
+-      return blockdev_direct_IO(rw, iocb, inode, inode->i_bdev, iov, offset,
++      return blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset,
+                               nr_segs, blkdev_get_blocks, NULL);
+ }
+@@ -161,11 +177,10 @@ static int blkdev_commit_write(struct fi
+  */
+ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
+ {
+-      struct inode *bd_inode;
++      struct inode *bd_inode = file->f_mapping->host;
+       loff_t size;
+       loff_t retval;
+-      bd_inode = file->f_dentry->d_inode->i_bdev->bd_inode;
+       down(&bd_inode->i_sem);
+       size = i_size_read(bd_inode);
+@@ -188,15 +203,13 @@ static loff_t block_llseek(struct file *
+ }
+       
+ /*
+- *    Filp may be NULL when we are called by an msync of a vma
+- *    since the vma has no handle.
++ *    Filp is never NULL; the only case when ->fsync() is called with
++ *    NULL first argument is nfsd_sync_dir() and that's not a directory.
+  */
+  
+ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
+ {
+-      struct inode * inode = dentry->d_inode;
+-
+-      return sync_blockdev(inode->i_bdev);
++      return sync_blockdev(I_BDEV(filp->f_mapping->host));
+ }
+ /*
+@@ -206,16 +219,6 @@ static int block_fsync(struct file *filp
+ static spinlock_t bdev_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+ static kmem_cache_t * bdev_cachep;
+-struct bdev_inode {
+-      struct block_device bdev;
+-      struct inode vfs_inode;
+-};
+-
+-static inline struct bdev_inode *BDEV_I(struct inode *inode)
+-{
+-      return container_of(inode, struct bdev_inode, vfs_inode);
+-}
+-
+ static struct inode *bdev_alloc_inode(struct super_block *sb)
+ {
+       struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, SLAB_KERNEL);
+@@ -387,26 +390,27 @@ void bdput(struct block_device *bdev)
+ EXPORT_SYMBOL(bdput);
+  
+-int bd_acquire(struct inode *inode)
++static struct block_device *bd_acquire(struct inode *inode)
+ {
+       struct block_device *bdev;
+       spin_lock(&bdev_lock);
+-      if (inode->i_bdev && igrab(inode->i_bdev->bd_inode)) {
++      bdev = inode->i_bdev;
++      if (bdev && igrab(bdev->bd_inode)) {
+               spin_unlock(&bdev_lock);
+-              return 0;
++              return bdev;
+       }
+       spin_unlock(&bdev_lock);
+       bdev = bdget(inode->i_rdev);
+-      if (!bdev)
+-              return -ENOMEM;
+-      spin_lock(&bdev_lock);
+-      if (inode->i_bdev)
+-              __bd_forget(inode);
+-      inode->i_bdev = bdev;
+-      inode->i_mapping = bdev->bd_inode->i_mapping;
+-      list_add(&inode->i_devices, &bdev->bd_inodes);
+-      spin_unlock(&bdev_lock);
+-      return 0;
++      if (bdev) {
++              spin_lock(&bdev_lock);
++              if (inode->i_bdev)
++                      __bd_forget(inode);
++              inode->i_bdev = bdev;
++              inode->i_mapping = bdev->bd_inode->i_mapping;
++              list_add(&inode->i_devices, &bdev->bd_inodes);
++              spin_unlock(&bdev_lock);
++      }
++      return bdev;
+ }
+ /* Call when you free inode */
+@@ -531,13 +535,14 @@ static void bd_set_size(struct block_dev
+       bdev->bd_inode->i_blkbits = blksize_bits(bsize);
+ }
+-static int do_open(struct block_device *bdev, struct inode *inode, struct file *file)
++static int do_open(struct block_device *bdev, struct file *file)
+ {
+       struct module *owner = NULL;
+       struct gendisk *disk;
+       int ret = -ENXIO;
+       int part;
++      file->f_mapping = bdev->bd_inode->i_mapping;
+       lock_kernel();
+       disk = get_gendisk(bdev->bd_dev, &part);
+       if (!disk) {
+@@ -554,7 +559,7 @@ static int do_open(struct block_device *
+               if (!part) {
+                       struct backing_dev_info *bdi;
+                       if (disk->fops->open) {
+-                              ret = disk->fops->open(inode, file);
++                              ret = disk->fops->open(bdev, file);
+                               if (ret)
+                                       goto out_first;
+                       }
+@@ -599,7 +604,7 @@ static int do_open(struct block_device *
+               module_put(owner);
+               if (bdev->bd_contains == bdev) {
+                       if (bdev->bd_disk->fops->open) {
+-                              ret = bdev->bd_disk->fops->open(inode, file);
++                              ret = bdev->bd_disk->fops->open(bdev, file);
+                               if (ret)
+                                       goto out;
+                       }
+@@ -647,7 +652,7 @@ int blkdev_get(struct block_device *bdev
+       fake_file.f_dentry = &fake_dentry;
+       fake_dentry.d_inode = bdev->bd_inode;
+-      return do_open(bdev, bdev->bd_inode, &fake_file);
++      return do_open(bdev, &fake_file);
+ }
+ EXPORT_SYMBOL(blkdev_get);
+@@ -665,10 +670,9 @@ int blkdev_open(struct inode * inode, st
+        */
+       filp->f_flags |= O_LARGEFILE;
+-      bd_acquire(inode);
+-      bdev = inode->i_bdev;
++      bdev = bd_acquire(inode);
+-      res = do_open(bdev, inode, filp);
++      res = do_open(bdev, filp);
+       if (res)
+               return res;
+@@ -687,7 +691,6 @@ EXPORT_SYMBOL(blkdev_open);
+ int blkdev_put(struct block_device *bdev, int kind)
+ {
+       int ret = 0;
+-      struct inode *bd_inode = bdev->bd_inode;
+       struct gendisk *disk = bdev->bd_disk;
+       down(&bdev->bd_sem);
+@@ -696,14 +699,14 @@ int blkdev_put(struct block_device *bdev
+               switch (kind) {
+               case BDEV_FILE:
+               case BDEV_FS:
+-                      sync_blockdev(bd_inode->i_bdev);
++                      sync_blockdev(bdev);
+                       break;
+               }
+               kill_bdev(bdev);
+       }
+       if (bdev->bd_contains == bdev) {
+               if (disk->fops->release)
+-                      ret = disk->fops->release(bd_inode, NULL);
++                      ret = disk->fops->release(disk);
+       } else {
+               down(&bdev->bd_contains->bd_sem);
+               bdev->bd_contains->bd_part_count--;
+@@ -734,11 +737,12 @@ int blkdev_put(struct block_device *bdev
+ EXPORT_SYMBOL(blkdev_put);
+-int blkdev_close(struct inode * inode, struct file * filp)
++static int blkdev_close(struct inode * inode, struct file * filp)
+ {
+-      if (inode->i_bdev->bd_holder == filp)
+-              bd_release(inode->i_bdev);
+-      return blkdev_put(inode->i_bdev, BDEV_FILE);
++      struct block_device *bdev = I_BDEV(filp->f_mapping->host);
++      if (bdev->bd_holder == filp)
++              bd_release(bdev);
++      return blkdev_put(bdev, BDEV_FILE);
+ }
+ static ssize_t blkdev_file_write(struct file *file, const char __user *buf,
+@@ -757,6 +761,11 @@ static ssize_t blkdev_file_aio_write(str
+       return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
+ }
++static int block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
++                      unsigned long arg)
++{
++      return blkdev_ioctl(I_BDEV(file->f_mapping->host), file, cmd, arg);
++}
+ struct address_space_operations def_blk_aops = {
+       .readpage       = blkdev_readpage,
+@@ -778,7 +787,7 @@ struct file_operations def_blk_fops = {
+       .aio_write      = blkdev_file_aio_write, 
+       .mmap           = generic_file_mmap,
+       .fsync          = block_fsync,
+-      .ioctl          = blkdev_ioctl,
++      .ioctl          = block_ioctl,
+       .readv          = generic_file_readv,
+       .writev         = generic_file_writev,
+       .sendfile       = generic_file_sendfile,
+@@ -791,7 +800,7 @@ int ioctl_by_bdev(struct block_device *b
+       int res;
+       mm_segment_t old_fs = get_fs();
+       set_fs(KERNEL_DS);
+-      res = blkdev_ioctl(bdev->bd_inode, NULL, cmd, arg);
++      res = blkdev_ioctl(bdev, NULL, cmd, arg);
+       set_fs(old_fs);
+       return res;
+ }
+@@ -828,11 +837,10 @@ struct block_device *lookup_bdev(const c
+       error = -EACCES;
+       if (nd.mnt->mnt_flags & MNT_NODEV)
+               goto fail;
+-      error = bd_acquire(inode);
+-      if (error)
++      error = -ENOMEM;
++      bdev = bd_acquire(inode);
++      if (!bdev)
+               goto fail;
+-      bdev = inode->i_bdev;
+-
+ out:
+       path_release(&nd);
+       return bdev;
+--- linux-2.6.0/fs/buffer.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/buffer.c     2003-12-28 23:26:41.000000000 -0800
+@@ -116,27 +116,50 @@ void unlock_buffer(struct buffer_head *b
+ }
+ /*
+- * Block until a buffer comes unlocked.  This doesn't stop it
++ * Wait until a buffer comes unlocked.  This doesn't stop it
+  * from becoming locked again - you have to lock it yourself
+  * if you want to preserve its state.
++ * If the wait queue parameter specifies an async i/o callback,
++ * then instead of blocking, we just queue up the callback
++ * on the wait queue for async notification when the buffer gets
++ * unlocked.
++ * A NULL wait queue parameter defaults to synchronous behaviour
+  */
+-void __wait_on_buffer(struct buffer_head * bh)
++int __wait_on_buffer_wq(struct buffer_head * bh, wait_queue_t *wait)
+ {
+       wait_queue_head_t *wqh = bh_waitq_head(bh);
+-      DEFINE_WAIT(wait);
++      DEFINE_WAIT(local_wait);
++
++      if (!wait)
++              wait = &local_wait;
+       if (atomic_read(&bh->b_count) == 0 &&
+                       (!bh->b_page || !PageLocked(bh->b_page)))
+               buffer_error();
+       do {
+-              prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
++              prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
+               if (buffer_locked(bh)) {
+                       blk_run_queues();
++                      if (!is_sync_wait(wait)) {
++                              /*
++                               * if we've queued an async wait queue
++                               * callback do not block; just tell the
++                               * caller to return and retry later when
++                               * the callback is notified
++                               */
++                              return -EIOCBRETRY;
++                      }
+                       io_schedule();
+               }
+       } while (buffer_locked(bh));
+-      finish_wait(wqh, &wait);
++      finish_wait(wqh, wait);
++      return 0;
++}
++
++void __wait_on_buffer(struct buffer_head * bh)
++{
++      __wait_on_buffer_wq(bh, NULL);
+ }
+ static void
+@@ -314,8 +337,7 @@ int file_fsync(struct file *filp, struct
+ asmlinkage long sys_fsync(unsigned int fd)
+ {
+       struct file * file;
+-      struct dentry * dentry;
+-      struct inode * inode;
++      struct address_space *mapping;
+       int ret, err;
+       ret = -EBADF;
+@@ -323,8 +345,7 @@ asmlinkage long sys_fsync(unsigned int f
+       if (!file)
+               goto out;
+-      dentry = file->f_dentry;
+-      inode = dentry->d_inode;
++      mapping = file->f_mapping;
+       ret = -EINVAL;
+       if (!file->f_op || !file->f_op->fsync) {
+@@ -333,17 +354,17 @@ asmlinkage long sys_fsync(unsigned int f
+       }
+       /* We need to protect against concurrent writers.. */
+-      down(&inode->i_sem);
++      down(&mapping->host->i_sem);
+       current->flags |= PF_SYNCWRITE;
+-      ret = filemap_fdatawrite(inode->i_mapping);
+-      err = file->f_op->fsync(file, dentry, 0);
++      ret = filemap_fdatawrite(mapping);
++      err = file->f_op->fsync(file, file->f_dentry, 0);
+       if (!ret)
+               ret = err;
+-      err = filemap_fdatawait(inode->i_mapping);
++      err = filemap_fdatawait(mapping);
+       if (!ret)
+               ret = err;
+       current->flags &= ~PF_SYNCWRITE;
+-      up(&inode->i_sem);
++      up(&mapping->host->i_sem);
+ out_putf:
+       fput(file);
+@@ -354,8 +375,7 @@ out:
+ asmlinkage long sys_fdatasync(unsigned int fd)
+ {
+       struct file * file;
+-      struct dentry * dentry;
+-      struct inode * inode;
++      struct address_space *mapping;
+       int ret, err;
+       ret = -EBADF;
+@@ -363,24 +383,23 @@ asmlinkage long sys_fdatasync(unsigned i
+       if (!file)
+               goto out;
+-      dentry = file->f_dentry;
+-      inode = dentry->d_inode;
+-
+       ret = -EINVAL;
+       if (!file->f_op || !file->f_op->fsync)
+               goto out_putf;
+-      down(&inode->i_sem);
++      mapping = file->f_mapping;
++
++      down(&mapping->host->i_sem);
+       current->flags |= PF_SYNCWRITE;
+-      ret = filemap_fdatawrite(inode->i_mapping);
+-      err = file->f_op->fsync(file, dentry, 1);
++      ret = filemap_fdatawrite(mapping);
++      err = file->f_op->fsync(file, file->f_dentry, 1);
+       if (!ret)
+               ret = err;
+-      err = filemap_fdatawait(inode->i_mapping);
++      err = filemap_fdatawait(mapping);
+       if (!ret)
+               ret = err;
+       current->flags &= ~PF_SYNCWRITE;
+-      up(&inode->i_sem);
++      up(&mapping->host->i_sem);
+ out_putf:
+       fput(file);
+@@ -432,6 +451,7 @@ __find_get_block_slow(struct block_devic
+       printk("block=%llu, b_blocknr=%llu\n",
+               (unsigned long long)block, (unsigned long long)bh->b_blocknr);
+       printk("b_state=0x%08lx, b_size=%u\n", bh->b_state, bh->b_size);
++      printk("device blocksize: %d\n", 1 << bd_inode->i_blkbits);
+ out_unlock:
+       spin_unlock(&bd_mapping->private_lock);
+       page_cache_release(page);
+@@ -487,7 +507,7 @@ void invalidate_bdev(struct block_device
+  */
+ static void free_more_memory(void)
+ {
+-      struct zone *zone;
++      struct zone **zones;
+       pg_data_t *pgdat;
+       wakeup_bdflush(1024);
+@@ -495,9 +515,9 @@ static void free_more_memory(void)
+       yield();
+       for_each_pgdat(pgdat) {
+-              zone = pgdat->node_zonelists[GFP_NOFS&GFP_ZONEMASK].zones[0];
+-              if (zone)
+-                      try_to_free_pages(zone, GFP_NOFS, 0);
++              zones = pgdat->node_zonelists[GFP_NOFS&GFP_ZONEMASK].zones;
++              if (*zones)
++                      try_to_free_pages(zones, GFP_NOFS, 0);
+       }
+ }
+@@ -1296,9 +1316,12 @@ void __bforget(struct buffer_head *bh)
+       __brelse(bh);
+ }
+-static struct buffer_head *__bread_slow(struct buffer_head *bh)
++static struct buffer_head *__bread_slow_wq(struct buffer_head *bh,
++              wait_queue_t *wait)
+ {
+-      lock_buffer(bh);
++      if (-EIOCBRETRY == lock_buffer_wq(bh, wait))
++              return ERR_PTR(-EIOCBRETRY);
++
+       if (buffer_uptodate(bh)) {
+               unlock_buffer(bh);
+               return bh;
+@@ -1308,7 +1331,8 @@ static struct buffer_head *__bread_slow(
+               get_bh(bh);
+               bh->b_end_io = end_buffer_read_sync;
+               submit_bh(READ, bh);
+-              wait_on_buffer(bh);
++              if (-EIOCBRETRY == wait_on_buffer_wq(bh, wait))
++                      return ERR_PTR(-EIOCBRETRY);
+               if (buffer_uptodate(bh))
+                       return bh;
+       }
+@@ -1316,6 +1340,11 @@ static struct buffer_head *__bread_slow(
+       return NULL;
+ }
++static inline struct buffer_head *__bread_slow(struct buffer_head *bh)
++{
++      return __bread_slow_wq(bh, NULL);
++}
++
+ /*
+  * Per-cpu buffer LRU implementation.  To reduce the cost of __find_get_block().
+  * The bhs[] array is sorted - newest buffer is at bhs[0].  Buffers have their
+@@ -1503,6 +1532,18 @@ __bread(struct block_device *bdev, secto
+ }
+ EXPORT_SYMBOL(__bread);
++struct buffer_head *
++__bread_wq(struct block_device *bdev, sector_t block, int size,
++      wait_queue_t *wait)
++{
++      struct buffer_head *bh = __getblk(bdev, block, size);
++
++      if (!buffer_uptodate(bh))
++              bh = __bread_slow_wq(bh, wait);
++      return bh;
++}
++EXPORT_SYMBOL(__bread_wq);
++
+ /*
+  * invalidate_bh_lrus() is called rarely - at unmount.  Because it is only for
+  * unmount it only needs to ensure that all buffers from the target device are
+@@ -1980,8 +2021,9 @@ static int __block_prepare_write(struct 
+       /*
+        * If we issued read requests - let them complete.
+        */
+-      while(wait_bh > wait) {
+-              wait_on_buffer(*--wait_bh);
++      while (wait_bh > wait) {
++              if ((err = wait_on_buffer_wq(*--wait_bh, current->io_wait)))
++                      return err;
+               if (!buffer_uptodate(*wait_bh))
+                       return -EIO;
+       }
+@@ -2823,7 +2865,7 @@ drop_buffers(struct page *page, struct b
+               bh = bh->b_this_page;
+       } while (bh != head);
+-      if (!was_uptodate && PageUptodate(page))
++      if (!was_uptodate && PageUptodate(page) && !PageError(page))
+               buffer_error();
+       do {
+@@ -3039,6 +3081,7 @@ void __init buffer_init(void)
+ EXPORT_SYMBOL(__bforget);
+ EXPORT_SYMBOL(__brelse);
+ EXPORT_SYMBOL(__wait_on_buffer);
++EXPORT_SYMBOL(__wait_on_buffer_wq);
+ EXPORT_SYMBOL(block_commit_write);
+ EXPORT_SYMBOL(block_prepare_write);
+ EXPORT_SYMBOL(block_read_full_page);
+--- linux-2.6.0/fs/char_dev.c  2003-11-23 19:03:01.000000000 -0800
++++ 25/fs/char_dev.c   2003-12-28 23:21:42.000000000 -0800
+@@ -434,7 +434,9 @@ void cdev_init(struct cdev *cdev, struct
+ static struct kobject *base_probe(dev_t dev, int *part, void *data)
+ {
+-      request_module("char-major-%d-%d", MAJOR(dev), MINOR(dev));
++      if (request_module("char-major-%d-%d", MAJOR(dev), MINOR(dev)) > 0)
++              /* Make old-style 2.4 aliases work */
++              request_module("char-major-%d", MAJOR(dev));
+       return NULL;
+ }
+--- linux-2.6.0/fs/coda/file.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/coda/file.c  2003-12-28 23:21:18.000000000 -0800
+@@ -89,6 +89,7 @@ coda_file_mmap(struct file *coda_file, s
+       coda_inode = coda_file->f_dentry->d_inode;
+       host_inode = host_file->f_dentry->d_inode;
++      coda_file->f_mapping = host_file->f_mapping;
+       if (coda_inode->i_mapping == &coda_inode->i_data)
+               coda_inode->i_mapping = host_inode->i_mapping;
+--- linux-2.6.0/fs/compat.c    2003-11-23 19:03:01.000000000 -0800
++++ 25/fs/compat.c     2003-12-28 23:21:47.000000000 -0800
+@@ -559,3 +559,96 @@ asmlinkage long compat_sys_fcntl(unsigne
+       return compat_sys_fcntl64(fd, cmd, arg);
+ }
++extern asmlinkage long sys_io_setup(unsigned nr_reqs, aio_context_t *ctx);
++
++asmlinkage long
++compat_sys_io_setup(unsigned nr_reqs, u32 *ctx32p)
++{
++      long ret;
++      aio_context_t ctx64;
++
++      mm_segment_t oldfs = get_fs();
++      if (unlikely(get_user(ctx64, ctx32p)))
++              return -EFAULT;
++
++      set_fs(KERNEL_DS);
++      ret = sys_io_setup(nr_reqs, &ctx64);
++      set_fs(oldfs);
++      /* truncating is ok because it's a user address */
++      if (!ret)
++              ret = put_user((u32) ctx64, ctx32p);
++      return ret;
++}
++
++extern asmlinkage long sys_io_getevents(aio_context_t ctx_id,
++                                        long min_nr,
++                                        long nr,
++                                        struct io_event *events,
++                                        struct timespec *timeout);
++
++asmlinkage long
++compat_sys_io_getevents(aio_context_t ctx_id,
++                               unsigned long min_nr,
++                               unsigned long nr,
++                               struct io_event *events,
++                               struct compat_timespec *timeout)
++{
++      long ret;
++      struct timespec t;
++      struct timespec *ut = NULL;
++
++      ret = -EFAULT;
++      if (unlikely(!access_ok(VERIFY_WRITE, events,
++                              nr * sizeof(struct io_event))))
++              goto out;
++      if (timeout) {
++              if (get_compat_timespec(&t, timeout))
++                      goto out;
++
++              ut = compat_alloc_user_space(sizeof(*ut));
++              if (copy_to_user(ut, &t, sizeof(t)) )
++                      goto out;
++      }
++      ret = sys_io_getevents(ctx_id, min_nr, nr, events, ut);
++out:
++      return ret;
++}
++
++extern asmlinkage long sys_io_submit(aio_context_t, long,
++                              struct iocb __user **);
++
++static inline long
++copy_iocb(long nr, u32 *ptr32, u64 *ptr64)
++{
++      compat_uptr_t uptr;
++      int i;
++
++      for (i = 0; i < nr; ++i) {
++              if (get_user(uptr, ptr32 + i))
++                      return -EFAULT;
++              if (put_user((u64)compat_ptr(uptr), ptr64 + i))
++                      return -EFAULT;
++      }
++      return 0;
++}
++
++#define MAX_AIO_SUBMITS       (PAGE_SIZE/sizeof(struct iocb *))
++
++asmlinkage long
++compat_sys_io_submit(aio_context_t ctx_id, int nr, u32 *iocb)
++{
++      struct iocb **iocb64;
++      long ret;
++
++      if (unlikely(nr < 0))
++              return -EINVAL;
++
++      if (nr > MAX_AIO_SUBMITS)
++              nr = MAX_AIO_SUBMITS;
++
++      iocb64 = compat_alloc_user_space(nr * sizeof(*iocb64));
++      ret = copy_iocb(nr, iocb, (u64 *) iocb64);
++      if (!ret)
++              ret = sys_io_submit(ctx_id, nr, iocb64);
++      return ret;
++}
+--- linux-2.6.0/fs/compat_ioctl.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/compat_ioctl.c       2003-12-28 23:21:48.000000000 -0800
+@@ -63,6 +63,8 @@
+ #include <linux/ctype.h>
+ #include <linux/ioctl32.h>
+ #include <linux/ncp_fs.h>
++#include <linux/i2c.h>
++#include <linux/i2c-dev.h>
+ #include <net/sock.h>          /* siocdevprivate_ioctl */
+ #include <net/bluetooth/bluetooth.h>
+@@ -128,7 +130,7 @@ static int w_long(unsigned int fd, unsig
+       set_fs (KERNEL_DS);
+       err = sys_ioctl(fd, cmd, (unsigned long)&val);
+       set_fs (old_fs);
+-      if (!err && put_user(val, (u32 *)arg))
++      if (!err && put_user(val, (u32 *)compat_ptr(arg)))
+               return -EFAULT;
+       return err;
+ }
+@@ -136,15 +138,16 @@ static int w_long(unsigned int fd, unsig
+ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+ {
+       mm_segment_t old_fs = get_fs();
++      u32 *argptr = compat_ptr(arg);
+       int err;
+       unsigned long val;
+       
+-      if(get_user(val, (u32 *)arg))
++      if(get_user(val, argptr))
+               return -EFAULT;
+       set_fs (KERNEL_DS);
+       err = sys_ioctl(fd, cmd, (unsigned long)&val);
+       set_fs (old_fs);
+-      if (!err && put_user(val, (u32 *)arg))
++      if (!err && put_user(val, argptr))
+               return -EFAULT;
+       return err;
+ }
+@@ -1701,7 +1704,7 @@ static int do_smb_getmountuid(unsigned i
+       set_fs(old_fs);
+       if (err >= 0)
+-              err = put_user(kuid, (compat_pid_t *)arg);
++              err = put_user(kuid, (compat_uid_t *)arg);
+       return err;
+ }
+@@ -2869,6 +2872,105 @@ static int do_usbdevfs_discsignal(unsign
+         return err;
+ }
++
++/*
++ * I2C layer ioctls
++ */
++
++struct i2c_msg32 {
++      u16 addr;
++      u16 flags;
++      u16 len;
++      compat_caddr_t buf;
++};
++
++struct i2c_rdwr_ioctl_data32 {
++      compat_caddr_t msgs; /* struct i2c_msg __user *msgs */
++      u32 nmsgs;
++};
++
++struct i2c_smbus_ioctl_data32 {
++      u8 read_write;
++      u8 command;
++      u32 size;
++      compat_caddr_t data; /* union i2c_smbus_data *data */
++};
++
++static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
++{
++      struct i2c_rdwr_ioctl_data      *tdata;
++      struct i2c_rdwr_ioctl_data32    *udata;
++      struct i2c_msg                  *tmsgs;
++      struct i2c_msg32                *umsgs;
++      compat_caddr_t                  datap;
++      int                             nmsgs, i;
++
++      tdata = compat_alloc_user_space(sizeof(*tdata));
++      if (tdata == NULL)
++              return -ENOMEM;
++      if (verify_area(VERIFY_WRITE, tdata, sizeof(*tdata)))
++              return -EFAULT;
++
++      udata = (struct i2c_rdwr_ioctl_data32 *)compat_ptr(arg);
++      if (verify_area(VERIFY_READ, udata, sizeof(*udata)))
++              return -EFAULT;
++      if (__get_user(nmsgs, &udata->nmsgs) || __put_user(nmsgs, &tdata->nmsgs))
++              return -EFAULT;
++      if (nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
++              return -EINVAL;
++      if (__get_user(datap, &udata->msgs))
++              return -EFAULT;
++      umsgs = (struct i2c_msg32 *)compat_ptr(datap);
++      if (verify_area(VERIFY_READ, umsgs, sizeof(struct i2c_msg) * nmsgs))
++              return -EFAULT;
++
++      tmsgs = compat_alloc_user_space(sizeof(struct i2c_msg) * nmsgs);
++      if (tmsgs == NULL)
++              return -ENOMEM;
++      if (verify_area(VERIFY_WRITE, tmsgs, sizeof(struct i2c_msg) * nmsgs))
++              return -EFAULT;
++      if (__put_user(tmsgs, &tdata->msgs))
++              return -ENOMEM;
++      for (i = 0; i < nmsgs; i++) {
++              if (__copy_in_user(&tmsgs[i].addr,
++                                 &umsgs[i].addr,
++                                 3 * sizeof(u16)))
++                      return -EFAULT;
++              if (__get_user(datap, &umsgs[i].buf) ||
++                  __put_user(compat_ptr(datap), &tmsgs[i].buf))
++                      return -EFAULT;
++      }
++      return sys_ioctl(fd, cmd, (unsigned long)tdata);
++}
++
++static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
++{
++      struct i2c_smbus_ioctl_data     *tdata;
++      struct i2c_smbus_ioctl_data32   *udata;
++      compat_caddr_t                  datap;
++
++      tdata = compat_alloc_user_space(sizeof(*tdata));
++      if (tdata == NULL)
++              return -ENOMEM;
++      if (verify_area(VERIFY_WRITE, tdata, sizeof(*tdata)))
++              return -EFAULT;
++
++      udata = (struct i2c_smbus_ioctl_data32 *)compat_ptr(arg);
++      if (verify_area(VERIFY_READ, udata, sizeof(*udata)))
++              return -EFAULT;
++
++      if (__copy_in_user(&tdata->read_write, &udata->read_write, 2 * sizeof(u8)))
++              return -EFAULT;
++      if (__copy_in_user(&tdata->size, &udata->size, 2 * sizeof(u32)))
++              return -EFAULT;
++      if (__get_user(datap, &udata->data) ||
++          __put_user(compat_ptr(datap), &tdata->data))
++              return -EFAULT;
++
++      return sys_ioctl(fd, cmd, (unsigned long)tdata);
++}
++
++
+ #undef CODE
+ #endif
+@@ -2979,7 +3081,7 @@ HANDLE_IOCTL(VIDIOCSFBUF32, do_video_ioc
+ HANDLE_IOCTL(VIDIOCGFREQ32, do_video_ioctl)
+ HANDLE_IOCTL(VIDIOCSFREQ32, do_video_ioctl)
+ /* One SMB ioctl needs translations. */
+-#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_pid_t)
++#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
+ HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
+ HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl)
+ HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl)
+@@ -3027,5 +3129,10 @@ HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevf
+ HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb)
+ HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
+ HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
++/* i2c */
++HANDLE_IOCTL(I2C_FUNCS, w_long)
++HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
++HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl)
++
+ #undef DECLARES
+ #endif
+--- linux-2.6.0/fs/cramfs/inode.c      2003-11-23 19:03:01.000000000 -0800
++++ 25/fs/cramfs/inode.c       2003-12-28 23:21:22.000000000 -0800
+@@ -112,8 +112,8 @@ static int next_buffer;
+  */
+ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len)
+ {
+-      struct buffer_head * bh_array[BLKS_PER_BUF];
+-      struct buffer_head * read_array[BLKS_PER_BUF];
++      struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
++      struct page *pages[BLKS_PER_BUF];
+       unsigned i, blocknr, buffer, unread;
+       unsigned long devsize;
+       char *data;
+@@ -138,33 +138,36 @@ static void *cramfs_read(struct super_bl
+               return read_buffers[i] + blk_offset;
+       }
+-      devsize = sb->s_bdev->bd_inode->i_size >> 12;
+-      if (!devsize)
+-              devsize = ~0UL;
++      devsize = mapping->host->i_size >> PAGE_CACHE_SHIFT;
+       /* Ok, read in BLKS_PER_BUF pages completely first. */
+       unread = 0;
+       for (i = 0; i < BLKS_PER_BUF; i++) {
+-              struct buffer_head *bh;
++              struct page *page = NULL;
+-              bh = NULL;
+               if (blocknr + i < devsize) {
+-                      bh = sb_getblk(sb, blocknr + i);
+-                      if (!buffer_uptodate(bh))
+-                              read_array[unread++] = bh;
++                      page = read_cache_page(mapping, blocknr + i,
++                              (filler_t *)mapping->a_ops->readpage,
++                              NULL);
++                      /* synchronous error? */
++                      if (IS_ERR(page))
++                              page = NULL;
+               }
+-              bh_array[i] = bh;
++              pages[i] = page;
+       }
+-      if (unread) {
+-              ll_rw_block(READ, unread, read_array);
+-              do {
+-                      unread--;
+-                      wait_on_buffer(read_array[unread]);
+-              } while (unread);
++      for (i = 0; i < BLKS_PER_BUF; i++) {
++              struct page *page = pages[i];
++              if (page) {
++                      wait_on_page_locked(page);
++                      if (!PageUptodate(page)) {
++                              /* asynchronous error */
++                              page_cache_release(page);
++                              pages[i] = NULL;
++                      }
++              }
+       }
+-      /* Ok, copy them to the staging area without sleeping. */
+       buffer = next_buffer;
+       next_buffer = NEXT_BUFFER(buffer);
+       buffer_blocknr[buffer] = blocknr;
+@@ -172,10 +175,11 @@ static void *cramfs_read(struct super_bl
+       data = read_buffers[buffer];
+       for (i = 0; i < BLKS_PER_BUF; i++) {
+-              struct buffer_head * bh = bh_array[i];
+-              if (bh) {
+-                      memcpy(data, bh->b_data, PAGE_CACHE_SIZE);
+-                      brelse(bh);
++              struct page *page = pages[i];
++              if (page) {
++                      memcpy(data, kmap(page), PAGE_CACHE_SIZE);
++                      kunmap(page);
++                      page_cache_release(page);
+               } else
+                       memset(data, 0, PAGE_CACHE_SIZE);
+               data += PAGE_CACHE_SIZE;
+@@ -202,8 +206,6 @@ static int cramfs_fill_super(struct supe
+       sb->s_fs_info = sbi;
+       memset(sbi, 0, sizeof(struct cramfs_sb_info));
+-      sb_set_blocksize(sb, PAGE_CACHE_SIZE);
+-
+       /* Invalidate the read buffers on mount: think disk change.. */
+       down(&read_mutex);
+       for (i = 0; i < READ_BUFFERS; i++)
+--- linux-2.6.0/fs/dcache.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/dcache.c     2003-12-28 23:21:54.000000000 -0800
+@@ -639,24 +639,9 @@ void shrink_dcache_anon(struct hlist_hea
+ /*
+  * This is called from kswapd when we think we need some more memory.
+- *
+- * We don't want the VM to steal _all_ unused dcache.  Because that leads to
+- * the VM stealing all unused inodes, which shoots down recently-used
+- * pagecache.  So what we do is to tell fibs to the VM about how many reapable
+- * objects there are in this cache.   If the number of unused dentries is
+- * less than half of the total dentry count then return zero.  The net effect
+- * is that the number of unused dentries will be, at a minimum, equal to the
+- * number of used ones.
+- *
+- * If unused_ratio is set to 5, the number of unused dentries will not fall
+- * below 5* the number of used ones.
+  */
+ static int shrink_dcache_memory(int nr, unsigned int gfp_mask)
+ {
+-      int nr_used;
+-      int nr_unused;
+-      const int unused_ratio = 1;
+-
+       if (nr) {
+               /*
+                * Nasty deadlock avoidance.
+@@ -672,11 +657,7 @@ static int shrink_dcache_memory(int nr, 
+               if (gfp_mask & __GFP_FS)
+                       prune_dcache(nr);
+       }
+-      nr_unused = dentry_stat.nr_unused;
+-      nr_used = dentry_stat.nr_dentry - nr_unused;
+-      if (nr_unused < nr_used * unused_ratio)
+-              return 0;
+-      return nr_unused - nr_used * unused_ratio;
++      return dentry_stat.nr_unused;
+ }
+ #define NAME_ALLOC_LEN(len)   ((len+16) & ~15)
+--- linux-2.6.0/fs/devfs/base.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/devfs/base.c 2003-12-28 23:21:21.000000000 -0800
+@@ -1955,15 +1955,9 @@ static int devfs_notify_change (struct d
+     return 0;
+ }   /*  End Function devfs_notify_change  */
+-static void devfs_clear_inode (struct inode *inode)
+-{
+-    if ( S_ISBLK (inode->i_mode) ) bdput (inode->i_bdev);
+-}   /*  End Function devfs_clear_inode  */
+-
+ static struct super_operations devfs_sops =
+ { 
+     .drop_inode    = generic_delete_inode,
+-    .clear_inode   = devfs_clear_inode,
+     .statfs        = simple_statfs,
+ };
+@@ -2015,11 +2009,7 @@ static struct inode *_devfs_get_vfs_inod
+       inode->i_rdev = de->u.cdev.dev;
+     }
+     else if ( S_ISBLK (de->mode) )
+-    {
+-      inode->i_rdev = de->u.bdev.dev;
+-      if (bd_acquire (inode) != 0)
+-              PRINTK ("(%d): no block device from bdget()\n",(int)inode->i_ino);
+-    }
++      init_special_inode(inode, de->mode, de->u.bdev.dev);
+     else if ( S_ISFIFO (de->mode) )
+       inode->i_fop = &def_fifo_fops;
+     else if ( S_ISDIR (de->mode) )
+@@ -2118,11 +2108,7 @@ static int devfs_open (struct inode *ino
+     if (de == NULL) return -ENODEV;
+     if ( S_ISDIR (de->mode) ) return 0;
+     file->private_data = de->info;
+-    if ( S_ISBLK (inode->i_mode) )
+-    {
+-      file->f_op = &def_blk_fops;
+-      err = def_blk_fops.open (inode, file); /* Module refcount unchanged */
+-    } else if (S_ISCHR(inode->i_mode)) {
++    if (S_ISCHR(inode->i_mode)) {
+       ops = devfs_get_ops (de);  /*  Now have module refcount  */
+       file->f_op = ops;
+       if (file->f_op)
+--- linux-2.6.0/fs/direct-io.c 2003-11-23 19:03:01.000000000 -0800
++++ 25/fs/direct-io.c  2003-12-28 23:26:38.000000000 -0800
+@@ -52,6 +52,10 @@
+  *
+  * If blkfactor is zero then the user's request was aligned to the filesystem's
+  * blocksize.
++ *
++ * needs_locking is set for regular files on direct-IO-naive filesystems.  It
++ * determines whether we need to do the fancy locking which prevents direct-IO
++ * from being able to read uninitialised disk blocks.
+  */
+ struct dio {
+@@ -59,6 +63,7 @@ struct dio {
+       struct bio *bio;                /* bio under assembly */
+       struct inode *inode;
+       int rw;
++      int needs_locking;              /* doesn't change */
+       unsigned blkbits;               /* doesn't change */
+       unsigned blkfactor;             /* When we're using an alignment which
+                                          is finer than the filesystem's soft
+@@ -204,8 +209,10 @@ static struct page *dio_get_page(struct 
+  */
+ static void dio_complete(struct dio *dio, loff_t offset, ssize_t bytes)
+ {
+-      if (dio->end_io)
++      if (dio->end_io && dio->result)
+               dio->end_io(dio->inode, offset, bytes, dio->map_bh.b_private);
++      if (dio->needs_locking)
++              up_read(&dio->inode->i_alloc_sem);
+ }
+ /*
+@@ -218,8 +225,14 @@ static void finished_one_bio(struct dio 
+               if (dio->is_async) {
+                       dio_complete(dio, dio->block_in_file << dio->blkbits,
+                                       dio->result);
+-                      aio_complete(dio->iocb, dio->result, 0);
+-                      kfree(dio);
++                      /* Complete AIO later if falling back to buffered i/o */
++                      if (dio->result != -ENOTBLK) {
++                              aio_complete(dio->iocb, dio->result, 0);
++                              kfree(dio);
++                      } else {
++                              if (dio->waiter)
++                                      wake_up_process(dio->waiter);
++                      }
+               }
+       }
+ }
+@@ -449,6 +462,7 @@ static int get_more_blocks(struct dio *d
+       unsigned long fs_count; /* Number of filesystem-sized blocks */
+       unsigned long dio_count;/* Number of dio_block-sized blocks */
+       unsigned long blkmask;
++      int beyond_eof = 0;
+       /*
+        * If there was a memory error and we've overwritten all the
+@@ -466,8 +480,19 @@ static int get_more_blocks(struct dio *d
+               if (dio_count & blkmask)        
+                       fs_count++;
++              if (dio->needs_locking) {
++                      if (dio->block_in_file >= (i_size_read(dio->inode) >>
++                                                      dio->blkbits))
++                              beyond_eof = 1;
++              }
++              /*
++               * For writes inside i_size we forbid block creations: only
++               * overwrites are permitted.  We fall back to buffered writes
++               * at a higher level for inside-i_size block-instantiating
++               * writes.
++               */
+               ret = (*dio->get_blocks)(dio->inode, fs_startblk, fs_count,
+-                              map_bh, dio->rw == WRITE);
++                              map_bh, (dio->rw == WRITE) && beyond_eof);
+       }
+       return ret;
+ }
+@@ -774,6 +799,10 @@ do_holes:
+                       if (!buffer_mapped(map_bh)) {
+                               char *kaddr;
++                              /* AKPM: eargh, -ENOTBLK is a hack */
++                              if (dio->rw == WRITE)
++                                      return -ENOTBLK;
++
+                               if (dio->block_in_file >=
+                                       i_size_read(dio->inode)>>blkbits) {
+                                       /* We hit eof */
+@@ -839,23 +868,21 @@ out:
+       return ret;
+ }
++/*
++ * Releases both i_sem and i_alloc_sem
++ */
+ static int
+ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, 
+       const struct iovec *iov, loff_t offset, unsigned long nr_segs, 
+-      unsigned blkbits, get_blocks_t get_blocks, dio_iodone_t end_io)
++      unsigned blkbits, get_blocks_t get_blocks, dio_iodone_t end_io,
++      struct dio *dio)
+ {
+       unsigned long user_addr; 
+       int seg;
+       int ret = 0;
+       int ret2;
+-      struct dio *dio;
+       size_t bytes;
+-      dio = kmalloc(sizeof(*dio), GFP_KERNEL);
+-      if (!dio)
+-              return -ENOMEM;
+-      dio->is_async = !is_sync_kiocb(iocb);
+-
+       dio->bio = NULL;
+       dio->inode = inode;
+       dio->rw = rw;
+@@ -864,7 +891,6 @@ direct_io_worker(int rw, struct kiocb *i
+       dio->start_zero_done = 0;
+       dio->block_in_file = offset >> blkbits;
+       dio->blocks_available = 0;
+-
+       dio->cur_page = NULL;
+       dio->boundary = 0;
+@@ -947,14 +973,51 @@ direct_io_worker(int rw, struct kiocb *i
+               dio_bio_submit(dio);
+       /*
++       * It is possible that, we return short IO due to end of file.
++       * In that case, we need to release all the pages we got hold on.
++       */
++      dio_cleanup(dio);
++
++      /*
++       * All block lookups have been performed. For READ requests
++       * we can let i_sem go now that its achieved its purpose
++       * of protecting us from looking up uninitialized blocks.
++       */
++      if ((rw == READ) && dio->needs_locking)
++              up(&dio->inode->i_sem);
++
++      /*
+        * OK, all BIOs are submitted, so we can decrement bio_count to truly
+        * reflect the number of to-be-processed BIOs.
+        */
+       if (dio->is_async) {
+               if (ret == 0)
+                       ret = dio->result;      /* Bytes written */
++              if (ret == -ENOTBLK) {
++                      /*
++                       * The request will be reissued via buffered I/O
++                       * when we return; Any I/O already issued
++                       * effectively becomes redundant.
++                       */
++                      dio->result = ret;
++                      dio->waiter = current;
++              }
+               finished_one_bio(dio);          /* This can free the dio */
+               blk_run_queues();
++              if (ret == -ENOTBLK) {
++                      /*
++                       * Wait for already issued I/O to drain out and
++                       * release its references to user-space pages
++                       * before returning to fallback on buffered I/O
++                       */
++                      set_current_state(TASK_UNINTERRUPTIBLE);
++                      while (atomic_read(&dio->bio_count)) {
++                              io_schedule();
++                              set_current_state(TASK_UNINTERRUPTIBLE);
++                      }
++                      set_current_state(TASK_RUNNING);
++                      dio->waiter = NULL;
++              }
+       } else {
+               finished_one_bio(dio);
+               ret2 = dio_await_completion(dio);
+@@ -974,6 +1037,9 @@ direct_io_worker(int rw, struct kiocb *i
+                               ret = i_size - offset;
+               }
+               dio_complete(dio, offset, ret);
++              /* We could have also come here on an AIO file extend */
++              if (!is_sync_kiocb(iocb) && (ret != -ENOTBLK))
++                      aio_complete(iocb, ret, 0);
+               kfree(dio);
+       }
+       return ret;
+@@ -981,11 +1047,17 @@ direct_io_worker(int rw, struct kiocb *i
+ /*
+  * This is a library function for use by filesystem drivers.
++ *
++ * For writes to S_ISREG files, we are called under i_sem and return with i_sem
++ * held, even though it is internally dropped.
++ *
++ * For writes to S_ISBLK files, i_sem is not held on entry; it is never taken.
+  */
+ int
+-blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, 
++__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
+       struct block_device *bdev, const struct iovec *iov, loff_t offset, 
+-      unsigned long nr_segs, get_blocks_t get_blocks, dio_iodone_t end_io)
++      unsigned long nr_segs, get_blocks_t get_blocks, dio_iodone_t end_io,
++      int needs_special_locking)
+ {
+       int seg;
+       size_t size;
+@@ -994,6 +1066,9 @@ blockdev_direct_IO(int rw, struct kiocb 
+       unsigned bdev_blkbits = 0;
+       unsigned blocksize_mask = (1 << blkbits) - 1;
+       ssize_t retval = -EINVAL;
++      loff_t end = offset;
++      struct dio *dio;
++      int needs_locking;
+       if (bdev)
+               bdev_blkbits = blksize_bits(bdev_hardsect_size(bdev));
+@@ -1010,6 +1085,7 @@ blockdev_direct_IO(int rw, struct kiocb 
+       for (seg = 0; seg < nr_segs; seg++) {
+               addr = (unsigned long)iov[seg].iov_base;
+               size = iov[seg].iov_len;
++              end += size;
+               if ((addr & blocksize_mask) || (size & blocksize_mask))  {
+                       if (bdev)
+                                blkbits = bdev_blkbits;
+@@ -1019,10 +1095,43 @@ blockdev_direct_IO(int rw, struct kiocb 
+               }
+       }
+-      retval = direct_io_worker(rw, iocb, inode, iov, offset, 
+-                              nr_segs, blkbits, get_blocks, end_io);
++      dio = kmalloc(sizeof(*dio), GFP_KERNEL);
++      retval = -ENOMEM;
++      if (!dio)
++              goto out;
++
++      /*
++       * For regular files,
++       *      readers need to grab i_sem and i_alloc_sem
++       *      writers need to grab i_alloc_sem only (i_sem is already held)
++       */
++      needs_locking = 0;
++      if (S_ISREG(inode->i_mode) && needs_special_locking) {
++              needs_locking = 1;
++              if (rw == READ) {
++                      down(&inode->i_sem);
++                      retval = filemap_write_and_wait(inode->i_mapping);
++                      if (retval) {
++                              up(&inode->i_sem);
++                              kfree(dio);
++                              goto out;
++                      }
++              }
++              down_read(&inode->i_alloc_sem);
++      }
++      dio->needs_locking = needs_locking;
++      /*
++       * For file extending writes updating i_size before data
++       * writeouts complete can expose uninitialized blocks. So
++       * even for AIO, we need to wait for i/o to complete before
++       * returning in this case.
++       */
++      dio->is_async = !is_sync_kiocb(iocb) && !((rw == WRITE) &&
++              (end > i_size_read(inode)));
++
++      retval = direct_io_worker(rw, iocb, inode, iov, offset,
++                              nr_segs, blkbits, get_blocks, end_io, dio);
+ out:
+       return retval;
+ }
+-
+-EXPORT_SYMBOL(blockdev_direct_IO);
++EXPORT_SYMBOL(__blockdev_direct_IO);
+--- linux-2.6.0/fs/dquot.c     2003-11-23 19:03:01.000000000 -0800
++++ 25/fs/dquot.c      2003-12-28 23:22:17.000000000 -0800
+@@ -192,6 +192,8 @@ static struct list_head dquot_hash[NR_DQ
+ struct dqstats dqstats;
++static void dqput(struct dquot *dquot);
++
+ static inline int const hashfn(struct super_block *sb, unsigned int id, int type)
+ {
+       return((((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type)) % NR_DQHASH;
+@@ -339,8 +341,11 @@ restart:
+                       continue;
+               if (!dquot_dirty(dquot))
+                       continue;
++              atomic_inc(&dquot->dq_count);
++              dqstats.lookups++;
+               spin_unlock(&dq_list_lock);
+-              sb->dq_op->sync_dquot(dquot);
++              sb->dq_op->write_dquot(dquot);
++              dqput(dquot);
+               goto restart;
+       }
+       spin_unlock(&dq_list_lock);
+@@ -427,7 +432,7 @@ we_slept:
+       }
+       if (dquot_dirty(dquot)) {
+               spin_unlock(&dq_list_lock);
+-              commit_dqblk(dquot);
++              dquot->dq_sb->dq_op->write_dquot(dquot);
+               goto we_slept;
+       }
+       atomic_dec(&dquot->dq_count);
+@@ -1083,7 +1088,7 @@ struct dquot_operations dquot_operations
+       .free_space     = dquot_free_space,
+       .free_inode     = dquot_free_inode,
+       .transfer       = dquot_transfer,
+-      .sync_dquot     = commit_dqblk
++      .write_dquot    = commit_dqblk
+ };
+ /* Function used by filesystems for initializing the dquot_operations structure */
+@@ -1207,9 +1212,9 @@ int vfs_quota_on(struct super_block *sb,
+       error = -EINVAL;
+       if (!fmt->qf_ops->check_quota_file(sb, type))
+               goto out_file_init;
+-      /* We don't want quota on quota files */
++      /* We don't want quota and atime on quota files (deadlocks possible) */
+       dquot_drop_nolock(inode);
+-      inode->i_flags |= S_NOQUOTA;
++      inode->i_flags |= S_NOQUOTA | S_NOATIME;
+       dqopt->ops[type] = fmt->qf_ops;
+       dqopt->info[type].dqi_format = fmt;
+--- linux-2.6.0/fs/eventpoll.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/eventpoll.c  2003-12-28 23:23:06.000000000 -0800
+@@ -93,6 +93,8 @@
+ #define EPI_SLAB_DEBUG 0
+ #endif /* #if DEBUG_EPI != 0 */
++/* Epoll private bits inside the event mask */
++#define EP_PRIVATE_BITS (EPOLLONESHOT | EPOLLET)
+ /* Maximum number of poll wake up nests we are allowing */
+ #define EP_MAX_POLLWAKE_NESTS 4
+@@ -740,6 +742,7 @@ static int ep_getfd(int *efd, struct ino
+       d_add(dentry, inode);
+       file->f_vfsmnt = mntget(eventpoll_mnt);
+       file->f_dentry = dget(dentry);
++      file->f_mapping = inode->i_mapping;
+       file->f_pos = 0;
+       file->f_flags = O_RDONLY;
+@@ -1305,6 +1308,15 @@ static int ep_poll_callback(wait_queue_t
+       write_lock_irqsave(&ep->lock, flags);
++      /*
++       * If the event mask does not contain any poll(2) event, we consider the
++       * descriptor to be disabled. This condition is likely the effect of the
++       * EPOLLONESHOT bit that disables the descriptor when an event is received,
++       * until the next EPOLL_CTL_MOD will be issued.
++       */
++      if (!(epi->event.events & ~EP_PRIVATE_BITS))
++              goto is_disabled;
++
+       /* If this file is already in the ready list we exit soon */
+       if (EP_IS_LINKED(&epi->rdllink))
+               goto is_linked;
+@@ -1321,6 +1333,7 @@ is_linked:
+       if (waitqueue_active(&ep->poll_wait))
+               pwake++;
++is_disabled:
+       write_unlock_irqrestore(&ep->lock, flags);
+       /* We have to call this outside the lock */
+@@ -1457,6 +1470,8 @@ static int ep_send_events(struct eventpo
+                               eventcnt += eventbuf;
+                               eventbuf = 0;
+                       }
++                      if (epi->event.events & EPOLLONESHOT)
++                              epi->event.events &= EP_PRIVATE_BITS;
+               }
+       }
+--- linux-2.6.0/fs/exec.c      2003-10-17 15:58:04.000000000 -0700
++++ 25/fs/exec.c       2003-12-28 23:22:56.000000000 -0800
+@@ -779,6 +779,7 @@ int flush_old_exec(struct linux_binprm *
+ {
+       char * name;
+       int i, ch, retval;
++      struct files_struct *files;
+       /*
+        * Make sure we have a private signal table and that
+@@ -789,15 +790,26 @@ int flush_old_exec(struct linux_binprm *
+               goto out;
+       /*
++       * Make sure we have private file handles. Ask the
++       * fork helper to do the work for us and the exit
++       * helper to do the cleanup of the old one.
++       */
++      files = current->files;         /* refcounted so safe to hold */
++      retval = unshare_files();
++      if (retval)
++              goto out;
++      /*
+        * Release all of the old mmap stuff
+        */
+       retval = exec_mmap(bprm->mm);
+       if (retval)
+-              goto out;
++              goto mmap_failed;
+       bprm->mm = NULL;                /* We're using it now */
+       /* This is the point of no return */
++      steal_locks(files);
++      put_files_struct(files);
+       current->sas_ss_sp = current->sas_ss_size = 0;
+@@ -830,6 +842,9 @@ int flush_old_exec(struct linux_binprm *
+       return 0;
++mmap_failed:
++      put_files_struct(current->files);
++      current->files = files;
+ out:
+       return retval;
+ }
+@@ -1070,6 +1085,7 @@ int do_execve(char * filename,
+       struct linux_binprm bprm;
+       struct file *file;
+       int retval;
++      int i;
+       sched_balance_exec();
+@@ -1138,7 +1154,11 @@ int do_execve(char * filename,
+ out:
+       /* Something went wrong, return the inode and free the argument pages*/
+-      free_arg_pages(&bprm);
++      for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
++              struct page * page = bprm.page[i];
++              if (page)
++                      __free_page(page);
++      }
+       if (bprm.security)
+               security_bprm_free(&bprm);
+--- linux-2.6.0/fs/ext2/inode.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/ext2/inode.c 2003-12-28 23:26:41.000000000 -0800
+@@ -257,11 +257,12 @@ static int ext2_block_to_path(struct ino
+  *    or when it reads all @depth-1 indirect blocks successfully and finds
+  *    the whole chain, all way to the data (returns %NULL, *err == 0).
+  */
+-static Indirect *ext2_get_branch(struct inode *inode,
++static Indirect *ext2_get_branch_wq(struct inode *inode,
+                                int depth,
+                                int *offsets,
+                                Indirect chain[4],
+-                               int *err)
++                               int *err,
++                               wait_queue_t *wait)
+ {
+       struct super_block *sb = inode->i_sb;
+       Indirect *p = chain;
+@@ -273,8 +274,8 @@ static Indirect *ext2_get_branch(struct 
+       if (!p->key)
+               goto no_block;
+       while (--depth) {
+-              bh = sb_bread(sb, le32_to_cpu(p->key));
+-              if (!bh)
++              bh = sb_bread_wq(sb, le32_to_cpu(p->key), wait);
++              if (!bh || IS_ERR(bh))
+                       goto failure;
+               read_lock(&EXT2_I(inode)->i_meta_lock);
+               if (!verify_chain(chain, p))
+@@ -292,11 +293,21 @@ changed:
+       *err = -EAGAIN;
+       goto no_block;
+ failure:
+-      *err = -EIO;
++      *err = IS_ERR(bh) ? PTR_ERR(bh) : -EIO;
+ no_block:
+       return p;
+ }
++static Indirect *ext2_get_branch(struct inode *inode,
++                               int depth,
++                               int *offsets,
++                               Indirect chain[4],
++                               int *err)
++{
++      return ext2_get_branch_wq(inode, depth, offsets, chain,
++              err, NULL);
++}
++
+ /**
+  *    ext2_find_near - find a place for allocation with sufficient locality
+  *    @inode: owner
+@@ -536,7 +547,8 @@ changed:
+  * reachable from inode.
+  */
+-static int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
++static int ext2_get_block_wq(struct inode *inode, sector_t iblock,
++      struct buffer_head *bh_result, int create, wait_queue_t *wait)
+ {
+       int err = -EIO;
+       int offsets[4];
+@@ -551,7 +563,8 @@ static int ext2_get_block(struct inode *
+               goto out;
+ reread:
+-      partial = ext2_get_branch(inode, depth, offsets, chain, &err);
++      partial = ext2_get_branch_wq(inode, depth, offsets, chain, &err,
++              wait);
+       /* Simplest case - block found, no allocation needed */
+       if (!partial) {
+@@ -565,7 +578,7 @@ got_it:
+       }
+       /* Next simple case - plain lookup or failed read of indirect block */
+-      if (!create || err == -EIO) {
++      if (!create || err == -EIO || err == -EIOCBRETRY) {
+ cleanup:
+               while (partial > chain) {
+                       brelse(partial->bh);
+@@ -606,6 +619,19 @@ changed:
+       goto reread;
+ }
++static int ext2_get_block_async(struct inode *inode, sector_t iblock,
++      struct buffer_head *bh_result, int create)
++{
++      return ext2_get_block_wq(inode, iblock, bh_result, create,
++              current->io_wait);
++}
++
++static int ext2_get_block(struct inode *inode, sector_t iblock,
++      struct buffer_head *bh_result, int create)
++{
++      return ext2_get_block_wq(inode, iblock, bh_result, create, NULL);
++}
++
+ static int ext2_writepage(struct page *page, struct writeback_control *wbc)
+ {
+       return block_write_full_page(page, ext2_get_block, wbc);
+@@ -627,7 +653,7 @@ static int
+ ext2_prepare_write(struct file *file, struct page *page,
+                       unsigned from, unsigned to)
+ {
+-      return block_prepare_write(page,from,to,ext2_get_block);
++      return block_prepare_write(page,from,to,ext2_get_block_async);
+ }
+ static int
+@@ -659,7 +685,7 @@ ext2_direct_IO(int rw, struct kiocb *ioc
+                       loff_t offset, unsigned long nr_segs)
+ {
+       struct file *file = iocb->ki_filp;
+-      struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++      struct inode *inode = file->f_mapping->host;
+       return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+                               offset, nr_segs, ext2_get_blocks, NULL);
+--- linux-2.6.0/fs/ext3/balloc.c       2003-08-22 19:23:42.000000000 -0700
++++ 25/fs/ext3/balloc.c        2003-12-28 23:22:36.000000000 -0800
+@@ -517,7 +517,7 @@ ext3_new_block(handle_t *handle, struct 
+               sbi->s_resuid != current->fsuid &&
+               (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
+               *errp = -ENOSPC;
+-              return 0;
++              goto out;
+       }
+       /*
+--- linux-2.6.0/fs/ext3/inode.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/ext3/inode.c 2003-12-28 23:21:19.000000000 -0800
+@@ -1532,7 +1532,7 @@ static int ext3_direct_IO(int rw, struct
+                       unsigned long nr_segs)
+ {
+       struct file *file = iocb->ki_filp;
+-      struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++      struct inode *inode = file->f_mapping->host;
+       struct ext3_inode_info *ei = EXT3_I(inode);
+       handle_t *handle = NULL;
+       int ret;
+--- linux-2.6.0/fs/ext3/super.c        2003-10-08 15:07:09.000000000 -0700
++++ 25/fs/ext3/super.c 2003-12-28 23:22:17.000000000 -0800
+@@ -340,6 +340,7 @@ fail:
+  */
+ static int ext3_blkdev_put(struct block_device *bdev)
+ {
++      bd_release(bdev);
+       return blkdev_put(bdev, BDEV_FS);
+ }
+@@ -1480,6 +1481,13 @@ static journal_t *ext3_get_dev_journal(s
+       if (bdev == NULL)
+               return NULL;
++      if (bd_claim(bdev, sb)) {
++              printk(KERN_ERR
++                      "EXT3: failed to claim external journal device.\n");
++              blkdev_put(bdev, BDEV_FS);
++              return NULL;
++      }
++
+       blocksize = sb->s_blocksize;
+       hblock = bdev_hardsect_size(bdev);
+       if (blocksize < hblock) {
+@@ -1944,9 +1952,9 @@ int ext3_statfs (struct super_block * sb
+ /* Blocks: quota info + (4 pointer blocks + 1 entry block) * (3 indirect + 1 descriptor + 1 bitmap) + superblock */
+ #define EXT3_V0_QFMT_BLOCKS 27
+-static int (*old_sync_dquot)(struct dquot *dquot);
++static int (*old_write_dquot)(struct dquot *dquot);
+-static int ext3_sync_dquot(struct dquot *dquot)
++static int ext3_write_dquot(struct dquot *dquot)
+ {
+       int nblocks;
+       int ret;
+@@ -1971,7 +1979,7 @@ static int ext3_sync_dquot(struct dquot 
+               ret = PTR_ERR(handle);
+               goto out;
+       }
+-      ret = old_sync_dquot(dquot);
++      ret = old_write_dquot(dquot);
+       err = ext3_journal_stop(handle);
+       if (ret == 0)
+               ret = err;
+@@ -2004,8 +2012,8 @@ static int __init init_ext3_fs(void)
+               goto out1;
+ #ifdef CONFIG_QUOTA
+       init_dquot_operations(&ext3_qops);
+-      old_sync_dquot = ext3_qops.sync_dquot;
+-      ext3_qops.sync_dquot = ext3_sync_dquot;
++      old_write_dquot = ext3_qops.write_dquot;
++      ext3_qops.write_dquot = ext3_write_dquot;
+ #endif
+         err = register_filesystem(&ext3_fs_type);
+       if (err)
+--- linux-2.6.0/fs/fat/file.c  2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/fat/file.c   2003-12-28 23:22:50.000000000 -0800
+@@ -20,6 +20,8 @@ struct file_operations fat_file_operatio
+       .write          = fat_file_write,
+       .mmap           = generic_file_mmap,
+       .fsync          = file_fsync,
++      .readv          = generic_file_readv,
++      .writev         = generic_file_writev,
+       .sendfile       = generic_file_sendfile,
+ };
+--- linux-2.6.0/fs/fat/inode.c 2003-11-23 19:03:01.000000000 -0800
++++ 25/fs/fat/inode.c  2003-12-28 23:22:52.000000000 -0800
+@@ -191,9 +191,9 @@ static int fat_show_options(struct seq_f
+       int isvfat = opts->isvfat;
+       if (opts->fs_uid != 0)
+-              seq_printf(m, ",uid=%d", opts->fs_uid);
++              seq_printf(m, ",uid=%u", opts->fs_uid);
+       if (opts->fs_gid != 0)
+-              seq_printf(m, ",gid=%d", opts->fs_gid);
++              seq_printf(m, ",gid=%u", opts->fs_gid);
+       seq_printf(m, ",fmask=%04o", opts->fs_fmask);
+       seq_printf(m, ",dmask=%04o", opts->fs_dmask);
+       if (sbi->nls_disk)
+@@ -765,8 +765,9 @@ int fat_fill_super(struct super_block *s
+       struct buffer_head *bh;
+       struct fat_boot_sector *b;
+       struct msdos_sb_info *sbi;
+-      int logical_sector_size, fat_clusters, debug, cp, first;
+-      unsigned int total_sectors, rootdir_sectors;
++      u16 logical_sector_size;
++      u32 total_sectors, total_clusters, fat_clusters, rootdir_sectors;
++      int debug, cp, first;
+       unsigned int media;
+       long error;
+       char buf[50];
+@@ -831,14 +832,13 @@ int fat_fill_super(struct super_block *s
+               brelse(bh);
+               goto out_invalid;
+       }
+-      logical_sector_size =
+-              CF_LE_W(get_unaligned((unsigned short *) &b->sector_size));
++      logical_sector_size = CF_LE_W(get_unaligned((u16 *)&b->sector_size));
+       if (!logical_sector_size
+           || (logical_sector_size & (logical_sector_size - 1))
+           || (logical_sector_size < 512)
+           || (PAGE_CACHE_SIZE < logical_sector_size)) {
+               if (!silent)
+-                      printk(KERN_ERR "FAT: bogus logical sector size %d\n",
++                      printk(KERN_ERR "FAT: bogus logical sector size %u\n",
+                              logical_sector_size);
+               brelse(bh);
+               goto out_invalid;
+@@ -847,7 +847,7 @@ int fat_fill_super(struct super_block *s
+       if (!sbi->sec_per_clus
+           || (sbi->sec_per_clus & (sbi->sec_per_clus - 1))) {
+               if (!silent)
+-                      printk(KERN_ERR "FAT: bogus sectors per cluster %d\n",
++                      printk(KERN_ERR "FAT: bogus sectors per cluster %u\n",
+                              sbi->sec_per_clus);
+               brelse(bh);
+               goto out_invalid;
+@@ -855,7 +855,7 @@ int fat_fill_super(struct super_block *s
+       if (logical_sector_size < sb->s_blocksize) {
+               printk(KERN_ERR "FAT: logical sector size too small for device"
+-                     " (logical sector size = %d)\n", logical_sector_size);
++                     " (logical sector size = %u)\n", logical_sector_size);
+               brelse(bh);
+               goto out_fail;
+       }
+@@ -863,7 +863,7 @@ int fat_fill_super(struct super_block *s
+               brelse(bh);
+               if (!sb_set_blocksize(sb, logical_sector_size)) {
+-                      printk(KERN_ERR "FAT: unable to set blocksize %d\n",
++                      printk(KERN_ERR "FAT: unable to set blocksize %u\n",
+                              logical_sector_size);
+                       goto out_fail;
+               }
+@@ -885,7 +885,7 @@ int fat_fill_super(struct super_block *s
+       sbi->fat_length = CF_LE_W(b->fat_length);
+       sbi->root_cluster = 0;
+       sbi->free_clusters = -1;        /* Don't know yet */
+-      sbi->prev_free = 0;
++      sbi->prev_free = -1;
+       if (!sbi->fat_length && b->fat32_length) {
+               struct fat_boot_fsinfo *fsinfo;
+@@ -932,10 +932,11 @@ int fat_fill_super(struct super_block *s
+       sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1;
+       sbi->dir_start = sbi->fat_start + sbi->fats * sbi->fat_length;
+-      sbi->dir_entries =
+-              CF_LE_W(get_unaligned((unsigned short *)&b->dir_entries));
++      sbi->dir_entries = CF_LE_W(get_unaligned((u16 *)&b->dir_entries));
+       if (sbi->dir_entries & (sbi->dir_per_block - 1)) {
+-              printk(KERN_ERR "FAT: bogus directroy-entries per block\n");
++              if (!silent)
++                      printk(KERN_ERR "FAT: bogus directroy-entries per block"
++                             " (%u)\n", sbi->dir_entries);
+               brelse(bh);
+               goto out_invalid;
+       }
+@@ -943,18 +944,27 @@ int fat_fill_super(struct super_block *s
+       rootdir_sectors = sbi->dir_entries
+               * sizeof(struct msdos_dir_entry) / sb->s_blocksize;
+       sbi->data_start = sbi->dir_start + rootdir_sectors;
+-      total_sectors = CF_LE_W(get_unaligned((unsigned short *)&b->sectors));
++      total_sectors = CF_LE_W(get_unaligned((u16 *)&b->sectors));
+       if (total_sectors == 0)
+               total_sectors = CF_LE_L(b->total_sect);
+-      sbi->clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
++
++      total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
+       if (sbi->fat_bits != 32)
+-              sbi->fat_bits = (sbi->clusters > MSDOS_FAT12) ? 16 : 12;
++              sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
+       /* check that FAT table does not overflow */
+       fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
+-      if (sbi->clusters > fat_clusters - 2)
+-              sbi->clusters = fat_clusters - 2;
++      total_clusters = min(total_clusters, fat_clusters - 2);
++      if (total_clusters > MAX_FAT(sb)) {
++              if (!silent)
++                      printk(KERN_ERR "FAT: count of clusters too big (%u)\n",
++                             total_clusters);
++              brelse(bh);
++              goto out_invalid;
++      }
++
++      sbi->clusters = total_clusters;
+       brelse(bh);
+@@ -968,6 +978,8 @@ int fat_fill_super(struct super_block *s
+               /* all is as it should be */
+       } else if (media == 0xf8 && FAT_FIRST_ENT(sb, 0xfe) == first) {
+               /* bad, reported on pc9800 */
++      } else if (media == 0xf0 && FAT_FIRST_ENT(sb, 0xf8) == first) {
++              /* bad, reported with a MO disk on win95/me */
+       } else if (first == 0) {
+               /* bad, reported with a SmartMedia card */
+       } else {
+@@ -1047,7 +1059,7 @@ out_fail:
+ int fat_statfs(struct super_block *sb, struct kstatfs *buf)
+ {
+-      int free, nr;
++      int free, nr, ret;
+        
+       if (MSDOS_SB(sb)->free_clusters != -1)
+               free = MSDOS_SB(sb)->free_clusters;
+@@ -1057,9 +1069,14 @@ int fat_statfs(struct super_block *sb, s
+                       free = MSDOS_SB(sb)->free_clusters;
+               else {
+                       free = 0;
+-                      for (nr = 2; nr < MSDOS_SB(sb)->clusters + 2; nr++)
+-                              if (fat_access(sb, nr, -1) == FAT_ENT_FREE)
++                      for (nr = 2; nr < MSDOS_SB(sb)->clusters + 2; nr++) {
++                              ret = fat_access(sb, nr, -1);
++                              if (ret < 0) {
++                                      unlock_fat(sb);
++                                      return ret;
++                              } else if (ret == FAT_ENT_FREE)
+                                       free++;
++                      }
+                       MSDOS_SB(sb)->free_clusters = free;
+               }
+               unlock_fat(sb);
+@@ -1209,10 +1226,10 @@ retry:
+       }
+       lock_kernel();
+       if (!(bh = sb_bread(sb, i_pos >> MSDOS_SB(sb)->dir_per_block_bits))) {
+-              fat_fs_panic(sb, "unable to read i-node block (i_pos %lld)",
+-                           i_pos);
++              printk(KERN_ERR "FAT: unable to read inode block "
++                     "for updating (i_pos %lld)", i_pos);
+               unlock_kernel();
+-              return;
++              return /* -EIO */;
+       }
+       spin_lock(&fat_inode_lock);
+       if (i_pos != MSDOS_I(inode)->i_pos) {
+--- linux-2.6.0/fs/fat/misc.c  2003-08-08 22:55:13.000000000 -0700
++++ 25/fs/fat/misc.c   2003-12-28 23:22:51.000000000 -0800
+@@ -74,7 +74,7 @@ void fat_clusters_flush(struct super_blo
+       } else {
+               if (sbi->free_clusters != -1)
+                       fsinfo->free_clusters = CF_LE_L(sbi->free_clusters);
+-              if (sbi->prev_free)
++              if (sbi->prev_free != -1)
+                       fsinfo->next_cluster = CF_LE_L(sbi->prev_free);
+               mark_buffer_dirty(bh);
+       }
+@@ -88,7 +88,7 @@ void fat_clusters_flush(struct super_blo
+ int fat_add_cluster(struct inode *inode)
+ {
+       struct super_block *sb = inode->i_sb;
+-      int count, limit, new_dclus, new_fclus, last;
++      int ret, count, limit, new_dclus, new_fclus, last;
+       int cluster_bits = MSDOS_SB(sb)->cluster_bits;
+       
+       /* 
+@@ -123,7 +123,12 @@ int fat_add_cluster(struct inode *inode)
+               new_dclus = new_dclus % limit;
+               if (new_dclus < 2)
+                       new_dclus = 2;
+-              if (fat_access(sb, new_dclus, -1) == FAT_ENT_FREE)
++
++              ret = fat_access(sb, new_dclus, -1);
++              if (ret < 0) {
++                      unlock_fat(sb);
++                      return ret;
++              } else if (ret == FAT_ENT_FREE)
+                       break;
+       }
+       if (count >= MSDOS_SB(sb)->clusters) {
+@@ -131,9 +136,14 @@ int fat_add_cluster(struct inode *inode)
+               unlock_fat(sb);
+               return -ENOSPC;
+       }
+-      MSDOS_SB(sb)->prev_free = new_dclus;
+-      fat_access(sb, new_dclus, FAT_ENT_EOF);
++      ret = fat_access(sb, new_dclus, FAT_ENT_EOF);
++      if (ret < 0) {
++              unlock_fat(sb);
++              return ret;
++      }
++
++      MSDOS_SB(sb)->prev_free = new_dclus;
+       if (MSDOS_SB(sb)->free_clusters != -1)
+               MSDOS_SB(sb)->free_clusters--;
+       fat_clusters_flush(sb);
+@@ -142,7 +152,9 @@ int fat_add_cluster(struct inode *inode)
+       /* add new one to the last of the cluster chain */
+       if (last) {
+-              fat_access(sb, last, new_dclus);
++              ret = fat_access(sb, last, new_dclus);
++              if (ret < 0)
++                      return ret;
+               fat_cache_add(inode, new_fclus, new_dclus);
+       } else {
+               MSDOS_I(inode)->i_start = new_dclus;
+--- linux-2.6.0/fs/fcntl.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/fcntl.c      2003-12-28 23:21:20.000000000 -0800
+@@ -229,8 +229,8 @@ static int setfl(int fd, struct file * f
+                  arg |= O_NONBLOCK;
+       if (arg & O_DIRECT) {
+-              if (!inode->i_mapping || !inode->i_mapping->a_ops ||
+-                      !inode->i_mapping->a_ops->direct_IO)
++              if (!filp->f_mapping || !filp->f_mapping->a_ops ||
++                      !filp->f_mapping->a_ops->direct_IO)
+                               return -EINVAL;
+       }
+--- linux-2.6.0/fs/file_table.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/file_table.c 2003-12-28 23:22:13.000000000 -0800
+@@ -120,6 +120,7 @@ int open_private_file(struct file *filp,
+       filp->f_mode   = (flags+1) & O_ACCMODE;
+       atomic_set(&filp->f_count, 1);
+       filp->f_dentry = dentry;
++      filp->f_mapping = dentry->d_inode->i_mapping;
+       filp->f_uid    = current->fsuid;
+       filp->f_gid    = current->fsgid;
+       filp->f_op     = dentry->d_inode->i_fop;
+@@ -183,9 +184,9 @@ void __fput(struct file *file)
+       fops_put(file->f_op);
+       if (file->f_mode & FMODE_WRITE)
+               put_write_access(inode);
++      file_kill(file);
+       file->f_dentry = NULL;
+       file->f_vfsmnt = NULL;
+-      file_kill(file);
+       file_free(file);
+       dput(dentry);
+       mntput(mnt);
+--- linux-2.6.0/fs/fs-writeback.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/fs-writeback.c       2003-12-28 23:21:20.000000000 -0800
+@@ -514,7 +514,7 @@ EXPORT_SYMBOL(write_inode_now);
+  *    OSYNC_INODE:    the inode itself
+  */
+-int generic_osync_inode(struct inode *inode, int what)
++int generic_osync_inode(struct inode *inode, struct address_space *mapping, int what)
+ {
+       int err = 0;
+       int need_write_inode_now = 0;
+@@ -522,14 +522,14 @@ int generic_osync_inode(struct inode *in
+       current->flags |= PF_SYNCWRITE;
+       if (what & OSYNC_DATA)
+-              err = filemap_fdatawrite(inode->i_mapping);
++              err = filemap_fdatawrite(mapping);
+       if (what & (OSYNC_METADATA|OSYNC_DATA)) {
+-              err2 = sync_mapping_buffers(inode->i_mapping);
++              err2 = sync_mapping_buffers(mapping);
+               if (!err)
+                       err = err2;
+       }
+       if (what & OSYNC_DATA) {
+-              err2 = filemap_fdatawait(inode->i_mapping);
++              err2 = filemap_fdatawait(mapping);
+               if (!err)
+                       err = err2;
+       }
+--- linux-2.6.0/fs/hugetlbfs/inode.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/hugetlbfs/inode.c    2003-12-28 23:26:43.000000000 -0800
+@@ -165,7 +165,7 @@ void truncate_hugepages(struct address_s
+       pagevec_init(&pvec, 0);
+       next = start;
+       while (1) {
+-              if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++              if (!pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+                       if (next == start)
+                               break;
+                       next = start;
+@@ -176,9 +176,6 @@ void truncate_hugepages(struct address_s
+                       struct page *page = pvec.pages[i];
+                       lock_page(page);
+-                      if (page->index > next)
+-                              next = page->index;
+-                      ++next;
+                       truncate_huge_page(page);
+                       unlock_page(page);
+                       hugetlb_put_quota(mapping);
+@@ -194,6 +191,7 @@ static void hugetlbfs_delete_inode(struc
+       hlist_del_init(&inode->i_hash);
+       list_del_init(&inode->i_list);
++      list_del_init(&inode->i_sb_list);
+       inode->i_state |= I_FREEING;
+       inodes_stat.nr_inodes--;
+       spin_unlock(&inode_lock);
+@@ -236,6 +234,7 @@ static void hugetlbfs_forget_inode(struc
+       hlist_del_init(&inode->i_hash);
+ out_truncate:
+       list_del_init(&inode->i_list);
++      list_del_init(&inode->i_sb_list);
+       inode->i_state |= I_FREEING;
+       inodes_stat.nr_inodes--;
+       spin_unlock(&inode_lock);
+@@ -788,6 +787,7 @@ struct file *hugetlb_zero_setup(size_t s
+       inode->i_nlink = 0;
+       file->f_vfsmnt = mntget(hugetlbfs_vfsmount);
+       file->f_dentry = dentry;
++      file->f_mapping = inode->i_mapping;
+       file->f_op = &hugetlbfs_file_operations;
+       file->f_mode = FMODE_WRITE | FMODE_READ;
+       return file;
+--- linux-2.6.0/fs/inode.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/inode.c      2003-12-28 23:26:37.000000000 -0800
+@@ -183,6 +183,7 @@ void inode_init_once(struct inode *inode
+       INIT_LIST_HEAD(&inode->i_dentry);
+       INIT_LIST_HEAD(&inode->i_devices);
+       sema_init(&inode->i_sem, 1);
++      init_rwsem(&inode->i_alloc_sem);
+       INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC);
+       spin_lock_init(&inode->i_data.page_lock);
+       init_MUTEX(&inode->i_data.i_shared_sem);
+@@ -285,7 +286,7 @@ static void dispose_list(struct list_hea
+ /*
+  * Invalidate all inodes for a device.
+  */
+-static int invalidate_list(struct list_head *head, struct super_block * sb, struct list_head * dispose)
++static int invalidate_list(struct list_head *head, struct list_head *dispose)
+ {
+       struct list_head *next;
+       int busy = 0, count = 0;
+@@ -298,13 +299,12 @@ static int invalidate_list(struct list_h
+               next = next->next;
+               if (tmp == head)
+                       break;
+-              inode = list_entry(tmp, struct inode, i_list);
+-              if (inode->i_sb != sb)
+-                      continue;
++              inode = list_entry(tmp, struct inode, i_sb_list);
+               invalidate_inode_buffers(inode);
+               if (!atomic_read(&inode->i_count)) {
+                       hlist_del_init(&inode->i_hash);
+                       list_del(&inode->i_list);
++                      list_del(&inode->i_sb_list);
+                       list_add(&inode->i_list, dispose);
+                       inode->i_state |= I_FREEING;
+                       count++;
+@@ -340,10 +340,7 @@ int invalidate_inodes(struct super_block
+       down(&iprune_sem);
+       spin_lock(&inode_lock);
+-      busy = invalidate_list(&inode_in_use, sb, &throw_away);
+-      busy |= invalidate_list(&inode_unused, sb, &throw_away);
+-      busy |= invalidate_list(&sb->s_dirty, sb, &throw_away);
+-      busy |= invalidate_list(&sb->s_io, sb, &throw_away);
++      busy = invalidate_list(&sb->s_inodes, &throw_away);
+       spin_unlock(&inode_lock);
+       dispose_list(&throw_away);
+@@ -443,6 +440,7 @@ static void prune_icache(int nr_to_scan)
+                               continue;
+               }
+               hlist_del_init(&inode->i_hash);
++              list_del_init(&inode->i_sb_list);
+               list_move(&inode->i_list, &freeable);
+               inode->i_state |= I_FREEING;
+               nr_pruned++;
+@@ -553,6 +551,7 @@ struct inode *new_inode(struct super_blo
+               spin_lock(&inode_lock);
+               inodes_stat.nr_inodes++;
+               list_add(&inode->i_list, &inode_in_use);
++              list_add(&inode->i_sb_list, &sb->s_inodes);
+               inode->i_ino = ++last_ino;
+               inode->i_state = 0;
+               spin_unlock(&inode_lock);
+@@ -601,6 +600,7 @@ static struct inode * get_new_inode(stru
+                       inodes_stat.nr_inodes++;
+                       list_add(&inode->i_list, &inode_in_use);
++                      list_add(&inode->i_sb_list, &sb->s_inodes);
+                       hlist_add_head(&inode->i_hash, head);
+                       inode->i_state = I_LOCK|I_NEW;
+                       spin_unlock(&inode_lock);
+@@ -649,6 +649,7 @@ static struct inode * get_new_inode_fast
+                       inode->i_ino = ino;
+                       inodes_stat.nr_inodes++;
+                       list_add(&inode->i_list, &inode_in_use);
++                      list_add(&inode->i_sb_list, &sb->s_inodes);
+                       hlist_add_head(&inode->i_hash, head);
+                       inode->i_state = I_LOCK|I_NEW;
+                       spin_unlock(&inode_lock);
+@@ -984,6 +985,7 @@ void generic_delete_inode(struct inode *
+       struct super_operations *op = inode->i_sb->s_op;
+       list_del_init(&inode->i_list);
++      list_del_init(&inode->i_sb_list);
+       inode->i_state|=I_FREEING;
+       inodes_stat.nr_inodes--;
+       spin_unlock(&inode_lock);
+@@ -1031,6 +1033,7 @@ static void generic_forget_inode(struct 
+               hlist_del_init(&inode->i_hash);
+       }
+       list_del_init(&inode->i_list);
++      list_del_init(&inode->i_sb_list);
+       inode->i_state|=I_FREEING;
+       inodes_stat.nr_inodes--;
+       spin_unlock(&inode_lock);
+@@ -1221,34 +1224,17 @@ int remove_inode_dquot_ref(struct inode 
+ void remove_dquot_ref(struct super_block *sb, int type)
+ {
+       struct inode *inode;
+-      struct list_head *act_head;
+       LIST_HEAD(tofree_head);
+       if (!sb->dq_op)
+               return; /* nothing to do */
+       spin_lock(&inode_lock); /* This lock is for inodes code */
+       /* We don't have to lock against quota code - test IS_QUOTAINIT is just for speedup... */
+- 
+-      list_for_each(act_head, &inode_in_use) {
+-              inode = list_entry(act_head, struct inode, i_list);
+-              if (inode->i_sb == sb && IS_QUOTAINIT(inode))
+-                      remove_inode_dquot_ref(inode, type, &tofree_head);
+-      }
+-      list_for_each(act_head, &inode_unused) {
+-              inode = list_entry(act_head, struct inode, i_list);
+-              if (inode->i_sb == sb && IS_QUOTAINIT(inode))
+-                      remove_inode_dquot_ref(inode, type, &tofree_head);
+-      }
+-      list_for_each(act_head, &sb->s_dirty) {
+-              inode = list_entry(act_head, struct inode, i_list);
+-              if (IS_QUOTAINIT(inode))
+-                      remove_inode_dquot_ref(inode, type, &tofree_head);
+-      }
+-      list_for_each(act_head, &sb->s_io) {
+-              inode = list_entry(act_head, struct inode, i_list);
++
++      list_for_each_entry(inode, &sb->s_inodes, i_sb_list)
+               if (IS_QUOTAINIT(inode))
+                       remove_inode_dquot_ref(inode, type, &tofree_head);
+-      }
++
+       spin_unlock(&inode_lock);
+       put_dquot_list(&tofree_head);
+--- linux-2.6.0/fs/intermezzo/file.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/intermezzo/file.c    2003-12-28 23:21:18.000000000 -0800
+@@ -336,7 +336,7 @@ static void presto_apply_write_policy(st
+                                 unlock_kernel();
+                                 return; 
+                         }
+-                        error = presto_journal_close(&rec, fset, file,
++                        error = presto_journal_close(&rec, fset, fdata,
+                                                      file->f_dentry,
+                                                      &fdata->fd_version,
+                                                      &new_file_ver);
+--- linux-2.6.0/fs/intermezzo/intermezzo_fs.h  2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/intermezzo/intermezzo_fs.h   2003-12-28 23:21:18.000000000 -0800
+@@ -603,7 +603,7 @@ int presto_journal_rename(struct rec_inf
+ int presto_journal_open(struct rec_info *, struct presto_file_set *,
+                         struct dentry *, struct presto_version *old_ver);
+ int presto_journal_close(struct rec_info *rec, struct presto_file_set *,
+-                         struct file *, struct dentry *,
++                         struct presto_file_data *, struct dentry *,
+                          struct presto_version *old_file_ver,
+                          struct presto_version *new_file_ver);
+ int presto_write_lml_close(struct rec_info *rec,
+--- linux-2.6.0/fs/intermezzo/journal.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/intermezzo/journal.c 2003-12-28 23:21:18.000000000 -0800
+@@ -2103,12 +2103,11 @@ int presto_journal_unlink(struct rec_inf
+ int
+ presto_journal_close(struct rec_info *rec, struct presto_file_set *fset,
+-                     struct file *file, struct dentry *dentry,
++                     struct presto_file_data *fd, struct dentry *dentry,
+                      struct presto_version *old_file_ver,
+                      struct presto_version *new_file_ver)
+ {
+         int opcode = KML_OPCODE_CLOSE;
+-        struct presto_file_data *fd;
+         char *buffer, *path, *logrecord, record[316];
+         struct dentry *root;
+         int error, size, i;
+@@ -2137,7 +2136,6 @@ presto_journal_close(struct rec_info *re
+         root = fset->fset_dentry;
+-        fd = (struct presto_file_data *)file->private_data;
+         if (fd) {
+                 open_ngroups = fd->fd_ngroups;
+                 for (i = 0; i < fd->fd_ngroups; i++)
+--- linux-2.6.0/fs/intermezzo/presto.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/intermezzo/presto.c  2003-12-28 23:21:18.000000000 -0800
+@@ -259,11 +259,8 @@ int lento_cancel_lml(char *path, 
+         if (info->flags & LENTO_FL_WRITE_KML) {
+-                struct file file;
+-                file.private_data = NULL;
+-                file.f_dentry = dentry; 
+                 presto_getversion(&new_ver, dentry->d_inode);
+-                error = presto_journal_close(&rec, fset, &file, dentry, 
++                error = presto_journal_close(&rec, fset, NULL, dentry,
+                                              &new_ver);
+                 if ( error ) {
+                         EXIT; 
+--- linux-2.6.0/fs/intermezzo/vfs.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/intermezzo/vfs.c     2003-12-28 23:21:18.000000000 -0800
+@@ -321,7 +321,7 @@ int presto_do_close(struct presto_file_s
+         }
+         if (fdata->fd_info.flags & LENTO_FL_KML) 
+-                rc = presto_journal_close(&rec, fset, file, file->f_dentry,
++                rc = presto_journal_close(&rec, fset, fdata, file->f_dentry,
+                                           &fdata->fd_version, 
+                                           &fdata->fd_info.remote_version);
+         if (rc) { 
+@@ -431,14 +431,11 @@ int presto_do_setattr(struct presto_file
+         if ( presto_do_kml(info, dentry) ) {
+                 if ((iattr->ia_valid & ATTR_SIZE) && (old_size != inode->i_size)) {
+-                        struct file file;
+                         /* Journal a close whenever we see a potential truncate
+                         * At the receiving end, lento should explicitly remove
+                         * ATTR_SIZE from the list of valid attributes */
+                         presto_getversion(&new_ver, inode);
+-                        file.private_data = NULL;
+-                        file.f_dentry = dentry;
+-                        error = presto_journal_close(&rec, fset, &file, dentry,
++                        error = presto_journal_close(&rec, fset, NULL, dentry,
+                                                      &old_ver, &new_ver);
+                 }
+@@ -2086,7 +2083,9 @@ static struct file *presto_filp_dopen(st
+                 }
+         }
++      /* XXX: where the fuck is ->f_vfsmnt? */
+         f->f_dentry = dentry;
++        f->f_mapping = dentry->d_inode->i_mapping;
+         f->f_pos = 0;
+         //f->f_reada = 0;
+         f->f_op = NULL;
+--- linux-2.6.0/fs/ioctl.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/ioctl.c      2003-12-28 23:21:20.000000000 -0800
+@@ -22,7 +22,7 @@ static int file_ioctl(struct file *filp,
+       switch (cmd) {
+               case FIBMAP:
+               {
+-                      struct address_space *mapping = inode->i_mapping;
++                      struct address_space *mapping = filp->f_mapping;
+                       int res;
+                       /* do we support this mess? */
+                       if (!mapping->a_ops->bmap)
+--- linux-2.6.0/fs/isofs/inode.c       2003-10-08 15:07:09.000000000 -0700
++++ 25/fs/isofs/inode.c        2003-12-28 23:23:02.000000000 -0800
+@@ -447,10 +447,7 @@ static int parse_options(char *options, 
+               case Opt_sb:
+                       if (match_int(&args[0], &option))
+                               return 0;
+-                      n = option;
+-                      if (n > 660 * 512)
+-                              return 0;
+-                      popt->sbsector = n;
++                      popt->sbsector = option;
+                       break;
+               case Opt_check_r:
+                       popt->check = 'r';
+@@ -1463,4 +1460,5 @@ static void __exit exit_iso9660_fs(void)
+ module_init(init_iso9660_fs)
+ module_exit(exit_iso9660_fs)
+ MODULE_LICENSE("GPL");
+-
++/* Actual filesystem name is iso9660, as requested in filesystems.c */
++MODULE_ALIAS("iso9660");
+--- linux-2.6.0/fs/jbd/commit.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/jbd/commit.c 2003-12-28 23:22:22.000000000 -0800
+@@ -177,8 +177,14 @@ void journal_commit_transaction(journal_
+                * leave undo-committed data.
+                */
+               if (jh->b_committed_data) {
+-                      kfree(jh->b_committed_data);
+-                      jh->b_committed_data = NULL;
++                      struct buffer_head *bh = jh2bh(jh);
++
++                      jbd_lock_bh_state(bh);
++                      if (jh->b_committed_data) {
++                              kfree(jh->b_committed_data);
++                              jh->b_committed_data = NULL;
++                      }
++                      jbd_unlock_bh_state(bh);
+               }
+               journal_refile_buffer(journal, jh);
+       }
+@@ -264,6 +270,16 @@ write_out_data_locked:
+                               jbd_unlock_bh_state(bh);
+                               journal_remove_journal_head(bh);
+                               __brelse(bh);
++                              if (need_resched() && commit_transaction->
++                                                      t_sync_datalist) {
++                                      commit_transaction->t_sync_datalist =
++                                                              next_jh;
++                                      if (bufs)
++                                              break;
++                                      spin_unlock(&journal->j_list_lock);
++                                      cond_resched();
++                                      goto write_out_data;
++                              }
+                       }
+               }
+               if (bufs == ARRAY_SIZE(wbuf)) {
+@@ -284,8 +300,7 @@ write_out_data_locked:
+               cond_resched();
+               journal_brelse_array(wbuf, bufs);
+               spin_lock(&journal->j_list_lock);
+-              if (bufs)
+-                      goto write_out_data_locked;
++              goto write_out_data_locked;
+       }
+       /*
+--- linux-2.6.0/fs/jffs/intrep.c       2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/jffs/intrep.c        2003-12-28 23:21:43.000000000 -0800
+@@ -3337,18 +3337,16 @@ jffs_garbage_collect_thread(void *ptr)
+       int result = 0;
+       D1(int i = 1);
++      daemonize("jffs_gcd");
++
+       c->gc_task = current;
+       lock_kernel();
+-      exit_mm(c->gc_task);
+-
+-      set_special_pids(1, 1);
+       init_completion(&c->gc_thread_comp); /* barrier */ 
+       spin_lock_irq(&current->sighand->siglock);
+       siginitsetinv (&current->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));
+       recalc_sigpending();
+       spin_unlock_irq(&current->sighand->siglock);
+-      strcpy(current->comm, "jffs_gcd");
+       D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): Starting infinite loop.\n"));
+--- linux-2.6.0/fs/jfs/inode.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/jfs/inode.c  2003-12-28 23:21:19.000000000 -0800
+@@ -306,7 +306,7 @@ static int jfs_direct_IO(int rw, struct 
+                       loff_t offset, unsigned long nr_segs)
+ {
+       struct file *file = iocb->ki_filp;
+-      struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++      struct inode *inode = file->f_mapping->host;
+       return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+                               offset, nr_segs, jfs_get_blocks, NULL);
+--- linux-2.6.0/fs/jfs/namei.c 2003-11-23 19:03:01.000000000 -0800
++++ 25/fs/jfs/namei.c  2003-12-28 23:22:29.000000000 -0800
+@@ -1439,14 +1439,18 @@ static struct dentry *jfs_lookup(struct 
+ struct dentry *jfs_get_parent(struct dentry *dentry)
+ {
+       struct super_block *sb = dentry->d_inode->i_sb;
+-      struct dentry *parent = ERR_PTR(-EACCES);
++      struct dentry *parent = ERR_PTR(-ENOENT);
+       struct inode *inode;
++      unsigned long parent_ino;
+-      inode = iget(sb, JFS_IP(dentry->d_inode)->i_dtroot.header.idotdot);
++      parent_ino =
++              le32_to_cpu(JFS_IP(dentry->d_inode)->i_dtroot.header.idotdot);
++      inode = iget(sb, parent_ino);
+       if (inode) {
+-              if (is_bad_inode(inode))
++              if (is_bad_inode(inode)) {
+                       iput(inode);
+-              else {
++                      parent = ERR_PTR(-EACCES);
++              } else {
+                       parent = d_alloc_anon(inode);
+                       if (!parent) {
+                               parent = ERR_PTR(-ENOMEM);
+--- linux-2.6.0/fs/Kconfig     2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/Kconfig      2003-12-28 23:21:55.000000000 -0800
+@@ -246,6 +246,7 @@ config REISERFS_PROC_INFO
+ config JFS_FS
+       tristate "JFS filesystem support"
++      select NLS
+       help
+         This is a port of IBM's Journaled Filesystem .  More information is
+         available in the file Documentation/filesystems/jfs.txt.
+@@ -485,6 +486,7 @@ config ISO9660_FS
+ config JOLIET
+       bool "Microsoft Joliet CDROM extensions"
+       depends on ISO9660_FS
++      select NLS
+       help
+         Joliet is a Microsoft extension for the ISO 9660 CD-ROM file system
+         which allows for long filenames in unicode format (unicode is the
+@@ -530,6 +532,7 @@ menu "DOS/FAT/NT Filesystems"
+ config FAT_FS
+       tristate "DOS FAT fs support"
++      select NLS
+       help
+         If you want to use one of the FAT-based file systems (the MS-DOS,
+         VFAT (Windows 95) and UMSDOS (used to run Linux on top of an
+@@ -651,6 +654,7 @@ config UMSDOS_FS
+ config NTFS_FS
+       tristate "NTFS file system support"
++      select NLS
+       help
+         NTFS is the file system of Microsoft Windows NT, 2000, XP and 2003.
+@@ -764,6 +768,30 @@ config PROC_KCORE
+       bool
+       default y if !ARM
++config SYSFS
++      bool "sysfs file system support" if EMBEDDED
++      default y
++      help
++      The sysfs filesystem is a virtual filesystem that the kernel uses to export
++      internal kernel objects, their attributes, and their relationships to one
++      another.
++
++      Users can use sysfs to ascertain useful information about the running kernel,
++      such as the devices the kernel has discovered on each bus and which driver
++      each is bound to. sysfs can also be used to tune devices and other kernel
++      subsystems.
++
++      Some system agents rely on the information in sysfs to operate. /sbin/hotplug
++      uses device and object attributes in sysfs to assist in delegating policy
++      decisions, like persistantly naming devices.
++
++      sysfs is currently needed by the block subsystem to mount the root partition.
++      Therefore, you MUST say Y if you're booting from a hard drive. If you use any
++      type of hotpluggable device, you'll also need sysfs for /sbin/hotplug support.
++
++      However, designers of embedded systems may want to say Y here to conserve
++      space.
++
+ config DEVFS_FS
+       bool "/dev file system support (OBSOLETE)"
+       depends on EXPERIMENTAL
+@@ -962,6 +990,7 @@ config HFS_FS
+ config BEFS_FS
+       tristate "BeOS file systemv(BeFS) support (read only) (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
++      select NLS
+       help
+         The BeOS File System (BeFS) is the native file system of Be, Inc's
+         BeOS. Notable features include support for arbitrary attributes
+@@ -1440,6 +1469,7 @@ config RPCSEC_GSS_KRB5
+ config SMB_FS
+       tristate "SMB file system support (to mount Windows shares etc.)"
+       depends on INET
++      select NLS
+       help
+         SMB (Server Message Block) is the protocol Windows for Workgroups
+         (WfW), Windows 95/98, Windows NT and OS/2 Lan Manager use to share
+@@ -1495,6 +1525,7 @@ config SMB_NLS_REMOTE
+ config CIFS
+       tristate "CIFS support (advanced network filesystem for Samba, Window and other CIFS compliant servers)(EXPERIMENTAL)"
+       depends on INET
++      select NLS
+       help
+         This is the client VFS module for the Common Internet File System
+         (CIFS) protocol which is the successor to the Server Message Block 
+--- linux-2.6.0/fs/Kconfig.binfmt      2003-11-23 19:03:01.000000000 -0800
++++ 25/fs/Kconfig.binfmt       2003-12-28 23:22:18.000000000 -0800
+@@ -23,10 +23,6 @@ config BINFMT_ELF
+         ld.so (check the file <file:Documentation/Changes> for location and
+         latest version).
+-        To compile this as a module, choose M here: the module will be called
+-        binfmt_elf. Saying M or N here is dangerous because some crucial
+-        programs on your system might be in ELF format.
+-
+ config BINFMT_FLAT
+       tristate "Kernel support for flat binaries"
+       depends on !MMU || SUPERH
+--- linux-2.6.0/fs/locks.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/locks.c      2003-12-28 23:21:24.000000000 -0800
+@@ -1454,7 +1454,7 @@ int fcntl_setlk(struct file *filp, unsig
+        */
+       if (IS_MANDLOCK(inode) &&
+           (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) {
+-              struct address_space *mapping = inode->i_mapping;
++              struct address_space *mapping = filp->f_mapping;
+               if (!list_empty(&mapping->i_mmap_shared)) {
+                       error = -EAGAIN;
+@@ -1592,7 +1592,7 @@ int fcntl_setlk64(struct file *filp, uns
+        */
+       if (IS_MANDLOCK(inode) &&
+           (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) {
+-              struct address_space *mapping = inode->i_mapping;
++              struct address_space *mapping = filp->f_mapping;
+               if (!list_empty(&mapping->i_mmap_shared)) {
+                       error = -EAGAIN;
+@@ -1983,6 +1983,24 @@ int lock_may_write(struct inode *inode, 
+ EXPORT_SYMBOL(lock_may_write);
++void steal_locks(fl_owner_t from)
++{
++      struct list_head *tmp;
++
++      if (from == current->files)
++              return;
++
++      lock_kernel();
++      list_for_each(tmp, &file_lock_list) {
++              struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
++              if (fl->fl_owner == from)
++                      fl->fl_owner = current->files;
++      }
++      unlock_kernel();
++}
++
++EXPORT_SYMBOL(steal_locks);
++
+ static int __init filelock_init(void)
+ {
+       filelock_cache = kmem_cache_create("file_lock_cache",
+--- linux-2.6.0/fs/Makefile    2003-08-22 19:23:42.000000000 -0700
++++ 25/fs/Makefile     2003-12-28 23:21:50.000000000 -0800
+@@ -39,7 +39,7 @@ obj-$(CONFIG_QUOTACTL)               += quota.o
+ obj-$(CONFIG_PROC_FS)         += proc/
+ obj-y                         += partitions/
+-obj-y                         += sysfs/
++obj-$(CONFIG_SYSFS)           += sysfs/
+ obj-y                         += devpts/
+ obj-$(CONFIG_PROFILING)               += dcookies.o
+--- linux-2.6.0/fs/msdos/namei.c       2003-07-27 12:14:40.000000000 -0700
++++ 25/fs/msdos/namei.c        2003-12-28 23:22:52.000000000 -0800
+@@ -244,13 +244,14 @@ static int msdos_add_entry(struct inode 
+        */
+       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+       mark_inode_dirty(dir);
+-      memcpy((*de)->name,name,MSDOS_NAME);
++
++      memcpy((*de)->name, name, MSDOS_NAME);
+       (*de)->attr = is_dir ? ATTR_DIR : ATTR_ARCH;
+       if (is_hid)
+               (*de)->attr |= ATTR_HIDDEN;
+       (*de)->start = 0;
+       (*de)->starthi = 0;
+-      fat_date_unix2dos(dir->i_mtime.tv_sec,&(*de)->time,&(*de)->date);
++      fat_date_unix2dos(dir->i_mtime.tv_sec, &(*de)->time, &(*de)->date);
+       (*de)->size = 0;
+       mark_buffer_dirty(*bh);
+       return 0;
+@@ -393,7 +394,6 @@ out_unlock:
+       return res;
+ mkdir_error:
+-      printk(KERN_WARNING "msdos_mkdir: error=%d, attempting cleanup\n", res);
+       inode->i_nlink = 0;
+       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+       dir->i_nlink--;
+@@ -468,13 +468,9 @@ static int do_msdos_rename(struct inode 
+                       if (error)
+                               goto out;
+               }
+-              error = fat_scan(old_inode, MSDOS_DOTDOT, &dotdot_bh,
+-                              &dotdot_de, &dotdot_i_pos);
+-              if (error < 0) {
+-                      printk(KERN_WARNING
+-                              "MSDOS: %s/%s, get dotdot failed, ret=%d\n",
+-                              old_dentry->d_parent->d_name.name,
+-                              old_dentry->d_name.name, error);
++              if (fat_scan(old_inode, MSDOS_DOTDOT, &dotdot_bh,
++                           &dotdot_de, &dotdot_i_pos) < 0) {
++                      error = -EIO;
+                       goto out;
+               }
+       }
+--- linux-2.6.0/fs/namespace.c 2003-10-08 15:07:09.000000000 -0700
++++ 25/fs/namespace.c  2003-12-28 23:21:50.000000000 -0800
+@@ -24,7 +24,15 @@
+ #include <asm/uaccess.h>
+ extern int __init init_rootfs(void);
++
++#ifdef CONFIG_SYSFS
+ extern int __init sysfs_init(void);
++#else
++static inline int sysfs_init(void)
++{
++      return 0;
++}
++#endif
+ /* spinlock for vfsmount related operations, inplace of dcache_lock */
+ spinlock_t vfsmount_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+--- linux-2.6.0/fs/ncpfs/Kconfig       2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/ncpfs/Kconfig        2003-12-28 23:21:55.000000000 -0800
+@@ -65,6 +65,7 @@ config NCPFS_SMALLDOS
+ config NCPFS_NLS
+       bool "Use Native Language Support"
+       depends on NCP_FS
++      select NLS
+       help
+         Allows you to use codepages and I/O charsets for file name
+         translation between the server file system and input/output. This
+--- linux-2.6.0/fs/ncpfs/mmap.c        2003-06-14 12:18:25.000000000 -0700
++++ 25/fs/ncpfs/mmap.c 2003-12-28 23:22:12.000000000 -0800
+@@ -26,7 +26,7 @@
+  * Fill in the supplied page for mmap
+  */
+ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area,
+-                                   unsigned long address, int write_access)
++                                   unsigned long address, int *type)
+ {
+       struct file *file = area->vm_file;
+       struct dentry *dentry = file->f_dentry;
+@@ -85,6 +85,15 @@ static struct page* ncp_file_mmap_nopage
+               memset(pg_addr + already_read, 0, PAGE_SIZE - already_read);
+       flush_dcache_page(page);
+       kunmap(page);
++
++      /*
++       * If I understand ncp_read_kernel() properly, the above always
++       * fetches from the network, here the analogue of disk.
++       * -- wli
++       */
++      if (type)
++              *type = VM_FAULT_MAJOR;
++      inc_page_state(pgmajfault);
+       return page;
+ }
+--- linux-2.6.0/fs/nfs/file.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/nfs/file.c   2003-12-28 23:21:20.000000000 -0800
+@@ -266,7 +266,7 @@ out_swapfile:
+ int
+ nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
+ {
+-      struct inode * inode = filp->f_dentry->d_inode;
++      struct inode * inode = filp->f_mapping->host;
+       int     status = 0;
+       int     status2;
+@@ -309,13 +309,13 @@ nfs_lock(struct file *filp, int cmd, str
+        * Flush all pending writes before doing anything
+        * with locks..
+        */
+-      status = filemap_fdatawrite(inode->i_mapping);
++      status = filemap_fdatawrite(filp->f_mapping);
+       down(&inode->i_sem);
+       status2 = nfs_wb_all(inode);
+       if (!status)
+               status = status2;
+       up(&inode->i_sem);
+-      status2 = filemap_fdatawait(inode->i_mapping);
++      status2 = filemap_fdatawait(filp->f_mapping);
+       if (!status)
+               status = status2;
+       if (status < 0)
+@@ -335,11 +335,11 @@ nfs_lock(struct file *filp, int cmd, str
+        */
+  out_ok:
+       if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
+-              filemap_fdatawrite(inode->i_mapping);
++              filemap_fdatawrite(filp->f_mapping);
+               down(&inode->i_sem);
+               nfs_wb_all(inode);      /* we may have slept */
+               up(&inode->i_sem);
+-              filemap_fdatawait(inode->i_mapping);
++              filemap_fdatawait(filp->f_mapping);
+               nfs_zap_caches(inode);
+       }
+       return status;
+--- linux-2.6.0/fs/nls/Kconfig 2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/nls/Kconfig  2003-12-28 23:21:55.000000000 -0800
+@@ -1,24 +1,25 @@
+ #
+ # Native language support configuration
+ #
+-# smb wants NLS
+-config SMB_NLS
+-      bool
+-      depends on SMB_FS
+-      default y
+-# msdos and Joliet want NLS
++menu "Native Language Support"
++
+ config NLS
+-      bool
+-      depends on JOLIET || FAT_FS || NTFS_FS || NCPFS_NLS || SMB_NLS || JFS_FS || CIFS || BEFS_FS
+-      default y
++      tristate "Base native language support"
++      ---help---
++        The base Native Language Support. A number of filesystems
++        depend on it (e.g. FAT, JOLIET, NT, BEOS filesystems), as well
++        as the ability of some filesystems to use native languages
++        (NCP, SMB).
++        If unsure, say Y.
+-menu "Native Language Support"
+-      depends on NLS
++        To compile this code as a module, choose M here: the module
++        will be called nls_base.
+ config NLS_DEFAULT
+       string "Default NLS Option"
++      depends on NLS
+       default "iso8859-1"
+       ---help---
+         The default NLS used when mounting file system. Note, that this is
+@@ -38,6 +39,7 @@ config NLS_DEFAULT
+ config NLS_CODEPAGE_437
+       tristate "Codepage 437 (United States, Canada)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored
+@@ -50,6 +52,7 @@ config NLS_CODEPAGE_437
+ config NLS_CODEPAGE_737
+       tristate "Codepage 737 (Greek)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored
+@@ -62,6 +65,7 @@ config NLS_CODEPAGE_737
+ config NLS_CODEPAGE_775
+       tristate "Codepage 775 (Baltic Rim)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored
+@@ -75,6 +79,7 @@ config NLS_CODEPAGE_775
+ config NLS_CODEPAGE_850
+       tristate "Codepage 850 (Europe)"
++      depends on NLS
+       ---help---
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -91,6 +96,7 @@ config NLS_CODEPAGE_850
+ config NLS_CODEPAGE_852
+       tristate "Codepage 852 (Central/Eastern Europe)"
++      depends on NLS
+       ---help---
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -106,6 +112,7 @@ config NLS_CODEPAGE_852
+ config NLS_CODEPAGE_855
+       tristate "Codepage 855 (Cyrillic)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -117,6 +124,7 @@ config NLS_CODEPAGE_855
+ config NLS_CODEPAGE_857
+       tristate "Codepage 857 (Turkish)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -128,6 +136,7 @@ config NLS_CODEPAGE_857
+ config NLS_CODEPAGE_860
+       tristate "Codepage 860 (Portuguese)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -139,6 +148,7 @@ config NLS_CODEPAGE_860
+ config NLS_CODEPAGE_861
+       tristate "Codepage 861 (Icelandic)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -150,6 +160,7 @@ config NLS_CODEPAGE_861
+ config NLS_CODEPAGE_862
+       tristate "Codepage 862 (Hebrew)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -161,6 +172,7 @@ config NLS_CODEPAGE_862
+ config NLS_CODEPAGE_863
+       tristate "Codepage 863 (Canadian French)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -173,6 +185,7 @@ config NLS_CODEPAGE_863
+ config NLS_CODEPAGE_864
+       tristate "Codepage 864 (Arabic)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -184,6 +197,7 @@ config NLS_CODEPAGE_864
+ config NLS_CODEPAGE_865
+       tristate "Codepage 865 (Norwegian, Danish)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -196,6 +210,7 @@ config NLS_CODEPAGE_865
+ config NLS_CODEPAGE_866
+       tristate "Codepage 866 (Cyrillic/Russian)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -208,6 +223,7 @@ config NLS_CODEPAGE_866
+ config NLS_CODEPAGE_869
+       tristate "Codepage 869 (Greek)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -219,6 +235,7 @@ config NLS_CODEPAGE_869
+ config NLS_CODEPAGE_936
+       tristate "Simplified Chinese charset (CP936, GB2312)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -231,6 +248,7 @@ config NLS_CODEPAGE_936
+ config NLS_CODEPAGE_950
+       tristate "Traditional Chinese charset (Big5)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -243,6 +261,7 @@ config NLS_CODEPAGE_950
+ config NLS_CODEPAGE_932
+       tristate "Japanese charsets (Shift-JIS, EUC-JP)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -256,6 +275,7 @@ config NLS_CODEPAGE_932
+ config NLS_CODEPAGE_949
+       tristate "Korean charset (CP949, EUC-KR)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -267,6 +287,7 @@ config NLS_CODEPAGE_949
+ config NLS_CODEPAGE_874
+       tristate "Thai charset (CP874, TIS-620)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -278,6 +299,7 @@ config NLS_CODEPAGE_874
+ config NLS_ISO8859_8
+       tristate "Hebrew charsets (ISO-8859-8, CP1255)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -287,6 +309,7 @@ config NLS_ISO8859_8
+ config NLS_CODEPAGE_1250
+       tristate "Windows CP1250 (Slavic/Central European Languages)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CDROMs
+@@ -298,6 +321,7 @@ config NLS_CODEPAGE_1250
+ config NLS_CODEPAGE_1251
+       tristate "Windows CP1251 (Bulgarian, Belarusian)"
++      depends on NLS
+       help
+         The Microsoft FAT file system family can deal with filenames in
+         native language character sets. These character sets are stored in
+@@ -310,6 +334,7 @@ config NLS_CODEPAGE_1251
+ config NLS_ISO8859_1
+       tristate "NLS ISO 8859-1  (Latin 1; Western European Languages)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -322,6 +347,7 @@ config NLS_ISO8859_1
+ config NLS_ISO8859_2
+       tristate "NLS ISO 8859-2  (Latin 2; Slavic/Central European Languages)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -333,6 +359,7 @@ config NLS_ISO8859_2
+ config NLS_ISO8859_3
+       tristate "NLS ISO 8859-3  (Latin 3; Esperanto, Galician, Maltese, Turkish)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -343,6 +370,7 @@ config NLS_ISO8859_3
+ config NLS_ISO8859_4
+       tristate "NLS ISO 8859-4  (Latin 4; old Baltic charset)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -353,6 +381,7 @@ config NLS_ISO8859_4
+ config NLS_ISO8859_5
+       tristate "NLS ISO 8859-5  (Cyrillic)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -364,6 +393,7 @@ config NLS_ISO8859_5
+ config NLS_ISO8859_6
+       tristate "NLS ISO 8859-6  (Arabic)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -373,6 +403,7 @@ config NLS_ISO8859_6
+ config NLS_ISO8859_7
+       tristate "NLS ISO 8859-7  (Modern Greek)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -382,6 +413,7 @@ config NLS_ISO8859_7
+ config NLS_ISO8859_9
+       tristate "NLS ISO 8859-9  (Latin 5; Turkish)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -392,6 +424,7 @@ config NLS_ISO8859_9
+ config NLS_ISO8859_13
+       tristate "NLS ISO 8859-13 (Latin 7; Baltic)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -402,6 +435,7 @@ config NLS_ISO8859_13
+ config NLS_ISO8859_14
+       tristate "NLS ISO 8859-14 (Latin 8; Celtic)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -413,6 +447,7 @@ config NLS_ISO8859_14
+ config NLS_ISO8859_15
+       tristate "NLS ISO 8859-15 (Latin 9; Western European Languages with Euro)"
++      depends on NLS
+       ---help---
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -429,6 +464,7 @@ config NLS_ISO8859_15
+ config NLS_KOI8_R
+       tristate "NLS KOI8-R (Russian)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -438,6 +474,7 @@ config NLS_KOI8_R
+ config NLS_KOI8_U
+       tristate "NLS KOI8-U/RU (Ukrainian, Belarusian)"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+@@ -447,6 +484,7 @@ config NLS_KOI8_U
+ config NLS_UTF8
+       tristate "NLS UTF8"
++      depends on NLS
+       help
+         If you want to display filenames with native language characters
+         from the Microsoft FAT file system family or from JOLIET CD-ROMs
+--- linux-2.6.0/fs/nls/nls_base.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/nls/nls_base.c       2003-12-28 23:22:50.000000000 -0800
+@@ -99,6 +99,7 @@ utf8_mbstowcs(wchar_t *pwcs, const __u8 
+                       }
+               } else {
+                       *op++ = *ip++;
++                      n--;
+               }
+       }
+       return (op - pwcs);
+@@ -480,7 +481,7 @@ struct nls_table *load_nls_default(void)
+       if (default_nls != NULL)
+               return default_nls;
+       else
+-               return &default_table;
++              return &default_table;
+ }
+ EXPORT_SYMBOL(register_nls);
+@@ -492,3 +493,5 @@ EXPORT_SYMBOL(utf8_mbtowc);
+ EXPORT_SYMBOL(utf8_mbstowcs);
+ EXPORT_SYMBOL(utf8_wctomb);
+ EXPORT_SYMBOL(utf8_wcstombs);
++
++MODULE_LICENSE("Dual BSD/GPL");
+--- linux-2.6.0/fs/open.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/open.c       2003-12-28 23:26:37.000000000 -0800
+@@ -192,7 +192,9 @@ int do_truncate(struct dentry *dentry, l
+       newattrs.ia_size = length;
+       newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+       down(&dentry->d_inode->i_sem);
++      down_write(&dentry->d_inode->i_alloc_sem);
+       err = notify_change(dentry, &newattrs);
++      up_write(&dentry->d_inode->i_alloc_sem);
+       up(&dentry->d_inode->i_sem);
+       return err;
+ }
+@@ -776,7 +778,8 @@ struct file *dentry_open(struct dentry *
+                       goto cleanup_file;
+       }
+-      file_ra_state_init(&f->f_ra, inode->i_mapping);
++      f->f_mapping = inode->i_mapping;
++      file_ra_state_init(&f->f_ra, f->f_mapping);
+       f->f_dentry = dentry;
+       f->f_vfsmnt = mnt;
+       f->f_pos = 0;
+@@ -792,8 +795,8 @@ struct file *dentry_open(struct dentry *
+       /* NB: we're sure to have correct a_ops only after f_op->open */
+       if (f->f_flags & O_DIRECT) {
+-              if (!inode->i_mapping || !inode->i_mapping->a_ops ||
+-                      !inode->i_mapping->a_ops->direct_IO) {
++              if (!f->f_mapping || !f->f_mapping->a_ops ||
++                      !f->f_mapping->a_ops->direct_IO) {
+                               fput(f);
+                               f = ERR_PTR(-EINVAL);
+               }
+--- linux-2.6.0/fs/pipe.c      2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/pipe.c       2003-12-28 23:22:03.000000000 -0800
+@@ -13,6 +13,7 @@
+ #include <linux/fs.h>
+ #include <linux/mount.h>
+ #include <linux/pipe_fs_i.h>
++#include <linux/uio.h>
+ #include <asm/uaccess.h>
+ #include <asm/ioctls.h>
+@@ -43,19 +44,63 @@ void pipe_wait(struct inode * inode)
+       down(PIPE_SEM(*inode));
+ }
++static inline int
++pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len)
++{
++      unsigned long copy;
++
++      while (len > 0) {
++              while (!iov->iov_len)
++                      iov++;
++              copy = min_t(unsigned long, len, iov->iov_len);
++
++              if (copy_from_user(to, iov->iov_base, copy))
++                      return -EFAULT;
++              to += copy;
++              len -= copy;
++              iov->iov_base += copy;
++              iov->iov_len -= copy;
++      }
++      return 0;
++}
++
++static inline int
++pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len)
++{
++      unsigned long copy;
++
++      while (len > 0) {
++              while (!iov->iov_len)
++                      iov++;
++              copy = min_t(unsigned long, len, iov->iov_len);
++
++              if (copy_to_user(iov->iov_base, from, copy))
++                      return -EFAULT;
++              from += copy;
++              len -= copy;
++              iov->iov_base += copy;
++              iov->iov_len -= copy;
++      }
++      return 0;
++}
++
+ static ssize_t
+-pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
++pipe_readv(struct file *filp, const struct iovec *_iov,
++         unsigned long nr_segs, loff_t *ppos)
+ {
+       struct inode *inode = filp->f_dentry->d_inode;
+       int do_wakeup;
+       ssize_t ret;
++      struct iovec *iov = (struct iovec *)_iov;
++      size_t total_len;
+       /* pread is not allowed on pipes. */
+       if (unlikely(ppos != &filp->f_pos))
+               return -ESPIPE;
+-      
++
++      total_len = iov_length(iov, nr_segs);
+       /* Null read succeeds. */
+-      if (unlikely(count == 0))
++      if (unlikely(total_len == 0))
+               return 0;
+       do_wakeup = 0;
+@@ -67,12 +112,12 @@ pipe_read(struct file *filp, char __user
+                       char *pipebuf = PIPE_BASE(*inode) + PIPE_START(*inode);
+                       ssize_t chars = PIPE_MAX_RCHUNK(*inode);
+-                      if (chars > count)
+-                              chars = count;
++                      if (chars > total_len)
++                              chars = total_len;
+                       if (chars > size)
+                               chars = size;
+-                      if (copy_to_user(buf, pipebuf, chars)) {
++                      if (pipe_iov_copy_to_user(iov, pipebuf, chars)) {
+                               if (!ret) ret = -EFAULT;
+                               break;
+                       }
+@@ -81,12 +126,11 @@ pipe_read(struct file *filp, char __user
+                       PIPE_START(*inode) += chars;
+                       PIPE_START(*inode) &= (PIPE_SIZE - 1);
+                       PIPE_LEN(*inode) -= chars;
+-                      count -= chars;
+-                      buf += chars;
++                      total_len -= chars;
+                       do_wakeup = 1;
++                      if (!total_len)
++                              break;  /* common path: read succeeded */
+               }
+-              if (!count)
+-                      break;  /* common path: read succeeded */
+               if (PIPE_LEN(*inode)) /* test for cyclic buffers */
+                       continue;
+               if (!PIPE_WRITERS(*inode))
+@@ -126,24 +170,35 @@ pipe_read(struct file *filp, char __user
+ }
+ static ssize_t
+-pipe_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
++pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
++{
++      struct iovec iov = { .iov_base = buf, .iov_len = count };
++      return pipe_readv(filp, &iov, 1, ppos);
++}
++
++static ssize_t
++pipe_writev(struct file *filp, const struct iovec *_iov,
++          unsigned long nr_segs, loff_t *ppos)
+ {
+       struct inode *inode = filp->f_dentry->d_inode;
+       ssize_t ret;
+       size_t min;
+       int do_wakeup;
++      struct iovec *iov = (struct iovec *)_iov;
++      size_t total_len;
+       /* pwrite is not allowed on pipes. */
+       if (unlikely(ppos != &filp->f_pos))
+               return -ESPIPE;
+-      
++
++      total_len = iov_length(iov, nr_segs);
+       /* Null write succeeds. */
+-      if (unlikely(count == 0))
++      if (unlikely(total_len == 0))
+               return 0;
+       do_wakeup = 0;
+       ret = 0;
+-      min = count;
++      min = total_len;
+       if (min > PIPE_BUF)
+               min = 1;
+       down(PIPE_SEM(*inode));
+@@ -164,23 +219,22 @@ pipe_write(struct file *filp, const char
+                        * syscall merging.
+                        */
+                       do_wakeup = 1;
+-                      if (chars > count)
+-                              chars = count;
++                      if (chars > total_len)
++                              chars = total_len;
+                       if (chars > free)
+                               chars = free;
+-                      if (copy_from_user(pipebuf, buf, chars)) {
++                      if (pipe_iov_copy_from_user(pipebuf, iov, chars)) {
+                               if (!ret) ret = -EFAULT;
+                               break;
+                       }
+-
+                       ret += chars;
++
+                       PIPE_LEN(*inode) += chars;
+-                      count -= chars;
+-                      buf += chars;
++                      total_len -= chars;
++                      if (!total_len)
++                              break;
+               }
+-              if (!count)
+-                      break;
+               if (PIPE_FREE(*inode) && ret) {
+                       /* handle cyclic data buffers */
+                       min = 1;
+@@ -214,6 +268,14 @@ pipe_write(struct file *filp, const char
+ }
+ static ssize_t
++pipe_write(struct file *filp, const char __user *buf,
++         size_t count, loff_t *ppos)
++{
++      struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count };
++      return pipe_writev(filp, &iov, 1, ppos);
++}
++
++static ssize_t
+ bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
+ {
+       return -EBADF;
+@@ -405,6 +467,7 @@ pipe_rdwr_open(struct inode *inode, stru
+ struct file_operations read_fifo_fops = {
+       .llseek         = no_llseek,
+       .read           = pipe_read,
++      .readv          = pipe_readv,
+       .write          = bad_pipe_w,
+       .poll           = fifo_poll,
+       .ioctl          = pipe_ioctl,
+@@ -417,6 +480,7 @@ struct file_operations write_fifo_fops =
+       .llseek         = no_llseek,
+       .read           = bad_pipe_r,
+       .write          = pipe_write,
++      .writev         = pipe_writev,
+       .poll           = fifo_poll,
+       .ioctl          = pipe_ioctl,
+       .open           = pipe_write_open,
+@@ -427,7 +491,9 @@ struct file_operations write_fifo_fops =
+ struct file_operations rdwr_fifo_fops = {
+       .llseek         = no_llseek,
+       .read           = pipe_read,
++      .readv          = pipe_readv,
+       .write          = pipe_write,
++      .writev         = pipe_writev,
+       .poll           = fifo_poll,
+       .ioctl          = pipe_ioctl,
+       .open           = pipe_rdwr_open,
+@@ -438,6 +504,7 @@ struct file_operations rdwr_fifo_fops = 
+ struct file_operations read_pipe_fops = {
+       .llseek         = no_llseek,
+       .read           = pipe_read,
++      .readv          = pipe_readv,
+       .write          = bad_pipe_w,
+       .poll           = pipe_poll,
+       .ioctl          = pipe_ioctl,
+@@ -450,6 +517,7 @@ struct file_operations write_pipe_fops =
+       .llseek         = no_llseek,
+       .read           = bad_pipe_r,
+       .write          = pipe_write,
++      .writev         = pipe_writev,
+       .poll           = pipe_poll,
+       .ioctl          = pipe_ioctl,
+       .open           = pipe_write_open,
+@@ -460,7 +528,9 @@ struct file_operations write_pipe_fops =
+ struct file_operations rdwr_pipe_fops = {
+       .llseek         = no_llseek,
+       .read           = pipe_read,
++      .readv          = pipe_readv,
+       .write          = pipe_write,
++      .writev         = pipe_writev,
+       .poll           = pipe_poll,
+       .ioctl          = pipe_ioctl,
+       .open           = pipe_rdwr_open,
+@@ -580,6 +650,7 @@ int do_pipe(int *fd)
+       d_add(dentry, inode);
+       f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt));
+       f1->f_dentry = f2->f_dentry = dget(dentry);
++      f1->f_mapping = f2->f_mapping = inode->i_mapping;
+       /* read file */
+       f1->f_pos = f2->f_pos = 0;
+--- linux-2.6.0/fs/proc/base.c 2003-12-17 21:20:02.000000000 -0800
++++ 25/fs/proc/base.c  2003-12-28 23:21:55.000000000 -0800
+@@ -277,15 +277,50 @@ static int proc_root_link(struct inode *
+       return result;
+ }
++#define MAY_PTRACE(task) \
++      (task == current || \
++      (task->parent == current && \
++      (task->ptrace & PT_PTRACED) &&  task->state == TASK_STOPPED && \
++       security_ptrace(current,task) == 0))
++
++static int may_ptrace_attach(struct task_struct *task)
++{
++      int retval = 0;
++
++      task_lock(task);
++
++      if (!task->mm)
++              goto out;
++      if (((current->uid != task->euid) ||
++           (current->uid != task->suid) ||
++           (current->uid != task->uid) ||
++           (current->gid != task->egid) ||
++           (current->gid != task->sgid) ||
++           (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
++              goto out;
++      rmb();
++      if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
++              goto out;
++      if (security_ptrace(current, task))
++              goto out;
++
++      retval = 1;
++out:
++      task_unlock(task);
++      return retval;
++}
++
+ static int proc_pid_environ(struct task_struct *task, char * buffer)
+ {
+       int res = 0;
+       struct mm_struct *mm = get_task_mm(task);
+       if (mm) {
+-              int len = mm->env_end - mm->env_start;
++              unsigned int len = mm->env_end - mm->env_start;
+               if (len > PAGE_SIZE)
+                       len = PAGE_SIZE;
+               res = access_process_vm(task, mm->env_start, buffer, len, 0);
++              if (!may_ptrace_attach(task))
++                      res = -ESRCH;
+               mmput(mm);
+       }
+       return res;
+@@ -294,7 +329,7 @@ static int proc_pid_environ(struct task_
+ static int proc_pid_cmdline(struct task_struct *task, char * buffer)
+ {
+       int res = 0;
+-      int len;
++      unsigned int len;
+       struct mm_struct *mm = get_task_mm(task);
+       if (!mm)
+               goto out;
+@@ -521,10 +556,6 @@ static struct file_operations proc_info_
+       .read           = proc_info_read,
+ };
+-#define MAY_PTRACE(p) \
+-(p==current||(p->parent==current&&(p->ptrace & PT_PTRACED)&&p->state==TASK_STOPPED&&security_ptrace(current,p)==0))
+-
+-
+ static int mem_open(struct inode* inode, struct file* file)
+ {
+       file->private_data = (void*)((long)current->self_exec_id);
+@@ -540,7 +571,7 @@ static ssize_t mem_read(struct file * fi
+       int ret = -ESRCH;
+       struct mm_struct *mm;
+-      if (!MAY_PTRACE(task))
++      if (!MAY_PTRACE(task) || !may_ptrace_attach(task))
+               goto out;
+       ret = -ENOMEM;
+@@ -566,7 +597,7 @@ static ssize_t mem_read(struct file * fi
+               this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
+               retval = access_process_vm(task, src, page, this_len, 0);
+-              if (!retval) {
++              if (!retval || !MAY_PTRACE(task) || !may_ptrace_attach(task)) {
+                       if (!ret)
+                               ret = -EIO;
+                       break;
+@@ -604,7 +635,7 @@ static ssize_t mem_write(struct file * f
+       struct task_struct *task = proc_task(file->f_dentry->d_inode);
+       unsigned long dst = *ppos;
+-      if (!MAY_PTRACE(task))
++      if (!MAY_PTRACE(task) || !may_ptrace_attach(task))
+               return -ESRCH;
+       page = (char *)__get_free_page(GFP_USER);
+@@ -1524,6 +1555,7 @@ struct dentry *proc_pid_lookup(struct in
+       struct inode *inode;
+       struct proc_inode *ei;
+       unsigned tgid;
++      int died;
+       if (dentry->d_name.len == 4 && !memcmp(dentry->d_name.name,"self",4)) {
+               inode = new_inode(dir->i_sb);
+@@ -1567,12 +1599,21 @@ struct dentry *proc_pid_lookup(struct in
+       dentry->d_op = &pid_base_dentry_operations;
++      died = 0;
++      d_add(dentry, inode);
+       spin_lock(&task->proc_lock);
+       task->proc_dentry = dentry;
+-      d_add(dentry, inode);
++      if (!pid_alive(task)) {
++              dentry = proc_pid_unhash(task);
++              died = 1;
++      }
+       spin_unlock(&task->proc_lock);
+       put_task_struct(task);
++      if (died) {
++              proc_pid_flush(dentry);
++              goto out;
++      }
+       return NULL;
+ out:
+       return ERR_PTR(-ENOENT);
+@@ -1612,10 +1653,7 @@ static struct dentry *proc_task_lookup(s
+       dentry->d_op = &pid_base_dentry_operations;
+-      spin_lock(&task->proc_lock);
+-      task->proc_dentry = dentry;
+       d_add(dentry, inode);
+-      spin_unlock(&task->proc_lock);
+       put_task_struct(task);
+       return NULL;
+--- linux-2.6.0/fs/proc/generic.c      2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/proc/generic.c       2003-12-28 23:21:25.000000000 -0800
+@@ -567,12 +567,12 @@ struct proc_dir_entry *proc_symlink(cons
+       return ent;
+ }
+-struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent)
++struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode,
++              struct proc_dir_entry *parent)
+ {
+       struct proc_dir_entry *ent;
+-      ent = proc_create(&parent,name,
+-                        (S_IFDIR | S_IRUGO | S_IXUGO),2);
++      ent = proc_create(&parent, name, S_IFDIR | mode, 2);
+       if (ent) {
+               ent->proc_fops = &proc_dir_operations;
+               ent->proc_iops = &proc_dir_inode_operations;
+@@ -585,6 +585,12 @@ struct proc_dir_entry *proc_mkdir(const 
+       return ent;
+ }
++struct proc_dir_entry *proc_mkdir(const char *name,
++              struct proc_dir_entry *parent)
++{
++      return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
++}
++
+ struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
+                                        struct proc_dir_entry *parent)
+ {
+--- linux-2.6.0/fs/proc/proc_misc.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/proc/proc_misc.c     2003-12-28 23:26:33.000000000 -0800
+@@ -473,30 +473,46 @@ static int devices_read_proc(char *page,
+       return proc_calc_metrics(page, start, off, count, eof, len);
+ }
+-extern int show_interrupts(struct seq_file *p, void *v);
+-static int interrupts_open(struct inode *inode, struct file *file)
++/*
++ * /proc/interrupts
++ */
++static void *int_seq_start(struct seq_file *f, loff_t *pos)
++{
++      return (*pos <= NR_IRQS) ? pos : NULL;
++}
++
++static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
++{
++      (*pos)++;
++      if (*pos > NR_IRQS)
++              return NULL;
++      return pos;
++}
++
++static void int_seq_stop(struct seq_file *f, void *v)
+ {
+-      unsigned size = 4096 * (1 + num_online_cpus() / 8);
+-      char *buf = kmalloc(size, GFP_KERNEL);
+-      struct seq_file *m;
+-      int res;
+-
+-      if (!buf)
+-              return -ENOMEM;
+-      res = single_open(file, show_interrupts, NULL);
+-      if (!res) {
+-              m = file->private_data;
+-              m->buf = buf;
+-              m->size = size;
+-      } else
+-              kfree(buf);
+-      return res;
++      /* Nothing to do */
+ }
++
++
++extern int show_interrupts(struct seq_file *f, void *v); /* In arch code */
++static struct seq_operations int_seq_ops = {
++      .start = int_seq_start,
++      .next  = int_seq_next,
++      .stop  = int_seq_stop,
++      .show  = show_interrupts
++};
++
++int interrupts_open(struct inode *inode, struct file *filp)
++{
++      return seq_open(filp, &int_seq_ops);
++}
++
+ static struct file_operations proc_interrupts_operations = {
+       .open           = interrupts_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+-      .release        = single_release,
++      .release        = seq_release,
+ };
+ static int filesystems_read_proc(char *page, char **start, off_t off,
+@@ -638,6 +654,36 @@ static void create_seq_entry(char *name,
+               entry->proc_fops = f;
+ }
++#ifdef CONFIG_LOCKMETER
++extern ssize_t get_lockmeter_info(char *, size_t, loff_t *);
++extern ssize_t put_lockmeter_info(const char *, size_t);
++extern int get_lockmeter_info_size(void);
++
++/*
++ * This function accesses lock metering information.
++ */
++static ssize_t read_lockmeter(struct file *file, char *buf,
++                            size_t count, loff_t *ppos)
++{
++      return get_lockmeter_info(buf, count, ppos);
++}
++
++/*
++ * Writing to /proc/lockmeter resets the counters
++ */
++static ssize_t write_lockmeter(struct file * file, const char * buf,
++                             size_t count, loff_t *ppos)
++{
++      return put_lockmeter_info(buf, count);
++}
++
++static struct file_operations proc_lockmeter_operations = {
++      NULL,           /* lseek */
++      read:           read_lockmeter,
++      write:          write_lockmeter,
++};
++#endif  /* CONFIG_LOCKMETER */
++
+ void __init proc_misc_init(void)
+ {
+       struct proc_dir_entry *entry;
+@@ -705,6 +751,13 @@ void __init proc_misc_init(void)
+       if (entry)
+               entry->proc_fops = &proc_sysrq_trigger_operations;
+ #endif
++#ifdef CONFIG_LOCKMETER
++      entry = create_proc_entry("lockmeter", S_IWUSR | S_IRUGO, NULL);
++      if (entry) {
++              entry->proc_fops = &proc_lockmeter_operations;
++              entry->size = get_lockmeter_info_size();
++      }
++#endif
+ #ifdef CONFIG_PPC32
+       {
+               extern struct file_operations ppc_htab_operations;
+--- linux-2.6.0/fs/proc/proc_tty.c     2003-11-26 13:53:35.000000000 -0800
++++ 25/fs/proc/proc_tty.c      2003-12-28 23:21:25.000000000 -0800
+@@ -229,7 +229,13 @@ void __init proc_tty_init(void)
+       if (!proc_mkdir("tty", 0))
+               return;
+       proc_tty_ldisc = proc_mkdir("tty/ldisc", 0);
+-      proc_tty_driver = proc_mkdir("tty/driver", 0);
++      /*
++       * /proc/tty/driver/serial reveals the exact character counts for
++       * serial links which is just too easy to abuse for inferring
++       * password lengths and inter-keystroke timings during password
++       * entry.
++       */
++      proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR | S_IXUSR, 0);
+       create_proc_read_entry("tty/ldiscs", 0, 0, tty_ldiscs_read_proc,NULL);
+       entry = create_proc_entry("tty/drivers", 0, NULL);
+--- linux-2.6.0/fs/proc/task_mmu.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/proc/task_mmu.c      2003-12-28 23:22:48.000000000 -0800
+@@ -1,6 +1,7 @@
+ #include <linux/mm.h>
+ #include <linux/hugetlb.h>
+ #include <linux/seq_file.h>
++#include <asm/elf.h>
+ #include <asm/uaccess.h>
+ char *task_mem(struct mm_struct *mm, char *buffer)
+@@ -75,6 +76,22 @@ int task_statm(struct mm_struct *mm, int
+       return size;
+ }
++#ifdef AT_SYSINFO_EHDR
++
++static struct vm_area_struct gate_vmarea = {
++      /* Do _not_ mark this area as readable, cuz not the entire range may be readable
++         (e.g., due to execute-only pages or holes) and the tools that read
++         /proc/PID/maps should read the interesting bits from the gate-DSO file
++         instead.  */
++      .vm_start = FIXADDR_USER_START,
++      .vm_end = FIXADDR_USER_END
++};
++
++# define gate_map()   &gate_vmarea
++#else
++# define gate_map()   NULL
++#endif
++
+ static int show_map(struct seq_file *m, void *v)
+ {
+       struct vm_area_struct *map = v;
+@@ -105,7 +122,7 @@ static int show_map(struct seq_file *m, 
+               if (len < 1)
+                       len = 1;
+               seq_printf(m, "%*c", len, ' ');
+-              seq_path(m, file->f_vfsmnt, file->f_dentry, " \t\n\\");
++              seq_path(m, file->f_vfsmnt, file->f_dentry, "");
+       }
+       seq_putc(m, '\n');
+       return 0;
+@@ -128,6 +145,8 @@ static void *m_start(struct seq_file *m,
+       if (!map) {
+               up_read(&mm->mmap_sem);
+               mmput(mm);
++              if (l == -1)
++                      map = gate_map();
+       }
+       return map;
+ }
+@@ -135,7 +154,7 @@ static void *m_start(struct seq_file *m,
+ static void m_stop(struct seq_file *m, void *v)
+ {
+       struct vm_area_struct *map = v;
+-      if (map) {
++      if (map && map != gate_map()) {
+               struct mm_struct *mm = map->vm_mm;
+               up_read(&mm->mmap_sem);
+               mmput(mm);
+@@ -149,6 +168,8 @@ static void *m_next(struct seq_file *m, 
+       if (map->vm_next)
+               return map->vm_next;
+       m_stop(m, v);
++      if (map != gate_map())
++              return gate_map();
+       return NULL;
+ }
+--- linux-2.6.0/fs/read_write.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/read_write.c 2003-12-28 23:21:19.000000000 -0800
+@@ -28,7 +28,7 @@ EXPORT_SYMBOL(generic_ro_fops);
+ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
+ {
+       long long retval;
+-      struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++      struct inode *inode = file->f_mapping->host;
+       down(&inode->i_sem);
+       switch (origin) {
+--- linux-2.6.0/fs/reiserfs/file.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/reiserfs/file.c      2003-12-28 23:21:22.000000000 -0800
+@@ -1052,7 +1052,7 @@ ssize_t reiserfs_file_write( struct file
+     /* Check if we can write to specified region of file, file
+        is not overly big and this kind of stuff. Adjust pos and
+        count, if needed */
+-    res = generic_write_checks(inode, file, &pos, &count, 0);
++    res = generic_write_checks(file, &pos, &count, 0);
+     if (res)
+       goto out;
+@@ -1179,7 +1179,7 @@ ssize_t reiserfs_file_write( struct file
+     }
+     if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
+-      res = generic_osync_inode(inode, OSYNC_METADATA|OSYNC_DATA);
++      res = generic_osync_inode(inode, file->f_mapping, OSYNC_METADATA|OSYNC_DATA);
+     up(&inode->i_sem);
+     return (already_written != 0)?already_written:res;
+--- linux-2.6.0/fs/reiserfs/inode.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/reiserfs/inode.c     2003-12-28 23:21:19.000000000 -0800
+@@ -2375,7 +2375,7 @@ static int reiserfs_direct_IO(int rw, st
+                             loff_t offset, unsigned long nr_segs)
+ {
+     struct file *file = iocb->ki_filp;
+-    struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
++    struct inode *inode = file->f_mapping->host;
+     return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+                             offset, nr_segs, reiserfs_get_blocks_direct_io, NULL);
+--- linux-2.6.0/fs/reiserfs/journal.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/reiserfs/journal.c   2003-12-28 23:23:05.000000000 -0800
+@@ -1937,18 +1937,13 @@ static int journal_init_dev( struct supe
+       journal -> j_dev_file = filp_open( jdev_name, 0, 0 );
+       if( !IS_ERR( journal -> j_dev_file ) ) {
+-              struct inode *jdev_inode;
+-
+-              jdev_inode = journal -> j_dev_file -> f_dentry -> d_inode;
+-              journal -> j_dev_bd = jdev_inode -> i_bdev;
++              struct inode *jdev_inode = journal->j_dev_file->f_mapping->host;
+               if( !S_ISBLK( jdev_inode -> i_mode ) ) {
+                       printk( "journal_init_dev: '%s' is not a block device\n", jdev_name );
+                       result = -ENOTBLK;
+-              } else if( jdev_inode -> i_bdev == NULL ) {
+-                      printk( "journal_init_dev: bdev uninitialized for '%s'\n", jdev_name );
+-                      result = -ENOMEM;
+               } else  {
+                       /* ok */
++                      journal->j_dev_bd = I_BDEV(jdev_inode);
+                       set_blocksize(journal->j_dev_bd, super->s_blocksize);
+               }
+       } else {
+@@ -1967,7 +1962,7 @@ static int journal_init_dev( struct supe
+ /*
+ ** must be called once on fs mount.  calls journal_read for you
+ */
+-int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_format) {
++int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_format, unsigned int commit_max_age) {
+     int num_cnodes = SB_ONDISK_JOURNAL_SIZE(p_s_sb) * 2 ;
+     struct buffer_head *bhjh;
+     struct reiserfs_super_block * rs;
+@@ -2032,7 +2027,11 @@ int journal_init(struct super_block *p_s
+      
+   SB_JOURNAL_TRANS_MAX(p_s_sb)      = le32_to_cpu (jh->jh_journal.jp_journal_trans_max);
+   SB_JOURNAL_MAX_BATCH(p_s_sb)      = le32_to_cpu (jh->jh_journal.jp_journal_max_batch);
++  if (commit_max_age != 0) {
++        SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb) = commit_max_age;
++  } else {
+   SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb) = le32_to_cpu (jh->jh_journal.jp_journal_max_commit_age);
++  }
+   SB_JOURNAL_MAX_TRANS_AGE(p_s_sb)  = JOURNAL_MAX_TRANS_AGE;
+   if (SB_JOURNAL_TRANS_MAX(p_s_sb)) {
+--- linux-2.6.0/fs/reiserfs/namei.c    2003-09-27 18:57:46.000000000 -0700
++++ 25/fs/reiserfs/namei.c     2003-12-28 23:23:05.000000000 -0800
+@@ -1088,11 +1088,16 @@ static int reiserfs_rename (struct inode
+     int jbegin_count ; 
+     umode_t old_inode_mode;
+     unsigned long savelink = 1;
++    struct timespec ctime;
+-    /* two balancings: old name removal, new name insertion or "save" link,
+-       stat data updates: old directory and new directory and maybe block
+-       containing ".." of renamed directory */
+-    jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 3;
++    /* three balancings: (1) old name removal, (2) new name insertion
++       and (3) maybe "save" link insertion
++       stat data updates: (1) old directory,
++       (2) new directory and (3) maybe old object stat data (when it is
++       directory) and (4) maybe stat data of object to which new entry
++       pointed initially and (5) maybe block containing ".." of
++       renamed directory */
++    jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 5;
+     old_inode = old_dentry->d_inode;
+     new_dentry_inode = new_dentry->d_inode;
+@@ -1255,8 +1260,12 @@ static int reiserfs_rename (struct inode
+     mark_de_hidden (old_de.de_deh + old_de.de_entry_num);
+     journal_mark_dirty (&th, old_dir->i_sb, old_de.de_bh);
+-    old_dir->i_ctime = old_dir->i_mtime = 
+-    new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
++    ctime = CURRENT_TIME;
++    old_dir->i_ctime = old_dir->i_mtime = ctime;
++    new_dir->i_ctime = new_dir->i_mtime = ctime;
++    /* thanks to Alex Adriaanse <alex_a@caltech.edu> for patch which adds ctime update of
++       renamed object */
++    old_inode->i_ctime = ctime;
+     if (new_dentry_inode) {
+       // adjust link number of the victim
+@@ -1265,7 +1274,7 @@ static int reiserfs_rename (struct inode
+       } else {
+           new_dentry_inode->i_nlink--;
+       }
+-      new_dentry_inode->i_ctime = new_dir->i_ctime;
++      new_dentry_inode->i_ctime = ctime;
+       savelink = new_dentry_inode->i_nlink;
+     }
+@@ -1298,6 +1307,7 @@ static int reiserfs_rename (struct inode
+     reiserfs_update_sd (&th, old_dir);
+     reiserfs_update_sd (&th, new_dir);
++    reiserfs_update_sd (&th, old_inode);
+     if (new_dentry_inode) {
+       if (savelink == 0)
+--- linux-2.6.0/fs/reiserfs/procfs.c   2003-10-17 15:58:04.000000000 -0700
++++ 25/fs/reiserfs/procfs.c    2003-12-28 23:23:05.000000000 -0800
+@@ -401,7 +401,7 @@ static int show_journal(struct seq_file 
+                         DJP( jp_journal_trans_max ),
+                         DJP( jp_journal_magic ),
+                         DJP( jp_journal_max_batch ),
+-                        DJP( jp_journal_max_commit_age ),
++                        SB_JOURNAL_MAX_COMMIT_AGE(sb),
+                         DJP( jp_journal_max_trans_age ),
+                       JF( j_1st_reserved_block ),                     
+--- linux-2.6.0/fs/reiserfs/super.c    2003-11-23 19:03:01.000000000 -0800
++++ 25/fs/reiserfs/super.c     2003-12-28 23:23:05.000000000 -0800
+@@ -645,7 +645,8 @@ static int reiserfs_parse_options (struc
+                                     collection of bitflags defining what
+                                     mount options were selected. */
+                                  unsigned long * blocks, /* strtol-ed from NNN of resize=NNN */
+-                                 char ** jdev_name)
++                                 char ** jdev_name,
++                                 unsigned int * commit_max_age)
+ {
+     int c;
+     char * arg = NULL;
+@@ -662,6 +663,7 @@ static int reiserfs_parse_options (struc
+       {"resize", 'r', 0, 0, 0},
+       {"jdev", 'j', 0, 0, 0},
+       {"nolargeio", 'w', 0, 0, 0},
++      {"commit", 'c', 0, 0, 0},
+       {NULL, 0, 0, 0, 0}
+     };
+       
+@@ -690,6 +692,19 @@ static int reiserfs_parse_options (struc
+           }
+       }
++      if ( c == 'c' ) {
++              char *p = 0;
++              int val = simple_strtoul (arg, &p, 0);
++              /* commit=NNN (time in seconds) */
++              if ( *p != '\0' || val == 0) {
++                      printk ("reiserfs_parse_options: bad value %s\n", arg);
++                      return 0;
++              }
++              if ( val > 0 ) {
++                      *commit_max_age = val;
++              }
++      }
++
+       if ( c == 'w' ) {
+               char *p=0;
+               int val = simple_strtoul (arg, &p, 0);
+@@ -743,10 +758,11 @@ static int reiserfs_remount (struct supe
+   unsigned long blocks;
+   unsigned long mount_options = REISERFS_SB(s)->s_mount_opt;
+   unsigned long safe_mask = 0;
++  unsigned int commit_max_age = 0;
+   rs = SB_DISK_SUPER_BLOCK (s);
+-  if (!reiserfs_parse_options(s, arg, &mount_options, &blocks, NULL))
++  if (!reiserfs_parse_options(s, arg, &mount_options, &blocks, NULL, &commit_max_age))
+     return -EINVAL;
+   
+   handle_attrs(s);
+@@ -764,6 +780,10 @@ static int reiserfs_remount (struct supe
+    * the bits we're not allowed to change here */
+   REISERFS_SB(s)->s_mount_opt = (REISERFS_SB(s)->s_mount_opt & ~safe_mask) |  (mount_options & safe_mask);
++  if(commit_max_age != 0) {
++        SB_JOURNAL_MAX_COMMIT_AGE(s) = commit_max_age;
++  }
++
+   if(blocks) {
+     int rc = reiserfs_resize(s, blocks);
+     if (rc != 0)
+@@ -1201,11 +1221,15 @@ int function2code (hashf_t func)
+     if (func == r5_hash)
+       return R5_HASH;
+-    BUG() ; // should never happen 
++    BUG() ; // should never happen
+     return 0;
+ }
++#define SPRINTK(silent, ...)                  \
++      if (!(silent))                          \
++              printk(__VA_ARGS__)
++
+ static int reiserfs_fill_super (struct super_block * s, void * data, int silent)
+ {
+     struct inode *root_inode;
+@@ -1213,6 +1237,7 @@ static int reiserfs_fill_super (struct s
+     struct reiserfs_transaction_handle th ;
+     int old_format = 0;
+     unsigned long blocks;
++      unsigned int commit_max_age = 0;
+     int jinit_done = 0 ;
+     struct reiserfs_iget_args args ;
+     struct reiserfs_super_block * rs;
+@@ -1237,58 +1262,58 @@ static int reiserfs_fill_super (struct s
+     REISERFS_SB(s)->s_alloc_options.preallocsize = 9;
+     jdev_name = NULL;
+-    if (reiserfs_parse_options (s, (char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name) == 0) {
++    if (reiserfs_parse_options (s, (char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name, &commit_max_age) == 0) {
+       goto error;
+     }
+     if (blocks) {
+-      printk("jmacd-7: reiserfs_fill_super: resize option for remount only\n");
++      SPRINTK(silent, "jmacd-7: reiserfs_fill_super: resize option for remount only\n");
+       goto error;
+     } 
+     /* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */
+-    if (!read_super_block (s, REISERFS_OLD_DISK_OFFSET_IN_BYTES)) 
++    if (!read_super_block (s, REISERFS_OLD_DISK_OFFSET_IN_BYTES))
+       old_format = 1;
+     /* try new format (64-th 1k block), which can contain reiserfs super block */
+     else if (read_super_block (s, REISERFS_DISK_OFFSET_IN_BYTES)) {
+-      printk("sh-2021: reiserfs_fill_super: can not find reiserfs on %s\n", reiserfs_bdevname (s));
+-      goto error;    
++      SPRINTK(silent, "sh-2021: reiserfs_fill_super: can not find reiserfs on %s\n", reiserfs_bdevname (s));
++      goto error;
+     }
+     rs = SB_DISK_SUPER_BLOCK (s);
+     /* Let's do basic sanity check to verify that underlying device is not
+        smaller than the filesystem. If the check fails then abort and scream,
+        because bad stuff will happen otherwise. */
+-    if ( s->s_bdev && s->s_bdev->bd_inode && i_size_read(s->s_bdev->bd_inode) < sb_block_count(rs)*sb_blocksize(rs) ) {
+-      printk("Filesystem on %s cannot be mounted because it is bigger than the device\n", reiserfs_bdevname(s));
+-      printk("You may need to run fsck or increase size of your LVM partition\n");
+-      printk("Or may be you forgot to reboot after fdisk when it told you to\n");
++    if ( s->s_bdev && s->s_bdev->bd_inode && i_size_read(s->s_bdev->bd_inode) < sb_block_count(rs)*sb_blocksize(rs)) {
++      SPRINTK(silent, "Filesystem on %s cannot be mounted because it is bigger than the device\n", reiserfs_bdevname(s));
++      SPRINTK(silent, "You may need to run fsck or increase size of your LVM partition\n");
++      SPRINTK(silent, "Or may be you forgot to reboot after fdisk when it told you to\n");
+       goto error;
+     }
+     sbi->s_mount_state = SB_REISERFS_STATE(s);
+     sbi->s_mount_state = REISERFS_VALID_FS ;
+-    if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { 
+-      printk ("jmacd-8: reiserfs_fill_super: unable to read bitmap\n");
++    if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) {
++      SPRINTK(silent, "jmacd-8: reiserfs_fill_super: unable to read bitmap\n");
+       goto error;
+     }
+ #ifdef CONFIG_REISERFS_CHECK
+-    printk("reiserfs:warning: CONFIG_REISERFS_CHECK is set ON\n");
+-    printk("reiserfs:warning: - it is slow mode for debugging.\n");
++    SPRINTK(silent, "reiserfs:warning: CONFIG_REISERFS_CHECK is set ON\n");
++    SPRINTK(silent, "reiserfs:warning: - it is slow mode for debugging.\n");
+ #endif
+     // set_device_ro(s->s_dev, 1) ;
+-    if( journal_init(s, jdev_name, old_format) ) {
+-      printk("sh-2022: reiserfs_fill_super: unable to initialize journal space\n") ;
++    if( journal_init(s, jdev_name, old_format, commit_max_age) ) {
++      SPRINTK(silent, "sh-2022: reiserfs_fill_super: unable to initialize journal space\n") ;
+       goto error ;
+     } else {
+       jinit_done = 1 ; /* once this is set, journal_release must be called
+-                       ** if we error out of the mount 
++                       ** if we error out of the mount
+                        */
+     }
+     if (reread_meta_blocks(s)) {
+-      printk("jmacd-9: reiserfs_fill_super: unable to reread meta blocks after journal init\n") ;
++      SPRINTK(silent, "jmacd-9: reiserfs_fill_super: unable to reread meta blocks after journal init\n") ;
+       goto error ;
+     }
+@@ -1296,14 +1321,14 @@ static int reiserfs_fill_super (struct s
+       goto error;
+     if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) {
+-        printk("clm-7000: Detected readonly device, marking FS readonly\n") ;
++        SPRINTK(silent, "clm-7000: Detected readonly device, marking FS readonly\n") ;
+       s->s_flags |= MS_RDONLY ;
+     }
+     args.objectid = REISERFS_ROOT_OBJECTID ;
+     args.dirid = REISERFS_ROOT_PARENT_OBJECTID ;
+     root_inode = iget5_locked (s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args));
+     if (!root_inode) {
+-      printk ("jmacd-10: reiserfs_fill_super: get root inode failed\n");
++      SPRINTK(silent, "jmacd-10: reiserfs_fill_super: get root inode failed\n");
+       goto error;
+     }
+@@ -1341,22 +1366,23 @@ static int reiserfs_fill_super (struct s
+       
+       if (old_format_only(s)) {
+         /* filesystem of format 3.5 either with standard or non-standard
+-           journal */       
++           journal */
+         if (convert_reiserfs (s)) {
+-          /* and -o conv is given */ 
+-          reiserfs_warning ("reiserfs: converting 3.5 filesystem to the 3.6 format\n") ;
+-          
++          /* and -o conv is given */
++          if(!silent)
++            reiserfs_warning ("reiserfs: converting 3.5 filesystem to the 3.6 format\n") ;
++
+           if (is_reiserfs_3_5 (rs))
+             /* put magic string of 3.6 format. 2.2 will not be able to
+                mount this filesystem anymore */
+-            memcpy (rs->s_v1.s_magic, reiserfs_3_6_magic_string, 
++            memcpy (rs->s_v1.s_magic, reiserfs_3_6_magic_string,
+                     sizeof (reiserfs_3_6_magic_string));
+-          
++
+           set_sb_version(rs,REISERFS_VERSION_2);
+           reiserfs_convert_objectid_map_v1(s) ;
+           set_bit(REISERFS_3_6, &(sbi->s_properties));
+           clear_bit(REISERFS_3_5, &(sbi->s_properties));
+-        } else {
++        } else if (!silent){
+           reiserfs_warning("reiserfs: using 3.5.x disk format\n") ;
+         }
+       }
+@@ -1369,7 +1395,7 @@ static int reiserfs_fill_super (struct s
+       s->s_dirt = 0;
+     } else {
+-      if ( old_format_only(s) ) {
++      if ( old_format_only(s) && !silent) {
+           reiserfs_warning("reiserfs: using 3.5.x disk format\n") ;
+       }
+     }
+--- linux-2.6.0/fs/stat.c      2003-10-08 15:07:10.000000000 -0700
++++ 25/fs/stat.c       2003-12-28 23:22:16.000000000 -0800
+@@ -106,7 +106,7 @@ int vfs_fstat(unsigned int fd, struct ks
+ EXPORT_SYMBOL(vfs_fstat);
+ #if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) \
+-  && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) \
++  && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) \
+   && !defined(__arm__) && !defined(CONFIG_V850) && !defined(__powerpc64__)
+ /*
+--- linux-2.6.0/fs/super.c     2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/super.c      2003-12-28 23:21:23.000000000 -0800
+@@ -66,6 +66,7 @@ static struct super_block *alloc_super(v
+               INIT_LIST_HEAD(&s->s_files);
+               INIT_LIST_HEAD(&s->s_instances);
+               INIT_HLIST_HEAD(&s->s_anon);
++              INIT_LIST_HEAD(&s->s_inodes);
+               init_rwsem(&s->s_umount);
+               sema_init(&s->s_lock, 1);
+               down_write(&s->s_umount);
+--- linux-2.6.0/fs/sysfs/dir.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/sysfs/dir.c  2003-12-28 23:22:59.000000000 -0800
+@@ -83,7 +83,8 @@ static void remove_dir(struct dentry * d
+       struct dentry * parent = dget(d->d_parent);
+       down(&parent->d_inode->i_sem);
+       d_delete(d);
+-      simple_rmdir(parent->d_inode,d);
++      if (d->d_inode)
++              simple_rmdir(parent->d_inode,d);
+       pr_debug(" o %s removing done (%d)\n",d->d_name.name,
+                atomic_read(&d->d_count));
+@@ -122,8 +123,8 @@ void sysfs_remove_dir(struct kobject * k
+       node = dentry->d_subdirs.next;
+       while (node != &dentry->d_subdirs) {
+               struct dentry * d = list_entry(node,struct dentry,d_child);
+-              list_del_init(node);
++              node = node->next;
+               pr_debug(" o %s (%d): ",d->d_name.name,atomic_read(&d->d_count));
+               if (d->d_inode) {
+                       d = dget_locked(d);
+@@ -139,9 +140,7 @@ void sysfs_remove_dir(struct kobject * k
+                       spin_lock(&dcache_lock);
+               }
+               pr_debug(" done\n");
+-              node = dentry->d_subdirs.next;
+       }
+-      list_del_init(&dentry->d_child);
+       spin_unlock(&dcache_lock);
+       up(&dentry->d_inode->i_sem);
+--- linux-2.6.0/fs/udf/super.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/udf/super.c  2003-12-28 23:21:55.000000000 -0800
+@@ -414,7 +414,7 @@ udf_parse_options(char *options, struct 
+               case Opt_utf8:
+                       uopt->flags |= (1 << UDF_FLAG_UTF8);
+                       break;
+-#ifdef CONFIG_NLS
++#if defined(CONFIG_NLS) || defined(CONFIG_NLS_MODULE)
+               case Opt_iocharset:
+                       uopt->nls_map = load_nls(args[0].from);
+                       uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
+@@ -1510,7 +1510,7 @@ static int udf_fill_super(struct super_b
+                       "utf8 cannot be combined with iocharset\n");
+               goto error_out;
+       }
+-#ifdef CONFIG_NLS
++#if defined(CONFIG_NLS) || defined(CONFIG_NLS_MODULE)
+       if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map)
+       {
+               uopt.nls_map = load_nls_default();
+@@ -1674,7 +1674,7 @@ error_out:
+                               udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+               }
+       }
+-#ifdef CONFIG_NLS
++#if defined(CONFIG_NLS) || defined(CONFIG_NLS_MODULE)
+       if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
+               unload_nls(UDF_SB(sb)->s_nls_map);
+ #endif
+@@ -1766,7 +1766,7 @@ udf_put_super(struct super_block *sb)
+                               udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+               }
+       }
+-#ifdef CONFIG_NLS
++#if defined(CONFIG_NLS) || defined(CONFIG_NLS_MODULE)
+       if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
+               unload_nls(UDF_SB(sb)->s_nls_map);
+ #endif
+--- linux-2.6.0/fs/vfat/namei.c        2003-10-08 15:07:10.000000000 -0700
++++ 25/fs/vfat/namei.c 2003-12-28 23:22:52.000000000 -0800
+@@ -25,23 +25,6 @@
+ #include <linux/buffer_head.h>
+ #include <linux/namei.h>
+-#define DEBUG_LEVEL 0
+-#if (DEBUG_LEVEL >= 1)
+-#  define PRINTK1(x) printk x
+-#else
+-#  define PRINTK1(x)
+-#endif
+-#if (DEBUG_LEVEL >= 2)
+-#  define PRINTK2(x) printk x
+-#else
+-#  define PRINTK2(x)
+-#endif
+-#if (DEBUG_LEVEL >= 3)
+-#  define PRINTK3(x) printk x
+-#else
+-#  define PRINTK3(x)
+-#endif
+-
+ static int vfat_hashi(struct dentry *parent, struct qstr *qstr);
+ static int vfat_hash(struct dentry *parent, struct qstr *qstr);
+ static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
+@@ -573,13 +556,18 @@ xlate_to_uni(const unsigned char *name, 
+       int charlen;
+       if (utf8) {
++              int name_len = strlen(name);
++
+               *outlen = utf8_mbstowcs((wchar_t *)outname, name, PAGE_SIZE);
+-              if (name[len-1] == '.')
+-                      *outlen-=2;
++
++              /*
++               * We stripped '.'s before and set len appropriately,
++               * but utf8_mbstowcs doesn't care about len
++               */
++              *outlen -= (name_len-len);
++
+               op = &outname[*outlen * sizeof(wchar_t)];
+       } else {
+-              if (name[len-1] == '.') 
+-                      len--;
+               if (nls) {
+                       for (i = 0, ip = name, op = outname, *outlen = 0;
+                            i < len && *outlen <= 260; *outlen += 1)
+@@ -694,7 +682,6 @@ static int vfat_build_slots(struct inode
+       for (cksum = i = 0; i < 11; i++) {
+               cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i];
+       }
+-      PRINTK3(("vfat_fill_slots 3: slots=%d\n",*slots));
+       for (ps = ds, slot = *slots; slot > 0; slot--, ps++) {
+               ps->id = slot;
+@@ -711,7 +698,6 @@ static int vfat_build_slots(struct inode
+       de = (struct msdos_dir_entry *) ps;
+ shortname:
+-      PRINTK3(("vfat_fill_slots 9\n"));
+       /* build the entry of 8.3 alias name */
+       (*slots)++;
+       memcpy(de->name, msdos_name, MSDOS_NAME);
+@@ -734,18 +720,22 @@ static int vfat_add_entry(struct inode *
+ {
+       struct msdos_dir_slot *dir_slots;
+       loff_t offset;
+-      int slots, slot;
+-      int res;
++      int res, slots, slot;
++      unsigned int len;
+       struct msdos_dir_entry *dummy_de;
+       struct buffer_head *dummy_bh;
+       loff_t dummy_i_pos;
+-      dir_slots = (struct msdos_dir_slot *)
++      len = vfat_striptail_len(qname);
++      if (len == 0)
++              return -ENOENT;
++
++      dir_slots =
+              kmalloc(sizeof(struct msdos_dir_slot) * MSDOS_SLOTS, GFP_KERNEL);
+       if (dir_slots == NULL)
+               return -ENOMEM;
+-      res = vfat_build_slots(dir, qname->name, vfat_striptail_len(qname),
++      res = vfat_build_slots(dir, qname->name, len,
+                              dir_slots, &slots, is_dir);
+       if (res < 0)
+               goto cleanup;
+@@ -796,11 +786,16 @@ static int vfat_find(struct inode *dir,s
+ {
+       struct super_block *sb = dir->i_sb;
+       loff_t offset;
++      unsigned int len;
+       int res;
+-      res = fat_search_long(dir, qname->name, vfat_striptail_len(qname),
+-                      (MSDOS_SB(sb)->options.name_check != 's'),
+-                      &offset,&sinfo->longname_offset);
++      len = vfat_striptail_len(qname);
++      if (len == 0)
++              return -ENOENT;
++
++      res = fat_search_long(dir, qname->name, len,
++                            (MSDOS_SB(sb)->options.name_check != 's'),
++                            &offset, &sinfo->longname_offset);
+       if (res>0) {
+               sinfo->long_slots = res-1;
+               if (fat_get_entry(dir,&offset,last_bh,last_de,&sinfo->i_pos)>=0)
+@@ -820,9 +815,6 @@ struct dentry *vfat_lookup(struct inode 
+       struct msdos_dir_entry *de;
+       int table;
+       
+-      PRINTK2(("vfat_lookup: name=%s, len=%d\n", 
+-               dentry->d_name.name, dentry->d_name.len));
+-
+       lock_kernel();
+       table = (MSDOS_SB(dir->i_sb)->options.name_check == 's') ? 2 : 0;
+       dentry->d_op = &vfat_dentry_ops[table];
+@@ -955,7 +947,6 @@ int vfat_unlink(struct inode *dir, struc
+       struct buffer_head *bh = NULL;
+       struct msdos_dir_entry *de;
+-      PRINTK1(("vfat_unlink: %s\n", dentry->d_name.name));
+       lock_kernel();
+       res = vfat_find(dir,&dentry->d_name,&sinfo,&bh,&de);
+       if (res < 0) {
+@@ -1036,14 +1027,18 @@ int vfat_rename(struct inode *old_dir,st
+       new_inode = new_dentry->d_inode;
+       lock_kernel();
+       res = vfat_find(old_dir,&old_dentry->d_name,&old_sinfo,&old_bh,&old_de);
+-      PRINTK3(("vfat_rename 2\n"));
+-      if (res < 0) goto rename_done;
++      if (res < 0)
++              goto rename_done;
+       is_dir = S_ISDIR(old_inode->i_mode);
+-      if (is_dir && (res = fat_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh,
+-                              &dotdot_de,&dotdot_i_pos)) < 0)
+-              goto rename_done;
++      if (is_dir) {
++              if (fat_scan(old_inode, MSDOS_DOTDOT, &dotdot_bh,
++                           &dotdot_de, &dotdot_i_pos) < 0) {
++                      res = -EIO;
++                      goto rename_done;
++              }
++      }
+       if (new_dentry->d_inode) {
+               res = vfat_find(new_dir,&new_dentry->d_name,&sinfo,&new_bh,
+--- linux-2.6.0/fs/xfs/linux/xfs_aops.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/xfs/linux/xfs_aops.c 2003-12-28 23:26:37.000000000 -0800
+@@ -974,7 +974,7 @@ linvfs_direct_IO(
+       unsigned long           nr_segs)
+ {
+       struct file     *file = iocb->ki_filp;
+-      struct inode    *inode = file->f_dentry->d_inode->i_mapping->host;
++      struct inode    *inode = file->f_mapping->host;
+       vnode_t         *vp = LINVFS_GET_VP(inode);
+       page_buf_bmap_t pbmap;
+       int             maps = 1;
+@@ -984,7 +984,8 @@ linvfs_direct_IO(
+       if (error)
+               return -error;
+-        return blockdev_direct_IO(rw, iocb, inode, pbmap.pbm_target->pbr_bdev,
++        return blockdev_direct_IO_no_locking(rw, iocb, inode,
++              pbmap.pbm_target->pbr_bdev,
+               iov, offset, nr_segs,
+               linvfs_get_blocks_direct,
+               linvfs_unwritten_convert_direct);
+--- linux-2.6.0/fs/xfs/linux/xfs_file.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/fs/xfs/linux/xfs_file.c 2003-12-28 23:21:19.000000000 -0800
+@@ -112,7 +112,7 @@ __linvfs_write(
+ {
+       struct iovec    iov = {(void *)buf, count};
+       struct file     *file = iocb->ki_filp;
+-      struct inode    *inode = file->f_dentry->d_inode->i_mapping->host;
++      struct inode    *inode = file->f_mapping->host;
+       vnode_t         *vp = LINVFS_GET_VP(inode);
+       int             error;
+@@ -160,7 +160,7 @@ __linvfs_readv(
+       unsigned long           nr_segs,
+       loff_t                  *ppos)
+ {
+-      struct inode    *inode = file->f_dentry->d_inode->i_mapping->host;
++      struct inode    *inode = file->f_mapping->host;
+       vnode_t         *vp = LINVFS_GET_VP(inode);
+       struct          kiocb kiocb;
+       int             error;
+@@ -207,7 +207,7 @@ __linvfs_writev(
+       unsigned long           nr_segs,
+       loff_t                  *ppos)
+ {
+-      struct inode    *inode = file->f_dentry->d_inode->i_mapping->host;
++      struct inode    *inode = file->f_mapping->host;
+       vnode_t         *vp = LINVFS_GET_VP(inode);
+       struct          kiocb kiocb;
+       int             error;
+--- linux-2.6.0/fs/xfs/pagebuf/page_buf.c      2003-10-08 15:07:10.000000000 -0700
++++ 25/fs/xfs/pagebuf/page_buf.c       2003-12-28 23:22:28.000000000 -0800
+@@ -1395,7 +1395,6 @@ next_chunk:
+                       break;
+               offset = 0;
+-
+               sector += nbytes >> BBSHIFT;
+               size -= nbytes;
+               total_nr_pages--;
+@@ -1403,15 +1402,11 @@ next_chunk:
+ submit_io:
+       if (likely(bio->bi_size)) {
+-              if (pb->pb_flags & PBF_READ) {
+-                      submit_bio(READ, bio);
+-              } else {
+-                      submit_bio(WRITE, bio);
+-              }
+-
++              submit_bio((pb->pb_flags & PBF_READ) ? READ : WRITE, bio);
+               if (size)
+                       goto next_chunk;
+       } else {
++              bio_put(bio);
+               pagebuf_ioerror(pb, EIO);
+       }
+--- linux-2.6.0/fs/xfs/xfs_vfsops.c    2003-10-17 15:58:04.000000000 -0700
++++ 25/fs/xfs/xfs_vfsops.c     2003-12-28 23:22:28.000000000 -0800
+@@ -1598,8 +1598,9 @@ xfs_vget(
+ #define MNTOPT_NORECOVERY   "norecovery"   /* don't run XFS recovery */
+ #define MNTOPT_NOLOGFLUSH   "nologflush"   /* don't hard flush on log writes */
+ #define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
+-#define MNTOPT_64BITINODE   "inode64"  /* inodes can be allocated anywhere */
+-#define MNTOPT_IKEEP  "ikeep"         /* free empty inode clusters */
++#define MNTOPT_64BITINODE   "inode64" /* inodes can be allocated anywhere */
++#define MNTOPT_IKEEP  "ikeep"         /* do not free empty inode clusters */
++#define MNTOPT_NOIKEEP        "noikeep"       /* free empty inode clusters */
+ int
+@@ -1614,7 +1615,9 @@ xfs_parseargs(
+       int                     dsunit, dswidth, vol_dsunit, vol_dswidth;
+       int                     iosize;
++#if 0 /* XXX: off by default, until some remaining issues ironed out */
+       args->flags |= XFSMNT_IDELETE; /* default to on */
++#endif
+       if (!options)
+               return 0;
+@@ -1722,6 +1725,8 @@ xfs_parseargs(
+                       args->flags |= XFSMNT_NOLOGFLUSH;
+               } else if (!strcmp(this_char, MNTOPT_IKEEP)) {
+                       args->flags &= ~XFSMNT_IDELETE;
++              } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
++                      args->flags |= XFSMNT_IDELETE;
+               } else if (!strcmp(this_char, "osyncisdsync")) {
+                       /* no-op, this is now the default */
+ printk("XFS: osyncisdsync is now the default, option is deprecated.\n");
+--- linux-2.6.0/include/acpi/acconfig.h        2003-10-17 15:58:04.000000000 -0700
++++ 25/include/acpi/acconfig.h 2003-12-28 23:21:33.000000000 -0800
+@@ -64,7 +64,7 @@
+ /* Version string */
+-#define ACPI_CA_VERSION                 0x20031002
++#define ACPI_CA_VERSION                 0x20031203
+ /* Maximum objects in the various object caches */
+--- linux-2.6.0/include/acpi/acevents.h        2003-06-14 12:18:23.000000000 -0700
++++ 25/include/acpi/acevents.h 2003-12-28 23:21:33.000000000 -0800
+@@ -182,6 +182,17 @@ acpi_ev_detach_region (
+       union acpi_operand_object      *region_obj,
+       u8                              acpi_ns_is_locked);
++acpi_status
++acpi_ev_execute_reg_method (
++      union acpi_operand_object      *region_obj,
++      u32                             function);
++
++acpi_status
++acpi_ev_reg_run (
++      acpi_handle                     obj_handle,
++      u32                             level,
++      void                            *context,
++      void                            **return_value);
+ /*
+  * Evregini - Region initialization and setup
+--- linux-2.6.0/include/acpi/acglobal.h        2003-06-22 12:04:44.000000000 -0700
++++ 25/include/acpi/acglobal.h 2003-12-28 23:21:33.000000000 -0800
+@@ -106,6 +106,9 @@ ACPI_EXTERN struct acpi_common_facs     
+ ACPI_EXTERN u8                                  acpi_gbl_integer_bit_width;
+ ACPI_EXTERN u8                                  acpi_gbl_integer_byte_width;
+ ACPI_EXTERN u8                                  acpi_gbl_integer_nybble_width;
++
++/* Keep local copies of these FADT-based registers */
++
+ ACPI_EXTERN struct acpi_generic_address         acpi_gbl_xpm1a_enable;
+ ACPI_EXTERN struct acpi_generic_address         acpi_gbl_xpm1b_enable;
+--- linux-2.6.0/include/acpi/acmacros.h        2003-06-14 12:18:22.000000000 -0700
++++ 25/include/acpi/acmacros.h 2003-12-28 23:21:33.000000000 -0800
+@@ -48,7 +48,6 @@
+ /*
+  * Data manipulation macros
+  */
+-
+ #define ACPI_LOWORD(l)                  ((u16)(u32)(l))
+ #define ACPI_HIWORD(l)                  ((u16)((((u32)(l)) >> 16) & 0xFFFF))
+ #define ACPI_LOBYTE(l)                  ((u8)(u16)(l))
+@@ -94,10 +93,18 @@
+ #endif
+ #endif
+- /*
+-  * Extract a byte of data using a pointer.  Any more than a byte and we
+-  * get into potential aligment issues -- see the STORE macros below
+-  */
++/*
++ * printf() format helpers
++ */
++
++/* Split 64-bit integer into two 32-bit values. use with %8,8_x%8.8X */
++
++#define ACPI_FORMAT_UINT64(i)           ACPI_HIDWORD(i),ACPI_LODWORD(i)
++
++/*
++ * Extract a byte of data using a pointer.  Any more than a byte and we
++ * get into potential aligment issues -- see the STORE macros below
++ */
+ #define ACPI_GET8(addr)                 (*(u8*)(addr))
+ /* Pointer arithmetic */
+@@ -129,7 +136,6 @@
+  * If the hardware supports the transfer of unaligned data, just do the store.
+  * Otherwise, we have to move one byte at a time.
+  */
+-
+ #ifdef ACPI_BIG_ENDIAN
+ /*
+  * Macros for big-endian machines
+@@ -299,7 +305,6 @@
+ /*
+  * Fast power-of-two math macros for non-optimized compilers
+  */
+-
+ #define _ACPI_DIV(value,power_of2)      ((u32) ((value) >> (power_of2)))
+ #define _ACPI_MUL(value,power_of2)      ((u32) ((value) << (power_of2)))
+ #define _ACPI_MOD(value,divisor)        ((u32) ((value) & ((divisor) -1)))
+@@ -443,7 +448,6 @@
+ /*
+  * Reporting macros that are never compiled out
+  */
+-
+ #define ACPI_PARAM_LIST(pl)                 pl
+ /*
+@@ -451,7 +455,6 @@
+  * _THIS_MODULE gets compiled out when ACPI_DEBUG_OUTPUT isn't defined, only
+  * use it in debug mode.
+  */
+-
+ #ifdef ACPI_DEBUG_OUTPUT
+ #define ACPI_REPORT_INFO(fp)                {acpi_ut_report_info(_THIS_MODULE,__LINE__,_COMPONENT); \
+@@ -490,7 +493,6 @@
+ /*
+  * Debug macros that are conditionally compiled
+  */
+-
+ #ifdef ACPI_DEBUG_OUTPUT
+ #define ACPI_MODULE_NAME(name)               static char ACPI_UNUSED_VAR *_THIS_MODULE = name;
+@@ -500,7 +502,6 @@
+  * The first parameter should be the procedure name as a quoted string.  This is declared
+  * as a local string ("_proc_name) so that it can be also used by the function exit macros below.
+  */
+-
+ #define ACPI_FUNCTION_NAME(a)               struct acpi_debug_print_info _dbg; \
+                                                                                               _dbg.component_id = _COMPONENT; \
+                                                                                               _dbg.proc_name   = a; \
+@@ -562,7 +563,6 @@
+ /*
+  * Generate INT3 on ACPI_ERROR (Debug only!)
+  */
+-
+ #define ACPI_ERROR_BREAK
+ #ifdef  ACPI_ERROR_BREAK
+ #define ACPI_BREAK_ON_ERROR(lvl)        if ((lvl)&ACPI_ERROR) \
+@@ -577,7 +577,6 @@
+  *    1) Debug print for the current component is enabled
+  *    2) Debug error level or trace level for the print statement is enabled
+  */
+-
+ #define ACPI_DEBUG_PRINT(pl)            acpi_ut_debug_print ACPI_PARAM_LIST(pl)
+ #define ACPI_DEBUG_PRINT_RAW(pl)        acpi_ut_debug_print_raw ACPI_PARAM_LIST(pl)
+@@ -587,7 +586,6 @@
+  * This is the non-debug case -- make everything go away,
+  * leaving no executable debug code!
+  */
+-
+ #define ACPI_MODULE_NAME(name)
+ #define _THIS_MODULE ""
+@@ -662,7 +660,6 @@
+ /*
+  * Memory allocation tracking (DEBUG ONLY)
+  */
+-
+ #ifndef ACPI_DBG_TRACK_ALLOCATIONS
+ /* Memory allocation */
+--- linux-2.6.0/include/acpi/acobject.h        2003-06-14 12:17:58.000000000 -0700
++++ 25/include/acpi/acobject.h 2003-12-28 23:21:33.000000000 -0800
+@@ -114,7 +114,7 @@
+ #define ACPI_COMMON_NOTIFY_INFO \
+       union acpi_operand_object               *system_notify;     /* Handler for system notifies */\
+       union acpi_operand_object               *device_notify;     /* Handler for driver notifies */\
+-      union acpi_operand_object               *address_space;     /* Handler for Address space */
++      union acpi_operand_object               *handler;           /* Handler for Address space */
+ /******************************************************************************
+@@ -214,7 +214,7 @@ struct acpi_object_region
+       ACPI_OBJECT_COMMON_HEADER
+       u8                                      space_id;
+-      union acpi_operand_object               *address_space;     /* Handler for region access */
++      union acpi_operand_object               *handler;           /* Handler for region access */
+       struct acpi_namespace_node              *node;              /* containing object */
+       union acpi_operand_object               *next;
+       u32                                     length;
+@@ -464,21 +464,22 @@ union acpi_operand_object
+ /* Object descriptor types */
+-#define ACPI_DESC_TYPE_CACHED           0x11        /* Used only when object is cached */
+-#define ACPI_DESC_TYPE_STATE            0x20
+-#define ACPI_DESC_TYPE_STATE_UPDATE     0x21
+-#define ACPI_DESC_TYPE_STATE_PACKAGE    0x22
+-#define ACPI_DESC_TYPE_STATE_CONTROL    0x23
+-#define ACPI_DESC_TYPE_STATE_RPSCOPE    0x24
+-#define ACPI_DESC_TYPE_STATE_PSCOPE     0x25
+-#define ACPI_DESC_TYPE_STATE_WSCOPE     0x26
+-#define ACPI_DESC_TYPE_STATE_RESULT     0x27
+-#define ACPI_DESC_TYPE_STATE_NOTIFY     0x28
+-#define ACPI_DESC_TYPE_STATE_THREAD     0x29
+-#define ACPI_DESC_TYPE_WALK             0x44
+-#define ACPI_DESC_TYPE_PARSER           0x66
+-#define ACPI_DESC_TYPE_OPERAND          0x88
+-#define ACPI_DESC_TYPE_NAMED            0xAA
++#define ACPI_DESC_TYPE_CACHED           0x01        /* Used only when object is cached */
++#define ACPI_DESC_TYPE_STATE            0x02
++#define ACPI_DESC_TYPE_STATE_UPDATE     0x03
++#define ACPI_DESC_TYPE_STATE_PACKAGE    0x04
++#define ACPI_DESC_TYPE_STATE_CONTROL    0x05
++#define ACPI_DESC_TYPE_STATE_RPSCOPE    0x06
++#define ACPI_DESC_TYPE_STATE_PSCOPE     0x07
++#define ACPI_DESC_TYPE_STATE_WSCOPE     0x08
++#define ACPI_DESC_TYPE_STATE_RESULT     0x09
++#define ACPI_DESC_TYPE_STATE_NOTIFY     0x0A
++#define ACPI_DESC_TYPE_STATE_THREAD     0x0B
++#define ACPI_DESC_TYPE_WALK             0x0C
++#define ACPI_DESC_TYPE_PARSER           0x0D
++#define ACPI_DESC_TYPE_OPERAND          0x0E
++#define ACPI_DESC_TYPE_NAMED            0x0F
++#define ACPI_DESC_TYPE_MAX              0x0F
+ union acpi_descriptor
+--- linux-2.6.0/include/acpi/acpi_drivers.h    2003-08-22 19:23:42.000000000 -0700
++++ 25/include/acpi/acpi_drivers.h     2003-12-28 23:21:33.000000000 -0800
+@@ -53,10 +53,6 @@
+ #define ACPI_PCI_COMPONENT            0x00400000
+-/* ACPI PCI Root Bridge (pci_root.c) */
+-
+-void acpi_pci_get_translations (struct acpi_pci_id* id, u64* mem_tra, u64* io_tra);
+-
+ /* ACPI PCI Interrupt Link (pci_link.c) */
+ int acpi_pci_link_check (void);
+--- linux-2.6.0/include/acpi/acutils.h 2003-06-14 12:17:56.000000000 -0700
++++ 25/include/acpi/acutils.h  2003-12-28 23:21:33.000000000 -0800
+@@ -125,6 +125,14 @@ acpi_ut_get_type_name (
+       acpi_object_type                type);
+ char *
++acpi_ut_get_node_name (
++      void                            *object);
++
++char *
++acpi_ut_get_descriptor_name (
++      void                            *object);
++
++char *
+ acpi_ut_get_object_type_name (
+       union acpi_operand_object       *obj_desc);
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-alpha/cpumask.h     2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_ALPHA_CPUMASK_H
++#define _ASM_ALPHA_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_ALPHA_CPUMASK_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-alpha/lockmeter.h   2003-12-28 23:26:33.000000000 -0800
+@@ -0,0 +1,90 @@
++/*
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ *
++ *  Modified by Peter Rival (frival@zk3.dec.com)
++ */
++
++#ifndef _ALPHA_LOCKMETER_H
++#define _ALPHA_LOCKMETER_H
++
++#include <asm/hwrpb.h>
++#define CPU_CYCLE_FREQUENCY   hwrpb->cycle_freq
++
++#define get_cycles64()                get_cycles()
++
++#define THIS_CPU_NUMBER               smp_processor_id()
++
++#include <linux/version.h>
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
++#define local_irq_save(x) \
++      __save_and_cli(x)
++#define local_irq_restore(x) \
++      __restore_flags(x)
++#endif        /* Linux version 2.2.x */
++
++#define SPINLOCK_MAGIC_INIT /**/
++
++/*
++ * Macros to cache and retrieve an index value inside of a lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.
++ * We also assume that the hash table has less than 32767 entries.
++ * the high order bit is used for write locking a rw_lock
++ * Note: although these defines and macros are the same as what is being used
++ *       in include/asm-i386/lockmeter.h, they are present here to easily
++ *     allow an alternate Alpha implementation.
++ */
++/*
++ * instrumented spinlock structure -- never used to allocate storage
++ * only used in macros below to overlay a spinlock_t
++ */
++typedef struct inst_spinlock_s {
++      /* remember, Alpha is little endian */
++      unsigned short lock;
++      unsigned short index;
++} inst_spinlock_t;
++#define PUT_INDEX(lock_ptr,indexv)    ((inst_spinlock_t *)(lock_ptr))->index = indexv
++#define GET_INDEX(lock_ptr)           ((inst_spinlock_t *)(lock_ptr))->index
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++      volatile int lock;
++      unsigned short index;
++      unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv)        ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr)               ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv)   ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr)                ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return true if rwlock is write locked
++ * (note that other lock attempts can cause the lock value to be negative)
++ */
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) (((inst_rwlock_t *)rwlock_ptr)->lock & 1)
++#define IABS(x) ((x) > 0 ? (x) : -(x))
++
++#define RWLOCK_READERS(rwlock_ptr)    rwlock_readers(rwlock_ptr)
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++      int tmp = (int) ((inst_rwlock_t *)rwlock_ptr)->lock;
++      /* readers subtract 2, so we have to:           */
++      /*      - andnot off a possible writer (bit 0)  */
++      /*      - get the absolute value                */
++      /*      - divide by 2 (right shift by one)      */
++      /* to find the number of readers                */
++      if (tmp == 0) return(0);
++      else return(IABS(tmp & ~1)>>1);
++}
++
++#endif /* _ALPHA_LOCKMETER_H */
+--- linux-2.6.0/include/asm-alpha/spinlock.h   2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-alpha/spinlock.h    2003-12-28 23:26:33.000000000 -0800
+@@ -6,6 +6,10 @@
+ #include <linux/kernel.h>
+ #include <asm/current.h>
++#ifdef CONFIG_LOCKMETER
++#undef DEBUG_SPINLOCK
++#undef DEBUG_RWLOCK
++#endif
+ /*
+  * Simple spin lock operations.  There are two variants, one clears IRQ's
+@@ -95,9 +99,18 @@ static inline int _raw_spin_trylock(spin
+ typedef struct {
+       volatile int write_lock:1, read_counter:31;
++#ifdef CONFIG_LOCKMETER
++      /* required for LOCKMETER since all bits in lock are used */
++      /* need this storage for CPU and lock INDEX ............. */
++      unsigned magic;
++#endif
+ } /*__attribute__((aligned(32)))*/ rwlock_t;
++#ifdef CONFIG_LOCKMETER
++#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0 }
++#else
+ #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
++#endif
+ #define rwlock_init(x)        do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+ #define rwlock_is_locked(x)   (*(volatile int *)(x) != 0)
+@@ -169,4 +182,41 @@ static inline void _raw_read_unlock(rwlo
+       : "m" (*lock) : "memory");
+ }
++#ifdef CONFIG_LOCKMETER
++static inline int _raw_write_trylock(rwlock_t *lock)
++{
++      long temp,result;
++
++      __asm__ __volatile__(
++      "       ldl_l %1,%0\n"
++      "       mov $31,%2\n"
++      "       bne %1,1f\n"
++      "       or $31,1,%2\n"
++      "       stl_c %2,%0\n"
++      "1:     mb\n"
++      : "=m" (*(volatile int *)lock), "=&r" (temp), "=&r" (result)
++      : "m" (*(volatile int *)lock)
++      );
++
++      return (result);
++}
++
++static inline int _raw_read_trylock(rwlock_t *lock)
++{
++      unsigned long temp,result;
++
++      __asm__ __volatile__(
++      "       ldl_l %1,%0\n"
++      "       mov $31,%2\n"
++      "       blbs %1,1f\n"
++      "       subl %1,2,%2\n"
++      "       stl_c %2,%0\n"
++      "1:     mb\n"
++      : "=m" (*(volatile int *)lock), "=&r" (temp), "=&r" (result)
++      : "m" (*(volatile int *)lock)
++      );
++      return (result);
++}
++#endif /* CONFIG_LOCKMETER */
++
+ #endif /* _ALPHA_SPINLOCK_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-arm26/cpumask.h     2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_ARM26_CPUMASK_H
++#define _ASM_ARM26_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_ARM26_CPUMASK_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-arm/cpumask.h       2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_ARM_CPUMASK_H
++#define _ASM_ARM_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_ARM_CPUMASK_H */
+--- linux-2.6.0/include/asm-cris/arch-v10/byteorder.h  2003-07-10 18:50:32.000000000 -0700
++++ 25/include/asm-cris/arch-v10/byteorder.h   2003-12-28 23:22:55.000000000 -0800
+@@ -2,20 +2,21 @@
+ #define _CRIS_ARCH_BYTEORDER_H
+ #include <asm/types.h>
++#include <linux/compiler.h>
+ /* we just define these two (as we can do the swap in a single
+  * asm instruction in CRIS) and the arch-independent files will put
+  * them together into ntohl etc.
+  */
+-extern __inline__ __const__ __u32 ___arch__swab32(__u32 x)
++extern __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+ {
+       __asm__ ("swapwb %0" : "=r" (x) : "0" (x));
+   
+       return(x);
+ }
+-extern __inline__ __const__ __u16 ___arch__swab16(__u16 x)
++extern __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+ {
+       __asm__ ("swapb %0" : "=r" (x) : "0" (x));
+       
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-cris/cpumask.h      2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_CRIS_CPUMASK_H
++#define _ASM_CRIS_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_CRIS_CPUMASK_H */
+--- linux-2.6.0/include/asm-generic/cpumask_arith.h    2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-generic/cpumask_arith.h     2003-12-28 23:22:10.000000000 -0800
+@@ -17,6 +17,7 @@
+ #define cpus_complement(map)          do { map = ~(map); } while (0)
+ #define cpus_equal(map1, map2)                ((map1) == (map2))
+ #define cpus_empty(map)                       ((map) == 0)
++#define cpus_addr(map)                        (&(map))
+ #if BITS_PER_LONG == 32
+ #define cpus_weight(map)              hweight32(map)
+--- linux-2.6.0/include/asm-generic/cpumask_array.h    2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-generic/cpumask_array.h     2003-12-28 23:22:10.000000000 -0800
+@@ -20,6 +20,7 @@
+ #define cpus_complement(map)  bitmap_complement((map).mask, NR_CPUS)
+ #define cpus_equal(map1, map2)        bitmap_equal((map1).mask, (map2).mask, NR_CPUS)
+ #define cpus_empty(map)               bitmap_empty(map.mask, NR_CPUS)
++#define cpus_addr(map)                ((map).mask)
+ #define cpus_weight(map)              bitmap_weight((map).mask, NR_CPUS)
+ #define cpus_shift_right(d, s, n)     bitmap_shift_right((d).mask, (s).mask, n, NR_CPUS)
+ #define cpus_shift_left(d, s, n)      bitmap_shift_left((d).mask, (s).mask, n, NR_CPUS)
+--- linux-2.6.0/include/asm-generic/cpumask_const_value.h      2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-generic/cpumask_const_value.h       2003-12-28 23:22:02.000000000 -0800
+@@ -3,7 +3,7 @@
+ typedef const cpumask_t cpumask_const_t;
+-#define mk_cpumask_const(map)         ((cpumask_const_t)(map))
++#define mk_cpumask_const(map)         (map)
+ #define cpu_isset_const(cpu, map)     cpu_isset(cpu, map)
+ #define cpus_and_const(dst,src1,src2) cpus_and(dst, src1, src2)
+ #define cpus_or_const(dst,src1,src2)  cpus_or(dst, src1, src2)
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-generic/cpumask.h   2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,40 @@
++#ifndef __ASM_GENERIC_CPUMASK_H
++#define __ASM_GENERIC_CPUMASK_H
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/threads.h>
++#include <linux/types.h>
++#include <linux/bitmap.h>
++
++#if NR_CPUS > BITS_PER_LONG && NR_CPUS != 1
++#define CPU_ARRAY_SIZE                BITS_TO_LONGS(NR_CPUS)
++
++struct cpumask
++{
++      unsigned long mask[CPU_ARRAY_SIZE];
++};
++
++typedef struct cpumask cpumask_t;
++
++#else
++typedef unsigned long cpumask_t;
++#endif
++
++#ifdef CONFIG_SMP
++#if NR_CPUS > BITS_PER_LONG
++#include <asm-generic/cpumask_array.h>
++#else
++#include <asm-generic/cpumask_arith.h>
++#endif
++#else
++#include <asm-generic/cpumask_up.h>
++#endif
++
++#if NR_CPUS <= 4*BITS_PER_LONG
++#include <asm-generic/cpumask_const_value.h>
++#else
++#include <asm-generic/cpumask_const_reference.h>
++#endif
++
++#endif /* __ASM_GENERIC_CPUMASK_H */
+--- linux-2.6.0/include/asm-generic/cpumask_up.h       2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-generic/cpumask_up.h        2003-12-28 23:22:10.000000000 -0800
+@@ -33,6 +33,7 @@
+ #define cpus_equal(map1, map2)                (cpus_coerce(map1) == cpus_coerce(map2))
+ #define cpus_empty(map)                       (cpus_coerce(map) == 0UL)
++#define cpus_addr(map)                        (&(map))
+ #define cpus_weight(map)              (cpus_coerce(map) ? 1UL : 0UL)
+ #define cpus_shift_right(d, s, n)     do { cpus_coerce(d) = 0UL; } while (0)
+ #define cpus_shift_left(d, s, n)      do { cpus_coerce(d) = 0UL; } while (0)
+--- linux-2.6.0/include/asm-generic/statfs.h   2003-06-22 12:04:45.000000000 -0700
++++ 25/include/asm-generic/statfs.h    2003-12-28 23:22:16.000000000 -0800
+@@ -34,4 +34,18 @@ struct statfs64 {
+       __u32 f_spare[5];
+ };
++struct compat_statfs64 {
++      __u32 f_type;
++      __u32 f_bsize;
++      __u64 f_blocks;
++      __u64 f_bfree;
++      __u64 f_bavail;
++      __u64 f_files;
++      __u64 f_ffree;
++      __kernel_fsid_t f_fsid;
++      __u32 f_namelen;
++      __u32 f_frsize;
++      __u32 f_spare[5];
++};
++
+ #endif
+--- linux-2.6.0/include/asm-h8300/bitops.h     2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-h8300/bitops.h      2003-12-28 23:22:56.000000000 -0800
+@@ -23,25 +23,22 @@
+  */
+ static __inline__ unsigned long ffz(unsigned long word)
+ {
+-      register unsigned long result asm("er0");
+-      register unsigned long _word asm("er1");
++      unsigned long result;
+-      _word = word;
+-      __asm__("sub.l %0,%0\n\t"
+-              "dec.l #1,%0\n"
+-              "1:\n\t"
+-              "shlr.l %1\n\t"
++      result = -1;
++      __asm__("1:\n\t"
++              "shlr.l %2\n\t"
+               "adds #1,%0\n\t"
+               "bcs 1b"
+-              : "=r" (result) : "r" (_word));
++              : "=r" (result)
++              : "0"  (result),"r" (word));
+       return result;
+ }
+ static __inline__ void set_bit(int nr, volatile unsigned long* addr)
+ {
+       volatile unsigned char *b_addr;
+-      b_addr = &(((volatile unsigned char *) addr)
+-                [((nr >> 3) & ~3) + 3 - ((nr >> 3) & 3)]);
++      b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);
+       __asm__("mov.l %1,er0\n\t"
+               "bset r0l,%0"
+               :"+m"(*b_addr)
+@@ -61,8 +58,7 @@ static __inline__ void set_bit(int nr, v
+ static __inline__ void clear_bit(int nr, volatile unsigned long* addr)
+ {
+       volatile unsigned char *b_addr;
+-      b_addr = &(((volatile unsigned char *) addr)
+-                [((nr >> 3) & ~3) + 3 - ((nr >> 3) & 3)]);
++      b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);
+       __asm__("mov.l %1,er0\n\t"
+               "bclr r0l,%0"
+               :"+m"(*b_addr)
+@@ -75,8 +71,7 @@ static __inline__ void clear_bit(int nr,
+ static __inline__ void change_bit(int nr, volatile unsigned long* addr)
+ {
+       volatile unsigned char *b_addr;
+-      b_addr = &(((volatile unsigned char *) addr)
+-                [((nr >> 3) & ~3) + 3 - ((nr >> 3) & 3)]);
++      b_addr = (volatile unsigned char *)addr + ((nr >> 3) ^ 3);
+       __asm__("mov.l %1,er0\n\t"
+               "bnot r0l,%0"
+               :"+m"(*b_addr)
+@@ -88,22 +83,18 @@ static __inline__ void change_bit(int nr
+ static __inline__ int test_bit(int nr, const unsigned long* addr)
+ {
+-      return ((1UL << (nr & 7)) & 
+-               (((const volatile unsigned char *) addr)
+-               [((nr >> 3) & ~3) + 3 - ((nr >> 3) & 3)])) != 0;
++      return (*((volatile unsigned char *)addr + ((nr >> 3) ^ 3)) & (1UL << (nr & 7))) != 0;
+ }
+ #define __test_bit(nr, addr) test_bit(nr, addr)
+ static __inline__ int test_and_set_bit(int nr, volatile unsigned long* addr)
+ {
+-      register int retval __asm__("er0");
++      int retval = 0;
+       volatile unsigned char *a;
+-      a = (volatile unsigned char *)addr;
+-      a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
+-      __asm__("mov.l %2,er3\n\t"
+-              "sub.l %0,%0\n\t"
++      a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3);             \
++      __asm__("mov.l %4,er3\n\t"
+               "stc ccr,r3h\n\t"
+               "orc #0x80,ccr\n\t"
+               "btst r3l,%1\n\t"
+@@ -112,37 +103,35 @@ static __inline__ int test_and_set_bit(i
+               "inc.l #1,%0\n\t"
+               "1:"
+               "ldc r3h,ccr"
+-              : "=r"(retval),"+m"(*a) :"g"(nr & 7):"er3","memory");
++              : "=r"(retval),"+m"(*a)
++              : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
+       return retval;
+ }
+ static __inline__ int __test_and_set_bit(int nr, volatile unsigned long* addr)
+ {
+-      register int retval __asm__("er0");
++      int retval = 0;
+       volatile unsigned char *a;
+-      a = (volatile unsigned char *)addr;
+-      a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
+-      __asm__("mov.l %2,er3\n\t"
+-              "sub.l %0,%0\n\t"
++      a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3);             \
++      __asm__("mov.l %4,er3\n\t"
+               "btst r3l,%1\n\t"
+               "bset r3l,%1\n\t"
+               "beq 1f\n\t"
+               "inc.l #1,%0\n\t"
+               "1:"
+-              : "=r"(retval),"+m"(*a) :"g"(nr & 7):"er3","memory");
++              : "=r"(retval),"+m"(*a)
++              : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
+       return retval;
+ }
+ static __inline__ int test_and_clear_bit(int nr, volatile unsigned long* addr)
+ {
+-      register int retval __asm__("er0");
++      int retval = 0;
+       volatile unsigned char *a;
+-      a = (volatile unsigned char *)addr;
+-      a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
+-      __asm__("mov.l %2,er3\n\t"
+-              "sub.l %0,%0\n\t"
++      a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3);             \
++      __asm__("mov.l %4,er3\n\t"
+               "stc ccr,r3h\n\t"
+               "orc #0x80,ccr\n\t"
+               "btst r3l,%1\n\t"
+@@ -151,37 +140,35 @@ static __inline__ int test_and_clear_bit
+               "inc.l #1,%0\n\t"
+               "1:"
+               "ldc r3h,ccr"
+-              : "=r"(retval),"=m"(*a) :"g"(nr & 7):"er3","memory");
++              : "=r"(retval),"+m"(*a)
++              : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
+       return retval;
+ }
+ static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long* addr)
+ {
+-      register int retval __asm__("er0");
++      int retval = 0;
+       volatile unsigned char *a;
+-      a = (volatile unsigned char *)addr;
+-      a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
+-      __asm__("mov.l %2,er3\n\t"
+-              "sub.l %0,%0\n\t"
++      a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3);             \
++      __asm__("mov.l %4,er3\n\t"
+               "btst r3l,%1\n\t"
+               "bclr r3l,%1\n\t"
+               "beq 1f\n\t"
+               "inc.l #1,%0\n\t"
+               "1:"
+-              : "=r"(retval),"+m"(*a) :"g"(nr & 7):"er3","memory");
++              : "=r"(retval),"+m"(*a)
++              : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
+       return retval;
+ }
+ static __inline__ int test_and_change_bit(int nr, volatile unsigned long* addr)
+ {
+-      register int retval __asm__("er0");
++      int retval = 0;
+       volatile unsigned char *a;
+-      a = (volatile unsigned char *)addr;
+-      a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
+-      __asm__("mov.l %2,er3\n\t"
+-              "sub.l %0,%0\n\t"
++      a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3);             \
++      __asm__("mov.l %4,er3\n\t"
+               "stc ccr,r3h\n\t"
+               "orc #0x80,ccr\n\t"
+               "btst r3l,%1\n\t"
+@@ -190,25 +177,25 @@ static __inline__ int test_and_change_bi
+               "inc.l #1,%0\n\t"
+               "1:"
+               "ldc r3h,ccr"
+-              : "=r"(retval),"+m"(*a) :"g"(nr & 7):"er3","memory");
++              : "=r"(retval),"+m"(*a)
++              : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
+       return retval;
+ }
+ static __inline__ int __test_and_change_bit(int nr, volatile unsigned long* addr)
+ {
+-      register int retval __asm__("er0");
++      int retval = 0;
+       volatile unsigned char *a;
+-      a = (volatile unsigned char *)addr;
+-      a += ((nr >> 3) & ~3) + (3 - ((nr >> 3) & 3));
+-      __asm__("mov.l %2,er3\n\t"
+-              "sub.l %0,%0\n\t"
++      a = (volatile unsigned char *)addr += ((nr >> 3) ^ 3);             \
++      __asm__("mov.l %4,er3\n\t"
+               "btst r3l,%1\n\t"
+               "bnot r3l,%1\n\t"
+               "beq 1f\n\t"
+               "inc.l #1,%0\n\t"
+               "1:"
+-              : "=r"(retval),"+m"(*a) :"g"(nr & 7):"er3","memory");
++              : "=r"(retval),"+m"(*a)
++              : "0" (retval),"m" (*a),"g"(nr & 7):"er3","memory");
+       return retval;
+ }
+@@ -251,27 +238,21 @@ found_middle:
+       return result + ffz(tmp);
+ }
+-static __inline__ unsigned long ffs(unsigned long word)
++static __inline__ unsigned long __ffs(unsigned long word)
+ {
+-      register unsigned long result asm("er0");
+-      register unsigned long _word asm("er1");
++      unsigned long result;
+-      _word = word;
+-      __asm__("sub.l %0,%0\n\t"
+-              "dec.l #1,%0\n"
+-              "1:\n\t"
+-              "shlr.l %1\n\t"
++      result = -1;
++      __asm__("1:\n\t"
++              "shlr.l %2\n\t"
+               "adds #1,%0\n\t"
+               "bcc 1b"
+-              : "=r" (result) : "r"(_word));
++              : "=r" (result)
++              : "0"(result),"r"(word));
+       return result;
+ }
+-#define __ffs(x) ffs(x)
+-
+-/*
+- * fls: find last bit set.
+- */
++#define ffs(x) generic_ffs(x)
+ #define fls(x) generic_fls(x)
+ /*
+@@ -316,6 +297,7 @@ static __inline__ int ext2_set_bit(int n
+       local_irq_restore(flags);
+       return retval;
+ }
++#define ext2_set_bit_atomic(lock, nr, addr) ext2_set_bit(nr, addr)
+ static __inline__ int ext2_clear_bit(int nr, volatile void * addr)
+ {
+@@ -331,6 +313,7 @@ static __inline__ int ext2_clear_bit(int
+       local_irq_restore(flags);
+       return retval;
+ }
++#define ext2_clear_bit_atomic(lock, nr, addr) ext2_set_bit(nr, addr)
+ static __inline__ int ext2_test_bit(int nr, const volatile void * addr)
+ {
+@@ -402,17 +385,6 @@ found_middle:
+ #define minix_test_bit(nr,addr) test_bit(nr,addr)
+ #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+-/**
+- * hweightN - returns the hamming weight of a N-bit word
+- * @x: the word to weigh
+- *
+- * The Hamming Weight of a number is the total number of bits set in it.
+- */
+-
+-#define hweight32(x) generic_hweight32(x)
+-#define hweight16(x) generic_hweight16(x)
+-#define hweight8(x) generic_hweight8(x)
+-
+ #endif /* __KERNEL__ */
+ #endif /* _H8300_BITOPS_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-h8300/cpumask.h     2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_H8300_CPUMASK_H
++#define _ASM_H8300_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_H8300_CPUMASK_H */
+--- linux-2.6.0/include/asm-i386/acpi.h        2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-i386/acpi.h 2003-12-28 23:21:33.000000000 -0800
+@@ -109,7 +109,7 @@
+ #ifdef CONFIG_ACPI_BOOT 
+ extern int acpi_lapic;
+ extern int acpi_ioapic;
+-
++extern int acpi_noirq;
+ /* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
+ #define FIX_ACPI_PAGES 4
+@@ -139,6 +139,14 @@ static inline void disable_ioapic_setup(
+ #endif
++#ifdef CONFIG_ACPI_PCI
++static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
++extern int acpi_irq_balance_set(char *str);
++#else
++static inline void acpi_noirq_set(void) { }
++static inline int acpi_irq_balance_set(char *str) { return 0; }
++#endif
++
+ #ifdef CONFIG_ACPI_SLEEP
+ /* routines for saving/restoring kernel state */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-i386/atomic_kmap.h  2003-12-28 23:26:36.000000000 -0800
+@@ -0,0 +1,95 @@
++/*
++ * atomic_kmap.h: temporary virtual kernel memory mappings
++ *
++ * Copyright (C) 2003 Ingo Molnar <mingo@redhat.com>
++ */
++
++#ifndef _ASM_ATOMIC_KMAP_H
++#define _ASM_ATOMIC_KMAP_H
++
++#ifdef __KERNEL__
++
++#include <linux/config.h>
++#include <asm/tlbflush.h>
++
++#ifdef CONFIG_DEBUG_HIGHMEM
++#define HIGHMEM_DEBUG 1
++#else
++#define HIGHMEM_DEBUG 0
++#endif
++
++extern pte_t *kmap_pte;
++#define kmap_prot PAGE_KERNEL
++
++#define PKMAP_BASE (0xff000000UL)
++#define NR_SHARED_PMDS ((0xffffffff-PKMAP_BASE+1)/PMD_SIZE)
++
++static inline unsigned long __kmap_atomic_vaddr(enum km_type type)
++{
++      enum fixed_addresses idx;
++
++      idx = type + KM_TYPE_NR*smp_processor_id();
++      return __fix_to_virt(FIX_KMAP_BEGIN + idx);
++}
++
++static inline void *__kmap_atomic_noflush(struct page *page, enum km_type type)
++{
++      enum fixed_addresses idx;
++      unsigned long vaddr;
++
++      idx = type + KM_TYPE_NR*smp_processor_id();
++      vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
++      /*
++       * NOTE: entries that rely on some secondary TLB-flush
++       * effect must not be global:
++       */
++      set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL));
++
++      return (void*) vaddr;
++}
++
++static inline void *__kmap_atomic(struct page *page, enum km_type type)
++{
++      enum fixed_addresses idx;
++      unsigned long vaddr;
++
++      idx = type + KM_TYPE_NR*smp_processor_id();
++      vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
++#if HIGHMEM_DEBUG
++      BUG_ON(!pte_none(*(kmap_pte-idx)));
++#else
++      /*
++       * Performance optimization - do not flush if the new
++       * pte is the same as the old one:
++       */
++      if (pte_val(*(kmap_pte-idx)) == pte_val(mk_pte(page, kmap_prot)))
++              return (void *) vaddr;
++#endif
++      set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
++      __flush_tlb_one(vaddr);
++
++      return (void*) vaddr;
++}
++
++static inline void __kunmap_atomic(void *kvaddr, enum km_type type)
++{
++#if HIGHMEM_DEBUG
++      unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
++      enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
++
++      BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx));
++      /*
++       * force other mappings to Oops if they'll try to access
++       * this pte without first remap it
++       */
++      pte_clear(kmap_pte-idx);
++      __flush_tlb_one(vaddr);
++#endif
++}
++
++#define __kunmap_atomic_type(type) \
++              __kunmap_atomic((void *)__kmap_atomic_vaddr(type), (type))
++
++#endif /* __KERNEL__ */
++
++#endif /* _ASM_ATOMIC_KMAP_H */
+--- linux-2.6.0/include/asm-i386/bugs.h        2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/bugs.h 2003-12-28 23:21:07.000000000 -0800
+@@ -1,11 +1,11 @@
+ /*
+  *  include/asm-i386/bugs.h
+  *
+- *  Copyright (C) 1994  Linus Torvalds
++ *  Copyright (C) 1994        Linus Torvalds
+  *
+  *  Cyrix stuff, June 1998 by:
+  *    - Rafael R. Reilova (moved everything from head.S),
+- *        <rreilova@ececs.uc.edu>
++ *      <rreilova@ececs.uc.edu>
+  *    - Channing Corn (tests & fixes),
+  *    - Andrew D. Balsa (code cleanup).
+  *
+@@ -25,7 +25,20 @@
+ #include <asm/processor.h>
+ #include <asm/i387.h>
+ #include <asm/msr.h>
+-
++#ifdef CONFIG_KGDB
++/*
++ * Provied the command line "gdb" initial break
++ */
++int __init kgdb_initial_break(char * str)
++{
++      if (*str == '\0'){
++              breakpoint();
++              return 1;
++      }
++      return 0;
++}
++__setup("gdb",kgdb_initial_break);
++#endif
+ static int __init no_halt(char *s)
+ {
+       boot_cpu_data.hlt_works_ok = 0;
+@@ -140,7 +153,7 @@ static void __init check_popad(void)
+         : "ecx", "edi" );
+       /* If this fails, it means that any user program may lock the CPU hard. Too bad. */
+       if (res != 12345678) printk( "Buggy.\n" );
+-                      else printk( "OK.\n" );
++                      else printk( "OK.\n" );
+ #endif
+ }
+--- linux-2.6.0/include/asm-i386/byteorder.h   2003-06-14 12:18:23.000000000 -0700
++++ 25/include/asm-i386/byteorder.h    2003-12-28 23:22:55.000000000 -0800
+@@ -2,6 +2,7 @@
+ #define _I386_BYTEORDER_H
+ #include <asm/types.h>
++#include <linux/compiler.h>
+ #ifdef __GNUC__
+@@ -10,7 +11,7 @@
+ #include <linux/config.h>
+ #endif
+-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
++static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+ {
+ #ifdef CONFIG_X86_BSWAP
+       __asm__("bswap %0" : "=r" (x) : "0" (x));
+@@ -24,18 +25,7 @@ static __inline__ __const__ __u32 ___arc
+       return x;
+ }
+-/* gcc should generate this for open coded C now too. May be worth switching to 
+-   it because inline assembly cannot be scheduled. -AK */
+-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+-{
+-      __asm__("xchgb %b0,%h0"         /* swap bytes           */
+-              : "=q" (x)
+-              :  "0" (x));
+-              return x;
+-}
+-
+-
+-static inline __u64 ___arch__swab64(__u64 val) 
++static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 val)
+ { 
+       union { 
+               struct { __u32 a,b; } s;
+@@ -54,9 +44,11 @@ static inline __u64 ___arch__swab64(__u6
+       return v.u;     
+ } 
++/* Do not define swab16.  Gcc is smart enough to recognize "C" version and
++   convert it into rotation or exhange.  */
++
+ #define __arch__swab64(x) ___arch__swab64(x)
+ #define __arch__swab32(x) ___arch__swab32(x)
+-#define __arch__swab16(x) ___arch__swab16(x)
+ #define __BYTEORDER_HAS_U64__
+--- linux-2.6.0/include/asm-i386/checksum.h    2003-11-23 19:03:01.000000000 -0800
++++ 25/include/asm-i386/checksum.h     2003-12-28 23:26:36.000000000 -0800
+@@ -25,7 +25,7 @@ asmlinkage unsigned int csum_partial(con
+  * better 64-bit) boundary
+  */
+-asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
++asmlinkage unsigned int direct_csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
+                                                  int *src_err_ptr, int *dst_err_ptr);
+ /*
+@@ -39,14 +39,19 @@ static __inline__
+ unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
+                                       int len, int sum)
+ {
+-      return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
++      /*
++       * The direct function is OK for kernel-space => kernel-space copies:
++       */
++      return direct_csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
+ }
+ static __inline__
+ unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
+                                               int len, int sum, int *err_ptr)
+ {
+-      return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL);
++      if (copy_from_user(dst, src, len))
++              *err_ptr = -EFAULT;
++      return csum_partial(dst, len, sum);
+ }
+ /*
+@@ -172,11 +177,26 @@ static __inline__ unsigned short int csu
+  *    Copy and checksum to user
+  */
+ #define HAVE_CSUM_COPY_USER
+-static __inline__ unsigned int csum_and_copy_to_user(const char *src, char *dst,
++static __inline__ unsigned int direct_csum_and_copy_to_user(const char *src, char *dst,
+                                   int len, int sum, int *err_ptr)
+ {
+       if (access_ok(VERIFY_WRITE, dst, len))
+-              return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
++              return direct_csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
++
++      if (len)
++              *err_ptr = -EFAULT;
++
++      return -1; /* invalid checksum */
++}
++
++static __inline__ unsigned int csum_and_copy_to_user(const char *src, char *dst,
++                                  int len, int sum, int *err_ptr)
++{
++      if (access_ok(VERIFY_WRITE, dst, len)) {
++              if (copy_to_user(dst, src, len))
++                      *err_ptr = -EFAULT;
++              return csum_partial(src, len, sum);
++      }
+       if (len)
+               *err_ptr = -EFAULT;
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-i386/cpumask.h      2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_I386_CPUMASK_H
++#define _ASM_I386_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_I386_CPUMASK_H */
+--- linux-2.6.0/include/asm-i386/desc.h        2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/desc.h 2003-12-28 23:26:36.000000000 -0800
+@@ -21,6 +21,13 @@ struct Xgt_desc_struct {
+ extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
++extern void trap_init_virtual_IDT(void);
++extern void trap_init_virtual_GDT(void);
++
++asmlinkage int system_call(void);
++asmlinkage void lcall7(void);
++asmlinkage void lcall27(void);
++
+ #define load_TR_desc() __asm__ __volatile__("ltr %%ax"::"a" (GDT_ENTRY_TSS*8))
+ #define load_LDT_desc() __asm__ __volatile__("lldt %%ax"::"a" (GDT_ENTRY_LDT*8))
+@@ -30,6 +37,7 @@ extern struct Xgt_desc_struct idt_descr,
+  */
+ extern struct desc_struct default_ldt[];
+ extern void set_intr_gate(unsigned int irq, void * addr);
++extern void set_trap_gate(unsigned int n, void *addr);
+ #define _set_tssldt_desc(n,addr,limit,type) \
+ __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
+@@ -90,31 +98,8 @@ static inline void load_TLS(struct threa
+ #undef C
+ }
+-static inline void clear_LDT(void)
+-{
+-      int cpu = get_cpu();
+-
+-      set_ldt_desc(cpu, &default_ldt[0], 5);
+-      load_LDT_desc();
+-      put_cpu();
+-}
+-
+-/*
+- * load one particular LDT into the current CPU
+- */
+-static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
+-{
+-      void *segments = pc->ldt;
+-      int count = pc->size;
+-
+-      if (likely(!count)) {
+-              segments = &default_ldt[0];
+-              count = 5;
+-      }
+-              
+-      set_ldt_desc(cpu, segments, count);
+-      load_LDT_desc();
+-}
++extern struct page *default_ldt_page;
++extern void load_LDT_nolock(mm_context_t *pc, int cpu);
+ static inline void load_LDT(mm_context_t *pc)
+ {
+@@ -123,6 +108,6 @@ static inline void load_LDT(mm_context_t
+       put_cpu();
+ }
+-#endif /* !__ASSEMBLY__ */
++#endif /* !__ASSEMBLY__ */
+ #endif
+--- linux-2.6.0/include/asm-i386/fixmap.h      2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/fixmap.h       2003-12-28 23:26:36.000000000 -0800
+@@ -18,17 +18,15 @@
+ #include <asm/acpi.h>
+ #include <asm/apicdef.h>
+ #include <asm/page.h>
+-#ifdef CONFIG_HIGHMEM
+ #include <linux/threads.h>
+ #include <asm/kmap_types.h>
+-#endif
+ /*
+  * Here we define all the compile-time 'special' virtual
+  * addresses. The point is to have a constant address at
+  * compile time, but to set the physical address only
+- * in the boot process. We allocate these special addresses
+- * from the end of virtual memory (0xfffff000) backwards.
++ * in the boot process. We allocate these special  addresses
++ * from the end of virtual memory (0xffffe000) backwards.
+  * Also this lets us do fail-safe vmalloc(), we
+  * can guarantee that these special addresses and
+  * vmalloc()-ed addresses never overlap.
+@@ -41,11 +39,20 @@
+  * TLB entries of such buffers will not be flushed across
+  * task switches.
+  */
++
++/*
++ * on UP currently we will have no trace of the fixmap mechanizm,
++ * no page table allocations, etc. This might change in the
++ * future, say framebuffers for the console driver(s) could be
++ * fix-mapped?
++ */
+ enum fixed_addresses {
+       FIX_HOLE,
+       FIX_VSYSCALL,
+ #ifdef CONFIG_X86_LOCAL_APIC
+       FIX_APIC_BASE,  /* local (CPU) APIC) -- required for SMP or not */
++#else
++      FIX_VSTACK_HOLE_1,
+ #endif
+ #ifdef CONFIG_X86_IO_APIC
+       FIX_IO_APIC_BASE_0,
+@@ -57,16 +64,21 @@ enum fixed_addresses {
+       FIX_LI_PCIA,    /* Lithium PCI Bridge A */
+       FIX_LI_PCIB,    /* Lithium PCI Bridge B */
+ #endif
+-#ifdef CONFIG_X86_F00F_BUG
+-      FIX_F00F_IDT,   /* Virtual mapping for IDT */
+-#endif
++      FIX_IDT,
++      FIX_GDT_1,
++      FIX_GDT_0,
++      FIX_TSS_3,
++      FIX_TSS_2,
++      FIX_TSS_1,
++      FIX_TSS_0,
++      FIX_ENTRY_TRAMPOLINE_1,
++      FIX_ENTRY_TRAMPOLINE_0,
+ #ifdef CONFIG_X86_CYCLONE_TIMER
+       FIX_CYCLONE_TIMER, /*cyclone timer register*/
++      FIX_VSTACK_HOLE_2,
+ #endif 
+-#ifdef CONFIG_HIGHMEM
+       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+-#endif
+ #ifdef CONFIG_ACPI_BOOT
+       FIX_ACPI_BEGIN,
+       FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
+@@ -95,12 +107,15 @@ extern void __set_fixmap (enum fixed_add
+               __set_fixmap(idx, 0, __pgprot(0))
+ /*
+- * used by vmalloc.c.
++ * used by vmalloc.c and various other places.
+  *
+  * Leave one empty page between vmalloc'ed areas and
+  * the start of the fixmap.
++ *
++ * IMPORTANT: dont change FIXADDR_TOP without adjusting KM_VSTACK0
++ * and KM_VSTACK1 so that the virtual stack is 8K aligned.
+  */
+-#define FIXADDR_TOP   (0xfffff000UL)
++#define FIXADDR_TOP   (0xffffe000UL)
+ #define __FIXADDR_SIZE        (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
+ #define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
+--- linux-2.6.0/include/asm-i386/genapic.h     2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/genapic.h      2003-12-28 23:21:32.000000000 -0800
+@@ -45,6 +45,7 @@ struct genapic { 
+       void (*setup_portio_remap)(void); 
+       int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
+       void (*enable_apic_mode)(void);
++      u32 (*phys_pkg_id)(u32 cpuid_apic, int index_msb);
+       /* mpparse */
+       void (*mpc_oem_bus_info)(struct mpc_config_bus *, char *, 
+@@ -105,6 +106,7 @@ struct genapic { 
+       APICFUNC(send_IPI_allbutself), \
+       APICFUNC(send_IPI_all), \
+       APICFUNC(enable_apic_mode), \
++      APICFUNC(phys_pkg_id), \
+       }
+ extern struct genapic *genapic;
+--- linux-2.6.0/include/asm-i386/highmem.h     2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/highmem.h      2003-12-28 23:26:36.000000000 -0800
+@@ -25,26 +25,19 @@
+ #include <linux/threads.h>
+ #include <asm/kmap_types.h>
+ #include <asm/tlbflush.h>
++#include <asm/atomic_kmap.h>
+ /* declarations for highmem.c */
+ extern unsigned long highstart_pfn, highend_pfn;
+-extern pte_t *kmap_pte;
+-extern pgprot_t kmap_prot;
+ extern pte_t *pkmap_page_table;
+-
+-extern void kmap_init(void);
++extern void kmap_init(void) __init;
+ /*
+  * Right now we initialize only a single pte table. It can be extended
+  * easily, subsequent pte tables have to be allocated in one physical
+  * chunk of RAM.
+  */
+-#if NR_CPUS <= 32
+-#define PKMAP_BASE (0xff800000UL)
+-#else
+-#define PKMAP_BASE (0xff600000UL)
+-#endif
+ #ifdef CONFIG_X86_PAE
+ #define LAST_PKMAP 512
+ #else
+--- linux-2.6.0/include/asm-i386/hw_irq.h      2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/hw_irq.h       2003-12-28 23:21:44.000000000 -0800
+@@ -41,6 +41,7 @@ asmlinkage void apic_timer_interrupt(voi
+ asmlinkage void error_interrupt(void);
+ asmlinkage void spurious_interrupt(void);
+ asmlinkage void thermal_interrupt(struct pt_regs);
++#define platform_legacy_irq(irq)      ((irq) < 16)
+ #endif
+ void mask_irq(unsigned int irq);
+--- linux-2.6.0/include/asm-i386/io_apic.h     2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/io_apic.h      2003-12-28 23:21:44.000000000 -0800
+@@ -13,6 +13,46 @@
+ #ifdef CONFIG_X86_IO_APIC
++#ifdef CONFIG_PCI_USE_VECTOR
++static inline int use_pci_vector(void)        {return 1;}
++static inline void disable_edge_ioapic_vector(unsigned int vector) { }
++static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
++static inline void end_edge_ioapic_vector (unsigned int vector) { }
++#define startup_level_ioapic  startup_level_ioapic_vector
++#define shutdown_level_ioapic mask_IO_APIC_vector
++#define enable_level_ioapic   unmask_IO_APIC_vector
++#define disable_level_ioapic  mask_IO_APIC_vector
++#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector
++#define end_level_ioapic      end_level_ioapic_vector
++#define set_ioapic_affinity   set_ioapic_affinity_vector
++
++#define startup_edge_ioapic   startup_edge_ioapic_vector
++#define shutdown_edge_ioapic  disable_edge_ioapic_vector
++#define enable_edge_ioapic    unmask_IO_APIC_vector
++#define disable_edge_ioapic   disable_edge_ioapic_vector
++#define ack_edge_ioapic       ack_edge_ioapic_vector
++#define end_edge_ioapic       end_edge_ioapic_vector
++#else
++static inline int use_pci_vector(void)        {return 0;}
++static inline void disable_edge_ioapic_irq(unsigned int irq) { }
++static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
++static inline void end_edge_ioapic_irq (unsigned int irq) { }
++#define startup_level_ioapic  startup_level_ioapic_irq
++#define shutdown_level_ioapic mask_IO_APIC_irq
++#define enable_level_ioapic   unmask_IO_APIC_irq
++#define disable_level_ioapic  mask_IO_APIC_irq
++#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq
++#define end_level_ioapic      end_level_ioapic_irq
++#define set_ioapic_affinity   set_ioapic_affinity_irq
++
++#define startup_edge_ioapic   startup_edge_ioapic_irq
++#define shutdown_edge_ioapic  disable_edge_ioapic_irq
++#define enable_edge_ioapic    unmask_IO_APIC_irq
++#define disable_edge_ioapic   disable_edge_ioapic_irq
++#define ack_edge_ioapic       ack_edge_ioapic_irq
++#define end_edge_ioapic       end_edge_ioapic_irq
++#endif
++
+ #define APIC_MISMATCH_DEBUG
+ #define IO_APIC_BASE(idx) \
+@@ -177,4 +217,6 @@ extern int io_apic_set_pci_routing (int 
+ #define io_apic_assign_pci_irqs 0
+ #endif
++extern int assign_irq_vector(int irq);
++
+ #endif
+--- linux-2.6.0/include/asm-i386/ioctl.h       2003-09-08 13:58:59.000000000 -0700
++++ 25/include/asm-i386/ioctl.h        2003-12-28 23:22:30.000000000 -0800
+@@ -53,7 +53,7 @@
+        ((size) << _IOC_SIZESHIFT))
+ /* provoke compile error for invalid uses of size argument */
+-extern int __invalid_size_argument_for_IOC;
++extern unsigned int __invalid_size_argument_for_IOC;
+ #define _IOC_TYPECHECK(t) \
+       ((sizeof(t) == sizeof(t[1]) && \
+         sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-i386/kgdb.h 2003-12-28 23:21:09.000000000 -0800
+@@ -0,0 +1,69 @@
++#ifndef __KGDB
++#define __KGDB
++
++/*
++ * This file should not include ANY others.  This makes it usable
++ * most anywhere without the fear of include order or inclusion.
++ * Make it so!
++ *
++ * This file may be included all the time.  It is only active if
++ * CONFIG_KGDB is defined, otherwise it stubs out all the macros
++ * and entry points.
++ */
++#if defined(CONFIG_KGDB) && !defined(__ASSEMBLY__)
++
++extern void breakpoint(void);
++#define INIT_KGDB_INTS kgdb_enable_ints()
++
++#ifndef BREAKPOINT
++#define BREAKPOINT   asm("   int $3")
++#endif
++
++extern void kgdb_schedule_breakpoint(void);
++extern void kgdb_process_breakpoint(void);
++
++extern int kgdb_tty_hook(void);
++extern int kgdb_eth_hook(void);
++extern int kgdboe;
++
++/*
++ * GDB debug stub (or any debug stub) can point the 'linux_debug_hook'
++ * pointer to its routine and it will be entered as the first thing
++ * when a trap occurs.
++ *
++ * Return values are, at present, undefined.
++ *
++ * The debug hook routine does not necessarily return to its caller.
++ * It has the register image and thus may choose to resume execution
++ * anywhere it pleases.
++ */
++struct pt_regs;
++
++extern int kgdb_handle_exception(int trapno,
++                               int signo, int err_code, struct pt_regs *regs);
++extern int in_kgdb(struct pt_regs *regs);
++
++#ifdef CONFIG_KGDB_TS
++void kgdb_tstamp(int line, char *source, int data0, int data1);
++/*
++ * This is the time stamp function.  The macro adds the source info and
++ * does a cast on the data to allow most any 32-bit value.
++ */
++
++#define kgdb_ts(data0,data1) kgdb_tstamp(__LINE__,__FILE__,(int)data0,(int)data1)
++#else
++#define kgdb_ts(data0,data1)
++#endif
++#else                         /* CONFIG_KGDB  && ! __ASSEMBLY__ ,stubs follow... */
++#ifndef BREAKPOINT
++#define BREAKPOINT
++#endif
++#define kgdb_ts(data0,data1)
++#define in_kgdb
++#define kgdb_handle_exception
++#define breakpoint
++#define INIT_KGDB_INTS
++#define kgdb_process_breakpoint() do {} while(0)
++
++#endif
++#endif                                /* __KGDB */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-i386/kgdb_local.h   2003-12-28 23:21:07.000000000 -0800
+@@ -0,0 +1,102 @@
++#ifndef __KGDB_LOCAL
++#define ___KGDB_LOCAL
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/serial.h>
++#include <linux/serialP.h>
++#include <linux/spinlock.h>
++#include <asm/processor.h>
++#include <asm/msr.h>
++#include <asm/kgdb.h>
++
++#define PORT 0x3f8
++#ifdef CONFIG_KGDB_PORT
++#undef PORT
++#define PORT CONFIG_KGDB_PORT
++#endif
++#define IRQ 4
++#ifdef CONFIG_KGDB_IRQ
++#undef IRQ
++#define IRQ CONFIG_KGDB_IRQ
++#endif
++#define SB_CLOCK 1843200
++#define SB_BASE (SB_CLOCK/16)
++#define SB_BAUD9600 SB_BASE/9600
++#define SB_BAUD192  SB_BASE/19200
++#define SB_BAUD384  SB_BASE/38400
++#define SB_BAUD576  SB_BASE/57600
++#define SB_BAUD1152 SB_BASE/115200
++#ifdef CONFIG_KGDB_9600BAUD
++#define SB_BAUD SB_BAUD9600
++#endif
++#ifdef CONFIG_KGDB_19200BAUD
++#define SB_BAUD SB_BAUD192
++#endif
++#ifdef CONFIG_KGDB_38400BAUD
++#define SB_BAUD SB_BAUD384
++#endif
++#ifdef CONFIG_KGDB_57600BAUD
++#define SB_BAUD SB_BAUD576
++#endif
++#ifdef CONFIG_KGDB_115200BAUD
++#define SB_BAUD SB_BAUD1152
++#endif
++#ifndef SB_BAUD
++#define SB_BAUD SB_BAUD1152   /* Start with this if not given */
++#endif
++
++#ifndef CONFIG_X86_TSC
++#undef rdtsc
++#define rdtsc(a,b) if (a++ > 10000){a = 0; b++;}
++#undef rdtscll
++#define rdtscll(s) s++
++#endif
++
++#ifdef _raw_read_unlock               /* must use a name that is "define"ed, not an inline */
++#undef spin_lock
++#undef spin_trylock
++#undef spin_unlock
++#define spin_lock      _raw_spin_lock
++#define spin_trylock   _raw_spin_trylock
++#define spin_unlock    _raw_spin_unlock
++#else
++#endif
++#undef spin_unlock_wait
++#define spin_unlock_wait(x)  do { cpu_relax(); barrier();} \
++                                     while(spin_is_locked(x))
++
++#define SB_IER 1
++#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
++
++#define FLAGS 0
++#define SB_STATE { \
++     magic: SSTATE_MAGIC, \
++     baud_base: SB_BASE,  \
++     port:      PORT,     \
++     irq:       IRQ,      \
++     flags:     FLAGS,    \
++     custom_divisor:SB_BAUD}
++#define SB_INFO  { \
++      magic: SERIAL_MAGIC, \
++      port:  PORT,0,FLAGS, \
++      state: &state,       \
++      tty:   (struct tty_struct *)&state, \
++      IER:   SB_IER,       \
++      MCR:   SB_MCR}
++extern void putDebugChar(int);
++/* RTAI support needs us to really stop/start interrupts */
++
++#define kgdb_sti() __asm__ __volatile__("sti": : :"memory")
++#define kgdb_cli() __asm__ __volatile__("cli": : :"memory")
++#define kgdb_local_save_flags(x) __asm__ __volatile__(\
++                                   "pushfl ; popl %0":"=g" (x): /* no input */)
++#define kgdb_local_irq_restore(x) __asm__ __volatile__(\
++                                   "pushl %0 ; popfl": \
++                                     /* no output */ :"g" (x):"memory", "cc")
++#define kgdb_local_irq_save(x) kgdb_local_save_flags(x); kgdb_cli()
++
++#ifdef CONFIG_SERIAL
++extern void shutdown_for_kgdb(struct async_struct *info);
++#endif
++#define INIT_KDEBUG putDebugChar("+");
++#endif                                /* __KGDB_LOCAL */
+--- linux-2.6.0/include/asm-i386/kmap_types.h  2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/kmap_types.h   2003-12-28 23:26:36.000000000 -0800
+@@ -3,30 +3,36 @@
+ #include <linux/config.h>
+-#ifdef CONFIG_DEBUG_HIGHMEM
+-# define D(n) __KM_FENCE_##n ,
+-#else
+-# define D(n)
+-#endif
+-
+ enum km_type {
+-D(0)  KM_BOUNCE_READ,
+-D(1)  KM_SKB_SUNRPC_DATA,
+-D(2)  KM_SKB_DATA_SOFTIRQ,
+-D(3)  KM_USER0,
+-D(4)  KM_USER1,
+-D(5)  KM_BIO_SRC_IRQ,
+-D(6)  KM_BIO_DST_IRQ,
+-D(7)  KM_PTE0,
+-D(8)  KM_PTE1,
+-D(9)  KM_PTE2,
+-D(10) KM_IRQ0,
+-D(11) KM_IRQ1,
+-D(12) KM_SOFTIRQ0,
+-D(13) KM_SOFTIRQ1,
+-D(14) KM_TYPE_NR
+-};
+-
+-#undef D
++      /*
++       * IMPORTANT: don't move these 3 entries, and only add entries in
++       * pairs: the 4G/4G virtual stack must be 8K aligned on each cpu.
++       */
++      KM_BOUNCE_READ,
++      KM_VSTACK1,
++      KM_VSTACK0,
++      KM_LDT_PAGE15,
++      KM_LDT_PAGE0 = KM_LDT_PAGE15 + 16-1,
++      KM_USER_COPY,
++      KM_VSTACK_HOLE,
++      KM_SKB_SUNRPC_DATA,
++      KM_SKB_DATA_SOFTIRQ,
++      KM_USER0,
++      KM_USER1,
++      KM_BIO_SRC_IRQ,
++      KM_BIO_DST_IRQ,
++      KM_PTE0,
++      KM_PTE1,
++      KM_PTE2,
++      KM_IRQ0,
++      KM_IRQ1,
++      KM_SOFTIRQ0,
++      KM_SOFTIRQ1,
++      /*
++       * Add new entries in pairs:
++       * the 4G/4G virtual stack must be 8K aligned on each cpu.
++       */
++      KM_TYPE_NR
++};
+ #endif
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-i386/lockmeter.h    2003-12-28 23:26:35.000000000 -0800
+@@ -0,0 +1,123 @@
++/*
++ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ *
++ *  Modified by Ray Bryant (raybry@us.ibm.com)
++ *  Changes Copyright (C) 2000 IBM, Inc.
++ *  Added save of index in spinlock_t to improve efficiency
++ *  of "hold" time reporting for spinlocks.
++ *  Added support for hold time statistics for read and write
++ *  locks.
++ *  Moved machine dependent code here from include/lockmeter.h.
++ *
++ */
++
++#ifndef _I386_LOCKMETER_H
++#define _I386_LOCKMETER_H
++
++#include <asm/spinlock.h>
++#include <asm/rwlock.h>
++
++#include <linux/version.h>
++
++#ifdef __KERNEL__
++extern unsigned long cpu_khz;
++#define CPU_CYCLE_FREQUENCY   (cpu_khz * 1000)
++#else
++#define CPU_CYCLE_FREQUENCY   450000000
++#endif
++
++#define THIS_CPU_NUMBER               smp_processor_id()
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
++#define local_irq_save(x) \
++    __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
++
++#define local_irq_restore(x) \
++    __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
++#endif        /* Linux version 2.2.x */
++
++/*
++ * macros to cache and retrieve an index value inside of a spin lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.  Not normally a problem!!
++ * we also assume that the hash table has less than 65535 entries.
++ */
++/*
++ * instrumented spinlock structure -- never used to allocate storage
++ * only used in macros below to overlay a spinlock_t
++ */
++typedef struct inst_spinlock_s {
++      /* remember, Intel is little endian */
++      unsigned short lock;
++      unsigned short index;
++} inst_spinlock_t;
++#define PUT_INDEX(lock_ptr,indexv) ((inst_spinlock_t *)(lock_ptr))->index = indexv
++#define GET_INDEX(lock_ptr)        ((inst_spinlock_t *)(lock_ptr))->index
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++      volatile int lock;
++      unsigned short index;
++      unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr)        ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv)    ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr)         ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return the number of readers for a rwlock_t
++ */
++#define RWLOCK_READERS(rwlock_ptr)   rwlock_readers(rwlock_ptr)
++
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++      int tmp = (int) rwlock_ptr->lock;
++      /* read and write lock attempts may cause the lock value to temporarily */
++      /* be negative.  Until it is >= 0 we know nothing (i. e. can't tell if  */
++      /* is -1 because it was write locked and somebody tried to read lock it */
++      /* or if it is -1 because it was read locked and somebody tried to write*/
++      /* lock it. ........................................................... */
++      do {
++              tmp = (int) rwlock_ptr->lock;
++      } while (tmp < 0);
++      if (tmp == 0) return(0);
++      else return(RW_LOCK_BIAS-tmp);
++}
++
++/*
++ * return true if rwlock is write locked
++ * (note that other lock attempts can cause the lock value to be negative)
++ */
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock <= 0)
++#define IABS(x) ((x) > 0 ? (x) : -(x))
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)  ((IABS((rwlock_ptr)->lock) % RW_LOCK_BIAS) != 0)
++
++/* this is a lot of typing just to get gcc to emit "rdtsc" */
++static inline long long get_cycles64 (void)
++{
++      union longlong_u {
++              long long intlong;
++              struct intint_s {
++                      uint32_t eax;
++                      uint32_t edx;
++              } intint;
++      } longlong;
++
++      rdtsc(longlong.intint.eax,longlong.intint.edx);
++      return longlong.intlong;
++}
++
++#endif /* _I386_LOCKMETER_H */
+--- linux-2.6.0/include/asm-i386/mach-bigsmp/mach_apic.h       2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/mach-bigsmp/mach_apic.h        2003-12-28 23:21:32.000000000 -0800
+@@ -173,4 +173,9 @@ static inline unsigned int cpu_mask_to_a
+       return apicid;
+ }
++static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
++{
++      return cpuid_apic >> index_msb;
++}
++
+ #endif /* __ASM_MACH_APIC_H */
+--- linux-2.6.0/include/asm-i386/mach-default/irq_vectors.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/mach-default/irq_vectors.h     2003-12-28 23:21:44.000000000 -0800
+@@ -76,6 +76,18 @@
+  * Since vectors 0x00-0x1f are used/reserved for the CPU,
+  * the usable vector space is 0x20-0xff (224 vectors)
+  */
++
++/*
++ * The maximum number of vectors supported by i386 processors
++ * is limited to 256. For processors other than i386, NR_VECTORS
++ * should be changed accordingly.
++ */
++#define NR_VECTORS 256
++
++#ifdef CONFIG_PCI_USE_VECTOR
++#define NR_IRQS FIRST_SYSTEM_VECTOR
++#define NR_IRQ_VECTORS NR_IRQS
++#else
+ #ifdef CONFIG_X86_IO_APIC
+ #define NR_IRQS 224
+ # if (224 >= 32 * NR_CPUS)
+@@ -87,6 +99,7 @@
+ #define NR_IRQS 16
+ #define NR_IRQ_VECTORS NR_IRQS
+ #endif
++#endif
+ #define FPU_IRQ                       13
+--- linux-2.6.0/include/asm-i386/mach-default/mach_apic.h      2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/mach-default/mach_apic.h       2003-12-28 23:22:02.000000000 -0800
+@@ -5,12 +5,12 @@
+ #define APIC_DFR_VALUE        (APIC_DFR_FLAT)
+-static inline cpumask_t target_cpus(void)
++static inline cpumask_const_t target_cpus(void)
+ { 
+ #ifdef CONFIG_SMP
+-      return cpu_online_map;
++      return mk_cpumask_const(cpu_online_map);
+ #else
+-      return cpumask_of_cpu(0);
++      return mk_cpumask_const(cpumask_of_cpu(0));
+ #endif
+ } 
+ #define TARGET_CPUS (target_cpus())
+@@ -127,4 +127,9 @@ static inline void enable_apic_mode(void
+ {
+ }
++static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
++{
++      return cpuid_apic >> index_msb;
++}
++
+ #endif /* __ASM_MACH_APIC_H */
+--- linux-2.6.0/include/asm-i386/mach-es7000/mach_apic.h       2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-i386/mach-es7000/mach_apic.h        2003-12-28 23:22:45.000000000 -0800
+@@ -39,6 +39,7 @@ static inline cpumask_t target_cpus(void
+ #endif
+ #define APIC_BROADCAST_ID     (0xff)
++#define NO_IOAPIC_CHECK (0)
+ static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
+ { 
+@@ -191,4 +192,9 @@ static inline unsigned int cpu_mask_to_a
+       return apicid;
+ }
++static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
++{
++      return cpuid_apic >> index_msb;
++}
++
+ #endif /* __ASM_MACH_APIC_H */
+--- linux-2.6.0/include/asm-i386/mach-generic/mach_apic.h      2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/mach-generic/mach_apic.h       2003-12-28 23:21:32.000000000 -0800
+@@ -27,5 +27,6 @@
+ #define check_apicid_used (genapic->check_apicid_used)
+ #define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
+ #define enable_apic_mode (genapic->enable_apic_mode)
++#define phys_pkg_id (genapic->phys_pkg_id)
+ #endif /* __ASM_MACH_APIC_H */
+--- linux-2.6.0/include/asm-i386/mach-numaq/mach_apic.h        2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/mach-numaq/mach_apic.h 2003-12-28 23:21:32.000000000 -0800
+@@ -141,4 +141,10 @@ static inline unsigned int cpu_mask_to_a
+       return (int) 0xF;
+ }
++/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */
++static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
++{
++      return cpuid_apic >> index_msb;
++}
++
+ #endif /* __ASM_MACH_APIC_H */
+--- linux-2.6.0/include/asm-i386/mach-summit/mach_apic.h       2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/mach-summit/mach_apic.h        2003-12-28 23:21:32.000000000 -0800
+@@ -173,4 +173,15 @@ static inline unsigned int cpu_mask_to_a
+       return apicid;
+ }
++/* cpuid returns the value latched in the HW at reset, not the APIC ID
++ * register's value.  For any box whose BIOS changes APIC IDs, like
++ * clustered APIC systems, we must use hard_smp_processor_id.
++ *
++ * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
++ */
++static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
++{
++      return hard_smp_processor_id() >> index_msb;
++}
++
+ #endif /* __ASM_MACH_APIC_H */
+--- linux-2.6.0/include/asm-i386/mach-summit/mach_mpparse.h    2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-i386/mach-summit/mach_mpparse.h     2003-12-28 23:22:43.000000000 -0800
+@@ -5,11 +5,11 @@
+ extern int use_cyclone;
+-#ifdef CONFIG_NUMA
++#ifdef CONFIG_X86_SUMMIT_NUMA
+ extern void setup_summit(void);
+-#else /* !CONFIG_NUMA */
++#else
+ #define setup_summit()        {}
+-#endif /* CONFIG_NUMA */
++#endif
+ static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, 
+                               struct mpc_config_translation *translation)
+@@ -110,9 +110,9 @@ typedef enum {
+       LookOutBWPEG  = 7,  /* LookOut WPEG                        */
+ } node_type;
+-static inline int is_WPEG(node_type type){
+-      return (type == CompatWPEG || type == AltWPEG ||
+-              type == LookOutAWPEG || type == LookOutBWPEG);
++static inline int is_WPEG(struct rio_detail *rio){
++      return (rio->type == CompatWPEG || rio->type == AltWPEG ||
++              rio->type == LookOutAWPEG || rio->type == LookOutBWPEG);
+ }
+ #endif /* __ASM_MACH_MPPARSE_H */
+--- linux-2.6.0/include/asm-i386/mach-visws/mach_apic.h        2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-i386/mach-visws/mach_apic.h 2003-12-28 23:21:32.000000000 -0800
+@@ -88,4 +88,10 @@ static inline unsigned int cpu_mask_to_a
+ {
+       return cpus_coerce_const(cpumask);
+ }
++
++static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
++{
++      return cpuid_apic >> index_msb;
++}
++
+ #endif /* __ASM_MACH_APIC_H */
+--- linux-2.6.0/include/asm-i386/mmu_context.h 2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/mmu_context.h  2003-12-28 23:26:36.000000000 -0800
+@@ -29,6 +29,10 @@ static inline void switch_mm(struct mm_s
+ {
+       int cpu = smp_processor_id();
++#ifdef CONFIG_X86_SWITCH_PAGETABLES
++      if (tsk->mm)
++              tsk->thread_info->user_pgd = (void *)__pa(tsk->mm->pgd);
++#endif
+       if (likely(prev != next)) {
+               /* stop flush ipis for the previous mm */
+               cpu_clear(cpu, prev->cpu_vm_mask);
+@@ -39,12 +43,14 @@ static inline void switch_mm(struct mm_s
+               cpu_set(cpu, next->cpu_vm_mask);
+               /* Re-load page tables */
++#if !defined(CONFIG_X86_SWITCH_PAGETABLES)
+               load_cr3(next->pgd);
++#endif
+               /*
+                * load the LDT, if the LDT is different:
+                */
+-              if (unlikely(prev->context.ldt != next->context.ldt))
++              if (unlikely(prev->context.size + next->context.size))
+                       load_LDT_nolock(&next->context, cpu);
+       }
+ #ifdef CONFIG_SMP
+@@ -56,7 +62,9 @@ static inline void switch_mm(struct mm_s
+                       /* We were in lazy tlb mode and leave_mm disabled 
+                        * tlb flush IPI delivery. We must reload %cr3.
+                        */
++#if !defined(CONFIG_X86_SWITCH_PAGETABLES)
+                       load_cr3(next->pgd);
++#endif
+                       load_LDT_nolock(&next->context, cpu);
+               }
+       }
+@@ -67,6 +75,6 @@ static inline void switch_mm(struct mm_s
+       asm("movl %0,%%fs ; movl %0,%%gs": :"r" (0))
+ #define activate_mm(prev, next) \
+-      switch_mm((prev),(next),NULL)
++      switch_mm((prev),(next),current)
+ #endif
+--- linux-2.6.0/include/asm-i386/mmu.h 2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/mmu.h  2003-12-28 23:26:36.000000000 -0800
+@@ -8,10 +8,13 @@
+  *
+  * cpu_vm_mask is used to optimize ldt flushing.
+  */
++
++#define MAX_LDT_PAGES 16
++
+ typedef struct { 
+       int size;
+       struct semaphore sem;
+-      void *ldt;
++      struct page *ldt_pages[MAX_LDT_PAGES];
+ } mm_context_t;
+ #endif
+--- linux-2.6.0/include/asm-i386/mpspec.h      2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-i386/mpspec.h       2003-12-28 23:22:43.000000000 -0800
+@@ -27,10 +27,6 @@ extern unsigned long mp_lapic_addr;
+ extern int pic_mode;
+ extern int using_apic_timer;
+-#ifdef CONFIG_X86_SUMMIT
+-extern void setup_summit (void);
+-#endif
+-
+ #ifdef CONFIG_ACPI_BOOT
+ extern void mp_register_lapic (u8 id, u8 enabled);
+ extern void mp_register_lapic_address (u64 address);
+--- linux-2.6.0/include/asm-i386/page.h        2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/page.h 2003-12-28 23:26:36.000000000 -0800
+@@ -1,6 +1,8 @@
+ #ifndef _I386_PAGE_H
+ #define _I386_PAGE_H
++#include <linux/config.h>
++
+ /* PAGE_SHIFT determines the page size */
+ #define PAGE_SHIFT    12
+ #define PAGE_SIZE     (1UL << PAGE_SHIFT)
+@@ -9,11 +11,10 @@
+ #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
+ #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
+-#ifdef __KERNEL__
+-#ifndef __ASSEMBLY__
+-
+ #include <linux/config.h>
++#ifdef __KERNEL__
++#ifndef __ASSEMBLY__
+ #ifdef CONFIG_X86_USE_3DNOW
+ #include <asm/mmx.h>
+@@ -88,8 +89,19 @@ typedef struct { unsigned long pgprot; }
+  *
+  * If you want more physical memory than this then see the CONFIG_HIGHMEM4G
+  * and CONFIG_HIGHMEM64G options in the kernel configuration.
++ *
++ * Note: on PAE the kernel must never go below 32 MB, we use the
++ * first 8 entries of the 2-level boot pgd for PAE magic.
+  */
++#ifdef CONFIG_X86_4G_VM_LAYOUT
++#define __PAGE_OFFSET         (0x02000000)
++#define TASK_SIZE             (0xff000000)
++#else
++#define __PAGE_OFFSET         (0xc0000000)
++#define TASK_SIZE             (0xc0000000)
++#endif
++
+ /*
+  * This much address space is reserved for vmalloc() and iomap()
+  * as well as fixmap mappings.
+@@ -114,16 +126,10 @@ static __inline__ int get_order(unsigned
+ #endif /* __ASSEMBLY__ */
+-#ifdef __ASSEMBLY__
+-#define __PAGE_OFFSET         (0xC0000000)
+-#else
+-#define __PAGE_OFFSET         (0xC0000000UL)
+-#endif
+-
+-
+ #define PAGE_OFFSET           ((unsigned long)__PAGE_OFFSET)
+ #define VMALLOC_RESERVE               ((unsigned long)__VMALLOC_RESERVE)
+-#define MAXMEM                        (-__PAGE_OFFSET-__VMALLOC_RESERVE)
++#define __MAXMEM              (-__PAGE_OFFSET-__VMALLOC_RESERVE)
++#define MAXMEM                        ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))
+ #define __pa(x)                       ((unsigned long)(x)-PAGE_OFFSET)
+ #define __va(x)                       ((void *)((unsigned long)(x)+PAGE_OFFSET))
+ #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
+--- linux-2.6.0/include/asm-i386/pgtable.h     2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/pgtable.h      2003-12-28 23:26:36.000000000 -0800
+@@ -32,16 +32,17 @@
+ #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+ extern unsigned long empty_zero_page[1024];
+ extern pgd_t swapper_pg_dir[1024];
+-extern kmem_cache_t *pgd_cache;
+-extern kmem_cache_t *pmd_cache;
++extern kmem_cache_t *pgd_cache, *pmd_cache, *kpmd_cache;
+ extern spinlock_t pgd_lock;
+ extern struct list_head pgd_list;
+ void pmd_ctor(void *, kmem_cache_t *, unsigned long);
++void kpmd_ctor(void *, kmem_cache_t *, unsigned long);
+ void pgd_ctor(void *, kmem_cache_t *, unsigned long);
+ void pgd_dtor(void *, kmem_cache_t *, unsigned long);
+ void pgtable_cache_init(void);
+ void paging_init(void);
++void setup_identity_mappings(pgd_t *pgd_base, unsigned long start, unsigned long end);
+ #endif /* !__ASSEMBLY__ */
+@@ -51,6 +52,11 @@ void paging_init(void);
+  * newer 3-level PAE-mode page tables.
+  */
+ #ifndef __ASSEMBLY__
++
++extern void set_system_gate(unsigned int n, void *addr);
++extern void init_entry_mappings(void);
++extern void entry_trampoline_setup(void);
++
+ #ifdef CONFIG_X86_PAE
+ # include <asm/pgtable-3level.h>
+ #else
+@@ -63,7 +69,12 @@ void paging_init(void);
+ #define PGDIR_SIZE    (1UL << PGDIR_SHIFT)
+ #define PGDIR_MASK    (~(PGDIR_SIZE-1))
+-#define USER_PTRS_PER_PGD     (TASK_SIZE/PGDIR_SIZE)
++#if defined(CONFIG_X86_PAE) && defined(CONFIG_X86_4G_VM_LAYOUT)
++# define USER_PTRS_PER_PGD    4
++#else
++# define USER_PTRS_PER_PGD    ((TASK_SIZE/PGDIR_SIZE) + ((TASK_SIZE % PGDIR_SIZE) + PGDIR_SIZE-1)/PGDIR_SIZE)
++#endif
++
+ #define FIRST_USER_PGD_NR     0
+ #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
+@@ -233,6 +244,7 @@ static inline void ptep_mkdirty(pte_t *p
+ #define mk_pte(page, pgprot)  pfn_pte(page_to_pfn(page), (pgprot))
+ #define mk_pte_huge(entry) ((entry).pte_low |= _PAGE_PRESENT | _PAGE_PSE)
++#define mk_pte_phys(physpage, pgprot) pfn_pte((physpage) >> PAGE_SHIFT, pgprot)
+ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ {
+--- linux-2.6.0/include/asm-i386/processor.h   2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/processor.h    2003-12-28 23:26:36.000000000 -0800
+@@ -291,11 +291,6 @@ extern unsigned int machine_submodel_id;
+ extern unsigned int BIOS_revision;
+ extern unsigned int mca_pentium_flag;
+-/*
+- * User space process size: 3GB (default).
+- */
+-#define TASK_SIZE     (PAGE_OFFSET)
+-
+ /* This decides where the kernel will search for a free chunk of vm
+  * space during mmap's.
+  */
+@@ -406,7 +401,9 @@ struct tss_struct {
+ struct thread_struct {
+ /* cached TLS descriptors. */
+       struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
++      void *stack_page0, *stack_page1;
+       unsigned long   esp0;
++      unsigned long   sysenter_cs;
+       unsigned long   eip;
+       unsigned long   esp;
+       unsigned long   fs;
+@@ -428,6 +425,7 @@ struct thread_struct {
+ #define INIT_THREAD  {                                                        \
+       .vm86_info = NULL,                                              \
++      .sysenter_cs = __KERNEL_CS,                                     \
+       .io_bitmap_ptr = NULL,                                          \
+ }
+@@ -447,21 +445,14 @@ struct thread_struct {
+       .io_bitmap      = { [ 0 ... IO_BITMAP_LONGS] = ~0 },            \
+ }
+-static inline void load_esp0(struct tss_struct *tss, unsigned long esp0)
++static inline void
++load_esp0(struct tss_struct *tss, struct thread_struct *thread)
+ {
+-      tss->esp0 = esp0;
++      tss->esp0 = thread->esp0;
+       /* This can only happen when SEP is enabled, no need to test "SEP"arately */
+-      if ((unlikely(tss->ss1 != __KERNEL_CS))) {
+-              tss->ss1 = __KERNEL_CS;
+-              wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
+-      }
+-}
+-
+-static inline void disable_sysenter(struct tss_struct *tss)
+-{
+-      if (cpu_has_sep)  {
+-              tss->ss1 = 0;
+-              wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);
++      if (unlikely(tss->ss1 != thread->sysenter_cs)) {
++              tss->ss1 = thread->sysenter_cs;
++              wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
+       }
+ }
+@@ -491,6 +482,23 @@ extern void prepare_to_copy(struct task_
+  */
+ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
++#ifdef CONFIG_X86_HIGH_ENTRY
++#define virtual_esp0(tsk) \
++      ((unsigned long)(tsk)->thread_info->virtual_stack + ((tsk)->thread.esp0 - (unsigned long)(tsk)->thread_info->real_stack))
++#else
++# define virtual_esp0(tsk) ((tsk)->thread.esp0)
++#endif
++
++#define load_virtual_esp0(tss, task)                                  \
++      do {                                                            \
++              tss->esp0 = virtual_esp0(task);                         \
++              if (likely(cpu_has_sep) && unlikely(tss->ss1 != task->thread.sysenter_cs)) {    \
++                      tss->ss1 = task->thread.sysenter_cs;            \
++                      wrmsr(MSR_IA32_SYSENTER_CS,                     \
++                              task->thread.sysenter_cs, 0);           \
++              }                                                       \
++      } while (0)
++
+ extern unsigned long thread_saved_pc(struct task_struct *tsk);
+ void show_trace(struct task_struct *task, unsigned long *stack);
+--- linux-2.6.0/include/asm-i386/rwlock.h      2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/rwlock.h       2003-12-28 23:21:35.000000000 -0800
+@@ -20,28 +20,52 @@
+ #define RW_LOCK_BIAS           0x01000000
+ #define RW_LOCK_BIAS_STR      "0x01000000"
+-#define __build_read_lock_ptr(rw, helper)   \
+-      asm volatile(LOCK "subl $1,(%0)\n\t" \
+-                   "js 2f\n" \
+-                   "1:\n" \
+-                   LOCK_SECTION_START("") \
+-                   "2:\tcall " helper "\n\t" \
+-                   "jmp 1b\n" \
+-                   LOCK_SECTION_END \
+-                   ::"a" (rw) : "memory")
+-
+-#define __build_read_lock_const(rw, helper)   \
+-      asm volatile(LOCK "subl $1,%0\n\t" \
+-                   "js 2f\n" \
+-                   "1:\n" \
+-                   LOCK_SECTION_START("") \
+-                   "2:\tpushl %%eax\n\t" \
+-                   "leal %0,%%eax\n\t" \
+-                   "call " helper "\n\t" \
+-                   "popl %%eax\n\t" \
+-                   "jmp 1b\n" \
+-                   LOCK_SECTION_END \
+-                   :"=m" (*(volatile int *)rw) : : "memory")
++#ifdef CONFIG_SPINLINE
++
++      #define __build_read_lock_ptr(rw, helper)   \
++              asm volatile(LOCK "subl $1,(%0)\n\t" \
++                           "jns 1f\n\t" \
++                           "call " helper "\n\t" \
++                           "1:\t" \
++                           ::"a" (rw) : "memory")
++
++      #define __build_read_lock_const(rw, helper)   \
++              asm volatile(LOCK "subl $1,%0\n\t" \
++                           "jns 1f\n\t" \
++                           "pushl %%eax\n\t" \
++                           "leal %0,%%eax\n\t" \
++                           "call " helper "\n\t" \
++                           "popl %%eax\n\t" \
++                           "1:\t" \
++                           :"=m" (*(volatile int *)rw) : : "memory")
++
++#else /* !CONFIG_SPINLINE */
++
++      #define __build_read_lock_ptr(rw, helper)   \
++              asm volatile(LOCK "subl $1,(%0)\n\t" \
++                           "js 2f\n" \
++                           "1:\n" \
++                           LOCK_SECTION_START("") \
++                           "2:\tcall " helper "\n\t" \
++                           "jmp 1b\n" \
++                           LOCK_SECTION_END \
++                           ::"a" (rw) : "memory")
++
++      #define __build_read_lock_const(rw, helper)   \
++              asm volatile(LOCK "subl $1,%0\n\t" \
++                           "js 2f\n" \
++                           "1:\n" \
++                           LOCK_SECTION_START("") \
++                           "2:\tpushl %%eax\n\t" \
++                           "leal %0,%%eax\n\t" \
++                           "call " helper "\n\t" \
++                           "popl %%eax\n\t" \
++                           "jmp 1b\n" \
++                           LOCK_SECTION_END \
++                           :"=m" (*(volatile int *)rw) : : "memory")
++
++#endif /* CONFIG_SPINLINE */
++
+ #define __build_read_lock(rw, helper) do { \
+                                               if (__builtin_constant_p(rw)) \
+@@ -50,28 +74,51 @@
+                                                       __build_read_lock_ptr(rw, helper); \
+                                       } while (0)
+-#define __build_write_lock_ptr(rw, helper) \
+-      asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
+-                   "jnz 2f\n" \
+-                   "1:\n" \
+-                   LOCK_SECTION_START("") \
+-                   "2:\tcall " helper "\n\t" \
+-                   "jmp 1b\n" \
+-                   LOCK_SECTION_END \
+-                   ::"a" (rw) : "memory")
+-
+-#define __build_write_lock_const(rw, helper) \
+-      asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
+-                   "jnz 2f\n" \
+-                   "1:\n" \
+-                   LOCK_SECTION_START("") \
+-                   "2:\tpushl %%eax\n\t" \
+-                   "leal %0,%%eax\n\t" \
+-                   "call " helper "\n\t" \
+-                   "popl %%eax\n\t" \
+-                   "jmp 1b\n" \
+-                   LOCK_SECTION_END \
+-                   :"=m" (*(volatile int *)rw) : : "memory")
++#ifdef CONFIG_SPINLINE
++
++      #define __build_write_lock_ptr(rw, helper) \
++              asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
++                           "jz 1f\n\t" \
++                           "call " helper "\n\t" \
++                           "1:\n" \
++                           ::"a" (rw) : "memory")
++
++      #define __build_write_lock_const(rw, helper) \
++              asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
++                           "jz 1f\n\t" \
++                           "pushl %%eax\n\t" \
++                           "leal %0,%%eax\n\t" \
++                           "call " helper "\n\t" \
++                           "popl %%eax\n\t" \
++                           "1:\n" \
++                           :"=m" (*(volatile int *)rw) : : "memory")
++
++#else /* !CONFIG_SPINLINE */
++
++      #define __build_write_lock_ptr(rw, helper) \
++              asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
++                           "jnz 2f\n" \
++                           "1:\n" \
++                           LOCK_SECTION_START("") \
++                           "2:\tcall " helper "\n\t" \
++                           "jmp 1b\n" \
++                           LOCK_SECTION_END \
++                           ::"a" (rw) : "memory")
++
++      #define __build_write_lock_const(rw, helper) \
++              asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
++                           "jnz 2f\n" \
++                           "1:\n" \
++                           LOCK_SECTION_START("") \
++                           "2:\tpushl %%eax\n\t" \
++                           "leal %0,%%eax\n\t" \
++                           "call " helper "\n\t" \
++                           "popl %%eax\n\t" \
++                           "jmp 1b\n" \
++                           LOCK_SECTION_END \
++                           :"=m" (*(volatile int *)rw) : : "memory")
++
++#endif /* CONFIG_SPINLINE */
+ #define __build_write_lock(rw, helper)        do { \
+                                               if (__builtin_constant_p(rw)) \
+--- linux-2.6.0/include/asm-i386/setup.h       2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/setup.h        2003-12-28 23:21:45.000000000 -0800
+@@ -29,6 +29,11 @@
+ #define IST_INFO   (*(struct ist_info *) (PARAM+0x60))
+ #define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
+ #define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
++#define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
++#define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
++#define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
++#define EFI_MEMMAP ((efi_memory_desc_t *) *((unsigned long *)(PARAM+0x1d0)))
++#define EFI_MEMMAP_SIZE (*((unsigned long *) (PARAM+0x1d4)))
+ #define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
+ #define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
+ #define VIDEO_MODE (*(unsigned short *) (PARAM+0x1FA))
+--- linux-2.6.0/include/asm-i386/spinlock.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/spinlock.h     2003-12-28 23:26:34.000000000 -0800
+@@ -43,18 +43,35 @@ typedef struct {
+ #define spin_is_locked(x)     (*(volatile signed char *)(&(x)->lock) <= 0)
+ #define spin_unlock_wait(x)   do { barrier(); } while(spin_is_locked(x))
+-#define spin_lock_string \
+-      "\n1:\t" \
+-      "lock ; decb %0\n\t" \
+-      "js 2f\n" \
+-      LOCK_SECTION_START("") \
+-      "2:\t" \
+-      "rep;nop\n\t" \
+-      "cmpb $0,%0\n\t" \
+-      "jle 2b\n\t" \
+-      "jmp 1b\n" \
+-      LOCK_SECTION_END
++#ifdef CONFIG_SPINLINE
++      #define spin_lock_string \
++              "\n1:\t" \
++              "lock ; decb %0\n\t" \
++              "js 2f\n" \
++              "jmp 3f\n" \
++              "2:\t" \
++              "rep;nop\n\t" \
++              "cmpb $0,%0\n\t" \
++              "jle 2b\n\t" \
++              "jmp 1b\n" \
++              "3:\t"
++
++#else /* !CONFIG_SPINLINE */
++
++      #define spin_lock_string \
++              "\n1:\t" \
++              "lock ; decb %0\n\t" \
++              "js 2f\n" \
++              LOCK_SECTION_START("") \
++              "2:\t" \
++              "rep;nop\n\t" \
++              "cmpb $0,%0\n\t" \
++              "jle 2b\n\t" \
++              "jmp 1b\n" \
++              LOCK_SECTION_END
++
++#endif /* CONFIG_SPINLINE */
+ /*
+  * This works. Despite all the confusion.
+  * (except on PPro SMP or if we are using OOSTORE)
+@@ -138,6 +155,11 @@ here:
+  */
+ typedef struct {
+       volatile unsigned int lock;
++#ifdef CONFIG_LOCKMETER
++      /* required for LOCKMETER since all bits in lock are used */
++      /* and we need this storage for CPU and lock INDEX        */
++      unsigned lockmeter_magic;
++#endif
+ #ifdef CONFIG_DEBUG_SPINLOCK
+       unsigned magic;
+ #endif
+@@ -145,11 +167,19 @@ typedef struct {
+ #define RWLOCK_MAGIC  0xdeaf1eed
++#ifdef CONFIG_LOCKMETER
++#ifdef CONFIG_DEBUG_SPINLOCK
++#define RWLOCK_MAGIC_INIT     , 0, RWLOCK_MAGIC
++#else
++#define RWLOCK_MAGIC_INIT     , 0
++#endif
++#else /* !CONFIG_LOCKMETER */
+ #ifdef CONFIG_DEBUG_SPINLOCK
+ #define RWLOCK_MAGIC_INIT     , RWLOCK_MAGIC
+ #else
+ #define RWLOCK_MAGIC_INIT     /* */
+ #endif
++#endif /* !CONFIG_LOCKMETER */
+ #define RW_LOCK_UNLOCKED (rwlock_t) { RW_LOCK_BIAS RWLOCK_MAGIC_INIT }
+@@ -196,4 +226,60 @@ static inline int _raw_write_trylock(rwl
+       return 0;
+ }
++#ifdef CONFIG_LOCKMETER
++static inline int _raw_read_trylock(rwlock_t *lock)
++{
++/* FIXME -- replace with assembler */
++      atomic_t *count = (atomic_t *)lock;
++      atomic_dec(count);
++      if (count->counter > 0)
++              return 1;
++      atomic_inc(count);
++      return 0;
++}
++#endif
++
++#if defined(CONFIG_LOCKMETER) && defined(CONFIG_HAVE_DEC_LOCK)
++extern void _metered_spin_lock  (spinlock_t *lock);
++extern void _metered_spin_unlock(spinlock_t *lock);
++
++/*
++ *  Matches what is in arch/i386/lib/dec_and_lock.c, except this one is
++ *  "static inline" so that the spin_lock(), if actually invoked, is charged
++ *  against the real caller, not against the catch-all atomic_dec_and_lock
++ */
++static inline int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
++{
++      int counter;
++      int newcount;
++
++repeat:
++      counter = atomic_read(atomic);
++      newcount = counter-1;
++
++      if (!newcount)
++              goto slow_path;
++
++      asm volatile("lock; cmpxchgl %1,%2"
++              :"=a" (newcount)
++              :"r" (newcount), "m" (atomic->counter), "0" (counter));
++
++      /* If the above failed, "eax" will have changed */
++      if (newcount != counter)
++              goto repeat;
++      return 0;
++
++slow_path:
++      preempt_disable();
++      _metered_spin_lock(lock);
++      if (atomic_dec_and_test(atomic))
++              return 1;
++      _metered_spin_unlock(lock);
++      preempt_enable();
++      return 0;
++}
++
++#define ATOMIC_DEC_AND_LOCK
++#endif
++
+ #endif /* __ASM_SPINLOCK_H */
+--- linux-2.6.0/include/asm-i386/string.h      2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/string.h       2003-12-28 23:26:36.000000000 -0800
+@@ -56,6 +56,29 @@ __asm__ __volatile__(
+ return dest;
+ }
++/*
++ * This is a more generic variant of strncpy_count() suitable for
++ * implementing string-access routines with all sorts of return
++ * code semantics. It's used by mm/usercopy.c.
++ */
++static inline size_t strncpy_count(char * dest,const char *src,size_t count)
++{
++      __asm__ __volatile__(
++
++      "1:\tdecl %0\n\t"
++      "js 2f\n\t"
++      "lodsb\n\t"
++      "stosb\n\t"
++      "testb %%al,%%al\n\t"
++      "jne 1b\n\t"
++      "2:"
++      "incl %0"
++      : "=c" (count)
++      :"S" (src),"D" (dest),"0" (count) : "memory");
++
++      return count;
++}
++
+ #define __HAVE_ARCH_STRCAT
+ static inline char * strcat(char * dest,const char * src)
+ {
+@@ -291,7 +314,7 @@ extern void __struct_cpy_bug (void);
+ #define struct_cpy(x,y)                       \
+ ({                                            \
+       if (sizeof(*(x)) != sizeof(*(y)))       \
+-              __struct_cpy_bug;               \
++              __struct_cpy_bug();             \
+       memcpy(x, y, sizeof(*(x)));             \
+ })
+@@ -299,14 +322,9 @@ extern void __struct_cpy_bug (void);
+ static inline void * memmove(void * dest,const void * src, size_t n)
+ {
+ int d0, d1, d2;
+-if (dest<src)
+-__asm__ __volatile__(
+-      "rep\n\t"
+-      "movsb"
+-      : "=&c" (d0), "=&S" (d1), "=&D" (d2)
+-      :"0" (n),"1" (src),"2" (dest)
+-      : "memory");
+-else
++if (dest<src) {
++      memcpy(dest,src,n);
++} else
+ __asm__ __volatile__(
+       "std\n\t"
+       "rep\n\t"
+--- linux-2.6.0/include/asm-i386/system.h      2003-06-14 12:17:56.000000000 -0700
++++ 25/include/asm-i386/system.h       2003-12-28 23:21:33.000000000 -0800
+@@ -470,6 +470,7 @@ void enable_hlt(void);
+ extern unsigned long dmi_broken;
+ extern int is_sony_vaio_laptop;
++extern int es7000_plat;
+ #define BROKEN_ACPI_Sx                0x0001
+ #define BROKEN_INIT_AFTER_S1  0x0002
+--- linux-2.6.0/include/asm-i386/thread_info.h 2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/thread_info.h  2003-12-28 23:26:36.000000000 -0800
+@@ -33,23 +33,12 @@ struct thread_info {
+                                                  0-0xBFFFFFFF for user-thead
+                                                  0-0xFFFFFFFF for kernel-thread
+                                               */
+-      struct restart_block    restart_block;
++      void *real_stack, *virtual_stack, *user_pgd;
++      struct restart_block    restart_block;
+       __u8                    supervisor_stack[0];
+ };
+-#else /* !__ASSEMBLY__ */
+-
+-/* offsets into the thread_info struct for assembly code access */
+-#define TI_TASK               0x00000000
+-#define TI_EXEC_DOMAIN        0x00000004
+-#define TI_FLAGS      0x00000008
+-#define TI_STATUS     0x0000000C
+-#define TI_CPU                0x00000010
+-#define TI_PRE_COUNT  0x00000014
+-#define TI_ADDR_LIMIT 0x00000018
+-#define TI_RESTART_BLOCK 0x000001C
+-
+ #endif
+ #define PREEMPT_ACTIVE                0x4000000
+@@ -61,7 +50,7 @@ struct thread_info {
+  */
+ #ifndef __ASSEMBLY__
+-#define INIT_THREAD_INFO(tsk)                 \
++#define INIT_THREAD_INFO(tsk, thread_info)    \
+ {                                             \
+       .task           = &tsk,                 \
+       .exec_domain    = &default_exec_domain, \
+@@ -72,6 +61,7 @@ struct thread_info {
+       .restart_block = {                      \
+               .fn = do_no_restart_syscall,    \
+       },                                      \
++      .real_stack     = &thread_info,         \
+ }
+ #define init_thread_info      (init_thread_union.thread_info)
+@@ -113,6 +103,7 @@ static inline struct thread_info *curren
+ #define TIF_NEED_RESCHED      3       /* rescheduling necessary */
+ #define TIF_SINGLESTEP                4       /* restore singlestep on return to user mode */
+ #define TIF_IRET              5       /* return with iret */
++#define TIF_DB7                       6       /* has debug registers */
+ #define TIF_POLLING_NRFLAG    16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
+ #define _TIF_SYSCALL_TRACE    (1<<TIF_SYSCALL_TRACE)
+@@ -121,6 +112,7 @@ static inline struct thread_info *curren
+ #define _TIF_NEED_RESCHED     (1<<TIF_NEED_RESCHED)
+ #define _TIF_SINGLESTEP               (1<<TIF_SINGLESTEP)
+ #define _TIF_IRET             (1<<TIF_IRET)
++#define _TIF_DB7              (1<<TIF_DB7)
+ #define _TIF_POLLING_NRFLAG   (1<<TIF_POLLING_NRFLAG)
+ #define _TIF_WORK_MASK                0x0000FFFE      /* work to do on interrupt/exception return */
+--- linux-2.6.0/include/asm-i386/timer.h       2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/timer.h        2003-12-28 23:21:57.000000000 -0800
+@@ -11,6 +11,7 @@
+  *    last timer intruupt.
+  */
+ struct timer_opts{
++      char* name;
+       int (*init)(char *override);
+       void (*mark_offset)(void);
+       unsigned long (*get_offset)(void);
+@@ -39,9 +40,13 @@ extern struct timer_opts timer_cyclone;
+ #endif
+ extern unsigned long calibrate_tsc(void);
++extern void init_cpu_khz(void);
+ #ifdef CONFIG_HPET_TIMER
+ extern struct timer_opts timer_hpet;
+ extern unsigned long calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr);
+ #endif
++#ifdef CONFIG_X86_PM_TIMER
++extern struct timer_opts timer_pmtmr;
++#endif
+ #endif
+--- linux-2.6.0/include/asm-i386/tlbflush.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/tlbflush.h     2003-12-28 23:26:36.000000000 -0800
+@@ -85,22 +85,28 @@ extern unsigned long pgkern_mask;
+ static inline void flush_tlb_mm(struct mm_struct *mm)
+ {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+       if (mm == current->active_mm)
+               __flush_tlb();
++#endif
+ }
+ static inline void flush_tlb_page(struct vm_area_struct *vma,
+       unsigned long addr)
+ {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+       if (vma->vm_mm == current->active_mm)
+               __flush_tlb_one(addr);
++#endif
+ }
+ static inline void flush_tlb_range(struct vm_area_struct *vma,
+       unsigned long start, unsigned long end)
+ {
++#ifndef CONFIG_X86_SWITCH_PAGETABLES
+       if (vma->vm_mm == current->active_mm)
+               __flush_tlb();
++#endif
+ }
+ #else
+@@ -111,11 +117,10 @@ static inline void flush_tlb_range(struc
+       __flush_tlb()
+ extern void flush_tlb_all(void);
+-extern void flush_tlb_current_task(void);
+ extern void flush_tlb_mm(struct mm_struct *);
+ extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
+-#define flush_tlb()   flush_tlb_current_task()
++#define flush_tlb()   flush_tlb_all()
+ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end)
+ {
+--- linux-2.6.0/include/asm-i386/uaccess.h     2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-i386/uaccess.h      2003-12-28 23:26:36.000000000 -0800
+@@ -26,7 +26,7 @@
+ #define KERNEL_DS     MAKE_MM_SEG(0xFFFFFFFFUL)
+-#define USER_DS               MAKE_MM_SEG(PAGE_OFFSET)
++#define USER_DS               MAKE_MM_SEG(TASK_SIZE)
+ #define get_ds()      (KERNEL_DS)
+ #define get_fs()      (current_thread_info()->addr_limit)
+@@ -149,6 +149,45 @@ extern void __get_user_4(void);
+               :"=a" (ret),"=d" (x) \
+               :"0" (ptr))
++extern int get_user_size(unsigned int size, void *val, const void *ptr);
++extern int put_user_size(unsigned int size, const void *val, void *ptr);
++extern int zero_user_size(unsigned int size, void *ptr);
++extern int copy_str_fromuser_size(unsigned int size, void *val, const void *ptr);
++extern int strlen_fromuser_size(unsigned int size, const void *ptr);
++
++
++# define indirect_get_user(x,ptr)                                     \
++({    int __ret_gu,__val_gu;                                          \
++      __typeof__(ptr) __ptr_gu = (ptr);                               \
++      __ret_gu = get_user_size(sizeof(*__ptr_gu), &__val_gu,__ptr_gu) ? -EFAULT : 0;\
++      (x) = (__typeof__(*__ptr_gu))__val_gu;                          \
++      __ret_gu;                                                       \
++})
++#define indirect_put_user(x,ptr)                                      \
++({                                                                    \
++      __typeof__(*(ptr)) *__ptr_pu = (ptr), __x_pu = (x);             \
++      put_user_size(sizeof(*__ptr_pu), &__x_pu, __ptr_pu) ? -EFAULT : 0; \
++})
++#define __indirect_put_user indirect_put_user
++#define __indirect_get_user indirect_get_user
++
++#define indirect_copy_from_user(to,from,n) get_user_size(n,to,from)
++#define indirect_copy_to_user(to,from,n) put_user_size(n,from,to)
++
++#define __indirect_copy_from_user indirect_copy_from_user
++#define __indirect_copy_to_user indirect_copy_to_user
++
++#define indirect_strncpy_from_user(dst, src, count) \
++              copy_str_fromuser_size(count, dst, src)
++
++extern int strlen_fromuser_size(unsigned int size, const void *ptr);
++#define indirect_strnlen_user(str, n) strlen_fromuser_size(n, str)
++#define indirect_strlen_user(str) indirect_strnlen_user(str, ~0UL >> 1)
++
++extern int zero_user_size(unsigned int size, void *ptr);
++
++#define indirect_clear_user(mem, len) zero_user_size(len, mem)
++#define __indirect_clear_user clear_user
+ /* Careful: we have to cast the result to the type of the pointer for sign reasons */
+ /**
+@@ -168,7 +207,7 @@ extern void __get_user_4(void);
+  * Returns zero on success, or -EFAULT on error.
+  * On error, the variable @x is set to zero.
+  */
+-#define get_user(x,ptr)                                                       \
++#define direct_get_user(x,ptr)                                                \
+ ({    int __ret_gu,__val_gu;                                          \
+       switch(sizeof (*(ptr))) {                                       \
+       case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;          \
+@@ -198,7 +237,7 @@ extern void __put_user_bad(void);
+  *
+  * Returns zero on success, or -EFAULT on error.
+  */
+-#define put_user(x,ptr)                                                       \
++#define direct_put_user(x,ptr)                                                \
+   __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+@@ -222,7 +261,7 @@ extern void __put_user_bad(void);
+  * Returns zero on success, or -EFAULT on error.
+  * On error, the variable @x is set to zero.
+  */
+-#define __get_user(x,ptr) \
++#define __direct_get_user(x,ptr) \
+   __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+@@ -245,7 +284,7 @@ extern void __put_user_bad(void);
+  *
+  * Returns zero on success, or -EFAULT on error.
+  */
+-#define __put_user(x,ptr) \
++#define __direct_put_user(x,ptr) \
+   __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+ #define __put_user_nocheck(x,ptr,size)                                \
+@@ -396,7 +435,7 @@ unsigned long __copy_from_user_ll(void *
+  * On success, this will be zero.
+  */
+ static inline unsigned long
+-__copy_to_user(void __user *to, const void *from, unsigned long n)
++__direct_copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+       if (__builtin_constant_p(n)) {
+               unsigned long ret;
+@@ -434,7 +473,7 @@ __copy_to_user(void __user *to, const vo
+  * data to the requested size using zero bytes.
+  */
+ static inline unsigned long
+-__copy_from_user(void *to, const void __user *from, unsigned long n)
++__direct_copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+       if (__builtin_constant_p(n)) {
+               unsigned long ret;
+@@ -468,11 +507,11 @@ __copy_from_user(void *to, const void __
+  * On success, this will be zero.
+  */
+ static inline unsigned long
+-copy_to_user(void __user *to, const void *from, unsigned long n)
++direct_copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+       might_sleep();
+       if (access_ok(VERIFY_WRITE, to, n))
+-              n = __copy_to_user(to, from, n);
++              n = __direct_copy_to_user(to, from, n);
+       return n;
+ }
+@@ -493,11 +532,11 @@ copy_to_user(void __user *to, const void
+  * data to the requested size using zero bytes.
+  */
+ static inline unsigned long
+-copy_from_user(void *to, const void __user *from, unsigned long n)
++direct_copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+       might_sleep();
+       if (access_ok(VERIFY_READ, from, n))
+-              n = __copy_from_user(to, from, n);
++              n = __direct_copy_from_user(to, from, n);
+       else
+               memset(to, 0, n);
+       return n;
+@@ -520,10 +559,68 @@ long __strncpy_from_user(char *dst, cons
+  * If there is a limit on the length of a valid string, you may wish to
+  * consider using strnlen_user() instead.
+  */
+-#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+-long strnlen_user(const char __user *str, long n);
+-unsigned long clear_user(void __user *mem, unsigned long len);
+-unsigned long __clear_user(void __user *mem, unsigned long len);
++long direct_strncpy_from_user(char *dst, const char *src, long count);
++long __direct_strncpy_from_user(char *dst, const char *src, long count);
++#define direct_strlen_user(str) direct_strnlen_user(str, ~0UL >> 1)
++long direct_strnlen_user(const char *str, long n);
++unsigned long direct_clear_user(void *mem, unsigned long len);
++unsigned long __direct_clear_user(void *mem, unsigned long len);
++
++extern int indirect_uaccess;
++
++#ifdef CONFIG_X86_UACCESS_INDIRECT
++
++/*
++ * Return code and zeroing semantics:
++
++ __clear_user          0                      <-> bytes not done
++ clear_user            0                      <-> bytes not done
++ __copy_to_user        0                      <-> bytes not done
++ copy_to_user          0                      <-> bytes not done
++ __copy_from_user      0                      <-> bytes not done, zero rest
++ copy_from_user        0                      <-> bytes not done, zero rest
++ __get_user            0                      <-> -EFAULT
++ get_user              0                      <-> -EFAULT
++ __put_user            0                      <-> -EFAULT
++ put_user              0                      <-> -EFAULT
++ strlen_user           strlen + 1             <-> 0
++ strnlen_user          strlen + 1 (or n+1)    <-> 0
++ strncpy_from_user     strlen (or n)          <-> -EFAULT
++
++ */
++
++#define __clear_user(mem,len) __indirect_clear_user(mem,len)
++#define clear_user(mem,len) indirect_clear_user(mem,len)
++#define __copy_to_user(to,from,n) __indirect_copy_to_user(to,from,n)
++#define copy_to_user(to,from,n) indirect_copy_to_user(to,from,n)
++#define __copy_from_user(to,from,n) __indirect_copy_from_user(to,from,n)
++#define copy_from_user(to,from,n) indirect_copy_from_user(to,from,n)
++#define __get_user(val,ptr) __indirect_get_user(val,ptr)
++#define get_user(val,ptr) indirect_get_user(val,ptr)
++#define __put_user(val,ptr) __indirect_put_user(val,ptr)
++#define put_user(val,ptr) indirect_put_user(val,ptr)
++#define strlen_user(str) indirect_strlen_user(str)
++#define strnlen_user(src,count) indirect_strnlen_user(src,count)
++#define strncpy_from_user(dst,src,count) \
++                      indirect_strncpy_from_user(dst,src,count)
++
++#else
++
++#define __clear_user __direct_clear_user
++#define clear_user direct_clear_user
++#define __copy_to_user __direct_copy_to_user
++#define copy_to_user direct_copy_to_user
++#define __copy_from_user __direct_copy_from_user
++#define copy_from_user direct_copy_from_user
++#define __get_user __direct_get_user
++#define get_user direct_get_user
++#define __put_user __direct_put_user
++#define put_user direct_put_user
++#define strlen_user direct_strlen_user
++#define strnlen_user direct_strnlen_user
++#define strncpy_from_user direct_strncpy_from_user
++
++#endif /* CONFIG_X86_UACCESS_INDIRECT */
+ #endif /* __i386_UACCESS_H */
+--- linux-2.6.0/include/asm-ia64/byteorder.h   2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-ia64/byteorder.h    2003-12-28 23:22:55.000000000 -0800
+@@ -8,8 +8,9 @@
+ #include <asm/types.h>
+ #include <asm/intrinsics.h>
++#include <linux/compiler.h>
+-static __inline__ __const__ __u64
++static __inline__ __attribute_const__ __u64
+ __ia64_swab64 (__u64 x)
+ {
+       __u64 result;
+@@ -18,13 +19,13 @@ __ia64_swab64 (__u64 x)
+       return result;
+ }
+-static __inline__ __const__ __u32
++static __inline__ __attribute_const__ __u32
+ __ia64_swab32 (__u32 x)
+ {
+       return __ia64_swab64(x) >> 32;
+ }
+-static __inline__ __const__ __u16
++static __inline__ __attribute_const__ __u16
+ __ia64_swab16(__u16 x)
+ {
+       return __ia64_swab64(x) >> 48;
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-ia64/cpumask.h      2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_IA64_CPUMASK_H
++#define _ASM_IA64_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_IA64_CPUMASK_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-ia64/lockmeter.h    2003-12-28 23:26:33.000000000 -0800
+@@ -0,0 +1,72 @@
++/*
++ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ */
++
++#ifndef _IA64_LOCKMETER_H
++#define _IA64_LOCKMETER_H
++
++#ifdef local_cpu_data
++#define CPU_CYCLE_FREQUENCY   local_cpu_data->itc_freq
++#else
++#define CPU_CYCLE_FREQUENCY   my_cpu_data.itc_freq
++#endif
++#define get_cycles64()                get_cycles()
++
++#define THIS_CPU_NUMBER               smp_processor_id()
++
++/*
++ * macros to cache and retrieve an index value inside of a lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.
++ * we also assume that the hash table has less than 32767 entries.
++ */
++/*
++ * instrumented spinlock structure -- never used to allocate storage
++ * only used in macros below to overlay a spinlock_t
++ */
++typedef struct inst_spinlock_s {
++      /* remember, Intel is little endian */
++      volatile unsigned short lock;
++      volatile unsigned short index;
++} inst_spinlock_t;
++#define PUT_INDEX(lock_ptr,indexv) ((inst_spinlock_t *)(lock_ptr))->index = indexv
++#define GET_INDEX(lock_ptr)        ((inst_spinlock_t *)(lock_ptr))->index
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++      volatile int read_counter:31;
++      volatile int write_lock:1;
++      volatile unsigned short index;
++      volatile unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr)        ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv)    ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr)         ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return the number of readers for a rwlock_t
++ */
++#define RWLOCK_READERS(rwlock_ptr)    ((rwlock_ptr)->read_counter)
++
++/*
++ * return true if rwlock is write locked
++ * (note that other lock attempts can cause the lock value to be negative)
++ */
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->write_lock)
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)  ((rwlock_ptr)->read_counter)
++
++#endif /* _IA64_LOCKMETER_H */
++
+--- linux-2.6.0/include/asm-ia64/spinlock.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-ia64/spinlock.h     2003-12-28 23:26:33.000000000 -0800
+@@ -110,8 +110,18 @@ do {                                                                                      \
+ typedef struct {
+       volatile int read_counter       : 31;
+       volatile int write_lock         :  1;
++#ifdef CONFIG_LOCKMETER
++      /* required for LOCKMETER since all bits in lock are used */
++      /* and we need this storage for CPU and lock INDEX        */
++      unsigned lockmeter_magic;
++#endif
+ } rwlock_t;
++
++#ifdef CONFIG_LOCKMETER
++#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0 }
++#else
+ #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
++#endif
+ #define rwlock_init(x)                do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+ #define rwlock_is_locked(x)   (*(volatile int *) (x) != 0)
+@@ -127,6 +137,48 @@ do {                                                                                      \
+       }                                                                               \
+ } while (0)
++#ifdef CONFIG_LOCKMETER
++/*
++ * HACK: This works, but still have a timing window that affects performance:
++ * we see that no one owns the Write lock, then someone * else grabs for Write
++ * lock before we do a read_lock().
++ * This means that on rare occasions our read_lock() will stall and spin-wait
++ * until we acquire for Read, instead of simply returning a trylock failure.
++ */
++static inline int _raw_read_trylock(rwlock_t *rw)
++{
++      if (rw->write_lock) {
++              return 0;
++      } else {
++              _raw_read_lock(rw);
++              return 1;
++      }
++}
++
++static inline int _raw_write_trylock(rwlock_t *rw)
++{
++      if (!(rw->write_lock)) {
++          /* isn't currently write-locked... that looks promising... */
++          if (test_and_set_bit(31, rw) == 0) {
++              /* now it is write-locked by me... */
++              if (rw->read_counter) {
++                  /* really read-locked, so release write-lock and fail */
++                  clear_bit(31, rw);
++              } else {
++                  /* we've the the write-lock, no read-lockers... success! */
++                  barrier();
++                  return 1;
++              }
++
++          }
++      }
++
++      /* falls through ... fails to write-lock */
++      barrier();
++      return 0;
++}
++#endif
++
+ #define _raw_read_unlock(rw)                                  \
+ do {                                                          \
+       rwlock_t *__read_lock_ptr = (rw);                       \
+@@ -190,4 +242,25 @@ do {                                                                              \
+       clear_bit(31, (x));                                                             \
+ })
++#ifdef CONFIG_LOCKMETER
++extern void _metered_spin_lock  (spinlock_t *lock);
++extern void _metered_spin_unlock(spinlock_t *lock);
++
++/*
++ *  Use a less efficient, and inline, atomic_dec_and_lock() if lockmetering
++ *  so we can see the callerPC of who is actually doing the spin_lock().
++ *  Otherwise, all we see is the generic rollup of all locks done by
++ *  atomic_dec_and_lock().
++ */
++static inline int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
++{
++      _metered_spin_lock(lock);
++      if (atomic_dec_and_test(atomic))
++              return 1;
++      _metered_spin_unlock(lock);
++      return 0;
++}
++#define ATOMIC_DEC_AND_LOCK
++#endif
++
+ #endif /*  _ASM_IA64_SPINLOCK_H */
+--- linux-2.6.0/include/asm-ia64/statfs.h      2003-08-08 22:55:13.000000000 -0700
++++ 25/include/asm-ia64/statfs.h       2003-12-28 23:22:16.000000000 -0800
+@@ -43,5 +43,18 @@ struct statfs64 {
+       long f_spare[5];
+ };
++struct compat_statfs64 {
++      __u32 f_type;
++      __u32 f_bsize;
++      __u64 f_blocks;
++      __u64 f_bfree;
++      __u64 f_bavail;
++      __u64 f_files;
++      __u64 f_ffree;
++      __kernel_fsid_t f_fsid;
++      __u32 f_namelen;
++      __u32 f_frsize;
++      __u32 f_spare[5];
++} __attribute__((packed));
+ #endif /* _ASM_IA64_STATFS_H */
+--- linux-2.6.0/include/asm-m68k/byteorder.h   2003-06-14 12:18:08.000000000 -0700
++++ 25/include/asm-m68k/byteorder.h    2003-12-28 23:22:55.000000000 -0800
+@@ -2,10 +2,11 @@
+ #define _M68K_BYTEORDER_H
+ #include <asm/types.h>
++#include <linux/compiler.h>
+ #ifdef __GNUC__
+-static __inline__ __const__ __u32 ___arch__swab32(__u32 val)
++static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 val)
+ {
+       __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val));
+       return val;
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-m68k/cpumask.h      2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_M68K_CPUMASK_H
++#define _ASM_M68K_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_M68K_CPUMASK_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-m68knommu/cpumask.h 2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_M68KNOMMU_CPUMASK_H
++#define _ASM_M68KNOMMU_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_M68KNOMMU_CPUMASK_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-mips/cpumask.h      2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_MIPS_CPUMASK_H
++#define _ASM_MIPS_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_MIPS_CPUMASK_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-mips/lockmeter.h    2003-12-28 23:26:33.000000000 -0800
+@@ -0,0 +1,126 @@
++/*
++ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ *  Ported to mips32 for Asita Technologies
++ *   by D.J. Barrow ( dj.barrow@asitatechnologies.com )
++ */
++#ifndef _ASM_LOCKMETER_H
++#define _ASM_LOCKMETER_H
++
++/* do_gettimeoffset is a function pointer on mips */
++/* & it is not included by <linux/time.h> */
++#include <asm/time.h>
++#include <linux/time.h>
++#include <asm/div64.h>
++
++#define SPINLOCK_MAGIC_INIT   /* */
++
++#define CPU_CYCLE_FREQUENCY   get_cpu_cycle_frequency()
++
++#define THIS_CPU_NUMBER               smp_processor_id()
++
++static uint32_t cpu_cycle_frequency = 0;
++
++static uint32_t get_cpu_cycle_frequency(void)
++{
++    /* a total hack, slow and invasive, but ... it works */
++    int sec;
++    uint32_t start_cycles;
++    struct timeval tv;
++
++    if (cpu_cycle_frequency == 0) {   /* uninitialized */
++      do_gettimeofday(&tv);
++      sec = tv.tv_sec;        /* set up to catch the tv_sec rollover */
++      while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
++      sec = tv.tv_sec;        /* rolled over to a new sec value */
++      start_cycles = get_cycles();
++      while (sec == tv.tv_sec) { do_gettimeofday(&tv); }
++      cpu_cycle_frequency = get_cycles() - start_cycles;
++    }
++
++    return cpu_cycle_frequency;
++}
++
++extern struct timeval xtime;
++
++static uint64_t get_cycles64(void)
++{
++    static uint64_t last_get_cycles64 = 0;
++    uint64_t ret;
++    unsigned long sec;
++    unsigned long usec, usec_offset;
++
++again:
++    sec  = xtime.tv_sec;
++    usec = xtime.tv_usec;
++    usec_offset = do_gettimeoffset();
++    if ((xtime.tv_sec != sec)  ||
++      (xtime.tv_usec != usec)||
++      (usec_offset >= 20000))
++      goto again;
++
++    ret = ((uint64_t)(usec + usec_offset) * cpu_cycle_frequency);
++    /* We can't do a normal 64 bit division on mips without libgcc.a */
++    do_div(ret,1000000);
++    ret +=  ((uint64_t)sec * cpu_cycle_frequency);
++
++    /* XXX why does time go backwards?  do_gettimeoffset?  general time adj? */
++    if (ret <= last_get_cycles64)
++      ret  = last_get_cycles64+1;
++    last_get_cycles64 = ret;
++
++    return ret;
++}
++
++/*
++ * macros to cache and retrieve an index value inside of a lock
++ * these macros assume that there are less than 65536 simultaneous
++ * (read mode) holders of a rwlock.
++ * we also assume that the hash table has less than 32767 entries.
++ * the high order bit is used for write locking a rw_lock
++ */
++#define INDEX_MASK   0x7FFF0000
++#define READERS_MASK 0x0000FFFF
++#define INDEX_SHIFT 16
++#define PUT_INDEX(lockp,index)   \
++        lockp->lock = (((lockp->lock) & ~INDEX_MASK) | (index) << INDEX_SHIFT)
++#define GET_INDEX(lockp) \
++        (((lockp->lock) & INDEX_MASK) >> INDEX_SHIFT)
++
++/*
++ * macros to cache and retrieve an index value in a read/write lock
++ * as well as the cpu where a reader busy period started
++ * we use the 2nd word (the debug word) for this, so require the
++ * debug word to be present
++ */
++/*
++ * instrumented rwlock structure -- never used to allocate storage
++ * only used in macros below to overlay a rwlock_t
++ */
++typedef struct inst_rwlock_s {
++      volatile int lock;
++      unsigned short index;
++      unsigned short cpu;
++} inst_rwlock_t;
++#define PUT_RWINDEX(rwlock_ptr,indexv) ((inst_rwlock_t *)(rwlock_ptr))->index = indexv
++#define GET_RWINDEX(rwlock_ptr)        ((inst_rwlock_t *)(rwlock_ptr))->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv)    ((inst_rwlock_t *)(rwlock_ptr))->cpu = cpuv
++#define GET_RW_CPU(rwlock_ptr)         ((inst_rwlock_t *)(rwlock_ptr))->cpu
++
++/*
++ * return the number of readers for a rwlock_t
++ */
++#define RWLOCK_READERS(rwlock_ptr)   rwlock_readers(rwlock_ptr)
++
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++      int tmp = (int) rwlock_ptr->lock;
++      return (tmp >= 0) ? tmp : 0;
++}
++
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr) ((rwlock_ptr)->lock < 0)
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)  ((rwlock_ptr)->lock > 0)
++
++#endif /* _ASM_LOCKMETER_H */
+--- linux-2.6.0/include/asm-mips/spinlock.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/include/asm-mips/spinlock.h     2003-12-28 23:26:33.000000000 -0800
+@@ -91,9 +91,18 @@ static inline unsigned int _raw_spin_try
+ typedef struct {
+       volatile unsigned int lock;
++#ifdef CONFIG_LOCKMETER
++      /* required for LOCKMETER since all bits in lock are used */
++      /* and we need this storage for CPU and lock INDEX        */
++      unsigned lockmeter_magic;
++#endif
+ } rwlock_t;
++#ifdef CONFIG_LOCKMETER
++#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
++#else
+ #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
++#endif
+ #define rwlock_init(x)  do { *(x) = RW_LOCK_UNLOCKED; } while(0)
+--- linux-2.6.0/include/asm-mips/statfs.h      2003-08-08 22:55:13.000000000 -0700
++++ 25/include/asm-mips/statfs.h       2003-12-28 23:22:16.000000000 -0800
+@@ -75,6 +75,20 @@ struct statfs64 {                   /* Same as struct st
+       long            f_spare[6];
+ };
++struct compat_statfs64 {
++      __u32 f_type;
++      __u32 f_bsize;
++      __u64 f_blocks;
++      __u64 f_bfree;
++      __u64 f_bavail;
++      __u64 f_files;
++      __u64 f_ffree;
++      __kernel_fsid_t f_fsid;
++      __u32 f_namelen;
++      __u32 f_frsize;
++      __u32 f_spare[5];
++};
++
+ #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
+ #endif /* _ASM_STATFS_H */
+--- linux-2.6.0/include/asm-parisc/byteorder.h 2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-parisc/byteorder.h  2003-12-28 23:22:55.000000000 -0800
+@@ -2,10 +2,11 @@
+ #define _PARISC_BYTEORDER_H
+ #include <asm/types.h>
++#include <linux/compiler.h>
+ #ifdef __GNUC__
+-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
++static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+ {
+       __asm__("dep %0, 15, 8, %0\n\t"         /* deposit 00ab -> 0bab */
+               "shd %%r0, %0, 8, %0"           /* shift 000000ab -> 00ba */
+@@ -14,7 +15,7 @@ static __inline__ __const__ __u16 ___arc
+       return x;
+ }
+-static __inline__ __const__ __u32 ___arch__swab24(__u32 x)
++static __inline__ __attribute_const__ __u32 ___arch__swab24(__u32 x)
+ {
+       __asm__("shd %0, %0, 8, %0\n\t"         /* shift xabcxabc -> cxab */
+               "dep %0, 15, 8, %0\n\t"         /* deposit cxab -> cbab */
+@@ -24,7 +25,7 @@ static __inline__ __const__ __u32 ___arc
+       return x;
+ }
+-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
++static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+ {
+       unsigned int temp;
+       __asm__("shd %0, %0, 16, %1\n\t"        /* shift abcdabcd -> cdab */
+@@ -47,7 +48,7 @@ static __inline__ __const__ __u32 ___arc
+ **      HSHR    67452301 -> *6*4*2*0 into %0
+ **      OR      %0 | %1  -> 76543210 into %0 (all done!)
+ */
+-static __inline__ __const__ __u64 ___arch__swab64(__u64 x) {
++static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) {
+       __u64 temp;
+       __asm__("permh,3210 %0, %0\n\t"
+               "hshl %0, 8, %1\n\t"
+@@ -60,7 +61,7 @@ static __inline__ __const__ __u64 ___arc
+ #define __arch__swab64(x) ___arch__swab64(x)
+ #define __BYTEORDER_HAS_U64__
+ #elif !defined(__STRICT_ANSI__)
+-static __inline__ __const__ __u64 ___arch__swab64(__u64 x)
++static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x)
+ {
+       __u32 t1 = ___arch__swab32((__u32) x);
+       __u32 t2 = ___arch__swab32((__u32) (x >> 32));
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-parisc/cpumask.h    2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_PARISC_CPUMASK_H
++#define _ASM_PARISC_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_PARISC_CPUMASK_H */
+--- linux-2.6.0/include/asm-parisc/ioctl.h     2003-10-08 15:07:10.000000000 -0700
++++ 25/include/asm-parisc/ioctl.h      2003-12-28 23:22:30.000000000 -0800
+@@ -45,7 +45,7 @@
+        ((size) << _IOC_SIZESHIFT))
+ /* provoke compile error for invalid uses of size argument */
+-extern int __invalid_size_argument_for_IOC;
++extern unsigned int __invalid_size_argument_for_IOC;
+ #define _IOC_TYPECHECK(t) \
+       ((sizeof(t) == sizeof(t[1]) && \
+         sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
+--- linux-2.6.0/include/asm-parisc/statfs.h    2003-06-22 12:04:45.000000000 -0700
++++ 25/include/asm-parisc/statfs.h     2003-12-28 23:22:16.000000000 -0800
+@@ -41,4 +41,18 @@ struct statfs64 {
+       long f_spare[5];
+ };
++struct compat_statfs64 {
++      __u32 f_type;
++      __u32 f_bsize;
++      __u64 f_blocks;
++      __u64 f_bfree;
++      __u64 f_bavail;
++      __u64 f_files;
++      __u64 f_ffree;
++      __kernel_fsid_t f_fsid;
++      __u32 f_namelen;
++      __u32 f_frsize;
++      __u32 f_spare[5];
++};
++
+ #endif
+--- linux-2.6.0/include/asm-ppc64/byteorder.h  2003-06-14 12:18:51.000000000 -0700
++++ 25/include/asm-ppc64/byteorder.h   2003-12-28 23:22:55.000000000 -0800
+@@ -9,6 +9,7 @@
+  */
+ #include <asm/types.h>
++#include <linux/compiler.h>
+ #ifdef __GNUC__
+ #ifdef __KERNEL__
+@@ -40,7 +41,7 @@ static __inline__ void st_le32(volatile 
+ }
+ #if 0
+-static __inline__ __const__ __u16 ___arch__swab16(__u16 value)
++static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
+ {
+       __u16 result;
+@@ -50,7 +51,7 @@ static __inline__ __const__ __u16 ___arc
+       return result;
+ }
+-static __inline__ __const__ __u32 ___arch__swab32(__u32 value)
++static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
+ {
+       __u32 result;
+@@ -62,7 +63,7 @@ static __inline__ __const__ __u32 ___arc
+       return result;
+ }
+-static __inline__ __const__ __u64 ___arch__swab64(__u64 value)
++static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 value)
+ {
+       __u64 result;
+ #error implement me
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-ppc64/cpumask.h     2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_PPC64_CPUMASK_H
++#define _ASM_PPC64_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_PPC64_CPUMASK_H */
+--- linux-2.6.0/include/asm-ppc64/ioctl.h      2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-ppc64/ioctl.h       2003-12-28 23:22:30.000000000 -0800
+@@ -43,7 +43,7 @@
+        ((size) << _IOC_SIZESHIFT))
+ /* provoke compile error for invalid uses of size argument */
+-extern int __invalid_size_argument_for_IOC;
++extern unsigned int __invalid_size_argument_for_IOC;
+ #define _IOC_TYPECHECK(t) \
+        ((sizeof(t) == sizeof(t[1]) && \
+          sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
+--- linux-2.6.0/include/asm-ppc64/page.h       2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-ppc64/page.h        2003-12-28 23:22:58.000000000 -0800
+@@ -41,6 +41,7 @@
+       ( ((addr > (TASK_HPAGE_BASE-len)) && (addr < TASK_HPAGE_END)) || \
+         ((current->mm->context & CONTEXT_LOW_HPAGES) && \
+          (addr > (TASK_HPAGE_BASE_32-len)) && (addr < TASK_HPAGE_END_32)) )
++#define hugetlb_free_pgtables free_pgtables
+ #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+ #define in_hugepage_area(context, addr) \
+--- linux-2.6.0/include/asm-ppc64/statfs.h     2003-06-22 12:04:45.000000000 -0700
++++ 25/include/asm-ppc64/statfs.h      2003-12-28 23:22:16.000000000 -0800
+@@ -44,4 +44,18 @@ struct statfs64 {
+       long f_spare[5];
+ };
++struct compat_statfs64 {
++      __u32 f_type;
++      __u32 f_bsize;
++      __u64 f_blocks;
++      __u64 f_bfree;
++      __u64 f_bavail;
++      __u64 f_files;
++      __u64 f_ffree;
++      __kernel_fsid_t f_fsid;
++      __u32 f_namelen;
++      __u32 f_frsize;
++      __u32 f_spare[5];
++};
++
+ #endif  /* _PPC64_STATFS_H */
+--- linux-2.6.0/include/asm-ppc/byteorder.h    2003-06-14 12:18:09.000000000 -0700
++++ 25/include/asm-ppc/byteorder.h     2003-12-28 23:22:55.000000000 -0800
+@@ -2,6 +2,7 @@
+ #define _PPC_BYTEORDER_H
+ #include <asm/types.h>
++#include <linux/compiler.h>
+ #ifdef __GNUC__
+ #ifdef __KERNEL__
+@@ -32,7 +33,7 @@ extern __inline__ void st_le32(volatile 
+       __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
+ }
+-static __inline__ __const__ __u16 ___arch__swab16(__u16 value)
++static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
+ {
+       __u16 result;
+@@ -40,7 +41,7 @@ static __inline__ __const__ __u16 ___arc
+       return result;
+ }
+-static __inline__ __const__ __u32 ___arch__swab32(__u32 value)
++static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
+ {
+       __u32 result;
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-ppc/cpumask.h       2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_PPC_CPUMASK_H
++#define _ASM_PPC_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_PPC_CPUMASK_H */
+--- linux-2.6.0/include/asm-ppc/highmem.h      2003-10-08 15:07:10.000000000 -0700
++++ 25/include/asm-ppc/highmem.h       2003-12-28 23:22:58.000000000 -0800
+@@ -81,6 +81,7 @@ static inline void *kmap_atomic(struct p
+       unsigned int idx;
+       unsigned long vaddr;
++      /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
+       inc_preempt_count();
+       if (page < highmem_start_page)
+               return page_address(page);
+@@ -105,6 +106,7 @@ static inline void kunmap_atomic(void *k
+       if (vaddr < KMAP_FIX_BEGIN) { // FIXME
+               dec_preempt_count();
++              preempt_check_resched();
+               return;
+       }
+@@ -119,6 +121,7 @@ static inline void kunmap_atomic(void *k
+       flush_tlb_page(0, vaddr);
+ #endif
+       dec_preempt_count();
++      preempt_check_resched();
+ }
+ static inline struct page *kmap_atomic_to_page(void *ptr)
+--- linux-2.6.0/include/asm-ppc/ibm4xx.h       2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-ppc/ibm4xx.h        2003-12-28 23:22:27.000000000 -0800
+@@ -90,8 +90,6 @@ void ppc4xx_init(unsigned long r3, unsig
+ #include <platforms/4xx/ocotea.h>
+ #endif
+-#endif /* CONFIG_40x */
+-
+ #ifndef __ASSEMBLY__
+ /*
+  * The "residual" board information structure the boot loader passes
+@@ -99,6 +97,7 @@ void ppc4xx_init(unsigned long r3, unsig
+  */
+ extern bd_t __res;
+ #endif
++#endif /* CONFIG_40x */
+ #endif /* __ASM_IBM4XX_H__ */
+ #endif /* __KERNEL__ */
+--- linux-2.6.0/include/asm-ppc/ioctl.h        2003-09-27 18:57:47.000000000 -0700
++++ 25/include/asm-ppc/ioctl.h 2003-12-28 23:22:30.000000000 -0800
+@@ -38,7 +38,7 @@
+        ((size) << _IOC_SIZESHIFT))
+ /* provoke compile error for invalid uses of size argument */
+-extern int __invalid_size_argument_for_IOC;
++extern unsigned int __invalid_size_argument_for_IOC;
+ #define _IOC_TYPECHECK(t) \
+       ((sizeof(t) == sizeof(t[1]) && \
+         sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
+--- linux-2.6.0/include/asm-ppc/mpc8260.h      2003-06-14 12:17:56.000000000 -0700
++++ 25/include/asm-ppc/mpc8260.h       2003-12-28 23:22:27.000000000 -0800
+@@ -1,15 +1,36 @@
+-/* This is the single file included by all MPC8260 build options.
++/*
+  * Since there are many different boards and no standard configuration,
+  * we have a unique include file for each.  Rather than change every
+  * file that has to include MPC8260 configuration, they all include
+  * this one and the configuration switching is done here.
+  */
+ #ifdef __KERNEL__
+-#ifndef __CONFIG_8260_DEFS
+-#define __CONFIG_8260_DEFS
++#ifndef __ASM_PPC_MPC8260_H__
++#define __ASM_PPC_MPC8260_H__
+ #include <linux/config.h>
+-#include <platforms/mpc82xx.h>
++
++#ifdef CONFIG_8260
++
++#ifdef CONFIG_EST8260
++#include <platforms/est8260.h>
++#endif
++
++#ifdef CONFIG_SBS8260
++#include <platforms/sbs8260.h>
++#endif
++
++#ifdef CONFIG_RPX6
++#include <platforms/rpxsuper.h>
++#endif
++
++#ifdef CONFIG_WILLOW
++#include <platforms/willow.h>
++#endif
++
++#ifdef CONFIG_TQM8260
++#include <platforms/tqm8260.h>
++#endif
+ /* Make sure the memory translation stuff is there if PCI not used.
+  */
+@@ -34,10 +55,13 @@
+ #define IO_VIRT_ADDR  IO_PHYS_ADDR
+ #endif
++#ifndef __ASSEMBLY__
+ /* The "residual" data board information structure the boot loader
+  * hands to us.
+  */
+ extern unsigned char __res[];
++#endif
+-#endif /* !__CONFIG_8260_DEFS */
++#endif /* CONFIG_8260 */
++#endif /* !__ASM_PPC_MPC8260_H__ */
+ #endif /* __KERNEL__ */
+--- linux-2.6.0/include/asm-s390/byteorder.h   2003-06-14 12:18:51.000000000 -0700
++++ 25/include/asm-s390/byteorder.h    2003-12-28 23:22:56.000000000 -0800
+@@ -10,11 +10,12 @@
+  */
+ #include <asm/types.h>
++#include <linux/compiler.h>
+ #ifdef __GNUC__
+ #ifdef __s390x__
+-static __inline__ __const__ __u64 ___arch__swab64p(__u64 *x)
++static __inline__ __attribute_pure__ __u64 ___arch__swab64p(__const__ __u64 *x)
+ {
+       __u64 result;
+@@ -24,7 +25,7 @@ static __inline__ __const__ __u64 ___arc
+       return result;
+ }
+-static __inline__ __const__ __u64 ___arch__swab64(__u64 x)
++static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x)
+ {
+       __u64 result;
+@@ -40,7 +41,7 @@ static __inline__ void ___arch__swab64s(
+ }
+ #endif /* __s390x__ */
+-static __inline__ __const__ __u32 ___arch__swab32p(__u32 *x)
++static __inline__ __attribute_pure__ __u32 ___arch__swab32p(__const__ __u32 *x)
+ {
+       __u32 result;
+       
+@@ -58,7 +59,7 @@ static __inline__ __const__ __u32 ___arc
+       return result;
+ }
+-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
++static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+ {
+ #ifndef __s390x__
+       return ___arch__swab32p(&x);
+@@ -77,7 +78,7 @@ static __inline__ void ___arch__swab32s(
+       *x = ___arch__swab32p(x);
+ }
+-static __inline__ __const__ __u16 ___arch__swab16p(__u16 *x)
++static __inline__ __attribute_pure__ __u16 ___arch__swab16p(__const__ __u16 *x)
+ {
+       __u16 result;
+       
+@@ -93,7 +94,7 @@ static __inline__ __const__ __u16 ___arc
+       return result;
+ }
+-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
++static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+ {
+       return ___arch__swab16p(&x);
+ }
+--- linux-2.6.0/include/asm-s390/ccwdev.h      2003-07-02 14:53:17.000000000 -0700
++++ 25/include/asm-s390/ccwdev.h       2003-12-28 23:23:06.000000000 -0800
+@@ -69,7 +69,7 @@ ccw_device_id_match(const struct ccw_dev
+ /* The struct ccw device is our replacement for the globally accessible
+  * ioinfo array. ioinfo will mutate into a subchannel device later.
+  *
+- * Reference: Documentation/driver-model.txt */
++ * Reference: Documentation/s390/driver-model.txt */
+ struct ccw_device {
+       spinlock_t *ccwlock;
+       struct ccw_device_private *private;     /* cio private information */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-s390/cpumask.h      2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_S390_CPUMASK_H
++#define _ASM_S390_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_S390_CPUMASK_H */
+--- linux-2.6.0/include/asm-s390/statfs.h      2003-07-02 14:53:17.000000000 -0700
++++ 25/include/asm-s390/statfs.h       2003-12-28 23:22:16.000000000 -0800
+@@ -53,5 +53,19 @@ struct statfs64 {
+       int  f_spare[5];
+ };
++struct compat_statfs64 {
++      __u32 f_type;
++      __u32 f_bsize;
++      __u64 f_blocks;
++      __u64 f_bfree;
++      __u64 f_bavail;
++      __u64 f_files;
++      __u64 f_ffree;
++      __kernel_fsid_t f_fsid;
++      __u32 f_namelen;
++      __u32 f_frsize;
++      __u32 f_spare[5];
++};
++
+ #endif /* __s390x__ */
+ #endif
+--- linux-2.6.0/include/asm-sh/byteorder.h     2003-07-02 14:53:18.000000000 -0700
++++ 25/include/asm-sh/byteorder.h      2003-12-28 23:22:55.000000000 -0800
+@@ -6,8 +6,9 @@
+  */
+ #include <asm/types.h>
++#include <linux/compiler.h>
+-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
++static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+ {
+       __asm__("swap.b %0, %0\n\t"
+               "swap.w %0, %0\n\t"
+@@ -17,7 +18,7 @@ static __inline__ __const__ __u32 ___arc
+       return x;
+ }
+-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
++static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+ {
+       __asm__("swap.b %0, %0"
+               : "=r" (x)
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-sh/cpumask.h        2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_SH_CPUMASK_H
++#define _ASM_SH_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_SH_CPUMASK_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-sparc64/cpumask.h   2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_SPARC64_CPUMASK_H
++#define _ASM_SPARC64_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_SPARC64_CPUMASK_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-sparc64/lockmeter.h 2003-12-28 23:26:33.000000000 -0800
+@@ -0,0 +1,45 @@
++/*
++ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
++ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
++ */
++
++#ifndef _SPARC64_LOCKMETER_H
++#define _SPARC64_LOCKMETER_H
++
++#include <linux/smp.h>
++#include <asm/spinlock.h>
++#include <asm/timer.h>
++#include <asm/timex.h>
++
++/* Actually, this is not the CPU frequency by the system tick
++ * frequency which is good enough for lock metering.
++ */
++#define CPU_CYCLE_FREQUENCY   (timer_tick_offset * HZ)
++#define THIS_CPU_NUMBER               smp_processor_id()
++
++#define PUT_INDEX(lock_ptr,indexv)    (lock_ptr)->index = (indexv)
++#define GET_INDEX(lock_ptr)           (lock_ptr)->index
++
++#define PUT_RWINDEX(rwlock_ptr,indexv) (rwlock_ptr)->index = (indexv)
++#define GET_RWINDEX(rwlock_ptr)        (rwlock_ptr)->index
++#define PUT_RW_CPU(rwlock_ptr,cpuv)    (rwlock_ptr)->cpu = (cpuv)
++#define GET_RW_CPU(rwlock_ptr)         (rwlock_ptr)->cpu
++
++#define RWLOCK_READERS(rwlock_ptr)    rwlock_readers(rwlock_ptr)
++
++extern inline int rwlock_readers(rwlock_t *rwlock_ptr)
++{
++      signed int tmp = rwlock_ptr->lock;
++
++      if (tmp > 0)
++              return tmp;
++      else
++              return 0;
++}
++
++#define RWLOCK_IS_WRITE_LOCKED(rwlock_ptr)    ((signed int)((rwlock_ptr)->lock) < 0)
++#define RWLOCK_IS_READ_LOCKED(rwlock_ptr)     ((signed int)((rwlock_ptr)->lock) > 0)
++
++#define get_cycles64()        get_cycles()
++
++#endif /* _SPARC64_LOCKMETER_H */
+--- linux-2.6.0/include/asm-sparc64/spinlock.h 2003-11-23 19:03:02.000000000 -0800
++++ 25/include/asm-sparc64/spinlock.h  2003-12-28 23:26:33.000000000 -0800
+@@ -30,15 +30,23 @@
+ #ifndef CONFIG_DEBUG_SPINLOCK
+-typedef unsigned char spinlock_t;
+-#define SPIN_LOCK_UNLOCKED    0
++typedef struct {
++      unsigned char lock;
++      unsigned int  index;
++} spinlock_t;
+-#define spin_lock_init(lock)  (*((unsigned char *)(lock)) = 0)
+-#define spin_is_locked(lock)  (*((volatile unsigned char *)(lock)) != 0)
++#ifdef CONFIG_LOCKMETER
++#define SPIN_LOCK_UNLOCKED    (spinlock_t) {0, 0}
++#else
++#define SPIN_LOCK_UNLOCKED    (spinlock_t) { 0 }
++#endif
+-#define spin_unlock_wait(lock)        \
++#define spin_lock_init(__lock)        do { *(__lock) = SPIN_LOCK_UNLOCKED; } while(0)
++#define spin_is_locked(__lock)        (*((volatile unsigned char *)(&((__lock)->lock))) != 0)
++
++#define spin_unlock_wait(__lock)      \
+ do {  membar("#LoadLoad");    \
+-} while(*((volatile unsigned char *)lock))
++} while(*((volatile unsigned char *)(&(((spinlock_t *)__lock)->lock))))
+ static __inline__ void _raw_spin_lock(spinlock_t *lock)
+ {
+@@ -109,17 +117,31 @@ extern int _spin_trylock (spinlock_t *lo
+ #ifndef CONFIG_DEBUG_SPINLOCK
+-typedef unsigned int rwlock_t;
+-#define RW_LOCK_UNLOCKED      0
+-#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
+-#define rwlock_is_locked(x) (*(x) != RW_LOCK_UNLOCKED)
++#ifdef CONFIG_LOCKMETER
++typedef struct {
++      unsigned int lock;
++      unsigned int index;
++      unsigned int cpu;
++} rwlock_t;
++#define RW_LOCK_UNLOCKED       (rwlock_t) { 0, 0, 0xff }
++#else
++typedef struct {
++      unsigned int lock;
++} rwlock_t;
++#define RW_LOCK_UNLOCKED        (rwlock_t) { 0 }
++#endif
++
++#define rwlock_init(lp)               do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
++#define rwlock_is_locked(x)   ((x)->lock != 0)
++extern int __read_trylock(rwlock_t *);
+ extern void __read_lock(rwlock_t *);
+ extern void __read_unlock(rwlock_t *);
+ extern void __write_lock(rwlock_t *);
+ extern void __write_unlock(rwlock_t *);
+ extern int __write_trylock(rwlock_t *);
++#define _raw_read_trylock(p)  __read_trylock(p)
+ #define _raw_read_lock(p)     __read_lock(p)
+ #define _raw_read_unlock(p)   __read_unlock(p)
+ #define _raw_write_lock(p)    __write_lock(p)
+--- linux-2.6.0/include/asm-sparc64/statfs.h   2003-06-22 12:04:45.000000000 -0700
++++ 25/include/asm-sparc64/statfs.h    2003-12-28 23:22:16.000000000 -0800
+@@ -38,4 +38,18 @@ struct statfs64 {
+       long f_spare[5];
+ };
++struct compat_statfs64 {
++      __u32 f_type;
++      __u32 f_bsize;
++      __u64 f_blocks;
++      __u64 f_bfree;
++      __u64 f_bavail;
++      __u64 f_files;
++      __u64 f_ffree;
++      __kernel_fsid_t f_fsid;
++      __u32 f_namelen;
++      __u32 f_frsize;
++      __u32 f_spare[5];
++};
++
+ #endif
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-sparc/cpumask.h     2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_SPARC_CPUMASK_H
++#define _ASM_SPARC_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_SPARC_CPUMASK_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-um/cpumask.h        2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_UM_CPUMASK_H
++#define _ASM_UM_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_UM_CPUMASK_H */
+--- linux-2.6.0/include/asm-v850/byteorder.h   2003-06-14 12:18:30.000000000 -0700
++++ 25/include/asm-v850/byteorder.h    2003-12-28 23:22:55.000000000 -0800
+@@ -15,17 +15,18 @@
+ #define __V850_BYTEORDER_H__
+ #include <asm/types.h>
++#include <linux/compiler.h>
+ #ifdef __GNUC__
+-static __inline__ __const__ __u32 ___arch__swab32 (__u32 word)
++static __inline__ __attribute_const__ __u32 ___arch__swab32 (__u32 word)
+ {
+       __u32 res;
+       __asm__ ("bsw %1, %0" : "=r" (res) : "r" (word));
+       return res;
+ }
+-static __inline__ __const__ __u16 ___arch__swab16 (__u16 half_word)
++static __inline__ __attribute_const__ __u16 ___arch__swab16 (__u16 half_word)
+ {
+       __u16 res;
+       __asm__ ("bsh %1, %0" : "=r" (res) : "r" (half_word));
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-v850/cpumask.h      2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_V850_CPUMASK_H
++#define _ASM_V850_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_V850_CPUMASK_H */
+--- linux-2.6.0/include/asm-x86_64/acpi.h      2003-06-14 12:18:25.000000000 -0700
++++ 25/include/asm-x86_64/acpi.h       2003-12-28 23:21:33.000000000 -0800
+@@ -104,25 +104,26 @@
+         :"0"(n_hi), "1"(n_lo))
+-#ifndef CONFIG_ACPI_BOOT
+-#define acpi_lapic 0
+-#define acpi_ioapic 0
+-#else
+-#ifdef CONFIG_X86_LOCAL_APIC
++#ifdef CONFIG_ACPI_BOOT
+ extern int acpi_lapic;
+-#else
+-#define acpi_lapic 0
+-#endif
+-#ifdef CONFIG_X86_IO_APIC
+ extern int acpi_ioapic;
+-#else
+-#define acpi_ioapic 0
+-#endif
++extern int acpi_noirq;
+ /* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
+ #define FIX_ACPI_PAGES 4
+-#endif /*CONFIG_ACPI_BOOT*/
++#else /* !CONFIG_ACPI_BOOT */
++#define acpi_lapic 0
++#define acpi_ioapic 0
++#endif /* !CONFIG_ACPI_BOOT */
++
++#ifdef CONFIG_ACPI_PCI
++static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
++extern int acpi_irq_balance_set(char *str);
++#else
++static inline void acpi_noirq_set(void) { }
++static inline int acpi_irq_balance_set(char *str) { return 0; }
++#endif
+ #ifdef CONFIG_ACPI_SLEEP
+--- linux-2.6.0/include/asm-x86_64/a.out.h     2003-06-14 12:18:08.000000000 -0700
++++ 25/include/asm-x86_64/a.out.h      2003-12-28 23:22:16.000000000 -0800
+@@ -1,13 +1,11 @@
+ #ifndef __X8664_A_OUT_H__
+ #define __X8664_A_OUT_H__
+-
+-/* Note: a.out is not supported in 64bit mode. This is just here to 
+-   still let some old things compile. */ 
++/* 32bit a.out */
+ struct exec
+ {
+-  unsigned long a_info;               /* Use macros N_MAGIC, etc for access */
++  unsigned int a_info;                /* Use macros N_MAGIC, etc for access */
+   unsigned a_text;            /* length of text, in bytes */
+   unsigned a_data;            /* length of data, in bytes */
+   unsigned a_bss;             /* length of uninitialized data area for file, in bytes */
+@@ -23,7 +21,7 @@ struct exec
+ #ifdef __KERNEL__
+-#define STACK_TOP     TASK_SIZE
++#define STACK_TOP     0xc0000000
+ #endif
+--- linux-2.6.0/include/asm-x86_64/byteorder.h 2003-06-14 12:18:29.000000000 -0700
++++ 25/include/asm-x86_64/byteorder.h  2003-12-28 23:22:55.000000000 -0800
+@@ -2,16 +2,17 @@
+ #define _X86_64_BYTEORDER_H
+ #include <asm/types.h>
++#include <linux/compiler.h>
+ #ifdef __GNUC__
+-static __inline__ __const__ __u64 ___arch__swab64(__u64 x)
++static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x)
+ {
+       __asm__("bswapq %0" : "=r" (x) : "0" (x));
+       return x;
+ }
+-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
++static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+ {
+       __asm__("bswapl %0" : "=r" (x) : "0" (x));
+       return x;
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/asm-x86_64/cpumask.h    2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,6 @@
++#ifndef _ASM_X86_64_CPUMASK_H
++#define _ASM_X86_64_CPUMASK_H
++
++#include <asm-generic/cpumask.h>
++
++#endif /* _ASM_X86_64_CPUMASK_H */
+--- linux-2.6.0/include/asm-x86_64/hw_irq.h    2003-11-23 19:03:02.000000000 -0800
++++ 25/include/asm-x86_64/hw_irq.h     2003-12-28 23:21:44.000000000 -0800
+@@ -173,6 +173,8 @@ static inline void hw_resend_irq(struct 
+ static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
+ #endif
++#define platform_legacy_irq(irq)      ((irq) < 16)
++
+ #endif
+ #endif /* _ASM_HW_IRQ_H */
+--- linux-2.6.0/include/asm-x86_64/io_apic.h   2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-x86_64/io_apic.h    2003-12-28 23:21:44.000000000 -0800
+@@ -174,6 +174,25 @@ extern int sis_apic_bug; /* dummy */ 
+ #define io_apic_assign_pci_irqs 0
+ #endif
++static inline int use_pci_vector(void)        {return 0;}
++static inline void disable_edge_ioapic_irq(unsigned int irq) { }
++static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
++static inline void end_edge_ioapic_irq (unsigned int irq) { }
++#define startup_level_ioapic  startup_level_ioapic_irq
++#define shutdown_level_ioapic mask_IO_APIC_irq
++#define enable_level_ioapic   unmask_IO_APIC_irq
++#define disable_level_ioapic  mask_IO_APIC_irq
++#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq
++#define end_level_ioapic      end_level_ioapic_irq
++#define set_ioapic_affinity   set_ioapic_affinity_irq
++
++#define startup_edge_ioapic   startup_edge_ioapic_irq
++#define shutdown_edge_ioapic  disable_edge_ioapic_irq
++#define enable_edge_ioapic    unmask_IO_APIC_irq
++#define disable_edge_ioapic   disable_edge_ioapic_irq
++#define ack_edge_ioapic       ack_edge_ioapic_irq
++#define end_edge_ioapic       end_edge_ioapic_irq
++
+ void enable_NMI_through_LVT0 (void * dummy);
+ #endif
+--- linux-2.6.0/include/asm-x86_64/io.h        2003-08-22 19:23:42.000000000 -0700
++++ 25/include/asm-x86_64/io.h 2003-12-28 23:26:30.000000000 -0800
+@@ -304,8 +304,8 @@ out:
+ /* Disable vmerge for now. Need to fix the block layer code
+    to check for non iommu addresses first.
+    When the IOMMU is force it is safe to enable. */
+-extern int force_iommu; 
+-#define BIO_VERMGE_BOUNDARY (force_iommu ? 4096 : 0)
++extern int iommu_merge;
++#define BIO_VMERGE_BOUNDARY (iommu_merge ? 4096 : 0)
+ #endif /* __KERNEL__ */
+--- linux-2.6.0/include/asm-x86_64/statfs.h    2003-06-22 12:04:45.000000000 -0700
++++ 25/include/asm-x86_64/statfs.h     2003-12-28 23:22:16.000000000 -0800
+@@ -41,4 +41,18 @@ struct statfs64 {
+       long f_spare[5];
+ };
++struct compat_statfs64 {
++      __u32 f_type;
++      __u32 f_bsize;
++      __u64 f_blocks;
++      __u64 f_bfree;
++      __u64 f_bavail;
++      __u64 f_files;
++      __u64 f_ffree;
++      __kernel_fsid_t f_fsid;
++      __u32 f_namelen;
++      __u32 f_frsize;
++      __u32 f_spare[5];
++} __attribute__((packed));
++
+ #endif
+--- linux-2.6.0/include/asm-x86_64/stat.h      2003-06-14 12:18:33.000000000 -0700
++++ 25/include/asm-x86_64/stat.h       2003-12-28 23:22:16.000000000 -0800
+@@ -26,4 +26,19 @@ struct stat {
+       long            __unused[3];
+ };
++/* For 32bit emulation */
++struct __old_kernel_stat {
++      unsigned short st_dev;
++      unsigned short st_ino;
++      unsigned short st_mode;
++      unsigned short st_nlink;
++      unsigned short st_uid;
++      unsigned short st_gid;
++      unsigned short st_rdev;
++      unsigned int  st_size;
++      unsigned int  st_atime;
++      unsigned int  st_mtime;
++      unsigned int  st_ctime;
++};
++
+ #endif
+--- linux-2.6.0/include/linux/aio.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/aio.h     2003-12-28 23:26:44.000000000 -0800
+@@ -29,21 +29,26 @@ struct kioctx;
+ #define KIF_LOCKED            0
+ #define KIF_KICKED            1
+ #define KIF_CANCELLED         2
++#define KIF_SYNCED            3
+ #define kiocbTryLock(iocb)    test_and_set_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbTryKick(iocb)    test_and_set_bit(KIF_KICKED, &(iocb)->ki_flags)
++#define kiocbTrySync(iocb)    test_and_set_bit(KIF_SYNCED, &(iocb)->ki_flags)
+ #define kiocbSetLocked(iocb)  set_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbSetKicked(iocb)  set_bit(KIF_KICKED, &(iocb)->ki_flags)
+ #define kiocbSetCancelled(iocb)       set_bit(KIF_CANCELLED, &(iocb)->ki_flags)
++#define kiocbSetSynced(iocb)  set_bit(KIF_SYNCED, &(iocb)->ki_flags)
+ #define kiocbClearLocked(iocb)        clear_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbClearKicked(iocb)        clear_bit(KIF_KICKED, &(iocb)->ki_flags)
+ #define kiocbClearCancelled(iocb)     clear_bit(KIF_CANCELLED, &(iocb)->ki_flags)
++#define kiocbClearSynced(iocb)        clear_bit(KIF_SYNCED, &(iocb)->ki_flags)
+ #define kiocbIsLocked(iocb)   test_bit(KIF_LOCKED, &(iocb)->ki_flags)
+ #define kiocbIsKicked(iocb)   test_bit(KIF_KICKED, &(iocb)->ki_flags)
+ #define kiocbIsCancelled(iocb)        test_bit(KIF_CANCELLED, &(iocb)->ki_flags)
++#define kiocbIsSynced(iocb)   test_bit(KIF_SYNCED, &(iocb)->ki_flags)
+ struct kiocb {
+       struct list_head        ki_run_list;
+@@ -54,7 +59,7 @@ struct kiocb {
+       struct file             *ki_filp;
+       struct kioctx           *ki_ctx;        /* may be NULL for sync ops */
+       int                     (*ki_cancel)(struct kiocb *, struct io_event *);
+-      long                    (*ki_retry)(struct kiocb *);
++      ssize_t                 (*ki_retry)(struct kiocb *);
+       struct list_head        ki_list;        /* the aio core uses this
+                                                * for cancellation */
+@@ -63,6 +68,16 @@ struct kiocb {
+       __u64                   ki_user_data;   /* user's data for completion */
+       loff_t                  ki_pos;
++      /* State that we remember to be able to restart/retry  */
++      unsigned short          ki_opcode;
++      size_t                  ki_nbytes;      /* copy of iocb->aio_nbytes */
++      char                    *ki_buf;        /* remaining iocb->aio_buf */
++      size_t                  ki_left;        /* remaining bytes */
++      wait_queue_t            ki_wait;
++      long                    ki_retried;     /* just for testing */
++      long                    ki_kicked;      /* just for testing */
++      long                    ki_queued;      /* just for testing */
++
+       char                    private[KIOCB_PRIVATE_SIZE];
+ };
+@@ -77,6 +92,8 @@ struct kiocb {
+               (x)->ki_ctx = &tsk->active_mm->default_kioctx;  \
+               (x)->ki_cancel = NULL;                  \
+               (x)->ki_user_obj = tsk;                 \
++              (x)->ki_user_data = 0;                  \
++              init_wait((&(x)->ki_wait));             \
+       } while (0)
+ #define AIO_RING_MAGIC                        0xa10a10a1
+@@ -159,6 +176,17 @@ int FASTCALL(io_submit_one(struct kioctx
+ #define get_ioctx(kioctx)     do { if (unlikely(atomic_read(&(kioctx)->users) <= 0)) BUG(); atomic_inc(&(kioctx)->users); } while (0)
+ #define put_ioctx(kioctx)     do { if (unlikely(atomic_dec_and_test(&(kioctx)->users))) __put_ioctx(kioctx); else if (unlikely(atomic_read(&(kioctx)->users) < 0)) BUG(); } while (0)
++#define in_aio() !is_sync_wait(current->io_wait)
++/* may be used for debugging */
++#define warn_if_async()       if (in_aio()) {\
++      printk(KERN_ERR "%s(%s:%d) called in async context!\n", \
++      __FUNCTION__, __FILE__, __LINE__); \
++      dump_stack(); \
++      }
++
++#define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait)
++#define is_retried_kiocb(iocb) ((iocb)->ki_retried > 1)
++
+ #include <linux/aio_abi.h>
+ static inline struct kiocb *list_kiocb(struct list_head *h)
+@@ -167,6 +195,7 @@ static inline struct kiocb *list_kiocb(s
+ }
+ /* for sysctl: */
+-extern unsigned aio_max_nr, aio_max_size, aio_max_pinned;
++extern atomic_t aio_nr;
++extern unsigned aio_max_nr;
+ #endif /* __LINUX__AIO_H */
+--- linux-2.6.0/include/linux/arcdevice.h      2003-07-27 12:14:40.000000000 -0700
++++ 25/include/linux/arcdevice.h       2003-12-28 23:21:01.000000000 -0800
+@@ -331,6 +331,7 @@ void arcnet_dump_packet(struct net_devic
+ void arcnet_unregister_proto(struct ArcProto *proto);
+ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+ void arcdev_setup(struct net_device *dev);
++struct net_device *alloc_arcdev(char *name);
+ void arcnet_rx(struct net_device *dev, int bufnum);
+ #endif                                /* __KERNEL__ */
+--- linux-2.6.0/include/linux/bio.h    2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/bio.h     2003-12-28 23:22:57.000000000 -0800
+@@ -162,7 +162,7 @@ struct bio {
+  */
+ #define __BVEC_END(bio)               bio_iovec_idx((bio), (bio)->bi_vcnt - 1)
+-#define __BVEC_START(bio)     bio_iovec_idx((bio), 0)
++#define __BVEC_START(bio)     bio_iovec_idx((bio), (bio)->bi_idx)
+ #define BIOVEC_PHYS_MERGEABLE(vec1, vec2)     \
+       ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2)))
+ #define BIOVEC_VIRT_MERGEABLE(vec1, vec2)     \
+--- linux-2.6.0/include/linux/blkdev.h 2003-12-17 21:20:03.000000000 -0800
++++ 25/include/linux/blkdev.h  2003-12-28 23:26:41.000000000 -0800
+@@ -195,11 +195,6 @@ enum rq_flag_bits {
+       __REQ_PM_SUSPEND,       /* suspend request */
+       __REQ_PM_RESUME,        /* resume request */
+       __REQ_PM_SHUTDOWN,      /* shutdown request */
+-      __REQ_IDETAPE_PC1,      /* packet command (first stage) */
+-      __REQ_IDETAPE_PC2,      /* packet command (second stage) */
+-      __REQ_IDETAPE_READ,
+-      __REQ_IDETAPE_WRITE,
+-      __REQ_IDETAPE_READ_BUFFER,
+       __REQ_NR_BITS,          /* stops here */
+ };
+@@ -225,11 +220,6 @@ enum rq_flag_bits {
+ #define REQ_PM_SUSPEND        (1 << __REQ_PM_SUSPEND)
+ #define REQ_PM_RESUME (1 << __REQ_PM_RESUME)
+ #define REQ_PM_SHUTDOWN       (1 << __REQ_PM_SHUTDOWN)
+-#define REQ_IDETAPE_PC1 (1 << __REQ_IDETAPE_PC1)
+-#define REQ_IDETAPE_PC2 (1 << __REQ_IDETAPE_PC2)
+-#define REQ_IDETAPE_READ      (1 << __REQ_IDETAPE_READ)
+-#define REQ_IDETAPE_WRITE     (1 << __REQ_IDETAPE_WRITE)
+-#define REQ_IDETAPE_READ_BUFFER       (1 << __REQ_IDETAPE_READ_BUFFER)
+ /*
+  * State information carried for REQ_PM_SUSPEND and REQ_PM_RESUME
+@@ -597,6 +587,7 @@ extern void blk_queue_free_tags(request_
+ extern int blk_queue_resize_tags(request_queue_t *, int);
+ extern void blk_queue_invalidate_tags(request_queue_t *);
+ extern void blk_congestion_wait(int rw, long timeout);
++extern int blk_congestion_wait_wq(int rw, long timeout, wait_queue_t *wait);
+ extern void blk_rq_bio_prep(request_queue_t *, struct request *, struct bio *);
+ extern void blk_rq_prep_restart(struct request *);
+--- linux-2.6.0/include/linux/buffer_head.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/buffer_head.h     2003-12-28 23:26:42.000000000 -0800
+@@ -162,6 +162,7 @@ void mark_buffer_async_write(struct buff
+ void invalidate_bdev(struct block_device *, int);
+ int sync_blockdev(struct block_device *bdev);
+ void __wait_on_buffer(struct buffer_head *);
++int __wait_on_buffer_wq(struct buffer_head *, wait_queue_t *wait);
+ wait_queue_head_t *bh_waitq_head(struct buffer_head *bh);
+ void wake_up_buffer(struct buffer_head *bh);
+ int fsync_bdev(struct block_device *);
+@@ -173,6 +174,8 @@ void __brelse(struct buffer_head *);
+ void __bforget(struct buffer_head *);
+ void __breadahead(struct block_device *, sector_t block, int size);
+ struct buffer_head *__bread(struct block_device *, sector_t block, int size);
++struct buffer_head *__bread_wq(struct block_device *, sector_t block,
++      int size, wait_queue_t *wait);
+ struct buffer_head *alloc_buffer_head(int gfp_flags);
+ void free_buffer_head(struct buffer_head * bh);
+ void FASTCALL(unlock_buffer(struct buffer_head *bh));
+@@ -207,12 +210,6 @@ int nobh_prepare_write(struct page*, uns
+ int nobh_commit_write(struct file *, struct page *, unsigned, unsigned);
+ int nobh_truncate_page(struct address_space *, loff_t);
+-#define OSYNC_METADATA        (1<<0)
+-#define OSYNC_DATA    (1<<1)
+-#define OSYNC_INODE   (1<<2)
+-int generic_osync_inode(struct inode *, int);
+-
+-
+ /*
+  * inline definitions
+  */
+@@ -230,13 +227,13 @@ static inline void put_bh(struct buffer_
+ static inline void brelse(struct buffer_head *bh)
+ {
+-      if (bh)
++      if (bh && !IS_ERR(bh))
+               __brelse(bh);
+ }
+ static inline void bforget(struct buffer_head *bh)
+ {
+-      if (bh)
++      if (bh && !IS_ERR(bh))
+               __bforget(bh);
+ }
+@@ -253,7 +250,12 @@ sb_breadahead(struct super_block *sb, se
+ }
+ static inline struct buffer_head *
+-sb_getblk(struct super_block *sb, sector_t block)
++sb_bread_wq(struct super_block *sb, sector_t block, wait_queue_t *wait)
++{
++      return __bread_wq(sb->s_bdev, block, sb->s_blocksize, wait);
++}
++
++static inline struct buffer_head *sb_getblk(struct super_block *sb, sector_t block)
+ {
+       return __getblk(sb->s_bdev, block, sb->s_blocksize);
+ }
+@@ -277,16 +279,34 @@ map_bh(struct buffer_head *bh, struct su
+  * __wait_on_buffer() just to trip a debug check.  Because debug code in inline
+  * functions is bloaty.
+  */
+-static inline void wait_on_buffer(struct buffer_head *bh)
++
++static inline int wait_on_buffer_wq(struct buffer_head *bh, wait_queue_t *wait)
+ {
+       if (buffer_locked(bh) || atomic_read(&bh->b_count) == 0)
+-              __wait_on_buffer(bh);
++              return __wait_on_buffer_wq(bh, wait);
++
++      return 0;
++}
++
++static inline void wait_on_buffer(struct buffer_head *bh)
++{
++      wait_on_buffer_wq(bh, NULL);
++}
++
++static inline int lock_buffer_wq(struct buffer_head *bh, wait_queue_t *wait)
++{
++      while (test_set_buffer_locked(bh)) {
++              int ret = __wait_on_buffer_wq(bh, wait);
++              if (ret)
++                      return ret;
++      }
++
++      return 0;
+ }
+ static inline void lock_buffer(struct buffer_head *bh)
+ {
+-      while (test_set_buffer_locked(bh))
+-              __wait_on_buffer(bh);
++      lock_buffer_wq(bh, NULL);
+ }
+ #endif /* _LINUX_BUFFER_HEAD_H */
+--- linux-2.6.0/include/linux/byteorder/swab.h 2003-06-14 12:18:51.000000000 -0700
++++ 25/include/linux/byteorder/swab.h  2003-12-28 23:22:55.000000000 -0800
+@@ -15,6 +15,8 @@
+  *
+  */
++#include <linux/compiler.h>
++
+ /* casts are necessary for constants, because we never know how for sure
+  * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
+  */
+@@ -128,7 +130,7 @@
+ #endif /* OPTIMIZE */
+-static __inline__ __const__ __u16 __fswab16(__u16 x)
++static __inline__ __attribute_const__ __u16 __fswab16(__u16 x)
+ {
+       return __arch__swab16(x);
+ }
+@@ -141,7 +143,7 @@ static __inline__ void __swab16s(__u16 *
+       __arch__swab16s(addr);
+ }
+-static __inline__ __const__ __u32 __fswab32(__u32 x)
++static __inline__ __attribute_const__ __u32 __fswab32(__u32 x)
+ {
+       return __arch__swab32(x);
+ }
+@@ -155,7 +157,7 @@ static __inline__ void __swab32s(__u32 *
+ }
+ #ifdef __BYTEORDER_HAS_U64__
+-static __inline__ __const__ __u64 __fswab64(__u64 x)
++static __inline__ __attribute_const__ __u64 __fswab64(__u64 x)
+ {
+ #  ifdef __SWAB_64_THRU_32__
+       __u32 h = x >> 32;
+--- linux-2.6.0/include/linux/cdrom.h  2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/cdrom.h   2003-12-28 23:22:35.000000000 -0800
+@@ -5,7 +5,7 @@
+  *               1994, 1995   Eberhard Moenkeberg, emoenke@gwdg.de
+  *               1996         David van Leeuwen, david@tm.tno.nl
+  *               1997, 1998   Erik Andersen, andersee@debian.org
+- *               1998-2000    Jens Axboe, axboe@suse.de
++ *               1998-2002    Jens Axboe, axboe@suse.de
+  */
+  
+ #ifndef       _LINUX_CDROM_H
+@@ -388,6 +388,9 @@ struct cdrom_generic_command
+ #define CDC_DVD_R             0x10000 /* drive can write DVD-R */
+ #define CDC_DVD_RAM           0x20000 /* drive can write DVD-RAM */
+ #define CDC_MO_DRIVE          0x40000 /* drive is an MO device */
++#define CDC_MRW                       0x80000 /* drive can read MRW */
++#define CDC_MRW_W             0x100000 /* drive can write MRW */
++#define CDC_RAM                       0x200000 /* ok to open for WRITE */
+ /* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */
+ #define CDS_NO_INFO           0       /* if not implemented */
+@@ -715,92 +718,57 @@ struct request_sense {
+       __u8 asb[46];
+ };
+-#ifdef __KERNEL__
+-#include <linux/fs.h>         /* not really needed, later.. */
+-#include <linux/device.h>
+-
+-struct cdrom_write_settings {
+-      unsigned char fpacket;          /* fixed/variable packets */
+-      unsigned long packet_size;      /* write out this number of packets */
+-      unsigned long nwa;              /* next writeable address */
+-      unsigned char writeable;        /* cdrom is writeable */
+-};
+-
+-/* Uniform cdrom data structures for cdrom.c */
+-struct cdrom_device_info {
+-      struct cdrom_device_ops  *ops;  /* link to device_ops */
+-      struct cdrom_device_info *next; /* next device_info for this major */
+-      void *handle;                   /* driver-dependent data */
+-/* specifications */
+-      int mask;                       /* mask of capability: disables them */
+-      int speed;                      /* maximum speed for reading data */
+-      int capacity;                   /* number of discs in jukebox */
+-/* device-related storage */
+-      int options             : 30;   /* options flags */
+-      unsigned mc_flags       : 2;    /* media change buffer flags */
+-      int use_count;                  /* number of times device opened */
+-      char name[20];                  /* name of the device type */
+-/* per-device flags */
+-        __u8 sanyo_slot               : 2;    /* Sanyo 3 CD changer support */
+-        __u8 reserved         : 6;    /* not used yet */
+-      struct cdrom_write_settings write;
+-};
+-
+-struct cdrom_device_ops {
+-/* routines */
+-      int (*open) (struct cdrom_device_info *, int);
+-      void (*release) (struct cdrom_device_info *);
+-      int (*drive_status) (struct cdrom_device_info *, int);
+-      int (*media_changed) (struct cdrom_device_info *, int);
+-      int (*tray_move) (struct cdrom_device_info *, int);
+-      int (*lock_door) (struct cdrom_device_info *, int);
+-      int (*select_speed) (struct cdrom_device_info *, int);
+-      int (*select_disc) (struct cdrom_device_info *, int);
+-      int (*get_last_session) (struct cdrom_device_info *,
+-                               struct cdrom_multisession *);
+-      int (*get_mcn) (struct cdrom_device_info *,
+-                      struct cdrom_mcn *);
+-      /* hard reset device */
+-      int (*reset) (struct cdrom_device_info *);
+-      /* play stuff */
+-      int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *);
+-      /* dev-specific */
+-      int (*dev_ioctl) (struct cdrom_device_info *,
+-                        unsigned int, unsigned long);
+-/* driver specifications */
+-      const int capability;   /* capability flags */
+-      int n_minors;           /* number of active minor devices */
+-      /* handle uniform packets for scsi type devices (scsi,atapi) */
+-      int (*generic_packet) (struct cdrom_device_info *,
+-                             struct cdrom_generic_command *);
+-};
++/*
++ * feature profile
++ */
++#define CDF_MRW               0x28
+-/* the general block_device operations structure: */
+-extern int cdrom_open(struct cdrom_device_info *, struct inode *, struct file *);
+-extern int cdrom_release(struct cdrom_device_info *, struct file *);
+-extern int cdrom_ioctl(struct cdrom_device_info *, struct inode *, unsigned, unsigned long);
+-extern int cdrom_media_changed(struct cdrom_device_info *);
++/*
++ * media status bits
++ */
++#define CDM_MRW_NOTMRW                        0
++#define CDM_MRW_BGFORMAT_INACTIVE     1
++#define CDM_MRW_BGFORMAT_ACTIVE               2
++#define CDM_MRW_BGFORMAT_COMPLETE     3
+-extern int register_cdrom(struct cdrom_device_info *cdi);
+-extern int unregister_cdrom(struct cdrom_device_info *cdi);
++/*
++ * mrw address spaces
++ */
++#define MRW_LBA_DMA                   0
++#define MRW_LBA_GAA                   1
+-typedef struct {
+-    int data;
+-    int audio;
+-    int cdi;
+-    int xa;
+-    long error;
+-} tracktype;
++/*
++ * mrw mode pages (first is deprecated) -- probed at init time and
++ * cdi->mrw_mode_page is set
++ */
++#define MRW_MODE_PC_PRE1              0x2c
++#define MRW_MODE_PC                   0x03
+-extern int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written);
+-extern int cdrom_number_of_slots(struct cdrom_device_info *cdi);
+-extern int cdrom_mode_select(struct cdrom_device_info *cdi,
+-                           struct cdrom_generic_command *cgc);
+-extern int cdrom_mode_sense(struct cdrom_device_info *cdi,
+-                          struct cdrom_generic_command *cgc,
+-                          int page_code, int page_control);
+-extern void init_cdrom_command(struct cdrom_generic_command *cgc,
+-                             void *buffer, int len, int type);
++struct mrw_feature_desc {
++      __u16 feature_code;
++#if defined(__BIG_ENDIAN_BITFIELD)
++      __u8 reserved1          : 2;
++      __u8 feature_version    : 4;
++      __u8 persistent         : 1;
++      __u8 curr               : 1;
++#elif defined(__LITTLE_ENDIAN_BITFIELD)
++      __u8 curr               : 1;
++      __u8 persistent         : 1;
++      __u8 feature_version    : 4;
++      __u8 reserved1          : 2;
++#endif
++      __u8 add_len;
++#if defined(__BIG_ENDIAN_BITFIELD)
++      __u8 reserved2          : 7;
++      __u8 write              : 1;
++#elif defined(__LITTLE_ENDIAN_BITFIELD)
++      __u8 write              : 1;
++      __u8 reserved2          : 7;
++#endif
++      __u8 reserved3;
++      __u8 reserved4;
++      __u8 reserved5;
++};
+ typedef struct {
+       __u16 disc_information_length;
+@@ -825,9 +793,13 @@ typedef struct {
+       __u8 did_v                      : 1;
+         __u8 dbc_v                    : 1;
+         __u8 uru                      : 1;
+-        __u8 reserved2                        : 5;
++        __u8 reserved2                        : 2;
++      __u8 dbit                       : 1;
++      __u8 mrw_status                 : 2;
+ #elif defined(__LITTLE_ENDIAN_BITFIELD)
+-        __u8 reserved2                        : 5;
++      __u8 mrw_status                 : 2;
++      __u8 dbit                       : 1;
++        __u8 reserved2                        : 2;
+         __u8 uru                      : 1;
+         __u8 dbc_v                    : 1;
+       __u8 did_v                      : 1;
+@@ -884,6 +856,104 @@ typedef struct {
+       __u32 last_rec_address;
+ } track_information;
++struct feature_header {
++      __u32 data_len;
++      __u8 reserved1;
++      __u8 reserved2;
++      __u16 curr_profile;
++};
++
++struct mode_page_header {
++      __u16 mode_data_length;
++      __u8 medium_type;
++      __u8 reserved1;
++      __u8 reserved2;
++      __u8 reserved3;
++      __u16 desc_length;
++};
++
++#ifdef __KERNEL__
++#include <linux/fs.h>         /* not really needed, later.. */
++#include <linux/device.h>
++
++/* Uniform cdrom data structures for cdrom.c */
++struct cdrom_device_info {
++      struct cdrom_device_ops  *ops;  /* link to device_ops */
++      struct cdrom_device_info *next; /* next device_info for this major */
++      void *handle;                   /* driver-dependent data */
++/* specifications */
++      int mask;                       /* mask of capability: disables them */
++      int speed;                      /* maximum speed for reading data */
++      int capacity;                   /* number of discs in jukebox */
++/* device-related storage */
++      int options             : 30;   /* options flags */
++      unsigned mc_flags       : 2;    /* media change buffer flags */
++      int use_count;                  /* number of times device opened */
++      char name[20];                  /* name of the device type */
++/* per-device flags */
++        __u8 sanyo_slot               : 2;    /* Sanyo 3 CD changer support */
++        __u8 reserved         : 6;    /* not used yet */
++      int for_data;
++      int (*exit)(struct cdrom_device_info *);
++      int mrw_mode_page;
++};
++
++struct cdrom_device_ops {
++/* routines */
++      int (*open) (struct cdrom_device_info *, int);
++      void (*release) (struct cdrom_device_info *);
++      int (*drive_status) (struct cdrom_device_info *, int);
++      int (*media_changed) (struct cdrom_device_info *, int);
++      int (*tray_move) (struct cdrom_device_info *, int);
++      int (*lock_door) (struct cdrom_device_info *, int);
++      int (*select_speed) (struct cdrom_device_info *, int);
++      int (*select_disc) (struct cdrom_device_info *, int);
++      int (*get_last_session) (struct cdrom_device_info *,
++                               struct cdrom_multisession *);
++      int (*get_mcn) (struct cdrom_device_info *,
++                      struct cdrom_mcn *);
++      /* hard reset device */
++      int (*reset) (struct cdrom_device_info *);
++      /* play stuff */
++      int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *);
++      /* dev-specific */
++      int (*dev_ioctl) (struct cdrom_device_info *,
++                        unsigned int, unsigned long);
++/* driver specifications */
++      const int capability;   /* capability flags */
++      int n_minors;           /* number of active minor devices */
++      /* handle uniform packets for scsi type devices (scsi,atapi) */
++      int (*generic_packet) (struct cdrom_device_info *,
++                             struct cdrom_generic_command *);
++};
++
++/* the general block_device operations structure: */
++extern int cdrom_open(struct cdrom_device_info *, struct block_device *, struct file *);
++extern int cdrom_release(struct cdrom_device_info *);
++extern int cdrom_ioctl(struct cdrom_device_info *, struct block_device *, unsigned, unsigned long);
++extern int cdrom_media_changed(struct cdrom_device_info *);
++
++extern int register_cdrom(struct cdrom_device_info *cdi);
++extern int unregister_cdrom(struct cdrom_device_info *cdi);
++
++typedef struct {
++    int data;
++    int audio;
++    int cdi;
++    int xa;
++    long error;
++} tracktype;
++
++extern int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written);
++extern int cdrom_number_of_slots(struct cdrom_device_info *cdi);
++extern int cdrom_mode_select(struct cdrom_device_info *cdi,
++                           struct cdrom_generic_command *cgc);
++extern int cdrom_mode_sense(struct cdrom_device_info *cdi,
++                          struct cdrom_generic_command *cgc,
++                          int page_code, int page_control);
++extern void init_cdrom_command(struct cdrom_generic_command *cgc,
++                             void *buffer, int len, int type);
++
+ /* The SCSI spec says there could be 256 slots. */
+ #define CDROM_MAX_SLOTS       256
+@@ -934,15 +1004,6 @@ typedef enum {
+       mechtype_cartridge_changer  = 5
+ } mechtype_t;
+-struct mode_page_header {
+-      __u16 mode_data_length;
+-      __u8 medium_type;
+-      __u8 reserved1;
+-      __u8 reserved2;
+-      __u8 reserved3;
+-      __u16 desc_length;
+-};
+-
+ typedef struct {
+ #if defined(__BIG_ENDIAN_BITFIELD)
+       __u8 ps                 : 1;
+@@ -1032,6 +1093,41 @@ typedef struct {
+       __u8 reserved3;
+ } rpc_state_t;
++struct event_header {
++      __u16 data_len;
++#if defined(__BIG_ENDIAN_BITFIELD)
++      __u8 nea                : 1;
++      __u8 reserved1          : 4;
++      __u8 notification_class : 3;
++#elif defined(__LITTLE_ENDIAN_BITFIELD)
++      __u8 notification_class : 3;
++      __u8 reserved1          : 4;
++      __u8 nea                : 1;
++#endif
++      __u8 supp_event_class;
++};
++
++struct media_event_desc {
++#if defined(__BIG_ENDIAN_BITFIELD)
++      __u8 reserved1          : 4;
++      __u8 media_event_code   : 4;
++      __u8 reserved2          : 6;
++      __u8 media_present      : 1;
++      __u8 door_open          : 1;
++#elif defined(__LITTLE_ENDIAN_BITFIELD)
++      __u8 media_event_code   : 4;
++      __u8 reserved1          : 4;
++      __u8 door_open          : 1;
++      __u8 media_present      : 1;
++      __u8 reserved2          : 6;
++#endif
++      __u8 start_slot;
++      __u8 end_slot;
++};
++
++extern int cdrom_get_media_event(struct cdrom_device_info *cdi, struct media_event_desc *med);
++extern int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write);
++
+ #endif  /* End of kernel only stuff */ 
+ #endif  /* _LINUX_CDROM_H */
+--- linux-2.6.0/include/linux/com20020.h       2003-06-14 12:18:25.000000000 -0700
++++ 25/include/linux/com20020.h        2003-12-28 23:21:01.000000000 -0800
+@@ -29,7 +29,6 @@
+ int com20020_check(struct net_device *dev);
+ int com20020_found(struct net_device *dev, int shared);
+-void com20020_remove(struct net_device *dev);
+ /* The number of low I/O ports used by the card. */
+ #define ARCNET_TOTAL_SIZE 8
+--- linux-2.6.0/include/linux/compat.h 2003-10-08 15:07:10.000000000 -0700
++++ 25/include/linux/compat.h  2003-12-28 23:22:22.000000000 -0800
+@@ -44,8 +44,8 @@ typedef struct {
+ } compat_sigset_t;
+ extern int cp_compat_stat(struct kstat *, struct compat_stat *);
+-extern int get_compat_timespec(struct timespec *, struct compat_timespec *);
+-extern int put_compat_timespec(struct timespec *, struct compat_timespec *);
++extern int get_compat_timespec(struct timespec *, const struct compat_timespec *);
++extern int put_compat_timespec(struct timespec *, const struct compat_timespec *);
+ struct compat_iovec {
+       compat_uptr_t   iov_base;
+@@ -76,20 +76,6 @@ struct compat_rusage {
+       compat_long_t   ru_nivcsw;
+ };
+-struct compat_statfs64 {
+-      __u32 f_type;
+-      __u32 f_bsize;
+-      __u64 f_blocks;
+-      __u64 f_bfree;
+-      __u64 f_bavail;
+-      __u64 f_files;
+-      __u64 f_ffree;
+-      __kernel_fsid_t f_fsid;
+-      __u32 f_namelen;
+-      __u32 f_frsize;
+-      __u32 f_spare[5];
+-};
+-
+ struct compat_dirent {
+       u32             d_ino;
+       compat_off_t    d_off;
+--- linux-2.6.0/include/linux/compat_ioctl.h   2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/compat_ioctl.h    2003-12-28 23:21:48.000000000 -0800
+@@ -678,3 +678,10 @@ COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
+ COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
+ COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS)
+ COMPATIBLE_IOCTL(NBD_DISCONNECT)
++/* i2c */
++COMPATIBLE_IOCTL(I2C_SLAVE)
++COMPATIBLE_IOCTL(I2C_SLAVE_FORCE)
++COMPATIBLE_IOCTL(I2C_TENBIT)
++COMPATIBLE_IOCTL(I2C_PEC)
++COMPATIBLE_IOCTL(I2C_RETRIES)
++COMPATIBLE_IOCTL(I2C_TIMEOUT)
+--- linux-2.6.0/include/linux/compiler-gcc2.h  2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/compiler-gcc2.h   2003-12-28 23:22:55.000000000 -0800
+@@ -20,4 +20,5 @@
+  */
+ #if __GNUC_MINOR__ >= 96
+ # define __attribute_pure__   __attribute__((pure))
++# define __attribute_const__  __attribute__((__const__))
+ #endif
+--- linux-2.6.0/include/linux/compiler-gcc3.h  2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/compiler-gcc3.h   2003-12-28 23:22:55.000000000 -0800
+@@ -20,3 +20,4 @@
+ #endif
+ #define __attribute_pure__    __attribute__((pure))
++#define __attribute_const__   __attribute__((__const__))
+--- linux-2.6.0/include/linux/compiler-gcc.h   2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/compiler-gcc.h    2003-12-28 23:21:36.000000000 -0800
+@@ -13,5 +13,5 @@
+    shouldn't recognize the original var, and make assumptions about it */
+ #define RELOC_HIDE(ptr, off)                                  \
+   ({ unsigned long __ptr;                                     \
+-    __asm__ ("" : "=g"(__ptr) : "0"(ptr));            \
++      __asm__ ("" : "=r"(__ptr) : "0"(ptr));                  \
+     (typeof(ptr)) (__ptr + (off)); })
+--- linux-2.6.0/include/linux/compiler-gcc+.h  2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/compiler-gcc+.h   2003-12-28 23:22:55.000000000 -0800
+@@ -12,3 +12,4 @@
+ #define __deprecated          __attribute__((deprecated))
+ #define __attribute_used__    __attribute__((__used__))
+ #define __attribute_pure__    __attribute__((pure))
++#define __attribute_const__   __attribute__((__const__))
+--- linux-2.6.0/include/linux/compiler.h       2003-11-23 19:03:02.000000000 -0800
++++ 25/include/linux/compiler.h        2003-12-28 23:22:55.000000000 -0800
+@@ -76,6 +76,24 @@
+ # define __attribute_pure__   /* unimplemented */
+ #endif
++/*
++ * From the GCC manual:
++ *
++ * Many functions do not examine any values except their arguments,
++ * and have no effects except the return value.  Basically this is
++ * just slightly more strict class than the `pure' attribute above,
++ * since function is not allowed to read global memory.
++ *
++ * Note that a function that has pointer arguments and examines the
++ * data pointed to must _not_ be declared `const'.  Likewise, a
++ * function that calls a non-`const' function usually must not be
++ * `const'.  It does not make sense for a `const' function to return
++ * `void'.
++ */
++#ifndef __attribute_const__
++# define __attribute_const__  /* unimplemented */
++#endif
++
+ /* Optimization barrier */
+ #ifndef barrier
+ # define barrier() __memory_barrier()
+--- linux-2.6.0/include/linux/config.h 2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/config.h  2003-12-28 23:21:09.000000000 -0800
+@@ -2,5 +2,8 @@
+ #define _LINUX_CONFIG_H
+ #include <linux/autoconf.h>
++#if defined(__i386__) && !defined(IN_BOOTLOADER)
++#include <asm/kgdb.h>
++#endif
+ #endif
+--- linux-2.6.0/include/linux/cpumask.h        2003-08-22 19:23:42.000000000 -0700
++++ 25/include/linux/cpumask.h 2003-12-28 23:22:10.000000000 -0800
+@@ -1,42 +1,9 @@
+ #ifndef __LINUX_CPUMASK_H
+ #define __LINUX_CPUMASK_H
+-#include <linux/config.h>
+-#include <linux/kernel.h>
+ #include <linux/threads.h>
+-#include <linux/types.h>
+-#include <linux/bitmap.h>
+-
+-#if NR_CPUS > BITS_PER_LONG && NR_CPUS != 1
+-#define CPU_ARRAY_SIZE                BITS_TO_LONGS(NR_CPUS)
+-
+-struct cpumask
+-{
+-      unsigned long mask[CPU_ARRAY_SIZE];
+-};
+-
+-typedef struct cpumask cpumask_t;
+-
+-#else
+-typedef unsigned long cpumask_t;
+-#endif
+-
+-#ifdef CONFIG_SMP
+-#if NR_CPUS > BITS_PER_LONG
+-#include <asm-generic/cpumask_array.h>
+-#else
+-#include <asm-generic/cpumask_arith.h>
+-#endif
+-#else
+-#include <asm-generic/cpumask_up.h>
+-#endif
+-
+-#if NR_CPUS <= 4*BITS_PER_LONG
+-#include <asm-generic/cpumask_const_value.h>
+-#else
+-#include <asm-generic/cpumask_const_reference.h>
+-#endif
+-
++#include <asm/cpumask.h>
++#include <asm/bug.h>
+ #ifdef CONFIG_SMP
+@@ -53,19 +20,31 @@ extern cpumask_t cpu_online_map;
+ static inline int next_online_cpu(int cpu, cpumask_t map)
+ {
+       do
+-              cpu = next_cpu_const(cpu, map);
++              cpu = next_cpu_const(cpu, mk_cpumask_const(map));
+       while (cpu < NR_CPUS && !cpu_online(cpu));
+       return cpu;
+ }
+ #define for_each_cpu(cpu, map)                                                \
+-      for (cpu = first_cpu_const(map);                                \
++      for (cpu = first_cpu_const(mk_cpumask_const(map));              \
+               cpu < NR_CPUS;                                          \
+-              cpu = next_cpu_const(cpu,map))
++              cpu = next_cpu_const(cpu,mk_cpumask_const(map)))
+ #define for_each_online_cpu(cpu, map)                                 \
+-      for (cpu = first_cpu_const(map);                                \
++      for (cpu = first_cpu_const(mk_cpumask_const(map));              \
+               cpu < NR_CPUS;                                          \
+               cpu = next_online_cpu(cpu,map))
++extern int __mask_snprintf_len(char *buf, unsigned int buflen,
++              const unsigned long *maskp, unsigned int maskbytes);
++
++#define cpumask_snprintf(buf, buflen, map)                            \
++      __mask_snprintf_len(buf, buflen, cpus_addr(map), sizeof(map))
++
++extern int __mask_parse_len(const char __user *ubuf, unsigned int ubuflen,
++      unsigned long *maskp, unsigned int maskbytes);
++
++#define cpumask_parse(buf, buflen, map)                                       \
++      __mask_parse_len(buf, buflen, cpus_addr(map), sizeof(map))
++
+ #endif /* __LINUX_CPUMASK_H */
+--- linux-2.6.0/include/linux/device.h 2003-10-17 15:58:04.000000000 -0700
++++ 25/include/linux/device.h  2003-12-28 23:22:59.000000000 -0800
+@@ -246,6 +246,11 @@ struct class_interface {
+ extern int class_interface_register(struct class_interface *);
+ extern void class_interface_unregister(struct class_interface *);
++/* interface for simple class devices */
++extern struct class_device *simple_add_class_device(struct class *class, dev_t dev, struct device *device, const char *fmt, ...)
++      __attribute__((format(printf,4,5)));
++extern void simple_remove_class_device(dev_t dev);
++
+ struct device {
+       struct list_head node;          /* node in sibling list */
+@@ -372,7 +377,7 @@ extern int platform_device_register(stru
+ extern void platform_device_unregister(struct platform_device *);
+ extern struct bus_type platform_bus_type;
+-extern struct device legacy_bus;
++extern struct device platform_bus;
+ /* drivers/base/power.c */
+ extern void device_shutdown(void);
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/dwarf2.h  2003-12-28 23:21:07.000000000 -0800
+@@ -0,0 +1,738 @@
++/* Declarations and definitions of codes relating to the DWARF2 symbolic
++   debugging information format.
++   Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002
++   Free Software Foundation, Inc.
++
++   Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
++   Office (AJPO), Florida State Unviversity and Silicon Graphics Inc.
++   provided support for this effort -- June 21, 1995.
++
++   Derived from the DWARF 1 implementation written by Ron Guilmette
++   (rfg@netcom.com), November 1990.
++
++   This file is part of GCC.
++
++   GCC 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.
++
++   GCC 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 GCC; see the file COPYING.  If not, write to the Free
++   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
++   02111-1307, USA.  */
++
++/* This file is derived from the DWARF specification (a public document)
++   Revision 2.0.0 (July 27, 1993) developed by the UNIX International
++   Programming Languages Special Interest Group (UI/PLSIG) and distributed
++   by UNIX International.  Copies of this specification are available from
++   UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
++
++   This file also now contains definitions from the DWARF 3 specification.  */
++
++/* This file is shared between GCC and GDB, and should not contain
++   prototypes.        */
++
++#ifndef _ELF_DWARF2_H
++#define _ELF_DWARF2_H
++
++/* Structure found in the .debug_line section.        */
++#ifndef __ASSEMBLY__
++typedef struct
++{
++  unsigned char li_length        [4];
++  unsigned char li_version       [2];
++  unsigned char li_prologue_length [4];
++  unsigned char li_min_insn_length [1];
++  unsigned char li_default_is_stmt [1];
++  unsigned char li_line_base     [1];
++  unsigned char li_line_range    [1];
++  unsigned char li_opcode_base           [1];
++}
++DWARF2_External_LineInfo;
++
++typedef struct
++{
++  unsigned long  li_length;
++  unsigned short li_version;
++  unsigned int         li_prologue_length;
++  unsigned char  li_min_insn_length;
++  unsigned char  li_default_is_stmt;
++  int          li_line_base;
++  unsigned char  li_line_range;
++  unsigned char  li_opcode_base;
++}
++DWARF2_Internal_LineInfo;
++
++/* Structure found in .debug_pubnames section.        */
++typedef struct
++{
++  unsigned char pn_length  [4];
++  unsigned char pn_version [2];
++  unsigned char pn_offset  [4];
++  unsigned char pn_size    [4];
++}
++DWARF2_External_PubNames;
++
++typedef struct
++{
++  unsigned long  pn_length;
++  unsigned short pn_version;
++  unsigned long  pn_offset;
++  unsigned long  pn_size;
++}
++DWARF2_Internal_PubNames;
++
++/* Structure found in .debug_info section.  */
++typedef struct
++{
++  unsigned char  cu_length      [4];
++  unsigned char  cu_version     [2];
++  unsigned char  cu_abbrev_offset [4];
++  unsigned char  cu_pointer_size  [1];
++}
++DWARF2_External_CompUnit;
++
++typedef struct
++{
++  unsigned long  cu_length;
++  unsigned short cu_version;
++  unsigned long  cu_abbrev_offset;
++  unsigned char  cu_pointer_size;
++}
++DWARF2_Internal_CompUnit;
++
++typedef struct
++{
++  unsigned char  ar_length     [4];
++  unsigned char  ar_version    [2];
++  unsigned char  ar_info_offset  [4];
++  unsigned char  ar_pointer_size [1];
++  unsigned char  ar_segment_size [1];
++}
++DWARF2_External_ARange;
++
++typedef struct
++{
++  unsigned long  ar_length;
++  unsigned short ar_version;
++  unsigned long  ar_info_offset;
++  unsigned char  ar_pointer_size;
++  unsigned char  ar_segment_size;
++}
++DWARF2_Internal_ARange;
++
++#define ENUM(name) enum name {
++#define IF_NOT_ASM(a) a
++#define COMMA ,
++#else
++#define ENUM(name)
++#define IF_NOT_ASM(a)
++#define COMMA
++
++#endif
++
++/* Tag names and codes.  */
++ENUM(dwarf_tag)
++
++    DW_TAG_padding = 0x00 COMMA
++    DW_TAG_array_type = 0x01 COMMA
++    DW_TAG_class_type = 0x02 COMMA
++    DW_TAG_entry_point = 0x03 COMMA
++    DW_TAG_enumeration_type = 0x04 COMMA
++    DW_TAG_formal_parameter = 0x05 COMMA
++    DW_TAG_imported_declaration = 0x08 COMMA
++    DW_TAG_label = 0x0a COMMA
++    DW_TAG_lexical_block = 0x0b COMMA
++    DW_TAG_member = 0x0d COMMA
++    DW_TAG_pointer_type = 0x0f COMMA
++    DW_TAG_reference_type = 0x10 COMMA
++    DW_TAG_compile_unit = 0x11 COMMA
++    DW_TAG_string_type = 0x12 COMMA
++    DW_TAG_structure_type = 0x13 COMMA
++    DW_TAG_subroutine_type = 0x15 COMMA
++    DW_TAG_typedef = 0x16 COMMA
++    DW_TAG_union_type = 0x17 COMMA
++    DW_TAG_unspecified_parameters = 0x18 COMMA
++    DW_TAG_variant = 0x19 COMMA
++    DW_TAG_common_block = 0x1a COMMA
++    DW_TAG_common_inclusion = 0x1b COMMA
++    DW_TAG_inheritance = 0x1c COMMA
++    DW_TAG_inlined_subroutine = 0x1d COMMA
++    DW_TAG_module = 0x1e COMMA
++    DW_TAG_ptr_to_member_type = 0x1f COMMA
++    DW_TAG_set_type = 0x20 COMMA
++    DW_TAG_subrange_type = 0x21 COMMA
++    DW_TAG_with_stmt = 0x22 COMMA
++    DW_TAG_access_declaration = 0x23 COMMA
++    DW_TAG_base_type = 0x24 COMMA
++    DW_TAG_catch_block = 0x25 COMMA
++    DW_TAG_const_type = 0x26 COMMA
++    DW_TAG_constant = 0x27 COMMA
++    DW_TAG_enumerator = 0x28 COMMA
++    DW_TAG_file_type = 0x29 COMMA
++    DW_TAG_friend = 0x2a COMMA
++    DW_TAG_namelist = 0x2b COMMA
++    DW_TAG_namelist_item = 0x2c COMMA
++    DW_TAG_packed_type = 0x2d COMMA
++    DW_TAG_subprogram = 0x2e COMMA
++    DW_TAG_template_type_param = 0x2f COMMA
++    DW_TAG_template_value_param = 0x30 COMMA
++    DW_TAG_thrown_type = 0x31 COMMA
++    DW_TAG_try_block = 0x32 COMMA
++    DW_TAG_variant_part = 0x33 COMMA
++    DW_TAG_variable = 0x34 COMMA
++    DW_TAG_volatile_type = 0x35 COMMA
++    /* DWARF 3.  */
++    DW_TAG_dwarf_procedure = 0x36 COMMA
++    DW_TAG_restrict_type = 0x37 COMMA
++    DW_TAG_interface_type = 0x38 COMMA
++    DW_TAG_namespace = 0x39 COMMA
++    DW_TAG_imported_module = 0x3a COMMA
++    DW_TAG_unspecified_type = 0x3b COMMA
++    DW_TAG_partial_unit = 0x3c COMMA
++    DW_TAG_imported_unit = 0x3d COMMA
++    /* SGI/MIPS Extensions.  */
++    DW_TAG_MIPS_loop = 0x4081 COMMA
++    /* GNU extensions.        */
++    DW_TAG_format_label = 0x4101 COMMA        /* For FORTRAN 77 and Fortran 90.  */
++    DW_TAG_function_template = 0x4102 COMMA   /* For C++.  */
++    DW_TAG_class_template = 0x4103 COMMA      /* For C++.  */
++    DW_TAG_GNU_BINCL = 0x4104 COMMA
++    DW_TAG_GNU_EINCL = 0x4105 COMMA
++    /* Extensions for UPC.  See: http://upc.gwu.edu/~upc.  */
++    DW_TAG_upc_shared_type = 0x8765 COMMA
++    DW_TAG_upc_strict_type = 0x8766 COMMA
++    DW_TAG_upc_relaxed_type = 0x8767
++IF_NOT_ASM(};)
++
++#define DW_TAG_lo_user        0x4080
++#define DW_TAG_hi_user        0xffff
++
++/* Flag that tells whether entry has a child or not.  */
++#define DW_children_no         0
++#define       DW_children_yes  1
++
++/* Form names and codes.  */
++ENUM(dwarf_form)
++
++    DW_FORM_addr = 0x01 COMMA
++    DW_FORM_block2 = 0x03 COMMA
++    DW_FORM_block4 = 0x04 COMMA
++    DW_FORM_data2 = 0x05 COMMA
++    DW_FORM_data4 = 0x06 COMMA
++    DW_FORM_data8 = 0x07 COMMA
++    DW_FORM_string = 0x08 COMMA
++    DW_FORM_block = 0x09 COMMA
++    DW_FORM_block1 = 0x0a COMMA
++    DW_FORM_data1 = 0x0b COMMA
++    DW_FORM_flag = 0x0c COMMA
++    DW_FORM_sdata = 0x0d COMMA
++    DW_FORM_strp = 0x0e COMMA
++    DW_FORM_udata = 0x0f COMMA
++    DW_FORM_ref_addr = 0x10 COMMA
++    DW_FORM_ref1 = 0x11 COMMA
++    DW_FORM_ref2 = 0x12 COMMA
++    DW_FORM_ref4 = 0x13 COMMA
++    DW_FORM_ref8 = 0x14 COMMA
++    DW_FORM_ref_udata = 0x15 COMMA
++    DW_FORM_indirect = 0x16
++IF_NOT_ASM(};)
++
++/* Attribute names and codes.  */
++
++ENUM(dwarf_attribute)
++
++    DW_AT_sibling = 0x01 COMMA
++    DW_AT_location = 0x02 COMMA
++    DW_AT_name = 0x03 COMMA
++    DW_AT_ordering = 0x09 COMMA
++    DW_AT_subscr_data = 0x0a COMMA
++    DW_AT_byte_size = 0x0b COMMA
++    DW_AT_bit_offset = 0x0c COMMA
++    DW_AT_bit_size = 0x0d COMMA
++    DW_AT_element_list = 0x0f COMMA
++    DW_AT_stmt_list = 0x10 COMMA
++    DW_AT_low_pc = 0x11 COMMA
++    DW_AT_high_pc = 0x12 COMMA
++    DW_AT_language = 0x13 COMMA
++    DW_AT_member = 0x14 COMMA
++    DW_AT_discr = 0x15 COMMA
++    DW_AT_discr_value = 0x16 COMMA
++    DW_AT_visibility = 0x17 COMMA
++    DW_AT_import = 0x18 COMMA
++    DW_AT_string_length = 0x19 COMMA
++    DW_AT_common_reference = 0x1a COMMA
++    DW_AT_comp_dir = 0x1b COMMA
++    DW_AT_const_value = 0x1c COMMA
++    DW_AT_containing_type = 0x1d COMMA
++    DW_AT_default_value = 0x1e COMMA
++    DW_AT_inline = 0x20 COMMA
++    DW_AT_is_optional = 0x21 COMMA
++    DW_AT_lower_bound = 0x22 COMMA
++    DW_AT_producer = 0x25 COMMA
++    DW_AT_prototyped = 0x27 COMMA
++    DW_AT_return_addr = 0x2a COMMA
++    DW_AT_start_scope = 0x2c COMMA
++    DW_AT_stride_size = 0x2e COMMA
++    DW_AT_upper_bound = 0x2f COMMA
++    DW_AT_abstract_origin = 0x31 COMMA
++    DW_AT_accessibility = 0x32 COMMA
++    DW_AT_address_class = 0x33 COMMA
++    DW_AT_artificial = 0x34 COMMA
++    DW_AT_base_types = 0x35 COMMA
++    DW_AT_calling_convention = 0x36 COMMA
++    DW_AT_count = 0x37 COMMA
++    DW_AT_data_member_location = 0x38 COMMA
++    DW_AT_decl_column = 0x39 COMMA
++    DW_AT_decl_file = 0x3a COMMA
++    DW_AT_decl_line = 0x3b COMMA
++    DW_AT_declaration = 0x3c COMMA
++    DW_AT_discr_list = 0x3d COMMA
++    DW_AT_encoding = 0x3e COMMA
++    DW_AT_external = 0x3f COMMA
++    DW_AT_frame_base = 0x40 COMMA
++    DW_AT_friend = 0x41 COMMA
++    DW_AT_identifier_case = 0x42 COMMA
++    DW_AT_macro_info = 0x43 COMMA
++    DW_AT_namelist_items = 0x44 COMMA
++    DW_AT_priority = 0x45 COMMA
++    DW_AT_segment = 0x46 COMMA
++    DW_AT_specification = 0x47 COMMA
++    DW_AT_static_link = 0x48 COMMA
++    DW_AT_type = 0x49 COMMA
++    DW_AT_use_location = 0x4a COMMA
++    DW_AT_variable_parameter = 0x4b COMMA
++    DW_AT_virtuality = 0x4c COMMA
++    DW_AT_vtable_elem_location = 0x4d COMMA
++    /* DWARF 3 values.        */
++    DW_AT_allocated   = 0x4e COMMA
++    DW_AT_associated  = 0x4f COMMA
++    DW_AT_data_location = 0x50 COMMA
++    DW_AT_stride      = 0x51 COMMA
++    DW_AT_entry_pc    = 0x52 COMMA
++    DW_AT_use_UTF8    = 0x53 COMMA
++    DW_AT_extension   = 0x54 COMMA
++    DW_AT_ranges      = 0x55 COMMA
++    DW_AT_trampoline  = 0x56 COMMA
++    DW_AT_call_column = 0x57 COMMA
++    DW_AT_call_file   = 0x58 COMMA
++    DW_AT_call_line   = 0x59 COMMA
++    /* SGI/MIPS extensions.  */
++    DW_AT_MIPS_fde = 0x2001 COMMA
++    DW_AT_MIPS_loop_begin = 0x2002 COMMA
++    DW_AT_MIPS_tail_loop_begin = 0x2003 COMMA
++    DW_AT_MIPS_epilog_begin = 0x2004 COMMA
++    DW_AT_MIPS_loop_unroll_factor = 0x2005 COMMA
++    DW_AT_MIPS_software_pipeline_depth = 0x2006 COMMA
++    DW_AT_MIPS_linkage_name = 0x2007 COMMA
++    DW_AT_MIPS_stride = 0x2008 COMMA
++    DW_AT_MIPS_abstract_name = 0x2009 COMMA
++    DW_AT_MIPS_clone_origin = 0x200a COMMA
++    DW_AT_MIPS_has_inlines = 0x200b COMMA
++    /* GNU extensions.        */
++    DW_AT_sf_names   = 0x2101 COMMA
++    DW_AT_src_info   = 0x2102 COMMA
++    DW_AT_mac_info   = 0x2103 COMMA
++    DW_AT_src_coords = 0x2104 COMMA
++    DW_AT_body_begin = 0x2105 COMMA
++    DW_AT_body_end   = 0x2106 COMMA
++    DW_AT_GNU_vector = 0x2107 COMMA
++    /* VMS extensions.        */
++    DW_AT_VMS_rtnbeg_pd_address = 0x2201 COMMA
++    /* UPC extension.  */
++    DW_AT_upc_threads_scaled = 0x3210
++IF_NOT_ASM(};)
++
++#define DW_AT_lo_user 0x2000  /* Implementation-defined range start.  */
++#define DW_AT_hi_user 0x3ff0  /* Implementation-defined range end.  */
++
++/* Location atom names and codes.  */
++ENUM(dwarf_location_atom)
++
++    DW_OP_addr = 0x03 COMMA
++    DW_OP_deref = 0x06 COMMA
++    DW_OP_const1u = 0x08 COMMA
++    DW_OP_const1s = 0x09 COMMA
++    DW_OP_const2u = 0x0a COMMA
++    DW_OP_const2s = 0x0b COMMA
++    DW_OP_const4u = 0x0c COMMA
++    DW_OP_const4s = 0x0d COMMA
++    DW_OP_const8u = 0x0e COMMA
++    DW_OP_const8s = 0x0f COMMA
++    DW_OP_constu = 0x10 COMMA
++    DW_OP_consts = 0x11 COMMA
++    DW_OP_dup = 0x12 COMMA
++    DW_OP_drop = 0x13 COMMA
++    DW_OP_over = 0x14 COMMA
++    DW_OP_pick = 0x15 COMMA
++    DW_OP_swap = 0x16 COMMA
++    DW_OP_rot = 0x17 COMMA
++    DW_OP_xderef = 0x18 COMMA
++    DW_OP_abs = 0x19 COMMA
++    DW_OP_and = 0x1a COMMA
++    DW_OP_div = 0x1b COMMA
++    DW_OP_minus = 0x1c COMMA
++    DW_OP_mod = 0x1d COMMA
++    DW_OP_mul = 0x1e COMMA
++    DW_OP_neg = 0x1f COMMA
++    DW_OP_not = 0x20 COMMA
++    DW_OP_or = 0x21 COMMA
++    DW_OP_plus = 0x22 COMMA
++    DW_OP_plus_uconst = 0x23 COMMA
++    DW_OP_shl = 0x24 COMMA
++    DW_OP_shr = 0x25 COMMA
++    DW_OP_shra = 0x26 COMMA
++    DW_OP_xor = 0x27 COMMA
++    DW_OP_bra = 0x28 COMMA
++    DW_OP_eq = 0x29 COMMA
++    DW_OP_ge = 0x2a COMMA
++    DW_OP_gt = 0x2b COMMA
++    DW_OP_le = 0x2c COMMA
++    DW_OP_lt = 0x2d COMMA
++    DW_OP_ne = 0x2e COMMA
++    DW_OP_skip = 0x2f COMMA
++    DW_OP_lit0 = 0x30 COMMA
++    DW_OP_lit1 = 0x31 COMMA
++    DW_OP_lit2 = 0x32 COMMA
++    DW_OP_lit3 = 0x33 COMMA
++    DW_OP_lit4 = 0x34 COMMA
++    DW_OP_lit5 = 0x35 COMMA
++    DW_OP_lit6 = 0x36 COMMA
++    DW_OP_lit7 = 0x37 COMMA
++    DW_OP_lit8 = 0x38 COMMA
++    DW_OP_lit9 = 0x39 COMMA
++    DW_OP_lit10 = 0x3a COMMA
++    DW_OP_lit11 = 0x3b COMMA
++    DW_OP_lit12 = 0x3c COMMA
++    DW_OP_lit13 = 0x3d COMMA
++    DW_OP_lit14 = 0x3e COMMA
++    DW_OP_lit15 = 0x3f COMMA
++    DW_OP_lit16 = 0x40 COMMA
++    DW_OP_lit17 = 0x41 COMMA
++    DW_OP_lit18 = 0x42 COMMA
++    DW_OP_lit19 = 0x43 COMMA
++    DW_OP_lit20 = 0x44 COMMA
++    DW_OP_lit21 = 0x45 COMMA
++    DW_OP_lit22 = 0x46 COMMA
++    DW_OP_lit23 = 0x47 COMMA
++    DW_OP_lit24 = 0x48 COMMA
++    DW_OP_lit25 = 0x49 COMMA
++    DW_OP_lit26 = 0x4a COMMA
++    DW_OP_lit27 = 0x4b COMMA
++    DW_OP_lit28 = 0x4c COMMA
++    DW_OP_lit29 = 0x4d COMMA
++    DW_OP_lit30 = 0x4e COMMA
++    DW_OP_lit31 = 0x4f COMMA
++    DW_OP_reg0 = 0x50 COMMA
++    DW_OP_reg1 = 0x51 COMMA
++    DW_OP_reg2 = 0x52 COMMA
++    DW_OP_reg3 = 0x53 COMMA
++    DW_OP_reg4 = 0x54 COMMA
++    DW_OP_reg5 = 0x55 COMMA
++    DW_OP_reg6 = 0x56 COMMA
++    DW_OP_reg7 = 0x57 COMMA
++    DW_OP_reg8 = 0x58 COMMA
++    DW_OP_reg9 = 0x59 COMMA
++    DW_OP_reg10 = 0x5a COMMA
++    DW_OP_reg11 = 0x5b COMMA
++    DW_OP_reg12 = 0x5c COMMA
++    DW_OP_reg13 = 0x5d COMMA
++    DW_OP_reg14 = 0x5e COMMA
++    DW_OP_reg15 = 0x5f COMMA
++    DW_OP_reg16 = 0x60 COMMA
++    DW_OP_reg17 = 0x61 COMMA
++    DW_OP_reg18 = 0x62 COMMA
++    DW_OP_reg19 = 0x63 COMMA
++    DW_OP_reg20 = 0x64 COMMA
++    DW_OP_reg21 = 0x65 COMMA
++    DW_OP_reg22 = 0x66 COMMA
++    DW_OP_reg23 = 0x67 COMMA
++    DW_OP_reg24 = 0x68 COMMA
++    DW_OP_reg25 = 0x69 COMMA
++    DW_OP_reg26 = 0x6a COMMA
++    DW_OP_reg27 = 0x6b COMMA
++    DW_OP_reg28 = 0x6c COMMA
++    DW_OP_reg29 = 0x6d COMMA
++    DW_OP_reg30 = 0x6e COMMA
++    DW_OP_reg31 = 0x6f COMMA
++    DW_OP_breg0 = 0x70 COMMA
++    DW_OP_breg1 = 0x71 COMMA
++    DW_OP_breg2 = 0x72 COMMA
++    DW_OP_breg3 = 0x73 COMMA
++    DW_OP_breg4 = 0x74 COMMA
++    DW_OP_breg5 = 0x75 COMMA
++    DW_OP_breg6 = 0x76 COMMA
++    DW_OP_breg7 = 0x77 COMMA
++    DW_OP_breg8 = 0x78 COMMA
++    DW_OP_breg9 = 0x79 COMMA
++    DW_OP_breg10 = 0x7a COMMA
++    DW_OP_breg11 = 0x7b COMMA
++    DW_OP_breg12 = 0x7c COMMA
++    DW_OP_breg13 = 0x7d COMMA
++    DW_OP_breg14 = 0x7e COMMA
++    DW_OP_breg15 = 0x7f COMMA
++    DW_OP_breg16 = 0x80 COMMA
++    DW_OP_breg17 = 0x81 COMMA
++    DW_OP_breg18 = 0x82 COMMA
++    DW_OP_breg19 = 0x83 COMMA
++    DW_OP_breg20 = 0x84 COMMA
++    DW_OP_breg21 = 0x85 COMMA
++    DW_OP_breg22 = 0x86 COMMA
++    DW_OP_breg23 = 0x87 COMMA
++    DW_OP_breg24 = 0x88 COMMA
++    DW_OP_breg25 = 0x89 COMMA
++    DW_OP_breg26 = 0x8a COMMA
++    DW_OP_breg27 = 0x8b COMMA
++    DW_OP_breg28 = 0x8c COMMA
++    DW_OP_breg29 = 0x8d COMMA
++    DW_OP_breg30 = 0x8e COMMA
++    DW_OP_breg31 = 0x8f COMMA
++    DW_OP_regx = 0x90 COMMA
++    DW_OP_fbreg = 0x91 COMMA
++    DW_OP_bregx = 0x92 COMMA
++    DW_OP_piece = 0x93 COMMA
++    DW_OP_deref_size = 0x94 COMMA
++    DW_OP_xderef_size = 0x95 COMMA
++    DW_OP_nop = 0x96 COMMA
++    /* DWARF 3 extensions.  */
++    DW_OP_push_object_address = 0x97 COMMA
++    DW_OP_call2 = 0x98 COMMA
++    DW_OP_call4 = 0x99 COMMA
++    DW_OP_call_ref = 0x9a COMMA
++    /* GNU extensions.        */
++    DW_OP_GNU_push_tls_address = 0xe0
++IF_NOT_ASM(};)
++
++#define DW_OP_lo_user 0xe0    /* Implementation-defined range start.  */
++#define DW_OP_hi_user 0xff    /* Implementation-defined range end.  */
++
++/* Type encodings.  */
++ENUM(dwarf_type)
++
++    DW_ATE_void = 0x0 COMMA
++    DW_ATE_address = 0x1 COMMA
++    DW_ATE_boolean = 0x2 COMMA
++    DW_ATE_complex_float = 0x3 COMMA
++    DW_ATE_float = 0x4 COMMA
++    DW_ATE_signed = 0x5 COMMA
++    DW_ATE_signed_char = 0x6 COMMA
++    DW_ATE_unsigned = 0x7 COMMA
++    DW_ATE_unsigned_char = 0x8 COMMA
++    /* DWARF 3.  */
++    DW_ATE_imaginary_float = 0x9
++IF_NOT_ASM(};)
++
++#define       DW_ATE_lo_user 0x80
++#define       DW_ATE_hi_user 0xff
++
++/* Array ordering names and codes.  */
++ENUM(dwarf_array_dim_ordering)
++
++    DW_ORD_row_major = 0 COMMA
++    DW_ORD_col_major = 1
++IF_NOT_ASM(};)
++
++/* Access attribute.  */
++ENUM(dwarf_access_attribute)
++
++    DW_ACCESS_public = 1 COMMA
++    DW_ACCESS_protected = 2 COMMA
++    DW_ACCESS_private = 3
++IF_NOT_ASM(};)
++
++/* Visibility.        */
++ENUM(dwarf_visibility_attribute)
++
++    DW_VIS_local = 1 COMMA
++    DW_VIS_exported = 2 COMMA
++    DW_VIS_qualified = 3
++IF_NOT_ASM(};)
++
++/* Virtuality.        */
++ENUM(dwarf_virtuality_attribute)
++
++    DW_VIRTUALITY_none = 0 COMMA
++    DW_VIRTUALITY_virtual = 1 COMMA
++    DW_VIRTUALITY_pure_virtual = 2
++IF_NOT_ASM(};)
++
++/* Case sensitivity.  */
++ENUM(dwarf_id_case)
++
++    DW_ID_case_sensitive = 0 COMMA
++    DW_ID_up_case = 1 COMMA
++    DW_ID_down_case = 2 COMMA
++    DW_ID_case_insensitive = 3
++IF_NOT_ASM(};)
++
++/* Calling convention.        */
++ENUM(dwarf_calling_convention)
++
++    DW_CC_normal = 0x1 COMMA
++    DW_CC_program = 0x2 COMMA
++    DW_CC_nocall = 0x3
++IF_NOT_ASM(};)
++
++#define DW_CC_lo_user 0x40
++#define DW_CC_hi_user 0xff
++
++/* Inline attribute.  */
++ENUM(dwarf_inline_attribute)
++
++    DW_INL_not_inlined = 0 COMMA
++    DW_INL_inlined = 1 COMMA
++    DW_INL_declared_not_inlined = 2 COMMA
++    DW_INL_declared_inlined = 3
++IF_NOT_ASM(};)
++
++/* Discriminant lists.        */
++ENUM(dwarf_discrim_list)
++
++    DW_DSC_label = 0 COMMA
++    DW_DSC_range = 1
++IF_NOT_ASM(};)
++
++/* Line number opcodes.  */
++ENUM(dwarf_line_number_ops)
++
++    DW_LNS_extended_op = 0 COMMA
++    DW_LNS_copy = 1 COMMA
++    DW_LNS_advance_pc = 2 COMMA
++    DW_LNS_advance_line = 3 COMMA
++    DW_LNS_set_file = 4 COMMA
++    DW_LNS_set_column = 5 COMMA
++    DW_LNS_negate_stmt = 6 COMMA
++    DW_LNS_set_basic_block = 7 COMMA
++    DW_LNS_const_add_pc = 8 COMMA
++    DW_LNS_fixed_advance_pc = 9 COMMA
++    /* DWARF 3.  */
++    DW_LNS_set_prologue_end = 10 COMMA
++    DW_LNS_set_epilogue_begin = 11 COMMA
++    DW_LNS_set_isa = 12
++IF_NOT_ASM(};)
++
++/* Line number extended opcodes.  */
++ENUM(dwarf_line_number_x_ops)
++
++    DW_LNE_end_sequence = 1 COMMA
++    DW_LNE_set_address = 2 COMMA
++    DW_LNE_define_file = 3
++IF_NOT_ASM(};)
++
++/* Call frame information.  */
++ENUM(dwarf_call_frame_info)
++
++    DW_CFA_advance_loc = 0x40 COMMA
++    DW_CFA_offset = 0x80 COMMA
++    DW_CFA_restore = 0xc0 COMMA
++    DW_CFA_nop = 0x00 COMMA
++    DW_CFA_set_loc = 0x01 COMMA
++    DW_CFA_advance_loc1 = 0x02 COMMA
++    DW_CFA_advance_loc2 = 0x03 COMMA
++    DW_CFA_advance_loc4 = 0x04 COMMA
++    DW_CFA_offset_extended = 0x05 COMMA
++    DW_CFA_restore_extended = 0x06 COMMA
++    DW_CFA_undefined = 0x07 COMMA
++    DW_CFA_same_value = 0x08 COMMA
++    DW_CFA_register = 0x09 COMMA
++    DW_CFA_remember_state = 0x0a COMMA
++    DW_CFA_restore_state = 0x0b COMMA
++    DW_CFA_def_cfa = 0x0c COMMA
++    DW_CFA_def_cfa_register = 0x0d COMMA
++    DW_CFA_def_cfa_offset = 0x0e COMMA
++
++    /* DWARF 3.  */
++    DW_CFA_def_cfa_expression = 0x0f COMMA
++    DW_CFA_expression = 0x10 COMMA
++    DW_CFA_offset_extended_sf = 0x11 COMMA
++    DW_CFA_def_cfa_sf = 0x12 COMMA
++    DW_CFA_def_cfa_offset_sf = 0x13 COMMA
++
++    /* SGI/MIPS specific.  */
++    DW_CFA_MIPS_advance_loc8 = 0x1d COMMA
++
++    /* GNU extensions.        */
++    DW_CFA_GNU_window_save = 0x2d COMMA
++    DW_CFA_GNU_args_size = 0x2e COMMA
++    DW_CFA_GNU_negative_offset_extended = 0x2f
++IF_NOT_ASM(};)
++
++#define DW_CIE_ID       0xffffffff
++#define DW_CIE_VERSION          1
++
++#define DW_CFA_extended   0
++#define DW_CFA_lo_user          0x1c
++#define DW_CFA_hi_user          0x3f
++
++#define DW_CHILDREN_no                     0x00
++#define DW_CHILDREN_yes                    0x01
++
++#define DW_ADDR_none          0
++
++/* Source language names and codes.  */
++ENUM(dwarf_source_language)
++
++    DW_LANG_C89 = 0x0001 COMMA
++    DW_LANG_C = 0x0002 COMMA
++    DW_LANG_Ada83 = 0x0003 COMMA
++    DW_LANG_C_plus_plus = 0x0004 COMMA
++    DW_LANG_Cobol74 = 0x0005 COMMA
++    DW_LANG_Cobol85 = 0x0006 COMMA
++    DW_LANG_Fortran77 = 0x0007 COMMA
++    DW_LANG_Fortran90 = 0x0008 COMMA
++    DW_LANG_Pascal83 = 0x0009 COMMA
++    DW_LANG_Modula2 = 0x000a COMMA
++    DW_LANG_Java = 0x000b COMMA
++    /* DWARF 3.  */
++    DW_LANG_C99 = 0x000c COMMA
++    DW_LANG_Ada95 = 0x000d COMMA
++    DW_LANG_Fortran95 = 0x000e COMMA
++    /* MIPS.  */
++    DW_LANG_Mips_Assembler = 0x8001 COMMA
++    /* UPC.  */
++    DW_LANG_Upc = 0x8765
++IF_NOT_ASM(};)
++
++#define DW_LANG_lo_user 0x8000        /* Implementation-defined range start.  */
++#define DW_LANG_hi_user 0xffff        /* Implementation-defined range start.  */
++
++/* Names and codes for macro information.  */
++ENUM(dwarf_macinfo_record_type)
++
++    DW_MACINFO_define = 1 COMMA
++    DW_MACINFO_undef = 2 COMMA
++    DW_MACINFO_start_file = 3 COMMA
++    DW_MACINFO_end_file = 4 COMMA
++    DW_MACINFO_vendor_ext = 255
++IF_NOT_ASM(};)
++\f
++/* @@@ For use with GNU frame unwind information.  */
++
++#define DW_EH_PE_absptr               0x00
++#define DW_EH_PE_omit         0xff
++
++#define DW_EH_PE_uleb128      0x01
++#define DW_EH_PE_udata2               0x02
++#define DW_EH_PE_udata4               0x03
++#define DW_EH_PE_udata8               0x04
++#define DW_EH_PE_sleb128      0x09
++#define DW_EH_PE_sdata2               0x0A
++#define DW_EH_PE_sdata4               0x0B
++#define DW_EH_PE_sdata8               0x0C
++#define DW_EH_PE_signed               0x08
++
++#define DW_EH_PE_pcrel                0x10
++#define DW_EH_PE_textrel      0x20
++#define DW_EH_PE_datarel      0x30
++#define DW_EH_PE_funcrel      0x40
++#define DW_EH_PE_aligned      0x50
++
++#define DW_EH_PE_indirect     0x80
++
++#endif /* _ELF_DWARF2_H */
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/dwarf2-lang.h     2003-12-28 23:21:07.000000000 -0800
+@@ -0,0 +1,132 @@
++#ifndef DWARF2_LANG
++#define DWARF2_LANG
++#include <linux/dwarf2.h>
++
++/*
++ * This 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 file defines macros that allow generation of DWARF debug records
++ * for asm files.  This file is platform independent.  Register numbers
++ * (which are about the only thing that is platform dependent) are to be
++ * supplied by a platform defined file.
++ */
++#define DWARF_preamble()      .section        .debug_frame,"",@progbits
++/*
++ * This macro starts a debug frame section.  The debug_frame describes
++ * where to find the registers that the enclosing function saved on
++ * entry.
++ *
++ * ORD is use by the label generator and should be the same as what is
++ * passed to CFI_postamble.
++ *
++ * pc,        pc register gdb ordinal.
++ *
++ * code_align this is the factor used to define locations or regions
++ * where the given definitions apply.  If you use labels to define these
++ * this should be 1.
++ *
++ * data_align this is the factor used to define register offsets.  If
++ * you use struct offset, this should be the size of the register in
++ * bytes or the negative of that.  This is how it is used: you will
++ * define a register as the reference register, say the stack pointer,
++ * then you will say where a register is located relative to this
++ * reference registers value, say 40 for register 3 (the gdb register
++ * number).  The <40> will be multiplied by <data_align> to define the
++ * byte offset of the given register (3, in this example).  So if your
++ * <40> is the byte offset and the reference register points at the
++ * begining, you would want 1 for the data_offset.  If <40> was the 40th
++ * 4-byte element in that structure you would want 4.  And if your
++ * reference register points at the end of the structure you would want
++ * a negative data_align value(and you would have to do other math as
++ * well).
++ */
++
++#define CFI_preamble(ORD, pc, code_align, data_align) \
++.section      .debug_frame,"",@progbits ;             \
++frame/**/_/**/ORD:                                            \
++      .long end/**/_/**/ORD-start/**/_/**/ORD;                        \
++start/**/_/**/ORD:                                            \
++      .long   DW_CIE_ID;                              \
++      .byte   DW_CIE_VERSION;                 \
++      .byte 0  ;                              \
++      .uleb128 code_align;                            \
++      .sleb128 data_align;                            \
++      .byte pc;
++
++/*
++ * After the above macro and prior to the CFI_postamble, you need to
++ * define the initial state.  This starts with defining the reference
++ * register and, usually the pc.  Here are some helper macros:
++ */
++
++#define CFA_define_reference(reg, offset)     \
++      .byte DW_CFA_def_cfa;                   \
++      .uleb128 reg;                           \
++      .uleb128 (offset);
++
++#define CFA_define_offset(reg, offset)                \
++      .byte (DW_CFA_offset + reg);            \
++      .uleb128 (offset);
++
++#define CFI_postamble(ORD)                    \
++      .align 4;                               \
++end/**/_/**/ORD:
++/*
++ * So now your code pushs stuff on the stack, you need a new location
++ * and the rules for what to do.  This starts a running description of
++ * the call frame.  You need to describe what changes with respect to
++ * the call registers as the location of the pc moves through the code.
++ * The following builds an FDE (fram descriptor entry?).  Like the
++ * above, it has a preamble and a postamble.  It also is tied to the CFI
++ * above.
++ * The first entry after the preamble must be the location in the code
++ * that the call frame is being described for.
++ */
++#define FDE_preamble(ORD, fde_no, initial_address, length)    \
++      .long FDE_end/**/_/**/fde_no-FDE_start/**/_/**/fde_no;          \
++FDE_start/**/_/**/fde_no:                                             \
++      .long frame/**/_/**/ORD;                                        \
++      .long initial_address;                                  \
++      .long length;
++
++#define FDE_postamble(fde_no)                 \
++      .align 4;                               \
++FDE_end/**/_/**/fde_no:
++/*
++ * That done, you can now add registers, subtract registers, move the
++ * reference and even change the reference.  You can also define a new
++ * area of code the info applies to.  For discontinuous bits you should
++ * start a new FDE.  You may have as many as you like.
++ */
++
++/*
++ * To advance the address by <bytes>
++ */
++
++#define FDE_advance(bytes)                    \
++      .byte DW_CFA_advance_loc4               \
++      .long bytes
++
++
++
++/*
++ * With the above you can define all the register locations.  But
++ * suppose the reference register moves... Takes the new offset NOT an
++ * increment.  This is how esp is tracked if it is not saved.
++ */
++
++#define CFA_define_cfa_offset(offset) \
++      .byte $DW_CFA_def_cfa_offset; \
++      .uleb128 (offset);
++/*
++ * Or suppose you want to use a different reference register...
++ */
++#define CFA_define_cfa_register(reg)          \
++      .byte DW_CFA_def_cfa_register;          \
++      .uleb128 reg;
++
++#endif
+--- linux-2.6.0/include/linux/efi.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/efi.h     2003-12-28 23:21:45.000000000 -0800
+@@ -16,6 +16,8 @@
+ #include <linux/time.h>
+ #include <linux/types.h>
+ #include <linux/proc_fs.h>
++#include <linux/rtc.h>
++#include <linux/ioport.h>
+ #include <asm/page.h>
+ #include <asm/system.h>
+@@ -77,18 +79,23 @@ typedef    struct {
+ #define EFI_MAX_MEMORY_TYPE           14
+ /* Attribute values: */
+-#define EFI_MEMORY_UC         0x0000000000000001      /* uncached */
+-#define EFI_MEMORY_WC         0x0000000000000002      /* write-coalescing */
+-#define EFI_MEMORY_WT         0x0000000000000004      /* write-through */
+-#define EFI_MEMORY_WB         0x0000000000000008      /* write-back */
+-#define EFI_MEMORY_WP         0x0000000000001000      /* write-protect */
+-#define EFI_MEMORY_RP         0x0000000000002000      /* read-protect */
+-#define EFI_MEMORY_XP         0x0000000000004000      /* execute-protect */
+-#define EFI_MEMORY_RUNTIME    0x8000000000000000      /* range requires runtime mapping */
++#define EFI_MEMORY_UC         ((u64)0x0000000000000001ULL)    /* uncached */
++#define EFI_MEMORY_WC         ((u64)0x0000000000000002ULL)    /* write-coalescing */
++#define EFI_MEMORY_WT         ((u64)0x0000000000000004ULL)    /* write-through */
++#define EFI_MEMORY_WB         ((u64)0x0000000000000008ULL)    /* write-back */
++#define EFI_MEMORY_WP         ((u64)0x0000000000001000ULL)    /* write-protect */
++#define EFI_MEMORY_RP         ((u64)0x0000000000002000ULL)    /* read-protect */
++#define EFI_MEMORY_XP         ((u64)0x0000000000004000ULL)    /* execute-protect */
++#define EFI_MEMORY_RUNTIME    ((u64)0x8000000000000000ULL)    /* range requires runtime mapping */
+ #define EFI_MEMORY_DESCRIPTOR_VERSION 1
+ #define EFI_PAGE_SHIFT                12
++/*
++ * For current x86 implementations of EFI, there is
++ * additional padding in the mem descriptors.  This is not
++ * the case in ia64.  Need to have this fixed in the f/w.
++ */
+ typedef struct {
+       u32 type;
+       u32 pad;
+@@ -96,6 +103,9 @@ typedef struct {
+       u64 virt_addr;
+       u64 num_pages;
+       u64 attribute;
++#if defined (__i386__)
++      u64 pad1;
++#endif
+ } efi_memory_desc_t;
+ typedef int efi_freemem_callback_t (unsigned long start, unsigned long end, void *arg);
+@@ -132,11 +142,12 @@ typedef struct {
+  */
+ #define EFI_RESET_COLD 0
+ #define EFI_RESET_WARM 1
++#define EFI_RESET_SHUTDOWN 2
+ /*
+  * EFI Runtime Services table
+  */
+-#define EFI_RUNTIME_SERVICES_SIGNATURE 0x5652453544e5552
++#define EFI_RUNTIME_SERVICES_SIGNATURE ((u64)0x5652453544e5552ULL)
+ #define EFI_RUNTIME_SERVICES_REVISION  0x00010000
+ typedef struct {
+@@ -169,6 +180,10 @@ typedef efi_status_t efi_set_variable_t 
+ typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count);
+ typedef void efi_reset_system_t (int reset_type, efi_status_t status,
+                                unsigned long data_size, efi_char16_t *data);
++typedef efi_status_t efi_set_virtual_address_map_t (unsigned long memory_map_size,
++                                              unsigned long descriptor_size,
++                                              u32 descriptor_version,
++                                              efi_memory_desc_t *virtual_map);
+ /*
+  *  EFI Configuration Table and GUID definitions
+@@ -194,12 +209,15 @@ typedef void efi_reset_system_t (int res
+ #define HCDP_TABLE_GUID       \
+     EFI_GUID(  0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 )
++#define UGA_IO_PROTOCOL_GUID \
++    EFI_GUID(  0x61a4d49e, 0x6f68, 0x4f1b, 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0xb, 0x7, 0xa2 )
++
+ typedef struct {
+       efi_guid_t guid;
+       unsigned long table;
+ } efi_config_table_t;
+-#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249
++#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
+ #define EFI_SYSTEM_TABLE_REVISION  ((1 << 16) | 00)
+ typedef struct {
+@@ -218,6 +236,13 @@ typedef struct {
+       unsigned long tables;
+ } efi_system_table_t;
++struct efi_memory_map {
++      efi_memory_desc_t *phys_map;
++      efi_memory_desc_t *map;
++      int nr_map;
++      unsigned long desc_version;
++};
++
+ /*
+  * All runtime access to EFI goes through this structure:
+  */
+@@ -230,6 +255,7 @@ extern struct efi {
+       void *sal_systab;               /* SAL system table */
+       void *boot_info;                /* boot info table */
+       void *hcdp;                     /* HCDP table */
++      void *uga;                      /* UGA table */
+       efi_get_time_t *get_time;
+       efi_set_time_t *set_time;
+       efi_get_wakeup_time_t *get_wakeup_time;
+@@ -239,6 +265,7 @@ extern struct efi {
+       efi_set_variable_t *set_variable;
+       efi_get_next_high_mono_count_t *get_next_high_mono_count;
+       efi_reset_system_t *reset_system;
++      efi_set_virtual_address_map_t *set_virtual_address_map;
+ } efi;
+ static inline int
+@@ -260,12 +287,25 @@ efi_guid_unparse(efi_guid_t *guid, char 
+ extern void efi_init (void);
+ extern void efi_map_pal_code (void);
++extern void efi_map_memmap(void);
+ extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
+ extern void efi_gettimeofday (struct timespec *ts);
+ extern void efi_enter_virtual_mode (void);    /* switch EFI to virtual mode, if possible */
+ extern u64 efi_get_iobase (void);
+ extern u32 efi_mem_type (unsigned long phys_addr);
+ extern u64 efi_mem_attributes (unsigned long phys_addr);
++extern void efi_initialize_iomem_resources(struct resource *code_resource,
++                                      struct resource *data_resource);
++extern efi_status_t phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc);
++extern unsigned long inline __init efi_get_time(void);
++extern int inline __init efi_set_rtc_mmss(unsigned long nowtime);
++extern struct efi_memory_map memmap;
++
++#ifdef CONFIG_EFI
++extern int efi_enabled;
++#else
++#define efi_enabled 0
++#endif
+ /*
+  * Variable Attributes
+--- linux-2.6.0/include/linux/elevator.h       2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/elevator.h        2003-12-28 23:21:35.000000000 -0800
+@@ -94,6 +94,11 @@ extern elevator_t iosched_deadline;
+  */
+ extern elevator_t iosched_as;
++/*
++ * completely fair queueing I/O scheduler
++ */
++extern elevator_t iosched_cfq;
++
+ extern int elevator_init(request_queue_t *, elevator_t *);
+ extern void elevator_exit(request_queue_t *);
+ extern inline int elv_rq_merge_ok(struct request *, struct bio *);
+--- linux-2.6.0/include/linux/errno.h  2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/errno.h   2003-12-28 23:26:39.000000000 -0800
+@@ -22,6 +22,7 @@
+ #define EBADTYPE      527     /* Type not supported by server */
+ #define EJUKEBOX      528     /* Request initiated, but will not complete before timeout */
+ #define EIOCBQUEUED   529     /* iocb queued, will get completion event */
++#define EIOCBRETRY    530     /* iocb queued, will trigger a retry */
+ #endif
+--- linux-2.6.0/include/linux/eventpoll.h      2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/eventpoll.h       2003-12-28 23:23:06.000000000 -0800
+@@ -22,6 +22,9 @@
+ #define EPOLL_CTL_DEL 2
+ #define EPOLL_CTL_MOD 3
++/* Set the One Shot behaviour for the target file descriptor */
++#define EPOLLONESHOT (1 << 30)
++
+ /* Set the Edge Triggered behaviour for the target file descriptor */
+ #define EPOLLET (1 << 31)
+--- linux-2.6.0/include/linux/fb.h     2003-06-14 12:18:06.000000000 -0700
++++ 25/include/linux/fb.h      2003-12-28 23:23:00.000000000 -0800
+@@ -352,6 +352,7 @@ struct fb_pixmap {
+ struct fb_info;
+ struct vm_area_struct;
+ struct file;
++struct device;
+     /*
+      *  Frame buffer operations
+@@ -412,6 +413,7 @@ struct fb_info {
+    struct vc_data *display_fg;                /* Console visible on this display */
+    int currcon;                               /* Current VC. */       
+    void *pseudo_palette;                /* Fake palette of 16 colors */ 
++   struct device *dev;                  /* pointer to the device for this fb */
+    /* From here on everything is device dependent */
+    void *par; 
+ };
+--- linux-2.6.0/include/linux/fs.h     2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/fs.h      2003-12-28 23:26:42.000000000 -0800
+@@ -369,6 +369,7 @@ struct block_device {
+ struct inode {
+       struct hlist_node       i_hash;
+       struct list_head        i_list;
++      struct list_head        i_sb_list;
+       struct list_head        i_dentry;
+       unsigned long           i_ino;
+       atomic_t                i_count;
+@@ -388,6 +389,7 @@ struct inode {
+       unsigned short          i_bytes;
+       spinlock_t              i_lock; /* i_blocks, i_bytes, maybe i_size */
+       struct semaphore        i_sem;
++      struct rw_semaphore     i_alloc_sem;
+       struct inode_operations *i_op;
+       struct file_operations  *i_fop; /* former ->i_op->default_file_ops */
+       struct super_block      *i_sb;
+@@ -480,6 +482,8 @@ static inline unsigned imajor(struct ino
+       return MAJOR(inode->i_rdev);
+ }
++extern struct block_device *I_BDEV(struct inode *inode);
++
+ struct fown_struct {
+       rwlock_t lock;          /* protects pid, uid, euid fields */
+       int pid;                /* pid or -pgrp where SIGIO should be sent */
+@@ -523,9 +527,12 @@ struct file {
+       /* needed for tty driver, and maybe others */
+       void                    *private_data;
++#ifdef CONFIG_EPOLL
+       /* Used by fs/eventpoll.c to link all the hooks to this file */
+       struct list_head        f_ep_links;
+       spinlock_t              f_ep_lock;
++#endif /* #ifdef CONFIG_EPOLL */
++      struct address_space    *f_mapping;
+ };
+ extern spinlock_t files_lock;
+ #define file_list_lock() spin_lock(&files_lock);
+@@ -630,6 +637,7 @@ extern int __break_lease(struct inode *i
+ extern void lease_get_mtime(struct inode *, struct timespec *time);
+ extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
+ extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
++extern void steal_locks(fl_owner_t from);
+ struct fasync_struct {
+       int     magic;
+@@ -687,6 +695,7 @@ struct super_block {
+       atomic_t                s_active;
+       void                    *s_security;
++      struct list_head        s_inodes;       /* all inodes */
+       struct list_head        s_dirty;        /* dirty inodes */
+       struct list_head        s_io;           /* parked for writeback */
+       struct hlist_head       s_anon;         /* anonymous dentries for (nfs) exporting */
+@@ -749,6 +758,11 @@ extern int vfs_rename(struct inode *, st
+ #define DT_SOCK               12
+ #define DT_WHT                14
++#define OSYNC_METADATA        (1<<0)
++#define OSYNC_DATA    (1<<1)
++#define OSYNC_INODE   (1<<2)
++int generic_osync_inode(struct inode *, struct address_space *, int);
++
+ /*
+  * This is the "filldir" function type, used by readdir() to let
+  * the kernel specify what kind of dirent layout it wants to have.
+@@ -758,9 +772,9 @@ extern int vfs_rename(struct inode *, st
+ typedef int (*filldir_t)(void *, const char *, int, loff_t, ino_t, unsigned);
+ struct block_device_operations {
+-      int (*open) (struct inode *, struct file *);
+-      int (*release) (struct inode *, struct file *);
+-      int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
++      int (*open) (struct block_device *, struct file *);
++      int (*release) (struct gendisk *);
++      int (*ioctl) (struct block_device *, struct file *, unsigned, unsigned long);
+       int (*media_changed) (struct gendisk *);
+       int (*revalidate_disk) (struct gendisk *);
+       struct module *owner;
+@@ -1123,11 +1137,9 @@ enum {BDEV_FILE, BDEV_SWAP, BDEV_FS, BDE
+ extern int register_blkdev(unsigned int, const char *);
+ extern int unregister_blkdev(unsigned int, const char *);
+ extern struct block_device *bdget(dev_t);
+-extern int bd_acquire(struct inode *inode);
+ extern void bd_forget(struct inode *inode);
+ extern void bdput(struct block_device *);
+ extern int blkdev_open(struct inode *, struct file *);
+-extern int blkdev_close(struct inode *, struct file *);
+ extern struct block_device *open_by_devnum(dev_t, unsigned, int);
+ extern struct file_operations def_blk_fops;
+ extern struct address_space_operations def_blk_aops;
+@@ -1135,7 +1147,7 @@ extern struct file_operations def_chr_fo
+ extern struct file_operations bad_sock_fops;
+ extern struct file_operations def_fifo_fops;
+ extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
+-extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long);
++extern int blkdev_ioctl(struct block_device *, struct file *, unsigned, unsigned long);
+ extern int blkdev_get(struct block_device *, mode_t, unsigned, int);
+ extern int blkdev_put(struct block_device *, int);
+ extern int bd_claim(struct block_device *, void *);
+@@ -1202,6 +1214,7 @@ extern void write_inode_now(struct inode
+ extern int filemap_fdatawrite(struct address_space *);
+ extern int filemap_flush(struct address_space *);
+ extern int filemap_fdatawait(struct address_space *);
++extern int filemap_write_and_wait(struct address_space *mapping);
+ extern void sync_supers(void);
+ extern void sync_filesystems(int wait);
+ extern void emergency_sync(void);
+@@ -1295,8 +1308,7 @@ extern int generic_file_readonly_mmap(st
+ extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
+ extern int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
+ extern ssize_t generic_file_read(struct file *, char __user *, size_t, loff_t *);
+-int generic_write_checks(struct inode *inode, struct file *file,
+-                      loff_t *pos, size_t *count, int isblk);
++int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
+ extern ssize_t generic_file_write(struct file *, const char __user *, size_t, loff_t *);
+ extern ssize_t generic_file_aio_read(struct kiocb *, char __user *, size_t, loff_t);
+ extern ssize_t __generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t *);
+@@ -1314,9 +1326,6 @@ extern void
+ file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
+ extern ssize_t generic_file_direct_IO(int rw, struct kiocb *iocb,
+       const struct iovec *iov, loff_t offset, unsigned long nr_segs);
+-extern int blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, 
+-      struct block_device *bdev, const struct iovec *iov, loff_t offset, 
+-      unsigned long nr_segs, get_blocks_t *get_blocks, dio_iodone_t *end_io);
+ extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, 
+       unsigned long nr_segs, loff_t *ppos);
+ ssize_t generic_file_writev(struct file *filp, const struct iovec *iov, 
+@@ -1330,7 +1339,7 @@ static inline void do_generic_file_read(
+                                       read_descriptor_t * desc,
+                                       read_actor_t actor)
+ {
+-      do_generic_mapping_read(filp->f_dentry->d_inode->i_mapping,
++      do_generic_mapping_read(filp->f_mapping,
+                               &filp->f_ra,
+                               filp,
+                               ppos,
+@@ -1338,6 +1347,32 @@ static inline void do_generic_file_read(
+                               actor);
+ }
++int __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
++      struct block_device *bdev, const struct iovec *iov, loff_t offset,
++      unsigned long nr_segs, get_blocks_t get_blocks, dio_iodone_t end_io,
++      int needs_special_locking);
++
++/*
++ * For filesystems which need locking between buffered and direct access
++ */
++static inline int blockdev_direct_IO(int rw, struct kiocb *iocb,
++      struct inode *inode, struct block_device *bdev, const struct iovec *iov,
++      loff_t offset, unsigned long nr_segs, get_blocks_t get_blocks,
++      dio_iodone_t end_io)
++{
++      return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
++                              nr_segs, get_blocks, end_io, 1);
++}
++
++static inline int blockdev_direct_IO_no_locking(int rw, struct kiocb *iocb,
++      struct inode *inode, struct block_device *bdev, const struct iovec *iov,
++      loff_t offset, unsigned long nr_segs, get_blocks_t get_blocks,
++      dio_iodone_t end_io)
++{
++      return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
++                              nr_segs, get_blocks, end_io, 0);
++}
++
+ extern struct file_operations generic_ro_fops;
+ #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
+@@ -1408,5 +1443,8 @@ static inline ino_t parent_ino(struct de
+       return res;
+ }
++/* kernel/fork.c */
++extern int unshare_files(void);
++
+ #endif /* __KERNEL__ */
+ #endif /* _LINUX_FS_H */
+--- linux-2.6.0/include/linux/hugetlb.h        2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/hugetlb.h 2003-12-28 23:22:58.000000000 -0800
+@@ -39,6 +39,7 @@ mark_mm_hugetlb(struct mm_struct *mm, st
+ #ifndef ARCH_HAS_HUGEPAGE_ONLY_RANGE
+ #define is_hugepage_only_range(addr, len)     0
++#define hugetlb_free_pgtables(tlb, prev, start, end) do { } while (0)
+ #endif
+ #else /* !CONFIG_HUGETLB_PAGE */
+@@ -63,6 +64,7 @@ static inline int is_vm_hugetlb_page(str
+ #define is_aligned_hugepage_range(addr, len)  0
+ #define pmd_huge(x)   0
+ #define is_hugepage_only_range(addr, len)     0
++#define hugetlb_free_pgtables(tlb, prev, start, end) do { } while (0)
+ #ifndef HPAGE_MASK
+ #define HPAGE_MASK    0               /* Keep the compiler happy */
+--- linux-2.6.0/include/linux/i2c-dev.h        2003-06-14 12:18:04.000000000 -0700
++++ 25/include/linux/i2c-dev.h 2003-12-28 23:21:48.000000000 -0800
+@@ -43,4 +43,6 @@ struct i2c_rdwr_ioctl_data {
+       __u32 nmsgs;                    /* number of i2c_msgs */
+ };
++#define  I2C_RDRW_IOCTL_MAX_MSGS      42
++
+ #endif /* _LINUX_I2C_DEV_H */
+--- linux-2.6.0/include/linux/ide.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/ide.h     2003-12-28 23:26:29.000000000 -0800
+@@ -51,9 +51,6 @@
+ #ifndef SUPPORT_VLB_SYNC              /* 1 to support weird 32-bit chips */
+ #define SUPPORT_VLB_SYNC      1       /* 0 to reduce kernel size */
+ #endif
+-#ifndef DISK_RECOVERY_TIME            /* off=0; on=access_delay_time */
+-#define DISK_RECOVERY_TIME    0       /*  for hardware that needs it */
+-#endif
+ #ifndef OK_TO_RESET_CONTROLLER                /* 1 needed for good error recovery */
+ #define OK_TO_RESET_CONTROLLER        1       /* 0 for use with AH2372A/B interface */
+ #endif
+@@ -999,10 +996,6 @@ typedef struct hwif_s {
+       unsigned        dma_extra;      /* extra addr for dma ports */
+       unsigned long   config_data;    /* for use by chipset-specific code */
+       unsigned long   select_data;    /* for use by chipset-specific code */
+-#if (DISK_RECOVERY_TIME > 0)
+-      unsigned long   last_time;      /* time when previous rq was done */
+-#endif
+-
+       unsigned        noprobe    : 1; /* don't probe for this interface */
+       unsigned        present    : 1; /* this interface exists */
+@@ -1693,6 +1686,8 @@ extern void ide_setup_pci_devices(struct
+ #define GOOD_DMA_DRIVE                1
+ #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
++extern int ide_build_sglist(ide_drive_t *, struct request *);
++extern int ide_raw_build_sglist(ide_drive_t *, struct request *);
+ extern int ide_build_dmatable(ide_drive_t *, struct request *);
+ extern void ide_destroy_dmatable(ide_drive_t *);
+ extern ide_startstop_t ide_dma_intr(ide_drive_t *);
+--- linux-2.6.0/include/linux/if_bonding.h     2003-06-14 12:18:30.000000000 -0700
++++ 25/include/linux/if_bonding.h      2003-12-28 23:21:01.000000000 -0800
+@@ -1,7 +1,7 @@
+ /*
+  * Bond several ethernet interfaces into a Cisco, running 'Etherchannel'.
+  *
+- * 
++ *
+  * Portions are (c) Copyright 1995 Simon "Guru Aleph-Null" Janes
+  * NCM: Network and Communications Management, Inc.
+  *
+@@ -10,11 +10,11 @@
+  *
+  *    This software may be used and distributed according to the terms
+  *    of the GNU Public License, incorporated herein by reference.
+- * 
++ *
+  * 2003/03/18 - Amir Noam <amir.noam at intel dot com>
+  *    - Added support for getting slave's speed and duplex via ethtool.
+  *      Needed for 802.3ad and other future modes.
+- * 
++ *
+  * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
+  *            Shmulik Hen <shmulik.hen at intel dot com>
+  *    - Enable support of modes that need to use the unique mac address of
+@@ -42,7 +42,7 @@
+ #include <linux/if_ether.h>
+ /* userland - kernel ABI version (2003/05/08) */
+-#define BOND_ABI_VERSION 1
++#define BOND_ABI_VERSION 2
+ /*
+  * We can remove these ioctl definitions in 2.5.  People should use the
+@@ -77,10 +77,6 @@
+ #define BOND_DEFAULT_MAX_BONDS  1   /* Default maximum number of devices to support */
+-#define BOND_MULTICAST_DISABLED 0
+-#define BOND_MULTICAST_ACTIVE   1
+-#define BOND_MULTICAST_ALL      2
+-
+ typedef struct ifbond {
+       __s32 bond_mode;
+       __s32 num_slaves;
+@@ -90,9 +86,9 @@ typedef struct ifbond {
+ typedef struct ifslave
+ {
+       __s32 slave_id; /* Used as an IN param to the BOND_SLAVE_INFO_QUERY ioctl */
+-      char slave_name[IFNAMSIZ];
+-      char link;
+-      char state;
++      __s8 slave_name[IFNAMSIZ];
++      __s8 link;
++      __s8 state;
+       __u32  link_failure_count;
+ } ifslave;
+@@ -115,3 +111,4 @@ struct ad_info {
+  *  tab-width: 8
+  * End:
+  */
++
+--- linux-2.6.0/include/linux/init_task.h      2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/init_task.h       2003-12-28 23:26:39.000000000 -0800
+@@ -108,6 +108,7 @@
+       .proc_lock      = SPIN_LOCK_UNLOCKED,                           \
+       .switch_lock    = SPIN_LOCK_UNLOCKED,                           \
+       .journal_info   = NULL,                                         \
++      .io_wait        = NULL,                                         \
+ }
+--- linux-2.6.0/include/linux/input.h  2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/input.h   2003-12-28 23:21:26.000000000 -0800
+@@ -870,6 +870,7 @@ struct input_handler {
+       char *name;
+       struct input_device_id *id_table;
++      struct input_device_id *blacklist;
+       struct list_head        h_list;
+       struct list_head        node;
+--- linux-2.6.0/include/linux/jiffies.h        2003-06-14 12:17:56.000000000 -0700
++++ 25/include/linux/jiffies.h 2003-12-28 23:22:24.000000000 -0800
+@@ -10,7 +10,7 @@
+ /*
+  * The 64-bit value is not volatile - you MUST NOT read it
+- * without holding read_lock_irq(&xtime_lock).
++ * without sampling the sequence number in xtime_lock.
+  * get_jiffies_64() will do this for you as appropriate.
+  */
+ extern u64 jiffies_64;
+--- linux-2.6.0/include/linux/kernel.h 2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/kernel.h  2003-12-28 23:21:48.000000000 -0800
+@@ -87,6 +87,8 @@ extern int session_of_pgrp(int pgrp);
+ asmlinkage int printk(const char * fmt, ...)
+       __attribute__ ((format (printf, 1, 2)));
++unsigned long int_sqrt(unsigned long);
++
+ static inline void console_silent(void)
+ {
+       console_loglevel = 0;
+--- linux-2.6.0/include/linux/keyboard.h       2003-06-14 12:17:58.000000000 -0700
++++ 25/include/linux/keyboard.h        2003-12-28 23:21:28.000000000 -0800
+@@ -2,7 +2,6 @@
+ #define __LINUX_KEYBOARD_H
+ #include <linux/wait.h>
+-#include <linux/input.h>
+ #define KG_SHIFT      0
+ #define KG_CTRL               2
+@@ -17,7 +16,7 @@
+ #define NR_SHIFT      9
+-#define NR_KEYS               (KEY_MAX+1)
++#define NR_KEYS               255
+ #define MAX_NR_KEYMAPS        256
+ /* This means 128Kb if all keymaps are allocated. Only the superuser
+       may increase the number of keymaps beyond MAX_NR_OF_USER_KEYMAPS. */
+--- linux-2.6.0/include/linux/kmod.h   2003-09-08 13:58:59.000000000 -0700
++++ 25/include/linux/kmod.h    2003-12-28 23:21:42.000000000 -0800
+@@ -24,6 +24,8 @@
+ #include <linux/compiler.h>
+ #ifdef CONFIG_KMOD
++/* modprobe exit status on success, -ve on error.  Return value
++ * usually useless though. */
+ extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
+ #else
+ static inline int request_module(const char * name, ...) { return -ENOSYS; }
+--- linux-2.6.0/include/linux/list.h   2003-12-17 21:20:03.000000000 -0800
++++ 25/include/linux/list.h    2003-12-28 23:26:32.000000000 -0800
+@@ -142,8 +142,11 @@ static inline void __list_del(struct lis
+  * Note: list_empty on entry does not return true after this, the entry is
+  * in an undefined state.
+  */
++#include <linux/kernel.h>     /* BUG_ON */
+ static inline void list_del(struct list_head *entry)
+ {
++      BUG_ON(entry->prev->next != entry);
++      BUG_ON(entry->next->prev != entry);
+       __list_del(entry->prev, entry->next);
+       entry->next = LIST_POISON1;
+       entry->prev = LIST_POISON2;
+@@ -212,6 +215,12 @@ static inline int list_empty(const struc
+  * list_empty_careful - tests whether a list is
+  * empty _and_ checks that no other CPU might be
+  * in the process of still modifying either member
++ *
++ * NOTE: using list_empty_careful() without synchronization
++ * can only be safe if the only activity that can happen
++ * to the list entry is list_del_init(). Eg. it cannot be used
++ * if another CPU could re-list_add() it.
++ *
+  * @head: the list to test.
+  */
+ static inline int list_empty_careful(const struct list_head *head)
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/lockmeter.h       2003-12-28 23:26:33.000000000 -0800
+@@ -0,0 +1,320 @@
++/*
++ *  Copyright (C) 1999-2002 Silicon Graphics, Inc.
++ *
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.h by Jack Steiner (steiner@sgi.com)
++ *
++ *  Modified by Ray Bryant (raybry@us.ibm.com) Feb-Apr 2000
++ *  Changes Copyright (C) 2000 IBM, Inc.
++ *  Added save of index in spinlock_t to improve efficiency
++ *  of "hold" time reporting for spinlocks
++ *  Added support for hold time statistics for read and write
++ *  locks.
++ *  Moved machine dependent code to include/asm/lockmeter.h.
++ *
++ */
++
++#ifndef _LINUX_LOCKMETER_H
++#define _LINUX_LOCKMETER_H
++
++
++/*---------------------------------------------------
++ *    architecture-independent lockmeter.h
++ *-------------------------------------------------*/
++
++/*
++ * raybry -- version 2: added efficient hold time statistics
++ *           requires lstat recompile, so flagged as new version
++ * raybry -- version 3: added global reader lock data
++ * hawkes -- version 4: removed some unnecessary fields to simplify mips64 port
++ */
++#define LSTAT_VERSION 5
++
++int   lstat_update(void*, void*, int);
++int   lstat_update_time(void*, void*, int, uint32_t);
++
++/*
++ * Currently, the mips64 and sparc64 kernels talk to a 32-bit lockstat, so we
++ * need to force compatibility in the inter-communication data structure.
++ */
++
++#if defined(CONFIG_MIPS32_COMPAT)
++#define TIME_T                uint32_t
++#elif defined(CONFIG_SPARC) || defined(CONFIG_SPARC64)
++#define TIME_T                uint64_t
++#else
++#define TIME_T                time_t
++#endif
++
++#if defined(__KERNEL__) || (!defined(CONFIG_MIPS32_COMPAT) && !defined(CONFIG_SPARC) && !defined(CONFIG_SPARC64)) || (_MIPS_SZLONG==32)
++#define POINTER               void *
++#else
++#define       POINTER         int64_t
++#endif
++
++/*
++ * Values for the "action" parameter passed to lstat_update.
++ *    ZZZ - do we want a try-success status here???
++ */
++#define LSTAT_ACT_NO_WAIT     0
++#define LSTAT_ACT_SPIN                1
++#define LSTAT_ACT_REJECT      2
++#define LSTAT_ACT_WW_SPIN       3
++#define LSTAT_ACT_SLEPT               4 /* UNUSED */
++
++#define LSTAT_ACT_MAX_VALUES  4 /* NOTE: Increase to 5 if use ACT_SLEPT */
++
++/*
++ * Special values for the low 2 bits of an RA passed to
++ * lstat_update.
++ */
++/* we use these values to figure out what kind of lock data */
++/* is stored in the statistics table entry at index ....... */
++#define LSTAT_RA_SPIN           0  /* spin lock data */
++#define LSTAT_RA_READ           1  /* read lock statistics */
++#define LSTAT_RA_SEMA         2  /* RESERVED */
++#define LSTAT_RA_WRITE          3  /* write lock statistics*/
++
++#define LSTAT_RA(n)   \
++      ((void*)( ((unsigned long)__builtin_return_address(0) & ~3) | n) )
++
++/*
++ * Constants used for lock addresses in the lstat_directory
++ * to indicate special values of the lock address.
++ */
++#define       LSTAT_MULTI_LOCK_ADDRESS        NULL
++
++/*
++ * Maximum size of the lockstats tables. Increase this value
++ * if its not big enough. (Nothing bad happens if its not
++ * big enough although some locks will not be monitored.)
++ * We record overflows of this quantity in lstat_control.dir_overflows
++ *
++ * Note:  The max value here must fit into the field set
++ * and obtained by the macro's PUT_INDEX() and GET_INDEX().
++ * This value depends on how many bits are available in the
++ * lock word in the particular machine implementation we are on.
++ */
++#define LSTAT_MAX_STAT_INDEX          2000
++
++/*
++ * Size and mask for the hash table into the directory.
++ */
++#define LSTAT_HASH_TABLE_SIZE         4096            /* must be 2**N */
++#define LSTAT_HASH_TABLE_MASK         (LSTAT_HASH_TABLE_SIZE-1)
++
++#define DIRHASH(ra)      ((unsigned long)(ra)>>2 & LSTAT_HASH_TABLE_MASK)
++
++/*
++ *    This defines an entry in the lockstat directory. It contains
++ *    information about a lock being monitored.
++ *    A directory entry only contains the lock identification -
++ *    counts on usage of the lock are kept elsewhere in a per-cpu
++ *    data structure to minimize cache line pinging.
++ */
++typedef struct {
++      POINTER caller_ra;                /* RA of code that set lock */
++      POINTER lock_ptr;                 /* lock address */
++      ushort  next_stat_index;  /* Used to link multiple locks that have the same hash table value */
++} lstat_directory_entry_t;
++
++/*
++ *    A multi-dimensioned array used to contain counts for lock accesses.
++ *    The array is 3-dimensional:
++ *            - CPU number. Keep from thrashing cache lines between CPUs
++ *            - Directory entry index. Identifies the lock
++ *            - Action. Indicates what kind of contention occurred on an
++ *              access to the lock.
++ *
++ *    The index of an entry in the directory is the same as the 2nd index
++ *    of the entry in the counts array.
++ */
++/*
++ *  This table contains data for spin_locks, write locks, and read locks
++ *  Not all data is used for all cases.  In particular, the hold time
++ *  information is not stored here for read locks since that is a global
++ *  (e. g. cannot be separated out by return address) quantity.
++ *  See the lstat_read_lock_counts_t structure for the global read lock
++ *  hold time.
++ */
++typedef struct {
++      uint64_t    cum_wait_ticks;     /* sum of wait times               */
++                                      /* for write locks, sum of time a  */
++                                      /* writer is waiting for a reader  */
++      int64_t     cum_hold_ticks;     /* cumulative sum of holds         */
++                                      /* not used for read mode locks    */
++                                      /* must be signed. ............... */
++      uint32_t    max_wait_ticks;     /* max waiting time                */
++      uint32_t    max_hold_ticks;     /* max holding time                */
++      uint64_t    cum_wait_ww_ticks;  /* sum times writer waits on writer*/
++      uint32_t    max_wait_ww_ticks;  /* max wait time writer vs writer  */
++                                      /* prev 2 only used for write locks*/
++      uint32_t    acquire_time;       /* time lock acquired this CPU     */
++      uint32_t    count[LSTAT_ACT_MAX_VALUES];
++} lstat_lock_counts_t;
++
++typedef lstat_lock_counts_t   lstat_cpu_counts_t[LSTAT_MAX_STAT_INDEX];
++
++/*
++ * User request to:
++ *    - turn statistic collection on/off, or to reset
++ */
++#define LSTAT_OFF      0
++#define LSTAT_ON       1
++#define LSTAT_RESET      2
++#define LSTAT_RELEASE    3
++
++#define LSTAT_MAX_READ_LOCK_INDEX 1000
++typedef struct {
++      POINTER     lock_ptr;            /* address of lock for output stats */
++      uint32_t    read_lock_count;
++      int64_t     cum_hold_ticks;       /* sum of read lock hold times over */
++                                        /* all callers. ....................*/
++      uint32_t    write_index;          /* last write lock hash table index */
++      uint32_t    busy_periods;         /* count of busy periods ended this */
++      uint64_t    start_busy;           /* time this busy period started. ..*/
++      uint64_t    busy_ticks;           /* sum of busy periods this lock. ..*/
++      uint64_t    max_busy;             /* longest busy period for this lock*/
++      uint32_t    max_readers;          /* maximum number of readers ...... */
++#ifdef USER_MODE_TESTING
++      rwlock_t    entry_lock;           /* lock for this read lock entry... */
++                                        /* avoid having more than one rdr at*/
++                                        /* needed for user space testing... */
++                                        /* not needed for kernel 'cause it  */
++                                        /* is non-preemptive. ............. */
++#endif
++} lstat_read_lock_counts_t;
++typedef lstat_read_lock_counts_t      lstat_read_lock_cpu_counts_t[LSTAT_MAX_READ_LOCK_INDEX];
++
++#if defined(__KERNEL__) || defined(USER_MODE_TESTING)
++
++#ifndef USER_MODE_TESTING
++#include <asm/lockmeter.h>
++#else
++#include "asm_newlockmeter.h"
++#endif
++
++/*
++ * Size and mask for the hash table into the directory.
++ */
++#define LSTAT_HASH_TABLE_SIZE         4096            /* must be 2**N */
++#define LSTAT_HASH_TABLE_MASK         (LSTAT_HASH_TABLE_SIZE-1)
++
++#define DIRHASH(ra)      ((unsigned long)(ra)>>2 & LSTAT_HASH_TABLE_MASK)
++
++/*
++ * This version eliminates the per processor lock stack.  What we do is to
++ * store the index of the lock hash structure in unused bits in the lock
++ * itself.  Then on unlock we can find the statistics record without doing
++ * any additional hash or lock stack lookup.  This works for spin_locks.
++ * Hold time reporting is now basically as cheap as wait time reporting
++ * so we ignore the difference between LSTAT_ON_HOLD and LSTAT_ON_WAIT
++ * as in version 1.1.* of lockmeter.
++ *
++ * For rw_locks, we store the index of a global reader stats structure in
++ * the lock and the writer index is stored in the latter structure.
++ * For read mode locks we hash at the time of the lock to find an entry
++ * in the directory for reader wait time and the like.
++ * At unlock time for read mode locks, we update just the global structure
++ * so we don't need to know the reader directory index value at unlock time.
++ *
++ */
++
++/*
++ * Protocol to change lstat_control.state
++ *   This is complicated because we don't want the cum_hold_time for
++ * a rw_lock to be decremented in _read_lock_ without making sure it
++ * is incremented in _read_lock_ and vice versa.  So here is the
++ * way we change the state of lstat_control.state:
++ * I.  To Turn Statistics On
++ *     After allocating storage, set lstat_control.state non-zero.
++ * This works because we don't start updating statistics for in use
++ * locks until the reader lock count goes to zero.
++ * II. To Turn Statistics Off:
++ * (0)  Disable interrupts on this CPU
++ * (1)  Seize the lstat_control.directory_lock
++ * (2)  Obtain the current value of lstat_control.next_free_read_lock_index
++ * (3)  Store a zero in lstat_control.state.
++ * (4)  Release the lstat_control.directory_lock
++ * (5)  For each lock in the read lock list up to the saved value
++ *      (well, -1) of the next_free_read_lock_index, do the following:
++ *      (a)  Check validity of the stored lock address
++ *           by making sure that the word at the saved addr
++ *           has an index that matches this entry.  If not
++ *           valid, then skip this entry.
++ *      (b)  If there is a write lock already set on this lock,
++ *           skip to (d) below.
++ *      (c)  Set a non-metered write lock on the lock
++ *      (d)  set the cached INDEX in the lock to zero
++ *      (e)  Release the non-metered write lock.
++ * (6)  Re-enable interrupts
++ *
++ * These rules ensure that a read lock will not have its statistics
++ * partially updated even though the global lock recording state has
++ * changed.  See put_lockmeter_info() for implementation.
++ *
++ * The reason for (b) is that there may be write locks set on the
++ * syscall path to put_lockmeter_info() from user space.  If we do
++ * not do this check, then we can deadlock.  A similar problem would
++ * occur if the lock was read locked by the current CPU.  At the
++ * moment this does not appear to happen.
++ */
++
++/*
++ * Main control structure for lockstat. Used to turn statistics on/off
++ * and to maintain directory info.
++ */
++typedef struct {
++      int                             state;
++      spinlock_t              control_lock;           /* used to serialize turning statistics on/off   */
++      spinlock_t              directory_lock;         /* for serialize adding entries to directory     */
++      volatile int    next_free_dir_index;/* next free entry in the directory */
++      /* FIXME not all of these fields are used / needed .............. */
++                /* the following fields represent data since     */
++              /* first "lstat on" or most recent "lstat reset" */
++      TIME_T      first_started_time;     /* time when measurement first enabled */
++      TIME_T      started_time;           /* time when measurement last started  */
++      TIME_T      ending_time;            /* time when measurement last disabled */
++      uint64_t    started_cycles64;       /* cycles when measurement last started          */
++      uint64_t    ending_cycles64;        /* cycles when measurement last disabled         */
++      uint64_t    enabled_cycles64;       /* total cycles with measurement enabled         */
++      int         intervals;              /* number of measurement intervals recorded      */
++                                          /* i. e. number of times did lstat on;lstat off  */
++      lstat_directory_entry_t *dir;           /* directory */
++      int         dir_overflow;           /* count of times ran out of space in directory  */
++      int         rwlock_overflow;        /* count of times we couldn't allocate a rw block*/
++      ushort          *hashtab;                           /* hash table for quick dir scans */
++      lstat_cpu_counts_t      *counts[NR_CPUS];        /* Array of pointers to per-cpu stats */
++    int         next_free_read_lock_index;   /* next rwlock reader (global) stats block  */
++    lstat_read_lock_cpu_counts_t *read_lock_counts[NR_CPUS]; /* per cpu read lock stats  */
++} lstat_control_t;
++
++#endif        /* defined(__KERNEL__) || defined(USER_MODE_TESTING) */
++
++typedef struct {
++      short           lstat_version;          /* version of the data */
++      short           state;                  /* the current state is returned */
++      int             maxcpus;                /* Number of cpus present */
++      int             next_free_dir_index;    /* index of the next free directory entry */
++      TIME_T          first_started_time;     /* when measurement enabled for first time */
++      TIME_T          started_time;           /* time in secs since 1969 when stats last turned on  */
++      TIME_T          ending_time;            /* time in secs since 1969 when stats last turned off */
++      uint32_t        cycleval;               /* cycles per second */
++#ifdef notyet
++      void            *kernel_magic_addr;     /* address of kernel_magic */
++      void            *kernel_end_addr;       /* contents of kernel magic (points to "end") */
++#endif
++      int              next_free_read_lock_index; /* index of next (global) read lock stats struct */
++      uint64_t         started_cycles64;      /* cycles when measurement last started        */
++      uint64_t         ending_cycles64;       /* cycles when stats last turned off           */
++      uint64_t         enabled_cycles64;      /* total cycles with measurement enabled       */
++      int              intervals;             /* number of measurement intervals recorded      */
++                                              /* i.e. number of times we did lstat on;lstat off*/
++      int              dir_overflow;          /* number of times we wanted more space in directory */
++      int              rwlock_overflow;       /* # of times we wanted more space in read_locks_count */
++      struct new_utsname   uts;               /* info about machine where stats are measured */
++                                              /* -T option of lockstat allows data to be     */
++                                              /* moved to another machine. ................. */
++} lstat_user_request_t;
++
++#endif /* _LINUX_LOCKMETER_H */
+--- linux-2.6.0/include/linux/loop.h   2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/loop.h    2003-12-28 23:21:53.000000000 -0800
+@@ -34,8 +34,9 @@ struct loop_device {
+       loff_t          lo_sizelimit;
+       int             lo_flags;
+       int             (*transfer)(struct loop_device *, int cmd,
+-                                  char *raw_buf, char *loop_buf, int size,
+-                                  sector_t real_block);
++                                  struct page *raw_page, unsigned raw_off,
++                                  struct page *loop_page, unsigned loop_off,
++                                  int size, sector_t real_block);
+       char            lo_file_name[LO_NAME_SIZE];
+       char            lo_crypt_name[LO_NAME_SIZE];
+       char            lo_encrypt_key[LO_KEY_SIZE];
+@@ -70,8 +71,7 @@ struct loop_device {
+ /*
+  * Loop flags
+  */
+-#define LO_FLAGS_DO_BMAP      1
+-#define LO_FLAGS_READ_ONLY    2
++#define LO_FLAGS_READ_ONLY    1
+ #include <asm/posix_types.h>  /* for __kernel_old_dev_t */
+ #include <asm/types.h>                /* for __u64 */
+@@ -128,8 +128,10 @@ struct loop_info64 {
+ /* Support for loadable transfer modules */
+ struct loop_func_table {
+       int number;     /* filter type */ 
+-      int (*transfer)(struct loop_device *lo, int cmd, char *raw_buf,
+-                      char *loop_buf, int size, sector_t real_block);
++      int (*transfer)(struct loop_device *lo, int cmd,
++                      struct page *raw_page, unsigned raw_off,
++                      struct page *loop_page, unsigned loop_off,
++                      int size, sector_t real_block);
+       int (*init)(struct loop_device *, const struct loop_info64 *); 
+       /* release is called from loop_unregister_transfer or clr_fd */
+       int (*release)(struct loop_device *); 
+--- linux-2.6.0/include/linux/miscdevice.h     2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/miscdevice.h      2003-12-28 23:23:00.000000000 -0800
+@@ -36,12 +36,15 @@
+ #define TUN_MINOR          200
++struct device;
++
+ struct miscdevice 
+ {
+       int minor;
+       const char *name;
+       struct file_operations *fops;
+       struct list_head list;
++      struct device *dev;
+       char devfs_name[64];
+ };
+--- linux-2.6.0/include/linux/mm.h     2003-10-08 15:07:10.000000000 -0700
++++ 25/include/linux/mm.h      2003-12-28 23:22:12.000000000 -0800
+@@ -143,7 +143,7 @@ extern pgprot_t protection_map[16];
+ struct vm_operations_struct {
+       void (*open)(struct vm_area_struct * area);
+       void (*close)(struct vm_area_struct * area);
+-      struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused);
++      struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int *type);
+       int (*populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock);
+ };
+@@ -322,8 +322,10 @@ static inline void put_page(struct page 
+ /*
+  * The zone field is never updated after free_area_init_core()
+  * sets it, so none of the operations on it need to be atomic.
++ * We'll have up to log2(MAX_NUMNODES * MAX_NR_ZONES) zones
++ * total, so we use NODES_SHIFT here to get enough bits.
+  */
+-#define ZONE_SHIFT (BITS_PER_LONG - 8)
++#define ZONE_SHIFT (BITS_PER_LONG - NODES_SHIFT - MAX_NR_ZONES_SHIFT)
+ struct zone;
+ extern struct zone *zone_table[];
+@@ -405,7 +407,7 @@ static inline int page_mapped(struct pag
+ extern void show_free_areas(void);
+ struct page *shmem_nopage(struct vm_area_struct * vma,
+-                      unsigned long address, int unused);
++                      unsigned long address, int *type);
+ struct file *shmem_file_setup(char * name, loff_t size, unsigned long flags);
+ void shmem_lock(struct file * file, int lock);
+ int shmem_zero_setup(struct vm_area_struct *);
+@@ -563,7 +565,7 @@ extern unsigned long page_unuse(struct p
+ extern void truncate_inode_pages(struct address_space *, loff_t);
+ /* generic vm_area_ops exported for stackable file systems */
+-extern struct page *filemap_nopage(struct vm_area_struct *, unsigned long, int);
++struct page *filemap_nopage(struct vm_area_struct *, unsigned long, int *);
+ /* mm/page-writeback.c */
+ int write_one_page(struct page *page, int wait);
+--- linux-2.6.0/include/linux/mmzone.h 2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/mmzone.h  2003-12-28 23:22:02.000000000 -0800
+@@ -159,7 +159,10 @@ struct zone {
+ #define ZONE_DMA              0
+ #define ZONE_NORMAL           1
+ #define ZONE_HIGHMEM          2
+-#define MAX_NR_ZONES          3
++
++#define MAX_NR_ZONES          3       /* Sync this with MAX_NR_ZONES_SHIFT */
++#define MAX_NR_ZONES_SHIFT    2       /* ceil(log2(MAX_NR_ZONES)) */
++
+ #define GFP_ZONEMASK  0x03
+ /*
+@@ -284,8 +287,6 @@ struct ctl_table;
+ struct file;
+ int min_free_kbytes_sysctl_handler(struct ctl_table *, int, struct file *, 
+                                         void *, size_t *);
+-extern void setup_per_zone_pages_min(void);
+-
+ #ifdef CONFIG_NUMA
+ #define MAX_NR_MEMBLKS        BITS_PER_LONG /* Max number of Memory Blocks */
+--- linux-2.6.0/include/linux/msdos_fs.h       2003-08-08 22:55:14.000000000 -0700
++++ 25/include/linux/msdos_fs.h        2003-12-28 23:22:51.000000000 -0800
+@@ -4,13 +4,8 @@
+ /*
+  * The MS-DOS filesystem constants/structures
+  */
+-#include <linux/buffer_head.h>
+-#include <linux/string.h>
+ #include <asm/byteorder.h>
+-struct statfs;
+-
+-
+ #define SECTOR_SIZE   512             /* sector size (bytes) */
+ #define SECTOR_BITS   9               /* log2(SECTOR_SIZE) */
+ #define MSDOS_DPB     (MSDOS_DPS)     /* dir entries per block */
+@@ -18,6 +13,9 @@ struct statfs;
+ #define MSDOS_DPS     (SECTOR_SIZE / sizeof(struct msdos_dir_entry))
+ #define MSDOS_DPS_BITS        4               /* log2(MSDOS_DPS) */
++
++#define MSDOS_SUPER_MAGIC 0x4d44 /* MD */
++
+ #define MSDOS_ROOT_INO        1       /* == MINIX_ROOT_INO */
+ #define MSDOS_DIR_BITS        5       /* log2(sizeof(struct msdos_dir_entry)) */
+@@ -25,8 +23,6 @@ struct statfs;
+ #define FAT_MAX_DIR_ENTRIES   (65536)
+ #define FAT_MAX_DIR_SIZE      (FAT_MAX_DIR_ENTRIES << MSDOS_DIR_BITS)
+-#define MSDOS_SUPER_MAGIC 0x4d44 /* MD */
+-
+ #define ATTR_NONE    0 /* no attribute bits */
+ #define ATTR_RO      1  /* read-only */
+ #define ATTR_HIDDEN  2  /* hidden */
+@@ -35,10 +31,10 @@ struct statfs;
+ #define ATTR_DIR     16 /* directory */
+ #define ATTR_ARCH    32 /* archived */
++/* attribute bits that are copied "as is" */
+ #define ATTR_UNUSED  (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
+-      /* attribute bits that are copied "as is" */
++/* bits that are used by the Windows 95/Windows NT extended FAT */
+ #define ATTR_EXT     (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
+-      /* bits that are used by the Windows 95/Windows NT extended FAT */
+ #define CASE_LOWER_BASE 8     /* base is lower case */
+ #define CASE_LOWER_EXT  16    /* extension is lower case */
+@@ -46,8 +42,12 @@ struct statfs;
+ #define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
+ #define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG)
++/* valid file mode bits */
+ #define MSDOS_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)
+-      /* valid file mode bits */
++/* Convert attribute bits and a mask to the UNIX mode. */
++#define MSDOS_MKMODE(a, m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO))
++/* Convert the UNIX mode to MS-DOS attribute bits. */
++#define MSDOS_MKATTR(m) ((m & S_IWUGO) ? ATTR_NONE : ATTR_RO)
+ #define MSDOS_NAME 11 /* maximum name length */
+ #define MSDOS_LONGNAME 256 /* maximum name length */
+@@ -55,24 +55,29 @@ struct statfs;
+ #define MSDOS_DOT    ".          " /* ".", padded to MSDOS_NAME chars */
+ #define MSDOS_DOTDOT "..         " /* "..", padded to MSDOS_NAME chars */
+-#define MSDOS_FAT12 4084 /* maximum number of clusters in a 12 bit FAT */
+-
+ /* media of boot sector */
+ #define FAT_VALID_MEDIA(x)    ((0xF8 <= (x) && (x) <= 0xFF) || (x) == 0xF0)
+ #define FAT_FIRST_ENT(s, x)   ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \
+       MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
++/* maximum number of clusters */
++#define MAX_FAT12 0xFF4
++#define MAX_FAT16 0xFFF4
++#define MAX_FAT32 0x0FFFFFF6
++#define MAX_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \
++      MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12)
++
+ /* bad cluster mark */
+ #define BAD_FAT12 0xFF7
+ #define BAD_FAT16 0xFFF7
+-#define BAD_FAT32 0xFFFFFF7
++#define BAD_FAT32 0x0FFFFFF7
+ #define BAD_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? BAD_FAT32 : \
+       MSDOS_SB(s)->fat_bits == 16 ? BAD_FAT16 : BAD_FAT12)
+ /* standard EOF */
+ #define EOF_FAT12 0xFFF
+ #define EOF_FAT16 0xFFFF
+-#define EOF_FAT32 0xFFFFFFF
++#define EOF_FAT32 0x0FFFFFFF
+ #define EOF_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? EOF_FAT32 : \
+       MSDOS_SB(s)->fat_bits == 16 ? EOF_FAT16 : EOF_FAT12)
+@@ -80,8 +85,8 @@ struct statfs;
+ #define FAT_ENT_BAD   (BAD_FAT32)
+ #define FAT_ENT_EOF   (EOF_FAT32)
+-#define FAT_FSINFO_SIG1               0x41615252
+-#define FAT_FSINFO_SIG2               0x61417272
++#define FAT_FSINFO_SIG1       0x41615252
++#define FAT_FSINFO_SIG2       0x61417272
+ #define IS_FSINFO(x)  (CF_LE_L((x)->signature1) == FAT_FSINFO_SIG1    \
+                        && CF_LE_L((x)->signature2) == FAT_FSINFO_SIG2)
+@@ -179,15 +184,10 @@ struct vfat_slot_info {
+       loff_t i_pos;                  /* on-disk position of directory entry */
+ };
+-/* Convert attribute bits and a mask to the UNIX mode. */
+-#define MSDOS_MKMODE(a,m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO))
+-
+-/* Convert the UNIX mode to MS-DOS attribute bits. */
+-#define MSDOS_MKATTR(m) ((m & S_IWUGO) ? ATTR_NONE : ATTR_RO)
+-
+-
+ #ifdef __KERNEL__
++#include <linux/buffer_head.h>
++#include <linux/string.h>
+ #include <linux/nls.h>
+ #include <linux/msdos_fs_i.h>
+ #include <linux/msdos_fs_sb.h>
+--- linux-2.6.0/include/linux/msdos_fs_sb.h    2003-07-27 12:14:40.000000000 -0700
++++ 25/include/linux/msdos_fs_sb.h     2003-12-28 23:22:51.000000000 -0800
+@@ -47,9 +47,9 @@ struct msdos_sb_info {
+       unsigned long data_start;    /* first data sector */
+       unsigned long clusters;      /* number of clusters */
+       unsigned long root_cluster;  /* first cluster of the root directory */
+-      unsigned long fsinfo_sector; /* FAT32 fsinfo offset from start of disk */
++      unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
+       struct semaphore fat_lock;
+-      int prev_free;               /* previously returned free cluster number */
++      int prev_free;               /* previously allocated cluster number */
+       int free_clusters;           /* -1 if undefined */
+       struct fat_mount_options options;
+       struct nls_table *nls_disk;  /* Codepage used on disk */
+--- linux-2.6.0/include/linux/nbd.h    2003-07-13 21:44:35.000000000 -0700
++++ 25/include/linux/nbd.h     2003-12-28 23:22:28.000000000 -0800
+@@ -35,6 +35,9 @@ enum {
+ /* Define PARANOIA to include extra sanity checking code in here & driver */
+ #define PARANOIA
++/* userspace doesn't need the nbd_device structure */
++#ifdef __KERNEL__
++
+ struct nbd_device {
+       int flags;
+       int harderror;          /* Code of hard error                   */
+@@ -53,6 +56,8 @@ struct nbd_device {
+       u64 bytesize;
+ };
++#endif
++
+ /* This now IS in some kind of include file...        */
+ /* These are send over network in request/reply magic field */
+--- linux-2.6.0/include/linux/netdevice.h      2003-11-23 19:03:02.000000000 -0800
++++ 25/include/linux/netdevice.h       2003-12-28 23:21:01.000000000 -0800
+@@ -452,6 +452,12 @@ struct net_device
+                                                    unsigned char *haddr);
+       int                     (*neigh_setup)(struct net_device *dev, struct neigh_parms *);
+       int                     (*accept_fastpath)(struct net_device *, struct dst_entry*);
++#ifdef CONFIG_NETPOLL_RX
++      int                     netpoll_rx;
++#endif
++#ifdef CONFIG_NET_POLL_CONTROLLER
++      void                    (*poll_controller)(struct net_device *dev);
++#endif
+       /* bridge stuff */
+       struct net_bridge_port  *br_port;
+@@ -470,8 +476,15 @@ struct net_device
+       /* class/net/name entry */
+       struct class_device     class_dev;
+       struct net_device_stats* (*last_stats)(struct net_device *);
++      /* how much padding had been added by alloc_netdev() */
++      int padded;
+ };
++static inline void *netdev_priv(struct net_device *dev)
++{
++      return (char *)dev + ((sizeof(struct net_device) + 31) & ~31);
++}
++
+ #define SET_MODULE_OWNER(dev) do { } while (0)
+ /* Set the sysfs physical device reference for the network logical device
+  * if set prior to registration will cause a symlink during initialization.
+@@ -496,6 +509,7 @@ extern rwlock_t                            dev_base_lock;          /* De
+ extern int                    netdev_boot_setup_add(char *name, struct ifmap *map);
+ extern int                    netdev_boot_setup_check(struct net_device *dev);
++extern unsigned long          netdev_boot_base(const char *prefix, int unit);
+ extern struct net_device    *dev_getbyhwaddr(unsigned short type, char *hwaddr);
+ extern struct net_device *__dev_getfirstbyhwtype(unsigned short type);
+ extern struct net_device *dev_getfirstbyhwtype(unsigned short type);
+@@ -533,6 +547,9 @@ extern int         dev_new_index(void);
+ extern struct net_device      *dev_get_by_index(int ifindex);
+ extern struct net_device      *__dev_get_by_index(int ifindex);
+ extern int            dev_restart(struct net_device *dev);
++#ifdef CONFIG_NETPOLL_TRAP
++extern int            netpoll_trap(void);
++#endif
+ typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len);
+ extern int            register_gifconf(unsigned int family, gifconf_func_t * gifconf);
+@@ -591,12 +608,20 @@ static inline void netif_start_queue(str
+ static inline void netif_wake_queue(struct net_device *dev)
+ {
++#ifdef CONFIG_NETPOLL_TRAP
++      if (netpoll_trap())
++              return;
++#endif
+       if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
+               __netif_schedule(dev);
+ }
+ static inline void netif_stop_queue(struct net_device *dev)
+ {
++#ifdef CONFIG_NETPOLL_TRAP
++      if (netpoll_trap())
++              return;
++#endif
+       set_bit(__LINK_STATE_XOFF, &dev->state);
+ }
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/netpoll.h 2003-12-28 23:21:01.000000000 -0800
+@@ -0,0 +1,38 @@
++/*
++ * Common code for low-level network console, dump, and debugger code
++ *
++ * Derived from netconsole, kgdb-over-ethernet, and netdump patches
++ */
++
++#ifndef _LINUX_NETPOLL_H
++#define _LINUX_NETPOLL_H
++
++#include <linux/netdevice.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/list.h>
++
++struct netpoll;
++
++struct netpoll {
++      struct net_device *dev;
++      char dev_name[16], *name;
++      void (*rx_hook)(struct netpoll *, int, char *, int);
++      u32 local_ip, remote_ip;
++      u16 local_port, remote_port;
++      unsigned char local_mac[6], remote_mac[6];
++      struct list_head rx_list;
++};
++
++void netpoll_poll(struct netpoll *np);
++void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);
++void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
++int netpoll_parse_options(struct netpoll *np, char *opt);
++int netpoll_setup(struct netpoll *np);
++int netpoll_trap(void);
++void netpoll_set_trap(int trap);
++void netpoll_cleanup(struct netpoll *np);
++int netpoll_rx(struct sk_buff *skb);
++
++
++#endif
+--- linux-2.6.0/include/linux/page-flags.h     2003-09-08 13:58:59.000000000 -0700
++++ 25/include/linux/page-flags.h      2003-12-28 23:22:25.000000000 -0800
+@@ -133,6 +133,7 @@ extern void get_full_page_state(struct p
+ #define inc_page_state(member)        mod_page_state(member, 1UL)
+ #define dec_page_state(member)        mod_page_state(member, 0UL - 1)
++#define add_page_state(member,delta) mod_page_state(member, (delta))
+ #define sub_page_state(member,delta) mod_page_state(member, 0UL - (delta))
+--- linux-2.6.0/include/linux/pagemap.h        2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/pagemap.h 2003-12-28 23:26:43.000000000 -0800
+@@ -8,7 +8,6 @@
+ #include <linux/fs.h>
+ #include <linux/list.h>
+ #include <linux/highmem.h>
+-#include <linux/pagemap.h>
+ #include <asm/uaccess.h>
+ #include <linux/gfp.h>
+@@ -71,7 +70,7 @@ extern struct page * find_trylock_page(s
+ extern struct page * find_or_create_page(struct address_space *mapping,
+                               unsigned long index, unsigned int gfp_mask);
+ extern unsigned int find_get_pages(struct address_space *mapping,
+-                              pgoff_t start, unsigned int nr_pages,
++                              pgoff_t *next, unsigned int nr_pages,
+                               struct page **pages);
+ /*
+@@ -153,17 +152,27 @@ static inline void ___add_to_page_cache(
+ extern void FASTCALL(__lock_page(struct page *page));
+ extern void FASTCALL(unlock_page(struct page *page));
+-static inline void lock_page(struct page *page)
++
++extern int FASTCALL(__lock_page_wq(struct page *page, wait_queue_t *wait));
++static inline int lock_page_wq(struct page *page, wait_queue_t *wait)
+ {
+       if (TestSetPageLocked(page))
+-              __lock_page(page);
++              return __lock_page_wq(page, wait);
++      else
++              return 0;
++}
++
++static inline void lock_page(struct page *page)
++{
++      lock_page_wq(page, NULL);
+ }
+       
+ /*
+  * This is exported only for wait_on_page_locked/wait_on_page_writeback.
+  * Never use this directly!
+  */
+-extern void FASTCALL(wait_on_page_bit(struct page *page, int bit_nr));
++extern int FASTCALL(wait_on_page_bit_wq(struct page *page, int bit_nr,
++      wait_queue_t *wait));
+ /* 
+  * Wait for a page to be unlocked.
+@@ -172,19 +181,33 @@ extern void FASTCALL(wait_on_page_bit(st
+  * ie with increased "page->count" so that the page won't
+  * go away during the wait..
+  */
+-static inline void wait_on_page_locked(struct page *page)
++static inline int wait_on_page_locked_wq(struct page *page, wait_queue_t *wait)
+ {
+       if (PageLocked(page))
+-              wait_on_page_bit(page, PG_locked);
++              return wait_on_page_bit_wq(page, PG_locked, wait);
++      return 0;
++}
++
++static inline int wait_on_page_writeback_wq(struct page *page,
++                                              wait_queue_t *wait)
++{
++      if (PageWriteback(page))
++              return wait_on_page_bit_wq(page, PG_writeback, wait);
++      return 0;
++}
++
++static inline void wait_on_page_locked(struct page *page)
++{
++      wait_on_page_locked_wq(page, NULL);
+ }
+ /* 
+  * Wait for a page to complete writeback
+  */
++
+ static inline void wait_on_page_writeback(struct page *page)
+ {
+-      if (PageWriteback(page))
+-              wait_on_page_bit(page, PG_writeback);
++      wait_on_page_writeback_wq(page, NULL);
+ }
+ extern void end_page_writeback(struct page *page);
+--- linux-2.6.0/include/linux/pagevec.h        2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/pagevec.h 2003-12-28 23:26:43.000000000 -0800
+@@ -23,7 +23,7 @@ void __pagevec_lru_add(struct pagevec *p
+ void __pagevec_lru_add_active(struct pagevec *pvec);
+ void pagevec_strip(struct pagevec *pvec);
+ unsigned int pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
+-              pgoff_t start, unsigned int nr_pages);
++              pgoff_t *next, unsigned int nr_pages);
+ static inline void pagevec_init(struct pagevec *pvec, int cold)
+ {
+--- linux-2.6.0/include/linux/parser.h 2003-10-08 15:07:10.000000000 -0700
++++ 25/include/linux/parser.h  2003-12-28 23:22:09.000000000 -0800
+@@ -1,3 +1,14 @@
++/*
++ * linux/include/linux/parser.h
++ *
++ * Header for lib/parser.c
++ * Intended use of these functions is parsing filesystem argument lists,
++ * but could potentially be used anywhere else that simple option=arg
++ * parsing is required.
++ */
++
++
++/* associates an integer enumerator with a pattern string. */
+ struct match_token {
+       int token;
+       char *pattern;
+@@ -5,15 +16,16 @@ struct match_token {
+ typedef struct match_token match_table_t[];
++/* Maximum number of arguments that match_token will find in a pattern */
+ enum {MAX_OPT_ARGS = 3};
++/* Describe the location within a string of a substring */
+ typedef struct {
+       char *from;
+       char *to;
+ } substring_t;
+-int match_token(char *s, match_table_t table, substring_t args[]);
+-
++int match_token(char *, match_table_t table, substring_t args[]);
+ int match_int(substring_t *, int *result);
+ int match_octal(substring_t *, int *result);
+ int match_hex(substring_t *, int *result);
+--- linux-2.6.0/include/linux/pci.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/pci.h     2003-12-28 23:21:44.000000000 -0800
+@@ -36,6 +36,7 @@
+ #define  PCI_COMMAND_WAIT     0x80    /* Enable address/data stepping */
+ #define  PCI_COMMAND_SERR     0x100   /* Enable SERR */
+ #define  PCI_COMMAND_FAST_BACK        0x200   /* Enable back-to-back writes */
++#define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
+ #define PCI_STATUS            0x06    /* 16 bits */
+ #define  PCI_STATUS_CAP_LIST  0x10    /* Support Capability List */
+@@ -198,6 +199,8 @@
+ #define  PCI_CAP_ID_MSI               0x05    /* Message Signalled Interrupts */
+ #define  PCI_CAP_ID_CHSWP     0x06    /* CompactPCI HotSwap */
+ #define  PCI_CAP_ID_PCIX      0x07    /* PCI-X */
++#define  PCI_CAP_ID_EXP       0x10    /* PCI Express */
++#define  PCI_CAP_ID_MSIX      0x11    /* MSI-X */
+ #define PCI_CAP_LIST_NEXT     1       /* Next capability in the list */
+ #define PCI_CAP_FLAGS         2       /* Capability defined flags (16 bits) */
+ #define PCI_CAP_SIZEOF                4
+@@ -275,11 +278,13 @@
+ #define  PCI_MSI_FLAGS_QSIZE  0x70    /* Message queue size configured */
+ #define  PCI_MSI_FLAGS_QMASK  0x0e    /* Maximum queue size available */
+ #define  PCI_MSI_FLAGS_ENABLE 0x01    /* MSI feature enabled */
++#define  PCI_MSI_FLAGS_MASKBIT        0x100   /* 64-bit mask bits allowed */
+ #define PCI_MSI_RFU           3       /* Rest of capability flags */
+ #define PCI_MSI_ADDRESS_LO    4       /* Lower 32 bits */
+ #define PCI_MSI_ADDRESS_HI    8       /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
+ #define PCI_MSI_DATA_32               8       /* 16 bits of data for 32-bit devices */
+ #define PCI_MSI_DATA_64               12      /* 16 bits of data for 64-bit devices */
++#define PCI_MSI_MASK_BIT      16      /* Mask bits register */
+ /* CompactPCI Hotswap Register */
+@@ -695,6 +700,18 @@ void pci_pool_free (struct pci_pool *poo
+ extern struct pci_dev *isa_bridge;
+ #endif
++#ifndef CONFIG_PCI_USE_VECTOR
++static inline void pci_scan_msi_device(struct pci_dev *dev) {}
++static inline int pci_enable_msi(struct pci_dev *dev) {return -1;}
++static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
++#else
++extern void pci_scan_msi_device(struct pci_dev *dev);
++extern int pci_enable_msi(struct pci_dev *dev);
++extern void msi_remove_pci_irq_vectors(struct pci_dev *dev);
++extern int msi_alloc_vectors(struct pci_dev* dev, int *vector, int nvec);
++extern int msi_free_vectors(struct pci_dev* dev, int *vector, int nvec);
++#endif
++
+ #endif /* CONFIG_PCI */
+ /* Include architecture-dependent settings and functions */
+--- linux-2.6.0/include/linux/pci_ids.h        2003-11-23 19:03:02.000000000 -0800
++++ 25/include/linux/pci_ids.h 2003-12-28 23:26:27.000000000 -0800
+@@ -630,6 +630,8 @@
+ #define PCI_DEVICE_ID_HP_TACHLITE     0x1029
+ #define PCI_DEVICE_ID_HP_J2585A               0x1030
+ #define PCI_DEVICE_ID_HP_J2585B               0x1031
++#define PCI_DEVICE_ID_HP_J2973A               0x1040
++#define PCI_DEVICE_ID_HP_J2970A               0x1042
+ #define PCI_DEVICE_ID_HP_DIVA         0x1048
+ #define PCI_DEVICE_ID_HP_DIVA_TOSCA1  0x1049
+ #define PCI_DEVICE_ID_HP_DIVA_TOSCA2  0x104A
+@@ -882,6 +884,7 @@
+ #define PCI_DEVICE_ID_SII_680         0x0680
+ #define PCI_DEVICE_ID_SII_3112                0x3112
++#define PCI_DEVICE_ID_SII_3114                0x3114
+ #define PCI_DEVICE_ID_SII_1210SA      0x0240
+ #define PCI_VENDOR_ID_VISION          0x1098
+@@ -900,6 +903,7 @@
+ #define PCI_VENDOR_ID_SGI             0x10a9
+ #define PCI_DEVICE_ID_SGI_IOC3                0x0003
++#define PCI_DEVICE_ID_SGI_IOC4                0x100a
+ #define PCI_VENDOR_ID_SGI_LITHIUM     0x1002
+ #define PCI_VENDOR_ID_ACC             0x10aa
+@@ -1784,11 +1788,13 @@
+ #define PCI_DEVICE_ID_TIGON3_5702     0x1646
+ #define PCI_DEVICE_ID_TIGON3_5703     0x1647
+ #define PCI_DEVICE_ID_TIGON3_5704     0x1648
++#define PCI_DEVICE_ID_TIGON3_5704S_2  0x1649
+ #define PCI_DEVICE_ID_TIGON3_5702FE   0x164d
+ #define PCI_DEVICE_ID_TIGON3_5705     0x1653
+ #define PCI_DEVICE_ID_TIGON3_5705_2   0x1654
+ #define PCI_DEVICE_ID_TIGON3_5705M    0x165d
+ #define PCI_DEVICE_ID_TIGON3_5705M_2  0x165e
++#define PCI_DEVICE_ID_TIGON3_5705F    0x166e
+ #define PCI_DEVICE_ID_TIGON3_5782     0x1696
+ #define PCI_DEVICE_ID_TIGON3_5788     0x169c
+ #define PCI_DEVICE_ID_TIGON3_5702X    0x16a6
+@@ -2052,6 +2058,7 @@
+ #define PCI_DEVICE_ID_INTEL_82443MX_3 0x719b
+ #define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0
+ #define PCI_DEVICE_ID_INTEL_82443GX_1 0x71a1
++#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2
+ #define PCI_DEVICE_ID_INTEL_82372FB_0 0x7600
+ #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
+ #define PCI_DEVICE_ID_INTEL_82372FB_2 0x7602
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/include/linux/pci_msi.h 2003-12-28 23:21:44.000000000 -0800
+@@ -0,0 +1,193 @@
++/*
++ *    ../include/linux/pci_msi.h
++ *
++ */
++
++#ifndef _ASM_PCI_MSI_H
++#define _ASM_PCI_MSI_H
++
++#include <linux/pci.h>
++
++#define MSI_AUTO -1
++#define NR_REPEATS    23
++#define NR_RESERVED_VECTORS 3 /*FIRST_DEVICE_VECTOR,FIRST_SYSTEM_VECTOR,0x80 */
++
++/*
++ * Assume the maximum number of hot plug slots supported by the system is about
++ * ten. The worstcase is that each of these slots is hot-added with a device,
++ * which has two MSI/MSI-X capable functions. To avoid any MSI-X driver, which
++ * attempts to request all available vectors, NR_HP_RESERVED_VECTORS is defined
++ * as below to ensure at least one message is assigned to each detected MSI/
++ * MSI-X device function.
++ */
++#define NR_HP_RESERVED_VECTORS        20
++
++extern int vector_irq[NR_IRQS];
++extern cpumask_t pending_irq_balance_cpumask[NR_IRQS];
++extern void (*interrupt[NR_IRQS])(void);
++
++#ifdef CONFIG_SMP
++#define set_msi_irq_affinity  set_msi_affinity
++#else
++#define set_msi_irq_affinity  NULL
++static inline void move_msi(int vector) {}
++#endif
++
++#ifndef CONFIG_X86_IO_APIC
++static inline int get_ioapic_vector(struct pci_dev *dev) { return -1;}
++static inline void restore_ioapic_irq_handler(int irq) {}
++#else
++extern void restore_ioapic_irq_handler(int irq);
++#endif
++
++/*
++ * MSI-X Address Register
++ */
++#define PCI_MSIX_FLAGS_QSIZE          0x7FF
++#define PCI_MSIX_FLAGS_ENABLE         (1 << 15)
++#define PCI_MSIX_FLAGS_BIRMASK                (7 << 0)
++#define PCI_MSIX_FLAGS_BITMASK                (1 << 0)
++
++#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET      0
++#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET      4
++#define PCI_MSIX_ENTRY_DATA_OFFSET            8
++#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET     12
++#define PCI_MSIX_ENTRY_SIZE                   16
++
++#define msi_control_reg(base)         (base + PCI_MSI_FLAGS)
++#define msi_lower_address_reg(base)   (base + PCI_MSI_ADDRESS_LO)
++#define msi_upper_address_reg(base)   (base + PCI_MSI_ADDRESS_HI)
++#define msi_data_reg(base, is64bit)   \
++      ( (is64bit == 1) ? base+PCI_MSI_DATA_64 : base+PCI_MSI_DATA_32 )
++#define msi_mask_bits_reg(base, is64bit) \
++      ( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4)
++#define msi_disable(control)          control &= ~PCI_MSI_FLAGS_ENABLE
++#define multi_msi_capable(control) \
++      (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1))
++#define multi_msi_enable(control, num) \
++      control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE);
++#define is_64bit_address(control)     (control & PCI_MSI_FLAGS_64BIT)
++#define is_mask_bit_support(control)  (control & PCI_MSI_FLAGS_MASKBIT)
++#define msi_enable(control, num) multi_msi_enable(control, num); \
++      control |= PCI_MSI_FLAGS_ENABLE
++
++#define msix_control_reg              msi_control_reg
++#define msix_table_offset_reg(base)   (base + 0x04)
++#define msix_pba_offset_reg(base)     (base + 0x08)
++#define msix_enable(control)          control |= PCI_MSIX_FLAGS_ENABLE
++#define msix_disable(control)         control &= ~PCI_MSIX_FLAGS_ENABLE
++#define msix_table_size(control)      ((control & PCI_MSIX_FLAGS_QSIZE)+1)
++#define multi_msix_capable            msix_table_size
++#define msix_unmask(address)          (address & ~PCI_MSIX_FLAGS_BITMASK)
++#define msix_mask(address)            (address | PCI_MSIX_FLAGS_BITMASK)
++#define msix_is_pending(address)      (address & PCI_MSIX_FLAGS_PENDMASK)
++
++extern char __dbg_str_buf[256];
++#define _DEFINE_DBG_BUFFER    char __dbg_str_buf[256];
++#define _DBG_K_TRACE_ENTRY    ((unsigned int)0x00000001)
++#define _DBG_K_TRACE_EXIT     ((unsigned int)0x00000002)
++#define _DBG_K_INFO           ((unsigned int)0x00000004)
++#define _DBG_K_ERROR          ((unsigned int)0x00000008)
++#define _DBG_K_TRACE  (_DBG_K_TRACE_ENTRY | _DBG_K_TRACE_EXIT)
++
++#define _DEBUG_LEVEL  (_DBG_K_INFO | _DBG_K_ERROR | _DBG_K_TRACE)
++#define _DBG_PRINT( dbg_flags, args... )              \
++if ( _DEBUG_LEVEL & (dbg_flags) )                     \
++{                                                     \
++      int len;                                        \
++      len = sprintf(__dbg_str_buf, "%s:%d: %s ",      \
++              __FILE__, __LINE__, __FUNCTION__ );     \
++      sprintf(__dbg_str_buf + len, args);             \
++      printk(KERN_INFO "%s\n", __dbg_str_buf);        \
++}
++
++#define MSI_FUNCTION_TRACE_ENTER      \
++      _DBG_PRINT (_DBG_K_TRACE_ENTRY, "%s", "[Entry]");
++#define MSI_FUNCTION_TRACE_EXIT               \
++      _DBG_PRINT (_DBG_K_TRACE_EXIT, "%s", "[Entry]");
++
++/*
++ * MSI Defined Data Structures
++ */
++#define MSI_ADDRESS_HEADER            0xfee
++#define MSI_ADDRESS_HEADER_SHIFT      12
++#define MSI_ADDRESS_HEADER_MASK               0xfff000
++#define MSI_TARGET_CPU_SHIFT          4
++#define MSI_TARGET_CPU_MASK           0xff
++#define MSI_DELIVERY_MODE             0
++#define MSI_LEVEL_MODE                        1       /* Edge always assert */
++#define MSI_TRIGGER_MODE              0       /* MSI is edge sensitive */
++#define MSI_LOGICAL_MODE              1
++#define MSI_REDIRECTION_HINT_MODE     0
++#ifdef CONFIG_SMP
++#define MSI_TARGET_CPU                        logical_smp_processor_id()
++#else
++#define MSI_TARGET_CPU                        TARGET_CPUS
++#endif
++
++struct msg_data {
++#if defined(__LITTLE_ENDIAN_BITFIELD)
++      __u32   vector          :  8;
++      __u32   delivery_mode   :  3;   /* 000b: FIXED | 001b: lowest prior */
++      __u32   reserved_1      :  3;
++      __u32   level           :  1;   /* 0: deassert | 1: assert */
++      __u32   trigger         :  1;   /* 0: edge | 1: level */
++      __u32   reserved_2      : 16;
++#elif defined(__BIG_ENDIAN_BITFIELD)
++      __u32   reserved_2      : 16;
++      __u32   trigger         :  1;   /* 0: edge | 1: level */
++      __u32   level           :  1;   /* 0: deassert | 1: assert */
++      __u32   reserved_1      :  3;
++      __u32   delivery_mode   :  3;   /* 000b: FIXED | 001b: lowest prior */
++      __u32   vector          :  8;
++#else
++#error "Bitfield endianness not defined! Check your byteorder.h"
++#endif
++} __attribute__ ((packed));
++
++struct msg_address {
++      union {
++              struct {
++#if defined(__LITTLE_ENDIAN_BITFIELD)
++                      __u32   reserved_1      :  2;
++                      __u32   dest_mode       :  1;   /*0:physic | 1:logic */
++                      __u32   redirection_hint:  1;   /*0: dedicated CPU
++                                                        1: lowest priority */
++                      __u32   reserved_2      :  4;
++                      __u32   dest_id         : 24;   /* Destination ID */
++#elif defined(__BIG_ENDIAN_BITFIELD)
++                      __u32   dest_id         : 24;   /* Destination ID */
++                      __u32   reserved_2      :  4;
++                      __u32   redirection_hint:  1;   /*0: dedicated CPU
++                                                        1: lowest priority */
++                      __u32   dest_mode       :  1;   /*0:physic | 1:logic */
++                      __u32   reserved_1      :  2;
++#else
++#error "Bitfield endianness not defined! Check your byteorder.h"
++#endif
++                      }u;
++                      __u32  value;
++      }lo_address;
++      __u32   hi_address;
++} __attribute__ ((packed));
++
++struct msi_desc {
++      struct {
++              __u8    type    : 5;    /* {0: unused, 5h:MSI, 11h:MSI-X} */
++              __u8    maskbit : 1;    /* mask-pending bit supported ?   */
++              __u8    reserved: 2;    /* reserved                       */
++              __u8    entry_nr;       /* specific enabled entry         */
++              __u8    default_vector; /* default pre-assigned vector    */
++              __u8    current_cpu;    /* current destination cpu        */
++      }msi_attrib;
++
++      struct {
++              __u16   head;
++              __u16   tail;
++      }link;
++
++      unsigned long mask_base;
++      struct pci_dev *dev;
++};
++
++#endif /* _ASM_PCI_MSI_H */
+--- linux-2.6.0/include/linux/percpu_counter.h 2003-06-14 12:18:22.000000000 -0700
++++ 25/include/linux/percpu_counter.h  2003-12-28 23:22:03.000000000 -0800
+@@ -8,17 +8,14 @@
+ #include <linux/spinlock.h>
+ #include <linux/smp.h>
+ #include <linux/threads.h>
++#include <linux/percpu.h>
+ #ifdef CONFIG_SMP
+-struct __percpu_counter {
+-      long count;
+-} ____cacheline_aligned;
+-
+ struct percpu_counter {
+       spinlock_t lock;
+       long count;
+-      struct __percpu_counter counters[NR_CPUS];
++      long *counters;
+ };
+ #if NR_CPUS >= 16
+@@ -29,12 +26,14 @@ struct percpu_counter {
+ static inline void percpu_counter_init(struct percpu_counter *fbc)
+ {
+-      int i;
+-
+       spin_lock_init(&fbc->lock);
+       fbc->count = 0;
+-      for (i = 0; i < NR_CPUS; i++)
+-              fbc->counters[i].count = 0;
++      fbc->counters = alloc_percpu(long);
++}
++
++static inline void percpu_counter_destroy(struct percpu_counter *fbc)
++{
++      free_percpu(fbc->counters);
+ }
+ void percpu_counter_mod(struct percpu_counter *fbc, long amount);
+@@ -69,6 +68,10 @@ static inline void percpu_counter_init(s
+       fbc->count = 0;
+ }
++static inline void percpu_counter_destroy(struct percpu_counter *fbc)
++{
++}
++
+ static inline void
+ percpu_counter_mod(struct percpu_counter *fbc, long amount)
+ {
+--- linux-2.6.0/include/linux/proc_fs.h        2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/proc_fs.h 2003-12-28 23:21:25.000000000 -0800
+@@ -141,6 +141,8 @@ extern void proc_rtas_init(void);
+ extern struct proc_dir_entry *proc_symlink(const char *,
+               struct proc_dir_entry *, const char *);
+ extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
++extern struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode,
++                      struct proc_dir_entry *parent);
+ static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
+       mode_t mode, struct proc_dir_entry *base, 
+--- linux-2.6.0/include/linux/quota.h  2003-08-08 22:55:14.000000000 -0700
++++ 25/include/linux/quota.h   2003-12-28 23:22:17.000000000 -0800
+@@ -250,7 +250,7 @@ struct dquot_operations {
+       void (*free_space) (struct inode *, qsize_t);
+       void (*free_inode) (const struct inode *, unsigned long);
+       int (*transfer) (struct inode *, struct iattr *);
+-      int (*sync_dquot) (struct dquot *);
++      int (*write_dquot) (struct dquot *);
+ };
+ /* Operations handling requests from userspace */
+--- linux-2.6.0/include/linux/reiserfs_fs.h    2003-09-27 18:57:47.000000000 -0700
++++ 25/include/linux/reiserfs_fs.h     2003-12-28 23:23:05.000000000 -0800
+@@ -1719,7 +1719,7 @@ void reiserfs_allow_writes(struct super_
+ void reiserfs_check_lock_depth(char *caller) ;
+ void reiserfs_prepare_for_journal(struct super_block *, struct buffer_head *bh, int wait) ;
+ void reiserfs_restore_prepared_buffer(struct super_block *, struct buffer_head *bh) ;
+-int journal_init(struct super_block *, const char * j_dev_name, int old_format) ;
++int journal_init(struct super_block *, const char * j_dev_name, int old_format, unsigned int) ;
+ int journal_release(struct reiserfs_transaction_handle*, struct super_block *) ;
+ int journal_release_error(struct reiserfs_transaction_handle*, struct super_block *) ;
+ int journal_end(struct reiserfs_transaction_handle *, struct super_block *, unsigned long) ;
+--- linux-2.6.0/include/linux/sched.h  2003-11-23 19:03:02.000000000 -0800
++++ 25/include/linux/sched.h   2003-12-28 23:26:39.000000000 -0800
+@@ -151,6 +151,7 @@ extern void init_idle(task_t *idle, int 
+ extern void show_state(void);
+ extern void show_regs(struct pt_regs *);
++extern void show_trace_task(task_t *tsk);
+ /*
+  * TASK is a pointer to the task whose backtrace we want to see (or NULL for current
+@@ -205,7 +206,6 @@ struct mm_struct {
+       unsigned long rss, total_vm, locked_vm;
+       unsigned long def_flags;
+       cpumask_t cpu_vm_mask;
+-      unsigned long swap_address;
+       unsigned long saved_auxv[40]; /* for /proc/PID/auxv */
+@@ -464,6 +464,13 @@ struct task_struct {
+       unsigned long ptrace_message;
+       siginfo_t *last_siginfo; /* For ptrace use.  */
++/*
++ * current io wait handle: wait queue entry to use for io waits
++ * If this thread is processing aio, this points at the waitqueue
++ * inside the currently handled kiocb. It may be NULL (i.e. default
++ * to a stack based synchronous wait) if its doing sync IO.
++ */
++      wait_queue_t *io_wait;
+ };
+ static inline pid_t process_group(struct task_struct *tsk)
+@@ -580,6 +587,7 @@ extern int FASTCALL(wake_up_process(stru
+  static inline void kick_process(struct task_struct *tsk) { }
+ #endif
+ extern void FASTCALL(wake_up_forked_process(struct task_struct * tsk));
++extern void FASTCALL(sched_fork(task_t * p));
+ extern void FASTCALL(sched_exit(task_t * p));
+ asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru);
+--- linux-2.6.0/include/linux/serial_core.h    2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/serial_core.h     2003-12-28 23:21:07.000000000 -0800
+@@ -158,7 +158,9 @@ struct uart_port {
+       unsigned char           x_char;                 /* xon/xoff char */
+       unsigned char           regshift;               /* reg offset shift */
+       unsigned char           iotype;                 /* io access style */
+-
++#ifdef CONFIG_KGDB
++      int                     kgdb;                   /* in use by kgdb */
++#endif
+ #define UPIO_PORT             (0)
+ #define UPIO_HUB6             (1)
+ #define UPIO_MEM              (2)
+--- linux-2.6.0/include/linux/serio.h  2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/serio.h   2003-12-28 23:21:30.000000000 -0800
+@@ -49,6 +49,7 @@ struct serio_dev {
+       irqreturn_t (*interrupt)(struct serio *, unsigned char,
+                       unsigned int, struct pt_regs *);
+       void (*connect)(struct serio *, struct serio_dev *dev);
++      int  (*reconnect)(struct serio *);
+       void (*disconnect)(struct serio *);
+       void (*cleanup)(struct serio *);
+@@ -58,12 +59,15 @@ struct serio_dev {
+ int serio_open(struct serio *serio, struct serio_dev *dev);
+ void serio_close(struct serio *serio);
+ void serio_rescan(struct serio *serio);
++void serio_reconnect(struct serio *serio);
+ irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs);
+ void serio_register_port(struct serio *serio);
+-void serio_register_slave_port(struct serio *serio);
++void serio_register_port_delayed(struct serio *serio);
++void __serio_register_port(struct serio *serio);
+ void serio_unregister_port(struct serio *serio);
+-void serio_unregister_slave_port(struct serio *serio);
++void serio_unregister_port_delayed(struct serio *serio);
++void __serio_unregister_port(struct serio *serio);
+ void serio_register_device(struct serio_dev *dev);
+ void serio_unregister_device(struct serio_dev *dev);
+--- linux-2.6.0/include/linux/spinlock.h       2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/spinlock.h        2003-12-28 23:26:33.000000000 -0800
+@@ -15,6 +15,12 @@
+ #include <asm/processor.h>    /* for cpu relax */
+ #include <asm/system.h>
++#ifdef CONFIG_KGDB
++#include <asm/current.h>
++#define SET_WHO(x, him) (x)->who = him;
++#else
++#define SET_WHO(x, him)
++#endif
+ /*
+  * Must define these before including other files, inline functions need them
+@@ -55,6 +61,9 @@ typedef struct {
+       const char *module;
+       char *owner;
+       int oline;
++#ifdef CONFIG_KGDB
++      struct task_struct *who;
++#endif
+ } spinlock_t;
+ #define SPIN_LOCK_UNLOCKED (spinlock_t) { SPINLOCK_MAGIC, 0, 10, __FILE__ , NULL, 0}
+@@ -66,6 +75,7 @@ typedef struct {
+               (x)->module = __FILE__; \
+               (x)->owner = NULL; \
+               (x)->oline = 0; \
++                SET_WHO(x, NULL) \
+       } while (0)
+ #define CHECK_LOCK(x) \
+@@ -88,6 +98,7 @@ typedef struct {
+               (x)->lock = 1; \
+               (x)->owner = __FILE__; \
+               (x)->oline = __LINE__; \
++                SET_WHO(x, current)       \
+       } while (0)
+ /* without debugging, spin_is_locked on UP always says
+@@ -118,6 +129,7 @@ typedef struct {
+               (x)->lock = 1; \
+               (x)->owner = __FILE__; \
+               (x)->oline = __LINE__; \
++                SET_WHO(x, current)       \
+               1; \
+       })
+@@ -184,6 +196,17 @@ typedef struct {
+ #endif /* !SMP */
++#ifdef CONFIG_LOCKMETER
++extern void _metered_spin_lock   (spinlock_t *lock);
++extern void _metered_spin_unlock (spinlock_t *lock);
++extern int  _metered_spin_trylock(spinlock_t *lock);
++extern void _metered_read_lock    (rwlock_t *lock);
++extern void _metered_read_unlock  (rwlock_t *lock);
++extern void _metered_write_lock   (rwlock_t *lock);
++extern void _metered_write_unlock (rwlock_t *lock);
++extern int  _metered_write_trylock(rwlock_t *lock);
++#endif
++
+ /*
+  * Define the various spin_lock and rw_lock methods.  Note we define these
+  * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various
+@@ -389,6 +412,141 @@ do { \
+                               _raw_spin_trylock(lock) ? 1 : \
+                               ({preempt_enable(); local_bh_enable(); 0;});})
++#ifdef CONFIG_LOCKMETER
++#undef spin_lock
++#undef spin_trylock
++#undef spin_unlock
++#undef spin_lock_irqsave
++#undef spin_lock_irq
++#undef spin_lock_bh
++#undef read_lock
++#undef read_unlock
++#undef write_lock
++#undef write_unlock
++#undef write_trylock
++#undef spin_unlock_bh
++#undef read_lock_irqsave
++#undef read_lock_irq
++#undef read_lock_bh
++#undef read_unlock_bh
++#undef write_lock_irqsave
++#undef write_lock_irq
++#undef write_lock_bh
++#undef write_unlock_bh
++
++#define spin_lock(lock) \
++do { \
++      preempt_disable(); \
++      _metered_spin_lock(lock); \
++} while(0)
++
++#define spin_trylock(lock)     ({preempt_disable(); _metered_spin_trylock(lock) ? \
++                              1 : ({preempt_enable(); 0;});})
++#define spin_unlock(lock) \
++do { \
++      _metered_spin_unlock(lock); \
++      preempt_enable(); \
++} while (0)
++
++#define spin_lock_irqsave(lock, flags) \
++do { \
++      local_irq_save(flags); \
++      preempt_disable(); \
++      _metered_spin_lock(lock); \
++} while (0)
++
++#define spin_lock_irq(lock) \
++do { \
++      local_irq_disable(); \
++      preempt_disable(); \
++      _metered_spin_lock(lock); \
++} while (0)
++
++#define spin_lock_bh(lock) \
++do { \
++      local_bh_disable(); \
++      preempt_disable(); \
++      _metered_spin_lock(lock); \
++} while (0)
++
++#define spin_unlock_bh(lock) \
++do { \
++      _metered_spin_unlock(lock); \
++      preempt_enable(); \
++      local_bh_enable(); \
++} while (0)
++
++
++#define read_lock(lock)                ({preempt_disable(); _metered_read_lock(lock);})
++#define read_unlock(lock)      ({_metered_read_unlock(lock); preempt_enable();})
++#define write_lock(lock)       ({preempt_disable(); _metered_write_lock(lock);})
++#define write_unlock(lock)     ({_metered_write_unlock(lock); preempt_enable();})
++#define write_trylock(lock)    ({preempt_disable();_metered_write_trylock(lock) ? \
++                              1 : ({preempt_enable(); 0;});})
++#define spin_unlock_no_resched(lock) \
++do { \
++      _metered_spin_unlock(lock); \
++      preempt_enable_no_resched(); \
++} while (0)
++
++#define read_lock_irqsave(lock, flags) \
++do { \
++      local_irq_save(flags); \
++      preempt_disable(); \
++      _metered_read_lock(lock); \
++} while (0)
++
++#define read_lock_irq(lock) \
++do { \
++      local_irq_disable(); \
++      preempt_disable(); \
++      _metered_read_lock(lock); \
++} while (0)
++
++#define read_lock_bh(lock) \
++do { \
++      local_bh_disable(); \
++      preempt_disable(); \
++      _metered_read_lock(lock); \
++} while (0)
++
++#define read_unlock_bh(lock) \
++do { \
++      _metered_read_unlock(lock); \
++      preempt_enable(); \
++      local_bh_enable(); \
++} while (0)
++
++#define write_lock_irqsave(lock, flags) \
++do { \
++      local_irq_save(flags); \
++      preempt_disable(); \
++      _metered_write_lock(lock); \
++} while (0)
++
++#define write_lock_irq(lock) \
++do { \
++      local_irq_disable(); \
++      preempt_disable(); \
++      _metered_write_lock(lock); \
++} while (0)
++
++#define write_lock_bh(lock) \
++do { \
++      local_bh_disable(); \
++      preempt_disable(); \
++      _metered_write_lock(lock); \
++} while (0)
++
++#define write_unlock_bh(lock) \
++do { \
++      _metered_write_unlock(lock); \
++      preempt_enable(); \
++      local_bh_enable(); \
++} while (0)
++
++#endif /* !CONFIG_LOCKMETER */
++
+ /* "lock on reference count zero" */
+ #ifndef ATOMIC_DEC_AND_LOCK
+ #include <asm/atomic.h>
+--- linux-2.6.0/include/linux/swap.h   2003-10-08 15:07:10.000000000 -0700
++++ 25/include/linux/swap.h    2003-12-28 23:22:46.000000000 -0800
+@@ -173,7 +173,7 @@ extern int rotate_reclaimable_page(struc
+ extern void swap_setup(void);
+ /* linux/mm/vmscan.c */
+-extern int try_to_free_pages(struct zone *, unsigned int, unsigned int);
++extern int try_to_free_pages(struct zone **, unsigned int, unsigned int);
+ extern int shrink_all_memory(int);
+ extern int vm_swappiness;
+--- linux-2.6.0/include/linux/sysctl.h 2003-11-23 19:03:02.000000000 -0800
++++ 25/include/linux/sysctl.h  2003-12-28 23:26:39.000000000 -0800
+@@ -601,6 +601,8 @@ enum
+       FS_LEASE_TIME=15,       /* int: maximum time to wait for a lease break */
+       FS_DQSTATS=16,  /* disc quota usage statistics */
+       FS_XFS=17,      /* struct: control xfs parameters */
++      FS_AIO_NR=18,   /* current system-wide number of aio requests */
++      FS_AIO_MAX_NR=19,       /* system-wide maximum number of aio requests */
+ };
+ /* /proc/sys/fs/quota/ */
+--- linux-2.6.0/include/linux/sysfs.h  2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/sysfs.h   2003-12-28 23:21:50.000000000 -0800
+@@ -18,6 +18,12 @@ struct attribute {
+       mode_t                  mode;
+ };
++struct attribute_group {
++      char                    * name;
++      struct attribute        ** attrs;
++};
++
++
+ struct bin_attribute {
+       struct attribute        attr;
+       size_t                  size;
+@@ -25,14 +31,13 @@ struct bin_attribute {
+       ssize_t (*write)(struct kobject *, char *, loff_t, size_t);
+ };
+-int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+-int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+-
+ struct sysfs_ops {
+       ssize_t (*show)(struct kobject *, struct attribute *,char *);
+       ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
+ };
++#ifdef CONFIG_SYSFS
++
+ extern int
+ sysfs_create_dir(struct kobject *);
+@@ -57,13 +62,75 @@ sysfs_create_link(struct kobject * kobj,
+ extern void
+ sysfs_remove_link(struct kobject *, char * name);
+-
+-struct attribute_group {
+-      char                    * name;
+-      struct attribute        ** attrs;
+-};
++int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
++int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
+ int sysfs_create_group(struct kobject *, const struct attribute_group *);
+ void sysfs_remove_group(struct kobject *, const struct attribute_group *);
++#else /* CONFIG_SYSFS */
++
++static inline int sysfs_create_dir(struct kobject * k)
++{
++      return 0;
++}
++
++static inline void sysfs_remove_dir(struct kobject * k)
++{
++      ;
++}
++
++static inline void sysfs_rename_dir(struct kobject * k, const char *new_name)
++{
++      ;
++}
++
++static inline int sysfs_create_file(struct kobject * k, const struct attribute * a)
++{
++      return 0;
++}
++
++static inline int sysfs_update_file(struct kobject * k, const struct attribute * a)
++{
++      return 0;
++}
++
++static inline void sysfs_remove_file(struct kobject * k, const struct attribute * a)
++{
++      ;
++}
++
++static inline int sysfs_create_link(struct kobject * k, struct kobject * t, char * n)
++{
++      return 0;
++}
++
++static inline void sysfs_remove_link(struct kobject * k, char * name)
++{
++      ;
++}
++
++
++static inline int sysfs_create_bin_file(struct kobject * k, struct bin_attribute * a)
++{
++      return 0;
++}
++
++static inline int sysfs_remove_bin_file(struct kobject * k, struct bin_attribute * a)
++{
++      return 0;
++}
++
++static inline int sysfs_create_group(struct kobject * k, const struct attribute_group *g)
++{
++      return 0;
++}
++
++static inline void sysfs_remove_group(struct kobject * k, const struct attribute_group * g)
++{
++      ;
++}
++
++#endif /* CONFIG_SYSFS */
++
+ #endif /* _SYSFS_H_ */
+--- linux-2.6.0/include/linux/wait.h   2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/wait.h    2003-12-28 23:26:39.000000000 -0800
+@@ -80,6 +80,15 @@ static inline int waitqueue_active(wait_
+       return !list_empty(&q->task_list);
+ }
++/*
++ * Used to distinguish between sync and async io wait context:
++ * sync i/o typically specifies a NULL wait queue entry or a wait
++ * queue entry bound to a task (current task) to wake up.
++ * aio specifies a wait queue entry with an async notification
++ * callback routine, not associated with any task.
++ */
++#define is_sync_wait(wait)    (!(wait) || ((wait)->task))
++
+ extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
+ extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
+ extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
+--- linux-2.6.0/include/linux/writeback.h      2003-11-09 16:45:05.000000000 -0800
++++ 25/include/linux/writeback.h       2003-12-28 23:26:42.000000000 -0800
+@@ -84,9 +84,13 @@ int dirty_writeback_centisecs_handler(st
+                                     void __user *, size_t *);
+ void page_writeback_init(void);
+-void balance_dirty_pages_ratelimited(struct address_space *mapping);
++int balance_dirty_pages_ratelimited(struct address_space *mapping);
+ int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
+ int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
++ssize_t sync_page_range(struct inode *inode, struct address_space *mapping,
++                      loff_t pos, size_t count);
++ssize_t sync_page_range_nolock(struct inode *inode, struct address_space
++              *mapping, loff_t pos, size_t count);
+ /* pdflush.c */
+ extern int nr_pdflush_threads;        /* Global so it can be exported to sysctl
+--- linux-2.6.0/include/media/saa7146.h        2003-07-27 12:14:40.000000000 -0700
++++ 25/include/media/saa7146.h 2003-12-28 23:22:37.000000000 -0800
+@@ -87,6 +87,7 @@ struct saa7146_extension
+ {
+       char    name[32];               /* name of the device */
+ #define SAA7146_USE_I2C_IRQ   0x1
++#define SAA7146_I2C_SHORT_DELAY       0x2
+       int     flags;
+       
+       /* pairs of subvendor and subdevice ids for
+@@ -162,9 +163,10 @@ int saa7146_unregister_extension(struct 
+ struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc);
+ int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt);
+ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt);
+-void saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length );
++int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length );
+ char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt);
+ void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data);
++int saa7146_wait_for_debi_done(struct saa7146_dev *dev);
+ /* some memory sizes */
+ #define SAA7146_I2C_MEM               ( 1*PAGE_SIZE)
+@@ -187,6 +189,9 @@ void saa7146_setgpio(struct saa7146_dev 
+ #define SAA7146_GPIO_OUTLO 0x40
+ #define SAA7146_GPIO_OUTHI 0x50
++/* debi defines */
++#define DEBINOSWAP 0x000e0000
++
+ /* define for the register programming sequencer (rps) */
+ #define CMD_NOP               0x00000000  /* No operation */
+ #define CMD_CLR_EVENT 0x00000000  /* Clear event */
+--- linux-2.6.0/include/media/saa7146_vv.h     2003-10-17 15:58:04.000000000 -0700
++++ 25/include/media/saa7146_vv.h      2003-12-28 23:22:37.000000000 -0800
+@@ -149,7 +149,7 @@ struct saa7146_extension_ioctls
+ };
+ /* flags */
+-#define SAA7146_EXT_SWAP_ODD_EVEN       0x1     /* needs odd/even fields swapped */
++// #define SAA7146_EXT_SWAP_ODD_EVEN  0x1     /* needs odd/even fields swapped */
+ #define SAA7146_USE_PORT_B_FOR_VBI    0x2     /* use input port b for vbi hardware bug workaround */
+ struct saa7146_ext_vv
+@@ -171,12 +171,10 @@ struct saa7146_ext_vv
+ struct saa7146_use_ops  {
+         void (*init)(struct saa7146_dev *, struct saa7146_vv *);
+-        void(*open)(struct saa7146_dev *, struct saa7146_fh *);
+-        void (*release)(struct saa7146_dev *, struct saa7146_fh *,struct file *);
++        void(*open)(struct saa7146_dev *, struct file *);
++        void (*release)(struct saa7146_dev *, struct file *);
+         void (*irq_done)(struct saa7146_dev *, unsigned long status);
+       ssize_t (*read)(struct file *, char *, size_t, loff_t *);
+-        int (*capture_begin)(struct saa7146_fh *);
+-        int (*capture_end)(struct saa7146_fh *);
+ };
+ /* from saa7146_fops.c */
+--- linux-2.6.0/include/net/atmclip.h  2003-09-27 18:57:47.000000000 -0700
++++ 25/include/net/atmclip.h   2003-12-28 23:21:01.000000000 -0800
+@@ -44,7 +44,7 @@ struct atmarp_entry {
+ };
+-#define PRIV(dev) ((struct clip_priv *) ((struct net_device *) (dev)+1))
++#define PRIV(dev) ((struct clip_priv *) netdev_priv(dev))
+ struct clip_priv {
+--- linux-2.6.0/include/pcmcia/cs.h    2003-10-08 15:07:10.000000000 -0700
++++ 25/include/pcmcia/cs.h     2003-12-28 23:22:54.000000000 -0800
+@@ -421,12 +421,6 @@ enum service {
+     GetFirstWindow, GetNextWindow, GetMemPage
+ };
+-#ifdef IN_CARD_SERVICES
+-extern int CardServices(int func, void *a1, void *a2, void *a3);
+-#else
+-extern int CardServices(int func, ...);
+-#endif
+-
+ int pcmcia_access_configuration_register(client_handle_t handle, conf_reg_t *reg);
+ int pcmcia_bind_device(bind_req_t *req);
+ int pcmcia_bind_mtd(mtd_bind_t *req);
+--- linux-2.6.0/include/sound/i2c.h    2003-06-14 12:18:00.000000000 -0700
++++ 25/include/sound/i2c.h     2003-12-28 23:22:19.000000000 -0800
+@@ -58,7 +58,7 @@ struct _snd_i2c_bus {
+       snd_card_t *card;       /* card which I2C belongs to */
+       char name[32];          /* some useful label */
+-      spinlock_t lock;
++      struct semaphore lock_mutex;
+       snd_i2c_bus_t *master;  /* master bus when SCK/SCL is shared */
+       struct list_head buses; /* master: slave buses sharing SCK/SCL, slave: link list */
+@@ -84,15 +84,15 @@ int snd_i2c_device_free(snd_i2c_device_t
+ static inline void snd_i2c_lock(snd_i2c_bus_t *bus) {
+       if (bus->master)
+-              spin_lock(&bus->master->lock);
++              down(&bus->master->lock_mutex);
+       else
+-              spin_lock(&bus->lock);
++              down(&bus->lock_mutex);
+ }
+ static inline void snd_i2c_unlock(snd_i2c_bus_t *bus) {
+       if (bus->master)
+-              spin_unlock(&bus->master->lock);
++              up(&bus->master->lock_mutex);
+       else
+-              spin_unlock(&bus->lock);
++              up(&bus->lock_mutex);
+ }
+ int snd_i2c_sendbytes(snd_i2c_device_t *device, unsigned char *bytes, int count);
+--- linux-2.6.0/init/do_mounts.c       2003-10-08 15:07:10.000000000 -0700
++++ 25/init/do_mounts.c        2003-12-28 23:22:34.000000000 -0800
+@@ -130,20 +130,22 @@ fail:
+  *    Driverfs is used to check if something is a disk name - it has
+  *    all known disks under bus/block/devices.  If the disk name
+  *    contains slashes, name of driverfs node has them replaced with
+- *    dots.  try_name() does the actual checks, assuming that driverfs
++ *    bangs.  try_name() does the actual checks, assuming that driverfs
+  *    is mounted on rootfs /sys.
+  */
+-dev_t name_to_dev_t(char *name)
++dev_t __init name_to_dev_t(char *name)
+ {
+       char s[32];
+       char *p;
+       dev_t res = 0;
+       int part;
++#ifdef CONFIG_SYSFS
+       sys_mkdir("/sys", 0700);
+       if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
+               goto out;
++#endif
+       if (strncmp(name, "/dev/", 5) != 0) {
+               unsigned maj, min;
+@@ -169,7 +171,7 @@ dev_t name_to_dev_t(char *name)
+       strcpy(s, name);
+       for (p = s; *p; p++)
+               if (*p == '/')
+-                      *p = '.';
++                      *p = '!';
+       res = try_name(s, 0);
+       if (res)
+               goto done;
+--- linux-2.6.0/init/Kconfig   2003-11-09 16:45:05.000000000 -0800
++++ 25/init/Kconfig    2003-12-28 23:21:55.000000000 -0800
+@@ -43,7 +43,7 @@ config CLEAN_COMPILE
+ config STANDALONE
+       bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL
+-      default y
++      default n
+       help
+         Select this option if you don't have magic firmware for drivers that
+         need it.
+@@ -196,6 +196,19 @@ config EPOLL
+ source "drivers/block/Kconfig.iosched"
++config CC_OPTIMIZE_FOR_SIZE
++      bool "Optimize for size" if EMBEDDED
++      default y if ARM || H8300
++      default n
++      help
++        Enabling this option will pass "-Os" instead of "-O2" to gcc
++        resulting in a smaller kernel.
++
++        WARNING: some versions of gcc may generate incorrect code with this
++        option.  If problems are observed, a gcc upgrade may be needed.
++
++        If unsure, say N.
++
+ endmenu               # General setup
+--- linux-2.6.0/init/main.c    2003-11-09 16:45:05.000000000 -0800
++++ 25/init/main.c     2003-12-28 23:22:49.000000000 -0800
+@@ -38,6 +38,7 @@
+ #include <linux/moduleparam.h>
+ #include <linux/writeback.h>
+ #include <linux/cpu.h>
++#include <linux/efi.h>
+ #include <asm/io.h>
+ #include <asm/bugs.h>
+@@ -107,9 +108,7 @@ extern void time_init(void);
+ void (*late_time_init)(void) = NULL;
+ extern void softirq_init(void);
+-int rows, cols;
+-
+-char *execute_command;
++static char *execute_command;
+ /* Setup configured maximum number of CPUs to activate */
+ static unsigned int max_cpus = NR_CPUS;
+@@ -374,7 +373,7 @@ static void __init smp_init(void)
+ static void rest_init(void)
+ {
+-      kernel_thread(init, NULL, CLONE_KERNEL);
++      kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
+       unlock_kernel();
+       cpu_idle();
+ } 
+@@ -395,7 +394,6 @@ asmlinkage void __init start_kernel(void
+       lock_kernel();
+       printk(linux_banner);
+       setup_arch(&command_line);
+-      setup_per_zone_pages_min();
+       setup_per_cpu_areas();
+       /*
+@@ -443,6 +441,10 @@ asmlinkage void __init start_kernel(void
+       pidmap_init();
+       pgtable_cache_init();
+       pte_chain_init();
++#ifdef CONFIG_X86
++      if (efi_enabled)
++              efi_enter_virtual_mode();
++#endif
+       fork_init(num_physpages);
+       proc_caches_init();
+       buffer_init();
+@@ -470,7 +472,7 @@ asmlinkage void __init start_kernel(void
+       rest_init();
+ }
+-int __initdata initcall_debug;
++static int __initdata initcall_debug;
+ static int __init initcall_debug_setup(char *str)
+ {
+--- linux-2.6.0/ipc/sem.c      2003-09-27 18:57:47.000000000 -0700
++++ 25/ipc/sem.c       2003-12-28 23:22:03.000000000 -0800
+@@ -59,6 +59,8 @@
+  * (c) 1999 Manfred Spraul <manfreds@colorfullife.com>
+  * Enforced range limit on SEM_UNDO
+  * (c) 2001 Red Hat Inc <alan@redhat.com>
++ * Lockless wakeup
++ * (c) 2003 Manfred Spraul <manfred@colorfullife.com>
+  */
+ #include <linux/config.h>
+@@ -118,6 +120,40 @@ void __init sem_init (void)
+ #endif
+ }
++/*
++ * Lockless wakeup algorithm:
++ * Without the check/retry algorithm a lockless wakeup is possible:
++ * - queue.status is initialized to -EINTR before blocking.
++ * - wakeup is performed by
++ *    * unlinking the queue entry from sma->sem_pending
++ *    * setting queue.status to IN_WAKEUP
++ *      This is the notification for the blocked thread that a
++ *      result value is imminent.
++ *    * call wake_up_process
++ *    * set queue.status to the final value.
++ * - the previously blocked thread checks queue.status:
++ *    * if it's IN_WAKEUP, then it must wait until the value changes
++ *    * if it's not -EINTR, then the operation was completed by
++ *      update_queue. semtimedop can return queue.status without
++ *      performing any operation on the semaphore array.
++ *    * otherwise it must acquire the spinlock and check what's up.
++ *
++ * The two-stage algorithm is necessary to protect against the following
++ * races:
++ * - if queue.status is set after wake_up_process, then the woken up idle
++ *   thread could race forward and try (and fail) to acquire sma->lock
++ *   before update_queue had a chance to set queue.status
++ * - if queue.status is written before wake_up_process and if the
++ *   blocked process is woken up by a signal between writing
++ *   queue.status and the wake_up_process, then the woken up
++ *   process could return from semtimedop and die by calling
++ *   sys_exit before wake_up_process is called. Then wake_up_process
++ *   will oops, because the task structure is already invalid.
++ *   (yes, this happened on s390 with sysv msg).
++ *
++ */
++#define IN_WAKEUP     1
++
+ static int newary (key_t key, int nsems, int semflg)
+ {
+       int id;
+@@ -331,16 +367,25 @@ static void update_queue (struct sem_arr
+       int error;
+       struct sem_queue * q;
+-      for (q = sma->sem_pending; q; q = q->next) {
+-                      
++      q = sma->sem_pending;
++      while(q) {
+               error = try_atomic_semop(sma, q->sops, q->nsops,
+                                        q->undo, q->pid);
+               /* Does q->sleeper still need to sleep? */
+               if (error <= 0) {
+-                      q->status = error;
++                      struct sem_queue *n;
+                       remove_from_queue(sma,q);
++                      n = q->next;
++                      q->status = IN_WAKEUP;
+                       wake_up_process(q->sleeper);
++                      /* hands-off: q will disappear immediately after
++                       * writing q->status.
++                       */
++                      q->status = error;
++                      q = n;
++              } else {
++                      q = q->next;
+               }
+       }
+ }
+@@ -409,10 +454,16 @@ static void freeary (struct sem_array *s
+               un->semid = -1;
+       /* Wake up all pending processes and let them fail with EIDRM. */
+-      for (q = sma->sem_pending; q; q = q->next) {
+-              q->status = -EIDRM;
++      q = sma->sem_pending;
++      while(q) {
++              struct sem_queue *n;
++              /* lazy remove_from_queue: we are killing the whole queue */
+               q->prev = NULL;
++              n = q->next;
++              q->status = IN_WAKEUP;
+               wake_up_process(q->sleeper); /* doesn't sleep */
++              q->status = -EIDRM;     /* hands-off q */
++              q = n;
+       }
+       /* Remove the semaphore set from the ID array*/
+@@ -1083,6 +1134,18 @@ retry_undos:
+       else
+               schedule();
++      error = queue.status;
++      while(unlikely(error == IN_WAKEUP)) {
++              cpu_relax();
++              error = queue.status;
++      }
++
++      if (error != -EINTR) {
++              /* fast path: update_queue already obtained all requested
++               * resources */
++              goto out_free;
++      }
++
+       sma = sem_lock(semid);
+       if(sma==NULL) {
+               if(queue.prev != NULL)
+@@ -1095,7 +1158,7 @@ retry_undos:
+        * If queue.status != -EINTR we are woken up by another process
+        */
+       error = queue.status;
+-      if (queue.status != -EINTR) {
++      if (error != -EINTR) {
+               goto out_unlock_free;
+       }
+--- linux-2.6.0/kernel/compat.c        2003-09-08 13:58:59.000000000 -0700
++++ 25/kernel/compat.c 2003-12-28 23:22:22.000000000 -0800
+@@ -22,14 +22,14 @@
+ #include <asm/uaccess.h>
+-int get_compat_timespec(struct timespec *ts, struct compat_timespec *cts)
++int get_compat_timespec(struct timespec *ts, const struct compat_timespec *cts)
+ {
+       return (verify_area(VERIFY_READ, cts, sizeof(*cts)) ||
+                       __get_user(ts->tv_sec, &cts->tv_sec) ||
+                       __get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
+ }
+-int put_compat_timespec(struct timespec *ts, struct compat_timespec *cts)
++int put_compat_timespec(struct timespec *ts, const struct compat_timespec *cts)
+ {
+       return (verify_area(VERIFY_WRITE, cts, sizeof(*cts)) ||
+                       __put_user(ts->tv_sec, &cts->tv_sec) ||
+@@ -204,7 +204,8 @@ asmlinkage long compat_sys_sigprocmask(i
+       ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
+       set_fs(old_fs);
+       if (ret == 0)
+-              ret = put_user(s, oset);
++              if (oset)
++                      ret = put_user(s, oset);
+       return ret;
+ }
+--- linux-2.6.0/kernel/exit.c  2003-12-17 21:20:03.000000000 -0800
++++ 25/kernel/exit.c   2003-12-28 23:22:30.000000000 -0800
+@@ -472,21 +472,29 @@ static inline void __exit_mm(struct task
+       if (!mm)
+               return;
+       /*
+-       * Serialize with any possible pending coredump:
++       * Serialize with any possible pending coredump.
++       * We must hold mmap_sem around checking core_waiters
++       * and clearing tsk->mm.  The core-inducing thread
++       * will increment core_waiters for each thread in the
++       * group with ->mm != NULL.
+        */
++      down_read(&mm->mmap_sem);
+       if (mm->core_waiters) {
++              up_read(&mm->mmap_sem);
+               down_write(&mm->mmap_sem);
+               if (!--mm->core_waiters)
+                       complete(mm->core_startup_done);
+               up_write(&mm->mmap_sem);
+               wait_for_completion(&mm->core_done);
++              down_read(&mm->mmap_sem);
+       }
+       atomic_inc(&mm->mm_count);
+       if (mm != tsk->active_mm) BUG();
+       /* more a memory barrier than a real lock */
+       task_lock(tsk);
+       tsk->mm = NULL;
++      up_read(&mm->mmap_sem);
+       enter_lazy_tlb(mm, current);
+       task_unlock(tsk);
+       mmput(mm);
+--- linux-2.6.0/kernel/fork.c  2003-12-17 21:20:03.000000000 -0800
++++ 25/kernel/fork.c   2003-12-28 23:26:39.000000000 -0800
+@@ -146,7 +146,12 @@ void prepare_to_wait(wait_queue_head_t *
+       spin_lock_irqsave(&q->lock, flags);
+       if (list_empty(&wait->task_list))
+               __add_wait_queue(q, wait);
+-      set_current_state(state);
++      /*
++       * don't alter the task state if this is just going to
++       * queue an async wait queue callback
++       */
++      if (is_sync_wait(wait))
++              set_current_state(state);
+       spin_unlock_irqrestore(&q->lock, flags);
+ }
+@@ -161,7 +166,12 @@ prepare_to_wait_exclusive(wait_queue_hea
+       spin_lock_irqsave(&q->lock, flags);
+       if (list_empty(&wait->task_list))
+               __add_wait_queue_tail(q, wait);
+-      set_current_state(state);
++      /*
++       * don't alter the task state if this is just going to
++       * queue an async wait queue callback
++       */
++      if (is_sync_wait(wait))
++              set_current_state(state);
+       spin_unlock_irqrestore(&q->lock, flags);
+ }
+@@ -316,9 +326,9 @@ static inline int dup_mmap(struct mm_str
+                               atomic_dec(&inode->i_writecount);
+       
+                       /* insert tmp into the share list, just after mpnt */
+-                      down(&inode->i_mapping->i_shared_sem);
++                      down(&file->f_mapping->i_shared_sem);
+                       list_add_tail(&tmp->shared, &mpnt->shared);
+-                      up(&inode->i_mapping->i_shared_sem);
++                      up(&file->f_mapping->i_shared_sem);
+               }
+               /*
+@@ -642,6 +652,11 @@ static int copy_files(unsigned long clon
+               goto out;
+       }
++      /*
++       * Note: we may be using current for both targets (See exec.c)
++       * This works because we cache current->files (old) as oldf. Don't
++       * break this.
++       */
+       tsk->files = NULL;
+       error = -ENOMEM;
+       newf = kmem_cache_alloc(files_cachep, SLAB_KERNEL);
+@@ -731,6 +746,35 @@ out_release:
+       goto out;
+ }
++/*
++ *    Helper to unshare the files of the current task.
++ *    We don't want to expose copy_files internals to
++ *    the exec layer of the kernel.
++ */
++
++int unshare_files(void)
++{
++      struct files_struct *files  = current->files;
++      int rc;
++
++      if(!files)
++              BUG();
++
++      /* This can race but the race causes us to copy when we don't
++         need to and drop the copy */
++      if(atomic_read(&files->count) == 1)
++      {
++              atomic_inc(&files->count);
++              return 0;
++      }
++      rc = copy_files(0, current);
++      if(rc)
++              current->files = files;
++      return rc;
++}
++
++EXPORT_SYMBOL(unshare_files);
++
+ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
+ {
+       struct sighand_struct *sig;
+@@ -876,15 +920,7 @@ struct task_struct *copy_process(unsigne
+       if (p->binfmt && !try_module_get(p->binfmt->module))
+               goto bad_fork_cleanup_put_domain;
+-#ifdef CONFIG_PREEMPT
+-      /*
+-       * schedule_tail drops this_rq()->lock so we compensate with a count
+-       * of 1.  Also, we want to start with kernel preemption disabled.
+-       */
+-      p->thread_info->preempt_count = 1;
+-#endif
+       p->did_exec = 0;
+-      p->state = TASK_UNINTERRUPTIBLE;
+       copy_flags(clone_flags, p);
+       if (clone_flags & CLONE_IDLETASK)
+@@ -901,15 +937,12 @@ struct task_struct *copy_process(unsigne
+       p->proc_dentry = NULL;
+-      INIT_LIST_HEAD(&p->run_list);
+-
+       INIT_LIST_HEAD(&p->children);
+       INIT_LIST_HEAD(&p->sibling);
+       INIT_LIST_HEAD(&p->posix_timers);
+       init_waitqueue_head(&p->wait_chldexit);
+       p->vfork_done = NULL;
+       spin_lock_init(&p->alloc_lock);
+-      spin_lock_init(&p->switch_lock);
+       spin_lock_init(&p->proc_lock);
+       clear_tsk_thread_flag(p, TIF_SIGPENDING);
+@@ -924,11 +957,11 @@ struct task_struct *copy_process(unsigne
+       p->tty_old_pgrp = 0;
+       p->utime = p->stime = 0;
+       p->cutime = p->cstime = 0;
+-      p->array = NULL;
+       p->lock_depth = -1;             /* -1 = no lock */
+       p->start_time = get_jiffies_64();
+       p->security = NULL;
+       p->io_context = NULL;
++      p->io_wait = NULL;
+       retval = -ENOMEM;
+       if ((retval = security_task_alloc(p)))
+@@ -973,38 +1006,12 @@ struct task_struct *copy_process(unsigne
+       p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL);
+       p->pdeath_signal = 0;
++      /* Perform scheduler related setup */
++      sched_fork(p);
++
+       /*
+-       * Share the timeslice between parent and child, thus the
+-       * total amount of pending timeslices in the system doesn't change,
+-       * resulting in more scheduling fairness.
+-       */
+-      local_irq_disable();
+-        p->time_slice = (current->time_slice + 1) >> 1;
+-      /*
+-       * The remainder of the first timeslice might be recovered by
+-       * the parent if the child exits early enough.
+-       */
+-      p->first_time_slice = 1;
+-      current->time_slice >>= 1;
+-      p->timestamp = sched_clock();
+-      if (!current->time_slice) {
+-              /*
+-               * This case is rare, it happens when the parent has only
+-               * a single jiffy left from its timeslice. Taking the
+-               * runqueue lock is not a problem.
+-               */
+-              current->time_slice = 1;
+-              preempt_disable();
+-              scheduler_tick(0, 0);
+-              local_irq_enable();
+-              preempt_enable();
+-      } else
+-              local_irq_enable();
+-      /*
+-       * Ok, add it to the run-queues and make it
+-       * visible to the rest of the system.
+-       *
+-       * Let it rip!
++       * Ok, make it visible to the rest of the system.
++       * We dont wake it up yet.
+        */
+       p->tgid = p->pid;
+       p->group_leader = p;
+--- linux-2.6.0/kernel/futex.c 2003-11-09 16:45:05.000000000 -0800
++++ 25/kernel/futex.c  2003-12-28 23:21:42.000000000 -0800
+@@ -246,7 +246,7 @@ static inline void get_key_refs(union fu
+  * Drop a reference to the resource addressed by a key.
+  * The hash bucket spinlock must not be held.
+  */
+-static inline void drop_key_refs(union futex_key *key)
++static void drop_key_refs(union futex_key *key)
+ {
+       if (key->both.ptr != 0) {
+               if (key->both.offset & 1)
+@@ -260,7 +260,7 @@ static inline void drop_key_refs(union f
+  * The hash bucket lock must be held when this is called.
+  * Afterwards, the futex_q must not be accessed.
+  */
+-static inline void wake_futex(struct futex_q *q)
++static void wake_futex(struct futex_q *q)
+ {
+       list_del_init(&q->list);
+       if (q->filp)
+@@ -384,7 +384,7 @@ out:
+  */
+ /* The key must be already stored in q->key. */
+-static inline void queue_me(struct futex_q *q, int fd, struct file *filp)
++static void queue_me(struct futex_q *q, int fd, struct file *filp)
+ {
+       struct futex_hash_bucket *bh;
+@@ -577,6 +577,7 @@ static int futex_fd(unsigned long uaddr,
+       filp->f_op = &futex_fops;
+       filp->f_vfsmnt = mntget(futex_mnt);
+       filp->f_dentry = dget(futex_mnt->mnt_root);
++      filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
+       if (signal) {
+               int err;
+--- linux-2.6.0/kernel/kmod.c  2003-11-09 16:45:05.000000000 -0800
++++ 25/kernel/kmod.c   2003-12-28 23:21:42.000000000 -0800
+@@ -182,16 +182,21 @@ static int wait_for_helper(void *data)
+ {
+       struct subprocess_info *sub_info = data;
+       pid_t pid;
++      struct k_sigaction sa;
++
++      /* Install a handler: if SIGCLD isn't handled sys_wait4 won't
++       * populate the status, but will return -ECHILD. */
++      sa.sa.sa_handler = SIG_IGN;
++      sa.sa.sa_flags = 0;
++      siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD));
++      do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0);
++      allow_signal(SIGCHLD);
+-      sub_info->retval = 0;
+       pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
+       if (pid < 0)
+               sub_info->retval = pid;
+       else
+-              /* We don't have a SIGCHLD signal handler, so this
+-               * always returns -ECHILD, but the important thing is
+-               * that it blocks. */
+-              sys_wait4(pid, NULL, 0, NULL);
++              sys_wait4(pid, &sub_info->retval, 0, NULL);
+       complete(sub_info->complete);
+       return 0;
+@@ -210,7 +215,7 @@ static void __call_usermodehelper(void *
+        * until that is done.  */
+       if (sub_info->wait)
+               pid = kernel_thread(wait_for_helper, sub_info,
+-                                  CLONE_KERNEL | SIGCHLD);
++                                  CLONE_FS | CLONE_FILES | SIGCHLD);
+       else
+               pid = kernel_thread(____call_usermodehelper, sub_info,
+                                   CLONE_VFORK | SIGCHLD);
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/kernel/lockmeter.c      2003-12-28 23:26:34.000000000 -0800
+@@ -0,0 +1,1178 @@
++/*
++ *  Copyright (C) 1999,2000 Silicon Graphics, Inc.
++ *
++ *  Written by John Hawkes (hawkes@sgi.com)
++ *  Based on klstat.c by Jack Steiner (steiner@sgi.com)
++ *
++ *  Modified by Ray Bryant (raybry@us.ibm.com)
++ *  Changes Copyright (C) 2000 IBM, Inc.
++ *  Added save of index in spinlock_t to improve efficiency
++ *  of "hold" time reporting for spinlocks
++ *  Added support for hold time statistics for read and write
++ *  locks.
++ */
++
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/smp.h>
++#include <linux/threads.h>
++#include <linux/version.h>
++#include <linux/vmalloc.h>
++#include <linux/spinlock.h>
++#include <linux/utsname.h>
++#include <linux/module.h>
++#include <asm/system.h>
++#include <asm/uaccess.h>
++
++#include <linux/lockmeter.h>
++
++#define ASSERT(cond)
++#define bzero(loc,size)               memset(loc,0,size)
++
++/*<---------------------------------------------------*/
++/*              lockmeter.c                           */
++/*>---------------------------------------------------*/
++
++static lstat_control_t lstat_control __cacheline_aligned =
++      { LSTAT_OFF, SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED,
++        19 * 0, NR_CPUS * 0, 0, NR_CPUS * 0 };
++
++static ushort lstat_make_dir_entry(void *, void *);
++
++/*
++ * lstat_lookup
++ *
++ * Given a RA, locate the directory entry for the lock.
++ */
++static ushort
++lstat_lookup(void *lock_ptr, void *caller_ra)
++{
++      ushort index;
++      lstat_directory_entry_t *dirp;
++
++      dirp = lstat_control.dir;
++
++      index = lstat_control.hashtab[DIRHASH(caller_ra)];
++      while (dirp[index].caller_ra != caller_ra) {
++              if (index == 0) {
++                      return lstat_make_dir_entry(lock_ptr, caller_ra);
++              }
++              index = dirp[index].next_stat_index;
++      }
++
++      if (dirp[index].lock_ptr != NULL && dirp[index].lock_ptr != lock_ptr) {
++              dirp[index].lock_ptr = NULL;
++      }
++
++      return index;
++}
++
++/*
++ * lstat_make_dir_entry
++ * Called to add a new lock to the lock directory.
++ */
++static ushort
++lstat_make_dir_entry(void *lock_ptr, void *caller_ra)
++{
++      lstat_directory_entry_t *dirp;
++      ushort index, hindex;
++      unsigned long flags;
++
++      /* lock the table without recursively reentering this metering code */
++      local_irq_save(flags);
++      _raw_spin_lock(&lstat_control.directory_lock);
++
++      hindex = DIRHASH(caller_ra);
++      index = lstat_control.hashtab[hindex];
++      dirp = lstat_control.dir;
++      while (index && dirp[index].caller_ra != caller_ra)
++              index = dirp[index].next_stat_index;
++
++      if (index == 0) {
++              if (lstat_control.next_free_dir_index < LSTAT_MAX_STAT_INDEX) {
++                      index = lstat_control.next_free_dir_index++;
++                      lstat_control.dir[index].caller_ra = caller_ra;
++                      lstat_control.dir[index].lock_ptr = lock_ptr;
++                      lstat_control.dir[index].next_stat_index =
++                              lstat_control.hashtab[hindex];
++                      lstat_control.hashtab[hindex] = index;
++              } else {
++                      lstat_control.dir_overflow++;
++              }
++      }
++      _raw_spin_unlock(&lstat_control.directory_lock);
++      local_irq_restore(flags);
++      return index;
++}
++
++int
++lstat_update(void *lock_ptr, void *caller_ra, int action)
++{
++      int index;
++      int cpu;
++
++      ASSERT(action < LSTAT_ACT_MAX_VALUES);
++
++      if (lstat_control.state == LSTAT_OFF)
++              return 0;
++
++      index = lstat_lookup(lock_ptr, caller_ra);
++      cpu = THIS_CPU_NUMBER;
++      (*lstat_control.counts[cpu])[index].count[action]++;
++      (*lstat_control.counts[cpu])[index].acquire_time = get_cycles();
++
++      return index;
++}
++
++int
++lstat_update_time(void *lock_ptr, void *caller_ra, int action, uint32_t ticks)
++{
++      ushort index;
++      int cpu;
++
++      ASSERT(action < LSTAT_ACT_MAX_VALUES);
++
++      if (lstat_control.state == LSTAT_OFF)
++              return 0;
++
++      index = lstat_lookup(lock_ptr, caller_ra);
++      cpu = THIS_CPU_NUMBER;
++      (*lstat_control.counts[cpu])[index].count[action]++;
++      (*lstat_control.counts[cpu])[index].cum_wait_ticks += (uint64_t) ticks;
++      if ((*lstat_control.counts[cpu])[index].max_wait_ticks < ticks)
++              (*lstat_control.counts[cpu])[index].max_wait_ticks = ticks;
++
++      (*lstat_control.counts[cpu])[index].acquire_time = get_cycles();
++
++      return index;
++}
++
++void
++_metered_spin_lock(spinlock_t * lock_ptr)
++{
++      if (lstat_control.state == LSTAT_OFF) {
++              _raw_spin_lock(lock_ptr);       /* do the real lock */
++              PUT_INDEX(lock_ptr, 0); /* clean index in case lockmetering  */
++              /* gets turned on before unlock */
++      } else {
++              void *this_pc = LSTAT_RA(LSTAT_RA_SPIN);
++              int index;
++
++              if (_raw_spin_trylock(lock_ptr)) {
++                      index = lstat_update(lock_ptr, this_pc,
++                                              LSTAT_ACT_NO_WAIT);
++              } else {
++                      uint32_t start_cycles = get_cycles();
++                      _raw_spin_lock(lock_ptr);       /* do the real lock */
++                      index = lstat_update_time(lock_ptr, this_pc,
++                              LSTAT_ACT_SPIN, get_cycles() - start_cycles);
++              }
++              /* save the index in the lock itself for use in spin unlock */
++              PUT_INDEX(lock_ptr, index);
++      }
++}
++
++int
++_metered_spin_trylock(spinlock_t * lock_ptr)
++{
++      if (lstat_control.state == LSTAT_OFF) {
++              return _raw_spin_trylock(lock_ptr);
++      } else {
++              int retval;
++              void *this_pc = LSTAT_RA(LSTAT_RA_SPIN);
++
++              if ((retval = _raw_spin_trylock(lock_ptr))) {
++                      int index = lstat_update(lock_ptr, this_pc,
++                                              LSTAT_ACT_NO_WAIT);
++                      /*
++                       * save the index in the lock itself for use in spin
++                       * unlock
++                       */
++                      PUT_INDEX(lock_ptr, index);
++              } else {
++                      lstat_update(lock_ptr, this_pc, LSTAT_ACT_REJECT);
++              }
++
++              return retval;
++      }
++}
++
++void
++_metered_spin_unlock(spinlock_t * lock_ptr)
++{
++      int index = -1;
++
++      if (lstat_control.state != LSTAT_OFF) {
++              index = GET_INDEX(lock_ptr);
++              /*
++               * If statistics were turned off when we set the lock,
++               * then the index can be zero.  If that is the case,
++               * then collect no stats on this call.
++               */
++              if (index > 0) {
++                      uint32_t hold_time;
++                      int cpu = THIS_CPU_NUMBER;
++                      hold_time = get_cycles() -
++                       (*lstat_control.counts[cpu])[index].acquire_time;
++                      (*lstat_control.counts[cpu])[index].cum_hold_ticks +=
++                              (uint64_t) hold_time;
++                      if ((*lstat_control.counts[cpu])[index].max_hold_ticks <
++                          hold_time)
++                              (*lstat_control.counts[cpu])[index].
++                                  max_hold_ticks = hold_time;
++              }
++      }
++
++      /* make sure we don't have a stale index value saved */
++      PUT_INDEX(lock_ptr, 0);
++      _raw_spin_unlock(lock_ptr);     /* do the real unlock */
++}
++
++/*
++ * allocate the next global read lock structure and store its index
++ * in the rwlock at "lock_ptr".
++ */
++uint32_t
++alloc_rwlock_struct(rwlock_t * rwlock_ptr)
++{
++      int index;
++      unsigned long flags;
++      int cpu = THIS_CPU_NUMBER;
++
++      /* If we've already overflowed, then do a quick exit */
++      if (lstat_control.next_free_read_lock_index >
++                      LSTAT_MAX_READ_LOCK_INDEX) {
++              lstat_control.rwlock_overflow++;
++              return 0;
++      }
++
++      local_irq_save(flags);
++      _raw_spin_lock(&lstat_control.directory_lock);
++
++      /* It is possible this changed while we were waiting for the directory_lock */
++      if (lstat_control.state == LSTAT_OFF) {
++              index = 0;
++              goto unlock;
++      }
++
++      /* It is possible someone else got here first and set the index */
++      if ((index = GET_RWINDEX(rwlock_ptr)) == 0) {
++              /*
++               * we can't turn on read stats for this lock while there are
++               * readers (this would mess up the running hold time sum at
++               * unlock time)
++               */
++              if (RWLOCK_READERS(rwlock_ptr) != 0) {
++                      index = 0;
++                      goto unlock;
++              }
++
++              /*
++               * if stats are turned on after being off, we may need to
++               * return an old index from when the statistics were on last
++               * time.
++               */
++              for (index = 1; index < lstat_control.next_free_read_lock_index;
++                              index++)
++                      if ((*lstat_control.read_lock_counts[cpu])[index].
++                                      lock_ptr == rwlock_ptr)
++                              goto put_index_and_unlock;
++
++              /* allocate the next global read lock structure */
++              if (lstat_control.next_free_read_lock_index >=
++                  LSTAT_MAX_READ_LOCK_INDEX) {
++                      lstat_control.rwlock_overflow++;
++                      index = 0;
++                      goto unlock;
++              }
++              index = lstat_control.next_free_read_lock_index++;
++
++              /*
++               * initialize the global read stats data structure for each
++               * cpu
++               */
++              for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++                      (*lstat_control.read_lock_counts[cpu])[index].lock_ptr =
++                              rwlock_ptr;
++              }
++put_index_and_unlock:
++              /* store the index for the read lock structure into the lock */
++              PUT_RWINDEX(rwlock_ptr, index);
++      }
++
++unlock:
++      _raw_spin_unlock(&lstat_control.directory_lock);
++      local_irq_restore(flags);
++      return index;
++}
++
++void
++_metered_read_lock(rwlock_t * rwlock_ptr)
++{
++      void *this_pc;
++      uint32_t start_cycles;
++      int index;
++      int cpu;
++      unsigned long flags;
++      int readers_before, readers_after;
++      uint64_t cycles64;
++
++      if (lstat_control.state == LSTAT_OFF) {
++              _raw_read_lock(rwlock_ptr);
++              /* clean index in case lockmetering turns on before an unlock */
++              PUT_RWINDEX(rwlock_ptr, 0);
++              return;
++      }
++
++      this_pc = LSTAT_RA(LSTAT_RA_READ);
++      cpu = THIS_CPU_NUMBER;
++      index = GET_RWINDEX(rwlock_ptr);
++
++      /* allocate the global stats entry for this lock, if needed */
++      if (index == 0)
++              index = alloc_rwlock_struct(rwlock_ptr);
++
++      readers_before = RWLOCK_READERS(rwlock_ptr);
++      if (_raw_read_trylock(rwlock_ptr)) {
++              /*
++               * We have decremented the lock to count a new reader,
++               * and have confirmed that no writer has it locked.
++               */
++              /* update statistics if enabled */
++              if (index > 0) {
++                      local_irq_save(flags);
++                      lstat_update((void *) rwlock_ptr, this_pc,
++                                      LSTAT_ACT_NO_WAIT);
++                      /* preserve value of TSC so cum_hold_ticks and start_busy use same value */
++                      cycles64 = get_cycles64();
++                      (*lstat_control.read_lock_counts[cpu])[index].
++                              cum_hold_ticks -= cycles64;
++
++                      /* record time and cpu of start of busy period */
++                      /* this is not perfect (some race conditions are possible) */
++                      if (readers_before == 0) {
++                              (*lstat_control.read_lock_counts[cpu])[index].
++                                      start_busy = cycles64;
++                              PUT_RW_CPU(rwlock_ptr, cpu);
++                      }
++                      readers_after = RWLOCK_READERS(rwlock_ptr);
++                      if (readers_after >
++                              (*lstat_control.read_lock_counts[cpu])[index].
++                                      max_readers)
++                              (*lstat_control.read_lock_counts[cpu])[index].
++                                      max_readers = readers_after;
++                      local_irq_restore(flags);
++              }
++
++              return;
++      }
++      /* If we get here, then we could not quickly grab the read lock */
++
++      start_cycles = get_cycles();    /* start counting the wait time */
++
++      /* Now spin until read_lock is successful */
++      _raw_read_lock(rwlock_ptr);
++
++      lstat_update_time((void *) rwlock_ptr, this_pc, LSTAT_ACT_SPIN,
++                        get_cycles() - start_cycles);
++
++      /* update statistics if they are enabled for this lock */
++      if (index > 0) {
++              local_irq_save(flags);
++              cycles64 = get_cycles64();
++              (*lstat_control.read_lock_counts[cpu])[index].cum_hold_ticks -=
++                              cycles64;
++
++              /* this is not perfect (some race conditions are possible) */
++              if (readers_before == 0) {
++                      (*lstat_control.read_lock_counts[cpu])[index].
++                              start_busy = cycles64;
++                      PUT_RW_CPU(rwlock_ptr, cpu);
++              }
++              readers_after = RWLOCK_READERS(rwlock_ptr);
++              if (readers_after >
++                  (*lstat_control.read_lock_counts[cpu])[index].max_readers)
++                      (*lstat_control.read_lock_counts[cpu])[index].
++                              max_readers = readers_after;
++              local_irq_restore(flags);
++      }
++}
++
++void
++_metered_read_unlock(rwlock_t * rwlock_ptr)
++{
++      int index;
++      int cpu;
++      unsigned long flags;
++      uint64_t busy_length;
++      uint64_t cycles64;
++
++      if (lstat_control.state == LSTAT_OFF) {
++              _raw_read_unlock(rwlock_ptr);
++              return;
++      }
++
++      index = GET_RWINDEX(rwlock_ptr);
++      cpu = THIS_CPU_NUMBER;
++
++      if (index > 0) {
++              local_irq_save(flags);
++              /*
++               * preserve value of TSC so cum_hold_ticks and busy_ticks are
++               * consistent.
++               */
++              cycles64 = get_cycles64();
++              (*lstat_control.read_lock_counts[cpu])[index].cum_hold_ticks +=
++                      cycles64;
++              (*lstat_control.read_lock_counts[cpu])[index].read_lock_count++;
++
++              /*
++               * once again, this is not perfect (some race conditions are
++               * possible)
++               */
++              if (RWLOCK_READERS(rwlock_ptr) == 1) {
++                      int cpu1 = GET_RW_CPU(rwlock_ptr);
++                      uint64_t last_start_busy =
++                              (*lstat_control.read_lock_counts[cpu1])[index].
++                                      start_busy;
++                      (*lstat_control.read_lock_counts[cpu])[index].
++                              busy_periods++;
++                      if (cycles64 > last_start_busy) {
++                              busy_length = cycles64 - last_start_busy;
++                              (*lstat_control.read_lock_counts[cpu])[index].
++                                      busy_ticks += busy_length;
++                              if (busy_length >
++                                      (*lstat_control.
++                                              read_lock_counts[cpu])[index].
++                                                      max_busy)
++                                      (*lstat_control.
++                                       read_lock_counts[cpu])[index].
++                                              max_busy = busy_length;
++                      }
++              }
++              local_irq_restore(flags);
++      }
++      _raw_read_unlock(rwlock_ptr);
++}
++
++void
++_metered_write_lock(rwlock_t * rwlock_ptr)
++{
++      uint32_t start_cycles;
++      void *this_pc;
++      uint32_t spin_ticks = 0; /* in anticipation of a potential wait */
++      int index;
++      int write_index = 0;
++      int cpu;
++      enum {
++              writer_writer_conflict,
++              writer_reader_conflict
++      } why_wait = writer_writer_conflict;
++
++      if (lstat_control.state == LSTAT_OFF) {
++              _raw_write_lock(rwlock_ptr);
++              /* clean index in case lockmetering turns on before an unlock */
++              PUT_RWINDEX(rwlock_ptr, 0);
++              return;
++      }
++
++      this_pc = LSTAT_RA(LSTAT_RA_WRITE);
++      cpu = THIS_CPU_NUMBER;
++      index = GET_RWINDEX(rwlock_ptr);
++
++      /* allocate the global stats entry for this lock, if needed */
++      if (index == 0) {
++              index = alloc_rwlock_struct(rwlock_ptr);
++      }
++
++      if (_raw_write_trylock(rwlock_ptr)) {
++              /* We acquired the lock on the first try */
++              write_index = lstat_update((void *) rwlock_ptr, this_pc,
++                                      LSTAT_ACT_NO_WAIT);
++              /* save the write_index for use in unlock if stats enabled */
++              if (index > 0)
++                      (*lstat_control.read_lock_counts[cpu])[index].
++                              write_index = write_index;
++              return;
++      }
++
++      /* If we get here, then we could not quickly grab the write lock */
++      start_cycles = get_cycles();    /* start counting the wait time */
++
++      why_wait = RWLOCK_READERS(rwlock_ptr) ?
++                      writer_reader_conflict : writer_writer_conflict;
++
++      /* Now set the lock and wait for conflicts to disappear */
++      _raw_write_lock(rwlock_ptr);
++
++      spin_ticks = get_cycles() - start_cycles;
++
++      /* update stats -- if enabled */
++      if (index > 0 && spin_ticks) {
++              if (why_wait == writer_reader_conflict) {
++                      /* waited due to a reader holding the lock */
++                      write_index = lstat_update_time((void *)rwlock_ptr,
++                                      this_pc, LSTAT_ACT_SPIN, spin_ticks);
++              } else {
++                      /*
++                       * waited due to another writer holding the lock
++                       */
++                      write_index = lstat_update_time((void *)rwlock_ptr,
++                              this_pc, LSTAT_ACT_WW_SPIN, spin_ticks);
++                      (*lstat_control.counts[cpu])[write_index].
++                              cum_wait_ww_ticks += spin_ticks;
++                      if (spin_ticks >
++                              (*lstat_control.counts[cpu])[write_index].
++                                      max_wait_ww_ticks) {
++                              (*lstat_control.counts[cpu])[write_index].
++                                      max_wait_ww_ticks = spin_ticks;
++                      }
++              }
++
++              /* save the directory index for use on write_unlock */
++              (*lstat_control.read_lock_counts[cpu])[index].
++                      write_index = write_index;
++      }
++}
++
++void
++_metered_write_unlock(rwlock_t * rwlock_ptr)
++{
++      int index;
++      int cpu;
++      int write_index;
++      uint32_t hold_time;
++
++      if (lstat_control.state == LSTAT_OFF) {
++              _raw_write_unlock(rwlock_ptr);
++              return;
++      }
++
++      cpu = THIS_CPU_NUMBER;
++      index = GET_RWINDEX(rwlock_ptr);
++
++      /* update statistics if stats enabled for this lock */
++      if (index > 0) {
++              write_index =
++                  (*lstat_control.read_lock_counts[cpu])[index].write_index;
++
++              hold_time = get_cycles() -
++                      (*lstat_control.counts[cpu])[write_index].acquire_time;
++              (*lstat_control.counts[cpu])[write_index].cum_hold_ticks +=
++                      (uint64_t) hold_time;
++              if ((*lstat_control.counts[cpu])[write_index].max_hold_ticks <
++                              hold_time)
++                      (*lstat_control.counts[cpu])[write_index].
++                              max_hold_ticks = hold_time;
++      }
++      _raw_write_unlock(rwlock_ptr);
++}
++
++int
++_metered_write_trylock(rwlock_t * rwlock_ptr)
++{
++      int retval;
++      void *this_pc = LSTAT_RA(LSTAT_RA_WRITE);
++
++      if ((retval = _raw_write_trylock(rwlock_ptr))) {
++              lstat_update(rwlock_ptr, this_pc, LSTAT_ACT_NO_WAIT);
++      } else {
++              lstat_update(rwlock_ptr, this_pc, LSTAT_ACT_REJECT);
++      }
++
++      return retval;
++}
++
++static void
++init_control_space(void)
++{
++      /* Set all control space pointers to null and indices to "empty" */
++      int cpu;
++
++      /*
++       * Access CPU_CYCLE_FREQUENCY at the outset, which in some
++       * architectures may trigger a runtime calculation that uses a
++       * spinlock.  Let's do this before lockmetering is turned on.
++       */
++      if (CPU_CYCLE_FREQUENCY == 0)
++              BUG();
++
++      lstat_control.hashtab = NULL;
++      lstat_control.dir = NULL;
++      for (cpu = 0; cpu < NR_CPUS; cpu++) {
++              lstat_control.counts[cpu] = NULL;
++              lstat_control.read_lock_counts[cpu] = NULL;
++      }
++}
++
++static int
++reset_lstat_data(void)
++{
++      int cpu, flags;
++
++      flags = 0;
++      lstat_control.next_free_dir_index = 1;  /* 0 is for overflows */
++      lstat_control.next_free_read_lock_index = 1;
++      lstat_control.dir_overflow = 0;
++      lstat_control.rwlock_overflow = 0;
++
++      lstat_control.started_cycles64 = 0;
++      lstat_control.ending_cycles64 = 0;
++      lstat_control.enabled_cycles64 = 0;
++      lstat_control.first_started_time = 0;
++      lstat_control.started_time = 0;
++      lstat_control.ending_time = 0;
++      lstat_control.intervals = 0;
++
++      /*
++       * paranoia -- in case someone does a "lockstat reset" before
++       * "lockstat on"
++       */
++      if (lstat_control.hashtab) {
++              bzero(lstat_control.hashtab,
++                      LSTAT_HASH_TABLE_SIZE * sizeof (short));
++              bzero(lstat_control.dir, LSTAT_MAX_STAT_INDEX *
++                              sizeof (lstat_directory_entry_t));
++
++              for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++                      bzero(lstat_control.counts[cpu],
++                              sizeof (lstat_cpu_counts_t));
++                      bzero(lstat_control.read_lock_counts[cpu],
++                              sizeof (lstat_read_lock_cpu_counts_t));
++              }
++      }
++#ifdef NOTDEF
++      _raw_spin_unlock(&lstat_control.directory_lock);
++      local_irq_restore(flags);
++#endif
++      return 1;
++}
++
++static void
++release_control_space(void)
++{
++      /*
++       * Called when either (1) allocation of kmem
++       * or (2) when user writes LSTAT_RELEASE to /pro/lockmeter.
++       * Assume that all pointers have been initialized to zero,
++       * i.e., nonzero pointers are valid addresses.
++       */
++      int cpu;
++
++      if (lstat_control.hashtab) {
++              kfree(lstat_control.hashtab);
++              lstat_control.hashtab = NULL;
++      }
++
++      if (lstat_control.dir) {
++              vfree(lstat_control.dir);
++              lstat_control.dir = NULL;
++      }
++
++      for (cpu = 0; cpu < NR_CPUS; cpu++) {
++              if (lstat_control.counts[cpu]) {
++                      vfree(lstat_control.counts[cpu]);
++                      lstat_control.counts[cpu] = NULL;
++              }
++              if (lstat_control.read_lock_counts[cpu]) {
++                      kfree(lstat_control.read_lock_counts[cpu]);
++                      lstat_control.read_lock_counts[cpu] = NULL;
++              }
++      }
++}
++
++int
++get_lockmeter_info_size(void)
++{
++      return sizeof (lstat_user_request_t)
++              + num_online_cpus() * sizeof (lstat_cpu_counts_t)
++              + num_online_cpus() * sizeof (lstat_read_lock_cpu_counts_t)
++              + (LSTAT_MAX_STAT_INDEX * sizeof (lstat_directory_entry_t));
++}
++
++ssize_t
++get_lockmeter_info(char *buffer, size_t max_len, loff_t * last_index)
++{
++      lstat_user_request_t req;
++      struct timeval tv;
++      ssize_t next_ret_bcount;
++      ssize_t actual_ret_bcount = 0;
++      int cpu;
++
++      *last_index = 0;        /* a one-shot read */
++
++      req.lstat_version = LSTAT_VERSION;
++      req.state = lstat_control.state;
++      req.maxcpus = num_online_cpus();
++      req.cycleval = CPU_CYCLE_FREQUENCY;
++#ifdef notyet
++      req.kernel_magic_addr = (void *) &_etext;
++      req.kernel_end_addr = (void *) &_etext;
++#endif
++      req.uts = system_utsname;
++      req.intervals = lstat_control.intervals;
++
++      req.first_started_time = lstat_control.first_started_time;
++      req.started_time = lstat_control.started_time;
++      req.started_cycles64 = lstat_control.started_cycles64;
++
++      req.next_free_dir_index = lstat_control.next_free_dir_index;
++      req.next_free_read_lock_index = lstat_control.next_free_read_lock_index;
++      req.dir_overflow = lstat_control.dir_overflow;
++      req.rwlock_overflow = lstat_control.rwlock_overflow;
++
++      if (lstat_control.state == LSTAT_OFF) {
++              if (req.intervals == 0) {
++                      /* mesasurement is off and no valid data present */
++                      next_ret_bcount = sizeof (lstat_user_request_t);
++                      req.enabled_cycles64 = 0;
++
++                      if ((actual_ret_bcount + next_ret_bcount) > max_len)
++                              return actual_ret_bcount;
++
++                      copy_to_user(buffer, (void *) &req, next_ret_bcount);
++                      actual_ret_bcount += next_ret_bcount;
++                      return actual_ret_bcount;
++              } else {
++                      /*
++                       * measurement is off but valid data present
++                       * fetch time info from lstat_control
++                       */
++                      req.ending_time = lstat_control.ending_time;
++                      req.ending_cycles64 = lstat_control.ending_cycles64;
++                      req.enabled_cycles64 = lstat_control.enabled_cycles64;
++              }
++      } else {
++              /*
++               * this must be a read while data active--use current time,
++               * etc
++               */
++              do_gettimeofday(&tv);
++              req.ending_time = tv.tv_sec;
++              req.ending_cycles64 = get_cycles64();
++              req.enabled_cycles64 = req.ending_cycles64 -
++                      req.started_cycles64 + lstat_control.enabled_cycles64;
++      }
++
++      next_ret_bcount = sizeof (lstat_user_request_t);
++      if ((actual_ret_bcount + next_ret_bcount) > max_len)
++              return actual_ret_bcount;
++
++      copy_to_user(buffer, (void *) &req, next_ret_bcount);
++      actual_ret_bcount += next_ret_bcount;
++
++      if (!lstat_control.counts[0])   /* not initialized? */
++              return actual_ret_bcount;
++
++      next_ret_bcount = sizeof (lstat_cpu_counts_t);
++      for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++              if ((actual_ret_bcount + next_ret_bcount) > max_len)
++                      return actual_ret_bcount;       /* leave early */
++              copy_to_user(buffer + actual_ret_bcount,
++                              lstat_control.counts[cpu], next_ret_bcount);
++              actual_ret_bcount += next_ret_bcount;
++      }
++
++      next_ret_bcount = LSTAT_MAX_STAT_INDEX *
++                      sizeof (lstat_directory_entry_t);
++      if (((actual_ret_bcount + next_ret_bcount) > max_len)
++                      || !lstat_control.dir)
++              return actual_ret_bcount;       /* leave early */
++
++      copy_to_user(buffer + actual_ret_bcount, lstat_control.dir,
++                      next_ret_bcount);
++      actual_ret_bcount += next_ret_bcount;
++
++      next_ret_bcount = sizeof (lstat_read_lock_cpu_counts_t);
++      for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++              if (actual_ret_bcount + next_ret_bcount > max_len)
++                      return actual_ret_bcount;
++              copy_to_user(buffer + actual_ret_bcount,
++                              lstat_control.read_lock_counts[cpu],
++                              next_ret_bcount);
++              actual_ret_bcount += next_ret_bcount;
++      }
++
++      return actual_ret_bcount;
++}
++
++/*
++ *  Writing to the /proc lockmeter node enables or disables metering.
++ *  based upon the first byte of the "written" data.
++ *  The following values are defined:
++ *  LSTAT_ON: 1st call: allocates storage, intializes and turns on measurement
++ *            subsequent calls just turn on measurement
++ *  LSTAT_OFF: turns off measurement
++ *  LSTAT_RESET: resets statistics
++ *  LSTAT_RELEASE: releases statistics storage
++ *
++ *  This allows one to accumulate statistics over several lockstat runs:
++ *
++ *  lockstat on
++ *  lockstat off
++ *  ...repeat above as desired...
++ *  lockstat get
++ *  ...now start a new set of measurements...
++ *  lockstat reset
++ *  lockstat on
++ *  ...
++ *
++ */
++ssize_t
++put_lockmeter_info(const char *buffer, size_t len)
++{
++      int error = 0;
++      int dirsize, countsize, read_lock_countsize, hashsize;
++      int cpu;
++      char put_char;
++      int i, read_lock_blocks;
++      unsigned long flags;
++      rwlock_t *lock_ptr;
++      struct timeval tv;
++
++      if (len <= 0)
++              return -EINVAL;
++
++      _raw_spin_lock(&lstat_control.control_lock);
++
++      get_user(put_char, buffer);
++      switch (put_char) {
++
++      case LSTAT_OFF:
++              if (lstat_control.state != LSTAT_OFF) {
++                      /*
++                       * To avoid seeing read lock hold times in an
++                       * inconsisent state, we have to follow this protocol
++                       * to turn off statistics
++                       */
++                      local_irq_save(flags);
++                      /*
++                       * getting this lock will stop any read lock block
++                       * allocations
++                       */
++                      _raw_spin_lock(&lstat_control.directory_lock);
++                      /*
++                       * keep any more read lock blocks from being
++                       * allocated
++                       */
++                      lstat_control.state = LSTAT_OFF;
++                      /* record how may read lock blocks there are */
++                      read_lock_blocks =
++                              lstat_control.next_free_read_lock_index;
++                      _raw_spin_unlock(&lstat_control.directory_lock);
++                      /* now go through the list of read locks */
++                      cpu = THIS_CPU_NUMBER;
++                      for (i = 1; i < read_lock_blocks; i++) {
++                              lock_ptr =
++                                  (*lstat_control.read_lock_counts[cpu])[i].
++                                  lock_ptr;
++                              /* is this saved lock address still valid? */
++                              if (GET_RWINDEX(lock_ptr) == i) {
++                                      /*
++                                       * lock address appears to still be
++                                       * valid because we only hold one lock
++                                       * at a time, this can't cause a
++                                       * deadlock unless this is a lock held
++                                       * as part of the current system call
++                                       * path. At the moment there
++                                       * are no READ mode locks held to get
++                                       * here from user space, so we solve
++                                       * this by skipping locks held in
++                                       * write mode.
++                                       */
++                                      if (RWLOCK_IS_WRITE_LOCKED(lock_ptr)) {
++                                              PUT_RWINDEX(lock_ptr, 0);
++                                              continue;
++                                      }
++                                      /*
++                                       * now we know there are no read
++                                       * holders of this lock! stop
++                                       * statistics collection for this
++                                       * lock
++                                       */
++                                      _raw_write_lock(lock_ptr);
++                                      PUT_RWINDEX(lock_ptr, 0);
++                                      _raw_write_unlock(lock_ptr);
++                              }
++                              /*
++                               * it may still be possible for the hold time
++                               * sum to be negative e.g. if a lock is
++                               * reallocated while "busy" we will have to fix
++                               * this up in the data reduction program.
++                               */
++                      }
++                      local_irq_restore(flags);
++                      lstat_control.intervals++;
++                      lstat_control.ending_cycles64 = get_cycles64();
++                      lstat_control.enabled_cycles64 +=
++                              lstat_control.ending_cycles64 -
++                              lstat_control.started_cycles64;
++                      do_gettimeofday(&tv);
++                      lstat_control.ending_time = tv.tv_sec;
++                      /*
++                       * don't deallocate the structures -- we may do a
++                       * lockstat on to add to the data that is already
++                       * there. Use LSTAT_RELEASE to release storage
++                       */
++              } else {
++                      error = -EBUSY; /* already OFF */
++              }
++              break;
++
++      case LSTAT_ON:
++              if (lstat_control.state == LSTAT_OFF) {
++#ifdef DEBUG_LOCKMETER
++                      printk("put_lockmeter_info(cpu=%d): LSTAT_ON\n",
++                              THIS_CPU_NUMBER);
++#endif
++                      lstat_control.next_free_dir_index = 1;  /* 0 is for overflows */
++
++                      dirsize = LSTAT_MAX_STAT_INDEX *
++                                      sizeof (lstat_directory_entry_t);
++                      hashsize =
++                              (1 + LSTAT_HASH_TABLE_SIZE) * sizeof (ushort);
++                      countsize = sizeof (lstat_cpu_counts_t);
++                      read_lock_countsize =
++                              sizeof (lstat_read_lock_cpu_counts_t);
++#ifdef DEBUG_LOCKMETER
++                      printk(" dirsize:%d", dirsize);
++                      printk(" hashsize:%d", hashsize);
++                      printk(" countsize:%d", countsize);
++                      printk(" read_lock_countsize:%d\n",
++                              read_lock_countsize);
++#endif
++#ifdef DEBUG_LOCKMETER
++                      {
++                              int secs;
++                              unsigned long cycles;
++                              uint64_t cycles64;
++
++                              do_gettimeofday(&tv);
++                              secs = tv.tv_sec;
++                              do {
++                                      do_gettimeofday(&tv);
++                              } while (secs == tv.tv_sec);
++                              cycles = get_cycles();
++                              cycles64 = get_cycles64();
++                              secs = tv.tv_sec;
++                              do {
++                                      do_gettimeofday(&tv);
++                              } while (secs == tv.tv_sec);
++                              cycles = get_cycles() - cycles;
++                              cycles64 = get_cycles64() - cycles;
++                              printk("lockmeter: cycleFrequency:%d "
++                                      "cycles:%d cycles64:%d\n",
++                                      CPU_CYCLE_FREQUENCY, cycles, cycles64);
++                      }
++#endif
++
++                      /*
++                       * if this is the first call, allocate storage and
++                       * initialize
++                       */
++                      if (!lstat_control.hashtab) {
++
++                              spin_lock_init(&lstat_control.directory_lock);
++
++                              /* guarantee all pointers at zero */
++                              init_control_space();
++
++                              lstat_control.hashtab =
++                                  kmalloc(hashsize, GFP_KERNEL);
++                              if (!lstat_control.hashtab) {
++                                      error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++                                      printk("!!error kmalloc of hashtab\n");
++#endif
++                              }
++                              lstat_control.dir = vmalloc(dirsize);
++                              if (!lstat_control.dir) {
++                                      error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++                                      printk("!!error kmalloc of dir\n");
++#endif
++                              }
++
++                              for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++                                      lstat_control.counts[cpu] =
++                                              vmalloc(countsize);
++                                      if (!lstat_control.counts[cpu]) {
++                                              error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++                                              printk("!!error vmalloc of "
++                                                      "counts[%d]\n", cpu);
++#endif
++                                      }
++                                      lstat_control.read_lock_counts[cpu] =
++                                              (lstat_read_lock_cpu_counts_t *)
++                                              kmalloc(read_lock_countsize,
++                                                      GFP_KERNEL);
++                                      if (!lstat_control.
++                                                      read_lock_counts[cpu]) {
++                                              error = -ENOSPC;
++#ifdef DEBUG_LOCKMETER
++                                              printk("!!error kmalloc of "
++                                                "read_lock_counts[%d]\n",
++                                                      cpu);
++#endif
++                                      }
++                              }
++                      }
++
++                      if (error) {
++                              /*
++                               * One or more kmalloc failures -- free
++                               * everything
++                               */
++                              release_control_space();
++                      } else {
++
++                              if (!reset_lstat_data()) {
++                                      error = -EINVAL;
++                                      break;
++                              };
++
++                              /*
++                               * record starting and ending times and the
++                               * like
++                               */
++                              if (lstat_control.intervals == 0) {
++                                      do_gettimeofday(&tv);
++                                      lstat_control.first_started_time =
++                                              tv.tv_sec;
++                              }
++                              lstat_control.started_cycles64 = get_cycles64();
++                              do_gettimeofday(&tv);
++                              lstat_control.started_time = tv.tv_sec;
++
++                              lstat_control.state = LSTAT_ON;
++                      }
++              } else {
++                      error = -EBUSY; /* already ON */
++              }
++              break;
++
++      case LSTAT_RESET:
++              if (lstat_control.state == LSTAT_OFF) {
++                      if (!reset_lstat_data())
++                              error = -EINVAL;
++              } else {
++                      error = -EBUSY; /* still on; can't reset */
++              }
++              break;
++
++      case LSTAT_RELEASE:
++              if (lstat_control.state == LSTAT_OFF) {
++                      release_control_space();
++                      lstat_control.intervals = 0;
++                      lstat_control.enabled_cycles64 = 0;
++              } else {
++                      error = -EBUSY;
++              }
++              break;
++
++      default:
++              error = -EINVAL;
++      }                       /* switch */
++
++      _raw_spin_unlock(&lstat_control.control_lock);
++      return error ? error : len;
++}
++
++#ifdef USER_MODE_TESTING
++/* following used for user mode testing */
++void
++lockmeter_init()
++{
++      int dirsize, hashsize, countsize, read_lock_countsize, cpu;
++
++      printf("lstat_control is at %x size=%d\n", &lstat_control,
++              sizeof (lstat_control));
++      printf("sizeof(spinlock_t)=%d\n", sizeof (spinlock_t));
++      lstat_control.state = LSTAT_ON;
++
++      lstat_control.directory_lock = SPIN_LOCK_UNLOCKED;
++      lstat_control.next_free_dir_index = 1;  /* 0 is for overflows */
++      lstat_control.next_free_read_lock_index = 1;
++
++      dirsize = LSTAT_MAX_STAT_INDEX * sizeof (lstat_directory_entry_t);
++      hashsize = (1 + LSTAT_HASH_TABLE_SIZE) * sizeof (ushort);
++      countsize = sizeof (lstat_cpu_counts_t);
++      read_lock_countsize = sizeof (lstat_read_lock_cpu_counts_t);
++
++      lstat_control.hashtab = (ushort *) malloc(hashsize);
++
++      if (lstat_control.hashtab == 0) {
++              printf("malloc failure for at line %d in lockmeter.c\n",
++                      __LINE__);
++              exit(0);
++      }
++
++      lstat_control.dir = (lstat_directory_entry_t *) malloc(dirsize);
++
++      if (lstat_control.dir == 0) {
++              printf("malloc failure for at line %d in lockmeter.c\n", cpu,
++                      __LINE__);
++              exit(0);
++      }
++
++      for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++              int j, k;
++              j = (int) (lstat_control.counts[cpu] =
++                         (lstat_cpu_counts_t *) malloc(countsize));
++              k = (int) (lstat_control.read_lock_counts[cpu] =
++                         (lstat_read_lock_cpu_counts_t *)
++                         malloc(read_lock_countsize));
++              if (j * k == 0) {
++                      printf("malloc failure for cpu=%d at line %d in "
++                              "lockmeter.c\n", cpu, __LINE__);
++                      exit(0);
++              }
++      }
++
++      memset(lstat_control.hashtab, 0, hashsize);
++      memset(lstat_control.dir, 0, dirsize);
++
++      for (cpu = 0; cpu < num_online_cpus(); cpu++) {
++              memset(lstat_control.counts[cpu], 0, countsize);
++              memset(lstat_control.read_lock_counts[cpu], 0,
++                      read_lock_countsize);
++      }
++}
++
++asm(" \
++.align        4 \
++.globl        __write_lock_failed \
++__write_lock_failed: \
++      " LOCK "addl    $" RW_LOCK_BIAS_STR ",(%eax) \
++1:    cmpl    $" RW_LOCK_BIAS_STR ",(%eax) \
++      jne     1b \
++\
++      " LOCK "subl    $" RW_LOCK_BIAS_STR ",(%eax) \
++      jnz     __write_lock_failed \
++      ret \
++\
++\
++.align        4 \
++.globl        __read_lock_failed \
++__read_lock_failed: \
++      lock ; incl     (%eax) \
++1:    cmpl    $1,(%eax) \
++      js      1b \
++\
++      lock ; decl     (%eax) \
++      js      __read_lock_failed \
++      ret \
++");
++#endif
++
++EXPORT_SYMBOL(_metered_spin_lock);
++EXPORT_SYMBOL(_metered_spin_unlock);
++EXPORT_SYMBOL(_metered_spin_trylock);
++EXPORT_SYMBOL(_metered_read_lock);
++EXPORT_SYMBOL(_metered_read_unlock);
++EXPORT_SYMBOL(_metered_write_lock);
++EXPORT_SYMBOL(_metered_write_unlock);
+--- linux-2.6.0/kernel/Makefile        2003-11-09 16:45:05.000000000 -0800
++++ 25/kernel/Makefile 2003-12-28 23:26:33.000000000 -0800
+@@ -11,6 +11,7 @@ obj-y     = sched.o fork.o exec_domain.o
+ obj-$(CONFIG_FUTEX) += futex.o
+ obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
+ obj-$(CONFIG_SMP) += cpu.o
++obj-$(CONFIG_LOCKMETER) += lockmeter.o
+ obj-$(CONFIG_UID16) += uid16.o
+ obj-$(CONFIG_MODULES) += module.o
+ obj-$(CONFIG_KALLSYMS) += kallsyms.o
+--- linux-2.6.0/kernel/pid.c   2003-11-09 16:45:05.000000000 -0800
++++ 25/kernel/pid.c    2003-12-28 23:21:08.000000000 -0800
+@@ -268,6 +268,9 @@ void switch_exec_pids(task_t *leader, ta
+  * machine.  From a minimum of 16 slots up to 4096 slots at one gigabyte or
+  * more.
+  */
++#ifdef CONFIG_KGDB
++int kgdb_pid_init_done; /* so we don't call prior to... */
++#endif
+ void __init pidhash_init(void)
+ {
+       int i, j, pidhash_size;
+@@ -289,6 +292,9 @@ void __init pidhash_init(void)
+               for (j = 0; j < pidhash_size; j++)
+                       INIT_LIST_HEAD(&pid_hash[i][j]);
+       }
++#ifdef CONFIG_KGDB
++      kgdb_pid_init_done++;
++#endif
+ }
+ void __init pidmap_init(void)
+--- linux-2.6.0/kernel/power/Kconfig   2003-09-27 18:57:47.000000000 -0700
++++ 25/kernel/power/Kconfig    2003-12-28 23:23:06.000000000 -0800
+@@ -40,7 +40,7 @@ config SOFTWARE_SUSPEND
+         involved in suspending. Also in this case there is a risk that buffers
+         on disk won't match with saved ones.
+-        For more information take a look at Documentation/swsusp.txt.
++        For more information take a look at Documentation/power/swsusp.txt.
+ config PM_DISK
+       bool "Suspend-to-Disk Support"
+--- linux-2.6.0/kernel/power/swsusp.c  2003-10-17 15:58:04.000000000 -0700
++++ 25/kernel/power/swsusp.c   2003-12-28 23:23:06.000000000 -0800
+@@ -33,7 +33,7 @@
+  *
+  * More state savers are welcome. Especially for the scsi layer...
+  *
+- * For TODOs,FIXMEs also look in Documentation/swsusp.txt
++ * For TODOs,FIXMEs also look in Documentation/power/swsusp.txt
+  */
+ #include <linux/module.h>
+--- linux-2.6.0/kernel/printk.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/kernel/printk.c 2003-12-28 23:26:35.000000000 -0800
+@@ -150,6 +150,7 @@ __setup("console=", console_setup);
+ static int __init log_buf_len_setup(char *str)
+ {
+       unsigned long size = memparse(str, &str);
++      unsigned long flags;
+       if (size > log_buf_len) {
+               unsigned long start, dest_idx, offset;
+@@ -161,7 +162,7 @@ static int __init log_buf_len_setup(char
+                       goto out;
+               }
+-              spin_lock_irq(&logbuf_lock);
++              spin_lock_irqsave(&logbuf_lock, flags);
+               log_buf_len = size;
+               log_buf = new_log_buf;
+@@ -175,7 +176,7 @@ static int __init log_buf_len_setup(char
+               log_start -= offset;
+               con_start -= offset;
+               log_end -= offset;
+-              spin_unlock_irq(&logbuf_lock);
++              spin_unlock_irqrestore(&logbuf_lock, flags);
+               printk("log_buf_len: %d\n", log_buf_len);
+       }
+@@ -447,9 +448,13 @@ asmlinkage int printk(const char *fmt, .
+       char *p;
+       static char printk_buf[1024];
+       static int log_level_unknown = 1;
++      static int printk_cpu = -1;
+-      if (oops_in_progress) {
+-              /* If a crash is occurring, make sure we can't deadlock */
++      if (oops_in_progress && printk_cpu == smp_processor_id()) {
++              /*
++               * If a crash is occurring during printk() on this CPU, make
++               * sure we can't deadlock
++               */
+               spin_lock_init(&logbuf_lock);
+               /* And make sure that we print immediately */
+               init_MUTEX(&console_sem);
+@@ -457,6 +462,7 @@ asmlinkage int printk(const char *fmt, .
+       /* This stops the holder of console_sem just where we want him */
+       spin_lock_irqsave(&logbuf_lock, flags);
++      printk_cpu = smp_processor_id();
+       /* Emit the output into the temporary buffer */
+       va_start(args, fmt);
+--- linux-2.6.0/kernel/sched.c 2003-12-17 21:20:03.000000000 -0800
++++ 25/kernel/sched.c  2003-12-28 23:26:33.000000000 -0800
+@@ -79,13 +79,13 @@
+  */
+ #define MIN_TIMESLICE         ( 10 * HZ / 1000)
+ #define MAX_TIMESLICE         (200 * HZ / 1000)
+-#define ON_RUNQUEUE_WEIGHT    30
+-#define CHILD_PENALTY         95
++#define ON_RUNQUEUE_WEIGHT     30
++#define CHILD_PENALTY          95
+ #define PARENT_PENALTY                100
+-#define EXIT_WEIGHT           3
+-#define PRIO_BONUS_RATIO      25
++#define EXIT_WEIGHT             3
++#define PRIO_BONUS_RATIO       25
+ #define MAX_BONUS             (MAX_USER_PRIO * PRIO_BONUS_RATIO / 100)
+-#define INTERACTIVE_DELTA     2
++#define INTERACTIVE_DELTA       2
+ #define MAX_SLEEP_AVG         (AVG_TIMESLICE * MAX_BONUS)
+ #define STARVATION_LIMIT      (MAX_SLEEP_AVG)
+ #define NS_MAX_SLEEP_AVG      (JIFFIES_TO_NS(MAX_SLEEP_AVG))
+@@ -143,7 +143,7 @@
+ #define TASK_INTERACTIVE(p) \
+       ((p)->prio <= (p)->static_prio - DELTA(p))
+-#define JUST_INTERACTIVE_SLEEP(p) \
++#define INTERACTIVE_SLEEP(p) \
+       (JIFFIES_TO_NS(MAX_SLEEP_AVG * \
+               (MAX_BONUS / 2 + DELTA((p)) + 1) / MAX_BONUS - 1))
+@@ -168,7 +168,8 @@
+  */
+ #define BASE_TIMESLICE(p) (MIN_TIMESLICE + \
+-      ((MAX_TIMESLICE - MIN_TIMESLICE) * (MAX_PRIO-1-(p)->static_prio)/(MAX_USER_PRIO - 1)))
++              ((MAX_TIMESLICE - MIN_TIMESLICE) * \
++                      (MAX_PRIO-1 - (p)->static_prio) / (MAX_USER_PRIO-1)))
+ static inline unsigned int task_timeslice(task_t *p)
+ {
+@@ -199,11 +200,11 @@ struct prio_array {
+ struct runqueue {
+       spinlock_t lock;
+       unsigned long nr_running, nr_switches, expired_timestamp,
+-                      nr_uninterruptible;
++                    nr_uninterruptible, timestamp_last_tick;
+       task_t *curr, *idle;
+       struct mm_struct *prev_mm;
+       prio_array_t *active, *expired, arrays[2];
+-      int prev_cpu_load[NR_CPUS];
++      int best_expired_prio, prev_cpu_load[NR_CPUS];
+ #ifdef CONFIG_NUMA
+       atomic_t *node_nr_running;
+       int prev_node_load[MAX_NUMNODES];
+@@ -225,7 +226,7 @@ static DEFINE_PER_CPU(struct runqueue, r
+  * Default context-switch locking:
+  */
+ #ifndef prepare_arch_switch
+-# define prepare_arch_switch(rq, next)        do { } while(0)
++# define prepare_arch_switch(rq, next)        do { } while (0)
+ # define finish_arch_switch(rq, next) spin_unlock_irq(&(rq)->lock)
+ # define task_running(rq, p)          ((rq)->curr == (p))
+ #endif
+@@ -269,9 +270,9 @@ __init void node_nr_running_init(void)
+ #else /* !CONFIG_NUMA */
+-# define nr_running_init(rq)   do { } while (0)
+-# define nr_running_inc(rq)    do { (rq)->nr_running++; } while (0)
+-# define nr_running_dec(rq)    do { (rq)->nr_running--; } while (0)
++# define nr_running_init(rq)  do { } while (0)
++# define nr_running_inc(rq)   do { (rq)->nr_running++; } while (0)
++# define nr_running_dec(rq)   do { (rq)->nr_running--; } while (0)
+ #endif /* CONFIG_NUMA */
+@@ -396,7 +397,7 @@ static void recalc_task_prio(task_t *p, 
+                * other processes.
+                */
+               if (p->mm && p->activated != -1 &&
+-                      sleep_time > JUST_INTERACTIVE_SLEEP(p)){
++                      sleep_time > INTERACTIVE_SLEEP(p)) {
+                               p->sleep_avg = JIFFIES_TO_NS(MAX_SLEEP_AVG -
+                                               AVG_TIMESLICE);
+                               if (!HIGH_CREDIT(p))
+@@ -413,37 +414,35 @@ static void recalc_task_prio(task_t *p, 
+                        * one timeslice worth of sleep avg bonus.
+                        */
+                       if (LOW_CREDIT(p) &&
+-                              sleep_time > JIFFIES_TO_NS(task_timeslice(p)))
+-                                      sleep_time =
+-                                              JIFFIES_TO_NS(task_timeslice(p));
++                          sleep_time > JIFFIES_TO_NS(task_timeslice(p)))
++                              sleep_time = JIFFIES_TO_NS(task_timeslice(p));
+                       /*
+                        * Non high_credit tasks waking from uninterruptible
+                        * sleep are limited in their sleep_avg rise as they
+                        * are likely to be cpu hogs waiting on I/O
+                        */
+-                      if (p->activated == -1 && !HIGH_CREDIT(p) && p->mm){
+-                              if (p->sleep_avg >= JUST_INTERACTIVE_SLEEP(p))
++                      if (p->activated == -1 && !HIGH_CREDIT(p) && p->mm) {
++                              if (p->sleep_avg >= INTERACTIVE_SLEEP(p))
+                                       sleep_time = 0;
+                               else if (p->sleep_avg + sleep_time >=
+-                                      JUST_INTERACTIVE_SLEEP(p)){
+-                                              p->sleep_avg =
+-                                                      JUST_INTERACTIVE_SLEEP(p);
+-                                              sleep_time = 0;
+-                                      }
++                                              INTERACTIVE_SLEEP(p)) {
++                                      p->sleep_avg = INTERACTIVE_SLEEP(p);
++                                      sleep_time = 0;
++                              }
+                       }
+                       /*
+                        * This code gives a bonus to interactive tasks.
+                        *
+                        * The boost works by updating the 'average sleep time'
+-                       * value here, based on ->timestamp. The more time a task
+-                       * spends sleeping, the higher the average gets - and the
+-                       * higher the priority boost gets as well.
++                       * value here, based on ->timestamp. The more time a
++                       * task spends sleeping, the higher the average gets -
++                       * and the higher the priority boost gets as well.
+                        */
+                       p->sleep_avg += sleep_time;
+-                      if (p->sleep_avg > NS_MAX_SLEEP_AVG){
++                      if (p->sleep_avg > NS_MAX_SLEEP_AVG) {
+                               p->sleep_avg = NS_MAX_SLEEP_AVG;
+                               if (!HIGH_CREDIT(p))
+                                       p->interactive_credit++;
+@@ -470,7 +469,7 @@ static inline void activate_task(task_t 
+        * This checks to make sure it's not an uninterruptible task
+        * that is now waking up.
+        */
+-      if (!p->activated){
++      if (!p->activated) {
+               /*
+                * Tasks which were woken up by interrupts (ie. hw events)
+                * are most likely of interactive nature. So we give them
+@@ -480,13 +479,14 @@ static inline void activate_task(task_t 
+                */
+               if (in_interrupt())
+                       p->activated = 2;
+-              else
+-              /*
+-               * Normal first-time wakeups get a credit too for on-runqueue
+-               * time, but it will be weighted down:
+-               */
++              else {
++                      /*
++                       * Normal first-time wakeups get a credit too for
++                       * on-runqueue time, but it will be weighted down:
++                       */
+                       p->activated = 1;
+               }
++      }
+       p->timestamp = now;
+       __activate_task(p, rq);
+@@ -632,13 +632,14 @@ repeat_lock_task:
+                        */
+                       if (unlikely(sync && !task_running(rq, p) &&
+                               (task_cpu(p) != smp_processor_id()) &&
+-                              cpu_isset(smp_processor_id(), p->cpus_allowed))) {
++                                      cpu_isset(smp_processor_id(),
++                                                      p->cpus_allowed))) {
+                               set_task_cpu(p, smp_processor_id());
+                               task_rq_unlock(rq, &flags);
+                               goto repeat_lock_task;
+                       }
+-                      if (old_state == TASK_UNINTERRUPTIBLE){
++                      if (old_state == TASK_UNINTERRUPTIBLE) {
+                               rq->nr_uninterruptible--;
+                               /*
+                                * Tasks on involuntary sleep don't earn
+@@ -663,7 +664,8 @@ repeat_lock_task:
+ }
+ int wake_up_process(task_t * p)
+ {
+-      return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0);
++      return try_to_wake_up(p, TASK_STOPPED |
++                               TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0);
+ }
+ EXPORT_SYMBOL(wake_up_process);
+@@ -674,6 +676,54 @@ int wake_up_state(task_t *p, unsigned in
+ }
+ /*
++ * Perform scheduler related setup for a newly forked process p.
++ * p is forked by current.
++ */
++void sched_fork(task_t *p)
++{
++      p->state = TASK_UNINTERRUPTIBLE;
++      INIT_LIST_HEAD(&p->run_list);
++      p->array = NULL;
++      spin_lock_init(&p->switch_lock);
++#ifdef CONFIG_PREEMPT
++      /*
++       * During context-switch we hold precisely one spinlock, which
++       * schedule_tail drops. (in the common case it's this_rq()->lock,
++       * but it also can be p->switch_lock.) So we compensate with a count
++       * of 1. Also, we want to start with kernel preemption disabled.
++       */
++      p->thread_info->preempt_count = 1;
++#endif
++      /*
++       * Share the timeslice between parent and child, thus the
++       * total amount of pending timeslices in the system doesn't change,
++       * resulting in more scheduling fairness.
++       */
++      local_irq_disable();
++      p->time_slice = (current->time_slice + 1) >> 1;
++      /*
++       * The remainder of the first timeslice might be recovered by
++       * the parent if the child exits early enough.
++       */
++      p->first_time_slice = 1;
++      current->time_slice >>= 1;
++      p->timestamp = sched_clock();
++      if (!current->time_slice) {
++              /*
++               * This case is rare, it happens when the parent has only
++               * a single jiffy left from its timeslice. Taking the
++               * runqueue lock is not a problem.
++               */
++              current->time_slice = 1;
++              preempt_disable();
++              scheduler_tick(0, 0);
++              local_irq_enable();
++              preempt_enable();
++      } else
++              local_irq_enable();
++}
++
++/*
+  * wake_up_forked_process - wake up a freshly forked process.
+  *
+  * This function will do some initial scheduler statistics housekeeping
+@@ -799,7 +849,8 @@ asmlinkage void schedule_tail(task_t *pr
+  * context_switch - switch to the new MM and the new
+  * thread's register state.
+  */
+-static inline task_t * context_switch(runqueue_t *rq, task_t *prev, task_t *next)
++static inline
++task_t * context_switch(runqueue_t *rq, task_t *prev, task_t *next)
+ {
+       struct mm_struct *mm = next->mm;
+       struct mm_struct *oldmm = prev->active_mm;
+@@ -947,10 +998,10 @@ static int sched_best_cpu(struct task_st
+       minload = 10000000;
+       for_each_node_with_cpus(i) {
+               /*
+-               * Node load is always divided by nr_cpus_node to normalise 
++               * Node load is always divided by nr_cpus_node to normalise
+                * load values in case cpu count differs from node to node.
+                * We first multiply node_nr_running by 10 to get a little
+-               * better resolution.   
++               * better resolution.
+                */
+               load = 10 * atomic_read(&node_nr_running[i]) / nr_cpus_node(i);
+               if (load < minload) {
+@@ -989,7 +1040,7 @@ void sched_balance_exec(void)
+  *      load_{t} = load_{t-1}/2 + nr_node_running_{t}
+  * This way sudden load peaks are flattened out a bit.
+  * Node load is divided by nr_cpus_node() in order to compare nodes
+- * of different cpu count but also [first] multiplied by 10 to 
++ * of different cpu count but also [first] multiplied by 10 to
+  * provide better resolution.
+  */
+ static int find_busiest_node(int this_node)
+@@ -1027,8 +1078,10 @@ static int find_busiest_node(int this_no
+  * this_rq is locked already. Recalculate nr_running if we have to
+  * drop the runqueue lock.
+  */
+-static inline unsigned int double_lock_balance(runqueue_t *this_rq,
+-      runqueue_t *busiest, int this_cpu, int idle, unsigned int nr_running)
++static inline
++unsigned int double_lock_balance(runqueue_t *this_rq, runqueue_t *busiest,
++                               int this_cpu, int idle,
++                               unsigned int nr_running)
+ {
+       if (unlikely(!spin_trylock(&busiest->lock))) {
+               if (busiest < this_rq) {
+@@ -1036,7 +1089,8 @@ static inline unsigned int double_lock_b
+                       spin_lock(&busiest->lock);
+                       spin_lock(&this_rq->lock);
+                       /* Need to recalculate nr_running */
+-                      if (idle || (this_rq->nr_running > this_rq->prev_cpu_load[this_cpu]))
++                      if (idle || (this_rq->nr_running >
++                                      this_rq->prev_cpu_load[this_cpu]))
+                               nr_running = this_rq->nr_running;
+                       else
+                               nr_running = this_rq->prev_cpu_load[this_cpu];
+@@ -1049,7 +1103,9 @@ static inline unsigned int double_lock_b
+ /*
+  * find_busiest_queue - find the busiest runqueue among the cpus in cpumask.
+  */
+-static inline runqueue_t *find_busiest_queue(runqueue_t *this_rq, int this_cpu, int idle, int *imbalance, cpumask_t cpumask)
++static inline
++runqueue_t *find_busiest_queue(runqueue_t *this_rq, int this_cpu, int idle,
++                             int *imbalance, cpumask_t cpumask)
+ {
+       int nr_running, load, max_load, i;
+       runqueue_t *busiest, *rq_src;
+@@ -1061,10 +1117,11 @@ static inline runqueue_t *find_busiest_q
+        * the lock held.
+        *
+        * We fend off statistical fluctuations in runqueue lengths by
+-       * saving the runqueue length during the previous load-balancing
+-       * operation and using the smaller one the current and saved lengths.
+-       * If a runqueue is long enough for a longer amount of time then
+-       * we recognize it and pull tasks from it.
++       * saving the runqueue length (as seen by the balancing CPU) during
++       * the previous load-balancing operation and using the smaller one
++       * of the current and saved lengths. If a runqueue is long enough
++       * for a longer amount of time then we recognize it and pull tasks
++       * from it.
+        *
+        * The 'current runqueue length' is a statistical maximum variable,
+        * for that one we take the longer one - to avoid fluctuations in
+@@ -1111,7 +1168,8 @@ static inline runqueue_t *find_busiest_q
+               goto out;
+       }
+-      nr_running = double_lock_balance(this_rq, busiest, this_cpu, idle, nr_running);
++      nr_running = double_lock_balance(this_rq, busiest, this_cpu,
++                                       idle, nr_running);
+       /*
+        * Make sure nothing changed since we checked the
+        * runqueue length.
+@@ -1128,13 +1186,17 @@ out:
+  * pull_task - move a task from a remote runqueue to the local runqueue.
+  * Both runqueues must be locked.
+  */
+-static inline void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t *p, runqueue_t *this_rq, int this_cpu)
++static inline
++void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t *p,
++             runqueue_t *this_rq, int this_cpu)
+ {
+       dequeue_task(p, src_array);
+       nr_running_dec(src_rq);
+       set_task_cpu(p, this_cpu);
+       nr_running_inc(this_rq);
+       enqueue_task(p, this_rq->active);
++      p->timestamp = sched_clock() -
++                              (src_rq->timestamp_last_tick - p->timestamp);
+       /*
+        * Note that idle threads have a prio of MAX_PRIO, for this test
+        * to be always true for them.
+@@ -1144,25 +1206,25 @@ static inline void pull_task(runqueue_t 
+ }
+ /*
+- * Previously:
+- *
+- * #define CAN_MIGRATE_TASK(p,rq,this_cpu)    \
+- *    ((!idle || (NS_TO_JIFFIES(now - (p)->timestamp) > \
+- *            cache_decay_ticks)) && !task_running(rq, p) && \
+- *                    cpu_isset(this_cpu, (p)->cpus_allowed))
++ * can_migrate_task - may task p from runqueue rq be migrated to this_cpu?
+  */
+-
+-static inline int
+-can_migrate_task(task_t *tsk, runqueue_t *rq, int this_cpu, int idle)
++static inline
++int can_migrate_task(task_t *tsk, runqueue_t *rq, int this_cpu, int idle)
+ {
+-      unsigned long delta = sched_clock() - tsk->timestamp;
++      unsigned long delta = rq->timestamp_last_tick - tsk->timestamp;
+-      if (!idle && (delta <= JIFFIES_TO_NS(cache_decay_ticks)))
+-              return 0;
++      /*
++       * We do not migrate tasks that are:
++       * 1) running (obviously), or
++       * 2) cannot be migrated to this CPU due to cpus_allowed, or
++       * 3) are cache-hot on their current CPU.
++       */
+       if (task_running(rq, tsk))
+               return 0;
+       if (!cpu_isset(this_cpu, tsk->cpus_allowed))
+               return 0;
++      if (!idle && (delta <= JIFFIES_TO_NS(cache_decay_ticks)))
++              return 0;
+       return 1;
+ }
+@@ -1182,7 +1244,8 @@ static void load_balance(runqueue_t *thi
+       struct list_head *head, *curr;
+       task_t *tmp;
+-      busiest = find_busiest_queue(this_rq, this_cpu, idle, &imbalance, cpumask);
++      busiest = find_busiest_queue(this_rq, this_cpu, idle,
++                                   &imbalance, cpumask);
+       if (!busiest)
+               goto out;
+@@ -1224,13 +1287,6 @@ skip_bitmap:
+ skip_queue:
+       tmp = list_entry(curr, task_t, run_list);
+-      /*
+-       * We do not migrate tasks that are:
+-       * 1) running (obviously), or
+-       * 2) cannot be migrated to this CPU due to cpus_allowed, or
+-       * 3) are cache-hot on their current CPU.
+-       */
+-
+       curr = curr->prev;
+       if (!can_migrate_task(tmp, busiest, this_cpu, idle)) {
+@@ -1240,6 +1296,8 @@ skip_queue:
+               goto skip_bitmap;
+       }
+       pull_task(busiest, array, tmp, this_rq, this_cpu);
++
++      /* Only migrate one task if we are idle */
+       if (!idle && --imbalance) {
+               if (curr != head)
+                       goto skip_queue;
+@@ -1329,7 +1387,7 @@ static inline void rebalance_tick(runque
+ }
+ #endif
+-DEFINE_PER_CPU(struct kernel_stat, kstat) = { { 0 } };
++DEFINE_PER_CPU(struct kernel_stat, kstat);
+ EXPORT_PER_CPU_SYMBOL(kstat);
+@@ -1340,12 +1398,14 @@ EXPORT_PER_CPU_SYMBOL(kstat);
+  * interactivity of a task if the first expired task had to wait more
+  * than a 'reasonable' amount of time. This deadline timeout is
+  * load-dependent, as the frequency of array switched decreases with
+- * increasing number of running tasks:
++ * increasing number of running tasks. We also ignore the interactivity
++ * if a better static_prio task has expired:
+  */
+ #define EXPIRED_STARVING(rq) \
+-              (STARVATION_LIMIT && ((rq)->expired_timestamp && \
++      ((STARVATION_LIMIT && ((rq)->expired_timestamp && \
+               (jiffies - (rq)->expired_timestamp >= \
+-                      STARVATION_LIMIT * ((rq)->nr_running) + 1)))
++                      STARVATION_LIMIT * ((rq)->nr_running) + 1))) || \
++                      ((rq)->curr->static_prio > (rq)->best_expired_prio))
+ /*
+  * This function gets called by the timer code, with HZ frequency.
+@@ -1361,6 +1421,8 @@ void scheduler_tick(int user_ticks, int 
+       runqueue_t *rq = this_rq();
+       task_t *p = current;
++      rq->timestamp_last_tick = sched_clock();
++
+       if (rcu_pending(cpu))
+               rcu_check_callbacks(cpu, user_ticks);
+@@ -1427,6 +1489,8 @@ void scheduler_tick(int user_ticks, int 
+                       rq->expired_timestamp = jiffies;
+               if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) {
+                       enqueue_task(p, rq->expired);
++                      if (p->static_prio < rq->best_expired_prio)
++                              rq->best_expired_prio = p->static_prio;
+               } else
+                       enqueue_task(p, rq->active);
+       } else {
+@@ -1470,6 +1534,7 @@ void scheduling_functions_start_here(voi
+  */
+ asmlinkage void schedule(void)
+ {
++      long *switch_count;
+       task_t *prev, *next;
+       runqueue_t *rq;
+       prio_array_t *array;
+@@ -1516,32 +1581,25 @@ need_resched:
+        * if entering off of a kernel preemption go straight
+        * to picking the next task.
+        */
+-      if (unlikely(preempt_count() & PREEMPT_ACTIVE))
+-              goto pick_next_task;
+-
+-      switch (prev->state) {
+-      case TASK_INTERRUPTIBLE:
+-              if (unlikely(signal_pending(prev))) {
++      switch_count = &prev->nivcsw;
++      if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
++              switch_count = &prev->nvcsw;
++              if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
++                              unlikely(signal_pending(prev))))
+                       prev->state = TASK_RUNNING;
+-                      break;
+-              }
+-      default:
+-              deactivate_task(prev, rq);
+-              prev->nvcsw++;
+-              break;
+-      case TASK_RUNNING:
+-              prev->nivcsw++;
++              else
++                      deactivate_task(prev, rq);
+       }
+-pick_next_task:
++
+       if (unlikely(!rq->nr_running)) {
+ #ifdef CONFIG_SMP
+               load_balance(rq, 1, cpu_to_node_mask(smp_processor_id()));
+-              if (rq->nr_running)
+-                      goto pick_next_task;
+ #endif
+-              next = rq->idle;
+-              rq->expired_timestamp = 0;
+-              goto switch_tasks;
++              if (!rq->nr_running) {
++                      next = rq->idle;
++                      rq->expired_timestamp = 0;
++                      goto switch_tasks;
++              }
+       }
+       array = rq->active;
+@@ -1553,6 +1611,7 @@ pick_next_task:
+               rq->expired = array;
+               array = rq->active;
+               rq->expired_timestamp = 0;
++              rq->best_expired_prio = MAX_PRIO;
+       }
+       idx = sched_find_first_bit(array->bitmap);
+@@ -1577,7 +1636,7 @@ switch_tasks:
+       RCU_qsctr(task_cpu(prev))++;
+       prev->sleep_avg -= run_time;
+-      if ((long)prev->sleep_avg <= 0){
++      if ((long)prev->sleep_avg <= 0) {
+               prev->sleep_avg = 0;
+               if (!(HIGH_CREDIT(prev) || LOW_CREDIT(prev)))
+                       prev->interactive_credit--;
+@@ -1588,6 +1647,7 @@ switch_tasks:
+               next->timestamp = now;
+               rq->nr_switches++;
+               rq->curr = next;
++              ++*switch_count;
+               prepare_arch_switch(rq, next);
+               prev = context_switch(rq, prev, next);
+@@ -1653,7 +1713,8 @@ EXPORT_SYMBOL(default_wake_function);
+  * started to run but is not in state TASK_RUNNING.  try_to_wake_up() returns
+  * zero in this (rare) case, and we handle it by continuing to scan the queue.
+  */
+-static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, int nr_exclusive, int sync)
++static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
++                           int nr_exclusive, int sync)
+ {
+       struct list_head *tmp, *next;
+@@ -1730,7 +1791,8 @@ void complete(struct completion *x)
+       spin_lock_irqsave(&x->wait.lock, flags);
+       x->done++;
+-      __wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1, 0);
++      __wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,
++                       1, 0);
+       spin_unlock_irqrestore(&x->wait.lock, flags);
+ }
+@@ -1742,7 +1804,8 @@ void complete_all(struct completion *x)
+       spin_lock_irqsave(&x->wait.lock, flags);
+       x->done += UINT_MAX/2;
+-      __wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0, 0);
++      __wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,
++                       0, 0);
+       spin_unlock_irqrestore(&x->wait.lock, flags);
+ }
+@@ -1769,9 +1832,9 @@ void wait_for_completion(struct completi
+ EXPORT_SYMBOL(wait_for_completion);
+-#define       SLEEP_ON_VAR                            \
+-      unsigned long flags;                    \
+-      wait_queue_t wait;                      \
++#define       SLEEP_ON_VAR                                    \
++      unsigned long flags;                            \
++      wait_queue_t wait;                              \
+       init_waitqueue_entry(&wait, current);
+ #define SLEEP_ON_HEAD                                 \
+@@ -1779,9 +1842,9 @@ EXPORT_SYMBOL(wait_for_completion);
+       __add_wait_queue(q, &wait);                     \
+       spin_unlock(&q->lock);
+-#define       SLEEP_ON_TAIL                                           \
+-      spin_lock_irq(&q->lock);                                \
+-      __remove_wait_queue(q, &wait);                          \
++#define       SLEEP_ON_TAIL                                   \
++      spin_lock_irq(&q->lock);                        \
++      __remove_wait_queue(q, &wait);                  \
+       spin_unlock_irqrestore(&q->lock, flags);
+ void interruptible_sleep_on(wait_queue_head_t *q)
+@@ -1891,6 +1954,13 @@ out_unlock:
+ EXPORT_SYMBOL(set_user_nice);
++#if defined( CONFIG_KGDB)
++struct task_struct * kgdb_get_idle(int this_cpu)
++{
++        return cpu_rq(this_cpu)->idle;
++}
++#endif
++
+ #ifndef __alpha__
+ /*
+@@ -1906,9 +1976,9 @@ asmlinkage long sys_nice(int increment)
+       long nice;
+       /*
+-       *      Setpriority might change our priority at the same moment.
+-       *      We don't have to worry. Conceptually one call occurs first
+-       *      and we have a single winner.
++       * Setpriority might change our priority at the same moment.
++       * We don't have to worry. Conceptually one call occurs first
++       * and we have a single winner.
+        */
+       if (increment < 0) {
+               if (!capable(CAP_SYS_NICE))
+@@ -2088,7 +2158,7 @@ out_nounlock:
+  * @param: structure containing the new RT priority.
+  */
+ asmlinkage long sys_sched_setscheduler(pid_t pid, int policy,
+-                                    struct sched_param __user *param)
++                                     struct sched_param __user *param)
+ {
+       return setscheduler(pid, policy, param);
+ }
+@@ -2395,7 +2465,8 @@ asmlinkage long sys_sched_get_priority_m
+  * this syscall writes the default timeslice value of a given process
+  * into the user-space timespec buffer. A value of '0' means infinity.
+  */
+-asmlinkage long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval)
++asmlinkage
++long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval)
+ {
+       int retval = -EINVAL;
+       struct timespec t;
+@@ -2445,17 +2516,16 @@ static inline struct task_struct *younge
+ static void show_task(task_t * p)
+ {
+-      unsigned long free = 0;
+       task_t *relative;
+-      int state;
+-      static const char * stat_nam[] = { "R", "S", "D", "T", "Z", "W" };
++      unsigned state;
++      static const char *stat_nam[] = { "R", "S", "D", "T", "Z", "W" };
+       printk("%-13.13s ", p->comm);
+       state = p->state ? __ffs(p->state) + 1 : 0;
+-      if (((unsigned) state) < sizeof(stat_nam)/sizeof(char *))
++      if (state < ARRAY_SIZE(stat_nam))
+               printk(stat_nam[state]);
+       else
+-              printk(" ");
++              printk("?");
+ #if (BITS_PER_LONG == 32)
+       if (p == current)
+               printk(" current  ");
+@@ -2467,13 +2537,7 @@ static void show_task(task_t * p)
+       else
+               printk(" %016lx ", thread_saved_pc(p));
+ #endif
+-      {
+-              unsigned long * n = (unsigned long *) (p->thread_info+1);
+-              while (!*n)
+-                      n++;
+-              free = (unsigned long) n - (unsigned long)(p->thread_info+1);
+-      }
+-      printk("%5lu %5d %6d ", free, p->pid, p->parent->pid);
++      printk("%5d %6d ", p->pid, p->parent->pid);
+       if ((relative = eldest_child(p)))
+               printk("%5d ", relative->pid);
+       else
+@@ -2500,12 +2564,12 @@ void show_state(void)
+ #if (BITS_PER_LONG == 32)
+       printk("\n"
+-             "                         free                        sibling\n");
+-      printk("  task             PC    stack   pid father child younger older\n");
++             "                                               sibling\n");
++      printk("  task             PC      pid father child younger older\n");
+ #else
+       printk("\n"
+-             "                                 free                        sibling\n");
+-      printk("  task                 PC        stack   pid father child younger older\n");
++             "                                                       sibling\n");
++      printk("  task                 PC          pid father child younger older\n");
+ #endif
+       read_lock(&tasklist_lock);
+       do_each_thread(g, p) {
+@@ -2639,7 +2703,9 @@ static void move_task_away(struct task_s
+               if (p->prio < rq_dest->curr->prio)
+                       resched_task(rq_dest->curr);
+       }
+- out:
++      p->timestamp = rq_dest->timestamp_last_tick;
++
++out:
+       double_rq_unlock(this_rq(), rq_dest);
+       local_irq_restore(flags);
+ }
+@@ -2708,11 +2774,10 @@ static int migration_thread(void * data)
+  * migration_call - callback that gets triggered when a CPU is added.
+  * Here we can start up the necessary migration thread for the new CPU.
+  */
+-static int migration_call(struct notifier_block *nfb,
+-                        unsigned long action,
++static int migration_call(struct notifier_block *nfb, unsigned long action,
+                         void *hcpu)
+ {
+-      long cpu = (long) hcpu;
++      long cpu = (long)hcpu;
+       migration_startup_t startup;
+       switch (action) {
+@@ -2741,7 +2806,8 @@ static int migration_call(struct notifie
+       return NOTIFY_OK;
+ }
+-static struct notifier_block migration_notifier = { &migration_call, NULL, 0 };
++static struct notifier_block migration_notifier
++                      = { .notifier_call = &migration_call };
+ __init int migration_init(void)
+ {
+@@ -2777,7 +2843,7 @@ static void kstat_init_cpu(int cpu)
+ }
+ static int __devinit kstat_cpu_notify(struct notifier_block *self,
+-                                      unsigned long action, void *hcpu)
++                                    unsigned long action, void *hcpu)
+ {
+       int cpu = (unsigned long)hcpu;
+       switch(action) {
+@@ -2791,13 +2857,14 @@ static int __devinit kstat_cpu_notify(st
+ }
+ static struct notifier_block __devinitdata kstat_nb = {
+-      .notifier_call  = kstat_cpu_notify,
+-      .next           = NULL,
++      .notifier_call  = kstat_cpu_notify,
++      .next           = NULL,
+ };
+-__init static void init_kstat(void) {
++__init static void init_kstat(void)
++{
+       kstat_cpu_notify(&kstat_nb, (unsigned long)CPU_UP_PREPARE,
+-                      (void *)(long)smp_processor_id());
++                       (void *)(long)smp_processor_id());
+       register_cpu_notifier(&kstat_nb);
+ }
+@@ -2814,6 +2881,8 @@ void __init sched_init(void)
+               rq = cpu_rq(i);
+               rq->active = rq->arrays;
+               rq->expired = rq->arrays + 1;
++              rq->best_expired_prio = MAX_PRIO;
++
+               spin_lock_init(&rq->lock);
+               INIT_LIST_HEAD(&rq->migration_queue);
+               atomic_set(&rq->nr_iowait, 0);
+@@ -2861,7 +2930,7 @@ void __might_sleep(char *file, int line)
+               printk(KERN_ERR "Debug: sleeping function called from invalid"
+                               " context at %s:%d\n", file, line);
+               printk("in_atomic():%d, irqs_disabled():%d\n",
+-                              in_atomic(), irqs_disabled());
++                      in_atomic(), irqs_disabled());
+               dump_stack();
+       }
+ #endif
+--- linux-2.6.0/kernel/softirq.c       2003-11-09 16:45:05.000000000 -0800
++++ 25/kernel/softirq.c        2003-12-28 23:22:00.000000000 -0800
+@@ -117,11 +117,22 @@ EXPORT_SYMBOL(do_softirq);
+ void local_bh_enable(void)
+ {
++      if (in_irq()) {
++              printk("local_bh_enable() was called in hard irq context.   "
++                      "This is probably a bug\n");
++              dump_stack();
++      }
++
+       __local_bh_enable();
+-      WARN_ON(irqs_disabled());
+-      if (unlikely(!in_interrupt() &&
+-                   local_softirq_pending()))
++      if (unlikely(!in_interrupt() && local_softirq_pending())) {
++              if (irqs_disabled()) {
++                      printk("local_bh_enable() was called with local "
++                              "interrupts disabled.  This is probably a"
++                              " bug\n");
++                      dump_stack();
++              }
+               invoke_softirq();
++      }
+       preempt_check_resched();
+ }
+ EXPORT_SYMBOL(local_bh_enable);
+--- linux-2.6.0/kernel/sys.c   2003-10-25 14:45:46.000000000 -0700
++++ 25/kernel/sys.c    2003-12-28 23:22:12.000000000 -0800
+@@ -1323,8 +1323,6 @@ asmlinkage long sys_setrlimit(unsigned i
+  * either stopped or zombied.  In the zombied case the task won't get
+  * reaped till shortly after the call to getrusage(), in both cases the
+  * task being examined is in a frozen state so the counters won't change.
+- *
+- * FIXME! Get the fault counts properly!
+  */
+ int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
+ {
+--- linux-2.6.0/kernel/sysctl.c        2003-11-09 16:45:05.000000000 -0800
++++ 25/kernel/sysctl.c 2003-12-28 23:26:39.000000000 -0800
+@@ -794,6 +794,22 @@ static ctl_table fs_table[] = {
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
++      {
++              .ctl_name       = FS_AIO_NR,
++              .procname       = "aio-nr",
++              .data           = &aio_nr,
++              .maxlen         = sizeof(aio_nr),
++              .mode           = 0444,
++              .proc_handler   = &proc_dointvec,
++      },
++      {
++              .ctl_name       = FS_AIO_MAX_NR,
++              .procname       = "aio-max-nr",
++              .data           = &aio_max_nr,
++              .maxlen         = sizeof(aio_max_nr),
++              .mode           = 0644,
++              .proc_handler   = &proc_dointvec,
++      },
+       { .ctl_name = 0 }
+ };
+--- linux-2.6.0/lib/inflate.c  2003-09-27 18:57:47.000000000 -0700
++++ 25/lib/inflate.c   2003-12-28 23:22:52.000000000 -0800
+@@ -221,7 +221,7 @@ STATIC const ush mask_bits[] = {
+     0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+ };
+-#define NEXTBYTE()  (uch)get_byte()
++#define NEXTBYTE()  ({ int v = get_byte(); if (v < 0) goto underrun; (uch)v; })
+ #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}}
+ #define DUMPBITS(n) {b>>=(n);k-=(n);}
+@@ -620,6 +620,9 @@ STATIC int inflate_codes(
+   /* done */
+   return 0;
++
++ underrun:
++  return 4;                   /* Input underrun */
+ }
+@@ -676,6 +679,9 @@ DEBG("<stor");
+   DEBG(">");
+   return 0;
++
++ underrun:
++  return 4;                   /* Input underrun */
+ }
+@@ -908,6 +914,9 @@ DEBG("dyn7 ");
+   DEBG(">");
+   return 0;
++
++ underrun:
++  return 4;                   /* Input underrun */
+ }
+@@ -956,6 +965,9 @@ STATIC int inflate_block(
+   /* bad block type */
+   return 2;
++
++ underrun:
++  return 4;                   /* Input underrun */
+ }
+@@ -1079,9 +1091,9 @@ static int gunzip(void)
+     ulg orig_len = 0;       /* original uncompressed length */
+     int res;
+-    magic[0] = (unsigned char)get_byte();
+-    magic[1] = (unsigned char)get_byte();
+-    method = (unsigned char)get_byte();
++    magic[0] = NEXTBYTE();
++    magic[1] = NEXTBYTE();
++    method   = NEXTBYTE();
+     if (magic[0] != 037 ||
+       ((magic[1] != 0213) && (magic[1] != 0236))) {
+@@ -1108,29 +1120,29 @@ static int gunzip(void)
+           error("Input has invalid flags");
+           return -1;
+     }
+-    (ulg)get_byte();  /* Get timestamp */
+-    ((ulg)get_byte()) << 8;
+-    ((ulg)get_byte()) << 16;
+-    ((ulg)get_byte()) << 24;
++    NEXTBYTE();       /* Get timestamp */
++    NEXTBYTE();
++    NEXTBYTE();
++    NEXTBYTE();
+-    (void)get_byte();  /* Ignore extra flags for the moment */
+-    (void)get_byte();  /* Ignore OS type for the moment */
++    (void)NEXTBYTE();  /* Ignore extra flags for the moment */
++    (void)NEXTBYTE();  /* Ignore OS type for the moment */
+     if ((flags & EXTRA_FIELD) != 0) {
+-          unsigned len = (unsigned)get_byte();
+-          len |= ((unsigned)get_byte())<<8;
+-          while (len--) (void)get_byte();
++          unsigned len = (unsigned)NEXTBYTE();
++          len |= ((unsigned)NEXTBYTE())<<8;
++          while (len--) (void)NEXTBYTE();
+     }
+     /* Get original file name if it was truncated */
+     if ((flags & ORIG_NAME) != 0) {
+           /* Discard the old name */
+-          while (get_byte() != 0) /* null */ ;
++          while (NEXTBYTE() != 0) /* null */ ;
+     } 
+     /* Discard file comment if any */
+     if ((flags & COMMENT) != 0) {
+-          while (get_byte() != 0) /* null */ ;
++          while (NEXTBYTE() != 0) /* null */ ;
+     }
+     /* Decompress */
+@@ -1147,6 +1159,9 @@ static int gunzip(void)
+           case 3:
+                   error("out of memory");
+                   break;
++          case 4:
++                  error("out of input data");
++                  break;
+           default:
+                   error("invalid compressed format (other)");
+           }
+@@ -1157,15 +1172,15 @@ static int gunzip(void)
+     /* crc32  (see algorithm.doc)
+      * uncompressed input size modulo 2^32
+      */
+-    orig_crc = (ulg) get_byte();
+-    orig_crc |= (ulg) get_byte() << 8;
+-    orig_crc |= (ulg) get_byte() << 16;
+-    orig_crc |= (ulg) get_byte() << 24;
++    orig_crc = (ulg) NEXTBYTE();
++    orig_crc |= (ulg) NEXTBYTE() << 8;
++    orig_crc |= (ulg) NEXTBYTE() << 16;
++    orig_crc |= (ulg) NEXTBYTE() << 24;
+     
+-    orig_len = (ulg) get_byte();
+-    orig_len |= (ulg) get_byte() << 8;
+-    orig_len |= (ulg) get_byte() << 16;
+-    orig_len |= (ulg) get_byte() << 24;
++    orig_len = (ulg) NEXTBYTE();
++    orig_len |= (ulg) NEXTBYTE() << 8;
++    orig_len |= (ulg) NEXTBYTE() << 16;
++    orig_len |= (ulg) NEXTBYTE() << 24;
+     
+     /* Validate decompression */
+     if (orig_crc != CRC_VALUE) {
+@@ -1177,6 +1192,10 @@ static int gunzip(void)
+           return -1;
+     }
+     return 0;
++
++ underrun:                    /* NEXTBYTE() goto's here if needed */
++    error("out of input data");
++    return -1;
+ }
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/lib/int_sqrt.c  2003-12-28 23:21:48.000000000 -0800
+@@ -0,0 +1,32 @@
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++
++/**
++ * int_sqrt - rough approximation to sqrt
++ * @x: integer of which to calculate the sqrt
++ *
++ * A very rough approximation to the sqrt() function.
++ */
++unsigned long int_sqrt(unsigned long x)
++{
++      unsigned long op, res, one;
++
++      op = x;
++      res = 0;
++
++      one = 1 << 30;
++      while (one > op)
++              one >>= 2;
++
++      while (one != 0) {
++              if (op >= res + one) {
++                      op = op - (res + one);
++                      res = res +  2 * one;
++              }
++              res /= 2;
++              one /= 4;
++      }
++      return res;
++}
++EXPORT_SYMBOL(int_sqrt);
+--- linux-2.6.0/lib/Makefile   2003-11-23 19:03:02.000000000 -0800
++++ 25/lib/Makefile    2003-12-28 23:22:10.000000000 -0800
+@@ -5,7 +5,7 @@
+ lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
+        bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
+-       kobject.o idr.o div64.o parser.o
++       kobject.o idr.o div64.o parser.o int_sqrt.o mask.o
+ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
+ lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/lib/mask.c      2003-12-28 23:22:10.000000000 -0800
+@@ -0,0 +1,178 @@
++/*
++ * lib/mask.c
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2003 Silicon Graphics, Inc.  All Rights Reserved.
++ */
++
++/*
++ * Routines to manipulate multi-word bit masks, such as cpumasks.
++ *
++ * The ascii representation of multi-word bit masks displays each
++ * 32bit word in hex (not zero filled), and for masks longer than
++ * one word, uses a comma separator between words.  Words are
++ * displayed in big-endian order most significant first.  And hex
++ * digits within a word are also in big-endian order, of course.
++ *
++ * Examples:
++ *   A mask with just bit 0 set displays as "1".
++ *   A mask with just bit 127 set displays as "80000000,0,0,0".
++ *   A mask with just bit 64 set displays as "1,0,0".
++ *   A mask with bits 0, 1, 2, 4, 8, 16, 32 and 64 set displays
++ *     as "1,1,10117".  The first "1" is for bit 64, the second
++ *     for bit 32, the third for bit 16, and so forth, to the
++ *     "7", which is for bits 2, 1 and 0.
++ *   A mask with bits 32 through 39 set displays as "ff,0".
++ *
++ * The internal binary representation of masks is as one or
++ * an array of unsigned longs, perhaps wrapped in a struct for
++ * convenient use as an lvalue.  The following code doesn't know
++ * about any such struct details, relying on inline macros in
++ * files such as cpumask.h to pass in an unsigned long pointer
++ * and a length (in bytes), describing the mask contents.
++ * The 32bit words in the array are in little-endian order,
++ * low order word first.  Beware that this is the reverse order
++ * of the ascii representation.
++ *
++ * Even though the size of the input mask is provided in bytes,
++ * the following code may assume that the mask is a multiple of
++ * 32 or 64 bit words long, and ignore any fractional portion
++ * of a word at the end.  The main reason the size is passed in
++ * bytes is because it is so easy to write 'sizeof(somemask_t)'
++ * in the macros.
++ *
++ * Masks are not a single,simple type, like classic 'C'
++ * nul-term strings.  Rather they are a family of types, one
++ * for each different length.  Inline macros are used to pick
++ * up the actual length, where it is known to the compiler, and
++ * pass it down to these routines, which work on any specified
++ * length array of unsigned longs.  Poor man's templates.
++ *
++ * Many of the inline macros don't call into the following
++ * routines.  Some of them call into other kernel routines,
++ * such as memset(), set_bit() or ffs().  Some of them can
++ * accomplish their task right inline, such as returning the
++ * size or address of the unsigned long array, or optimized
++ * versions of the macros for the most common case of an array
++ * of a single unsigned long.
++ */
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/ctype.h>
++#include <linux/slab.h>
++#include <linux/errno.h>
++#include <linux/gfp.h>
++#include <asm/uaccess.h>
++
++#define MAX_HEX_PER_BYTE 4    /* dont need > 4 hex chars to encode byte */
++#define BASE 16                       /* masks are input in hex (base 16) */
++#define NUL ((char)'\0')      /* nul-terminator */
++
++/**
++ * __mask_snprintf_len - represent multi-word bit mask as string.
++ * @buf: The buffer to place the result into
++ * @buflen: The size of the buffer, including the trailing null space
++ * @maskp: Points to beginning of multi-word bit mask.
++ * @maskbytes: Number of bytes in bit mask at maskp.
++ *
++ * This routine is expected to be called from a macro such as:
++ *
++ * #define cpumask_snprintf(buf, buflen, mask) \
++ *   __mask_snprintf_len(buf, buflen, cpus_addr(mask), sizeof(mask))
++ */
++
++int __mask_snprintf_len(char *buf, unsigned int buflen,
++      const unsigned long *maskp, unsigned int maskbytes)
++{
++      u32 *wordp = (u32 *)maskp;
++      int i = maskbytes/sizeof(u32) - 1;
++      int len = 0;
++      char *sep = "";
++
++      while (i >= 1 && wordp[i] == 0)
++              i--;
++      while (i >= 0) {
++              len += snprintf(buf+len, buflen-len, "%s%x", sep, wordp[i]);
++              sep = ",";
++              i--;
++      }
++      return len;
++}
++
++/**
++ * __mask_parse_len - parse user string into maskbytes mask at maskp
++ * @ubuf: The user buffer from which to take the string
++ * @ubuflen: The size of this buffer, including the terminating char
++ * @maskp: Place resulting mask (array of unsigned longs) here
++ * @masklen: Construct mask at @maskp to have exactly @masklen bytes
++ *
++ * @masklen is a multiple of sizeof(unsigned long).  A mask of
++ * @masklen bytes is constructed starting at location @maskp.
++ * The value of this mask is specified by the user provided
++ * string starting at address @ubuf.  Only bytes in the range
++ * [@ubuf, @ubuf+@ubuflen) can be read from user space, and
++ * reading will stop after the first byte that is not a comma
++ * or valid hex digit in the characters [,0-9a-fA-F], or at
++ * the point @ubuf+@ubuflen, whichever comes first.
++ *
++ * Since the user only needs about 2.25 chars per byte to encode
++ * a mask (one char per nibble plus one comma separator or nul
++ * terminator per byte), we blow them off with -EINVAL if they
++ * claim a @ubuflen more than 4 (MAX_HEX_PER_BYTE) times maskbytes.
++ * An empty word (delimited by two consecutive commas, for example)
++ * is taken as zero.  If @buflen is zero, the entire @maskp is set
++ * to zero.
++ *
++ * If the user provides fewer comma-separated ascii words
++ * than there are 32 bit words in maskbytes, we zero fill the
++ * remaining high order words.  If they provide more, they fail
++ * with -EINVAL.  Each comma-separate ascii word is taken as
++ * a hex representation; leading zeros are ignored, and do not
++ * imply octal.  '00e1', 'e1', '00E1', 'E1' are all the same.
++ * If user passes a word that is larger than fits in a u32,
++ * they fail with -EOVERFLOW.
++ */
++
++int __mask_parse_len(const char __user *ubuf, unsigned int ubuflen,
++      unsigned long *maskp, unsigned int maskbytes)
++{
++      char buf[maskbytes * MAX_HEX_PER_BYTE + sizeof(NUL)];
++      char *bp = buf;
++      u32 *wordp = (u32 *)maskp;
++      char *p;
++      int i, j;
++
++      if (ubuflen > maskbytes * MAX_HEX_PER_BYTE)
++              return -EINVAL;
++      if (copy_from_user(buf, ubuf, ubuflen))
++              return -EFAULT;
++      buf[ubuflen] = NUL;
++
++      /*
++       * Put the words into wordp[] in big-endian order,
++       * then go back and reverse them.
++       */
++      memset(wordp, 0, maskbytes);
++      i = j = 0;
++      while ((p = strsep(&bp, ",")) != NULL) {
++              unsigned long long t;
++              if (j == maskbytes/sizeof(u32))
++                      return -EINVAL;
++              t = simple_strtoull(p, 0, BASE);
++              if (t != (u32)t)
++                      return -EOVERFLOW;
++              wordp[j++] = t;
++      }
++      --j;
++      while (i < j) {
++              u32 t = wordp[i];
++              wordp[i] = wordp[j];
++              wordp[j] = t;
++              i++, --j;
++      }
++      return 0;
++}
+--- linux-2.6.0/lib/parser.c   2003-10-08 15:07:10.000000000 -0700
++++ 25/lib/parser.c    2003-12-28 23:22:09.000000000 -0800
+@@ -11,6 +11,17 @@
+ #include <linux/slab.h>
+ #include <linux/string.h>
++/**
++ * match_one: - Determines if a string matches a simple pattern
++ * @s: the string to examine for presense of the pattern
++ * @p: the string containing the pattern
++ * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match
++ * locations.
++ *
++ * Description: Determines if the pattern @p is present in string @s. Can only
++ * match extremely simple token=arg style patterns. If the pattern is found,
++ * the location(s) of the arguments will be returned in the @args array.
++ */
+ static int match_one(char *s, char *p, substring_t args[])
+ {
+       char *meta;
+@@ -74,6 +85,20 @@ static int match_one(char *s, char *p, s
+       }
+ }
++/**
++ * match_token: - Find a token (and optional args) in a string
++ * @s: the string to examine for token/argument pairs
++ * @table: match_table_t describing the set of allowed option tokens and the
++ * arguments that may be associated with them. Must be terminated with a
++ * &struct match_token whose pattern is set to the NULL pointer.
++ * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match
++ * locations.
++ *
++ * Description: Detects which if any of a set of token strings has been passed
++ * to it. Tokens can include up to MAX_OPT_ARGS instances of basic c-style
++ * format identifiers which will be taken into account when matching the
++ * tokens, and whose locations will be returned in the @args array.
++ */
+ int match_token(char *s, match_table_t table, substring_t args[])
+ {
+       struct match_token *p;
+@@ -84,6 +109,16 @@ int match_token(char *s, match_table_t t
+       return p->token;
+ }
++/**
++ * match_number: scan a number in the given base from a substring_t
++ * @s: substring to be scanned
++ * @result: resulting integer on success
++ * @base: base to use when converting string
++ *
++ * Description: Given a &substring_t and a base, attempts to parse the substring
++ * as a number in that base. On success, sets @result to the integer represented
++ * by the string and returns 0. Returns either -ENOMEM or -EINVAL on failure.
++ */
+ static int match_number(substring_t *s, int *result, int base)
+ {
+       char *endp;
+@@ -103,27 +138,71 @@ static int match_number(substring_t *s, 
+       return ret;
+ }
++/**
++ * match_int: - scan a decimal representation of an integer from a substring_t
++ * @s: substring_t to be scanned
++ * @result: resulting integer on success
++ *
++ * Description: Attempts to parse the &substring_t @s as a decimal integer. On
++ * success, sets @result to the integer represented by the string and returns 0.
++ * Returns either -ENOMEM or -EINVAL on failure.
++ */
+ int match_int(substring_t *s, int *result)
+ {
+       return match_number(s, result, 0);
+ }
++/**
++ * match_octal: - scan an octal representation of an integer from a substring_t
++ * @s: substring_t to be scanned
++ * @result: resulting integer on success
++ *
++ * Description: Attempts to parse the &substring_t @s as an octal integer. On
++ * success, sets @result to the integer represented by the string and returns
++ * 0. Returns either -ENOMEM or -EINVAL on failure.
++ */
+ int match_octal(substring_t *s, int *result)
+ {
+       return match_number(s, result, 8);
+ }
++/**
++ * match_hex: - scan a hex representation of an integer from a substring_t
++ * @s: substring_t to be scanned
++ * @result: resulting integer on success
++ *
++ * Description: Attempts to parse the &substring_t @s as a hexadecimal integer.
++ * On success, sets @result to the integer represented by the string and
++ * returns 0. Returns either -ENOMEM or -EINVAL on failure.
++ */
+ int match_hex(substring_t *s, int *result)
+ {
+       return match_number(s, result, 16);
+ }
++/**
++ * match_strcpy: - copies the characters from a substring_t to a string
++ * @to: string to copy characters to.
++ * @s: &substring_t to copy
++ *
++ * Description: Copies the set of characters represented by the given
++ * &substring_t @s to the c-style string @to. Caller guarantees that @to is
++ * large enough to hold the characters of @s.
++ */
+ void match_strcpy(char *to, substring_t *s)
+ {
+       memcpy(to, s->from, s->to - s->from);
+       to[s->to - s->from] = '\0';
+ }
++/**
++ * match_strdup: - allocate a new string with the contents of a substring_t
++ * @s: &substring_t to copy
++ *
++ * Description: Allocates and returns a string filled with the contents of
++ * the &substring_t @s. The caller is responsible for freeing the returned
++ * string with kfree().
++ */
+ char *match_strdup(substring_t *s)
+ {
+       char *p = kmalloc(s->to - s->from + 1, GFP_KERNEL);
+--- linux-2.6.0/MAINTAINERS    2003-11-23 19:03:00.000000000 -0800
++++ 25/MAINTAINERS     2003-12-28 23:22:47.000000000 -0800
+@@ -73,7 +73,7 @@ S: Status, one of the following:
+ 3C359 NETWORK DRIVER
+ P:    Mike Phillips
+ M:    mikep@linuxtr.net
+-L:    linux-net@vger.rutgers.edu
++L:    linux-net@vger.kernel.org
+ L:    linux-tr@linuxtr.net
+ W:    http://www.linuxtr.net
+ S:    Maintained
+@@ -929,8 +929,9 @@ W: http://www.linuxia64.org/
+ S:    Maintained
+ SN-IA64 (Itanium) SUB-PLATFORM
+-P:    John Hesterberg
+-M:    jh@sgi.com
++P:    Jesse Barnes
++M:    jbarnes@sgi.com
++L:    linux-altix@sgi.com
+ L:    linux-ia64@linuxia64.org
+ W:    http://www.sgi.com/altix
+ S:    Maintained
+@@ -1154,6 +1155,12 @@ W:      http://sf.net/projects/kernel-janitor
+ W:    http://developer.osdl.org/rddunlap/kj-patches/
+ S:    Maintained
++KGDB FOR I386 PLATFORM
++P:    George Anzinger
++M:    george@mvista.com
++L:    linux-net@vger.kernel.org
++S:    Supported
++
+ KERNEL NFSD
+ P:    Neil Brown
+ M:    neilb@cse.unsw.edu.au
+@@ -1234,8 +1241,8 @@ W:       http://ldm.sourceforge.net
+ S:    Maintained
+ LSILOGIC/SYMBIOS/NCR 53C8XX and 53C1010 PCI-SCSI drivers
+-P:    Gerard Roudier
+-M:    groudier@free.fr
++P:    Matthew Wilcox
++M:    matthew@wil.cx
+ L:    linux-scsi@vger.kernel.org
+ S:    Maintained
+@@ -1468,7 +1475,7 @@ ONSTREAM SCSI TAPE DRIVER
+ P:    Willem Riede
+ M:    osst@riede.org
+ L:    osst@linux1.onstream.nl
+-L:    linux-scsi@vger.rutgers.edu
++L:    linux-scsi@vger.kernel.org
+ S:    Maintained
+ OPL3-SA2, SA3, and SAx DRIVER
+@@ -1556,11 +1563,8 @@ M:      greg@kroah.com
+ S:    Maintained
+ PCMCIA SUBSYSTEM
+-P:    David Hinds
+-M:    dahinds@users.sourceforge.net
+-L:    linux-kernel@vger.kernel.org
+-W:    http://pcmcia-cs.sourceforge.net
+-S:    Maintained
++L:    http://lists.infradead.org/mailman/listinfo/linux-pcmcia
++S:    Unmaintained
+ PCNET32 NETWORK DRIVER
+ P:    Thomas Bogendörfer
+--- linux-2.6.0/Makefile       2003-12-17 21:20:01.000000000 -0800
++++ 25/Makefile        2003-12-28 23:23:07.000000000 -0800
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 0
+-EXTRAVERSION =
++EXTRAVERSION = -mm2
+ # *DOCUMENTATION*
+ # To see a list of typical targets execute "make help"
+@@ -275,7 +275,7 @@ NOSTDINC_FLAGS  = -nostdinc -iwithprefix
+ CPPFLAGS        := -D__KERNEL__ -Iinclude \
+                  $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include)
+-CFLAGS                := -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
++CFLAGS                := -Wall -Wstrict-prototypes -Wno-trigraphs \
+                  -fno-strict-aliasing -fno-common
+ AFLAGS                := -D__ASSEMBLY__
+@@ -431,6 +431,12 @@ libs-y            := $(libs-y1) $(libs-y2)
+ # ---------------------------------------------------------------------------
++ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
++CFLAGS                += -Os
++else
++CFLAGS                += -O2
++endif
++
+ ifndef CONFIG_FRAME_POINTER
+ CFLAGS                += -fomit-frame-pointer
+ endif
+@@ -872,7 +878,7 @@ rpm:       clean spec
+       $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version;\
+       mv -f $(objtree)/.tmp_version $(objtree)/.version;
+-      $(RPM) -ta ../$(KERNELPATH).tar.gz
++      $(RPM) --target $(UTS_MACHINE) -ta ../$(KERNELPATH).tar.gz
+       rm ../$(KERNELPATH).tar.gz
+ # Brief documentation of the typical targets used
+--- linux-2.6.0/mm/fadvise.c   2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/fadvise.c    2003-12-28 23:21:20.000000000 -0800
+@@ -23,7 +23,6 @@
+ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
+ {
+       struct file *file = fget(fd);
+-      struct inode *inode;
+       struct address_space *mapping;
+       struct backing_dev_info *bdi;
+       pgoff_t start_index;
+@@ -33,8 +32,7 @@ asmlinkage long sys_fadvise64_64(int fd,
+       if (!file)
+               return -EBADF;
+-      inode = file->f_dentry->d_inode;
+-      mapping = inode->i_mapping;
++      mapping = file->f_mapping;
+       if (!mapping) {
+               ret = -EINVAL;
+               goto out;
+--- linux-2.6.0/mm/filemap.c   2003-11-23 19:03:02.000000000 -0800
++++ 25/mm/filemap.c    2003-12-28 23:26:44.000000000 -0800
+@@ -73,6 +73,9 @@
+  *  ->mmap_sem
+  *    ->i_sem                 (msync)
+  *
++ *  ->i_sem
++ *    ->i_alloc_sem             (various)
++ *
+  *  ->inode_lock
+  *    ->sb_lock                       (fs/fs-writeback.c)
+  *    ->mapping->page_lock    (__sync_single_inode)
+@@ -226,6 +229,18 @@ restart:
+ EXPORT_SYMBOL(filemap_fdatawait);
++int filemap_write_and_wait(struct address_space *mapping)
++{
++      int retval = 0;
++
++      if (mapping->nrpages) {
++              retval = filemap_fdatawrite(mapping);
++              if (retval == 0)
++                      retval = filemap_fdatawait(mapping);
++      }
++      return retval;
++}
++
+ /*
+  * This adds a page to the page cache, starting out as locked, unreferenced,
+  * not uptodate and with no errors.
+@@ -292,22 +307,42 @@ static wait_queue_head_t *page_waitqueue
+       return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)];
+ }
+-void wait_on_page_bit(struct page *page, int bit_nr)
++/*
++ * wait for the specified page bit to be cleared
++ * this could be a synchronous wait or could just queue an async
++ * notification callback depending on the wait queue entry parameter
++ *
++ * A NULL wait queue parameter defaults to sync behaviour
++ */
++int wait_on_page_bit_wq(struct page *page, int bit_nr, wait_queue_t *wait)
+ {
+       wait_queue_head_t *waitqueue = page_waitqueue(page);
+-      DEFINE_WAIT(wait);
++      DEFINE_WAIT(local_wait);
++
++      if (!wait)
++              wait = &local_wait; /* default to a sync wait entry */
+       do {
+-              prepare_to_wait(waitqueue, &wait, TASK_UNINTERRUPTIBLE);
++              prepare_to_wait(waitqueue, wait, TASK_UNINTERRUPTIBLE);
+               if (test_bit(bit_nr, &page->flags)) {
+                       sync_page(page);
++                      if (!is_sync_wait(wait)) {
++                              /*
++                               * if we've queued an async wait queue
++                               * callback do not block; just tell the
++                               * caller to return and retry later when
++                               * the callback is notified
++                               */
++                              return -EIOCBRETRY;
++                      }
+                       io_schedule();
+               }
+       } while (test_bit(bit_nr, &page->flags));
+-      finish_wait(waitqueue, &wait);
+-}
++      finish_wait(waitqueue, wait);
+-EXPORT_SYMBOL(wait_on_page_bit);
++      return 0;
++}
++EXPORT_SYMBOL(wait_on_page_bit_wq);
+ /**
+  * unlock_page() - unlock a locked page
+@@ -317,7 +352,9 @@ EXPORT_SYMBOL(wait_on_page_bit);
+  * Unlocks the page and wakes up sleepers in ___wait_on_page_locked().
+  * Also wakes sleepers in wait_on_page_writeback() because the wakeup
+  * mechananism between PageLocked pages and PageWriteback pages is shared.
+- * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep.
++ * But that's OK - sleepers in wait_on_page_writeback() just go back to sleep,
++ * or in case the wakeup notifies async wait queue entries, as in the case
++ * of aio, retries would be triggered and may re-queue their callbacks.
+  *
+  * The first mb is necessary to safely close the critical section opened by the
+  * TestSetPageLocked(), the second mb is necessary to enforce ordering between
+@@ -358,26 +395,51 @@ void end_page_writeback(struct page *pag
+ EXPORT_SYMBOL(end_page_writeback);
+ /*
+- * Get a lock on the page, assuming we need to sleep to get it.
++ * Get a lock on the page, assuming we need to either sleep to get it
++ * or to queue an async notification callback to try again when its
++ * available.
++ *
++ * A NULL wait queue parameter defaults to sync behaviour. Otherwise
++ * it specifies the wait queue entry to be used for async notification
++ * or waiting.
+  *
+  * Ugly: running sync_page() in state TASK_UNINTERRUPTIBLE is scary.  If some
+  * random driver's requestfn sets TASK_RUNNING, we could busywait.  However
+  * chances are that on the second loop, the block layer's plug list is empty,
+  * so sync_page() will then return in state TASK_UNINTERRUPTIBLE.
+  */
+-void __lock_page(struct page *page)
++int __lock_page_wq(struct page *page, wait_queue_t *wait)
+ {
+       wait_queue_head_t *wqh = page_waitqueue(page);
+-      DEFINE_WAIT(wait);
++      DEFINE_WAIT(local_wait);
++
++      if (!wait)
++              wait = &local_wait;
+       while (TestSetPageLocked(page)) {
+-              prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
++              prepare_to_wait(wqh, wait, TASK_UNINTERRUPTIBLE);
+               if (PageLocked(page)) {
+                       sync_page(page);
++                      if (!is_sync_wait(wait)) {
++                              /*
++                               * if we've queued an async wait queue
++                               * callback do not block; just tell the
++                               * caller to return and retry later when
++                               * the callback is notified
++                               */
++                              return -EIOCBRETRY;
++                      }
+                       io_schedule();
+               }
+       }
+-      finish_wait(wqh, &wait);
++      finish_wait(wqh, wait);
++      return 0;
++}
++EXPORT_SYMBOL(__lock_page_wq);
++
++void __lock_page(struct page *page)
++{
++      __lock_page_wq(page, NULL);
+ }
+ EXPORT_SYMBOL(__lock_page);
+@@ -432,8 +494,8 @@ EXPORT_SYMBOL(find_trylock_page);
+  *
+  * Returns zero if the page was not present. find_lock_page() may sleep.
+  */
+-struct page *find_lock_page(struct address_space *mapping,
+-                              unsigned long offset)
++struct page *find_lock_page_wq(struct address_space *mapping,
++                              unsigned long offset, wait_queue_t *wait)
+ {
+       struct page *page;
+@@ -444,7 +506,10 @@ repeat:
+               page_cache_get(page);
+               if (TestSetPageLocked(page)) {
+                       spin_unlock(&mapping->page_lock);
+-                      lock_page(page);
++                      if (-EIOCBRETRY == lock_page_wq(page, wait)) {
++                              page_cache_release(page);
++                              return ERR_PTR(-EIOCBRETRY);
++                      }
+                       spin_lock(&mapping->page_lock);
+                       /* Has the page been truncated while we slept? */
+@@ -461,6 +526,12 @@ repeat:
+ EXPORT_SYMBOL(find_lock_page);
++struct page *find_lock_page(struct address_space *mapping,
++                              unsigned long offset)
++{
++      return find_lock_page_wq(mapping, offset, NULL);
++}
++
+ /**
+  * find_or_create_page - locate or add a pagecache page
+  *
+@@ -521,9 +592,12 @@ EXPORT_SYMBOL(find_or_create_page);
+  * The search returns a group of mapping-contiguous pages with ascending
+  * indexes.  There may be holes in the indices due to not-present pages.
+  *
+- * find_get_pages() returns the number of pages which were found.
++ * find_get_pages() returns the number of pages which were found
++ * and also atomically sets the next offset to continue looking up
++ * mapping contiguous pages from (useful when doing a range of
++ * pagevec lookups in chunks of PAGEVEC_SIZE).
+  */
+-unsigned int find_get_pages(struct address_space *mapping, pgoff_t start,
++unsigned int find_get_pages(struct address_space *mapping, pgoff_t *next,
+                           unsigned int nr_pages, struct page **pages)
+ {
+       unsigned int i;
+@@ -531,9 +605,12 @@ unsigned int find_get_pages(struct addre
+       spin_lock(&mapping->page_lock);
+       ret = radix_tree_gang_lookup(&mapping->page_tree,
+-                              (void **)pages, start, nr_pages);
++                              (void **)pages, *next, nr_pages);
+       for (i = 0; i < ret; i++)
+               page_cache_get(pages[i]);
++      if (ret)
++              *next = pages[ret - 1]->index + 1;
++
+       spin_unlock(&mapping->page_lock);
+       return ret;
+ }
+@@ -587,21 +664,46 @@ void do_generic_mapping_read(struct addr
+                            read_actor_t actor)
+ {
+       struct inode *inode = mapping->host;
+-      unsigned long index, offset;
++      unsigned long index, offset, first, last, end_index;
++      loff_t isize = i_size_read(inode);
+       struct page *cached_page;
+       int error;
+       cached_page = NULL;
+-      index = *ppos >> PAGE_CACHE_SHIFT;
++      first = *ppos >> PAGE_CACHE_SHIFT;
+       offset = *ppos & ~PAGE_CACHE_MASK;
++      last = (*ppos + desc->count) >> PAGE_CACHE_SHIFT;
++      end_index = isize >> PAGE_CACHE_SHIFT;
++      if (last > end_index)
++              last = end_index;
++      /* Don't repeat the readahead if we are executing aio retries */
++      if (in_aio()) {
++              if (is_retried_kiocb(io_wait_to_kiocb(current->io_wait)))
++                      goto done_readahead;
++      }
++
++      /*
++       * Let the readahead logic know upfront about all
++       * the pages we'll need to satisfy this request
++       */
++      for (index = first; index < last; index++)
++              page_cache_readahead(mapping, ra, filp, index);
++
++      if (ra->next_size == -1UL) {
++              /* the readahead window was maximally shrunk */
++              /* explicitly readahead at least what is needed now */
++              for (index = first; index < last; index++)
++                      handle_ra_miss(mapping, ra, index);
++              do_page_cache_readahead(mapping, filp, first, last - first);
++      }
++
++done_readahead:
++      index = first;
+       for (;;) {
+               struct page *page;
+-              unsigned long end_index, nr, ret;
+-              loff_t isize = i_size_read(inode);
++              unsigned long nr, ret;
+-              end_index = isize >> PAGE_CACHE_SHIFT;
+-                      
+               if (index > end_index)
+                       break;
+               nr = PAGE_CACHE_SIZE;
+@@ -612,7 +714,6 @@ void do_generic_mapping_read(struct addr
+               }
+               cond_resched();
+-              page_cache_readahead(mapping, ra, filp, index);
+               nr = nr - offset;
+ find_page:
+@@ -662,7 +763,12 @@ page_not_up_to_date:
+                       goto page_ok;
+               /* Get exclusive access to the page ... */
+-              lock_page(page);
++
++              if (lock_page_wq(page, current->io_wait)) {
++                      pr_debug("queued lock page \n");
++                      error = -EIOCBRETRY;
++                      goto sync_error;
++              }
+               /* Did it get unhashed before we got the lock? */
+               if (!page->mapping) {
+@@ -684,13 +790,23 @@ readpage:
+               if (!error) {
+                       if (PageUptodate(page))
+                               goto page_ok;
+-                      wait_on_page_locked(page);
++                      if (wait_on_page_locked_wq(page, current->io_wait)) {
++                              pr_debug("queued wait_on_page \n");
++                              error = -EIOCBRETRY;
++                              goto sync_error;
++                      }
++
+                       if (PageUptodate(page))
+                               goto page_ok;
+                       error = -EIO;
+               }
+-              /* UHHUH! A synchronous read error occurred. Report it */
++sync_error:
++              /* We don't have uptodate data in the page yet */
++              /* Could be due to an error or because we need to
++               * retry when we get an async i/o notification.
++               * Report the reason.
++               */
+               desc->error = error;
+               page_cache_release(page);
+               break;
+@@ -804,7 +920,7 @@ __generic_file_aio_read(struct kiocb *io
+               struct address_space *mapping;
+               struct inode *inode;
+-              mapping = filp->f_dentry->d_inode->i_mapping;
++              mapping = filp->f_mapping;
+               inode = mapping->host;
+               retval = 0;
+               if (!count)
+@@ -844,22 +960,19 @@ __generic_file_aio_read(struct kiocb *io
+ out:
+       return retval;
+ }
+-
+ EXPORT_SYMBOL(__generic_file_aio_read);
+-ssize_t
+-generic_file_aio_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
++ssize_t generic_file_aio_read(struct kiocb *iocb, char __user *buf,
++                              size_t count, loff_t pos)
+ {
+       struct iovec local_iov = { .iov_base = buf, .iov_len = count };
+-      BUG_ON(iocb->ki_pos != pos);
+       return __generic_file_aio_read(iocb, &local_iov, 1, &iocb->ki_pos);
+ }
+-
+ EXPORT_SYMBOL(generic_file_aio_read);
+-ssize_t
+-generic_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
++ssize_t generic_file_read(struct file *filp, char __user *buf,
++                              size_t count, loff_t *ppos)
+ {
+       struct iovec local_iov = { .iov_base = buf, .iov_len = count };
+       struct kiocb kiocb;
+@@ -871,10 +984,10 @@ generic_file_read(struct file *filp, cha
+               ret = wait_on_sync_kiocb(&kiocb);
+       return ret;
+ }
+-
+ EXPORT_SYMBOL(generic_file_read);
+-int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
++int file_send_actor(read_descriptor_t * desc, struct page *page,
++                              unsigned long offset, unsigned long size)
+ {
+       ssize_t written;
+       unsigned long count = desc->count;
+@@ -936,7 +1049,7 @@ asmlinkage ssize_t sys_readahead(int fd,
+       file = fget(fd);
+       if (file) {
+               if (file->f_mode & FMODE_READ) {
+-                      struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++                      struct address_space *mapping = file->f_mapping;
+                       unsigned long start = offset >> PAGE_CACHE_SHIFT;
+                       unsigned long end = (offset + count - 1) >> PAGE_CACHE_SHIFT;
+                       unsigned long len = end - start + 1;
+@@ -955,7 +1068,7 @@ asmlinkage ssize_t sys_readahead(int fd,
+ static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
+ static int page_cache_read(struct file * file, unsigned long offset)
+ {
+-      struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++      struct address_space *mapping = file->f_mapping;
+       struct page *page; 
+       int error;
+@@ -990,16 +1103,16 @@ static int page_cache_read(struct file *
+  * it in the page cache, and handles the special cases reasonably without
+  * having a lot of duplicated code.
+  */
+-struct page * filemap_nopage(struct vm_area_struct * area, unsigned long address, int unused)
++struct page * filemap_nopage(struct vm_area_struct * area, unsigned long address, int *type)
+ {
+       int error;
+       struct file *file = area->vm_file;
+-      struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++      struct address_space *mapping = file->f_mapping;
+       struct file_ra_state *ra = &file->f_ra;
+       struct inode *inode = mapping->host;
+       struct page *page;
+       unsigned long size, pgoff, endoff;
+-      int did_readaround = 0;
++      int did_readaround = 0, majmin = VM_FAULT_MINOR;
+       pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;
+       endoff = ((area->vm_end - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;
+@@ -1048,6 +1161,14 @@ retry_find:
+               if (ra->mmap_miss > ra->mmap_hit + MMAP_LOTSAMISS)
+                       goto no_cached_page;
++              /*
++               * To keep the pgmajfault counter straight, we need to
++               * check did_readaround, as this is an inner loop.
++               */
++              if (!did_readaround) {
++                      majmin = VM_FAULT_MAJOR;
++                      inc_page_state(pgmajfault);
++              }
+               did_readaround = 1;
+               do_page_cache_readahead(mapping, file,
+                               pgoff & ~(MMAP_READAROUND-1), MMAP_READAROUND);
+@@ -1069,6 +1190,8 @@ success:
+        * Found the page and have a reference on it.
+        */
+       mark_page_accessed(page);
++      if (type)
++              *type = majmin;
+       return page;
+ outside_data_content:
+@@ -1104,7 +1227,10 @@ no_cached_page:
+       return NULL;
+ page_not_uptodate:
+-      inc_page_state(pgmajfault);
++      if (!did_readaround) {
++              majmin = VM_FAULT_MAJOR;
++              inc_page_state(pgmajfault);
++      }
+       lock_page(page);
+       /* Did it get unhashed while we waited for it? */
+@@ -1166,7 +1292,7 @@ EXPORT_SYMBOL(filemap_nopage);
+ static struct page * filemap_getpage(struct file *file, unsigned long pgoff,
+                                       int nonblock)
+ {
+-      struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++      struct address_space *mapping = file->f_mapping;
+       struct page *page;
+       int error;
+@@ -1278,7 +1404,7 @@ static int filemap_populate(struct vm_ar
+                       int nonblock)
+ {
+       struct file *file = vma->vm_file;
+-      struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++      struct address_space *mapping = file->f_mapping;
+       struct inode *inode = mapping->host;
+       unsigned long size;
+       struct mm_struct *mm = vma->vm_mm;
+@@ -1337,7 +1463,7 @@ static struct vm_operations_struct gener
+ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
+ {
+-      struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++      struct address_space *mapping = file->f_mapping;
+       struct inode *inode = mapping->host;
+       if (!mapping->a_ops->readpage)
+@@ -1460,7 +1586,9 @@ __grab_cache_page(struct address_space *
+       int err;
+       struct page *page;
+ repeat:
+-      page = find_lock_page(mapping, index);
++      page = find_lock_page_wq(mapping, index, current->io_wait);
++      if (IS_ERR(page))
++              return page;
+       if (!page) {
+               if (!*cached_page) {
+                       *cached_page = page_cache_alloc(mapping);
+@@ -1605,9 +1733,9 @@ filemap_set_next_iovec(const struct iove
+  * Returns appropriate error code that caller should return or
+  * zero in case that write should be allowed.
+  */
+-inline int generic_write_checks(struct inode *inode,
+-              struct file *file, loff_t *pos, size_t *count, int isblk)
++inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk)
+ {
++      struct inode *inode = file->f_mapping->host;
+       unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+         if (unlikely(*pos < 0))
+@@ -1669,7 +1797,7 @@ inline int generic_write_checks(struct i
+                       *count = inode->i_sb->s_maxbytes - *pos;
+       } else {
+               loff_t isize;
+-              if (bdev_read_only(inode->i_bdev))
++              if (bdev_read_only(I_BDEV(inode)))
+                       return -EPERM;
+               isize = i_size_read(inode);
+               if (*pos >= isize) {
+@@ -1687,6 +1815,7 @@ EXPORT_SYMBOL(generic_write_checks);
+ /*
+  * Write to a file through the page cache. 
++ * Called under i_sem for S_ISREG files.
+  *
+  * We put everything into the page cache prior to writing it. This is not a
+  * problem when writing full pages. With partial pages, however, we first have
+@@ -1695,11 +1824,11 @@ EXPORT_SYMBOL(generic_write_checks);
+  *                                                    okir@monad.swb.de
+  */
+ ssize_t
+-generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
++__generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
+                               unsigned long nr_segs, loff_t *ppos)
+ {
+       struct file *file = iocb->ki_filp;
+-      struct address_space * mapping = file->f_dentry->d_inode->i_mapping;
++      struct address_space * mapping = file->f_mapping;
+       struct address_space_operations *a_ops = mapping->a_ops;
+       size_t ocount;          /* original count */
+       size_t count;           /* after file limit checks */
+@@ -1746,11 +1875,10 @@ generic_file_aio_write_nolock(struct kio
+       current->backing_dev_info = mapping->backing_dev_info;
+       written = 0;
+-      err = generic_write_checks(inode, file, &pos, &count, isblk);
++      err = generic_write_checks(file, &pos, &count, isblk);
+       if (err)
+               goto out;
+-
+       if (count == 0)
+               goto out;
+@@ -1775,12 +1903,19 @@ generic_file_aio_write_nolock(struct kio
+               /*
+                * Sync the fs metadata but not the minor inode changes and
+                * of course not the data as we did direct DMA for the IO.
++               * i_sem is held, which protects generic_osync_inode() from
++               * livelocking.
+                */
+               if (written >= 0 && file->f_flags & O_SYNC)
+-                      status = generic_osync_inode(inode, OSYNC_METADATA);
++                      status = generic_osync_inode(inode, mapping, OSYNC_METADATA);
+               if (written >= 0 && !is_sync_kiocb(iocb))
+                       written = -EIOCBQUEUED;
+-              goto out_status;
++              if (written != -ENOTBLK)
++                      goto out_status;
++              /*
++               * direct-io write to a hole: fall through to buffered I/O
++               */
++              written = 0;
+       }
+       buf = iov->iov_base;
+@@ -1804,6 +1939,10 @@ generic_file_aio_write_nolock(struct kio
+               fault_in_pages_readable(buf, bytes);
+               page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
++              if (IS_ERR(page)) {
++                      status = PTR_ERR(page);
++                      break;
++              }
+               if (!page) {
+                       status = -ENOMEM;
+                       break;
+@@ -1852,7 +1991,11 @@ generic_file_aio_write_nolock(struct kio
+               page_cache_release(page);
+               if (status < 0)
+                       break;
+-              balance_dirty_pages_ratelimited(mapping);
++              status = balance_dirty_pages_ratelimited(mapping);
++              if (status < 0) {
++                      pr_debug("async balance_dirty_pages\n");
++                      break;
++              }
+               cond_resched();
+       } while (count);
+       *ppos = pos;
+@@ -1863,12 +2006,22 @@ generic_file_aio_write_nolock(struct kio
+       /*
+        * For now, when the user asks for O_SYNC, we'll actually give O_DSYNC
+        */
+-      if (status >= 0) {
+-              if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
+-                      status = generic_osync_inode(inode,
+-                                      OSYNC_METADATA|OSYNC_DATA);
+-      }
++      if (likely(status >= 0)) {
++              if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++                      if (!a_ops->writepage)
++                              status = generic_osync_inode(inode, mapping,
++                                              OSYNC_METADATA|OSYNC_DATA);
++              }
++      }
+       
++      /*
++       * If we get here for O_DIRECT writes then we must have fallen through
++       * to buffered writes (block instantiation inside i_size).  So we sync
++       * the file data here, to try to honour O_DIRECT expectations.
++       */
++      if (unlikely(file->f_flags & O_DIRECT) && written)
++              status = filemap_write_and_wait(mapping);
++
+ out_status:   
+       err = written ? written : status;
+ out:
+@@ -1880,6 +2033,55 @@ out:
+ EXPORT_SYMBOL(generic_file_aio_write_nolock);
+ ssize_t
++generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
++                              unsigned long nr_segs, loff_t *ppos)
++{
++      struct file *file = iocb->ki_filp;
++      struct address_space *mapping = file->f_mapping;
++      struct inode *inode = mapping->host;
++      ssize_t ret;
++      loff_t pos = *ppos;
++
++      if (!iov->iov_base && !is_sync_kiocb(iocb)) {
++              /* nothing to transfer, may just need to sync data */
++              ret = iov->iov_len; /* vector AIO not supported yet */
++              goto osync;
++      }
++
++      ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs, ppos);
++
++      /*
++       * Avoid doing a sync in parts for aio - its more efficient to
++       * call in again after all the data has been copied
++       */
++      if (!is_sync_kiocb(iocb))
++              return ret;
++
++osync:
++      if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++              ret = sync_page_range_nolock(inode, mapping, pos, ret);
++              if (ret >= 0)
++                      *ppos = pos + ret;
++      }
++      return ret;
++}
++
++
++ssize_t
++__generic_file_write_nolock(struct file *file, const struct iovec *iov,
++                              unsigned long nr_segs, loff_t *ppos)
++{
++      struct kiocb kiocb;
++      ssize_t ret;
++
++      init_sync_kiocb(&kiocb, file);
++      ret = __generic_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
++      if (-EIOCBQUEUED == ret)
++              ret = wait_on_sync_kiocb(&kiocb);
++      return ret;
++}
++
++ssize_t
+ generic_file_write_nolock(struct file *file, const struct iovec *iov,
+                               unsigned long nr_segs, loff_t *ppos)
+ {
+@@ -1899,36 +2101,62 @@ ssize_t generic_file_aio_write(struct ki
+                              size_t count, loff_t pos)
+ {
+       struct file *file = iocb->ki_filp;
+-      struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
+-      ssize_t err;
+-      struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
++      struct address_space *mapping = file->f_mapping;
++      struct inode *inode = mapping->host;
++      ssize_t ret;
++      struct iovec local_iov = { .iov_base = (void __user *)buf,
++                                      .iov_len = count };
+-      BUG_ON(iocb->ki_pos != pos);
++      if (!buf && !is_sync_kiocb(iocb)) {
++              /* nothing to transfer, may just need to sync data */
++              ret = count;
++              goto osync;
++      }
+       down(&inode->i_sem);
+-      err = generic_file_aio_write_nolock(iocb, &local_iov, 1, 
++      ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1,
+                                               &iocb->ki_pos);
+       up(&inode->i_sem);
+-      return err;
+-}
++      /*
++       * Avoid doing a sync in parts for aio - its more efficient to
++       * call in again after all the data has been copied
++       */
++      if (!is_sync_kiocb(iocb))
++              return ret;
++osync:
++      if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++              ret = sync_page_range(inode, mapping, pos, ret);
++              if (ret >= 0)
++                      iocb->ki_pos = pos + ret;
++      }
++      return ret;
++}
+ EXPORT_SYMBOL(generic_file_aio_write);
+ ssize_t generic_file_write(struct file *file, const char __user *buf,
+                          size_t count, loff_t *ppos)
+ {
+-      struct inode    *inode = file->f_dentry->d_inode->i_mapping->host;
+-      ssize_t         err;
+-      struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
++      struct address_space *mapping = file->f_mapping;
++      struct inode *inode = mapping->host;
++      ssize_t ret;
++      struct iovec local_iov = { .iov_base = (void __user *)buf,
++                                      .iov_len = count };
+       down(&inode->i_sem);
+-      err = generic_file_write_nolock(file, &local_iov, 1, ppos);
++      ret = __generic_file_write_nolock(file, &local_iov, 1, ppos);
+       up(&inode->i_sem);
+-      return err;
+-}
++      if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++              ssize_t err;
++              err = sync_page_range(inode, mapping, *ppos - ret, ret);
++              if (err < 0)
++                      ret = err;
++      }
++      return ret;
++}
+ EXPORT_SYMBOL(generic_file_write);
+ ssize_t generic_file_readv(struct file *filp, const struct iovec *iov,
+@@ -1947,39 +2175,46 @@ ssize_t generic_file_readv(struct file *
+ EXPORT_SYMBOL(generic_file_readv);
+ ssize_t generic_file_writev(struct file *file, const struct iovec *iov,
+-                      unsigned long nr_segs, loff_t * ppos) 
++                      unsigned long nr_segs, loff_t *ppos)
+ {
+-      struct inode *inode = file->f_dentry->d_inode;
++      struct address_space *mapping = file->f_mapping;
++      struct inode *inode = mapping->host;
+       ssize_t ret;
+       down(&inode->i_sem);
+-      ret = generic_file_write_nolock(file, iov, nr_segs, ppos);
++      ret = __generic_file_write_nolock(file, iov, nr_segs, ppos);
+       up(&inode->i_sem);
++
++      if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
++              ssize_t err;
++
++              err = sync_page_range(inode, mapping, *ppos - ret, ret);
++              if (err < 0)
++                      ret = err;
++      }
+       return ret;
+ }
+ EXPORT_SYMBOL(generic_file_writev);
++/*
++ * Called under i_sem for writes to S_ISREG files
++ */
+ ssize_t
+ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
+       loff_t offset, unsigned long nr_segs)
+ {
+       struct file *file = iocb->ki_filp;
+-      struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
++      struct address_space *mapping = file->f_mapping;
+       ssize_t retval;
+-      if (mapping->nrpages) {
+-              retval = filemap_fdatawrite(mapping);
+-              if (retval == 0)
+-                      retval = filemap_fdatawait(mapping);
+-              if (retval)
+-                      goto out;
++      retval = filemap_write_and_wait(mapping);
++      if (retval == 0) {
++              retval = mapping->a_ops->direct_IO(rw, iocb, iov,
++                                              offset, nr_segs);
++              if (rw == WRITE && mapping->nrpages)
++                      invalidate_inode_pages2(mapping);
+       }
+-
+-      retval = mapping->a_ops->direct_IO(rw, iocb, iov, offset, nr_segs);
+-      if (rw == WRITE && mapping->nrpages)
+-              invalidate_inode_pages2(mapping);
+-out:
+       return retval;
+ }
+--- linux-2.6.0/mm/highmem.c   2003-10-08 15:07:10.000000000 -0700
++++ 25/mm/highmem.c    2003-12-28 23:22:14.000000000 -0800
+@@ -285,7 +285,7 @@ static void copy_to_high_bio_irq(struct 
+       struct bio_vec *tovec, *fromvec;
+       int i;
+-      __bio_for_each_segment(tovec, to, i, 0) {
++      bio_for_each_segment(tovec, to, i) {
+               fromvec = from->bi_io_vec + i;
+               /*
+@@ -314,7 +314,7 @@ static void bounce_end_io(struct bio *bi
+       /*
+        * free up bounce indirect pages used
+        */
+-      __bio_for_each_segment(bvec, bio, i, 0) {
++      bio_for_each_segment(bvec, bio, i) {
+               org_vec = bio_orig->bi_io_vec + i;
+               if (bvec->bv_page == org_vec->bv_page)
+                       continue;
+@@ -437,7 +437,7 @@ static void __blk_queue_bounce(request_q
+       bio->bi_rw = (*bio_orig)->bi_rw;
+       bio->bi_vcnt = (*bio_orig)->bi_vcnt;
+-      bio->bi_idx = 0;
++      bio->bi_idx = (*bio_orig)->bi_idx;
+       bio->bi_size = (*bio_orig)->bi_size;
+       if (pool == page_pool) {
+--- linux-2.6.0/mm/madvise.c   2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/madvise.c    2003-12-28 23:21:19.000000000 -0800
+@@ -65,7 +65,7 @@ static long madvise_willneed(struct vm_a
+               end = vma->vm_end;
+       end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+-      force_page_cache_readahead(file->f_dentry->d_inode->i_mapping,
++      force_page_cache_readahead(file->f_mapping,
+                       file, start, max_sane_readahead(end - start));
+       return 0;
+ }
+--- linux-2.6.0/mm/Makefile    2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/Makefile     2003-12-28 23:26:36.000000000 -0800
+@@ -12,3 +12,6 @@ obj-y                        := bootmem.o filemap.o mempool.o
+                          slab.o swap.o truncate.o vmscan.o $(mmu-y)
+ obj-$(CONFIG_SWAP)    += page_io.o swap_state.o swapfile.o
++
++obj-$(CONFIG_X86_4G) += usercopy.o
++
+--- linux-2.6.0/mm/memory.c    2003-11-23 19:03:02.000000000 -0800
++++ 25/mm/memory.c     2003-12-28 23:26:36.000000000 -0800
+@@ -107,7 +107,8 @@ static inline void free_one_pmd(struct m
+       pte_free_tlb(tlb, page);
+ }
+-static inline void free_one_pgd(struct mmu_gather *tlb, pgd_t * dir)
++static inline void free_one_pgd(struct mmu_gather *tlb, pgd_t * dir,
++                                                      int pgd_idx)
+ {
+       int j;
+       pmd_t * pmd;
+@@ -121,8 +122,11 @@ static inline void free_one_pgd(struct m
+       }
+       pmd = pmd_offset(dir, 0);
+       pgd_clear(dir);
+-      for (j = 0; j < PTRS_PER_PMD ; j++)
++      for (j = 0; j < PTRS_PER_PMD ; j++) {
++              if (pgd_idx * PGDIR_SIZE + j * PMD_SIZE >= TASK_SIZE)
++                      break;
+               free_one_pmd(tlb, pmd+j);
++      }
+       pmd_free_tlb(tlb, pmd);
+ }
+@@ -135,11 +139,13 @@ static inline void free_one_pgd(struct m
+ void clear_page_tables(struct mmu_gather *tlb, unsigned long first, int nr)
+ {
+       pgd_t * page_dir = tlb->mm->pgd;
++      int pgd_idx = first;
+       page_dir += first;
+       do {
+-              free_one_pgd(tlb, page_dir);
++              free_one_pgd(tlb, page_dir, pgd_idx);
+               page_dir++;
++              pgd_idx++;
+       } while (--nr);
+ }
+@@ -437,7 +443,7 @@ zap_pmd_range(struct mmu_gather *tlb, pg
+               unsigned long address, unsigned long size)
+ {
+       pmd_t * pmd;
+-      unsigned long end;
++      unsigned long end, pgd_boundary;
+       if (pgd_none(*dir))
+               return;
+@@ -448,8 +454,9 @@ zap_pmd_range(struct mmu_gather *tlb, pg
+       }
+       pmd = pmd_offset(dir, address);
+       end = address + size;
+-      if (end > ((address + PGDIR_SIZE) & PGDIR_MASK))
+-              end = ((address + PGDIR_SIZE) & PGDIR_MASK);
++      pgd_boundary = ((address + PGDIR_SIZE) & PGDIR_MASK);
++      if (pgd_boundary && (end > pgd_boundary))
++              end = pgd_boundary;
+       do {
+               zap_pte_range(tlb, pmd, address, end - address);
+               address = (address + PMD_SIZE) & PMD_MASK; 
+@@ -603,6 +610,11 @@ void zap_page_range(struct vm_area_struc
+       might_sleep();
+       if (is_vm_hugetlb_page(vma)) {
++              static int x;
++              if (x < 10) {
++                      x++;
++                      dump_stack();
++              }
+               zap_hugepage_range(vma, address, size);
+               return;
+       }
+@@ -685,6 +697,7 @@ int get_user_pages(struct task_struct *t
+               struct page **pages, struct vm_area_struct **vmas)
+ {
+       int i;
++      int vm_io;
+       unsigned int flags;
+       /* 
+@@ -741,8 +754,10 @@ int get_user_pages(struct task_struct *t
+               }
+ #endif
+-              if (!vma || (pages && (vma->vm_flags & VM_IO))
+-                              || !(flags & vma->vm_flags))
++              if (!vma)
++                      return i ? : -EFAULT;
++              vm_io = vma->vm_flags & VM_IO;
++              if ((pages && vm_io) || !(flags & vma->vm_flags))
+                       return i ? : -EFAULT;
+               if (is_vm_hugetlb_page(vma)) {
+@@ -750,9 +765,17 @@ int get_user_pages(struct task_struct *t
+                                               &start, &len, i);
+                       continue;
+               }
++
+               spin_lock(&mm->page_table_lock);
+               do {
+-                      struct page *map;
++                      struct page *map = NULL;
++
++                      /*
++                       * We don't follow pagetables for VM_IO regions - they
++                       * may have no pageframes.
++                       */
++                      if (vm_io)
++                              goto no_follow;
+                       while (!(map = follow_page(mm, start, write))) {
+                               spin_unlock(&mm->page_table_lock);
+                               switch (handle_mm_fault(mm,vma,start,write)) {
+@@ -784,6 +807,7 @@ int get_user_pages(struct task_struct *t
+                               if (!PageReserved(pages[i]))
+                                       page_cache_get(pages[i]);
+                       }
++no_follow:
+                       if (vmas)
+                               vmas[i] = vma;
+                       i++;
+@@ -1147,7 +1171,7 @@ void invalidate_mmap_range(struct addres
+               invalidate_mmap_range_list(&mapping->i_mmap_shared, hba, hlen);
+       up(&mapping->i_shared_sem);
+ }
+-EXPORT_SYMBOL_GPL(invalidate_mmap_range);
++EXPORT_SYMBOL(invalidate_mmap_range);
+ /*
+  * Handle all mappings that got truncated by a "truncate()"
+@@ -1400,7 +1424,7 @@ do_no_page(struct mm_struct *mm, struct 
+       pte_t entry;
+       struct pte_chain *pte_chain;
+       int sequence = 0;
+-      int ret;
++      int ret = VM_FAULT_MINOR;
+       if (!vma->vm_ops || !vma->vm_ops->nopage)
+               return do_anonymous_page(mm, vma, page_table,
+@@ -1409,12 +1433,12 @@ do_no_page(struct mm_struct *mm, struct 
+       spin_unlock(&mm->page_table_lock);
+       if (vma->vm_file) {
+-              mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
++              mapping = vma->vm_file->f_mapping;
+               sequence = atomic_read(&mapping->truncate_count);
+       }
+       smp_rmb();  /* Prevent CPU from reordering lock-free ->nopage() */
+ retry:
+-      new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0);
++      new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret);
+       /* no page was available -- either SIGBUS or OOM */
+       if (new_page == NOPAGE_SIGBUS)
+@@ -1483,14 +1507,12 @@ retry:
+               pte_unmap(page_table);
+               page_cache_release(new_page);
+               spin_unlock(&mm->page_table_lock);
+-              ret = VM_FAULT_MINOR;
+               goto out;
+       }
+       /* no need to invalidate: a not-present page shouldn't be cached */
+       update_mmu_cache(vma, address, entry);
+       spin_unlock(&mm->page_table_lock);
+-      ret = VM_FAULT_MAJOR;
+       goto out;
+ oom:
+       ret = VM_FAULT_OOM;
+--- linux-2.6.0/mm/mincore.c   2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/mincore.c    2003-12-28 23:21:19.000000000 -0800
+@@ -26,7 +26,7 @@ static unsigned char mincore_page(struct
+       unsigned long pgoff)
+ {
+       unsigned char present = 0;
+-      struct address_space * as = vma->vm_file->f_dentry->d_inode->i_mapping;
++      struct address_space * as = vma->vm_file->f_mapping;
+       struct page * page;
+       page = find_get_page(as, pgoff);
+--- linux-2.6.0/mm/mmap.c      2003-12-17 21:20:03.000000000 -0800
++++ 25/mm/mmap.c       2003-12-28 23:22:58.000000000 -0800
+@@ -80,11 +80,10 @@ static void remove_shared_vm_struct(stru
+       struct file *file = vma->vm_file;
+       if (file) {
+-              struct inode *inode = file->f_dentry->d_inode;
+-
+-              down(&inode->i_mapping->i_shared_sem);
+-              __remove_shared_vm_struct(vma, inode);
+-              up(&inode->i_mapping->i_shared_sem);
++              struct address_space *mapping = file->f_mapping;
++              down(&mapping->i_shared_sem);
++              __remove_shared_vm_struct(vma, file->f_dentry->d_inode);
++              up(&mapping->i_shared_sem);
+       }
+ }
+@@ -235,11 +234,10 @@ static inline void __vma_link_file(struc
+       file = vma->vm_file;
+       if (file) {
+-              struct inode * inode = file->f_dentry->d_inode;
+-              struct address_space *mapping = inode->i_mapping;
++              struct address_space *mapping = file->f_mapping;
+               if (vma->vm_flags & VM_DENYWRITE)
+-                      atomic_dec(&inode->i_writecount);
++                      atomic_dec(&file->f_dentry->d_inode->i_writecount);
+               if (vma->vm_flags & VM_SHARED)
+                       list_add_tail(&vma->shared, &mapping->i_mmap_shared);
+@@ -265,7 +263,7 @@ static void vma_link(struct mm_struct *m
+       struct address_space *mapping = NULL;
+       if (vma->vm_file)
+-              mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
++              mapping = vma->vm_file->f_mapping;
+       if (mapping)
+               down(&mapping->i_shared_sem);
+@@ -383,7 +381,7 @@ static int vma_merge(struct mm_struct *m
+       if (vm_flags & VM_SPECIAL)
+               return 0;
+-      i_shared_sem = file ? &inode->i_mapping->i_shared_sem : NULL;
++      i_shared_sem = file ? &file->f_mapping->i_shared_sem : NULL;
+       if (!prev) {
+               prev = rb_entry(rb_parent, struct vm_area_struct, vm_rb);
+@@ -1138,7 +1136,11 @@ static void unmap_region(struct mm_struc
+       tlb = tlb_gather_mmu(mm, 0);
+       unmap_vmas(&tlb, mm, vma, start, end, &nr_accounted);
+       vm_unacct_memory(nr_accounted);
+-      free_pgtables(tlb, prev, start, end);
++
++      if (is_hugepage_only_range(start, end - start))
++              hugetlb_free_pgtables(tlb, prev, start, end);
++      else
++              free_pgtables(tlb, prev, start, end);
+       tlb_finish_mmu(tlb, start, end);
+ }
+@@ -1203,7 +1205,7 @@ int split_vma(struct mm_struct * mm, str
+               new->vm_ops->open(new);
+       if (vma->vm_file)
+-               mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
++               mapping = vma->vm_file->f_mapping;
+       if (mapping)
+               down(&mapping->i_shared_sem);
+--- linux-2.6.0/mm/msync.c     2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/msync.c      2003-12-28 23:21:20.000000000 -0800
+@@ -146,20 +146,20 @@ static int msync_interval(struct vm_area
+               ret = filemap_sync(vma, start, end-start, flags);
+               if (!ret && (flags & MS_SYNC)) {
+-                      struct inode *inode = file->f_dentry->d_inode;
++                      struct address_space *mapping = file->f_mapping;
+                       int err;
+-                      down(&inode->i_sem);
+-                      ret = filemap_fdatawrite(inode->i_mapping);
++                      down(&mapping->host->i_sem);
++                      ret = filemap_fdatawrite(mapping);
+                       if (file->f_op && file->f_op->fsync) {
+                               err = file->f_op->fsync(file,file->f_dentry,1);
+                               if (err && !ret)
+                                       ret = err;
+                       }
+-                      err = filemap_fdatawait(inode->i_mapping);
++                      err = filemap_fdatawait(mapping);
+                       if (!ret)
+                               ret = err;
+-                      up(&inode->i_sem);
++                      up(&mapping->host->i_sem);
+               }
+       }
+       return ret;
+--- linux-2.6.0/mm/oom_kill.c  2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/oom_kill.c   2003-12-28 23:21:48.000000000 -0800
+@@ -24,20 +24,6 @@
+ /* #define DEBUG */
+ /**
+- * int_sqrt - oom_kill.c internal function, rough approximation to sqrt
+- * @x: integer of which to calculate the sqrt
+- * 
+- * A very rough approximation to the sqrt() function.
+- */
+-static unsigned int int_sqrt(unsigned int x)
+-{
+-      unsigned int out = x;
+-      while (x & ~(unsigned int)1) x >>=2, out >>=1;
+-      if (x) out -= out >> 2;
+-      return (out ? out : 1);
+-}     
+-
+-/**
+  * oom_badness - calculate a numeric value for how bad this task has been
+  * @p: task struct of which task we should calculate
+  *
+@@ -57,7 +43,7 @@ static unsigned int int_sqrt(unsigned in
+ static int badness(struct task_struct *p)
+ {
+-      int points, cpu_time, run_time;
++      int points, cpu_time, run_time, s;
+       if (!p->mm)
+               return 0;
+@@ -77,8 +63,12 @@ static int badness(struct task_struct *p
+       cpu_time = (p->utime + p->stime) >> (SHIFT_HZ + 3);
+       run_time = (get_jiffies_64() - p->start_time) >> (SHIFT_HZ + 10);
+-      points /= int_sqrt(cpu_time);
+-      points /= int_sqrt(int_sqrt(run_time));
++      s = int_sqrt(cpu_time);
++      if (s)
++              points /= s;
++      s = int_sqrt(int_sqrt(run_time));
++      if (s)
++              points /= s;
+       /*
+        * Niced processes are most likely less important, so double
+--- linux-2.6.0/mm/page_alloc.c        2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/page_alloc.c 2003-12-28 23:22:46.000000000 -0800
+@@ -267,9 +267,11 @@ free_pages_bulk(struct zone *zone, int c
+ void __free_pages_ok(struct page *page, unsigned int order)
+ {
+       LIST_HEAD(list);
++      int i;
+       mod_page_state(pgfree, 1 << order);
+-      free_pages_check(__FUNCTION__, page);
++      for (i = 0 ; i < (1 << order) ; ++i)
++              free_pages_check(__FUNCTION__, page + i);
+       list_add(&page->list, &list);
+       kernel_map_pages(page, 1<<order, 0);
+       free_pages_bulk(page_zone(page), 1, &list, order);
+@@ -537,7 +539,7 @@ __alloc_pages(unsigned int gfp_mask, uns
+ {
+       const int wait = gfp_mask & __GFP_WAIT;
+       unsigned long min;
+-      struct zone **zones, *classzone;
++      struct zone **zones;
+       struct page *page;
+       struct reclaim_state reclaim_state;
+       struct task_struct *p = current;
+@@ -552,8 +554,7 @@ __alloc_pages(unsigned int gfp_mask, uns
+               cold = 1;
+       zones = zonelist->zones;  /* the list of zones suitable for gfp_mask */
+-      classzone = zones[0]; 
+-      if (classzone == NULL)    /* no zones in the zonelist */
++      if (zones[0] == NULL)     /* no zones in the zonelist */
+               return NULL;
+       /* Go through the zonelist once, looking for a zone with enough free */
+@@ -628,7 +629,7 @@ rebalance:
+       reclaim_state.reclaimed_slab = 0;
+       p->reclaim_state = &reclaim_state;
+-      try_to_free_pages(classzone, gfp_mask, order);
++      try_to_free_pages(zones, gfp_mask, order);
+       p->reclaim_state = NULL;
+       p->flags &= ~PF_MEMALLOC;
+@@ -672,6 +673,7 @@ nopage:
+               printk("%s: page allocation failure."
+                       " order:%d, mode:0x%x\n",
+                       p->comm, order, gfp_mask);
++              dump_stack();
+       }
+       return NULL;
+ got_pg:
+@@ -1589,7 +1591,7 @@ void __init page_alloc_init(void)
+  *    that the pages_{min,low,high} values for each zone are set correctly 
+  *    with respect to min_free_kbytes.
+  */
+-void setup_per_zone_pages_min(void)
++static void setup_per_zone_pages_min(void)
+ {
+       unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
+       unsigned long lowmem_pages = 0;
+@@ -1633,6 +1635,45 @@ void setup_per_zone_pages_min(void)
+ }
+ /*
++ * Initialise min_free_kbytes.
++ *
++ * For small machines we want it small (128k min).  For large machines
++ * we want it large (16MB max).  But it is not linear, because network
++ * bandwidth does not increase linearly with machine size.  We use
++ *
++ *    min_free_kbytes = sqrt(lowmem_kbytes)
++ *
++ * which yields
++ *
++ * 16MB:      128k
++ * 32MB:      181k
++ * 64MB:      256k
++ * 128MB:     362k
++ * 256MB:     512k
++ * 512MB:     724k
++ * 1024MB:    1024k
++ * 2048MB:    1448k
++ * 4096MB:    2048k
++ * 8192MB:    2896k
++ * 16384MB:   4096k
++ */
++static int __init init_per_zone_pages_min(void)
++{
++      unsigned long lowmem_kbytes;
++
++      lowmem_kbytes = nr_free_buffer_pages() * (PAGE_SIZE >> 10);
++
++      min_free_kbytes = int_sqrt(lowmem_kbytes);
++      if (min_free_kbytes < 128)
++              min_free_kbytes = 128;
++      if (min_free_kbytes > 16384)
++              min_free_kbytes = 16384;
++      setup_per_zone_pages_min();
++      return 0;
++}
++module_init(init_per_zone_pages_min)
++
++/*
+  * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so 
+  *    that we can call setup_per_zone_pages_min() whenever min_free_kbytes 
+  *    changes.
+--- linux-2.6.0/mm/page-writeback.c    2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/page-writeback.c     2003-12-28 23:26:44.000000000 -0800
+@@ -28,6 +28,7 @@
+ #include <linux/smp.h>
+ #include <linux/sysctl.h>
+ #include <linux/cpu.h>
++#include <linux/pagevec.h>
+ /*
+  * The maximum number of pages to writeout in a single bdflush/kupdate
+@@ -146,7 +147,7 @@ get_dirty_limits(struct page_state *ps, 
+  * If we're over `background_thresh' then pdflush is woken to perform some
+  * writeout.
+  */
+-static void balance_dirty_pages(struct address_space *mapping)
++static int balance_dirty_pages(struct address_space *mapping)
+ {
+       struct page_state ps;
+       long nr_reclaimable;
+@@ -163,6 +164,7 @@ static void balance_dirty_pages(struct a
+                       .sync_mode      = WB_SYNC_NONE,
+                       .older_than_this = NULL,
+                       .nr_to_write    = write_chunk,
++                      .nonblocking    = !is_sync_wait(current->io_wait)
+               };
+               get_dirty_limits(&ps, &background_thresh, &dirty_thresh);
+@@ -189,7 +191,11 @@ static void balance_dirty_pages(struct a
+                       if (pages_written >= write_chunk)
+                               break;          /* We've done our duty */
+               }
+-              blk_congestion_wait(WRITE, HZ/10);
++              if (-EIOCBRETRY == blk_congestion_wait_wq(WRITE, HZ/10,
++                      current->io_wait)) {
++                      pr_debug("async blk congestion wait\n");
++                      return -EIOCBRETRY;
++              }
+       }
+       if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
+@@ -197,6 +203,8 @@ static void balance_dirty_pages(struct a
+       if (!writeback_in_progress(bdi) && nr_reclaimable > background_thresh)
+               pdflush_operation(background_writeout, 0);
++
++      return 0;
+ }
+ /**
+@@ -212,7 +220,7 @@ static void balance_dirty_pages(struct a
+  * decrease the ratelimiting by a lot, to prevent individual processes from
+  * overshooting the limit by (ratelimit_pages) each.
+  */
+-void balance_dirty_pages_ratelimited(struct address_space *mapping)
++int balance_dirty_pages_ratelimited(struct address_space *mapping)
+ {
+       static DEFINE_PER_CPU(int, ratelimits) = 0;
+       long ratelimit;
+@@ -228,10 +236,10 @@ void balance_dirty_pages_ratelimited(str
+       if (get_cpu_var(ratelimits)++ >= ratelimit) {
+               __get_cpu_var(ratelimits) = 0;
+               put_cpu_var(ratelimits);
+-              balance_dirty_pages(mapping);
+-              return;
++              return balance_dirty_pages(mapping);
+       }
+       put_cpu_var(ratelimits);
++      return 0;
+ }
+ /*
+@@ -567,3 +575,152 @@ int test_clear_page_dirty(struct page *p
+       return 0;
+ }
+ EXPORT_SYMBOL(test_clear_page_dirty);
++
++
++static ssize_t operate_on_page_range(struct address_space *mapping,
++              loff_t pos, size_t count, int (*operator)(struct page *))
++{
++      pgoff_t first = pos >> PAGE_CACHE_SHIFT;
++      pgoff_t last = (pos + count - 1) >> PAGE_CACHE_SHIFT;   /* inclusive */
++      pgoff_t next = first, curr = first;
++      struct pagevec pvec;
++      ssize_t ret = 0, bytes = 0;
++      int i, nr;
++
++      if (count == 0)
++              return 0;
++
++      pagevec_init(&pvec, 0);
++      while ((nr = pagevec_lookup(&pvec, mapping, &next,
++                              min((pgoff_t)PAGEVEC_SIZE, last - next + 1)))) {
++              for (i = 0; i < pagevec_count(&pvec); i++) {
++                      struct page *page = pvec.pages[i];
++
++                      curr = page->index;
++                      if (page->mapping != mapping) /* truncated ?*/ {
++                              curr = next;
++                              break;
++                      } else {
++                              ret = (*operator)(page);
++                              if (ret == -EIOCBRETRY)
++                                      break;
++                              if (PageError(page)) {
++                                      if (!ret)
++                                              ret = -EIO;
++                              } else
++                                      curr++;
++                      }
++              }
++              pagevec_release(&pvec);
++              if ((ret == -EIOCBRETRY) || (next > last))
++                      break;
++      }
++      if (!nr)
++              curr = last + 1;
++
++      bytes = (curr << PAGE_CACHE_SHIFT) - pos;
++      if (bytes > count)
++              bytes = count;
++      return (bytes && (!ret || (ret == -EIOCBRETRY))) ? bytes : ret;
++}
++
++static int page_waiter(struct page *page)
++{
++      return wait_on_page_writeback_wq(page, current->io_wait);
++}
++
++static size_t
++wait_on_page_range(struct address_space *mapping, loff_t pos, size_t count)
++{
++      return operate_on_page_range(mapping, pos, count, page_waiter);
++}
++
++static int page_writer(struct page *page)
++{
++      struct writeback_control wbc = {
++              .sync_mode      = WB_SYNC_ALL,
++              .nr_to_write    = 1,
++      };
++
++      lock_page(page);
++      if (!page->mapping) {   /* truncated */
++              unlock_page(page);
++              return 0;
++      }
++      if (!test_clear_page_dirty(page)) {
++              unlock_page(page);
++              return 0;
++      }
++      wait_on_page_writeback(page);
++      return page->mapping->a_ops->writepage(page, &wbc);
++}
++
++static ssize_t
++write_out_page_range(struct address_space *mapping, loff_t pos, size_t count)
++{
++      return operate_on_page_range(mapping, pos, count, page_writer);
++}
++
++/*
++ * Write and wait upon all the pages in the passed range.  This is a "data
++ * integrity" operation.  It waits upon in-flight writeout before starting and
++ * waiting upon new writeout.  If there was an IO error, return it.
++ *
++ * We need to re-take i_sem during the generic_osync_inode list walk because
++ * it is otherwise livelockable.
++ */
++ssize_t sync_page_range(struct inode *inode, struct address_space *mapping,
++                      loff_t pos, size_t count)
++{
++      int ret = 0;
++
++      if (in_aio()) {
++              /* Already issued writeouts for this iocb ? */
++              if (kiocbTrySync(io_wait_to_kiocb(current->io_wait)))
++                      goto do_wait; /* just need to check if done */
++      }
++      if (!mapping->a_ops->writepage)
++              return 0;
++      if (mapping->backing_dev_info->memory_backed)
++              return 0;
++      ret = write_out_page_range(mapping, pos, count);
++      if (ret >= 0) {
++              down(&inode->i_sem);
++              ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);
++              up(&inode->i_sem);
++      }
++do_wait:
++      if (ret >= 0)
++              ret = wait_on_page_range(mapping, pos, count);
++      return ret;
++}
++
++/*
++ * It is really better to use sync_page_range, rather than call
++ * sync_page_range_nolock while holding i_sem, if you don't
++ * want to block parallel O_SYNC writes until the pages in this
++ * range are written out.
++ */
++ssize_t sync_page_range_nolock(struct inode *inode, struct address_space
++      *mapping, loff_t pos, size_t count)
++{
++      ssize_t ret = 0;
++
++      if (in_aio()) {
++              /* Already issued writeouts for this iocb ? */
++              if (kiocbTrySync(io_wait_to_kiocb(current->io_wait)))
++                      goto do_wait; /* just need to check if done */
++      }
++      if (!mapping->a_ops->writepage)
++              return 0;
++      if (mapping->backing_dev_info->memory_backed)
++              return 0;
++      ret = write_out_page_range(mapping, pos, count);
++      if (ret >= 0) {
++              ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);
++      }
++do_wait:
++      if (ret >= 0)
++              ret = wait_on_page_range(mapping, pos, count);
++      return ret;
++}
+--- linux-2.6.0/mm/pdflush.c   2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/pdflush.c    2003-12-28 23:21:42.000000000 -0800
+@@ -84,6 +84,8 @@ struct pdflush_work {
+       unsigned long when_i_went_to_sleep;
+ };
++static int wakeup_count = 100;
++
+ static int __pdflush(struct pdflush_work *my_work)
+ {
+       daemonize("pdflush");
+@@ -112,7 +114,10 @@ static int __pdflush(struct pdflush_work
+               spin_lock_irq(&pdflush_lock);
+               if (!list_empty(&my_work->list)) {
+-                      printk("pdflush: bogus wakeup!\n");
++                      if (wakeup_count > 0) {
++                              wakeup_count--;
++                              printk("pdflush: bogus wakeup!\n");
++                      }
+                       my_work->fn = NULL;
+                       continue;
+               }
+@@ -182,6 +187,7 @@ int pdflush_operation(void (*fn)(unsigne
+ {
+       unsigned long flags;
+       int ret = 0;
++      static int poke_count = 0;
+       if (fn == NULL)
+               BUG();          /* Hard to diagnose if it's deferred */
+@@ -190,9 +196,19 @@ int pdflush_operation(void (*fn)(unsigne
+       if (list_empty(&pdflush_list)) {
+               spin_unlock_irqrestore(&pdflush_lock, flags);
+               ret = -1;
++              if (wakeup_count < 100 && poke_count < 10) {
++                      printk("%s: no threads\n", __FUNCTION__);
++                      dump_stack();
++                      poke_count++;
++              }
+       } else {
+               struct pdflush_work *pdf;
++              if (wakeup_count < 100 && poke_count < 10) {
++                      printk("%s: found a thread\n", __FUNCTION__);
++                      dump_stack();
++                      poke_count++;
++              }
+               pdf = list_entry(pdflush_list.next, struct pdflush_work, list);
+               list_del_init(&pdf->list);
+               if (list_empty(&pdflush_list))
+--- linux-2.6.0/mm/readahead.c 2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/readahead.c  2003-12-28 23:26:38.000000000 -0800
+@@ -347,6 +347,8 @@ page_cache_readahead(struct address_spac
+       unsigned min;
+       unsigned orig_next_size;
+       unsigned actual;
++      int first_access=0;
++      unsigned long preoffset=0;
+       /*
+        * Here we detect the case where the application is performing
+@@ -370,16 +372,18 @@ page_cache_readahead(struct address_spac
+       min = get_min_readahead(ra);
+       orig_next_size = ra->next_size;
+-      if (ra->next_size == 0 && offset == 0) {
++      if (ra->next_size == 0) {
+               /*
+-               * Special case - first read from first page.
++               * Special case - first read.
+                * We'll assume it's a whole-file read, and
+                * grow the window fast.
+                */
++              first_access=1;
+               ra->next_size = max / 2;
+               goto do_io;
+       }
++      preoffset = ra->prev_page;
+       ra->prev_page = offset;
+       if (offset >= ra->start && offset <= (ra->start + ra->size)) {
+@@ -439,20 +443,44 @@ do_io:
+                * ahead window and get some I/O underway for the new
+                * current window.
+                */
++              if (!first_access && preoffset >= ra->start &&
++                              preoffset < (ra->start + ra->size)) {
++                       /* Heuristic:  If 'n' pages were
++                        * accessed in the current window, there
++                        * is a high probability that around 'n' pages
++                        * shall be used in the next current window.
++                        *
++                        * To minimize lazy-readahead triggered
++                        * in the next current window, read in
++                        * an extra page.
++                        */
++                      ra->next_size = preoffset - ra->start + 2;
++              }
+               ra->start = offset;
+               ra->size = ra->next_size;
+               ra->ahead_start = 0;            /* Invalidate these */
+               ra->ahead_size = 0;
+               actual = do_page_cache_readahead(mapping, filp, offset,
+                                                ra->size);
+-              check_ra_success(ra, ra->size, actual, orig_next_size);
++              if(!first_access) {
++                      /*
++                       * do not adjust the readahead window size the first
++                       * time, the ahead window might get closed if all
++                       * the pages are already in the cache.
++                       */
++                      check_ra_success(ra, ra->size, actual, orig_next_size);
++              }
+       } else {
+               /*
+                * This read request is within the current window.  It is time
+                * to submit I/O for the ahead window while the application is
+-               * crunching through the current window.
++               * about to step into the ahead window.
++               * Heuristic: Defer reading the ahead window till we hit
++               * the last page in the current window. (lazy readahead)
++               * If we read in earlier we run the risk of wasting
++               * the ahead window.
+                */
+-              if (ra->ahead_start == 0) {
++              if (ra->ahead_start == 0 && offset == (ra->start + ra->size -1)) {
+                       ra->ahead_start = ra->start + ra->size;
+                       ra->ahead_size = ra->next_size;
+                       actual = do_page_cache_readahead(mapping, filp,
+@@ -488,7 +516,7 @@ void handle_ra_miss(struct address_space
+               const unsigned long max = get_max_readahead(ra);
+               if (offset != ra->prev_page + 1) {
+-                      ra->size = 0;                   /* Not sequential */
++                      ra->size = ra->size?ra->size-1:0; /* Not sequential */
+               } else {
+                       ra->size++;                     /* A sequential read */
+                       if (ra->size >= max) {          /* Resume readahead */
+--- linux-2.6.0/mm/shmem.c     2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/shmem.c      2003-12-28 23:22:12.000000000 -0800
+@@ -71,7 +71,7 @@ enum sgp_type {
+ };
+ static int shmem_getpage(struct inode *inode, unsigned long idx,
+-                       struct page **pagep, enum sgp_type sgp);
++                       struct page **pagep, enum sgp_type sgp, int *type);
+ static inline struct page *shmem_dir_alloc(unsigned int gfp_mask)
+ {
+@@ -540,7 +540,7 @@ static int shmem_notify_change(struct de
+                       if (attr->ia_size & (PAGE_CACHE_SIZE-1)) {
+                               (void) shmem_getpage(inode,
+                                       attr->ia_size>>PAGE_CACHE_SHIFT,
+-                                              &page, SGP_READ);
++                                              &page, SGP_READ, NULL);
+                       }
+                       /*
+                        * Reset SHMEM_PAGEIN flag so that shmem_truncate can
+@@ -765,7 +765,7 @@ redirty:
+  * vm. If we swap it in we mark it dirty since we also free the swap
+  * entry since a page cannot live in both the swap and page cache
+  */
+-static int shmem_getpage(struct inode *inode, unsigned long idx, struct page **pagep, enum sgp_type sgp)
++static int shmem_getpage(struct inode *inode, unsigned long idx, struct page **pagep, enum sgp_type sgp, int *type)
+ {
+       struct address_space *mapping = inode->i_mapping;
+       struct shmem_inode_info *info = SHMEM_I(inode);
+@@ -774,7 +774,7 @@ static int shmem_getpage(struct inode *i
+       struct page *swappage;
+       swp_entry_t *entry;
+       swp_entry_t swap;
+-      int error;
++      int error, majmin = VM_FAULT_MINOR;
+       if (idx >= SHMEM_MAX_INDEX)
+               return -EFBIG;
+@@ -811,6 +811,10 @@ repeat:
+               if (!swappage) {
+                       shmem_swp_unmap(entry);
+                       spin_unlock(&info->lock);
++                      /* here we actually do the io */
++                      if (majmin == VM_FAULT_MINOR && type)
++                              inc_page_state(pgmajfault);
++                      majmin = VM_FAULT_MAJOR;
+                       swapin_readahead(swap);
+                       swappage = read_swap_cache_async(swap);
+                       if (!swappage) {
+@@ -959,6 +963,8 @@ done:
+               } else
+                       *pagep = ZERO_PAGE(0);
+       }
++      if (type)
++              *type = majmin;
+       return 0;
+ failed:
+@@ -969,7 +975,7 @@ failed:
+       return error;
+ }
+-struct page *shmem_nopage(struct vm_area_struct *vma, unsigned long address, int unused)
++struct page *shmem_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
+ {
+       struct inode *inode = vma->vm_file->f_dentry->d_inode;
+       struct page *page = NULL;
+@@ -980,7 +986,7 @@ struct page *shmem_nopage(struct vm_area
+       idx += vma->vm_pgoff;
+       idx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT;
+-      error = shmem_getpage(inode, idx, &page, SGP_CACHE);
++      error = shmem_getpage(inode, idx, &page, SGP_CACHE, type);
+       if (error)
+               return (error == -ENOMEM)? NOPAGE_OOM: NOPAGE_SIGBUS;
+@@ -1007,7 +1013,7 @@ static int shmem_populate(struct vm_area
+               /*
+                * Will need changing if PAGE_CACHE_SIZE != PAGE_SIZE
+                */
+-              err = shmem_getpage(inode, pgoff, &page, sgp);
++              err = shmem_getpage(inode, pgoff, &page, sgp, NULL);
+               if (err)
+                       return err;
+               if (page) {
+@@ -1157,7 +1163,7 @@ static int
+ shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+ {
+       struct inode *inode = page->mapping->host;
+-      return shmem_getpage(inode, page->index, &page, SGP_WRITE);
++      return shmem_getpage(inode, page->index, &page, SGP_WRITE, NULL);
+ }
+ static ssize_t
+@@ -1180,7 +1186,7 @@ shmem_file_write(struct file *file, cons
+       pos = *ppos;
+       written = 0;
+-      err = generic_write_checks(inode, file, &pos, &count, 0);
++      err = generic_write_checks(file, &pos, &count, 0);
+       if (err || !count)
+               goto out;
+@@ -1214,7 +1220,7 @@ shmem_file_write(struct file *file, cons
+                * But it still may be a good idea to prefault below.
+                */
+-              err = shmem_getpage(inode, index, &page, SGP_WRITE);
++              err = shmem_getpage(inode, index, &page, SGP_WRITE, NULL);
+               if (err)
+                       break;
+@@ -1296,7 +1302,7 @@ static void do_shmem_file_read(struct fi
+                               break;
+               }
+-              desc->error = shmem_getpage(inode, index, &page, SGP_READ);
++              desc->error = shmem_getpage(inode, index, &page, SGP_READ, NULL);
+               if (desc->error) {
+                       if (desc->error == -EINVAL)
+                               desc->error = 0;
+@@ -1552,7 +1558,7 @@ static int shmem_symlink(struct inode *d
+                       iput(inode);
+                       return -ENOMEM;
+               }
+-              error = shmem_getpage(inode, 0, &page, SGP_WRITE);
++              error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL);
+               if (error) {
+                       vm_unacct_memory(VM_ACCT(1));
+                       iput(inode);
+@@ -1590,7 +1596,7 @@ static int shmem_follow_link_inline(stru
+ static int shmem_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+ {
+       struct page *page = NULL;
+-      int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ);
++      int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL);
+       if (res)
+               return res;
+       res = vfs_readlink(dentry, buffer, buflen, kmap(page));
+@@ -1603,7 +1609,7 @@ static int shmem_readlink(struct dentry 
+ static int shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
+ {
+       struct page *page = NULL;
+-      int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ);
++      int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL);
+       if (res)
+               return res;
+       res = vfs_follow_link(nd, kmap(page));
+@@ -1972,6 +1978,7 @@ struct file *shmem_file_setup(char *name
+       inode->i_nlink = 0;     /* It is unlinked */
+       file->f_vfsmnt = mntget(shm_mnt);
+       file->f_dentry = dentry;
++      file->f_mapping = inode->i_mapping;
+       file->f_op = &shmem_file_operations;
+       file->f_mode = FMODE_WRITE | FMODE_READ;
+       return(file);
+--- linux-2.6.0/mm/slab.c      2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/slab.c       2003-12-28 23:26:36.000000000 -0800
+@@ -805,13 +805,14 @@ static inline void *kmem_getpages(kmem_c
+       void *addr;
+       flags |= cachep->gfpflags;
+-      if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
+-              atomic_add(1<<cachep->gfporder, &slab_reclaim_pages);
+       addr = (void*)__get_free_pages(flags, cachep->gfporder);
+       if (addr) {
+               int i = (1 << cachep->gfporder);
+               struct page *page = virt_to_page(addr);
++              if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
++                      atomic_add(i, &slab_reclaim_pages);
++              add_page_state(nr_slab, i);
+               while (i--) {
+                       SetPageSlab(page);
+                       page++;
+@@ -1180,7 +1181,8 @@ next:
+               cachep = NULL;
+               goto opps;
+       }
+-      slab_size = L1_CACHE_ALIGN(cachep->num*sizeof(kmem_bufctl_t)+sizeof(struct slab));
++      slab_size = L1_CACHE_ALIGN(cachep->num*sizeof(kmem_bufctl_t) +
++                      sizeof(struct slab));
+       /*
+        * If the slab has been placed off-slab, and we have enough space then
+@@ -1224,10 +1226,13 @@ next:
+                        * the cache that's used by kmalloc(24), otherwise
+                        * the creation of further caches will BUG().
+                        */
+-                      cachep->array[smp_processor_id()] = &initarray_generic.cache;
++                      cachep->array[smp_processor_id()] =
++                                      &initarray_generic.cache;
+                       g_cpucache_up = PARTIAL;
+               } else {
+-                      cachep->array[smp_processor_id()] = kmalloc(sizeof(struct arraycache_init),GFP_KERNEL);
++                      cachep->array[smp_processor_id()] =
++                              kmalloc(sizeof(struct arraycache_init),
++                                      GFP_KERNEL);
+               }
+               BUG_ON(!ac_data(cachep));
+               ac_data(cachep)->avail = 0;
+@@ -1241,7 +1246,7 @@ next:
+       } 
+       cachep->lists.next_reap = jiffies + REAPTIMEOUT_LIST3 +
+-                                      ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
++                              ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
+       /* Need the semaphore to access the chain. */
+       down(&cache_chain_sem);
+@@ -1254,16 +1259,24 @@ next:
+               list_for_each(p, &cache_chain) {
+                       kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
+                       char tmp;
+-                      /* This happens when the module gets unloaded and doesn't
+-                         destroy its slab cache and noone else reuses the vmalloc
+-                         area of the module. Print a warning. */
+-                      if (__get_user(tmp,pc->name)) { 
+-                              printk("SLAB: cache with size %d has lost its name\n", 
+-                                      pc->objsize); 
++
++                      /*
++                       * This happens when the module gets unloaded and
++                       * doesn't destroy its slab cache and noone else reuses
++                       * the vmalloc area of the module. Print a warning.
++                       */
++#ifdef CONFIG_X86_UACCESS_INDIRECT
++                      if (__direct_get_user(tmp,pc->name)) {
++#else
++                      if (__get_user(tmp,pc->name)) {
++#endif
++                              printk("SLAB: cache with size %d has lost its "
++                                              "name\n", pc->objsize);
+                               continue; 
+                       }       
+                       if (!strcmp(pc->name,name)) { 
+-                              printk("kmem_cache_create: duplicate cache %s\n",name); 
++                              printk("kmem_cache_create: duplicate "
++                                              "cache %s\n",name);
+                               up(&cache_chain_sem); 
+                               BUG(); 
+                       }       
+@@ -1608,7 +1621,6 @@ static int cache_grow (kmem_cache_t * ca
+       do {
+               SET_PAGE_CACHE(page, cachep);
+               SET_PAGE_SLAB(page, slabp);
+-              inc_page_state(nr_slab);
+               page++;
+       } while (--i);
+@@ -1890,6 +1902,15 @@ cache_alloc_debugcheck_after(kmem_cache_
+               *dbg_redzone1(cachep, objp) = RED_ACTIVE;
+               *dbg_redzone2(cachep, objp) = RED_ACTIVE;
+       }
++      {
++              int objnr;
++              struct slab *slabp;
++
++              slabp = GET_PAGE_SLAB(virt_to_page(objp));
++
++              objnr = (objp - slabp->s_mem) / cachep->objsize;
++              slab_bufctl(slabp)[objnr] = (int)caller;
++      }
+       objp += obj_dbghead(cachep);
+       if (cachep->ctor && cachep->flags & SLAB_POISON) {
+               unsigned long   ctor_flags = SLAB_CTOR_CONSTRUCTOR;
+@@ -1951,12 +1972,14 @@ static void free_block(kmem_cache_t *cac
+               objnr = (objp - slabp->s_mem) / cachep->objsize;
+               check_slabp(cachep, slabp);
+ #if DEBUG
++#if 0
+               if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
+                       printk(KERN_ERR "slab: double free detected in cache '%s', objp %p.\n",
+                                               cachep->name, objp);
+                       BUG();
+               }
+ #endif
++#endif
+               slab_bufctl(slabp)[objnr] = slabp->free;
+               slabp->free = objnr;
+               STATS_DEC_ACTIVE(cachep);
+@@ -2693,6 +2716,29 @@ struct seq_operations slabinfo_op = {
+       .show   = s_show,
+ };
++static void do_dump_slabp(kmem_cache_t *cachep)
++{
++#if DEBUG
++      struct list_head *q;
++
++      check_irq_on();
++      spin_lock_irq(&cachep->spinlock);
++      list_for_each(q,&cachep->lists.slabs_full) {
++              struct slab *slabp;
++              int i;
++              slabp = list_entry(q, struct slab, list);
++              for (i = 0; i < cachep->num; i++) {
++                      unsigned long sym = slab_bufctl(slabp)[i];
++
++                      printk("obj %p/%d: %p", slabp, i, (void *)sym);
++                      print_symbol(" <%s>", sym);
++                      printk("\n");
++              }
++      }
++      spin_unlock_irq(&cachep->spinlock);
++#endif
++}
++
+ #define MAX_SLABINFO_WRITE 128
+ /**
+  * slabinfo_write - Tuning for the slab allocator
+@@ -2733,9 +2779,11 @@ ssize_t slabinfo_write(struct file *file
+                           batchcount < 1 ||
+                           batchcount > limit ||
+                           shared < 0) {
+-                              res = -EINVAL;
++                              do_dump_slabp(cachep);
++                              res = 0;
+                       } else {
+-                              res = do_tune_cpucache(cachep, limit, batchcount, shared);
++                              res = do_tune_cpucache(cachep, limit,
++                                                      batchcount, shared);
+                       }
+                       break;
+               }
+--- linux-2.6.0/mm/swap.c      2003-11-23 19:03:02.000000000 -0800
++++ 25/mm/swap.c       2003-12-28 23:26:43.000000000 -0800
+@@ -348,12 +348,15 @@ void pagevec_strip(struct pagevec *pvec)
+  * The search returns a group of mapping-contiguous pages with ascending
+  * indexes.  There may be holes in the indices due to not-present pages.
+  *
+- * pagevec_lookup() returns the number of pages which were found.
++ * pagevec_lookup() returns the number of pages which were found
++ * and also atomically sets the next offset to continue looking up
++ * mapping contiguous pages from (useful when doing a range of
++ * pagevec lookups in chunks of PAGEVEC_SIZE).
+  */
+ unsigned int pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
+-              pgoff_t start, unsigned int nr_pages)
++              pgoff_t *next, unsigned int nr_pages)
+ {
+-      pvec->nr = find_get_pages(mapping, start, nr_pages, pvec->pages);
++      pvec->nr = find_get_pages(mapping, next, nr_pages, pvec->pages);
+       return pagevec_count(pvec);
+ }
+@@ -386,17 +389,19 @@ EXPORT_SYMBOL(vm_acct_memory);
+ #ifdef CONFIG_SMP
+ void percpu_counter_mod(struct percpu_counter *fbc, long amount)
+ {
++      long count;
++      long *pcount;
+       int cpu = get_cpu();
+-      long count = fbc->counters[cpu].count;
+-      count += amount;
++      pcount = per_cpu_ptr(fbc->counters, cpu);
++      count = *pcount + amount;
+       if (count >= FBC_BATCH || count <= -FBC_BATCH) {
+               spin_lock(&fbc->lock);
+               fbc->count += count;
+               spin_unlock(&fbc->lock);
+               count = 0;
+       }
+-      fbc->counters[cpu].count = count;
++      *pcount = count;
+       put_cpu();
+ }
+ EXPORT_SYMBOL(percpu_counter_mod);
+--- linux-2.6.0/mm/swapfile.c  2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/swapfile.c   2003-12-28 23:21:22.000000000 -0800
+@@ -912,7 +912,7 @@ static int setup_swap_extents(struct swa
+       sector_t last_block;
+       int ret;
+-      inode = sis->swap_file->f_dentry->d_inode;
++      inode = sis->swap_file->f_mapping->host;
+       if (S_ISBLK(inode->i_mode)) {
+               ret = add_swap_extent(sis, 0, sis->max, 0);
+               goto done;
+@@ -1031,13 +1031,13 @@ asmlinkage long sys_swapoff(const char _
+       if (IS_ERR(victim))
+               goto out;
+-      mapping = victim->f_dentry->d_inode->i_mapping;
++      mapping = victim->f_mapping;
+       prev = -1;
+       swap_list_lock();
+       for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
+               p = swap_info + type;
+               if ((p->flags & SWP_ACTIVE) == SWP_ACTIVE) {
+-                      if (p->swap_file->f_dentry->d_inode->i_mapping==mapping)
++                      if (p->swap_file->f_mapping == mapping)
+                               break;
+               }
+               prev = type;
+@@ -1099,13 +1099,12 @@ asmlinkage long sys_swapoff(const char _
+       swap_device_unlock(p);
+       swap_list_unlock();
+       vfree(swap_map);
+-      if (S_ISBLK(swap_file->f_dentry->d_inode->i_mode)) {
+-              struct block_device *bdev;
+-              bdev = swap_file->f_dentry->d_inode->i_bdev;
++      if (S_ISBLK(mapping->host->i_mode)) {
++              struct block_device *bdev = I_BDEV(mapping->host);
+               set_blocksize(bdev, p->old_block_size);
+               bd_release(bdev);
+       } else {
+-              up(&swap_file->f_dentry->d_inode->i_mapping->host->i_sem);
++              up(&mapping->host->i_sem);
+       }
+       filp_close(swap_file, NULL);
+       err = 0;
+@@ -1231,8 +1230,8 @@ asmlinkage long sys_swapon(const char __
+       int swapfilesize;
+       unsigned short *swap_map;
+       struct page *page = NULL;
+-      struct inode *inode;
+-      struct inode *downed_inode = NULL;
++      struct inode *inode = NULL;
++      int did_down = 0;
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+@@ -1279,8 +1278,8 @@ asmlinkage long sys_swapon(const char __
+       }
+       p->swap_file = swap_file;
+-      inode = swap_file->f_dentry->d_inode;
+-      mapping = swap_file->f_dentry->d_inode->i_mapping;
++      mapping = swap_file->f_mapping;
++      inode = mapping->host;
+       error = -EBUSY;
+       for (i = 0; i < nr_swapfiles; i++) {
+@@ -1288,32 +1287,32 @@ asmlinkage long sys_swapon(const char __
+               if (i == type || !q->swap_file)
+                       continue;
+-              if (mapping == q->swap_file->f_dentry->d_inode->i_mapping)
++              if (mapping == q->swap_file->f_mapping)
+                       goto bad_swap;
+       }
+       error = -EINVAL;
+       if (S_ISBLK(inode->i_mode)) {
+-              bdev = inode->i_bdev;
++              bdev = I_BDEV(inode);
+               error = bd_claim(bdev, sys_swapon);
+               if (error < 0) {
+                       bdev = NULL;
+                       goto bad_swap;
+               }
+               p->old_block_size = block_size(bdev);
+-              error = set_blocksize(inode->i_bdev, PAGE_SIZE);
++              error = set_blocksize(bdev, PAGE_SIZE);
+               if (error < 0)
+                       goto bad_swap;
+               p->bdev = bdev;
+       } else if (S_ISREG(inode->i_mode)) {
+               p->bdev = inode->i_sb->s_bdev;
+-              downed_inode = mapping->host;
+-              down(&downed_inode->i_sem);
++              down(&inode->i_sem);
++              did_down = 1;
+       } else {
+               goto bad_swap;
+       }
+-      swapfilesize = i_size_read(mapping->host) >> PAGE_SHIFT;
++      swapfilesize = i_size_read(inode) >> PAGE_SHIFT;
+       /*
+        * Read the swap header.
+@@ -1465,8 +1464,8 @@ out:
+       }
+       if (name)
+               putname(name);
+-      if (error && downed_inode)
+-              up(&downed_inode->i_sem);
++      if (error && did_down)
++              up(&inode->i_sem);
+       return error;
+ }
+--- linux-2.6.0/mm/truncate.c  2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/truncate.c   2003-12-28 23:26:43.000000000 -0800
+@@ -122,14 +122,10 @@ void truncate_inode_pages(struct address
+       pagevec_init(&pvec, 0);
+       next = start;
+-      while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++      while (pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+               for (i = 0; i < pagevec_count(&pvec); i++) {
+                       struct page *page = pvec.pages[i];
+-                      pgoff_t page_index = page->index;
+-                      if (page_index > next)
+-                              next = page_index;
+-                      next++;
+                       if (TestSetPageLocked(page))
+                               continue;
+                       if (PageWriteback(page)) {
+@@ -155,7 +151,7 @@ void truncate_inode_pages(struct address
+       next = start;
+       for ( ; ; ) {
+-              if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++              if (!pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+                       if (next == start)
+                               break;
+                       next = start;
+@@ -166,14 +162,19 @@ void truncate_inode_pages(struct address
+                       lock_page(page);
+                       wait_on_page_writeback(page);
+-                      if (page->index > next)
+-                              next = page->index;
+-                      next++;
+                       truncate_complete_page(mapping, page);
+                       unlock_page(page);
+               }
+               pagevec_release(&pvec);
+       }
++
++      if (lstart == 0) {
++              WARN_ON(mapping->nrpages);
++              WARN_ON(!list_empty(&mapping->clean_pages));
++              WARN_ON(!list_empty(&mapping->dirty_pages));
++              WARN_ON(!list_empty(&mapping->locked_pages));
++              WARN_ON(!list_empty(&mapping->io_pages));
++      }
+ }
+ EXPORT_SYMBOL(truncate_inode_pages);
+@@ -201,17 +202,13 @@ unsigned long invalidate_mapping_pages(s
+       pagevec_init(&pvec, 0);
+       while (next <= end &&
+-                      pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++                      pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+               for (i = 0; i < pagevec_count(&pvec); i++) {
+                       struct page *page = pvec.pages[i];
+                       if (TestSetPageLocked(page)) {
+-                              next++;
+                               continue;
+                       }
+-                      if (page->index > next)
+-                              next = page->index;
+-                      next++;
+                       if (PageDirty(page) || PageWriteback(page))
+                               goto unlock;
+                       if (page_mapped(page))
+@@ -250,14 +247,13 @@ void invalidate_inode_pages2(struct addr
+       int i;
+       pagevec_init(&pvec, 0);
+-      while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
++      while (pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE)) {
+               for (i = 0; i < pagevec_count(&pvec); i++) {
+                       struct page *page = pvec.pages[i];
+                       lock_page(page);
+                       if (page->mapping == mapping) { /* truncate race? */
+                               wait_on_page_writeback(page);
+-                              next = page->index + 1;
+                               if (page_mapped(page))
+                                       clear_page_dirty(page);
+                               else
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/mm/usercopy.c   2003-12-28 23:26:37.000000000 -0800
+@@ -0,0 +1,291 @@
++/*
++ * linux/mm/usercopy.c
++ *
++ * (C) Copyright 2003 Ingo Molnar
++ *
++ * Generic implementation of all the user-VM access functions, without
++ * relying on being able to access the VM directly.
++ */
++
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/mm.h>
++#include <linux/highmem.h>
++#include <linux/pagemap.h>
++#include <linux/smp_lock.h>
++#include <linux/ptrace.h>
++#include <linux/interrupt.h>
++
++#include <asm/pgtable.h>
++#include <asm/uaccess.h>
++#include <asm/atomic_kmap.h>
++
++/*
++ * Get kernel address of the user page and pin it.
++ */
++static inline struct page *pin_page(unsigned long addr, int write)
++{
++      struct mm_struct *mm = current->mm ? : &init_mm;
++      struct page *page = NULL;
++      int ret;
++
++      /*
++       * Do a quick atomic lookup first - this is the fastpath.
++       */
++retry:
++      page = follow_page(mm, addr, write);
++      if (likely(page != NULL)) {
++              if (!PageReserved(page))
++                      get_page(page);
++              return page;
++      }
++
++      /*
++       * No luck - bad address or need to fault in the page:
++       */
++
++      /* Release the lock so get_user_pages can sleep */
++      spin_unlock(&mm->page_table_lock);
++
++      /*
++       * In the context of filemap_copy_from_user(), we are not allowed
++       * to sleep.  We must fail this usercopy attempt and allow
++       * filemap_copy_from_user() to recover: drop its atomic kmap and use
++       * a sleeping kmap instead.
++       */
++      if (in_atomic()) {
++              spin_lock(&mm->page_table_lock);
++              return NULL;
++      }
++
++      down_read(&mm->mmap_sem);
++      ret = get_user_pages(current, mm, addr, 1, write, 0, NULL, NULL);
++      up_read(&mm->mmap_sem);
++      spin_lock(&mm->page_table_lock);
++
++      if (ret <= 0)
++              return NULL;
++
++      /*
++       * Go try the follow_page again.
++       */
++      goto retry;
++}
++
++static inline void unpin_page(struct page *page)
++{
++      put_page(page);
++}
++
++/*
++ * Access another process' address space.
++ * Source/target buffer must be kernel space,
++ * Do not walk the page table directly, use get_user_pages
++ */
++static int rw_vm(unsigned long addr, void *buf, int len, int write)
++{
++      struct mm_struct *mm = current->mm ? : &init_mm;
++
++      if (!len)
++              return 0;
++
++      spin_lock(&mm->page_table_lock);
++
++      /* ignore errors, just check how much was sucessfully transfered */
++      while (len) {
++              struct page *page = NULL;
++              int bytes, offset;
++              void *maddr;
++
++              page = pin_page(addr, write);
++              if (!page)
++                      break;
++
++              bytes = len;
++              offset = addr & (PAGE_SIZE-1);
++              if (bytes > PAGE_SIZE-offset)
++                      bytes = PAGE_SIZE-offset;
++
++              maddr = kmap_atomic(page, KM_USER_COPY);
++
++#define HANDLE_TYPE(type) \
++      case sizeof(type): *(type *)(maddr+offset) = *(type *)(buf); break;
++
++              if (write) {
++                      switch (bytes) {
++                      HANDLE_TYPE(char);
++                      HANDLE_TYPE(int);
++                      HANDLE_TYPE(long long);
++                      default:
++                              memcpy(maddr + offset, buf, bytes);
++                      }
++              } else {
++#undef HANDLE_TYPE
++#define HANDLE_TYPE(type) \
++      case sizeof(type): *(type *)(buf) = *(type *)(maddr+offset); break;
++                      switch (bytes) {
++                      HANDLE_TYPE(char);
++                      HANDLE_TYPE(int);
++                      HANDLE_TYPE(long long);
++                      default:
++                              memcpy(buf, maddr + offset, bytes);
++                      }
++#undef HANDLE_TYPE
++              }
++              kunmap_atomic(maddr, KM_USER_COPY);
++              unpin_page(page);
++              len -= bytes;
++              buf += bytes;
++              addr += bytes;
++      }
++      spin_unlock(&mm->page_table_lock);
++
++      return len;
++}
++
++static int str_vm(unsigned long addr, void *buf0, int len, int copy)
++{
++      struct mm_struct *mm = current->mm ? : &init_mm;
++      struct page *page;
++      void *buf = buf0;
++
++      if (!len)
++              return len;
++
++      spin_lock(&mm->page_table_lock);
++
++      /* ignore errors, just check how much was sucessfully transfered */
++      while (len) {
++              int bytes, offset, left, copied;
++              char *maddr;
++
++              page = pin_page(addr, copy == 2);
++              if (!page) {
++                      spin_unlock(&mm->page_table_lock);
++                      return -EFAULT;
++              }
++              bytes = len;
++              offset = addr & (PAGE_SIZE-1);
++              if (bytes > PAGE_SIZE-offset)
++                      bytes = PAGE_SIZE-offset;
++
++              maddr = kmap_atomic(page, KM_USER_COPY);
++              if (copy == 2) {
++                      memset(maddr + offset, 0, bytes);
++                      copied = bytes;
++                      left = 0;
++              } else if (copy == 1) {
++                      left = strncpy_count(buf, maddr + offset, bytes);
++                      copied = bytes - left;
++              } else {
++                      copied = strnlen(maddr + offset, bytes);
++                      left = bytes - copied;
++              }
++              BUG_ON(bytes < 0 || copied < 0);
++              kunmap_atomic(maddr, KM_USER_COPY);
++              unpin_page(page);
++              len -= copied;
++              buf += copied;
++              addr += copied;
++              if (left)
++                      break;
++      }
++      spin_unlock(&mm->page_table_lock);
++
++      return len;
++}
++
++/*
++ * Copies memory from userspace (ptr) into kernelspace (val).
++ *
++ * returns # of bytes not copied.
++ */
++int get_user_size(unsigned int size, void *val, const void *ptr)
++{
++      int ret;
++
++      if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
++              ret = __direct_copy_from_user(val, ptr, size);
++      else
++              ret = rw_vm((unsigned long)ptr, val, size, 0);
++      if (ret)
++              /*
++               * Zero the rest:
++               */
++              memset(val + size - ret, 0, ret);
++      return ret;
++}
++
++/*
++ * Copies memory from kernelspace (val) into userspace (ptr).
++ *
++ * returns # of bytes not copied.
++ */
++int put_user_size(unsigned int size, const void *val, void *ptr)
++{
++      if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
++              return __direct_copy_to_user(ptr, val, size);
++      else
++              return rw_vm((unsigned long)ptr, (void *)val, size, 1);
++}
++
++int copy_str_fromuser_size(unsigned int size, void *val, const void *ptr)
++{
++      int copied, left;
++
++      if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++              left = strncpy_count(val, ptr, size);
++              copied = size - left;
++              BUG_ON(copied < 0);
++
++              return copied;
++      }
++      left = str_vm((unsigned long)ptr, val, size, 1);
++      if (left < 0)
++              return left;
++      copied = size - left;
++      BUG_ON(copied < 0);
++
++      return copied;
++}
++
++int strlen_fromuser_size(unsigned int size, const void *ptr)
++{
++      int copied, left;
++
++      if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++              copied = strnlen(ptr, size) + 1;
++              BUG_ON(copied < 0);
++
++              return copied;
++      }
++      left = str_vm((unsigned long)ptr, NULL, size, 0);
++      if (left < 0)
++              return 0;
++      copied = size - left + 1;
++      BUG_ON(copied < 0);
++
++      return copied;
++}
++
++int zero_user_size(unsigned int size, void *ptr)
++{
++      int left;
++
++      if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
++              memset(ptr, 0, size);
++              return 0;
++      }
++      left = str_vm((unsigned long)ptr, NULL, size, 2);
++      if (left < 0)
++              return size;
++      return left;
++}
++
++EXPORT_SYMBOL(get_user_size);
++EXPORT_SYMBOL(put_user_size);
++EXPORT_SYMBOL(zero_user_size);
++EXPORT_SYMBOL(copy_str_fromuser_size);
++EXPORT_SYMBOL(strlen_fromuser_size);
++
+--- linux-2.6.0/mm/vmscan.c    2003-11-09 16:45:06.000000000 -0800
++++ 25/mm/vmscan.c     2003-12-28 23:23:03.000000000 -0800
+@@ -154,7 +154,7 @@ static int shrink_slab(long scanned, uns
+       list_for_each_entry(shrinker, &shrinker_list, list) {
+               unsigned long long delta;
+-              delta = scanned * shrinker->seeks;
++              delta = 4 * (scanned / shrinker->seeks);
+               delta *= (*shrinker->shrinker)(0, gfp_mask);
+               do_div(delta, pages + 1);
+               shrinker->nr += delta;
+@@ -779,7 +779,7 @@ shrink_zone(struct zone *zone, int max_s
+               count = atomic_read(&zone->refill_counter);
+               if (count > SWAP_CLUSTER_MAX * 4)
+                       count = SWAP_CLUSTER_MAX * 4;
+-              atomic_sub(count, &zone->refill_counter);
++              atomic_set(&zone->refill_counter, 0);
+               refill_inactive_zone(zone, count, ps, priority);
+       }
+       return shrink_cache(nr_pages, zone, gfp_mask,
+@@ -803,16 +803,15 @@ shrink_zone(struct zone *zone, int max_s
+  * scan then give up on it.
+  */
+ static int
+-shrink_caches(struct zone *classzone, int priority, int *total_scanned,
++shrink_caches(struct zone **zones, int priority, int *total_scanned,
+               int gfp_mask, int nr_pages, struct page_state *ps)
+ {
+-      struct zone *first_classzone;
+-      struct zone *zone;
+       int ret = 0;
++      int i;
+-      first_classzone = classzone->zone_pgdat->node_zones;
+-      for (zone = classzone; zone >= first_classzone; zone--) {
++      for (i = 0; zones[i] != NULL; i++) {
+               int to_reclaim = max(nr_pages, SWAP_CLUSTER_MAX);
++              struct zone *zone = zones[i];
+               int nr_mapped = 0;
+               int max_scan;
+@@ -855,27 +854,27 @@ shrink_caches(struct zone *classzone, in
+  * excessive rotation of the inactive list, which is _supposed_ to be an LRU,
+  * yes?
+  */
+-int try_to_free_pages(struct zone *cz,
++int try_to_free_pages(struct zone **zones,
+               unsigned int gfp_mask, unsigned int order)
+ {
+       int priority;
+       int ret = 0;
+       const int nr_pages = SWAP_CLUSTER_MAX;
+       int nr_reclaimed = 0;
+-      struct zone *zone;
+       struct reclaim_state *reclaim_state = current->reclaim_state;
++      int i;
+       inc_page_state(allocstall);
+-      for (zone = cz; zone >= cz->zone_pgdat->node_zones; --zone)
+-              zone->temp_priority = DEF_PRIORITY;
++      for (i = 0; zones[i] != 0; i++)
++              zones[i]->temp_priority = DEF_PRIORITY;
+       for (priority = DEF_PRIORITY; priority >= 0; priority--) {
+               int total_scanned = 0;
+               struct page_state ps;
+               get_page_state(&ps);
+-              nr_reclaimed += shrink_caches(cz, priority, &total_scanned,
++              nr_reclaimed += shrink_caches(zones, priority, &total_scanned,
+                                               gfp_mask, nr_pages, &ps);
+               if (nr_reclaimed >= nr_pages) {
+                       ret = 1;
+@@ -892,7 +891,7 @@ int try_to_free_pages(struct zone *cz,
+               /* Take a nap, wait for some writeback to complete */
+               blk_congestion_wait(WRITE, HZ/10);
+-              if (cz - cz->zone_pgdat->node_zones < ZONE_HIGHMEM) {
++              if (zones[0] - zones[0]->zone_pgdat->node_zones < ZONE_HIGHMEM) {
+                       shrink_slab(total_scanned, gfp_mask);
+                       if (reclaim_state) {
+                               nr_reclaimed += reclaim_state->reclaimed_slab;
+@@ -903,8 +902,8 @@ int try_to_free_pages(struct zone *cz,
+       if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY))
+               out_of_memory();
+ out:
+-      for (zone = cz; zone >= cz->zone_pgdat->node_zones; --zone)
+-              zone->prev_priority = zone->temp_priority;
++      for (i = 0; zones[i] != 0; i++)
++              zones[i]->prev_priority = zones[i]->temp_priority;
+       return ret;
+ }
+--- linux-2.6.0/net/atm/clip.c 2003-10-17 15:58:05.000000000 -0700
++++ 25/net/atm/clip.c  2003-12-28 23:21:01.000000000 -0800
+@@ -563,32 +563,20 @@ static int clip_setentry(struct atm_vcc 
+ }
+-static int clip_init(struct net_device *dev)
++static void clip_setup(struct net_device *dev)
+ {
+-      DPRINTK("clip_init %s\n",dev->name);
+       dev->hard_start_xmit = clip_start_xmit;
+       /* sg_xmit ... */
+-      dev->hard_header = NULL;
+-      dev->rebuild_header = NULL;
+-      dev->set_mac_address = NULL;
+-      dev->hard_header_parse = NULL;
+-      dev->hard_header_cache = NULL;
+-      dev->header_cache_update = NULL;
+-      dev->change_mtu = NULL;
+-      dev->do_ioctl = NULL;
+       dev->get_stats = clip_get_stats;
+       dev->type = ARPHRD_ATM;
+       dev->hard_header_len = RFC1483LLC_LEN;
+       dev->mtu = RFC1626_MTU;
+-      dev->addr_len = 0;
+       dev->tx_queue_len = 100; /* "normal" queue (packets) */
+           /* When using a "real" qdisc, the qdisc determines the queue */
+           /* length. tx_queue_len is only used for the default case, */
+           /* without any more elaborate queuing. 100 is a reasonable */
+           /* compromise between decent burst-tolerance and protection */
+           /* against memory hogs. */
+-      dev->flags = 0;
+-      return 0;
+ }
+@@ -608,18 +596,16 @@ static int clip_create(int number)
+                       if (PRIV(dev)->number >= number)
+                               number = PRIV(dev)->number+1;
+       }
+-      dev = kmalloc(sizeof(struct net_device)+sizeof(struct clip_priv),
+-          GFP_KERNEL); 
+-      if (!dev) return -ENOMEM;
+-      memset(dev,0,sizeof(struct net_device)+sizeof(struct clip_priv));
++      dev = alloc_netdev(sizeof(struct clip_priv), "", clip_setup);
++      if (!dev)
++              return -ENOMEM;
+       clip_priv = PRIV(dev);
+       sprintf(dev->name,"atm%d",number);
+-      dev->init = clip_init;
+       spin_lock_init(&clip_priv->xoff_lock);
+       clip_priv->number = number;
+       error = register_netdev(dev);
+       if (error) {
+-              kfree(dev);
++              free_netdev(dev);
+               return error;
+       }
+       clip_priv->next = clip_devs;
+@@ -634,7 +620,7 @@ static int clip_device_event(struct noti
+ {
+       /* ignore non-CLIP devices */
+       if (((struct net_device *) dev)->type != ARPHRD_ATM ||
+-          ((struct net_device *) dev)->init != clip_init)
++          ((struct net_device *) dev)->hard_start_xmit != clip_start_xmit)
+               return NOTIFY_DONE;
+       switch (event) {
+               case NETDEV_UP:
+--- linux-2.6.0/net/bridge/br_if.c     2003-07-27 12:14:40.000000000 -0700
++++ 25/net/bridge/br_if.c      2003-12-28 23:21:01.000000000 -0800
+@@ -172,7 +172,7 @@ int br_add_bridge(const char *name)
+       ret = register_netdev(br->dev);
+       if (ret)
+-              kfree(br->dev);
++              free_netdev(br->dev);
+       return ret;
+ }
+--- linux-2.6.0/net/bridge/netfilter/Kconfig   2003-10-17 15:58:05.000000000 -0700
++++ 25/net/bridge/netfilter/Kconfig    2003-12-28 23:23:06.000000000 -0800
+@@ -92,7 +92,7 @@ config BRIDGE_EBT_LIMIT
+         equivalent of the iptables limit match.
+         If you want to compile it as a module, say M here and read
+-        <file:Documentation/modules.txt>.  If unsure, say `N'.
++        <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
+ config BRIDGE_EBT_MARK
+       tristate "ebt: mark filter support"
+--- linux-2.6.0/net/core/dev.c 2003-11-23 19:03:03.000000000 -0800
++++ 25/net/core/dev.c  2003-12-28 23:21:10.000000000 -0800
+@@ -105,6 +105,7 @@
+ #include <linux/kmod.h>
+ #include <linux/module.h>
+ #include <linux/kallsyms.h>
++#include <linux/netpoll.h>
+ #ifdef CONFIG_NET_RADIO
+ #include <linux/wireless.h>           /* Note : will define WIRELESS_EXT */
+ #include <net/iw_handler.h>
+@@ -371,6 +372,30 @@ int netdev_boot_setup_check(struct net_d
+       return 0;
+ }
++
++/**
++ *    netdev_boot_base        - get address from boot time settings
++ *    @prefix: prefix for network device
++ *    @unit: id for network device
++ *
++ *    Check boot time settings for the base address of device.
++ *    The found settings are set for the device to be used
++ *    later in the device probing.
++ *    Returns 0 if no settings found.
++ */
++unsigned long netdev_boot_base(const char *prefix, int unit)
++{
++      const struct netdev_boot_setup *s = dev_boot_setup;
++      char name[IFNAMSIZ];
++      int i;
++
++      sprintf(name, "%s%d", prefix, unit);
++      for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++)
++              if (!strcmp(name, s[i].name))
++                      return s[i].map.base_addr;
++      return 0;
++}
++
+ /*
+  * Saves at boot time configured settings for any netdevice.
+  */
+@@ -1380,7 +1405,6 @@ static void sample_queue(unsigned long d
+ }
+ #endif
+-
+ /**
+  *    netif_rx        -       post buffer to the network code
+  *    @skb: buffer to post
+@@ -1405,6 +1429,13 @@ int netif_rx(struct sk_buff *skb)
+       struct softnet_data *queue;
+       unsigned long flags;
++#ifdef CONFIG_NETPOLL_RX
++      if (skb->dev->netpoll_rx && netpoll_rx(skb)) {
++              kfree_skb(skb);
++              return NET_RX_DROP;
++      }
++#endif
++
+       if (!skb->stamp.tv_sec)
+               do_gettimeofday(&skb->stamp);
+@@ -1560,6 +1591,13 @@ int netif_receive_skb(struct sk_buff *sk
+       int ret = NET_RX_DROP;
+       unsigned short type = skb->protocol;
++#ifdef CONFIG_NETPOLL_RX
++      if (skb->dev->netpoll_rx && skb->dev->poll && netpoll_rx(skb)) {
++              kfree_skb(skb);
++              return NET_RX_DROP;
++      }
++#endif
++
+       if (!skb->stamp.tv_sec)
+               do_gettimeofday(&skb->stamp);
+@@ -1684,7 +1722,6 @@ static void net_rx_action(struct softirq
+       unsigned long start_time = jiffies;
+       int budget = netdev_max_backlog;
+-      
+       preempt_disable();
+       local_irq_disable();
+@@ -1711,6 +1748,10 @@ static void net_rx_action(struct softirq
+                       dev_put(dev);
+                       local_irq_disable();
+               }
++
++#ifdef CONFIG_KGDBOE
++              kgdb_process_breakpoint();
++#endif
+       }
+ out:
+       local_irq_enable();
+@@ -2875,7 +2916,7 @@ void free_netdev(struct net_device *dev)
+ {
+       /*  Compatiablity with error handling in drivers */
+       if (dev->reg_state == NETREG_UNINITIALIZED) {
+-              kfree(dev);
++              kfree((char *)dev - dev->padded);
+               return;
+       }
+--- linux-2.6.0/net/core/Makefile      2003-09-08 13:58:59.000000000 -0700
++++ 25/net/core/Makefile       2003-12-28 23:21:01.000000000 -0800
+@@ -13,3 +13,4 @@ obj-$(CONFIG_NETFILTER) += netfilter.o
+ obj-$(CONFIG_NET_DIVERT) += dv.o
+ obj-$(CONFIG_NET_PKTGEN) += pktgen.o
+ obj-$(CONFIG_NET_RADIO) += wireless.o
++obj-$(CONFIG_NETPOLL) += netpoll.o
+--- /dev/null  2002-08-30 16:31:37.000000000 -0700
++++ 25/net/core/netpoll.c      2003-12-28 23:21:01.000000000 -0800
+@@ -0,0 +1,642 @@
++/*
++ * Common framework for low-level network console, dump, and debugger code
++ *
++ * Sep 8 2003  Matt Mackall <mpm@selenic.com>
++ */
++
++#include <linux/smp_lock.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/string.h>
++#include <linux/inetdevice.h>
++#include <linux/inet.h>
++#include <linux/interrupt.h>
++#include <linux/netpoll.h>
++#include <linux/sched.h>
++#include <net/tcp.h>
++#include <net/udp.h>
++
++/*
++ * We maintain a small pool of fully-sized skbs, to make sure the
++ * message gets out even in extreme OOM situations.
++ */
++
++#define MAX_SKBS 32
++#define MAX_UDP_CHUNK 1460
++
++static spinlock_t skb_list_lock = SPIN_LOCK_UNLOCKED;
++static int nr_skbs;
++static struct sk_buff *skbs;
++
++static spinlock_t rx_list_lock = SPIN_LOCK_UNLOCKED;
++static LIST_HEAD(rx_list);
++
++static int trapped;
++
++#define MAX_SKB_SIZE \
++              (MAX_UDP_CHUNK + sizeof(struct udphdr) + \
++                              sizeof(struct iphdr) + sizeof(struct ethhdr))
++
++static void zap_completion_queue(void);
++
++static int checksum_udp(struct sk_buff *skb, struct udphdr *uh,
++                           unsigned short ulen, u32 saddr, u32 daddr)
++{
++      if (uh->check == 0)
++              return 0;
++
++      if (skb->ip_summed == CHECKSUM_HW)
++              return csum_tcpudp_magic(
++                      saddr, daddr, ulen, IPPROTO_UDP, skb->csum);
++
++      skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
++
++      return csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
++}
++
++void netpoll_poll(struct netpoll *np)
++{
++      int budget = 1;
++
++      if(!np->dev || !netif_running(np->dev) || !np->dev->poll_controller)
++              return;
++
++      /* Process pending work on NIC */
++      np->dev->poll_controller(np->dev);
++
++      /* If scheduling is stopped, tickle NAPI bits */
++      if(trapped && np->dev->poll &&
++         test_bit(__LINK_STATE_RX_SCHED, &np->dev->state))
++              np->dev->poll(np->dev, &budget);
++      zap_completion_queue();
++}
++
++static void refill_skbs(void)
++{
++      struct sk_buff *skb;
++      unsigned long flags;
++
++      spin_lock_irqsave(&skb_list_lock, flags);
++      while (nr_skbs < MAX_SKBS) {
++              skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC);
++              if (!skb)
++                      break;
++
++              skb->next = skbs;
++              skbs = skb;
++              nr_skbs++;
++      }
++      spin_unlock_irqrestore(&skb_list_lock, flags);
++}
++
++static void zap_completion_queue(void)
++{
++      unsigned long flags;
++      struct softnet_data *sd = &get_cpu_var(softnet_data);
++
++      if (sd->completion_queue) {
++              struct sk_buff *clist;
++
++              local_irq_save(flags);
++              clist = sd->completion_queue;
++              sd->completion_queue = NULL;
++              local_irq_restore(flags);
++
++              while (clist != NULL) {
++                      struct sk_buff *skb = clist;
++                      clist = clist->next;
++                      __kfree_skb(skb);
++              }
++      }
++
++      put_cpu_var(softnet_data);
++}
++
++static struct sk_buff * find_skb(struct netpoll *np, int len, int reserve)
++{
++      int once = 1, count = 0;
++      unsigned long flags;
++      struct sk_buff *skb = NULL;
++
++      zap_completion_queue();
++repeat:
++      if (nr_skbs < MAX_SKBS)
++              refill_skbs();
++
++      skb = alloc_skb(len, GFP_ATOMIC);
++
++      if (!skb) {
++              spin_lock_irqsave(&skb_list_lock, flags);
++              skb = skbs;
++              if (skb)
++                      skbs = skb->next;
++              skb->next = NULL;
++              nr_skbs--;
++              spin_unlock_irqrestore(&skb_list_lock, flags);
++      }
++
++      if(!skb) {
++              count++;
++              if (once && (count == 1000000)) {
++                      printk("out of netpoll skbs!\n");
++                      once = 0;
++              }
++              netpoll_poll(np);
++              goto repeat;
++      }
++
++      atomic_set(&skb->users, 1);
++      skb_reserve(skb, reserve);
++      return skb;
++}
++
++void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
++{
++      int status;
++
++repeat:
++      if(!np || !np->dev || !netif_running(np->dev)) {
++              __kfree_skb(skb);
++              return;
++      }
++
++      spin_lock(&np->dev->xmit_lock);
++      np->dev->xmit_lock_owner = smp_processor_id();
++
++      if (netif_queue_stopped(np->dev)) {
++              np->dev->xmit_lock_owner = -1;
++              spin_unlock(&np->dev->xmit_lock);
++
++              netpoll_poll(np);
++              goto repeat;
++      }
++
++      status = np->dev->hard_start_xmit(skb, np->dev);
++      np->dev->xmit_lock_owner = -1;
++      spin_unlock(&np->dev->xmit_lock);
++
++      /* transmit busy */
++      if(status)
++              goto repeat;
++}
++
++void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
++{
++      int total_len, eth_len, ip_len, udp_len;
++      struct sk_buff *skb;
++      struct udphdr *udph;
++      struct iphdr *iph;
++      struct ethhdr *eth;
++
++      udp_len = len + sizeof(*udph);
++      ip_len = eth_len = udp_len + sizeof(*iph);
++      total_len = eth_len + ETH_HLEN;
++
++      skb = find_skb(np, total_len, total_len - len);
++      if (!skb)
++              return;
++
++      memcpy(skb->data, msg, len);
++      skb->len += len;
++
++      udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
++      udph->source = htons(np->local_port);
++      udph->dest = htons(np->remote_port);
++      udph->len = htons(udp_len);
++      udph->check = 0;
++
++      iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
++
++      iph->version  = 4;
++      iph->ihl      = 5;
++      iph->tos      = 0;
++      iph->tot_len  = htons(ip_len);
++      iph->id       = 0;
++      iph->frag_off = 0;
++      iph->ttl      = 64;
++      iph->protocol = IPPROTO_UDP;
++      iph->check    = 0;
++      iph->saddr    = htonl(np->local_ip);
++      iph->daddr    = htonl(np->remote_ip);
++      iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);
++
++      eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
++
++      eth->h_proto = htons(ETH_P_IP);
++      memcpy(eth->h_source, np->local_mac, 6);
++      memcpy(eth->h_dest, np->remote_mac, 6);
++
++      netpoll_send_skb(np, skb);
++}
++
++static void arp_reply(struct sk_buff *skb)
++{
++      struct in_device *in_dev = (struct in_device *) skb->dev->ip_ptr;
++      struct arphdr *arp;
++      unsigned char *arp_ptr, *sha, *tha;
++      int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
++      u32 sip, tip;
++      struct sk_buff *send_skb;
++      unsigned long flags;
++      struct list_head *p;
++      struct netpoll *np = 0;
++
++      spin_lock_irqsave(&rx_list_lock, flags);
++      list_for_each(p, &rx_list) {
++              np = list_entry(p, struct netpoll, rx_list);
++              if ( np->dev == skb->dev )
++                      break;
++              np = 0;
++      }
++      spin_unlock_irqrestore(&rx_list_lock, flags);
++
++      if (!np) return;
++
++      /* No arp on this interface */
++      if (!in_dev || skb->dev->flags & IFF_NOARP)
++              return;
++
++      if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
++                               (2 * skb->dev->addr_len) +
++                               (2 * sizeof(u32)))))
++              return;
++
++      skb->h.raw = skb->nh.raw = skb->data;
++      arp = skb->nh.arph;
++
++      if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
++           arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
++          arp->ar_pro != htons(ETH_P_IP) ||
++          arp->ar_op != htons(ARPOP_REQUEST))
++              return;
++
++      arp_ptr= (unsigned char *)(arp+1);
++      sha = arp_ptr;
++      arp_ptr += skb->dev->addr_len;
++      memcpy(&sip, arp_ptr, 4);
++      arp_ptr += 4;
++      tha = arp_ptr;
++      arp_ptr += skb->dev->addr_len;
++      memcpy(&tip, arp_ptr, 4);
++
++      /* Should we ignore arp? */
++      if (tip != in_dev->ifa_list->ifa_address ||
++          LOOPBACK(tip) || MULTICAST(tip))
++              return;
++
++
++      size = sizeof(struct arphdr) + 2 * (skb->dev->addr_len + 4);
++      send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev),
++                          LL_RESERVED_SPACE(np->dev));
++
++      if (!send_skb)
++              return;
++
++      send_skb->nh.raw = send_skb->data;
++      arp = (struct arphdr *) skb_put(send_skb, size);
++      send_skb->dev = skb->dev;
++      send_skb->protocol = htons(ETH_P_ARP);
++
++      /* Fill the device header for the ARP frame */
++
++      if (np->dev->hard_header &&
++          np->dev->hard_header(send_skb, skb->dev, ptype,
++                                     np->remote_mac, np->local_mac,
++                                     send_skb->len) < 0) {
++              kfree_skb(send_skb);
++              return;
++      }
++
++      /*
++       * Fill out the arp protocol part.
++       *
++       * we only support ethernet device type,
++       * which (according to RFC 1390) should always equal 1 (Ethernet).
++       */
++
++      arp->ar_hrd = htons(np->dev->type);
++      arp->ar_pro = htons(ETH_P_IP);
++      arp->ar_hln = np->dev->addr_len;
++      arp->ar_pln = 4;
++      arp->ar_op = htons(type);
++
++      arp_ptr=(unsigned char *)(arp + 1);
++      memcpy(arp_ptr, np->dev->dev_addr, np->dev->addr_len);
++      arp_ptr += np->dev->addr_len;
++      memcpy(arp_ptr, &tip, 4);
++      arp_ptr += 4;
++      memcpy(arp_ptr, np->local_mac, np->dev->addr_len);
++      arp_ptr += np->dev->addr_len;
++      memcpy(arp_ptr, &sip, 4);
++
++      netpoll_send_skb(np, send_skb);
++}
++
++int netpoll_rx(struct sk_buff *skb)
++{
++      int proto, len, ulen;
++      struct iphdr *iph;
++      struct udphdr *uh;
++      struct netpoll *np;
++      struct list_head *p;
++      unsigned long flags;
++
++      if (skb->dev->type != ARPHRD_ETHER)
++              goto out;
++
++      /* check if netpoll clients need ARP */
++      if (skb->protocol == __constant_htons(ETH_P_ARP) && trapped) {
++              arp_reply(skb);
++              return 1;
++      }
++
++      proto = ntohs(skb->mac.ethernet->h_proto);
++      if (proto != ETH_P_IP)
++              goto out;
++      if (skb->pkt_type == PACKET_OTHERHOST)
++              goto out;
++      if (skb_shared(skb))
++              goto out;
++
++      iph = (struct iphdr *)skb->data;
++      if (!pskb_may_pull(skb, sizeof(struct iphdr)))
++              goto out;
++      if (iph->ihl < 5 || iph->version != 4)
++              goto out;
++      if (!pskb_may_pull(skb, iph->ihl*4))
++              goto out;
++      if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
++              goto out;
++
++      len = ntohs(iph->tot_len);
++      if (skb->len < len || len < iph->ihl*4)
++              goto out;
++
++      if (iph->protocol != IPPROTO_UDP)
++              goto out;
++
++      len -= iph->ihl*4;
++      uh = (struct udphdr *)(((char *)iph) + iph->ihl*4);
++      ulen = ntohs(uh->len);
++
++      if (ulen != len)
++              goto out;
++      if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr) < 0)
++              goto out;
++
++      spin_lock_irqsave(&rx_list_lock, flags);
++      list_for_each(p, &rx_list) {
++              np = list_entry(p, struct netpoll, rx_list);
++              if (np->dev && np->dev != skb->dev)
++                      continue;
++              if (np->local_ip && np->local_ip != ntohl(iph->daddr))
++                      continue;
++              if (np->remote_ip && np->remote_ip != ntohl(iph->saddr))
++                      continue;
++              if (np->local_port && np->local_port != ntohs(uh->dest))
++                      continue;
++
++              spin_unlock_irqrestore(&rx_list_lock, flags);
++
++              if (np->rx_hook)
++                      np->rx_hook(np, ntohs(uh->source),
++                                  (char *)(uh+1), ulen-sizeof(uh)-4);
++
++              return 1;
++      }
++      spin_unlock_irqrestore(&rx_list_lock, flags);
++
++out:
++      return trapped;
++}
++
++int netpoll_parse_options(struct netpoll *np, char *opt)
++{
++      char *cur=opt, *delim;
++
++      if(*cur != '@') {
++              if ((delim = strchr(cur, '@')) == NULL)
++                      goto parse_failed;
++              *delim=0;
++              np->local_port=simple_strtol(cur, 0, 10);
++              cur=delim;
++      }
++      cur++;
++      printk(KERN_INFO "%s: local port %d\n", np->name, np->local_port);
++
++      if(*cur != '/') {
++              if ((delim = strchr(cur, '/')) == NULL)
++                      goto parse_failed;
++              *delim=0;
++              np->local_ip=ntohl(in_aton(cur));
++              cur=delim;
++
++              printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
++                     np->name, HIPQUAD(np->local_ip));
++      }
++      cur++;
++
++      if ( *cur != ',') {
++              /* parse out dev name */
++              if ((delim = strchr(cur, ',')) == NULL)
++                      goto parse_failed;
++              *delim=0;
++              strlcpy(np->dev_name, cur, sizeof(np->dev_name));
++              cur=delim;
++      }
++      cur++;
++
++      printk(KERN_INFO "%s: interface %s\n", np->name, np->dev_name);
++
++      if ( *cur != '@' ) {
++              /* dst port */
++              if ((delim = strchr(cur, '@')) == NULL)
++                      goto parse_failed;
++              *delim=0;
++              np->remote_port=simple_strtol(cur, 0, 10);
++              cur=delim;
++      }
++      cur++;
++      printk(KERN_INFO "%s: remote port %d\n", np->name, np->remote_port);
++
++      /* dst ip */
++      if ((delim = strchr(cur, '/')) == NULL)
++              goto parse_failed;
++      *delim=0;
++      np->remote_ip=ntohl(in_aton(cur));
++      cur=delim+1;
++
++      printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n",
++                     np->name, HIPQUAD(np->remote_ip));
++
++      if( *cur != 0 )
++      {
++              /* MAC address */
++              if ((delim = strchr(cur, ':')) == NULL)
++                      goto parse_failed;
++              *delim=0;
++              np->remote_mac[0]=simple_strtol(cur, 0, 16);
++              cur=delim+1;
++              if ((delim = strchr(cur, ':')) == NULL)
++                      goto parse_failed;
++              *delim=0;
++              np->remote_mac[1]=simple_strtol(cur, 0, 16);
++              cur=delim+1;
++              if ((delim = strchr(cur, ':')) == NULL)
++                      goto parse_failed;
++              *delim=0;
++              np->remote_mac[2]=simple_strtol(cur, 0, 16);
++              cur=delim+1;
++              if ((delim = strchr(cur, ':')) == NULL)
++                      goto parse_failed;
++              *delim=0;
++              np->remote_mac[3]=simple_strtol(cur, 0, 16);
++              cur=delim+1;
++              if ((delim = strchr(cur, ':')) == NULL)
++                      goto parse_failed;
++              *delim=0;
++              np->remote_mac[4]=simple_strtol(cur, 0, 16);
++              cur=delim+1;
++              np->remote_mac[5]=simple_strtol(cur, 0, 16);
++      }
++
++      printk(KERN_INFO "%s: remote ethernet address "
++             "%02x:%02x:%02x:%02x:%02x:%02x\n",
++             np->name,
++             np->remote_mac[0],
++             np->remote_mac[1],
++             np->remote_mac[2],
++             np->remote_mac[3],
++             np->remote_mac[4],
++             np->remote_mac[5]);
++
++      return 0;
++
++ parse_failed:
++      printk(KERN_INFO "%s: couldn't parse config at %s!\n",
++             np->name, cur);
++      return -1;
++}
++
++int netpoll_setup(struct netpoll *np)
++{
++      struct net_device *ndev = NULL;
++      struct in_device *in_dev;
++
++      if (np->dev_name)
++              ndev = dev_get_by_name(np->dev_name);
++      if (!ndev) {
++              printk(KERN_ERR "%s: %s doesn't exist, aborting.\n",
++                     np->name, np->dev_name);
++              goto release;
++      }
++      if (!ndev->poll_controller) {
++              printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
++                     np->name, np->dev_name);
++              goto release;
++      }
++
++      if (!(ndev->flags & IFF_UP)) {
++              unsigned short oflags;
++              unsigned long jiff;
++
++              printk(KERN_INFO "%s: device %s not up yet, forcing it\n",
++                     np->name, np->dev_name);
++
++              oflags = ndev->flags;
++
++              rtnl_shlock();
++              if (dev_change_flags(ndev, oflags | IFF_UP) < 0) {
++                      printk(KERN_ERR "%s: failed to open %s\n",
++                             np->name, np->dev_name);
++                      rtnl_shunlock();
++                      goto release;
++              }
++              rtnl_shunlock();
++
++              jiff = jiffies + 6*HZ;
++              while(!netif_carrier_ok(ndev)) {
++                      if (!time_before(jiffies, jiff)) {
++                              printk(KERN_NOTICE
++                                     "%s: timeout waiting for carrier\n",
++                                     np->name);
++                              break;
++                      }
++                      cond_resched();
++              }
++
++      }
++
++      if (!memcmp(np->local_mac, "\0\0\0\0\0\0", 6) && ndev->dev_addr)
++              memcpy(np->local_mac, ndev->dev_addr, 6);
++
++      if (!np->local_ip) {
++              in_dev = in_dev_get(ndev);
++
++              if (!in_dev) {
++                      printk(KERN_ERR "%s: no IP address for %s, aborting\n",
++                             np->name, np->dev_name);
++                      goto release;
++              }
++
++              np->local_ip = ntohl(in_dev->ifa_list->ifa_local);
++              in_dev_put(in_dev);
++              printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
++                     np->name, HIPQUAD(np->local_ip));
++      }
++
++      np->dev = ndev;
++
++      if(np->rx_hook) {
++              unsigned long flags;
++
++#ifdef CONFIG_NETPOLL_RX
++              np->dev->netpoll_rx = 1;
++#endif
++
++              spin_lock_irqsave(&rx_list_lock, flags);
++              list_add(&np->rx_list, &rx_list);
++              spin_unlock_irqrestore(&rx_list_lock, flags);
++      }
++
++      return 0;
++ release:
++      dev_put(ndev);
++      return -1;
++}
++
++void netpoll_cleanup(struct netpoll *np)
++{
++      if(np->rx_hook) {
++              unsigned long flags;
++
++              spin_lock_irqsave(&rx_list_lock, flags);
++              list_del(&np->rx_list);
++#ifdef CONFIG_NETPOLL_RX
++              np->dev->netpoll_rx = 0;
++#endif
++              spin_unlock_irqrestore(&rx_list_lock, flags);
++      }
++
++      dev_put(np->dev);
++      np->dev = 0;
++}
++
++int netpoll_trap()
++{
++      return trapped;
++}
++
++void netpoll_set_trap(int trap)
++{
++      trapped = trap;
++}
++
++EXPORT_SYMBOL(netpoll_set_trap);
++EXPORT_SYMBOL(netpoll_trap);
++EXPORT_SYMBOL(netpoll_parse_options);
++EXPORT_SYMBOL(netpoll_setup);
++EXPORT_SYMBOL(netpoll_cleanup);
++EXPORT_SYMBOL(netpoll_send_skb);
++EXPORT_SYMBOL(netpoll_send_udp);
++EXPORT_SYMBOL(netpoll_poll);
+--- linux-2.6.0/net/core/net-sysfs.c   2003-10-25 14:45:46.000000000 -0700
++++ 25/net/core/net-sysfs.c    2003-12-28 23:21:01.000000000 -0800
+@@ -372,7 +372,7 @@ static void netdev_release(struct class_
+       BUG_ON(dev->reg_state != NETREG_RELEASED);
+-      kfree(dev);
++      kfree((char *)dev - dev->padded);
+ }
+ static struct class net_class = {
+--- linux-2.6.0/net/Kconfig    2003-11-23 19:03:02.000000000 -0800
++++ 25/net/Kconfig     2003-12-28 23:21:09.000000000 -0800
+@@ -664,4 +664,19 @@ source "net/irda/Kconfig"
+ source "net/bluetooth/Kconfig"
++config KGDBOE
++      def_bool X86 && KGDB
++
++config NETPOLL
++      def_bool NETCONSOLE || KGDBOE
++
++config NETPOLL_RX
++      def_bool KGDBOE
++
++config NETPOLL_TRAP
++      def_bool KGDBOE
++
++config NET_POLL_CONTROLLER
++      def_bool NETPOLL
++
+ endmenu
+--- linux-2.6.0/net/socket.c   2003-11-23 19:03:03.000000000 -0800
++++ 25/net/socket.c    2003-12-28 23:21:18.000000000 -0800
+@@ -394,6 +394,7 @@ int sock_map_fd(struct socket *sock)
+               file->f_dentry->d_op = &sockfs_dentry_operations;
+               d_add(file->f_dentry, SOCK_INODE(sock));
+               file->f_vfsmnt = mntget(sock_mnt);
++              file->f_mapping = file->f_dentry->d_inode->i_mapping;
+               sock->file = file;
+               file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
+--- linux-2.6.0/net/wanrouter/wanmain.c        2003-09-27 18:57:47.000000000 -0700
++++ 25/net/wanrouter/wanmain.c 2003-12-28 23:21:01.000000000 -0800
+@@ -726,8 +726,6 @@ static int wanrouter_device_new_if(struc
+               if (dev->name == NULL) {
+                       err = -EINVAL;
+-              } else if (dev_get(dev->name)) {
+-                      err = -EEXIST;  /* name already exists */
+               } else {
+                       #ifdef WANDEBUG
+--- linux-2.6.0/README 2003-10-08 15:07:08.000000000 -0700
++++ 25/README  2003-12-28 23:22:44.000000000 -0800
+@@ -119,7 +119,7 @@ BUILD directory for the kernel:
+    cd /usr/src/linux-2.6.N
+    make O=/home/name/build/kernel menuconfig
+    make O=/home/name/build/kernel
+-   sudo make O=/home/name/build/kernel install_modules install
++   sudo make O=/home/name/build/kernel modules_install install
+    Please note: If the 'O=output/dir' option is used then it must be
+    used for all invocations of make.
+--- linux-2.6.0/scripts/kconfig/gconf.c        2003-08-08 22:55:14.000000000 -0700
++++ 25/scripts/kconfig/gconf.c 2003-12-28 23:22:45.000000000 -0800
+@@ -1172,7 +1172,7 @@ on_treeview1_button_press_event(GtkWidge
+       gtk_widget_realize(tree2_w);
+       gtk_tree_view_set_cursor(view, path, NULL, FALSE);
+-      gtk_widget_grab_focus(GTK_TREE_VIEW(tree2_w));
++      gtk_widget_grab_focus(GTK_WIDGET(tree2_w));
+       return FALSE;
+ }
+--- linux-2.6.0/scripts/mkspec 2003-09-27 18:57:47.000000000 -0700
++++ 25/scripts/mkspec  2003-12-28 23:23:07.000000000 -0800
+@@ -9,7 +9,7 @@
+ #     Patched for non-x86 by Opencon (L) 2002 <opencon@rio.skydome.net>
+ #
+ # That's the voodoo to see if it's a x86.
+-ISX86=`arch | grep -ie i.86`
++ISX86=`echo ${ARCH:=\`arch\`} | grep -ie i.86`
+ if [ ! -z $ISX86 ]; then
+       PC=1
+ else
+--- linux-2.6.0/scripts/modpost.c      2003-09-27 18:57:47.000000000 -0700
++++ 25/scripts/modpost.c       2003-12-28 23:22:29.000000000 -0800
+@@ -324,6 +324,19 @@ handle_modversions(struct module *mod, s
+       }
+ }
++int
++is_vmlinux(const char *modname)
++{
++      const char *myname;
++
++      if ((myname = strrchr(modname, '/')))
++              myname++;
++      else
++              myname = modname;
++
++      return strcmp(myname, "vmlinux") == 0;
++}
++
+ void
+ read_symbols(char *modname)
+ {
+@@ -335,8 +348,7 @@ read_symbols(char *modname)
+       /* When there's no vmlinux, don't print warnings about
+        * unresolved symbols (since there'll be too many ;) */
+-      if (strcmp(modname, "vmlinux") == 0)
+-              have_vmlinux = 1;
++      have_vmlinux = is_vmlinux(modname);
+       parse_elf(&info, modname);
+@@ -460,10 +472,7 @@ add_depends(struct buffer *b, struct mod
+       int first = 1;
+       for (m = modules; m; m = m->next) {
+-              if (strcmp(m->name, "vmlinux") == 0)
+-                      m->seen = 1;
+-              else 
+-                      m->seen = 0;
++              m->seen = is_vmlinux(m->name);
+       }
+       buf_printf(b, "\n");
+@@ -543,7 +552,7 @@ main(int argc, char **argv)
+       }
+       for (mod = modules; mod; mod = mod->next) {
+-              if (strcmp(mod->name, "vmlinux") == 0)
++              if (is_vmlinux(mod->name))
+                       continue;
+               buf.pos = 0;
+--- linux-2.6.0/security/selinux/hooks.c       2003-10-08 15:07:10.000000000 -0700
++++ 25/security/selinux/hooks.c        2003-12-28 23:22:42.000000000 -0800
+@@ -1515,7 +1515,8 @@ static void selinux_bprm_compute_creds(s
+       struct bprm_security_struct *bsec;
+       u32 sid;
+       struct av_decision avd;
+-      int rc;
++      struct itimerval itimer;
++      int rc, i;
+       secondary_ops->bprm_compute_creds(bprm);
+@@ -1565,6 +1566,26 @@ static void selinux_bprm_compute_creds(s
+               /* Close files for which the new task SID is not authorized. */
+               flush_unauthorized_files(current->files);
++              /* Check whether the new SID can inherit signal state
++                 from the old SID.  If not, clear itimers to avoid
++                 subsequent signal generation and flush and unblock
++                 signals. This must occur _after_ the task SID has
++                  been updated so that any kill done after the flush
++                  will be checked against the new SID. */
++              rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,
++                                PROCESS__SIGINH, NULL, NULL);
++              if (rc) {
++                      memset(&itimer, 0, sizeof itimer);
++                      for (i = 0; i < 3; i++)
++                              do_setitimer(i, &itimer, NULL);
++                      flush_signals(current);
++                      spin_lock_irq(&current->sighand->siglock);
++                      flush_signal_handlers(current, 1);
++                      sigemptyset(&current->blocked);
++                      recalc_sigpending();
++                      spin_unlock_irq(&current->sighand->siglock);
++              }
++
+               /* Wake up the parent if it is waiting so that it can
+                  recheck wait permission to the new task SID. */
+               wake_up_interruptible(&current->parent->wait_chldexit);
+@@ -1738,10 +1759,6 @@ static int selinux_inode_permission(stru
+               return 0;
+       }
+-      if (nd && nd->dentry)
+-              return dentry_has_perm(current, nd->mnt, nd->dentry,
+-                                     file_mask_to_av(inode->i_mode, mask));
+-
+       return inode_has_perm(current, inode,
+                              file_mask_to_av(inode->i_mode, mask), NULL, NULL);
+ }
+@@ -1992,8 +2009,7 @@ static int selinux_file_ioctl(struct fil
+               case KDSKBENT:
+               case KDSKBSENT:
+-                      if (!capable(CAP_SYS_TTY_CONFIG))
+-                              error = -EPERM;
++                      error = task_has_capability(current,CAP_SYS_TTY_CONFIG);
+                       break;
+               /* default case assumes that the command will go
+--- linux-2.6.0/security/selinux/include/av_permissions.h      2003-08-08 22:55:14.000000000 -0700
++++ 25/security/selinux/include/av_permissions.h       2003-12-28 23:22:42.000000000 -0800
+@@ -450,6 +450,7 @@
+ #define PROCESS__SETEXEC                          0x00020000UL
+ #define PROCESS__SETFSCREATE                      0x00040000UL
+ #define PROCESS__NOATSECURE                       0x00080000UL
++#define PROCESS__SIGINH                           0x00100000UL
+ #define IPC__SETATTR                              0x00000008UL
+ #define IPC__READ                                 0x00000010UL
+--- linux-2.6.0/security/selinux/include/av_perm_to_string.h   2003-08-08 22:55:14.000000000 -0700
++++ 25/security/selinux/include/av_perm_to_string.h    2003-12-28 23:22:42.000000000 -0800
+@@ -66,6 +66,7 @@ static struct av_perm_to_string av_perm_
+    { SECCLASS_PROCESS, PROCESS__SETEXEC, "setexec" },
+    { SECCLASS_PROCESS, PROCESS__SETFSCREATE, "setfscreate" },
+    { SECCLASS_PROCESS, PROCESS__NOATSECURE, "noatsecure" },
++   { SECCLASS_PROCESS, PROCESS__SIGINH, "siginh" },
+    { SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue" },
+    { SECCLASS_MSG, MSG__SEND, "send" },
+    { SECCLASS_MSG, MSG__RECEIVE, "receive" },
+--- linux-2.6.0/security/selinux/ss/avtab.c    2003-09-08 13:58:59.000000000 -0700
++++ 25/security/selinux/ss/avtab.c     2003-12-28 23:22:41.000000000 -0800
+@@ -3,6 +3,10 @@
+  *
+  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+  */
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/errno.h>
+ #include "avtab.h"
+ #include "policydb.h"
+--- linux-2.6.0/security/selinux/ss/ebitmap.c  2003-09-08 13:58:59.000000000 -0700
++++ 25/security/selinux/ss/ebitmap.c   2003-12-28 23:22:41.000000000 -0800
+@@ -3,6 +3,9 @@
+  *
+  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+  */
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/errno.h>
+ #include "ebitmap.h"
+ #include "policydb.h"
+--- linux-2.6.0/security/selinux/ss/global.h   2003-09-08 13:58:59.000000000 -0700
++++ 25/security/selinux/ss/global.h    2003-12-28 23:22:41.000000000 -0800
+@@ -1,18 +0,0 @@
+-#ifndef _SS_GLOBAL_H_
+-#define _SS_GLOBAL_H_
+-
+-#include <linux/kernel.h>
+-#include <linux/slab.h>
+-#include <linux/string.h>
+-#include <linux/ctype.h>
+-#include <linux/in.h>
+-#include <linux/spinlock.h>
+-#include <linux/sched.h>
+-#include <linux/vmalloc.h>
+-
+-#include "flask.h"
+-#include "avc.h"
+-#include "avc_ss.h"
+-#include "security.h"
+-
+-#endif /* _SS_GLOBAL_H_ */
+--- linux-2.6.0/security/selinux/ss/hashtab.c  2003-08-08 22:55:14.000000000 -0700
++++ 25/security/selinux/ss/hashtab.c   2003-12-28 23:22:41.000000000 -0800
+@@ -3,6 +3,9 @@
+  *
+  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+  */
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/errno.h>
+ #include "hashtab.h"
+ struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, void *key),
+--- linux-2.6.0/security/selinux/ss/Makefile   2003-08-08 22:55:14.000000000 -0700
++++ 25/security/selinux/ss/Makefile    2003-12-28 23:22:41.000000000 -0800
+@@ -2,8 +2,7 @@
+ # Makefile for building the SELinux security server as part of the kernel tree.
+ #
+-EXTRA_CFLAGS += -Isecurity/selinux/include -include security/selinux/ss/global.h
+-
++EXTRA_CFLAGS += -Isecurity/selinux/include
+ obj-y := ss.o
+ ss-objs := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o
+--- linux-2.6.0/security/selinux/ss/mls.c      2003-09-27 18:57:47.000000000 -0700
++++ 25/security/selinux/ss/mls.c       2003-12-28 23:22:41.000000000 -0800
+@@ -3,6 +3,10 @@
+  *
+  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+  */
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/errno.h>
+ #include "mls.h"
+ #include "policydb.h"
+ #include "services.h"
+--- linux-2.6.0/security/selinux/ss/policydb.c 2003-09-27 18:57:47.000000000 -0700
++++ 25/security/selinux/ss/policydb.c  2003-12-28 23:22:41.000000000 -0800
+@@ -3,6 +3,11 @@
+  *
+  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+  */
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/errno.h>
++#include "security.h"
+ #include "policydb.h"
+ #include "mls.h"
+--- linux-2.6.0/security/selinux/ss/services.c 2003-10-08 15:07:10.000000000 -0700
++++ 25/security/selinux/ss/services.c  2003-12-28 23:22:41.000000000 -0800
+@@ -10,6 +10,17 @@
+  *    it under the terms of the GNU General Public License version 2,
+  *      as published by the Free Software Foundation.
+  */
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/spinlock.h>
++#include <linux/errno.h>
++#include <linux/in.h>
++#include <asm/semaphore.h>
++#include "flask.h"
++#include "avc.h"
++#include "avc_ss.h"
++#include "security.h"
+ #include "context.h"
+ #include "policydb.h"
+ #include "sidtab.h"
+--- linux-2.6.0/security/selinux/ss/sidtab.c   2003-08-08 22:55:14.000000000 -0700
++++ 25/security/selinux/ss/sidtab.c    2003-12-28 23:22:41.000000000 -0800
+@@ -3,6 +3,12 @@
+  *
+  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+  */
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/errno.h>
++#include "flask.h"
++#include "security.h"
+ #include "sidtab.h"
+ #define SIDTAB_HASH(sid) \
+--- linux-2.6.0/security/selinux/ss/symtab.c   2003-08-08 22:55:14.000000000 -0700
++++ 25/security/selinux/ss/symtab.c    2003-12-28 23:22:41.000000000 -0800
+@@ -3,6 +3,10 @@
+  *
+  * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
+  */
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/errno.h>
+ #include "symtab.h"
+ static unsigned int symhash(struct hashtab *h, void *key)
+--- linux-2.6.0/sound/core/pcm_native.c        2003-10-25 14:45:46.000000000 -0700
++++ 25/sound/core/pcm_native.c 2003-12-28 23:22:12.000000000 -0800
+@@ -2779,7 +2779,7 @@ unsigned int snd_pcm_capture_poll(struct
+       return mask;
+ }
+-static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, unsigned long address, int no_share)
++static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, unsigned long address, int *type)
+ {
+       snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
+       snd_pcm_runtime_t *runtime;
+@@ -2791,6 +2791,8 @@ static struct page * snd_pcm_mmap_status
+       page = virt_to_page(runtime->status);
+       if (!PageReserved(page))
+               get_page(page);
++      if (type)
++              *type = VM_FAULT_MINOR;
+       return page;
+ }
+@@ -2817,7 +2819,7 @@ int snd_pcm_mmap_status(snd_pcm_substrea
+       return 0;
+ }
+-static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, unsigned long address, int no_share)
++static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, unsigned long address, int *type)
+ {
+       snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
+       snd_pcm_runtime_t *runtime;
+@@ -2829,6 +2831,8 @@ static struct page * snd_pcm_mmap_contro
+       page = virt_to_page(runtime->control);
+       if (!PageReserved(page))
+               get_page(page);
++      if (type)
++              *type = VM_FAULT_MINOR;
+       return page;
+ }
+@@ -2867,7 +2871,7 @@ static void snd_pcm_mmap_data_close(stru
+       atomic_dec(&substream->runtime->mmap_count);
+ }
+-static struct page * snd_pcm_mmap_data_nopage(struct vm_area_struct *area, unsigned long address, int no_share)
++static struct page * snd_pcm_mmap_data_nopage(struct vm_area_struct *area, unsigned long address, int *type)
+ {
+       snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
+       snd_pcm_runtime_t *runtime;
+@@ -2895,6 +2899,8 @@ static struct page * snd_pcm_mmap_data_n
+       }
+       if (!PageReserved(page))
+               get_page(page);
++      if (type)
++              *type = VM_FAULT_MINOR;
+       return page;
+ }
+--- linux-2.6.0/sound/core/sound.c     2003-09-27 18:57:47.000000000 -0700
++++ 25/sound/core/sound.c      2003-12-28 23:22:25.000000000 -0800
+@@ -31,6 +31,7 @@
+ #include <sound/initval.h>
+ #include <linux/kmod.h>
+ #include <linux/devfs_fs_kernel.h>
++#include <linux/device.h>
+ #define SNDRV_OS_MINORS 256
+@@ -52,6 +53,7 @@ MODULE_PARM_SYNTAX(major, "default:116,s
+ MODULE_PARM(cards_limit, "i");
+ MODULE_PARM_DESC(cards_limit, "Count of soundcards installed in the system.");
+ MODULE_PARM_SYNTAX(cards_limit, "default:8,skill:advanced");
++MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
+ #ifdef CONFIG_DEVFS_FS
+ MODULE_PARM(device_mode, "i");
+ MODULE_PARM_DESC(device_mode, "Device file permission mask for devfs.");
+--- linux-2.6.0/sound/i2c/i2c.c        2003-06-14 12:18:09.000000000 -0700
++++ 25/sound/i2c/i2c.c 2003-12-28 23:22:19.000000000 -0800
+@@ -84,7 +84,7 @@ int snd_i2c_bus_create(snd_card_t *card,
+       bus = (snd_i2c_bus_t *)snd_magic_kcalloc(snd_i2c_bus_t, 0, GFP_KERNEL);
+       if (bus == NULL)
+               return -ENOMEM;
+-      spin_lock_init(&bus->lock);
++      init_MUTEX(&bus->lock_mutex);
+       INIT_LIST_HEAD(&bus->devices);
+       INIT_LIST_HEAD(&bus->buses);
+       bus->card = card;
+--- linux-2.6.0/sound/isa/gus/gus_pcm.c        2003-06-14 12:18:08.000000000 -0700
++++ 25/sound/isa/gus/gus_pcm.c 2003-12-28 23:22:44.000000000 -0800
+@@ -334,9 +334,11 @@ static int snd_gf1_pcm_poke_block(snd_gu
+                                       snd_gf1_poke(gus, pos++, *buf++ ^ invert);
+                       }
+               }
+-              schedule_timeout(1);
+-              if (signal_pending(current))
+-                      return -EAGAIN;
++              if (count > 0 && !in_interrupt()) {
++                      schedule_timeout(1);
++                      if (signal_pending(current))
++                              return -EAGAIN;
++              }
+       }
+       return 0;
+ }
+--- linux-2.6.0/sound/oss/cmpci.c      2003-11-09 16:45:06.000000000 -0800
++++ 25/sound/oss/cmpci.c       2003-12-28 23:21:54.000000000 -0800
+@@ -2876,7 +2876,6 @@ MODULE_DEVICE_TABLE(pci, cmpci_pci_tbl);
+ void initialize_chip(struct pci_dev *pcidev)
+ {
+       struct cm_state *s;
+-      mm_segment_t fs;
+       int i, val;
+ #if defined(CONFIG_SOUND_CMPCI_MIDI) || defined(CONFIG_SOUND_CMPCI_FM)
+       unsigned char reg_mask = 0;
+@@ -3038,8 +3037,6 @@ void initialize_chip(struct pci_dev *pci
+ #endif
+               pci_set_master(pcidev); /* enable bus mastering */
+               /* initialize the chips */
+-              fs = get_fs();
+-              set_fs(KERNEL_DS);
+               /* set mixer output */
+               frobindir(s, DSP_MIX_OUTMIXIDX, 0x1f, 0x1f);
+               /* set mixer input */
+--- linux-2.6.0/sound/oss/dmasound/Kconfig     2003-10-08 15:07:10.000000000 -0700
++++ 25/sound/oss/dmasound/Kconfig      2003-12-28 23:23:06.000000000 -0800
+@@ -10,7 +10,7 @@ config DMASOUND_ATARI
+         This driver is also available as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you
+         want). If you want to compile it as a module, say M here and read
+-        <file:Documentation/modules.txt>.
++        <file:Documentation/kbuild/modules.txt>.
+ config DMASOUND_PMAC
+       tristate "PowerMac DMA sound support"
+@@ -24,7 +24,7 @@ config DMASOUND_PMAC
+         This driver is also available as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you
+         want). If you want to compile it as a module, say M here and read
+-        <file:Documentation/modules.txt>.
++        <file:Documentation/kbuild/modules.txt>.
+ config DMASOUND_PAULA
+       tristate "Amiga DMA sound support"
+@@ -38,7 +38,7 @@ config DMASOUND_PAULA
+         This driver is also available as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you
+         want). If you want to compile it as a module, say M here and read
+-        <file:Documentation/modules.txt>.
++        <file:Documentation/kbuild/modules.txt>.
+ config DMASOUND_Q40
+       tristate "Q40 sound support"
+@@ -52,7 +52,7 @@ config DMASOUND_Q40
+         This driver is also available as a module ( = code which can be
+         inserted in and removed from the running kernel whenever you
+         want). If you want to compile it as a module, say M here and read
+-        <file:Documentation/modules.txt>.
++        <file:Documentation/kbuild/modules.txt>.
+ config DMASOUND
+       tristate
+--- linux-2.6.0/sound/oss/emu10k1/audio.c      2003-09-08 13:58:59.000000000 -0700
++++ 25/sound/oss/emu10k1/audio.c       2003-12-28 23:22:12.000000000 -0800
+@@ -989,7 +989,7 @@ static int emu10k1_audio_ioctl(struct in
+       return 0;
+ }
+-static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned long address, int write_access)
++static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned long address, int *type)
+ {
+       struct emu10k1_wavedevice *wave_dev = vma->vm_private_data;
+       struct woinst *woinst = wave_dev->woinst;
+@@ -1032,6 +1032,8 @@ static struct page *emu10k1_mm_nopage (s
+       get_page (dmapage);
+       DPD(3, "page: %#lx\n", (unsigned long) dmapage);
++      if (type)
++              *type = VM_FAULT_MINOR;
+       return dmapage;
+ }
+--- linux-2.6.0/sound/oss/Kconfig      2003-10-17 15:58:05.000000000 -0700
++++ 25/sound/oss/Kconfig       2003-12-28 23:23:06.000000000 -0800
+@@ -25,7 +25,7 @@ config SOUND_CMPCI
+       depends on SOUND_PRIME!=n && SOUND && PCI
+       help
+         Say Y or M if you have a PCI sound card using the CMI8338
+-        or the CMI8378 chipset.  Data on these chips are available at
++        or the CMI8738 chipset.  Data on these chips are available at
+         <http://www.cmedia.com.tw/>.
+         A userspace utility to control some internal registers of these
+@@ -195,7 +195,7 @@ config SOUND_ES1371
+         Ensoniq was bought by Creative Labs, Sound Blaster 64/PCI
+         models are either ES1370 or ES1371 based. This driver differs
+         slightly from OSS/Free, so PLEASE READ
+-        <file:Documentation/sound/es1371>.
++        <file:Documentation/sound/oss/es1371>.
+ config SOUND_ESSSOLO1
+       tristate "ESS Technology Solo1"
+--- linux-2.6.0/sound/oss/via82cxxx_audio.c    2003-10-17 15:58:05.000000000 -0700
++++ 25/sound/oss/via82cxxx_audio.c     2003-12-28 23:22:33.000000000 -0800
+@@ -15,7 +15,7 @@
+  */
+-#define VIA_VERSION   "1.9.1-ac3-2.5"
++#define VIA_VERSION   "1.9.1-ac4-2.5"
+ #include <linux/config.h>
+@@ -1237,7 +1237,6 @@ static int via_chan_set_stereo (struct v
+               }
+       /* unknown */
+       default:
+-              printk (KERN_WARNING PFX "unknown number of channels\n");
+               val = -EINVAL;
+               break;
+       }
+@@ -2116,7 +2115,7 @@ static void via_dsp_cleanup (struct via_
+ static struct page * via_mm_nopage (struct vm_area_struct * vma,
+-                                  unsigned long address, int write_access)
++                                  unsigned long address, int *type)
+ {
+       struct via_info *card = vma->vm_private_data;
+       struct via_channel *chan = &card->ch_out;
+@@ -2124,12 +2123,11 @@ static struct page * via_mm_nopage (stru
+       unsigned long pgoff;
+       int rd, wr;
+-      DPRINTK ("ENTER, start %lXh, ofs %lXh, pgoff %ld, addr %lXh, wr %d\n",
++      DPRINTK ("ENTER, start %lXh, ofs %lXh, pgoff %ld, addr %lXh\n",
+                vma->vm_start,
+                address - vma->vm_start,
+                (address - vma->vm_start) >> PAGE_SHIFT,
+-               address,
+-               write_access);
++               address);
+         if (address > vma->vm_end) {
+               DPRINTK ("EXIT, returning NOPAGE_SIGBUS\n");
+@@ -2167,6 +2165,8 @@ static struct page * via_mm_nopage (stru
+       DPRINTK ("EXIT, returning page %p for cpuaddr %lXh\n",
+                dmapage, (unsigned long) chan->pgtbl[pgoff].cpuaddr);
+       get_page (dmapage);
++      if (type)
++              *type = VM_FAULT_MINOR;
+       return dmapage;
+ }
+@@ -3367,7 +3367,7 @@ static int via_dsp_release(struct inode 
+       if (file->f_mode & FMODE_WRITE) {
+               rc = via_dsp_drain_playback (card, &card->ch_out, nonblock);
+-              if (rc && rc != ERESTARTSYS)    /* Nobody needs to know about ^C */
++              if (rc && rc != -ERESTARTSYS)   /* Nobody needs to know about ^C */
+                       printk (KERN_DEBUG "via_audio: ignoring drain playback error %d\n", rc);
+               via_chan_free (card, &card->ch_out);
+--- linux-2.6.0/sound/oss/vwsnd.c      2003-09-27 18:57:48.000000000 -0700
++++ 25/sound/oss/vwsnd.c       2003-12-28 23:23:06.000000000 -0800
+@@ -1,6 +1,6 @@
+ /*
+  * Sound driver for Silicon Graphics 320 and 540 Visual Workstations'
+- * onboard audio.  See notes in ../../Documentation/sound/vwsnd .
++ * onboard audio.  See notes in ../../Documentation/sound/oss/vwsnd .
+  *
+  * Copyright 1999 Silicon Graphics, Inc.  All rights reserved.
+  *
+--- linux-2.6.0/sound/pci/intel8x0.c   2003-11-09 16:45:06.000000000 -0800
++++ 25/sound/pci/intel8x0.c    2003-12-28 23:21:41.000000000 -0800
+@@ -2271,10 +2271,8 @@ static void __devinit intel8x0_measure_a
+       t = stop_time.tv_sec - start_time.tv_sec;
+       t *= 1000000;
+-      if (stop_time.tv_usec < start_time.tv_usec)
+-              t -= start_time.tv_usec - stop_time.tv_usec;
+-      else
+-              t += stop_time.tv_usec - start_time.tv_usec;
++      t += stop_time.tv_usec - start_time.tv_usec;
++      printk(KERN_INFO "%s: measured %lu usecs\n", __FUNCTION__, t);
+       if (t == 0) {
+               snd_printk(KERN_ERR "?? calculation error..\n");
+               return;
+--- linux-2.6.0/sound/pcmcia/vx/vx_entry.c     2003-09-27 18:57:48.000000000 -0700
++++ 25/sound/pcmcia/vx/vx_entry.c      2003-12-28 23:22:54.000000000 -0800
+@@ -38,9 +38,9 @@ static void vxpocket_release(dev_link_t 
+ {
+       if (link->state & DEV_CONFIG) {
+               /* release cs resources */
+-              CardServices(ReleaseConfiguration, link->handle);
+-              CardServices(ReleaseIO, link->handle, &link->io);
+-              CardServices(ReleaseIRQ, link->handle, &link->irq);
++              pcmcia_release_configuration(link->handle);
++              pcmcia_release_io(link->handle, &link->io);
++              pcmcia_release_irq(link->handle, &link->irq);
+               link->state &= ~DEV_CONFIG;
+       }
+ }
+@@ -58,7 +58,7 @@ static int snd_vxpocket_free(vx_core_t *
+       /* Break the link with Card Services */
+       if (link->handle)
+-              CardServices(DeregisterClient, link->handle);
++              pcmcia_deregister_client(link->handle);
+       hw = vxp->hw_entry;
+       if (hw)
+@@ -170,7 +170,7 @@ dev_link_t *snd_vxpocket_attach(struct s
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+-      ret = CardServices(RegisterClient, &link->handle, &client_reg);
++      ret = pcmcia_register_client(&link->handle, &client_reg);
+       if (ret != CS_SUCCESS) {
+               cs_error(link->handle, RegisterClient, ret);
+               snd_vxpocket_detach(hw, link);
+@@ -253,8 +253,8 @@ void snd_vxpocket_detach_all(struct snd_
+  * configuration callback
+  */
+-#define CS_CHECK(fn, args...) \
+-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
++#define CS_CHECK(fn, ret) \
++do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+ static void vxpocket_config(dev_link_t *link)
+ {
+@@ -274,21 +274,21 @@ static void vxpocket_config(dev_link_t *
+       tuple.TupleDataMax = sizeof(buf);
+       tuple.TupleOffset = 0;
+       tuple.DesiredTuple = CISTPL_CONFIG;
+-      CS_CHECK(GetFirstTuple, handle, &tuple);
+-      CS_CHECK(GetTupleData, handle, &tuple);
+-      CS_CHECK(ParseTuple, handle, &tuple, &parse);
++      CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
++      CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
++      CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+       link->conf.ConfigBase = parse.config.base;
+       link->conf.ConfigIndex = 1;
+-      CS_CHECK(GetConfigurationInfo, handle, &conf);
++      CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
+       link->conf.Vcc = conf.Vcc;
+       /* Configure card */
+       link->state |= DEV_CONFIG;
+-      CS_CHECK(RequestIO, handle, &link->io);
+-      CS_CHECK(RequestIRQ, link->handle, &link->irq);
+-      CS_CHECK(RequestConfiguration, link->handle, &link->conf);
++      CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io));
++      CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
++      CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+       if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
+               goto failed;
+@@ -300,9 +300,9 @@ static void vxpocket_config(dev_link_t *
+ cs_failed:
+       cs_error(link->handle, last_fn, last_ret);
+ failed:
+-      CardServices(ReleaseConfiguration, link->handle);
+-      CardServices(ReleaseIO, link->handle, &link->io);
+-      CardServices(ReleaseIRQ, link->handle, &link->irq);
++      pcmcia_release_configuration(link->handle);
++      pcmcia_release_io(link->handle, &link->io);
++      pcmcia_release_irq(link->handle, &link->irq);
+ }
+@@ -339,7 +339,7 @@ static int vxpocket_event(event_t event,
+       case CS_EVENT_RESET_PHYSICAL:
+               snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
+               if (link->state & DEV_CONFIG)
+-                      CardServices(ReleaseConfiguration, link->handle);
++                      pcmcia_release_configuration(link->handle);
+               break;
+       case CS_EVENT_PM_RESUME:
+               snd_printdd(KERN_DEBUG "RESUME\n");
+@@ -350,7 +350,7 @@ static int vxpocket_event(event_t event,
+               if (DEV_OK(link)) {
+                       //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
+                       snd_printdd(KERN_DEBUG "requestconfig...\n");
+-                      CardServices(RequestConfiguration, link->handle, &link->conf);
++                      pcmcia_request_configuration(link->handle, &link->conf);
+                       if (chip) {
+                               snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
+                               snd_vx_resume(chip);
+--- linux-2.6.0/sound/sound_core.c     2003-09-08 13:58:59.000000000 -0700
++++ 25/sound/sound_core.c      2003-12-28 23:22:25.000000000 -0800
+@@ -45,6 +45,7 @@
+ #include <linux/major.h>
+ #include <linux/kmod.h>
+ #include <linux/devfs_fs_kernel.h>
++#include <linux/device.h>
+ #define SOUND_STEP 16
+@@ -547,6 +548,7 @@ EXPORT_SYMBOL(mod_firmware_load);
+ MODULE_DESCRIPTION("Core sound module");
+ MODULE_AUTHOR("Alan Cox");
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS_CHARDEV_MAJOR(SOUND_MAJOR);
+ static void __exit cleanup_soundcore(void)
+ {
+--- linux-2.6.0/usr/gen_init_cpio.c    2003-09-27 18:57:48.000000000 -0700
++++ 25/usr/gen_init_cpio.c     2003-12-28 23:22:09.000000000 -0800
+@@ -197,6 +197,7 @@ void cpio_mkfile(const char *filename, c
+       for (i = 0; i < buf.st_size; ++i)
+               fputc(filebuf[i], stdout);
++      offset += buf.st_size;
+       close(file);
+       free(filebuf);
+       push_pad();